mirror of
https://github.com/micropython/micropython.git
synced 2025-07-21 04:51:12 +02:00
stm32/uart: Suppress additional RX idle IRQs on F4/L1.
These MCUs only clear the RX idle IRQ if the data register is read, which won't occur if the only IRQ is the RX idle IRQ (because then reading and discarding the DR may lead to lost data). To work around this, explicitly suppress the RX idle IRQ so that it's only passed through to the Python callback once. Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
@@ -689,6 +689,10 @@ bool uart_init(machine_uart_obj_t *uart_obj,
|
||||
uart_obj->is_enabled = true;
|
||||
uart_obj->attached_to_repl = false;
|
||||
|
||||
#if defined(STM32F4) || defined(STM32L1)
|
||||
uart_obj->suppress_idle_irq = true;
|
||||
#endif
|
||||
|
||||
if (bits == UART_WORDLENGTH_9B && parity == UART_PARITY_NONE) {
|
||||
uart_obj->char_mask = 0x1ff;
|
||||
uart_obj->char_width = CHAR_WIDTH_9BIT;
|
||||
@@ -1274,6 +1278,9 @@ void uart_irq_handler(mp_uint_t uart_id) {
|
||||
self->uartx->CR1 &= ~USART_CR1_RXNEIE;
|
||||
}
|
||||
}
|
||||
if (self->suppress_idle_irq) {
|
||||
self->mp_irq_flags &= ~USART_SR_IDLE;
|
||||
}
|
||||
#else
|
||||
self->uartx->ICR = self->mp_irq_flags & (USART_ICR_IDLECF | USART_ICR_ORECF);
|
||||
#endif
|
||||
@@ -1282,6 +1289,14 @@ void uart_irq_handler(mp_uint_t uart_id) {
|
||||
if (self->mp_irq_trigger & self->mp_irq_flags) {
|
||||
mp_irq_handler(self->mp_irq_obj);
|
||||
}
|
||||
|
||||
#if defined(STM32F4) || defined(STM32L1)
|
||||
if (did_clear_sr) {
|
||||
self->suppress_idle_irq = false;
|
||||
} else {
|
||||
self->suppress_idle_irq = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static mp_uint_t uart_irq_trigger(mp_obj_t self_in, mp_uint_t new_trigger) {
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#ifndef MICROPY_INCLUDED_STM32_UART_H
|
||||
#define MICROPY_INCLUDED_STM32_UART_H
|
||||
|
||||
#include "py/mphal.h"
|
||||
#include "shared/runtime/mpirq.h"
|
||||
|
||||
typedef enum {
|
||||
@@ -63,6 +64,9 @@ typedef struct _machine_uart_obj_t {
|
||||
pyb_uart_t uart_id : 8;
|
||||
bool is_static : 1;
|
||||
bool is_enabled : 1;
|
||||
#if defined(STM32F4) || defined(STM32L1)
|
||||
bool suppress_idle_irq : 1; // whether the RX idle IRQ is suppressed (F4/L1 only)
|
||||
#endif
|
||||
bool attached_to_repl; // whether the UART is attached to REPL
|
||||
byte char_width; // 0 for 7,8 bit chars, 1 for 9 bit chars
|
||||
uint16_t char_mask; // 0x7f for 7 bit, 0xff for 8 bit, 0x1ff for 9 bit
|
||||
|
Reference in New Issue
Block a user