But using that libary and the official ST RM0008 reference manual, I have mostly been able to figure out how the deepsleep (called stop mode in ST docs) works, and allows my code to resume where it left off. But I am running into an issue where the Serial stops printing after waking up from deepsleep/stop mode. I can see using a debugger that the wakeup function is getting called, just nothing appears on the serial console. I checked with minicom when turning HEX mode on, and it appears the serial port actually is sending data, because NULL bytes are displayed at wakeup time. And the LED also resumes blinking, so I know the device woke up again.
I am guessing the sleep somehow messed up the serial console. But I don't know how to get it back. I added a Serial.flush() already at the beginning of the sleep function, and also even disabled and enabled the USART to see if I can reinitialize it or something. But nothing works.
Any thoughts?
Code: Select all
#include <Arduino.h>
#include <RTClock.h>
#include <libmaple/pwr.h> // PWR_BASE ref
#include <libmaple/scb.h> // SCB_BASE ref
#include <libmaple/usart.h> //USART functions
#define SLEEP_TIME 10
#define LED_PIN PC13
uint32 tt;
uint16_t cnt = 0;
static bool nappy_time = false;
static bool woken_up = false;
// This function is called in the attachSecondsInterrpt
void blink ()
{
digitalWrite(LED_PIN,!digitalRead(LED_PIN));
}
void set_nappy_time() {
nappy_time = true;
}
void nothing() {
SCB_BASE->SCR &= ~SCB_SCR_SLEEPDEEP;
SCB_BASE->SCR &= ~SCB_SCR_SLEEPONEXIT;
woken_up = true;
}
void wakeup() {
///usart_foreach(usart_enable);
//adc_foreach(adc_enable);
PWR_BASE->CR |= PWR_CR_CWUF; // clear the wakeup flag
woken_up = false;
//Serial.begin(115200);
Serial.print("good morning ");
Serial.println(cnt);
}
void deepsleep(uint32_t sleep_time) {
uint16_t now = rtc_get_count();
Serial.print("Sleeping at ");
Serial.print(now);
Serial.print(" until ");
Serial.println(now+sleep_time);
Serial.flush();
//Serial.end();
rtc_detach_interrupt(RTC_ALARM_SPECIFIC_INTERRUPT);
rtc_detach_interrupt(RTC_ALARM_GLOBAL_INTERRUPT);
rtc_detach_interrupt(RTC_SECONDS_INTERRUPT);
//adc_disable_all();
//usart_disable_all();
//Enable ABP1 bus, on which the RTC clock registers (and a ton of other stuff) are located
RCC_BASE->APB1ENR |= RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN;
//Disable external wakeup pin
PWR_BASE->CSR &= ~PWR_CSR_EWUP;
//Enable external wakeup pin just in case we want to try it
//PWR_BASE->CSR |= PWR_CSR_EWUP;
//clear Wakeup flag
PWR_BASE->CR |= PWR_CR_CWUF;
//Clear PPDS bit.
PWR_BASE->CR &= ~PWR_CR_PDDS;
//Low power regulator or normal regulator. Bit set=low power regulator.
PWR_BASE->CR |= PWR_CR_LPDS;
SCB_BASE->SCR |= SCB_SCR_SLEEPONEXIT;
SCB_BASE->SCR |= SCB_SCR_SLEEPDEEP;
rtc_set_alarm(now + sleep_time);
//rtc_enable_irq(RTC_ALARM_SPECIFIC_INTERRUPT);
//nvic_irq_enable(NVIC_RTCALARM);
rtc_attach_interrupt(RTC_ALARM_SPECIFIC_INTERRUPT, nothing);
asm("WFE");
}
void setup()
{
rtc_init(RTCSEL_LSI);
rtc_set_prescaler_load(0x7fff);
usart_foreach(usart_enable);
Serial.begin(115200);
Serial.println("Setup");
Serial.flush();
pinMode(LED_PIN, OUTPUT);
rtc_set_count(0);
rtc_set_alarm(rtc_get_count() + SLEEP_TIME);
rtc_attach_interrupt(RTC_ALARM_SPECIFIC_INTERRUPT, set_nappy_time);
}
void loop()
{
Serial.flush();
if(nappy_time) {
nappy_time = false;
deepsleep(sleep_time);
}
if(woken_up) {
// detect wakeup
wakeup();
}
if (rtc_get_count()!=tt)
{
cnt++;
tt = rtc_get_count();
blink();
}
}