mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-27 18:25:05 +00:00
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
This commit is contained in:
committed by
chrome-bot
parent
3fc374b7fd
commit
81d269dc00
@@ -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},
|
||||
|
||||
@@ -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;
|
||||
return i;
|
||||
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;
|
||||
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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user