ErikkEnglund opened a new pull request, #20390: URL: https://github.com/apache/nuttx/pull/20390
## Summary Fixes #15888 After PR #20389 for ESP32-S3 that caught the same issue. - Root cause: DIR was only released on TX_BRK_IDLE_DONE, which belongs to the UART break feature and never fires after normal data. - Fix: keep TX_DONE enabled after txint(false). On TX_DONE, with the buffer and FIFO empty, wait (bounded) for the transmitter to go idle, drop DIR, then disable TX_DONE. - txempty(): now checks FIFO count and transmitter state, as ESP-IDF does. esp_setup(): remove a dangling else that skipped leave_critical_section() on RS-485 ports, so a tcsetattr() that changed settings left the calling task with interrupts disabled. ## Impact This affects all RISC-V based ESP32 devices. In RS485-mode the broken behaviour is fixed. Affecting all ESP32 RISC-V chip users: tcdrain() and close() now wait until the last byte has actually gone out, instead of returning up to about 10 bytes early. No build, Kconfig, documentation or API changes. ## Testing Testing done on ESP32-C3-WROOM-02 hardware with a MAX485 adapter board connected to a USB-RS485 module. Logging via Saleae Logic device. Built using WSL2 Ubuntu 24.04, xPack riscv-none-elf-gcc 13.2.0-2 and the config `esp32c3-devkit:nsh` + `CONFIG_ESPRESSIF_UART1_RS485`, TX=GPIO5, RX=GPIO6, DIR=GPIO4. Test compilation for C6, H2 and P4, no hardware tests done - as I dont have the boards in hand. Upstream code never releases DIR-pin after TX: <img width="1710" height="638" alt="image" src="https://github.com/user-attachments/assets/8a4a1c99-beba-4a5c-95a0-3dd7f78284b9" /> After fix we get the intended behaviour. 9600 Baud: <img width="1715" height="650" alt="image" src="https://github.com/user-attachments/assets/16f5e64d-0e3c-4c81-ae84-8700dfdeabd3" /> 115200 Baud: <img width="1705" height="654" alt="image" src="https://github.com/user-attachments/assets/a83e2497-876f-4e1d-bca7-56c8e749e209" /> 921600 Baud: <img width="1718" height="651" alt="image" src="https://github.com/user-attachments/assets/ed1daced-565b-4d5d-b998-8c8d8866fd2d" /> tcsirq is a small local test app: it changes the baud with tcsetattr(), checks that interrupts are still enabled, and that the system tick advances during a 200 ms busy-wait. On upstream it reports interrupts off and 0 ticks. <details><summary>Test Log</summary> ``` ===== git 93ab151874 arch/risc-v/espressif: Release RS-485 DIR on TX_DONE. 811b809e7f arch/risc-v/espressif: Fix dangling else in esp_setup() for RS-485. 3297bbec44 arch/arm/mps: Let user code run modules from the text and data heaps. ===== configure (esp32c3-devkit:nsh + RS-485 options) CONFIG_ESPRESSIF_UART1=y CONFIG_ESPRESSIF_UART1_RS485=y CONFIG_ESPRESSIF_UART1_RS485_DIR_PIN=4 CONFIG_ESPRESSIF_UART1_RS485_DIR_POLARITY=1 CONFIG_ESPRESSIF_UART1_TXPIN=5 CONFIG_ESPRESSIF_UART1_RXPIN=6 CONFIG_ARCH_BOARD="esp32c3-devkit" CONFIG_SERIAL_TERMIOS=y CONFIG_UART1_BAUD=115200 ===== build (riscv-none-elf-gcc (xPack GNU RISC-V Embedded GCC x86_64) 13.2.0) irom0_0_seg: 140604 B 4 MB 3.35% dram0_0_seg: 26816 B 321296 B 8.35% drom0_0_seg: 246080 B 4 MB 5.87% rtc_iram_seg: 52 B 8168 B 0.64% rtc_reserved_seg: 0 GB 24 B 0.00% CP: nuttx.hex MKIMAGE: NuttX binary esptool.py -c esp32c3 elf2image --ram-only-header -fs 4MB -fm dio -ff "80m" -o nuttx.bin nuttx esptool.py v4.12.0 Creating esp32c3 image... Image has only RAM segments visible. ROM segments are hidden and SHA256 digest is not appended. Merged 1 ELF section Successfully created esp32c3 image. Generated: nuttx.bin ===== flash esptool.py -c esp32c3 elf2image --ram-only-header -fs 4MB -fm dio -ff "80m" -o nuttx.bin nuttx esptool.py v4.12.0 esptool.py v4.12.0 Chip is ESP32-C3 (QFN32) (revision v0.3) Wrote 311616 bytes (123790 compressed) at 0x00000000 in 4.6 seconds (effective 537.6 kbit/s)... Hash of data verified. Hard resetting via RTS pin... ===== nsh console (UART0) after reset NuttShell (NSH) NuttX-13.1.0-RC0 nsh> nsh> uname -a NuttX 13.1.0-RC0 93ab151874 Sep 28 2026 22:37:43 risc-v esp32c3-devkit nsh> cat /dev/ttyS1 > /dev/ttyS1 & sh [3:100] nsh> tcsirq /dev/ttyS1 tcsirq: /dev/ttyS1 115200 -> 57600 baud: interrupts before tcsetattr: on, after: on; ticks during a 200 ms busy-wait: 20 -> PASS ===== RS-485 bus, PC side (FTDI USB-RS485 at 115200); ESP echoes via cat (bytes on the bus from the ESP reset/boot, discarded: 1) PC sent 8 B b'PING1234' -> echo ok PC sent 8 B b'PONG5678' -> echo ok PC sent 119 B b'xxxxxxxxxxxxxxxxxxxx'... -> echo ok PC sent 17 B b'second-after-long' -> echo ok nsh> serialblaster /dev/ttyS1 1000 -> PC received 1000 B, pattern ok: True PC sent reply right after the burst -> echo ok ``` </details> -- 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]
