Skip to content

Commit ab1f622

Browse files
committed
zephyr: Fix problem with flush at low baudrates.
Also make the read() method interrupt safe. Signed-off-by: Daniel Campora <[email protected]>
1 parent fe2bec7 commit ab1f622

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

ports/zephyr/machine_uart.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
#include <zephyr/kernel.h>
3333
#include <zephyr/drivers/uart.h>
34+
#include <zephyr/irq.h>
3435

3536
#include "py/mperrno.h"
3637
#include "py/obj.h"
@@ -62,6 +63,7 @@ typedef struct _machine_uart_obj_t {
6263
uint16_t timeout_char; // timeout waiting between chars (in ms)
6364
ringbuf_t rx_ringbuffer;
6465
ringbuf_t tx_ringbuffer;
66+
bool tx_complete;
6567
} machine_uart_obj_t;
6668

6769
static const char *_parity_name[] = {"None", "Odd", "Even", "Mark", "Space"};
@@ -168,6 +170,7 @@ static mp_obj_t mp_machine_uart_make_new(const mp_obj_type_t *type, size_t n_arg
168170

169171
machine_uart_obj_t *self = mp_obj_malloc_with_finaliser(machine_uart_obj_t, &machine_uart_type);
170172
self->dev = zephyr_device_find(args[0]);
173+
self->tx_complete = true;
171174

172175
mp_map_t kw_args;
173176
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
@@ -186,7 +189,7 @@ static mp_int_t mp_machine_uart_any(machine_uart_obj_t *self) {
186189
}
187190

188191
static bool mp_machine_uart_txdone(machine_uart_obj_t *self) {
189-
return ringbuf_avail(&self->tx_ringbuffer) ? false : true;
192+
return (ringbuf_avail(&self->tx_ringbuffer) || (self->tx_complete == false)) ? false : true;
190193
}
191194

192195
static mp_uint_t mp_machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
@@ -199,7 +202,9 @@ static mp_uint_t mp_machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t
199202
do {
200203
int _rx_len = MIN(ringbuf_avail(&self->rx_ringbuffer), size - bytes_read);
201204
if (_rx_len > 0) {
205+
uint32_t key = irq_lock();
202206
ringbuf_get_bytes(&self->rx_ringbuffer, &buffer[bytes_read], _rx_len);
207+
irq_unlock(key);
203208
bytes_read += _rx_len;
204209
elapsed_ms = 0;
205210
time_to_wait = self->timeout_char;
@@ -233,6 +238,7 @@ static mp_uint_t mp_machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_
233238
}
234239

235240
ringbuf_put_bytes(&self->tx_ringbuffer, &buffer[_ex_size], size - _ex_size);
241+
self->tx_complete = false;
236242
uart_irq_tx_enable(self->dev);
237243

238244
return size;
@@ -291,8 +297,9 @@ static void uart_interrupt_handler(const struct device *dev, void *user_data) {
291297
_buffer_tx_len = MIN(_max_uart_tx_len, _buffer_tx_len);
292298
ringbuf_get_bytes(&self->tx_ringbuffer, _tx_buffer, _buffer_tx_len);
293299
uart_fifo_fill(dev, _tx_buffer, _buffer_tx_len);
294-
} else {
300+
} else if (uart_irq_tx_complete(dev)) {
295301
uart_irq_tx_disable(dev);
302+
self->tx_complete = true;
296303
}
297304
}
298305
}

0 commit comments

Comments
 (0)