2828#include "shared-bindings/busio/UART.h"
2929
3030#include "mpconfigport.h"
31+ #include "lib/mp-readline/readline.h"
3132#include "lib/utils/interrupt_char.h"
3233#include "py/gc.h"
3334#include "py/mperrno.h"
3940
4041//arrays use 0 based numbering: UART1 is stored at index 0
4142STATIC bool reserved_uart [MAX_UART ];
43+ STATIC bool never_reset_uart [MAX_UART ];
4244int errflag ; //Used to restart read halts
4345
4446STATIC void uart_clock_enable (uint16_t mask );
@@ -61,19 +63,25 @@ STATIC USART_TypeDef * assign_uart_or_throw(busio_uart_obj_t* self, bool pin_eva
6163}
6264
6365void uart_reset (void ) {
66+ uint16_t never_reset_mask = 0x00 ;
6467 for (uint8_t i = 0 ; i < MAX_UART ; i ++ ) {
65- reserved_uart [i ] = false;
66- MP_STATE_PORT (cpy_uart_obj_all )[i ] = NULL ;
68+ if (!never_reset_uart [i ]) {
69+ reserved_uart [i ] = false;
70+ MP_STATE_PORT (cpy_uart_obj_all )[i ] = NULL ;
71+ } else {
72+ never_reset_mask |= 1 << i ;
73+ }
6774 }
68- uart_clock_disable (ALL_UARTS );
75+ uart_clock_disable (ALL_UARTS & ~( never_reset_mask ) );
6976}
7077
7178void common_hal_busio_uart_construct (busio_uart_obj_t * self ,
7279 const mcu_pin_obj_t * tx , const mcu_pin_obj_t * rx ,
7380 const mcu_pin_obj_t * rts , const mcu_pin_obj_t * cts ,
7481 const mcu_pin_obj_t * rs485_dir , bool rs485_invert ,
7582 uint32_t baudrate , uint8_t bits , uart_parity_t parity , uint8_t stop ,
76- mp_float_t timeout , uint16_t receiver_buffer_size ) {
83+ mp_float_t timeout , uint16_t receiver_buffer_size , byte * receiver_buffer ,
84+ bool sigint_enabled ) {
7785
7886 //match pins to UART objects
7987 USART_TypeDef * USARTx ;
@@ -209,8 +217,12 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
209217
210218 // Init buffer for rx and claim pins
211219 if (self -> rx != NULL ) {
212- if (!ringbuf_alloc (& self -> ringbuf , receiver_buffer_size , true)) {
213- mp_raise_ValueError (translate ("UART Buffer allocation error" ));
220+ if (receiver_buffer != NULL ) {
221+ self -> ringbuf = (ringbuf_t ){ receiver_buffer , receiver_buffer_size };
222+ } else {
223+ if (!ringbuf_alloc (& self -> ringbuf , receiver_buffer_size , true)) {
224+ mp_raise_ValueError (translate ("UART Buffer allocation error" ));
225+ }
214226 }
215227 claim_pin (rx );
216228 }
@@ -219,6 +231,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
219231 }
220232 self -> baudrate = baudrate ;
221233 self -> timeout_ms = timeout * 1000 ;
234+ self -> sigint_enabled = sigint_enabled ;
222235
223236 //start the interrupt series
224237 if ((HAL_UART_GetState (& self -> handle ) & HAL_UART_STATE_BUSY_RX ) == HAL_UART_STATE_BUSY_RX ) {
@@ -234,13 +247,31 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
234247 errflag = HAL_OK ;
235248}
236249
250+ void common_hal_busio_uart_never_reset (busio_uart_obj_t * self ) {
251+ for (size_t i = 0 ; i < MP_ARRAY_SIZE (mcu_uart_banks ); i ++ ) {
252+ if (mcu_uart_banks [i ] == self -> handle .Instance ) {
253+ never_reset_uart [i ] = true;
254+ never_reset_pin_number (self -> tx -> pin -> port , self -> tx -> pin -> number );
255+ never_reset_pin_number (self -> rx -> pin -> port , self -> rx -> pin -> number );
256+ break ;
257+ }
258+ }
259+ }
260+
237261bool common_hal_busio_uart_deinited (busio_uart_obj_t * self ) {
238262 return self -> tx -> pin == NULL ;
239263}
240264
241265void common_hal_busio_uart_deinit (busio_uart_obj_t * self ) {
242266 if (common_hal_busio_uart_deinited (self )) return ;
243267
268+ for (size_t i = 0 ; i < MP_ARRAY_SIZE (mcu_uart_banks ); i ++ ) {
269+ if (mcu_uart_banks [i ] == self -> handle .Instance ) {
270+ never_reset_uart [i ] = false;
271+ break ;
272+ }
273+ }
274+
244275 reset_pin_number (self -> tx -> pin -> port ,self -> tx -> pin -> number );
245276 reset_pin_number (self -> rx -> pin -> port ,self -> rx -> pin -> number );
246277 self -> tx = NULL ;
@@ -289,7 +320,8 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data,
289320 bool write_err = false; //write error shouldn't disable interrupts
290321
291322 HAL_NVIC_DisableIRQ (self -> irq );
292- if (HAL_UART_Transmit (& self -> handle , (uint8_t * )data , len , HAL_MAX_DELAY ) != HAL_OK ) {
323+ HAL_StatusTypeDef ret = HAL_UART_Transmit (& self -> handle , (uint8_t * )data , len , HAL_MAX_DELAY );
324+ if (ret != HAL_OK ) {
293325 write_err = true;
294326 }
295327 HAL_UART_Receive_IT (& self -> handle , & self -> rx_char , 1 );
@@ -313,6 +345,12 @@ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *handle)
313345 }
314346 ringbuf_put_n (& context -> ringbuf , & context -> rx_char , 1 );
315347 errflag = HAL_UART_Receive_IT (handle , & context -> rx_char , 1 );
348+ if (context -> sigint_enabled ) {
349+ if (context -> rx_char == CHAR_CTRL_C ) {
350+ common_hal_busio_uart_clear_rx_buffer (context );
351+ mp_keyboard_interrupt ();
352+ }
353+ }
316354
317355 return ;
318356 }
0 commit comments