Skip to content

Commit 0975255

Browse files
committed
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>
1 parent d5246ce commit 0975255

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

ports/stm32/uart.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,10 @@ bool uart_init(machine_uart_obj_t *uart_obj,
689689
uart_obj->is_enabled = true;
690690
uart_obj->attached_to_repl = false;
691691

692+
#if defined(STM32F4) || defined(STM32L1)
693+
uart_obj->suppress_idle_irq = true;
694+
#endif
695+
692696
if (bits == UART_WORDLENGTH_9B && parity == UART_PARITY_NONE) {
693697
uart_obj->char_mask = 0x1ff;
694698
uart_obj->char_width = CHAR_WIDTH_9BIT;
@@ -1274,6 +1278,9 @@ void uart_irq_handler(mp_uint_t uart_id) {
12741278
self->uartx->CR1 &= ~USART_CR1_RXNEIE;
12751279
}
12761280
}
1281+
if (self->suppress_idle_irq) {
1282+
self->mp_irq_flags &= ~USART_SR_IDLE;
1283+
}
12771284
#else
12781285
self->uartx->ICR = self->mp_irq_flags & (USART_ICR_IDLECF | USART_ICR_ORECF);
12791286
#endif
@@ -1282,6 +1289,14 @@ void uart_irq_handler(mp_uint_t uart_id) {
12821289
if (self->mp_irq_trigger & self->mp_irq_flags) {
12831290
mp_irq_handler(self->mp_irq_obj);
12841291
}
1292+
1293+
#if defined(STM32F4) || defined(STM32L1)
1294+
if (did_clear_sr) {
1295+
self->suppress_idle_irq = false;
1296+
} else {
1297+
self->suppress_idle_irq = true;
1298+
}
1299+
#endif
12851300
}
12861301

12871302
static mp_uint_t uart_irq_trigger(mp_obj_t self_in, mp_uint_t new_trigger) {

ports/stm32/uart.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#ifndef MICROPY_INCLUDED_STM32_UART_H
2727
#define MICROPY_INCLUDED_STM32_UART_H
2828

29+
#include "py/mphal.h"
2930
#include "shared/runtime/mpirq.h"
3031

3132
typedef enum {
@@ -63,6 +64,9 @@ typedef struct _machine_uart_obj_t {
6364
pyb_uart_t uart_id : 8;
6465
bool is_static : 1;
6566
bool is_enabled : 1;
67+
#if defined(STM32F4) || defined(STM32L1)
68+
bool suppress_idle_irq : 1; // whether the RX idle IRQ is suppressed (F4/L1 only)
69+
#endif
6670
bool attached_to_repl; // whether the UART is attached to REPL
6771
byte char_width; // 0 for 7,8 bit chars, 1 for 9 bit chars
6872
uint16_t char_mask; // 0x7f for 7 bit, 0xff for 8 bit, 0x1ff for 9 bit

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy