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]

Reply via email to