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:
Gil Pitney 2018-11-13 18:04:24 -08:00 committed by Kumar Gala
commit 759b987f72

View file

@ -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 */