@@ -372,9 +372,22 @@ STATIC mp_uint_t machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uin
372
372
lpuart_transfer_t xfer ;
373
373
uint64_t t ;
374
374
size_t remaining = size ;
375
+ size_t sent = 0 ;
375
376
size_t offset = 0 ;
377
+ uint32_t block_time ;
378
+ uint32_t timeout_budget = self -> timeout ;
376
379
uint8_t fifo_size = FSL_FEATURE_LPUART_FIFO_SIZEn (0 );
377
380
381
+ // Check if a tansmission is still going on and write will block longer than timeout
382
+ if (self -> tx_status != kStatus_LPUART_TxIdle ) {
383
+ block_time = (fifo_size + self -> handle .txDataSize ) * (13000000 / self -> config .baudRate_Bps ) / 1000 ;
384
+ if (timeout_budget < block_time ) {
385
+ * errcode = MP_EAGAIN ;
386
+ return MP_STREAM_ERROR ;
387
+ }
388
+ timeout_budget -= block_time ;
389
+ }
390
+
378
391
// First check if a previous transfer is still ongoing,
379
392
// then wait at least the number of remaining character times.
380
393
t = ticks_us64 () + (uint64_t )(self -> handle .txDataSize + fifo_size ) * (13000000 / self -> config .baudRate_Bps + 1000 );
@@ -388,31 +401,33 @@ STATIC mp_uint_t machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uin
388
401
389
402
// Check if the first part has to be sent semi-blocking.
390
403
if (size > self -> txbuf_len ) {
391
- // Send the first block.
392
- xfer .data = (uint8_t * )buf_in ;
393
- offset = xfer .dataSize = size - self -> txbuf_len ;
394
- self -> tx_status = kStatus_LPUART_TxBusy ;
395
- LPUART_TransferSendNonBlocking (self -> lpuart , & self -> handle , & xfer );
396
-
397
- // Wait at least the number of character times for this chunk.
398
- t = ticks_us64 () + (uint64_t )xfer .dataSize * (13000000 / self -> config .baudRate_Bps + 1000 );
399
- while (self -> tx_status != kStatus_LPUART_TxIdle ) {
400
- // Wait for the first/next character to be sent.
401
- if (ticks_us64 () > t ) { // timed out
402
- if (self -> handle .txDataSize >= size ) {
403
- * errcode = MP_ETIMEDOUT ;
404
- return MP_STREAM_ERROR ;
405
- } else {
406
- return size - self -> handle .txDataSize ;
404
+ // check it it blocks shorter than a timeout
405
+ block_time = (size - self -> txbuf_len ) * (13000000 / self -> config .baudRate_Bps ) / 1000 ;
406
+ if (timeout_budget > block_time ) {
407
+ // Send the first block.
408
+ xfer .data = (uint8_t * )buf_in ;
409
+ sent = size - self -> txbuf_len ;
410
+ offset = xfer .dataSize = sent ;
411
+ self -> tx_status = kStatus_LPUART_TxBusy ;
412
+ LPUART_TransferSendNonBlocking (self -> lpuart , & self -> handle , & xfer );
413
+
414
+ // Wait at least the number of character times for this chunk.
415
+ t = ticks_us64 () + (uint64_t )xfer .dataSize * (13000000 / self -> config .baudRate_Bps + 1000 );
416
+ while (self -> tx_status != kStatus_LPUART_TxIdle ) {
417
+ // Wait for the first/next character to be sent.
418
+ if (ticks_us64 () > t ) { // timed out
419
+ if (self -> handle .txDataSize >= sent ) {
420
+ * errcode = MP_ETIMEDOUT ;
421
+ return MP_STREAM_ERROR ;
422
+ } else {
423
+ return sent - self -> handle .txDataSize ;
424
+ }
407
425
}
426
+ MICROPY_EVENT_POLL_HOOK
408
427
}
409
- MICROPY_EVENT_POLL_HOOK
410
428
}
429
+ // In any case, just sent a buffer sized chunk in the next step
411
430
remaining = self -> txbuf_len ;
412
- } else {
413
- // The data fits into the tx buffer.
414
- offset = 0 ;
415
- remaining = size ;
416
431
}
417
432
418
433
// Send the remaining data without waiting for completion.
@@ -422,7 +437,7 @@ STATIC mp_uint_t machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uin
422
437
self -> tx_status = kStatus_LPUART_TxBusy ;
423
438
LPUART_TransferSendNonBlocking (self -> lpuart , & self -> handle , & xfer );
424
439
425
- return size ;
440
+ return sent + remaining ;
426
441
}
427
442
428
443
STATIC mp_uint_t machine_uart_ioctl (mp_obj_t self_in , mp_uint_t request , mp_uint_t arg , int * errcode ) {
0 commit comments