void usb_bulk_out_task(void) { if (!sched_check_wake(&usb_bulk_out_wake)) return; // Read data uint_fast8_t rpos = receive_pos, pop_count; if (rpos + USB_CDC_EP_BULK_OUT_SIZE <= sizeof(receive_buf)) { int_fast8_t ret = usb_read_bulk_out( &receive_buf[rpos], USB_CDC_EP_BULK_OUT_SIZE); if (ret > 0) { rpos += ret; usb_notify_bulk_out(); } } else { usb_notify_bulk_out(); } // Process a message block int_fast8_t ret = command_find_and_dispatch(receive_buf, rpos, &pop_count); if (ret) { // Move buffer uint_fast8_t needcopy = rpos - pop_count; if (needcopy) { memmove(receive_buf, &receive_buf[pop_count], needcopy); usb_notify_bulk_out(); } rpos = needcopy; } receive_pos = rpos; }
void __visible USB_Handler(void) { uint8_t s = USB->DEVICE.INTFLAG.reg; if (s & USB_DEVICE_INTFLAG_EORST) { USB->DEVICE.INTFLAG.reg = USB_DEVICE_INTFLAG_EORST; // Enable endpoint 0 irqs EP0.EPINTENSET.reg = ( USB_DEVICE_EPINTENSET_TRCPT0 | USB_DEVICE_EPINTENSET_TRCPT1 | USB_DEVICE_EPINTENSET_RXSTP); } uint16_t ep = USB->DEVICE.EPINTSMRY.reg; if (ep & (1<<0)) { uint8_t sts = EP0.EPINTFLAG.reg; EP0.EPINTFLAG.reg = sts; if (set_address && sts & USB_DEVICE_EPINTFLAG_TRCPT1) { // Apply address after last "in" message transmitted USB->DEVICE.DADD.reg = set_address; set_address = 0; } usb_notify_setup(); } if (ep & (1<<USB_CDC_EP_BULK_OUT)) { uint8_t sts = EP_BULKOUT.EPINTFLAG.reg; EP_BULKOUT.EPINTFLAG.reg = sts; usb_notify_bulk_out(); } if (ep & (1<<USB_CDC_EP_BULK_IN)) { uint8_t sts = EP_BULKIN.EPINTFLAG.reg; EP_BULKIN.EPINTFLAG.reg = sts; usb_notify_bulk_in(); } }