UART seems to crash after receiving a few bytes

I’m using a DaisySeed. Here’s my code:

#include <string.h>
#include "daisy_seed.h"
#include <math.h>

using namespace daisy;

static DaisySeed hw;

void handleByte(uint8_t byte)
{
    if (byte == 48) // ascii '0'
    {
        // turn LED off
        hw.SetLed(false);
    }
    else if (byte == 49) // ascii '1'
    {
        // turn LED on
        hw.SetLed(true);
    }
}

int main(void)
{
    hw.Init();
    hw.StartLog(false);
    System::Delay(3000);
    hw.PrintLine("Starting Read-test");
    UartHandler         uart;
    UartHandler::Config config;
    config.baudrate = 9600 ;
    config.periph   = UartHandler::Config::Peripheral::USART_1;
    config.mode          = UartHandler::Config::Mode::RX;
    config.pin_config.rx = {DSY_GPIOB, 7};  // (USART_1 RX) Daisy pin 15
    config.pin_config.tx = {DSY_GPIOB, 6};  // (USART_1 TX) Daisy pin 14

    uart.Init(config);
    
    uint8_t mybuffer[2] = {0,0};
    
    while(1)
    {
        uart.BlockingReceive(mybuffer,2,1000);
        hw.PrintLine("%d", mybuffer[0]);

        handleByte(mybuffer[0]);

        System::Delay(1000);
    }
}

This code works just as expected, but only for 1 to 3 bytes received. I can reliably reset the DS, wait any amount of time, and send a ‘1’ to turn on the LED. Usually, I can then send a ‘0’ to turn it off. Sometimes, I can turn it back on with another ‘1’. But invariably, it stops working; BlockingReceive() just times out and mybuffer is unchanged.

Anybody got any ideas?

In my experience, the Blocking UART read is very delicate, I think it’s due to e.g. getting an overrun error. Try removing the System.Delay(1000), I’ve had better luck when I poll it very quickly. Also, it may work better if you just try to read one character at a time, and check the return code. I ended up using a timeout of 0 and then just check the return code to see if it actually got anything:

	uint8_t got_it=0;
	UartHandler::Result rx_stat=dbg_uart.BlockingReceive(&got_it, 1, 0);
	if (rx_stat !=UartHandler::Result::OK)
              ...
// didn't get a character

Wow, thank you for the tip – I’ve just implemented and it’s working perfectly now! Kudos to you sir!

1 Like