Skip to content

Commit f31a7b7

Browse files
tannewtdhalbert
authored andcommitted
atmel-samd: Fix CDC now that its clear its async.
1 parent 51cd4da commit f31a7b7

File tree

1 file changed

+36
-26
lines changed

1 file changed

+36
-26
lines changed

atmel-samd/usb.c

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ static uint8_t multi_desc_bytes[] = {
7474
static struct usbd_descriptors multi_desc = {multi_desc_bytes, multi_desc_bytes + sizeof(multi_desc_bytes)};
7575

7676
/** Ctrl endpoint buffer */
77-
static uint8_t ctrl_buffer[64];
77+
COMPILER_ALIGNED(4) static uint8_t ctrl_buffer[64];
7878

7979
static void init_hardware(void) {
8080
#ifdef SAMD21
@@ -107,12 +107,19 @@ static void init_hardware(void) {
107107
#endif
108108
}
109109

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.
115121
}
122+
pending_read = false;
116123
volatile hal_atomic_t flags;
117124
atomic_enter_critical(&flags);
118125
// 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
121128
return true;
122129
}
123130

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-
135131
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];
137133
if (c == mp_interrupt_char) {
138-
atomic_leave_critical(&flags);
139134
mp_keyboard_interrupt();
140135
// Don't put the interrupt into the buffer, just continue.
141-
return false;
136+
continue;
142137
} else {
143138
// The count of characters present in receive buffer is
144139
// incremented.
@@ -154,12 +149,21 @@ static bool usb_device_cb_bulk_out(const uint8_t ep, const enum usb_xfer_code rc
154149
}
155150
atomic_leave_critical(&flags);
156151

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+
157160
/* No error. */
158161
return false;
159162
}
160163

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)
162165
{
166+
// This is called after writed are finished.
163167
/* No error. */
164168
return false;
165169
}
@@ -193,6 +197,7 @@ void init_usb(void) {
193197

194198
/* usbdc_register_funcion inside */
195199
cdcdf_acm_init();
200+
pending_read = false;
196201

197202
mscdf_init(1);
198203
// hiddf_mouse_init();
@@ -218,19 +223,19 @@ static inline bool cdc_enabled(void) {
218223
if (!cdcdf_acm_is_enabled()) {
219224
return false;
220225
}
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);
223228
cdcdf_acm_register_callback(CDCDF_ACM_CB_STATE_C, (FUNC_PTR)usb_device_cb_state_c);
224229
cdcdf_acm_register_callback(CDCDF_ACM_CB_LINE_CODING_C, (FUNC_PTR)usb_device_cb_line_coding_c);
225230
mp_cdc_enabled = true;
226231

227-
// Ignored read.
228-
uint8_t buf[64];
229-
cdcdf_acm_read(buf, 64);
230232
return true;
231233
}
232234

233235
bool usb_bytes_available(void) {
236+
if (!pending_read) {
237+
start_read();
238+
}
234239
if (usb_rx_count == 0) {
235240
cdc_enabled();
236241
return false;
@@ -254,6 +259,11 @@ int usb_read(void) {
254259
}
255260
CRITICAL_SECTION_LEAVE();
256261

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+
257267
return data;
258268
}
259269

0 commit comments

Comments
 (0)