@@ -83,24 +83,6 @@ static void config_periph_pin(const mcu_periph_obj_t *periph) {
83
83
| IOMUXC_SW_PAD_CTL_PAD_SRE (0 ));
84
84
}
85
85
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
-
104
86
void common_hal_busio_uart_never_reset (busio_uart_obj_t * self ) {
105
87
never_reset_uart [self -> index ] = true;
106
88
common_hal_never_reset_pin (self -> tx );
@@ -348,6 +330,8 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
348
330
349
331
if (self -> rx != NULL ) {
350
332
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 ;
351
335
self -> ringbuf = gc_alloc (receiver_buffer_size , false);
352
336
} else {
353
337
self -> ringbuf = receiver_buffer ;
@@ -359,7 +343,8 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
359
343
m_malloc_fail (receiver_buffer_size );
360
344
}
361
345
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 );
363
348
// Pass actual allocated size; the LPUART routines are cognizant that
364
349
// the capacity is one less than the size.
365
350
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) {
378
363
return ;
379
364
}
380
365
381
- reserved_uart [self -> index ] = false;
382
- never_reset_uart [self -> index ] = false;
383
-
366
+ LPUART_TransferStopRingBuffer (self -> uart , & self -> handle );
384
367
LPUART_Deinit (self -> uart );
385
368
gc_free (self -> ringbuf );
386
369
370
+ reserved_uart [self -> index ] = false;
371
+ never_reset_uart [self -> index ] = false;
372
+
387
373
common_hal_reset_pin (self -> rx );
388
374
common_hal_reset_pin (self -> tx );
389
375
common_hal_reset_pin (self -> cts );
@@ -395,7 +381,6 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
395
381
self -> cts = NULL ;
396
382
self -> rts = NULL ;
397
383
self -> rs485_dir = NULL ;
398
-
399
384
}
400
385
401
386
// Read characters.
@@ -409,18 +394,24 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
409
394
return 0 ;
410
395
}
411
396
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 ;
420
398
uint64_t start_ticks = supervisor_ticks_ms64 ();
421
-
422
399
// 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
+ }
424
415
RUN_BACKGROUND_TASKS ;
425
416
426
417
// 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
429
420
}
430
421
}
431
422
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 ;
447
426
}
448
427
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 ;
456
429
}
457
430
458
431
// Write characters.
0 commit comments