From afdd12955841217ee8b95f8378204deb2fcdad34 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Tue, 12 Mar 2019 00:26:53 -0600
Subject: created directory for Fireflies UI
---
spaghetti-monster/fireflies-ui/Makefile | 7 +
spaghetti-monster/fireflies-ui/build-all.sh | 13 +
spaghetti-monster/fireflies-ui/fireflies-ui.c | 1956 +++++++++++++++++++++++++
3 files changed, 1976 insertions(+)
create mode 100644 spaghetti-monster/fireflies-ui/Makefile
create mode 100755 spaghetti-monster/fireflies-ui/build-all.sh
create mode 100644 spaghetti-monster/fireflies-ui/fireflies-ui.c
(limited to 'spaghetti-monster')
diff --git a/spaghetti-monster/fireflies-ui/Makefile b/spaghetti-monster/fireflies-ui/Makefile
new file mode 100644
index 0000000..8db198e
--- /dev/null
+++ b/spaghetti-monster/fireflies-ui/Makefile
@@ -0,0 +1,7 @@
+all:
+ ./build-all.sh
+
+clean:
+ rm -f *.hex cfg-*.h *~ *.elf *.o
+
+.phony: clean
diff --git a/spaghetti-monster/fireflies-ui/build-all.sh b/spaghetti-monster/fireflies-ui/build-all.sh
new file mode 100755
index 0000000..41d92d0
--- /dev/null
+++ b/spaghetti-monster/fireflies-ui/build-all.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+cp -av ../anduril/cfg-ff*.h .
+
+UI=fireflies-ui
+
+for TARGET in cfg-*.h ; do
+ NAME=$(echo "$TARGET" | perl -ne '/cfg-(.*).h/ && print "$1\n";')
+ echo "===== $NAME ====="
+ echo ../../../bin/build.sh 85 "$UI" "-DCONFIGFILE=${TARGET}"
+ ../../../bin/build.sh 85 "$UI" "-DCONFIGFILE=${TARGET}"
+ mv -f "$UI".hex "$UI".$NAME.hex
+done
diff --git a/spaghetti-monster/fireflies-ui/fireflies-ui.c b/spaghetti-monster/fireflies-ui/fireflies-ui.c
new file mode 100644
index 0000000..09c7927
--- /dev/null
+++ b/spaghetti-monster/fireflies-ui/fireflies-ui.c
@@ -0,0 +1,1956 @@
+/*
+ * Anduril: Narsil-inspired UI for SpaghettiMonster.
+ * (Anduril is Aragorn's sword, the blade Narsil reforged)
+ *
+ * Copyright (C) 2017 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+/********* User-configurable options *********/
+// Anduril config file name (set it here or define it at the gcc command line)
+//#define CONFIGFILE cfg-blf-q8.h
+
+#define USE_LVP // FIXME: won't build when this option is turned off
+
+// parameters for this defined below or per-driver
+#define USE_THERMAL_REGULATION
+#define DEFAULT_THERM_CEIL 45 // try not to get hotter than this
+
+// short blip when crossing from "click" to "hold" from off
+// (helps the user hit moon mode exactly, instead of holding too long
+// or too short)
+#define MOON_TIMING_HINT
+// short blips while ramping
+#define BLINK_AT_CHANNEL_BOUNDARIES
+//#define BLINK_AT_RAMP_FLOOR
+#define BLINK_AT_RAMP_CEILING
+//#define BLINK_AT_STEPS // whenever a discrete ramp mode is passed in smooth mode
+
+// ramp down via regular button hold if a ramp-up ended <1s ago
+// ("hold, release, hold" ramps down instead of up)
+#define USE_REVERSING
+
+// battery readout style (pick one)
+#define BATTCHECK_VpT
+//#define BATTCHECK_8bars // FIXME: breaks build
+//#define BATTCHECK_4bars // FIXME: breaks build
+
+// enable/disable various strobe modes
+#define USE_BIKE_FLASHER_MODE
+#define USE_PARTY_STROBE_MODE
+#define USE_TACTICAL_STROBE_MODE
+#define USE_LIGHTNING_MODE
+#define USE_CANDLE_MODE
+
+//Muggle mode for easy UI
+#define USE_MUGGLE_MODE
+
+#define GOODNIGHT_TIME 60 // minutes (approximately)
+#define GOODNIGHT_LEVEL 24 // ~11 lm
+
+// dual-switch support (second switch is a tail clicky)
+//#define START_AT_MEMORIZED_LEVEL
+
+/***** specific settings for known driver types *****/
+#include "tk.h"
+#include incfile(CONFIGFILE)
+
+
+// thermal properties, if not defined per-driver
+#ifndef MIN_THERM_STEPDOWN
+#define MIN_THERM_STEPDOWN MAX_1x7135 // lowest value it'll step down to
+#endif
+#ifndef THERM_FASTER_LEVEL
+ #ifdef MAX_Nx7135
+ #define THERM_FASTER_LEVEL MAX_Nx7135 // throttle back faster when high
+ #else
+ #define THERM_FASTER_LEVEL (RAMP_SIZE*4/5) // throttle back faster when high
+ #endif
+#endif
+#ifdef USE_THERMAL_REGULATION
+#define USE_SET_LEVEL_GRADUALLY // isn't used except for thermal adjustments
+#endif
+
+
+/********* Configure SpaghettiMonster *********/
+#define USE_DELAY_ZERO
+#define USE_RAMPING
+#ifndef RAMP_LENGTH
+#define RAMP_LENGTH 150 // default, if not overridden in a driver cfg file
+#endif
+#define MAX_BIKING_LEVEL 120 // should be 127 or less
+#define USE_BATTCHECK
+
+#if defined(USE_MUGGLE_MODE)
+#ifndef MUGGLE_FLOOR
+#define MUGGLE_FLOOR 22
+#endif
+#ifndef MUGGLE_CEILING
+#define MUGGLE_CEILING (MAX_1x7135+20)
+#endif
+#endif
+#define USE_IDLE_MODE // reduce power use while awake and no tasks are pending
+#define USE_DYNAMIC_UNDERCLOCKING // cut clock speed at very low modes for better efficiency
+
+// full FET strobe can be a bit much... use max regulated level instead,
+// if there's a bright enough regulated level
+#ifdef MAX_Nx7135
+#define STROBE_BRIGHTNESS MAX_Nx7135
+#else
+#define STROBE_BRIGHTNESS MAX_LEVEL
+#endif
+
+#if defined(USE_CANDLE_MODE) || defined(USE_BIKE_FLASHER_MODE) || defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE) || defined(USE_LIGHTNING_MODE)
+#define USE_STROBE_STATE
+#endif
+
+// auto-detect how many eeprom bytes
+#define USE_EEPROM
+typedef enum {
+ ramp_style_e,
+ ramp_smooth_floor_e,
+ ramp_smooth_ceil_e,
+ ramp_discrete_floor_e,
+ ramp_discrete_ceil_e,
+ ramp_discrete_steps_e,
+ #ifdef USE_STROBE_STATE
+ strobe_type_e,
+ #endif
+ #if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE)
+ strobe_delays_0_e,
+ strobe_delays_1_e,
+ #endif
+ #ifdef USE_BIKE_FLASHER_MODE
+ bike_flasher_brightness_e,
+ #endif
+ beacon_seconds_e,
+ #ifdef USE_MUGGLE_MODE
+ muggle_mode_active_e,
+ #endif
+ #ifdef USE_THERMAL_REGULATION
+ therm_ceil_e,
+ therm_cal_offset_e,
+ #endif
+ #ifdef USE_INDICATOR_LED
+ indicator_led_mode_e,
+ #endif
+ eeprom_indexes_e_END
+} eeprom_indexes_e;
+#define EEPROM_BYTES eeprom_indexes_e_END
+
+#ifdef START_AT_MEMORIZED_LEVEL
+#define USE_EEPROM_WL
+#define EEPROM_WL_BYTES 1
+#endif
+
+// auto-configure other stuff...
+#if defined(USE_LIGHTNING_MODE) || defined(USE_CANDLE_MODE)
+#define USE_PSEUDO_RAND
+#endif
+
+#include "spaghetti-monster.h"
+
+
+// FSM states
+uint8_t off_state(Event event, uint16_t arg);
+// simple numeric entry config menu
+uint8_t config_state_base(Event event, uint16_t arg,
+ uint8_t num_config_steps,
+ void (*savefunc)());
+#define MAX_CONFIG_VALUES 3
+uint8_t config_state_values[MAX_CONFIG_VALUES];
+// ramping mode and its related config mode
+uint8_t steady_state(Event event, uint16_t arg);
+uint8_t ramp_config_state(Event event, uint16_t arg);
+// party and tactical strobes
+#ifdef USE_STROBE_STATE
+uint8_t strobe_state(Event event, uint16_t arg);
+#endif
+#ifdef USE_BATTCHECK
+uint8_t battcheck_state(Event event, uint16_t arg);
+#endif
+#ifdef USE_THERMAL_REGULATION
+uint8_t tempcheck_state(Event event, uint16_t arg);
+uint8_t thermal_config_state(Event event, uint16_t arg);
+#endif
+// 1-hour ramp down from low, then automatic off
+uint8_t goodnight_state(Event event, uint16_t arg);
+// 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);
+// soft lockout
+#define MOON_DURING_LOCKOUT_MODE
+// if enabled, 2nd lockout click goes to the other ramp's floor level
+//#define LOCKOUT_MOON_FANCY
+uint8_t lockout_state(Event event, uint16_t arg);
+// momentary / signalling mode
+uint8_t momentary_state(Event event, uint16_t arg);
+#ifdef USE_MUGGLE_MODE
+// muggle mode, super-simple, hard to exit
+uint8_t muggle_state(Event event, uint16_t arg);
+uint8_t muggle_mode_active = 0;
+#endif
+
+// general helper function for config modes
+uint8_t number_entry_state(Event event, uint16_t arg);
+// return value from number_entry_state()
+volatile uint8_t number_entry_value;
+
+void blink_confirm(uint8_t num);
+#if defined(USE_INDICATOR_LED) && defined(TICK_DURING_STANDBY)
+void indicator_blink(uint8_t arg);
+#endif
+
+// remember stuff even after battery was changed
+void load_config();
+void save_config();
+#ifdef START_AT_MEMORIZED_LEVEL
+void save_config_wl();
+#endif
+
+// default ramp options if not overridden earlier per-driver
+#ifndef RAMP_SMOOTH_FLOOR
+ #define RAMP_SMOOTH_FLOOR 1
+#endif
+#ifndef RAMP_SMOOTH_CEIL
+ #if PWM_CHANNELS == 3
+ #define RAMP_SMOOTH_CEIL MAX_Nx7135
+ #else
+ #define RAMP_SMOOTH_CEIL MAX_LEVEL - 30
+ #endif
+#endif
+#ifndef RAMP_DISCRETE_FLOOR
+ #define RAMP_DISCRETE_FLOOR 20
+#endif
+#ifndef RAMP_DISCRETE_CEIL
+ #define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#endif
+#ifndef RAMP_DISCRETE_STEPS
+ #define RAMP_DISCRETE_STEPS 7
+#endif
+
+// brightness control
+uint8_t memorized_level = MAX_1x7135;
+// smooth vs discrete ramping
+volatile uint8_t ramp_style = 0; // 0 = smooth, 1 = discrete
+volatile uint8_t ramp_smooth_floor = RAMP_SMOOTH_FLOOR;
+volatile uint8_t ramp_smooth_ceil = RAMP_SMOOTH_CEIL;
+volatile uint8_t ramp_discrete_floor = RAMP_DISCRETE_FLOOR;
+volatile uint8_t ramp_discrete_ceil = RAMP_DISCRETE_CEIL;
+volatile uint8_t ramp_discrete_steps = RAMP_DISCRETE_STEPS;
+uint8_t ramp_discrete_step_size; // don't set this
+
+#ifdef USE_INDICATOR_LED
+ // bits 2-3 control lockout mode
+ // bits 0-1 control "off" mode
+ // modes are: 0=off, 1=low, 2=high, 3=blinking (if TICK_DURING_STANDBY enabled)
+ #ifdef INDICATOR_LED_DEFAULT_MODE
+ uint8_t indicator_led_mode = INDICATOR_LED_DEFAULT_MODE;
+ #else
+ #ifdef USE_INDICATOR_LED_WHILE_RAMPING
+ //uint8_t indicator_led_mode = (1<<2) + 2;
+ uint8_t indicator_led_mode = (2<<2) + 1;
+ #else
+ uint8_t indicator_led_mode = (3<<2) + 1;
+ #endif
+ #endif
+#endif
+
+// calculate the nearest ramp level which would be valid at the moment
+// (is a no-op for smooth ramp, but limits discrete ramp to only the
+// correct levels for the user's config)
+uint8_t nearest_level(int16_t target);
+
+#ifdef USE_THERMAL_REGULATION
+// brightness before thermal step-down
+uint8_t target_level = 0;
+#endif
+
+// internal numbering for strobe modes
+#ifdef USE_STROBE_STATE
+typedef enum {
+ #ifdef USE_PARTY_STROBE_MODE
+ party_strobe_e,
+ #endif
+ #ifdef USE_TACTICAL_STROBE_MODE
+ tactical_strobe_e,
+ #endif
+ #ifdef USE_LIGHTNING_MODE
+ lightning_storm_e,
+ #endif
+ #ifdef USE_CANDLE_MODE
+ candle_mode_e,
+ #endif
+ #ifdef USE_BIKE_FLASHER_MODE
+ bike_flasher_e,
+ #endif
+ strobe_mode_END
+} strobe_mode_te;
+
+const int NUM_STROBES = strobe_mode_END;
+
+// which strobe mode is active?
+#ifdef USE_CANDLE_MODE
+volatile strobe_mode_te strobe_type = candle_mode_e;
+#else
+volatile strobe_mode_te strobe_type = 0;
+#endif
+#endif
+
+#if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE)
+// party / tactical strobe timing
+volatile uint8_t strobe_delays[] = { 40, 67 }; // party strobe, tactical strobe
+#endif
+
+// bike mode config options
+#ifdef USE_BIKE_FLASHER_MODE
+volatile uint8_t bike_flasher_brightness = MAX_1x7135;
+#endif
+
+#ifdef USE_CANDLE_MODE
+uint8_t triangle_wave(uint8_t phase);
+#endif
+
+// beacon timing
+volatile uint8_t beacon_seconds = 2;
+
+
+uint8_t off_state(Event event, uint16_t arg) {
+ // turn emitter off when entering state
+ if (event == EV_enter_state) {
+ set_level(0);
+ #ifdef USE_INDICATOR_LED
+ indicator_led(indicator_led_mode & 0x03);
+ #endif
+ // sleep while off (lower power use)
+ go_to_standby = 1;
+ return MISCHIEF_MANAGED;
+ }
+ // go back to sleep eventually if we got bumped but didn't leave "off" state
+ else if (event == EV_tick) {
+ if (arg > TICKS_PER_SECOND*2) {
+ go_to_standby = 1;
+ #ifdef USE_INDICATOR_LED
+ indicator_led(indicator_led_mode & 0x03);
+ #endif
+ }
+ return MISCHIEF_MANAGED;
+ }
+ #if defined(TICK_DURING_STANDBY) && defined(USE_INDICATOR_LED)
+ // blink the indicator LED, maybe
+ else if (event == EV_sleep_tick) {
+ if ((indicator_led_mode & 0b00000011) == 0b00000011) {
+ indicator_blink(arg);
+ }
+ return MISCHIEF_MANAGED;
+ }
+ #endif
+ // hold (initially): go to lowest level (floor), but allow abort for regular click
+ else if (event == EV_click1_press) {
+ set_level(nearest_level(1));
+ return MISCHIEF_MANAGED;
+ }
+ // hold: go to lowest level
+ else if (event == EV_click1_hold) {
+ #ifdef MOON_TIMING_HINT
+ if (arg == 0) {
+ // let the user know they can let go now to stay at moon
+ uint8_t temp = actual_level;
+ set_level(0);
+ delay_4ms(2);
+ set_level(temp);
+ } else
+ #endif
+ // don't start ramping immediately;
+ // give the user time to release at moon level
+ //if (arg >= HOLD_TIMEOUT) { // smaller
+ if (arg >= (!ramp_style) * HOLD_TIMEOUT) { // more consistent
+ set_state(steady_state, 1);
+ }
+ return MISCHIEF_MANAGED;
+ }
+ // hold, release quickly: go to lowest level (floor)
+ else if (event == EV_click1_hold_release) {
+ set_state(steady_state, 1);
+ return MISCHIEF_MANAGED;
+ }
+ // 1 click (before timeout): go to memorized level, but allow abort for double click
+ else if (event == EV_click1_release) {
+ set_level(nearest_level(memorized_level));
+ return MISCHIEF_MANAGED;
+ }
+ // 1 click: regular mode
+ else if (event == EV_1click) {
+ set_state(steady_state, memorized_level);
+ return MISCHIEF_MANAGED;
+ }
+ // click, hold: go to highest level (ceiling) (for ramping down)
+ else if (event == EV_click2_hold) {
+ set_state(steady_state, MAX_LEVEL);
+ return MISCHIEF_MANAGED;
+ }
+ // 2 clicks: highest mode (ceiling)
+ else if (event == EV_2clicks) {
+ set_state(steady_state, MAX_LEVEL);
+ return MISCHIEF_MANAGED;
+ }
+ // 3 clicks (initial press): off, to prep for later events
+ else if (event == EV_click3_press) {
+ set_level(0);
+ return MISCHIEF_MANAGED;
+ }
+ #ifdef USE_BATTCHECK
+ // 3 clicks: battcheck mode / blinky mode group 1
+ else if (event == EV_3clicks) {
+ set_state(battcheck_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+ #endif
+ // click, click, long-click: strobe mode
+ #ifdef USE_STROBE_STATE
+ else if (event == EV_click3_hold) {
+ set_state(strobe_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+ #endif
+ // 4 clicks: soft lockout
+ else if (event == EV_4clicks) {
+ blink_confirm(2);
+ set_state(lockout_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+ // 5 clicks: momentary mode
+ else if (event == EV_5clicks) {
+ blink_confirm(1);
+ set_state(momentary_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+ #ifdef USE_MUGGLE_MODE
+ // 6 clicks: muggle mode
+ else if (event == EV_6clicks) {
+ blink_confirm(1);
+ set_state(muggle_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+ #endif
+ #ifdef USE_INDICATOR_LED
+ // 7 clicks: change indicator LED mode
+ 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();
+ return MISCHIEF_MANAGED;
+ }
+ #endif
+ return EVENT_NOT_HANDLED;
+}
+
+
+uint8_t steady_state(Event event, uint16_t arg) {
+ uint8_t mode_min = ramp_smooth_floor;
+ uint8_t mode_max = ramp_smooth_ceil;
+ uint8_t ramp_step_size = 1;
+ #ifdef USE_REVERSING
+ static int8_t ramp_direction = 1;
+ #endif
+ if (ramp_style) {
+ mode_min = ramp_discrete_floor;
+ mode_max = ramp_discrete_ceil;
+ ramp_step_size = ramp_discrete_step_size;
+ }
+
+ // turn LED on when we first enter the mode
+ if ((event == EV_enter_state) || (event == EV_reenter_state)) {
+ // if we just got back from config mode, go back to memorized level
+ if (event == EV_reenter_state) {
+ arg = memorized_level;
+ }
+ // remember this level, unless it's moon or turbo
+ if ((arg > mode_min) && (arg < mode_max))
+ memorized_level = arg;
+ // use the requested level even if not memorized
+ arg = nearest_level(arg);
+ #ifdef USE_THERMAL_REGULATION
+ target_level = arg;
+ #endif
+ set_level(arg);
+ #ifdef USE_REVERSING
+ ramp_direction = 1;
+ #endif
+ return MISCHIEF_MANAGED;
+ }
+ // 1 click: off
+ else if (event == EV_1click) {
+ set_state(off_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+ // 2 clicks: go to/from highest level
+ else if (event == EV_2clicks) {
+ if (actual_level < MAX_LEVEL) {
+ #ifdef USE_THERMAL_REGULATION
+ target_level = MAX_LEVEL;
+ #endif
+ // true turbo, not the mode-specific ceiling
+ set_level(MAX_LEVEL);
+ }
+ else {
+ #ifdef USE_THERMAL_REGULATION
+ target_level = memorized_level;
+ #endif
+ set_level(memorized_level);
+ }
+ return MISCHIEF_MANAGED;
+ }
+ // 3 clicks: toggle smooth vs discrete ramping
+ else if (event == EV_3clicks) {
+ ramp_style = !ramp_style;
+ memorized_level = nearest_level(actual_level);
+ #ifdef USE_THERMAL_REGULATION
+ target_level = memorized_level;
+ #ifdef USE_SET_LEVEL_GRADUALLY
+ //set_level_gradually(lvl);
+ #endif
+ #endif
+ save_config();
+ #ifdef START_AT_MEMORIZED_LEVEL
+ save_config_wl();
+ #endif
+ set_level(0);
+ delay_4ms(20/4);
+ set_level(memorized_level);
+ return MISCHIEF_MANAGED;
+ }
+ // 4 clicks: configure this ramp mode
+ else if (event == EV_4clicks) {
+ push_state(ramp_config_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+ // hold: change brightness (brighter)
+ else if (event == EV_click1_hold) {
+ // ramp slower in discrete mode
+ if (ramp_style && (arg % HOLD_TIMEOUT != 0)) {
+ return MISCHIEF_MANAGED;
+ }
+ #ifdef USE_REVERSING
+ // make it ramp down instead, if already at max
+ if ((arg <= 1) && (actual_level >= mode_max)) {
+ ramp_direction = -1;
+ }
+ memorized_level = nearest_level((int16_t)actual_level \
+ + (ramp_step_size * ramp_direction));
+ #else
+ memorized_level = nearest_level((int16_t)actual_level + ramp_step_size);
+ #endif
+ #ifdef USE_THERMAL_REGULATION
+ target_level = memorized_level;
+ #endif
+ #if defined(BLINK_AT_RAMP_CEILING) || defined(BLINK_AT_CHANNEL_BOUNDARIES)
+ // only blink once for each threshold
+ if ((memorized_level != actual_level) && (
+ 0 // for easier syntax below
+ #ifdef BLINK_AT_CHANNEL_BOUNDARIES
+ || (memorized_level == MAX_1x7135)
+ #if PWM_CHANNELS >= 3
+ || (memorized_level == MAX_Nx7135)
+ #endif
+ #endif
+ #ifdef BLINK_AT_RAMP_CEILING
+ || (memorized_level == mode_max)
+ #endif
+ #if defined(USE_REVERSING) && defined(BLINK_AT_RAMP_FLOOR)
+ || (memorized_level == mode_min)
+ #endif
+ )) {
+ set_level(0);
+ delay_4ms(8/4);
+ }
+ #endif
+ #if defined(BLINK_AT_STEPS)
+ uint8_t foo = ramp_style;
+ ramp_style = 1;
+ uint8_t nearest = nearest_level((int16_t)actual_level);
+ ramp_style = foo;
+ // only blink once for each threshold
+ if ((memorized_level != actual_level) &&
+ (ramp_style == 0) &&
+ (memorized_level == nearest)
+ )
+ {
+ set_level(0);
+ delay_4ms(8/4);
+ }
+ #endif
+ set_level(memorized_level);
+ return MISCHIEF_MANAGED;
+ }
+ #if defined(USE_REVERSING) || defined(START_AT_MEMORIZED_LEVEL)
+ // reverse ramp direction on hold release
+ else if (event == EV_click1_hold_release) {
+ #ifdef USE_REVERSING
+ ramp_direction = -ramp_direction;
+ #endif
+ #ifdef START_AT_MEMORIZED_LEVEL
+ save_config_wl();
+ #endif
+ return MISCHIEF_MANAGED;
+ }
+ #endif
+ // click, hold: change brightness (dimmer)
+ else if (event == EV_click2_hold) {
+ #ifdef USE_REVERSING
+ ramp_direction = 1;
+ #endif
+ // ramp slower in discrete mode
+ if (ramp_style && (arg % HOLD_TIMEOUT != 0)) {
+ return MISCHIEF_MANAGED;
+ }
+ // TODO? make it ramp up instead, if already at min?
+ memorized_level = nearest_level((int16_t)actual_level - ramp_step_size);
+ #ifdef USE_THERMAL_REGULATION
+ target_level = memorized_level;
+ #endif
+ #if defined(BLINK_AT_RAMP_FLOOR) || defined(BLINK_AT_CHANNEL_BOUNDARIES)
+ // only blink once for each threshold
+ if ((memorized_level != actual_level) && (
+ 0 // for easier syntax below
+ #ifdef BLINK_AT_CHANNEL_BOUNDARIES
+ || (memorized_level == MAX_1x7135)
+ #if PWM_CHANNELS >= 3
+ || (memorized_level == MAX_Nx7135)
+ #endif
+ #endif
+ #ifdef BLINK_AT_RAMP_FLOOR
+ || (memorized_level == mode_min)
+ #endif
+ )) {
+ set_level(0);
+ delay_4ms(8/4);
+ }
+ #endif
+ #if defined(BLINK_AT_STEPS)
+ uint8_t foo = ramp_style;
+ ramp_style = 1;
+ uint8_t nearest = nearest_level((int16_t)actual_level);
+ ramp_style = foo;
+ // only blink once for each threshold
+ if ((memorized_level != actual_level) &&
+ (ramp_style == 0) &&
+ (memorized_level == nearest)
+ )
+ {
+ set_level(0);
+ delay_4ms(8/4);
+ }
+ #endif
+ set_level(memorized_level);
+ return MISCHIEF_MANAGED;
+ }
+ #ifdef START_AT_MEMORIZED_LEVEL
+ // click, release, hold, release: save new ramp level (if necessary)
+ else if (event == EV_click2_hold_release) {
+ save_config_wl();
+ return MISCHIEF_MANAGED;
+ }
+ #endif
+ #if defined(USE_SET_LEVEL_GRADUALLY) || defined(USE_REVERSING)
+ else if (event == EV_tick) {
+ #ifdef USE_REVERSING
+ // un-reverse after 1 second
+ if (arg == TICKS_PER_SECOND) ramp_direction = 1;
+ #endif
+ #ifdef USE_SET_LEVEL_GRADUALLY
+ // make thermal adjustment speed scale with magnitude
+ if ((arg & 1) && (actual_level < THERM_FASTER_LEVEL)) {
+ return MISCHIEF_MANAGED; // adjust slower when not a high mode
+ }
+ #ifdef THERM_HARD_TURBO_DROP
+ else if ((! (actual_level < THERM_FASTER_LEVEL))
+ && (actual_level > gradual_target)) {
+ gradual_tick();
+ }
+ else {
+ #endif
+ // [int(62*4 / (x**0.8)) for x in (1,2,4,8,16,32,64,128)]
+ //uint8_t intervals[] = {248, 142, 81, 46, 26, 15, 8, 5};
+ // [int(62*4 / (x**0.9)) for x in (1,2,4,8,16,32,64,128)]
+ //uint8_t intervals[] = {248, 132, 71, 38, 20, 10, 5, 3};
+ // [int(62*4 / (x**0.95)) for x in (1,2,4,8,16,32,64,128)]
+ uint8_t intervals[] = {248, 128, 66, 34, 17, 9, 4, 2};
+ uint8_t diff;
+ static uint8_t ticks_since_adjust = 0;
+ ticks_since_adjust ++;
+ if (gradual_target > actual_level) diff = gradual_target - actual_level;
+ else {
+ diff = actual_level - gradual_target;
+ }
+ uint8_t magnitude = 0;
+ #ifndef THERM_HARD_TURBO_DROP
+ // if we're on a really high mode, drop faster
+ if (actual_level >= THERM_FASTER_LEVEL) { magnitude ++; }
+ #endif
+ while (diff) {
+ magnitude ++;
+ diff >>= 1;
+ }
+ uint8_t ticks_per_adjust = intervals[magnitude];
+ if (ticks_since_adjust > ticks_per_adjust)
+ {
+ gradual_tick();
+ ticks_since_adjust = 0;
+ }
+ //if (!(arg % ticks_per_adjust)) gradual_tick();
+ #ifdef THERM_HARD_TURBO_DROP
+ }
+ #endif
+ #endif
+ return MISCHIEF_MANAGED;
+ }
+ #endif
+ #ifdef USE_THERMAL_REGULATION
+ // overheating: drop by an amount proportional to how far we are above the ceiling
+ else if (event == EV_temperature_high) {
+ #if 0
+ uint8_t foo = actual_level;
+ set_level(0);
+ delay_4ms(2);
+ set_level(foo);
+ #endif
+ #ifdef THERM_HARD_TURBO_DROP
+ if (actual_level > THERM_FASTER_LEVEL) {
+ #ifdef USE_SET_LEVEL_GRADUALLY
+ set_level_gradually(THERM_FASTER_LEVEL);
+ #else
+ set_level(THERM_FASTER_LEVEL);
+ #endif
+ target_level = THERM_FASTER_LEVEL;
+ } else
+ #endif
+ if (actual_level > MIN_THERM_STEPDOWN) {
+ int16_t stepdown = actual_level - arg;
+ if (stepdown < MIN_THERM_STEPDOWN) stepdown = MIN_THERM_STEPDOWN;
+ else if (stepdown > MAX_LEVEL) stepdown = MAX_LEVEL;
+ #ifdef USE_SET_LEVEL_GRADUALLY
+ set_level_gradually(stepdown);
+ #else
+ set_level(stepdown);
+ #endif
+ }
+ return MISCHIEF_MANAGED;
+ }
+ // underheating: increase slowly if we're lower than the target
+ // (proportional to how low we are)
+ else if (event == EV_temperature_low) {
+ #if 0
+ uint8_t foo = actual_level;
+ set_level(0);
+ delay_4ms(2);
+ set_level(foo);
+ #endif
+ if (actual_level < target_level) {
+ //int16_t stepup = actual_level + (arg>>1);
+ int16_t stepup = actual_level + arg;
+ if (stepup > target_level) stepup = target_level;
+ else if (stepup < MIN_THERM_STEPDOWN) stepup = MIN_THERM_STEPDOWN;
+ #ifdef USE_SET_LEVEL_GRADUALLY
+ set_level_gradually(stepup);
+ #else
+ set_level(stepup);
+ #endif
+ }
+ return MISCHIEF_MANAGED;
+ }
+ #endif
+ return EVENT_NOT_HANDLED;
+}
+
+
+#ifdef USE_STROBE_STATE
+uint8_t strobe_state(Event event, uint16_t arg) {
+ // 'st' reduces ROM size by avoiding access to a volatile var
+ // (maybe I should just make it nonvolatile?)
+ strobe_mode_te st = strobe_type;
+ #ifdef USE_CANDLE_MODE
+ // FIXME: make candle variance magnitude a compile-time option,
+ // since 20 is sometimes too much or too little,
+ // depending on the driver type and ramp shape
+ //#define MAX_CANDLE_LEVEL (RAMP_SIZE-8-6-4)
+ #define MAX_CANDLE_LEVEL (RAMP_SIZE/2)
+ static uint8_t candle_wave1 = 0;
+ static uint8_t candle_wave2 = 0;
+ static uint8_t candle_wave3 = 0;
+ static uint8_t candle_wave2_speed = 0;
+ static uint8_t candle_wave2_depth = 7;
+ static uint8_t candle_wave3_depth = 4;
+ static uint8_t candle_mode_brightness = 24;
+ static uint8_t candle_mode_timer = 0;
+ #define TICKS_PER_CANDLE_MINUTE 4096 // about 65 seconds
+ #define MINUTES_PER_CANDLE_HALFHOUR 27 // ish
+ #endif
+
+ if (event == EV_enter_state) {
+ #ifdef USE_CANDLE_MODE
+ candle_mode_timer = 0; // in case any time was left over from earlier
+ #endif
+ return MISCHIEF_MANAGED;
+ }
+ // 1 click: off
+ else if (event == EV_1click) {
+ set_state(off_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+ // 2 clicks: rotate through strobe/flasher modes
+ else if (event == EV_2clicks) {
+ strobe_type = (st + 1) % NUM_STROBES;
+ #ifdef USE_CANDLE_MODE
+ candle_mode_timer = 0; // in case any time was left over from earlier
+ #endif
+ //interrupt_nice_delays();
+ save_config();
+ return MISCHIEF_MANAGED;
+ }
+ // hold: change speed (go faster)
+ // or change brightness (brighter)
+ else if (event == EV_click1_hold) {
+ if (0) {} // placeholder
+
+ // party / tactical strobe faster
+ #if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE)
+ #ifdef USE_TACTICAL_STROBE_MODE
+ else if (st <= tactical_strobe_e) {
+ #else
+ else if (st == party_strobe_e) {
+ #endif
+ if ((arg & 1) == 0) {
+ if (strobe_delays[st] > 8) strobe_delays[st] --;
+ }
+ }
+ #endif
+
+ // lightning has no adjustments
+ //else if (st == lightning_storm_e) {}
+
+ // candle mode brighter
+ #ifdef USE_CANDLE_MODE
+ else if (st == candle_mode_e) {
+ if (candle_mode_brightness < MAX_CANDLE_LEVEL)
+ candle_mode_brightness ++;
+ }
+ #endif
+
+ // biking mode brighter
+ #ifdef USE_BIKE_FLASHER_MODE
+ else if (st == bike_flasher_e) {
+ if (bike_flasher_brightness < MAX_BIKING_LEVEL)
+ bike_flasher_brightness ++;
+ set_level(bike_flasher_brightness);
+ }
+ #endif
+
+ return MISCHIEF_MANAGED;
+ }
+ // click, hold: change speed (go slower)
+ // or change brightness (dimmer)
+ else if (event == EV_click2_hold) {
+ if (0) {} // placeholder
+
+ // party / tactical strobe slower
+ #if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE)
+ #ifdef USE_TACTICAL_STROBE_MODE
+ else if (st <= tactical_strobe_e) {
+ #else
+ else if (st == party_strobe_e) {
+ #endif
+ if ((arg & 1) == 0) {
+ if (strobe_delays[st] < 255) strobe_delays[st] ++;
+ }
+ }
+ #endif
+
+ // lightning has no adjustments
+ //else if (st == lightning_storm_e) {}
+
+ // candle mode dimmer
+ #ifdef USE_CANDLE_MODE
+ else if (st == candle_mode_e) {
+ if (candle_mode_brightness > 1)
+ candle_mode_brightness --;
+ }
+ #endif
+
+ // biking mode dimmer
+ #ifdef USE_BIKE_FLASHER_MODE
+ else if (st == bike_flasher_e) {
+ if (bike_flasher_brightness > 2)
+ bike_flasher_brightness --;
+ set_level(bike_flasher_brightness);
+ }
+ #endif
+
+ return MISCHIEF_MANAGED;
+ }
+ // release hold: save new strobe settings
+ else if ((event == EV_click1_hold_release)
+ || (event == EV_click2_hold_release)) {
+ save_config();
+ return MISCHIEF_MANAGED;
+ }
+ #if defined(USE_CANDLE_MODE)
+ // 3 clicks: add 30m to candle timer
+ else if (event == EV_3clicks) {
+ // candle mode only
+ if (st == candle_mode_e) {
+ if (candle_mode_timer < (255 - MINUTES_PER_CANDLE_HALFHOUR)) {
+ // add 30m to the timer
+ candle_mode_timer += MINUTES_PER_CANDLE_HALFHOUR;
+ // blink to confirm
+ set_level(actual_level + 32);
+ delay_4ms(2);
+ }
+ }
+ return MISCHIEF_MANAGED;
+ }
+ #endif
+ #if defined(USE_LIGHTNING_MODE) || defined(USE_CANDLE_MODE)
+ // clock tick: bump the random seed, adjust candle brightness
+ else if (event == EV_tick) {
+ pseudo_rand_seed += arg;
+
+ #ifdef USE_CANDLE_MODE
+ if (st == candle_mode_e) {
+ // self-timer dims the light during the final minute
+ uint8_t subtract = 0;
+ if (candle_mode_timer == 1) {
+ subtract = ((candle_mode_brightness+20)
+ * ((arg & (TICKS_PER_CANDLE_MINUTE-1)) >> 4))
+ >> 8;
+ }
+ // we passed a minute mark, decrease timer if it's running
+ if ((arg & (TICKS_PER_CANDLE_MINUTE-1)) == (TICKS_PER_CANDLE_MINUTE - 1)) {
+ if (candle_mode_timer > 0) {
+ candle_mode_timer --;
+ //set_level(0); delay_4ms(2);
+ // if the timer ran out, shut off
+ if (! candle_mode_timer) {
+ set_state(off_state, 0);
+ }
+ }
+ }
+ // 3-oscillator synth for a relatively organic pattern
+ uint8_t add;
+ add = ((triangle_wave(candle_wave1) * 8) >> 8)
+ + ((triangle_wave(candle_wave2) * candle_wave2_depth) >> 8)
+ + ((triangle_wave(candle_wave3) * candle_wave3_depth) >> 8);
+ int8_t brightness = candle_mode_brightness + add - subtract;
+ if (brightness < 0) { brightness = 0; }
+ set_level(brightness);
+
+ // wave1: slow random LFO
+ if ((arg & 1) == 0) candle_wave1 += pseudo_rand() & 1;
+ // wave2: medium-speed erratic LFO
+ candle_wave2 += candle_wave2_speed;
+ // wave3: erratic fast wave
+ candle_wave3 += pseudo_rand() % 37;
+ // S&H on wave2 frequency to make it more erratic
+ if ((pseudo_rand() & 0b00111111) == 0)
+ candle_wave2_speed = pseudo_rand() % 13;
+ // downward sawtooth on wave2 depth to simulate stabilizing
+ if ((candle_wave2_depth > 0) && ((pseudo_rand() & 0b00111111) == 0))
+ candle_wave2_depth --;
+ // random sawtooth retrigger
+ if ((pseudo_rand()) == 0) {
+ candle_wave2_depth = 7;
+ //candle_wave3_depth = 5;
+ candle_wave2 = 0;
+ }
+ // downward sawtooth on wave3 depth to simulate stabilizing
+ if ((candle_wave3_depth > 2) && ((pseudo_rand() & 0b00011111) == 0))
+ candle_wave3_depth --;
+ if ((pseudo_rand() & 0b01111111) == 0)
+ candle_wave3_depth = 5;
+ }
+ #endif
+ return MISCHIEF_MANAGED;
+ }
+ #endif
+ return EVENT_NOT_HANDLED;
+}
+#endif // ifdef USE_STROBE_STATE
+
+
+#ifdef USE_BATTCHECK
+uint8_t battcheck_state(Event event, uint16_t arg) {
+ // 1 click: off
+ if (event == EV_1click) {
+ set_state(off_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+ // 2 clicks: goodnight mode
+ else if (event == EV_2clicks) {
+ set_state(goodnight_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+ return EVENT_NOT_HANDLED;
+}
+#endif
+
+
+#ifdef USE_THERMAL_REGULATION
+uint8_t tempcheck_state(Event event, uint16_t arg) {
+ // 1 click: off
+ if (event == EV_1click) {
+ set_state(off_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+ // 2 clicks: battcheck mode
+ else if (event == EV_2clicks) {
+ set_state(battcheck_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+ // 4 clicks: thermal config mode
+ else if (event == EV_4clicks) {
+ push_state(thermal_config_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+ return EVENT_NOT_HANDLED;
+}
+#endif
+
+
+uint8_t beacon_state(Event event, uint16_t arg) {
+ // 1 click: off
+ if (event == EV_1click) {
+ set_state(off_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+ // TODO: use sleep ticks to measure time between pulses,
+ // to save power
+ // 2 clicks: tempcheck mode
+ else if (event == EV_2clicks) {
+ #ifdef USE_THERMAL_REGULATION
+ set_state(tempcheck_state, 0);
+ #else
+ set_state(battcheck_state, 0);
+ #endif
+ return MISCHIEF_MANAGED;
+ }
+ // 4 clicks: beacon config mode
+ else if (event == EV_4clicks) {
+ push_state(beacon_config_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+ return EVENT_NOT_HANDLED;
+}
+
+
+#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;
+ // blink on start
+ if (event == EV_enter_state) {
+ ticks_since_stepdown = 0;
+ blink_confirm(2);
+ set_level(GOODNIGHT_LEVEL);
+ return MISCHIEF_MANAGED;
+ }
+ // 1 click: off
+ else if (event == EV_1click) {
+ set_state(off_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+ // 2 clicks: beacon mode
+ else if (event == EV_2clicks) {
+ set_state(beacon_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+ // tick: step down (maybe) or off (maybe)
+ else if (event == EV_tick) {
+ if (++ticks_since_stepdown > GOODNIGHT_TICKS_PER_STEPDOWN) {
+ ticks_since_stepdown = 0;
+ set_level(actual_level-1);
+ if (! actual_level) {
+ #if 0 // test blink, to help measure timing
+ set_level(MAX_LEVEL>>2);
+ delay_4ms(8/2);
+ set_level(0);
+ #endif
+ set_state(off_state, 0);
+ }
+ }
+ return MISCHIEF_MANAGED;
+ }
+ return EVENT_NOT_HANDLED;
+}
+
+
+uint8_t lockout_state(Event event, uint16_t arg) {
+ #ifdef MOON_DURING_LOCKOUT_MODE
+ // momentary(ish) moon mode during lockout
+ // button is being held
+ if ((event & (B_CLICK | B_PRESS)) == (B_CLICK | B_PRESS)) {
+ #ifdef LOCKOUT_MOON_LOWEST
+ // Use lowest moon configured
+ uint8_t lvl = ramp_smooth_floor;
+ if (ramp_discrete_floor < lvl) lvl = ramp_discrete_floor;
+ set_level(lvl);
+ #elif defined(LOCKOUT_MOON_FANCY)
+ uint8_t levels[] = { ramp_smooth_floor, ramp_discrete_floor };
+ if ((event & 0x0f) == 2) {
+ set_level(levels[ramp_style^1]);
+ } else {
+ set_level(levels[ramp_style]);
+ }
+ #else
+ // Use moon from current ramp
+ set_level(nearest_level(1));
+ #endif
+ }
+ // button was released
+ else if ((event & (B_CLICK | B_PRESS)) == (B_CLICK)) {
+ set_level(0);
+ }
+ #endif
+
+ // regular event handling
+ // conserve power while locked out
+ // (allow staying awake long enough to exit, but otherwise
+ // be persistent about going back to sleep every few seconds
+ // even if the user keeps pressing the button)
+ #ifdef USE_INDICATOR_LED
+ if (event == EV_enter_state) {
+ indicator_led(indicator_led_mode >> 2);
+ } else
+ #endif
+ if (event == EV_tick) {
+ if (arg > TICKS_PER_SECOND*2) {
+ go_to_standby = 1;
+ #ifdef USE_INDICATOR_LED
+ indicator_led(indicator_led_mode >> 2);
+ #endif
+ }
+ return MISCHIEF_MANAGED;
+ }
+ #if defined(TICK_DURING_STANDBY) && defined(USE_INDICATOR_LED)
+ else if (event == EV_sleep_tick) {
+ if ((indicator_led_mode & 0b00001100) == 0b00001100) {
+ indicator_blink(arg);
+ }
+ return MISCHIEF_MANAGED;
+ }
+ #endif
+ #ifdef USE_INDICATOR_LED
+ // 3 clicks: rotate through indicator LED modes (lockout mode)
+ else if (event == EV_3clicks) {
+ uint8_t mode = indicator_led_mode >> 2;
+ #ifdef TICK_DURING_STANDBY
+ mode = (mode + 1) & 3;
+ #else
+ mode = (mode + 1) % 3;
+ #endif
+ #ifdef INDICATOR_LED_SKIP_LOW
+ if (mode == 1) { mode ++; }
+ #endif
+ indicator_led_mode = (mode << 2) + (indicator_led_mode & 0x03);
+ indicator_led(mode);
+ save_config();
+ return MISCHIEF_MANAGED;
+ }
+ #if 0 // old method, deprecated in favor of "7 clicks from off"
+ // click, click, hold: rotate through indicator LED modes (off mode)
+ else if (event == EV_click3_hold) {
+ #ifndef USE_INDICATOR_LED_WHILE_RAMPING
+ // if main LED obscures aux LEDs, turn it off
+ set_level(0);
+ #endif
+ #ifdef TICK_DURING_STANDBY
+ uint8_t mode = (arg >> 5) & 3;
+ #else
+ uint8_t mode = (arg >> 5) % 3;
+ #endif
+ #ifdef INDICATOR_LED_SKIP_LOW
+ if (mode == 1) { mode ++; }
+ #endif
+ indicator_led_mode = (indicator_led_mode & 0b11111100) | mode;
+ #ifdef TICK_DURING_STANDBY
+ if (mode == 3)
+ indicator_led(mode & (arg&3));
+ else
+ indicator_led(mode);
+ #else
+ indicator_led(mode);
+ #endif
+ //save_config();
+ return MISCHIEF_MANAGED;
+ }
+ // click, click, hold, release: save indicator LED mode (off mode)
+ else if (event == EV_click3_hold_release) {
+ save_config();
+ return MISCHIEF_MANAGED;
+ }
+ #endif
+ #endif
+ // 4 clicks: exit
+ else if (event == EV_4clicks) {
+ blink_confirm(1);
+ set_state(off_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+
+ return EVENT_NOT_HANDLED;
+}
+
+
+uint8_t momentary_state(Event event, uint16_t arg) {
+ // TODO: momentary strobe here? (for light painting)
+
+ // light up when the button is pressed; go dark otherwise
+ // button is being held
+ if ((event & (B_CLICK | B_PRESS)) == (B_CLICK | B_PRESS)) {
+ set_level(memorized_level);
+ return MISCHIEF_MANAGED;
+ }
+ // button was released
+ else if ((event & (B_CLICK | B_PRESS)) == (B_CLICK)) {
+ set_level(0);
+ //go_to_standby = 1; // sleep while light is off
+ return MISCHIEF_MANAGED;
+ }
+
+ // Sleep, dammit! (but wait a few seconds first)
+ // (because standby mode uses such little power that it can interfere
+ // with exiting via tailcap loosen+tighten unless you leave power
+ // disconnected for several seconds, so we want to be awake when that
+ // happens to speed up the process)
+ else if ((event == EV_tick) && (actual_level == 0)) {
+ if (arg > TICKS_PER_SECOND*15) { // sleep after 15 seconds
+ go_to_standby = 1; // sleep while light is off
+ // TODO: lighted button should use lockout config?
+ }
+ return MISCHIEF_MANAGED;
+ }
+
+ return EVENT_NOT_HANDLED;
+}
+
+
+#ifdef USE_MUGGLE_MODE
+uint8_t muggle_state(Event event, uint16_t arg) {
+ static int8_t ramp_direction;
+ static int8_t muggle_off_mode;
+
+ // turn LED off when we first enter the mode
+ if (event == EV_enter_state) {
+ ramp_direction = 1;
+
+ #ifdef START_AT_MEMORIZED_LEVEL
+ memorized_level = arg;
+ muggle_off_mode = 0;
+ set_level(memorized_level);
+
+ if (! muggle_mode_active) { // don't write eeprom at every boot
+ muggle_mode_active = 1;
+ save_config();
+ }
+ #else
+ muggle_mode_active = 1;
+ save_config();
+
+ muggle_off_mode = 1;
+ //memorized_level = MAX_1x7135;
+ memorized_level = (MUGGLE_FLOOR + MUGGLE_CEILING) / 2;
+ #endif
+ return MISCHIEF_MANAGED;
+ }
+ // initial press: moon hint
+ else if (event == EV_click1_press) {
+ if (muggle_off_mode)
+ set_level(MUGGLE_FLOOR);
+ }
+ // initial release: direct to memorized level
+ else if (event == EV_click1_release) {
+ if (muggle_off_mode)
+ set_level(memorized_level);
+ }
+ // if the user keeps pressing, turn off
+ else if (event == EV_click2_press) {
+ muggle_off_mode = 1;
+ set_level(0);
+ }
+ // 1 click: on/off
+ else if (event == EV_1click) {
+ muggle_off_mode ^= 1;
+ if (muggle_off_mode) {
+ set_level(0);
+ }
+ /*
+ else {
+ set_level(memorized_level);
+ }
+ */
+ return MISCHIEF_MANAGED;
+ }
+ // hold: change brightness
+ else if (event == EV_click1_hold) {
+ // ramp at half speed
+ if (arg & 1) return MISCHIEF_MANAGED;
+
+ // if off, start at bottom
+ if (muggle_off_mode) {
+ muggle_off_mode = 0;
+ ramp_direction = 1;
+ set_level(MUGGLE_FLOOR);
+ }
+ else {
+ uint8_t m;
+ m = actual_level;
+ // ramp down if already at ceiling
+ if ((arg <= 1) && (m >= MUGGLE_CEILING)) ramp_direction = -1;
+ // ramp
+ m += ramp_direction;
+ if (m < MUGGLE_FLOOR)
+ m = MUGGLE_FLOOR;
+ if (m > MUGGLE_CEILING)
+ m = MUGGLE_CEILING;
+ memorized_level = m;
+ set_level(m);
+ }
+ return MISCHIEF_MANAGED;
+ }
+ // reverse ramp direction on hold release
+ else if (event == EV_click1_hold_release) {
+ ramp_direction = -ramp_direction;
+ #ifdef START_AT_MEMORIZED_LEVEL
+ save_config_wl(); // momentary use should retain brightness level
+ #endif
+ return MISCHIEF_MANAGED;
+ }
+ /*
+ // click, hold: change brightness (dimmer)
+ else if (event == EV_click2_hold) {
+ ramp_direction = 1;
+ if (memorized_level > MUGGLE_FLOOR)
+ memorized_level = actual_level - 1;
+ set_level(memorized_level);
+ return MISCHIEF_MANAGED;
+ }
+ */
+ // 6 clicks: exit muggle mode
+ else if (event == EV_6clicks) {
+ blink_confirm(1);
+ muggle_mode_active = 0;
+ save_config();
+ set_state(off_state, 0);
+ return MISCHIEF_MANAGED;
+ }
+ // tick: housekeeping
+ else if (event == EV_tick) {
+ // un-reverse after 1 second
+ if (arg == TICKS_PER_SECOND) ramp_direction = 1;
+
+ // turn off, but don't go to the main "off" state
+ if (muggle_off_mode) {
+ if (arg > TICKS_PER_SECOND*1) { // sleep after 1 second
+ go_to_standby = 1; // sleep while light is off
+ }
+ }
+ return MISCHIEF_MANAGED;
+ }
+ #ifdef USE_THERMAL_REGULATION
+ // overheating is handled specially in muggle mode
+ else if(event == EV_temperature_high) {
+ // don't even try...
+ // go immediately to the bottom, in case someone put the light on
+ // maximum while wrapped in dark-colored flammable insulation
+ // or something, because muggles are cool like that
+ // memorized_level = MUGGLE_FLOOR; // override memory? maybe not
+ set_level(MUGGLE_FLOOR);
+ return MISCHIEF_MANAGED;
+ }
+ #endif
+ // low voltage is handled specially in muggle mode
+ else if(event == EV_voltage_low) {
+ uint8_t lvl = (actual_level >> 1) + (actual_level >> 2);
+ if (lvl >= MUGGLE_FLOOR) {
+ set_level(lvl);
+ } else {
+ muggle_off_mode = 1;
+ }
+ return MISCHIEF_MANAGED;
+ }
+
+ return EVENT_NOT_HANDLED;
+}
+#endif
+
+
+// ask the user for a sequence of numbers, then save them and return to caller
+uint8_t config_state_base(Event event, uint16_t arg,
+ uint8_t num_config_steps,
+ void (*savefunc)()) {
+ static uint8_t config_step;
+ if (event == EV_enter_state) {
+ config_step = 0;
+ set_level(0);
+ return MISCHIEF_MANAGED;
+ }
+ // advance forward through config steps
+ else if (event == EV_tick) {
+ if (config_step < num_config_steps) {
+ push_state(number_entry_state, config_step + 1);
+ }
+ else {
+ // TODO: blink out some sort of success pattern
+ savefunc();
+ save_config();
+ //set_state(retstate, retval);
+ pop_state();
+ }
+ return MISCHIEF_MANAGED;
+ }
+ // an option was set (return from number_entry_state)
+ else if (event == EV_reenter_state) {
+ config_state_values[config_step] = number_entry_value;
+ config_step ++;
+ return MISCHIEF_MANAGED;
+ }
+ //return EVENT_NOT_HANDLED;
+ // eat all other events; don't pass any through to parent
+ return EVENT_HANDLED;
+}
+
+void ramp_config_save() {
+ // parse values
+ uint8_t val;
+ if (ramp_style) { // discrete / stepped ramp
+
+ val = config_state_values[0];
+ if (val) { ramp_discrete_floor = val; }
+
+ val = config_state_values[1];
+ if (val) { ramp_discrete_ceil = MAX_LEVEL + 1 - val; }
+
+ val = config_state_values[2];
+ if (val) ramp_discrete_steps = val;
+
+ } else { // smooth ramp
+
+ val = config_state_values[0];
+ if (val) { ramp_smooth_floor = val; }
+
+ val = config_state_values[1];
+ if (val) { ramp_smooth_ceil = MAX_LEVEL + 1 - val; }
+
+ }
+}
+
+uint8_t ramp_config_state(Event event, uint16_t arg) {
+ uint8_t num_config_steps;
+ num_config_steps = 2 + ramp_style;
+ return config_state_base(event, arg,
+ num_config_steps, ramp_config_save);
+}
+
+
+#ifdef USE_THERMAL_REGULATION
+void thermal_config_save() {
+ // parse values
+ uint8_t val;
+
+ // calibrate room temperature
+ val = config_state_values[0];
+ if (val) {
+ int8_t rawtemp = (temperature >> 1) - therm_cal_offset;
+ therm_cal_offset = val - rawtemp;
+ }
+
+ val = config_state_values[1];
+ if (val) {
+ // set maximum heat limit
+ therm_ceil = 30 + val;
+ }
+ if (therm_ceil > MAX_THERM_CEIL) therm_ceil = MAX_THERM_CEIL;
+}
+
+uint8_t thermal_config_state(Event event, uint16_t arg) {
+ return config_state_base(event, arg,
+ 2, thermal_config_save);
+}
+#endif
+
+
+void beacon_config_save() {
+ // parse values
+ uint8_t val = config_state_values[0];
+ if (val) {
+ beacon_seconds = val;
+ }
+}
+
+uint8_t beacon_config_state(Event event, uint16_t arg) {
+ return config_state_base(event, arg,
+ 1, beacon_config_save);
+}
+
+
+uint8_t number_entry_state(Event event, uint16_t arg) {
+ static uint8_t value;
+ static uint8_t blinks_left;
+ static uint8_t entry_step;
+ static uint16_t wait_ticks;
+ if (event == EV_enter_state) {
+ value = 0;
+ blinks_left = arg;
+ entry_step = 0;
+ wait_ticks = 0;
+ return MISCHIEF_MANAGED;
+ }
+ // advance through the process:
+ // 0: wait a moment
+ // 1: blink out the 'arg' value
+ // 2: wait a moment
+ // 3: "buzz" while counting clicks
+ // 4: save and exit
+ else if (event == EV_tick) {
+ // wait a moment
+ if ((entry_step == 0) || (entry_step == 2)) {
+ if (wait_ticks < TICKS_PER_SECOND/2)
+ wait_ticks ++;
+ else {
+ entry_step ++;
+ wait_ticks = 0;
+ }
+ }
+ // blink out the option number
+ else if (entry_step == 1) {
+ if (blinks_left) {
+ if ((wait_ticks & 31) == 10) {
+ set_level(RAMP_SIZE/4);
+ }
+ else if ((wait_ticks & 31) == 20) {
+ set_level(0);
+ }
+ else if ((wait_ticks & 31) == 31) {
+ blinks_left --;
+ }
+ wait_ticks ++;
+ }
+ else {
+ entry_step ++;
+ wait_ticks = 0;
+ }
+ }
+ else if (entry_step == 3) { // buzz while waiting for a number to be entered
+ wait_ticks ++;
+ // buzz for N seconds after last event
+ if ((wait_ticks & 3) == 0) {
+ set_level(RAMP_SIZE/6);
+ }
+ else if ((wait_ticks & 3) == 2) {
+ set_level(RAMP_SIZE/8);
+ }
+ // time out after 3 seconds
+ if (wait_ticks > TICKS_PER_SECOND*3) {
+ //number_entry_value = value;
+ set_level(0);
+ entry_step ++;
+ }
+ }
+ else if (entry_step == 4) {
+ number_entry_value = value;
+ pop_state();
+ }
+ return MISCHIEF_MANAGED;
+ }
+ // count clicks
+ else if (event == EV_click1_release) {
+ empty_event_sequence();
+ if (entry_step == 3) { // only count during the "buzz"
+ value ++;
+ wait_ticks = 0;
+ // flash briefly
+ set_level(RAMP_SIZE/2);
+ delay_4ms(8/2);
+ set_level(0);
+ }
+ return MISCHIEF_MANAGED;
+ }
+ return EVENT_NOT_HANDLED;
+}
+
+
+// find the ramp level closest to the target,
+// using only the levels which are allowed in the current state
+uint8_t nearest_level(int16_t target) {
+ // bounds check
+ // using int16_t here saves us a bunch of logic elsewhere,
+ // by allowing us to correct for numbers < 0 or > 255 in one central place
+ uint8_t mode_min = ramp_smooth_floor;
+ uint8_t mode_max = ramp_smooth_ceil;
+ if (ramp_style) {
+ mode_min = ramp_discrete_floor;
+ mode_max = ramp_discrete_ceil;
+ }
+ if (target < mode_min) return mode_min;
+ if (target > mode_max) return mode_max;
+ // the rest isn't relevant for smooth ramping
+ if (! ramp_style) return target;
+
+ uint8_t ramp_range = ramp_discrete_ceil - ramp_discrete_floor;
+ ramp_discrete_step_size = ramp_range / (ramp_discrete_steps-1);
+ uint8_t this_level = ramp_discrete_floor;
+
+ for(uint8_t i=0; i>1))
+ return this_level;
+ }
+ return this_level;
+}
+
+
+void blink_confirm(uint8_t num) {
+ for (; num>0; num--) {
+ set_level(MAX_LEVEL/4);
+ delay_4ms(10/4);
+ set_level(0);
+ delay_4ms(100/4);
+ }
+}
+
+
+#if defined(USE_INDICATOR_LED) && defined(TICK_DURING_STANDBY)
+// beacon-like mode for the indicator LED
+void indicator_blink(uint8_t arg) {
+ #ifdef USE_FANCIER_BLINKING_INDICATOR
+
+ // fancy blink, set off/low/high levels here:
+ uint8_t seq[] = {0, 1, 2, 1, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0};
+ indicator_led(seq[arg & 15]);
+
+ #else // basic blink, 1/8th duty cycle
+
+ if (! (arg & 7)) {
+ indicator_led(2);
+ }
+ else {
+ indicator_led(0);
+ }
+
+ #endif
+}
+#endif
+
+
+#ifdef USE_CANDLE_MODE
+uint8_t triangle_wave(uint8_t phase) {
+ uint8_t result = phase << 1;
+ if (phase > 127) result = 255 - result;
+ return result;
+}
+#endif
+
+
+void load_config() {
+ if (load_eeprom()) {
+ ramp_style = eeprom[ramp_style_e];
+ 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];
+ #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];
+ strobe_delays[1] = eeprom[strobe_delays_1_e];
+ #endif
+ #ifdef USE_BIKE_FLASHER_MODE
+ bike_flasher_brightness = eeprom[bike_flasher_brightness_e];
+ #endif
+ beacon_seconds = eeprom[beacon_seconds_e];
+ #ifdef USE_MUGGLE_MODE
+ muggle_mode_active = eeprom[muggle_mode_active_e];
+ #endif
+ #ifdef USE_THERMAL_REGULATION
+ therm_ceil = eeprom[therm_ceil_e];
+ therm_cal_offset = eeprom[therm_cal_offset_e];
+ #endif
+ #ifdef USE_INDICATOR_LED
+ indicator_led_mode = eeprom[indicator_led_mode_e];
+ #endif
+ }
+ #ifdef START_AT_MEMORIZED_LEVEL
+ if (load_eeprom_wl()) {
+ memorized_level = eeprom_wl[0];
+ }
+ #endif
+}
+
+void save_config() {
+ eeprom[ramp_style_e] = ramp_style;
+ 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;
+ #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];
+ eeprom[strobe_delays_1_e] = strobe_delays[1];
+ #endif
+ #ifdef USE_BIKE_FLASHER_MODE
+ eeprom[bike_flasher_brightness_e] = bike_flasher_brightness;
+ #endif
+ eeprom[beacon_seconds_e] = beacon_seconds;
+ #ifdef USE_MUGGLE_MODE
+ eeprom[muggle_mode_active_e] = muggle_mode_active;
+ #endif
+ #ifdef USE_THERMAL_REGULATION
+ eeprom[therm_ceil_e] = therm_ceil;
+ eeprom[therm_cal_offset_e] = therm_cal_offset;
+ #endif
+ #ifdef USE_INDICATOR_LED
+ eeprom[indicator_led_mode_e] = indicator_led_mode;
+ #endif
+
+ save_eeprom();
+}
+
+#ifdef START_AT_MEMORIZED_LEVEL
+void save_config_wl() {
+ eeprom_wl[0] = memorized_level;
+ save_eeprom_wl();
+}
+#endif
+
+void low_voltage() {
+ StatePtr state = current_state;
+
+ // TODO: turn off aux LED(s) when power is really low
+
+ if (0) {} // placeholder
+
+ #ifdef USE_STROBE_STATE
+ // "step down" from strobe to something low
+ else if (state == strobe_state) {
+ set_state(steady_state, RAMP_SIZE/6);
+ }
+ #endif
+
+ // in normal or muggle mode, step down or turn off
+ //else if ((state == steady_state) || (state == muggle_state)) {
+ else if (state == steady_state) {
+ if (actual_level > 1) {
+ uint8_t lvl = (actual_level >> 1) + (actual_level >> 2);
+ set_level(lvl);
+ #ifdef USE_THERMAL_REGULATION
+ target_level = lvl;
+ #ifdef USE_SET_LEVEL_GRADUALLY
+ // not needed?
+ //set_level_gradually(lvl);
+ #endif
+ #endif
+ }
+ else {
+ set_state(off_state, 0);
+ }
+ }
+ // all other modes, just turn off when voltage is low
+ else {
+ set_state(off_state, 0);
+ }
+}
+
+
+void setup() {
+ #ifdef START_AT_MEMORIZED_LEVEL
+ // dual switch: e-switch + power clicky
+ // power clicky acts as a momentary mode
+ load_config();
+
+ #ifdef USE_MUGGLE_MODE
+ if (muggle_mode_active)
+ push_state(muggle_state, memorized_level);
+ else
+ #endif
+ if (button_is_pressed())
+ // hold button to go to moon
+ push_state(steady_state, 1);
+ else
+ // otherwise use memory
+ push_state(steady_state, memorized_level);
+
+ #else // if not START_AT_MEMORIZED_LEVEL
+
+ // blink at power-on to let user know power is connected
+ set_level(RAMP_SIZE/8);
+ delay_4ms(3);
+ set_level(0);
+
+ load_config();
+
+ #ifdef USE_MUGGLE_MODE
+ if (muggle_mode_active)
+ push_state(muggle_state, (MUGGLE_FLOOR+MUGGLE_CEILING)/2);
+ else
+ #endif
+ push_state(off_state, 0);
+ #endif
+
+}
+
+
+void loop() {
+
+ StatePtr state = current_state;
+
+ if (0) {}
+
+ #ifdef USE_STROBE_STATE
+ if (state == strobe_state) {
+ uint8_t st = strobe_type;
+
+ if (0) {} // placeholder
+
+ // party / tactial strobe
+ #if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE)
+ #ifdef USE_TACTICAL_STROBE_MODE
+ else if (st <= tactical_strobe_e) {
+ #else
+ else if (st == party_strobe_e) {
+ #endif
+ uint8_t del = strobe_delays[st];
+ // TODO: make tac strobe brightness configurable?
+ set_level(STROBE_BRIGHTNESS);
+ if (st == party_strobe_e) { // party strobe
+ if (del < 42) delay_zero();
+ else nice_delay_ms(1);
+ } else { //tactical strobe
+ nice_delay_ms(del >> 1);
+ }
+ set_level(0);
+ nice_delay_ms(del); // no return check necessary on final delay
+ }
+ #endif
+
+ // lightning storm
+ #ifdef USE_LIGHTNING_MODE
+ else if (st == lightning_storm_e) {
+ int16_t brightness;
+ uint16_t rand_time;
+
+ // turn the emitter on at a random level,
+ // for a random amount of time between 1ms and 32ms
+ //rand_time = 1 << (pseudo_rand() % 7);
+ rand_time = pseudo_rand() & 63;
+ brightness = 1 << (pseudo_rand() % 7); // 1, 2, 4, 8, 16, 32, 64
+ brightness += 1 << (pseudo_rand() & 0x03); // 2 to 80 now
+ brightness += pseudo_rand() % brightness; // 2 to 159 now (w/ low bias)
+ if (brightness > MAX_LEVEL) brightness = MAX_LEVEL;
+ set_level(brightness);
+ nice_delay_ms(rand_time);
+
+ // decrease the brightness somewhat more gradually, like lightning
+ uint8_t stepdown = brightness >> 3;
+ if (stepdown < 1) stepdown = 1;
+ while(brightness > 1) {
+ nice_delay_ms(rand_time);
+ brightness -= stepdown;
+ if (brightness < 0) brightness = 0;
+ set_level(brightness);
+ /*
+ if ((brightness < MAX_LEVEL/2) && (! (pseudo_rand() & 15))) {
+ brightness <<= 1;
+ set_level(brightness);
+ }
+ */
+ if (! (pseudo_rand() & 3)) {
+ nice_delay_ms(rand_time);
+ set_level(brightness>>1);
+ }
+ }
+
+ // turn the emitter off,
+ // for a random amount of time between 1ms and 8192ms
+ // (with a low bias)
+ rand_time = 1 << (pseudo_rand() % 13);
+ rand_time += pseudo_rand() % rand_time;
+ set_level(0);
+ nice_delay_ms(rand_time); // no return check necessary on final delay
+ }
+ #endif
+
+ // candle mode
+ #ifdef USE_CANDLE_MODE
+ // this NOP should get compiled out
+ else if (st == candle_mode_e) {}
+ #endif
+
+ // bike flasher
+ #ifdef USE_BIKE_FLASHER_MODE
+ else if (st == bike_flasher_e) {
+ uint8_t burst = bike_flasher_brightness << 1;
+ if (burst > MAX_LEVEL) burst = MAX_LEVEL;
+ for(uint8_t i=0; i<4; i++) {
+ set_level(burst);
+ nice_delay_ms(5);
+ set_level(bike_flasher_brightness);
+ nice_delay_ms(65);
+ }
+ nice_delay_ms(720); // no return check necessary on final delay
+ }
+ #endif
+
+ }
+ #endif // #ifdef USE_STROBE_STATE
+
+ #ifdef USE_BATTCHECK
+ else if (state == battcheck_state) {
+ battcheck();
+ }
+ #endif
+ #ifdef USE_THERMAL_REGULATION
+ // TODO: blink out therm_ceil during thermal_config_state
+ else if (state == tempcheck_state) {
+ blink_num(temperature>>1);
+ nice_delay_ms(1000);
+ }
+ #endif
+
+ else if (state == beacon_state) {
+ set_level(memorized_level);
+ nice_delay_ms(500);
+ set_level(0);
+ nice_delay_ms(((beacon_seconds) * 1000) - 500);
+ }
+
+ #ifdef USE_IDLE_MODE
+ else {
+ // doze until next clock tick
+ idle_mode();
+ }
+ #endif
+
+}
--
cgit v1.2.3
From d70330a712b2b410717aa775f031fd39961adb04 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Tue, 12 Mar 2019 01:39:40 -0600
Subject: config file for unnamed Fireflies EDC thrower, with spec'd values
---
.../fireflies-ui/cfg-ff-edc-thrower.h | 27 ++++++++++++++++++++++
1 file changed, 27 insertions(+)
create mode 100644 spaghetti-monster/fireflies-ui/cfg-ff-edc-thrower.h
(limited to 'spaghetti-monster')
diff --git a/spaghetti-monster/fireflies-ui/cfg-ff-edc-thrower.h b/spaghetti-monster/fireflies-ui/cfg-ff-edc-thrower.h
new file mode 100644
index 0000000..752afe2
--- /dev/null
+++ b/spaghetti-monster/fireflies-ui/cfg-ff-edc-thrower.h
@@ -0,0 +1,27 @@
+// Fireflies EDC thrower config options for Fireflies UI
+#include "cfg-ff-pl47.h"
+
+// disable indicator LED
+#undef USE_INDICATOR_LED
+
+// ceiling is level 130/150 (50% power)
+#undef RAMP_SMOOTH_CEIL
+#define RAMP_SMOOTH_CEIL 130
+
+// 10, 28, 46, 65, 83, 101, 120 (83 is highest regulated)
+#undef RAMP_DISCRETE_FLOOR
+#define RAMP_DISCRETE_FLOOR 20
+#undef RAMP_DISCRETE_CEIL
+#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#undef RAMP_DISCRETE_STEPS
+#define RAMP_DISCRETE_STEPS 3
+
+// regulate down faster when the FET is active, slower otherwise
+#undef THERM_FASTER_LEVEL
+#define THERM_FASTER_LEVEL 130 // throttle back faster when high
+
+// play it safe, don't try to regulate above the recommended safe level
+#ifndef THERM_HARD_TURBO_DROP
+#define THERM_HARD_TURBO_DROP
+#endif
+
--
cgit v1.2.3
From 3a5ed200c051a3e54b4ad6ae5bf719516d2fa267 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Tue, 12 Mar 2019 01:45:40 -0600
Subject: 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
---
spaghetti-monster/fireflies-ui/fireflies-ui.c | 197 +++++++++++++++++++++++---
1 file changed, 176 insertions(+), 21 deletions(-)
(limited to 'spaghetti-monster')
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 {
--
cgit v1.2.3
From 0554aef811ddc792a1b15c302f65d484bfa70ed9 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Tue, 12 Mar 2019 02:13:05 -0600
Subject: merged some (most) of ffui's changes back into anduril
---
spaghetti-monster/anduril/anduril.c | 145 +++++++++++++++++++++++++-
spaghetti-monster/fireflies-ui/fireflies-ui.c | 35 ++++++-
2 files changed, 171 insertions(+), 9 deletions(-)
(limited to 'spaghetti-monster')
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];
--
cgit v1.2.3
From e326c6e86131afbb76f05f5f0ea565eae88f4dfb Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Tue, 12 Mar 2019 03:35:53 -0600
Subject: anduril: refactored pretty much all the blinky code, to put inner
loops in their own functions (because it keeps the code cleaner) (also moved
candle mode to its own pseudo-state, even though it cost about 24 bytes,
because the code for strobe state was really messy with candle mode
intertwined)
---
spaghetti-monster/anduril/anduril.c | 519 ++++++++++++++++++++----------------
1 file changed, 282 insertions(+), 237 deletions(-)
(limited to 'spaghetti-monster')
diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c
index 5bbf39b..d25e88d 100644
--- a/spaghetti-monster/anduril/anduril.c
+++ b/spaghetti-monster/anduril/anduril.c
@@ -352,6 +352,7 @@ volatile uint8_t bike_flasher_brightness = MAX_1x7135;
#endif
#ifdef USE_CANDLE_MODE
+uint8_t candle_mode_state(Event event, uint16_t arg);
uint8_t triangle_wave(uint8_t phase);
#endif
@@ -838,30 +839,21 @@ uint8_t strobe_state(Event event, uint16_t arg) {
// 'st' reduces ROM size by avoiding access to a volatile var
// (maybe I should just make it nonvolatile?)
strobe_mode_te st = strobe_type;
+
#ifdef USE_CANDLE_MODE
- // FIXME: make candle variance magnitude a compile-time option,
- // since 20 is sometimes too much or too little,
- // depending on the driver type and ramp shape
- //#define MAX_CANDLE_LEVEL (RAMP_SIZE-8-6-4)
- #define MAX_CANDLE_LEVEL (RAMP_SIZE/2)
- static uint8_t candle_wave1 = 0;
- static uint8_t candle_wave2 = 0;
- static uint8_t candle_wave3 = 0;
- static uint8_t candle_wave2_speed = 0;
- static uint8_t candle_wave2_depth = 7;
- static uint8_t candle_wave3_depth = 4;
- static uint8_t candle_mode_brightness = 24;
- static uint8_t candle_mode_timer = 0;
- #define TICKS_PER_CANDLE_MINUTE 4096 // about 65 seconds
- #define MINUTES_PER_CANDLE_HALFHOUR 27 // ish
+ // pass all events to candle mode, when it's active
+ // (the code is in its own pseudo-state to keep things cleaner)
+ if (st == candle_mode_e) {
+ candle_mode_state(event, arg);
+ }
#endif
- if (event == EV_enter_state) {
- #ifdef USE_CANDLE_MODE
- candle_mode_timer = 0; // in case any time was left over from earlier
- #endif
+ if (0) {} // placeholder
+ /* not used any more
+ else if (event == EV_enter_state) {
return MISCHIEF_MANAGED;
}
+ */
// 1 click: off
else if (event == EV_1click) {
set_state(off_state, 0);
@@ -870,10 +862,6 @@ uint8_t strobe_state(Event event, uint16_t arg) {
// 2 clicks: rotate through strobe/flasher modes
else if (event == EV_2clicks) {
strobe_type = (st + 1) % NUM_STROBES;
- #ifdef USE_CANDLE_MODE
- candle_mode_timer = 0; // in case any time was left over from earlier
- #endif
- //interrupt_nice_delays();
save_config();
return MISCHIEF_MANAGED;
}
@@ -898,14 +886,6 @@ uint8_t strobe_state(Event event, uint16_t arg) {
// lightning has no adjustments
//else if (st == lightning_storm_e) {}
- // candle mode brighter
- #ifdef USE_CANDLE_MODE
- else if (st == candle_mode_e) {
- if (candle_mode_brightness < MAX_CANDLE_LEVEL)
- candle_mode_brightness ++;
- }
- #endif
-
// biking mode brighter
#ifdef USE_BIKE_FLASHER_MODE
else if (st == bike_flasher_e) {
@@ -938,14 +918,6 @@ uint8_t strobe_state(Event event, uint16_t arg) {
// lightning has no adjustments
//else if (st == lightning_storm_e) {}
- // candle mode dimmer
- #ifdef USE_CANDLE_MODE
- else if (st == candle_mode_e) {
- if (candle_mode_brightness > 1)
- candle_mode_brightness --;
- }
- #endif
-
// biking mode dimmer
#ifdef USE_BIKE_FLASHER_MODE
else if (st == bike_flasher_e) {
@@ -963,87 +935,212 @@ uint8_t strobe_state(Event event, uint16_t arg) {
save_config();
return MISCHIEF_MANAGED;
}
- #if defined(USE_CANDLE_MODE)
+ #if defined(USE_LIGHTNING_MODE) || defined(USE_CANDLE_MODE)
+ // clock tick: bump the random seed
+ else if (event == EV_tick) {
+ pseudo_rand_seed += arg;
+ return MISCHIEF_MANAGED;
+ }
+ #endif
+ return EVENT_NOT_HANDLED;
+}
+
+#if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE)
+inline void party_tactical_strobe_mode_iter(uint8_t st) {
+ // one iteration of main loop()
+ uint8_t del = strobe_delays[st];
+ // TODO: make tac strobe brightness configurable?
+ set_level(STROBE_BRIGHTNESS);
+ if (st == party_strobe_e) { // party strobe
+ if (del < 42) delay_zero();
+ else nice_delay_ms(1);
+ } else { //tactical strobe
+ nice_delay_ms(del >> 1);
+ }
+ set_level(0);
+ nice_delay_ms(del); // no return check necessary on final delay
+}
+#endif
+
+#ifdef USE_LIGHTNING_MODE
+inline void lightning_storm_iter() {
+ // one iteration of main loop()
+ int16_t brightness;
+ uint16_t rand_time;
+
+ // turn the emitter on at a random level,
+ // for a random amount of time between 1ms and 32ms
+ //rand_time = 1 << (pseudo_rand() % 7);
+ rand_time = pseudo_rand() & 63;
+ brightness = 1 << (pseudo_rand() % 7); // 1, 2, 4, 8, 16, 32, 64
+ brightness += 1 << (pseudo_rand() & 0x03); // 2 to 80 now
+ brightness += pseudo_rand() % brightness; // 2 to 159 now (w/ low bias)
+ if (brightness > MAX_LEVEL) brightness = MAX_LEVEL;
+ set_level(brightness);
+ nice_delay_ms(rand_time);
+
+ // decrease the brightness somewhat more gradually, like lightning
+ uint8_t stepdown = brightness >> 3;
+ if (stepdown < 1) stepdown = 1;
+ while(brightness > 1) {
+ nice_delay_ms(rand_time);
+ brightness -= stepdown;
+ if (brightness < 0) brightness = 0;
+ set_level(brightness);
+ /*
+ if ((brightness < MAX_LEVEL/2) && (! (pseudo_rand() & 15))) {
+ brightness <<= 1;
+ set_level(brightness);
+ }
+ */
+ if (! (pseudo_rand() & 3)) {
+ nice_delay_ms(rand_time);
+ set_level(brightness>>1);
+ }
+ }
+
+ // turn the emitter off,
+ // for a random amount of time between 1ms and 8192ms
+ // (with a low bias)
+ rand_time = 1 << (pseudo_rand() % 13);
+ rand_time += pseudo_rand() % rand_time;
+ set_level(0);
+ nice_delay_ms(rand_time); // no return check necessary on final delay
+}
+#endif
+
+#ifdef USE_BIKE_FLASHER_MODE
+inline void bike_flasher_iter() {
+ // one iteration of main loop()
+ uint8_t burst = bike_flasher_brightness << 1;
+ if (burst > MAX_LEVEL) burst = MAX_LEVEL;
+ for(uint8_t i=0; i<4; i++) {
+ set_level(burst);
+ nice_delay_ms(5);
+ set_level(bike_flasher_brightness);
+ nice_delay_ms(65);
+ }
+ nice_delay_ms(720); // no return check necessary on final delay
+}
+#endif
+
+#endif // ifdef USE_STROBE_STATE
+
+#ifdef USE_CANDLE_MODE
+uint8_t candle_mode_state(Event event, uint16_t arg) {
+ // FIXME: make candle variance magnitude a compile-time option,
+ // since 20 is sometimes too much or too little,
+ // depending on the driver type and ramp shape
+ //#define MAX_CANDLE_LEVEL (RAMP_SIZE-8-6-4)
+ #define MAX_CANDLE_LEVEL (RAMP_SIZE/2)
+ static uint8_t candle_wave1 = 0;
+ static uint8_t candle_wave2 = 0;
+ static uint8_t candle_wave3 = 0;
+ static uint8_t candle_wave2_speed = 0;
+ static uint8_t candle_wave2_depth = 7;
+ static uint8_t candle_wave3_depth = 4;
+ static uint8_t candle_mode_brightness = 24;
+ static uint8_t candle_mode_timer = 0;
+ #define TICKS_PER_CANDLE_MINUTE 4096 // about 65 seconds
+ #define MINUTES_PER_CANDLE_HALFHOUR 27 // ish
+
+ if (event == EV_enter_state) {
+ candle_mode_timer = 0; // in case any time was left over from earlier
+ return MISCHIEF_MANAGED;
+ }
+ // 2 clicks: cancel timer
+ else if (event == EV_2clicks) {
+ // parent state just rotated through strobe/flasher modes,
+ // so cancel timer... in case any time was left over from earlier
+ candle_mode_timer = 0;
+ return MISCHIEF_MANAGED;
+ }
+ // hold: change brightness (brighter)
+ else if (event == EV_click1_hold) {
+ if (candle_mode_brightness < MAX_CANDLE_LEVEL)
+ candle_mode_brightness ++;
+ return MISCHIEF_MANAGED;
+ }
+ // click, hold: change brightness (dimmer)
+ else if (event == EV_click2_hold) {
+ if (candle_mode_brightness > 1)
+ candle_mode_brightness --;
+ return MISCHIEF_MANAGED;
+ }
// 3 clicks: add 30m to candle timer
else if (event == EV_3clicks) {
- // candle mode only
- if (st == candle_mode_e) {
- if (candle_mode_timer < (255 - MINUTES_PER_CANDLE_HALFHOUR)) {
- // add 30m to the timer
- candle_mode_timer += MINUTES_PER_CANDLE_HALFHOUR;
- // blink to confirm
- set_level(actual_level + 32);
- delay_4ms(2);
- }
+ if (candle_mode_timer < (255 - MINUTES_PER_CANDLE_HALFHOUR)) {
+ // add 30m to the timer
+ candle_mode_timer += MINUTES_PER_CANDLE_HALFHOUR;
+ // blink to confirm
+ set_level(actual_level + 32);
+ delay_4ms(2);
}
return MISCHIEF_MANAGED;
}
- #endif
- #if defined(USE_LIGHTNING_MODE) || defined(USE_CANDLE_MODE)
- // clock tick: bump the random seed, adjust candle brightness
+ // clock tick: animate candle brightness
else if (event == EV_tick) {
- pseudo_rand_seed += arg;
-
- #ifdef USE_CANDLE_MODE
- if (st == candle_mode_e) {
- // self-timer dims the light during the final minute
- uint8_t subtract = 0;
- if (candle_mode_timer == 1) {
- subtract = ((candle_mode_brightness+20)
- * ((arg & (TICKS_PER_CANDLE_MINUTE-1)) >> 4))
- >> 8;
- }
- // we passed a minute mark, decrease timer if it's running
- if ((arg & (TICKS_PER_CANDLE_MINUTE-1)) == (TICKS_PER_CANDLE_MINUTE - 1)) {
- if (candle_mode_timer > 0) {
- candle_mode_timer --;
- //set_level(0); delay_4ms(2);
- // if the timer ran out, shut off
- if (! candle_mode_timer) {
- set_state(off_state, 0);
- }
+ // self-timer dims the light during the final minute
+ uint8_t subtract = 0;
+ if (candle_mode_timer == 1) {
+ subtract = ((candle_mode_brightness+20)
+ * ((arg & (TICKS_PER_CANDLE_MINUTE-1)) >> 4))
+ >> 8;
+ }
+ // we passed a minute mark, decrease timer if it's running
+ if ((arg & (TICKS_PER_CANDLE_MINUTE-1)) == (TICKS_PER_CANDLE_MINUTE - 1)) {
+ if (candle_mode_timer > 0) {
+ candle_mode_timer --;
+ //set_level(0); delay_4ms(2);
+ // if the timer ran out, shut off
+ if (! candle_mode_timer) {
+ set_state(off_state, 0);
}
}
- // 3-oscillator synth for a relatively organic pattern
- uint8_t add;
- add = ((triangle_wave(candle_wave1) * 8) >> 8)
- + ((triangle_wave(candle_wave2) * candle_wave2_depth) >> 8)
- + ((triangle_wave(candle_wave3) * candle_wave3_depth) >> 8);
- int8_t brightness = candle_mode_brightness + add - subtract;
- if (brightness < 0) { brightness = 0; }
- set_level(brightness);
-
- // wave1: slow random LFO
- if ((arg & 1) == 0) candle_wave1 += pseudo_rand() & 1;
- // wave2: medium-speed erratic LFO
- candle_wave2 += candle_wave2_speed;
- // wave3: erratic fast wave
- candle_wave3 += pseudo_rand() % 37;
- // S&H on wave2 frequency to make it more erratic
- if ((pseudo_rand() & 0b00111111) == 0)
- candle_wave2_speed = pseudo_rand() % 13;
- // downward sawtooth on wave2 depth to simulate stabilizing
- if ((candle_wave2_depth > 0) && ((pseudo_rand() & 0b00111111) == 0))
- candle_wave2_depth --;
- // random sawtooth retrigger
- if ((pseudo_rand()) == 0) {
- candle_wave2_depth = 7;
- //candle_wave3_depth = 5;
- candle_wave2 = 0;
- }
- // downward sawtooth on wave3 depth to simulate stabilizing
- if ((candle_wave3_depth > 2) && ((pseudo_rand() & 0b00011111) == 0))
- candle_wave3_depth --;
- if ((pseudo_rand() & 0b01111111) == 0)
- candle_wave3_depth = 5;
}
- #endif
+ // 3-oscillator synth for a relatively organic pattern
+ uint8_t add;
+ add = ((triangle_wave(candle_wave1) * 8) >> 8)
+ + ((triangle_wave(candle_wave2) * candle_wave2_depth) >> 8)
+ + ((triangle_wave(candle_wave3) * candle_wave3_depth) >> 8);
+ int8_t brightness = candle_mode_brightness + add - subtract;
+ if (brightness < 0) { brightness = 0; }
+ set_level(brightness);
+
+ // wave1: slow random LFO
+ if ((arg & 1) == 0) candle_wave1 += pseudo_rand() & 1;
+ // wave2: medium-speed erratic LFO
+ candle_wave2 += candle_wave2_speed;
+ // wave3: erratic fast wave
+ candle_wave3 += pseudo_rand() % 37;
+ // S&H on wave2 frequency to make it more erratic
+ if ((pseudo_rand() & 0b00111111) == 0)
+ candle_wave2_speed = pseudo_rand() % 13;
+ // downward sawtooth on wave2 depth to simulate stabilizing
+ if ((candle_wave2_depth > 0) && ((pseudo_rand() & 0b00111111) == 0))
+ candle_wave2_depth --;
+ // random sawtooth retrigger
+ if ((pseudo_rand()) == 0) {
+ candle_wave2_depth = 7;
+ //candle_wave3_depth = 5;
+ candle_wave2 = 0;
+ }
+ // downward sawtooth on wave3 depth to simulate stabilizing
+ if ((candle_wave3_depth > 2) && ((pseudo_rand() & 0b00011111) == 0))
+ candle_wave3_depth --;
+ if ((pseudo_rand() & 0b01111111) == 0)
+ candle_wave3_depth = 5;
return MISCHIEF_MANAGED;
}
- #endif
return EVENT_NOT_HANDLED;
}
-#endif // ifdef USE_STROBE_STATE
+
+uint8_t triangle_wave(uint8_t phase) {
+ uint8_t result = phase << 1;
+ if (phase > 127) result = 255 - result;
+ return result;
+}
+#endif // #ifdef USE_CANDLE_MODE
#ifdef USE_BORING_STROBE_STATE
@@ -1071,6 +1168,22 @@ uint8_t boring_strobe_state(Event event, uint16_t arg) {
return EVENT_NOT_HANDLED;
}
+#ifdef USE_POLICE_STROBE_MODE
+inline void police_strobe_iter() {
+ // one iteration of main loop()
+ // 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);
+ }
+ }
+}
+#endif
+
+#ifdef USE_SOS_MODE
void sos_blink(uint8_t num, uint8_t dah) {
#define DIT_LENGTH 200
for (; num > 0; num--) {
@@ -1086,7 +1199,17 @@ void sos_blink(uint8_t num, uint8_t dah) {
// three "off" dits (or one "dah") between letters
nice_delay_ms(DIT_LENGTH*2);
}
-#endif // ifdef USE_BORING_STROBE_STATE
+
+inline void sos_mode_iter() {
+ // one iteration of main loop()
+ nice_delay_ms(1000);
+ sos_blink(3, 0); // S
+ sos_blink(3, 1); // O
+ sos_blink(3, 0); // S
+ nice_delay_ms(1000);
+}
+#endif // #ifdef USE_SOS_MODE
+#endif // #ifdef USE_BORING_STROBE_STATE
#ifdef USE_BATTCHECK
@@ -1608,6 +1731,14 @@ uint8_t beacon_config_state(Event event, uint16_t arg) {
return config_state_base(event, arg,
1, beacon_config_save);
}
+
+inline void beacon_mode_iter() {
+ // one iteration of main loop()
+ set_level(memorized_level);
+ nice_delay_ms(500);
+ set_level(0);
+ nice_delay_ms(((beacon_seconds) * 1000) - 500);
+}
#endif // #ifdef USE_BEACON_MODE
@@ -1763,15 +1894,6 @@ void indicator_blink(uint8_t arg) {
#endif
-#ifdef USE_CANDLE_MODE
-uint8_t triangle_wave(uint8_t phase) {
- uint8_t result = phase << 1;
- if (phase > 127) result = 255 - result;
- return result;
-}
-#endif
-
-
void load_config() {
if (load_eeprom()) {
ramp_style = eeprom[ramp_style_e];
@@ -1852,6 +1974,7 @@ void save_config_wl() {
}
#endif
+
void low_voltage() {
StatePtr state = current_state;
@@ -1936,127 +2059,51 @@ void loop() {
if (0) {}
#ifdef USE_STROBE_STATE
- if (state == strobe_state) {
+ else if (state == strobe_state) {
uint8_t st = strobe_type;
- if (0) {} // placeholder
-
- // party / tactial strobe
- #if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE)
- #ifdef USE_TACTICAL_STROBE_MODE
- else if (st <= tactical_strobe_e) {
- #else
- else if (st == party_strobe_e) {
- #endif
- uint8_t del = strobe_delays[st];
- // TODO: make tac strobe brightness configurable?
- set_level(STROBE_BRIGHTNESS);
- if (st == party_strobe_e) { // party strobe
- if (del < 42) delay_zero();
- else nice_delay_ms(1);
- } else { //tactical strobe
- nice_delay_ms(del >> 1);
- }
- set_level(0);
- nice_delay_ms(del); // no return check necessary on final delay
- }
- #endif
-
- // lightning storm
- #ifdef USE_LIGHTNING_MODE
- else if (st == lightning_storm_e) {
- int16_t brightness;
- uint16_t rand_time;
-
- // turn the emitter on at a random level,
- // for a random amount of time between 1ms and 32ms
- //rand_time = 1 << (pseudo_rand() % 7);
- rand_time = pseudo_rand() & 63;
- brightness = 1 << (pseudo_rand() % 7); // 1, 2, 4, 8, 16, 32, 64
- brightness += 1 << (pseudo_rand() & 0x03); // 2 to 80 now
- brightness += pseudo_rand() % brightness; // 2 to 159 now (w/ low bias)
- if (brightness > MAX_LEVEL) brightness = MAX_LEVEL;
- set_level(brightness);
- nice_delay_ms(rand_time);
-
- // decrease the brightness somewhat more gradually, like lightning
- uint8_t stepdown = brightness >> 3;
- if (stepdown < 1) stepdown = 1;
- while(brightness > 1) {
- nice_delay_ms(rand_time);
- brightness -= stepdown;
- if (brightness < 0) brightness = 0;
- set_level(brightness);
- /*
- if ((brightness < MAX_LEVEL/2) && (! (pseudo_rand() & 15))) {
- brightness <<= 1;
- set_level(brightness);
- }
- */
- if (! (pseudo_rand() & 3)) {
- nice_delay_ms(rand_time);
- set_level(brightness>>1);
- }
- }
-
- // turn the emitter off,
- // for a random amount of time between 1ms and 8192ms
- // (with a low bias)
- rand_time = 1 << (pseudo_rand() % 13);
- rand_time += pseudo_rand() % rand_time;
- set_level(0);
- nice_delay_ms(rand_time); // no return check necessary on final delay
- }
- #endif
+ switch(st) {
+ #if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE)
+ #ifdef USE_PARTY_STROBE_MODE
+ case party_strobe_e:
+ #endif
+ #ifdef USE_TACTICAL_STROBE_MODE
+ case tactical_strobe_e:
+ #endif
+ party_tactical_strobe_mode_iter(st);
+ break;
+ #endif
- // candle mode
- #ifdef USE_CANDLE_MODE
- // this NOP should get compiled out
- else if (st == candle_mode_e) {}
- #endif
+ #ifdef USE_LIGHTNING_MODE
+ case lightning_storm_e:
+ lightning_storm_iter();
+ break;
+ #endif
- // bike flasher
- #ifdef USE_BIKE_FLASHER_MODE
- else if (st == bike_flasher_e) {
- uint8_t burst = bike_flasher_brightness << 1;
- if (burst > MAX_LEVEL) burst = MAX_LEVEL;
- for(uint8_t i=0; i<4; i++) {
- set_level(burst);
- nice_delay_ms(5);
- set_level(bike_flasher_brightness);
- nice_delay_ms(65);
- }
- nice_delay_ms(720); // no return check necessary on final delay
+ #ifdef USE_BIKE_FLASHER_MODE
+ case bike_flasher_e:
+ bike_flasher_iter();
+ break;
+ #endif
}
- #endif
}
#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);
- }
- }
- }
+ else if (state == boring_strobe_state) {
+ switch(boring_strobe_type) {
+ #ifdef USE_POLICE_STROBE_MODE
+ case 0: // police strobe
+ police_strobe_iter();
+ break;
+ #endif
- // 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);
+ #ifdef USE_SOS_MODE
+ default: // SOS
+ sos_mode_iter();
+ break;
+ #endif
}
}
#endif // #ifdef USE_BORING_STROBE_STATE
@@ -2066,23 +2113,21 @@ void loop() {
battcheck();
}
#endif
+
+ #ifdef USE_BEACON_MODE
+ else if (state == beacon_state) {
+ beacon_mode_iter();
+ }
+ #endif
+
#ifdef USE_THERMAL_REGULATION
- // TODO: blink out therm_ceil during thermal_config_state
+ // TODO: blink out therm_ceil during thermal_config_state?
else if (state == tempcheck_state) {
blink_num(temperature>>1);
nice_delay_ms(1000);
}
#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 {
// doze until next clock tick
--
cgit v1.2.3
From 6cf59ea2a2bee60d81f0445c233bfd4b9e20d732 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Tue, 12 Mar 2019 03:41:09 -0600
Subject: fixed build error when only one of the two main strobes was enabled
---
spaghetti-monster/anduril/anduril.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
(limited to 'spaghetti-monster')
diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c
index d25e88d..fa4508e 100644
--- a/spaghetti-monster/anduril/anduril.c
+++ b/spaghetti-monster/anduril/anduril.c
@@ -951,12 +951,18 @@ inline void party_tactical_strobe_mode_iter(uint8_t st) {
uint8_t del = strobe_delays[st];
// TODO: make tac strobe brightness configurable?
set_level(STROBE_BRIGHTNESS);
- if (st == party_strobe_e) { // party strobe
+ if (0) {} // placeholde0
+ #ifdef USE_PARTY_STROBE_MODE
+ else if (st == party_strobe_e) { // party strobe
if (del < 42) delay_zero();
else nice_delay_ms(1);
- } else { //tactical strobe
+ }
+ #endif
+ #ifdef USE_TACTICAL_STROBE_MODE
+ else { //tactical strobe
nice_delay_ms(del >> 1);
}
+ #endif
set_level(0);
nice_delay_ms(del); // no return check necessary on final delay
}
--
cgit v1.2.3
From 891aa1c0f10c170e034d08ae1d654d2878f3d762 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Tue, 12 Mar 2019 03:45:35 -0600
Subject: merged anduril refactor changes into fireflies-ui
---
spaghetti-monster/fireflies-ui/fireflies-ui.c | 525 ++++++++++++++------------
1 file changed, 288 insertions(+), 237 deletions(-)
(limited to 'spaghetti-monster')
diff --git a/spaghetti-monster/fireflies-ui/fireflies-ui.c b/spaghetti-monster/fireflies-ui/fireflies-ui.c
index ba30605..6402a9d 100644
--- a/spaghetti-monster/fireflies-ui/fireflies-ui.c
+++ b/spaghetti-monster/fireflies-ui/fireflies-ui.c
@@ -396,6 +396,7 @@ volatile uint8_t bike_flasher_brightness = MAX_1x7135;
#endif
#ifdef USE_CANDLE_MODE
+uint8_t candle_mode_state(Event event, uint16_t arg);
uint8_t triangle_wave(uint8_t phase);
#endif
@@ -869,30 +870,21 @@ uint8_t strobe_state(Event event, uint16_t arg) {
// 'st' reduces ROM size by avoiding access to a volatile var
// (maybe I should just make it nonvolatile?)
strobe_mode_te st = strobe_type;
+
#ifdef USE_CANDLE_MODE
- // FIXME: make candle variance magnitude a compile-time option,
- // since 20 is sometimes too much or too little,
- // depending on the driver type and ramp shape
- //#define MAX_CANDLE_LEVEL (RAMP_SIZE-8-6-4)
- #define MAX_CANDLE_LEVEL (RAMP_SIZE/2)
- static uint8_t candle_wave1 = 0;
- static uint8_t candle_wave2 = 0;
- static uint8_t candle_wave3 = 0;
- static uint8_t candle_wave2_speed = 0;
- static uint8_t candle_wave2_depth = 7;
- static uint8_t candle_wave3_depth = 4;
- static uint8_t candle_mode_brightness = 24;
- static uint8_t candle_mode_timer = 0;
- #define TICKS_PER_CANDLE_MINUTE 4096 // about 65 seconds
- #define MINUTES_PER_CANDLE_HALFHOUR 27 // ish
+ // pass all events to candle mode, when it's active
+ // (the code is in its own pseudo-state to keep things cleaner)
+ if (st == candle_mode_e) {
+ candle_mode_state(event, arg);
+ }
#endif
- if (event == EV_enter_state) {
- #ifdef USE_CANDLE_MODE
- candle_mode_timer = 0; // in case any time was left over from earlier
- #endif
+ if (0) {} // placeholder
+ /* not used any more
+ else if (event == EV_enter_state) {
return MISCHIEF_MANAGED;
}
+ */
// 1 click: off
else if (event == EV_1click) {
set_state(off_state, 0);
@@ -901,10 +893,6 @@ uint8_t strobe_state(Event event, uint16_t arg) {
// 2 clicks: rotate through strobe/flasher modes
else if (event == EV_2clicks) {
strobe_type = (st + 1) % NUM_STROBES;
- #ifdef USE_CANDLE_MODE
- candle_mode_timer = 0; // in case any time was left over from earlier
- #endif
- //interrupt_nice_delays();
save_config();
return MISCHIEF_MANAGED;
}
@@ -929,14 +917,6 @@ uint8_t strobe_state(Event event, uint16_t arg) {
// lightning has no adjustments
//else if (st == lightning_storm_e) {}
- // candle mode brighter
- #ifdef USE_CANDLE_MODE
- else if (st == candle_mode_e) {
- if (candle_mode_brightness < MAX_CANDLE_LEVEL)
- candle_mode_brightness ++;
- }
- #endif
-
// biking mode brighter
#ifdef USE_BIKE_FLASHER_MODE
else if (st == bike_flasher_e) {
@@ -969,14 +949,6 @@ uint8_t strobe_state(Event event, uint16_t arg) {
// lightning has no adjustments
//else if (st == lightning_storm_e) {}
- // candle mode dimmer
- #ifdef USE_CANDLE_MODE
- else if (st == candle_mode_e) {
- if (candle_mode_brightness > 1)
- candle_mode_brightness --;
- }
- #endif
-
// biking mode dimmer
#ifdef USE_BIKE_FLASHER_MODE
else if (st == bike_flasher_e) {
@@ -994,87 +966,218 @@ uint8_t strobe_state(Event event, uint16_t arg) {
save_config();
return MISCHIEF_MANAGED;
}
- #if defined(USE_CANDLE_MODE)
+ #if defined(USE_LIGHTNING_MODE) || defined(USE_CANDLE_MODE)
+ // clock tick: bump the random seed
+ else if (event == EV_tick) {
+ pseudo_rand_seed += arg;
+ return MISCHIEF_MANAGED;
+ }
+ #endif
+ return EVENT_NOT_HANDLED;
+}
+
+#if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE)
+inline void party_tactical_strobe_mode_iter(uint8_t st) {
+ // one iteration of main loop()
+ uint8_t del = strobe_delays[st];
+ // TODO: make tac strobe brightness configurable?
+ set_level(STROBE_BRIGHTNESS);
+ if (0) {} // placeholde0
+ #ifdef USE_PARTY_STROBE_MODE
+ else if (st == party_strobe_e) { // party strobe
+ if (del < 42) delay_zero();
+ else nice_delay_ms(1);
+ }
+ #endif
+ #ifdef USE_TACTICAL_STROBE_MODE
+ else { //tactical strobe
+ nice_delay_ms(del >> 1);
+ }
+ #endif
+ set_level(0);
+ nice_delay_ms(del); // no return check necessary on final delay
+}
+#endif
+
+#ifdef USE_LIGHTNING_MODE
+inline void lightning_storm_iter() {
+ // one iteration of main loop()
+ int16_t brightness;
+ uint16_t rand_time;
+
+ // turn the emitter on at a random level,
+ // for a random amount of time between 1ms and 32ms
+ //rand_time = 1 << (pseudo_rand() % 7);
+ rand_time = pseudo_rand() & 63;
+ brightness = 1 << (pseudo_rand() % 7); // 1, 2, 4, 8, 16, 32, 64
+ brightness += 1 << (pseudo_rand() & 0x03); // 2 to 80 now
+ brightness += pseudo_rand() % brightness; // 2 to 159 now (w/ low bias)
+ if (brightness > MAX_LEVEL) brightness = MAX_LEVEL;
+ set_level(brightness);
+ nice_delay_ms(rand_time);
+
+ // decrease the brightness somewhat more gradually, like lightning
+ uint8_t stepdown = brightness >> 3;
+ if (stepdown < 1) stepdown = 1;
+ while(brightness > 1) {
+ nice_delay_ms(rand_time);
+ brightness -= stepdown;
+ if (brightness < 0) brightness = 0;
+ set_level(brightness);
+ /*
+ if ((brightness < MAX_LEVEL/2) && (! (pseudo_rand() & 15))) {
+ brightness <<= 1;
+ set_level(brightness);
+ }
+ */
+ if (! (pseudo_rand() & 3)) {
+ nice_delay_ms(rand_time);
+ set_level(brightness>>1);
+ }
+ }
+
+ // turn the emitter off,
+ // for a random amount of time between 1ms and 8192ms
+ // (with a low bias)
+ rand_time = 1 << (pseudo_rand() % 13);
+ rand_time += pseudo_rand() % rand_time;
+ set_level(0);
+ nice_delay_ms(rand_time); // no return check necessary on final delay
+}
+#endif
+
+#ifdef USE_BIKE_FLASHER_MODE
+inline void bike_flasher_iter() {
+ // one iteration of main loop()
+ uint8_t burst = bike_flasher_brightness << 1;
+ if (burst > MAX_LEVEL) burst = MAX_LEVEL;
+ for(uint8_t i=0; i<4; i++) {
+ set_level(burst);
+ nice_delay_ms(5);
+ set_level(bike_flasher_brightness);
+ nice_delay_ms(65);
+ }
+ nice_delay_ms(720); // no return check necessary on final delay
+}
+#endif
+
+#endif // ifdef USE_STROBE_STATE
+
+#ifdef USE_CANDLE_MODE
+uint8_t candle_mode_state(Event event, uint16_t arg) {
+ // FIXME: make candle variance magnitude a compile-time option,
+ // since 20 is sometimes too much or too little,
+ // depending on the driver type and ramp shape
+ //#define MAX_CANDLE_LEVEL (RAMP_SIZE-8-6-4)
+ #define MAX_CANDLE_LEVEL (RAMP_SIZE/2)
+ static uint8_t candle_wave1 = 0;
+ static uint8_t candle_wave2 = 0;
+ static uint8_t candle_wave3 = 0;
+ static uint8_t candle_wave2_speed = 0;
+ static uint8_t candle_wave2_depth = 7;
+ static uint8_t candle_wave3_depth = 4;
+ static uint8_t candle_mode_brightness = 24;
+ static uint8_t candle_mode_timer = 0;
+ #define TICKS_PER_CANDLE_MINUTE 4096 // about 65 seconds
+ #define MINUTES_PER_CANDLE_HALFHOUR 27 // ish
+
+ if (event == EV_enter_state) {
+ candle_mode_timer = 0; // in case any time was left over from earlier
+ return MISCHIEF_MANAGED;
+ }
+ // 2 clicks: cancel timer
+ else if (event == EV_2clicks) {
+ // parent state just rotated through strobe/flasher modes,
+ // so cancel timer... in case any time was left over from earlier
+ candle_mode_timer = 0;
+ return MISCHIEF_MANAGED;
+ }
+ // hold: change brightness (brighter)
+ else if (event == EV_click1_hold) {
+ if (candle_mode_brightness < MAX_CANDLE_LEVEL)
+ candle_mode_brightness ++;
+ return MISCHIEF_MANAGED;
+ }
+ // click, hold: change brightness (dimmer)
+ else if (event == EV_click2_hold) {
+ if (candle_mode_brightness > 1)
+ candle_mode_brightness --;
+ return MISCHIEF_MANAGED;
+ }
// 3 clicks: add 30m to candle timer
else if (event == EV_3clicks) {
- // candle mode only
- if (st == candle_mode_e) {
- if (candle_mode_timer < (255 - MINUTES_PER_CANDLE_HALFHOUR)) {
- // add 30m to the timer
- candle_mode_timer += MINUTES_PER_CANDLE_HALFHOUR;
- // blink to confirm
- set_level(actual_level + 32);
- delay_4ms(2);
- }
+ if (candle_mode_timer < (255 - MINUTES_PER_CANDLE_HALFHOUR)) {
+ // add 30m to the timer
+ candle_mode_timer += MINUTES_PER_CANDLE_HALFHOUR;
+ // blink to confirm
+ set_level(actual_level + 32);
+ delay_4ms(2);
}
return MISCHIEF_MANAGED;
}
- #endif
- #if defined(USE_LIGHTNING_MODE) || defined(USE_CANDLE_MODE)
- // clock tick: bump the random seed, adjust candle brightness
+ // clock tick: animate candle brightness
else if (event == EV_tick) {
- pseudo_rand_seed += arg;
-
- #ifdef USE_CANDLE_MODE
- if (st == candle_mode_e) {
- // self-timer dims the light during the final minute
- uint8_t subtract = 0;
- if (candle_mode_timer == 1) {
- subtract = ((candle_mode_brightness+20)
- * ((arg & (TICKS_PER_CANDLE_MINUTE-1)) >> 4))
- >> 8;
- }
- // we passed a minute mark, decrease timer if it's running
- if ((arg & (TICKS_PER_CANDLE_MINUTE-1)) == (TICKS_PER_CANDLE_MINUTE - 1)) {
- if (candle_mode_timer > 0) {
- candle_mode_timer --;
- //set_level(0); delay_4ms(2);
- // if the timer ran out, shut off
- if (! candle_mode_timer) {
- set_state(off_state, 0);
- }
+ // self-timer dims the light during the final minute
+ uint8_t subtract = 0;
+ if (candle_mode_timer == 1) {
+ subtract = ((candle_mode_brightness+20)
+ * ((arg & (TICKS_PER_CANDLE_MINUTE-1)) >> 4))
+ >> 8;
+ }
+ // we passed a minute mark, decrease timer if it's running
+ if ((arg & (TICKS_PER_CANDLE_MINUTE-1)) == (TICKS_PER_CANDLE_MINUTE - 1)) {
+ if (candle_mode_timer > 0) {
+ candle_mode_timer --;
+ //set_level(0); delay_4ms(2);
+ // if the timer ran out, shut off
+ if (! candle_mode_timer) {
+ set_state(off_state, 0);
}
}
- // 3-oscillator synth for a relatively organic pattern
- uint8_t add;
- add = ((triangle_wave(candle_wave1) * 8) >> 8)
- + ((triangle_wave(candle_wave2) * candle_wave2_depth) >> 8)
- + ((triangle_wave(candle_wave3) * candle_wave3_depth) >> 8);
- int8_t brightness = candle_mode_brightness + add - subtract;
- if (brightness < 0) { brightness = 0; }
- set_level(brightness);
-
- // wave1: slow random LFO
- if ((arg & 1) == 0) candle_wave1 += pseudo_rand() & 1;
- // wave2: medium-speed erratic LFO
- candle_wave2 += candle_wave2_speed;
- // wave3: erratic fast wave
- candle_wave3 += pseudo_rand() % 37;
- // S&H on wave2 frequency to make it more erratic
- if ((pseudo_rand() & 0b00111111) == 0)
- candle_wave2_speed = pseudo_rand() % 13;
- // downward sawtooth on wave2 depth to simulate stabilizing
- if ((candle_wave2_depth > 0) && ((pseudo_rand() & 0b00111111) == 0))
- candle_wave2_depth --;
- // random sawtooth retrigger
- if ((pseudo_rand()) == 0) {
- candle_wave2_depth = 7;
- //candle_wave3_depth = 5;
- candle_wave2 = 0;
- }
- // downward sawtooth on wave3 depth to simulate stabilizing
- if ((candle_wave3_depth > 2) && ((pseudo_rand() & 0b00011111) == 0))
- candle_wave3_depth --;
- if ((pseudo_rand() & 0b01111111) == 0)
- candle_wave3_depth = 5;
}
- #endif
+ // 3-oscillator synth for a relatively organic pattern
+ uint8_t add;
+ add = ((triangle_wave(candle_wave1) * 8) >> 8)
+ + ((triangle_wave(candle_wave2) * candle_wave2_depth) >> 8)
+ + ((triangle_wave(candle_wave3) * candle_wave3_depth) >> 8);
+ int8_t brightness = candle_mode_brightness + add - subtract;
+ if (brightness < 0) { brightness = 0; }
+ set_level(brightness);
+
+ // wave1: slow random LFO
+ if ((arg & 1) == 0) candle_wave1 += pseudo_rand() & 1;
+ // wave2: medium-speed erratic LFO
+ candle_wave2 += candle_wave2_speed;
+ // wave3: erratic fast wave
+ candle_wave3 += pseudo_rand() % 37;
+ // S&H on wave2 frequency to make it more erratic
+ if ((pseudo_rand() & 0b00111111) == 0)
+ candle_wave2_speed = pseudo_rand() % 13;
+ // downward sawtooth on wave2 depth to simulate stabilizing
+ if ((candle_wave2_depth > 0) && ((pseudo_rand() & 0b00111111) == 0))
+ candle_wave2_depth --;
+ // random sawtooth retrigger
+ if ((pseudo_rand()) == 0) {
+ candle_wave2_depth = 7;
+ //candle_wave3_depth = 5;
+ candle_wave2 = 0;
+ }
+ // downward sawtooth on wave3 depth to simulate stabilizing
+ if ((candle_wave3_depth > 2) && ((pseudo_rand() & 0b00011111) == 0))
+ candle_wave3_depth --;
+ if ((pseudo_rand() & 0b01111111) == 0)
+ candle_wave3_depth = 5;
return MISCHIEF_MANAGED;
}
- #endif
return EVENT_NOT_HANDLED;
}
-#endif // ifdef USE_STROBE_STATE
+
+uint8_t triangle_wave(uint8_t phase) {
+ uint8_t result = phase << 1;
+ if (phase > 127) result = 255 - result;
+ return result;
+}
+#endif // #ifdef USE_CANDLE_MODE
#ifdef USE_BORING_STROBE_STATE
@@ -1102,6 +1205,22 @@ uint8_t boring_strobe_state(Event event, uint16_t arg) {
return EVENT_NOT_HANDLED;
}
+#ifdef USE_POLICE_STROBE_MODE
+inline void police_strobe_iter() {
+ // one iteration of main loop()
+ // 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);
+ }
+ }
+}
+#endif
+
+#ifdef USE_SOS_MODE
void sos_blink(uint8_t num, uint8_t dah) {
#define DIT_LENGTH 200
for (; num > 0; num--) {
@@ -1117,7 +1236,17 @@ void sos_blink(uint8_t num, uint8_t dah) {
// three "off" dits (or one "dah") between letters
nice_delay_ms(DIT_LENGTH*2);
}
-#endif // ifdef USE_BORING_STROBE_STATE
+
+inline void sos_mode_iter() {
+ // one iteration of main loop()
+ nice_delay_ms(1000);
+ sos_blink(3, 0); // S
+ sos_blink(3, 1); // O
+ sos_blink(3, 0); // S
+ nice_delay_ms(1000);
+}
+#endif // #ifdef USE_SOS_MODE
+#endif // #ifdef USE_BORING_STROBE_STATE
#ifdef USE_BATTCHECK
@@ -1651,6 +1780,14 @@ uint8_t beacon_config_state(Event event, uint16_t arg) {
return config_state_base(event, arg,
1, beacon_config_save);
}
+
+inline void beacon_mode_iter() {
+ // one iteration of main loop()
+ set_level(memorized_level);
+ nice_delay_ms(500);
+ set_level(0);
+ nice_delay_ms(((beacon_seconds) * 1000) - 500);
+}
#endif // #ifdef USE_BEACON_MODE
@@ -1806,15 +1943,6 @@ void indicator_blink(uint8_t arg) {
#endif
-#ifdef USE_CANDLE_MODE
-uint8_t triangle_wave(uint8_t phase) {
- uint8_t result = phase << 1;
- if (phase > 127) result = 255 - result;
- return result;
-}
-#endif
-
-
void load_config() {
if (load_eeprom()) {
ramp_style = eeprom[ramp_style_e];
@@ -1895,6 +2023,7 @@ void save_config_wl() {
}
#endif
+
void low_voltage() {
StatePtr state = current_state;
@@ -1979,127 +2108,51 @@ void loop() {
if (0) {}
#ifdef USE_STROBE_STATE
- if (state == strobe_state) {
+ else if (state == strobe_state) {
uint8_t st = strobe_type;
- if (0) {} // placeholder
-
- // party / tactial strobe
- #if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE)
- #ifdef USE_TACTICAL_STROBE_MODE
- else if (st <= tactical_strobe_e) {
- #else
- else if (st == party_strobe_e) {
- #endif
- uint8_t del = strobe_delays[st];
- // TODO: make tac strobe brightness configurable?
- set_level(STROBE_BRIGHTNESS);
- if (st == party_strobe_e) { // party strobe
- if (del < 42) delay_zero();
- else nice_delay_ms(1);
- } else { //tactical strobe
- nice_delay_ms(del >> 1);
- }
- set_level(0);
- nice_delay_ms(del); // no return check necessary on final delay
- }
- #endif
-
- // lightning storm
- #ifdef USE_LIGHTNING_MODE
- else if (st == lightning_storm_e) {
- int16_t brightness;
- uint16_t rand_time;
-
- // turn the emitter on at a random level,
- // for a random amount of time between 1ms and 32ms
- //rand_time = 1 << (pseudo_rand() % 7);
- rand_time = pseudo_rand() & 63;
- brightness = 1 << (pseudo_rand() % 7); // 1, 2, 4, 8, 16, 32, 64
- brightness += 1 << (pseudo_rand() & 0x03); // 2 to 80 now
- brightness += pseudo_rand() % brightness; // 2 to 159 now (w/ low bias)
- if (brightness > MAX_LEVEL) brightness = MAX_LEVEL;
- set_level(brightness);
- nice_delay_ms(rand_time);
-
- // decrease the brightness somewhat more gradually, like lightning
- uint8_t stepdown = brightness >> 3;
- if (stepdown < 1) stepdown = 1;
- while(brightness > 1) {
- nice_delay_ms(rand_time);
- brightness -= stepdown;
- if (brightness < 0) brightness = 0;
- set_level(brightness);
- /*
- if ((brightness < MAX_LEVEL/2) && (! (pseudo_rand() & 15))) {
- brightness <<= 1;
- set_level(brightness);
- }
- */
- if (! (pseudo_rand() & 3)) {
- nice_delay_ms(rand_time);
- set_level(brightness>>1);
- }
- }
-
- // turn the emitter off,
- // for a random amount of time between 1ms and 8192ms
- // (with a low bias)
- rand_time = 1 << (pseudo_rand() % 13);
- rand_time += pseudo_rand() % rand_time;
- set_level(0);
- nice_delay_ms(rand_time); // no return check necessary on final delay
- }
- #endif
+ switch(st) {
+ #if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE)
+ #ifdef USE_PARTY_STROBE_MODE
+ case party_strobe_e:
+ #endif
+ #ifdef USE_TACTICAL_STROBE_MODE
+ case tactical_strobe_e:
+ #endif
+ party_tactical_strobe_mode_iter(st);
+ break;
+ #endif
- // candle mode
- #ifdef USE_CANDLE_MODE
- // this NOP should get compiled out
- else if (st == candle_mode_e) {}
- #endif
+ #ifdef USE_LIGHTNING_MODE
+ case lightning_storm_e:
+ lightning_storm_iter();
+ break;
+ #endif
- // bike flasher
- #ifdef USE_BIKE_FLASHER_MODE
- else if (st == bike_flasher_e) {
- uint8_t burst = bike_flasher_brightness << 1;
- if (burst > MAX_LEVEL) burst = MAX_LEVEL;
- for(uint8_t i=0; i<4; i++) {
- set_level(burst);
- nice_delay_ms(5);
- set_level(bike_flasher_brightness);
- nice_delay_ms(65);
- }
- nice_delay_ms(720); // no return check necessary on final delay
+ #ifdef USE_BIKE_FLASHER_MODE
+ case bike_flasher_e:
+ bike_flasher_iter();
+ break;
+ #endif
}
- #endif
}
#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);
- }
- }
- }
+ else if (state == boring_strobe_state) {
+ switch(boring_strobe_type) {
+ #ifdef USE_POLICE_STROBE_MODE
+ case 0: // police strobe
+ police_strobe_iter();
+ break;
+ #endif
- // 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);
+ #ifdef USE_SOS_MODE
+ default: // SOS
+ sos_mode_iter();
+ break;
+ #endif
}
}
#endif // #ifdef USE_BORING_STROBE_STATE
@@ -2109,23 +2162,21 @@ void loop() {
battcheck();
}
#endif
+
+ #ifdef USE_BEACON_MODE
+ else if (state == beacon_state) {
+ beacon_mode_iter();
+ }
+ #endif
+
#ifdef USE_THERMAL_REGULATION
- // TODO: blink out therm_ceil during thermal_config_state
+ // TODO: blink out therm_ceil during thermal_config_state?
else if (state == tempcheck_state) {
blink_num(temperature>>1);
nice_delay_ms(1000);
}
#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 {
// doze until next clock tick
--
cgit v1.2.3
From 8362deff89f567de28ee2dd961a2805994f75c61 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Tue, 12 Mar 2019 04:05:49 -0600
Subject: merged anduril updates into rampingios
---
spaghetti-monster/anduril/anduril.c | 2 +-
spaghetti-monster/fireflies-ui/fireflies-ui.c | 2 +-
spaghetti-monster/rampingios/rampingiosv3.c | 85 +++++++++++++++++++++++----
3 files changed, 76 insertions(+), 13 deletions(-)
(limited to 'spaghetti-monster')
diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c
index fa4508e..30a0780 100644
--- a/spaghetti-monster/anduril/anduril.c
+++ b/spaghetti-monster/anduril/anduril.c
@@ -1282,7 +1282,7 @@ uint8_t beacon_state(Event event, uint16_t arg) {
}
return EVENT_NOT_HANDLED;
}
-#endif
+#endif // #ifdef USE_BEACON_MODE
#ifdef USE_GOODNIGHT_MODE
diff --git a/spaghetti-monster/fireflies-ui/fireflies-ui.c b/spaghetti-monster/fireflies-ui/fireflies-ui.c
index 6402a9d..fa0b160 100644
--- a/spaghetti-monster/fireflies-ui/fireflies-ui.c
+++ b/spaghetti-monster/fireflies-ui/fireflies-ui.c
@@ -1321,7 +1321,7 @@ uint8_t beacon_state(Event event, uint16_t arg) {
}
return EVENT_NOT_HANDLED;
}
-#endif
+#endif // #ifdef USE_BEACON_MODE
#ifdef USE_GOODNIGHT_MODE
diff --git a/spaghetti-monster/rampingios/rampingiosv3.c b/spaghetti-monster/rampingios/rampingiosv3.c
index 399bcf0..c6886e7 100644
--- a/spaghetti-monster/rampingios/rampingiosv3.c
+++ b/spaghetti-monster/rampingios/rampingiosv3.c
@@ -1,7 +1,7 @@
/*
* RampingIOS V3: FSM-based version of RampingIOS V2 UI, with upgrades.
*
- * Copyright (C) 2018 Selene ToyKeeper
+ * Copyright (C) 2018-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
@@ -26,6 +26,7 @@
// parameters for this defined below or per-driver
#define USE_THERMAL_REGULATION
#define DEFAULT_THERM_CEIL 45 // try not to get hotter than this
+#define USE_TENCLICK_THERMAL_CONFIG // ten clicks from off -> thermal config mode
// short blip when crossing from "click" to "hold" from off
// (helps the user hit moon mode exactly, instead of holding too long
@@ -46,6 +47,12 @@
//#define BATTCHECK_8bars // FIXME: breaks build
//#define BATTCHECK_4bars // FIXME: breaks build
+// enable beacon mode
+#define USE_BEACON_MODE
+
+// make the ramps configurable by the user
+#define USE_RAMP_CONFIG
+
/***** specific settings for known driver types *****/
#include "tk.h"
#include incfile(CONFIGFILE)
@@ -109,7 +116,9 @@ 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
#ifdef USE_BATTCHECK
uint8_t battcheck_state(Event event, uint16_t arg);
#endif
@@ -117,11 +126,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_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
+//#define LOCKOUT_MOON_FANCY
uint8_t lockout_state(Event event, uint16_t arg);
// momentary / signalling mode
uint8_t momentary_state(Event event, uint16_t arg);
@@ -201,8 +214,10 @@ uint8_t nearest_level(int16_t target);
uint8_t target_level = 0;
#endif
+#ifdef USE_BEACON_MODE
// beacon timing
volatile uint8_t beacon_seconds = 2;
+#endif
uint8_t off_state(Event event, uint16_t arg) {
@@ -321,11 +336,13 @@ uint8_t off_state(Event event, uint16_t arg) {
set_state(beacon_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;
}
@@ -401,11 +418,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
@@ -669,6 +688,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) {
@@ -684,6 +704,7 @@ uint8_t beacon_state(Event event, uint16_t arg) {
}
return EVENT_NOT_HANDLED;
}
+#endif // #ifdef USE_BEACON_MODE
uint8_t lockout_state(Event event, uint16_t arg) {
@@ -696,6 +717,13 @@ uint8_t lockout_state(Event event, uint16_t arg) {
uint8_t lvl = ramp_smooth_floor;
if (ramp_discrete_floor < lvl) lvl = ramp_discrete_floor;
set_level(lvl);
+ #elif defined(LOCKOUT_MOON_FANCY)
+ uint8_t levels[] = { ramp_smooth_floor, ramp_discrete_floor };
+ if ((event & 0x0f) == 2) {
+ set_level(levels[ramp_style^1]);
+ } else {
+ set_level(levels[ramp_style]);
+ }
#else
// Use moon from current ramp
set_level(nearest_level(1));
@@ -858,6 +886,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;
@@ -889,6 +918,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
@@ -915,9 +945,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];
@@ -931,6 +962,15 @@ uint8_t beacon_config_state(Event event, uint16_t arg) {
1, beacon_config_save);
}
+inline void beacon_mode_iter() {
+ // one iteration of main loop()
+ set_level(memorized_level);
+ nice_delay_ms(500);
+ set_level(0);
+ nice_delay_ms(((beacon_seconds) * 1000) - 500);
+}
+#endif // #ifdef USE_BEACON_MODE
+
uint8_t number_entry_state(Event event, uint16_t arg) {
static uint8_t value;
@@ -1063,12 +1103,23 @@ void blink_confirm(uint8_t num) {
#if defined(USE_INDICATOR_LED) && defined(TICK_DURING_STANDBY)
// beacon-like mode for the indicator LED
void indicator_blink(uint8_t arg) {
+ #ifdef USE_FANCIER_BLINKING_INDICATOR
+
+ // fancy blink, set off/low/high levels here:
+ uint8_t seq[] = {0, 1, 2, 1, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0};
+ indicator_led(seq[arg & 15]);
+
+ #else // basic blink, 1/8th duty cycle
+
if (! (arg & 7)) {
indicator_led(2);
}
else {
indicator_led(0);
}
+
+ #endif
}
#endif
@@ -1076,12 +1127,16 @@ void indicator_blink(uint8_t arg) {
void load_config() {
if (load_eeprom()) {
ramp_style = eeprom[0];
+ #ifdef USE_RAMP_CONFIG
ramp_smooth_floor = eeprom[1];
ramp_smooth_ceil = eeprom[2];
ramp_discrete_floor = eeprom[3];
ramp_discrete_ceil = eeprom[4];
ramp_discrete_steps = eeprom[5];
+ #endif
+ #ifdef USE_BEACON_MODE
beacon_seconds = eeprom[6];
+ #endif
#ifdef USE_THERMAL_REGULATION
therm_ceil = eeprom[EEPROM_BYTES_BASE];
therm_cal_offset = eeprom[EEPROM_BYTES_BASE+1];
@@ -1094,12 +1149,16 @@ void load_config() {
void save_config() {
eeprom[0] = ramp_style;
+ #ifdef USE_RAMP_CONFIG
eeprom[1] = ramp_smooth_floor;
eeprom[2] = ramp_smooth_ceil;
eeprom[3] = ramp_discrete_floor;
eeprom[4] = ramp_discrete_ceil;
eeprom[5] = ramp_discrete_steps;
+ #endif
+ #ifdef USE_BEACON_MODE
eeprom[6] = beacon_seconds;
+ #endif
#ifdef USE_THERMAL_REGULATION
eeprom[EEPROM_BYTES_BASE ] = therm_ceil;
eeprom[EEPROM_BYTES_BASE+1] = therm_cal_offset;
@@ -1114,8 +1173,12 @@ void save_config() {
void low_voltage() {
StatePtr state = current_state;
+ // TODO: turn off aux LED(s) when power is really low
+
+ if (0) {} // placeholder
+
// in normal mode, step down or turn off
- if (state == steady_state) {
+ else if (state == steady_state) {
if (actual_level > 1) {
uint8_t lvl = (actual_level >> 1) + (actual_level >> 2);
set_level(lvl);
@@ -1161,21 +1224,21 @@ void loop() {
battcheck();
}
#endif
+
+ #ifdef USE_BEACON_MODE
+ else if (state == beacon_state) {
+ beacon_mode_iter();
+ }
+ #endif
+
#ifdef USE_THERMAL_REGULATION
- // TODO: blink out therm_ceil during thermal_config_state
+ // TODO: blink out therm_ceil during thermal_config_state?
else if (state == tempcheck_state) {
blink_num(temperature>>1);
nice_delay_ms(1000);
}
#endif
- else if (state == beacon_state) {
- set_level(memorized_level);
- nice_delay_ms(500);
- set_level(0);
- nice_delay_ms(((beacon_seconds) * 1000) - 500);
- }
-
#ifdef USE_IDLE_MODE
else {
// doze until next clock tick
--
cgit v1.2.3
From ef752306f1766973f234be31c8d41cb586908f23 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Tue, 12 Mar 2019 04:38:40 -0600
Subject: don't use eeprom for ramp config if ramp config isn't enabled
---
spaghetti-monster/anduril/anduril.c | 2 ++
spaghetti-monster/fireflies-ui/fireflies-ui.c | 2 ++
2 files changed, 4 insertions(+)
(limited to 'spaghetti-monster')
diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c
index 30a0780..f92b8f9 100644
--- a/spaghetti-monster/anduril/anduril.c
+++ b/spaghetti-monster/anduril/anduril.c
@@ -138,11 +138,13 @@
#define USE_EEPROM
typedef enum {
ramp_style_e,
+ #ifdef USE_RAMP_CONFIG
ramp_smooth_floor_e,
ramp_smooth_ceil_e,
ramp_discrete_floor_e,
ramp_discrete_ceil_e,
ramp_discrete_steps_e,
+ #endif
#ifdef USE_STROBE_STATE
strobe_type_e,
#endif
diff --git a/spaghetti-monster/fireflies-ui/fireflies-ui.c b/spaghetti-monster/fireflies-ui/fireflies-ui.c
index fa0b160..0fc2a1d 100644
--- a/spaghetti-monster/fireflies-ui/fireflies-ui.c
+++ b/spaghetti-monster/fireflies-ui/fireflies-ui.c
@@ -182,11 +182,13 @@
#define USE_EEPROM
typedef enum {
ramp_style_e,
+ #ifdef USE_RAMP_CONFIG
ramp_smooth_floor_e,
ramp_smooth_ceil_e,
ramp_discrete_floor_e,
ramp_discrete_ceil_e,
ramp_discrete_steps_e,
+ #endif
#ifdef USE_STROBE_STATE
strobe_type_e,
#endif
--
cgit v1.2.3
From 4e15dced6d2274dcb0c6b952eb4d22bf51af422e Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Tue, 12 Mar 2019 04:39:42 -0600
Subject: configured Fireflies-EDC-Thrower discrete ramp better, updated meta
info
---
spaghetti-monster/fireflies-ui/cfg-ff-edc-thrower.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'spaghetti-monster')
diff --git a/spaghetti-monster/fireflies-ui/cfg-ff-edc-thrower.h b/spaghetti-monster/fireflies-ui/cfg-ff-edc-thrower.h
index 752afe2..31be0ef 100644
--- a/spaghetti-monster/fireflies-ui/cfg-ff-edc-thrower.h
+++ b/spaghetti-monster/fireflies-ui/cfg-ff-edc-thrower.h
@@ -8,9 +8,9 @@
#undef RAMP_SMOOTH_CEIL
#define RAMP_SMOOTH_CEIL 130
-// 10, 28, 46, 65, 83, 101, 120 (83 is highest regulated)
+// 36, 83, 130 (83 is highest regulated)
#undef RAMP_DISCRETE_FLOOR
-#define RAMP_DISCRETE_FLOOR 20
+#define RAMP_DISCRETE_FLOOR 36
#undef RAMP_DISCRETE_CEIL
#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
#undef RAMP_DISCRETE_STEPS
--
cgit v1.2.3
From ce07a791ecb5dd9c2bd6ac773c4b6b2e993ad681 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Mon, 18 Mar 2019 02:53:27 -0600
Subject: Made default level configurable per build target, made moon hint blip
a bit more noticeable.
---
spaghetti-monster/anduril/anduril.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
(limited to 'spaghetti-monster')
diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c
index 09c7927..7f19a5a 100644
--- a/spaghetti-monster/anduril/anduril.c
+++ b/spaghetti-monster/anduril/anduril.c
@@ -242,7 +242,10 @@ void save_config_wl();
#endif
// brightness control
-uint8_t memorized_level = MAX_1x7135;
+#ifndef DEFAULT_LEVEL
+#define DEFAULT_LEVEL MAX_1x7135
+#endif
+uint8_t memorized_level = DEFAULT_LEVEL;
// smooth vs discrete ramping
volatile uint8_t ramp_style = 0; // 0 = smooth, 1 = discrete
volatile uint8_t ramp_smooth_floor = RAMP_SMOOTH_FLOOR;
@@ -369,7 +372,7 @@ uint8_t off_state(Event event, uint16_t arg) {
// let the user know they can let go now to stay at moon
uint8_t temp = actual_level;
set_level(0);
- delay_4ms(2);
+ delay_4ms(3);
set_level(temp);
} else
#endif
--
cgit v1.2.3
From 7599d9827a94f199c170298b97b482faaf19520e Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Mon, 18 Mar 2019 03:00:56 -0600
Subject: added Emisar D18 config (not final)
---
spaghetti-monster/anduril/cfg-emisar-d18.h | 38 ++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
create mode 100644 spaghetti-monster/anduril/cfg-emisar-d18.h
(limited to 'spaghetti-monster')
diff --git a/spaghetti-monster/anduril/cfg-emisar-d18.h b/spaghetti-monster/anduril/cfg-emisar-d18.h
new file mode 100644
index 0000000..5171dba
--- /dev/null
+++ b/spaghetti-monster/anduril/cfg-emisar-d18.h
@@ -0,0 +1,38 @@
+// Emisar FET+13+1 config options for Anduril
+#include "hwdef-Emisar_D18.h"
+
+// front-facing aux LEDs
+#define USE_INDICATOR_LED
+//#define USE_INDICATOR_LED_WHILE_RAMPING
+// enable blinking indicator LED while off
+#define TICK_DURING_STANDBY
+#define STANDBY_TICK_SPEED 3 // every 0.128 s
+#define USE_FANCIER_BLINKING_INDICATOR
+// off mode: low (1)
+// lockout: blinking (3)
+#define INDICATOR_LED_DEFAULT_MODE ((3<<2) + 1)
+
+// Emisar wanted a shortcut to this
+#define USE_TENCLICK_THERMAL_CONFIG
+
+
+// FW3A 1x7135 ramp:
+// ../../bin/level_calc.py cube 1 65 7135 1 0.8 150
+// ... mixed with this:
+// ../../../bin/level_calc.py ninth 3 150 7135 1 2.5 150 7135 1 1 1600 FET 1 10 5265
+#define RAMP_LENGTH 150
+#define 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
+#define 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,2,3,5,6,8,9,11,13,14,16,18,20,22,25,27,29,32,34,37,40,43,46,49,53,56,60,63,67,71,76,80,85,89,94,100,105,110,116,122,128,135,142,148,156,163,171,179,187,196,205,214,224,234,244,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
+#define PWM3_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,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,5,10,16,21,27,33,39,46,52,59,66,74,81,89,97,105,114,123,132,142,151,162,172,183,194,205,217,229,242,255
+#define MAX_1x7135 65
+#define MAX_Nx7135 120
+#define HALFSPEED_LEVEL 14
+#define QUARTERSPEED_LEVEL 5
+
+// start at ~1500 lm, not ~150 lm
+#define DEFAULT_LEVEL MAX_Nx7135
+
+// stop panicking at about 4.9A or ~1750 lm
+#define THERM_FASTER_LEVEL MAX_Nx7135
+// optional, makes initial turbo step-down faster so first peak isn't as hot
+#define THERM_HARD_TURBO_DROP
--
cgit v1.2.3
From de0c7eadd70220d29ab6a332d0c47b80c91985c8 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Mon, 18 Mar 2019 04:06:37 -0600
Subject: made mid-ramp blinks more configurable per build target (allows for 1
or 2 mid-ramp blinks, at arbitrary levels, but it defaults to the old
behavior at power channel boundaries) also merged anduril updates into
rampingios
---
spaghetti-monster/anduril/anduril.c | 39 +++++++++++++++++-------
spaghetti-monster/anduril/cfg-blf-gt.h | 2 +-
spaghetti-monster/anduril/cfg-ff-pl47.h | 2 +-
spaghetti-monster/anduril/cfg-ff-rot66.h | 2 +-
spaghetti-monster/anduril/cfg-sofirn-sp36.h | 4 +--
spaghetti-monster/rampingios/rampingiosv3.c | 46 +++++++++++++++++++++--------
6 files changed, 66 insertions(+), 29 deletions(-)
(limited to 'spaghetti-monster')
diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c
index a9ae959..93f8c16 100644
--- a/spaghetti-monster/anduril/anduril.c
+++ b/spaghetti-monster/anduril/anduril.c
@@ -33,7 +33,7 @@
// or too short)
#define MOON_TIMING_HINT
// short blips while ramping
-#define BLINK_AT_CHANNEL_BOUNDARIES
+#define BLINK_AT_RAMP_MIDDLE
//#define BLINK_AT_RAMP_FLOOR
#define BLINK_AT_RAMP_CEILING
//#define BLINK_AT_STEPS // whenever a discrete ramp mode is passed in smooth mode
@@ -275,6 +275,23 @@ void save_config_wl();
#define RAMP_DISCRETE_STEPS 7
#endif
+// mile marker(s) partway up the ramp
+// default: blink only at border between regulated and FET
+#ifdef BLINK_AT_RAMP_MIDDLE
+ #if PWM_CHANNELS >= 3
+ #ifndef BLINK_AT_RAMP_MIDDLE_1
+ #define BLINK_AT_RAMP_MIDDLE_1 MAX_Nx7135
+ #ifndef BLINK_AT_RAMP_MIDDLE_2
+ #define BLINK_AT_RAMP_MIDDLE_2 MAX_1x7135
+ #endif
+ #endif
+ #else
+ #ifndef BLINK_AT_RAMP_MIDDLE_1
+ #define BLINK_AT_RAMP_MIDDLE_1 MAX_1x7135
+ #endif
+ #endif
+#endif
+
// brightness control
#ifndef DEFAULT_LEVEL
#define DEFAULT_LEVEL MAX_1x7135
@@ -619,15 +636,15 @@ uint8_t steady_state(Event event, uint16_t arg) {
#ifdef USE_THERMAL_REGULATION
target_level = memorized_level;
#endif
- #if defined(BLINK_AT_RAMP_CEILING) || defined(BLINK_AT_CHANNEL_BOUNDARIES)
+ #if defined(BLINK_AT_RAMP_CEILING) || defined(BLINK_AT_RAMP_MIDDLE)
// only blink once for each threshold
if ((memorized_level != actual_level) && (
0 // for easier syntax below
- #ifdef BLINK_AT_CHANNEL_BOUNDARIES
- || (memorized_level == MAX_1x7135)
- #if PWM_CHANNELS >= 3
- || (memorized_level == MAX_Nx7135)
+ #ifdef BLINK_AT_RAMP_MIDDLE_1
+ || (memorized_level == BLINK_AT_RAMP_MIDDLE_1)
#endif
+ #ifdef BLINK_AT_RAMP_MIDDLE_2
+ || (memorized_level == BLINK_AT_RAMP_MIDDLE_2)
#endif
#ifdef BLINK_AT_RAMP_CEILING
|| (memorized_level == mode_max)
@@ -684,15 +701,15 @@ uint8_t steady_state(Event event, uint16_t arg) {
#ifdef USE_THERMAL_REGULATION
target_level = memorized_level;
#endif
- #if defined(BLINK_AT_RAMP_FLOOR) || defined(BLINK_AT_CHANNEL_BOUNDARIES)
+ #if defined(BLINK_AT_RAMP_FLOOR) || defined(BLINK_AT_RAMP_MIDDLE)
// only blink once for each threshold
if ((memorized_level != actual_level) && (
0 // for easier syntax below
- #ifdef BLINK_AT_CHANNEL_BOUNDARIES
- || (memorized_level == MAX_1x7135)
- #if PWM_CHANNELS >= 3
- || (memorized_level == MAX_Nx7135)
+ #ifdef BLINK_AT_RAMP_MIDDLE_1
+ || (memorized_level == BLINK_AT_RAMP_MIDDLE_1)
#endif
+ #ifdef BLINK_AT_RAMP_MIDDLE_2
+ || (memorized_level == BLINK_AT_RAMP_MIDDLE_2)
#endif
#ifdef BLINK_AT_RAMP_FLOOR
|| (memorized_level == mode_min)
diff --git a/spaghetti-monster/anduril/cfg-blf-gt.h b/spaghetti-monster/anduril/cfg-blf-gt.h
index b8f4d6d..6a74bbc 100644
--- a/spaghetti-monster/anduril/cfg-blf-gt.h
+++ b/spaghetti-monster/anduril/cfg-blf-gt.h
@@ -9,8 +9,8 @@
#define TICK_DURING_STANDBY
// don't blink during ramp, it's irrelevant and annoying on this light
-#undef BLINK_AT_CHANNEL_BOUNDARIES
#undef BLINK_AT_RAMP_CEILING
+#undef BLINK_AT_RAMP_MIDDLE
#undef BLINK_AT_RAMP_FLOOR
//#undef USE_SET_LEVEL_GRADUALLY
diff --git a/spaghetti-monster/anduril/cfg-ff-pl47.h b/spaghetti-monster/anduril/cfg-ff-pl47.h
index 8e21013..f9c8974 100644
--- a/spaghetti-monster/anduril/cfg-ff-pl47.h
+++ b/spaghetti-monster/anduril/cfg-ff-pl47.h
@@ -65,6 +65,6 @@
#define THERM_HARD_TURBO_DROP
// don't do this
-#undef BLINK_AT_CHANNEL_BOUNDARIES
+#undef BLINK_AT_RAMP_MIDDLE
#undef BLINK_AT_RAMP_CEILING
diff --git a/spaghetti-monster/anduril/cfg-ff-rot66.h b/spaghetti-monster/anduril/cfg-ff-rot66.h
index 78d7f66..6073ce0 100644
--- a/spaghetti-monster/anduril/cfg-ff-rot66.h
+++ b/spaghetti-monster/anduril/cfg-ff-rot66.h
@@ -42,6 +42,6 @@
#define THERM_HARD_TURBO_DROP
// don't do this
-#undef BLINK_AT_CHANNEL_BOUNDARIES
+#undef BLINK_AT_RAMP_MIDDLE
#undef BLINK_AT_RAMP_CEILING
diff --git a/spaghetti-monster/anduril/cfg-sofirn-sp36.h b/spaghetti-monster/anduril/cfg-sofirn-sp36.h
index 1150a62..494a263 100644
--- a/spaghetti-monster/anduril/cfg-sofirn-sp36.h
+++ b/spaghetti-monster/anduril/cfg-sofirn-sp36.h
@@ -16,8 +16,8 @@
// don't blink during the ramp; the button LED brightness is sufficient
// to indicate which power channel(s) are being used
-#ifdef BLINK_AT_CHANNEL_BOUNDARIES
-#undef BLINK_AT_CHANNEL_BOUNDARIES
+#ifdef BLINK_AT_RAMP_MIDDLE
+#undef BLINK_AT_RAMP_MIDDLE
#endif
#ifdef BLINK_AT_RAMP_CEILING
#undef BLINK_AT_RAMP_CEILING
diff --git a/spaghetti-monster/rampingios/rampingiosv3.c b/spaghetti-monster/rampingios/rampingiosv3.c
index c6886e7..e4eb2fa 100644
--- a/spaghetti-monster/rampingios/rampingiosv3.c
+++ b/spaghetti-monster/rampingios/rampingiosv3.c
@@ -33,7 +33,7 @@
// or too short)
#define MOON_TIMING_HINT
// short blips while ramping
-#define BLINK_AT_CHANNEL_BOUNDARIES
+#define BLINK_AT_RAMP_MIDDLE
//#define BLINK_AT_RAMP_FLOOR
#define BLINK_AT_RAMP_CEILING
//#define BLINK_AT_STEPS // whenever a discrete ramp mode is passed in smooth mode
@@ -177,8 +177,28 @@ void save_config();
#define RAMP_DISCRETE_STEPS 7
#endif
+// mile marker(s) partway up the ramp
+// default: blink only at border between regulated and FET
+#ifdef BLINK_AT_RAMP_MIDDLE
+ #if PWM_CHANNELS >= 3
+ #ifndef BLINK_AT_RAMP_MIDDLE_1
+ #define BLINK_AT_RAMP_MIDDLE_1 MAX_Nx7135
+ #ifndef BLINK_AT_RAMP_MIDDLE_2
+ #define BLINK_AT_RAMP_MIDDLE_2 MAX_1x7135
+ #endif
+ #endif
+ #else
+ #ifndef BLINK_AT_RAMP_MIDDLE_1
+ #define BLINK_AT_RAMP_MIDDLE_1 MAX_1x7135
+ #endif
+ #endif
+#endif
+
// brightness control
-uint8_t memorized_level = MAX_1x7135;
+#ifndef DEFAULT_LEVEL
+#define DEFAULT_LEVEL MAX_1x7135
+#endif
+uint8_t memorized_level = DEFAULT_LEVEL;
// smooth vs discrete ramping
volatile uint8_t ramp_style = 0; // 0 = smooth, 1 = discrete
volatile uint8_t ramp_smooth_floor = RAMP_SMOOTH_FLOOR;
@@ -262,7 +282,7 @@ uint8_t off_state(Event event, uint16_t arg) {
// let the user know they can let go now to stay at moon
uint8_t temp = actual_level;
set_level(0);
- delay_4ms(2);
+ delay_4ms(3);
set_level(temp);
} else
#endif
@@ -444,15 +464,15 @@ uint8_t steady_state(Event event, uint16_t arg) {
#ifdef USE_THERMAL_REGULATION
target_level = memorized_level;
#endif
- #if defined(BLINK_AT_RAMP_CEILING) || defined(BLINK_AT_CHANNEL_BOUNDARIES)
+ #if defined(BLINK_AT_RAMP_CEILING) || defined(BLINK_AT_RAMP_MIDDLE)
// only blink once for each threshold
if ((memorized_level != actual_level) && (
0 // for easier syntax below
- #ifdef BLINK_AT_CHANNEL_BOUNDARIES
- || (memorized_level == MAX_1x7135)
- #if PWM_CHANNELS >= 3
- || (memorized_level == MAX_Nx7135)
+ #ifdef BLINK_AT_RAMP_MIDDLE_1
+ || (memorized_level == BLINK_AT_RAMP_MIDDLE_1)
#endif
+ #ifdef BLINK_AT_RAMP_MIDDLE_2
+ || (memorized_level == BLINK_AT_RAMP_MIDDLE_2)
#endif
#ifdef BLINK_AT_RAMP_CEILING
|| (memorized_level == mode_max)
@@ -506,15 +526,15 @@ uint8_t steady_state(Event event, uint16_t arg) {
#ifdef USE_THERMAL_REGULATION
target_level = memorized_level;
#endif
- #if defined(BLINK_AT_RAMP_FLOOR) || defined(BLINK_AT_CHANNEL_BOUNDARIES)
+ #if defined(BLINK_AT_RAMP_FLOOR) || defined(BLINK_AT_RAMP_MIDDLE)
// only blink once for each threshold
if ((memorized_level != actual_level) && (
0 // for easier syntax below
- #ifdef BLINK_AT_CHANNEL_BOUNDARIES
- || (memorized_level == MAX_1x7135)
- #if PWM_CHANNELS >= 3
- || (memorized_level == MAX_Nx7135)
+ #ifdef BLINK_AT_RAMP_MIDDLE_1
+ || (memorized_level == BLINK_AT_RAMP_MIDDLE_1)
#endif
+ #ifdef BLINK_AT_RAMP_MIDDLE_2
+ || (memorized_level == BLINK_AT_RAMP_MIDDLE_2)
#endif
#ifdef BLINK_AT_RAMP_FLOOR
|| (memorized_level == mode_min)
--
cgit v1.2.3
From 6e645f9f442493e55b00ce801a8d8e1219833198 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Mon, 18 Mar 2019 04:07:47 -0600
Subject: adjusted Emisar D18 ramp shape and other config options
---
spaghetti-monster/anduril/cfg-emisar-d18.h | 34 ++++++++++++++++++------------
1 file changed, 21 insertions(+), 13 deletions(-)
(limited to 'spaghetti-monster')
diff --git a/spaghetti-monster/anduril/cfg-emisar-d18.h b/spaghetti-monster/anduril/cfg-emisar-d18.h
index 5171dba..bba846f 100644
--- a/spaghetti-monster/anduril/cfg-emisar-d18.h
+++ b/spaghetti-monster/anduril/cfg-emisar-d18.h
@@ -16,23 +16,31 @@
#define USE_TENCLICK_THERMAL_CONFIG
-// FW3A 1x7135 ramp:
-// ../../bin/level_calc.py cube 1 65 7135 1 0.8 150
-// ... mixed with this:
-// ../../../bin/level_calc.py ninth 3 150 7135 1 2.5 150 7135 1 1 1600 FET 1 10 5265
+// level_calc.py ninth 3 150 7135 1 2.0 130.2 7135 1 1 2203.62 FET 1 10 12000
+// (designed to make 1x hit at level 55, and Nx hit at level 110)
#define RAMP_LENGTH 150
-#define 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
-#define 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,2,3,5,6,8,9,11,13,14,16,18,20,22,25,27,29,32,34,37,40,43,46,49,53,56,60,63,67,71,76,80,85,89,94,100,105,110,116,122,128,135,142,148,156,163,171,179,187,196,205,214,224,234,244,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
-#define PWM3_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,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,5,10,16,21,27,33,39,46,52,59,66,74,81,89,97,105,114,123,132,142,151,162,172,183,194,205,217,229,242,255
-#define MAX_1x7135 65
-#define MAX_Nx7135 120
-#define HALFSPEED_LEVEL 14
+#define PWM1_LEVELS 1,1,2,2,3,3,4,5,5,6,7,8,9,10,11,13,14,15,17,19,21,22,25,27,29,32,35,38,41,44,48,52,56,60,65,70,76,81,87,94,101,108,116,124,133,142,152,163,174,185,198,211,225,239,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,255,255,255,255,255,255,255,255,255,255,0
+#define 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,2,3,4,5,6,7,9,10,12,13,15,17,18,20,22,24,26,29,31,34,36,39,42,45,48,52,55,59,63,67,71,76,80,85,90,96,101,107,113,120,126,133,140,148,156,164,172,181,191,200,210,221,232,243,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
+#define PWM3_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,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,4,6,10,13,16,19,23,27,30,34,39,43,47,52,57,62,67,72,78,84,90,96,103,109,116,123,131,138,146,155,163,172,181,191,201,211,221,232,243,255
+#define MAX_1x7135 55
+#define MAX_Nx7135 110
+#define HALFSPEED_LEVEL 16
#define QUARTERSPEED_LEVEL 5
-// start at ~1500 lm, not ~150 lm
+// start at ~2000 lm after battery change, not ~150 lm (at Emisar's request)
#define DEFAULT_LEVEL MAX_Nx7135
-// stop panicking at about 4.9A or ~1750 lm
-#define THERM_FASTER_LEVEL MAX_Nx7135
+// higher floor than default, and stop at highest regulated level
+#define RAMP_DISCRETE_FLOOR 20
+#define RAMP_DISCRETE_CEIL MAX_Nx7135
+#define RAMP_DISCRETE_STEPS 7
+
+// only blink at max regulated level and ceiling
+#define BLINK_AT_RAMP_MIDDLE
+#define BLINK_AT_RAMP_MIDDLE_1 MAX_Nx7135
+#define BLINK_AT_RAMP_CEILING
+
+// stop panicking at about ~30% power or ~3600 lm
+#define THERM_FASTER_LEVEL 120
// optional, makes initial turbo step-down faster so first peak isn't as hot
#define THERM_HARD_TURBO_DROP
--
cgit v1.2.3
From f4d0a69d866556fc1f66d723cf9f19163ed2bcec Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Tue, 26 Mar 2019 11:47:38 -0600
Subject: tweaked D18 ramp (03-18a version)
---
spaghetti-monster/anduril/cfg-emisar-d18.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'spaghetti-monster')
diff --git a/spaghetti-monster/anduril/cfg-emisar-d18.h b/spaghetti-monster/anduril/cfg-emisar-d18.h
index bba846f..a9a5d4e 100644
--- a/spaghetti-monster/anduril/cfg-emisar-d18.h
+++ b/spaghetti-monster/anduril/cfg-emisar-d18.h
@@ -20,8 +20,8 @@
// (designed to make 1x hit at level 55, and Nx hit at level 110)
#define RAMP_LENGTH 150
#define PWM1_LEVELS 1,1,2,2,3,3,4,5,5,6,7,8,9,10,11,13,14,15,17,19,21,22,25,27,29,32,35,38,41,44,48,52,56,60,65,70,76,81,87,94,101,108,116,124,133,142,152,163,174,185,198,211,225,239,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,255,255,255,255,255,255,255,255,255,255,0
-#define 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,2,3,4,5,6,7,9,10,12,13,15,17,18,20,22,24,26,29,31,34,36,39,42,45,48,52,55,59,63,67,71,76,80,85,90,96,101,107,113,120,126,133,140,148,156,164,172,181,191,200,210,221,232,243,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
-#define PWM3_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,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,4,6,10,13,16,19,23,27,30,34,39,43,47,52,57,62,67,72,78,84,90,96,103,109,116,123,131,138,146,155,163,172,181,191,201,211,221,232,243,255
+#define 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,7,8,9,10,11,12,14,15,16,18,20,21,23,25,27,29,31,33,36,38,41,43,46,49,53,56,59,63,67,71,75,79,84,89,94,99,104,110,116,122,129,135,143,150,158,166,174,183,192,201,211,222,232,243,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
+#define PWM3_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,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,6,8,11,15,18,21,25,28,32,36,40,45,49,54,58,63,69,74,79,85,91,97,104,110,117,124,132,139,147,156,164,173,182,191,201,211,222,232,243,255
#define MAX_1x7135 55
#define MAX_Nx7135 110
#define HALFSPEED_LEVEL 16
--
cgit v1.2.3
From 81bfb809ed4fcec12ae96b07e826c78e14d019a0 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Tue, 26 Mar 2019 11:49:23 -0600
Subject: updated D18 config to 03-21 version
---
spaghetti-monster/anduril/cfg-emisar-d18.h | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
(limited to 'spaghetti-monster')
diff --git a/spaghetti-monster/anduril/cfg-emisar-d18.h b/spaghetti-monster/anduril/cfg-emisar-d18.h
index a9a5d4e..fcea43a 100644
--- a/spaghetti-monster/anduril/cfg-emisar-d18.h
+++ b/spaghetti-monster/anduril/cfg-emisar-d18.h
@@ -16,22 +16,22 @@
#define USE_TENCLICK_THERMAL_CONFIG
-// level_calc.py ninth 3 150 7135 1 2.0 130.2 7135 1 1 2203.62 FET 1 10 12000
-// (designed to make 1x hit at level 55, and Nx hit at level 110)
+// level_calc.py seventh 3 150 7135 1 1.4 117.99 7135 6 1 1706.86 FET 3 10 13000
+// (designed to make 1x hit at level 50, and Nx hit at level 100)
#define RAMP_LENGTH 150
-#define PWM1_LEVELS 1,1,2,2,3,3,4,5,5,6,7,8,9,10,11,13,14,15,17,19,21,22,25,27,29,32,35,38,41,44,48,52,56,60,65,70,76,81,87,94,101,108,116,124,133,142,152,163,174,185,198,211,225,239,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,255,255,255,255,255,255,255,255,255,255,0
-#define 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,7,8,9,10,11,12,14,15,16,18,20,21,23,25,27,29,31,33,36,38,41,43,46,49,53,56,59,63,67,71,75,79,84,89,94,99,104,110,116,122,129,135,143,150,158,166,174,183,192,201,211,222,232,243,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
-#define PWM3_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,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,6,8,11,15,18,21,25,28,32,36,40,45,49,54,58,63,69,74,79,85,91,97,104,110,117,124,132,139,147,156,164,173,182,191,201,211,222,232,243,255
-#define MAX_1x7135 55
-#define MAX_Nx7135 110
-#define HALFSPEED_LEVEL 16
-#define QUARTERSPEED_LEVEL 5
+#define PWM1_LEVELS 1,1,2,2,3,4,4,5,6,7,8,9,10,11,15,16,18,20,22,24,26,28,30,33,36,39,43,47,51,56,61,66,72,78,85,92,99,107,116,125,135,145,156,168,180,194,208,222,238,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0
+#define 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,7,8,10,11,13,14,16,18,19,21,23,26,28,30,33,35,38,41,44,47,51,54,58,62,66,70,75,79,84,90,95,101,106,112,119,126,133,140,147,155,164,172,181,190,200,210,221,232,243,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
+#define PWM3_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,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,5,7,9,11,13,15,18,20,23,25,28,31,34,37,40,44,47,51,54,58,62,66,70,75,79,84,89,94,99,104,110,115,121,127,134,140,147,154,161,168,176,183,191,200,208,217,226,235,245,255
+#define MAX_1x7135 50
+#define MAX_Nx7135 100
+#define HALFSPEED_LEVEL 15
+#define QUARTERSPEED_LEVEL 6
// start at ~2000 lm after battery change, not ~150 lm (at Emisar's request)
#define DEFAULT_LEVEL MAX_Nx7135
// higher floor than default, and stop at highest regulated level
-#define RAMP_DISCRETE_FLOOR 20
+#define RAMP_DISCRETE_FLOOR 25
#define RAMP_DISCRETE_CEIL MAX_Nx7135
#define RAMP_DISCRETE_STEPS 7
@@ -40,7 +40,7 @@
#define BLINK_AT_RAMP_MIDDLE_1 MAX_Nx7135
#define BLINK_AT_RAMP_CEILING
-// stop panicking at about ~30% power or ~3600 lm
-#define THERM_FASTER_LEVEL 120
+// stop panicking at about ~40% power or ~5000 lm
+#define THERM_FASTER_LEVEL 125
// optional, makes initial turbo step-down faster so first peak isn't as hot
#define THERM_HARD_TURBO_DROP
--
cgit v1.2.3
From 8991713b7209dd030ada252b19af5d536c5f07f7 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Fri, 29 Mar 2019 10:34:27 -0600
Subject: fixed bug: hold-from-off then release and hold failed in stepped ramp
(was necessary to wait 1 second before it'd ramp the right way) (reported by
maukka)
---
spaghetti-monster/anduril/anduril.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
(limited to 'spaghetti-monster')
diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c
index 93f8c16..88aafbb 100644
--- a/spaghetti-monster/anduril/anduril.c
+++ b/spaghetti-monster/anduril/anduril.c
@@ -624,9 +624,13 @@ uint8_t steady_state(Event event, uint16_t arg) {
return MISCHIEF_MANAGED;
}
#ifdef USE_REVERSING
- // make it ramp down instead, if already at max
- if ((arg <= 1) && (actual_level >= mode_max)) {
- ramp_direction = -1;
+ // fix ramp direction on first frame if necessary
+ if (!arg) {
+ // make it ramp down instead, if already at max
+ if (actual_level >= mode_max) { ramp_direction = -1; }
+ // make it ramp up if already at min
+ // (off->hold->stepped_min->release causes this state)
+ else if (actual_level <= mode_min) { ramp_direction = 1; }
}
memorized_level = nearest_level((int16_t)actual_level \
+ (ramp_step_size * ramp_direction));
--
cgit v1.2.3