2424 * THE SOFTWARE.
2525 */
2626
27+ /** TODO:
28+ * - Fix readline issue
29+ *
30+ */
31+
2732#if CIRCUITPY_BUSIO_UART
2833
34+ #include "mpconfigport.h"
35+ #include "supervisor/shared/tick.h"
36+
2937#include "shared-bindings/microcontroller/__init__.h"
3038#include "shared-bindings/microcontroller/Pin.h"
31- #include "supervisor/shared/tick.h"
3239#include "shared-bindings/busio/UART.h"
33-
3440#include "shared-bindings/microcontroller/Pin.h"
35-
36- #include "mpconfigport.h"
3741#include "shared/readline/readline.h"
3842#include "shared/runtime/interrupt_char.h"
43+
3944#include "py/gc.h"
45+ #include "py/ringbuf.h"
4046#include "py/mperrno.h"
47+ #include "py/mpprint.h"
4148#include "py/runtime.h"
4249
4350#include "max32_port.h"
4754// UART IRQ Priority
4855#define UART_PRIORITY 1
4956
50- /**
51- *
52- // Define a struct for what BUSIO.UART should contain
53- typedef struct {
54- mp_obj_base_t base;
55- int uart_id;
56- mxc_uart_regs_t* uart_regs;
57-
58- const mcu_pin_obj_t *rx_pin;
59- const mcu_pin_obj_t *tx_pin;
60- const mcu_pin_obj_t *rts_pin;
61- const mcu_pin_obj_t *cts_pin;
62-
63- uint8_t bits;
64- uint32_t baudrate;
65- bool parity;
66- uint8_t stop_bits;
67-
68- uint32_t timeout_ms;
69- bool error;
70- } busio_uart_obj_t;
71- */
72-
7357typedef enum {
7458 UART_9600 = 9600 ,
7559 UART_14400 = 14400 ,
@@ -82,7 +66,6 @@ typedef enum {
8266 UART_921600 = 921600 ,
8367} uart_valid_baudrates ;
8468
85-
8669typedef enum {
8770 UART_FREE = 0 ,
8871 UART_BUSY ,
@@ -97,6 +80,7 @@ static uint8_t uarts_active = 0;
9780static uart_status_t uart_status [NUM_UARTS ];
9881static volatile int uart_err ;
9982static uint8_t uart_never_reset_mask = 0 ;
83+ static busio_uart_obj_t * context ;
10084
10185static int isValidBaudrate (uint32_t baudrate ) {
10286 switch (baudrate ) {
@@ -159,6 +143,10 @@ void uart_isr(void) {
159143static volatile void uartCallback (mxc_uart_req_t * req , int error ) {
160144 uart_status [MXC_UART_GET_IDX (req -> uart )] = UART_FREE ;
161145 uart_err = error ;
146+
147+ MXC_SYS_Crit_Enter ();
148+ ringbuf_put_n (context -> ringbuf , req -> rxData , req -> rxLen );
149+ MXC_SYS_Crit_Exit ();
162150}
163151
164152// Construct an underlying UART object.
@@ -183,9 +171,15 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
183171 self -> uart_id = temp ;
184172 self -> uart_regs = MXC_UART_GET_UART (temp );
185173 }
186-
187174 assert ((self -> uart_id >= 0 ) && (self -> uart_id < NUM_UARTS ));
188175
176+ // Check for size of ringbuffer, desire powers of 2
177+ // At least use 1 byte if no size is given
178+ assert ((receiver_buffer_size & (receiver_buffer_size - 1 )) == 0 );
179+ if (receiver_buffer_size == 0 ) {
180+ receiver_buffer_size += 1 ;
181+ }
182+
189183 // Indicate RS485 not implemented
190184 if ((rs485_dir != NULL ) || (rs485_invert )) {
191185 mp_raise_NotImplementedError (MP_ERROR_TEXT ("RS485" ));
@@ -246,12 +240,31 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
246240 self -> timeout = timeout ;
247241 }
248242
249- /* Setup UART interrupt */
243+ // Initialize ringbuffer
244+ if (receiver_buffer == NULL ) {
245+ self -> ringbuf = gc_alloc (receiver_buffer_size , false);
246+ if (!ringbuf_alloc (self -> ringbuf , receiver_buffer_size )) {
247+ m_malloc_fail (receiver_buffer_size );
248+ mp_raise_RuntimeError (MP_ERROR_TEXT ("ERR: Could not init ringbuffer\n" ));
249+ }
250+ } else {
251+ if (!(ringbuf_init (self -> ringbuf , receiver_buffer , receiver_buffer_size ))) {
252+ mp_raise_RuntimeError (MP_ERROR_TEXT ("ERR: Could not init ringbuffer\n" ));
253+ }
254+ ;
255+ }
256+
257+ context = self ;
258+
259+ // Setup UART interrupt
260+
250261 NVIC_ClearPendingIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
251262 NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
252263 NVIC_SetPriority (MXC_UART_GET_IRQ (self -> uart_id ), UART_PRIORITY );
253264 NVIC_SetVector (MXC_UART_GET_IRQ (self -> uart_id ), (uint32_t )uart_isr );
254265
266+ NVIC_EnableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
267+
255268 return ;
256269}
257270
@@ -260,7 +273,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
260273
261274 if (!common_hal_busio_uart_deinited (self )) {
262275 // First disable the ISR to avoid pre-emption
263- NVIC_DisableIRQ (UART0_IRQn );
276+ NVIC_DisableIRQ (MXC_UART_GET_IRQ ( self -> uart_id ) );
264277
265278 // Shutdown the UART Controller
266279 MXC_UART_Shutdown (self -> uart_regs );
@@ -280,6 +293,8 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
280293 self -> cts_pin = NULL ;
281294 self -> rts_pin = NULL ;
282295
296+ ringbuf_deinit (self -> ringbuf );
297+
283298 // Indicate to this module that the UART is not active
284299 uarts_active &= ~(1 << self -> uart_id );
285300 }
@@ -306,8 +321,6 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self,
306321 uart_status [self -> uart_id ] = UART_BUSY ;
307322 bytes_remaining = len ;
308323
309- NVIC_EnableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
310-
311324 mxc_uart_req_t uart_rd_req ;
312325 uart_rd_req .rxCnt = 0 ;
313326 uart_rd_req .txCnt = 0 ;
@@ -341,13 +354,16 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self,
341354 }
342355 // Check for errors from the callback
343356 else if (uart_err != E_NO_ERROR ) {
357+ mp_printf (& mp_sys_stdout_print , "MAX32 ERR: %d\n" , uart_err );
344358 MXC_UART_AbortAsync (self -> uart_regs );
345- NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
346- mp_raise_RuntimeError_varg (MP_ERROR_TEXT ("MAX32 ERR: %d\n" ), uart_err );
347359 }
348360
349- NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
350- return len ;
361+ // Copy the data from the ringbuf (or return error)
362+ MXC_SYS_Crit_Enter ();
363+ err = ringbuf_get_n (context -> ringbuf , data , len );
364+ MXC_SYS_Crit_Exit ();
365+
366+ return err ;
351367}
352368
353369// Write characters. len is in characters NOT bytes!
@@ -391,11 +407,10 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self,
391407 (supervisor_ticks_ms64 () - start_time < (self -> timeout * 1000 ))) {
392408
393409 // Call the handler and abort if errors
394- uart_err = MXC_UART_AsyncHandler (MXC_UART_GET_UART ( 0 ) );
410+ uart_err = MXC_UART_AsyncHandler (self -> uart_regs );
395411 if (uart_err != E_NO_ERROR ) {
396- MXC_UART_AbortAsync (MXC_UART_GET_UART (0 ));
397- NVIC_DisableIRQ (MXC_UART_GET_IRQ (0 ));
398- mp_raise_RuntimeError_varg (MP_ERROR_TEXT ("MAX32 ERR: %d\n" ), uart_err );
412+ mp_printf (& mp_sys_stdout_print , "MAX32 ERR: %d\n" , uart_err );
413+ MXC_UART_AbortAsync (self -> uart_regs );
399414 }
400415 }
401416
@@ -407,9 +422,8 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self,
407422 }
408423 // Check for errors from the callback
409424 else if (uart_err != E_NO_ERROR ) {
425+ mp_printf (& mp_sys_stdout_print , "MAX32 ERR: %d\n" , uart_err );
410426 MXC_UART_AbortAsync (self -> uart_regs );
411- NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
412- mp_raise_RuntimeError_varg (MP_ERROR_TEXT ("MAX32 ERR: %d\n" ), uart_err );
413427 }
414428
415429 return len ;
@@ -444,11 +458,12 @@ void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeou
444458}
445459
446460uint32_t common_hal_busio_uart_rx_characters_available (busio_uart_obj_t * self ) {
447- return MXC_UART_GetRXFIFOAvailable (self -> uart_regs );
461+ return ringbuf_num_filled (self -> ringbuf );
448462}
449463
450464void common_hal_busio_uart_clear_rx_buffer (busio_uart_obj_t * self ) {
451465 MXC_UART_ClearRXFIFO (self -> uart_regs );
466+ ringbuf_clear (self -> ringbuf );
452467}
453468
454469bool common_hal_busio_uart_ready_to_tx (busio_uart_obj_t * self ) {
0 commit comments