From 79b2d4ff222636075a9b6530e1694fa277132106 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 17 Jul 2025 16:49:26 +1000 Subject: [PATCH 1/2] esp32/machine_uart: Improve sendbreak so it doesn't reconfig the UART. Currently, `UART.sendbreak()` on esp32 will reconfigure the UART to a slower baudrate and send out a null byte, to synthesise a break condition. That's not great because it changes the baudrate of the RX path as well, which could miss incoming bytes while sending the break. This commit changes the sendbreak implementation to just reconfigure the TX pin as GPIO in output mode, and hold the pin low for the required duration. Signed-off-by: Damien George --- ports/esp32/machine_uart.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/ports/esp32/machine_uart.c b/ports/esp32/machine_uart.c index 982d9a7e27aed..661c07138e535 100644 --- a/ports/esp32/machine_uart.c +++ b/ports/esp32/machine_uart.c @@ -508,20 +508,21 @@ static bool mp_machine_uart_txdone(machine_uart_obj_t *self) { } static void mp_machine_uart_sendbreak(machine_uart_obj_t *self) { - // Save settings + // Calculate the length of the break, as 13 bits. uint32_t baudrate; check_esp_err(uart_get_baudrate(self->uart_num, &baudrate)); + uint32_t break_delay_us = 13000000 / baudrate; - // Synthesise the break condition by reducing the baud rate, - // and cater for the worst case of 5 data bits, no parity. - check_esp_err(uart_wait_tx_done(self->uart_num, pdMS_TO_TICKS(1000))); - check_esp_err(uart_set_baudrate(self->uart_num, baudrate * 6 / 15)); - char buf[1] = {0}; - uart_write_bytes(self->uart_num, buf, 1); + // Wait for any outstanding data to be transmitted. check_esp_err(uart_wait_tx_done(self->uart_num, pdMS_TO_TICKS(1000))); - // Restore original setting - check_esp_err(uart_set_baudrate(self->uart_num, baudrate)); + // Set the TX pin to output, pull it low, and wait for the break period. + mp_hal_pin_output(self->tx); + mp_hal_pin_write(self->tx, 0); + mp_hal_delay_us(break_delay_us); + + // Restore original UART pin settings. + check_esp_err(uart_set_pin(self->uart_num, self->tx, self->rx, self->rts, self->cts)); } // Configure the timer used for IRQ_RXIDLE From 1ab1f857b3eef3608cebb623526301621086faa1 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 17 Jul 2025 16:49:42 +1000 Subject: [PATCH 2/2] tests/extmod_hardware/machine_uart_irq_break.py: Remove send_uart. This is no longer needed, the esp32 port can now pass this test using just a single UART. Signed-off-by: Damien George --- .../extmod_hardware/machine_uart_irq_break.py | 34 +++++++------------ 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/tests/extmod_hardware/machine_uart_irq_break.py b/tests/extmod_hardware/machine_uart_irq_break.py index f255e0f0e6725..879f9cee6762f 100644 --- a/tests/extmod_hardware/machine_uart_irq_break.py +++ b/tests/extmod_hardware/machine_uart_irq_break.py @@ -19,18 +19,13 @@ if "ESP32S2" in _machine or "ESP32C3" in _machine or "ESP32C6" in _machine: print("SKIP") raise SystemExit - # ESP32 needs separate UART instances for the test - recv_uart_id = 1 - recv_tx_pin = 14 - recv_rx_pin = 5 - send_uart_id = 2 - send_tx_pin = 4 - send_rx_pin = 12 + uart_id = 1 + tx_pin = 4 + rx_pin = 5 elif "rp2" in sys.platform: - recv_uart_id = 0 - send_uart_id = 0 - recv_tx_pin = "GPIO0" - recv_rx_pin = "GPIO1" + uart_id = 0 + tx_pin = "GPIO0" + rx_pin = "GPIO1" else: print("Please add support for this test on this platform.") raise SystemExit @@ -42,22 +37,17 @@ def irq(u): # Test that the IRQ is called for each break received. for bits_per_s in (2400, 9600, 57600): - recv_uart = UART(recv_uart_id, bits_per_s, tx=recv_tx_pin, rx=recv_rx_pin) - if recv_uart_id != send_uart_id: - send_uart = UART(send_uart_id, bits_per_s, tx=send_tx_pin, rx=send_rx_pin) - else: - send_uart = recv_uart - - recv_uart.irq(irq, recv_uart.IRQ_BREAK) + uart = UART(uart_id, bits_per_s, tx=tx_pin, rx=rx_pin) + uart.irq(irq, uart.IRQ_BREAK) print("write", bits_per_s) for i in range(3): - send_uart.write(str(i)) - send_uart.flush() + uart.write(str(i)) + uart.flush() time.sleep_ms(10) - send_uart.sendbreak() + uart.sendbreak() time.sleep_ms(10) if "esp32" in sys.platform: # On esp32 a read is needed to read in the break byte. - recv_uart.read() + uart.read() print("done") pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy