2626
2727#include "py/mphal.h"
2828#include "py/runtime.h"
29+ #include "shared/runtime/softtimer.h"
2930#include "mpuart.h"
30-
3131#include "sys_ctrl_uart.h"
32- #include "uart.h"
3332
34- #define UART_MAX (8)
33+ #define mp_container_of (ptr , structure , member ) (void *)((uintptr_t)(ptr) - offsetof(structure, member))
34+
35+ #define UART_LSR_TEMT_Pos (6)
3536#define SYST_PCLK (100000000)
3637
38+ #define CALCULATE_BITS_PER_CHAR (data_bits , parity , stop_bits ) \
39+ (1 + ((data_bits) + 5) + ((parity) != UART_PARITY_NONE) + ((stop_bits) + 1))
40+
3741typedef struct _uart_state_t {
3842 UART_TRANSFER_STATUS status ;
43+ uint32_t baudrate ;
44+ uint32_t bits_per_char ;
3945 ringbuf_t * rx_ringbuf ;
4046 const uint8_t * tx_src ;
4147 const uint8_t * tx_src_max ;
42- void (* irq_callback )(void );
48+ soft_timer_entry_t rx_idle_timer ;
49+ unsigned int irq_trigger ;
50+ void (* irq_callback )(unsigned int uart_id , unsigned int trigger );
4351} uart_state_t ;
4452
4553static const uint8_t uart_irqn [UART_MAX ] = {
@@ -66,7 +74,19 @@ static UART_Type *const uart_periph[UART_MAX] = {
6674
6775static uart_state_t uart_state [UART_MAX ];
6876
69- void mp_uart_init (unsigned int uart_id , uint32_t baudrate , mp_hal_pin_obj_t tx , mp_hal_pin_obj_t rx , ringbuf_t * rx_ringbuf ) {
77+ // This is called by soft_timer and executes at IRQ_PRI_PENDSV.
78+ static void rx_idle_timer_callback (soft_timer_entry_t * self ) {
79+ uart_state_t * state = mp_container_of (self , uart_state_t , rx_idle_timer );
80+ if (state -> irq_callback != NULL && state -> irq_trigger & MP_UART_IRQ_RXIDLE ) {
81+ unsigned int uart_id = state - & uart_state [0 ];
82+ state -> irq_callback (uart_id , MP_UART_IRQ_RXIDLE );
83+ }
84+ }
85+
86+ void mp_uart_init (unsigned int uart_id , uint32_t baudrate ,
87+ UART_DATA_BITS data_bits , UART_PARITY parity , UART_STOP_BITS stop_bits ,
88+ mp_hal_pin_obj_t tx , mp_hal_pin_obj_t rx , ringbuf_t * rx_ringbuf ) {
89+
7090 UART_Type * uart = uart_periph [uart_id ];
7191 uart_state_t * state = & uart_state [uart_id ];
7292
@@ -82,24 +102,29 @@ void mp_uart_init(unsigned int uart_id, uint32_t baudrate, mp_hal_pin_obj_t tx,
82102 uart_disable_tx_irq (uart );
83103 uart_disable_rx_irq (uart );
84104 uart_set_baudrate (uart , SYST_PCLK , baudrate );
85- uart_set_data_parity_stop_bits (uart , UART_DATA_BITS_8 , UART_PARITY_NONE , UART_STOP_BITS_1 );
105+ uart_set_data_parity_stop_bits (uart , data_bits , parity , stop_bits );
86106 uart_set_flow_control (uart , UART_FLOW_CONTROL_NONE );
87107 uart -> UART_FCR |= UART_FCR_RCVR_FIFO_RESET ;
88108 uart_set_tx_trigger (uart , UART_TX_FIFO_EMPTY );
89- uart_set_rx_trigger (uart , UART_RX_ONE_CHAR_IN_FIFO );
109+ uart_set_rx_trigger (uart , UART_RX_FIFO_QUARTER_FULL );
90110
91111 // Initialise the state.
92112 state -> status = UART_TRANSFER_STATUS_NONE ;
113+ state -> baudrate = baudrate ;
114+ state -> bits_per_char = CALCULATE_BITS_PER_CHAR (data_bits , parity , stop_bits );
93115 state -> rx_ringbuf = rx_ringbuf ;
94116 state -> tx_src = NULL ;
95117 state -> tx_src_max = NULL ;
118+ state -> irq_trigger = 0 ;
96119 state -> irq_callback = NULL ;
97120
98121 // Enable interrupts.
99122 NVIC_ClearPendingIRQ (uart_irqn [uart_id ]);
100123 NVIC_SetPriority (uart_irqn [uart_id ], IRQ_PRI_UART_REPL );
101124 NVIC_EnableIRQ (uart_irqn [uart_id ]);
102125 uart_enable_rx_irq (uart );
126+
127+ soft_timer_static_init (& state -> rx_idle_timer , SOFT_TIMER_MODE_ONE_SHOT , 0 , rx_idle_timer_callback );
103128}
104129
105130void mp_uart_deinit (unsigned int uart_id ) {
@@ -109,9 +134,16 @@ void mp_uart_deinit(unsigned int uart_id) {
109134 NVIC_DisableIRQ (uart_irqn [uart_id ]);
110135}
111136
112- void mp_uart_set_irq_callback (unsigned int uart_id , void (* callback )(void )) {
137+ void mp_uart_set_irq_callback (unsigned int uart_id , unsigned int trigger , void (* callback )(unsigned int uart_id , unsigned int trigger )) {
138+ UART_Type * uart = uart_periph [uart_id ];
113139 uart_state_t * state = & uart_state [uart_id ];
140+ state -> irq_trigger = trigger ;
114141 state -> irq_callback = callback ;
142+ if (trigger & MP_UART_IRQ_RX ) {
143+ uart_set_rx_trigger (uart , UART_RX_ONE_CHAR_IN_FIFO );
144+ } else {
145+ uart_set_rx_trigger (uart , UART_RX_FIFO_QUARTER_FULL );
146+ }
115147}
116148
117149void mp_uart_set_flow (unsigned int uart_id , mp_hal_pin_obj_t rts , mp_hal_pin_obj_t cts ) {
@@ -131,10 +163,20 @@ void mp_uart_set_flow(unsigned int uart_id, mp_hal_pin_obj_t rts, mp_hal_pin_obj
131163
132164void mp_uart_set_baudrate (unsigned int uart_id , uint32_t baudrate ) {
133165 UART_Type * uart = uart_periph [uart_id ];
166+ uart_state_t * state = & uart_state [uart_id ];
134167
168+ state -> baudrate = baudrate ;
135169 uart_set_baudrate (uart , SYST_PCLK , baudrate );
136170}
137171
172+ void mp_uart_set_bits_parity_stop (unsigned int uart_id , UART_DATA_BITS data_bits , UART_PARITY parity , UART_STOP_BITS stop_bits ) {
173+ UART_Type * uart = uart_periph [uart_id ];
174+ uart_state_t * state = & uart_state [uart_id ];
175+
176+ state -> bits_per_char = CALCULATE_BITS_PER_CHAR (data_bits , parity , stop_bits );
177+ uart_set_data_parity_stop_bits (uart , data_bits , parity , stop_bits );
178+ }
179+
138180size_t mp_uart_rx_any (unsigned int uart_id ) {
139181 uart_state_t * state = & uart_state [uart_id ];
140182 if (state -> rx_ringbuf != NULL ) {
@@ -143,6 +185,11 @@ size_t mp_uart_rx_any(unsigned int uart_id) {
143185 return 0 ;
144186}
145187
188+ size_t mp_uart_tx_any (unsigned int uart_id ) {
189+ UART_Type * uart = uart_periph [uart_id ];
190+ return uart -> UART_TFL + !((uart -> UART_LSR >> UART_LSR_TEMT_Pos ) & 1 );
191+ }
192+
146193int mp_uart_rx_char (unsigned int uart_id ) {
147194 uart_state_t * state = & uart_state [uart_id ];
148195 if (state -> rx_ringbuf != NULL && ringbuf_avail (state -> rx_ringbuf )) {
@@ -208,9 +255,11 @@ static void mp_uart_irq_handler(unsigned int uart_id) {
208255 }
209256
210257 case UART_IIR_RECEIVED_DATA_AVAILABLE :
211- case UART_IIR_CHARACTER_TIMEOUT :
258+ case UART_IIR_CHARACTER_TIMEOUT : {
259+ bool had_char = false;
212260 while (uart -> UART_USR & UART_USR_RECEIVE_FIFO_NOT_EMPTY ) {
213261 for (uint32_t rfl = uart -> UART_RFL ; rfl ; -- rfl ) {
262+ had_char = true;
214263 int c = uart -> UART_RBR ;
215264 #if MICROPY_HW_ENABLE_UART_REPL && MICROPY_KBD_EXCEPTION
216265 if (uart_id == MICROPY_HW_UART_REPL ) {
@@ -226,13 +275,18 @@ static void mp_uart_irq_handler(unsigned int uart_id) {
226275 }
227276 }
228277
229- if (iir == UART_IIR_CHARACTER_TIMEOUT ) {
230- if (state -> irq_callback != NULL ) {
231- state -> irq_callback ();
278+ if (had_char ) {
279+ if (state -> irq_callback != NULL && state -> irq_trigger & MP_UART_IRQ_RX ) {
280+ state -> irq_callback (uart_id , MP_UART_IRQ_RX );
232281 }
233282 }
234283
284+ if (state -> irq_trigger & MP_UART_IRQ_RXIDLE ) {
285+ // Wait for 2 characters worth of time before triggering the RXIDLE event.
286+ soft_timer_reinsert (& state -> rx_idle_timer , 2000 * state -> bits_per_char / state -> baudrate + 1 );
287+ }
235288 break ;
289+ }
236290
237291 case UART_IIR_TRANSMIT_HOLDING_REG_EMPTY :
238292 while (uart -> UART_USR & UART_USR_TRANSMIT_FIFO_NOT_FULL ) {
@@ -241,6 +295,9 @@ static void mp_uart_irq_handler(unsigned int uart_id) {
241295 } else {
242296 uart_disable_tx_irq (uart );
243297 state -> status = UART_TRANSFER_STATUS_SEND_COMPLETE ;
298+ if (state -> irq_callback != NULL && state -> irq_trigger & MP_UART_IRQ_TXIDLE ) {
299+ state -> irq_callback (uart_id , MP_UART_IRQ_TXIDLE );
300+ }
244301 break ;
245302 }
246303 }
@@ -273,7 +330,9 @@ DEFINE_IRQ_HANDLER(7)
273330#define REPL_BAUDRATE (115200)
274331
275332void mp_uart_init_repl (void ) {
276- mp_uart_init (MICROPY_HW_UART_REPL , REPL_BAUDRATE , pin_REPL_UART_TX , pin_REPL_UART_RX , & stdin_ringbuf );
333+ mp_uart_init (MICROPY_HW_UART_REPL ,
334+ REPL_BAUDRATE , UART_DATA_BITS_8 , UART_PARITY_NONE , UART_STOP_BITS_1 ,
335+ pin_REPL_UART_TX , pin_REPL_UART_RX , & stdin_ringbuf );
277336}
278337
279338void mp_uart_write_strn_repl (const char * str , size_t len ) {
0 commit comments