Skip to content

Commit

Permalink
Stabilize Half-duplex PIO split comms (qmk#17612)
Browse files Browse the repository at this point in the history
  • Loading branch information
KarlK90 authored and nolanseaton committed Jan 23, 2023
1 parent 1d6a6db commit 8de6945
Showing 1 changed file with 17 additions and 3 deletions.
20 changes: 17 additions & 3 deletions platforms/chibios/drivers/vendor/RP/RP2040/serial_vendor.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ void pio_serve_interrupt(void) {
// the generated low level with 360mV will generate a logical zero.
static inline void 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
Expand All @@ -163,6 +164,9 @@ static inline void enter_rx_state(void) {

static inline void 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.
Expand Down Expand Up @@ -194,12 +198,21 @@ 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) {
break;
}
}
#if !defined(SERIAL_USART_FULL_DUPLEX)
// Entering timing critical territory again.
nvicDisableVector(RP_USBCTRL_IRQ_NUMBER);
#endif
osalSysUnlock();
return msg;
}
Expand Down Expand Up @@ -412,11 +425,12 @@ static inline void pio_init(pin_t tx_pin, pin_t rx_pin) {
pio_set_irq0_source_enabled(pio, pis_sm0_tx_fifo_not_full + tx_state_machine, true);
pio_set_irq0_source_enabled(pio, pis_interrupt0, true);

// Enable PIO specific interrupt vector
// Enable PIO specific interrupt vector, as the pio implementation is timing
// critical we use the highest possible priority.
#if defined(SERIAL_PIO_USE_PIO1)
nvicEnableVector(RP_PIO1_IRQ_0_NUMBER, RP_IRQ_UART0_PRIORITY);
nvicEnableVector(RP_PIO1_IRQ_0_NUMBER, CORTEX_MAX_KERNEL_PRIORITY);
#else
nvicEnableVector(RP_PIO0_IRQ_0_NUMBER, RP_IRQ_UART0_PRIORITY);
nvicEnableVector(RP_PIO0_IRQ_0_NUMBER, CORTEX_MAX_KERNEL_PRIORITY);
#endif

enter_rx_state();
Expand Down

0 comments on commit 8de6945

Please sign in to comment.