Skip to content

Commit bc401cd

Browse files
authored
Reset EEPROM (#510)
* Fix comments * Reset EEPROM * Reset EEPROM * Disable EEPROM access * Reboot after user selection * Fix mistakes * UI changes * Overload Ethernet_TC::instance() * Claude's fix to reboot issue * ResetEEPROM tests * Free space * lint
1 parent 7e17c34 commit bc401cd

15 files changed

Lines changed: 225 additions & 31 deletions

Makefile

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ all : \
7171
$(BIN)/PIDTest.cpp.bin \
7272
$(BIN)/PushingBoxTest.cpp.bin \
7373
$(BIN)/RemoteLogPusherTest.cpp.bin \
74+
$(BIN)/ResetEEPROMTest.cpp.bin \
7475
$(BIN)/ResetPHCalibrationTest.cpp.bin \
7576
$(BIN)/ResetThermalCalibrationTest.cpp.bin \
7677
$(BIN)/SDTest.cpp.bin \
@@ -175,6 +176,15 @@ $(BIN)/PushingBoxTest.cpp.bin: $(BIN)/libarduino.so $(TEST)/PushingBoxTest.cpp $
175176
$(BIN)/RemoteLogPusherTest.cpp.bin: $(BIN)/libarduino.so $(TEST)/RemoteLogPusherTest.cpp $(HEADERS)
176177
$(GPP_TEST) -o $(BIN)/RemoteLogPusherTest.cpp.bin $(TEST)/RemoteLogPusherTest.cpp -larduino
177178

179+
$(BIN)/ResetEEPROMTest.cpp.bin: $(BIN)/libarduino.so $(TEST)/ResetEEPROMTest.cpp $(HEADERS)
180+
$(GPP_TEST) -o $(BIN)/ResetEEPROMTest.cpp.bin $(TEST)/ResetEEPROMTest.cpp -larduino
181+
182+
$(BIN)/ResetPHCalibrationTest.cpp.bin: $(BIN)/libarduino.so $(TEST)/ResetPHCalibrationTest.cpp $(HEADERS)
183+
$(GPP_TEST) -o $(BIN)/ResetPHCalibrationTest.cpp.bin $(TEST)/ResetPHCalibrationTest.cpp -larduino
184+
185+
$(BIN)/ResetThermalCalibrationTest.cpp.bin: $(BIN)/libarduino.so $(TEST)/ResetThermalCalibrationTest.cpp $(HEADERS)
186+
$(GPP_TEST) -o $(BIN)/ResetThermalCalibrationTest.cpp.bin $(TEST)/ResetThermalCalibrationTest.cpp -larduino
187+
178188
$(BIN)/SDTest.cpp.bin: $(BIN)/libarduino.so $(TEST)/SDTest.cpp $(HEADERS)
179189
$(GPP_TEST) -o $(BIN)/SDTest.cpp.bin $(TEST)/SDTest.cpp -larduino
180190

@@ -229,9 +239,6 @@ $(BIN)/SetKITest.cpp.bin: $(BIN)/libarduino.so $(TEST)/SetKITest.cpp $(HEADERS)
229239
$(BIN)/SetKPTest.cpp.bin: $(BIN)/libarduino.so $(TEST)/SetKPTest.cpp $(HEADERS)
230240
$(GPP_TEST) -o $(BIN)/SetKPTest.cpp.bin $(TEST)/SetKPTest.cpp -larduino
231241

232-
$(BIN)/ResetPHCalibrationTest.cpp.bin: $(BIN)/libarduino.so $(TEST)/ResetPHCalibrationTest.cpp $(HEADERS)
233-
$(GPP_TEST) -o $(BIN)/ResetPHCalibrationTest.cpp.bin $(TEST)/ResetPHCalibrationTest.cpp -larduino
234-
235242
$(BIN)/SetPHTargetTest.cpp.bin: $(BIN)/libarduino.so $(TEST)/SetPHTargetTest.cpp $(HEADERS)
236243
$(GPP_TEST) -o $(BIN)/SetPHTargetTest.cpp.bin $(TEST)/SetPHTargetTest.cpp -larduino
237244

@@ -241,9 +248,6 @@ $(BIN)/SetPHSineWaveTest.cpp.bin: $(BIN)/libarduino.so $(TEST)/SetPHSineWaveTest
241248
$(BIN)/SetTankIDTest.cpp.bin: $(BIN)/libarduino.so $(TEST)/SetTankIDTest.cpp $(HEADERS)
242249
$(GPP_TEST) -o $(BIN)/SetTankIDTest.cpp.bin $(TEST)/SetTankIDTest.cpp -larduino
243250

244-
$(BIN)/ResetThermalCalibrationTest.cpp.bin: $(BIN)/libarduino.so $(TEST)/ResetThermalCalibrationTest.cpp $(HEADERS)
245-
$(GPP_TEST) -o $(BIN)/ResetThermalCalibrationTest.cpp.bin $(TEST)/ResetThermalCalibrationTest.cpp -larduino
246-
247251
$(BIN)/SetThermalTargetTest.cpp.bin: $(BIN)/libarduino.so $(TEST)/SetThermalTargetTest.cpp $(HEADERS)
248252
$(GPP_TEST) -o $(BIN)/SetThermalTargetTest.cpp.bin $(TEST)/SetThermalTargetTest.cpp -larduino
249253

@@ -377,6 +381,7 @@ OBJECTS=$(BIN)/Arduino.o \
377381
$(BIN)/PHCalibrationMid.o \
378382
$(BIN)/PHCalibrationPrompt.o \
379383
$(BIN)/RemoteLogPusher.o \
384+
$(BIN)/ResetEEPROM.o \
380385
$(BIN)/SeeDeviceAddress.o \
381386
$(BIN)/SeeDeviceUptime.o \
382387
$(BIN)/SeeFreeMemory.o \
@@ -506,6 +511,9 @@ $(BIN)/PHCalibrationPrompt.o: $(SRC)/UIState/PHCalibrationPrompt.cpp $(HEADERS)
506511
$(BIN)/RemoteLogPusher.o: $(SRC)/model/RemoteLogPusher.cpp $(HEADERS)
507512
g++ -c $(FLAGS) $(INCLUDE) -o $(BIN)/RemoteLogPusher.o $(SRC)/model/RemoteLogPusher.cpp
508513

514+
$(BIN)/ResetEEPROM.o: $(SRC)/UIState/ResetEEPROM.cpp $(HEADERS)
515+
g++ -c $(FLAGS) $(INCLUDE) -o $(BIN)/ResetEEPROM.o $(SRC)/UIState/ResetEEPROM.cpp
516+
509517
$(BIN)/SeeDeviceAddress.o: $(SRC)/UIState/SeeDeviceAddress.cpp $(HEADERS)
510518
g++ -c $(FLAGS) $(INCLUDE) -o $(BIN)/SeeDeviceAddress.o $(SRC)/UIState/SeeDeviceAddress.cpp
511519

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
const String gitVersion = 'v25.4.1 +';
1+
const String gitVersion = 'v25.4.1-18-g9ac+';

extras/scripts/build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#! /bin/bash
22
bundle config set --local path 'vendor/bundle'
33
bundle install
4-
bundle exec arduino_ci.rb --min-free-space=5640 --skip-unittests 1> >(tee stdout.txt ) 2> >(tee stderr.txt >&2 ); result=$?
4+
bundle exec arduino_ci.rb --min-free-space=5632 --skip-unittests 1> >(tee stdout.txt ) 2> >(tee stderr.txt >&2 ); result=$?
55
exit "$result"

extras/scripts/testAndBuild.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
cp extras/scripts/p*-commit .git/hooks/
44
bundle config set --local path 'vendor/bundle'
55
bundle install
6-
bundle exec arduino_ci.rb --min-free-space=5640 1> >(tee stdout.txt ) 2> >(tee stderr.txt >&2 )
6+
bundle exec arduino_ci.rb --min-free-space=5632 1> >(tee stdout.txt ) 2> >(tee stderr.txt >&2 )
77
result="${PIPESTATUS[0]}"
88
exit "$result"

src/TankController.cpp

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <stdlib.h>
55

66
#include "UIState/MainMenu.h"
7+
#include "UIState/ResetEEPROM.h"
78
#include "UIState/UIState.h"
89
#include "Version.h"
910
#include "model/DataLogger.h"
@@ -27,27 +28,52 @@
2728

2829
const char TANK_CONTROLLER_VERSION[] = VERSION;
2930

31+
// ------------ Early Boot Watchdog Disable ------------
32+
/**
33+
* Disable the watchdog timer immediately on boot, before main()/setup() runs.
34+
*
35+
* After a watchdog reset on AVR, the WDT remains enabled with whatever timeout
36+
* triggered the reset (e.g. the 15 ms used by ResetEEPROM). The stock Mega2560
37+
* bootloader does not clear MCUSR or call wdt_disable(), and it takes longer
38+
* than 15 ms to hand control to the sketch -- so the WDT fires again inside
39+
* the bootloader, looping forever and appearing as a "freeze." Clearing MCUSR
40+
* and disabling the WDT from .init3 runs before the C runtime / main() and
41+
* breaks that loop. See avr-libc <avr/wdt.h> documentation.
42+
*/
43+
#if !defined(ARDUINO_CI_COMPILATION_MOCKS)
44+
void disableWatchdogAtBoot(void) __attribute__((naked, used, section(".init3")));
45+
void disableWatchdogAtBoot(void) {
46+
MCUSR = 0;
47+
wdt_disable();
48+
}
49+
#endif
50+
3051
// ------------ Class Methods ------------
3152
/**
3253
* static variable to hold singleton
3354
*/
34-
TankController *TankController::_instance = nullptr;
55+
TankController* TankController::_instance = nullptr;
3556

3657
/**
3758
* static function to return singleton
3859
*/
39-
TankController *TankController::instance(const char *remoteLogName, const char *pushingBoxID, int tzOffsetHrs) {
60+
TankController* TankController::instance(const char* remoteLogName, const char* pushingBoxID, int tzOffsetHrs) {
4061
if (!_instance) {
4162
serial(F("\r\n##############\r\nTankController %s"), TANK_CONTROLLER_VERSION);
4263
_instance = new TankController();
4364
SD_TC::instance();
4465
RemoteLogPusher::instance()->setRemoteLogName(remoteLogName);
4566
EEPROM_TC::instance();
4667
Keypad_TC::instance();
68+
char key = Keypad_TC::instance()->getKey();
69+
if (key == '1') {
70+
EEPROM_TC::instance()->setEEPROMAccessEnabled(false);
71+
serial(F("EEPROM access disabled"));
72+
};
4773
LiquidCrystal_TC::instance(TANK_CONTROLLER_VERSION);
4874
DataLogger::instance();
4975
DateTime_TC::rtc();
50-
Ethernet_TC::instance();
76+
Ethernet_TC::instance(key == NO_KEY ? (long)60000 : (long)1); // if a key is held, use a short timeout
5177
EthernetServer_TC::instance();
5278
ThermalProbe_TC::instance();
5379
ThermalControl::instance();
@@ -56,6 +82,9 @@ TankController *TankController::instance(const char *remoteLogName, const char *
5682
PID_TC::instance();
5783
pinMode(LED_BUILTIN, OUTPUT);
5884
_instance->state = new MainMenu();
85+
if (key == '1') {
86+
_instance->setNextState(new ResetEEPROM());
87+
}
5988
PushingBox::instance(pushingBoxID);
6089
GetTime::instance(tzOffsetHrs);
6190
serial(F("Free memory = %i"), _instance->freeMemory());
@@ -114,7 +143,7 @@ int TankController::freeMemory() {
114143
#if defined(ARDUINO_CI_COMPILATION_MOCKS)
115144
return 1024;
116145
#else
117-
extern char *__brkval;
146+
extern char* __brkval;
118147
int topOfStack;
119148

120149
return (int)((size_t)&topOfStack) - ((size_t)__brkval);
@@ -146,7 +175,7 @@ void TankController::handleUI() {
146175
// we already have a next state teed-up, do don't try to return to main menu
147176
} else if (millis() - lastKeypadTime > IDLE_TIMEOUT) {
148177
// time since last keypress exceeds the idle timeout, so return to main menu
149-
setNextState((UIState *)new MainMenu());
178+
setNextState((UIState*)new MainMenu());
150179
lastKeypadTime = 0; // so we don't do this until another keypress!
151180
}
152181
} else {
@@ -211,7 +240,7 @@ void TankController::serialEvent1() {
211240
/**
212241
* Set the next state
213242
*/
214-
void TankController::setNextState(UIState *newState, bool update) {
243+
void TankController::setNextState(UIState* newState, bool update) {
215244
assert(nextState == nullptr);
216245
nextState = newState;
217246
if (update) {
@@ -231,7 +260,7 @@ void TankController::setup() {
231260
* Public member function used to get the current state name.
232261
* This is primarily used by testing.
233262
*/
234-
const __FlashStringHelper *TankController::stateName() {
263+
const __FlashStringHelper* TankController::stateName() {
235264
return state->name();
236265
}
237266

@@ -262,13 +291,13 @@ void TankController::updateState() {
262291
/**
263292
* What is the current version?
264293
*/
265-
const char *TankController::version() {
294+
const char* TankController::version() {
266295
return TANK_CONTROLLER_VERSION;
267296
}
268297

269298
#if defined(__CYGWIN__)
270-
size_t strnlen(const char *s, size_t n) {
271-
void *found = memchr(s, '\0', n);
272-
return found ? (size_t)((char *)found - s) : n;
299+
size_t strnlen(const char* s, size_t n) {
300+
void* found = memchr(s, '\0', n);
301+
return found ? (size_t)((char*)found - s) : n;
273302
}
274303
#endif

src/UIState/ResetEEPROM.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* ResetEEPROM.cpp
3+
*/
4+
#include "ResetEEPROM.h"
5+
6+
#include <avr/wdt.h>
7+
8+
#include "Wait.h"
9+
#include "wrappers/EEPROM_TC.h"
10+
#include "wrappers/LiquidCrystal_TC.h"
11+
12+
void ResetEEPROM::handleKey(char key) {
13+
switch (key) {
14+
case 'A': // Save (erase EEPROM)
15+
EEPROM_TC::instance()->resetEEPROM();
16+
wdt_enable(WDTO_15MS);
17+
do {
18+
} while (true);
19+
break;
20+
case 'D': // Don't save (cancel)
21+
wdt_enable(WDTO_15MS);
22+
do {
23+
} while (true);
24+
break;
25+
default:
26+
break;
27+
};
28+
}
29+
30+
void ResetEEPROM::start() {
31+
LiquidCrystal_TC::instance()->writeLine(prompt(), 0);
32+
LiquidCrystal_TC::instance()->writeLine(F("D: Cancel"), 1);
33+
}

src/UIState/ResetEEPROM.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* ResetEEPROM.h
3+
*
4+
* Asks whether to reset EEPROM to factory default, which is useful if the data is corrupted and causing crashes. This
5+
* is accessed by holding the '1' key on the keypad during startup. The device is rebooted after the selection is made.
6+
*/
7+
#pragma once
8+
#include "UIState.h"
9+
10+
class ResetEEPROM : public UIState {
11+
public:
12+
void handleKey(char key) override;
13+
bool isInCalibration() override {
14+
return true;
15+
}
16+
void start() override;
17+
const __FlashStringHelper* name() override {
18+
return F("ResetEEPROM");
19+
}
20+
const __FlashStringHelper* prompt() override {
21+
return F("A: Erase EEPROM");
22+
};
23+
};

src/UIState/ResetPHCalibration.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* SetCalibrationClear.cpp
2+
* ResetPHCalibration.cpp
33
*/
44
#include "ResetPHCalibration.h"
55

src/UIState/ResetThermalCalibration.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* SetCalibrationClear.cpp
2+
* ResetThermalCalibration.cpp
33
*/
44
#include "ResetThermalCalibration.h"
55

src/Version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
#define VERSION "v25.4.1 +"
1+
#define VERSION "v25.4.1-18-g9ac+"

0 commit comments

Comments
 (0)