aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spaghetti-monster/anduril/anduril.c145
-rw-r--r--spaghetti-monster/fireflies-ui/fireflies-ui.c35
2 files changed, 171 insertions, 9 deletions
diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c
index 09c7927..5bbf39b 100644
--- a/spaghetti-monster/anduril/anduril.c
+++ b/spaghetti-monster/anduril/anduril.c
@@ -2,7 +2,7 @@
* Anduril: Narsil-inspired UI for SpaghettiMonster.
* (Anduril is Aragorn's sword, the blade Narsil reforged)
*
- * Copyright (C) 2017 Selene ToyKeeper
+ * Copyright (C) 2017-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
@@ -54,11 +54,25 @@
#define USE_LIGHTNING_MODE
#define USE_CANDLE_MODE
+// enable sunset (goodnight) mode
+#define USE_GOODNIGHT_MODE
+#define GOODNIGHT_TIME 60 // minutes (approximately)
+#define GOODNIGHT_LEVEL 24 // ~11 lm
+
+// enable beacon mode
+#define USE_BEACON_MODE
+
//Muggle mode for easy UI
#define USE_MUGGLE_MODE
-#define GOODNIGHT_TIME 60 // minutes (approximately)
-#define GOODNIGHT_LEVEL 24 // ~11 lm
+// make the ramps configurable by the user
+#define USE_RAMP_CONFIG
+
+// boring strobes nobody really likes, but sometimes flashlight companies want
+// (these replace the fun strobe group,
+// so don't enable them at the same time as any of the above strobes)
+//#define USE_POLICE_STROBE_MODE
+//#define USE_SOS_MODE
// dual-switch support (second switch is a tail clicky)
//#define START_AT_MEMORIZED_LEVEL
@@ -116,6 +130,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 +153,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 +193,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 +213,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 +355,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 +458,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) {
@@ -463,6 +502,13 @@ uint8_t off_state(Event event, uint16_t arg) {
return MISCHIEF_MANAGED;
}
#endif
+ #ifdef USE_TENCLICK_THERMAL_CONFIG
+ // 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 +587,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 +1046,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
@@ -1037,6 +1128,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 +1153,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;
@@ -1101,6 +1195,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 +1533,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 +1565,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
@@ -1495,9 +1592,10 @@ uint8_t thermal_config_state(Event event, uint16_t arg) {
return config_state_base(event, arg,
2, thermal_config_save);
}
-#endif
+#endif // #ifdef USE_THERMAL_REGULATION
+#ifdef USE_BEACON_MODE
void beacon_config_save() {
// parse values
uint8_t val = config_state_values[0];
@@ -1510,6 +1608,7 @@ uint8_t beacon_config_state(Event event, uint16_t arg) {
return config_state_base(event, arg,
1, beacon_config_save);
}
+#endif // #ifdef USE_BEACON_MODE
uint8_t number_entry_state(Event event, uint16_t arg) {
@@ -1676,11 +1775,13 @@ uint8_t triangle_wave(uint8_t phase) {
void load_config() {
if (load_eeprom()) {
ramp_style = eeprom[ramp_style_e];
+ #ifdef USE_RAMP_CONFIG
ramp_smooth_floor = eeprom[ramp_smooth_floor_e];
ramp_smooth_ceil = eeprom[ramp_smooth_ceil_e];
ramp_discrete_floor = eeprom[ramp_discrete_floor_e];
ramp_discrete_ceil = eeprom[ramp_discrete_ceil_e];
ramp_discrete_steps = eeprom[ramp_discrete_steps_e];
+ #endif
#if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE)
strobe_type = eeprom[strobe_type_e]; // TODO: move this to eeprom_wl?
strobe_delays[0] = eeprom[strobe_delays_0_e];
@@ -1689,7 +1790,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
@@ -1710,11 +1813,13 @@ void load_config() {
void save_config() {
eeprom[ramp_style_e] = ramp_style;
+ #ifdef USE_RAMP_CONFIG
eeprom[ramp_smooth_floor_e] = ramp_smooth_floor;
eeprom[ramp_smooth_ceil_e] = ramp_smooth_ceil;
eeprom[ramp_discrete_floor_e] = ramp_discrete_floor;
eeprom[ramp_discrete_ceil_e] = ramp_discrete_ceil;
eeprom[ramp_discrete_steps_e] = ramp_discrete_steps;
+ #endif
#if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE)
eeprom[strobe_type_e] = strobe_type; // TODO: move this to eeprom_wl?
eeprom[strobe_delays_0_e] = strobe_delays[0];
@@ -1723,7 +1828,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 +2033,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 +2074,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 {
diff --git a/spaghetti-monster/fireflies-ui/fireflies-ui.c b/spaghetti-monster/fireflies-ui/fireflies-ui.c
index 5ad5ad0..ba30605 100644
--- a/spaghetti-monster/fireflies-ui/fireflies-ui.c
+++ b/spaghetti-monster/fireflies-ui/fireflies-ui.c
@@ -54,11 +54,25 @@
#define USE_LIGHTNING_MODE
#define USE_CANDLE_MODE
+// enable sunset (goodnight) mode
+#define USE_GOODNIGHT_MODE
+#define GOODNIGHT_TIME 60 // minutes (approximately)
+#define GOODNIGHT_LEVEL 24 // ~11 lm
+
+// enable beacon mode
+#define USE_BEACON_MODE
+
//Muggle mode for easy UI
#define USE_MUGGLE_MODE
-#define GOODNIGHT_TIME 60 // minutes (approximately)
-#define GOODNIGHT_LEVEL 24 // ~11 lm
+// make the ramps configurable by the user
+#define USE_RAMP_CONFIG
+
+// boring strobes nobody really likes, but sometimes flashlight companies want
+// (these replace the fun strobe group,
+// so don't enable them at the same time as any of the above strobes)
+//#define USE_POLICE_STROBE_MODE
+//#define USE_SOS_MODE
// dual-switch support (second switch is a tail clicky)
//#define START_AT_MEMORIZED_LEVEL
@@ -67,7 +81,7 @@
#include "tk.h"
#include incfile(CONFIGFILE)
-// Fireflies-specific configuration
+///// Fireflies-specific configuration
// disable ramp config
#ifdef USE_RAMP_CONFIG
#undef USE_RAMP_CONFIG
@@ -107,6 +121,11 @@
#define USE_POLICE_STROBE_MODE
#define USE_SOS_MODE
+// thermal config mode on 10 clicks from off
+#define USE_TENCLICK_THERMAL_CONFIG
+
+///// end Fireflies-specific configuration
+
// thermal properties, if not defined per-driver
#ifndef MIN_THERM_STEPDOWN
#define MIN_THERM_STEPDOWN MAX_1x7135 // lowest value it'll step down to
@@ -514,11 +533,13 @@ uint8_t off_state(Event event, uint16_t arg) {
set_state(tempcheck_state, 0);
return MISCHIEF_MANAGED;
}
+ #ifdef USE_TENCLICK_THERMAL_CONFIG
// 10 clicks: thermal config mode
else if (event == EV_10clicks) {
push_state(thermal_config_state, 0);
return MISCHIEF_MANAGED;
}
+ #endif
return EVENT_NOT_HANDLED;
}
@@ -1614,7 +1635,7 @@ uint8_t thermal_config_state(Event event, uint16_t arg) {
return config_state_base(event, arg,
2, thermal_config_save);
}
-#endif
+#endif // #ifdef USE_THERMAL_REGULATION
#ifdef USE_BEACON_MODE
@@ -1630,7 +1651,7 @@ uint8_t beacon_config_state(Event event, uint16_t arg) {
return config_state_base(event, arg,
1, beacon_config_save);
}
-#endif
+#endif // #ifdef USE_BEACON_MODE
uint8_t number_entry_state(Event event, uint16_t arg) {
@@ -1797,11 +1818,13 @@ uint8_t triangle_wave(uint8_t phase) {
void load_config() {
if (load_eeprom()) {
ramp_style = eeprom[ramp_style_e];
+ #ifdef USE_RAMP_CONFIG
ramp_smooth_floor = eeprom[ramp_smooth_floor_e];
ramp_smooth_ceil = eeprom[ramp_smooth_ceil_e];
ramp_discrete_floor = eeprom[ramp_discrete_floor_e];
ramp_discrete_ceil = eeprom[ramp_discrete_ceil_e];
ramp_discrete_steps = eeprom[ramp_discrete_steps_e];
+ #endif
#if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE)
strobe_type = eeprom[strobe_type_e]; // TODO: move this to eeprom_wl?
strobe_delays[0] = eeprom[strobe_delays_0_e];
@@ -1833,11 +1856,13 @@ void load_config() {
void save_config() {
eeprom[ramp_style_e] = ramp_style;
+ #ifdef USE_RAMP_CONFIG
eeprom[ramp_smooth_floor_e] = ramp_smooth_floor;
eeprom[ramp_smooth_ceil_e] = ramp_smooth_ceil;
eeprom[ramp_discrete_floor_e] = ramp_discrete_floor;
eeprom[ramp_discrete_ceil_e] = ramp_discrete_ceil;
eeprom[ramp_discrete_steps_e] = ramp_discrete_steps;
+ #endif
#if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE)
eeprom[strobe_type_e] = strobe_type; // TODO: move this to eeprom_wl?
eeprom[strobe_delays_0_e] = strobe_delays[0];
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.