void usbserial_init(void) { // configure usb clock enable_pclock(USB_GCLK_ID, 0); // configure USBD+ and USBD- pins gpio_peripheral('A', 24, 'G', 0); gpio_peripheral('A', 25, 'G', 0); uint16_t trim = (readl((void*)USB_FUSES_TRIM_ADDR) & USB_FUSES_TRIM_Msk) >> USB_FUSES_TRIM_Pos; uint16_t transp = (readl((void*)USB_FUSES_TRANSP_ADDR) & USB_FUSES_TRANSP_Msk) >> USB_FUSES_TRANSP_Pos; uint16_t transn = (readl((void*)USB_FUSES_TRANSN_ADDR) & USB_FUSES_TRANSN_Msk) >> USB_FUSES_TRANSN_Pos; USB->DEVICE.PADCAL.reg = (USB_PADCAL_TRIM(trim) | USB_PADCAL_TRANSP(transp) | USB_PADCAL_TRANSN(transn)); // Enable USB in device mode USB->DEVICE.CTRLA.reg = USB_CTRLA_ENABLE; USB->DEVICE.DESCADD.reg = (uint32_t)usb_desc; EP0.EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE0(1) | USB_DEVICE_EPCFG_EPTYPE1(1); EP_ACM.EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE1(4); USB->DEVICE.CTRLB.reg = 0; // enable irqs USB->DEVICE.INTENSET.reg = USB_DEVICE_INTENSET_EORST; NVIC_SetPriority(USB_IRQn, 1); NVIC_EnableIRQ(USB_IRQn); }
void usb_set_configure(void) { EP_ACM.EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE1(4); EP_BULKOUT.EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE0(3); EP_BULKOUT.EPINTENSET.reg = ( USB_DEVICE_EPINTENSET_TRCPT0 | USB_DEVICE_EPINTENSET_TRCPT1); EP_BULKIN.EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE1(3); EP_BULKIN.EPINTENSET.reg = ( USB_DEVICE_EPINTENSET_TRCPT0 | USB_DEVICE_EPINTENSET_TRCPT1); }
// Setup the control endpoint 0. static void bus_reset(void) { // Max size of packets is 64 bytes. UsbDeviceDescBank* bank_out = &sram_registers[0][TUSB_DIR_OUT]; bank_out->PCKSIZE.bit.SIZE = 0x3; UsbDeviceDescBank* bank_in = &sram_registers[0][TUSB_DIR_IN]; bank_in->PCKSIZE.bit.SIZE = 0x3; UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[0]; ep->EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE0(0x1) | USB_DEVICE_EPCFG_EPTYPE1(0x1); ep->EPINTENSET.reg = USB_DEVICE_EPINTENSET_TRCPT0 | USB_DEVICE_EPINTENSET_TRCPT1 | USB_DEVICE_EPINTENSET_RXSTP; // Prepare for setup packet dcd_edpt_xfer(0, 0, _setup_packet, sizeof(_setup_packet)); }
/*---------------------------------------------------------------------------- * \brief Configure USB device */ void USB_Configure(Usb *pUsb) { /* Configure BULK OUT endpoint for CDC Data interface*/ pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE0(3); /* Set maximum packet size as 64 bytes */ usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].PCKSIZE.bit.SIZE = 3; pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK0RDY; /* Configure the data buffer */ usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].ADDR.reg = (uint32_t)&udd_ep_out_cache_buffer[1]; /* Configure BULK IN endpoint for CDC Data interface */ pUsb->DEVICE.DeviceEndpoint[USB_EP_IN].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE1(3); /* Set maximum packet size as 64 bytes */ usb_endpoint_table[USB_EP_IN].DeviceDescBank[1].PCKSIZE.bit.SIZE = 3; pUsb->DEVICE.DeviceEndpoint[USB_EP_IN].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY; /* Configure the data buffer */ usb_endpoint_table[USB_EP_IN].DeviceDescBank[1].ADDR.reg = (uint32_t)&udd_ep_in_cache_buffer[1]; /* Configure INTERRUPT IN endpoint for CDC COMM interface*/ pUsb->DEVICE.DeviceEndpoint[USB_EP_COMM].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE1(4); /* Set maximum packet size as 64 bytes */ usb_endpoint_table[USB_EP_COMM].DeviceDescBank[1].PCKSIZE.bit.SIZE = 0; pUsb->DEVICE.DeviceEndpoint[USB_EP_COMM].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY; }
/*---------------------------------------------------------------------------- * \brief Test if the device is configured and handle enumeration */ uint8_t USB_IsConfigured(P_USB_CDC pCdc) { Usb *pUsb = pCdc->pUsb; /* Check for End of Reset flag */ if (pUsb->DEVICE.INTFLAG.reg & USB_DEVICE_INTFLAG_EORST) { /* Clear the flag */ pUsb->DEVICE.INTFLAG.bit.EORST = true; /* Set Device address as 0 */ pUsb->DEVICE.DADD.reg = USB_DEVICE_DADD_ADDEN | 0; /* Configure endpoint 0 */ /* Configure Endpoint 0 for Control IN and Control OUT */ pUsb->DEVICE.DeviceEndpoint[0].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE0(1) | USB_DEVICE_EPCFG_EPTYPE1(1); pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK0RDY; pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY; /* Configure control OUT Packet size to 64 bytes */ usb_endpoint_table[0].DeviceDescBank[0].PCKSIZE.bit.SIZE = 3; /* Configure control IN Packet size to 64 bytes */ usb_endpoint_table[0].DeviceDescBank[1].PCKSIZE.bit.SIZE = 3; /* Configure the data buffer address for control OUT */ usb_endpoint_table[0].DeviceDescBank[0].ADDR.reg = (uint32_t)&udd_ep_out_cache_buffer[0]; /* Configure the data buffer address for control IN */ usb_endpoint_table[0].DeviceDescBank[1].ADDR.reg = (uint32_t)&udd_ep_in_cache_buffer[0]; /* Set Multipacket size to 8 for control OUT and byte count to 0*/ usb_endpoint_table[0].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = 8; usb_endpoint_table[0].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0; pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY; // Reset current configuration value to 0 pCdc->currentConfiguration = 0; } else { if (pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_RXSTP) { sam_ba_usb_CDC_Enumerate(pCdc); } } return pCdc->currentConfiguration; }
//----------------------------------------------------------------------------- void irq_handler_usb(void) { int epint, flags; if (USB->DEVICE.INTFLAG.bit.EORST) { USB->DEVICE.INTFLAG.reg = USB_DEVICE_INTFLAG_EORST; USB->DEVICE.DADD.reg = USB_DEVICE_DADD_ADDEN; for (int i = 0; i < USB_EPT_NUM; i++) { udc_reset_endpoint(i, USB_IN_ENDPOINT); udc_reset_endpoint(i, USB_OUT_ENDPOINT); } USB->DEVICE.DeviceEndpoint[0].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE0(USB_DEVICE_EPCFG_EPTYPE_CONTROL) | USB_DEVICE_EPCFG_EPTYPE1(USB_DEVICE_EPCFG_EPTYPE_CONTROL); USB->DEVICE.DeviceEndpoint[0].EPSTATUSSET.bit.BK0RDY = 1; USB->DEVICE.DeviceEndpoint[0].EPSTATUSCLR.bit.BK1RDY = 1; udc_mem[0].in.ADDR.reg = (uint32_t)udc_ctrl_in_buf; udc_mem[0].in.PCKSIZE.bit.SIZE = USB_DEVICE_PCKSIZE_SIZE_64; udc_mem[0].in.PCKSIZE.bit.BYTE_COUNT = 0; udc_mem[0].in.PCKSIZE.bit.MULTI_PACKET_SIZE = 0; udc_mem[0].out.ADDR.reg = (uint32_t)udc_ctrl_out_buf; udc_mem[0].out.PCKSIZE.bit.SIZE = USB_DEVICE_PCKSIZE_SIZE_64; udc_mem[0].out.PCKSIZE.bit.MULTI_PACKET_SIZE = 8; udc_mem[0].out.PCKSIZE.bit.BYTE_COUNT = 0; USB->DEVICE.DeviceEndpoint[0].EPSTATUSCLR.bit.BK0RDY = 1; USB->DEVICE.DeviceEndpoint[0].EPINTENSET.bit.RXSTP = 1; } if (USB->DEVICE.DeviceEndpoint[0].EPINTFLAG.bit.RXSTP) { USB->DEVICE.DeviceEndpoint[0].EPINTFLAG.bit.RXSTP = 1; USB->DEVICE.DeviceEndpoint[0].EPSTATUSCLR.bit.BK0RDY = 1; usb_handle_standard_request((usb_request_t *)udc_ctrl_out_buf); } epint = USB->DEVICE.EPINTSMRY.reg; for (int i = 0; epint && i < USB_EPT_NUM; i++) { if (0 == (epint & (1 << i))) continue; epint &= ~(1 << i); flags = USB->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg; if (flags & USB_DEVICE_EPINTFLAG_TRCPT0) { USB->DEVICE.DeviceEndpoint[i].EPINTFLAG.bit.TRCPT0 = 1; USB->DEVICE.DeviceEndpoint[i].EPSTATUSSET.bit.BK0RDY = 1; udc_recv_callback(i); } if (flags & USB_DEVICE_EPINTFLAG_TRCPT1) { USB->DEVICE.DeviceEndpoint[i].EPINTFLAG.bit.TRCPT1 = 1; USB->DEVICE.DeviceEndpoint[i].EPSTATUSCLR.bit.BK1RDY = 1; udc_send_callback(i); } } }