From 3c6a834486ef756e05db88fece2fd248479846ce Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Wed, 22 Jul 2020 16:42:28 -0600 Subject: renamed ramping.* -> ramp-mode.* --- spaghetti-monster/anduril/anduril.c | 8 +- spaghetti-monster/anduril/ramp-mode-fsm.h | 40 +++ spaghetti-monster/anduril/ramp-mode.c | 460 ++++++++++++++++++++++++++++++ spaghetti-monster/anduril/ramp-mode.h | 182 ++++++++++++ spaghetti-monster/anduril/ramping-fsm.h | 37 --- spaghetti-monster/anduril/ramping.c | 460 ------------------------------ spaghetti-monster/anduril/ramping.h | 179 ------------ 7 files changed, 686 insertions(+), 680 deletions(-) create mode 100644 spaghetti-monster/anduril/ramp-mode-fsm.h create mode 100644 spaghetti-monster/anduril/ramp-mode.c create mode 100644 spaghetti-monster/anduril/ramp-mode.h delete mode 100644 spaghetti-monster/anduril/ramping-fsm.h delete mode 100644 spaghetti-monster/anduril/ramping.c delete mode 100644 spaghetti-monster/anduril/ramping.h (limited to 'spaghetti-monster') diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c index d508b3b..67b4b3f 100644 --- a/spaghetti-monster/anduril/anduril.c +++ b/spaghetti-monster/anduril/anduril.c @@ -61,7 +61,7 @@ /********* Include headers which need to be before FSM *********/ // enable FSM features needed by basic ramping functions -#include "ramping-fsm.h" +#include "ramp-mode-fsm.h" #ifdef USE_FACTORY_RESET #include "factory-reset-fsm.h" @@ -89,7 +89,7 @@ /********* Include all the regular app headers *********/ #include "off-state.h" -#include "ramping.h" +#include "ramp-mode.h" #include "load-save-config.h" #include "config-mode.h" #include "misc.h" @@ -202,10 +202,10 @@ uint8_t rgb_led_lockout_mode = RGB_LED_LOCKOUT_DEFAULT; /********* Include all the app logic source files *********/ // (is a bit weird to do things this way, -// but it saves a lot of space by letting use use the -fwhole-program flag) +// but it saves a lot of space by letting us use the -fwhole-program flag) #include "off-state.c" -#include "ramping.c" +#include "ramp-mode.c" #include "load-save-config.c" #include "config-mode.c" #include "misc.c" diff --git a/spaghetti-monster/anduril/ramp-mode-fsm.h b/spaghetti-monster/anduril/ramp-mode-fsm.h new file mode 100644 index 0000000..9d8a1f4 --- /dev/null +++ b/spaghetti-monster/anduril/ramp-mode-fsm.h @@ -0,0 +1,40 @@ +/* + * ramp-mode-fsm.h: FSM config for ramping functions in Anduril. + * + * 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 . + */ + +#ifndef RAMP_MODE_FSM_H +#define RAMP_MODE_FSM_H + +// enable FSM's ramping features +#define USE_RAMPING + +// do smooth adjustments when compensating for temperature +#ifdef USE_THERMAL_REGULATION +#define USE_SET_LEVEL_GRADUALLY // isn't used except for thermal adjustments +#endif + +// brightness to use when no memory is set +// FIXME: this is only here to stop an error in fsm-ramping.c, +// which should be fixed by using a different symbol instead +// (like BUTTON_LED_BRIGHT_LEVEL or RAMP_HALFWAY_LEVEL or something) +#ifndef DEFAULT_LEVEL +#define DEFAULT_LEVEL MAX_1x7135 +#endif + + +#endif diff --git a/spaghetti-monster/anduril/ramp-mode.c b/spaghetti-monster/anduril/ramp-mode.c new file mode 100644 index 0000000..b870550 --- /dev/null +++ b/spaghetti-monster/anduril/ramp-mode.c @@ -0,0 +1,460 @@ +/* + * ramp-mode.c: Ramping functions for Anduril. + * + * 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 . + */ + +#ifndef RAMP_MODE_C +#define RAMP_MODE_C + +#include "ramp-mode.h" + +uint8_t steady_state(Event event, uint16_t arg) { + #ifdef USE_REVERSING + static int8_t ramp_direction = 1; + #endif + #if (B_TIMING_OFF == B_RELEASE_T) + // if the user double clicks, we need to abort turning off, + // and this stores the level to return to + static uint8_t level_before_off = 0; + #endif + + // make sure ramp globals are correct... + // ... but they already are; no need to do it here + //ramp_update_config(); + //nearest_level(1); // same effect, takes less space + + uint8_t mode_min = ramp_floor; + uint8_t mode_max = ramp_ceil; + uint8_t step_size; + if (ramp_style) { step_size = ramp_discrete_step_size; } + else { step_size = 1; } + + // turn LED on when we first enter the mode + if ((event == EV_enter_state) || (event == EV_reenter_state)) { + #if defined(USE_MOMENTARY_MODE) && defined(USE_STROBE_STATE) + momentary_mode = 0; // 0 = ramping, 1 = strobes + #endif + // 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); + set_level_and_therm_target(arg); + #ifdef USE_REVERSING + ramp_direction = 1; + #endif + return MISCHIEF_MANAGED; + } + #if (B_TIMING_OFF == B_RELEASE_T) + // 1 click (early): off, if configured for early response + else if (event == EV_click1_release) { + level_before_off = actual_level; + set_level_and_therm_target(0); + return MISCHIEF_MANAGED; + } + // 2 clicks (early): abort turning off, if configured for early response + else if (event == EV_click2_press) { + set_level_and_therm_target(level_before_off); + return MISCHIEF_MANAGED; + } + #endif // if (B_TIMING_OFF == B_RELEASE_T) + // 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) { + uint8_t turbo_level; + #ifdef USE_SIMPLE_UI + if (simple_ui_active) { turbo_level = mode_max; } + else + #endif + turbo_level = MAX_LEVEL; + + if (actual_level < turbo_level) { + // true turbo, not the mode-specific ceiling + set_level_and_therm_target(turbo_level); + } + else { + set_level_and_therm_target(memorized_level); + } + 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 + // 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; } + } + // if the button is stuck, err on the side of safety and ramp down + else if ((arg > TICKS_PER_SECOND * 5) && (actual_level >= mode_max)) { + ramp_direction = -1; + } + #ifdef USE_LOCKOUT_MODE + // if the button is still stuck, lock the light + else if ((arg > TICKS_PER_SECOND * 10) && (actual_level <= mode_min)) { + blip(); + set_state(lockout_state, 0); + } + #endif + memorized_level = nearest_level((int16_t)actual_level \ + + (step_size * ramp_direction)); + #else + memorized_level = nearest_level((int16_t)actual_level + step_size); + #endif + #if defined(BLINK_AT_RAMP_CEIL) || defined(BLINK_AT_RAMP_MIDDLE) + // only blink once for each threshold + if ((memorized_level != actual_level) && ( + 0 // for easier syntax below + #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_CEIL + || (memorized_level == mode_max) + #endif + #if defined(USE_REVERSING) && defined(BLINK_AT_RAMP_FLOOR) + || (memorized_level == mode_min) + #endif + )) { + blip(); + } + #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) + ) + { + blip(); + } + #endif + set_level_and_therm_target(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 - step_size); + #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_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) + #endif + )) { + blip(); + } + #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) + ) + { + blip(); + } + #endif + set_level_and_therm_target(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 + int16_t diff = gradual_target - actual_level; + static uint16_t ticks_since_adjust = 0; + ticks_since_adjust++; + if (diff) { + uint16_t ticks_per_adjust = 256; + if (diff < 0) { + //diff = -diff; + if (actual_level > THERM_FASTER_LEVEL) { + #ifdef THERM_HARD_TURBO_DROP + ticks_per_adjust >>= 2; + #endif + ticks_per_adjust >>= 2; + } + } else { + // rise at half speed + ticks_per_adjust <<= 1; + } + while (diff) { + ticks_per_adjust >>= 1; + //diff >>= 1; + diff /= 2; // because shifting produces weird behavior + } + if (ticks_since_adjust > ticks_per_adjust) + { + gradual_tick(); + ticks_since_adjust = 0; + } + } + #endif // ifdef USE_SET_LEVEL_GRADUALLY + 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 + blip(); + #endif + #ifdef THERM_HARD_TURBO_DROP + //if (actual_level > THERM_FASTER_LEVEL) { + if (actual_level == MAX_LEVEL) { + #ifdef USE_SET_LEVEL_GRADUALLY + set_level_gradually(THERM_FASTER_LEVEL); + target_level = THERM_FASTER_LEVEL; + #else + set_level_and_therm_target(THERM_FASTER_LEVEL); + #endif + } 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 + blip(); + #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; + } + #ifdef USE_SET_LEVEL_GRADUALLY + // temperature is within target window + // (so stop trying to adjust output) + else if (event == EV_temperature_okay) { + // if we're still adjusting output... stop after the current step + if (gradual_target > actual_level) + gradual_target = actual_level + 1; + else if (gradual_target < actual_level) + gradual_target = actual_level - 1; + return MISCHIEF_MANAGED; + } + #endif // ifdef USE_SET_LEVEL_GRADUALLY + #endif // ifdef USE_THERMAL_REGULATION + + ////////// Every action below here is blocked in the simple UI ////////// + #ifdef USE_SIMPLE_UI + if (simple_ui_active) { + return EVENT_NOT_HANDLED; + } + #endif + + // 3 clicks: toggle smooth vs discrete ramping + else if (event == EV_3clicks) { + ramp_style = !ramp_style; + save_config(); + #ifdef START_AT_MEMORIZED_LEVEL + save_config_wl(); + #endif + blip(); + memorized_level = nearest_level(actual_level); + set_level_and_therm_target(memorized_level); + return MISCHIEF_MANAGED; + } + + #ifdef USE_MANUAL_MEMORY + else if (event == EV_5clicks) { + manual_memory = actual_level; + save_config(); + blip(); + return MISCHIEF_MANAGED; + } + else if (event == EV_click5_hold) { + if (0 == arg) { + manual_memory = 0; + save_config(); + blip(); + } + return MISCHIEF_MANAGED; + } + #endif + + #ifdef USE_RAMP_CONFIG + // 7 clicks: configure this ramp mode + else if (event == EV_7clicks) { + push_state(ramp_config_state, 0); + return MISCHIEF_MANAGED; + } + #endif + return EVENT_NOT_HANDLED; +} + + +#ifdef USE_RAMP_CONFIG +void ramp_config_save() { + // parse values + uint8_t val; + uint8_t style = ramp_style; + // TODO: detect if we're configuring the simple UI + + val = config_state_values[0]; + if (val) { ramp_floors[style] = val; } + + val = config_state_values[1]; + if (val) { ramp_ceils[style] = MAX_LEVEL + 1 - val; } + + if (ramp_style) { // discrete / stepped ramp + val = config_state_values[2]; + if (val) ramp_stepss[style] = 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); +} +#endif // #ifdef USE_RAMP_CONFIG + + +// 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) { + ramp_update_config(); + + // 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_floor; + uint8_t mode_max = ramp_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 = mode_max - mode_min; + uint8_t num_steps = ramp_stepss[1 + simple_ui_active]; + ramp_discrete_step_size = ramp_range / (num_steps-1); + uint8_t this_level = mode_min; + + for(uint8_t i=0; i>1)) + return this_level; + } + return this_level; +} + +// ensure ramp globals are correct +void ramp_update_config() { + uint8_t which = ramp_style; + if (simple_ui_active) { which = 2; } + + ramp_floor = ramp_floors[which]; + ramp_ceil = ramp_ceils[which]; +} + +#ifdef USE_THERMAL_REGULATION +void set_level_and_therm_target(uint8_t level) { + target_level = level; + set_level(level); +} +#endif + + +#endif + diff --git a/spaghetti-monster/anduril/ramp-mode.h b/spaghetti-monster/anduril/ramp-mode.h new file mode 100644 index 0000000..00cac9f --- /dev/null +++ b/spaghetti-monster/anduril/ramp-mode.h @@ -0,0 +1,182 @@ +/* + * ramp-mode.h: Ramping functions for Anduril. + * + * 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 . + */ + +#ifndef RAMP_MODE_H +#define RAMP_MODE_H + +#ifndef RAMP_LENGTH +#define RAMP_LENGTH 150 // default, if not overridden in a driver cfg file +#endif + +// 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 + +#if defined(USE_SIMPLE_UI) +// TODO: Move these settings to config-default.h? +// start in the simple UI after each factory reset? +#ifndef DEFAULT_SIMPLE_UI_ACTIVE +#define DEFAULT_SIMPLE_UI_ACTIVE 1 +#endif +#ifndef DEFAULT_SIMPLE_UI_FLOOR +#define DEFAULT_SIMPLE_UI_FLOOR 22 +#endif +#ifndef DEFAULT_SIMPLE_UI_CEIL +#define DEFAULT_SIMPLE_UI_CEIL (MAX_1x7135+20) +#endif +#ifndef DEFAULT_SIMPLE_UI_STEPS +#define DEFAULT_SIMPLE_UI_STEPS 3 +#endif +#endif + + +// configure the timing of turning on/off in regular ramp mode +// press: react as soon as the button is pressed +#define B_PRESS_T 0 +// release: react as soon as the button is released +#define B_RELEASE_T 1 +// timeout: react as soon as we're sure the user isn't doing a double-click +#define B_TIMEOUT_T 2 +// defaults are release on, timeout off +// TODO: Move these settings to config-default.h? +#ifndef B_TIMING_ON +//#define B_TIMING_ON B_PRESS_T +#define B_TIMING_ON B_RELEASE_T +#endif +#ifndef B_TIMING_OFF +//#define B_TIMING_OFF B_RELEASE_T +#define B_TIMING_OFF B_TIMEOUT_T +#endif + +// default ramp options if not overridden earlier per-driver +#ifndef RAMP_STYLE +// TODO: Move this setting to config-default.h? +#define RAMP_STYLE 0 // smooth default +#endif +#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 + +// 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 + + +// 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); +void ramp_config_save(); +#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); + +// ensure ramp globals are correct +void ramp_update_config(); + +#ifdef USE_THERMAL_REGULATION +// brightness before thermal step-down +uint8_t target_level = 0; +void set_level_and_therm_target(uint8_t level); +#else +#define set_level_and_therm_target(level) set_level(level) +#endif + + +// brightness control +uint8_t memorized_level = DEFAULT_LEVEL; +#ifdef USE_MANUAL_MEMORY +uint8_t manual_memory = 0; +#endif +#ifdef USE_SIMPLE_UI +// whether to enable the simplified interface or not +uint8_t simple_ui_active = DEFAULT_SIMPLE_UI_ACTIVE; +#endif +// smooth vs discrete ramping +uint8_t ramp_style = RAMP_STYLE; // 0 = smooth, 1 = discrete +// current values, regardless of style +uint8_t ramp_floor = RAMP_SMOOTH_FLOOR; +uint8_t ramp_ceil = RAMP_SMOOTH_CEIL; +// per style +uint8_t ramp_floors[] = { + RAMP_SMOOTH_FLOOR, + RAMP_DISCRETE_FLOOR, + #ifdef USE_SIMPLE_UI + DEFAULT_SIMPLE_UI_FLOOR, + #endif + }; +uint8_t ramp_ceils[] = { + RAMP_SMOOTH_CEIL, + RAMP_DISCRETE_CEIL, + #ifdef USE_SIMPLE_UI + DEFAULT_SIMPLE_UI_CEIL, + #endif + }; +uint8_t ramp_stepss[] = { + 0, + RAMP_DISCRETE_STEPS, + #ifdef USE_SIMPLE_UI + DEFAULT_SIMPLE_UI_STEPS, + #endif + }; +uint8_t ramp_discrete_step_size; // don't set this + + +#endif diff --git a/spaghetti-monster/anduril/ramping-fsm.h b/spaghetti-monster/anduril/ramping-fsm.h deleted file mode 100644 index 97b4321..0000000 --- a/spaghetti-monster/anduril/ramping-fsm.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * ramping-fsm.h: FSM config for ramping functions in Anduril. - * - * 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 . - */ - -#ifndef RAMPING_FSM_H -#define RAMPING_FSM_H - -#define USE_RAMPING - -#ifdef USE_THERMAL_REGULATION -#define USE_SET_LEVEL_GRADUALLY // isn't used except for thermal adjustments -#endif - -// brightness to use when no memory is set -// FIXME: this is only here to stop an error in fsm-ramping.c, -// which should be fixed by using a different symbol instead -#ifndef DEFAULT_LEVEL -#define DEFAULT_LEVEL MAX_1x7135 -#endif - - -#endif diff --git a/spaghetti-monster/anduril/ramping.c b/spaghetti-monster/anduril/ramping.c deleted file mode 100644 index f2a23c8..0000000 --- a/spaghetti-monster/anduril/ramping.c +++ /dev/null @@ -1,460 +0,0 @@ -/* - * ramping.c: Ramping functions for Anduril. - * - * 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 . - */ - -#ifndef RAMPING_C -#define RAMPING_C - -#include "ramping.h" - -uint8_t steady_state(Event event, uint16_t arg) { - #ifdef USE_REVERSING - static int8_t ramp_direction = 1; - #endif - #if (B_TIMING_OFF == B_RELEASE_T) - // if the user double clicks, we need to abort turning off, - // and this stores the level to return to - static uint8_t level_before_off = 0; - #endif - - // make sure ramp globals are correct... - // ... but they already are; no need to do it here - //ramp_update_config(); - //nearest_level(1); // same effect, takes less space - - uint8_t mode_min = ramp_floor; - uint8_t mode_max = ramp_ceil; - uint8_t step_size; - if (ramp_style) { step_size = ramp_discrete_step_size; } - else { step_size = 1; } - - // turn LED on when we first enter the mode - if ((event == EV_enter_state) || (event == EV_reenter_state)) { - #if defined(USE_MOMENTARY_MODE) && defined(USE_STROBE_STATE) - momentary_mode = 0; // 0 = ramping, 1 = strobes - #endif - // 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); - set_level_and_therm_target(arg); - #ifdef USE_REVERSING - ramp_direction = 1; - #endif - return MISCHIEF_MANAGED; - } - #if (B_TIMING_OFF == B_RELEASE_T) - // 1 click (early): off, if configured for early response - else if (event == EV_click1_release) { - level_before_off = actual_level; - set_level_and_therm_target(0); - return MISCHIEF_MANAGED; - } - // 2 clicks (early): abort turning off, if configured for early response - else if (event == EV_click2_press) { - set_level_and_therm_target(level_before_off); - return MISCHIEF_MANAGED; - } - #endif // if (B_TIMING_OFF == B_RELEASE_T) - // 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) { - uint8_t turbo_level; - #ifdef USE_SIMPLE_UI - if (simple_ui_active) { turbo_level = mode_max; } - else - #endif - turbo_level = MAX_LEVEL; - - if (actual_level < turbo_level) { - // true turbo, not the mode-specific ceiling - set_level_and_therm_target(turbo_level); - } - else { - set_level_and_therm_target(memorized_level); - } - 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 - // 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; } - } - // if the button is stuck, err on the side of safety and ramp down - else if ((arg > TICKS_PER_SECOND * 5) && (actual_level >= mode_max)) { - ramp_direction = -1; - } - #ifdef USE_LOCKOUT_MODE - // if the button is still stuck, lock the light - else if ((arg > TICKS_PER_SECOND * 10) && (actual_level <= mode_min)) { - blip(); - set_state(lockout_state, 0); - } - #endif - memorized_level = nearest_level((int16_t)actual_level \ - + (step_size * ramp_direction)); - #else - memorized_level = nearest_level((int16_t)actual_level + step_size); - #endif - #if defined(BLINK_AT_RAMP_CEIL) || defined(BLINK_AT_RAMP_MIDDLE) - // only blink once for each threshold - if ((memorized_level != actual_level) && ( - 0 // for easier syntax below - #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_CEIL - || (memorized_level == mode_max) - #endif - #if defined(USE_REVERSING) && defined(BLINK_AT_RAMP_FLOOR) - || (memorized_level == mode_min) - #endif - )) { - blip(); - } - #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) - ) - { - blip(); - } - #endif - set_level_and_therm_target(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 - step_size); - #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_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) - #endif - )) { - blip(); - } - #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) - ) - { - blip(); - } - #endif - set_level_and_therm_target(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 - int16_t diff = gradual_target - actual_level; - static uint16_t ticks_since_adjust = 0; - ticks_since_adjust++; - if (diff) { - uint16_t ticks_per_adjust = 256; - if (diff < 0) { - //diff = -diff; - if (actual_level > THERM_FASTER_LEVEL) { - #ifdef THERM_HARD_TURBO_DROP - ticks_per_adjust >>= 2; - #endif - ticks_per_adjust >>= 2; - } - } else { - // rise at half speed - ticks_per_adjust <<= 1; - } - while (diff) { - ticks_per_adjust >>= 1; - //diff >>= 1; - diff /= 2; // because shifting produces weird behavior - } - if (ticks_since_adjust > ticks_per_adjust) - { - gradual_tick(); - ticks_since_adjust = 0; - } - } - #endif // ifdef USE_SET_LEVEL_GRADUALLY - 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 - blip(); - #endif - #ifdef THERM_HARD_TURBO_DROP - //if (actual_level > THERM_FASTER_LEVEL) { - if (actual_level == MAX_LEVEL) { - #ifdef USE_SET_LEVEL_GRADUALLY - set_level_gradually(THERM_FASTER_LEVEL); - target_level = THERM_FASTER_LEVEL; - #else - set_level_and_therm_target(THERM_FASTER_LEVEL); - #endif - } 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 - blip(); - #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; - } - #ifdef USE_SET_LEVEL_GRADUALLY - // temperature is within target window - // (so stop trying to adjust output) - else if (event == EV_temperature_okay) { - // if we're still adjusting output... stop after the current step - if (gradual_target > actual_level) - gradual_target = actual_level + 1; - else if (gradual_target < actual_level) - gradual_target = actual_level - 1; - return MISCHIEF_MANAGED; - } - #endif // ifdef USE_SET_LEVEL_GRADUALLY - #endif // ifdef USE_THERMAL_REGULATION - - ////////// Every action below here is blocked in the simple UI ////////// - #ifdef USE_SIMPLE_UI - if (simple_ui_active) { - return EVENT_NOT_HANDLED; - } - #endif - - // 3 clicks: toggle smooth vs discrete ramping - else if (event == EV_3clicks) { - ramp_style = !ramp_style; - save_config(); - #ifdef START_AT_MEMORIZED_LEVEL - save_config_wl(); - #endif - blip(); - memorized_level = nearest_level(actual_level); - set_level_and_therm_target(memorized_level); - return MISCHIEF_MANAGED; - } - - #ifdef USE_MANUAL_MEMORY - else if (event == EV_5clicks) { - manual_memory = actual_level; - save_config(); - blip(); - return MISCHIEF_MANAGED; - } - else if (event == EV_click5_hold) { - if (0 == arg) { - manual_memory = 0; - save_config(); - blip(); - } - return MISCHIEF_MANAGED; - } - #endif - - #ifdef USE_RAMP_CONFIG - // 7 clicks: configure this ramp mode - else if (event == EV_7clicks) { - push_state(ramp_config_state, 0); - return MISCHIEF_MANAGED; - } - #endif - return EVENT_NOT_HANDLED; -} - - -#ifdef USE_RAMP_CONFIG -void ramp_config_save() { - // parse values - uint8_t val; - uint8_t style = ramp_style; - // TODO: detect if we're configuring the simple UI - - val = config_state_values[0]; - if (val) { ramp_floors[style] = val; } - - val = config_state_values[1]; - if (val) { ramp_ceils[style] = MAX_LEVEL + 1 - val; } - - if (ramp_style) { // discrete / stepped ramp - val = config_state_values[2]; - if (val) ramp_stepss[style] = 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); -} -#endif // #ifdef USE_RAMP_CONFIG - - -// 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) { - ramp_update_config(); - - // 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_floor; - uint8_t mode_max = ramp_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 = mode_max - mode_min; - uint8_t num_steps = ramp_stepss[1 + simple_ui_active]; - ramp_discrete_step_size = ramp_range / (num_steps-1); - uint8_t this_level = mode_min; - - for(uint8_t i=0; i>1)) - return this_level; - } - return this_level; -} - -// ensure ramp globals are correct -void ramp_update_config() { - uint8_t which = ramp_style; - if (simple_ui_active) { which = 2; } - - ramp_floor = ramp_floors[which]; - ramp_ceil = ramp_ceils[which]; -} - -#ifdef USE_THERMAL_REGULATION -void set_level_and_therm_target(uint8_t level) { - target_level = level; - set_level(level); -} -#endif - - -#endif - diff --git a/spaghetti-monster/anduril/ramping.h b/spaghetti-monster/anduril/ramping.h deleted file mode 100644 index b47297d..0000000 --- a/spaghetti-monster/anduril/ramping.h +++ /dev/null @@ -1,179 +0,0 @@ -/* - * ramping.h: Ramping functions for Anduril. - * - * 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 . - */ - -#ifndef RAMPING_H -#define RAMPING_H - -#ifndef RAMP_LENGTH -#define RAMP_LENGTH 150 // default, if not overridden in a driver cfg file -#endif - -// 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 - -#if defined(USE_SIMPLE_UI) -// start in the simple UI after each factory reset? -#ifndef DEFAULT_SIMPLE_UI_ACTIVE -#define DEFAULT_SIMPLE_UI_ACTIVE 1 -#endif -#ifndef DEFAULT_SIMPLE_UI_FLOOR -#define DEFAULT_SIMPLE_UI_FLOOR 22 -#endif -#ifndef DEFAULT_SIMPLE_UI_CEIL -#define DEFAULT_SIMPLE_UI_CEIL (MAX_1x7135+20) -#endif -#ifndef DEFAULT_SIMPLE_UI_STEPS -#define DEFAULT_SIMPLE_UI_STEPS 3 -#endif -#endif - - -// configure the timing of turning on/off in regular ramp mode -// press: react as soon as the button is pressed -#define B_PRESS_T 0 -// release: react as soon as the button is released -#define B_RELEASE_T 1 -// timeout: react as soon as we're sure the user isn't doing a double-click -#define B_TIMEOUT_T 2 -// defaults are release on, timeout off -#ifndef B_TIMING_ON -//#define B_TIMING_ON B_PRESS_T -#define B_TIMING_ON B_RELEASE_T -#endif -#ifndef B_TIMING_OFF -//#define B_TIMING_OFF B_RELEASE_T -#define B_TIMING_OFF B_TIMEOUT_T -#endif - -// default ramp options if not overridden earlier per-driver -#ifndef RAMP_STYLE -#define RAMP_STYLE 0 // smooth default -#endif -#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 - -// 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 - - -// 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); -void ramp_config_save(); -#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); - -// ensure ramp globals are correct -void ramp_update_config(); - -#ifdef USE_THERMAL_REGULATION -// brightness before thermal step-down -uint8_t target_level = 0; -void set_level_and_therm_target(uint8_t level); -#else -#define set_level_and_therm_target(level) set_level(level) -#endif - - -// brightness control -uint8_t memorized_level = DEFAULT_LEVEL; -#ifdef USE_MANUAL_MEMORY -uint8_t manual_memory = 0; -#endif -#ifdef USE_SIMPLE_UI -// whether to enable the simplified interface or not -uint8_t simple_ui_active = DEFAULT_SIMPLE_UI_ACTIVE; -#endif -// smooth vs discrete ramping -uint8_t ramp_style = RAMP_STYLE; // 0 = smooth, 1 = discrete -// current values, regardless of style -uint8_t ramp_floor = RAMP_SMOOTH_FLOOR; -uint8_t ramp_ceil = RAMP_SMOOTH_CEIL; -// per style -uint8_t ramp_floors[] = { - RAMP_SMOOTH_FLOOR, - RAMP_DISCRETE_FLOOR, - #ifdef USE_SIMPLE_UI - DEFAULT_SIMPLE_UI_FLOOR, - #endif - }; -uint8_t ramp_ceils[] = { - RAMP_SMOOTH_CEIL, - RAMP_DISCRETE_CEIL, - #ifdef USE_SIMPLE_UI - DEFAULT_SIMPLE_UI_CEIL, - #endif - }; -uint8_t ramp_stepss[] = { - 0, - RAMP_DISCRETE_STEPS, - #ifdef USE_SIMPLE_UI - DEFAULT_SIMPLE_UI_STEPS, - #endif - }; -uint8_t ramp_discrete_step_size; // don't set this - - -#endif -- cgit v1.2.3