Problem with serial after waking up from stop/deepsleep

Post here all questions related to LibMaple core if you can't find a relevant section!
Post Reply
dolfandringa
Posts: 20
Joined: Wed Jun 03, 2020 3:47 am

Problem with serial after waking up from stop/deepsleep

Post by dolfandringa »

I am using the libmaple core with my STM32F103C8 MCU. I have quite a bit of code written for it already, so I'd prefer not to switch to the arduino core, even though it has the LowPower library that's not available here.
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();
    }
}
stevestrong
Posts: 502
Joined: Fri Dec 27, 2019 4:53 pm
Answers: 8
Location: Munich, Germany
Contact:

Re: Problem with serial after waking up from stop/deepsleep

Post by stevestrong »

You can try

Code: Select all

Serial.end(); // before going to sleep
and

Code: Select all

Serial.begin(); // at wake up
dolfandringa
Posts: 20
Joined: Wed Jun 03, 2020 3:47 am

Re: Problem with serial after waking up from stop/deepsleep

Post by dolfandringa »

Like I said, and those lines are also commented in the code, I already tried that an no luck.
stevestrong
Posts: 502
Joined: Fri Dec 27, 2019 4:53 pm
Answers: 8
Location: Munich, Germany
Contact:

Re: Problem with serial after waking up from stop/deepsleep

Post by stevestrong »

Before writing something to the USB serial you have to wait till it is activated.

Code: Select all

Serial.begin(); // no need for baudrate, because USB serial does not need it
while (!Serial);
delay(10); // needed by Arduino serial port monitor
Btw, this has not been yet tested by anyone else, so do not expect for a prompt solution, we have to figure out a solution together.

UPDATE
It eventually may be necessary to insert these code lines to signalize the host a change on the USB lines:
https://github.com/rogerclarkmelbourne/ ... #L102-L107
In this case, however, the Serial COM port will be re-enumerated so you would need to close the old port monitor window and open a new one.
dolfandringa
Posts: 20
Joined: Wed Jun 03, 2020 3:47 am

Re: Problem with serial after waking up from stop/deepsleep

Post by dolfandringa »

Sorry, I didn't say in my original question that I am not using USB serial but rx1 with a FTDI usb serial converter.
dolfandringa
Posts: 20
Joined: Wed Jun 03, 2020 3:47 am

Re: Problem with serial after waking up from stop/deepsleep

Post by dolfandringa »

Switching to the official stm32duino Arduino Core doesn't actually solve this issue. There seems to be something deeper in the hardware that either I don't understand, or is a bug in both cores or I don't know what: viewtopic.php?f=62&t=514
stevestrong
Posts: 502
Joined: Fri Dec 27, 2019 4:53 pm
Answers: 8
Location: Munich, Germany
Contact:

Re: Problem with serial after waking up from stop/deepsleep

Post by stevestrong »

dolfandringa wrote: Fri Jun 19, 2020 1:34 am Sorry, I didn't say in my original question that I am not using USB serial but rx1 with a FTDI usb serial converter.
Right, but in your code you use Serial which is USB serial.
For USART1 you have to use Serial1.
Post Reply

Return to “General discussion”