mirror of
https://github.com/micropython/micropython.git
synced 2025-12-16 09:50:15 +01:00
esp32/usb_serial_jtag: Flush usb_serial_jtag TXFIFO from ISR.
This was necessary to un-wedge the USJ TX path on ESP32-P4, I think because the bootloader prints a lot on this chip. I think it might be possible to hit it on other chips, though. The implementation is based on the ESP-IDF driver, which will always add an extra flush when the TXFIFO is empty in case the host is expecting a ZLP. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
This commit is contained in:
committed by
Damien George
parent
50a06b6404
commit
eb5d89cd83
@@ -71,23 +71,31 @@ static void usb_serial_jtag_handle_rx(void) {
|
|||||||
|
|
||||||
static void usb_serial_jtag_isr_handler(void *arg) {
|
static void usb_serial_jtag_isr_handler(void *arg) {
|
||||||
uint32_t flags = usb_serial_jtag_ll_get_intsts_mask();
|
uint32_t flags = usb_serial_jtag_ll_get_intsts_mask();
|
||||||
|
usb_serial_jtag_ll_clr_intsts_mask(flags);
|
||||||
if (flags & USB_SERIAL_JTAG_INTR_SOF) {
|
|
||||||
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SOF);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT) {
|
if (flags & USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT) {
|
||||||
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT);
|
|
||||||
usb_serial_jtag_handle_rx();
|
usb_serial_jtag_handle_rx();
|
||||||
mp_hal_wake_main_task_from_isr();
|
mp_hal_wake_main_task_from_isr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flags & USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY) {
|
||||||
|
// As per the ESP-IDF driver, allow for the possibility the USJ just sent a full
|
||||||
|
// 64-bit endpoint to the host and now it's waiting for another ZLP to flush the result
|
||||||
|
// to the OS
|
||||||
|
usb_serial_jtag_ll_txfifo_flush();
|
||||||
|
|
||||||
|
// Disable this interrupt until next time we write into the FIFO
|
||||||
|
usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void usb_serial_jtag_init(void) {
|
void usb_serial_jtag_init(void) {
|
||||||
|
// Note: Don't clear the SERIAL_IN_EMPTY interrupt, as it's possible the
|
||||||
|
// bootloader wrote enough data to the host that we need the interrupt to flush it.
|
||||||
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT |
|
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT |
|
||||||
USB_SERIAL_JTAG_INTR_SOF);
|
USB_SERIAL_JTAG_INTR_SOF);
|
||||||
usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT |
|
usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT |
|
||||||
USB_SERIAL_JTAG_INTR_SOF);
|
USB_SERIAL_JTAG_INTR_SOF | USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
|
||||||
ESP_ERROR_CHECK(esp_intr_alloc(ETS_USB_SERIAL_JTAG_INTR_SOURCE, ESP_INTR_FLAG_LEVEL1,
|
ESP_ERROR_CHECK(esp_intr_alloc(ETS_USB_SERIAL_JTAG_INTR_SOURCE, ESP_INTR_FLAG_LEVEL1,
|
||||||
usb_serial_jtag_isr_handler, NULL, NULL));
|
usb_serial_jtag_isr_handler, NULL, NULL));
|
||||||
}
|
}
|
||||||
@@ -114,10 +122,11 @@ void usb_serial_jtag_tx_strn(const char *str, size_t len) {
|
|||||||
}
|
}
|
||||||
terminal_connected = true;
|
terminal_connected = true;
|
||||||
l = usb_serial_jtag_ll_write_txfifo((const uint8_t *)str, l);
|
l = usb_serial_jtag_ll_write_txfifo((const uint8_t *)str, l);
|
||||||
usb_serial_jtag_ll_txfifo_flush();
|
|
||||||
str += l;
|
str += l;
|
||||||
len -= l;
|
len -= l;
|
||||||
|
usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
|
||||||
}
|
}
|
||||||
|
usb_serial_jtag_ll_txfifo_flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MICROPY_HW_ESP_USB_SERIAL_JTAG
|
#endif // MICROPY_HW_ESP_USB_SERIAL_JTAG
|
||||||
|
|||||||
Reference in New Issue
Block a user