aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spaghetti-monster/darkhorse.c37
-rw-r--r--spaghetti-monster/fsm-eeprom.c71
-rw-r--r--spaghetti-monster/fsm-eeprom.h58
-rw-r--r--spaghetti-monster/fsm-events.h8
-rw-r--r--spaghetti-monster/spaghetti-monster.h6
5 files changed, 179 insertions, 1 deletions
diff --git a/spaghetti-monster/darkhorse.c b/spaghetti-monster/darkhorse.c
index a7937e6..2aa1b7b 100644
--- a/spaghetti-monster/darkhorse.c
+++ b/spaghetti-monster/darkhorse.c
@@ -27,6 +27,8 @@
#define USE_BATTCHECK
#define BATTCHECK_4bars
#define DONT_DELAY_AFTER_BATTCHECK
+#define USE_EEPROM
+#define EEPROM_BYTES 5
#include "spaghetti-monster.h"
// FSM states
@@ -41,6 +43,9 @@ uint8_t battcheck_state(EventPtr event, uint16_t arg);
// Not a FSM state, just handles stuff common to all low/med/hi states
uint8_t any_mode_state(EventPtr event, uint16_t arg, uint8_t *primary, uint8_t *secondary, uint8_t *modes);
+void load_config();
+void save_config();
+
// toggle between L1/L2, M1/M2, H1/H2
uint8_t L1 = 1;
uint8_t M1 = 1;
@@ -192,10 +197,11 @@ uint8_t any_mode_state(EventPtr event, uint16_t arg, uint8_t *primary, uint8_t *
else if (event == EV_2clicks) {
*primary ^= 1;
set_any_mode(*primary, *secondary, modes);
+ save_config();
return MISCHIEF_MANAGED;
}
// click-release-hold: change secondary level
- if (event == EV_click2_hold) {
+ else if (event == EV_click2_hold) {
if (arg % HOLD_TIMEOUT == 0) {
*secondary = (*secondary + 1) & 3;
if (! *secondary) *secondary = 1;
@@ -204,6 +210,10 @@ uint8_t any_mode_state(EventPtr event, uint16_t arg, uint8_t *primary, uint8_t *
}
return MISCHIEF_MANAGED;
}
+ // click, hold, release: save secondary level
+ else if (event == EV_click2_hold_release) {
+ save_config();
+ }
#ifdef USE_THERMAL_REGULATION
// TODO: test this on a real light
// overheating: drop by an amount proportional to how far we are above the ceiling
@@ -263,6 +273,7 @@ uint8_t strobe_beacon_state(EventPtr event, uint16_t arg) {
// 2 clicks: rotate through blinky modes
else if (event == EV_2clicks) {
strobe_beacon_mode = (strobe_beacon_mode + 1) & 3;
+ save_config();
interrupt_nice_delays();
return MISCHIEF_MANAGED;
}
@@ -293,11 +304,35 @@ void strobe(uint8_t level, uint16_t ontime, uint16_t offtime) {
nice_delay_ms(offtime);
}
+void load_config() {
+ if (load_eeprom()) {
+ H1 = !(!(eeprom[0] & 0b00000100));
+ M1 = !(!(eeprom[0] & 0b00000010));
+ L1 = !(!(eeprom[0] & 0b00000001));
+ H2 = eeprom[1];
+ M2 = eeprom[2];
+ L2 = eeprom[3];
+ strobe_beacon_mode = eeprom[4];
+ }
+}
+
+void save_config() {
+ eeprom[0] = (H1<<2) | (M1<<1) | (L1);
+ eeprom[1] = H2;
+ eeprom[2] = M2;
+ eeprom[3] = L2;
+ eeprom[4] = strobe_beacon_mode;
+
+ save_eeprom();
+}
+
void setup() {
set_level(RAMP_SIZE/8);
delay_4ms(3);
set_level(0);
+ load_config();
+
push_state(off_state, 0);
}
diff --git a/spaghetti-monster/fsm-eeprom.c b/spaghetti-monster/fsm-eeprom.c
new file mode 100644
index 0000000..5451baf
--- /dev/null
+++ b/spaghetti-monster/fsm-eeprom.c
@@ -0,0 +1,71 @@
+/*
+ * fsm-eeprom.c: EEPROM API for SpaghettiMonster.
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef FSM_EEPROM_C
+#define FSM_EEPROM_C
+
+#include "fsm-eeprom.h"
+
+#if EEPROM_BYTES > 0
+#if EEPROM_BYTES >= (EEPSIZE/2)
+#error Requested EEPROM_BYTES too big.
+#endif
+uint8_t eeprom[EEPROM_BYTES];
+
+uint8_t load_eeprom() {
+ cli();
+ // check if eeprom has been initialized; abort if it hasn't
+ uint8_t marker = eeprom_read_byte((uint8_t *)EEP_START);
+ if (marker != EEP_MARKER) { sei(); return 0; }
+
+ // load the actual data
+ for(uint8_t i=0; i<EEPROM_BYTES; i++) {
+ eeprom[i] = eeprom_read_byte((uint8_t *)(EEP_START+1+i));
+ }
+ sei();
+ return 1;
+}
+
+void save_eeprom() {
+ cli();
+ eeprom_update_byte((uint8_t *)EEP_START, EEP_MARKER);
+
+ // save the actual data
+ for(uint8_t i=0; i<EEPROM_BYTES; i++) {
+ eeprom_update_byte((uint8_t *)(EEP_START+1+i), eeprom[i]);
+ }
+ sei();
+}
+#endif
+
+#if EEPROM_WL_BYTES > 0
+#if EEPROM_WL_BYTES >= (EEPSIZE/4)
+#error Requested EEPROM_WL_BYTES too big.
+#endif
+uint8_t eeprom_wl[EEPROM_WL_BYTES];
+
+uint8_t load_wl_eeprom() {
+}
+
+void save_wl_eeprom() {
+}
+#endif
+
+
+#endif
diff --git a/spaghetti-monster/fsm-eeprom.h b/spaghetti-monster/fsm-eeprom.h
new file mode 100644
index 0000000..3d34f23
--- /dev/null
+++ b/spaghetti-monster/fsm-eeprom.h
@@ -0,0 +1,58 @@
+/*
+ * fsm-eeprom.h: EEPROM API for SpaghettiMonster.
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef FSM_EEPROM_H
+#define FSM_EEPROM_H
+
+#include <avr/eeprom.h>
+
+// set this higher to enable normal eeprom functions
+#ifndef EEPROM_BYTES
+#define EEPROM_BYTES 0
+#endif
+
+// set this higher to enable wear-levelled eeprom functions
+#ifndef EEPROM_WL_BYTES
+#define EEPROM_WL_BYTES 0
+#endif
+
+#if EEPROM_BYTES > 0
+uint8_t eeprom[EEPROM_BYTES];
+uint8_t load_eeprom(); // returns 1 for success, 0 for no data found
+void save_eeprom();
+#define EEP_START (EEPSIZE/2)
+#endif
+
+#if EEPROM_WL_BYTES > 0
+uint8_t eeprom_wl[EEPROM_WL_BYTES];
+uint8_t load_wl_eeprom(); // returns 1 for success, 0 for no data found
+void save_wl_eeprom();
+#define EEP_WL_SIZE (EEPSIZE/2)
+#endif
+
+#if EEPSIZE > 256
+#define EEP_OFFSET_T uint16_t
+#else
+#define EEP_OFFSET_T uint8_t
+#endif
+
+// if this marker isn't found, the eeprom is assumed to be blank
+#define EEP_MARKER 0b10100101
+
+#endif
diff --git a/spaghetti-monster/fsm-events.h b/spaghetti-monster/fsm-events.h
index f2a0181..90dcbd6 100644
--- a/spaghetti-monster/fsm-events.h
+++ b/spaghetti-monster/fsm-events.h
@@ -127,6 +127,13 @@ Event EV_click2_hold[] = {
A_PRESS,
A_HOLD,
0 };
+Event EV_click2_hold_release[] = {
+ A_PRESS,
+ A_RELEASE,
+ A_PRESS,
+ A_HOLD,
+ A_RELEASE,
+ 0 };
Event EV_click2_release[] = {
A_PRESS,
A_RELEASE,
@@ -190,6 +197,7 @@ EventPtr event_sequences[] = {
EV_click1_hold_release,
EV_click2_press,
EV_click2_hold,
+ EV_click2_hold_release,
EV_click2_release,
EV_click2_complete,
EV_click3_press,
diff --git a/spaghetti-monster/spaghetti-monster.h b/spaghetti-monster/spaghetti-monster.h
index 3727930..82800b4 100644
--- a/spaghetti-monster/spaghetti-monster.h
+++ b/spaghetti-monster/spaghetti-monster.h
@@ -34,6 +34,9 @@
#include "fsm-pcint.h"
#include "fsm-standby.h"
#include "fsm-ramping.h"
+#ifdef USE_EEPROM
+#include "fsm-eeprom.h"
+#endif
#include "fsm-misc.h"
#include "fsm-main.h"
@@ -71,5 +74,8 @@ void loop();
#include "fsm-pcint.c"
#include "fsm-standby.c"
#include "fsm-ramping.c"
+#ifdef USE_EEPROM
+#include "fsm-eeprom.c"
+#endif
#include "fsm-misc.c"
#include "fsm-main.c"