drivers: serial: Update cc32xx uart interrupt handling
The Zephyr console and shell interrupt processing assumes a TX interrupt is evoked upon first enabling the TX interrupt via uart_irq_tx_enable. This was not the case with the cc32xx uart, coming out of reset, with FIFO's disabled. The only way found to achieve this behavior is to fill the fifo with a non-printable character on initialization. Also, the uart driver was explicitly clearing TX/RX interrupts in its isr, which was unnecessary, as the act of reading/writing did that implicitly. These fixes allow the cc32xx uart to work with the current Zephyr console/shell design. Fixes: #11202 Signed-off-by: Gil Pitney <gil.pitney@linaro.org>
This commit is contained in:
parent
84fe1ec63f
commit
759b987f72
1 changed files with 15 additions and 6 deletions
|
@ -27,6 +27,8 @@ struct uart_cc32xx_dev_data_t {
|
||||||
#define DEV_DATA(dev) \
|
#define DEV_DATA(dev) \
|
||||||
((struct uart_cc32xx_dev_data_t * const)(dev)->driver_data)
|
((struct uart_cc32xx_dev_data_t * const)(dev)->driver_data)
|
||||||
|
|
||||||
|
#define PRIME_CHAR '\r'
|
||||||
|
|
||||||
/* Forward decls: */
|
/* Forward decls: */
|
||||||
static struct device DEVICE_NAME_GET(uart_cc32xx_0);
|
static struct device DEVICE_NAME_GET(uart_cc32xx_0);
|
||||||
|
|
||||||
|
@ -70,15 +72,20 @@ static int uart_cc32xx_init(struct device *dev)
|
||||||
MAP_UARTFIFODisable((unsigned long)config->base);
|
MAP_UARTFIFODisable((unsigned long)config->base);
|
||||||
|
|
||||||
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
|
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
|
||||||
/* Clear any pending UART interrupts: we only care about RX, TX: */
|
/* Clear any pending UART RX interrupts: */
|
||||||
MAP_UARTIntClear((unsigned long)config->base,
|
MAP_UARTIntClear((unsigned long)config->base, UART_INT_RX);
|
||||||
(UART_INT_RX | UART_INT_TX));
|
|
||||||
|
|
||||||
IRQ_CONNECT(DT_TI_CC32XX_UART_4000C000_IRQ_0,
|
IRQ_CONNECT(DT_TI_CC32XX_UART_4000C000_IRQ_0,
|
||||||
DT_TI_CC32XX_UART_4000C000_IRQ_0_PRIORITY,
|
DT_TI_CC32XX_UART_4000C000_IRQ_0_PRIORITY,
|
||||||
uart_cc32xx_isr, DEVICE_GET(uart_cc32xx_0),
|
uart_cc32xx_isr, DEVICE_GET(uart_cc32xx_0),
|
||||||
0);
|
0);
|
||||||
irq_enable(DT_TI_CC32XX_UART_4000C000_IRQ_0);
|
irq_enable(DT_TI_CC32XX_UART_4000C000_IRQ_0);
|
||||||
|
|
||||||
|
/* Fill the tx fifo, so Zephyr console & shell subsystems get "primed"
|
||||||
|
* with first tx fifo empty interrupt when they first call
|
||||||
|
* uart_irq_tx_enable().
|
||||||
|
*/
|
||||||
|
MAP_UARTCharPutNonBlocking((unsigned long)config->base, PRIME_CHAR);
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -278,10 +285,12 @@ static void uart_cc32xx_isr(void *arg)
|
||||||
dev_data->cb(dev_data->cb_data);
|
dev_data->cb(dev_data->cb_data);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Clear interrupts only after cb called, as Zephyr UART clients expect
|
* RX/TX interrupt should have been implicitly cleared by Zephyr UART
|
||||||
* to check interrupt status during the callback.
|
* clients calling uart_fifo_read() or uart_fifo_write().
|
||||||
|
* Still, clear any error interrupts here, as they're not yet handled.
|
||||||
*/
|
*/
|
||||||
MAP_UARTIntClear((unsigned long)config->base, intStatus);
|
MAP_UARTIntClear((unsigned long)config->base,
|
||||||
|
intStatus & ~(UART_INT_RX | UART_INT_TX));
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */
|
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue