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/03/09 23:17:16 UTC
incubator-mynewt-core git commit: MYNEWT-665 SensorAPI: Add TCS34725
Driver and color sensor support
Repository: incubator-mynewt-core
Updated Branches:
refs/heads/develop 605317587 -> 2d4f8a760
MYNEWT-665
SensorAPI: Add TCS34725 Driver and color sensor support
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/2d4f8a76
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/2d4f8a76
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/2d4f8a76
Branch: refs/heads/develop
Commit: 2d4f8a76055e50d42983da0eef2158e99be721d1
Parents: 6053175
Author: Vipul Rahane <vi...@apache.org>
Authored: Thu Mar 9 15:07:58 2017 -0800
Committer: Vipul Rahane <vi...@apache.org>
Committed: Thu Mar 9 15:16:46 2017 -0800
----------------------------------------------------------------------
apps/sensors_test/pkg.yml | 1 +
apps/sensors_test/src/main.c | 32 +-
apps/sensors_test/syscfg.yml | 7 +-
hw/bsp/nrf52dk/src/hal_bsp.c | 68 ++
.../tcs34725/include/tcs34725/tcs34725.h | 84 ++
hw/drivers/sensors/tcs34725/pkg.yml | 32 +
hw/drivers/sensors/tcs34725/src/tcs34725.c | 920 +++++++++++++++++++
hw/drivers/sensors/tcs34725/src/tcs34725_priv.h | 278 ++++++
.../sensors/tcs34725/src/tcs34725_shell.c | 471 ++++++++++
hw/drivers/sensors/tcs34725/syscfg.yml | 35 +
hw/sensor/include/sensor/color.h | 51 +
hw/sensor/include/sensor/sensor.h | 8 +-
hw/sensor/src/sensor_shell.c | 25 +
13 files changed, 2004 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2d4f8a76/apps/sensors_test/pkg.yml
----------------------------------------------------------------------
diff --git a/apps/sensors_test/pkg.yml b/apps/sensors_test/pkg.yml
index 406ad30..41db418 100644
--- a/apps/sensors_test/pkg.yml
+++ b/apps/sensors_test/pkg.yml
@@ -35,6 +35,7 @@ pkg.deps:
- hw/drivers/sensors/lsm303dlhc
- hw/drivers/sensors/tsl2561
- hw/drivers/sensors/bno055
+ - hw/drivers/sensors/tcs34725
- boot/bootutil
- sys/shell
- sys/config
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2d4f8a76/apps/sensors_test/src/main.c
----------------------------------------------------------------------
diff --git a/apps/sensors_test/src/main.c b/apps/sensors_test/src/main.c
index b79b2b5..45d25a2 100755
--- a/apps/sensors_test/src/main.c
+++ b/apps/sensors_test/src/main.c
@@ -32,6 +32,7 @@
#include <sensor/sensor.h>
#include <lsm303dlhc/lsm303dlhc.h>
#include <tsl2561/tsl2561.h>
+#include <tcs34725/tcs34725.h>
#include <bno055/bno055.h>
#include "flash_map/flash_map.h"
#include <hal/hal_system.h>
@@ -244,6 +245,29 @@ config_sensor(void)
struct os_dev *dev;
int rc;
+#if MYNEWT_VAL(TCS34725_PRESENT)
+ struct tcs34725_cfg tcscfg;
+
+ dev = (struct os_dev *) os_dev_open("color0", OS_TIMEOUT_NEVER, NULL);
+ assert(dev != NULL);
+ rc = tcs34725_init(dev, NULL);
+ if (rc) {
+ os_dev_close(dev);
+ goto err;
+ }
+
+ /* Gain set to 16X and Inetgration time set to 24ms */
+ tcscfg.gain = TCS34725_GAIN_16X;;
+ tcscfg.integration_time = TCS34725_INTEGRATIONTIME_24MS;
+
+ rc = tcs34725_config((struct tcs34725 *)dev, &tcscfg);
+ if (rc) {
+ os_dev_close(dev);
+ goto err;
+ }
+ os_dev_close(dev);
+#endif
+
#if MYNEWT_VAL(TSL2561_PRESENT)
struct tsl2561_cfg tslcfg;
@@ -309,9 +333,9 @@ config_sensor(void)
BNO055_DO_FORMAT_ANDROID;
bcfg.bc_opr_mode = BNO055_OPR_MODE_ACCONLY;
-
bcfg.bc_pwr_mode = BNO055_PWR_MODE_NORMAL;
-
+ bcfg.bc_acc_bw = BNO055_ACC_CFG_BW_125HZ;
+ bcfg.bc_acc_range = BNO055_ACC_CFG_RNG_16G;
bcfg.bc_use_ext_xtal = 1;
rc = bno055_config((struct bno055 *) dev, &bcfg);
@@ -418,6 +442,10 @@ main(int argc, char **argv)
}
#endif
+#if MYNEWT_VAL(TCS34725_CLI)
+ tcs34725_shell_init();
+#endif
+
#if MYNEWT_VAL(TSL2561_CLI)
tsl2561_shell_init();
#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2d4f8a76/apps/sensors_test/syscfg.yml
----------------------------------------------------------------------
diff --git a/apps/sensors_test/syscfg.yml b/apps/sensors_test/syscfg.yml
index 5507f28..bdbe400 100644
--- a/apps/sensors_test/syscfg.yml
+++ b/apps/sensors_test/syscfg.yml
@@ -47,11 +47,14 @@ syscfg.vals:
syscfg.defs:
TSL2561_PRESENT:
description: 'TSL2561 is present'
- value : 1
+ value : 0
LSM303DLHC_PRESENT:
description: 'LSM303 is present'
value : 1
BNO055_PRESENT:
description: 'BNO055 is present'
- value : 1
+ value : 0
+ TCS34725_PRESENT:
+ description: 'BNO055 is present'
+ value : 0
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2d4f8a76/hw/bsp/nrf52dk/src/hal_bsp.c
----------------------------------------------------------------------
diff --git a/hw/bsp/nrf52dk/src/hal_bsp.c b/hw/bsp/nrf52dk/src/hal_bsp.c
index 1ab37e1..3b7b375 100644
--- a/hw/bsp/nrf52dk/src/hal_bsp.c
+++ b/hw/bsp/nrf52dk/src/hal_bsp.c
@@ -42,6 +42,26 @@
#endif
#include "os/os_dev.h"
#include "bsp.h"
+#include <lsm303dlhc/lsm303dlhc.h>
+#include <tsl2561/tsl2561.h>
+#include <tcs34725/tcs34725.h>
+#include <bno055/bno055.h>
+
+#if MYNEWT_VAL(LSM303DLHC_PRESENT)
+static struct lsm303dlhc lsm303dlhc;
+#endif
+
+#if MYNEWT_VAL(BNO055_PRESENT)
+static struct bno055 bno055;
+#endif
+
+#if MYNEWT_VAL(TSL2561_PRESENT)
+static struct tsl2561 tsl2561;
+#endif
+
+#if MYNEWT_VAL(TCS34725_PRESENT)
+static struct tcs34725 tcs34725;
+#endif
#if MYNEWT_VAL(UART_0)
static struct uart_dev os_bsp_uart0;
@@ -151,6 +171,30 @@ hal_bsp_get_nvic_priority(int irq_num, uint32_t pri)
return cfg_pri;
}
+#if MYNEWT_VAL(LSM303DLHC_PRESENT) || MYNEWT_VAL(BNO055_PRESENT)
+static int
+slinky_accel_init(struct os_dev *dev, void *arg)
+{
+ return (0);
+}
+#endif
+
+#if MYNEWT_VAL(TSL2561_PRESENT)
+static int
+slinky_light_init(struct os_dev *dev, void *arg)
+{
+ return (0);
+}
+#endif
+
+#if MYNEWT_VAL(TCS34725_PRESENT)
+static int
+slinky_color_init(struct os_dev *dev, void *arg)
+{
+ return (0);
+}
+#endif
+
void
hal_bsp_init(void)
{
@@ -202,6 +246,30 @@ hal_bsp_init(void)
assert(rc == 0);
#endif
+#if MYNEWT_VAL(LSM303DLHC_PRESENT)
+ rc = os_dev_create((struct os_dev *) &lsm303dlhc, "accel0",
+ OS_DEV_INIT_PRIMARY, 0, slinky_accel_init, NULL);
+ assert(rc == 0);
+#endif
+
+#if MYNEWT_VAL(BNO055_PRESENT)
+ rc = os_dev_create((struct os_dev *) &bno055, "accel1",
+ OS_DEV_INIT_PRIMARY, 0, slinky_accel_init, NULL);
+ assert(rc == 0);
+#endif
+
+#if MYNEWT_VAL(TSL2561_PRESENT)
+ rc = os_dev_create((struct os_dev *) &tsl2561, "light0",
+ OS_DEV_INIT_PRIMARY, 0, slinky_light_init, NULL);
+ assert(rc == 0);
+#endif
+
+#if MYNEWT_VAL(TCS34725_PRESENT)
+ rc = os_dev_create((struct os_dev *) &tcs34725, "color0",
+ OS_DEV_INIT_PRIMARY, 0, slinky_color_init, NULL);
+ assert(rc == 0);
+#endif
+
#if MYNEWT_VAL(UART_0)
rc = os_dev_create((struct os_dev *) &os_bsp_uart0, "uart0",
OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&os_bsp_uart0_cfg);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2d4f8a76/hw/drivers/sensors/tcs34725/include/tcs34725/tcs34725.h
----------------------------------------------------------------------
diff --git a/hw/drivers/sensors/tcs34725/include/tcs34725/tcs34725.h b/hw/drivers/sensors/tcs34725/include/tcs34725/tcs34725.h
new file mode 100644
index 0000000..59e4385
--- /dev/null
+++ b/hw/drivers/sensors/tcs34725/include/tcs34725/tcs34725.h
@@ -0,0 +1,84 @@
+/*
+ * 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
+ * resarding 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 __TCS34725_H__
+#define __TCS34725_H__
+
+#define TCS34725_INTEGRATIONTIME_2_4MS 0xFF /* 2.4ms - 1 cycle - Max Count: 1024 */
+#define TCS34725_INTEGRATIONTIME_24MS 0xF6 /* 24ms - 10 cycles - Max Count: 10240 */
+#define TCS34725_INTEGRATIONTIME_50MS 0xEB /* 50ms - 20 cycles - Max Count: 20480 */
+#define TCS34725_INTEGRATIONTIME_101MS 0xD5 /* 101ms - 42 cycles - Max Count: 43008 */
+#define TCS34725_INTEGRATIONTIME_154MS 0xC0 /* 154ms - 64 cycles - Max Count: 65535 */
+#define TCS34725_INTEGRATIONTIME_700MS 0x00 /* 700ms - 256 cycles - Max Count: 65535 */
+
+#define TCS34725_GAIN_1X 0x00 /* No gain */
+#define TCS34725_GAIN_4X 0x01 /* 4x gain */
+#define TCS34725_GAIN_16X 0x02 /* 16x gain */
+#define TCS34725_GAIN_60X 0x03 /* 60x gain */
+
+#include <os/os.h>
+#include "os/os_dev.h"
+#include "sensor/sensor.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct tcs34725_cfg {
+ uint8_t gain;
+ uint8_t integration_time;
+};
+
+struct tcs34725 {
+ struct os_dev dev;
+ struct sensor sensor;
+ struct tcs34725_cfg cfg;
+ os_time_t last_read_time;
+};
+
+/**
+ * Expects to be called back through os_dev_create().
+ *
+ * @param The device object associated with this accellerometer
+ * @param Argument passed to OS device init, unused
+ *
+ * @return 0 on success, non-zero error on failure.
+ */
+int
+tcs34725_init(struct os_dev *dev, void *arg);
+
+/**
+ * Configure the sensor
+ *
+ * @param ptr to the sensor
+ * @param ptr to sensor config
+ * @return 0 on success, non-zero on failure
+ */
+int
+tcs34725_config(struct tcs34725 *tcs34725, struct tcs34725_cfg *cfg);
+
+#if MYNEWT_VAL(TCS34725_CLI)
+int tcs34725_shell_init(void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2d4f8a76/hw/drivers/sensors/tcs34725/pkg.yml
----------------------------------------------------------------------
diff --git a/hw/drivers/sensors/tcs34725/pkg.yml b/hw/drivers/sensors/tcs34725/pkg.yml
new file mode 100644
index 0000000..18c65c4
--- /dev/null
+++ b/hw/drivers/sensors/tcs34725/pkg.yml
@@ -0,0 +1,32 @@
+#
+# 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.
+#
+
+pkg.name: hw/drivers/sensors/tcs34725
+pkg.description: Driver for the TCS34725 light to digital sensor
+pkg.author: "Adafruit <su...@adafruit.com>"
+pkg.homepage: "http://www.adafruit.com/"
+pkg.keywords:
+ - adafruit
+ - tcs34725
+ - i2c
+ - sensor
+
+pkg.deps:
+ - "@apache-mynewt-core/kernel/os"
+ - "@apache-mynewt-core/hw/hal"
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2d4f8a76/hw/drivers/sensors/tcs34725/src/tcs34725.c
----------------------------------------------------------------------
diff --git a/hw/drivers/sensors/tcs34725/src/tcs34725.c b/hw/drivers/sensors/tcs34725/src/tcs34725.c
new file mode 100644
index 0000000..cd0f2c2
--- /dev/null
+++ b/hw/drivers/sensors/tcs34725/src/tcs34725.c
@@ -0,0 +1,920 @@
+/*
+ * 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
+ * resarding 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.
+ */
+
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "defs/error.h"
+#include "os/os.h"
+#include "sysinit/sysinit.h"
+#include "hal/hal_i2c.h"
+#include "sensor/sensor.h"
+#include "tcs34725/tcs34725.h"
+#include "tcs34725_priv.h"
+#include "sensor/color.h"
+
+#if MYNEWT_VAL(TCS34725_LOG)
+#include "log/log.h"
+#endif
+
+#if MYNEWT_VAL(TCS34725_STATS)
+#include "stats/stats.h"
+#endif
+
+#if MYNEWT_VAL(TCS34725_STATS)
+/* Define the stats section and records */
+STATS_SECT_START(tcs34725_stat_section)
+ STATS_SECT_ENTRY(samples_2_4ms)
+ STATS_SECT_ENTRY(samples_24ms)
+ STATS_SECT_ENTRY(samples_50ms)
+ STATS_SECT_ENTRY(samples_101ms)
+ STATS_SECT_ENTRY(samples_154ms)
+ STATS_SECT_ENTRY(samples_700ms)
+ STATS_SECT_ENTRY(samples_userdef)
+ STATS_SECT_ENTRY(errors)
+STATS_SECT_END
+
+/* Define stat names for querying */
+STATS_NAME_START(tcs34725_stat_section)
+ STATS_NAME(tcs34725_stat_section, samples_2_4ms)
+ STATS_NAME(tcs34725_stat_section, samples_24ms)
+ STATS_NAME(tcs34725_stat_section, samples_50ms)
+ STATS_NAME(tcs34725_stat_section, samples_101ms)
+ STATS_NAME(tcs34725_stat_section, samples_154ms)
+ STATS_NAME(tcs34725_stat_section, samples_700ms)
+ STATS_NAME(tcs34725_stat_section, samples_userdef)
+ STATS_NAME(tcs34725_stat_section, errors)
+STATS_NAME_END(tcs34725_stat_section)
+
+/* Global variable used to hold stats data */
+STATS_SECT_DECL(tcs34725_stat_section) g_tcs34725stats;
+#endif
+
+#if MYNEWT_VAL(TCS34725_LOG)
+#define LOG_MODULE_TCS34725 (307)
+#define TCS34725_INFO(...) LOG_INFO(&_log, LOG_MODULE_TCS34725, __VA_ARGS__)
+#define TCS34725_ERR(...) LOG_ERROR(&_log, LOG_MODULE_TCS34725, __VA_ARGS__)
+static struct log _log;
+#else
+#define TCS34725_INFO(...)
+#define TCS34725_ERR(...)
+#endif
+
+/* Exports for the sensor interface.
+ */
+static void *tcs34725_sensor_get_interface(struct sensor *, sensor_type_t);
+static int tcs34725_sensor_read(struct sensor *, sensor_type_t,
+ sensor_data_func_t, void *, uint32_t);
+static int tcs34725_sensor_get_config(struct sensor *, sensor_type_t,
+ struct sensor_cfg *);
+
+static const struct sensor_driver g_tcs34725_sensor_driver = {
+ tcs34725_sensor_get_interface,
+ tcs34725_sensor_read,
+ tcs34725_sensor_get_config
+};
+
+uint8_t g_tcs34725_gain;
+uint8_t g_tcs34725_integration_time;
+uint8_t g_tcs34725_enabled;
+
+/**
+ * Writes a single byte to the specified register
+ *
+ * @param The register address to write to
+ * @param The value to write
+ *
+ * @return 0 on success, non-zero error on failure.
+ */
+int
+tcs34725_write8(uint8_t reg, uint32_t value)
+{
+ int rc;
+ uint8_t payload[2] = { reg | TCS34725_COMMAND_BIT, value & 0xFF };
+
+ struct hal_i2c_master_data data_struct = {
+ .address = MYNEWT_VAL(TCS34725_I2CADDR),
+ .len = 2,
+ .buffer = payload
+ };
+
+ rc = hal_i2c_master_write(MYNEWT_VAL(TCS34725_I2CBUS), &data_struct,
+ OS_TICKS_PER_SEC / 10, 1);
+ if (rc) {
+ TCS34725_ERR("Failed to write to 0x%02X:0x%02X with value 0x%02X\n",
+ addr, reg, value);
+#if MYNEWT_VAL(TCS34725_STATS)
+ STATS_INC(g_tcs34725stats, errors);
+#endif
+ }
+
+ return rc;
+}
+
+/**
+ * Reads a single byte from the specified register
+ *
+ * @param The register address to read from
+ * @param Pointer to where the register value should be written
+ *
+ * @return 0 on success, non-zero error on failure.
+ */
+int
+tcs34725_read8(uint8_t reg, uint8_t *value)
+{
+ int rc;
+ uint8_t payload;
+
+ struct hal_i2c_master_data data_struct = {
+ .address = MYNEWT_VAL(TCS34725_I2CADDR),
+ .len = 1,
+ .buffer = &payload
+ };
+
+ /* Register write */
+ payload = reg | TCS34725_COMMAND_BIT;
+ rc = hal_i2c_master_write(MYNEWT_VAL(TCS34725_I2CBUS), &data_struct,
+ OS_TICKS_PER_SEC / 10, 1);
+ if (rc) {
+ TCS34725_ERR("I2C access failed at address 0x%02X\n", addr);
+#if MYNEWT_VAL(TCS34725_STATS)
+ STATS_INC(g_tcs34725stats, errors);
+#endif
+ goto error;
+ }
+
+ /* Read one byte back */
+ payload = 0;
+ rc = hal_i2c_master_read(MYNEWT_VAL(TCS34725_I2CBUS), &data_struct,
+ OS_TICKS_PER_SEC / 10, 1);
+ *value = payload;
+ if (rc) {
+ TCS34725_ERR("Failed to read from 0x%02X:0x%02X\n", addr, reg);
+#if MYNEWT_VAL(TCS34725_STATS)
+ STATS_INC(g_tcs34725stats, errors);
+#endif
+ }
+
+error:
+ return rc;
+}
+
+/**
+ * Read data from the sensor of variable length (MAX: 8 bytes)
+ *
+ * @param Register to read from
+ * @param Bufer to read into
+ * @param Length of the buffer
+ *
+ * @return 0 on success and non-zero on failure
+ */
+int
+tcs34725_readlen(uint8_t reg, uint8_t *buffer, uint8_t len)
+{
+ int rc;
+ uint8_t payload[9] = { reg | TCS34725_COMMAND_BIT, 0, 0, 0, 0, 0, 0, 0, 0};
+
+ struct hal_i2c_master_data data_struct = {
+ .address = MYNEWT_VAL(TCS34725_I2CADDR),
+ .len = 1,
+ .buffer = payload
+ };
+
+ /* Clear the supplied buffer */
+ memset(buffer, 0, len);
+
+ /* Register write */
+ rc = hal_i2c_master_write(MYNEWT_VAL(TCS34725_I2CBUS), &data_struct,
+ OS_TICKS_PER_SEC / 10, 1);
+ if (rc) {
+ TCS34725_ERR("I2C access failed at address 0x%02X\n", addr);
+#if MYNEWT_VAL(TCS34725_STATS)
+ STATS_INC(g_tcs34725stats, errors);
+#endif
+ goto err;
+ }
+
+ /* Read len bytes back */
+ memset(payload, 0, sizeof(payload));
+ data_struct.len = len;
+ rc = hal_i2c_master_read(MYNEWT_VAL(TCS34725_I2CBUS), &data_struct,
+ OS_TICKS_PER_SEC / 10, 1);
+
+ if (rc) {
+ TCS34725_ERR("Failed to read from 0x%02X:0x%02X\n", addr, reg);
+#if MYNEWT_VAL(TCS34725_STATS)
+ STATS_INC(g_tcs34725stats, errors);
+#endif
+ goto err;
+ }
+
+ /* Copy the I2C results into the supplied buffer */
+ memcpy(buffer, payload, len);
+
+ return 0;
+err:
+ return rc;
+}
+
+/**
+ * Writes a multiple bytes to the specified register
+ *
+ * @param The register address to write to
+ * @param The data buffer to write from
+ *
+ * @return 0 on success, non-zero error on failure.
+ */
+int
+tcs34725_writelen(uint8_t reg, uint8_t *buffer, uint8_t len)
+{
+ int rc;
+ uint8_t payload[9] = { reg, 0, 0, 0, 0, 0, 0, 0, 0};
+
+ struct hal_i2c_master_data data_struct = {
+ .address = MYNEWT_VAL(TCS34725_I2CADDR),
+ .len = 1,
+ .buffer = payload
+ };
+
+ memcpy(&payload[1], buffer, len);
+
+ /* Register write */
+ rc = hal_i2c_master_write(MYNEWT_VAL(TCS34725_I2CBUS), &data_struct,
+ OS_TICKS_PER_SEC / 10, 1);
+ if (rc) {
+ TCS34725_ERR("I2C access failed at address 0x%02X\n", addr);
+#if MYNEWT_VAL(TCS34725_STATS)
+ STATS_INC(g_tcs34725stats, errors);
+#endif
+ goto err;
+ }
+
+ memset(payload, 0, sizeof(payload));
+ data_struct.len = len;
+ rc = hal_i2c_master_write(MYNEWT_VAL(TCS34725_I2CBUS), &data_struct,
+ OS_TICKS_PER_SEC / 10, len);
+
+ if (rc) {
+ TCS34725_ERR("Failed to read from 0x%02X:0x%02X\n", addr, reg);
+#if MYNEWT_VAL(TCS34725_STATS)
+ STATS_INC(g_tcs34725stats, errors);
+#endif
+ goto err;
+ }
+
+ return 0;
+err:
+ return rc;
+}
+
+
+#if MYNEWT_VAL(USE_MATH)
+/**
+ * Float power function
+ *
+ * @param float base
+ * @param float exponent
+ */
+static float
+powf(float base, float exp)
+{
+ return (float)(pow((double)base, (double)exp));
+}
+
+#endif
+
+/**
+ *
+ * Enables the device
+ *
+ * @param enable/disable
+ * @return 0 on success, non-zero on error
+ */
+int
+tcs34725_enable(uint8_t enable)
+{
+ int rc;
+ uint8_t reg;
+
+ rc = tcs34725_read8(TCS34725_REG_ENABLE, ®);
+ if (rc) {
+ goto err;
+ }
+
+ os_time_delay((3 * OS_TICKS_PER_SEC)/1000 + 1);
+
+ if (enable) {
+ rc = tcs34725_write8(TCS34725_REG_ENABLE, reg | TCS34725_ENABLE_PON | TCS34725_ENABLE_AEN);
+ if (rc) {
+ goto err;
+ }
+ } else {
+ rc = tcs34725_write8(TCS34725_REG_ENABLE, reg & ~(TCS34725_ENABLE_PON | TCS34725_ENABLE_AEN));
+ if (rc) {
+ goto err;
+ }
+ }
+
+ g_tcs34725_enabled = enable;
+
+ return 0;
+err:
+ return rc;
+}
+
+/**
+ * Expects to be called back through os_dev_create().
+ *
+ * @param The device object associated with this accellerometer
+ * @param Argument passed to OS device init, unused
+ *
+ * @return 0 on success, non-zero error on failure.
+ */
+int
+tcs34725_init(struct os_dev *dev, void *arg)
+{
+ struct tcs34725 *tcs34725;
+ struct sensor *sensor;
+ int rc;
+
+ tcs34725 = (struct tcs34725 *) dev;
+
+#if MYNEWT_VAL(TCS34725_LOG)
+ log_register("tcs34725", &_log, &log_console_handler, NULL, LOG_SYSLEVEL);
+#endif
+
+ sensor = &tcs34725->sensor;
+
+#if MYNEWT_VAL(TCS34725_STATS)
+ /* Initialise the stats entry */
+ rc = stats_init(
+ STATS_HDR(g_tcs34725stats),
+ STATS_SIZE_INIT_PARMS(g_tcs34725stats, STATS_SIZE_32),
+ STATS_NAME_INIT_PARMS(tcs34725_stat_section));
+ SYSINIT_PANIC_ASSERT(rc == 0);
+ /* Register the entry with the stats registry */
+ rc = stats_register("tcs34725", STATS_HDR(g_tcs34725stats));
+ SYSINIT_PANIC_ASSERT(rc == 0);
+#endif
+
+ rc = sensor_init(sensor, dev);
+ if (rc != 0) {
+ goto err;
+ }
+
+ /* Add the color sensor driver */
+ rc = sensor_set_driver(sensor, SENSOR_TYPE_COLOR,
+ (struct sensor_driver *) &g_tcs34725_sensor_driver);
+ if (rc != 0) {
+ goto err;
+ }
+
+ rc = sensor_mgr_register(sensor);
+ if (rc != 0) {
+ goto err;
+ }
+
+ return (0);
+err:
+ return (rc);
+}
+
+/**
+ * Indicates whether the sensor is enabled or not
+ *
+ * @return 1 if enabled, 0 if disabled
+ */
+uint8_t
+tcs34725_get_enable (void)
+{
+ return g_tcs34725_enabled;
+}
+
+/**
+ * Sets integration time
+ *
+ * @param integration time to be set
+ * @return 0 on success, non-zero on failure
+ */
+int
+tcs34725_set_integration_time(uint8_t int_time)
+{
+ int rc;
+
+ rc = tcs34725_write8(TCS34725_REG_ATIME,
+ int_time | g_tcs34725_gain);
+ if (rc) {
+ goto err;
+ }
+
+ g_tcs34725_integration_time = int_time;
+
+err:
+ return rc;
+}
+
+/**
+ * Gets integration time set earlier
+ *
+ * @return integration time
+ */
+uint8_t
+tcs34725_get_integration_time(void)
+{
+ return g_tcs34725_integration_time;
+}
+
+/**
+ * Set gain of the sensor
+ *
+ * @param gain
+ * @return 0 on success, non-zero on failure
+ */
+int
+tcs34725_set_gain(uint8_t gain)
+{
+ int rc;
+
+ if (gain > TCS34725_GAIN_60X) {
+ TCS34725_ERR("Invalid gain value\n");
+ rc = SYS_EINVAL;
+ goto err;
+ }
+
+ rc = tcs34725_write8(TCS34725_REG_CONTROL,
+ g_tcs34725_integration_time | gain);
+ if (rc) {
+ goto err;
+ }
+
+ g_tcs34725_gain = gain;
+
+err:
+ return rc;
+}
+
+/**
+ * Get gain of the sensor
+ *
+ * @return gain
+ */
+uint8_t
+tcs34725_get_gain(void)
+{
+ return g_tcs34725_gain;
+}
+
+/**
+ * Get chip ID from the sensor
+ *
+ * @param Pointer to the variable to fill up chip ID in
+ * @return 0 on success, non-zero on failure
+ */
+int
+tcs34725_get_chip_id(uint8_t *id)
+{
+ int rc;
+ uint8_t idtmp;
+
+ /* Check if we can read the chip address */
+ rc = tcs34725_read8(TCS34725_REG_ID, &idtmp);
+ if (rc) {
+ goto err;
+ }
+
+ *id = idtmp;
+
+ return 0;
+err:
+ return rc;
+}
+
+/**
+ * Configure the sensor
+ *
+ * @param ptr to the sensor
+ * @param ptr to sensor config
+ * @return 0 on success, non-zero on failure
+ */
+int
+tcs34725_config(struct tcs34725 *tcs34725, struct tcs34725_cfg *cfg)
+{
+ int rc;
+ uint8_t id;
+
+ rc = tcs34725_get_chip_id(&id);
+ if (id != TCS34725_ID || rc != 0) {
+ rc = SYS_EINVAL;
+ goto err;
+ }
+
+ rc |= tcs34725_enable(1);
+
+ rc |= tcs34725_set_integration_time(cfg->integration_time);
+
+ rc |= tcs34725_set_gain(cfg->gain);
+ if (rc) {
+ goto err;
+ }
+
+ /* Overwrite the configuration data. */
+ memcpy(&tcs34725->cfg, cfg, sizeof(*cfg));
+
+err:
+ return (rc);
+}
+
+/**
+ * Reads the raw red, green, blue and clear channel values
+ *
+ *
+ * @param red value to return
+ * @param green value to return
+ * @param blue value to return
+ * @param clear channel value
+ * @param driver sturcture containing config
+ */
+int
+tcs34725_get_rawdata(uint16_t *r, uint16_t *g, uint16_t *b, uint16_t *c,
+ struct tcs34725 *tcs34725)
+{
+ uint8_t payload[8] = {0};
+ int rc;
+ int delay_ticks;
+
+ /* Set a delay for the integration time */
+ switch (tcs34725->cfg.integration_time)
+ {
+ case TCS34725_INTEGRATIONTIME_2_4MS:
+ delay_ticks = (3 * OS_TICKS_PER_SEC)/1000 + 1;
+ break;
+ case TCS34725_INTEGRATIONTIME_24MS:
+ delay_ticks = (24 * OS_TICKS_PER_SEC)/1000 + 1;
+ break;
+ case TCS34725_INTEGRATIONTIME_50MS:
+ delay_ticks = (50 * OS_TICKS_PER_SEC)/1000 + 1;
+ break;
+ case TCS34725_INTEGRATIONTIME_101MS:
+ delay_ticks = (101 * OS_TICKS_PER_SEC)/1000 + 1;
+ break;
+ case TCS34725_INTEGRATIONTIME_154MS:
+ delay_ticks = (154 * OS_TICKS_PER_SEC)/1000 + 1;
+ break;
+ case TCS34725_INTEGRATIONTIME_700MS:
+ delay_ticks = (700 * OS_TICKS_PER_SEC)/1000 + 1;
+ break;
+ default:
+ /*
+ * If the integration time specified is not from the config,
+ * it will get considered as valid inetgration time in ms
+ */
+ delay_ticks = (tcs34725->cfg.integration_time * OS_TICKS_PER_SEC)/
+ 1000 + 1;
+ break;
+ }
+
+ os_time_delay(delay_ticks);
+
+ *c = *r = *g = *b = 0;
+
+ rc = tcs34725_readlen(TCS34725_REG_CDATAL, payload, 8);
+ if (rc) {
+ goto err;
+ }
+
+ *c = payload[1] << 8 | payload[0];
+ *r = payload[3] << 8 | payload[2];
+ *g = payload[5] << 8 | payload[4];
+ *b = payload[7] << 8 | payload[6];
+
+#if MYNEWT_VAL(TCS34725_STATS)
+ switch (tcs34725->cfg.integration_time) {
+ case TCS34725_INTEGRATIONTIME_2_4MS:
+ STATS_INC(g_tcs34725stats, samples_2_4ms);
+ break;
+ case TCS34725_INTEGRATIONTIME_24MS:
+ STATS_INC(g_tcs34725stats, samples_24ms);
+ break;
+ case TCS34725_INTEGRATIONTIME_50MS:
+ STATS_INC(g_tcs34725stats, samples_50ms);
+ break;
+ case TCS34725_INTEGRATIONTIME_101MS:
+ STATS_INC(g_tcs34725stats, samples_101ms);
+ break;
+ case TCS34725_INTEGRATIONTIME_154MS:
+ STATS_INC(g_tcs34725stats, samples_154ms);
+ break;
+ case TCS34725_INTEGRATIONTIME_700MS:
+ STATS_INC(g_tcs34725stats, samples_700ms);
+ default:
+ STATS_INC(g_tcs34725stats, samples_userdef);
+ break;
+ }
+
+#endif
+
+ return 0;
+err:
+ return rc;
+
+}
+
+/**
+ *
+ * Converts raw RGB values to color temp in deg K
+ *
+ * @param red value
+ * @param green value
+ * @param blue value
+ * @return final CCT value using McCamy's formula
+ */
+static uint16_t
+tcs34725_calculate_color_temp(uint16_t r, uint16_t g, uint16_t b)
+{
+ float n;
+ float cct;
+
+ /**
+ * From the designer's notebook by TAOS:
+ * Mapping sensor response RGB values to CIE tristimulus values(XYZ)
+ * based on broad enough transformation, the light sources chosen were a
+ * high color temperature fluorescent (6500K), a low color temperature
+ * fluorescent (3000K), and an incandescent (60W)
+ * Note: y = Illuminance or lux
+ *
+ * For applications requiring more precision,
+ * narrower range of light sources should be used and a new correlation
+ * matrix could be formulated and CIE tristimulus values should be
+ * calculated. Please refer the manual for calculating tristumulus values.
+ *
+ * x = (-0.14282F * r) + (1.54924F * g) + (-0.95641F * b);
+ * y = (-0.32466F * r) + (1.57837F * g) + (-0.73191F * b);
+ * z = (-0.68202F * r) + (0.77073F * g) + ( 0.56332F * b);
+ *
+ *
+ * Calculating chromaticity co-ordinates, the light can be plotted on a two
+ * dimensional chromaticity diagram
+ *
+ * xc = x / (x + y + z);
+ * yc = y / (x + y + z);
+ *
+ * Use McCamy's formula to determine the CCT
+ * n = (xc - 0.3320F) / (0.1858F - yc);
+ */
+
+ /*
+ * n can be calculated directly using the following formula for
+ * above considerations
+ */
+ n = ((0.23881)*r + (0.25499)*g + (-0.58291)*b) / ((0.11109)*r + (-0.85406)*g +
+ (0.52289)*b);
+
+ /*
+ * Calculate the final CCT
+ * CCT is only meant to characterize near white lights.
+ */
+
+#if MYNEWT_VAL(USE_MATH)
+ cct = (449.0F * powf(n, 3)) + (3525.0F * powf(n, 2)) + (6823.3F * n) + 5520.33F;
+#else
+ cct = (449.0F * n * n * n) + (3525.0F * n * n) + (6823.3F * n) + 5520.33F;
+#endif
+
+ /* Return the results in degrees Kelvin */
+ return (uint16_t)cct;
+}
+
+/**
+ *
+ * Converts the raw RGB values to lux
+ *
+ * @param red value
+ * @param green value
+ * @param blue value
+ * @return lux value
+ */
+static uint16_t
+tcs34725_calculate_lux(uint16_t r, uint16_t g, uint16_t b)
+{
+ float lux;
+
+ lux = (-0.32466F * r) + (1.57837F * g) + (-0.73191F * b);
+
+ return (uint16_t)lux;
+}
+
+
+
+static int
+tcs34725_sensor_read(struct sensor *sensor, sensor_type_t type,
+ sensor_data_func_t data_func, void *data_arg, uint32_t timeout)
+{
+ struct tcs34725 *tcs34725;
+ struct sensor_color_data scd;
+ uint16_t r;
+ uint16_t g;
+ uint16_t b;
+ uint16_t c;
+ int rc;
+
+ /* If the read isn't looking for accel or mag data, don't do anything. */
+ if (!(type & SENSOR_TYPE_COLOR)) {
+ rc = SYS_EINVAL;
+ goto err;
+ }
+
+ tcs34725 = (struct tcs34725 *) SENSOR_GET_DEVICE(sensor);
+
+ /* Get a new accelerometer sample */
+ if (type & SENSOR_TYPE_COLOR) {
+ r = g = b = c = 0;
+
+ rc = tcs34725_get_rawdata(&r, &g, &b, &c, tcs34725);
+ if (rc) {
+ goto err;
+ }
+
+ scd.scd_r = r;
+ scd.scd_g = g;
+ scd.scd_b = b;
+ scd.scd_c = c;
+ scd.scd_lux = tcs34725_calculate_lux(r, g, b);
+ scd.scd_colortemp = tcs34725_calculate_color_temp(r, g, b);
+
+ /* Call data function */
+ rc = data_func(sensor, data_arg, &scd);
+ if (rc != 0) {
+ goto err;
+ }
+ }
+
+ return 0;
+err:
+ return rc;
+}
+
+/**
+ * enables/disables interrupts
+ *
+ * @param enable/disable
+ * @return 0 on success, non-zero on failure
+ */
+int
+tcs34725_enable_interrupt(uint8_t enable)
+{
+ uint8_t reg;
+ int rc;
+
+ rc = tcs34725_read8(TCS34725_REG_ENABLE, ®);
+ if (rc) {
+ goto err;
+ }
+
+ if (enable) {
+ reg |= TCS34725_ENABLE_AIEN;
+ } else {
+ reg &= ~TCS34725_ENABLE_AIEN;
+ }
+
+ rc = tcs34725_write8(TCS34725_REG_ENABLE, reg);
+ if (rc) {
+ goto err;
+ }
+
+ return 0;
+err:
+ return rc;
+}
+
+/**
+ * Clears the interrupt by writing to the command register
+ * as a special function
+ * ______________________________________________________
+ * | CMD | TYPE | ADDR/SF |
+ * | 7 | 6:5 | 4:0 |
+ * | 1 | 11 | 00110 |
+ * |_______|_____________|______________________________|
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+tcs34725_clear_interrupt(void)
+{
+ int rc;
+ uint8_t payload = TCS34725_COMMAND_BIT | TCS34725_CMD_TYPE | TCS34725_CMD_ADDR;
+
+ struct hal_i2c_master_data data_struct = {
+ .address = MYNEWT_VAL(TCS34725_I2CADDR),
+ .len = 0,
+ .buffer = &payload
+ };
+
+ rc = hal_i2c_master_write(MYNEWT_VAL(TCS34725_I2CBUS), &data_struct,
+ OS_TICKS_PER_SEC / 10, 1);
+ if (rc) {
+ goto err;
+ }
+
+ return 0;
+err:
+ return rc;
+}
+
+/**
+ * Sets threshold limits for interrupts, if the low threshold is set above
+ * the high threshold, the high threshold is ignored and only the low
+ * threshold is evaluated
+ *
+ * @param lower threshold
+ * @param higher threshold
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+tcs34725_set_int_limits(uint16_t low, uint16_t high)
+{
+ uint8_t payload[4];
+ int rc;
+
+ payload[0] = low & 0xFF;
+ payload[1] = low >> 8;
+ payload[2] = high & 0xFF;
+ payload[3] = high >> 8;
+
+ rc = tcs34725_writelen(TCS34725_REG_AILTL, payload, sizeof(payload));
+ if (rc) {
+ return rc;
+ }
+ return 0;
+}
+
+static void *
+tcs34725_sensor_get_interface(struct sensor *sensor, sensor_type_t type)
+{
+ return (NULL);
+}
+
+/**
+ *
+ * Gets threshold limits for interrupts, if the low threshold is set above
+ * the high threshold, the high threshold is ignored and only the low
+ * threshold is evaluated
+ *
+ * @param ptr to lower threshold
+ * @param ptr to higher threshold
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+tcs34725_get_int_limits(uint16_t *low, uint16_t *high)
+{
+ uint8_t payload[4];
+ int rc;
+
+ rc = tcs34725_readlen(TCS34725_REG_AILTL, payload, sizeof(payload));
+ if (rc) {
+ return rc;
+ }
+
+ *low = payload[0];
+ *low |= payload[1] << 8;
+ *high = payload[2];
+ *high |= payload[3] << 8;
+
+ return 0;
+}
+
+static int
+tcs34725_sensor_get_config(struct sensor *sensor, sensor_type_t type,
+ struct sensor_cfg *cfg)
+{
+ int rc;
+
+ if ((type != SENSOR_TYPE_COLOR)) {
+ rc = SYS_EINVAL;
+ goto err;
+ }
+
+ cfg->sc_valtype = SENSOR_VALUE_TYPE_INT32;
+
+ return (0);
+err:
+ return (rc);
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2d4f8a76/hw/drivers/sensors/tcs34725/src/tcs34725_priv.h
----------------------------------------------------------------------
diff --git a/hw/drivers/sensors/tcs34725/src/tcs34725_priv.h b/hw/drivers/sensors/tcs34725/src/tcs34725_priv.h
new file mode 100644
index 0000000..4c47929
--- /dev/null
+++ b/hw/drivers/sensors/tcs34725/src/tcs34725_priv.h
@@ -0,0 +1,278 @@
+/*
+ * 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
+ * resarding 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 __TCS34725_PRIV_H__
+#define __TCS34725_PRIV_H__
+
+#define TCS34725_ID 0x44
+
+/* COMMAND Register - Specific register address */
+#define TCS34725_COMMAND_BIT (1 << 7)
+#define TCS34725_CMD_TYPE (3 << 5)
+#define TCS34725_CMD_ADDR (6 << 1)
+
+/* Enable register */
+#define TCS34725_REG_ENABLE 0x00
+#define TCS34725_ENABLE_AIEN 0x10 /* enable/disable RGBC interrupt */
+#define TCS34725_ENABLE_WEN 0x08 /* enable/disable wait timer */
+#define TCS34725_ENABLE_AEN 0x02 /* enable/disable ADC */
+#define TCS34725_ENABLE_PON 0x01 /* enable/disable int oscillator */
+
+/* Integration time */
+#define TCS34725_REG_ATIME 0x01
+
+/* Wait time register (if TCS34725_ENABLE_WEN is asserted) */
+#define TCS34725_REG_WTIME 0x03
+#define TCS34725_WTIME_2_4MS 0xFF /* WLONG0 = 2.4ms WLONG1 = 0.029s */
+#define TCS34725_WTIME_204MS 0xAB /* WLONG0 = 204ms WLONG1 = 2.45s */
+#define TCS34725_WTIME_614MS 0x00 /* WLONG0 = 614ms WLONG1 = 7.4s */
+
+/* Clear channel lower interrupt threshold register */
+#define TCS34725_REG_AILTL 0x04
+#define TCS34725_REG_AILTH 0x05
+
+/* Clear channel upper interrupt threshold register */
+#define TCS34725_REG_AIHTL 0x06
+#define TCS34725_REG_AIHTH 0x07
+
+/* Persistence register */
+#define TCS34725_REG_PERS 0x0C
+#define TCS34725_PERS_NONE 0x00 /* interrupt for each RGBC cycle */
+#define TCS34725_PERS_1_CYCLE 0x01 /* interrupt for 1 RGBC cycle */
+#define TCS34725_PERS_2_CYCLE 0x02 /* interrupt for 2 RGBC cycle */
+#define TCS34725_PERS_3_CYCLE 0x03 /* interrupt for 3 RGBC cycle */
+#define TCS34725_PERS_5_CYCLE 0x04 /* interrupt for 5 RGBC cycle */
+#define TCS34725_PERS_10_CYCLE 0x05 /* interrupt for 10 RGBC cycle */
+#define TCS34725_PERS_15_CYCLE 0x06 /* interrupt for 15 RGBC cycle */
+#define TCS34725_PERS_20_CYCLE 0x07 /* interrupt for 20 RGBC cycle */
+#define TCS34725_PERS_25_CYCLE 0x08 /* interrupt for 25 RGBC cycle */
+#define TCS34725_PERS_30_CYCLE 0x09 /* interrupt for 30 RGBC cycle */
+#define TCS34725_PERS_35_CYCLE 0x0A /* interrupt for 35 RGBC cycle */
+#define TCS34725_PERS_40_CYCLE 0x0B /* interrupt for 40 RGBC cycle */
+#define TCS34725_PERS_45_CYCLE 0x0C /* interrupt for 45 RGBC cycle */
+#define TCS34725_PERS_50_CYCLE 0x0D /* interrupt for 50 RGBC cycle */
+#define TCS34725_PERS_55_CYCLE 0x0E /* interrupt for 55 RGBC cycle */
+#define TCS34725_PERS_60_CYCLE 0x0F /* interrupt for 60 RGBC cycle */
+
+/* Configuration register */
+#define TCS34725_REG_CONFIG 0x0D
+#define TCS34725_CONFIG_WLONG 0x02 /* 0x or 12x TCS34725_WTIME */
+
+/* Set the gain level for the sensor */
+#define TCS34725_REG_CONTROL 0x0F
+
+/* Should be 0x44 for TCS34725 */
+#define TCS34725_REG_ID 0x12
+
+/* Device status register */
+#define TCS34725_REG_STATUS 0x13
+#define TCS34725_STATUS_AINT 0x10 /* RGBC Clean channel interrupt */
+#define TCS34725_STATUS_AVALID 0x01 /* RGBC completed an integ cycle */
+
+/* Clear channel data */
+#define TCS34725_REG_CDATAL 0x14
+#define TCS34725_REG_CDATAH 0x15
+
+/* Red channel data */
+#define TCS34725_REG_RDATAL 0x16
+#define TCS34725_REG_RDATAH 0x17
+
+/* Green channel data */
+#define TCS34725_REG_GDATAL 0x18
+#define TCS34725_REG_GDATAH 0x19
+
+/* Blue channel data */
+#define TCS34725_REG_BDATAL 0x1A
+#define TCS34725_REG_BDATAH 0x1B
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Writes a single byte to the specified register
+ *
+ * @param The register address to write to
+ * @param The value to write
+ *
+ * @return 0 on success, non-zero error on failure.
+ */
+
+int tcs34725_write8(uint8_t reg, uint32_t value);
+
+/**
+ * Writes multiple bytes to the specified register
+ *
+ * @param The register address to write to
+ * @param The data buffer to write from
+ *
+ * @return 0 on success, non-zero error on failure.
+ */
+int
+tcs34725_writelen(uint8_t reg, uint8_t *buffer, uint8_t len);
+
+
+/**
+ * Reads a single byte from the specified register
+ *
+ * @param The register address to read from
+ * @param Pointer to where the register value should be written
+ *
+ * @return 0 on success, non-zero error on failure.
+ */
+int
+tcs34725_read8(uint8_t reg, uint8_t *value);
+
+/**
+ * Read data from the sensor of variable length (MAX: 8 bytes)
+ *
+ *
+ * @param Register to read from
+ * @param Bufer to read into
+ * @param Length of the buffer
+ *
+ * @return 0 on success and non-zero on failure
+ */
+int
+tcs34725_readlen(uint8_t reg, uint8_t *buffer, uint8_t len);
+
+/**
+ * Get chip ID from the sensor
+ *
+ * @param Pointer to the variable to fill up chip ID in
+ * @return 0 on success, non-zero on failure
+ */
+int
+tcs34725_get_chip_id(uint8_t *id);
+
+/**
+ * Get gain of the sensor
+ *
+ * @return gain
+ */
+uint8_t
+tcs34725_get_gain(void);
+
+/**
+ * Set gain of the sensor
+ *
+ * @param gain
+ * @return 0 on success, non-zero on failure
+ */
+int
+tcs34725_set_gain(uint8_t gain);
+
+/**
+ * enables/disables interrupts
+ *
+ * @param enable/disable
+ * @return 0 on success, non-zero on failure
+ */
+int
+tcs34725_enable_interrupt(uint8_t enable);
+
+/**
+ * Clears the interrupts
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+tcs34725_clear_interrupt(void);
+
+/**
+ * Sets threshold limits for interrupts, if the low threshold is set above
+ * the high threshold, the high threshold is ignored and only the low
+ * threshold is evaluated
+ *
+ * @param lower threshold
+ * @param higher threshold
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+tcs34725_set_int_limits(uint16_t low, uint16_t high);
+
+/**
+ * Sets integration time
+ *
+ * @param integration time to be set
+ * @return 0 on success, non-zero on failure
+ */
+int
+tcs34725_set_integration_time(uint8_t int_time);
+
+/**
+ * Gets integration time set earlier
+ *
+ * @return integration time
+ */
+uint8_t
+tcs34725_get_integration_time(void);
+
+/**
+ *
+ * Enables the device
+ *
+ * @param enable/disable
+ * @return 0 on success, non-zero on error
+ */
+int
+tcs34725_enable(uint8_t enable);
+
+/**
+ * Indicates whether the sensor is enabled or not
+ *
+ * @return 1 if enabled, 0 if disabled
+ */
+uint8_t
+tcs34725_get_enable (void);
+
+/**
+ * Reads the raw red, green, blue and clear channel values
+ *
+ *
+ * @param red value to return
+ * @param green value to return
+ * @param blue value to return
+ * @param clear channel value
+ * @param driver sturcture containing config
+ */
+int
+tcs34725_get_rawdata(uint16_t *r, uint16_t *g, uint16_t *b, uint16_t *c,
+ struct tcs34725 *tcs34725);
+
+/**
+ *
+ * Gets threshold limits for interrupts, if the low threshold is set above
+ * the high threshold, the high threshold is ignored and only the low
+ * threshold is evaluated
+ *
+ * @param ptr to lower threshold
+ * @param ptr to higher threshold
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+tcs34725_get_int_limits(uint16_t *low, uint16_t *high);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TCS34725_PRIV_H_ */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2d4f8a76/hw/drivers/sensors/tcs34725/src/tcs34725_shell.c
----------------------------------------------------------------------
diff --git a/hw/drivers/sensors/tcs34725/src/tcs34725_shell.c b/hw/drivers/sensors/tcs34725/src/tcs34725_shell.c
new file mode 100644
index 0000000..e15b4fc
--- /dev/null
+++ b/hw/drivers/sensors/tcs34725/src/tcs34725_shell.c
@@ -0,0 +1,471 @@
+/*
+ * 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
+ * resarding 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.
+ */
+
+#include <string.h>
+#include "sysinit/sysinit.h"
+#include "console/console.h"
+#include "shell/shell.h"
+#include "hal/hal_gpio.h"
+#include "tcs34725/tcs34725.h"
+#include "tcs34725_priv.h"
+#include "defs/error.h"
+
+#if MYNEWT_VAL(TCS34725_CLI)
+extern uint8_t g_tcs34725_integration_time;
+extern uint8_t g_tcs34725_gain;
+
+static int tcs34725_shell_cmd(int argc, char **argv);
+
+static struct shell_cmd tcs34725_shell_cmd_struct = {
+ .sc_cmd = "tcs34725",
+ .sc_cmd_func = tcs34725_shell_cmd
+};
+
+static int
+tcs34725_shell_stol(char *param_val, long min, long max, long *output)
+{
+ char *endptr;
+ long lval;
+
+ lval = strtol(param_val, &endptr, 10); /* Base 10 */
+ if (param_val != '\0' && *endptr == '\0' &&
+ lval >= min && lval <= max) {
+ *output = lval;
+ } else {
+ return SYS_EINVAL;
+ }
+
+ return 0;
+}
+
+static int
+tcs34725_shell_err_too_many_args(char *cmd_name)
+{
+ console_printf("Error: too many arguments for command \"%s\"\n",
+ cmd_name);
+ return SYS_EINVAL;
+}
+
+static int
+tcs34725_shell_err_unknown_arg(char *cmd_name)
+{
+ console_printf("Error: unknown argument \"%s\"\n",
+ cmd_name);
+ return SYS_EINVAL;
+}
+
+static int
+tcs34725_shell_err_invalid_arg(char *cmd_name)
+{
+ console_printf("Error: invalid argument \"%s\"\n",
+ cmd_name);
+ return SYS_EINVAL;
+}
+
+static int
+tcs34725_shell_help(void)
+{
+ console_printf("%s cmd [flags...]\n", tcs34725_shell_cmd_struct.sc_cmd);
+ console_printf("cmd:\n");
+ console_printf("\tr [n_samples]\n");
+ console_printf("\tgain [1|16]\n");
+ console_printf("\ttime [13|101|402]\n");
+ console_printf("\ten [0|1]\n");
+ console_printf("\tint pin [p_num(0..255)]\n");
+ console_printf("\tint on|off|clr\n");
+ console_printf("\tint set [rate(0..15)] [lower(0..65535)] [upper(0..65535)]\n");
+ console_printf("\tdump\n");
+
+ return 0;
+}
+
+static int
+tcs34725_shell_cmd_read(int argc, char **argv)
+{
+ uint16_t r;
+ uint16_t g;
+ uint16_t b;
+ uint16_t c;
+ uint16_t samples = 1;
+ long val;
+ int rc;
+ struct tcs34725 tcs34725;
+
+ if (argc > 3) {
+ return tcs34725_shell_err_too_many_args(argv[1]);
+ }
+
+ /* Check if more than one sample requested */
+ if (argc == 3) {
+ if (tcs34725_shell_stol(argv[2], 1, UINT16_MAX, &val)) {
+ return tcs34725_shell_err_invalid_arg(argv[2]);
+ }
+ samples = (uint16_t)val;
+ }
+
+ while(samples--) {
+
+ tcs34725.cfg.gain = g_tcs34725_gain;
+ tcs34725.cfg.integration_time = g_tcs34725_integration_time;
+
+ rc = tcs34725_get_rawdata(&r, &g, &b, &c, &tcs34725);
+ if (rc) {
+ console_printf("Read failed: %d\n", rc);
+ return rc;
+ }
+
+ console_printf("r: %u g: %u b: %u c: %u \n", r, g, b, c);
+ }
+
+ return 0;
+}
+
+
+static int
+tcs34725_shell_cmd_gain(int argc, char **argv)
+{
+ long val;
+ uint8_t gain;
+ int rc;
+
+ if (argc > 3) {
+ return tcs34725_shell_err_too_many_args(argv[1]);
+ }
+
+ /* Display the gain */
+ if (argc == 2) {
+ gain = tcs34725_get_gain();
+ console_printf("\tgain [0: 1|1: 4|2: 16|3: 60]\n");
+ console_printf("%u\n", gain);
+ }
+
+ /* Update the gain */
+ if (argc == 3) {
+ if (tcs34725_shell_stol(argv[2], 0, 3, &val)) {
+ return tcs34725_shell_err_invalid_arg(argv[2]);
+ }
+ /* Make sure gain is valid */
+ if (val > 3) {
+ return tcs34725_shell_err_invalid_arg(argv[2]);
+ }
+ rc = tcs34725_set_gain(val);
+ if (rc) {
+ goto err;
+ }
+ }
+
+ return 0;
+err:
+ return rc;
+}
+
+
+static int
+tcs34725_shell_cmd_time(int argc, char **argv)
+{
+ uint8_t time;
+ long val;
+ int rc;
+
+ if (argc > 3) {
+ return tcs34725_shell_err_too_many_args(argv[1]);
+ }
+
+ /* Display the integration time */
+ if (argc == 2) {
+ time = tcs34725_get_integration_time();
+ switch (time) {
+ case TCS34725_INTEGRATIONTIME_2_4MS:
+ console_printf("2.4\n");
+ break;
+ case TCS34725_INTEGRATIONTIME_24MS:
+ console_printf("24\n");
+ break;
+ case TCS34725_INTEGRATIONTIME_50MS:
+ console_printf("50\n");
+ break;
+ case TCS34725_INTEGRATIONTIME_101MS:
+ console_printf("101\n");
+ break;
+ case TCS34725_INTEGRATIONTIME_154MS:
+ console_printf("154\n");
+ break;
+ case TCS34725_INTEGRATIONTIME_700MS:
+ console_printf("700\n");
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+
+ /* Set the integration time */
+ if (argc == 3) {
+ if (tcs34725_shell_stol(argv[2], 0, 5, &val)) {
+ return tcs34725_shell_err_invalid_arg(argv[2]);
+ }
+
+ switch(val) {
+ case 0:
+ time = TCS34725_INTEGRATIONTIME_2_4MS;
+ break;
+ case 1:
+ time = TCS34725_INTEGRATIONTIME_24MS;
+ break;
+ case 2:
+ time = TCS34725_INTEGRATIONTIME_50MS;
+ break;
+ case 3:
+ time = TCS34725_INTEGRATIONTIME_101MS;
+ break;
+ case 4:
+ time = TCS34725_INTEGRATIONTIME_154MS;
+ break;
+ case 5:
+ time = TCS34725_INTEGRATIONTIME_700MS;
+ break;
+ default:
+ assert(0);
+ }
+
+ rc = tcs34725_set_integration_time(time);
+ if (rc) {
+ goto err;
+ }
+ }
+
+ return 0;
+err:
+ return rc;
+}
+
+
+static int
+tcs34725_shell_cmd_int(int argc, char **argv)
+{
+ int rc;
+ int pin;
+ long val;
+ uint16_t lower;
+ uint16_t upper;
+
+ if (argc > 6) {
+ return tcs34725_shell_err_too_many_args(argv[1]);
+ }
+
+ if (argc == 2) {
+ rc = tcs34725_get_int_limits(&lower, &upper);
+ if (rc) {
+ return rc;
+ }
+ console_printf("Interrupt lower limit: %u upper limit: %u",
+ lower, upper);
+ return 0;
+ }
+
+ /* Enable the interrupt */
+ if (argc == 3 && strcmp(argv[2], "on") == 0) {
+ return tcs34725_enable_interrupt(1);
+ }
+
+ /* Disable the interrupt */
+ if (argc == 3 && strcmp(argv[2], "off") == 0) {
+ return tcs34725_enable_interrupt(0);
+ }
+
+ /* Clear the interrupt on 'clr' */
+ if (argc == 3 && strcmp(argv[2], "clr") == 0) {
+ return tcs34725_clear_interrupt();
+ }
+
+ /* Configure the interrupt on 'set' */
+ if (argc == 3 && strcmp(argv[2], "set") == 0) {
+ /* Get lower threshold */
+ if (tcs34725_shell_stol(argv[4], 0, UINT16_MAX, &val)) {
+ return tcs34725_shell_err_invalid_arg(argv[4]);
+ }
+ lower = (uint16_t)val;
+ /* Get upper threshold */
+ if (tcs34725_shell_stol(argv[5], 0, UINT16_MAX, &val)) {
+ return tcs34725_shell_err_invalid_arg(argv[5]);
+ }
+ upper = (uint16_t)val;
+ /* Set the values */
+ rc = tcs34725_set_int_limits(lower, upper);
+ console_printf("Configured interrupt as:\n");
+ console_printf("\tlower: %u\n", lower);
+ console_printf("\tupper: %u\n", upper);
+ return rc;
+ }
+
+ /* Setup INT pin on 'pin' */
+ if (argc == 4 && strcmp(argv[2], "pin") == 0) {
+ /* Get the pin number */
+ if (tcs34725_shell_stol(argv[3], 0, 0xFF, &val)) {
+ return tcs34725_shell_err_invalid_arg(argv[3]);
+ }
+ pin = (int)val;
+ /* INT is open drain, pullup is required */
+ rc = hal_gpio_init_in(pin, HAL_GPIO_PULL_UP);
+ assert(rc == 0);
+ console_printf("Set pin \"%d\" to INPUT with pull up enabled\n", pin);
+ return 0;
+ }
+
+ /* Unknown command */
+ return tcs34725_shell_err_invalid_arg(argv[2]);
+}
+
+
+static int
+tcs34725_shell_cmd_en(int argc, char **argv)
+{
+ char *endptr;
+ long lval;
+
+ if (argc > 3) {
+ return tcs34725_shell_err_too_many_args(argv[1]);
+ }
+
+ /* Display current enable state */
+ if (argc == 2) {
+ console_printf("%u\n", tcs34725_get_enable());
+ }
+
+ /* Update the enable state */
+ if (argc == 3) {
+ lval = strtol(argv[2], &endptr, 10); /* Base 10 */
+ if (argv[2] != '\0' && *endptr == '\0' &&
+ lval >= 0 && lval <= 1) {
+ tcs34725_enable(lval);
+ } else {
+ return tcs34725_shell_err_invalid_arg(argv[2]);
+ }
+ }
+
+ return 0;
+}
+
+static int
+tcs34725_shell_cmd_dump(int argc, char **argv)
+{
+ uint8_t val;
+
+ if (argc > 3) {
+ return tcs34725_shell_err_too_many_args(argv[1]);
+ }
+
+ /* Dump all the register values for debug purposes */
+ val = 0;
+ assert(0 == tcs34725_read8(TCS34725_REG_ENABLE, &val));
+ console_printf("0x%02X (ENABLE): 0x%02X\n", TCS34725_REG_ENABLE, val);
+ assert(0 == tcs34725_read8(TCS34725_REG_ATIME, &val));
+ console_printf("0x%02X (ATIME): 0x%02X\n", TCS34725_REG_ATIME, val);
+ assert(0 == tcs34725_read8(TCS34725_REG_WTIME, &val));
+ console_printf("0x%02X (WTIME): 0x%02X\n", TCS34725_REG_WTIME, val);
+ assert(0 == tcs34725_read8(TCS34725_REG_AILTL, &val));
+ console_printf("0x%02X (AILTL): 0x%02X\n", TCS34725_REG_AILTL, val);
+ assert(0 == tcs34725_read8(TCS34725_REG_AILTH, &val));
+ console_printf("0x%02X (AILTH): 0x%02X\n", TCS34725_REG_AILTH, val);
+ assert(0 == tcs34725_read8(TCS34725_REG_AIHTL, &val));
+ console_printf("0x%02X (AIHTL): 0x%02X\n", TCS34725_REG_AIHTL, val);
+ assert(0 == tcs34725_read8(TCS34725_REG_AIHTH, &val));
+ console_printf("0x%02X (AIHTH): 0x%02X\n", TCS34725_REG_AIHTH, val);
+ assert(0 == tcs34725_read8(TCS34725_REG_PERS, &val));
+ console_printf("0x%02X (PERS): 0x%02X\n", TCS34725_REG_PERS, val);
+ assert(0 == tcs34725_read8(TCS34725_REG_CONFIG, &val));
+ console_printf("0x%02X (CONFIG): 0x%02X\n", TCS34725_REG_CONFIG, val);
+ assert(0 == tcs34725_read8(TCS34725_REG_CONTROL, &val));
+ console_printf("0x%02X (CONTROL): 0x%02X\n", TCS34725_REG_CONTROL, val);
+ assert(0 == tcs34725_read8(TCS34725_REG_ID, &val));
+ console_printf("0x%02X (ID): 0x%02X\n", TCS34725_REG_ID, val);
+ assert(0 == tcs34725_read8(TCS34725_REG_STATUS, &val));
+ console_printf("0x%02X (STATUS): 0x%02X\n", TCS34725_REG_STATUS, val);
+ assert(0 == tcs34725_read8(TCS34725_REG_CDATAL, &val));
+ console_printf("0x%02X (CDATAL): 0x%02X\n", TCS34725_REG_CDATAL, val);
+ assert(0 == tcs34725_read8(TCS34725_REG_CDATAH, &val));
+ console_printf("0x%02X (CDATAH): 0x%02X\n", TCS34725_REG_CDATAH, val);
+ assert(0 == tcs34725_read8(TCS34725_REG_RDATAL, &val));
+ console_printf("0x%02X (RDATAL): 0x%02X\n", TCS34725_REG_RDATAL, val);
+ assert(0 == tcs34725_read8(TCS34725_REG_RDATAH, &val));
+ console_printf("0x%02X (RDATAH): 0x%02X\n", TCS34725_REG_RDATAH, val);
+ assert(0 == tcs34725_read8(TCS34725_REG_GDATAL, &val));
+ console_printf("0x%02X (GDATAL): 0x%02X\n", TCS34725_REG_GDATAL, val);
+ assert(0 == tcs34725_read8(TCS34725_REG_GDATAH, &val));
+ console_printf("0x%02X (GDATAH): 0x%02X\n", TCS34725_REG_GDATAH, val);
+ assert(0 == tcs34725_read8(TCS34725_REG_BDATAL, &val));
+ console_printf("0x%02X (BDATAL): 0x%02X\n", TCS34725_REG_BDATAL, val);
+ assert(0 == tcs34725_read8(TCS34725_REG_BDATAH, &val));
+ console_printf("0x%02X (BDATAH): 0x%02X\n", TCS34725_REG_BDATAH, val);
+
+ return 0;
+}
+
+static int
+tcs34725_shell_cmd(int argc, char **argv)
+{
+ if (argc == 1) {
+ return tcs34725_shell_help();
+ }
+
+ /* Read command (get a new data sample) */
+ if (argc > 1 && strcmp(argv[1], "r") == 0) {
+ return tcs34725_shell_cmd_read(argc, argv);
+ }
+
+ /* Gain command */
+ if (argc > 1 && strcmp(argv[1], "gain") == 0) {
+ return tcs34725_shell_cmd_gain(argc, argv);
+ }
+
+ /* Integration time command */
+ if (argc > 1 && strcmp(argv[1], "time") == 0) {
+ return tcs34725_shell_cmd_time(argc, argv);
+ }
+
+ /* Enable */
+ if (argc > 1 && strcmp(argv[1], "en") == 0) {
+ return tcs34725_shell_cmd_en(argc, argv);
+ }
+
+ /* Interrupt */
+ if (argc > 1 && strcmp(argv[1], "int") == 0) {
+ return tcs34725_shell_cmd_int(argc, argv);
+ }
+
+ /* Debug */
+ if (argc > 1 && strcmp(argv[1], "dumpreg") == 0) {
+ return tcs34725_shell_cmd_dump(argc, argv);
+ }
+
+ return tcs34725_shell_err_unknown_arg(argv[1]);
+}
+
+int
+tcs34725_shell_init(void)
+{
+ int rc;
+
+ rc = shell_cmd_register(&tcs34725_shell_cmd_struct);
+ SYSINIT_PANIC_ASSERT(rc == 0);
+
+ return rc;
+}
+
+#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2d4f8a76/hw/drivers/sensors/tcs34725/syscfg.yml
----------------------------------------------------------------------
diff --git a/hw/drivers/sensors/tcs34725/syscfg.yml b/hw/drivers/sensors/tcs34725/syscfg.yml
new file mode 100644
index 0000000..4df3b64
--- /dev/null
+++ b/hw/drivers/sensors/tcs34725/syscfg.yml
@@ -0,0 +1,35 @@
+#
+# 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.
+#
+
+syscfg.defs:
+ TCS34725_I2CADDR:
+ description: 'HW I2C address for the TCS34725 (0x29)'
+ value: 0x29
+ TCS34725_I2CBUS:
+ description: 'I2C bus number for the TCS34725'
+ value: -1
+ TCS34725_CLI:
+ description: 'Enable shell support for the TCS34725'
+ value: 0
+ TCS34725_LOG:
+ description: 'Enable TCS34725 logging'
+ value: 0
+ TCS34725_STATS:
+ description: 'Enable TCS34725 statistics'
+ value: 0
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2d4f8a76/hw/sensor/include/sensor/color.h
----------------------------------------------------------------------
diff --git a/hw/sensor/include/sensor/color.h b/hw/sensor/include/sensor/color.h
new file mode 100644
index 0000000..6f219d7
--- /dev/null
+++ b/hw/sensor/include/sensor/color.h
@@ -0,0 +1,51 @@
+/*
+ * 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_COLOR_H__
+#define __SENSOR_COLOR_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 color sensor
+ */
+struct sensor_color_data {
+ uint16_t scd_r; /* Red data */
+ uint16_t scd_g; /* Green data */
+ uint16_t scd_b; /* Blue data */
+ uint16_t scd_c; /* Clear data */
+ uint16_t scd_lux; /* Lux data */
+ uint16_t scd_colortemp; /* Color temp */
+} __attribute__((packed));
+
+/**
+ * Color Sensor data is unused for this field.
+ */
+#define SENSOR_COLOR_DATA_UNUSED (-1)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SENSOR_COLOR_H__ */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2d4f8a76/hw/sensor/include/sensor/sensor.h
----------------------------------------------------------------------
diff --git a/hw/sensor/include/sensor/sensor.h b/hw/sensor/include/sensor/sensor.h
index 813634b..9dc7cc0 100644
--- a/hw/sensor/include/sensor/sensor.h
+++ b/hw/sensor/include/sensor/sensor.h
@@ -72,12 +72,12 @@ typedef enum {
SENSOR_TYPE_GRAVITY = (1 << 27),
/* Euler Orientation Sensor */
SENSOR_TYPE_EULER = (1 << 28),
+ /* Color Sensor */
+ SENSOR_TYPE_COLOR = (1 << 29),
/* User defined sensor type 1 */
- SENSOR_TYPE_USER_DEFINED_1 = (1 << 29),
+ SENSOR_TYPE_USER_DEFINED_1 = (1 << 30),
/* User defined sensor type 2 */
- SENSOR_TYPE_USER_DEFINED_2 = (1 << 30),
- /* User defined sensor type 3 */
- SENSOR_TYPE_USER_DEFINED_3 = (1 << 31),
+ SENSOR_TYPE_USER_DEFINED_2 = (1 << 31),
/* A selector, describes all sensors */
SENSOR_TYPE_ALL = 0xFFFFFFFF
} sensor_type_t;
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2d4f8a76/hw/sensor/src/sensor_shell.c
----------------------------------------------------------------------
diff --git a/hw/sensor/src/sensor_shell.c b/hw/sensor/src/sensor_shell.c
index 291ae04..3d86beb 100644
--- a/hw/sensor/src/sensor_shell.c
+++ b/hw/sensor/src/sensor_shell.c
@@ -36,6 +36,7 @@
#include "sensor/light.h"
#include "sensor/quat.h"
#include "sensor/euler.h"
+#include "sensor/color.h"
#include "console/console.h"
#include "shell/shell.h"
#include "hal/hal_i2c.h"
@@ -107,6 +108,7 @@ sensor_shell_read_listener(struct sensor *sensor, void *arg, void *data)
struct sensor_light_data *sld;
struct sensor_euler_data *sed;
struct sensor_quat_data *sqd;
+ struct sensor_color_data *scd;
int8_t *temperature;
char tmpstr[13];
@@ -196,6 +198,29 @@ sensor_shell_read_listener(struct sensor *sensor, void *arg, void *data)
console_printf("\n");
}
+ if (ctx->type == SENSOR_TYPE_COLOR) {
+ scd = (struct sensor_color_data *) data;
+ if (scd->scd_r != SENSOR_LIGHT_DATA_UNUSED) {
+ console_printf("red = %u, ", scd->scd_r);
+ }
+ if (scd->scd_g != SENSOR_LIGHT_DATA_UNUSED) {
+ console_printf("green = %u, ", scd->scd_g);
+ }
+ if (scd->scd_b != SENSOR_LIGHT_DATA_UNUSED) {
+ console_printf("blue = %u, ", scd->scd_b);
+ }
+ if (scd->scd_c != SENSOR_LIGHT_DATA_UNUSED) {
+ console_printf("clear = %u, ", scd->scd_c);
+ }
+ if (scd->scd_lux != SENSOR_LIGHT_DATA_UNUSED) {
+ console_printf("lux = %u, ", scd->scd_lux);
+ }
+ if (scd->scd_colortemp != SENSOR_LIGHT_DATA_UNUSED) {
+ console_printf("color temperature = %u, ", scd->scd_colortemp);
+ }
+ console_printf("\n");
+ }
+
return (0);
}