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.
This commit is contained in:
Damien George 2018-12-29 22:44:41 +11:00
parent a5f7a3022d
commit 0d860fdcd0
2 changed files with 45 additions and 5 deletions

View File

@ -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);
}
}

View File

@ -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;