Skip to content

Commit 99d89dc

Browse files
committed
Adding resetOnZeroDeviceCount
1 parent fc61e4b commit 99d89dc

File tree

9 files changed

+173
-23
lines changed

9 files changed

+173
-23
lines changed

Firmware/OpenLog_Artemis/OpenLog_Artemis.ino

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,13 @@ void setup() {
379379
beginQwiicDevices(); //Begin() each device in the node list
380380
loadDeviceSettingsFromFile(); //Load config settings into node list
381381
configureQwiicDevices(); //Apply config settings to each device in the node list
382-
printOnlineDevice();
382+
int deviceCount = printOnlineDevice();
383+
if ((deviceCount == 0) && (settings.resetOnZeroDeviceCount == true))
384+
{
385+
SerialPrintln(F("*** Zero Qwiic Devices Found! Resetting... ***"));
386+
SerialFlush();
387+
resetArtemis(); //Thank you and goodnight...
388+
}
383389
}
384390
else
385391
SerialPrintln(F("No Qwiic devices detected"));
@@ -766,7 +772,7 @@ void beginSD()
766772

767773
if (sd.begin(PIN_MICROSD_CHIP_SELECT, SD_SCK_MHZ(24)) == false) //Standard SdFat
768774
{
769-
printDebug("SD init failed (first attempt). Trying again...\r\n");
775+
printDebug(F("SD init failed (first attempt). Trying again...\r\n"));
770776
for (int i = 0; i < 250; i++) //Give SD more time to power up, then try again
771777
{
772778
checkBattery();
@@ -810,7 +816,7 @@ void enableCIPOpullUp()
810816
cipoPinCfg.ePullup = AM_HAL_GPIO_PIN_PULLUP_1_5K;
811817
padMode(MISO, cipoPinCfg, &retval);
812818
if (retval != AP3_OK)
813-
printDebug("Setting CIPO padMode failed!");
819+
printDebug(F("Setting CIPO padMode failed!"));
814820
}
815821

816822
void beginIMU()

Firmware/OpenLog_Artemis/autoDetect.ino

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -401,9 +401,10 @@ bool beginQwiicDevices()
401401
// Delay before starting the second and subsequent SCD30s to try and stagger the measurements and the peak current draw
402402
if (numberOfSCD30s >= 2)
403403
{
404-
printDebug("beginQwiicDevices: found more than one SCD30. Delaying for 375ms to stagger the peak current draw...\r\n");
404+
printDebug(F("beginQwiicDevices: found more than one SCD30. Delaying for 375ms to stagger the peak current draw...\r\n"));
405405
delay(375);
406406
}
407+
if(settings.printDebugMessages == true) tempDevice->enableDebugging(); // Enable debug messages if required
407408
temp->online = tempDevice->begin(qwiic); //Wire port
408409
}
409410
break;
@@ -475,11 +476,11 @@ bool beginQwiicDevices()
475476

476477
if (temp->online == true)
477478
{
478-
printDebug("beginQwiicDevices: device is online\r\n");
479+
printDebug(F("beginQwiicDevices: device is online\r\n"));
479480
}
480481
else
481482
{
482-
printDebug("beginQwiicDevices: device is **NOT** online\r\n");
483+
printDebug(F("beginQwiicDevices: device is **NOT** online\r\n"));
483484
everythingStarted = false;
484485
}
485486

@@ -490,7 +491,7 @@ bool beginQwiicDevices()
490491
}
491492

492493
//Pretty print all the online devices
493-
void printOnlineDevice()
494+
int printOnlineDevice()
494495
{
495496
int deviceCount = 0;
496497

@@ -500,7 +501,7 @@ void printOnlineDevice()
500501
if (temp == NULL)
501502
{
502503
printDebug(F("printOnlineDevice: No devices detected\r\n"));
503-
return;
504+
return (0);
504505
}
505506

506507
while (temp != NULL)
@@ -528,6 +529,8 @@ void printOnlineDevice()
528529
{
529530
SerialPrintf2("Device count: %d\r\n", deviceCount);
530531
}
532+
533+
return (deviceCount);
531534
}
532535

533536
//Given the node number, apply the node's configuration settings to the device
@@ -1135,7 +1138,7 @@ deviceType_e testDevice(uint8_t i2cAddress, uint8_t muxAddress, uint8_t portNumb
11351138

11361139
//Confidence: High - begin now checks FW Ver CRC
11371140
SCD30 sensor1;
1138-
//sensor1.enableDebugging();
1141+
if(settings.printDebugMessages == true) sensor1.enableDebugging(); // Enable debug messages if required
11391142
// Set measBegin to false. beginQwiicDevices will call begin with measBegin set true.
11401143
if (sensor1.begin(qwiic, true, false) == true) //Wire port, autoCalibrate, measBegin
11411144
return (DEVICE_CO2_SCD30);

Firmware/OpenLog_Artemis/lowerPower.ino

Lines changed: 117 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,77 @@ void powerDown()
153153
}
154154
}
155155

156+
//Reset the Artemis
157+
void resetArtemis(void)
158+
{
159+
//Save files before resetting
160+
if (online.dataLogging == true)
161+
{
162+
sensorDataFile.sync();
163+
updateDataFileAccess(&sensorDataFile); // Update the file access time & date
164+
sensorDataFile.close(); //No need to close files. https://forum.arduino.cc/index.php?topic=149504.msg1125098#msg1125098
165+
}
166+
if (online.serialLogging == true)
167+
{
168+
serialDataFile.sync();
169+
updateDataFileAccess(&serialDataFile); // Update the file access time & date
170+
serialDataFile.close();
171+
}
172+
173+
delay(sdPowerDownDelay); // Give the SD card time to finish writing ***** THIS IS CRITICAL *****
174+
175+
SerialFlush(); //Finish any prints
176+
177+
// Wire.end(); //Power down I2C
178+
qwiic.end(); //Power down I2C
179+
180+
SPI.end(); //Power down SPI
181+
182+
power_adc_disable(); //Power down ADC. It it started by default before setup().
183+
184+
Serial.end(); //Power down UART
185+
SerialLog.end();
186+
187+
//Force the peripherals off
188+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM0);
189+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM1);
190+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM2);
191+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM3);
192+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM4);
193+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM5);
194+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_ADC);
195+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_UART0);
196+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_UART1);
197+
198+
//Disable pads
199+
for (int x = 0; x < 50; x++)
200+
{
201+
if ((x != ap3_gpio_pin2pad(PIN_POWER_LOSS)) &&
202+
//(x != ap3_gpio_pin2pad(PIN_LOGIC_DEBUG)) &&
203+
(x != ap3_gpio_pin2pad(PIN_MICROSD_POWER)) &&
204+
(x != ap3_gpio_pin2pad(PIN_QWIIC_POWER)) &&
205+
(x != ap3_gpio_pin2pad(PIN_IMU_POWER)))
206+
{
207+
am_hal_gpio_pinconfig(x, g_AM_HAL_GPIO_DISABLE);
208+
}
209+
}
210+
211+
//We can't leave these power control pins floating
212+
imuPowerOff();
213+
microSDPowerOff();
214+
215+
//Disable power for the Qwiic bus
216+
qwiicPowerOff();
217+
218+
//Disable the power LED
219+
powerLEDOff();
220+
221+
//Enable the Watchdog so it can reset the Artemis
222+
startWatchdog();
223+
while (1) // That's all folks! Artemis will reset in 1.25 seconds
224+
;
225+
}
226+
156227
//Power everything down and wait for interrupt wakeup
157228
void goToSleep(uint32_t sysTicksToSleep)
158229
{
@@ -360,11 +431,11 @@ void wakeFromSleep()
360431
SerialLog.begin(settings.serialTerminalBaudRate); // Start the serial port
361432
}
362433

363-
printDebug("wakeFromSleep: I'm awake!\r\n");
434+
printDebug(F("wakeFromSleep: I'm awake!\r\n"));
364435
printDebug("wakeFromSleep: adcError is " + (String)adcError + ".");
365436
if (adcError > 0)
366-
printDebug(" This indicates an error was returned by ap3_adc_setup or one of the calls to ap3_set_pin_to_analog.");
367-
printDebug("\r\n");
437+
printDebug(F(" This indicates an error was returned by ap3_adc_setup or one of the calls to ap3_set_pin_to_analog."));
438+
printDebug(F("\r\n"));
368439

369440
beginQwiic(); //Power up Qwiic bus as early as possible
370441

@@ -560,3 +631,46 @@ int calculateDayOfYear(int day, int month, int year)
560631
doy += day;
561632
return doy;
562633
}
634+
635+
//WatchDog Timer code by Adam Garbo:
636+
//https://forum.sparkfun.com/viewtopic.php?f=169&t=52431&p=213296#p213296
637+
638+
// Watchdog timer configuration structure.
639+
am_hal_wdt_config_t g_sWatchdogConfig = {
640+
641+
// Configuration values for generated watchdog timer event.
642+
.ui32Config = AM_HAL_WDT_LFRC_CLK_16HZ | AM_HAL_WDT_ENABLE_RESET | AM_HAL_WDT_ENABLE_INTERRUPT,
643+
644+
// Number of watchdog timer ticks allowed before a watchdog interrupt event is generated.
645+
.ui16InterruptCount = 16, // Set WDT interrupt timeout for 1 second.
646+
647+
// Number of watchdog timer ticks allowed before the watchdog will issue a system reset.
648+
.ui16ResetCount = 20 // Set WDT reset timeout for 1.25 seconds.
649+
};
650+
651+
void startWatchdog()
652+
{
653+
// LFRC must be turned on for this example as the watchdog only runs off of the LFRC.
654+
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_LFRC_START, 0);
655+
656+
// Configure the watchdog.
657+
am_hal_wdt_init(&g_sWatchdogConfig);
658+
659+
// Enable the interrupt for the watchdog in the NVIC.
660+
NVIC_EnableIRQ(WDT_IRQn);
661+
//NVIC_SetPriority(WDT_IRQn, 0); // Set the interrupt priority to 0 = highest (255 = lowest)
662+
//am_hal_interrupt_master_enable(); // ap3_initialization.cpp does this - no need to do it here
663+
664+
// Enable the watchdog.
665+
am_hal_wdt_start();
666+
}
667+
668+
// Interrupt handler for the watchdog.
669+
extern "C++" void am_watchdog_isr(void)
670+
{
671+
// Clear the watchdog interrupt.
672+
am_hal_wdt_int_clear();
673+
674+
// DON'T Restart the watchdog.
675+
//am_hal_wdt_restart(); // "Pet" the dog.
676+
}

Firmware/OpenLog_Artemis/menuAttachedDevices.ino

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
//Returns true if devices detected > 0
3131
bool detectQwiicDevices()
3232
{
33-
printDebug("detectQwiicDevices started\r\n");
33+
printDebug(F("detectQwiicDevices started\r\n"));
3434
bool somethingDetected = false;
3535

3636
qwiic.setClock(100000); //During detection, go slow
@@ -154,7 +154,7 @@ bool detectQwiicDevices()
154154
QWIICMUX *myMux = (QWIICMUX *)muxNode->classPtr;
155155

156156
printDebug("detectQwiicDevices: scanning the ports of multiplexer " + (String)muxNumber);
157-
printDebug("\r\n");
157+
printDebug(F("\r\n"));
158158

159159
for (int portNumber = 0 ; portNumber < 8 ; portNumber++) //Assumes we are using a mux with 8 ports max
160160
{
@@ -163,7 +163,7 @@ bool detectQwiicDevices()
163163

164164
printDebug("detectQwiicDevices: scanning port number " + (String)portNumber);
165165
printDebug(" on multiplexer " + (String)muxNumber);
166-
printDebug("\r\n");
166+
printDebug(F("\r\n"));
167167

168168
//Scan this new bus for new addresses
169169
for (uint8_t address = 1 ; address < 127 ; address++)

Firmware/OpenLog_Artemis/menuDebug.ino

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ void menuDebug()
99
if (settings.printDebugMessages == true) SerialPrintln(F("Enabled"));
1010
else SerialPrintln(F("Disabled"));
1111

12+
SerialPrint(F("2) Reset on Zero Device Count: "));
13+
if (settings.resetOnZeroDeviceCount == true) SerialPrintln(F("Enabled"));
14+
else SerialPrintln(F("Disabled"));
15+
1216
SerialPrintln(F("x) Exit"));
1317

1418
byte incoming = getByteChoice(menuTimeout); //Timeout after x seconds
@@ -17,6 +21,27 @@ void menuDebug()
1721
{
1822
settings.printDebugMessages ^= 1;
1923
}
24+
else if (incoming == '2')
25+
{
26+
if (settings.resetOnZeroDeviceCount == false)
27+
{
28+
SerialPrintln(F(""));
29+
SerialPrintln(F("Enabling resetOnZeroDeviceCount will cause the OLA to completely reset if no devices are found on the Qwiic bus."));
30+
SerialPrintln(F("Do not enable this option if you are only logging IMU or Serial data."));
31+
SerialPrintln(F("Are you sure? Press 'y' to confirm: "));
32+
byte bContinue = getByteChoice(menuTimeout);
33+
if (bContinue == 'y')
34+
{
35+
settings.resetOnZeroDeviceCount ^= 1;
36+
}
37+
else
38+
SerialPrintln(F("\"resetOnZeroDeviceCount\" aborted"));
39+
}
40+
else
41+
{
42+
settings.resetOnZeroDeviceCount ^= 1;
43+
}
44+
}
2045
else if (incoming == 'x')
2146
break;
2247
else if (incoming == STATUS_GETBYTE_TIMEOUT)

Firmware/OpenLog_Artemis/menuMain.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ void menuMain()
9797
}
9898
else if (incoming == 'r')
9999
{
100-
SerialPrintln(F("\r\nResetting to factory defaults. Press 'y' to confirm:"));
100+
SerialPrintln(F("\r\nResetting to factory defaults. Press 'y' to confirm: "));
101101
byte bContinue = getByteChoice(menuTimeout);
102102
if (bContinue == 'y')
103103
{

Firmware/OpenLog_Artemis/menuTerminal.ino

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,11 +288,10 @@ void menuLogRate()
288288
if (settings.useTxRxPinsForTerminal == false)
289289
{
290290
SerialPrintln(F(""));
291-
SerialPrintln(F("WARNING:"));
292291
SerialPrintln(F("\"Use TX and RX pins for terminal\" can only be disabled by \"Reset all settings to default\"."));
293292
SerialPrintln(F("Analog logging on TX/A12 and RX/A13 will be disabled."));
294293
SerialPrintln(F("Serial logging will be disabled."));
295-
SerialPrintln(F("Are you sure? Press 'y' to confirm:"));
294+
SerialPrintln(F("Are you sure? Press 'y' to confirm: "));
296295
byte bContinue = getByteChoice(menuTimeout);
297296
if (bContinue == 'y')
298297
{

Firmware/OpenLog_Artemis/nvm.ino

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,9 @@ void recordSystemSettingsToFile()
9898

9999
settingsFile.println("usBetweenReadings=" + (String)tempTime);
100100

101-
//printDebug("Saving usBetweenReadings to SD card: ");
101+
//printDebug(F("Saving usBetweenReadings to SD card: "));
102102
//printDebug((String)tempTime);
103-
//printDebug("\r\n");
103+
//printDebug(F("\r\n"));
104104

105105
settingsFile.println("logMaxRate=" + (String)settings.logMaxRate);
106106
settingsFile.println("enableRTC=" + (String)settings.enableRTC);
@@ -163,6 +163,7 @@ void recordSystemSettingsToFile()
163163
settingsFile.println("slowLoggingIntervalSeconds=" + (String)settings.slowLoggingIntervalSeconds);
164164
settingsFile.println("slowLoggingStartMOD=" + (String)settings.slowLoggingStartMOD);
165165
settingsFile.println("slowLoggingStopMOD=" + (String)settings.slowLoggingStopMOD);
166+
settingsFile.println("resetOnZeroDeviceCount=" + (String)settings.resetOnZeroDeviceCount);
166167
updateDataFileAccess(&settingsFile); // Update the file access time & date
167168
settingsFile.close();
168169
}
@@ -295,9 +296,9 @@ bool parseLine(char* str) {
295296
else if (strcmp(settingName, "usBetweenReadings") == 0)
296297
{
297298
settings.usBetweenReadings = d;
298-
//printDebug("Read usBetweenReadings from SD card: ");
299+
//printDebug(F("Read usBetweenReadings from SD card: "));
299300
//printDebug(String(d));
300-
//printDebug("\r\n");
301+
//printDebug(F("\r\n"));
301302
}
302303
else if (strcmp(settingName, "logMaxRate") == 0)
303304
settings.logMaxRate = d;
@@ -421,6 +422,8 @@ bool parseLine(char* str) {
421422
settings.slowLoggingStartMOD = d;
422423
else if (strcmp(settingName, "slowLoggingStopMOD") == 0)
423424
settings.slowLoggingStopMOD = d;
425+
else if (strcmp(settingName, "resetOnZeroDeviceCount") == 0)
426+
settings.resetOnZeroDeviceCount = d;
424427
else
425428
{
426429
SerialPrintf2("Unknown setting %s. Ignoring...\r\n", settingName);

Firmware/OpenLog_Artemis/settings.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ struct struct_settings {
359359
int slowLoggingIntervalSeconds = 300; // Slow logging interval in seconds. Default to 5 mins
360360
int slowLoggingStartMOD = 1260; // Start slow logging at this many Minutes Of Day. Default to 21:00
361361
int slowLoggingStopMOD = 420; // Stop slow logging at this many Minutes Of Day. Default to 07:00
362-
362+
bool resetOnZeroDeviceCount = false; // A work-around for I2C bus crashes. Enable this via the debug menu.
363363
} settings;
364364

365365
//These are the devices on board OpenLog that may be on or offline.

0 commit comments

Comments
 (0)