diff options
| -rw-r--r-- | spaghetti-monster/anduril/anduril.c | 13 | ||||
| -rw-r--r-- | spaghetti-monster/baton/baton-simpler.c | 8 | ||||
| -rw-r--r-- | spaghetti-monster/baton/baton.c | 3 | ||||
| -rw-r--r-- | spaghetti-monster/darkhorse/darkhorse.c | 13 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-events.c | 4 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-main.c | 89 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-misc.c | 2 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-standby.h | 7 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-states.c | 11 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-states.h | 2 | ||||
| -rw-r--r-- | spaghetti-monster/momentary/momentary.c | 4 | ||||
| -rw-r--r-- | spaghetti-monster/ramping-ui/ramping-ui.c | 3 | ||||
| -rw-r--r-- | tk-attiny.h | 18 |
13 files changed, 91 insertions, 86 deletions
diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c index 998c0c5..c27ca68 100644 --- a/spaghetti-monster/anduril/anduril.c +++ b/spaghetti-monster/anduril/anduril.c @@ -114,9 +114,6 @@ uint8_t pseudo_rand(); // beacon timing volatile uint8_t beacon_seconds = 2; -// deferred "off" so we won't suspend in a weird state -volatile uint8_t go_to_standby = 0; - uint8_t off_state(EventPtr event, uint16_t arg) { // turn emitter off when entering state @@ -452,8 +449,8 @@ uint8_t goodnight_state(EventPtr event, uint16_t arg) { static uint16_t ticks_since_stepdown = 0; // blink on start if (event == EV_enter_state) { - blink_confirm(4); ticks_since_stepdown = 0; + blink_confirm(2); set_level(GOODNIGHT_LEVEL); return MISCHIEF_MANAGED; } @@ -871,14 +868,6 @@ void setup() { void loop() { - // deferred "off" so we won't suspend in a weird state - // (like... during the middle of a strobe pulse) - if (go_to_standby) { - go_to_standby = 0; - set_level(0); - standby_mode(); - } - if (current_state == strobe_state) { // party / tactical strobe if (strobe_type < 2) { diff --git a/spaghetti-monster/baton/baton-simpler.c b/spaghetti-monster/baton/baton-simpler.c index a6ddf36..96b0ea7 100644 --- a/spaghetti-monster/baton/baton-simpler.c +++ b/spaghetti-monster/baton/baton-simpler.c @@ -36,9 +36,6 @@ uint8_t actual_level = 0; uint8_t target_level = 0; #endif -// deferred "off" so we won't suspend in a weird state -volatile uint8_t go_to_standby = 0; - // moon + ../../bin/level_calc.py 2 6 7135 18 10 150 FET 1 10 1500 uint8_t pwm1_levels[] = { 3, 18, 110, 255, 255, 255, 0, }; uint8_t pwm2_levels[] = { 0, 0, 0, 9, 58, 138, 255, }; @@ -194,9 +191,4 @@ void setup() { } void loop() { - if (go_to_standby) { - go_to_standby = 0; - PWM1_LVL = 0; PWM2_LVL = 0; - standby_mode(); - } } diff --git a/spaghetti-monster/baton/baton.c b/spaghetti-monster/baton/baton.c index 515f2d0..1266ddd 100644 --- a/spaghetti-monster/baton/baton.c +++ b/spaghetti-monster/baton/baton.c @@ -56,8 +56,7 @@ uint8_t off_state(EventPtr event, uint16_t arg) { PWM1_LVL = 0; PWM2_LVL = 0; // sleep while off (lower power use) - //empty_event_sequence(); // just in case (but shouldn't be needed) - standby_mode(); + go_to_standby = 1; return 0; } // hold (initially): go to lowest level, but allow abort for regular click diff --git a/spaghetti-monster/darkhorse/darkhorse.c b/spaghetti-monster/darkhorse/darkhorse.c index 2aa3e90..97053b5 100644 --- a/spaghetti-monster/darkhorse/darkhorse.c +++ b/spaghetti-monster/darkhorse/darkhorse.c @@ -55,7 +55,7 @@ uint8_t L2 = 1; uint8_t M2 = 1; uint8_t H2 = 1; // mode groups, ish -uint8_t low_modes[] = {12, 1, 4, 9}; // 3.3 lm, 2.0 lm, 0.8 lm, 0.3 lm +uint8_t low_modes[] = {12, 3, 5, 9}; // 3.3 lm, 2.0 lm, 0.8 lm, 0.3 lm uint8_t med_modes[] = {56, 21, 29, 37}; // 101 lm, 35 lm, 20 lm, 10 lm uint8_t hi_modes[] = {MAX_LEVEL, 81, 96, 113}; // 1500 lm, 678 lm, 430 lm, 270 lm // strobe/beacon modes: @@ -65,9 +65,6 @@ uint8_t hi_modes[] = {MAX_LEVEL, 81, 96, 113}; // 1500 lm, 678 lm, 430 lm, 270 // 3: 19 Hz strobe at H1 uint8_t strobe_beacon_mode = 0; -// deferred "off" so we won't suspend in a weird state -volatile uint8_t go_to_standby = 0; - #ifdef USE_THERMAL_REGULATION // brightness before thermal step-down uint8_t target_level = 0; @@ -337,14 +334,6 @@ void setup() { } void loop() { - // deferred "off" so we won't suspend in a weird state - // (like... during the middle of a strobe pulse) - if (go_to_standby) { - go_to_standby = 0; - set_level(0); - standby_mode(); - } - if (current_state == strobe_beacon_state) { switch(strobe_beacon_mode) { // 0.2 Hz beacon at L1 diff --git a/spaghetti-monster/fsm-events.c b/spaghetti-monster/fsm-events.c index 99a6a72..5448feb 100644 --- a/spaghetti-monster/fsm-events.c +++ b/spaghetti-monster/fsm-events.c @@ -170,8 +170,4 @@ void emit_current_event(uint16_t arg) { //return err; } -// TODO? add events to a queue when inside an interrupt -// instead of calling the event functions directly? -// (then empty the queue in main loop?) - #endif diff --git a/spaghetti-monster/fsm-main.c b/spaghetti-monster/fsm-main.c index 9505322..d526455 100644 --- a/spaghetti-monster/fsm-main.c +++ b/spaghetti-monster/fsm-main.c @@ -22,6 +22,20 @@ #include "fsm-main.h" +#if PWM_CHANNELS == 4 +// 4th PWM channel requires manually turning the pin on/off via interrupt :( +ISR(TIMER1_OVF_vect) { + //bitClear(PORTB, 3); + PORTB &= 0b11110111; + //PORTB |= 0b00001000; +} +ISR(TIMER1_COMPA_vect) { + //if (!bitRead(TIFR,TOV1)) bitSet(PORTB, 3); + if (! (TIFR & (1<<TOV1))) PORTB |= 0b00001000; + //if (! (TIFR & (1<<TOV1))) PORTB &= 0b11110111; +} +#endif + int main() { // Don't allow interrupts while booting cli(); @@ -29,49 +43,39 @@ int main() { //PCINT_off(); // configure PWM channels - #if PWM_CHANNELS == 1 + #if PWM_CHANNELS >= 1 DDRB |= (1 << PWM1_PIN); TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...) TCCR0A = PHASE; - #elif PWM_CHANNELS == 2 - DDRB |= (1 << PWM1_PIN); - DDRB |= (1 << PWM2_PIN); - TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...) - TCCR0A = PHASE; - #elif PWM_CHANNELS == 3 - DDRB |= (1 << PWM1_PIN); - DDRB |= (1 << PWM2_PIN); - TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...) - TCCR0A = PHASE; - // Second PWM counter is ... weird - DDRB |= (1 << PWM3_PIN); - TCCR1 = _BV (CS10); - GTCCR = _BV (COM1B1) | _BV (PWM1B); - OCR1C = 255; // Set ceiling value to maximum - #elif PWM_CHANNELS == 4 - DDRB |= (1 << PWM1_PIN); + #endif + #if PWM_CHANNELS >= 2 DDRB |= (1 << PWM2_PIN); - TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...) - TCCR0A = PHASE; + #endif + #if PWM_CHANNELS >= 3 // Second PWM counter is ... weird DDRB |= (1 << PWM3_PIN); - // FIXME: How exactly do we do PWM on channel 4? TCCR1 = _BV (CS10); GTCCR = _BV (COM1B1) | _BV (PWM1B); OCR1C = 255; // Set ceiling value to maximum + #endif + #if PWM_CHANNELS >= 4 + // 4th PWM channel is ... not actually supported in hardware :( DDRB |= (1 << PWM4_PIN); + //OCR1C = 255; // Set ceiling value to maximum + TCCR1 = 1<<CTC1 | 1<<PWM1A | 3<<COM1A0 | 2<<CS10; + GTCCR = (2<<COM1B0) | (1<<PWM1B); + // set up an interrupt to control PWM4 pin + TIMSK |= (1<<OCIE1A) | (1<<TOIE1); #endif - // TODO: turn on ADC? // configure e-switch PORTB = (1 << SWITCH_PIN); // e-switch is the only input PCMSK = (1 << SWITCH_PIN); // pin change interrupt uses this pin - // TODO: configure sleep mode + // configure sleep mode set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Read config values and saved state - // restore_state(); // TODO // TODO: handle long press vs short press (or even medium press)? @@ -85,9 +89,6 @@ int main() { ADC_on(); sei(); - // fallback for handling a few things - push_state(default_state, 0); - // in case any spurious button presses were detected at boot #ifdef USE_DELAY_MS delay_ms(1); @@ -96,17 +97,43 @@ int main() { #endif empty_event_sequence(); + // fallback for handling a few things + #ifndef DONT_USE_DEFAULT_STATE + push_state(default_state, 0); + #endif + // call recipe's setup setup(); // main loop while (1) { - // TODO: update e-switch press state? - // TODO: check voltage? - // TODO: check temperature? - // if event queue not empty, process and pop first item in queue? + // if event queue not empty, empty it process_emissions(); + // enter standby mode if requested + // (works better if deferred like this) + if (go_to_standby) { + go_to_standby = 0; + #ifdef USE_RAMPING + set_level(0); + #else + #if PWM_CHANNELS >= 1 + PWM1_LVL = 0; + #endif + #if PWM_CHANNELS >= 2 + PWM2_LVL = 0; + #endif + #if PWM_CHANNELS >= 3 + PWM3_LVL = 0; + #endif + #if PWM_CHANNELS >= 4 + PWM4_LVL = 255; // inverted :( + #endif + #endif + standby_mode(); + } + + // give the recipe some time slices loop(); } } diff --git a/spaghetti-monster/fsm-misc.c b/spaghetti-monster/fsm-misc.c index 7322a59..5d28002 100644 --- a/spaghetti-monster/fsm-misc.c +++ b/spaghetti-monster/fsm-misc.c @@ -30,7 +30,7 @@ uint8_t blink_digit(uint8_t num) { for (; num>0; num--) { set_level(BLINK_BRIGHTNESS); - if (! nice_delay_ms(ontime)) { set_level(0); return 0; } + if (! nice_delay_ms(ontime)) { return 0; } set_level(0); //if (current_state != old_state) return 0; if (! nice_delay_ms(400)) return 0; diff --git a/spaghetti-monster/fsm-standby.h b/spaghetti-monster/fsm-standby.h index baeb6af..a23bd0c 100644 --- a/spaghetti-monster/fsm-standby.h +++ b/spaghetti-monster/fsm-standby.h @@ -20,7 +20,14 @@ #ifndef FSM_STANDBY_H #define FSM_STANDBY_H +// deferred "off" so we won't suspend in a weird state +// (like... during the middle of a strobe pulse) +// set this to nonzero to enter standby mode next time the system is idle +volatile uint8_t go_to_standby = 0; + #define standby_mode sleep_until_eswitch_pressed void sleep_until_eswitch_pressed(); +// TODO: half-sleep "twilight" mode with WDT on but running slowly + #endif diff --git a/spaghetti-monster/fsm-states.c b/spaghetti-monster/fsm-states.c index 2939475..09ae804 100644 --- a/spaghetti-monster/fsm-states.c +++ b/spaghetti-monster/fsm-states.c @@ -67,26 +67,28 @@ StatePtr pop_state() { if (state_stack_len > 0) { new_state = state_stack[state_stack_len-1]; } - // FIXME: what should 'arg' be? + // FIXME: what should 'arg' be? (maybe re-entry should be entry with arg+1?) _set_state(new_state, 0, EV_leave_state, EV_reenter_state); return old_state; } uint8_t set_state(StatePtr new_state, uint16_t arg) { // FIXME: this calls exit/enter hooks it shouldn't + // (for the layer underneath the top) pop_state(); return push_state(new_state, arg); } +#ifndef DONT_USE_DEFAULT_STATE // bottom state on stack // handles default actions for LVP, thermal regulation, etc uint8_t default_state(EventPtr event, uint16_t arg) { - if (0) {} + if (0) {} // this should get compiled out #ifdef USE_LVP else if (event == EV_voltage_low) { low_voltage(); - return 0; + return EVENT_HANDLED; } #endif @@ -105,7 +107,8 @@ uint8_t default_state(EventPtr event, uint16_t arg) { #endif // event not handled - return 1; + return EVENT_NOT_HANDLED; } +#endif #endif diff --git a/spaghetti-monster/fsm-states.h b/spaghetti-monster/fsm-states.h index f92abba..6e4a2a0 100644 --- a/spaghetti-monster/fsm-states.h +++ b/spaghetti-monster/fsm-states.h @@ -40,6 +40,8 @@ void _set_state(StatePtr new_state, uint16_t arg, int8_t push_state(StatePtr new_state, uint16_t arg); StatePtr pop_state(); uint8_t set_state(StatePtr new_state, uint16_t arg); +#ifndef DONT_USE_DEFAULT_STATE uint8_t default_state(EventPtr event, uint16_t arg); +#endif #endif diff --git a/spaghetti-monster/momentary/momentary.c b/spaghetti-monster/momentary/momentary.c index 6b049f4..d4ac1db 100644 --- a/spaghetti-monster/momentary/momentary.c +++ b/spaghetti-monster/momentary/momentary.c @@ -52,7 +52,7 @@ uint8_t momentary_state(EventPtr event, uint16_t arg) { else if (event == EV_release) { light_off(); empty_event_sequence(); // don't attempt to parse multiple clicks - standby_mode(); // sleep while light is off + go_to_standby = 1; // sleep while light is off return 0; } @@ -68,7 +68,7 @@ void low_voltage() { } else { debug_blink(8); light_off(); - standby_mode(); + go_to_standby = 1; } } diff --git a/spaghetti-monster/ramping-ui/ramping-ui.c b/spaghetti-monster/ramping-ui/ramping-ui.c index 527a824..e6f571d 100644 --- a/spaghetti-monster/ramping-ui/ramping-ui.c +++ b/spaghetti-monster/ramping-ui/ramping-ui.c @@ -59,8 +59,7 @@ uint8_t off_state(EventPtr event, uint16_t arg) { if (event == EV_enter_state) { set_level(0); // sleep while off (lower power use) - //empty_event_sequence(); // just in case (but shouldn't be needed) - standby_mode(); + go_to_standby = 1; return MISCHIEF_MANAGED; } // hold (initially): go to lowest level, but allow abort for regular click diff --git a/tk-attiny.h b/tk-attiny.h index 7939ccc..887a151 100644 --- a/tk-attiny.h +++ b/tk-attiny.h @@ -188,6 +188,7 @@ #define PWM2_PIN PB1 // pin 6, FET PWM #define PWM2_LVL OCR0B // OCR0B is the output compare register for PB1 +// (FIXME: remove? not used?) #define VOLTAGE_PIN PB2 // pin 7, voltage ADC #define ADC_CHANNEL 0x01 // MUX 01 corresponds with PB2 #define ADC_DIDR ADC1D // Digital input disable bit corresponding with PB2 @@ -208,7 +209,7 @@ * ---- * Reset -|1 8|- VCC * PWM 4 (A) -|2 7|- e-switch - * PWM 3 (B) -|3 6|- PWM 2 (G) + * PWM 3 (G) -|3 6|- PWM 2 (B) * GND -|4 5|- PWM 1 (R) * ---- */ @@ -221,17 +222,18 @@ #define PWM3_PIN PB4 // pin 3 #define PWM3_LVL OCR1B #define PWM4_PIN PB3 // pin 2 -#define PWM4_LVL OCR1A // FIXME: does this work? +#define PWM4_LVL OCR1A -#define SWITCH_PIN PB2 // pin 7 +#define SWITCH_PIN PB2 // pin 7 #define SWITCH_PCINT PCINT2 // pin 7 pin change interrupt -#define ADC_PRSCL 0x07 // clk/128 (no need to be super fast) -// FIXME: What is the DIDR for pin 8? -//#define ADC_DIDR ADC1D // Digital input disable bit corresponding with PB2 +#define ADC_PRSCL 0x06 // clk/64 (no need to be super fast) -#define FAST 0xA3 // fast PWM both channels -#define PHASE 0xA1 // phase-correct PWM both channels +//#define TEMP_DIDR ADC4D +#define TEMP_CHANNEL 0b00001111 + +#define FAST 0xA3 // fast PWM both channels +#define PHASE 0xA1 // phase-correct PWM both channels #endif // TKSABER_DRIVER |
