You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by vi...@apache.org on 2017/02/24 19:38:25 UTC
[30/50] incubator-mynewt-core git commit: Modifying tsl2561 driver
Modifying tsl2561 driver
- Changing the driver to match the Sensor API
- Adding it to the shell
- We might want to keep the individual sensor tsl shell as it is. Hence
keeping the file around for now.
- Current implementation is polling based. We might want to add
interrupt based sampling to the Sensor API.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/9f59c4f0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/9f59c4f0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/9f59c4f0
Branch: refs/heads/develop
Commit: 9f59c4f06a7ba1000d53745a7fcaca114e74d4f9
Parents: 674aa7d
Author: Vipul Rahane <vi...@apache.org>
Authored: Wed Feb 1 15:37:39 2017 -0800
Committer: Vipul Rahane <vi...@apache.org>
Committed: Wed Feb 1 15:37:39 2017 -0800
----------------------------------------------------------------------
apps/slinky/pkg.yml | 1 +
apps/slinky/src/main.c | 36 +-
apps/slinky/syscfg.yml | 8 +
.../sensors/tsl2561/include/tsl2561/tsl2561.h | 30 +-
hw/drivers/sensors/tsl2561/pkg.yml | 14 -
hw/drivers/sensors/tsl2561/src/tsl2561.c | 428 +++++++++++++------
hw/drivers/sensors/tsl2561/src/tsl2561_priv.h | 81 +++-
hw/drivers/sensors/tsl2561/syscfg.yml | 3 -
hw/sensor/include/sensor/light.h | 49 +++
hw/sensor/src/sensor_shell.c | 16 +
sys/shell/src/shell.c | 2 +-
sys/shell/syscfg.yml | 2 +-
12 files changed, 496 insertions(+), 174 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9f59c4f0/apps/slinky/pkg.yml
----------------------------------------------------------------------
diff --git a/apps/slinky/pkg.yml b/apps/slinky/pkg.yml
index 8515446..2f84f69 100644
--- a/apps/slinky/pkg.yml
+++ b/apps/slinky/pkg.yml
@@ -33,6 +33,7 @@ pkg.deps:
- hw/sensor
- hw/drivers/sensors/sim
- hw/drivers/sensors/lsm303dlhc
+ - hw/drivers/sensors/tsl2561
- boot/bootutil
- sys/shell
- sys/config
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9f59c4f0/apps/slinky/src/main.c
----------------------------------------------------------------------
diff --git a/apps/slinky/src/main.c b/apps/slinky/src/main.c
index 4b0e870..e87aa0e 100755
--- a/apps/slinky/src/main.c
+++ b/apps/slinky/src/main.c
@@ -31,6 +31,7 @@
#include <config/config.h>
#include <sensor/sensor.h>
#include <lsm303dlhc/lsm303dlhc.h>
+#include <tsl2561/tsl2561.h>
#include "flash_map/flash_map.h"
#include <hal/hal_system.h>
#if MYNEWT_VAL(SPLIT_LOADER)
@@ -240,33 +241,50 @@ static int
config_sensor(void)
{
struct os_dev *dev;
- struct lsm303dlhc_cfg cfg;
int rc;
- dev = (struct os_dev *) os_dev_open("accel0", OS_TIMEOUT_NEVER, NULL);
+#if MYNEWT_VAL(TSL2561_PRESENT)
+ struct tsl2561_cfg tslcfg;
+
+ dev = (struct os_dev *) os_dev_open("light0", OS_TIMEOUT_NEVER, NULL);
assert(dev != NULL);
+ rc = tsl2561_init(dev, NULL);
- rc = lsm303dlhc_init(dev, NULL);
- if (rc != 0) {
+ /* Gain set to 1X and Inetgration time set to 13ms */
+ tslcfg.gain = TSL2561_LIGHT_GAIN_1X;
+ tslcfg.integration_time = TSL2561_LIGHT_ITIME_13MS;
+
+ rc = tsl2561_config((struct tsl2561 *)dev, &tslcfg);
+ if (rc) {
os_dev_close(dev);
goto err;
}
+#endif
+
+#if MYNEWT_VAL(LSM303DLHC_PRESENT)
+ struct lsm303dlhc_cfg lsmcfg;
+
+ dev = (struct os_dev *) os_dev_open("accel0", OS_TIMEOUT_NEVER, NULL);
+ assert(dev != NULL);
+
+ rc = lsm303dlhc_init(dev, NULL);
/* read once per sec. API should take this value in ms. */
- cfg.accel_rate = LSM303DLHC_ACCEL_RATE_1;
- cfg.accel_range = LSM303DLHC_ACCEL_RANGE_2;
+ lsmcfg.accel_rate = LSM303DLHC_ACCEL_RATE_1;
+ lsmcfg.accel_range = LSM303DLHC_ACCEL_RANGE_2;
- rc = lsm303dlhc_config((struct lsm303dlhc *) dev, &cfg);
- if (rc != 0) {
+ rc = lsm303dlhc_config((struct lsm303dlhc *) dev, &lsmcfg);
+ if (rc) {
os_dev_close(dev);
goto err;
}
+#endif
os_dev_close(dev);
return (0);
err:
- return (rc);
+ return rc;
}
#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9f59c4f0/apps/slinky/syscfg.yml
----------------------------------------------------------------------
diff --git a/apps/slinky/syscfg.yml b/apps/slinky/syscfg.yml
index 1beee37..d324731 100644
--- a/apps/slinky/syscfg.yml
+++ b/apps/slinky/syscfg.yml
@@ -43,3 +43,11 @@ syscfg.vals:
OS_MAIN_TASK_PRIO: 10
OS_MAIN_STACKS_SIZE: 512
+
+syscfg.defs:
+ TSL2561_PRESENT:
+ description: 'TSL2561 is present'
+ value: 0
+ LSM303DLHC_PRESENT:
+ description: 'LSM303 is present'
+ value: 0
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9f59c4f0/hw/drivers/sensors/tsl2561/include/tsl2561/tsl2561.h
----------------------------------------------------------------------
diff --git a/hw/drivers/sensors/tsl2561/include/tsl2561/tsl2561.h b/hw/drivers/sensors/tsl2561/include/tsl2561/tsl2561.h
index 03320e8..2f093be 100644
--- a/hw/drivers/sensors/tsl2561/include/tsl2561/tsl2561.h
+++ b/hw/drivers/sensors/tsl2561/include/tsl2561/tsl2561.h
@@ -38,35 +38,42 @@
#define __ADAFRUIT_TSL2561_H__
#include <os/os.h>
+#include "os/os_dev.h"
+#include "sensor/sensor.h"
#ifdef __cplusplus
extern "C" {
#endif
-/*
-struct tsl2561_i2c {
- uint8_t i2c_num;
- uint8_t i2c_addr;
+enum tsl2561_light_gain {
+ TSL2561_LIGHT_GAIN_1X = 0x00, /* 1X */
+ TSL2561_LIGHT_GAIN_16X = 0x01 << 4 /* 16X */
+};
+
+enum tsl2561_light_itime {
+ TSL2561_LIGHT_ITIME_13MS = 0x00, /* 13ms */
+ TSL2561_LIGHT_ITIME_101MS = 0x01, /* 101ms */
+ TSL2561_LIGHT_ITIME_402MS = 0x01 << 1 /* 402ms */
};
struct tsl2561_cfg {
uint8_t gain;
uint8_t integration_time;
- uint8_t enabled;
};
-struct tsl2561_dev {
- struct tsl2561_i2c i2c;
+struct tsl2561 {
+ struct os_dev dev;
+ struct sensor sensor;
struct tsl2561_cfg cfg;
+ os_time_t last_read_time;
};
-*/
/**
* Initialize the tsl2561. This function is normally called by sysinit.
*
* @param dev Pointer to the tsl2561_dev device descriptor
*/
-void tsl2561_init(void);
+int tsl2561_init(struct os_dev *dev, void *arg);
/**
* Enable or disables the sensor to save power
@@ -89,10 +96,11 @@ uint8_t tsl2561_get_enable(void);
*
* @param broadband The full (visible + ir) sensor output
* @param ir The ir sensor output
+ * @param tsl2561 Config and OS device structure
*
* @return 0 on success, and non-zero error code on failure
*/
-int tsl2561_get_data(uint16_t *broadband, uint16_t *ir);
+int tsl2561_get_data(uint16_t *broadband, uint16_t *ir, struct tsl2561 *tsl2561);
/**
* Sets the integration time used when sampling light values.
@@ -179,6 +187,8 @@ int tsl2561_enable_interrupt(uint8_t enable);
*/
int tsl2561_clear_interrupt(void);
+int tsl2561_config(struct tsl2561 *, struct tsl2561_cfg *);
+
#ifdef __cplusplus
}
#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9f59c4f0/hw/drivers/sensors/tsl2561/pkg.yml
----------------------------------------------------------------------
diff --git a/hw/drivers/sensors/tsl2561/pkg.yml b/hw/drivers/sensors/tsl2561/pkg.yml
index e7d0ffd..cebb755 100644
--- a/hw/drivers/sensors/tsl2561/pkg.yml
+++ b/hw/drivers/sensors/tsl2561/pkg.yml
@@ -33,17 +33,3 @@ pkg.keywords:
pkg.deps:
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-core/hw/hal"
-
-pkg.deps.TSL2561_CLI:
- - "@apache-mynewt-core/sys/console/full"
- - "@apache-mynewt-core/sys/shell"
- - "@apache-mynewt-core/sys/sysinit"
-
-pkg.deps.TSL2561_LOG:
- - "@apache-mynewt-core/sys/log"
-
-pkg.deps.TSL2561_STATS:
- - "@apache-mynewt-core/sys/stats"
-
-pkg.init_function: tsl2561_init
-pkg.init_stage: 6
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9f59c4f0/hw/drivers/sensors/tsl2561/src/tsl2561.c
----------------------------------------------------------------------
diff --git a/hw/drivers/sensors/tsl2561/src/tsl2561.c b/hw/drivers/sensors/tsl2561/src/tsl2561.c
index 037ccf8..8f90718 100644
--- a/hw/drivers/sensors/tsl2561/src/tsl2561.c
+++ b/hw/drivers/sensors/tsl2561/src/tsl2561.c
@@ -37,8 +37,13 @@
#include <assert.h>
#include <stdio.h>
#include <errno.h>
+
+#include "defs/error.h"
+#include "os/os.h"
#include "sysinit/sysinit.h"
#include "hal/hal_i2c.h"
+#include "sensor/sensor.h"
+#include "sensor/light.h"
#include "tsl2561/tsl2561.h"
#include "tsl2561_priv.h"
@@ -53,10 +58,6 @@
/* ToDo: Add timer based polling in bg and data ready callback (os_event?) */
/* ToDo: Move values to struct incl. address to allow multiple instances */
-static uint8_t g_tsl2561_gain;
-static uint8_t g_tsl2561_integration_time;
-static uint8_t g_tsl2561_enabled;
-
#if MYNEWT_VAL(TSL2561_STATS)
/* Define the stats section and records */
STATS_SECT_START(tsl2561_stat_section)
@@ -90,6 +91,20 @@ static struct log _log;
#define TSL2561_ERR(...)
#endif
+/* Exports for the sensor interface.
+ */
+static void *tsl2561_sensor_get_interface(struct sensor *, sensor_type_t);
+static int tsl2561_sensor_read(struct sensor *, sensor_type_t,
+ sensor_data_func_t, void *, uint32_t);
+static int tsl2561_sensor_get_config(struct sensor *, sensor_type_t,
+ struct sensor_cfg *);
+
+static const struct sensor_driver g_tsl2561_sensor_driver = {
+ tsl2561_sensor_get_interface,
+ tsl2561_sensor_read,
+ tsl2561_sensor_get_config
+};
+
int
tsl2561_write8(uint8_t reg, uint32_t value)
{
@@ -151,7 +166,7 @@ tsl2561_read8(uint8_t reg, uint8_t *value)
OS_TICKS_PER_SEC / 10, 1);
if (rc) {
TSL2561_ERR("Failed to address sensor\n");
- goto error;
+ goto err;
}
/* Read one byte back */
@@ -163,7 +178,7 @@ tsl2561_read8(uint8_t reg, uint8_t *value)
TSL2561_ERR("Failed to read @0x%02X\n", reg);
}
-error:
+err:
return rc;
}
@@ -184,7 +199,7 @@ tsl2561_read16(uint8_t reg, uint16_t *value)
OS_TICKS_PER_SEC / 10, 1);
if (rc) {
TSL2561_ERR("Failed to address sensor\n");
- goto error;
+ goto err;
}
/* Read two bytes back */
@@ -195,53 +210,28 @@ tsl2561_read16(uint8_t reg, uint16_t *value)
*value = (uint16_t)payload[0] | ((uint16_t)payload[1] << 8);
if (rc) {
TSL2561_ERR("Failed to read @0x%02X\n", reg);
- goto error;
+ goto err;
}
- /* ToDo: Log raw reads */
- // console_printf("0x%04X\n", (uint16_t)payload[0] | ((uint16_t)payload[1] << 8));
-
-error:
+err:
return rc;
}
int
-tsl2561_enable(uint8_t state)
-{
- int rc;
-
- /* Enable the device by setting the control bit to 0x03 */
- rc = tsl2561_write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL,
- state ? TSL2561_CONTROL_POWERON :
- TSL2561_CONTROL_POWEROFF);
- if (!rc) {
- g_tsl2561_enabled = state ? 1 : 0;
- }
-
- return rc;
-}
-
-uint8_t
-tsl2561_get_enable (void)
-{
- return g_tsl2561_enabled;
-}
-
-int
-tsl2561_get_data(uint16_t *broadband, uint16_t *ir)
+tsl2561_get_data(uint16_t *broadband, uint16_t *ir, struct tsl2561 *tsl2561)
{
int rc;
int delay_ticks;
/* Wait integration time ms before getting a data sample */
- switch (g_tsl2561_integration_time) {
- case TSL2561_INTEGRATIONTIME_13MS:
+ switch (tsl2561->cfg.integration_time) {
+ case TSL2561_LIGHT_ITIME_13MS:
delay_ticks = 14 * OS_TICKS_PER_SEC / 1000;
break;
- case TSL2561_INTEGRATIONTIME_101MS:
+ case TSL2561_LIGHT_ITIME_101MS:
delay_ticks = 102 * OS_TICKS_PER_SEC / 1000;
break;
- case TSL2561_INTEGRATIONTIME_402MS:
+ case TSL2561_LIGHT_ITIME_402MS:
default:
delay_ticks = 403 * OS_TICKS_PER_SEC / 1000;
break;
@@ -252,85 +242,33 @@ tsl2561_get_data(uint16_t *broadband, uint16_t *ir)
rc = tsl2561_read16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN0_LOW,
broadband);
if (rc) {
- goto error;
+ goto err;
}
rc = tsl2561_read16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN1_LOW,
ir);
if (rc) {
- goto error;
+ goto err;
}
#if MYNEWT_VAL(TSL2561_STATS)
- switch (g_tsl2561_integration_time) {
- case TSL2561_INTEGRATIONTIME_13MS:
+ switch (tsl2561->cfg.integration_time) {
+ case TSL2561_LIGHT_ITIME_13MS:
STATS_INC(g_tsl2561stats, samples_13ms);
break;
- case TSL2561_INTEGRATIONTIME_101MS:
+ case TSL2561_LIGHT_ITIME_101MS:
STATS_INC(g_tsl2561stats, samples_101ms);
break;
- case TSL2561_INTEGRATIONTIME_402MS:
+ case TSL2561_LIGHT_ITIME_402MS:
STATS_INC(g_tsl2561stats, samples_402ms);
default:
break;
}
#endif
-error:
- return rc;
-}
-
-int
-tsl2561_set_integration_time(uint8_t int_time)
-{
- int rc;
-
- rc = tsl2561_write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING,
- g_tsl2561_integration_time | g_tsl2561_gain);
- if (rc) {
- goto error;
- }
-
- g_tsl2561_integration_time = int_time;
-
-error:
+err:
return rc;
}
-uint8_t
-tsl2561_get_integration_time(void)
-{
- return g_tsl2561_integration_time;
-}
-
-int
-tsl2561_set_gain(uint8_t gain)
-{
- int rc;
-
- if ((gain != TSL2561_GAIN_1X) && (gain != TSL2561_GAIN_16X)) {
- TSL2561_ERR("Invalid gain value\n");
- rc = EINVAL;
- goto error;
- }
-
- rc = tsl2561_write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING,
- g_tsl2561_integration_time | gain);
- if (rc) {
- goto error;
- }
-
- g_tsl2561_gain = gain;
-
-error:
- return rc;
-}
-
-uint8_t
-tsl2561_get_gain(void)
-{
- return g_tsl2561_gain;
-}
-
int tsl2561_setup_interrupt (uint8_t rate, uint16_t lower, uint16_t upper)
{
int rc;
@@ -340,30 +278,30 @@ int tsl2561_setup_interrupt (uint8_t rate, uint16_t lower, uint16_t upper)
rc = tsl2561_write16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_THRESHHOLDL_LOW,
lower);
if (rc) {
- goto error;
+ goto err;
}
/* Set upper threshold */
rc = tsl2561_write16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_THRESHHOLDH_LOW,
upper);
if (rc) {
- goto error;
+ goto err;
}
/* Set rate */
rc = tsl2561_read8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_INTERRUPT, &intval);
if (rc) {
- goto error;
+ goto err;
}
/* Maintain the INTR Control Select bits */
rate = (intval & 0xF0) | (rate & 0xF);
rc = tsl2561_write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_INTERRUPT,
rate);
if (rc) {
- goto error;
+ goto err;
}
-error:
+err:
return rc;
}
@@ -375,24 +313,24 @@ int tsl2561_enable_interrupt (uint8_t enable)
if (enable > 1) {
TSL2561_ERR("Invalid value 0x%02X in tsl2561_enable_interrupt\n",
enable);
- rc = EINVAL;
- goto error;
+ rc = SYS_EINVAL;
+ goto err;
}
/* Read the current value to maintain PERSIST state */
rc = tsl2561_read8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_INTERRUPT, &persist_val);
if (rc) {
- goto error;
+ goto err;
}
/* Enable (1) or disable (0) level interrupts */
rc = tsl2561_write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_INTERRUPT,
((enable & 0x01) << 4) | (persist_val & 0x0F) );
if (rc) {
- goto error;
+ goto err;
}
-error:
+err:
return rc;
}
@@ -411,34 +349,31 @@ int tsl2561_clear_interrupt (void)
rc = hal_i2c_master_write(MYNEWT_VAL(TSL2561_I2CBUS), &data_struct,
OS_TICKS_PER_SEC / 10, 1);
if (rc) {
- goto error;
+ goto err;
}
#if MYNEWT_VAL(TSL2561_STATS)
STATS_INC(g_tsl2561stats, ints_cleared);
#endif
-error:
+err:
return rc;
}
-void
-tsl2561_init(void)
+int
+tsl2561_init(struct os_dev *dev, void *arg)
{
+ struct tsl2561 *tsl2561;
+ struct sensor *sensor;
int rc;
-#if !MYNEWT_VAL(TSL2561_TASK)
- return;
-#endif
+ tsl2561 = (struct tsl2561 *) dev;
#if MYNEWT_VAL(TSL2561_LOG)
log_register("tsl2561", &_log, &log_console_handler, NULL, LOG_SYSLEVEL);
#endif
-#if MYNEWT_VAL(TSL2561_CLI)
- rc = tsl2561_shell_init();
- SYSINIT_PANIC_ASSERT(rc == 0);
-#endif
+ sensor = &tsl2561->sensor;
#if MYNEWT_VAL(TSL2561_STATS)
/* Initialise the stats entry */
@@ -451,14 +386,255 @@ tsl2561_init(void)
rc = stats_register("tsl2561", STATS_HDR(g_tsl2561stats));
SYSINIT_PANIC_ASSERT(rc == 0);
#endif
+ rc = sensor_init(sensor, dev);
+ if (rc != 0) {
+ goto err;
+ }
- /* Enable the device by default */
- rc = tsl2561_enable(1);
- SYSINIT_PANIC_ASSERT(rc == 0);
+ /* Add the light driver */
+ rc = sensor_set_driver(sensor, SENSOR_TYPE_LIGHT,
+ (struct sensor_driver *) &g_tsl2561_sensor_driver);
+ if (rc != 0) {
+ goto err;
+ }
- rc = tsl2561_set_gain(TSL2561_GAIN_1X);
- SYSINIT_PANIC_ASSERT(rc == 0);
+ rc = sensor_mgr_register(sensor);
+ if (rc != 0) {
+ goto err;
+ }
- rc = tsl2561_set_integration_time(TSL2561_INTEGRATIONTIME_13MS);
- SYSINIT_PANIC_ASSERT(rc == 0);
+ return (0);
+err:
+ return (rc);
+
+}
+
+static void *
+tsl2561_sensor_get_interface(struct sensor *sensor, sensor_type_t type)
+{
+ return (NULL);
+}
+
+static uint32_t
+tsl2561_calculate_lux(uint16_t broadband, uint16_t ir, struct tsl2561_cfg *cfg)
+{
+ uint64_t chscale;
+ uint64_t channel1;
+ uint64_t channel0;
+ uint16_t clipthreshold;
+ uint64_t ratio1;
+ uint64_t ratio;
+ int64_t b, m;
+ uint64_t temp;
+ uint32_t lux;
+
+ /* Make sure the sensor isn't saturated! */
+ switch (cfg->integration_time) {
+ case TSL2561_LIGHT_ITIME_13MS:
+ clipthreshold = TSL2561_CLIPPING_13MS;
+ break;
+ case TSL2561_LIGHT_ITIME_101MS:
+ clipthreshold = TSL2561_CLIPPING_101MS;
+ break;
+ default:
+ clipthreshold = TSL2561_CLIPPING_402MS;
+ break;
+ }
+
+ /* Return 65536 lux if the sensor is saturated */
+ if ((broadband > clipthreshold) || (ir > clipthreshold)) {
+ return 65536;
+ }
+
+ /* Get the correct scale depending on the intergration time */
+ switch (cfg->integration_time) {
+ case TSL2561_LIGHT_ITIME_13MS:
+ chscale = TSL2561_LUX_CHSCALE_TINT0;
+ break;
+ case TSL2561_LIGHT_ITIME_101MS:
+ chscale = TSL2561_LUX_CHSCALE_TINT1;
+ break;
+ default: /* No scaling ... integration time = 402ms */
+ chscale = (1 << TSL2561_LUX_CHSCALE);
+ break;
+ }
+
+ /* Scale for gain (1x or 16x) */
+ if (!cfg->gain) {
+ chscale = chscale << 4;
+ }
+
+ /* Scale the channel values */
+ channel0 = (broadband * chscale) >> TSL2561_LUX_CHSCALE;
+ channel1 = (ir * chscale) >> TSL2561_LUX_CHSCALE;
+
+ ratio1 = 0;
+ /* Find the ratio of the channel values (Channel1/Channel0) */
+ if (channel0 != 0) {
+ ratio1 = (channel1 << (TSL2561_LUX_RATIOSCALE+1)) / channel0;
+ }
+
+ /* round the ratio value */
+ ratio = (ratio1 + 1) >> 1;
+
+#if MYNEWT_VAL(TSL2561_PACKAGE_CS)
+ if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1C)) {
+ b = TSL2561_LUX_B1C;
+ m = TSL2561_LUX_M1C;
+ } else if (ratio <= TSL2561_LUX_K2C) {
+ b = TSL2561_LUX_B2C;
+ m = TSL2561_LUX_M2C;
+ } else if (ratio <= TSL2561_LUX_K3C) {
+ b = TSL2561_LUX_B3C;
+ m = TSL2561_LUX_M3C;
+ } else if (ratio <= TSL2561_LUX_K4C) {
+ b = TSL2561_LUX_B4C;
+ m = TSL2561_LUX_M4C;
+ } else if (ratio <= TSL2561_LUX_K5C) {
+ b = TSL2561_LUX_B5C;
+ m = TSL2561_LUX_M5C;
+ } else if (ratio <= TSL2561_LUX_K6C) {
+ b = TSL2561_LUX_B6C;
+ m = TSL2561_LUX_M6C;
+ } else if (ratio <= TSL2561_LUX_K7C) {
+ b = TSL2561_LUX_B7C;
+ m = TSL2561_LUX_M7C;
+ } else if (ratio > TSL2561_LUX_K8C) {
+ b = TSL2561_LUX_B8C;
+ m = TSL2561_LUX_M8C;
+ }
+#else
+ if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1T)) {
+ b = TSL2561_LUX_B1T;
+ m = TSL2561_LUX_M1T;
+ } else if (ratio <= TSL2561_LUX_K2T) {
+ b = TSL2561_LUX_B2T;
+ m = TSL2561_LUX_M2T;
+ } else if (ratio <= TSL2561_LUX_K3T) {
+ b = TSL2561_LUX_B3T;
+ m = TSL2561_LUX_M3T;
+ } else if (ratio <= TSL2561_LUX_K4T) {
+ b = TSL2561_LUX_B4T;
+ m = TSL2561_LUX_M4T;
+ } else if (ratio <= TSL2561_LUX_K5T) {
+ b = TSL2561_LUX_B5T;
+ m = TSL2561_LUX_M5T;
+ } else if (ratio <= TSL2561_LUX_K6T) {
+ b = TSL2561_LUX_B6T;
+ m = TSL2561_LUX_M6T;
+ } else if (ratio <= TSL2561_LUX_K7T) {
+ b = TSL2561_LUX_B7T;
+ m = TSL2561_LUX_M7T;
+ } else if (ratio > TSL2561_LUX_K8T) {
+ b = TSL2561_LUX_B8T;
+ m = TSL2561_LUX_M8T;
+ }
+#endif
+
+ temp = ((channel0 * b) - (channel1 * m));
+
+ /* Do not allow negative lux value */
+ if (temp < 0) {
+ temp = 0;
+ }
+ /* Round lsb (2^(LUX_SCALE-1)) */
+ temp += (1 << (TSL2561_LUX_LUXSCALE - 1));
+
+ /* Strip off fractional portion */
+ lux = temp >> TSL2561_LUX_LUXSCALE;
+
+ return lux;
+}
+
+static int
+tsl2561_sensor_read(struct sensor *sensor, sensor_type_t type,
+ sensor_data_func_t data_func, void *data_arg, uint32_t timeout)
+{
+ struct tsl2561 *tsl2561;
+ struct sensor_light_data sld;
+ uint16_t full;
+ uint16_t ir;
+ uint32_t lux;
+ int rc;
+
+ /* If the read isn't looking for accel or mag data, don't do anything. */
+ if (!(type & SENSOR_TYPE_LIGHT)) {
+ rc = SYS_EINVAL;
+ goto err;
+ }
+
+ tsl2561 = (struct tsl2561 *) SENSOR_GET_DEVICE(sensor);
+
+ /* Get a new accelerometer sample */
+ if (type & SENSOR_TYPE_LIGHT) {
+ full = ir = 0;
+
+ rc = tsl2561_get_data(&full, &ir, tsl2561);
+ if (rc) {
+ goto err;
+ }
+
+ lux = tsl2561_calculate_lux(full, ir, &(tsl2561->cfg));
+ sld.sld_full = full;
+ sld.sld_ir = ir;
+ sld.sld_lux = lux;
+
+ /* Call data function */
+ rc = data_func(sensor, data_arg, &sld);
+ if (rc != 0) {
+ goto err;
+ }
+ }
+
+ return 0;
+err:
+ return rc;
+}
+
+static int
+tsl2561_sensor_get_config(struct sensor *sensor, sensor_type_t type,
+ struct sensor_cfg *cfg)
+{
+ int rc;
+
+ if ((type != SENSOR_TYPE_LIGHT)) {
+ rc = SYS_EINVAL;
+ goto err;
+ }
+
+ cfg->sc_valtype = SENSOR_VALUE_TYPE_INT32;
+
+ return (0);
+err:
+ return (rc);
+}
+
+int
+tsl2561_config(struct tsl2561 *tsl2561, struct tsl2561_cfg *cfg)
+{
+ int rc;
+
+ if ((cfg->gain != TSL2561_LIGHT_GAIN_1X) &&
+ (cfg->gain != TSL2561_LIGHT_GAIN_16X)) {
+ TSL2561_ERR("Invalid gain value\n");
+ rc = SYS_EINVAL;
+ goto err;
+ }
+
+ /* Overwrite the configuration data. */
+ memcpy(&tsl2561->cfg, cfg, sizeof(*cfg));
+
+ /* Enable the device by setting the control bit to 0x03 */
+ rc = tsl2561_write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL,
+ TSL2561_CONTROL_POWERON);
+
+ /* Set integration time and gain */
+ rc = tsl2561_write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING,
+ cfg->integration_time | cfg->gain);
+ if (rc) {
+ goto err;
+ }
+
+err:
+ return (rc);
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9f59c4f0/hw/drivers/sensors/tsl2561/src/tsl2561_priv.h
----------------------------------------------------------------------
diff --git a/hw/drivers/sensors/tsl2561/src/tsl2561_priv.h b/hw/drivers/sensors/tsl2561/src/tsl2561_priv.h
index 5ead614..7d92d5f 100644
--- a/hw/drivers/sensors/tsl2561/src/tsl2561_priv.h
+++ b/hw/drivers/sensors/tsl2561/src/tsl2561_priv.h
@@ -49,16 +49,6 @@
#define TSL2561_REGISTER_CHAN1_LOW (0x0E)
#define TSL2561_REGISTER_CHAN1_HIGH (0x0F)
-#define TSL2561_CONTROL_POWERON (0x03)
-#define TSL2561_CONTROL_POWEROFF (0x00)
-
-#define TSL2561_INTEGRATIONTIME_13MS (0x00) /* 13.7ms */
-#define TSL2561_INTEGRATIONTIME_101MS (0x01) /* 101ms */
-#define TSL2561_INTEGRATIONTIME_402MS (0x02) /* 402ms */
-
-#define TSL2561_GAIN_1X (0x00) /* No gain */
-#define TSL2561_GAIN_16X (0x10) /* 16x gain */
-
#define TSL2561_COMMAND_BIT (0x80) /* Must be 1 */
#define TSL2561_CLEAR_BIT (0x40) /* 1=Clear any pending int */
#define TSL2561_WORD_BIT (0x20) /* 1=Read/write word */
@@ -67,6 +57,77 @@
#define TSL2561_CONTROL_POWERON (0x03)
#define TSL2561_CONTROL_POWEROFF (0x00)
+#define TSL2561_LUX_LUXSCALE (14) // Scale by 2^14
+#define TSL2561_LUX_RATIOSCALE (9) // Scale ratio by 2^9
+#define TSL2561_LUX_CHSCALE (10) // Scale channel values by 2^10
+#define TSL2561_LUX_CHSCALE_TINT0 (0x7517) // 322/11 * 2^TSL2561_LUX_CHSCALE
+#define TSL2561_LUX_CHSCALE_TINT1 (0x0FE7) // 322/81 * 2^TSL2561_LUX_CHSCALE
+
+// T, FN and CL package values
+#define TSL2561_LUX_K1T (0x0040) // 0.125 * 2^RATIO_SCALE
+#define TSL2561_LUX_B1T (0x01f2) // 0.0304 * 2^LUX_SCALE
+#define TSL2561_LUX_M1T (0x01be) // 0.0272 * 2^LUX_SCALE
+#define TSL2561_LUX_K2T (0x0080) // 0.250 * 2^RATIO_SCALE
+#define TSL2561_LUX_B2T (0x0214) // 0.0325 * 2^LUX_SCALE
+#define TSL2561_LUX_M2T (0x02d1) // 0.0440 * 2^LUX_SCALE
+#define TSL2561_LUX_K3T (0x00c0) // 0.375 * 2^RATIO_SCALE
+#define TSL2561_LUX_B3T (0x023f) // 0.0351 * 2^LUX_SCALE
+#define TSL2561_LUX_M3T (0x037b) // 0.0544 * 2^LUX_SCALE
+#define TSL2561_LUX_K4T (0x0100) // 0.50 * 2^RATIO_SCALE
+#define TSL2561_LUX_B4T (0x0270) // 0.0381 * 2^LUX_SCALE
+#define TSL2561_LUX_M4T (0x03fe) // 0.0624 * 2^LUX_SCALE
+#define TSL2561_LUX_K5T (0x0138) // 0.61 * 2^RATIO_SCALE
+#define TSL2561_LUX_B5T (0x016f) // 0.0224 * 2^LUX_SCALE
+#define TSL2561_LUX_M5T (0x01fc) // 0.0310 * 2^LUX_SCALE
+#define TSL2561_LUX_K6T (0x019a) // 0.80 * 2^RATIO_SCALE
+#define TSL2561_LUX_B6T (0x00d2) // 0.0128 * 2^LUX_SCALE
+#define TSL2561_LUX_M6T (0x00fb) // 0.0153 * 2^LUX_SCALE
+#define TSL2561_LUX_K7T (0x029a) // 1.3 * 2^RATIO_SCALE
+#define TSL2561_LUX_B7T (0x0018) // 0.00146 * 2^LUX_SCALE
+#define TSL2561_LUX_M7T (0x0012) // 0.00112 * 2^LUX_SCALE
+#define TSL2561_LUX_K8T (0x029a) // 1.3 * 2^RATIO_SCALE
+#define TSL2561_LUX_B8T (0x0000) // 0.000 * 2^LUX_SCALE
+#define TSL2561_LUX_M8T (0x0000) // 0.000 * 2^LUX_SCALE
+
+// CS package values
+#define TSL2561_LUX_K1C (0x0043) // 0.130 * 2^RATIO_SCALE
+#define TSL2561_LUX_B1C (0x0204) // 0.0315 * 2^LUX_SCALE
+#define TSL2561_LUX_M1C (0x01ad) // 0.0262 * 2^LUX_SCALE
+#define TSL2561_LUX_K2C (0x0085) // 0.260 * 2^RATIO_SCALE
+#define TSL2561_LUX_B2C (0x0228) // 0.0337 * 2^LUX_SCALE
+#define TSL2561_LUX_M2C (0x02c1) // 0.0430 * 2^LUX_SCALE
+#define TSL2561_LUX_K3C (0x00c8) // 0.390 * 2^RATIO_SCALE
+#define TSL2561_LUX_B3C (0x0253) // 0.0363 * 2^LUX_SCALE
+#define TSL2561_LUX_M3C (0x0363) // 0.0529 * 2^LUX_SCALE
+#define TSL2561_LUX_K4C (0x010a) // 0.520 * 2^RATIO_SCALE
+#define TSL2561_LUX_B4C (0x0282) // 0.0392 * 2^LUX_SCALE
+#define TSL2561_LUX_M4C (0x03df) // 0.0605 * 2^LUX_SCALE
+#define TSL2561_LUX_K5C (0x014d) // 0.65 * 2^RATIO_SCALE
+#define TSL2561_LUX_B5C (0x0177) // 0.0229 * 2^LUX_SCALE
+#define TSL2561_LUX_M5C (0x01dd) // 0.0291 * 2^LUX_SCALE
+#define TSL2561_LUX_K6C (0x019a) // 0.80 * 2^RATIO_SCALE
+#define TSL2561_LUX_B6C (0x0101) // 0.0157 * 2^LUX_SCALE
+#define TSL2561_LUX_M6C (0x0127) // 0.0180 * 2^LUX_SCALE
+#define TSL2561_LUX_K7C (0x029a) // 1.3 * 2^RATIO_SCALE
+#define TSL2561_LUX_B7C (0x0037) // 0.00338 * 2^LUX_SCALE
+#define TSL2561_LUX_M7C (0x002b) // 0.00260 * 2^LUX_SCALE
+#define TSL2561_LUX_K8C (0x029a) // 1.3 * 2^RATIO_SCALE
+#define TSL2561_LUX_B8C (0x0000) // 0.000 * 2^LUX_SCALE
+#define TSL2561_LUX_M8C (0x0000) // 0.000 * 2^LUX_SCALE
+
+// Auto-gain thresholds
+#define TSL2561_AGC_THI_13MS (4850) // Max value at Ti 13ms = 5047
+#define TSL2561_AGC_TLO_13MS (100)
+#define TSL2561_AGC_THI_101MS (36000) // Max value at Ti 101ms = 37177
+#define TSL2561_AGC_TLO_101MS (200)
+#define TSL2561_AGC_THI_402MS (63000) // Max value at Ti 402ms = 65535
+#define TSL2561_AGC_TLO_402MS (500)
+
+// Clipping thresholds
+#define TSL2561_CLIPPING_13MS (4900)
+#define TSL2561_CLIPPING_101MS (37000)
+#define TSL2561_CLIPPING_402MS (65000)
+
#ifdef __cplusplus
extern "C" {
#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9f59c4f0/hw/drivers/sensors/tsl2561/syscfg.yml
----------------------------------------------------------------------
diff --git a/hw/drivers/sensors/tsl2561/syscfg.yml b/hw/drivers/sensors/tsl2561/syscfg.yml
index f6e6801..d507b79 100644
--- a/hw/drivers/sensors/tsl2561/syscfg.yml
+++ b/hw/drivers/sensors/tsl2561/syscfg.yml
@@ -21,9 +21,6 @@
# SOFTWARE.
syscfg.defs:
- TSL2561_TASK:
- description: 'Enable the TSL2561 sensor driver'
- value: 0
TSL2561_I2CADDR:
description: 'HW I2C address for the TSL2561 (0x29, 0x39 or 0x49)'
value: 0x39
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9f59c4f0/hw/sensor/include/sensor/light.h
----------------------------------------------------------------------
diff --git a/hw/sensor/include/sensor/light.h b/hw/sensor/include/sensor/light.h
new file mode 100644
index 0000000..677f5c4
--- /dev/null
+++ b/hw/sensor/include/sensor/light.h
@@ -0,0 +1,49 @@
+/*
+ * 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 __SENSOR_LIGHT_H__
+#define __SENSOR_LIGHT_H__
+
+#include "os/os.h"
+#include "os/os_dev.h"
+#include "sensor/sensor.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Data representing a singular read from a luminosity sensor.
+ * All data is in lux
+ */
+struct sensor_light_data {
+ uint16_t sld_full;
+ uint16_t sld_ir;
+ uint32_t sld_lux;
+} __attribute__((packed));
+
+/**
+ * Luminosity Sensor data is unused for this field.
+ */
+#define SENSOR_LIGHT_DATA_UNUSED (-1)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SENSOR_LIGHT_H__ */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9f59c4f0/hw/sensor/src/sensor_shell.c
----------------------------------------------------------------------
diff --git a/hw/sensor/src/sensor_shell.c b/hw/sensor/src/sensor_shell.c
index 6312f81..c2c68b1 100644
--- a/hw/sensor/src/sensor_shell.c
+++ b/hw/sensor/src/sensor_shell.c
@@ -33,6 +33,7 @@
#include "sensor/sensor.h"
#include "sensor/accel.h"
#include "sensor/mag.h"
+#include "sensor/light.h"
#include "console/console.h"
#include "shell/shell.h"
@@ -96,6 +97,7 @@ sensor_shell_read_listener(struct sensor *sensor, void *arg, void *data)
struct sensor_shell_read_ctx *ctx;
struct sensor_accel_data *sad;
struct sensor_mag_data *smd;
+ struct sensor_light_data *sld;
char tmpstr[13];
ctx = (struct sensor_shell_read_ctx *) arg;
@@ -130,6 +132,20 @@ sensor_shell_read_listener(struct sensor *sensor, void *arg, void *data)
console_printf("\n");
}
+ if (ctx->type == SENSOR_TYPE_LIGHT) {
+ sld = (struct sensor_light_data *) data;
+ if (sld->sld_full != SENSOR_LIGHT_DATA_UNUSED) {
+ console_printf("Full = %u, ", sld->sld_full);
+ }
+ if (sld->sld_ir != SENSOR_LIGHT_DATA_UNUSED) {
+ console_printf("IR = %u, ", sld->sld_ir);
+ }
+ if (sld->sld_lux != SENSOR_LIGHT_DATA_UNUSED) {
+ console_printf("Lux = %u, ", (unsigned int)sld->sld_lux);
+ }
+ console_printf("\n");
+ }
+
return (0);
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9f59c4f0/sys/shell/src/shell.c
----------------------------------------------------------------------
diff --git a/sys/shell/src/shell.c b/sys/shell/src/shell.c
index f11086b..bc8554e 100644
--- a/sys/shell/src/shell.c
+++ b/sys/shell/src/shell.c
@@ -211,7 +211,7 @@ err:
static int
shell_cmd(char *cmd, char **argv, int argc)
{
- struct shell_cmd *sc;
+ struct shell_cmd *sc = NULL;
int rc;
rc = shell_cmd_find(cmd, &sc);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9f59c4f0/sys/shell/syscfg.yml
----------------------------------------------------------------------
diff --git a/sys/shell/syscfg.yml b/sys/shell/syscfg.yml
index c495c58..236a20d 100644
--- a/sys/shell/syscfg.yml
+++ b/sys/shell/syscfg.yml
@@ -27,4 +27,4 @@ syscfg.defs:
value: 256
SHELL_DEBUG:
description: Enables additional error checking in the shell package.
- value: 1
+ value: 0