5252
5353static 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+
5570static 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
139160bool 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
260269uint32_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
264273void 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
272280bool common_hal_busio_uart_ready_to_tx (busio_uart_obj_t * self ) {
0 commit comments