You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by we...@apache.org on 2017/03/24 23:15:30 UTC

[08/50] [abbrv] incubator-mynewt-core git commit: SensorAPI TCS34725 Add AMS DN40 calculations

SensorAPI TCS34725 Add AMS DN40 calculations

- Adding DN40 calculation and results to the sensor structure
- Instead of using the UNUSED_DATA constant which is -1 for various
  sensors, using bit fields to see if the data is valid/invalid.
- Adding conditional compilation for DN25 Vs DN40 based calculations
  (For reflective Vs incident light readings, interrupt pin should be
  shorted to the LED pin on the TCS34725 Adafruit breakout board)


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/70592981
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/70592981
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/70592981

Branch: refs/heads/nrf_cputime
Commit: 70592981db0c053a84cb2bed86b5a9325d1eaaee
Parents: 631db77
Author: Vipul Rahane <vi...@apache.org>
Authored: Fri Mar 10 17:45:41 2017 -0800
Committer: Vipul Rahane <vi...@apache.org>
Committed: Fri Mar 10 17:49:52 2017 -0800

----------------------------------------------------------------------
 hw/drivers/sensors/tcs34725/src/tcs34725.c      | 183 +++++++++++++++----
 hw/drivers/sensors/tcs34725/src/tcs34725_priv.h |  15 ++
 hw/sensor/include/sensor/color.h                |  41 +++--
 hw/sensor/src/sensor_shell.c                    |  43 +++--
 4 files changed, 221 insertions(+), 61 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/70592981/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
index cd0f2c2..7a4c07f 100644
--- a/hw/drivers/sensors/tcs34725/src/tcs34725.c
+++ b/hw/drivers/sensors/tcs34725/src/tcs34725.c
@@ -534,6 +534,11 @@ tcs34725_config(struct tcs34725 *tcs34725, struct tcs34725_cfg *cfg)
         goto err;
     }
 
+    rc = tcs34725_enable_interrupt(1);
+    if (rc) {
+        goto err;
+    }
+
     /* Overwrite the configuration data. */
     memcpy(&tcs34725->cfg, cfg, sizeof(*cfg));
 
@@ -638,19 +643,19 @@ err:
 
 /**
  *
- * Converts raw RGB values to color temp in deg K
+ * Converts raw RGB values to color temp in deg K and lux
  *
- * @param red value
- * @param green value
- * @param blue value
- * @return final CCT value using McCamy's formula
+ * @param ptr to sensor color data ptr
+ * @param ptr to sensor
  */
-static uint16_t
-tcs34725_calculate_color_temp(uint16_t r, uint16_t g, uint16_t b)
+static int
+tcs34725_calc_colortemp_lux(struct sensor_color_data *scd, struct tcs34725 *tcs34725)
 {
-    float n;
-    float cct;
+    int rc;
 
+    rc = 0;
+#if MYNEWT_VAL(USE_TCS34725_TAOS_DN25)
+    float n;
     /**
      * From the designer's notebook by TAOS:
      * Mapping sensor response  RGB values to CIE tristimulus values(XYZ)
@@ -679,12 +684,13 @@ tcs34725_calculate_color_temp(uint16_t r, uint16_t g, uint16_t b)
      * 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);
+    /*
+     * n can be calculated directly using the following formula for
+     * above considerations
+     */
+    n = ((0.23881)*scd->scd_r + (0.25499)*scd->scd_g + (-0.58291)*scd->scd_b) /
+         ((0.11109)*scd->scd_r + (-0.85406)*scd->scd_g + (0.52289)*scd->scd_b);
+
 
     /*
      * Calculate the final CCT
@@ -692,35 +698,134 @@ tcs34725_calculate_color_temp(uint16_t r, uint16_t g, uint16_t b)
      */
 
 #if MYNEWT_VAL(USE_MATH)
-    cct = (449.0F * powf(n, 3)) + (3525.0F * powf(n, 2)) + (6823.3F * n) + 5520.33F;
+    scd->scd_colortemp = (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;
+    scd->scd_colortemp = (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;
-}
+    scd->scd_lux = (-0.32466F * scd->scd_r) + (1.57837F * scd->scd_g) + (-0.73191F * scd->scd_b);
 
-/**
- *
- * 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;
+    scd->scd_r_is_valid = 1;
+    scd->scd_g_is_valid = 1;
+    scd->scd_b_is_valid = 1;
+    scd->scd_c_is_valid = 1;
+    scd->scd_colortemp_is_valid = 1;
+    scd->scd_lux_is_valid = 1;
 
-    lux = (-0.32466F * r) + (1.57837F * g) + (-0.73191F * b);
+    goto err;
+#else
+    uint8_t againx;
+    uint8_t atime;
+    uint16_t atime_ms;
+    uint16_t r_comp;
+    uint16_t g_comp;
+    uint16_t b_comp;
+    float cpl;
+    uint8_t agc_cur;
+
+    const struct tcs_agc agc_list[4] = {
+        { TCS34725_GAIN_60X, TCS34725_INTEGRATIONTIME_700MS,     0, 47566 },
+        { TCS34725_GAIN_16X, TCS34725_INTEGRATIONTIME_154MS,  3171, 63422 },
+        { TCS34725_GAIN_4X,  TCS34725_INTEGRATIONTIME_154MS, 15855, 63422 },
+        { TCS34725_GAIN_1X,  TCS34725_INTEGRATIONTIME_2_4MS,   248,     0 }
+    };
 
-    return (uint16_t)lux;
-}
+    agc_cur = 0;
+    while(1) {
+        if (agc_list[agc_cur].max_cnt && scd->scd_c > agc_list[agc_cur].max_cnt) {
+            agc_cur++;
+        } else if (agc_list[agc_cur].min_cnt &&
+                   scd->scd_c < agc_list[agc_cur].min_cnt) {
+            agc_cur--;
+            break;
+        } else {
+            break;
+        }
+
+        rc = tcs34725_set_gain(agc_list[agc_cur].ta_gain);
+        if (rc) {
+            goto err;
+        }
 
+        rc = tcs34725_set_integration_time(agc_list[agc_cur].ta_time);
+        if (rc) {
+            goto err;
+        }
 
+        /* Shock absorber */
+        os_time_delay((256 - (uint16_t)agc_list[agc_cur].ta_time) * 2.4 * 2 * OS_TICKS_PER_SEC);
+
+        rc = tcs34725_get_rawdata(&scd->scd_r, &scd->scd_g, &scd->scd_b, &scd->scd_c, tcs34725);
+        if (rc) {
+            goto err;
+        }
+        break;
+    }
+
+    atime = (uint16_t)agc_list[agc_cur].ta_time;
+
+    /* Formula from the datasheet */
+    atime_ms = ((256 - atime) * 2.4);
+
+    switch(agc_list[agc_cur].ta_time) {
+        case TCS34725_GAIN_1X:
+            againx = 1;
+            break;
+        case TCS34725_GAIN_4X:
+            againx = 4;
+            break;
+        case TCS34725_GAIN_16X:
+            againx = 16;
+            break;
+        case TCS34725_GAIN_60X:
+            againx = 60;
+            break;
+        default:
+            rc = SYS_EINVAL;
+            goto err;
+    }
+
+    scd->scd_ir = (scd->scd_r + scd->scd_g + scd->scd_b > scd->scd_c) ?
+                  (scd->scd_r + scd->scd_g + scd->scd_b - scd->scd_c) / 2 : 0;
+
+    r_comp = scd->scd_r - scd->scd_ir;
+    g_comp = scd->scd_g - scd->scd_ir;
+    b_comp = scd->scd_b - scd->scd_ir;
+
+    scd->scd_cratio = (float)scd->scd_ir / (float)scd->scd_c;
+
+    scd->scd_saturation = ((256 - atime) > 63) ? 65535 : 1024 * (256 - atime);
+
+    scd->scd_saturation75 = (atime_ms < 150) ? (scd->scd_saturation - scd->scd_saturation / 4) : scd->scd_saturation;
+
+    scd->scd_is_sat = (atime_ms < 150 && scd->scd_c > scd->scd_saturation75) ? 1 : 0;
+
+    cpl = (atime_ms * againx) / (TCS34725_GA * TCS34725_DF);
+
+    scd->scd_maxlux = 65535 / (cpl * 3);
+
+    scd->scd_lux = (TCS34725_R_COEF * (float)r_comp + TCS34725_G_COEF * (float)g_comp +
+           TCS34725_B_COEF * (float)b_comp) / cpl;
+
+    scd->scd_colortemp = TCS34725_CT_COEF * (float)b_comp / (float)r_comp + TCS34725_CT_OFFSET;
+
+    scd->scd_r_is_valid = 1;
+    scd->scd_g_is_valid = 1;
+    scd->scd_b_is_valid = 1;
+    scd->scd_c_is_valid = 1;
+    scd->scd_lux_is_valid = 1;
+    scd->scd_colortemp_is_valid = 1;
+    scd->scd_saturation_is_valid = 1;
+    scd->scd_saturation75_is_valid = 1;
+    scd->scd_is_sat_is_valid = 1;
+    scd->scd_cratio_is_valid = 1;
+    scd->scd_maxlux_is_valid = 1;
+    scd->scd_ir_is_valid = 1;
+#endif
+
+err:
+    return rc;
+}
 
 static int
 tcs34725_sensor_read(struct sensor *sensor, sensor_type_t type,
@@ -755,8 +860,10 @@ tcs34725_sensor_read(struct sensor *sensor, sensor_type_t type,
         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);
+        rc = tcs34725_calc_colortemp_lux(&scd, tcs34725);
+        if (rc) {
+            goto err;
+        }
 
         /* Call data function */
         rc = data_func(sensor, data_arg, &scd);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/70592981/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
index 4c47929..5d5448c 100644
--- a/hw/drivers/sensors/tcs34725/src/tcs34725_priv.h
+++ b/hw/drivers/sensors/tcs34725/src/tcs34725_priv.h
@@ -101,10 +101,25 @@
 #define TCS34725_REG_BDATAL       0x1A
 #define TCS34725_REG_BDATAH       0x1B
 
+#define TCS34725_R_COEF         0.136F
+#define TCS34725_G_COEF         1.000F
+#define TCS34725_B_COEF        -0.444F
+#define TCS34725_GA               1.0F
+#define TCS34725_DF             310.0F
+#define TCS34725_CT_COEF       3810.0F
+#define TCS34725_CT_OFFSET     1391.0F
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+struct tcs_agc {
+    uint8_t ta_gain;
+    uint8_t ta_time;
+    uint16_t min_cnt;
+    uint16_t max_cnt;
+};
+
 /**
  * Writes a single byte to the specified register
  *

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/70592981/hw/sensor/include/sensor/color.h
----------------------------------------------------------------------
diff --git a/hw/sensor/include/sensor/color.h b/hw/sensor/include/sensor/color.h
index 6f219d7..46f3436 100644
--- a/hw/sensor/include/sensor/color.h
+++ b/hw/sensor/include/sensor/color.h
@@ -31,18 +31,37 @@ extern "C" {
 /* 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));
+    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 */
+    /*
+     * The following is only used in AMS DN40
+     * calculation for lux
+     */
+    uint16_t scd_saturation;   /* Saturation        */
+    uint16_t scd_saturation75; /* Saturation75      */
+    uint8_t scd_is_sat;        /* Sensor saturrated */
+    float scd_cratio;          /* C Ratio           */
+    uint16_t scd_maxlux;       /* Max Lux value     */
+    uint16_t scd_ir;           /* Infrared value    */
 
-/**
- * Color Sensor data is unused for this field.
- */
-#define SENSOR_COLOR_DATA_UNUSED (-1)
+    /* Validity */
+    uint16_t scd_r_is_valid:1;
+    uint16_t scd_g_is_valid:1;
+    uint16_t scd_b_is_valid:1;
+    uint16_t scd_c_is_valid:1;
+    uint16_t scd_lux_is_valid:1;
+    uint16_t scd_colortemp_is_valid:1;
+    uint16_t scd_saturation_is_valid:1;
+    uint16_t scd_saturation75_is_valid:1;
+    uint16_t scd_is_sat_is_valid:1;
+    uint16_t scd_cratio_is_valid:1;
+    uint16_t scd_maxlux_is_valid:1;
+    uint16_t scd_ir_is_valid:1;
+} __attribute__((packed));
 
 #ifdef __cplusplus
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/70592981/hw/sensor/src/sensor_shell.c
----------------------------------------------------------------------
diff --git a/hw/sensor/src/sensor_shell.c b/hw/sensor/src/sensor_shell.c
index 3d86beb..fbddd96 100644
--- a/hw/sensor/src/sensor_shell.c
+++ b/hw/sensor/src/sensor_shell.c
@@ -200,25 +200,44 @@ sensor_shell_read_listener(struct sensor *sensor, void *arg, void *data)
 
     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_r_is_valid) {
+            console_printf("r = %u, ", scd->scd_r);
         }
-        if (scd->scd_g != SENSOR_LIGHT_DATA_UNUSED) {
-            console_printf("green = %u, ", scd->scd_g);
+        if (scd->scd_g_is_valid) {
+            console_printf("g = %u, ", scd->scd_g);
         }
-        if (scd->scd_b != SENSOR_LIGHT_DATA_UNUSED) {
-            console_printf("blue = %u, ", scd->scd_b);
+        if (scd->scd_b_is_valid) {
+            console_printf("b = %u, ", scd->scd_b);
         }
-        if (scd->scd_c != SENSOR_LIGHT_DATA_UNUSED) {
-            console_printf("clear = %u, ", scd->scd_c);
+        if (scd->scd_c_is_valid) {
+            console_printf("c = %u, ", scd->scd_c);
         }
-        if (scd->scd_lux != SENSOR_LIGHT_DATA_UNUSED) {
+        if (scd->scd_lux_is_valid) {
             console_printf("lux = %u, ", scd->scd_lux);
         }
-        if (scd->scd_colortemp != SENSOR_LIGHT_DATA_UNUSED) {
-            console_printf("color temperature = %u, ", scd->scd_colortemp);
+        if (scd->scd_colortemp_is_valid) {
+            console_printf("cct = %uK, ", scd->scd_colortemp);
         }
-        console_printf("\n");
+        if (scd->scd_ir_is_valid) {
+            console_printf("ir = %u, \n", scd->scd_ir);
+        }
+        if (scd->scd_saturation_is_valid) {
+            console_printf("sat = %u, ", scd->scd_saturation);
+        }
+        if (scd->scd_saturation_is_valid) {
+            console_printf("sat75 = %u, ", scd->scd_saturation75);
+        }
+        if (scd->scd_is_sat_is_valid) {
+            console_printf(scd->scd_is_sat ? "is saturated, " : "not saturated, ");
+        }
+        if (scd->scd_cratio_is_valid) {
+            console_printf("cRatio = %s, ", sensor_ftostr(scd->scd_cratio, tmpstr, 13));
+        }
+        if (scd->scd_maxlux_is_valid) {
+            console_printf("max lux = %u, ", scd->scd_maxlux);
+        }
+
+        console_printf("\n\n");
     }
 
     return (0);