diff options
author | Gwendal Grignou <gwendal@chromium.org> | 2015-10-22 14:13:35 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2015-10-23 18:03:12 -0700 |
commit | 81d269dc004b6c7334e4e8eafbb2872e5b6fdcf1 (patch) | |
tree | 85829474533fddf3e030c2aa2c105bd621bb228d | |
parent | 3fc374b7fd8b618d513db27d9f10c8200f603e15 (diff) | |
download | chrome-ec-81d269dc004b6c7334e4e8eafbb2872e5b6fdcf1.tar.gz |
common: lightbar: Add histeresis to prevent flickering
When ALS is enabled, if light is around one threshold (say 40 lux),
the lightbar will flicker between readings.
Add a histeresis to prevent the flickering.
The current setting is:
setting ^
(dim) 2 | ------+---->---+
1 | +----<---+--->---+
(bright) 0 | +---<---+---------
+-------+--------+-------+--------> lux
20 40 60
BRANCH=smaug
BUG=chrome-os-partner:44400
TEST=check in a dark room (30~40 lux) there is no flickering.
Add unit test.
Change-Id: I4018e2c2ed764abf9c9ed28e2d50a3e94a7d5f75
Signed-off-by: Gwendal Grignou <gwendal@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/308205
-rw-r--r-- | board/ryu/board.c | 11 | ||||
-rw-r--r-- | common/lightbar.c | 45 | ||||
-rw-r--r-- | include/lightbar.h | 8 | ||||
-rw-r--r-- | include/motion_sense.h | 5 | ||||
-rw-r--r-- | test/lightbar.c | 49 | ||||
-rw-r--r-- | test/test_config.h | 1 |
6 files changed, 96 insertions, 23 deletions
diff --git a/board/ryu/board.c b/board/ryu/board.c index f47370d2e5..6d98af9890 100644 --- a/board/ryu/board.c +++ b/board/ryu/board.c @@ -456,10 +456,11 @@ struct motion_sensor_t motion_sensors[] = { }; const unsigned int motion_sensor_count = ARRAY_SIZE(motion_sensors); -struct lb_brightness_def lb_brightness_levels[] = { +const struct lb_brightness_def lb_brightness_levels[] = { { /* regular brightness */ - .lux = 40, + .lux_up = 60, + .lux_down = 40, .color = { {0x74, 0x58, 0xb4}, /* Segment0: Google blue */ {0xd6, 0x40, 0x20}, /* Segment1: Google red */ @@ -469,7 +470,8 @@ struct lb_brightness_def lb_brightness_levels[] = { }, { /* 25 - 50% brightness */ - .lux = 20, + .lux_up = 40, + .lux_down = 20, .color = { {0x51, 0x38, 0x7d}, {0x99, 0x28, 0x15}, @@ -479,7 +481,8 @@ struct lb_brightness_def lb_brightness_levels[] = { }, { /* 0 .. 25% brightness */ - .lux = 0, + .lux_up = 0, + .lux_down = 0, .color = { {0x3d, 0x28, 0x5c}, {0x71, 0x28, 0x10}, diff --git a/common/lightbar.c b/common/lightbar.c index 4e9179ad12..97d0444396 100644 --- a/common/lightbar.c +++ b/common/lightbar.c @@ -204,7 +204,7 @@ static void lightbar_restore_state(void) static int last_backlight_level; #endif #ifdef CONFIG_ALS_LIGHTBAR_DIMMING -static int last_google_color = -1; +test_export_static int google_color_id; #endif static int demo_mode = DEMO_MODE_DEFAULT; @@ -219,18 +219,37 @@ static int quantize_battery_level(int pct) } #ifdef CONFIG_ALS_LIGHTBAR_DIMMING -static int lux_level_to_google_color(int lux) +test_export_static int lux_level_to_google_color(const int lux) { int i; - if (!lid_is_open()) + if (!lid_is_open()) { /* The lid shades the light sensor, use full brightness. */ - return 0; + if (google_color_id != 0) { + google_color_id = 0; + return 1; + } else { + return 0; + } + } - for (i = 0; i < lb_brightness_levels_count ; i++) - if (lux >= lb_brightness_levels[i].lux) + /* See if we need to decrease brightness */ + for (i = google_color_id; i < lb_brightness_levels_count ; i++) + if (lux >= lb_brightness_levels[i].lux_down) + break; + if (i > google_color_id) { + google_color_id = i; + return 1; + } + /* See if we need to increase brightness */ + for (i = google_color_id; i > 0; i--) + if (lux < lb_brightness_levels[i - 1].lux_up) break; - return i; + if (i < google_color_id) { + google_color_id = i; + return 1; + } + return 0; } #endif @@ -239,9 +258,6 @@ static void get_battery_level(void) { int pct = 0; int bl; -#ifdef CONFIG_ALS_LIGHTBAR_DIMMING - int color_id; -#endif if (demo_mode) return; @@ -289,12 +305,9 @@ static void get_battery_level(void) #ifdef CONFIG_ALS_LIGHTBAR_DIMMING /* Read last value (in lux) collected by the motion sensor. */ /* Convert lux into brightness percentage */ - color_id = lux_level_to_google_color(MOTION_SENSE_LUX); - - if (color_id != last_google_color) { - last_google_color = pct; - memcpy(st.p.color, lb_brightness_levels[color_id].color, - sizeof(lb_brightness_levels[color_id].color)); + if (lux_level_to_google_color(MOTION_SENSE_LUX)) { + memcpy(st.p.color, lb_brightness_levels[google_color_id].color, + sizeof(lb_brightness_levels[google_color_id].color)); } #endif } diff --git a/include/lightbar.h b/include/lightbar.h index 8648e3f3bd..61ee5a2a9d 100644 --- a/include/lightbar.h +++ b/include/lightbar.h @@ -38,17 +38,19 @@ enum lb_control { /* * For dimming the lightbar in the dark, we define an array to * describe the expected colors: - * if luminosity is more than 'lux', the color defined will be used. + * if luminosity is more than 'lux_up', the color defined will be used. + * if luminosity is more than 'lux_down', we will look at the next band. * The last entry must have lux == 0. * Defining brightness is not enough to prevent washed color in low * lux setting. */ struct lb_brightness_def { - uint16_t lux; + uint16_t lux_up; + uint16_t lux_down; struct rgb_s color[4]; }; -extern struct lb_brightness_def lb_brightness_levels[]; +extern const struct lb_brightness_def lb_brightness_levels[]; extern const unsigned lb_brightness_levels_count; #endif diff --git a/include/motion_sense.h b/include/motion_sense.h index ed24f232fd..aa4170b722 100644 --- a/include/motion_sense.h +++ b/include/motion_sense.h @@ -187,6 +187,11 @@ void motion_sense_fifo_add_unit(struct ec_response_motion_sensor_data *data, #endif #ifdef CONFIG_ALS_LIGHTBAR_DIMMING +#ifdef TEST_BUILD +#define MOTION_SENSE_LUX 0 +#else #define MOTION_SENSE_LUX motion_sensors[CONFIG_ALS_LIGHTBAR_DIMMING].raw_xyz[0] #endif +#endif + #endif /* __CROS_EC_MOTION_SENSE_H */ diff --git a/test/lightbar.c b/test/lightbar.c index 3aae1e71f3..8a21c1fc62 100644 --- a/test/lightbar.c +++ b/test/lightbar.c @@ -11,6 +11,7 @@ #include "timer.h" #include "util.h" + static int get_seq(void) { int rv; @@ -272,6 +273,53 @@ static int test_stable_states(void) return EC_SUCCESS; } +const struct lb_brightness_def lb_brightness_levels[] = { + { + /* regular brightness */ + .lux_up = 60, + .lux_down = 40, + }, + { + /* 25 - 50% brightness */ + .lux_up = 40, + .lux_down = 20, + }, + { + /* 0 .. 25% brightness */ + .lux_up = 0, + .lux_down = 0, + }, +}; +const unsigned int lb_brightness_levels_count = + ARRAY_SIZE(lb_brightness_levels); + +int lux_level_to_google_color(const int lux); +extern int google_color_id; + +int lid_is_open(void) +{ + return 1; +} + +static int test_als_lightbar(void) +{ + int lux_data[] = { 500, 100, 35, 15, 30, 35, 55, 70, 55, 100 }; + int exp_gcid[] = { 0, 0, 1, 2, 2, 2, 1, 0, 0, 0 }; + int exp_chg[] = { 0, 0, 1, 1, 0, 0, 1, 1, 0, 0 }; + int i; + + BUILD_ASSERT(ARRAY_SIZE(lux_data) == ARRAY_SIZE(exp_gcid)); + BUILD_ASSERT(ARRAY_SIZE(lux_data) == ARRAY_SIZE(exp_chg)); + + google_color_id = 0; + for (i = 0; i < ARRAY_SIZE(lux_data); i++) { + TEST_ASSERT(exp_chg[i] == + lux_level_to_google_color(lux_data[i])); + TEST_ASSERT(exp_gcid[i] == google_color_id); + } + return EC_SUCCESS; +} + void run_test(void) { RUN_TEST(test_stable_states); @@ -280,5 +328,6 @@ void run_test(void) RUN_TEST(test_stop_timeout); RUN_TEST(test_oneshots_norm_msg); RUN_TEST(test_double_oneshots); + RUN_TEST(test_als_lightbar); test_print_result(); } diff --git a/test/test_config.h b/test/test_config.h index f758d87410..1ef48eba69 100644 --- a/test/test_config.h +++ b/test/test_config.h @@ -109,6 +109,7 @@ int ncp15wb_calculate_temp(uint16_t adc); #ifdef TEST_LIGHTBAR #define CONFIG_I2C #define I2C_PORT_LIGHTBAR 0 +#define CONFIG_ALS_LIGHTBAR_DIMMING 0 #endif #ifdef TEST_USB_PD |