drivers/sensors: add LTR308 ambient light sensor
Add support for the LTR308 ambient light sensor through I2C. Currently, the interrupt-driven mode of operation is not supported. Signed-off-by: Robert-Ionut Alexa <robertalexa2000@gmail.com>
This commit is contained in:
parent
5f82e2aeac
commit
039262484a
@ -1144,4 +1144,36 @@ config HDC1008_DEBUG
|
||||
Enables debug features for the HDC1008
|
||||
|
||||
endif # SENSORS_HDC1008
|
||||
|
||||
config SENSORS_LTR308
|
||||
bool "LTR308 Lite-On ambient light sensor"
|
||||
default n
|
||||
select I2C
|
||||
---help---
|
||||
Enable driver support for the LTR308 Lite-on ambient light sensor.
|
||||
|
||||
if SENSORS_LTR308
|
||||
|
||||
config SENSORS_LTR308_I2C_FREQUENCY
|
||||
int "LTR308 I2C frequency"
|
||||
default 400000
|
||||
range 1 400000
|
||||
|
||||
config SENSORS_LTR308_POLL_INTERVAL
|
||||
int "Polling interval in microseconds, default 1 sec"
|
||||
depends on SENSORS_LTR308
|
||||
default 1000000
|
||||
range 0 4294967295
|
||||
---help---
|
||||
The interval until a new sensor measurement will be triggered.
|
||||
|
||||
config SENSORS_LTR308_THREAD_STACKSIZE
|
||||
int "Worker thread stack size"
|
||||
depends on SENSORS_LTR308
|
||||
default 1024
|
||||
---help---
|
||||
The stack size for the worker thread.
|
||||
|
||||
endif # SENSORS_LTR308
|
||||
|
||||
endif # SENSORS
|
||||
|
@ -228,6 +228,10 @@ ifeq ($(CONFIG_SENSORS_T67XX),y)
|
||||
CSRCS += t67xx.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SENSORS_LTR308),y)
|
||||
CSRCS += ltr308.c
|
||||
endif
|
||||
|
||||
endif # CONFIG_I2C
|
||||
|
||||
# These drivers depend on SPI support
|
||||
|
655
drivers/sensors/ltr308.c
Normal file
655
drivers/sensors/ltr308.c
Normal file
@ -0,0 +1,655 @@
|
||||
/****************************************************************************
|
||||
* drivers/sensors/ltr308.c
|
||||
* Character driver for the LTR-308ALS-01 Lite-On ambient light sensor.
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/nuttx.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/kthread.h>
|
||||
#include <nuttx/signal.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
#include <nuttx/sensors/sensor.h>
|
||||
#include <nuttx/sensors/ltr308.h>
|
||||
|
||||
#if defined(CONFIG_I2C) && defined(CONFIG_SENSORS_LTR308)
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define LTR308_ADDR 0x53
|
||||
#define DEVID 0xB1
|
||||
|
||||
#define LTR308_CTRL 0x00
|
||||
#define LTR308_MEAS_RATE 0x04
|
||||
#define LTR308_ALS_GAIN 0x05
|
||||
#define LTR308_PART_ID 0x06
|
||||
#define LTR308_STATUS 0x07
|
||||
#define LTR308_DATA_0 0x0D
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type Definitions
|
||||
****************************************************************************/
|
||||
|
||||
struct ltr308_sensor_s
|
||||
{
|
||||
struct sensor_lowerhalf_s lower; /* Common lower interface */
|
||||
uint8_t integration_time; /* The interval between 2 ALS cycles */
|
||||
uint8_t measurement_rate; /* The interval between 2 data updates */
|
||||
uint8_t gain; /* Sensor gain */
|
||||
};
|
||||
|
||||
struct ltr308_dev_s
|
||||
{
|
||||
struct ltr308_sensor_s dev; /* Sensor private data */
|
||||
FAR struct i2c_master_s *i2c; /* I2C interface */
|
||||
mutex_t dev_lock; /* Manages exclusive access to the device */
|
||||
sem_t run; /* Locks sensor thread */
|
||||
bool enabled; /* Enable/Disable LTR308 */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static int ltr308_activate(FAR struct sensor_lowerhalf_s *lower,
|
||||
FAR struct file *filep, bool enabled);
|
||||
static int ltr308_calibrate(FAR struct sensor_lowerhalf_s *lower,
|
||||
FAR struct file *filep,
|
||||
unsigned long arg);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static const struct sensor_ops_s g_sensor_ops =
|
||||
{
|
||||
NULL, /* open */
|
||||
NULL, /* close */
|
||||
ltr308_activate, /* activate */
|
||||
NULL, /* set_interval */
|
||||
NULL, /* batch */
|
||||
NULL, /* fetch */
|
||||
NULL, /* selftest */
|
||||
NULL, /* set_calibvalue */
|
||||
ltr308_calibrate, /* calibrate */
|
||||
NULL /* control */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ltr308_set_reg8
|
||||
*
|
||||
* Description:
|
||||
* Write to an 8-bit LTR308 register
|
||||
*
|
||||
* Return value:
|
||||
* Zero (OK) on success; a negated errno value on failure
|
||||
****************************************************************************/
|
||||
|
||||
static int ltr308_set_reg8(FAR struct ltr308_dev_s *priv, uint8_t regaddr,
|
||||
uint8_t regval)
|
||||
{
|
||||
struct i2c_msg_s msg;
|
||||
uint8_t txbuffer[2];
|
||||
int ret;
|
||||
|
||||
txbuffer[0] = regaddr;
|
||||
txbuffer[1] = regval;
|
||||
|
||||
msg.frequency = CONFIG_SENSORS_LTR308_I2C_FREQUENCY;
|
||||
msg.addr = LTR308_ADDR;
|
||||
msg.flags = 0;
|
||||
msg.buffer = txbuffer;
|
||||
msg.length = 2;
|
||||
|
||||
ret = I2C_TRANSFER(priv->i2c, &msg, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("I2C_TRANSFER failed (err = %d)\n", ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ltr308_get_reg8
|
||||
*
|
||||
* Description:
|
||||
* Read from an 8-bit LTR308 register
|
||||
*
|
||||
* Return value:
|
||||
* Zero (OK) on success; a negated errno value on failure
|
||||
****************************************************************************/
|
||||
|
||||
static int ltr308_get_reg8(FAR struct ltr308_dev_s *priv, uint8_t regaddr,
|
||||
FAR uint8_t *regval)
|
||||
{
|
||||
struct i2c_msg_s msg[2];
|
||||
int ret;
|
||||
|
||||
msg[0].frequency = CONFIG_SENSORS_LTR308_I2C_FREQUENCY;
|
||||
msg[0].addr = LTR308_ADDR;
|
||||
msg[0].flags = 0;
|
||||
msg[0].buffer = ®addr;
|
||||
msg[0].length = 1;
|
||||
|
||||
msg[1].frequency = CONFIG_SENSORS_LTR308_I2C_FREQUENCY;
|
||||
msg[1].addr = LTR308_ADDR;
|
||||
msg[1].flags = I2C_M_READ;
|
||||
msg[1].buffer = regval;
|
||||
msg[1].length = 1;
|
||||
|
||||
ret = I2C_TRANSFER(priv->i2c, msg, 2);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("ERROR: I2C_TRANSFER failed (err = %d)\n", ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ltr308_get_reg24
|
||||
*
|
||||
* Description:
|
||||
* Read from 3 8-bit LTR308 registers
|
||||
*
|
||||
* Return value:
|
||||
* Zero (OK) on success; a negated errno value on failure
|
||||
****************************************************************************/
|
||||
|
||||
static int ltr308_get_reg24(FAR struct ltr308_dev_s *priv, uint8_t regaddr,
|
||||
FAR uint32_t *val)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
*val = 0;
|
||||
for (i = 0; i < 3; i++, regaddr++)
|
||||
{
|
||||
ret = ltr308_get_reg8(priv, regaddr, ((uint8_t *)val) + i);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ltr308_checkid
|
||||
*
|
||||
* Description:
|
||||
* Read and verify the LTR308 chip ID
|
||||
*
|
||||
* Return value:
|
||||
* Zero (OK) on success; a negated errno value on failure
|
||||
****************************************************************************/
|
||||
|
||||
static int ltr308_checkid(FAR struct ltr308_dev_s *priv)
|
||||
{
|
||||
uint8_t devid;
|
||||
int ret;
|
||||
|
||||
/* Read device ID */
|
||||
|
||||
ret = ltr308_get_reg8(priv, LTR308_PART_ID, &devid);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
sninfo("devid: 0x%02x\n", devid);
|
||||
|
||||
return (devid != DEVID) ? -ENODEV : OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ltr308_get_status
|
||||
*
|
||||
* Description:
|
||||
* Get the status information of LTR308
|
||||
*
|
||||
* Return value:
|
||||
* Zero (OK) on success; a negated errno value on failure
|
||||
****************************************************************************/
|
||||
|
||||
static int ltr308_get_status(FAR struct ltr308_dev_s *priv,
|
||||
FAR bool *power_on,
|
||||
FAR bool *interrupt_pending,
|
||||
FAR bool *data_pending)
|
||||
{
|
||||
uint8_t status;
|
||||
uint8_t ret;
|
||||
|
||||
ret = ltr308_get_reg8(priv, LTR308_STATUS, &status);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (power_on != NULL)
|
||||
{
|
||||
*power_on = status & 0x20;
|
||||
}
|
||||
|
||||
if (interrupt_pending != NULL)
|
||||
{
|
||||
*interrupt_pending = status & 0x10;
|
||||
}
|
||||
|
||||
if (data_pending != NULL)
|
||||
{
|
||||
*data_pending = status & 0x08;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ltr308_get_lux
|
||||
*
|
||||
* Description:
|
||||
* Convert raw data to lux
|
||||
* @gain: see ltr308_calibrate()
|
||||
* @integration_time: see ltr308_calibrate()
|
||||
* @ch: result from ltr308_get_data()
|
||||
*
|
||||
* Return value:
|
||||
* Zero (OK) on success; a negated errno value on failure
|
||||
****************************************************************************/
|
||||
|
||||
static int ltr308_get_lux(FAR struct ltr308_dev_s *priv, uint8_t gain,
|
||||
uint8_t integration_time, uint32_t data,
|
||||
FAR float *lux)
|
||||
{
|
||||
float d0;
|
||||
|
||||
/* Determine if sensor is saturated. If so, abandon ship (calculation will
|
||||
* not be accurate)
|
||||
*/
|
||||
|
||||
if (data == 0x000fffff)
|
||||
{
|
||||
*lux = 0.0;
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
d0 = ((float)data * 0.6);
|
||||
switch (gain)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case 1:
|
||||
d0 /= 3;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
d0 /= 6;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
d0 /= 9;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
d0 /= 18;
|
||||
break;
|
||||
|
||||
default:
|
||||
d0 = 0.0;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (integration_time)
|
||||
{
|
||||
case 0:
|
||||
*lux = d0 / 4;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
*lux = d0 / 2;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
*lux = d0;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
*lux = d0 * 2;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
*lux = d0 * 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
*lux = 0.0;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ltr308_activate
|
||||
*
|
||||
* Description:
|
||||
* Enable/Disable LTR308 sensor
|
||||
*
|
||||
* Return value:
|
||||
* Zero (OK) on success; a negated errno value on failure
|
||||
****************************************************************************/
|
||||
|
||||
static int ltr308_activate(FAR struct sensor_lowerhalf_s *lower,
|
||||
FAR struct file *filep, bool enabled)
|
||||
{
|
||||
FAR struct ltr308_sensor_s *dev = container_of(lower,
|
||||
FAR struct ltr308_sensor_s,
|
||||
lower);
|
||||
FAR struct ltr308_dev_s *priv = container_of(dev,
|
||||
FAR struct ltr308_dev_s,
|
||||
dev);
|
||||
int ret;
|
||||
|
||||
ret = ltr308_set_reg8(priv, LTR308_CTRL, enabled << 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("ERROR: Could not enable sensor\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
priv->enabled = enabled;
|
||||
if (enabled == true)
|
||||
{
|
||||
/* Wake up the polling thread */
|
||||
|
||||
nxsem_post(&priv->run);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ltr308_calibrate
|
||||
*
|
||||
* Description:
|
||||
* Set the integration time, measurement rate and gain of LTR308
|
||||
* @integration_time - the measurement time for each ALS cycle
|
||||
* @measurement_rate - the interval between DATA_REGISTERS update. Must be
|
||||
* set to be equal or greater than integration time
|
||||
* @gain - the sensor gain
|
||||
*
|
||||
* Return value:
|
||||
* Zero (OK) on success; a negated errno value on failure
|
||||
****************************************************************************/
|
||||
|
||||
static int ltr308_calibrate(FAR struct sensor_lowerhalf_s *lower,
|
||||
FAR struct file *filep,
|
||||
unsigned long arg)
|
||||
{
|
||||
FAR struct ltr308_sensor_s *dev = container_of(lower,
|
||||
FAR struct ltr308_sensor_s,
|
||||
lower);
|
||||
FAR struct ltr308_dev_s *priv = container_of(dev,
|
||||
FAR struct ltr308_dev_s,
|
||||
dev);
|
||||
FAR struct ltr308_calibval *calibval =
|
||||
(FAR struct ltr308_calibval *) arg;
|
||||
uint8_t measurement = 0;
|
||||
int ret;
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
if (calibval->integration_time >= 5)
|
||||
{
|
||||
calibval->integration_time = 0;
|
||||
}
|
||||
|
||||
if (calibval->measurement_rate >= 6 || calibval->measurement_rate == 4)
|
||||
{
|
||||
calibval->measurement_rate = 0;
|
||||
}
|
||||
|
||||
if (calibval->gain >= 5)
|
||||
{
|
||||
calibval->gain = 0;
|
||||
}
|
||||
|
||||
/* Do not overwrite if the values have not been modified */
|
||||
|
||||
nxmutex_lock(&priv->dev_lock);
|
||||
|
||||
if (dev->integration_time != calibval->integration_time ||
|
||||
dev->measurement_rate != calibval->measurement_rate)
|
||||
{
|
||||
dev->integration_time = calibval->integration_time;
|
||||
dev->measurement_rate = calibval->measurement_rate;
|
||||
|
||||
measurement |= calibval->integration_time << 4;
|
||||
measurement |= calibval->measurement_rate;
|
||||
|
||||
ret = ltr308_set_reg8(priv, LTR308_MEAS_RATE, measurement);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->gain != calibval->gain)
|
||||
{
|
||||
dev->gain = calibval->gain;
|
||||
|
||||
ret = ltr308_set_reg8(priv, LTR308_ALS_GAIN, calibval->gain);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
|
||||
nxmutex_unlock(&priv->dev_lock);
|
||||
return OK;
|
||||
|
||||
err_out:
|
||||
nxmutex_unlock(&priv->dev_lock);
|
||||
snerr("ERROR: Failed to calibrate sensor\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ltr308_thread
|
||||
*
|
||||
* Description:
|
||||
* Thread for performing data readings at fixed intervals, defined by
|
||||
* CONFIG_SENSORS_LTR308_POLL_INTERVAL
|
||||
* @argc - Number of arguments
|
||||
* @argv - Pointer to argument list
|
||||
*
|
||||
* Return value:
|
||||
* Zero (OK) on success; a negated errno value on failure
|
||||
****************************************************************************/
|
||||
|
||||
static int ltr308_thread(int argc, char** argv)
|
||||
{
|
||||
FAR struct ltr308_dev_s *priv = (FAR struct ltr308_dev_s *)
|
||||
((uintptr_t)strtoul(argv[1], NULL, 0));
|
||||
struct sensor_light light;
|
||||
uint32_t data = 0;
|
||||
bool data_pending;
|
||||
float lux;
|
||||
int ret;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (priv->enabled == false)
|
||||
{
|
||||
/* Wait for the sensor to be enabled */
|
||||
|
||||
nxsem_wait(&priv->run);
|
||||
}
|
||||
|
||||
/* Read the data registers and sleep if no change is detected
|
||||
* or the sensor is saturated
|
||||
*/
|
||||
|
||||
ret = ltr308_get_status(priv, NULL, NULL, &data_pending);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("ERROR: Failed to read sensor's status\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (data_pending == false)
|
||||
{
|
||||
goto thread_sleep;
|
||||
}
|
||||
|
||||
ret = ltr308_get_reg24(priv, LTR308_DATA_0, &data);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("ERROR: Failed to read data from sensor\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ltr308_get_lux(priv, priv->dev.gain, priv->dev.integration_time,
|
||||
data, &lux);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto thread_sleep;
|
||||
}
|
||||
|
||||
light.timestamp = sensor_get_timestamp();
|
||||
light.light = lux;
|
||||
priv->dev.lower.push_event(priv->dev.lower.priv, &light,
|
||||
sizeof(struct sensor_light));
|
||||
|
||||
thread_sleep:
|
||||
nxsig_usleep(CONFIG_SENSORS_LTR308_POLL_INTERVAL);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ltr308_register
|
||||
*
|
||||
* Description:
|
||||
* Register the LTR308 character device
|
||||
* @devno - The user-specified device number, starting from 0
|
||||
* @i2c - An instance of the I2C interface to use to communicate with
|
||||
* LTR308
|
||||
*
|
||||
* Return value:
|
||||
* Zero (OK) on success; a negated errno value on failure
|
||||
****************************************************************************/
|
||||
|
||||
int ltr308_register(int devno, FAR struct i2c_master_s *i2c)
|
||||
{
|
||||
FAR struct sensor_lowerhalf_s *lower;
|
||||
FAR struct ltr308_dev_s *priv;
|
||||
FAR char *argv[2];
|
||||
char arg1[32];
|
||||
int ret = OK;
|
||||
|
||||
DEBUGASSERT(i2c != NULL);
|
||||
|
||||
/* Initialize the LTR308 device structure */
|
||||
|
||||
priv = (FAR struct ltr308_dev_s *)kmm_zalloc(sizeof(struct ltr308_dev_s));
|
||||
if (priv == NULL)
|
||||
{
|
||||
snerr("ERROR: Failed to allocate instance (err = %d)\n", ret);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
priv->i2c = i2c;
|
||||
priv->enabled = false;
|
||||
nxmutex_init(&priv->dev_lock);
|
||||
nxsem_init(&priv->run, 0, 0);
|
||||
|
||||
/* Check Device ID */
|
||||
|
||||
ret = ltr308_checkid(priv);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("ERROR: Wrong device ID!\n");
|
||||
goto err_init;
|
||||
}
|
||||
|
||||
/* Register the character driver */
|
||||
|
||||
lower = &priv->dev.lower;
|
||||
lower->ops = &g_sensor_ops;
|
||||
lower->type = SENSOR_TYPE_LIGHT;
|
||||
|
||||
ret = sensor_register(lower, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("ERROR: Failed to register driver (err = %d)\n", ret);
|
||||
goto err_init;
|
||||
}
|
||||
|
||||
/* Create thread for polling sensor data */
|
||||
|
||||
snprintf(arg1, 16, "0x%" PRIxPTR, (uintptr_t)priv);
|
||||
argv[0] = arg1;
|
||||
argv[1] = NULL;
|
||||
ret = kthread_create("ltr308_thread", SCHED_PRIORITY_DEFAULT,
|
||||
CONFIG_SENSORS_LTR308_THREAD_STACKSIZE,
|
||||
ltr308_thread, argv);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("ERROR: Failed to create poll thread (err = %d)\n", ret);
|
||||
goto err_register;
|
||||
}
|
||||
|
||||
sninfo("LTR308 driver loaded successfully!\n");
|
||||
return OK;
|
||||
|
||||
err_register:
|
||||
sensor_unregister(lower, 0);
|
||||
err_init:
|
||||
nxsem_destroy(&priv->run);
|
||||
nxmutex_destroy(&priv->dev_lock);
|
||||
kmm_free(priv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_I2C && CONFIG_SENSORS_LTR308 */
|
91
include/nuttx/sensors/ltr308.h
Normal file
91
include/nuttx/sensors/ltr308.h
Normal file
@ -0,0 +1,91 @@
|
||||
/****************************************************************************
|
||||
* include/nuttx/sensors/ltr308.h
|
||||
* Character driver for the LTR-308ALS-01 Lite-On ambient light sensor.
|
||||
*
|
||||
* 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_LTR308_H
|
||||
#define __INCLUDE_NUTTX_SENSORS_LTR308_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/sensors/ioctl.h>
|
||||
|
||||
/* Configuration ************************************************************
|
||||
* Prerequisites:
|
||||
*
|
||||
* CONFIG_I2C
|
||||
* Enables support for I2C drivers
|
||||
* CONFIG_SENSORS_LTR308
|
||||
* Enables support for the LTR308 driver
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_I2C) && defined(CONFIG_SENSORS_LTR308)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
struct i2c_master_s;
|
||||
|
||||
struct ltr308_calibval
|
||||
{
|
||||
uint8_t integration_time;
|
||||
uint8_t measurement_rate;
|
||||
uint8_t gain;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ltr308_register
|
||||
*
|
||||
* Description:
|
||||
* Register the LTR308 character device as 'devpath'.
|
||||
*
|
||||
* Input Parameters:
|
||||
* devno - Number of device (i.e. ltr0, ltr1, ...)
|
||||
* i2c - An I2C driver instance.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ltr308_register(int devno, FAR struct i2c_master_s *i2c);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_I2C && CONFIG_SENSORS_LTR308 */
|
||||
#endif /* __INCLUDE_NUTTX_SENSORS_LTR308_H */
|
Loading…
Reference in New Issue
Block a user