From 5d8e326da3fd12a7764464076dca98ceada2c1cf Mon Sep 17 00:00:00 2001 From: Vincent Palatin Date: Wed, 1 Feb 2012 20:14:12 +0000 Subject: [PATCH] stm32l: avoid spurious USART interrupts The TX empty interrupt needs an actual write to DR to be cleared. So, we de-activate it before filling the TX buffer to ensure the interrupt won't fire after the last write. Signed-off-by: Vincent Palatin BUG=None TEST=run EC console along with a lower priority task on Discovery board, and check the task is scheduled as expected. Change-Id: I56c33c6dd7ccfd238fd9d5910780d12945467010 --- chip/stm32l/uart.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/chip/stm32l/uart.c b/chip/stm32l/uart.c index 988dea9e5f..46fbf9cda8 100644 --- a/chip/stm32l/uart.c +++ b/chip/stm32l/uart.c @@ -20,15 +20,19 @@ /* Console USART index */ #define UARTN CONFIG_CONSOLE_UART +/* record last TX control action */ +static int should_stop; + void uart_tx_start(void) { STM32L_USART_CR1(UARTN) |= 0x80; - task_trigger_irq(STM32L_IRQ_USART(UARTN)); + should_stop = 0; } void uart_tx_stop(void) { STM32L_USART_CR1(UARTN) &= ~0x80; + should_stop = 1; } int uart_tx_stopped(void) @@ -75,8 +79,21 @@ void uart_enable_interrupt(void) /* Interrupt handler for console USART */ static void uart_interrupt(void) { + /* + * Disable the TX empty interrupt before filling the TX buffer since it + * needs an actual write to DR to be cleared. + */ + STM32L_USART_CR1(UARTN) &= ~0x80; + /* Read input FIFO until empty, then fill output FIFO */ uart_process(); + + /* + * Re-enable TX empty interrupt only if it was not disabled by + * uart_process. + */ + if (!should_stop) + STM32L_USART_CR1(UARTN) |= 0x80; } DECLARE_IRQ(STM32L_IRQ_USART(UARTN), uart_interrupt, 1); @@ -97,9 +114,9 @@ int uart_init(void) STM32L_RCC_APB1ENR |= 1 << 18; /* USART3 */ /* UART enabled, 8 Data bits, oversampling x16, no parity, - * TXE and RXNE interrupts, TX and RX enabled. + * RXNE interrupt, TX and RX enabled. */ - STM32L_USART_CR1(UARTN) = 0x20AC; + STM32L_USART_CR1(UARTN) = 0x202C; /* 1 stop bit, no fancy stuff */ STM32L_USART_CR2(UARTN) = 0x0000;