Skip to content

Commit b32a919

Browse files
committed
make UART.write be blocking on SAMD; add timeout property
1 parent cc00859 commit b32a919

File tree

9 files changed

+144
-85
lines changed

9 files changed

+144
-85
lines changed

ports/atmel-samd/common-hal/busio/UART.c

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -323,29 +323,23 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data,
323323
struct io_descriptor *io;
324324
usart_async_get_io_descriptor(usart_desc_p, &io);
325325

326+
// Start writing characters. This is non-blocking and will
327+
// return immediately after setting up the write.
326328
if (io_write(io, data, len) < 0) {
327329
*errcode = MP_EAGAIN;
328330
return MP_STREAM_ERROR;
329331
}
330332

331-
// Wait until write is complete or timeout.
332-
bool done = false;
333-
uint64_t start_ticks = ticks_ms;
334-
// Busy-wait for timeout.
335-
while (ticks_ms - start_ticks < self->timeout_ms) {
336-
if (usart_async_is_tx_empty(usart_desc_p)) {
337-
done = true;
333+
// Busy-wait until all characters transmitted.
334+
struct usart_async_status async_status;
335+
while (true) {
336+
usart_async_get_status(usart_desc_p, &async_status);
337+
if (async_status.txcnt >= len) {
338338
break;
339339
}
340340
RUN_BACKGROUND_TASKS;
341341
}
342342

343-
if (!done) {
344-
*errcode = MP_EAGAIN;
345-
return MP_STREAM_ERROR;
346-
}
347-
348-
// All the characters got written.
349343
return len;
350344
}
351345

@@ -368,6 +362,14 @@ void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrat
368362
self->baudrate = baudrate;
369363
}
370364

365+
mp_float_t common_hal_busio_uart_get_timeout(busio_uart_obj_t *self) {
366+
return (mp_float_t) (self->timeout_ms / 1000.0f);
367+
}
368+
369+
void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeout) {
370+
self->timeout_ms = timeout * 1000;
371+
}
372+
371373
uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
372374
// This assignment is only here because the usart_async routines take a *const argument.
373375
struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc;
@@ -383,12 +385,14 @@ void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) {
383385

384386
}
385387

388+
// True if there are no characters still to be written.
386389
bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) {
387390
if (self->tx_pin == NO_PIN) {
388391
return false;
389392
}
390393
// This assignment is only here because the usart_async routines take a *const argument.
391-
const struct _usart_async_device * const usart_device_p =
392-
(struct _usart_async_device * const) &self->usart_desc.device;
393-
return _usart_async_is_byte_sent(usart_device_p);
394+
struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc;
395+
struct usart_async_status async_status;
396+
usart_async_get_status(usart_desc_p, &async_status);
397+
return !(async_status.flags & USART_ASYNC_STATUS_BUSY);
394398
}

ports/cxd56/common-hal/busio/UART.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
102102
self->tx_pin = tx;
103103
self->rx_pin = rx;
104104
self->baudrate = baudrate;
105-
self->timeout = timeout;
105+
self->timeout_us = timeout * 1000000;
106106
}
107107

108108
void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
@@ -135,7 +135,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
135135
FD_SET(busio_uart_dev[self->number].fd, &rfds);
136136

137137
tv.tv_sec = 0;
138-
tv.tv_usec = self->timeout * 1000;
138+
tv.tv_usec = self->timeout_us;
139139

140140
retval = select(busio_uart_dev[self->number].fd + 1, &rfds, NULL, NULL, &tv);
141141

@@ -172,6 +172,14 @@ void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrat
172172
ioctl(busio_uart_dev[self->number].fd, TCFLSH, (long unsigned int)NULL);
173173
}
174174

175+
mp_float_t common_hal_busio_uart_get_timeout(busio_uart_obj_t *self) {
176+
return (mp_float_t) (self->timeout / 1000000.0f);
177+
}
178+
179+
void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeout) {
180+
self->timeout_us = timeout * 1000000;
181+
}
182+
175183
uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
176184
int count = 0;
177185

ports/cxd56/common-hal/busio/UART.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ typedef struct {
3737
const mcu_pin_obj_t *tx_pin;
3838
const mcu_pin_obj_t *rx_pin;
3939
uint32_t baudrate;
40-
uint32_t timeout;
40+
uint32_t timeout_us;
4141
} busio_uart_obj_t;
4242

4343
void busio_uart_reset(void);

ports/nrf/common-hal/busio/UART.c

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -265,19 +265,6 @@ size_t common_hal_busio_uart_write (busio_uart_obj_t *self, const uint8_t *data,
265265

266266
if ( len == 0 ) return 0;
267267

268-
uint64_t start_ticks = ticks_ms;
269-
270-
// Wait for on-going transfer to complete
271-
while ( nrfx_uarte_tx_in_progress(self->uarte) && (ticks_ms - start_ticks < self->timeout_ms) ) {
272-
RUN_BACKGROUND_TASKS;
273-
}
274-
275-
// Time up
276-
if ( !(ticks_ms - start_ticks < self->timeout_ms) ) {
277-
*errcode = MP_EAGAIN;
278-
return MP_STREAM_ERROR;
279-
}
280-
281268
// EasyDMA can only access SRAM
282269
uint8_t * tx_buf = (uint8_t*) data;
283270
if ( !nrfx_is_in_ram(data) ) {
@@ -290,7 +277,8 @@ size_t common_hal_busio_uart_write (busio_uart_obj_t *self, const uint8_t *data,
290277
_VERIFY_ERR(*errcode);
291278
(*errcode) = 0;
292279

293-
while ( nrfx_uarte_tx_in_progress(self->uarte) && (ticks_ms - start_ticks < self->timeout_ms) ) {
280+
// Wait for write to complete.
281+
while ( nrfx_uarte_tx_in_progress(self->uarte) ) {
294282
RUN_BACKGROUND_TASKS;
295283
}
296284

@@ -310,6 +298,14 @@ void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrat
310298
nrf_uarte_baudrate_set(self->uarte->p_reg, get_nrf_baud(baudrate));
311299
}
312300

301+
mp_float_t common_hal_busio_uart_get_timeout(busio_uart_obj_t *self) {
302+
return (mp_float_t) (self->timeout_ms / 1000.0f);
303+
}
304+
305+
void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeout) {
306+
self->timeout_ms = timeout * 1000;
307+
}
308+
313309
uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
314310
return ringbuf_count(&self->rbuf);
315311
}

0 commit comments

Comments
 (0)