E.HP.S wrote: ↑Mon Oct 23, 2023 6:46 am
paulvha wrote: ↑Fri Oct 20, 2023 8:57 am
I think originally this sketch was run on V 1.x.x, which has the stack starting at address 0x0 growing up.
In V2.x.x the stack is at the TOP of memory growing down, thus turning off any RAM memory above 64K will cause the stack information to be lost and thus a hardfault on trying to wakeup.
You said a hardfault, right? Wouldn't the built-in LED start doing that S.O.S style flashing pattern if that was the case? I don't see that happening here, only the other LED going from illuminated to dark after a second or two. I tried cutting out the parts that mess with memory and so far its the same result.
I ran a modified version of Example6_LowPower_Alarm to use a GPIO interrupt instead of the RTC interrupt, and I got mostly the same results, sans the LED shutting down.
Code: Select all
#include "RTC.h"
#define BUTTON_CTRL 14
#define DEBOUNCETIME 1000 // number of milli seconds needed between pushes
unsigned long debounce; // Stores the last millis()
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
pinMode(BUTTON_CTRL, INPUT_PULLUP);
Serial.begin(115200);
Serial.println("SparkFun RTC Low-power Alarm Example");
// // Easily set RTC using the system __DATE__ and __TIME__ macros from compiler
//RTC.setToCompilerTime();
// Manually set RTC date and time
rtc.setTime(0, 50, 59, 12, 3, 6, 20); // 12:59:50.000, June 3rd, 2020 (hund, ss, mm, hh, dd, mm, yy)
// Set the RTC's alarm
//rtc.setAlarm(0, 0, 0, 13, 3, 6); // 13:00:00.000, June 3rd (hund, ss, mm, hh, dd, mm). Note: No year alarm register
// Set the RTC alarm mode
/*
0: Alarm interrupt disabled
1: Alarm match every year (hundredths, seconds, minutes, hour, day, month)
2: Alarm match every month (hundredths, seconds, minutes, hours, day)
3: Alarm match every week (hundredths, seconds, minutes, hours, weekday)
4: Alarm match every day (hundredths, seconds, minute, hours)
5: Alarm match every hour (hundredths, seconds, minutes)
6: Alarm match every minute (hundredths, seconds)
7: Alarm match every second (hundredths)
*/
//rtc.setAlarmMode(6); // Set the RTC alarm to match on minutes rollover
//rtc.attachInterrupt(); // Attach RTC alarm interrupt
debounce = millis();
attachInterrupt(digitalPinToInterrupt(BUTTON_CTRL), goToSleep, FALLING);
}
void loop()
{
// Print date and time of RTC alarm trigger
//Serial.print("Alarm interrupt: "); printDateTime();
delay(1000);
// Enter deep sleep and await RTC alarm interrupt
//goToSleep();
}
// Print the RTC's current date and time
void printDateTime()
{
rtc.getTime();
Serial.printf("20%02d-%02d-%02d %02d:%02d:%02d.%03d\n",
rtc.year, rtc.month, rtc.dayOfMonth,
rtc.hour, rtc.minute, rtc.seconds, rtc.hundredths);
Serial.println();
}
// Power down gracefully
void goToSleep()
{
digitalWrite(LED_BUILTIN, HIGH);
if (millis() - debounce < DEBOUNCETIME )
{
debounce = millis();
return;
}
detachInterrupt(digitalPinToInterrupt(BUTTON_CTRL));
attachInterrupt(digitalPinToInterrupt(BUTTON_CTRL), wakeUp, FALLING);
// Disable UART
Serial.end();
// Disable ADC
powerControlADC(false);
// Force the peripherals off
//am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM0);
//am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM1);
//am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM2);
//am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM3);
//am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM4);
//am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM5);
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_ADC);
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_UART0);
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_UART1);
// Disable all pads (except UART TX/RX)
for (int x = 0 ; x < 50 ; x++)
{
if(x != LED_BUILTIN && x != BUTTON_CTRL)
{
am_hal_gpio_pinconfig(x, g_AM_HAL_GPIO_DISABLE);
}
}
//Power down CACHE, flashand SRAM
am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_ALL); // Turn off CACHE and flash
am_hal_pwrctrl_memory_deepsleep_retain(AM_HAL_PWRCTRL_MEM_SRAM_384K); // Retain all SRAM (0.6 uA)
// Keep the 32kHz clock running for RTC
am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE);
am_hal_stimer_config(AM_HAL_STIMER_XTAL_32KHZ);
am_hal_interrupt_master_enable();
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP); // Sleep forever
// And we're back!
wakeUp();
}
// Power up gracefully
void wakeUp()
{
// Go back to using the main clock
am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE);
am_hal_stimer_config(AM_HAL_STIMER_HFRC_3MHZ);
// Power up SRAM, turn on entire Flash
am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_MAX);
// Go back to using the main clock
am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE);
am_hal_stimer_config(AM_HAL_STIMER_HFRC_3MHZ);
// Renable UART0 pins
am_hal_gpio_pinconfig(48, g_AM_BSP_GPIO_COM_UART_TX);
am_hal_gpio_pinconfig(49, g_AM_BSP_GPIO_COM_UART_RX);
// Renable power to UART0
am_hal_pwrctrl_periph_enable(AM_HAL_PWRCTRL_PERIPH_UART0);
// Enable ADC
initializeADC();
// Enable Serial
Serial.begin(115200);
digitalWrite(LED_BUILTIN, LOW);
debounce = millis();
}
At this point, I'm starting to question whether or not it's possible to have a GPIO interrupt wake the Artemis up after it goes to sleep. I know the RTC and Watchdog both work, but I need to be able to wake the device up outside of a regimented schedule