@@ -74,7 +74,7 @@ static uint8_t multi_desc_bytes[] = {
74
74
static struct usbd_descriptors multi_desc = {multi_desc_bytes , multi_desc_bytes + sizeof (multi_desc_bytes )};
75
75
76
76
/** Ctrl endpoint buffer */
77
- static uint8_t ctrl_buffer [64 ];
77
+ COMPILER_ALIGNED ( 4 ) static uint8_t ctrl_buffer [64 ];
78
78
79
79
static void init_hardware (void ) {
80
80
#ifdef SAMD21
@@ -107,12 +107,19 @@ static void init_hardware(void) {
107
107
#endif
108
108
}
109
109
110
- extern uint32_t * _usb_ep1_cache ;
111
- static bool usb_device_cb_bulk_out (const uint8_t ep , const enum usb_xfer_code rc , const uint32_t count )
112
- {
113
- if (rc == USB_XFER_RESET ) {
114
- return false;
110
+ COMPILER_ALIGNED (4 ) uint8_t cdc_packet_buffer [64 ];
111
+ static volatile bool pending_read ;
112
+
113
+ static int32_t start_read (void ) {
114
+ pending_read = true;
115
+ return cdcdf_acm_read (cdc_packet_buffer , 64 );
116
+ }
117
+
118
+ static bool read_complete (const uint8_t ep , const enum usb_xfer_code rc , const uint32_t count ) {
119
+ if (rc != USB_XFER_DONE ) {
120
+ return false; // No errors.
115
121
}
122
+ pending_read = false;
116
123
volatile hal_atomic_t flags ;
117
124
atomic_enter_critical (& flags );
118
125
// If our buffer can't fit the data received, then error out.
@@ -121,24 +128,12 @@ static bool usb_device_cb_bulk_out(const uint8_t ep, const enum usb_xfer_code rc
121
128
return true;
122
129
}
123
130
124
- // We read the data but ignore it later. The data itself isn't correct but
125
- // it does mark it as read so further data is received ok.
126
- // TODO(tannewt): Get ASF4 fixed so the data is correct and then stop using
127
- // _usb_ep1_cache directly below.
128
- uint8_t buf [count ];
129
- int32_t result = cdcdf_acm_read (buf , count );
130
- if (result != ERR_NONE ) {
131
- atomic_leave_critical (& flags );
132
- return true;
133
- }
134
-
135
131
for (uint16_t i = 0 ; i < count ; i ++ ) {
136
- uint8_t c = (( uint8_t * ) & _usb_ep1_cache ) [i ];
132
+ uint8_t c = cdc_packet_buffer [i ];
137
133
if (c == mp_interrupt_char ) {
138
- atomic_leave_critical (& flags );
139
134
mp_keyboard_interrupt ();
140
135
// Don't put the interrupt into the buffer, just continue.
141
- return false ;
136
+ continue ;
142
137
} else {
143
138
// The count of characters present in receive buffer is
144
139
// incremented.
@@ -154,12 +149,21 @@ static bool usb_device_cb_bulk_out(const uint8_t ep, const enum usb_xfer_code rc
154
149
}
155
150
atomic_leave_critical (& flags );
156
151
152
+ // Trigger a follow up read if we have space.
153
+ if (usb_rx_count < USB_RX_BUF_SIZE ) {
154
+ int32_t result = start_read ();
155
+ if (result != ERR_NONE ) {
156
+ return true;
157
+ }
158
+ }
159
+
157
160
/* No error. */
158
161
return false;
159
162
}
160
163
161
- static bool usb_device_cb_bulk_in (const uint8_t ep , const enum usb_xfer_code rc , const uint32_t count )
164
+ static bool write_complete (const uint8_t ep , const enum usb_xfer_code rc , const uint32_t count )
162
165
{
166
+ // This is called after writed are finished.
163
167
/* No error. */
164
168
return false;
165
169
}
@@ -193,6 +197,7 @@ void init_usb(void) {
193
197
194
198
/* usbdc_register_funcion inside */
195
199
cdcdf_acm_init ();
200
+ pending_read = false;
196
201
197
202
mscdf_init (1 );
198
203
// hiddf_mouse_init();
@@ -218,19 +223,19 @@ static inline bool cdc_enabled(void) {
218
223
if (!cdcdf_acm_is_enabled ()) {
219
224
return false;
220
225
}
221
- cdcdf_acm_register_callback (CDCDF_ACM_CB_READ , (FUNC_PTR )usb_device_cb_bulk_out );
222
- cdcdf_acm_register_callback (CDCDF_ACM_CB_WRITE , (FUNC_PTR )usb_device_cb_bulk_in );
226
+ cdcdf_acm_register_callback (CDCDF_ACM_CB_READ , (FUNC_PTR )read_complete );
227
+ cdcdf_acm_register_callback (CDCDF_ACM_CB_WRITE , (FUNC_PTR )write_complete );
223
228
cdcdf_acm_register_callback (CDCDF_ACM_CB_STATE_C , (FUNC_PTR )usb_device_cb_state_c );
224
229
cdcdf_acm_register_callback (CDCDF_ACM_CB_LINE_CODING_C , (FUNC_PTR )usb_device_cb_line_coding_c );
225
230
mp_cdc_enabled = true;
226
231
227
- // Ignored read.
228
- uint8_t buf [64 ];
229
- cdcdf_acm_read (buf , 64 );
230
232
return true;
231
233
}
232
234
233
235
bool usb_bytes_available (void ) {
236
+ if (!pending_read ) {
237
+ start_read ();
238
+ }
234
239
if (usb_rx_count == 0 ) {
235
240
cdc_enabled ();
236
241
return false;
@@ -254,6 +259,11 @@ int usb_read(void) {
254
259
}
255
260
CRITICAL_SECTION_LEAVE ();
256
261
262
+ // Trigger a new read because we just cleared some space.
263
+ if (!pending_read && usb_rx_count == USB_RX_BUF_SIZE - 1 ) {
264
+ start_read ();
265
+ }
266
+
257
267
return data ;
258
268
}
259
269
0 commit comments