35
35
#include "py/stream.h"
36
36
#include "py/mperrno.h"
37
37
#include "py/mphal.h"
38
+ #include "py/ringbuf.h"
38
39
#include "pin.h"
39
40
#include "genhdr/pins.h"
41
+ #include "lib/utils/interrupt_char.h"
40
42
41
43
#include "uart.h"
42
44
#include "mpconfigboard.h"
47
49
48
50
#if MICROPY_PY_MACHINE_UART
49
51
52
+ typedef struct _machine_hard_uart_buf_t {
53
+ uint8_t tx_buf [1 ];
54
+ uint8_t rx_buf [1 ];
55
+ uint8_t rx_ringbuf_array [64 ];
56
+ volatile ringbuf_t rx_ringbuf ;
57
+ } machine_hard_uart_buf_t ;
58
+
50
59
typedef struct _machine_hard_uart_obj_t {
51
60
mp_obj_base_t base ;
52
61
const nrfx_uart_t * p_uart ; // Driver instance
62
+ machine_hard_uart_buf_t * buf ;
53
63
} machine_hard_uart_obj_t ;
54
64
55
65
static const nrfx_uart_t instance0 = NRFX_UART_INSTANCE (0 );
56
66
67
+ STATIC machine_hard_uart_buf_t machine_hard_uart_buf [1 ];
68
+
57
69
STATIC const machine_hard_uart_obj_t machine_hard_uart_obj [] = {
58
- {{& machine_hard_uart_type }, .p_uart = & instance0 },
70
+ {{& machine_hard_uart_type }, .p_uart = & instance0 , . buf = & machine_hard_uart_buf [ 0 ] },
59
71
};
60
72
61
73
void uart_init0 (void ) {
@@ -70,27 +82,36 @@ STATIC int uart_find(mp_obj_t id) {
70
82
mp_raise_ValueError ("UART doesn't exist" );
71
83
}
72
84
73
- void uart_irq_handler (mp_uint_t uart_id ) {
74
-
85
+ STATIC void uart_event_handler (nrfx_uart_event_t const * p_event , void * p_context ) {
86
+ machine_hard_uart_obj_t * self = p_context ;
87
+ if (p_event -> type == NRFX_UART_EVT_RX_DONE ) {
88
+ int chr = self -> buf -> rx_buf [0 ];
89
+ nrfx_uart_rx (self -> p_uart , & self -> buf -> rx_buf [0 ], 1 );
90
+ #if !MICROPY_PY_BLE_NUS && MICROPY_KBD_EXCEPTION
91
+ if (chr == mp_interrupt_char ) {
92
+ mp_keyboard_interrupt ();
93
+ } else
94
+ #endif
95
+ {
96
+ ringbuf_put ((ringbuf_t * )& self -> buf -> rx_ringbuf , chr );
97
+ }
98
+ }
75
99
}
76
100
77
- bool uart_rx_any (const machine_hard_uart_obj_t * uart_obj ) {
78
- // TODO: uart will block for now.
79
- return true;
101
+ bool uart_rx_any (const machine_hard_uart_obj_t * self ) {
102
+ return self -> buf -> rx_ringbuf .iput != self -> buf -> rx_ringbuf .iget ;
80
103
}
81
104
82
105
int uart_rx_char (const machine_hard_uart_obj_t * self ) {
83
- uint8_t ch ;
84
- nrfx_uart_rx (self -> p_uart , & ch , 1 );
85
- return (int )ch ;
106
+ return ringbuf_get ((ringbuf_t * )& self -> buf -> rx_ringbuf );
86
107
}
87
108
88
109
STATIC nrfx_err_t uart_tx_char (const machine_hard_uart_obj_t * self , int c ) {
89
110
while (nrfx_uart_tx_in_progress (self -> p_uart )) {
90
111
;
91
112
}
92
-
93
- return nrfx_uart_tx (self -> p_uart , ( uint8_t * ) & c , 1 );
113
+ self -> buf -> tx_buf [ 0 ] = c ;
114
+ return nrfx_uart_tx (self -> p_uart , & self -> buf -> tx_buf [ 0 ] , 1 );
94
115
}
95
116
96
117
@@ -181,9 +202,15 @@ STATIC mp_obj_t machine_hard_uart_make_new(const mp_obj_type_t *type, size_t n_a
181
202
// Set context to this instance of UART
182
203
config .p_context = (void * )self ;
183
204
184
- // Set NULL as callback function to keep it blocking
185
- nrfx_uart_init (self -> p_uart , & config , NULL );
205
+ // Initialise ring buffer
206
+ self -> buf -> rx_ringbuf .buf = self -> buf -> rx_ringbuf_array ;
207
+ self -> buf -> rx_ringbuf .size = sizeof (self -> buf -> rx_ringbuf_array );
208
+ self -> buf -> rx_ringbuf .iget = 0 ;
209
+ self -> buf -> rx_ringbuf .iput = 0 ;
186
210
211
+ // Enable event callback and start asynchronous receive
212
+ nrfx_uart_init (self -> p_uart , & config , uart_event_handler );
213
+ nrfx_uart_rx (self -> p_uart , & self -> buf -> rx_buf [0 ], 1 );
187
214
nrfx_uart_rx_enable (self -> p_uart );
188
215
189
216
return MP_OBJ_FROM_PTR (self );
@@ -250,6 +277,8 @@ STATIC mp_uint_t machine_hard_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_
250
277
251
278
// read the data
252
279
for (size_t i = 0 ; i < size ; i ++ ) {
280
+ while (!uart_rx_any (self )) {
281
+ }
253
282
buf [i ] = uart_rx_char (self );
254
283
}
255
284
0 commit comments