aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spaghetti-monster/anduril/anduril.c29
-rw-r--r--spaghetti-monster/fsm-events.c30
-rw-r--r--spaghetti-monster/fsm-misc.c19
-rw-r--r--spaghetti-monster/fsm-misc.h4
-rw-r--r--spaghetti-monster/fsm-ramping.c3
-rw-r--r--spaghetti-monster/fsm-ramping.h2
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