diff options
| author | Selene ToyKeeper | 2017-09-26 16:47:44 -0600 |
|---|---|---|
| committer | Selene ToyKeeper | 2017-09-26 16:47:44 -0600 |
| commit | 45e3a7758046536754f073c42ac27dc737e69fab (patch) | |
| tree | 189c6c5e42b34d89e80ca4d13d78af4680043fd1 | |
| parent | Fixed moon in lockout state. Was too low since the MCU wasn't underclocked. (diff) | |
| download | anduril-45e3a7758046536754f073c42ac27dc737e69fab.tar.gz anduril-45e3a7758046536754f073c42ac27dc737e69fab.tar.bz2 anduril-45e3a7758046536754f073c42ac27dc737e69fab.zip | |
Added dynamic underclocking to FSM, instead of doing it manually in Anduril.
Diffstat (limited to '')
| -rw-r--r-- | spaghetti-monster/anduril/anduril.c | 29 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-events.c | 30 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-misc.c | 19 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-misc.h | 4 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-ramping.c | 3 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-ramping.h | 2 |
6 files changed, 63 insertions, 24 deletions
diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c index 1044398..6740e23 100644 --- a/spaghetti-monster/anduril/anduril.c +++ b/spaghetti-monster/anduril/anduril.c @@ -23,8 +23,6 @@ #define USE_LVP #define USE_THERMAL_REGULATION #define DEFAULT_THERM_CEIL 50 -#define USE_DELAY_MS -#define USE_DELAY_4MS #define USE_DELAY_ZERO #define USE_RAMPING #define USE_SET_LEVEL_GRADUALLY @@ -37,9 +35,7 @@ #define USE_EEPROM #define EEPROM_BYTES 12 #define USE_IDLE_MODE -#define MOON_POWERSAVE // cut clock speed at very low modes for better efficiency -//#define HALFSPEED_LEVEL 30 // looks good, but sounds bad -#define HALFSPEED_LEVEL 14 +#define USE_DYNAMIC_UNDERCLOCKING // cut clock speed at very low modes for better efficiency #include "spaghetti-monster.h" // Options specific to this UI (not inherited from SpaghettiMonster) @@ -966,27 +962,12 @@ void loop() { || (state == off_state) || (state == lockout_state) || (state == goodnight_state) ) { - #ifdef MOON_POWERSAVE - if (actual_level < 5) { - // run at quarter speed - CLKPR = 1<<CLKPCE; CLKPR = 2; - } - else if (actual_level < HALFSPEED_LEVEL) { - // run at half speed - CLKPR = 1<<CLKPCE; CLKPR = 1; - } else { - // run at full speed - CLKPR = 1<<CLKPCE; CLKPR = 0; - } - #endif // doze until next clock tick idle_mode(); } - else { - // run at full speed - CLKPR = 1<<CLKPCE; - CLKPR = 0; - } + #endif + #ifdef USE_DYNAMIC_UNDERCLOCKING + auto_clock_speed(); #endif if (state == strobe_state) { @@ -995,7 +976,7 @@ void loop() { set_level(MAX_LEVEL); if (strobe_type == 0) { // party strobe if (strobe_delays[strobe_type] < 42) delay_zero(); - else delay_ms(1); + else nice_delay_ms(1); } else { //tactical strobe nice_delay_ms(strobe_delays[strobe_type] >> 1); } diff --git a/spaghetti-monster/fsm-events.c b/spaghetti-monster/fsm-events.c index 5448feb..e965224 100644 --- a/spaghetti-monster/fsm-events.c +++ b/spaghetti-monster/fsm-events.c @@ -116,8 +116,26 @@ inline void interrupt_nice_delays() { nice_delay_interrupt = 1; } // 1: normal completion uint8_t nice_delay_ms(uint16_t ms) { StatePtr old_state = current_state; + /* // delay_zero() implementation + if (ms == 0) { + CLKPR = 1<<CLKPCE; CLKPR = 0; // full speed + _delay_loop_2(BOGOMIPS*98/100/3); + return 1; + } + */ while(ms-- > 0) { + #ifdef USE_DYNAMIC_UNDERCLOCKING + // underclock MCU to save power + CLKPR = 1<<CLKPCE; CLKPR = 2; + // wait + _delay_loop_2(BOGOMIPS*98/100/4); + // restore regular clock speed + CLKPR = 1<<CLKPCE; CLKPR = 0; + #else + // wait _delay_loop_2(BOGOMIPS*98/100); + #endif + process_emissions(); if ((nice_delay_interrupt) || (old_state != current_state)) { nice_delay_interrupt = 0; @@ -127,6 +145,18 @@ uint8_t nice_delay_ms(uint16_t ms) { return 1; } +#ifdef USE_DYNAMIC_UNDERCLOCKING +void delay_4ms(uint8_t ms) { + while(ms-- > 0) { + // underclock MCU to save power + CLKPR = 1<<CLKPCE; CLKPR = 2; + // wait + _delay_loop_2(BOGOMIPS*98/100); + // restore regular clock speed + CLKPR = 1<<CLKPCE; CLKPR = 0; + } +} +#endif /* uint8_t nice_delay_4ms(uint8_t ms) { return nice_delay_ms((uint16_t)ms << 2); diff --git a/spaghetti-monster/fsm-misc.c b/spaghetti-monster/fsm-misc.c index 5d28002..1b8f864 100644 --- a/spaghetti-monster/fsm-misc.c +++ b/spaghetti-monster/fsm-misc.c @@ -20,6 +20,25 @@ #ifndef FSM_MISC_C #define FSM_MISC_C +#ifdef USE_DYNAMIC_UNDERCLOCKING +void auto_clock_speed() { + uint8_t level = actual_level; // volatile, avoid repeat access + if (level < QUARTERSPEED_LEVEL) { + // run at quarter speed + // note: this only works when executed as two consecutive instructions + // (don't try to combine them or put other stuff between) + CLKPR = 1<<CLKPCE; CLKPR = 2; + } + else if (level < HALFSPEED_LEVEL) { + // run at half speed + CLKPR = 1<<CLKPCE; CLKPR = 1; + } else { + // run at full speed + CLKPR = 1<<CLKPCE; CLKPR = 0; + } +} +#endif + #if defined(USE_BLINK_NUM) || defined(USE_BLINK_DIGIT) uint8_t blink_digit(uint8_t num) { //StatePtr old_state = current_state; diff --git a/spaghetti-monster/fsm-misc.h b/spaghetti-monster/fsm-misc.h index 58667a1..5e4f3d6 100644 --- a/spaghetti-monster/fsm-misc.h +++ b/spaghetti-monster/fsm-misc.h @@ -20,6 +20,10 @@ #ifndef FSM_MISC_H #define FSM_MISC_H +#ifdef USE_DYNAMIC_UNDERCLOCKING +void auto_clock_speed(); +#endif + #if defined(USE_BLINK_NUM) || defined(USE_BLINK_DIGIT) #ifndef BLINK_BRIGHTNESS #define BLINK_BRIGHTNESS (MAX_LEVEL/6) diff --git a/spaghetti-monster/fsm-ramping.c b/spaghetti-monster/fsm-ramping.c index cc5f486..11e56a5 100644 --- a/spaghetti-monster/fsm-ramping.c +++ b/spaghetti-monster/fsm-ramping.c @@ -57,6 +57,9 @@ void set_level(uint8_t level) { PWM4_LVL = pgm_read_byte(pwm4_levels + level); #endif } + #ifdef USE_DYNAMIC_UNDERCLOCKING + auto_clock_speed(); + #endif } #ifdef USE_SET_LEVEL_GRADUALLY diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h index 0914186..900630c 100644 --- a/spaghetti-monster/fsm-ramping.h +++ b/spaghetti-monster/fsm-ramping.h @@ -69,6 +69,8 @@ void gradual_tick(); PROGMEM const uint8_t pwm1_levels[] = { 1,1,2,2,3,3,4,4,5,6,7,8,9,10,12,13,14,15,17,19,20,22,24,26,29,31,34,36,39,42,45,48,51,55,59,62,66,70,75,79,84,89,93,99,104,110,115,121,127,134,140,147,154,161,168,176,184,192,200,209,217,226,236,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 }; PROGMEM const uint8_t pwm2_levels[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,4,5,7,8,9,11,12,14,15,17,19,20,22,24,25,27,29,31,33,35,37,39,41,43,45,48,50,52,55,57,59,62,64,67,70,72,75,78,81,84,87,90,93,96,99,102,105,109,112,115,119,122,126,129,133,137,141,144,148,152,156,160,165,169,173,177,182,186,191,195,200,205,209,214,219,224,229,234,239,244,250,255 }; #define MAX_1x7135 65 + #define HALFSPEED_LEVEL 14 + #define QUARTERSPEED_LEVEL 5 #endif #elif PWM_CHANNELS == 3 #if RAMP_LENGTH == 50 |
