@@ -58,7 +58,9 @@ uintptr_t mp_usbd_cdc_poll_interfaces(uintptr_t poll_flags) {
58
58
if ((poll_flags & MP_STREAM_POLL_RD ) && ringbuf_peek (& stdin_ringbuf ) != -1 ) {
59
59
ret |= MP_STREAM_POLL_RD ;
60
60
}
61
- if ((poll_flags & MP_STREAM_POLL_WR ) && tud_cdc_connected () && tud_cdc_write_available () > 0 ) {
61
+ if ((poll_flags & MP_STREAM_POLL_WR ) &&
62
+ (!tud_cdc_connected () || (tud_cdc_connected () && tud_cdc_write_available () > 0 ))) {
63
+ // Always allow write when not connected, fifo will retain latest.
62
64
// When connected operate as blocking, only allow if space is available.
63
65
ret |= MP_STREAM_POLL_WR ;
64
66
}
@@ -93,42 +95,60 @@ void tud_cdc_rx_cb(uint8_t itf) {
93
95
94
96
mp_uint_t mp_usbd_cdc_tx_strn (const char * str , mp_uint_t len ) {
95
97
size_t i = 0 ;
96
- if (tud_cdc_connected ()) {
97
- while (i < len ) {
98
- uint32_t n = len - i ;
99
- if (n > CFG_TUD_CDC_EP_BUFSIZE ) {
100
- n = CFG_TUD_CDC_EP_BUFSIZE ;
101
- }
102
- int timeout = 0 ;
103
- // Wait with a max of USC_CDC_TIMEOUT ms
104
- while (n > tud_cdc_write_available () && timeout ++ < MICROPY_HW_USB_CDC_TX_TIMEOUT ) {
98
+ while (i < len ) {
99
+ uint32_t n = len - i ;
100
+ if (n > CFG_TUD_CDC_EP_BUFSIZE ) {
101
+ n = CFG_TUD_CDC_EP_BUFSIZE ;
102
+ }
103
+ int timeout = 0 ;
104
+ if (tud_cdc_connected ()) {
105
+ // If cdc port is connected but the buffer is full,
106
+ // wait for up to USC_CDC_TIMEOUT ms
107
+ while (n > tud_cdc_write_available ()
108
+ && timeout ++ < MICROPY_HW_USB_CDC_TX_TIMEOUT ) {
105
109
mp_event_wait_ms (1 );
106
110
107
111
// Explicitly run the USB stack as the scheduler may be locked (eg we
108
112
// are in an interrupt handler), while there is data pending.
109
113
mp_usbd_task ();
110
114
}
111
- if (timeout >= MICROPY_HW_USB_CDC_TX_TIMEOUT ) {
115
+ // Limit write to available space in tx buffer when connected.
116
+ n = MIN (n , tud_cdc_write_available ());
117
+ if (n == 0 ) {
112
118
break ;
113
119
}
114
- uint32_t n2 = tud_cdc_write (str + i , n );
115
- tud_cdc_write_flush ();
116
- i += n2 ;
117
120
}
121
+ // When not connected we always write to usb fifo, ensuring it has latest data.
122
+ uint32_t n2 = tud_cdc_write (str + i , n );
123
+ tud_cdc_write_flush ();
124
+ i += n2 ;
118
125
}
119
126
return i ;
120
127
}
121
128
129
+ static int8_t cdc_connected_flush_delay = 0 ;
130
+
131
+ void tud_sof_cb (uint32_t frame_count ) {
132
+ if (-- cdc_connected_flush_delay < 0 ) {
133
+ // Finished on-connection delay, disable SOF interrupt again.
134
+ // Finished on-connection delay, disable SOF interrupt again.
135
+ tud_sof_cb_enable (false);
136
+ tud_cdc_write_flush ();
137
+ }
138
+ }
139
+
122
140
#endif
123
141
124
- #if MICROPY_HW_USB_CDC_1200BPS_TOUCH && MICROPY_HW_ENABLE_USBDEV
142
+ #if MICROPY_HW_ENABLE_USBDEV && ( MICROPY_HW_USB_CDC_1200BPS_TOUCH || MICROPY_HW_USB_CDC )
125
143
144
+ #if MICROPY_HW_USB_CDC_1200BPS_TOUCH
126
145
static mp_sched_node_t mp_bootloader_sched_node ;
127
146
128
147
static void usbd_cdc_run_bootloader_task (mp_sched_node_t * node ) {
129
148
mp_hal_delay_ms (250 );
130
149
machine_bootloader (0 , NULL );
131
150
}
151
+ #endif
132
152
133
153
void
134
154
#if MICROPY_HW_USB_EXTERNAL_TINYUSB
@@ -137,6 +157,16 @@ mp_usbd_line_state_cb
137
157
tud_cdc_line_state_cb
138
158
#endif
139
159
(uint8_t itf , bool dtr , bool rts ) {
160
+ #if MICROPY_HW_USB_CDC
161
+ if (dtr ) {
162
+ // A host application has started to open the cdc serial port.
163
+ // Wait a few ms for host to be ready then send tx buffer.
164
+ // High speed connection SOF fires at 125us, full speed at 1ms.
165
+ cdc_connected_flush_delay = (tud_speed_get () == TUSB_SPEED_HIGH ) ? 128 : 16 ;
166
+ tud_sof_cb_enable (true);
167
+ }
168
+ #endif
169
+ #if MICROPY_HW_USB_CDC_1200BPS_TOUCH
140
170
if (dtr == false && rts == false) {
141
171
// Device is disconnected.
142
172
cdc_line_coding_t line_coding ;
@@ -146,6 +176,7 @@ tud_cdc_line_state_cb
146
176
mp_sched_schedule_node (& mp_bootloader_sched_node , usbd_cdc_run_bootloader_task );
147
177
}
148
178
}
179
+ #endif
149
180
}
150
181
151
182
#endif
0 commit comments