The used formula results in a fractional divisor value of 64 which gets truncated once it's written into the register, so the effective fractional value will be zero.
The issue is in this line. baud_fbrd = ((baud_rate_div & 0x7f) + 1) / 2 The recommended +0.5 correction is only added to the fractional part but the overflowing carry bit is not added to the integer part. Adding 1 and dividing by 2 before splitting into integer and fractional parts would solve the issue.
I've tested the issue on a Raspberry Pi Pico board using the hello_uart example and changing the baudrate in line 15. I've measured the actual baudrate (with ~10Hz precision) using a logic analyzer and I got the following results:
The issue occurs for each baudrate where the integer divisor is about to change, or more precisely, where (baud_rate_div & 0x7f) == 0x7f. The baudrate error will be around 1 / ibrd.
Note: Originally I found this issue in rp-hal where they've pointed out that their implementation was inspired by pico-sdk so it might by also affected.
The fractional part of the UART baudrate divisor can overflow for certain baudrates.
The used formula results in a fractional divisor value of 64 which gets truncated once it's written into the register, so the effective fractional value will be zero.
The issue is in this line.
baud_fbrd = ((baud_rate_div & 0x7f) + 1) / 2
The recommended +0.5 correction is only added to the fractional part but the overflowing carry bit is not added to the integer part. Adding 1 and dividing by 2 before splitting into integer and fractional parts would solve the issue.I've tested the issue on a Raspberry Pi Pico board using the
hello_uart
example and changing the baudrate in line 15. I've measured the actual baudrate (with ~10Hz precision) using a logic analyzer and I got the following results:The issue occurs for each baudrate where the integer divisor is about to change, or more precisely, where
(baud_rate_div & 0x7f) == 0x7f
. The baudrate error will be around1 / ibrd
.Note: Originally I found this issue in rp-hal where they've pointed out that their implementation was inspired by pico-sdk so it might by also affected.