29
29
#include "py/mphal.h"
30
30
#include "extmod/misc.h"
31
31
#include "shared/timeutils/timeutils.h"
32
+ #include "shared/runtime/interrupt_char.h"
32
33
#include "tusb.h"
33
34
#include "uart.h"
34
35
#include "hardware/rtc.h"
35
36
36
- #if MICROPY_HW_ENABLE_UART_REPL
37
+ #if MICROPY_HW_ENABLE_UART_REPL || MICROPY_HW_ENABLE_USBDEV
37
38
38
- #ifndef UART_BUFFER_LEN
39
- // reasonably big so we can paste
40
- #define UART_BUFFER_LEN 256
39
+ #ifndef MICROPY_HW_STDIN_BUFFER_LEN
40
+ #define MICROPY_HW_STDIN_BUFFER_LEN 512
41
41
#endif
42
42
43
- STATIC uint8_t stdin_ringbuf_array [UART_BUFFER_LEN ];
43
+ STATIC uint8_t stdin_ringbuf_array [MICROPY_HW_STDIN_BUFFER_LEN ];
44
44
ringbuf_t stdin_ringbuf = { stdin_ringbuf_array , sizeof (stdin_ringbuf_array ) };
45
45
46
- #endif
47
-
48
- #if MICROPY_KBD_EXCEPTION
49
-
50
- int mp_interrupt_char = -1 ;
51
-
52
- void tud_cdc_rx_wanted_cb (uint8_t itf , char wanted_char ) {
53
- (void )itf ;
54
- (void )wanted_char ;
55
- tud_cdc_read_char (); // discard interrupt char
56
- mp_sched_keyboard_interrupt ();
46
+ #if MICROPY_HW_ENABLE_USBDEV
47
+ uint8_t cdc_itf_pending ; // keep track of cdc interfaces which needs attention to poll
48
+
49
+ void poll_cdc_interfaces (void ) {
50
+ // any CDC interfaces left to poll?
51
+ if (cdc_itf_pending && ringbuf_free (& stdin_ringbuf )) {
52
+ for (uint8_t itf = 0 ; itf < 8 ; ++ itf ) {
53
+ if (cdc_itf_pending & (1 << itf )) {
54
+ tud_cdc_rx_cb (itf );
55
+ if (!cdc_itf_pending ) {
56
+ break ;
57
+ }
58
+ }
59
+ }
60
+ }
57
61
}
58
62
59
- void mp_hal_set_interrupt_char (int c ) {
60
- mp_interrupt_char = c ;
61
- tud_cdc_set_wanted_char (c );
63
+ void tud_cdc_rx_cb (uint8_t itf ) {
64
+ // consume pending USB data immediately to free usb buffer and keep the endpoint from stalling.
65
+ // in case the ringbuffer is full, mark the CDC interface that need attention later on for polling
66
+ cdc_itf_pending &= ~(1 << itf );
67
+ for (uint32_t bytes_avail = tud_cdc_n_available (itf ); bytes_avail > 0 ; bytes_avail -- ) {
68
+ if (ringbuf_free (& stdin_ringbuf )) {
69
+ int data_char = tud_cdc_read_char ();
70
+ if (data_char == mp_interrupt_char ) {
71
+ mp_sched_keyboard_interrupt ();
72
+ } else {
73
+ ringbuf_put (& stdin_ringbuf , data_char );
74
+ }
75
+ } else {
76
+ cdc_itf_pending |= (1 << itf );
77
+ return ;
78
+ }
79
+ }
62
80
}
63
-
81
+ #endif
64
82
#endif
65
83
66
84
uintptr_t mp_hal_stdio_poll (uintptr_t poll_flags ) {
67
85
uintptr_t ret = 0 ;
68
- #if MICROPY_HW_ENABLE_UART_REPL
69
- if ((poll_flags & MP_STREAM_POLL_RD ) && ringbuf_peek (& stdin_ringbuf ) != -1 ) {
70
- ret |= MP_STREAM_POLL_RD ;
71
- }
72
- #endif
73
86
#if MICROPY_HW_ENABLE_USBDEV
74
- if (tud_cdc_connected () && tud_cdc_available ()) {
87
+ poll_cdc_interfaces ();
88
+ #endif
89
+ #if MICROPY_HW_ENABLE_UART_REPL || MICROPY_HW_ENABLE_USBDEV
90
+ if ((poll_flags & MP_STREAM_POLL_RD ) && ringbuf_peek (& stdin_ringbuf ) != -1 ) {
75
91
ret |= MP_STREAM_POLL_RD ;
76
92
}
77
93
#endif
@@ -84,21 +100,14 @@ uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) {
84
100
// Receive single character
85
101
int mp_hal_stdin_rx_chr (void ) {
86
102
for (;;) {
87
- #if MICROPY_HW_ENABLE_UART_REPL
103
+ #if MICROPY_HW_ENABLE_USBDEV
104
+ poll_cdc_interfaces ();
105
+ #endif
106
+
88
107
int c = ringbuf_get (& stdin_ringbuf );
89
108
if (c != -1 ) {
90
109
return c ;
91
110
}
92
- #endif
93
- #if MICROPY_HW_ENABLE_USBDEV
94
- if (tud_cdc_connected () && tud_cdc_available ()) {
95
- uint8_t buf [1 ];
96
- uint32_t count = tud_cdc_read (buf , sizeof (buf ));
97
- if (count ) {
98
- return buf [0 ];
99
- }
100
- }
101
- #endif
102
111
#if MICROPY_PY_OS_DUPTERM
103
112
int dupterm_c = mp_uos_dupterm_rx_chr ();
104
113
if (dupterm_c >= 0 ) {
@@ -123,11 +132,9 @@ void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
123
132
n = CFG_TUD_CDC_EP_BUFSIZE ;
124
133
}
125
134
while (n > tud_cdc_write_available ()) {
126
- tud_task ();
127
- tud_cdc_write_flush ();
135
+ MICROPY_EVENT_POLL_HOOK
128
136
}
129
137
uint32_t n2 = tud_cdc_write (str + i , n );
130
- tud_task ();
131
138
tud_cdc_write_flush ();
132
139
i += n2 ;
133
140
}
0 commit comments