diff options
| author | Selene ToyKeeper | 2017-09-03 14:58:22 -0600 |
|---|---|---|
| committer | Selene ToyKeeper | 2017-09-03 14:58:22 -0600 |
| commit | a419850e536f00549120255a627137faffded47a (patch) | |
| tree | 60976f561f189d6e5e08a581bdc3824f163f65be | |
| parent | Added UI2. UI2 is weird. (diff) | |
| download | anduril-a419850e536f00549120255a627137faffded47a.tar.gz anduril-a419850e536f00549120255a627137faffded47a.tar.bz2 anduril-a419850e536f00549120255a627137faffded47a.zip | |
Got the 4th PWM channel to work, ish. (channel 4 is inverted though)
Moved go_to_suspend thing into main() instead of making each UI handle that during loop().
Made default_state() optional.
Fixed bug where battcheck and other number readouts could interfere with the state which interrupted them.
(they would sometimes turn the LED off after the new state had already started)
Updated darkhorse's moon levels to match new ramp on D4 hardware.
| -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 |
