From 0d860fdcd01614a109cd85a09c727b547dcb1378 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 29 Dec 2018 22:44:41 +1100 Subject: [PATCH] stm32/uart: Always enable global UART IRQ handler on init. Otherwise IRQs may not be enabled for the user UART.irq() handler. In particular this fixes the user IRQ_RXIDLE interrupt so that it triggers even when there is no RX buffer. --- ports/stm32/uart.c | 49 ++++++++++++++++++++++++++++++++++++++++++---- ports/stm32/uart.h | 1 - 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/ports/stm32/uart.c b/ports/stm32/uart.c index 4031d8acd4..cdc3e2670b 100644 --- a/ports/stm32/uart.c +++ b/ports/stm32/uart.c @@ -46,6 +46,44 @@ #define UART_RXNE_IT_EN(uart) do { (uart)->CR1 |= USART_CR1_RXNEIE; } while (0) #define UART_RXNE_IT_DIS(uart) do { (uart)->CR1 &= ~USART_CR1_RXNEIE; } while (0) +#define USART_CR1_IE_BASE (USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE | USART_CR1_RXNEIE | USART_CR1_IDLEIE) +#define USART_CR2_IE_BASE (USART_CR2_LBDIE) +#define USART_CR3_IE_BASE (USART_CR3_CTSIE | USART_CR3_EIE) + +#if defined(STM32F0) +#define USART_CR1_IE_ALL (USART_CR1_IE_BASE | USART_CR1_EOBIE | USART_CR1_RTOIE | USART_CR1_CMIE) +#define USART_CR2_IE_ALL (USART_CR2_IE_BASE) +#define USART_CR3_IE_ALL (USART_CR3_IE_BASE | USART_CR3_WUFIE) + +#elif defined(STM32F4) +#define USART_CR1_IE_ALL (USART_CR1_IE_BASE) +#define USART_CR2_IE_ALL (USART_CR2_IE_BASE) +#define USART_CR3_IE_ALL (USART_CR3_IE_BASE) + +#elif defined(STM32F7) +#define USART_CR1_IE_ALL (USART_CR1_IE_BASE | USART_CR1_EOBIE | USART_CR1_RTOIE | USART_CR1_CMIE) +#define USART_CR2_IE_ALL (USART_CR2_IE_BASE) +#if defined(USART_CR3_TCBGTIE) +#define USART_CR3_IE_ALL (USART_CR3_IE_BASE | USART_CR3_TCBGTIE) +#else +#define USART_CR3_IE_ALL (USART_CR3_IE_BASE) +#endif + +#elif defined(STM32H7) +#define USART_CR1_IE_ALL (USART_CR1_IE_BASE | USART_CR1_RXFFIE | USART_CR1_TXFEIE | USART_CR1_EOBIE | USART_CR1_RTOIE | USART_CR1_CMIE) +#define USART_CR2_IE_ALL (USART_CR2_IE_BASE) +#define USART_CR3_IE_ALL (USART_CR3_IE_BASE | USART_CR3_RXFTIE | USART_CR3_TCBGTIE | USART_CR3_TXFTIE | USART_CR3_WUFIE) + +#elif defined(STM32L4) +#define USART_CR1_IE_ALL (USART_CR1_IE_BASE | USART_CR1_EOBIE | USART_CR1_RTOIE | USART_CR1_CMIE) +#define USART_CR2_IE_ALL (USART_CR2_IE_BASE) +#if defined(USART_CR3_TCBGTIE) +#define USART_CR3_IE_ALL (USART_CR3_IE_BASE | USART_CR3_TCBGTIE | USART_CR3_WUFIE) +#else +#define USART_CR3_IE_ALL (USART_CR3_IE_BASE | USART_CR3_WUFIE) +#endif +#endif + extern void NORETURN __fatal_error(const char *msg); void uart_init0(void) { @@ -297,7 +335,6 @@ bool uart_init(pyb_uart_obj_t *uart_obj, } } - uart_obj->irqn = irqn; uart_obj->uartx = UARTx; // init UARTx @@ -313,6 +350,13 @@ bool uart_init(pyb_uart_obj_t *uart_obj, huart.Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(&huart); + // Disable all individual UART IRQs, but enable the global handler + uart_obj->uartx->CR1 &= ~USART_CR1_IE_ALL; + uart_obj->uartx->CR2 &= ~USART_CR2_IE_ALL; + uart_obj->uartx->CR3 &= ~USART_CR3_IE_ALL; + NVIC_SetPriority(IRQn_NONNEG(irqn), IRQ_PRI_UART); + HAL_NVIC_EnableIRQ(irqn); + uart_obj->is_enabled = true; uart_obj->attached_to_repl = false; @@ -340,12 +384,9 @@ void uart_set_rxbuf(pyb_uart_obj_t *self, size_t len, void *buf) { self->read_buf_len = len; self->read_buf = buf; if (len == 0) { - HAL_NVIC_DisableIRQ(self->irqn); UART_RXNE_IT_DIS(self->uartx); } else { UART_RXNE_IT_EN(self->uartx); - NVIC_SetPriority(IRQn_NONNEG(self->irqn), IRQ_PRI_UART); - HAL_NVIC_EnableIRQ(self->irqn); } } diff --git a/ports/stm32/uart.h b/ports/stm32/uart.h index e21b4dd9c1..827b3c12d7 100644 --- a/ports/stm32/uart.h +++ b/ports/stm32/uart.h @@ -46,7 +46,6 @@ typedef enum { typedef struct _pyb_uart_obj_t { mp_obj_base_t base; USART_TypeDef *uartx; - IRQn_Type irqn; pyb_uart_t uart_id : 8; bool is_static : 1; bool is_enabled : 1;