// --------------------------------------------------------------------------- static ErrorCode_t USB_InitStack(int core) { if (USB_HANDLE(core)) return RET_OK; // Only init once USBD_API_INIT_PARAM_T usb_param; USB_CORE_DESCS_T core_desc; // Initialize USB parameter structure memset((void *)&usb_param, 0, sizeof(USBD_API_INIT_PARAM_T)); // Configure USB memory usb_param.usb_reg_base = (UINT32)USB_REG(core); usb_param.max_num_ep = USB_MAX_EP_NUM; usb_param.mem_base = (UINT32)&usbrom_buff[core]; usb_param.mem_size = USBROM_MEM_SIZE; // Configure USB callbacks usb_param.USB_Reset_Event = USB_Reset_Event_Handler; // Configure stack with initial device, configuration and string descriptors // ep0 class handler can manage USB dynamic configuration afterwards memcpy(USBROM_DeviceDescriptor, USB_DeviceDescriptor, sizeof(USB_DeviceDescriptor)); memcpy(USBROM_ConfigDescriptor, USB_ConfigDescriptor, sizeof(USB_ConfigDescriptor)); memcpy(USBROM_FSConfigDescriptor, USB_FSConfigDescriptor, sizeof(USB_FSConfigDescriptor)); memcpy(USBROM_StringDescriptor, USB_StringDescriptor, sizeof(USB_StringDescriptor)); memcpy(USBROM_DeviceQualifier, USB_DeviceQualifier, sizeof(USB_DeviceQualifier)); core_desc.device_desc = (UINT8*)USBROM_DeviceDescriptor; core_desc.high_speed_desc = (UINT8*)USBROM_ConfigDescriptor; core_desc.full_speed_desc = (UINT8*)USBROM_FSConfigDescriptor; core_desc.string_desc = (UINT8*)USBROM_StringDescriptor; core_desc.device_qualifier = (UINT8*)USBROM_DeviceQualifier; return USBD_Init(&(USB_HANDLE(core)), &core_desc, &usb_param); }
// --------------------------------------------------------------------------- BOOL CPU_USB_StartOutput(USB_CONTROLLER_STATE* State, int epNum) { if (State == NULL || epNum >= State->EndpointCount) return FALSE; GLOBAL_LOCK(irq); // Exit if endpoint has no output queue if (State->Queues[epNum] == NULL || !State->IsTxQueue[epNum]) return FALSE; // If endpoint status is halt, clear all queues if (State->EndpointStatus[epNum] & USB_STATUS_ENDPOINT_HALT) { while (USB_TxDequeue(State, epNum, TRUE) != NULL); // Clear TX queue return TRUE; } USBD_HANDLE_T hUsb = (State == USB_STATE(0)) ? USB_HANDLE(0) : USB_HANDLE(1); int core = USB_CORE(hUsb); USB_PACKET64* Packet64; UINT8* dst = ep_in_data[core]; UINT32 cnt = 0; // Hold if buffer pending if (ep_in_count[core] != 0) return FALSE; // If payload missing, hold until flush to avoid host timeout at HS Packet64 = USB_TxDequeue(State, epNum, FALSE); if (Packet64->Size == sizeof(WP_Packet) && ((memcmp(Packet64->Buffer, MARKER_DEBUGGER_V1, 7) == 0) || (memcmp(Packet64->Buffer, MARKER_PACKET_V1, 7) == 0))) { memcpy(dst, Packet64->Buffer, Packet64->Size); int missing = ((WP_Packet*)dst)->m_size + sizeof(WP_Packet); for (int i = 0; i < State->Queues[epNum]->NumberOfElements(); i++) { missing -= (*State->Queues[epNum])[i]->Size; } if (missing != 0) return FALSE; } // Copy packets to endpoint buffer cnt = 0; while ((Packet64 = USB_TxDequeue(State, epNum, FALSE)) != NULL) // Peek { if ((cnt + Packet64->Size) > EP_MEM_SIZE) break; Packet64 = USB_TxDequeue(State, epNum, TRUE); // Pop memcpy(dst, Packet64->Buffer, Packet64->Size); dst += Packet64->Size; cnt += Packet64->Size; } ep_in_count[core] = cnt; // Transmit buffer USB_EP_In_Handler(hUsb, (void*) epNum, USB_EVT_IN); return TRUE; }
// --------------------------------------------------------------------------- BOOL CPU_USB_ProtectPins(int core, BOOL On) { USB_CONTROLLER_STATE *State; USBD_HANDLE_T hUsb = USB_HANDLE(core); GLOBAL_LOCK(irq); if (core >= MAX_USB_CORE) return FALSE; State = USB_STATE(core); if (On) { // Clear queues for (int epNum = 1; epNum < State->EndpointCount; epNum++) { if (State->Queues[epNum] != NULL && State->IsTxQueue[epNum]) State->Queues[epNum]->Initialize(); } #if 0 // Don't disconnect on CDC // Make soft disconnect and set detached state USBD_Connect(hUsb, 0); // Disconnect State->DeviceState = USB_DEVICE_STATE_DETACHED; USB_StateCallback(State); #endif } else { // Make soft connect and set attached state USBD_Connect(hUsb, 1); // Connect State->DeviceState = USB_DEVICE_STATE_ATTACHED; USB_StateCallback(State); } return TRUE; }
// --------------------------------------------------------------------------- BOOL CPU_USB_RxEnable(USB_CONTROLLER_STATE* State, int epNum) { // If this is not a legal Rx queue if (State == NULL || State->Queues[epNum] == NULL || State->IsTxQueue[epNum]) return FALSE; GLOBAL_LOCK(irq); // Enable endpoint USBD_EnableEP(USB_HANDLE(State->ControllerNum), USB_ENDPOINT_OUT(epNum)); return TRUE; }
// --------------------------------------------------------------------------- static ErrorCode_t CDC_Init(int core) { if (USB_HCDC(core)) return RET_OK; // Only init once USBD_CDC_INIT_PARAM_T cdc_param; USB_CORE_CTRL_T* pCtrl; USB_INTERFACE_DESCRIPTOR *pIfDesc; USB_INTERFACE_DESCRIPTOR *pDataIfDesc; USBD_HANDLE_T hUsb = USB_HANDLE(core); ErrorCode_t ret; pIfDesc = (USB_INTERFACE_DESCRIPTOR*)((UINT32)USBROM_ConfigDescriptor + USB_CONFIGURATION_DESCRIPTOR_LENGTH); pDataIfDesc = (USB_INTERFACE_DESCRIPTOR*)((UINT32)pIfDesc + sizeof(USB_INTERFACE_DESCRIPTOR) + 0x0013 + sizeof(USB_ENDPOINT_DESCRIPTOR)); // Set CDC parameters memset((void*)&cdc_param, 0, sizeof(USBD_CDC_INIT_PARAM_T)); cdc_param.mem_base = (UINT32)&cdc_buff[core]; cdc_param.mem_size = CDC_MEM_SIZE; cdc_param.cif_intf_desc = (UINT8*)pIfDesc; cdc_param.dif_intf_desc = (UINT8*)pDataIfDesc; cdc_param.SetLineCode = CDC_SetLineCode; USBD_RegisterEpHandler(hUsb, USB_EP_INDEX_IN(BULK_IN_EP), USB_EP_In_Handler, (void*)BULK_IN_EP); USBD_RegisterEpHandler(hUsb, USB_EP_INDEX_OUT(BULK_OUT_EP), USB_EP_Out_Handler, (void*)BULK_OUT_EP); ret = USBD_API->cdc->init(hUsb, &cdc_param, &USB_HCDC(core)); // Patch from LPC43XX errata - Save default CDC handler and replace it pCtrl = (USB_CORE_CTRL_T*)hUsb; if (pCtrl->ep0_hdlr_cb[pCtrl->num_ep0_hdlrs - 1] != CDC_EP0_Handler) { CDC_Default_Handler = pCtrl->ep0_hdlr_cb[pCtrl->num_ep0_hdlrs - 1]; pCtrl->ep0_hdlr_cb[pCtrl->num_ep0_hdlrs - 1] = CDC_EP0_Handler; } cdc_coding = &(((USB_CDC_CTRL_T*)USB_HCDC(core))->line_coding); return ret; }
//------------------------------------------------------------------------ static inline void stm32_otg_on_isr_rx(EXO* exo) { IPC ipc; unsigned int sta = OTG_FS_GENERAL->RXSTSP; unsigned int pktsts = sta & OTG_FS_GENERAL_RXSTSR_PKTSTS; int bcnt = (sta & OTG_FS_GENERAL_RXSTSR_BCNT) >> OTG_FS_GENERAL_RXSTSR_BCNT_POS; unsigned int ep_num = (sta & OTG_FS_GENERAL_RXSTSR_EPNUM) >> OTG_FS_GENERAL_RXSTSR_EPNUM_POS; EP* ep = exo->usb.out[ep_num]; if (pktsts == OTG_FS_GENERAL_RXSTSR_PKTSTS_SETUP_RX) { //ignore all data on setup packet exo->usb.setup_lo = ((uint32_t*)(OTG_FS_FIFO_BASE + ep_num * 0x1000))[0]; exo->usb.setup_hi = ((uint32_t*)(OTG_FS_FIFO_BASE + ep_num * 0x1000))[1]; } else if ((pktsts == OTG_FS_GENERAL_RXSTSR_PKTSTS_SETUP_DONE)) { ipc.process = exo->usb.device; ipc.cmd = HAL_CMD(HAL_USB, USB_SETUP); ipc.param1 = USB_HANDLE(USB_0, 0); ipc.param2 = exo->usb.setup_lo; ipc.param3 = exo->usb.setup_hi; ipc_ipost(&ipc); } else if ((pktsts == OTG_FS_GENERAL_RXSTSR_PKTSTS_OUT_RX) && bcnt) { memcpy4(io_data(ep->io) + ep->io->data_size, (void*)(OTG_FS_FIFO_BASE + ep_num * 0x1000), bcnt); ep->io->data_size += bcnt; if (ep->io->data_size >= ep->size || bcnt < ep->mps ) { iio_complete(exo->usb.device, HAL_IO_CMD(HAL_USB, IPC_READ), ep_num, ep->io); ep->io_active = false; ep->io = NULL; } else stm32_otg_rx_prepare(exo, ep_num); } OTG_FS_GENERAL->INTMSK |= OTG_FS_GENERAL_INTMSK_RXFLVLM; }
// --------------------------------------------------------------------------- void USB1_IRQHandler(void* param) { USBD_ISR(USB_HANDLE(1)); }
// --------------------------------------------------------------------------- void USB0_IRQHandler(void* param) { USBD_ISR(USB_HANDLE(0)); }