Stabilize Half-duplex PIO split comms (#17612)
This commit is contained in:
		
							parent
							
								
									35d78aa8a4
								
							
						
					
					
						commit
						0348071810
					
				
					 1 changed files with 17 additions and 3 deletions
				
			
		| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -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.
 | 
			
		||||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue