From 9e5f2dacebf880f61671974ddd8f604cf1782f37 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Fri, 25 Aug 2023 17:27:43 -0600 Subject: started splitting set_level(0) into its own set_level_zero(), and made USE_AUX_RGB_LEDS_WHILE_ON work more like the old indicator LEDs, where it gets set automatically with set_level() Using set_level_zero() reduces space used by channel modes, and simplifies code for each mode's set_level_*() functions. I measured about 220 bytes less in the emisar-d4k-3ch build this way, while also reducing the chance of bugs. --- hwdef-emisar-d4k-3ch.c | 132 ++++++------------------- spaghetti-monster/anduril/anduril.c | 2 +- spaghetti-monster/anduril/cfg-emisar-d4k-3ch.h | 2 +- spaghetti-monster/fsm-ramping.c | 33 ++++++- spaghetti-monster/fsm-ramping.h | 1 + 5 files changed, 64 insertions(+), 106 deletions(-) diff --git a/hwdef-emisar-d4k-3ch.c b/hwdef-emisar-d4k-3ch.c index 1955b59..ac9c597 100644 --- a/hwdef-emisar-d4k-3ch.c +++ b/hwdef-emisar-d4k-3ch.c @@ -76,20 +76,26 @@ StatePtr channel_3H_modes[NUM_CHANNEL_MODES] = { NULL, NULL, circular_tint_3h, NULL, }; +void set_level_zero() { + // turn off all LEDs + MAIN2_ENABLE_PORT &= ~(1 << MAIN2_ENABLE_PIN); + LED3_ENABLE_PORT &= ~(1 << LED3_ENABLE_PIN ); + LED4_ENABLE_PORT &= ~(1 << LED4_ENABLE_PIN ); + MAIN2_PWM_LVL = 0; + LED3_PWM_LVL = 0; + LED4_PWM_LVL = 0; + PWM_CNT = 0; + PWM_TOP = PWM_TOP_INIT; +} + // LEDs 1+2 are 8-bit // this 8-bit channel may be LEDs 1+2 or LED 4, depending on wiring void set_level_main2(uint8_t level) { LED3_ENABLE_PORT &= ~(1 << LED3_ENABLE_PIN ); // turn off unused LEDs LED4_ENABLE_PORT &= ~(1 << LED4_ENABLE_PIN ); // turn off unused LEDs - if (level == 0) { - MAIN2_PWM_LVL = 0; - MAIN2_ENABLE_PORT &= ~(1 << MAIN2_ENABLE_PIN); // turn off opamp - } else { - level --; - MAIN2_ENABLE_PORT |= (1 << MAIN2_ENABLE_PIN); - MAIN2_PWM_LVL = PWM_GET8(pwm1_levels, level); - } + MAIN2_ENABLE_PORT |= (1 << MAIN2_ENABLE_PIN); + MAIN2_PWM_LVL = PWM_GET8(pwm1_levels, level); } // LED 3 is 16-bit @@ -97,19 +103,12 @@ void set_level_led3(uint8_t level) { MAIN2_ENABLE_PORT &= ~(1 << MAIN2_ENABLE_PIN); // turn off unused LEDs LED4_ENABLE_PORT &= ~(1 << LED4_ENABLE_PIN ); // turn off unused LEDs - if (level == 0) { - LED3_PWM_LVL = 0; - PWM_CNT = 0; - LED3_ENABLE_PORT &= ~(1 << LED3_ENABLE_PIN ); // turn off opamp - } else { - level --; - LED3_ENABLE_PORT |= (1 << LED3_ENABLE_PIN); - LED3_PWM_LVL = PWM_GET16(pwm2_levels, level); - uint16_t top = PWM_GET16(pwm_tops, level); - while(actual_level && (PWM_CNT > (top - 32))) {} - PWM_TOP = top; - if (! actual_level) PWM_CNT = 0; - } + LED3_ENABLE_PORT |= (1 << LED3_ENABLE_PIN); + LED3_PWM_LVL = PWM_GET16(pwm2_levels, level); + uint16_t top = PWM_GET16(pwm_tops, level); + while(actual_level && (PWM_CNT > (top - 32))) {} + PWM_TOP = top; + if (! actual_level) PWM_CNT = 0; } // this 16-bit channel may be LED 4 or LEDs 1+2, depending on wiring @@ -117,40 +116,20 @@ void set_level_led4(uint8_t level) { MAIN2_ENABLE_PORT &= ~(1 << MAIN2_ENABLE_PIN); // turn off unused LEDs LED3_ENABLE_PORT &= ~(1 << LED3_ENABLE_PIN ); // turn off unused LEDs - if (level == 0) { - LED4_PWM_LVL = 0; - PWM_CNT = 0; // reset phase - LED4_ENABLE_PORT &= ~(1 << LED4_ENABLE_PIN ); // turn off opamp - } else { - level --; // PWM array index = level - 1 - // gotta turn on the opamp before light can come out - LED4_ENABLE_PORT |= (1 << LED4_ENABLE_PIN); - LED4_PWM_LVL = PWM_GET16(pwm2_levels, level); - // pulse frequency modulation, a.k.a. dynamic PWM - uint16_t top = PWM_GET16(pwm_tops, level); - // wait to sync the counter and avoid flashes - while(actual_level && (PWM_CNT > (top - 32))) {} - PWM_TOP = top; - // force reset phase when turning on from zero - // (because otherwise the initial response is inconsistent) - if (! actual_level) PWM_CNT = 0; - } + // gotta turn on the opamp before light can come out + LED4_ENABLE_PORT |= (1 << LED4_ENABLE_PIN); + LED4_PWM_LVL = PWM_GET16(pwm2_levels, level); + // pulse frequency modulation, a.k.a. dynamic PWM + uint16_t top = PWM_GET16(pwm_tops, level); + // wait to sync the counter and avoid flashes + while(actual_level && (PWM_CNT > (top - 32))) {} + PWM_TOP = top; + // force reset phase when turning on from zero + // (because otherwise the initial response is inconsistent) + if (! actual_level) PWM_CNT = 0; } void set_level_all(uint8_t level) { - if (level == 0) { - MAIN2_PWM_LVL = 0; - LED3_PWM_LVL = 0; - LED4_PWM_LVL = 0; - PWM_CNT = 0; - MAIN2_ENABLE_PORT &= ~(1 << MAIN2_ENABLE_PIN); // turn off opamp - LED3_ENABLE_PORT &= ~(1 << LED3_ENABLE_PIN ); // turn off opamp - LED4_ENABLE_PORT &= ~(1 << LED4_ENABLE_PIN ); // turn off opamp - return; - } - - level --; - MAIN2_ENABLE_PORT |= (1 << MAIN2_ENABLE_PIN); LED3_ENABLE_PORT |= (1 << LED3_ENABLE_PIN ); LED4_ENABLE_PORT |= (1 << LED4_ENABLE_PIN ); @@ -170,17 +149,6 @@ void set_level_all(uint8_t level) { void set_level_led34a_blend(uint8_t level) { MAIN2_ENABLE_PORT &= ~(1 << MAIN2_ENABLE_PIN); // turn off unused LEDs - if (level == 0) { - LED3_PWM_LVL = 0; - LED4_PWM_LVL = 0; - PWM_CNT = 0; // reset phase - LED3_ENABLE_PORT &= ~(1 << LED3_ENABLE_PIN ); // turn off opamp - LED4_ENABLE_PORT &= ~(1 << LED4_ENABLE_PIN ); // turn off opamp - return; - } - - level --; // PWM array index = level - 1 - PWM_DATATYPE warm_PWM, cool_PWM; PWM_DATATYPE brightness = PWM_GET16(pwm2_levels, level); PWM_DATATYPE top = PWM_GET16(pwm_tops, level); @@ -201,17 +169,6 @@ void set_level_led34a_blend(uint8_t level) { void set_level_led34b_blend(uint8_t level) { LED4_ENABLE_PORT &= ~(1 << LED4_ENABLE_PIN ); // turn off unused LEDs - if (level == 0) { - MAIN2_PWM_LVL = 0; - LED3_PWM_LVL = 0; - PWM_CNT = 0; // reset phase - MAIN2_ENABLE_PORT &= ~(1 << MAIN2_ENABLE_PIN); // turn off opamp - LED3_ENABLE_PORT &= ~(1 << LED3_ENABLE_PIN ); // turn off opamp - return; - } - - level --; - const uint16_t top = 2047; uint16_t warm_PWM, cool_PWM; // 11 bits, 8 bits uint8_t blend = cfg.channel_mode_args[channel_mode]; @@ -236,20 +193,6 @@ void set_level_led34b_blend(uint8_t level) { } void set_level_hsv(uint8_t level) { - // TODO: implement a custom 3H handler which wraps around 0 to 255 - if (level == 0) { - MAIN2_PWM_LVL = 0; - LED3_PWM_LVL = 0; - LED4_PWM_LVL = 0; - PWM_CNT = 0; - MAIN2_ENABLE_PORT &= ~(1 << MAIN2_ENABLE_PIN); // turn off opamp - LED3_ENABLE_PORT &= ~(1 << LED3_ENABLE_PIN ); // turn off opamp - LED4_ENABLE_PORT &= ~(1 << LED4_ENABLE_PIN ); // turn off opamp - return; - } - - level --; - RGB_t color; uint8_t h = cfg.channel_mode_args[channel_mode]; uint8_t s = 255; // TODO: drop saturation at brightest levels @@ -304,19 +247,6 @@ void calc_auto_3ch_blend( // 3-channel "auto tint" channel mode void set_level_auto3(uint8_t level) { - if (level == 0) { - MAIN2_PWM_LVL = 0; - LED3_PWM_LVL = 0; - LED4_PWM_LVL = 0; - PWM_CNT = 0; - MAIN2_ENABLE_PORT &= ~(1 << MAIN2_ENABLE_PIN); // turn off opamp - LED3_ENABLE_PORT &= ~(1 << LED3_ENABLE_PIN ); // turn off opamp - LED4_ENABLE_PORT &= ~(1 << LED4_ENABLE_PIN ); // turn off opamp - return; - } - - level --; - uint16_t a, b; uint8_t c; calc_auto_3ch_blend(&a, &b, &c, level); diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c index ab43df6..6399ef6 100644 --- a/spaghetti-monster/anduril/anduril.c +++ b/spaghetti-monster/anduril/anduril.c @@ -267,7 +267,7 @@ void loop() { #ifdef USE_AUX_RGB_LEDS_WHILE_ON // display battery charge on RGB button during use - if (! setting_rgb_mode_now) + if (state == steady_state) rgb_led_voltage_readout(actual_level > USE_AUX_RGB_LEDS_WHILE_ON); #endif diff --git a/spaghetti-monster/anduril/cfg-emisar-d4k-3ch.h b/spaghetti-monster/anduril/cfg-emisar-d4k-3ch.h index 46d5796..c015295 100644 --- a/spaghetti-monster/anduril/cfg-emisar-d4k-3ch.h +++ b/spaghetti-monster/anduril/cfg-emisar-d4k-3ch.h @@ -13,7 +13,7 @@ // turn on the aux LEDs while main LEDs are on // (in case there's a RGB button) -#define USE_AUX_RGB_LEDS_WHILE_ON 20 +#define USE_AUX_RGB_LEDS_WHILE_ON 25 #define USE_INDICATOR_LED_WHILE_RAMPING // channel modes... diff --git a/spaghetti-monster/fsm-ramping.c b/spaghetti-monster/fsm-ramping.c index a970f0e..89f540b 100644 --- a/spaghetti-monster/fsm-ramping.c +++ b/spaghetti-monster/fsm-ramping.c @@ -36,6 +36,25 @@ inline void set_level_aux_leds(uint8_t level) { } #endif // ifdef HAS_AUX_LEDS +#ifdef USE_AUX_RGB_LEDS_WHILE_ON +// TODO: maybe move this stuff into FSM +#include "anduril/aux-leds.h" // for rgb_led_voltage_readout() +inline void set_level_aux_rgb_leds(uint8_t level) { + if (! go_to_standby) { + if (level > 0) { + rgb_led_voltage_readout(level > USE_AUX_RGB_LEDS_WHILE_ON); + } else { + rgb_led_set(0); + } + // some drivers can be wired with RGB or single color to button + // ... so support both even though only one is connected + #ifdef USE_BUTTON_LED + button_led_set((level > 0) + (level > DEFAULT_LEVEL)); + #endif + } +} +#endif // ifdef USE_AUX_RGB_LEDS_WHILE_ON + void set_level(uint8_t level) { #ifdef USE_JUMP_START @@ -58,9 +77,17 @@ void set_level(uint8_t level) { set_level_aux_leds(level); #endif - // call the relevant hardware-specific set_level_*() - SetLevelFuncPtr set_level_func = channels[channel_mode].set_level; - set_level_func(level); + #ifdef USE_AUX_RGB_LEDS_WHILE_ON + set_level_aux_rgb_leds(level); + #endif + + if (0 == level) { + set_level_zero(); + } else { + // call the relevant hardware-specific set_level_*() + SetLevelFuncPtr set_level_func = channels[channel_mode].set_level; + set_level_func(level - 1); + } if (actual_level != level) prev_level = actual_level; actual_level = level; diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h index cae9a4d..bfcc5fb 100644 --- a/spaghetti-monster/fsm-ramping.h +++ b/spaghetti-monster/fsm-ramping.h @@ -13,6 +13,7 @@ uint8_t prev_level = 0; void set_level(uint8_t level); //void set_level_smooth(uint8_t level); +void set_level_zero(); // implement this in a hwdef #ifdef USE_SET_LEVEL_GRADUALLY // adjust brightness very smoothly -- cgit v1.2.3