Skip to content

Commit 40d6c27

Browse files
committed
mimxrt: Refactor timeout handling for uart.write().
1. if a transmission is ongoing - if the blocking time is longer than the timeout, set MP_AGAIN and return MP_STREAM_ERROR. - If the blocking time is shorter than the timeout, wait. 2. if no transmission is ongoing - if the message is shorter than the buffer, just send it. - if the message is longer than the buffer and the expected blocking time is larger than the timeout, just send a buffer size amount of data and return that size. - if the message is longer than the buffer and the expected blocking time is smaller than the timeout, send all data and return that size.
1 parent e435583 commit 40d6c27

File tree

1 file changed

+37
-22
lines changed

1 file changed

+37
-22
lines changed

ports/mimxrt/machine_uart.c

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -372,9 +372,22 @@ STATIC mp_uint_t machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uin
372372
lpuart_transfer_t xfer;
373373
uint64_t t;
374374
size_t remaining = size;
375+
size_t sent = 0;
375376
size_t offset = 0;
377+
uint32_t block_time;
378+
uint32_t timeout_budget = self->timeout;
376379
uint8_t fifo_size = FSL_FEATURE_LPUART_FIFO_SIZEn(0);
377380

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+
378391
// First check if a previous transfer is still ongoing,
379392
// then wait at least the number of remaining character times.
380393
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
388401

389402
// Check if the first part has to be sent semi-blocking.
390403
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+
}
407425
}
426+
MICROPY_EVENT_POLL_HOOK
408427
}
409-
MICROPY_EVENT_POLL_HOOK
410428
}
429+
// In any case, just sent a buffer sized chunk in the next step
411430
remaining = self->txbuf_len;
412-
} else {
413-
// The data fits into the tx buffer.
414-
offset = 0;
415-
remaining = size;
416431
}
417432

418433
// 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
422437
self->tx_status = kStatus_LPUART_TxBusy;
423438
LPUART_TransferSendNonBlocking(self->lpuart, &self->handle, &xfer);
424439

425-
return size;
440+
return sent + remaining;
426441
}
427442

428443
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

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy