mirror of
https://github.com/apache/nuttx.git
synced 2026-10-06 22:05:21 +00:00
sensors/bh1749nuc: add support for the new sensor framework
bh1749nuc can be used with the new sensor framework
This commit is contained in:
parent
7c4e3aff14
commit
41803a0c20
8 changed files with 870 additions and 200 deletions
|
|
@ -60,6 +60,15 @@ if(CONFIG_SENSORS)
|
|||
list(APPEND SRCS adxl362_uorb.c)
|
||||
endif()
|
||||
|
||||
if(CONFIG_SENSORS_BH1749NUC)
|
||||
list(APPEND SRCS bh1749nuc_base.c)
|
||||
if(CONFIG_SENSORS_BH1749NUC_UORB)
|
||||
list(APPEND SRCS bh1749nuc_uorb.c)
|
||||
else()
|
||||
list(APPEND SRCS bh1749nuc.c)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CONFIG_SENSORS_DHTXX)
|
||||
list(APPEND SRCS dhtxx.c)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -141,6 +141,39 @@ config SENSORS_BH1749NUC
|
|||
---help---
|
||||
Enable driver support for the Rohm BH1749NUC color sensor.
|
||||
|
||||
if SENSORS_BH1749NUC
|
||||
|
||||
config SENSORS_BH1749NUC_UORB
|
||||
bool "BH1749NUC UORB Interface"
|
||||
default n
|
||||
|
||||
if SENSORS_BH1749NUC_UORB
|
||||
|
||||
config SENSORS_BH1749NUC_POLL
|
||||
bool "Enables polling sensor data"
|
||||
default n
|
||||
---help---
|
||||
Enables polling of sensor.
|
||||
|
||||
config SENSORS_BH1749NUC_POLL_INTERVAL
|
||||
int "Polling interval in microseconds, default 1 sec"
|
||||
depends on SENSORS_BH1749NUC_POLL
|
||||
default 1000000
|
||||
range 0 4294967295
|
||||
---help---
|
||||
The interval until a new sensor measurement will be triggered.
|
||||
|
||||
config SENSORS_BH1749NUC_THREAD_STACKSIZE
|
||||
int "Worker thread stack size"
|
||||
depends on SENSORS_BH1749NUC_POLL
|
||||
default 1024
|
||||
---help---
|
||||
The stack size for the worker thread.
|
||||
|
||||
endif #SENSORS_BH1749NUC_UORB
|
||||
|
||||
endif # SENSORS_BH1749NUC
|
||||
|
||||
config SENSORS_BH1750FVI
|
||||
bool "Rohm BH1750FVI Ambient Light Sensor support"
|
||||
default n
|
||||
|
|
|
|||
|
|
@ -147,8 +147,13 @@ ifeq ($(CONFIG_ADXL345_I2C),y)
|
|||
endif
|
||||
|
||||
ifeq ($(CONFIG_SENSORS_BH1749NUC),y)
|
||||
CSRCS += bh1749nuc_base.c
|
||||
ifeq ($(CONFIG_SENSORS_BH1749NUC_UORB),y)
|
||||
CSRCS += bh1749nuc_uorb.c
|
||||
else
|
||||
CSRCS += bh1749nuc.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SENSORS_BH1750FVI),y)
|
||||
CSRCS += bh1750fvi.c
|
||||
|
|
|
|||
|
|
@ -24,66 +24,7 @@
|
|||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
|
||||
#include <nuttx/sensors/bh1749nuc.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define BH1749NUC_I2C_FREQ 400000
|
||||
|
||||
#define BH1749NUC_MANUFACTID 0xE0 /* Manufact ID */
|
||||
#define BH1749NUC_PARTID 0x0D /* Part ID */
|
||||
|
||||
/* BH1749NUC Registers */
|
||||
|
||||
#define BH1749NUC_SYSTEM_CONTROL 0x40
|
||||
#define BH1749NUC_MODE_CONTROL1 0x41
|
||||
#define BH1749NUC_MODE_CONTROL2 0x42
|
||||
#define BH1749NUC_RED_DATA_LSB 0x50
|
||||
#define BH1749NUC_GREEN_DATA_LSB 0x52
|
||||
#define BH1749NUC_BLUE_DATA_LSB 0x54
|
||||
#define BH1749NUC_IR_DATA_LSB 0x58
|
||||
#define BH1749NUC_GREEN2_DATA_LSB 0x5a
|
||||
#define BH1749NUC_MANUFACTURER_ID 0x92
|
||||
|
||||
/* Register SYSTEM_CONTROL */
|
||||
|
||||
#define BH1749NUC_SYSTEM_CONTROL_SW_RESET (1 << 7)
|
||||
#define BH1749NUC_SYSTEM_CONTROL_INT_RESET (1 << 6)
|
||||
|
||||
/* Register MODE_CONTROL1 */
|
||||
|
||||
#define BH1749NUC_MODE_CONTROL1_IR_GAIN_X1 (0x20)
|
||||
#define BH1749NUC_MODE_CONTROL1_IR_GAIN_X32 (0x60)
|
||||
#define BH1749NUC_MODE_CONTROL1_RGB_GAIN_X1 (0x08)
|
||||
#define BH1749NUC_MODE_CONTROL1_RGB_GAIN_X32 (0x18)
|
||||
#define BH1749NUC_MODE_CONTROL1_MEAS_TIME160MS (0x02)
|
||||
|
||||
/* Register MODE_CONTROL2 */
|
||||
|
||||
#define BH1749NUC_MODE_CONTROL2_RGBI_EN (1 << 4)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Structure for bh1749nuc device */
|
||||
|
||||
struct bh1749nuc_dev_s
|
||||
{
|
||||
FAR struct i2c_master_s *i2c; /* I2C interface */
|
||||
int freq; /* Frequency */
|
||||
uint8_t addr; /* I2C address */
|
||||
};
|
||||
#include "bh1749nuc_base.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
|
|
@ -120,146 +61,6 @@ static const struct file_operations g_bh1749nucfops =
|
|||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bh1749nuc_getreg8
|
||||
*
|
||||
* Description:
|
||||
* Read from an 8-bit BH1749NUC register
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint8_t bh1749nuc_getreg8(FAR struct bh1749nuc_dev_s *priv,
|
||||
uint8_t regaddr)
|
||||
{
|
||||
struct i2c_msg_s msg[2];
|
||||
uint8_t regval = 0;
|
||||
int ret;
|
||||
|
||||
msg[0].frequency = priv->freq;
|
||||
msg[0].addr = priv->addr;
|
||||
msg[0].flags = I2C_M_NOSTOP;
|
||||
msg[0].buffer = ®addr;
|
||||
msg[0].length = 1;
|
||||
|
||||
msg[1].frequency = priv->freq;
|
||||
msg[1].addr = priv->addr;
|
||||
msg[1].flags = I2C_M_READ;
|
||||
msg[1].buffer = ®val;
|
||||
msg[1].length = 1;
|
||||
|
||||
ret = I2C_TRANSFER(priv->i2c, msg, 2);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("I2C_TRANSFER failed: %d\n", ret);
|
||||
}
|
||||
|
||||
return regval;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bh1749nuc_read16
|
||||
*
|
||||
* Description:
|
||||
* Read 16-bit register
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint16_t bh1749nuc_read16(FAR struct bh1749nuc_dev_s *priv,
|
||||
uint8_t regaddr)
|
||||
{
|
||||
struct i2c_msg_s msg[2];
|
||||
uint8_t regval[2];
|
||||
int ret;
|
||||
|
||||
msg[0].frequency = priv->freq;
|
||||
msg[0].addr = priv->addr;
|
||||
msg[0].flags = I2C_M_NOSTOP;
|
||||
msg[0].buffer = ®addr;
|
||||
msg[0].length = 1;
|
||||
|
||||
msg[1].frequency = priv->freq;
|
||||
msg[1].addr = priv->addr;
|
||||
msg[1].flags = I2C_M_READ;
|
||||
msg[1].buffer = (uint8_t *)®val;
|
||||
msg[1].length = 2;
|
||||
|
||||
ret = I2C_TRANSFER(priv->i2c, msg, 2);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("I2C_TRANSFER failed: %d\n", ret);
|
||||
}
|
||||
|
||||
return regval[1] << 8 | regval[0] << 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bh1749nuc_putreg8
|
||||
*
|
||||
* Description:
|
||||
* Write to an 8-bit BH1749NUC register
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void bh1749nuc_putreg8(FAR struct bh1749nuc_dev_s *priv,
|
||||
uint8_t regaddr, uint8_t regval)
|
||||
{
|
||||
struct i2c_msg_s msg[2];
|
||||
uint8_t txbuffer[2];
|
||||
int ret;
|
||||
|
||||
txbuffer[0] = regaddr;
|
||||
txbuffer[1] = regval;
|
||||
|
||||
msg[0].frequency = priv->freq;
|
||||
msg[0].addr = priv->addr;
|
||||
msg[0].flags = 0;
|
||||
msg[0].buffer = txbuffer;
|
||||
msg[0].length = 2;
|
||||
|
||||
ret = I2C_TRANSFER(priv->i2c, msg, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("I2C_TRANSFER failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bh1749nuc_checkid
|
||||
*
|
||||
* Description:
|
||||
* Read and verify the BH1749NUC chip ID
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int bh1749nuc_checkid(FAR struct bh1749nuc_dev_s *priv)
|
||||
{
|
||||
uint8_t id;
|
||||
|
||||
/* Read Manufact ID */
|
||||
|
||||
id = bh1749nuc_getreg8(priv, BH1749NUC_MANUFACTURER_ID);
|
||||
if (id != BH1749NUC_MANUFACTID)
|
||||
{
|
||||
/* Manufact ID is not Correct */
|
||||
|
||||
snerr("Wrong Manufact ID! %02x\n", id);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Read Part ID */
|
||||
|
||||
id = bh1749nuc_getreg8(priv, BH1749NUC_SYSTEM_CONTROL);
|
||||
if ((id & 0x3f) != BH1749NUC_PARTID)
|
||||
{
|
||||
/* Part ID is not Correct */
|
||||
|
||||
snerr("Wrong Part ID! %02x\n", id);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bh1749nuc_open
|
||||
*
|
||||
|
|
|
|||
173
drivers/sensors/bh1749nuc_base.c
Normal file
173
drivers/sensors/bh1749nuc_base.c
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
/****************************************************************************
|
||||
* drivers/sensors/bh1749nuc_base.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include "bh1749nuc_base.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bh1749nuc_getreg8
|
||||
*
|
||||
* Description:
|
||||
* Read from an 8-bit BH1749NUC register
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint8_t bh1749nuc_getreg8(FAR struct bh1749nuc_dev_s *priv, uint8_t regaddr)
|
||||
{
|
||||
struct i2c_msg_s msg[2];
|
||||
uint8_t regval = 0;
|
||||
int ret;
|
||||
|
||||
msg[0].frequency = priv->freq;
|
||||
msg[0].addr = priv->addr;
|
||||
msg[0].flags = I2C_M_NOSTOP;
|
||||
msg[0].buffer = ®addr;
|
||||
msg[0].length = 1;
|
||||
|
||||
msg[1].frequency = priv->freq;
|
||||
msg[1].addr = priv->addr;
|
||||
msg[1].flags = I2C_M_READ;
|
||||
msg[1].buffer = ®val;
|
||||
msg[1].length = 1;
|
||||
|
||||
ret = I2C_TRANSFER(priv->i2c, msg, 2);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("I2C_TRANSFER failed: %d\n", ret);
|
||||
}
|
||||
|
||||
return regval;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bh1749nuc_read16
|
||||
*
|
||||
* Description:
|
||||
* Read 16-bit register
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint16_t bh1749nuc_read16(FAR struct bh1749nuc_dev_s *priv, uint8_t regaddr)
|
||||
{
|
||||
struct i2c_msg_s msg[2];
|
||||
uint8_t regval[2];
|
||||
int ret;
|
||||
|
||||
msg[0].frequency = priv->freq;
|
||||
msg[0].addr = priv->addr;
|
||||
msg[0].flags = I2C_M_NOSTOP;
|
||||
msg[0].buffer = ®addr;
|
||||
msg[0].length = 1;
|
||||
|
||||
msg[1].frequency = priv->freq;
|
||||
msg[1].addr = priv->addr;
|
||||
msg[1].flags = I2C_M_READ;
|
||||
msg[1].buffer = (uint8_t *)®val;
|
||||
msg[1].length = 2;
|
||||
|
||||
ret = I2C_TRANSFER(priv->i2c, msg, 2);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("I2C_TRANSFER failed: %d\n", ret);
|
||||
}
|
||||
|
||||
return regval[1] << 8 | regval[0] << 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bh1749nuc_putreg8
|
||||
*
|
||||
* Description:
|
||||
* Write to an 8-bit BH1749NUC register
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void bh1749nuc_putreg8(FAR struct bh1749nuc_dev_s *priv,
|
||||
uint8_t regaddr, uint8_t regval)
|
||||
{
|
||||
struct i2c_msg_s msg[2];
|
||||
uint8_t txbuffer[2];
|
||||
int ret;
|
||||
|
||||
txbuffer[0] = regaddr;
|
||||
txbuffer[1] = regval;
|
||||
|
||||
msg[0].frequency = priv->freq;
|
||||
msg[0].addr = priv->addr;
|
||||
msg[0].flags = 0;
|
||||
msg[0].buffer = txbuffer;
|
||||
msg[0].length = 2;
|
||||
|
||||
ret = I2C_TRANSFER(priv->i2c, msg, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("I2C_TRANSFER failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bh1749nuc_checkid
|
||||
*
|
||||
* Description:
|
||||
* Read and verify the BH1749NUC chip ID
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int bh1749nuc_checkid(FAR struct bh1749nuc_dev_s *priv)
|
||||
{
|
||||
uint8_t id;
|
||||
|
||||
/* Read Manufact ID */
|
||||
|
||||
id = bh1749nuc_getreg8(priv, BH1749NUC_MANUFACTURER_ID);
|
||||
if (id != BH1749NUC_MANUFACTID)
|
||||
{
|
||||
/* Manufact ID is not Correct */
|
||||
|
||||
snerr("Wrong Manufact ID! %02x\n", id);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Read Part ID */
|
||||
|
||||
id = bh1749nuc_getreg8(priv, BH1749NUC_SYSTEM_CONTROL);
|
||||
if ((id & 0x3f) != BH1749NUC_PARTID)
|
||||
{
|
||||
/* Part ID is not Correct */
|
||||
|
||||
snerr("Wrong Part ID! %02x\n", id);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
102
drivers/sensors/bh1749nuc_base.h
Normal file
102
drivers/sensors/bh1749nuc_base.h
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/****************************************************************************
|
||||
* drivers/sensors/bh1749nuc_base.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __INCLUDE_NUTTX_SENSORS_BH1749NUC_BASE_H
|
||||
#define __INCLUDE_NUTTX_SENSORS_BH1749NUC_BASE_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
|
||||
#include <nuttx/sensors/bh1749nuc.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define BH1749NUC_I2C_FREQ 400000
|
||||
|
||||
#define BH1749NUC_MANUFACTID 0xE0 /* Manufact ID */
|
||||
#define BH1749NUC_PARTID 0x0D /* Part ID */
|
||||
|
||||
/* BH1749NUC Registers */
|
||||
|
||||
#define BH1749NUC_SYSTEM_CONTROL 0x40
|
||||
#define BH1749NUC_MODE_CONTROL1 0x41
|
||||
#define BH1749NUC_MODE_CONTROL2 0x42
|
||||
#define BH1749NUC_RED_DATA_LSB 0x50
|
||||
#define BH1749NUC_GREEN_DATA_LSB 0x52
|
||||
#define BH1749NUC_BLUE_DATA_LSB 0x54
|
||||
#define BH1749NUC_IR_DATA_LSB 0x58
|
||||
#define BH1749NUC_GREEN2_DATA_LSB 0x5a
|
||||
#define BH1749NUC_MANUFACTURER_ID 0x92
|
||||
|
||||
/* Register SYSTEM_CONTROL */
|
||||
|
||||
#define BH1749NUC_SYSTEM_CONTROL_SW_RESET (1 << 7)
|
||||
#define BH1749NUC_SYSTEM_CONTROL_INT_RESET (1 << 6)
|
||||
|
||||
/* Register MODE_CONTROL1 */
|
||||
|
||||
#define BH1749NUC_MODE_CONTROL1_IR_GAIN_X1 (0x20)
|
||||
#define BH1749NUC_MODE_CONTROL1_IR_GAIN_X32 (0x60)
|
||||
#define BH1749NUC_MODE_CONTROL1_RGB_GAIN_X1 (0x08)
|
||||
#define BH1749NUC_MODE_CONTROL1_RGB_GAIN_X32 (0x18)
|
||||
#define BH1749NUC_MODE_CONTROL1_MEAS_TIME160MS (0x02)
|
||||
|
||||
/* Register MODE_CONTROL2 */
|
||||
|
||||
#define BH1749NUC_MODE_CONTROL2_RGBI_EN (1 << 4)
|
||||
#define BH1749NUC_MODE_CONTROL2_VALID (1 << 7)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* Structure for bh1749nuc device */
|
||||
|
||||
struct bh1749nuc_dev_s
|
||||
{
|
||||
FAR struct i2c_master_s *i2c; /* I2C interface */
|
||||
int freq; /* Frequency */
|
||||
uint8_t addr; /* I2C address */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
uint8_t bh1749nuc_getreg8(FAR struct bh1749nuc_dev_s *priv, uint8_t regaddr);
|
||||
uint16_t bh1749nuc_read16(FAR struct bh1749nuc_dev_s *priv, uint8_t regaddr);
|
||||
void bh1749nuc_putreg8(FAR struct bh1749nuc_dev_s *priv,
|
||||
uint8_t regaddr, uint8_t regval);
|
||||
int bh1749nuc_checkid(FAR struct bh1749nuc_dev_s *priv);
|
||||
|
||||
#endif /* __INCLUDE_NUTTX_SENSORS_BH1749NUC_BASE_H */
|
||||
536
drivers/sensors/bh1749nuc_uorb.c
Normal file
536
drivers/sensors/bh1749nuc_uorb.c
Normal file
|
|
@ -0,0 +1,536 @@
|
|||
/****************************************************************************
|
||||
* drivers/sensors/bh1749nuc_uorb.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <nuttx/mutex.h>
|
||||
#include <nuttx/signal.h>
|
||||
#include <nuttx/kthread.h>
|
||||
|
||||
#include <nuttx/sensors/sensor.h>
|
||||
|
||||
#include "bh1749nuc_base.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type Definitions
|
||||
****************************************************************************/
|
||||
|
||||
enum bh1749nuc_idx_e
|
||||
{
|
||||
BH1749NUC_RGB_IDX = 0,
|
||||
BH1749NUC_IR_IDX,
|
||||
BH1749NUC_MAX_IDX
|
||||
};
|
||||
|
||||
struct bh1749nuc_sensor_dev_s;
|
||||
struct bh1749nuc_sensor_s
|
||||
{
|
||||
struct sensor_lowerhalf_s lower;
|
||||
int gain;
|
||||
FAR struct bh1749nuc_sensor_dev_s *dev;
|
||||
#ifdef CONFIG_SENSORS_BH1749NUC_POLL
|
||||
unsigned long interval;
|
||||
uint64_t last_update;
|
||||
#endif
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
struct bh1749nuc_sensor_dev_s
|
||||
{
|
||||
struct bh1749nuc_sensor_s priv[BH1749NUC_MAX_IDX];
|
||||
struct bh1749nuc_dev_s dev;
|
||||
float scale_r;
|
||||
float scale_g;
|
||||
float scale_b;
|
||||
float scale_ir;
|
||||
mutex_t lock;
|
||||
#ifdef CONFIG_SENSORS_BH1749NUC_POLL
|
||||
sem_t run;
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static int bh1749nuc_activate(FAR struct sensor_lowerhalf_s *lower,
|
||||
FAR struct file *filep, bool enable);
|
||||
#ifndef CONFIG_SENSORS_BH1749NUC_POLL
|
||||
static int bh1749nuc_fetch(FAR struct sensor_lowerhalf_s *lower,
|
||||
FAR struct file *filep,
|
||||
FAR char *buffer, size_t buflen);
|
||||
#endif
|
||||
static int bh1749nuc_set_interval(FAR struct sensor_lowerhalf_s *lower,
|
||||
FAR struct file *filep,
|
||||
FAR unsigned long *period_us);
|
||||
static int bh1749nuc_control(FAR struct sensor_lowerhalf_s *lower,
|
||||
FAR struct file *filep,
|
||||
int cmd, unsigned long arg);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static const struct sensor_ops_s g_bh1749nuc_sensor_ops =
|
||||
{
|
||||
NULL, /* open */
|
||||
NULL, /* close */
|
||||
bh1749nuc_activate,
|
||||
bh1749nuc_set_interval,
|
||||
NULL, /* batch */
|
||||
#ifdef CONFIG_SENSORS_BH1749NUC_POLL
|
||||
NULL, /* fetch */
|
||||
#else
|
||||
bh1749nuc_fetch,
|
||||
#endif
|
||||
NULL, /* selftest */
|
||||
NULL, /* set_calibvalue */
|
||||
NULL, /* calibrate */
|
||||
bh1749nuc_control
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bh1749nuc_activate
|
||||
****************************************************************************/
|
||||
|
||||
static int bh1749nuc_activate(FAR struct sensor_lowerhalf_s *lower,
|
||||
FAR struct file *filep, bool enable)
|
||||
{
|
||||
FAR struct bh1749nuc_sensor_s *priv = NULL;
|
||||
FAR struct bh1749nuc_dev_s *dev = NULL;
|
||||
uint8_t val = 0;
|
||||
#ifdef CONFIG_SENSORS_BH1749NUC_POLL
|
||||
bool start_thread = false;
|
||||
#endif
|
||||
|
||||
/* Get dev */
|
||||
|
||||
priv = (FAR struct bh1749nuc_sensor_s *)lower;
|
||||
dev = &priv->dev->dev;
|
||||
|
||||
nxmutex_lock(&priv->dev->lock);
|
||||
|
||||
if (enable)
|
||||
{
|
||||
#ifdef CONFIG_SENSORS_BH1749NUC_POLL
|
||||
if (!priv->enabled)
|
||||
{
|
||||
start_thread = true;
|
||||
priv->last_update = sensor_get_timestamp();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* MODE_CONTROL1 */
|
||||
|
||||
val = (BH1749NUC_MODE_CONTROL1_MEAS_TIME160MS |
|
||||
BH1749NUC_MODE_CONTROL1_IR_GAIN_X1 |
|
||||
BH1749NUC_MODE_CONTROL1_RGB_GAIN_X1);
|
||||
bh1749nuc_putreg8(dev, BH1749NUC_MODE_CONTROL1, val);
|
||||
|
||||
/* MODE_CONTROL2 */
|
||||
|
||||
val = BH1749NUC_MODE_CONTROL2_RGBI_EN;
|
||||
bh1749nuc_putreg8(dev, BH1749NUC_MODE_CONTROL2, val);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Stop sampling */
|
||||
|
||||
val = 0;
|
||||
bh1749nuc_putreg8(dev, BH1749NUC_MODE_CONTROL2, val);
|
||||
}
|
||||
|
||||
priv->enabled = enable;
|
||||
|
||||
#ifdef CONFIG_SENSORS_BH1749NUC_POLL
|
||||
if (start_thread)
|
||||
{
|
||||
/* Wake up the thread */
|
||||
|
||||
nxsem_post(&priv->dev->run);
|
||||
}
|
||||
#endif
|
||||
|
||||
nxmutex_unlock(&priv->dev->lock);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SENSORS_BH1749NUC_POLL
|
||||
/****************************************************************************
|
||||
* Name: bh1749nuc_fetch
|
||||
****************************************************************************/
|
||||
|
||||
static int bh1749nuc_fetch(FAR struct sensor_lowerhalf_s *lower,
|
||||
FAR struct file *filep,
|
||||
FAR char *buffer, size_t buflen)
|
||||
{
|
||||
FAR struct bh1749nuc_sensor_s *priv = NULL;
|
||||
FAR struct bh1749nuc_dev_s *dev = NULL;
|
||||
struct sensor_rgb rgb_data;
|
||||
struct sensor_ir ir_data;
|
||||
uint16_t tmp = 0;
|
||||
uint64_t now = sensor_get_timestamp();
|
||||
int ret = 0;
|
||||
|
||||
/* Get dev */
|
||||
|
||||
priv = (FAR struct bh1749nuc_sensor_s *)lower;
|
||||
dev = &priv->dev->dev;
|
||||
|
||||
nxmutex_lock(&priv->dev->lock);
|
||||
|
||||
if (!priv->enabled)
|
||||
{
|
||||
ret = -EACCES;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Wait for data */
|
||||
|
||||
while (!(bh1749nuc_getreg8(dev, BH1749NUC_MODE_CONTROL2) &
|
||||
BH1749NUC_MODE_CONTROL2_VALID));
|
||||
|
||||
if (lower->type == SENSOR_TYPE_RGB)
|
||||
{
|
||||
if (buflen != sizeof(rgb_data))
|
||||
{
|
||||
ret = -EINVAL;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
rgb_data.timestamp = now;
|
||||
tmp = bh1749nuc_read16(dev, BH1749NUC_RED_DATA_LSB);
|
||||
rgb_data.r = (tmp * dev->scale_r);
|
||||
tmp = bh1749nuc_read16(dev, BH1749NUC_GREEN_DATA_LSB);
|
||||
rgb_data.g = (tmp * dev->scale_g);
|
||||
tmp = bh1749nuc_read16(dev, BH1749NUC_BLUE_DATA_LSB);
|
||||
rgb_data.b = (tmp * dev->scale_b);
|
||||
|
||||
memcpy(buffer, &rgb_data, sizeof(rgb_data));
|
||||
ret = sizeof(rgb_data);
|
||||
}
|
||||
else if (lower->type == SENSOR_TYPE_IR)
|
||||
{
|
||||
if (buflen != sizeof(ir_data))
|
||||
{
|
||||
ret = -EINVAL;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
ir_data.timestamp = now;
|
||||
tmp = bh1749nuc_read16(dev, BH1749NUC_IR_DATA_LSB);
|
||||
ir_data.ir = (tmp * dev->scale_ir);
|
||||
|
||||
memcpy(buffer, &ir_data, sizeof(ir_data));
|
||||
ret = sizeof(ir_data);
|
||||
}
|
||||
|
||||
errout:
|
||||
nxmutex_unlock(&priv->dev->lock);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bh1749nuc_cotrol
|
||||
****************************************************************************/
|
||||
|
||||
static int bh1749nuc_control(FAR struct sensor_lowerhalf_s *lower,
|
||||
FAR struct file *filep, int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
FAR struct bh1749nuc_sensor_s *priv = NULL;
|
||||
int ret = OK;
|
||||
|
||||
priv = (FAR struct bh1749nuc_sensor_s *)lower;
|
||||
UNUSED(priv);
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
default:
|
||||
{
|
||||
snerr("ERROR: Unrecognized cmd: %d\n", cmd);
|
||||
ret = -ENOTTY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bh1749nuc_set_interval
|
||||
****************************************************************************/
|
||||
|
||||
static int bh1749nuc_set_interval(FAR struct sensor_lowerhalf_s *lower,
|
||||
FAR struct file *filep,
|
||||
FAR unsigned long *interval)
|
||||
{
|
||||
#ifdef CONFIG_SENSORS_BH1749NUC_POLL
|
||||
FAR struct bh1749nuc_sensor_s *priv = NULL;
|
||||
|
||||
priv = (FAR struct bh1749nuc_sensor_s *)lower;
|
||||
|
||||
priv->interval = *interval;
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SENSORS_BH1749NUC_POLL
|
||||
/****************************************************************************
|
||||
* Name: bh1749nuc_thread
|
||||
*
|
||||
* Description: Thread for performing interval measurement cycle and data
|
||||
* read.
|
||||
*
|
||||
* Parameter:
|
||||
* argc - Number opf arguments
|
||||
* argv - Pointer to argument list
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int bh1749nuc_thread(int argc, FAR char **argv)
|
||||
{
|
||||
FAR struct bh1749nuc_sensor_dev_s *dev =
|
||||
(FAR struct bh1749nuc_sensor_dev_s *)((uintptr_t)strtoul(argv[1], NULL,
|
||||
16));
|
||||
FAR struct bh1749nuc_sensor_s *rgb = &dev->priv[BH1749NUC_RGB_IDX];
|
||||
FAR struct bh1749nuc_sensor_s *ir = &dev->priv[BH1749NUC_IR_IDX];
|
||||
struct sensor_rgb rgb_data;
|
||||
struct sensor_ir ir_data;
|
||||
uint64_t min_interval;
|
||||
uint16_t tmp = 0;
|
||||
uint64_t now = sensor_get_timestamp();
|
||||
int ret = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if ((!rgb->enabled) && (!ir->enabled))
|
||||
{
|
||||
/* Waiting to be woken up */
|
||||
|
||||
ret = nxsem_wait(&dev->run);
|
||||
if (ret < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for data */
|
||||
|
||||
while (!(bh1749nuc_getreg8(&dev->dev, BH1749NUC_MODE_CONTROL2) &
|
||||
BH1749NUC_MODE_CONTROL2_VALID));
|
||||
|
||||
/* Get timestamp */
|
||||
|
||||
now = sensor_get_timestamp();
|
||||
|
||||
if (rgb->enabled)
|
||||
{
|
||||
rgb_data.timestamp = now;
|
||||
tmp = bh1749nuc_read16(&dev->dev, BH1749NUC_RED_DATA_LSB);
|
||||
rgb_data.r = (tmp * dev->scale_r);
|
||||
tmp = bh1749nuc_read16(&dev->dev, BH1749NUC_GREEN_DATA_LSB);
|
||||
rgb_data.g = (tmp * dev->scale_g);
|
||||
tmp = bh1749nuc_read16(&dev->dev, BH1749NUC_BLUE_DATA_LSB);
|
||||
rgb_data.b = (tmp * dev->scale_b);
|
||||
|
||||
rgb->lower.push_event(rgb->lower.priv,
|
||||
&rgb_data, sizeof(rgb_data));
|
||||
}
|
||||
|
||||
if (ir->enabled)
|
||||
{
|
||||
ir_data.timestamp = now;
|
||||
tmp = bh1749nuc_read16(&dev->dev, BH1749NUC_IR_DATA_LSB);
|
||||
ir_data.ir = (tmp * dev->scale_ir);
|
||||
|
||||
ir->lower.push_event(ir->lower.priv,
|
||||
&ir_data, sizeof(ir_data));
|
||||
}
|
||||
|
||||
/* Sleeping thread before fetching the next sensor data */
|
||||
|
||||
min_interval = MIN(rgb->interval, ir->interval);
|
||||
nxsig_usleep(min_interval);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bh1749nuc_register_uorb
|
||||
*
|
||||
* Description:
|
||||
* Register the BH1749NUC uorb device as 'devpath'
|
||||
*
|
||||
* Input Parameters:
|
||||
* devno - The user specifies device number, from 0.
|
||||
* config - device configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int bh1749nuc_register_uorb(int devno, FAR struct bh1749nuc_config_s *config)
|
||||
{
|
||||
FAR struct bh1749nuc_sensor_dev_s *dev = NULL;
|
||||
FAR struct bh1749nuc_sensor_s *tmp = NULL;
|
||||
int ret = OK;
|
||||
#ifdef CONFIG_SENSORS_BH1749NUC_POLL
|
||||
FAR char *argv[2];
|
||||
char arg1[32];
|
||||
#endif
|
||||
|
||||
/* Without config info, we can't do anything. */
|
||||
|
||||
if (config == NULL)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Initialize the device structure. */
|
||||
|
||||
dev = kmm_malloc(sizeof(struct bh1749nuc_sensor_dev_s));
|
||||
if (dev == NULL)
|
||||
{
|
||||
snerr("ERROR: Failed to allocate bh1749nuc device instance\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(dev, 0, sizeof(struct bh1749nuc_sensor_dev_s));
|
||||
nxmutex_init(&dev->lock);
|
||||
#ifdef CONFIG_SENSORS_BH1749NUC_POLL
|
||||
nxsem_init(&dev->run, 0, 0);
|
||||
#endif
|
||||
|
||||
/* Configure dev */
|
||||
|
||||
dev->dev.i2c = config->i2c;
|
||||
dev->dev.addr = config->addr;
|
||||
dev->dev.freq = BH1749NUC_I2C_FREQ;
|
||||
|
||||
/* Check Device ID */
|
||||
|
||||
ret = bh1749nuc_checkid(&dev->dev);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("Failed to register driver: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Return data in lux unit for RGB and IR */
|
||||
|
||||
dev->scale_r = (20.0f / 71.0f) * (1e-6 / 1.46e-7);
|
||||
dev->scale_g = (20.0f / 99.0f) * (1e-6 / 1.46e-7);
|
||||
dev->scale_b = (20.0f / 70.0f) * (1e-6 / 1.46e-7);
|
||||
dev->scale_ir = (20.0f / 25.0f) * (1e-6 / 1.46e-7);
|
||||
|
||||
/* Register sensor */
|
||||
|
||||
tmp = &dev->priv[BH1749NUC_RGB_IDX];
|
||||
tmp->lower.type = SENSOR_TYPE_RGB;
|
||||
tmp->lower.ops = &g_bh1749nuc_sensor_ops;
|
||||
tmp->dev = dev;
|
||||
tmp->gain = 1;
|
||||
#ifdef CONFIG_SENSORS_BH1749NUC_POLL
|
||||
tmp->enabled = false;
|
||||
tmp->interval = CONFIG_SENSORS_BH1749NUC_POLL_INTERVAL;
|
||||
#endif
|
||||
|
||||
ret = sensor_register(&tmp->lower, devno);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto rgb_err;
|
||||
}
|
||||
|
||||
/* Register sensor */
|
||||
|
||||
tmp = &dev->priv[BH1749NUC_IR_IDX];
|
||||
tmp->lower.type = SENSOR_TYPE_IR;
|
||||
tmp->lower.ops = &g_bh1749nuc_sensor_ops;
|
||||
tmp->dev = dev;
|
||||
tmp->gain = 1;
|
||||
#ifdef CONFIG_SENSORS_BH1749NUC_POLL
|
||||
tmp->enabled = false;
|
||||
tmp->interval = CONFIG_SENSORS_BH1749NUC_POLL_INTERVAL;
|
||||
#endif
|
||||
|
||||
ret = sensor_register(&tmp->lower, devno);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto ir_err;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SENSORS_BH1749NUC_POLL
|
||||
/* Create thread for polling sensor data */
|
||||
|
||||
snprintf(arg1, 16, "%p", dev);
|
||||
argv[0] = arg1;
|
||||
argv[1] = NULL;
|
||||
|
||||
ret = kthread_create("bh1749nuc_thread", SCHED_PRIORITY_DEFAULT,
|
||||
CONFIG_SENSORS_BH1749NUC_THREAD_STACKSIZE,
|
||||
bh1749nuc_thread,
|
||||
argv);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto thr_err;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
|
||||
#ifdef CONFIG_SENSORS_BH1749NUC_POLL
|
||||
thr_err:
|
||||
#endif
|
||||
sensor_unregister(&dev->priv[BH1749NUC_IR_IDX].lower, devno);
|
||||
ir_err:
|
||||
sensor_unregister(&dev->priv[BH1749NUC_RGB_IDX].lower, devno);
|
||||
rgb_err:
|
||||
kmm_free(dev);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -46,6 +46,12 @@ struct bh1749nuc_data_s
|
|||
uint16_t green2;
|
||||
};
|
||||
|
||||
struct bh1749nuc_config_s
|
||||
{
|
||||
FAR struct i2c_master_s *i2c;
|
||||
uint8_t addr;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
|
@ -75,8 +81,13 @@ extern "C"
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_SENSORS_BH1749NUC_UORB
|
||||
int bh1749nuc_register(FAR const char *devpath, FAR struct i2c_master_s *i2c,
|
||||
uint8_t addr);
|
||||
#else
|
||||
int bh1749nuc_register_uorb(int devno,
|
||||
FAR struct bh1749nuc_config_s *config);
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue