Skip to content

Commit e136222

Browse files
committed
use rbuf for busio uart
1 parent 6773fe6 commit e136222

2 files changed

Lines changed: 60 additions & 53 deletions

File tree

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

Lines changed: 58 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -52,21 +52,40 @@
5252

5353
static uint32_t get_nrf_baud (uint32_t baudrate);
5454

55+
static uint16_t ringbuf_count(ringbuf_t *r)
56+
{
57+
volatile int count = r->iput - r->iget;
58+
if ( count < 0 ) {
59+
count += r->size;
60+
}
61+
62+
return (uint16_t) count;
63+
}
64+
65+
static void ringbuf_clear(ringbuf_t *r)
66+
{
67+
r->iput = r->iget = 0;
68+
}
69+
5570
static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context) {
5671
busio_uart_obj_t* self = (busio_uart_obj_t*) context;
5772

5873
switch ( event->type ) {
5974
case NRFX_UARTE_EVT_RX_DONE:
60-
self->rx_count = event->data.rxtx.bytes;
75+
for(uint8_t i=0; i < event->data.rxtx.bytes; i++) {
76+
ringbuf_put(&self->rbuf, event->data.rxtx.p_data[i]);
77+
}
78+
79+
// keep receiving
80+
_VERIFY_ERR(nrfx_uarte_rx(&self->uarte, &self->rx_char, 1));
6181
break;
6282

6383
case NRFX_UARTE_EVT_TX_DONE:
84+
// nothing to do
6485
break;
6586

6687
case NRFX_UARTE_EVT_ERROR:
67-
if ( self->rx_count == -1 ) {
68-
self->rx_count = 0;
69-
}
88+
// Handle error
7089
break;
7190

7291
default:
@@ -110,12 +129,15 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self,
110129

111130
// Init buffer for rx
112131
if ( rx != mp_const_none ) {
113-
self->buffer = (uint8_t *) gc_alloc(receiver_buffer_size, false, false);
114-
if ( !self->buffer ) {
132+
self->rbuf.buf = (uint8_t *) gc_alloc(receiver_buffer_size, false, false);
133+
134+
if ( !self->rbuf.buf ) {
115135
nrfx_uarte_uninit(&self->uarte);
116136
mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate RX buffer"));
117137
}
118-
self->bufsize = receiver_buffer_size;
138+
139+
self->rbuf.size = receiver_buffer_size;
140+
self->rbuf.iget = self->rbuf.iput = 0;
119141

120142
self->rx_pin_number = rx->number;
121143
claim_pin(rx);
@@ -131,9 +153,8 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self,
131153
self->baudrate = baudrate;
132154
self->timeout_ms = timeout * 1000;
133155

134-
// queue 1-byte transfer for rx_characters_available()
135-
self->rx_count = -1;
136-
_VERIFY_ERR(nrfx_uarte_rx(&self->uarte, self->buffer, 1));
156+
// Initial wait for incoming byte
157+
_VERIFY_ERR(nrfx_uarte_rx(&self->uarte, &self->rx_char, 1));
137158
}
138159

139160
bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) {
@@ -147,7 +168,10 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
147168
reset_pin_number(self->rx_pin_number);
148169
self->tx_pin_number = NO_PIN;
149170
self->rx_pin_number = NO_PIN;
150-
gc_free(self->buffer);
171+
172+
gc_free(self->rbuf.buf);
173+
self->rbuf.size = 0;
174+
self->rbuf.iput = self->rbuf.iget = 0;
151175
}
152176
}
153177

@@ -157,48 +181,33 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
157181
mp_raise_ValueError(translate("No RX pin"));
158182
}
159183

160-
size_t remain = len;
184+
size_t rx_bytes = 0;
161185
uint64_t start_ticks = ticks_ms;
162186

163-
while ( 1 ) {
164-
// Wait for on-going transfer to complete
165-
while ( (self->rx_count == -1) && (ticks_ms - start_ticks < self->timeout_ms) ) {
187+
// Wait for all bytes received or timeout
188+
while ( (ringbuf_count(&self->rbuf) < len) && (ticks_ms - start_ticks < self->timeout_ms) ) {
166189
#ifdef MICROPY_VM_HOOK_LOOP
167-
MICROPY_VM_HOOK_LOOP;
168-
// Allow user to break out of a timeout with a KeyboardInterrupt.
169-
if (mp_hal_is_interrupted()) {
170-
return 0;
171-
}
172-
#endif
173-
}
174-
175-
// copy received data
176-
if ( self->rx_count > 0 ) {
177-
memcpy(data, self->buffer, self->rx_count);
178-
data += self->rx_count;
179-
remain -= self->rx_count;
180-
181-
self->rx_count = 0;
190+
MICROPY_VM_HOOK_LOOP ;
191+
// Allow user to break out of a timeout with a KeyboardInterrupt.
192+
if ( mp_hal_is_interrupted() ) {
193+
return 0;
182194
}
195+
#endif
196+
}
183197

184-
// exit if complete or time up
185-
if ( !remain || !(ticks_ms - start_ticks < self->timeout_ms) ) {
186-
break;
187-
}
198+
// prevent conflict with uart irq
199+
NVIC_DisableIRQ(nrfx_get_irq_number(self->uarte.p_reg));
188200

189-
// prepare next receiving
190-
const size_t cnt = MIN(self->bufsize, remain);
191-
self->rx_count = -1;
192-
_VERIFY_ERR(nrfx_uarte_rx(&self->uarte, self->buffer, cnt));
201+
// copy received data
202+
rx_bytes = ringbuf_count(&self->rbuf);
203+
rx_bytes = MIN(rx_bytes, len);
204+
for ( uint16_t i = 0; i < rx_bytes; i++ ) {
205+
data[i] = ringbuf_get(&self->rbuf);
193206
}
194207

195-
// queue 1-byte transfer for rx_characters_available()
196-
if ( self->rx_count == 0 ) {
197-
self->rx_count = -1;
198-
_VERIFY_ERR(nrfx_uarte_rx(&self->uarte, self->buffer, 1));
199-
}
208+
NVIC_EnableIRQ(nrfx_get_irq_number(self->uarte.p_reg));
200209

201-
return len - remain;
210+
return rx_bytes;
202211
}
203212

204213
// Write characters.
@@ -258,15 +267,14 @@ void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrat
258267
}
259268

260269
uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
261-
return (self->rx_count > 0) ? self->rx_count : 0;
270+
return ringbuf_count(&self->rbuf);
262271
}
263272

264273
void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) {
265-
// Discard received byte, and queue 1-byte transfer for rx_characters_available()
266-
if ( self->rx_count > 0 ) {
267-
self->rx_count = -1;
268-
_VERIFY_ERR(nrfx_uarte_rx(&self->uarte, self->buffer, 1));
269-
}
274+
// prevent conflict with uart irq
275+
NVIC_DisableIRQ(nrfx_get_irq_number(self->uarte.p_reg));
276+
ringbuf_clear(&self->rbuf);
277+
NVIC_EnableIRQ(nrfx_get_irq_number(self->uarte.p_reg));
270278
}
271279

272280
bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) {

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,8 @@ typedef struct {
4141
uint32_t baudrate;
4242
uint32_t timeout_ms;
4343

44-
uint8_t* buffer;
45-
uint32_t bufsize;
46-
volatile int32_t rx_count;
44+
ringbuf_t rbuf;
45+
uint8_t rx_char; // EasyDMA buf
4746

4847
uint8_t tx_pin_number;
4948
uint8_t rx_pin_number;

0 commit comments

Comments
 (0)