Target
NUCLEO_L476RG
Expected behavior
being able to use : Serial lpuart_port0(PC_1, PC_0);
Actual behavior
using Serial lpuart_port0(PC_1, PC_0);
compiles, but at runtime we receive the mbed_error Cannot initialize UART
Steps to reproduce
main.cpp:
#include "mbed.h"
int main() {
Serial lpuart_port0(PC_1, PC_0, 115200);
while(1) {
wait(1.0); // 1 sec
lpuart_port0.printf("something\n");
}
}
cc @jeromecoutant @bcostm @LMESTM
The problem is that the LPUART baudrate can only be in the range of
[sys_clk / 4096 ... sys_clk / 3]
STM32L476RG is initialized at 80MHz, and the default baudrate is 9600.
It cannot work.
Lowering the system clock would restrain the clock for many IPs of the microcontroler. We are not in favour of this fix.
Question for armteam is it acceptable to initialise some instances of UART with a different baudrate, as long as they are not the stdio uart ?
By the way, we cannot use the function Serial lpuart_port0(PC_1, PC_0,115200);
because the SerialBase function first calls serial_init (with default baud = 9600, which leads to mbed_error in our case), then calls serial_baud
SerialBase::SerialBase(PinName tx, PinName rx, int baud) :
...
serial_init(&_serial, tx, rx);
serial_baud(&_serial, _baud);
...
I think there should be a serial_init_with_baud(&_serial, tx, rx, baud) function (the same kind of function that is used for can_init_freq)
Kind regards
I think there should be a serial_init_with_baud(&_serial, tx, rx, baud) function (the same kind of function that is used for can_init_freq)
Either that or init should not touch baudrate, and upper layer is expected to set format via another API (thus Serial is doing a seq init, format).
@bulislaw @c1728p9 note this
Question for armteam is it acceptable to initialise some instances of UART with a different baudrate, as long as they are not the stdio uart ?
By the way, we cannot use the function Serial lpuart_port0(PC_1, PC_0,115200);
because the SerialBase function first calls serial_init (with default baud = 9600, which leads to mbed_error in our case), then calls serial_baud
OK, so 9600 cannot be set for some serial modules (in this case lpuart) ? Thus using a regulart Serial ctor ends up with an error. Apart from that this should be cleaned up (init, format sequence), that serial module is not compatible with the current serial_init assumptions.
Question for armteam is it acceptable to initialise some instances of UART with a different baudrate, as long as they are not the stdio uart ?
Changing the default baud for one target may silently break some applications. If the hardware can't work at 9600 then an error/trap should occur so the user knows this uart can't be used at 9600.
Hello, @c1728p9
If the hardware can't work at 9600 then an error/trap should occur so the user knows this uart can't be used at 9600.
The error/trap is already present (maybe it could be more explicit). The problem is that the user cannot program any other baudrate, because it first initializes the 9600 baud rate (ERRROR), then change the baud rate, instead of initializing a serial at a specific baud rate.
My suggestion would be to implement a serial_init(obj, pin_tx, pin_rx, baud) function that would avoid hard-coding the baud at 9600
I have already done such an implementation for can_init in #4165
Hi @adustm, that makes sense. I just misinterpreted your question.
Question for armteam is it acceptable to initialise some instances of UART with a different baudrate, as long as they are not the stdio uart ?
Since serial_init provides no requirements on default baudrate, I think this is fair to be implementation defined. I thought you were proposing chaining a user facing API, which this doesn't. SerialBase sets the baudrate explicitly, so the default constructor of the serial classes still sets the baudrate consistently for all devices.
I closed this on accident so I re-opened it.