summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Vaccaro <nvaccaro@google.com>2019-06-25 17:38:37 -0700
committerCommit Bot <commit-bot@chromium.org>2019-08-20 16:31:49 +0000
commit8aaeb9fd05ab185a7807f3650e491d2c3042637a (patch)
tree1ea559dd616d2f4e389ede9d33890540393ccb49
parent8b07b326496025530911f63b220fa987f1950f06 (diff)
downloadchrome-ec-8aaeb9fd05ab185a7807f3650e491d2c3042637a.tar.gz
driver/tcs3400: improve efficiency of auto-adjust
Adds an array which holds the number of atime increments needed at various lux levels and again settings to change delta from saturation by 1%. Using this table, the anti-saturation algorithm can get to the 90% band in most cases in a single adjustment vs the 10 to 15 adjustments previously needed when not using this table. Enabling CONFIG_TCS_USE_LUX_TABLES takes up 280 bytes in the ec.obj. BUG=b:124512628 BRANCH=master TEST=Flash and boot flapjack, verify that ALS and RGB sensors are still generating data. I used alslog patch and enabled ALS logging in EC console via "alslog 2047". Verify that under a constant light source, the adjustment mechanism correctly drives the ALS values such that they land in the sweet spot between 90 to <100% of saturation. Change-Id: I7cd0b8242e72233f50ff2751834f7bba367c6706 Signed-off-by: Nick Vaccaro <nvaccaro@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1677764 Reviewed-by: Gwendal Grignou <gwendal@chromium.org>
-rw-r--r--driver/als_tcs3400.c76
-rw-r--r--driver/als_tcs3400.h5
-rw-r--r--include/config.h9
3 files changed, 74 insertions, 16 deletions
diff --git a/driver/als_tcs3400.c b/driver/als_tcs3400.c
index 5744767780..6b58735ad2 100644
--- a/driver/als_tcs3400.c
+++ b/driver/als_tcs3400.c
@@ -21,6 +21,51 @@
static volatile uint32_t last_interrupt_timestamp;
#endif
+#ifdef CONFIG_TCS_USE_LUX_TABLE
+/*
+ * Stores the number of atime increments/decrements needed to change light value
+ * by 1% of saturation for each gain setting for each predefined LUX range.
+ *
+ * Values in array are TCS_ATIME_GAIN_FACTOR (100x) times actual value to allow
+ * for fractions using integers.
+ */
+static const uint16_t
+range_atime[TCS_MAX_AGAIN - TCS_MIN_AGAIN + 1][TCS_MAX_ATIME_RANGES] = {
+{11200, 5600, 5600, 7200, 5500, 4500, 3800, 3800, 3300, 2900, 2575, 2275, 2075},
+{11200, 5100, 2700, 1840, 1400, 1133, 981, 963, 833, 728, 650, 577, 525},
+{250, 1225, 643, 441, 337, 276, 237, 235, 203, 176, 150, 0, 0},
+{790, 311, 163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
+
+static void
+decrement_atime(struct tcs_saturation_t *sat_p, uint16_t cur_lux, int percent)
+{
+ int atime;
+ uint16_t steps;
+ int lux = MIN(cur_lux, TCS_GAIN_TABLE_MAX_LUX);
+
+ steps = percent * range_atime[sat_p->again][lux / 1000] /
+ TCS_ATIME_GAIN_FACTOR;
+ atime = MAX(sat_p->atime - steps, TCS_MIN_ATIME);
+ sat_p->atime = MIN(atime, TCS_MAX_ATIME);
+}
+
+#else
+
+static void
+decrement_atime(struct tcs_saturation_t *sat_p,
+ uint16_t __attribute__((unused)) cur_lux,
+ int __attribute__((unused)) percent)
+{
+ sat_p->atime = MAX(sat_p->atime - TCS_ATIME_DEC_STEP, TCS_MIN_ATIME);
+}
+
+#endif /* CONFIG_TCS_USE_LUX_TABLE */
+
+static void increment_atime(struct tcs_saturation_t *sat_p)
+{
+ sat_p->atime = MIN(sat_p->atime + TCS_ATIME_INC_STEP, TCS_MAX_ATIME);
+}
+
static inline int tcs3400_i2c_read8(const struct motion_sensor_t *s,
int reg, int *data)
{
@@ -96,16 +141,6 @@ static int tcs3400_rgb_read(const struct motion_sensor_t *s, intv3_t v)
return EC_SUCCESS;
}
-static void decrement_atime(struct tcs_saturation_t *sat_p)
-{
- sat_p->atime = MAX(sat_p->atime - TCS_ATIME_DEC_STEP, TCS_MIN_ATIME);
-}
-
-static void increment_atime(struct tcs_saturation_t *sat_p)
-{
- sat_p->atime = MIN(sat_p->atime + TCS_ATIME_INC_STEP, TCS_MAX_ATIME);
-}
-
/*
* tcs3400_adjust_sensor_for_saturation() tries to keep CRGB values as
* close to saturation as possible without saturating by implementing
@@ -121,6 +156,7 @@ static void increment_atime(struct tcs_saturation_t *sat_p)
*/
static int
tcs3400_adjust_sensor_for_saturation(struct motion_sensor_t *s,
+ uint16_t cur_lux,
uint16_t *crgb_data)
{
struct tcs_saturation_t *sat_p =
@@ -130,6 +166,7 @@ tcs3400_adjust_sensor_for_saturation(struct motion_sensor_t *s,
uint16_t max_val = 0;
int ret;
int status = 0;
+ int percent_left = 0;
/* Adjust for saturation if needed */
ret = tcs3400_i2c_read8(s, TCS_I2C_STATUS, &status);
@@ -153,19 +190,25 @@ tcs3400_adjust_sensor_for_saturation(struct motion_sensor_t *s,
increment_atime(sat_p);
} else if (max_val < TSC_SATURATION_LOW_BAND_LEVEL) {
/* value < 90% saturation, try to increase sensitivity */
- /* increase AGAIN if we can without saturating */
if (max_val <= TCS_GAIN_SAT_LEVEL) {
- if (sat_p->again < TCS_MAX_AGAIN)
+ if (sat_p->again < TCS_MAX_AGAIN) {
sat_p->again++;
- else if (sat_p->atime > TCS_MIN_ATIME)
+ } else if (sat_p->atime > TCS_MIN_ATIME) {
/*
* increase accumulation time by decrementing
* ATIME register
*/
- decrement_atime(sat_p);
+ percent_left = TSC_SATURATION_LOW_BAND_PERCENT -
+ (max_val * 100 / TCS_SATURATION_LEVEL);
+ decrement_atime(sat_p, cur_lux, percent_left);
+ }
} else if (sat_p->atime > TCS_MIN_ATIME) {
+ /* calculate percentage between current and desired */
+ percent_left = TSC_SATURATION_LOW_BAND_PERCENT -
+ (max_val * 100 / TCS_SATURATION_LEVEL);
+
/* increase accumulation time by decrementing ATIME */
- decrement_atime(sat_p);
+ decrement_atime(sat_p, cur_lux, percent_left);
} else if (sat_p->again < TCS_MAX_AGAIN) {
/*
* Although we're not at maximum gain yet, we
@@ -424,7 +467,8 @@ static int tcs3400_post_events(struct motion_sensor_t *s, uint32_t last_ts)
#endif
if (!calibration_mode)
- ret = tcs3400_adjust_sensor_for_saturation(s, raw_data);
+ ret = tcs3400_adjust_sensor_for_saturation(s, xyz_data[Y],
+ raw_data);
return ret;
}
diff --git a/driver/als_tcs3400.h b/driver/als_tcs3400.h
index eace416c94..9681a39a56 100644
--- a/driver/als_tcs3400.h
+++ b/driver/als_tcs3400.h
@@ -97,6 +97,11 @@ enum tcs3400_mode {
#define TCS_CALIBRATION_ATIME TCS_MIN_ATIME
#define TCS_GAIN_UPSHIFT_ATIME TCS_MAX_ATIME
+/* Number of different ranges supported for atime adjustment support */
+#define TCS_MAX_ATIME_RANGES 13
+#define TCS_GAIN_TABLE_MAX_LUX 12999
+#define TCS_ATIME_GAIN_FACTOR 100 /* table values are 100x actual value */
+
#define TCS_MIN_AGAIN 0x00 /* 1x gain */
#define TCS_MAX_AGAIN 0x03 /* 64x gain */
#define TCS_CALIBRATION_AGAIN 0x02 /* 16x gain */
diff --git a/include/config.h b/include/config.h
index 3b23804552..377f89d603 100644
--- a/include/config.h
+++ b/include/config.h
@@ -270,6 +270,15 @@
#undef CONFIG_ALS_TCS3400
/*
+ * Define to use atime tables in anti-saturation algos in the tcs3400 driver.
+ * Defining this for a board makes the anti-saturation algorithm much more
+ * efficient, but requires the board to have it's lens cover scale and k_channel
+ * scales to be determined. Define this for a board once it's added its
+ * cover_scale and k_channel scale factors.
+ */
+#undef CONFIG_TCS_USE_LUX_TABLE
+
+/*
* Define the event to raise when a sensor interrupt triggers.
* Must be within TASK_EVENT_MOTION_INTERRUPT_MASK.
*/