From 858efa0ed9393731a90c4206d9b095bce819d1c2 Mon Sep 17 00:00:00 2001 From: Stefan Kerkmann Date: Mon, 19 Sep 2022 17:41:03 +0200 Subject: [PATCH] Stabilize Half-duplex PIO split comms take 2 ...by moving the actually timing critical `enter_rx_state()` and `leave_rx_state()` functions to RAM in order to not be affected by XIP cache spikes. This commit also reverts the hacky USB interrupt disabling that was done in 293c53d774 --- .../drivers/vendor/RP/RP2040/serial_vendor.c | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/platforms/chibios/drivers/vendor/RP/RP2040/serial_vendor.c b/platforms/chibios/drivers/vendor/RP/RP2040/serial_vendor.c index 764764b3f9e0..afd7e65ad81f 100644 --- a/platforms/chibios/drivers/vendor/RP/RP2040/serial_vendor.c +++ b/platforms/chibios/drivers/vendor/RP/RP2040/serial_vendor.c @@ -140,9 +140,8 @@ void pio_serve_interrupt(void) { // strength is chosen because the transmitting side must still be able to drive // the signal low. With this configuration the rise times are fast enough and // the generated low level with 360mV will generate a logical zero. -static inline void enter_rx_state(void) { +static void __no_inline_not_in_flash_func(enter_rx_state)(void) { osalSysLock(); - nvicEnableVector(RP_USBCTRL_IRQ_NUMBER, RP_IRQ_USB0_PRIORITY); // Wait for the transmitting state machines FIFO to run empty. At this point // the last byte has been pulled from the transmitting state machines FIFO // into the output shift register. We have to wait a tiny bit more until @@ -162,11 +161,8 @@ static inline void enter_rx_state(void) { osalSysUnlock(); } -static inline void leave_rx_state(void) { +static void __no_inline_not_in_flash_func(leave_rx_state)(void) { osalSysLock(); - // We don't want to be interrupted by frequent (1KHz) USB interrupts while - // doing our timing critical sending operation. - nvicDisableVector(RP_USBCTRL_IRQ_NUMBER); // In Half-duplex operation the tx pin dual-functions as sender and // receiver. To not receive the data we will send, we disable the receiving // state machine. @@ -198,11 +194,6 @@ static inline msg_t sync_tx(sysinterval_t timeout) { msg_t msg = MSG_OK; osalSysLock(); while (pio_sm_is_tx_fifo_full(pio, tx_state_machine)) { -#if !defined(SERIAL_USART_FULL_DUPLEX) - // Enable USB interrupts again, because we might sleep for a long time - // here and don't want to be disconnected from the host. - nvicEnableVector(RP_USBCTRL_IRQ_NUMBER, RP_IRQ_USB0_PRIORITY); -#endif pio_set_irq0_source_enabled(pio, pis_sm0_tx_fifo_not_full + tx_state_machine, true); msg = osalThreadSuspendTimeoutS(&tx_thread, timeout); if (msg < MSG_OK) { @@ -210,10 +201,6 @@ static inline msg_t sync_tx(sysinterval_t timeout) { break; } } -#if !defined(SERIAL_USART_FULL_DUPLEX) - // Entering timing critical territory again. - nvicDisableVector(RP_USBCTRL_IRQ_NUMBER); -#endif osalSysUnlock(); return msg; }