29
29
#include "py/mpconfig.h"
30
30
#include "extmod/modmachine.h"
31
31
32
- #if MICROPY_HW_USB_CDC
32
+ #if MICROPY_HW_USB_CDC && MICROPY_HW_ENABLE_USBDEV
33
33
#include "tusb.h"
34
+ #include "device/usbd.h"
35
+
34
36
#include "shared/tinyusb/mp_usbd.h"
35
37
36
38
static uint8_t cdc_itf_pending ; // keep track of cdc interfaces which need attention to poll
@@ -83,40 +85,50 @@ void tud_cdc_rx_cb(uint8_t itf) {
83
85
84
86
mp_uint_t mp_usbd_cdc_tx_strn (const char * str , mp_uint_t len ) {
85
87
size_t i = 0 ;
86
- if (tud_cdc_connected ()) {
87
- while (i < len ) {
88
- uint32_t n = len - i ;
89
- if (n > CFG_TUD_CDC_EP_BUFSIZE ) {
90
- n = CFG_TUD_CDC_EP_BUFSIZE ;
91
- }
92
- int timeout = 0 ;
93
- // Wait with a max of USC_CDC_TIMEOUT ms
94
- while (n > tud_cdc_write_available () && timeout ++ < MICROPY_HW_USB_CDC_TX_TIMEOUT ) {
95
- mp_event_wait_ms (1 );
88
+ while (i < len ) {
89
+ uint32_t n = len - i ;
90
+ if (n > CFG_TUD_CDC_EP_BUFSIZE ) {
91
+ n = CFG_TUD_CDC_EP_BUFSIZE ;
92
+ }
93
+ int timeout = 0 ;
94
+ // Wait with a max of USC_CDC_TIMEOUT ms
95
+ while (n > tud_cdc_write_available ()
96
+ && timeout ++ < MICROPY_HW_USB_CDC_TX_TIMEOUT
97
+ && tud_cdc_connected ()) {
98
+ mp_event_wait_ms (1 );
96
99
97
- // Explicitly run the USB stack as the scheduler may be locked (eg we
98
- // are in an interrupt handler), while there is data pending.
99
- mp_usbd_task ();
100
- }
101
- if (timeout >= MICROPY_HW_USB_CDC_TX_TIMEOUT ) {
102
- break ;
103
- }
104
- uint32_t n2 = tud_cdc_write (str + i , n );
105
- tud_cdc_write_flush ();
106
- i += n2 ;
100
+ // Explicitly run the USB stack as the scheduler may be locked (eg we
101
+ // are in an interrupt handler), while there is data pending.
102
+ mp_usbd_task ();
103
+ }
104
+ n = MIN (n , tud_cdc_write_available ());
105
+ if (n == 0 ) {
106
+ break ;
107
107
}
108
+ uint32_t n2 = tud_cdc_write (str + i , n );
109
+ tud_cdc_write_flush ();
110
+ i += n2 ;
108
111
}
109
112
return i ;
110
113
}
111
114
112
- #if MICROPY_HW_USB_CDC_1200BPS_TOUCH && MICROPY_HW_ENABLE_USBDEV
115
+ static int8_t cdc_connected_flush_delay = 0 ;
113
116
117
+ void tud_sof_cb (uint32_t frame_count ) {
118
+ if (-- cdc_connected_flush_delay < 0 ) {
119
+ tud_cdc_write_flush ();
120
+ tud_sof_cb_enable (false);
121
+ }
122
+ }
123
+
124
+ #if MICROPY_HW_USB_CDC_1200BPS_TOUCH
114
125
static mp_sched_node_t mp_bootloader_sched_node ;
115
126
116
127
static void usbd_cdc_run_bootloader_task (mp_sched_node_t * node ) {
117
128
mp_hal_delay_ms (250 );
118
129
machine_bootloader (0 , NULL );
119
130
}
131
+ #endif // MICROPY_HW_USB_CDC_1200BPS_TOUCH
120
132
121
133
void
122
134
#if MICROPY_HW_USB_EXTERNAL_TINYUSB
@@ -125,6 +137,13 @@ mp_usbd_line_state_cb
125
137
tud_cdc_line_state_cb
126
138
#endif
127
139
(uint8_t itf , bool dtr , bool rts ) {
140
+ if (dtr ) {
141
+ // The host has started to open the cdc serial port.
142
+ // Wait a few ms for host to be ready then send tx buffer.
143
+ cdc_connected_flush_delay = (tud_speed_get () == TUSB_SPEED_HIGH ) ? 64 : 8 ;
144
+ tud_sof_cb_enable (true);
145
+ }
146
+ #if MICROPY_HW_USB_CDC_1200BPS_TOUCH
128
147
if (dtr == false && rts == false) {
129
148
// Device is disconnected.
130
149
cdc_line_coding_t line_coding ;
@@ -134,7 +153,7 @@ tud_cdc_line_state_cb
134
153
mp_sched_schedule_node (& mp_bootloader_sched_node , usbd_cdc_run_bootloader_task );
135
154
}
136
155
}
156
+ #endif
137
157
}
138
158
139
159
#endif
140
- #endif
0 commit comments