daniel-p-carvalho opened a new pull request, #20914: URL: https://github.com/apache/nuttx/pull/20914
## Summary `stm32l4serial_setformat()` writes the baud rate, the parity and word length bits of `CR1` and the stop bits with the USART enabled. On this USART `BRR` and the `PCE`, `PS`, `M0` and `M1` bits can only be written while `UE = 0` (RM0394, `USART_CR1` and `USART_BRR`), so those writes are dropped silently. At open time the USART is still disabled, so the format from the configuration is applied correctly. A later `tcsetattr()` that changes parity or stop bits returns success and leaves the USART unchanged. The change saves and clears `UE` before touching the registers and restores it afterwards, inside a critical section. This is the same pattern the STM32H7, STM32F7 and STM32 M0 v4 serial drivers already use. Found with `nxmodbus` (`nxmb_serial_configure()` calls `tcsetattr()` to select 8E1): the server asked for 8E1, the USART stayed in 8N1, and a master using 8E1 got no answer. ### Other drivers with the same pattern (not changed here) By code reading only. Only the STM32L4 was reproduced on hardware, so I am leaving the others for separate changes that can be tested: - `arch/arm/src/stm32wb/stm32wb_serial.c`, `stm32wl5/stm32wl5_serial.c`, `stm32n6/stm32_serial.c`: same `setformat` without `UE` handling, called from `TCSETS`. - `arch/arm/src/common/stm32/stm32_serial_m33_v3.c` and `stm32_serial_m0_v3.c`: same. - `arch/arm/src/common/stm32/stm32_serial_m3m4_v1v2v3v4.c`: `up_set_format()` clears `UE`, `TE` and `RE` only under `CONFIG_STM32_STM32G4XXX`. The F3 branches (`F30XX`, `F33XX`, `F37XX`) use the same USART v2 and look affected. I plan to test an F334 and follow up. - STM32H7, STM32F7 and the M0 v4 driver already handle `UE` correctly. ## Impact `tcsetattr()` on an STM32L4 USART now applies parity and stop bits at run time. No change at open time, no API or configuration change. The write sequence is a few register accesses in a critical section, the same cost as in the H7 and F7 drivers. ## Testing Host: Linux x86_64, `arm-none-eabi-gcc` 15.2.1, OpenOCD 0.12 and `arm-none-eabi-gdb`. Board: NUCLEO-L432KC (STM32L432KC), USART2 through the ST-LINK VCP, `nucleo-l432kc:nsh` with `CONFIG_SERIAL_TERMIOS=y` and `nxmbserver` started as the init entry point (`-t rtu -d /dev/ttyS0 -b 115200`, parity even by default). Before the change, with a breakpoint after `stm32l4serial_setformat()`: the driver stores `CR1 = 0x142d` (`PCE | M0` set) and `CR1` reads back `0x0000002d`. Writing `0x142d` by hand with gdb while `UE = 1` gives the same result, `0x2d`. After the change, `CR1` keeps `PCE` and `M0` and the server answers read holding registers (FC03, unit 1, pymodbus 3.16) in 8E1 and in 8N2. In 8N1 it does not answer, as expected for an even-parity server. ``` 115200 E 1 ReadHoldingRegistersResponse(dev_id=1, ... registers=[0, 100], status=1) 115200 N 2 ReadHoldingRegistersResponse(dev_id=1, ... registers=[0, 100], status=1) 115200 N 1 No response received ``` `tools/nxstyle` reports no new findings in the file (77 findings, all outside the changed lines; 78 on `master`). I have not run OSTest. The change only touches the format path of one serial driver and is not built for other boards. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
