24
24
* THE SOFTWARE.
25
25
*/
26
26
27
+ /** TODO:
28
+ * - Fix readline issue
29
+ *
30
+ */
31
+
27
32
#if CIRCUITPY_BUSIO_UART
28
33
34
+ #include "mpconfigport.h"
35
+ #include "supervisor/shared/tick.h"
36
+
29
37
#include "shared-bindings/microcontroller/__init__.h"
30
38
#include "shared-bindings/microcontroller/Pin.h"
31
- #include "supervisor/shared/tick.h"
32
39
#include "shared-bindings/busio/UART.h"
33
-
34
40
#include "shared-bindings/microcontroller/Pin.h"
35
-
36
- #include "mpconfigport.h"
37
41
#include "shared/readline/readline.h"
38
42
#include "shared/runtime/interrupt_char.h"
43
+
39
44
#include "py/gc.h"
45
+ #include "py/ringbuf.h"
40
46
#include "py/mperrno.h"
47
+ #include "py/mpprint.h"
41
48
#include "py/runtime.h"
42
49
43
50
#include "max32_port.h"
47
54
// UART IRQ Priority
48
55
#define UART_PRIORITY 1
49
56
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
-
73
57
typedef enum {
74
58
UART_9600 = 9600 ,
75
59
UART_14400 = 14400 ,
@@ -82,7 +66,6 @@ typedef enum {
82
66
UART_921600 = 921600 ,
83
67
} uart_valid_baudrates ;
84
68
85
-
86
69
typedef enum {
87
70
UART_FREE = 0 ,
88
71
UART_BUSY ,
@@ -97,6 +80,7 @@ static uint8_t uarts_active = 0;
97
80
static uart_status_t uart_status [NUM_UARTS ];
98
81
static volatile int uart_err ;
99
82
static uint8_t uart_never_reset_mask = 0 ;
83
+ static busio_uart_obj_t * context ;
100
84
101
85
static int isValidBaudrate (uint32_t baudrate ) {
102
86
switch (baudrate ) {
@@ -159,6 +143,10 @@ void uart_isr(void) {
159
143
static volatile void uartCallback (mxc_uart_req_t * req , int error ) {
160
144
uart_status [MXC_UART_GET_IDX (req -> uart )] = UART_FREE ;
161
145
uart_err = error ;
146
+
147
+ MXC_SYS_Crit_Enter ();
148
+ ringbuf_put_n (context -> ringbuf , req -> rxData , req -> rxLen );
149
+ MXC_SYS_Crit_Exit ();
162
150
}
163
151
164
152
// Construct an underlying UART object.
@@ -183,9 +171,15 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
183
171
self -> uart_id = temp ;
184
172
self -> uart_regs = MXC_UART_GET_UART (temp );
185
173
}
186
-
187
174
assert ((self -> uart_id >= 0 ) && (self -> uart_id < NUM_UARTS ));
188
175
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
+
189
183
// Indicate RS485 not implemented
190
184
if ((rs485_dir != NULL ) || (rs485_invert )) {
191
185
mp_raise_NotImplementedError (MP_ERROR_TEXT ("RS485" ));
@@ -246,12 +240,31 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
246
240
self -> timeout = timeout ;
247
241
}
248
242
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
+
250
261
NVIC_ClearPendingIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
251
262
NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
252
263
NVIC_SetPriority (MXC_UART_GET_IRQ (self -> uart_id ), UART_PRIORITY );
253
264
NVIC_SetVector (MXC_UART_GET_IRQ (self -> uart_id ), (uint32_t )uart_isr );
254
265
266
+ NVIC_EnableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
267
+
255
268
return ;
256
269
}
257
270
@@ -260,7 +273,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
260
273
261
274
if (!common_hal_busio_uart_deinited (self )) {
262
275
// First disable the ISR to avoid pre-emption
263
- NVIC_DisableIRQ (UART0_IRQn );
276
+ NVIC_DisableIRQ (MXC_UART_GET_IRQ ( self -> uart_id ) );
264
277
265
278
// Shutdown the UART Controller
266
279
MXC_UART_Shutdown (self -> uart_regs );
@@ -280,6 +293,8 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
280
293
self -> cts_pin = NULL ;
281
294
self -> rts_pin = NULL ;
282
295
296
+ ringbuf_deinit (self -> ringbuf );
297
+
283
298
// Indicate to this module that the UART is not active
284
299
uarts_active &= ~(1 << self -> uart_id );
285
300
}
@@ -306,8 +321,6 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self,
306
321
uart_status [self -> uart_id ] = UART_BUSY ;
307
322
bytes_remaining = len ;
308
323
309
- NVIC_EnableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
310
-
311
324
mxc_uart_req_t uart_rd_req ;
312
325
uart_rd_req .rxCnt = 0 ;
313
326
uart_rd_req .txCnt = 0 ;
@@ -341,13 +354,16 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self,
341
354
}
342
355
// Check for errors from the callback
343
356
else if (uart_err != E_NO_ERROR ) {
357
+ mp_printf (& mp_sys_stdout_print , "MAX32 ERR: %d\n" , uart_err );
344
358
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 );
347
359
}
348
360
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 ;
351
367
}
352
368
353
369
// Write characters. len is in characters NOT bytes!
@@ -391,11 +407,10 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self,
391
407
(supervisor_ticks_ms64 () - start_time < (self -> timeout * 1000 ))) {
392
408
393
409
// 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 );
395
411
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 );
399
414
}
400
415
}
401
416
@@ -407,9 +422,8 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self,
407
422
}
408
423
// Check for errors from the callback
409
424
else if (uart_err != E_NO_ERROR ) {
425
+ mp_printf (& mp_sys_stdout_print , "MAX32 ERR: %d\n" , uart_err );
410
426
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 );
413
427
}
414
428
415
429
return len ;
@@ -444,11 +458,12 @@ void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeou
444
458
}
445
459
446
460
uint32_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 );
448
462
}
449
463
450
464
void common_hal_busio_uart_clear_rx_buffer (busio_uart_obj_t * self ) {
451
465
MXC_UART_ClearRXFIFO (self -> uart_regs );
466
+ ringbuf_clear (self -> ringbuf );
452
467
}
453
468
454
469
bool common_hal_busio_uart_ready_to_tx (busio_uart_obj_t * self ) {
0 commit comments