diff options
author | Nick Vaccaro <nvaccaro@google.com> | 2019-05-07 15:23:03 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-08-20 16:31:46 +0000 |
commit | 72c142d8a751089baac1f042d6a199e49daa32d0 (patch) | |
tree | e5ebf12bb8e3edb4e1b3ecb8352888028e8d9ca8 /driver/als_tcs3400.h | |
parent | 6d8a5d3f207af7481e2aa114d306f8448d21b74f (diff) | |
download | chrome-ec-72c142d8a751089baac1f042d6a199e49daa32d0.tar.gz |
driver/tcs3400: add auto-compensation for saturation
Making settings more sensitive makes the SNR better, so this
algorithm strives to keep the output level as close to 90%
saturation as possible.
Adds calibration mode and lux calculation.
Removes unused last_value field from the tcs3400_rgb_drv_data_t
structure, we use raw_xyz field in motion_sensor_t struct instead.
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 1023". 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.
Cq-Depend: chromium:1711958,chromium:1702543
Change-Id: Ibf260a990fe285cb54ee94c1ebe8aa85ea10affc
Signed-off-by: Nick Vaccaro <nvaccaro@google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1633269
Reviewed-by: Gwendal Grignou <gwendal@chromium.org>
Diffstat (limited to 'driver/als_tcs3400.h')
-rw-r--r-- | driver/als_tcs3400.h | 81 |
1 files changed, 66 insertions, 15 deletions
diff --git a/driver/als_tcs3400.h b/driver/als_tcs3400.h index bad2ec5857..eace416c94 100644 --- a/driver/als_tcs3400.h +++ b/driver/als_tcs3400.h @@ -68,7 +68,7 @@ enum tcs3400_mode { #define TCS_I2C_CONTROL_MASK 0x03 #define TCS_I2C_STATUS_RGBC_VALID BIT(0) #define TCS_I2C_STATUS_ALS_IRQ BIT(4) -#define TCS_I2C_STATUS_ALS_VALID BIT(7) +#define TCS_I2C_STATUS_ALS_SATURATED BIT(7) #define TCS_I2C_AUX_ASL_INT_ENABLE BIT(5) @@ -79,7 +79,7 @@ enum tcs3400_mode { /* Min and Max sampling frequency in mHz */ #define TCS3400_LIGHT_MIN_FREQ 149 -#define TCS3400_LIGHT_MAX_FREQ 10000 +#define TCS3400_LIGHT_MAX_FREQ 1000 #if (CONFIG_EC_MAX_SENSOR_FREQ_MILLIHZ <= TCS3400_LIGHT_MAX_FREQ) #error "EC too slow for light sensor" #endif @@ -91,27 +91,78 @@ enum tcs3400_mode { /* NOTE: The higher the ATIME value in reg, the shorter the accumulation time */ #define TCS_MIN_ATIME 0x00 /* 712 ms */ #define TCS_MAX_ATIME 0x70 /* 400 ms */ +#define TCS_ATIME_GRANULARITY 256 /* 256 atime settings */ +#define TCS_SATURATION_LEVEL 0xffff /* for 0 < atime < 0x70 */ #define TCS_DEFAULT_ATIME TCS_MIN_ATIME /* 712 ms */ +#define TCS_CALIBRATION_ATIME TCS_MIN_ATIME +#define TCS_GAIN_UPSHIFT_ATIME TCS_MAX_ATIME #define TCS_MIN_AGAIN 0x00 /* 1x gain */ #define TCS_MAX_AGAIN 0x03 /* 64x gain */ -#define TCS_DEFAULT_AGAIN 0x02 /* 16x gain */ +#define TCS_CALIBRATION_AGAIN 0x02 /* 16x gain */ +#define TCS_DEFAULT_AGAIN TCS_CALIBRATION_AGAIN -/* tcs3400 rgb als driver data */ -struct tcs3400_rgb_drv_data_t { +#define TCS_ATIME_DEC_STEP 5 +#define TCS_ATIME_INC_STEP TCS_GAIN_UPSHIFT_ATIME + +/* + * Factor to multiply light value by to determine if an increase in gain + * would cause the next value to saturate. + * + * On the TCS3400, gain increases 4x each time again register setting is + * incremented. However, I see cases where values that are 24% of saturation + * go into saturation after increasing gain, causing a back-and-forth cycle to + * occur : + * + * [134.654994 tcs3400_adjust_sensor_for_saturation value=65535 100% Gain=2 ] + * [135.655064 tcs3400_adjust_sensor_for_saturation value=15750 24% Gain=1 ] + * [136.655107 tcs3400_adjust_sensor_for_saturation value=65535 100% Gain=2 ] + * + * To avoid this, we require value to be <= 20% of saturation level + * (TCS_GAIN_SAT_LEVEL) before allowing gain to be increased. + */ +#define TCS_GAIN_ADJUST_FACTOR 5 +#define TCS_GAIN_SAT_LEVEL (TCS_SATURATION_LEVEL / TCS_GAIN_ADJUST_FACTOR) +#define TCS_UPSHIFT_FACTOR 3 +#define TCS_GAIN_SAT_UPSHIFT_LEVEL (TCS_SATURATION_LEVEL / TCS_UPSHIFT_FACTOR) + +/* + * Percentage of saturation level that the auto-adjusting anti-saturation + * method will drive towards. + */ +#define TSC_SATURATION_LOW_BAND_PERCENT 90 +#define TSC_SATURATION_LOW_BAND_LEVEL (TCS_SATURATION_LEVEL * \ + TSC_SATURATION_LOW_BAND_PERCENT / 100) + +enum crbg_index { + CLEAR_CRGB_IDX = 0, + RED_CRGB_IDX, + GREEN_CRGB_IDX, + BLUE_CRGB_IDX, + CRGB_COUNT, +}; + +/* saturation auto-adjustment */ +struct tcs_saturation_t { /* - * device_scale and device_uscale are used to adjust raw rgb channel - * values prior to applying any channel-specific scaling required. - * raw_value += rgb_cal.offset; - * adjusted_value = raw_value * device_scale + - * raw_value * device_uscale / 10000; + * Gain Scaling; must be value between 0 and 3 + * 0 - 1x scaling + * 1 - 4x scaling + * 2 - 16x scaling + * 3 - 64x scaling */ - uint16_t device_scale; - uint16_t device_uscale; + uint8_t again; + + /* Acquisition Time, controlled by the ATIME register */ + uint8_t atime; /* ATIME register setting */ +}; + +/* tcs3400 rgb als driver data */ +struct tcs3400_rgb_drv_data_t { + uint8_t calibration_mode;/* 0 = normal run mode, 1 = calibration mode */ - int rate; /* holds current sensor rate */ - int last_value[3]; /* holds last RGB values */ - struct rgb_calibration_t rgb_cal[3]; /* calibration data */ + struct rgb_calibration_t rgb_cal[RGB_CHANNEL_COUNT]; + struct tcs_saturation_t saturation; /* saturation adjustment */ }; extern const struct accelgyro_drv tcs3400_drv; |