@@ -83,24 +83,6 @@ static void config_periph_pin(const mcu_periph_obj_t *periph) {
8383 | IOMUXC_SW_PAD_CTL_PAD_SRE (0 ));
8484}
8585
86- STATIC void LPUART_UserCallback (LPUART_Type * base , lpuart_handle_t * handle , status_t status , void * user_data ) {
87- busio_uart_obj_t * self = (busio_uart_obj_t * )user_data ;
88-
89- if (status == kStatus_LPUART_RxIdle ) {
90- self -> rx_ongoing = false;
91- }
92- }
93-
94- void uart_reset (void ) {
95- for (uint i = 0 ; i < MP_ARRAY_SIZE (mcu_uart_banks ); i ++ ) {
96- if (never_reset_uart [i ]) {
97- continue ;
98- }
99- reserved_uart [i ] = false;
100- LPUART_Deinit (mcu_uart_banks [i ]);
101- }
102- }
103-
10486void common_hal_busio_uart_never_reset (busio_uart_obj_t * self ) {
10587 never_reset_uart [self -> index ] = true;
10688 common_hal_never_reset_pin (self -> tx );
@@ -348,6 +330,8 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
348330
349331 if (self -> rx != NULL ) {
350332 if (receiver_buffer == NULL ) {
333+ // One byte is used internally so add one to make sure we have enough space.
334+ receiver_buffer_size += 1 ;
351335 self -> ringbuf = gc_alloc (receiver_buffer_size , false);
352336 } else {
353337 self -> ringbuf = receiver_buffer ;
@@ -359,7 +343,8 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
359343 m_malloc_fail (receiver_buffer_size );
360344 }
361345
362- LPUART_TransferCreateHandle (self -> uart , & self -> handle , LPUART_UserCallback , self );
346+ // Use the internal ring buffer implementation.
347+ LPUART_TransferCreateHandle (self -> uart , & self -> handle , NULL , NULL );
363348 // Pass actual allocated size; the LPUART routines are cognizant that
364349 // the capacity is one less than the size.
365350 LPUART_TransferStartRingBuffer (self -> uart , & self -> handle , self -> ringbuf , receiver_buffer_size );
@@ -378,12 +363,13 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
378363 return ;
379364 }
380365
381- reserved_uart [self -> index ] = false;
382- never_reset_uart [self -> index ] = false;
383-
366+ LPUART_TransferStopRingBuffer (self -> uart , & self -> handle );
384367 LPUART_Deinit (self -> uart );
385368 gc_free (self -> ringbuf );
386369
370+ reserved_uart [self -> index ] = false;
371+ never_reset_uart [self -> index ] = false;
372+
387373 common_hal_reset_pin (self -> rx );
388374 common_hal_reset_pin (self -> tx );
389375 common_hal_reset_pin (self -> cts );
@@ -395,7 +381,6 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
395381 self -> cts = NULL ;
396382 self -> rts = NULL ;
397383 self -> rs485_dir = NULL ;
398-
399384}
400385
401386// Read characters.
@@ -409,18 +394,24 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
409394 return 0 ;
410395 }
411396
412- lpuart_transfer_t xfer = {
413- .data = data ,
414- .dataSize = len ,
415- };
416-
417- self -> rx_ongoing = true;
418- LPUART_TransferReceiveNonBlocking (self -> uart , & self -> handle , & xfer , NULL );
419-
397+ size_t received = 0 ;
420398 uint64_t start_ticks = supervisor_ticks_ms64 ();
421-
422399 // Wait for all bytes received or timeout
423- while (self -> rx_ongoing && (supervisor_ticks_ms64 () - start_ticks < self -> timeout_ms )) {
400+ while (received < len && (supervisor_ticks_ms64 () - start_ticks < self -> timeout_ms )) {
401+ lpuart_transfer_t xfer = {
402+ .data = data + received
403+ };
404+ size_t remaining = len - received ;
405+ xfer .dataSize = MIN (remaining , LPUART_TransferGetRxRingBufferLength (self -> uart , & self -> handle ));
406+ // Only request as much as has already been received. Otherwise, we need to deal with
407+ // callbacks.
408+ size_t additional_read = 0 ;
409+ LPUART_TransferReceiveNonBlocking (self -> uart , & self -> handle , & xfer , & additional_read );
410+ received += additional_read ;
411+ // Break early when we're done to skip background tasks.
412+ if (received == len ) {
413+ break ;
414+ }
424415 RUN_BACKGROUND_TASKS ;
425416
426417 // Allow user to break out of a timeout with a KeyboardInterrupt.
@@ -429,30 +420,12 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
429420 }
430421 }
431422
432- // if we timed out, stop the transfer
433- if (self -> rx_ongoing ) {
434- uint32_t recvd = 0 ;
435- LPUART_TransferGetReceiveCount (self -> uart , & self -> handle , & recvd );
436- LPUART_TransferAbortReceive (self -> uart , & self -> handle );
437- if (recvd == 0 ) {
438- * errcode = EAGAIN ;
439- return MP_STREAM_ERROR ;
440- }
441- return recvd ;
442- }
443-
444- // No data left, we got it all
445- if (self -> handle .rxData == NULL ) {
446- return len ;
423+ if (received == 0 ) {
424+ * errcode = EAGAIN ;
425+ return MP_STREAM_ERROR ;
447426 }
448427
449- // The only place we can reliably tell how many bytes have been received is from the current
450- // wp in the handle (because the abort nukes rxDataSize, and reading it before abort is a race.)
451- if (self -> handle .rxData > data ) {
452- return self -> handle .rxData - data ;
453- } else {
454- return len ;
455- }
428+ return received ;
456429}
457430
458431// Write characters.
0 commit comments