diff options
-rw-r--r-- | common/lightbar.c | 180 |
1 files changed, 96 insertions, 84 deletions
diff --git a/common/lightbar.c b/common/lightbar.c index 8b0352a878..a2643d607e 100644 --- a/common/lightbar.c +++ b/common/lightbar.c @@ -37,6 +37,8 @@ #define CPUTS(outstr) cputs(CC_LIGHTBAR, outstr) #define CPRINTS(format, args...) cprints(CC_LIGHTBAR, format, ## args) +#define FP_SCALE 10000 + /******************************************************************************/ /* Here's some state that we might want to maintain across sysjumps, just to * prevent the lightbar from flashing during normal boot as the EC jumps from @@ -271,51 +273,58 @@ void demo_brightness(int inc) /* Helper functions and data. */ /******************************************************************************/ -static const float _ramp_table[] = { - 0.000000f, 0.000151f, 0.000602f, 0.001355f, 0.002408f, 0.003760f, - 0.005412f, 0.007361f, 0.009607f, 0.012149f, 0.014984f, 0.018112f, - 0.021530f, 0.025236f, 0.029228f, 0.033504f, 0.038060f, 0.042895f, - 0.048005f, 0.053388f, 0.059039f, 0.064957f, 0.071136f, 0.077573f, - 0.084265f, 0.091208f, 0.098396f, 0.105827f, 0.113495f, 0.121396f, - 0.129524f, 0.137876f, 0.146447f, 0.155230f, 0.164221f, 0.173414f, - 0.182803f, 0.192384f, 0.202150f, 0.212096f, 0.222215f, 0.232501f, - 0.242949f, 0.253551f, 0.264302f, 0.275194f, 0.286222f, 0.297379f, - 0.308658f, 0.320052f, 0.331555f, 0.343159f, 0.354858f, 0.366644f, - 0.378510f, 0.390449f, 0.402455f, 0.414519f, 0.426635f, 0.438795f, - 0.450991f, 0.463218f, 0.475466f, 0.487729f, 0.500000f, 0.512271f, - 0.524534f, 0.536782f, 0.549009f, 0.561205f, 0.573365f, 0.585481f, - 0.597545f, 0.609551f, 0.621490f, 0.633356f, 0.645142f, 0.656841f, - 0.668445f, 0.679947f, 0.691342f, 0.702621f, 0.713778f, 0.724806f, - 0.735698f, 0.746449f, 0.757051f, 0.767499f, 0.777785f, 0.787904f, - 0.797850f, 0.807616f, 0.817197f, 0.826586f, 0.835780f, 0.844770f, - 0.853553f, 0.862124f, 0.870476f, 0.878604f, 0.886505f, 0.894173f, - 0.901604f, 0.908792f, 0.915735f, 0.922427f, 0.928864f, 0.935044f, - 0.940961f, 0.946612f, 0.951995f, 0.957105f, 0.961940f, 0.966496f, - 0.970772f, 0.974764f, 0.978470f, 0.981888f, 0.985016f, 0.987851f, - 0.990393f, 0.992639f, 0.994588f, 0.996240f, 0.997592f, 0.998645f, - 0.999398f, 0.999849f, 1.000000f, +#define F(x) (x * FP_SCALE) +static const int _ramp_table[] = { + F(0.000000), F(0.000151), F(0.000602), F(0.001355), F(0.002408), + F(0.003760), F(0.005412), F(0.007361), F(0.009607), F(0.012149), + F(0.014984), F(0.018112), F(0.021530), F(0.025236), F(0.029228), + F(0.033504), F(0.038060), F(0.042895), F(0.048005), F(0.053388), + F(0.059039), F(0.064957), F(0.071136), F(0.077573), F(0.084265), + F(0.091208), F(0.098396), F(0.105827), F(0.113495), F(0.121396), + F(0.129524), F(0.137876), F(0.146447), F(0.155230), F(0.164221), + F(0.173414), F(0.182803), F(0.192384), F(0.202150), F(0.212096), + F(0.222215), F(0.232501), F(0.242949), F(0.253551), F(0.264302), + F(0.275194), F(0.286222), F(0.297379), F(0.308658), F(0.320052), + F(0.331555), F(0.343159), F(0.354858), F(0.366644), F(0.378510), + F(0.390449), F(0.402455), F(0.414519), F(0.426635), F(0.438795), + F(0.450991), F(0.463218), F(0.475466), F(0.487729), F(0.500000), + F(0.512271), F(0.524534), F(0.536782), F(0.549009), F(0.561205), + F(0.573365), F(0.585481), F(0.597545), F(0.609551), F(0.621490), + F(0.633356), F(0.645142), F(0.656841), F(0.668445), F(0.679947), + F(0.691342), F(0.702621), F(0.713778), F(0.724806), F(0.735698), + F(0.746449), F(0.757051), F(0.767499), F(0.777785), F(0.787904), + F(0.797850), F(0.807616), F(0.817197), F(0.826586), F(0.835780), + F(0.844770), F(0.853553), F(0.862124), F(0.870476), F(0.878604), + F(0.886505), F(0.894173), F(0.901604), F(0.908792), F(0.915735), + F(0.922427), F(0.928864), F(0.935044), F(0.940961), F(0.946612), + F(0.951995), F(0.957105), F(0.961940), F(0.966496), F(0.970772), + F(0.974764), F(0.978470), F(0.981888), F(0.985016), F(0.987851), + F(0.990393), F(0.992639), F(0.994588), F(0.996240), F(0.997592), + F(0.998645), F(0.999398), F(0.999849), F(1.000000), }; +#undef F + /* This function provides a smooth ramp up from 0.0 to 1.0 and back to 0.0, * for input from 0x00 to 0xff. */ -static inline float cycle_010(uint8_t i) +static inline int cycle_010(uint8_t i) { return i < 128 ? _ramp_table[i] : _ramp_table[256-i]; } /* This function provides a smooth oscillation between -0.5 and +0.5. * Zero starts at 0x00. */ -static inline float cycle_0p0n0(uint8_t i) +static inline int cycle_0p0n0(uint8_t i) { - return cycle_010(i + 64) - 0.5f; + return cycle_010(i + 64) - FP_SCALE / 2; } /* This function provides a pulsing oscillation between -0.5 and +0.5. */ -static inline float cycle_npn(uint16_t i) +static inline int cycle_npn(uint16_t i) { if ((i / 256) % 4) - return -0.5f; - return cycle_010(i) - 0.5f; + return -FP_SCALE / 2; + return cycle_010(i) - FP_SCALE / 2; } /******************************************************************************/ @@ -340,14 +349,14 @@ static uint32_t pending_msg; static uint32_t pulse_google_colors(void) { int w, i, r, g, b; - float f; + int f; for (w = 0; w < 128; w += 2) { f = cycle_010(w); for (i = 0; i < NUM_LEDS; i++) { - r = st.p.color[i].r * f; - g = st.p.color[i].g * f; - b = st.p.color[i].b * f; + r = st.p.color[i].r * f / FP_SCALE; + g = st.p.color[i].g * f / FP_SCALE; + b = st.p.color[i].b * f / FP_SCALE; lb_set_rgb(i, r, g, b); } WAIT_OR_RET(st.p.google_ramp_up); @@ -355,9 +364,9 @@ static uint32_t pulse_google_colors(void) for (w = 128; w <= 256; w++) { f = cycle_010(w); for (i = 0; i < NUM_LEDS; i++) { - r = st.p.color[i].r * f; - g = st.p.color[i].g * f; - b = st.p.color[i].b * f; + r = st.p.color[i].r * f / FP_SCALE; + g = st.p.color[i].g * f / FP_SCALE; + b = st.p.color[i].b * f / FP_SCALE; lb_set_rgb(i, r, g, b); } WAIT_OR_RET(st.p.google_ramp_down); @@ -370,7 +379,7 @@ static uint32_t pulse_google_colors(void) static uint32_t sequence_S3S0(void) { int w, r, g, b; - float f, fmin; + int f, fmin; int ci; uint32_t res; @@ -387,13 +396,13 @@ static uint32_t sequence_S3S0(void) if (ci >= ARRAY_SIZE(st.p.color)) ci = 0; - fmin = st.p.osc_min[st.battery_is_charging] / 255.0f; + fmin = st.p.osc_min[st.battery_is_charging] * FP_SCALE / 255; for (w = 0; w <= 128; w++) { - f = cycle_010(w) * fmin; - r = st.p.color[ci].r * f; - g = st.p.color[ci].g * f; - b = st.p.color[ci].b * f; + f = cycle_010(w) * fmin / FP_SCALE; + r = st.p.color[ci].r * f / FP_SCALE; + g = st.p.color[ci].g * f / FP_SCALE; + b = st.p.color[ci].b * f / FP_SCALE; lb_set_rgb(NUM_LEDS, r, g, b); WAIT_OR_RET(st.p.s3s0_ramp_up); } @@ -415,7 +424,7 @@ static uint32_t sequence_S0(void) int i, ci; uint8_t w_ofs; uint16_t w; - float f, fmin, fmax, base_s0, osc_s0, f_ramp; + int f, fmin, fmax, base_s0, osc_s0, f_ramp; start = get_time(); tick = last_tick = 0; @@ -440,18 +449,18 @@ static uint32_t sequence_S0(void) if (ci >= ARRAY_SIZE(st.p.color)) ci = 0; w_ofs = st.p.w_ofs[st.battery_is_charging]; - fmin = st.p.osc_min[st.battery_is_charging] / 255.0f; - fmax = st.p.osc_max[st.battery_is_charging] / 255.0f; - base_s0 = (fmax + fmin) * 0.5f; + fmin = st.p.osc_min[st.battery_is_charging] * FP_SCALE / 255; + fmax = st.p.osc_max[st.battery_is_charging] * FP_SCALE / 255; + base_s0 = (fmax + fmin) / 2; osc_s0 = fmax - fmin; - f_ramp = st.ramp / 255.0f; + f_ramp = st.ramp * FP_SCALE / 255; for (i = 0; i < NUM_LEDS; i++) { - w = st.w0 - i * w_ofs * f_ramp; - f = base_s0 + osc_s0 * cycle_npn(w); - r = st.p.color[ci].r * f; - g = st.p.color[ci].g * f; - b = st.p.color[ci].b * f; + w = st.w0 - i * w_ofs * f_ramp / FP_SCALE; + f = base_s0 + osc_s0 * cycle_npn(w) / FP_SCALE; + r = st.p.color[ci].r * f / FP_SCALE; + g = st.p.color[ci].g * f / FP_SCALE; + b = st.p.color[ci].b * f / FP_SCALE; lb_set_rgb(i, r, g, b); } @@ -475,7 +484,7 @@ static uint32_t sequence_S0(void) static uint32_t sequence_S0S3(void) { int w, i, r, g, b; - float f; + int f; uint8_t drop[NUM_LEDS][3]; /* Grab current colors */ @@ -486,9 +495,9 @@ static uint32_t sequence_S0S3(void) for (w = 128; w <= 256; w++) { f = cycle_010(w); for (i = 0; i < NUM_LEDS; i++) { - r = drop[i][0] * f; - g = drop[i][1] * f; - b = drop[i][2] * f; + r = drop[i][0] * f / FP_SCALE; + g = drop[i][1] * f / FP_SCALE; + b = drop[i][2] * f / FP_SCALE; lb_set_rgb(i, r, g, b); } WAIT_OR_RET(st.p.s0s3_ramp_down); @@ -503,7 +512,7 @@ static uint32_t sequence_S3(void) { int r, g, b; int w; - float f; + int f; int ci; lb_off(); @@ -523,17 +532,17 @@ static uint32_t sequence_S3(void) for (w = 0; w < 128; w += 2) { f = cycle_010(w); - r = st.p.color[ci].r * f; - g = st.p.color[ci].g * f; - b = st.p.color[ci].b * f; + r = st.p.color[ci].r * f / FP_SCALE; + g = st.p.color[ci].g * f / FP_SCALE; + b = st.p.color[ci].b * f / FP_SCALE; lb_set_rgb(NUM_LEDS, r, g, b); WAIT_OR_RET(st.p.s3_ramp_up); } for (w = 128; w <= 256; w++) { f = cycle_010(w); - r = st.p.color[ci].r * f; - g = st.p.color[ci].g * f; - b = st.p.color[ci].b * f; + r = st.p.color[ci].r * f / FP_SCALE; + g = st.p.color[ci].g * f / FP_SCALE; + b = st.p.color[ci].b * f / FP_SCALE; lb_set_rgb(NUM_LEDS, r, g, b); WAIT_OR_RET(st.p.s3_ramp_down); } @@ -793,13 +802,13 @@ static uint32_t sequence_KONAMI(void) } /* Returns 0.0 to 1.0 for val in [min, min + ofs] */ -static float range(int val, int min, int ofs) +static int range(int val, int min, int ofs) { if (val <= min) - return 0.0f; + return 0; if (val >= min+ofs) - return 1.0f; - return (float)(val - min) / ofs; + return FP_SCALE; + return (val - min) * FP_SCALE / ofs; } /* Handy constant */ @@ -810,12 +819,12 @@ static uint32_t sequence_TAP_inner(void) enum { RED, YELLOW, GREEN } base_color; timestamp_t start, now; int i, ci, max_led; - float min, delta, osc, power, mult; + int f_min, f_delta, f_osc, f_power, f_mult; uint8_t w = 0; - min = st.p.tap_seg_min_on / 100.0f; - delta = (st.p.tap_seg_max_on - st.p.tap_seg_min_on) / 100.0f; - osc = st.p.tap_seg_osc / 100.0f; + f_min = st.p.tap_seg_min_on * FP_SCALE / 100; + f_delta = (st.p.tap_seg_max_on - st.p.tap_seg_min_on) * FP_SCALE / 100; + f_osc = st.p.tap_seg_osc * FP_SCALE / 100; start = get_time(); while (1) { @@ -834,33 +843,36 @@ static uint32_t sequence_TAP_inner(void) for (i = 0; i < NUM_LEDS; i++) { if (max_led > i) { - mult = 1.0f; + f_mult = FP_SCALE; } else if (max_led < i) { - mult = 0.0f; + f_mult = 0; } else { switch (base_color) { case RED: - power = range(st.battery_percent, - 0, st.p.tap_pct_red - 1); + f_power = range(st.battery_percent, 0, + st.p.tap_pct_red - 1); break; case YELLOW: - power = range(st.battery_percent, - i * CUT, CUT - 1); + f_power = range(st.battery_percent, + i * CUT, CUT - 1); break; case GREEN: /* green is always full on */ - power = 1.0f; + f_power = FP_SCALE; } - mult = min + power * delta; + f_mult = f_min + f_power * f_delta / FP_SCALE; } /* Pulse when charging */ - if (st.battery_is_charging) - mult *= 1.0f - (osc * cycle_010(w++)); + if (st.battery_is_charging) { + int scale = (FP_SCALE - + f_osc * cycle_010(w++) / FP_SCALE); + f_mult = f_mult * scale / FP_SCALE; + } - lb_set_rgb(i, mult * st.p.color[ci].r, - mult * st.p.color[ci].g, - mult * st.p.color[ci].b); + lb_set_rgb(i, f_mult * st.p.color[ci].r / FP_SCALE, + f_mult * st.p.color[ci].g / FP_SCALE, + f_mult * st.p.color[ci].b / FP_SCALE); } WAIT_OR_RET(st.p.tap_tick_delay); |