33
33
#include "samd_soc.h"
34
34
#include "tusb.h"
35
35
36
- #if MICROPY_KBD_EXCEPTION
37
- int mp_interrupt_char = -1 ;
38
-
39
- void tud_cdc_rx_wanted_cb (uint8_t itf , char wanted_char ) {
40
- (void )itf ;
41
- (void )wanted_char ;
42
- tud_cdc_read_char (); // discard interrupt char
43
- mp_sched_keyboard_interrupt ();
44
- }
36
+ #ifndef MICROPY_HW_STDIN_BUFFER_LEN
37
+ #define MICROPY_HW_STDIN_BUFFER_LEN 128
38
+ #endif
39
+
40
+ STATIC uint8_t stdin_ringbuf_array [MICROPY_HW_STDIN_BUFFER_LEN ];
41
+ ringbuf_t stdin_ringbuf = { stdin_ringbuf_array , sizeof (stdin_ringbuf_array ), 0 , 0 };
45
42
46
- void mp_hal_set_interrupt_char (int c ) {
47
- mp_interrupt_char = c ;
48
- tud_cdc_set_wanted_char (c );
43
+ uint8_t cdc_itf_pending ; // keep track of cdc interfaces which need attention to poll
44
+
45
+ void poll_cdc_interfaces (void ) {
46
+ // any CDC interfaces left to poll?
47
+ if (cdc_itf_pending && ringbuf_free (& stdin_ringbuf )) {
48
+ for (uint8_t itf = 0 ; itf < 8 ; ++ itf ) {
49
+ if (cdc_itf_pending & (1 << itf )) {
50
+ tud_cdc_rx_cb (itf );
51
+ if (!cdc_itf_pending ) {
52
+ break ;
53
+ }
54
+ }
55
+ }
56
+ }
49
57
}
50
58
51
- #endif
59
+ void tud_cdc_rx_cb (uint8_t itf ) {
60
+ // consume pending USB data immediately to free usb buffer and keep the endpoint from stalling.
61
+ // in case the ringbuffer is full, mark the CDC interface that need attention later on for polling
62
+ cdc_itf_pending &= ~(1 << itf );
63
+ for (uint32_t bytes_avail = tud_cdc_n_available (itf ); bytes_avail > 0 ; -- bytes_avail ) {
64
+ if (ringbuf_free (& stdin_ringbuf )) {
65
+ int data_char = tud_cdc_read_char ();
66
+ #if MICROPY_KBD_EXCEPTION
67
+ if (data_char == mp_interrupt_char ) {
68
+ // Clear the ring buffer
69
+ stdin_ringbuf .iget = stdin_ringbuf .iput = 0 ;
70
+ // and stop
71
+ mp_sched_keyboard_interrupt ();
72
+ } else {
73
+ ringbuf_put (& stdin_ringbuf , data_char );
74
+ }
75
+ #else
76
+ ringbuf_put (& stdin_ringbuf , data_char );
77
+ #endif
78
+ } else {
79
+ cdc_itf_pending |= (1 << itf );
80
+ return ;
81
+ }
82
+ }
83
+ }
52
84
53
85
void mp_hal_set_pin_mux (mp_hal_pin_obj_t pin , uint8_t mux ) {
54
86
int pin_grp = pin / 32 ;
@@ -94,9 +126,12 @@ void mp_hal_delay_us(mp_uint_t us) {
94
126
95
127
uintptr_t mp_hal_stdio_poll (uintptr_t poll_flags ) {
96
128
uintptr_t ret = 0 ;
97
- if (tud_cdc_connected () && tud_cdc_available ()) {
129
+
130
+ poll_cdc_interfaces ();
131
+ if ((poll_flags & MP_STREAM_POLL_RD ) && ringbuf_peek (& stdin_ringbuf ) != -1 ) {
98
132
ret |= MP_STREAM_POLL_RD ;
99
133
}
134
+
100
135
#if MICROPY_PY_OS_DUPTERM
101
136
ret |= mp_uos_dupterm_poll (poll_flags );
102
137
#endif
@@ -105,13 +140,13 @@ uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) {
105
140
106
141
int mp_hal_stdin_rx_chr (void ) {
107
142
for (;;) {
108
- if (tud_cdc_connected () && tud_cdc_available ()) {
109
- uint8_t buf [1 ];
110
- uint32_t count = tud_cdc_read (buf , sizeof (buf ));
111
- if (count ) {
112
- return buf [0 ];
113
- }
143
+
144
+ poll_cdc_interfaces ();
145
+ int c = ringbuf_get (& stdin_ringbuf );
146
+ if (c != -1 ) {
147
+ return c ;
114
148
}
149
+
115
150
#if MICROPY_PY_OS_DUPTERM
116
151
int dupterm_c = mp_uos_dupterm_rx_chr ();
117
152
if (dupterm_c >= 0 ) {
0 commit comments