/* * Copyright (c) 2022 OpenLuat & AirM2M * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "user.h" typedef struct { USB_SetupInfoStruct Setup; USB_HWCapsStruct HWCaps; usb_device_request_t LastRequest; Buffer_Struct FullConfigDataBuf; Buffer_Struct FullOtherSpeedConfigDataBuf; USB_EndpointCtrlStruct *pEpCtrl; Timer_t *WaitDataTimer; HANDLE pHWCtrl; union { uint16_t DeviceStatus; struct { uint16_t SelfPower:1; uint16_t RemoteWakeupEnable:1; uint16_t U1Enable:1; uint16_t U2Enable:1; uint16_t LTMEnable:1; uint16_t Zero:11; }DEVSTATUS_b; }; union { uint16_t InterfaceStatus; struct { uint16_t RemoteWakeCapable:1; uint16_t RemoteWakeupEnable:1; uint16_t Zero:14; }INFSTATUS_b; }; uint8_t DeviceState; uint8_t Ep0Stage; uint8_t IsRequestError; uint8_t BusPowered; uint8_t SelfID; uint8_t ConfigNo; uint8_t DefaultConfigNo; }USB_StackCtrlStruct; #define USB_DBG(x, y...) //#define USB_DBG DBG #define USB_ERR DBG static USB_StackCtrlStruct prvUSBCore[USB_MAX]; static int32_t prvUSB_StackDummyEpCB(void *pData, void *pParam) { USB_EndpointDataStruct *EpData = (USB_EndpointDataStruct *)pData; USB_ERR("USB%d EP%d no work!", EpData->USB_ID, EpData->EpIndex); return -ERROR_OPERATION_FAILED; } static int32_t prvUSB_StackDummyStateCB(void *pData, void *pParam) { return -ERROR_OPERATION_FAILED; } static void prvUSB_ResetEpCtrl(uint8_t USB_ID, uint8_t Index) { OS_DeInitBuffer(&prvUSBCore[USB_ID].pEpCtrl[Index].RxBuf); memset(&prvUSBCore[USB_ID].pEpCtrl[Index], 0, sizeof(USB_EndpointCtrlStruct)); prvUSBCore[USB_ID].pEpCtrl[Index].CB = prvUSB_StackDummyEpCB; prvUSBCore[USB_ID].pEpCtrl[Index].ForceZeroPacket = 0; } static int32_t prvUSB_SetupRxTimeout(void *pData, void *pParam) { USB_SetDeviceEPStatus(pParam, 0, 1, USB_EP_STATE_STALL); USB_ERR("!"); } static void prvUSB_StackEpInit(uint8_t USB_ID) { usb_full_config_t *pConfig = prvUSBCore[USB_ID].Setup.pCurConfigInfo->pFullConfig[prvUSBCore[USB_ID].Setup.CurSpeed]; uint32_t i, Index; usb_full_interface_t *pFullInterface; uint8_t EpID, ToHost, EpNum; for(Index = 0; Index < pConfig->InterfaceNum; Index++) { pFullInterface = &pConfig->pInterfaceFullDesc[Index]; EpNum = pFullInterface->EndpointNum; for(i = 0; i < EpNum; i++) { ToHost = UE_GET_DIR(pFullInterface->pEndpointDesc[i].bEndpointAddress); EpID = UE_GET_ADDR(pFullInterface->pEndpointDesc[i].bEndpointAddress); prvUSBCore[USB_ID].pEpCtrl[EpID].XferType = UE_GET_XFERTYPE(pFullInterface->pEndpointDesc[i].bmAttributes); prvUSBCore[USB_ID].pEpCtrl[EpID].MaxPacketLen = BytesGetLe16(pFullInterface->pEndpointDesc[i].wMaxPacketSize); if (ToHost) { prvUSBCore[USB_ID].pEpCtrl[EpID].ToHostEnable = 1; } else { prvUSBCore[USB_ID].pEpCtrl[EpID].ToDeviceEnable = 1; OS_ReInitBuffer(&prvUSBCore[USB_ID].pEpCtrl[EpID].RxBuf, prvUSBCore[USB_ID].pEpCtrl[EpID].MaxPacketLen * 2); } USB_DBG("interface %d, Ep %x address %x fifo %d type %d", Index, i, pFullInterface->pEndpointDesc[i].bEndpointAddress, prvUSBCore[USB_ID].pEpCtrl[EpID].MaxPacketLen, prvUSBCore[USB_ID].pEpCtrl[EpID].XferType); } } } static void prvUSB_StackMakeFullConfigData(uint8_t USB_ID) { usb_full_config_t *pConfig; usb_config_descriptor_t TempConfigDesc; uint32_t i, Index; volatile uint16_t TotalLen; pConfig = prvUSBCore[USB_ID].Setup.pCurConfigInfo->pFullConfig[prvUSBCore[USB_ID].Setup.CurSpeed]; memcpy(&TempConfigDesc, pConfig->pConfigDesc, sizeof(usb_config_descriptor_t)); if (!prvUSBCore[USB_ID].BusPowered) { TempConfigDesc.bmAttributes &= ~UC_BUS_POWERED; TempConfigDesc.bmAttributes |= UC_SELF_POWERED; } else { TempConfigDesc.bmAttributes |= UC_BUS_POWERED; } TotalLen = sizeof(usb_config_descriptor_t); if (pConfig->pInterfaceAssocDesc) { TotalLen += sizeof(usb_interface_assoc_descriptor_t); } for(Index = 0; Index < pConfig->InterfaceNum; Index++) { TotalLen += sizeof(usb_interface_descriptor_t); if (pConfig->pInterfaceFullDesc[Index].GetOtherDesc) { TotalLen += pConfig->pInterfaceFullDesc[Index].GetOtherDesc(NULL, NULL); } if (USB_DEVICE_SPEED_SUPER_SPEED == prvUSBCore[USB_ID].Setup.CurSpeed) { for(i = 0; i < pConfig->pInterfaceFullDesc[Index].EndpointNum; i++) { TotalLen += sizeof(usb_endpoint_descriptor_t); TotalLen += sizeof(usb_endpoint_ss_comp_descriptor_t); } } else { for(i = 0; i < pConfig->pInterfaceFullDesc[Index].EndpointNum; i++) { TotalLen += sizeof(usb_endpoint_descriptor_t); } } } OS_ReInitBuffer(&prvUSBCore[USB_ID].FullConfigDataBuf, TotalLen); BytesPutLe16(TempConfigDesc.wTotalLength, TotalLen); TempConfigDesc.bConfigurationValue = prvUSBCore[USB_ID].ConfigNo; OS_BufferWrite(&prvUSBCore[USB_ID].FullConfigDataBuf, &TempConfigDesc, sizeof(usb_config_descriptor_t)); if (pConfig->pInterfaceAssocDesc) { OS_BufferWrite(&prvUSBCore[USB_ID].FullConfigDataBuf, pConfig->pInterfaceAssocDesc, sizeof(usb_interface_assoc_descriptor_t)); } for(Index = 0; Index < pConfig->InterfaceNum; Index++) { OS_BufferWrite(&prvUSBCore[USB_ID].FullConfigDataBuf, pConfig->pInterfaceFullDesc[Index].pInterfaceDesc, sizeof(usb_interface_descriptor_t)); if (pConfig->pInterfaceFullDesc[Index].GetOtherDesc) { prvUSBCore[USB_ID].FullConfigDataBuf.Pos += pConfig->pInterfaceFullDesc[Index].GetOtherDesc(prvUSBCore[USB_ID].FullConfigDataBuf.Data + prvUSBCore[USB_ID].FullConfigDataBuf.Pos, NULL); } if (USB_DEVICE_SPEED_SUPER_SPEED == prvUSBCore[USB_ID].Setup.CurSpeed) { for(i = 0; i < pConfig->pInterfaceFullDesc[Index].EndpointNum; i++) { OS_BufferWrite(&prvUSBCore[USB_ID].FullConfigDataBuf, &pConfig->pInterfaceFullDesc[Index].pEndpointDesc[i], sizeof(usb_endpoint_descriptor_t)); OS_BufferWrite(&prvUSBCore[USB_ID].FullConfigDataBuf, &pConfig->pInterfaceFullDesc[Index].pEndpointSSCompDesc[i], sizeof(usb_endpoint_ss_comp_descriptor_t)); } } else { for(i = 0; i < pConfig->pInterfaceFullDesc[Index].EndpointNum; i++) { OS_BufferWrite(&prvUSBCore[USB_ID].FullConfigDataBuf, &pConfig->pInterfaceFullDesc[Index].pEndpointDesc[i], sizeof(usb_endpoint_descriptor_t)); } } } OS_DeInitBuffer(&prvUSBCore[USB_ID].FullOtherSpeedConfigDataBuf); switch(prvUSBCore[USB_ID].Setup.CurSpeed) { case USB_DEVICE_SPEED_FULL_SPEED: pConfig = prvUSBCore[USB_ID].Setup.pCurConfigInfo->pFullConfig[USB_DEVICE_SPEED_HIGH_SPEED]; if (pConfig) { goto MAKE_OTHER_SPEED; } break; case USB_DEVICE_SPEED_HIGH_SPEED: pConfig = prvUSBCore[USB_ID].Setup.pCurConfigInfo->pFullConfig[USB_DEVICE_SPEED_FULL_SPEED]; if (pConfig) { goto MAKE_OTHER_SPEED; } break; default: return; } return; MAKE_OTHER_SPEED: OS_ReInitBuffer(&prvUSBCore[USB_ID].FullOtherSpeedConfigDataBuf, TotalLen); memcpy(&TempConfigDesc, pConfig->pConfigDesc, sizeof(usb_config_descriptor_t)); BytesPutLe16(TempConfigDesc.wTotalLength, TotalLen); TempConfigDesc.bDescriptorType = UDESC_OTHER_SPEED_CONFIGURATION; TempConfigDesc.bConfigurationValue = prvUSBCore[USB_ID].ConfigNo; if (!prvUSBCore[USB_ID].BusPowered) { TempConfigDesc.bmAttributes &= ~UC_BUS_POWERED; TempConfigDesc.bmAttributes |= UC_SELF_POWERED; } else { TempConfigDesc.bmAttributes |= UC_BUS_POWERED; } OS_BufferWrite(&prvUSBCore[USB_ID].FullOtherSpeedConfigDataBuf, &TempConfigDesc, sizeof(usb_config_descriptor_t)); if (pConfig->pInterfaceAssocDesc) { OS_BufferWrite(&prvUSBCore[USB_ID].FullOtherSpeedConfigDataBuf, pConfig->pInterfaceAssocDesc, sizeof(usb_interface_assoc_descriptor_t)); } for(Index = 0; Index < pConfig->InterfaceNum; Index++) { OS_BufferWrite(&prvUSBCore[USB_ID].FullOtherSpeedConfigDataBuf, pConfig->pInterfaceFullDesc[Index].pInterfaceDesc, sizeof(usb_interface_descriptor_t)); if (pConfig->pInterfaceFullDesc[Index].GetOtherDesc) { prvUSBCore[USB_ID].FullOtherSpeedConfigDataBuf.Pos += pConfig->pInterfaceFullDesc[Index].GetOtherDesc(prvUSBCore[USB_ID].FullOtherSpeedConfigDataBuf.Data + prvUSBCore[USB_ID].FullOtherSpeedConfigDataBuf.Pos, NULL); } for(i = 0; i < pConfig->pInterfaceFullDesc[Index].EndpointNum; i++) { OS_BufferWrite(&prvUSBCore[USB_ID].FullOtherSpeedConfigDataBuf, &pConfig->pInterfaceFullDesc[Index].pEndpointDesc[i], sizeof(usb_endpoint_descriptor_t)); } } } void USB_StackResetEpBuffer(uint8_t USB_ID, uint8_t Index) { if (prvUSBCore[USB_ID].pEpCtrl[Index].RxBuf.MaxLen > prvUSBCore[USB_ID].HWCaps.EpBufMaxLen) { OS_DeInitBuffer(&prvUSBCore[USB_ID].pEpCtrl[Index].RxBuf); OS_InitBuffer(&prvUSBCore[USB_ID].pEpCtrl[Index].RxBuf, prvUSBCore[USB_ID].pEpCtrl[Index].MaxPacketLen * 2); } else { prvUSBCore[USB_ID].pEpCtrl[Index].RxBuf.Pos = 0; } memset(&prvUSBCore[USB_ID].pEpCtrl[Index].TxBuf, 0, sizeof(Buffer_Struct)); } void USB_StackSetControl(uint8_t USB_ID, HANDLE pHWCtrl,USB_EndpointCtrlStruct *pEpCtrl, USB_HWCapsStruct *Caps) { uint32_t i; USB_StackCtrlStruct *USBCore = &prvUSBCore[USB_ID]; USBCore->pHWCtrl = pHWCtrl; memcpy(&USBCore->HWCaps, Caps, sizeof(USB_HWCapsStruct)); for(i = 0; i < USB_EP_MAX; i++) { USBCore->pEpCtrl[i].CB = prvUSB_StackDummyEpCB; } USBCore->SelfID = USB_ID; USBCore->pEpCtrl = pEpCtrl; prvUSBCore[USB_ID].WaitDataTimer = Timer_Create(prvUSB_SetupRxTimeout, pHWCtrl, NULL); } void USB_StackClearSetup(uint8_t USB_ID) { USB_SetupInfoStruct *pSetup = &prvUSBCore[USB_ID].Setup; uint32_t i, j; if (pSetup->pString) { for(i = 0;i < pSetup->StringNum; i++) { OS_DeInitBuffer(&pSetup->pString[i]); } } free(pSetup->pString); memset(&prvUSBCore[USB_ID].Setup, 0, sizeof(USB_SetupInfoStruct)); for(i = 0; i < USB_EP_MAX; i++) { prvUSB_ResetEpCtrl(USB_ID, i); // prvUSBCore[USB_ID].pEpCtrl[i].CB = prvUSB_StackDummyEpCB; } prvUSBCore[USB_ID].Ep0Stage = USB_EP0_STAGE_SETUP; prvUSBCore[USB_ID].pEpCtrl[0].ForceZeroPacket = 1; prvUSBCore[USB_ID].Setup.CB = prvUSB_StackDummyStateCB; } void USB_StackDeviceAfterDisconnect(uint8_t USB_ID) { USB_StackCtrlStruct *USBCore = &prvUSBCore[USB_ID]; PV_Union uPV; uint8_t i; uPV.u8[0] = USB_ID; uPV.u8[1] = USBD_BUS_TYPE_ENABLE_CONNECT; USBCore->Setup.CB(uPV.u32, USBCore->Setup.pUserData); } void USB_StackSetDeviceConfig(uint8_t USB_ID, usb_device_descriptor_t *pDeviceDesc, USB_FullConfigStruct *pConfigInfo, uint8_t ConfigNum, uint8_t StringNum, CBFuncEx_t CB, void *pUserData) { USB_SetupInfoStruct *pSetup = &prvUSBCore[USB_ID].Setup; uint32_t i; if (pSetup->pDeviceDesc) { USB_ERR("clear device info first"); return; } pSetup->pDeviceDesc = pDeviceDesc; if (CB) { pSetup->CB = CB; } else { pSetup->CB = prvUSB_StackDummyStateCB; } pSetup->pUserData = pUserData; pSetup->pConfigInfo = pConfigInfo; pSetup->ConfigNum = ConfigNum; pSetup->pString = zalloc(sizeof(Buffer_Struct) * StringNum); pSetup->StringNum = StringNum; prvUSBCore[USB_ID].pEpCtrl[0].ToDeviceEnable = 1; prvUSBCore[USB_ID].pEpCtrl[0].ToHostEnable = 1; prvUSBCore[USB_ID].DefaultConfigNo = 0; prvUSBCore[USB_ID].ConfigNo = 0; OS_ReInitBuffer(&prvUSBCore[USB_ID].pEpCtrl[0].RxBuf, pSetup->pDeviceDesc->bMaxPacketSize * 2); } void USB_StackSetDeviceSpeed(uint8_t USB_ID, uint8_t Speed) { prvUSBCore[USB_ID].Setup.CurSpeed = Speed; } void USB_StackSetEpCB(uint8_t USB_ID, uint8_t Index, CBFuncEx_t CB, void *pUserData) { USB_SetupInfoStruct *pSetup = &prvUSBCore[USB_ID].Setup; if (!CB) { prvUSBCore[USB_ID].pEpCtrl[Index].CB = prvUSB_StackDummyEpCB; } else { prvUSBCore[USB_ID].pEpCtrl[Index].CB = CB; } prvUSBCore[USB_ID].pEpCtrl[Index].pData = pUserData; } void USB_StackSetString(uint8_t USB_ID, uint8_t Index, const uint8_t *Data, uint16_t Len) { USB_SetupInfoStruct *pSetup = &prvUSBCore[USB_ID].Setup; if (Index >= pSetup->StringNum) { USB_ERR("over index %d,%d", Index, pSetup->StringNum); return; } OS_ReInitBuffer(&pSetup->pString[Index], Len + 2); pSetup->pString[Index].Data[0] = Len + 2; pSetup->pString[Index].Data[1] = UDESC_STRING; memcpy(pSetup->pString[Index].Data, Data, Len); } void USB_StackSetCharString(uint8_t USB_ID, uint8_t Index, const char *Data, uint16_t Len) { uint16_t i; USB_SetupInfoStruct *pSetup = &prvUSBCore[USB_ID].Setup; if (Index >= pSetup->StringNum) { USB_ERR("over index %d,%d", Index, pSetup->StringNum); return; } OS_ReInitBuffer(&pSetup->pString[Index], (Len * 2) + 2); pSetup->pString[Index].Data[0] = (Len * 2) + 2; pSetup->pString[Index].Data[1] = UDESC_STRING; pSetup->pString[Index].Pos = 2; for(i = 0; i < Len; i++) { pSetup->pString[Index].Data[pSetup->pString[Index].Pos] = Data[i]; pSetup->pString[Index].Pos+=2; } } int32_t USB_StackStop(uint8_t USB_ID) { USB_StackCtrlStruct *USBCore = &prvUSBCore[USB_ID]; USB_Stop(USBCore->pHWCtrl); USB_ResetStart(USBCore->pHWCtrl); USBCore->DeviceState = USB_STATE_DETACHED; return ERROR_NONE; } void USB_StackPowerOnOff(uint8_t USB_ID, uint8_t OnOff) { USB_StackCtrlStruct *USBCore = &prvUSBCore[USB_ID]; USB_PowerOnOff(USBCore->pHWCtrl, OnOff); } void USB_StackPutRxData(uint8_t USB_ID, uint8_t EpIndex, const uint8_t *Data, uint32_t Len) { USB_StackCtrlStruct *USBCore = &prvUSBCore[USB_ID]; OS_BufferWrite(&USBCore->pEpCtrl[EpIndex].RxBuf, Data, Len); } int32_t USB_StackStartDevice(uint8_t USB_ID) { USB_StackCtrlStruct *USBCore = &prvUSBCore[USB_ID]; USB_ResetEnd(USBCore->pHWCtrl); USB_SetWorkMode(USBCore->pHWCtrl, USB_MODE_DEVICE); USBCore->ConfigNo = 0; USBCore->DefaultConfigNo = 0; USBCore->Setup.pCurConfigInfo = &USBCore->Setup.pConfigInfo[USBCore->ConfigNo]; prvUSB_StackEpInit(USB_ID); USB_InitEpCfg(USBCore->pHWCtrl); prvUSB_StackMakeFullConfigData(USBCore->SelfID); USB_Start(USBCore->pHWCtrl); USBCore->DeviceState = USB_STATE_DETACHED; return ERROR_NONE; } int32_t USB_StackStartHost(uint8_t USB_ID) { return -1; } int32_t USB_StackStartOTG(uint8_t USB_ID) { return -1; } int32_t USB_StackTxEpData(uint8_t USB_ID, uint8_t EpIndex, void *pData, uint32_t Len, uint32_t MaxLen, uint8_t ForceZeroPacket) { USB_StackCtrlStruct *USBCore = &prvUSBCore[USB_ID]; USB_SetDeviceEPStatus(USBCore->pHWCtrl, EpIndex, 0, USB_EP_STATE_ACK); if (USBCore->pEpCtrl[EpIndex].TxBuf.Data) { USB_FlushFifo(USBCore->pHWCtrl, EpIndex, 0); } Buffer_StaticInit(&USBCore->pEpCtrl[EpIndex].TxBuf, pData, Len); USBCore->pEpCtrl[EpIndex].XferMaxLen = MaxLen; if (!EpIndex) { USBCore->Ep0Stage = USB_EP0_STAGE_DATA_TO_HOST; } else { USBCore->pEpCtrl[EpIndex].ForceZeroPacket = ForceZeroPacket; if (USBCore->pEpCtrl[EpIndex].TxBuf.Data) { USB_DeviceXfer(USBCore->pHWCtrl, EpIndex); } else { DBG("!"); USB_SendZeroPacket(USBCore->pHWCtrl, EpIndex); } } return ERROR_NONE; } void USB_StackStopDeviceTx(uint8_t USB_ID, uint8_t EpIndex, uint8_t IsNeedNotify) { if (EpIndex) { USB_StackCtrlStruct *USBCore = &prvUSBCore[USB_ID]; USB_EndpointCtrlStruct *pEpCtrl = &USBCore->pEpCtrl[EpIndex]; USB_EndpointDataStruct EpData; EpData.USB_ID = USB_ID; EpData.EpIndex = EpIndex; EpData.IsToDevice = 0; EpData.Len = 0xffffffff; USB_DeviceXferStop(USBCore->pHWCtrl, EpIndex); memset(&pEpCtrl->TxBuf, 0, sizeof(Buffer_Struct)); if (IsNeedNotify) { pEpCtrl->CB(&EpData, pEpCtrl->pData); } } } void USB_StackEpIntOnOff(uint8_t USB_ID, uint8_t EpIndex, uint8_t IsToDevice, uint8_t OnOff) { USB_StackCtrlStruct *USBCore = &prvUSBCore[USB_ID]; USB_EpIntOnOff(USB_ID, EpIndex, IsToDevice, OnOff); } void USB_StackSetEp0Stage(uint8_t USB_ID, uint8_t Stage) { USB_StackCtrlStruct *USBCore = &prvUSBCore[USB_ID]; if (USBCore->Ep0Stage != USB_EP0_STAGE_SETUP) { USBCore->Ep0Stage = Stage; } } void USB_StackSetRxEpDataLen(uint8_t USB_ID, uint8_t EpIndex, uint32_t Len) { USB_StackCtrlStruct *USBCore = &prvUSBCore[USB_ID]; USBCore->pEpCtrl[EpIndex].XferMaxLen = Len; } void USB_StackSetEpStatus(uint8_t USB_ID, uint8_t EpIndex, uint8_t IsToDevice, uint8_t Status) { USB_StackCtrlStruct *USBCore = &prvUSBCore[USB_ID]; // DBG("%d,%d,%d", EpIndex, IsToDevice, Status); USB_SetDeviceEPStatus(USBCore->pHWCtrl, EpIndex, IsToDevice, Status); } void USB_StackDeviceBusChange(uint8_t USB_ID, uint8_t Type) { USB_StackCtrlStruct *USBCore = &prvUSBCore[USB_ID]; PV_Union uPV; uint8_t i; uPV.u8[0] = USB_ID; uPV.u8[1] = Type; switch (Type) { case USBD_BUS_TYPE_SUSPEND: PM_SetDriverRunFlag(PM_DRV_USB, 0); Core_USBAction(USB_ID, SERV_USB_SUSPEND, USBCore->pHWCtrl); USBCore->Setup.CB(uPV.u32, USBCore->Setup.pUserData); break; case USBD_BUS_TYPE_RESUME: Core_USBAction(USB_ID, SERV_USB_RESUME, USBCore->pHWCtrl); USBCore->Setup.CB(uPV.u32, USBCore->Setup.pUserData); break; case USBD_BUS_TYPE_RESET: PM_SetDriverRunFlag(PM_DRV_USB, 1); for(i = 0; i < USB_EP_MAX; i++) { USB_StackResetEpBuffer(USB_ID, i); } USBCore->DeviceState = USB_STATE_ATTACHED; USBCore->Setup.CB(uPV.u32, USBCore->Setup.pUserData); break; case USBD_BUS_TYPE_NEW_SOF: break; case USBD_BUS_TYPE_DISCONNECT: PM_SetDriverRunFlag(PM_DRV_USB, 0); if (USBCore->DeviceState != USB_STATE_DETACHED) { USB_Stop(USBCore->pHWCtrl); USB_ResetStart(USBCore->pHWCtrl); USBCore->DeviceState = USB_STATE_DETACHED; //交给用户层决定是继续保持device,还是变成OTG Core_USBAction(USB_ID, SERV_USB_RESET_END, USBCore->pHWCtrl); } break; } } static int32_t prvUSB_DeviceNoSupport(void *pData, void *pParam) { return -1; } static int32_t prvUSB_DeviceGetStatus(void *pData, void *pParam) { USB_StackCtrlStruct *USBCore = (USB_StackCtrlStruct *)pData; usb_device_request_t *Request = (usb_device_request_t *)pParam; uint8_t EpID, ToHost; switch(Request->bmRequestType & UT_RECIP_MASK) { case UT_RECIP_DEVICE: Buffer_StaticInit(&USBCore->pEpCtrl[0].TxBuf, &USBCore->DeviceStatus, 2); break; case UT_RECIP_INTERFACE: if (Request->wIndex[0] >= USBCore->Setup.pCurConfigInfo->pFullConfig[USBCore->Setup.CurSpeed]->InterfaceNum) { return -1; } Buffer_StaticInit(&USBCore->pEpCtrl[0].TxBuf, &USBCore->InterfaceStatus, 2); break; case UT_RECIP_ENDPOINT: ToHost = UE_GET_DIR(Request->wIndex[0]); EpID = UE_GET_ADDR(Request->wIndex[0]); if (EpID >= USB_EP_MAX) { return -1; } if (ToHost) { Buffer_StaticInit(&USBCore->pEpCtrl[0].TxBuf, &USBCore->pEpCtrl[EpID].ToHostStatus, 2); } else { Buffer_StaticInit(&USBCore->pEpCtrl[0].TxBuf, &USBCore->pEpCtrl[EpID].ToDeviceStatus, 2); } break; default: return -1; break; } USBCore->Ep0Stage = USB_EP0_STAGE_DATA_TO_HOST; return 0; } static int32_t prvUSB_DeviceClearFeature(void *pData, void *pParam) { USB_StackCtrlStruct *USBCore = (USB_StackCtrlStruct *)pData; usb_device_request_t *Request = (usb_device_request_t *)pParam; uint16_t wValue = BytesGetLe16(Request->wValue); uint8_t EpID, ToHost; USBCore->Ep0Stage = USB_EP0_STAGE_SETUP; switch(Request->bmRequestType & UT_RECIP_MASK) { case UT_RECIP_DEVICE: switch(wValue) { case UF_DEVICE_REMOTE_WAKEUP: if (USBCore->HWCaps.FEATURE_b.RemoteWakeup) { USBCore->DEVSTATUS_b.RemoteWakeupEnable = 0; USBCore->INFSTATUS_b.RemoteWakeupEnable = 0; } else { return -1; } break; case UF_U1_ENABLE: if (USBCore->HWCaps.FEATURE_b.U1) { USBCore->DEVSTATUS_b.U1Enable = 0; } else { return -1; } break; case UF_U2_ENABLE: if (USBCore->HWCaps.FEATURE_b.U2) { USBCore->DEVSTATUS_b.U2Enable = 0; } else { return -1; } break; case UF_LTM_ENABLE: if (USBCore->HWCaps.FEATURE_b.LTM) { USBCore->DEVSTATUS_b.LTMEnable = 0; } else { return -1; } break; default: return -1; break; } break; case UT_RECIP_INTERFACE: if (Request->wIndex[0] >= USBCore->Setup.pCurConfigInfo->pFullConfig[USBCore->Setup.CurSpeed]->InterfaceNum) { return -1; } switch(wValue) { case UF_DEVICE_SUSPEND: break; default: return -1; break; } break; case UT_RECIP_ENDPOINT: Request->wIndex[0] &= 0x00ff; ToHost = UE_GET_DIR(Request->wIndex[0]); EpID = UE_GET_ADDR(Request->wIndex[0]); if (EpID >= USB_EP_MAX) { return -1; } if (ToHost) { switch(wValue) { case UF_ENDPOINT_HALT: USBCore->pEpCtrl[EpID].INSTATUS_b.Halt = 0; break; default: break; } } else { switch(wValue) { case UF_ENDPOINT_HALT: USBCore->pEpCtrl[EpID].OUTSTATUS_b.Halt = 0; break; default: break; } } break; default: return -1; break; } return 0; } static int32_t prvUSB_DeviceSetFeature(void *pData, void *pParam) { USB_StackCtrlStruct *USBCore = (USB_StackCtrlStruct *)pData; usb_device_request_t *Request = (usb_device_request_t *)pParam; uint8_t EpID, ToHost; USBCore->Ep0Stage = USB_EP0_STAGE_SETUP; if (USBCore->DeviceState < USB_STATE_ADDRESSED) { return -1; } switch(Request->bmRequestType & UT_RECIP_MASK) { case UT_RECIP_DEVICE: switch(Request->wValue[0]) { case UF_DEVICE_REMOTE_WAKEUP: if (USBCore->HWCaps.FEATURE_b.RemoteWakeup) { USBCore->DEVSTATUS_b.RemoteWakeupEnable = 1; USBCore->INFSTATUS_b.RemoteWakeupEnable = 1; } else { return -1; } break; case UF_U1_ENABLE: if (USBCore->HWCaps.FEATURE_b.U1) { USBCore->DEVSTATUS_b.U1Enable = 1; } else { return -1; } break; case UF_U2_ENABLE: if (USBCore->HWCaps.FEATURE_b.U2) { USBCore->DEVSTATUS_b.U2Enable = 1; } else { return -1; } break; case UF_LTM_ENABLE: if (USBCore->HWCaps.FEATURE_b.LTM) { USBCore->DEVSTATUS_b.LTMEnable = 1; } else { return -1; } break; default: return -1; break; } break; case UT_RECIP_INTERFACE: if (Request->wIndex[0] >= USBCore->Setup.pCurConfigInfo->pFullConfig[USBCore->Setup.CurSpeed]->InterfaceNum) { return -1; } switch(Request->wValue[0]) { case UF_DEVICE_SUSPEND: if (Request->wIndex[1] & 0x01) { //设备准备休眠 Core_USBAction(USBCore->SelfID, SERV_USB_SUSPEND, USBCore->pHWCtrl); } else { //设备唤醒 USB_ResumeStart(USBCore->pHWCtrl); Core_USBAction(USBCore->SelfID, SERV_USB_RESUME, USBCore->pHWCtrl); } if (Request->wIndex[1] & 0x02) { USBCore->DEVSTATUS_b.RemoteWakeupEnable = 1; USBCore->INFSTATUS_b.RemoteWakeupEnable = 1; } else { USBCore->DEVSTATUS_b.RemoteWakeupEnable = 0; USBCore->INFSTATUS_b.RemoteWakeupEnable = 0; } break; default: break; } break; case UT_RECIP_ENDPOINT: Request->wIndex[0] &= 0x00ff; ToHost = UE_GET_DIR(Request->wIndex[0]); EpID = UE_GET_ADDR(Request->wIndex[0]); if (EpID >= USB_EP_MAX) { return -1; } if (ToHost) { switch(Request->wValue[0]) { case UF_ENDPOINT_HALT: USBCore->pEpCtrl[EpID].INSTATUS_b.Halt = 1; break; default: break; } } else { switch(Request->wValue[0]) { case UF_ENDPOINT_HALT: USBCore->pEpCtrl[EpID].OUTSTATUS_b.Halt = 1; break; default: break; } } break; default: return -1; break; } return 0; } static int32_t prvUSB_DeviceSetAddress(void *pData, void *pParam) { USB_StackCtrlStruct *USBCore = (USB_StackCtrlStruct *)pData; usb_device_request_t *Request = (usb_device_request_t *)pParam; USB_SetDeviceAddress(USBCore->pHWCtrl, Request->wValue[0]); if (!USBCore->ConfigNo) { USBCore->ConfigNo = 0; USBCore->DefaultConfigNo = 0; USBCore->DeviceState = USB_STATE_ADDRESSED; USBCore->Setup.pCurConfigInfo = &USBCore->Setup.pConfigInfo[USBCore->ConfigNo]; prvUSB_StackEpInit(USBCore->SelfID); USB_ReInitEpCfg(USBCore->pHWCtrl); prvUSB_StackMakeFullConfigData(USBCore->SelfID); } return 0; } static int32_t prvUSB_DeviceGetDescriptor(void *pData, void *pParam) { USB_StackCtrlStruct *USBCore = (USB_StackCtrlStruct *)pData; usb_device_request_t *Request = (usb_device_request_t *)pParam; uint16_t TxLen; uint8_t CurSpeed = USBCore->Setup.CurSpeed; USBCore->pEpCtrl[0].XferMaxLen = BytesGetLe16(Request->wLength); USB_EndpointDataStruct EpData; switch (Request->wValue[1]) { case UDESC_DEVICE: TxLen = MIN(USBCore->pEpCtrl[0].XferMaxLen, sizeof(usb_device_descriptor_t)); Buffer_StaticInit(&USBCore->pEpCtrl[0].TxBuf, USBCore->Setup.pDeviceDesc, TxLen); break; case UDESC_CONFIG: TxLen = MIN(USBCore->pEpCtrl[0].XferMaxLen, USBCore->FullConfigDataBuf.Pos); Buffer_StaticInit(&USBCore->pEpCtrl[0].TxBuf, USBCore->FullConfigDataBuf.Data, TxLen); break; case UDESC_STRING: if (Request->wValue[0] < USBCore->Setup.StringNum) { TxLen = MIN(USBCore->pEpCtrl[0].XferMaxLen, USBCore->Setup.pString[Request->wValue[0]].MaxLen); Buffer_StaticInit(&USBCore->pEpCtrl[0].TxBuf, USBCore->Setup.pString[Request->wValue[0]].Data, TxLen); break; } else { return -1; } case UDESC_DEVICE_QUALIFIER: if (USBCore->HWCaps.FEATURE_b.HighSpeed && USBCore->HWCaps.FEATURE_b.FullSpeed && !USBCore->HWCaps.FEATURE_b.SuperSpeed) { if (USBCore->Setup.pCurConfigInfo->pQualifierDesc) { TxLen = MIN(USBCore->pEpCtrl[0].XferMaxLen, sizeof(usb_device_qualifier_t)); Buffer_StaticInit(&USBCore->pEpCtrl[0].TxBuf, USBCore->Setup.pCurConfigInfo->pQualifierDesc, TxLen); } else { return -1; } } else { return -1; } break; case UDESC_OTHER_SPEED_CONFIGURATION: if (USBCore->HWCaps.FEATURE_b.HighSpeed && USBCore->HWCaps.FEATURE_b.FullSpeed) { if (USBCore->FullOtherSpeedConfigDataBuf.Data && USBCore->FullOtherSpeedConfigDataBuf.Pos) { TxLen = MIN(USBCore->pEpCtrl[0].XferMaxLen, USBCore->FullOtherSpeedConfigDataBuf.Pos); Buffer_StaticInit(&USBCore->pEpCtrl[0].TxBuf, USBCore->FullOtherSpeedConfigDataBuf.Data, TxLen); } else { return -1; } } else { return -1; } break; case UDESC_BOS: case UDESC_OTG: case UDESC_DEBUG: return -1; break; default: memset(&EpData, 0, sizeof(EpData)); EpData.USB_ID = USBCore->SelfID; EpData.IsToDevice = 1; EpData.Data = USBCore->pEpCtrl[0].RxBuf.Data; EpData.Len = USBCore->pEpCtrl[0].RxBuf.Pos; EpData.pLastRequest = Request; return USBCore->pEpCtrl[0].CB(&EpData, USBCore->pEpCtrl[0].pData); break; } USBCore->Ep0Stage = USB_EP0_STAGE_DATA_TO_HOST; return 0; } static int32_t prvUSB_DeviceSetDescriptor(void *pData, void *pParam) { return -1; } static int32_t prvUSB_DeviceGetConfiguration(void *pData, void *pParam) { USB_StackCtrlStruct *USBCore = (USB_StackCtrlStruct *)pData; usb_device_request_t *Request = (usb_device_request_t *)pParam; if (Request->wLength[0] != 1) { return -1; } switch(USBCore->DeviceState) { case USB_STATE_CONFIGURED: Buffer_StaticInit(&USBCore->pEpCtrl[0].TxBuf, &USBCore->ConfigNo, 1); USBCore->Ep0Stage = USB_EP0_STAGE_DATA_TO_HOST; break; case USB_STATE_ADDRESSED: Buffer_StaticInit(&USBCore->pEpCtrl[0].TxBuf, &USBCore->DefaultConfigNo, 1); USBCore->Ep0Stage = USB_EP0_STAGE_DATA_TO_HOST; break; default: return -1; break; } return 0; } static int32_t prvUSB_DeviceSetConfiguration(void *pData, void *pParam) { USB_StackCtrlStruct *USBCore = (USB_StackCtrlStruct *)pData; usb_device_request_t *Request = (usb_device_request_t *)pParam; if (Request->wValue[0] >= USBCore->Setup.ConfigNum) { return -1; } USBCore->ConfigNo = Request->wValue[0]; USBCore->Setup.pCurConfigInfo = &USBCore->Setup.pConfigInfo[USBCore->ConfigNo]; if (!USBCore->ConfigNo) { USBCore->DeviceState = USB_STATE_ADDRESSED; } else { USBCore->DeviceState = USB_STATE_CONFIGURED; } prvUSB_StackEpInit(USBCore->SelfID); USB_ReInitEpCfg(USBCore->pHWCtrl); prvUSB_StackMakeFullConfigData(USBCore->SelfID); return 0; } static int32_t prvUSB_DeviceGetInterface(void *pData, void *pParam) { return -1; } static int32_t prvUSB_DeviceSetInterface(void *pData, void *pParam) { return -1; } static int32_t prvUSB_DeviceSynchFrame(void *pData, void *pParam) { USB_StackCtrlStruct *USBCore = (USB_StackCtrlStruct *)pData; usb_device_request_t *Request = (usb_device_request_t *)pParam; uint8_t EpID, ToHost; USBCore->Ep0Stage = USB_EP0_STAGE_DATA_TO_DEVICE; USBCore->pEpCtrl[0].XferMaxLen = 2; return 0; } static CBFuncEx_t prvUSB_StandardRequestTable[UR_SYNCH_FRAME + 1] = { prvUSB_DeviceGetStatus, prvUSB_DeviceClearFeature, prvUSB_DeviceNoSupport, prvUSB_DeviceSetFeature, prvUSB_DeviceNoSupport, prvUSB_DeviceSetAddress, prvUSB_DeviceGetDescriptor, prvUSB_DeviceSetDescriptor, prvUSB_DeviceGetConfiguration, prvUSB_DeviceSetConfiguration, prvUSB_DeviceGetInterface, prvUSB_DeviceSetInterface, prvUSB_DeviceSynchFrame, }; void USB_StackDeviceEp0TxDone(uint8_t USB_ID) { USB_StackCtrlStruct *USBCore = &prvUSBCore[USB_ID]; USBCore->Ep0Stage = USB_EP0_STAGE_SETUP; USB_SetDeviceNoDataSetup(USBCore->pHWCtrl); } void USB_StackAnalyzeDeviceEpRx(uint8_t USB_ID, uint8_t EpIndex) { USB_EndpointDataStruct EpData; USB_StackCtrlStruct *USBCore = &prvUSBCore[USB_ID]; USB_EndpointCtrlStruct *pEpCtrl; uint16_t wTemp; memset(&EpData, 0, sizeof(EpData)); EpData.USB_ID = USB_ID; EpData.EpIndex = EpIndex; EpData.IsToDevice = 1; EpData.Data = USBCore->pEpCtrl[EpIndex].RxBuf.Data; EpData.Len = USBCore->pEpCtrl[EpIndex].RxBuf.Pos; EpData.pLastRequest = &USBCore->LastRequest; if (EpIndex) { USBCore->pEpCtrl[EpIndex].RxBuf.Pos = 0; EpData.IsDataStage = (EpData.Len < USBCore->pEpCtrl[EpIndex].MaxPacketLen)?0:1; if (USBCore->pEpCtrl[EpIndex].CB(&EpData, USBCore->pEpCtrl[EpIndex].pData)) { USB_SetDeviceEPStatus(USBCore->pHWCtrl, EpIndex, 1, USB_EP_STATE_STALL); } } else { switch(USBCore->Ep0Stage) { case USB_EP0_STAGE_SETUP: pEpCtrl = &USBCore->pEpCtrl[0]; if (pEpCtrl->RxBuf.Pos != sizeof(usb_device_request_t)) { USBCore->IsRequestError = 1; DBG_ERR("USB%d EP%d Request size %d error", USB_ID, EpIndex, pEpCtrl->RxBuf.Pos); } memcpy(&USBCore->LastRequest, pEpCtrl->RxBuf.Data, pEpCtrl->RxBuf.Pos); if ( !(USBCore->LastRequest.bmRequestType & UT_MASK) ) { if (USBCore->LastRequest.bRequest <= UR_SYNCH_FRAME) { if (prvUSB_StandardRequestTable[USBCore->LastRequest.bRequest](USBCore, &USBCore->LastRequest)) { USBCore->IsRequestError = 1; } } else { switch(USBCore->LastRequest.bRequest) { case UR_SET_SEL: if (USBCore->HWCaps.FEATURE_b.U1 && USBCore->HWCaps.FEATURE_b.U2) { wTemp = BytesGetLe16(USBCore->LastRequest.wValue); if (USB_SetISOCHDelay(USBCore->pHWCtrl, wTemp)) { USBCore->IsRequestError = 1; } } else { USBCore->IsRequestError = 1; } break; case UR_ISOCH_DELAY: if (USBCore->HWCaps.FEATURE_b.U1 && USBCore->HWCaps.FEATURE_b.U2) { pEpCtrl->XferMaxLen = BytesGetLe16(USBCore->LastRequest.wLength); USBCore->Ep0Stage = USB_EP0_STAGE_DATA_TO_DEVICE; } else { USBCore->IsRequestError = 1; } break; default: if (USBCore->pEpCtrl[EpIndex].CB(&EpData, USBCore->pEpCtrl[EpIndex].pData)) { USB_SetDeviceEPStatus(USBCore->pHWCtrl, 0, 1, USB_EP_STATE_STALL); USBCore->IsRequestError = 1; } break; } } } else { if (USBCore->pEpCtrl[EpIndex].CB(&EpData, USBCore->pEpCtrl[EpIndex].pData)) { USB_SetDeviceEPStatus(USBCore->pHWCtrl, 0, 1, USB_EP_STATE_STALL); USBCore->IsRequestError = 1; } } if (USBCore->IsRequestError) { if (USBCore->LastRequest.bRequest != UR_GET_DESCRIPTOR && USBCore->LastRequest.wValue[1] != UDESC_DEVICE_QUALIFIER) { DBG_ERR("USB%d EP%d Request %x error", USB_ID, EpIndex, USBCore->LastRequest.bRequest); DBG_HexPrintf(USBCore->pEpCtrl[0].RxBuf.Data, USBCore->pEpCtrl[0].RxBuf.Pos); } USBCore->IsRequestError = 0; USBCore->Ep0Stage = USB_EP0_STAGE_SETUP; USB_SetDeviceEPStatus(USBCore->pHWCtrl, 0, 1, USB_EP_STATE_STALL); } USBCore->pEpCtrl[0].RxBuf.Pos = 0; switch(USBCore->Ep0Stage) { case USB_EP0_STAGE_SETUP: USB_SetDeviceNoDataSetup(USBCore->pHWCtrl); break; case USB_EP0_STAGE_DATA_TO_HOST: USB_DeviceXfer(USBCore->pHWCtrl, 0); break; case USB_EP0_STAGE_DATA_TO_DEVICE: Timer_StartMS(USBCore->WaitDataTimer, 100, 0); break; } pEpCtrl->RxBuf.Pos = 0; break; case USB_EP0_STAGE_DATA_TO_HOST: USB_ERR("!!!"); USB_SetDeviceEPStatus(USBCore->pHWCtrl, 0, 1, USB_EP_STATE_STALL); break; case USB_EP0_STAGE_DATA_TO_DEVICE: if (USBCore->pEpCtrl[0].RxBuf.Pos >= USBCore->pEpCtrl[0].XferMaxLen) { Timer_Stop(USBCore->WaitDataTimer); EpData.IsDataStage = 1; USB_DBG("setup data out done!"); if (USBCore->LastRequest.bRequest & UT_MASK) { switch(USBCore->LastRequest.bRequest) { case UR_SYNCH_FRAME: USB_DBG("frame sn %u", BytesGetLe16(USBCore->pEpCtrl[0].RxBuf.Data)); break; default: if (USBCore->pEpCtrl[0].CB(&EpData, USBCore->pEpCtrl[0].pData)) { USB_SetDeviceEPStatus(USBCore->pHWCtrl, 0, 1, USB_EP_STATE_STALL); } break; } } else { if (USBCore->pEpCtrl[0].CB(&EpData, USBCore->pEpCtrl[0].pData)) { USB_SetDeviceEPStatus(USBCore->pHWCtrl, 0, 1, USB_EP_STATE_STALL); } } USBCore->pEpCtrl[0].RxBuf.Pos = 0; } break; } } } void USB_StackSetDeviceSelfPower(uint8_t USB_ID, uint8_t OnOff) { prvUSBCore[USB_ID].DEVSTATUS_b.SelfPower = OnOff; } void USB_StackSetDeviceBusPower(uint8_t USB_ID, uint8_t OnOff) { prvUSBCore[USB_ID].BusPowered = OnOff; } void USB_StackSetDeviceRemoteWakeupCapable(uint8_t USB_ID, uint8_t OnOff) { if (prvUSBCore[USB_ID].HWCaps.FEATURE_b.RemoteWakeup) { prvUSBCore[USB_ID].INFSTATUS_b.RemoteWakeCapable = OnOff; } else { prvUSBCore[USB_ID].INFSTATUS_b.RemoteWakeCapable = 0; } }