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
If you find this content useful please consider a small donation via bitcoin: bitcoin:1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2?amount=0.001&message=Donation Scraping git contents via cgit is very resource intensive. The continued hosting of these git repositories is entirely financed by your bitcoin contributions. For donations of a least 1 mBTC you include your IP address in the message of your bitcoin donation. This will remove this message in the future for requests from your IP, which will significantly reduce token usage. In any case, any contributions to bitcoin address 1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2 are very welcome. Thanks in advance for you contribution to a self-sustaining ecosystem.