aboutsummaryrefslogtreecommitdiff
path: root/spaghetti-monster/fireflies-ui/fireflies-ui.c
diff options
context:
space:
mode:
authorSelene ToyKeeper2019-03-12 01:45:40 -0600
committerSelene ToyKeeper2019-03-12 01:45:40 -0600
commit3a5ed200c051a3e54b4ad6ae5bf719516d2fa267 (patch)
tree941e38c42d51d7509c2efed8f4d1f8d02a4781a2 /spaghetti-monster/fireflies-ui/fireflies-ui.c
parentconfig file for unnamed Fireflies EDC thrower, with spec'd values (diff)
downloadanduril-3a5ed200c051a3e54b4ad6ae5bf719516d2fa267.tar.gz
anduril-3a5ed200c051a3e54b4ad6ae5bf719516d2fa267.tar.bz2
anduril-3a5ed200c051a3e54b4ad6ae5bf719516d2fa267.zip
first working rev of Fireflies UI, with changes basically as minimal as possible
from Anduril to make it easier to keep the two in sync later - changed name - changed default config file - disabled ramp config - disabled muggle mode - disabled entire strobe group - disabled goodnight and beacon mode - made battcheck group only one mode, not a group - added boring strobe group (police strobe, SOS) - changed "7 clicks from off" to tempcheck mode - added "10 clicks from off" for thermal config mode - made stuff able to be turned off at compile time: - beacon mode - ramp config - goodnight mode
Diffstat (limited to 'spaghetti-monster/fireflies-ui/fireflies-ui.c')
-rw-r--r--spaghetti-monster/fireflies-ui/fireflies-ui.c197
1 files changed, 176 insertions, 21 deletions
diff --git a/spaghetti-monster/fireflies-ui/fireflies-ui.c b/spaghetti-monster/fireflies-ui/fireflies-ui.c
index 09c7927..5ad5ad0 100644
--- a/spaghetti-monster/fireflies-ui/fireflies-ui.c
+++ b/spaghetti-monster/fireflies-ui/fireflies-ui.c
@@ -1,8 +1,8 @@
/*
- * Anduril: Narsil-inspired UI for SpaghettiMonster.
- * (Anduril is Aragorn's sword, the blade Narsil reforged)
+ * Fireflies UI: A custom UI for Fireflies-brand flashlights.
+ * (based on Anduril by ToyKeeper)
*
- * Copyright (C) 2017 Selene ToyKeeper
+ * Copyright (C) 2019 Selene ToyKeeper
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,8 +19,8 @@
*/
/********* User-configurable options *********/
-// Anduril config file name (set it here or define it at the gcc command line)
-//#define CONFIGFILE cfg-blf-q8.h
+// UI config file name (set it here or define it at the gcc command line)
+//#define CONFIGFILE cfg-ff-pl47.h
#define USE_LVP // FIXME: won't build when this option is turned off
@@ -67,6 +67,45 @@
#include "tk.h"
#include incfile(CONFIGFILE)
+// Fireflies-specific configuration
+// disable ramp config
+#ifdef USE_RAMP_CONFIG
+#undef USE_RAMP_CONFIG
+#endif
+
+// no muggle mode
+#ifdef USE_MUGGLE_MODE
+#undef USE_MUGGLE_MODE
+#endif
+
+// turn off strobe mode entirely; we're replacing it
+#ifdef USE_BIKE_FLASHER_MODE
+#undef USE_BIKE_FLASHER_MODE
+#endif
+#ifdef USE_PARTY_STROBE_MODE
+#undef USE_PARTY_STROBE_MODE
+#endif
+#ifdef USE_TACTICAL_STROBE_MODE
+#undef USE_TACTICAL_STROBE_MODE
+#endif
+#ifdef USE_LIGHTNING_MODE
+#undef USE_LIGHTNING_MODE
+#endif
+#ifdef USE_CANDLE_MODE
+#undef USE_CANDLE_MODE
+#endif
+
+// remove other blinkies too
+#ifdef USE_GOODNIGHT_MODE
+#undef USE_GOODNIGHT_MODE
+#endif
+#ifdef USE_BEACON_MODE
+#undef USE_BEACON_MODE
+#endif
+
+// use these strobes instead
+#define USE_POLICE_STROBE_MODE
+#define USE_SOS_MODE
// thermal properties, if not defined per-driver
#ifndef MIN_THERM_STEPDOWN
@@ -116,6 +155,10 @@
#define USE_STROBE_STATE
#endif
+#if defined(USE_POLICE_STROBE_MODE) || defined(USE_SOS_MODE)
+#define USE_BORING_STROBE_STATE
+#endif
+
// auto-detect how many eeprom bytes
#define USE_EEPROM
typedef enum {
@@ -135,7 +178,9 @@ typedef enum {
#ifdef USE_BIKE_FLASHER_MODE
bike_flasher_brightness_e,
#endif
+ #ifdef USE_BEACON_MODE
beacon_seconds_e,
+ #endif
#ifdef USE_MUGGLE_MODE
muggle_mode_active_e,
#endif
@@ -173,11 +218,19 @@ uint8_t config_state_base(Event event, uint16_t arg,
uint8_t config_state_values[MAX_CONFIG_VALUES];
// ramping mode and its related config mode
uint8_t steady_state(Event event, uint16_t arg);
+#ifdef USE_RAMP_CONFIG
uint8_t ramp_config_state(Event event, uint16_t arg);
+#endif
// party and tactical strobes
#ifdef USE_STROBE_STATE
uint8_t strobe_state(Event event, uint16_t arg);
#endif
+#ifdef USE_BORING_STROBE_STATE
+uint8_t boring_strobe_state(Event event, uint16_t arg);
+volatile uint8_t boring_strobe_type = 0;
+void sos_blink(uint8_t num, uint8_t dah);
+#define NUM_BORING_STROBES 2
+#endif
#ifdef USE_BATTCHECK
uint8_t battcheck_state(Event event, uint16_t arg);
#endif
@@ -185,11 +238,15 @@ uint8_t battcheck_state(Event event, uint16_t arg);
uint8_t tempcheck_state(Event event, uint16_t arg);
uint8_t thermal_config_state(Event event, uint16_t arg);
#endif
+#ifdef USE_GOODNIGHT_MODE
// 1-hour ramp down from low, then automatic off
uint8_t goodnight_state(Event event, uint16_t arg);
+#endif
+#ifdef USE_BEACON_MODE
// beacon mode and its related config mode
uint8_t beacon_state(Event event, uint16_t arg);
uint8_t beacon_config_state(Event event, uint16_t arg);
+#endif
// soft lockout
#define MOON_DURING_LOCKOUT_MODE
// if enabled, 2nd lockout click goes to the other ramp's floor level
@@ -323,8 +380,10 @@ volatile uint8_t bike_flasher_brightness = MAX_1x7135;
uint8_t triangle_wave(uint8_t phase);
#endif
+#ifdef USE_BEACON_MODE
// beacon timing
volatile uint8_t beacon_seconds = 2;
+#endif
uint8_t off_state(Event event, uint16_t arg) {
@@ -424,6 +483,11 @@ uint8_t off_state(Event event, uint16_t arg) {
set_state(strobe_state, 0);
return MISCHIEF_MANAGED;
}
+ #elif defined(USE_BORING_STROBE_STATE)
+ else if (event == EV_click3_hold) {
+ set_state(boring_strobe_state, 0);
+ return MISCHIEF_MANAGED;
+ }
#endif
// 4 clicks: soft lockout
else if (event == EV_4clicks) {
@@ -445,24 +509,16 @@ uint8_t off_state(Event event, uint16_t arg) {
return MISCHIEF_MANAGED;
}
#endif
- #ifdef USE_INDICATOR_LED
- // 7 clicks: change indicator LED mode
+ // 7 clicks: temperature check
else if (event == EV_7clicks) {
- uint8_t mode = (indicator_led_mode & 3) + 1;
- #ifdef TICK_DURING_STANDBY
- mode = mode & 3;
- #else
- mode = mode % 3;
- #endif
- #ifdef INDICATOR_LED_SKIP_LOW
- if (mode == 1) { mode ++; }
- #endif
- indicator_led_mode = (indicator_led_mode & 0b11111100) | mode;
- indicator_led(mode);
- save_config();
+ set_state(tempcheck_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+ // 10 clicks: thermal config mode
+ else if (event == EV_10clicks) {
+ push_state(thermal_config_state, 0);
return MISCHIEF_MANAGED;
}
- #endif
return EVENT_NOT_HANDLED;
}
@@ -541,11 +597,13 @@ uint8_t steady_state(Event event, uint16_t arg) {
set_level(memorized_level);
return MISCHIEF_MANAGED;
}
+ #ifdef USE_RAMP_CONFIG
// 4 clicks: configure this ramp mode
else if (event == EV_4clicks) {
push_state(ramp_config_state, 0);
return MISCHIEF_MANAGED;
}
+ #endif
// hold: change brightness (brighter)
else if (event == EV_click1_hold) {
// ramp slower in discrete mode
@@ -998,6 +1056,49 @@ uint8_t strobe_state(Event event, uint16_t arg) {
#endif // ifdef USE_STROBE_STATE
+#ifdef USE_BORING_STROBE_STATE
+uint8_t boring_strobe_state(Event event, uint16_t arg) {
+ // police strobe and SOS, meh
+ // 'st' reduces ROM size by avoiding access to a volatile var
+ // (maybe I should just make it nonvolatile?)
+ uint8_t st = boring_strobe_type;
+
+ if (event == EV_enter_state) {
+ return MISCHIEF_MANAGED;
+ }
+ // 1 click: off
+ else if (event == EV_1click) {
+ // reset to police strobe for next time
+ boring_strobe_type = 0;
+ set_state(off_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+ // 2 clicks: rotate through strobe/flasher modes
+ else if (event == EV_2clicks) {
+ boring_strobe_type = (st + 1) % NUM_BORING_STROBES;
+ return MISCHIEF_MANAGED;
+ }
+ return EVENT_NOT_HANDLED;
+}
+
+void sos_blink(uint8_t num, uint8_t dah) {
+ #define DIT_LENGTH 200
+ for (; num > 0; num--) {
+ set_level(memorized_level);
+ nice_delay_ms(DIT_LENGTH);
+ if (dah) { // dah is 3X as long as a dit
+ nice_delay_ms(DIT_LENGTH*2);
+ }
+ set_level(0);
+ // one "off" dit between blinks
+ nice_delay_ms(DIT_LENGTH);
+ }
+ // three "off" dits (or one "dah") between letters
+ nice_delay_ms(DIT_LENGTH*2);
+}
+#endif // ifdef USE_BORING_STROBE_STATE
+
+
#ifdef USE_BATTCHECK
uint8_t battcheck_state(Event event, uint16_t arg) {
// 1 click: off
@@ -1005,11 +1106,17 @@ uint8_t battcheck_state(Event event, uint16_t arg) {
set_state(off_state, 0);
return MISCHIEF_MANAGED;
}
- // 2 clicks: goodnight mode
+ #if defined(USE_GOODNIGHT_MODE) || defined(USE_BEACON_MODE)
+ // 2 clicks: next mode
else if (event == EV_2clicks) {
+ #ifdef USE_GOODNIGHT_MODE
set_state(goodnight_state, 0);
+ #elif defined(USE_BEACON_MODE)
+ set_state(beacon_state, 0);
+ #endif
return MISCHIEF_MANAGED;
}
+ #endif
return EVENT_NOT_HANDLED;
}
#endif
@@ -1022,11 +1129,13 @@ uint8_t tempcheck_state(Event event, uint16_t arg) {
set_state(off_state, 0);
return MISCHIEF_MANAGED;
}
+ #if 0 // not part of a loop in this UI
// 2 clicks: battcheck mode
else if (event == EV_2clicks) {
set_state(battcheck_state, 0);
return MISCHIEF_MANAGED;
}
+ #endif
// 4 clicks: thermal config mode
else if (event == EV_4clicks) {
push_state(thermal_config_state, 0);
@@ -1037,6 +1146,7 @@ uint8_t tempcheck_state(Event event, uint16_t arg) {
#endif
+#ifdef USE_BEACON_MODE
uint8_t beacon_state(Event event, uint16_t arg) {
// 1 click: off
if (event == EV_1click) {
@@ -1061,8 +1171,10 @@ uint8_t beacon_state(Event event, uint16_t arg) {
}
return EVENT_NOT_HANDLED;
}
+#endif
+#ifdef USE_GOODNIGHT_MODE
#define GOODNIGHT_TICKS_PER_STEPDOWN (GOODNIGHT_TIME*TICKS_PER_SECOND*60L/GOODNIGHT_LEVEL)
uint8_t goodnight_state(Event event, uint16_t arg) {
static uint16_t ticks_since_stepdown = 0;
@@ -1080,7 +1192,11 @@ uint8_t goodnight_state(Event event, uint16_t arg) {
}
// 2 clicks: beacon mode
else if (event == EV_2clicks) {
+ #ifdef USE_BEACON_MODE
set_state(beacon_state, 0);
+ #elif defined(USE_TEMPCHECK_MODE)
+ set_state(tempcheck_state, 0);
+ #endif
return MISCHIEF_MANAGED;
}
// tick: step down (maybe) or off (maybe)
@@ -1101,6 +1217,7 @@ uint8_t goodnight_state(Event event, uint16_t arg) {
}
return EVENT_NOT_HANDLED;
}
+#endif
uint8_t lockout_state(Event event, uint16_t arg) {
@@ -1438,6 +1555,7 @@ uint8_t config_state_base(Event event, uint16_t arg,
return EVENT_HANDLED;
}
+#ifdef USE_RAMP_CONFIG
void ramp_config_save() {
// parse values
uint8_t val;
@@ -1469,6 +1587,7 @@ uint8_t ramp_config_state(Event event, uint16_t arg) {
return config_state_base(event, arg,
num_config_steps, ramp_config_save);
}
+#endif // #ifdef USE_RAMP_CONFIG
#ifdef USE_THERMAL_REGULATION
@@ -1498,6 +1617,7 @@ uint8_t thermal_config_state(Event event, uint16_t arg) {
#endif
+#ifdef USE_BEACON_MODE
void beacon_config_save() {
// parse values
uint8_t val = config_state_values[0];
@@ -1510,6 +1630,7 @@ uint8_t beacon_config_state(Event event, uint16_t arg) {
return config_state_base(event, arg,
1, beacon_config_save);
}
+#endif
uint8_t number_entry_state(Event event, uint16_t arg) {
@@ -1689,7 +1810,9 @@ void load_config() {
#ifdef USE_BIKE_FLASHER_MODE
bike_flasher_brightness = eeprom[bike_flasher_brightness_e];
#endif
+ #ifdef USE_BEACON_MODE
beacon_seconds = eeprom[beacon_seconds_e];
+ #endif
#ifdef USE_MUGGLE_MODE
muggle_mode_active = eeprom[muggle_mode_active_e];
#endif
@@ -1723,7 +1846,9 @@ void save_config() {
#ifdef USE_BIKE_FLASHER_MODE
eeprom[bike_flasher_brightness_e] = bike_flasher_brightness;
#endif
+ #ifdef USE_BEACON_MODE
eeprom[beacon_seconds_e] = beacon_seconds;
+ #endif
#ifdef USE_MUGGLE_MODE
eeprom[muggle_mode_active_e] = muggle_mode_active;
#endif
@@ -1926,6 +2051,34 @@ void loop() {
}
#endif // #ifdef USE_STROBE_STATE
+ #ifdef USE_BORING_STROBE_STATE
+ if (state == boring_strobe_state) {
+ uint8_t st = boring_strobe_type;
+
+ // police strobe
+ if (st == 0) {
+ // flash at 16 Hz then 8 Hz, 8 times each
+ for (uint8_t del=41; del<100; del+=41) {
+ for (uint8_t f=0; f<8; f++) {
+ set_level(STROBE_BRIGHTNESS);
+ nice_delay_ms(del >> 1);
+ set_level(0);
+ nice_delay_ms(del);
+ }
+ }
+ }
+
+ // SOS
+ else if (st == 1) {
+ nice_delay_ms(1000);
+ sos_blink(3, 0);
+ sos_blink(3, 1);
+ sos_blink(3, 0);
+ nice_delay_ms(1000);
+ }
+ }
+ #endif // #ifdef USE_BORING_STROBE_STATE
+
#ifdef USE_BATTCHECK
else if (state == battcheck_state) {
battcheck();
@@ -1939,12 +2092,14 @@ void loop() {
}
#endif
+ #ifdef USE_BEACON_MODE
else if (state == beacon_state) {
set_level(memorized_level);
nice_delay_ms(500);
set_level(0);
nice_delay_ms(((beacon_seconds) * 1000) - 500);
}
+ #endif
#ifdef USE_IDLE_MODE
else {