Hi All,
Acknowledgement - something wrong, not sure what:
I’ve noticed a number of threads talking about issues with UARTs losing data, and here’s another… I know that people insist this is fixed, so I’m not saying this is an mbed bug, but it is a bug I can’t track down to my code, my config or the hardware signals, so more brains would be appreciated!
Problem summary
I’m doing everything I can to get reliable communication with a custom board’s UART based on STM32L432, but it just won’t behave nicely!
I’m losing bytes in a minimal test sending from a USB UART adapter to the device and reporting back the received bytes and the number of bytes the device received (main firmware code below).
Baud rate matters
At 115200 baud, it loses 0, 1 or 2 bytes in a 37 byte test message (estimate 80% >1 byte loss).
At 19200 baud, it receives no data at all and the chip doesn’t send any serial pulses on the line TX - refusing to output at 19200 baud? may actually be receiving, but more likely some settings is invalid - this could be a separate bug??
At 9600 baud, it receives 100% of the data over 50+ tests.
Excluded USB dongle
To rule out the sender: I’ve swapped the USB dongle and get the same results. Sending from one USB dongle to the other works flawlessly at all baud.
mbed config settings of interest
I’m using:
- the ‘stdin’ port (which I believe is an LPUART, be great if someone knows a method to confirm?)
- platform.stdio-buffered-serial = 1
- drivers.uart-serial-rxbuf-size = 256
- target.console-uart = 1
- target.lpuart_clock_source = {USE_LPUART_CLK_PCLK1, USE_LPUART_CLK_LSE} (tried both settings, issues persist)
Are there other settings that I should investigate? Or is there something up with my code?
Checked on a scope
I have looked at the wave forms and they seem fine - nice square waves and the scope decodes the data fine. I’ve identified a “lost” byte and confirmed that their do not appear to be any anomalies.
Sample erroneous output:
started.
ABCdefghijkTotal: 11
lmnopqrstuvwTotal: 23
xyz123456780Total: 35
Total: 36
Active...
ATotal: 1
CdefghijklmnTotal: 13
opqrstuvwxyzTotal: 25
1234567890
Total: 36
NB: The missing byte in the first block is ‘9’, the missing byte in the second block is ‘B’
The missing ‘9’ is between other characters that are successfully captured, so this doesn’t seem possible it is my code.
Is that a reasonable conclusion?
Code
#include "mbed.h"
#include "events/EventQueue.h"
#define MAX_NUMBER_OF_EVENTS 20
#define USE_UART
EventQueue eq(MAX_NUMBER_OF_EVENTS * EVENTS_EVENT_SIZE);
#ifdef USE_UART
FileHandle
*serial_in,
*serial_out;
int total = 0;
void processChars()
{
char buffer[100];
bool report = false;
while(serial_in->readable())
{
//docs say this is non-blocking while 'readable()' returns true.
int read = serial_in->read(buffer,100); //not using the data, just counting characters read.
serial_out->write(buffer,read);
if(read > 0) //should always be true.
{
total += read;
report = true;
}
}
if(report)
printf("Total: %d\n",total);
}
#endif
void report()
{
printf("Active...\n");
#ifdef USE_UART
total=0;
#endif
}
void initSerialMonitor()
{
#ifdef USE_UART
//get access to stdin and attach a sigio handler.
serial_in = mbed::mbed_file_handle(0);
serial_out = mbed::mbed_file_handle(1);
BufferedSerial *bs = ((BufferedSerial *)serial_in); //serial_in is already configured to be a BufferedSerial object using: "platform.stdio-buffered-serial":1
eq.call_every(1ms,processChars);
#endif
eq.call_every(10s,report);
}
int main()
{
initSerialMonitor();
printf("started.\n");
eq.dispatch_forever();
printf("ended.\n");
return 0;
}
Thanks for reading!
Will.