GrumpyOldPizza / ArduinoCore-stm32l0

Arduino Core for STM32L0
125 stars 67 forks source link

Uart RX 2nd char is lost after wakeup from stop at 115200 Bd #191

Open gitMichael opened 3 years ago

gitMichael commented 3 years ago

if you send terminal string e.g. '01234' echo is '0234' with testcode below on a NUCLEO-L073RZ. Switching of DMA in variant.cpp doesn't change anything. With 230400 Bd echo is '034', but at 56700 Bd and lower everything is OK ('01234'). Where start searching?

#include "STM32L0.h"
#include "stm32l0_uart.h" // workaround to include serial config 'SERIAL_8N1' and 'uart.h'

void setup()
{
    pinMode(PIN_LED, OUTPUT);
    pinMode(PIN_BUTTON, INPUT_PULLUP);
    Serial.begin(115200, SERIAL_8N1 | SERIAL_WAKEUP); // Serial on STLINK programming port
    Serial.enableWakeup(); // serial wakes up system from sleep if Uart RX event

    delay(500);
    Serial.println("Start");
}

void loop()
{
    delay(500);
    digitalWrite(PIN_LED,0);
    STM32L0.deepsleep();
}

void serialEvent()
{
    while (Serial.available()) {
        uint8_t inChar = (uint8_t)Serial.read();
        Serial.write(inChar);    // echo RX
    }
    digitalWrite(PIN_LED,1);
}
GrumpyOldPizza commented 3 years ago

I would think the core issue is the time between when STM32L0 internally comes back from STOP mode and when the uart driver then is able to service the peripheral. The first character will be latched in the "receive data register", but it looks like the 2nd character and perhaps 3rd one will be lost.

The relevant code is in system/STM32L0xx/Source/stm32l0_system, stm32l0_system_sleep().

One possible fix for 115200 could be to use WUS == 10 for the USART instead of WUS == 11 in stm32l0_uart.c, stm32l0_uart_configure().

I would think that realistically this UART feature will work only up to 38400. If the baudrate gets too high you need to keep HSI16 alive in STOP, which adds an extra 150uA ...