summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGwendal Grignou <gwendal@chromium.org>2015-10-22 14:13:35 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2016-08-01 16:41:16 +0000
commit4deef677cdad11b1d6ffff035574ba7fdb9dd4ea (patch)
treea9b85ed2e97fe718740723937acf6c32a8ed188c
parent68ce3cb2e209679efcffc33f22aa0ed1fb04b7ae (diff)
downloadchrome-ec-4deef677cdad11b1d6ffff035574ba7fdb9dd4ea.tar.gz
BACKPORT: 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, cyan BUG=chrome-os-partner:44400, b:27849483 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 (cherry picked from commit 81d269dc004b6c7334e4e8eafbb2872e5b6fdcf1) Signed-off-by: Gwendal Grignou <gwendal@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/359392
-rw-r--r--common/lightbar.c45
-rw-r--r--include/lightbar.h8
-rw-r--r--include/motion_sense.h5
-rw-r--r--test/lightbar.c49
-rw-r--r--test/test_config.h4
5 files changed, 91 insertions, 20 deletions
diff --git a/common/lightbar.c b/common/lightbar.c
index 3a1e005c9e..94e79fa43d 100644
--- a/common/lightbar.c
+++ b/common/lightbar.c
@@ -195,7 +195,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;
@@ -210,18 +210,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
@@ -230,9 +249,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;
@@ -282,12 +298,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 8cdb12d1d8..0b1608001d 100644
--- a/test/test_config.h
+++ b/test/test_config.h
@@ -103,7 +103,9 @@ int bd99992gw_get_temp(uint16_t adc);
#endif
#ifdef TEST_LIGHTBAR
-#define I2C_PORT_LIGHTBAR 1
+#define CONFIG_I2C
+#define I2C_PORT_LIGHTBAR 0
+#define CONFIG_ALS_LIGHTBAR_DIMMING 0
#endif
#ifdef TEST_USB_PD