diff --git a/Class/AUDIO/Inc/usbd_audio.h b/Class/AUDIO/Inc/usbd_audio.h index b445858..a082d19 100644 --- a/Class/AUDIO/Inc/usbd_audio.h +++ b/Class/AUDIO/Inc/usbd_audio.h @@ -57,7 +57,10 @@ extern "C" { #define AUDIO_FS_BINTERVAL 0x01U #endif /* AUDIO_FS_BINTERVAL */ +#ifndef AUDIO_OUT_EP #define AUDIO_OUT_EP 0x01U +#endif /* AUDIO_OUT_EP */ + #define USB_AUDIO_CONFIG_DESC_SIZ 0x6DU #define AUDIO_INTERFACE_DESC_SIZE 0x09U #define USB_AUDIO_DESC_SIZ 0x09U @@ -166,6 +169,115 @@ typedef struct int8_t (*PeriodicTC)(uint8_t *pbuf, uint32_t size, uint8_t cmd); int8_t (*GetState)(void); } USBD_AUDIO_ItfTypeDef; + +/* + * Audio Class specification release 1.0 + */ + +/* Table 4-2: Class-Specific AC Interface Header Descriptor */ +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint16_t bcdADC; + uint16_t wTotalLength; + uint8_t bInCollection; + uint8_t baInterfaceNr; +} __PACKED USBD_SpeakerIfDescTypeDef; + +/* Table 4-3: Input Terminal Descriptor */ +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bTerminalID; + uint16_t wTerminalType; + uint8_t bAssocTerminal; + uint8_t bNrChannels; + uint16_t wChannelConfig; + uint8_t iChannelNames; + uint8_t iTerminal; +} __PACKED USBD_SpeakerInDescTypeDef; + +/* USB Speaker Audio Feature Unit Descriptor */ +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bUnitID; + uint8_t bSourceID; + uint8_t bControlSize; + uint16_t bmaControls; + uint8_t iTerminal; +} __PACKED USBD_SpeakerFeatureDescTypeDef; + +/* Table 4-4: Output Terminal Descriptor */ +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bTerminalID; + uint16_t wTerminalType; + uint8_t bAssocTerminal; + uint8_t bSourceID; + uint8_t iTerminal; +} __PACKED USBD_SpeakerOutDescTypeDef; + +/* Table 4-19: Class-Specific AS Interface Descriptor */ +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bTerminalLink; + uint8_t bDelay; + uint16_t wFormatTag; +} __PACKED USBD_SpeakerStreamIfDescTypeDef; + +/* USB Speaker Audio Type III Format Interface Descriptor */ +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bFormatType; + uint8_t bNrChannels; + uint8_t bSubFrameSize; + uint8_t bBitResolution; + uint8_t bSamFreqType; + uint8_t tSamFreq2; + uint8_t tSamFreq1; + uint8_t tSamFreq0; +} USBD_SpeakerIIIFormatIfDescTypeDef; + +/* Table 4-17: Standard AC Interrupt Endpoint Descriptor */ +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint16_t wMaxPacketSize; + uint8_t bInterval; + uint8_t bRefresh; + uint8_t bSynchAddress; +} __PACKED USBD_SpeakerEndDescTypeDef; + +/* Table 4-21: Class-Specific AS Isochronous Audio Data Endpoint Descriptor */ +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptor; + uint8_t bmAttributes; + uint8_t bLockDelayUnits; + uint16_t wLockDelay; +} __PACKED USBD_SpeakerEndStDescTypeDef; + /** * @} */ @@ -197,6 +309,11 @@ uint8_t USBD_AUDIO_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_AUDIO_ItfTypeDef *fops); void USBD_AUDIO_Sync(USBD_HandleTypeDef *pdev, AUDIO_OffsetTypeDef offset); + +#ifdef USE_USBD_COMPOSITE +uint32_t USBD_AUDIO_GetEpPcktSze(USBD_HandleTypeDef *pdev, uint8_t If, uint8_t Ep); +#endif /* USE_USBD_COMPOSITE */ + /** * @} */ diff --git a/Class/AUDIO/Src/usbd_audio.c b/Class/AUDIO/Src/usbd_audio.c index 2acc975..7ea0a34 100644 --- a/Class/AUDIO/Src/usbd_audio.c +++ b/Class/AUDIO/Src/usbd_audio.c @@ -99,6 +99,9 @@ EndBSPDependencies */ #define AUDIO_PACKET_SZE(frq) \ (uint8_t)(((frq * 2U * 2U) / 1000U) & 0xFFU), (uint8_t)((((frq * 2U * 2U) / 1000U) >> 8) & 0xFFU) +#ifdef USE_USBD_COMPOSITE +#define AUDIO_PACKET_SZE_WORD(frq) (uint32_t)((((frq) * 2U * 2U)/1000U)) +#endif /* USE_USBD_COMPOSITE */ /** * @} */ @@ -112,9 +115,10 @@ static uint8_t USBD_AUDIO_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx); static uint8_t USBD_AUDIO_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); - +#ifndef USE_USBD_COMPOSITE static uint8_t *USBD_AUDIO_GetCfgDesc(uint16_t *length); static uint8_t *USBD_AUDIO_GetDeviceQualifierDesc(uint16_t *length); +#endif /* USE_USBD_COMPOSITE */ static uint8_t USBD_AUDIO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); static uint8_t USBD_AUDIO_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum); static uint8_t USBD_AUDIO_EP0_RxReady(USBD_HandleTypeDef *pdev); @@ -125,6 +129,7 @@ static uint8_t USBD_AUDIO_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnu static uint8_t USBD_AUDIO_IsoOutIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); static void AUDIO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); static void AUDIO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static void *USBD_AUDIO_GetAudioHeaderDesc(uint8_t *pConfDesc); /** * @} @@ -146,12 +151,20 @@ USBD_ClassTypeDef USBD_AUDIO = USBD_AUDIO_SOF, USBD_AUDIO_IsoINIncomplete, USBD_AUDIO_IsoOutIncomplete, +#ifdef USE_USBD_COMPOSITE + NULL, + NULL, + NULL, + NULL, +#else USBD_AUDIO_GetCfgDesc, USBD_AUDIO_GetCfgDesc, USBD_AUDIO_GetCfgDesc, USBD_AUDIO_GetDeviceQualifierDesc, +#endif /* USE_USBD_COMPOSITE */ }; +#ifndef USE_USBD_COMPOSITE /* USB AUDIO device Configuration Descriptor */ __ALIGN_BEGIN static uint8_t USBD_AUDIO_CfgDesc[USB_AUDIO_CONFIG_DESC_SIZ] __ALIGN_END = { @@ -167,7 +180,7 @@ __ALIGN_BEGIN static uint8_t USBD_AUDIO_CfgDesc[USB_AUDIO_CONFIG_DESC_SIZ] __ALI 0xC0, /* bmAttributes: Bus Powered according to user configuration */ #else 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif +#endif /* USBD_SELF_POWERED */ USBD_MAX_POWER, /* MaxPower (mA) */ /* 09 byte*/ @@ -318,7 +331,9 @@ __ALIGN_BEGIN static uint8_t USBD_AUDIO_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIE 0x01, 0x00, }; +#endif /* USE_USBD_COMPOSITE */ +static uint8_t AUDIOOutEpAdd = AUDIO_OUT_EP; /** * @} */ @@ -344,24 +359,30 @@ static uint8_t USBD_AUDIO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) if (haudio == NULL) { - pdev->pClassData = NULL; + pdev->pClassDataCmsit[pdev->classId] = NULL; return (uint8_t)USBD_EMEM; } - pdev->pClassData = (void *)haudio; + pdev->pClassDataCmsit[pdev->classId] = (void *)haudio; + pdev->pClassData = pdev->pClassDataCmsit[pdev->classId]; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + AUDIOOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_ISOC); +#endif /* USE_USBD_COMPOSITE */ if (pdev->dev_speed == USBD_SPEED_HIGH) { - pdev->ep_out[AUDIO_OUT_EP & 0xFU].bInterval = AUDIO_HS_BINTERVAL; + pdev->ep_out[AUDIOOutEpAdd & 0xFU].bInterval = AUDIO_HS_BINTERVAL; } else /* LOW and FULL-speed endpoints */ { - pdev->ep_out[AUDIO_OUT_EP & 0xFU].bInterval = AUDIO_FS_BINTERVAL; + pdev->ep_out[AUDIOOutEpAdd & 0xFU].bInterval = AUDIO_FS_BINTERVAL; } /* Open EP OUT */ - (void)USBD_LL_OpenEP(pdev, AUDIO_OUT_EP, USBD_EP_TYPE_ISOC, AUDIO_OUT_PACKET); - pdev->ep_out[AUDIO_OUT_EP & 0xFU].is_used = 1U; + (void)USBD_LL_OpenEP(pdev, AUDIOOutEpAdd, USBD_EP_TYPE_ISOC, AUDIO_OUT_PACKET); + pdev->ep_out[AUDIOOutEpAdd & 0xFU].is_used = 1U; haudio->alt_setting = 0U; haudio->offset = AUDIO_OFFSET_UNKNOWN; @@ -370,15 +391,15 @@ static uint8_t USBD_AUDIO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) haudio->rd_enable = 0U; /* Initialize the Audio output Hardware layer */ - if (((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->Init(USBD_AUDIO_FREQ, - AUDIO_DEFAULT_VOLUME, - 0U) != 0U) + if (((USBD_AUDIO_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init(USBD_AUDIO_FREQ, + AUDIO_DEFAULT_VOLUME, + 0U) != 0U) { return (uint8_t)USBD_FAIL; } /* Prepare Out endpoint to receive 1st packet */ - (void)USBD_LL_PrepareReceive(pdev, AUDIO_OUT_EP, haudio->buffer, + (void)USBD_LL_PrepareReceive(pdev, AUDIOOutEpAdd, haudio->buffer, AUDIO_OUT_PACKET); return (uint8_t)USBD_OK; @@ -395,16 +416,22 @@ static uint8_t USBD_AUDIO_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { UNUSED(cfgidx); +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + AUDIOOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_ISOC); +#endif /* USE_USBD_COMPOSITE */ + /* Open EP OUT */ - (void)USBD_LL_CloseEP(pdev, AUDIO_OUT_EP); - pdev->ep_out[AUDIO_OUT_EP & 0xFU].is_used = 0U; - pdev->ep_out[AUDIO_OUT_EP & 0xFU].bInterval = 0U; + (void)USBD_LL_CloseEP(pdev, AUDIOOutEpAdd); + pdev->ep_out[AUDIOOutEpAdd & 0xFU].is_used = 0U; + pdev->ep_out[AUDIOOutEpAdd & 0xFU].bInterval = 0U; /* DeInit physical Interface components */ - if (pdev->pClassData != NULL) + if (pdev->pClassDataCmsit[pdev->classId] != NULL) { - ((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->DeInit(0U); - (void)USBD_free(pdev->pClassData); + ((USBD_AUDIO_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit(0U); + (void)USBD_free(pdev->pClassDataCmsit[pdev->classId]); + pdev->pClassDataCmsit[pdev->classId] = NULL; pdev->pClassData = NULL; } @@ -427,7 +454,7 @@ static uint8_t USBD_AUDIO_Setup(USBD_HandleTypeDef *pdev, uint16_t status_info = 0U; USBD_StatusTypeDef ret = USBD_OK; - haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassData; + haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (haudio == NULL) { @@ -472,10 +499,17 @@ static uint8_t USBD_AUDIO_Setup(USBD_HandleTypeDef *pdev, case USB_REQ_GET_DESCRIPTOR: if ((req->wValue >> 8) == AUDIO_DESCRIPTOR_TYPE) { - pbuf = USBD_AUDIO_CfgDesc + 18; - len = MIN(USB_AUDIO_DESC_SIZ, req->wLength); - - (void)USBD_CtlSendData(pdev, pbuf, len); + pbuf = (uint8_t *)USBD_AUDIO_GetAudioHeaderDesc(pdev->pConfDesc); + if (pbuf != NULL) + { + len = MIN(USB_AUDIO_DESC_SIZ, req->wLength); + (void)USBD_CtlSendData(pdev, pbuf, len); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } } break; @@ -530,7 +564,7 @@ static uint8_t USBD_AUDIO_Setup(USBD_HandleTypeDef *pdev, return (uint8_t)ret; } - +#ifndef USE_USBD_COMPOSITE /** * @brief USBD_AUDIO_GetCfgDesc * return configuration descriptor @@ -543,7 +577,7 @@ static uint8_t *USBD_AUDIO_GetCfgDesc(uint16_t *length) return USBD_AUDIO_CfgDesc; } - +#endif /* USE_USBD_COMPOSITE */ /** * @brief USBD_AUDIO_DataIn * handle data IN Stage @@ -569,7 +603,7 @@ static uint8_t USBD_AUDIO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) static uint8_t USBD_AUDIO_EP0_RxReady(USBD_HandleTypeDef *pdev) { USBD_AUDIO_HandleTypeDef *haudio; - haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassData; + haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (haudio == NULL) { @@ -582,7 +616,7 @@ static uint8_t USBD_AUDIO_EP0_RxReady(USBD_HandleTypeDef *pdev) if (haudio->control.unit == AUDIO_OUT_STREAMING_CTRL) { - ((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->MuteCtl(haudio->control.data[0]); + ((USBD_AUDIO_ItfTypeDef *)pdev->pUserData[pdev->classId])->MuteCtl(haudio->control.data[0]); haudio->control.cmd = 0U; haudio->control.len = 0U; } @@ -628,12 +662,12 @@ void USBD_AUDIO_Sync(USBD_HandleTypeDef *pdev, AUDIO_OffsetTypeDef offset) USBD_AUDIO_HandleTypeDef *haudio; uint32_t BufferSize = AUDIO_TOTAL_BUF_SIZE / 2U; - if (pdev->pClassData == NULL) + if (pdev->pClassDataCmsit[pdev->classId] == NULL) { return; } - haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassData; + haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; haudio->offset = offset; @@ -679,8 +713,8 @@ void USBD_AUDIO_Sync(USBD_HandleTypeDef *pdev, AUDIO_OffsetTypeDef offset) if (haudio->offset == AUDIO_OFFSET_FULL) { - ((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->AudioCmd(&haudio->buffer[0], - BufferSize, AUDIO_CMD_PLAY); + ((USBD_AUDIO_ItfTypeDef *)pdev->pUserData[pdev->classId])->AudioCmd(&haudio->buffer[0], + BufferSize, AUDIO_CMD_PLAY); haudio->offset = AUDIO_OFFSET_NONE; } } @@ -725,21 +759,26 @@ static uint8_t USBD_AUDIO_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) uint16_t PacketSize; USBD_AUDIO_HandleTypeDef *haudio; - haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassData; +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + AUDIOOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_ISOC); +#endif /* USE_USBD_COMPOSITE */ + + haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (haudio == NULL) { return (uint8_t)USBD_FAIL; } - if (epnum == AUDIO_OUT_EP) + if (epnum == AUDIOOutEpAdd) { /* Get received data packet length */ PacketSize = (uint16_t)USBD_LL_GetRxDataSize(pdev, epnum); /* Packet received Callback */ - ((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->PeriodicTC(&haudio->buffer[haudio->wr_ptr], - PacketSize, AUDIO_OUT_TC); + ((USBD_AUDIO_ItfTypeDef *)pdev->pUserData[pdev->classId])->PeriodicTC(&haudio->buffer[haudio->wr_ptr], + PacketSize, AUDIO_OUT_TC); /* Increment the Buffer pointer or roll it back when all buffers are full */ haudio->wr_ptr += PacketSize; @@ -751,9 +790,9 @@ static uint8_t USBD_AUDIO_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) if (haudio->offset == AUDIO_OFFSET_UNKNOWN) { - ((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->AudioCmd(&haudio->buffer[0], - AUDIO_TOTAL_BUF_SIZE / 2U, - AUDIO_CMD_START); + ((USBD_AUDIO_ItfTypeDef *)pdev->pUserData[pdev->classId])->AudioCmd(&haudio->buffer[0], + AUDIO_TOTAL_BUF_SIZE / 2U, + AUDIO_CMD_START); haudio->offset = AUDIO_OFFSET_NONE; } } @@ -767,7 +806,7 @@ static uint8_t USBD_AUDIO_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) } /* Prepare Out endpoint to receive next audio packet */ - (void)USBD_LL_PrepareReceive(pdev, AUDIO_OUT_EP, + (void)USBD_LL_PrepareReceive(pdev, AUDIOOutEpAdd, &haudio->buffer[haudio->wr_ptr], AUDIO_OUT_PACKET); } @@ -785,7 +824,7 @@ static uint8_t USBD_AUDIO_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) static void AUDIO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { USBD_AUDIO_HandleTypeDef *haudio; - haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassData; + haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (haudio == NULL) { @@ -809,7 +848,7 @@ static void AUDIO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef static void AUDIO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { USBD_AUDIO_HandleTypeDef *haudio; - haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassData; + haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (haudio == NULL) { @@ -827,7 +866,7 @@ static void AUDIO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef } } - +#ifndef USE_USBD_COMPOSITE /** * @brief DeviceQualifierDescriptor * return Device Qualifier descriptor @@ -840,7 +879,7 @@ static uint8_t *USBD_AUDIO_GetDeviceQualifierDesc(uint16_t *length) return USBD_AUDIO_DeviceQualifierDesc; } - +#endif /* USE_USBD_COMPOSITE */ /** * @brief USBD_AUDIO_RegisterInterface * @param pdev: device instance @@ -855,10 +894,66 @@ uint8_t USBD_AUDIO_RegisterInterface(USBD_HandleTypeDef *pdev, return (uint8_t)USBD_FAIL; } - pdev->pUserData = fops; + pdev->pUserData[pdev->classId] = fops; return (uint8_t)USBD_OK; } + +#ifdef USE_USBD_COMPOSITE +/** + * @brief USBD_AUDIO_GetEpPcktSze + * @param pdev: device instance (reserved for future use) + * @param If: Interface number (reserved for future use) + * @param Ep: Endpoint number (reserved for future use) + * @retval status + */ +uint32_t USBD_AUDIO_GetEpPcktSze(USBD_HandleTypeDef *pdev, uint8_t If, uint8_t Ep) +{ + uint32_t mps; + + UNUSED(pdev); + UNUSED(If); + UNUSED(Ep); + + mps = AUDIO_PACKET_SZE_WORD(USBD_AUDIO_FREQ); + + /* Return the wMaxPacketSize value in Bytes (Freq(Samples)*2(Stereo)*2(HalfWord)) */ + return mps; +} +#endif /* USE_USBD_COMPOSITE */ + +/** + * @brief USBD_AUDIO_GetAudioHeaderDesc + * This function return the Audio descriptor + * @param pdev: device instance + * @param pConfDesc: pointer to Bos descriptor + * @retval pointer to the Audio AC Header descriptor + */ +static void *USBD_AUDIO_GetAudioHeaderDesc(uint8_t *pConfDesc) +{ + USBD_ConfigDescTypeDef *desc = (USBD_ConfigDescTypeDef *)(void *)pConfDesc; + USBD_DescHeaderTypeDef *pdesc = (USBD_DescHeaderTypeDef *)(void *)pConfDesc; + uint8_t *pAudioDesc = NULL; + uint16_t ptr; + + if (desc->wTotalLength > desc->bLength) + { + ptr = desc->bLength; + + while (ptr < desc->wTotalLength) + { + pdesc = USBD_GetNextDesc((uint8_t *)pdesc, &ptr); + if ((pdesc->bDescriptorType == AUDIO_INTERFACE_DESCRIPTOR_TYPE) && + (pdesc->bDescriptorSubType == AUDIO_CONTROL_HEADER)) + { + pAudioDesc = (uint8_t *)pdesc; + break; + } + } + } + return pAudioDesc; +} + /** * @} */ diff --git a/Class/BillBoard/Inc/usbd_billboard.h b/Class/BillBoard/Inc/usbd_billboard.h index e2acdaf..8045140 100644 --- a/Class/BillBoard/Inc/usbd_billboard.h +++ b/Class/BillBoard/Inc/usbd_billboard.h @@ -140,7 +140,7 @@ extern USBD_ClassTypeDef USBD_BB; #if (USBD_CLASS_BOS_ENABLED == 1) void *USBD_BB_GetCapDesc(USBD_HandleTypeDef *pdev, uint8_t *buf); void *USBD_BB_GetAltModeDesc(USBD_HandleTypeDef *pdev, uint8_t *buf, uint8_t idx); -#endif +#endif /* (USBD_CLASS_BOS_ENABLED == 1) */ /** * @} diff --git a/Class/BillBoard/Src/usbd_billboard.c b/Class/BillBoard/Src/usbd_billboard.c index f546425..f86c003 100644 --- a/Class/BillBoard/Src/usbd_billboard.c +++ b/Class/BillBoard/Src/usbd_billboard.c @@ -93,7 +93,7 @@ static uint8_t *USBD_BB_GetOtherSpeedCfgDesc(uint16_t *length); #if (USBD_CLASS_BOS_ENABLED == 1) USBD_BB_DescHeader_t *USBD_BB_GetNextDesc(uint8_t *pbuf, uint16_t *ptr); -#endif +#endif /* USBD_CLASS_BOS_ENABLED */ @@ -122,7 +122,7 @@ USBD_ClassTypeDef USBD_BB = USBD_BB_GetDeviceQualifierDesc, #if (USBD_SUPPORT_USER_STRING_DESC == 1U) NULL, -#endif +#endif /* USBD_SUPPORT_USER_STRING_DESC */ }; /* USB Standard Device Qualifier Descriptor */ @@ -154,7 +154,7 @@ __ALIGN_BEGIN static uint8_t USBD_BB_CfgDesc[USB_BB_CONFIG_DESC_SIZ] __ALIGN_EN 0xC0, /* bmAttributes: Bus Powered according to user configuration */ #else 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif +#endif /* USBD_SELF_POWERED */ USBD_MAX_POWER, /* MaxPower (mA) */ /* 09 */ @@ -185,7 +185,7 @@ __ALIGN_BEGIN static uint8_t USBD_BB_OtherSpeedCfgDesc[USB_BB_CONFIG_DESC_SIZ] 0xC0, /* bmAttributes: Bus Powered according to user configuration */ #else 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif +#endif /* USBD_SELF_POWERED */ USBD_MAX_POWER, /* MaxPower (mA) */ /************** Descriptor of BillBoard interface ****************/ @@ -420,7 +420,7 @@ void *USBD_BB_GetCapDesc(USBD_HandleTypeDef *pdev, uint8_t *pBosDesc) UNUSED(pdev); USBD_BB_DescHeader_t *pdesc = (USBD_BB_DescHeader_t *)(void *)pBosDesc; - USBD_BosDescTypedef *desc = (USBD_BosDescTypedef *)(void *)pBosDesc; + USBD_BosDescTypeDef *desc = (USBD_BosDescTypeDef *)(void *)pBosDesc; USBD_BosBBCapDescTypedef *pCapDesc = NULL; uint16_t ptr; @@ -456,7 +456,7 @@ void *USBD_BB_GetAltModeDesc(USBD_HandleTypeDef *pdev, uint8_t *pBosDesc, uint8_ UNUSED(pdev); USBD_BB_DescHeader_t *pdesc = (USBD_BB_DescHeader_t *)(void *)pBosDesc; - USBD_BosDescTypedef *desc = (USBD_BosDescTypedef *)(void *)pBosDesc; + USBD_BosDescTypeDef *desc = (USBD_BosDescTypeDef *)(void *)pBosDesc; USBD_BB_AltModeCapDescTypeDef *pAltModDesc = NULL; uint8_t cnt = 0U; uint16_t ptr; @@ -485,7 +485,7 @@ void *USBD_BB_GetAltModeDesc(USBD_HandleTypeDef *pdev, uint8_t *pBosDesc, uint8_ } return (void *)pAltModDesc; } -#endif +#endif /* USBD_CLASS_BOS_ENABLED */ /** * @} diff --git a/Class/CCID/Inc/usbd_ccid.h b/Class/CCID/Inc/usbd_ccid.h index cc4bb1d..9a0f6c2 100644 --- a/Class/CCID/Inc/usbd_ccid.h +++ b/Class/CCID/Inc/usbd_ccid.h @@ -101,28 +101,28 @@ extern "C" { #ifndef CCID_VOLTAGE_SUPP #define CCID_VOLTAGE_SUPP 0x07U -#endif +#endif /* CCID_VOLTAGE_SUPP */ #ifndef USBD_CCID_PROTOCOL #define USBD_CCID_PROTOCOL 0x03U -#endif +#endif /* USBD_CCID_PROTOCOL */ #ifndef USBD_CCID_DEFAULT_CLOCK_FREQ #define USBD_CCID_DEFAULT_CLOCK_FREQ 3600U -#endif +#endif /* USBD_CCID_DEFAULT_CLOCK_FREQ */ #ifndef USBD_CCID_MAX_CLOCK_FREQ #define USBD_CCID_MAX_CLOCK_FREQ USBD_CCID_DEFAULT_CLOCK_FREQ -#endif +#endif /* USBD_CCID_MAX_CLOCK_FREQ */ #ifndef USBD_CCID_DEFAULT_DATA_RATE #define USBD_CCID_DEFAULT_DATA_RATE 9677U -#endif +#endif /* USBD_CCID_DEFAULT_DATA_RATE */ #ifndef USBD_CCID_MAX_DATA_RATE #define USBD_CCID_MAX_DATA_RATE USBD_CCID_DEFAULT_DATA_RATE -#endif +#endif /* USBD_CCID_MAX_DATA_RATE */ #ifndef USBD_CCID_MAX_INF_FIELD_SIZE #define USBD_CCID_MAX_INF_FIELD_SIZE 254U -#endif +#endif /* USBD_CCID_MAX_INF_FIELD_SIZE */ #ifndef CCID_MAX_BLOCK_SIZE_HEADER #define CCID_MAX_BLOCK_SIZE_HEADER 271U -#endif +#endif /* CCID_MAX_BLOCK_SIZE_HEADER */ #define TPDU_EXCHANGE 0x01U #define SHORT_APDU_EXCHANGE 0x02U @@ -131,20 +131,24 @@ extern "C" { #ifndef EXCHANGE_LEVEL_FEATURE #define EXCHANGE_LEVEL_FEATURE TPDU_EXCHANGE -#endif +#endif /* EXCHANGE_LEVEL_FEATURE */ #define CCID_ENDPOINT_DESC_SIZE 0x07U #ifndef CCID_EP0_BUFF_SIZ #define CCID_EP0_BUFF_SIZ 64U -#endif +#endif /* CCID_EP0_BUFF_SIZ */ #ifndef CCID_BULK_EPIN_SIZE #define CCID_BULK_EPIN_SIZE 64U -#endif +#endif /* CCID_BULK_EPIN_SIZE */ #define CCID_INT_BUFF_SIZ 2U /*---------------------------------------------------------------------*/ +/* + * CCID Class specification revision 1.1 + * Command Pipe. Bulk Messages + */ /* CCID Bulk Out Command definitions */ #define PC_TO_RDR_ICCPOWERON 0x62U @@ -213,7 +217,6 @@ typedef struct uint8_t datatype; } USBD_CCID_LineCodingTypeDef; -#pragma pack(1) typedef struct { uint8_t bMessageType; /* Offset = 0*/ @@ -230,10 +233,8 @@ typedef struct or for a TPDU T=1 block is 259 bytes, or for a short APDU T=1 block is 261 bytes, or for an extended APDU T=1 block is 65544 bytes.*/ -} USBD_CCID_BulkOut_DataTypeDef; -#pragma pack() +} __PACKED USBD_CCID_BulkOut_DataTypeDef; -#pragma pack(1) typedef struct { uint8_t bMessageType; /* Offset = 0 */ @@ -245,8 +246,7 @@ typedef struct uint8_t bSpecific; /* Offset = 9 */ uint8_t abData[ABDATA_SIZE]; /* Offset = 10 */ uint16_t u16SizeToSend; -} USBD_CCID_BulkIn_DataTypeDef; -#pragma pack() +} __PACKED USBD_CCID_BulkIn_DataTypeDef; typedef struct { @@ -262,6 +262,36 @@ typedef struct __IO uint8_t bSlot; } USBD_CCID_ParamTypeDef; +/* + * CCID Class specification revsion 1.1 + * Smart Card Device Class Descriptor Table + */ + +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdCCID; + uint8_t bMaxSlotIndex; + uint8_t bVoltageSupport; + uint32_t dwProtocols; + uint32_t dwDefaultClock; + uint32_t dwMaximumClock; + uint8_t bNumClockSupported; + uint32_t dwDataRate; + uint32_t dwMaxDataRate; + uint8_t bNumDataRatesSupported; + uint32_t dwMaxIFSD; + uint32_t dwSynchProtocols; + uint32_t dwMechanical; + uint32_t dwFeatures; + uint32_t dwMaxCCIDMessageLength; + uint8_t bClassGetResponse; + uint8_t bClassEnvelope; + uint16_t wLcdLayout; + uint8_t bPINSupport; + uint8_t bMaxCCIDBusySlots; +} __PACKED USBD_CCID_DescTypeDef; typedef struct { diff --git a/Class/CCID/Inc/usbd_ccid_cmd.h b/Class/CCID/Inc/usbd_ccid_cmd.h index 3d9d56b..c9bc3b9 100644 --- a/Class/CCID/Inc/usbd_ccid_cmd.h +++ b/Class/CCID/Inc/usbd_ccid_cmd.h @@ -27,11 +27,11 @@ extern "C" { /* Includes ------------------------------------------------------------------*/ #ifndef __USBD_CCID_IF_H #include "usbd_ccid_if_template.h" -#endif +#endif /* __USBD_CCID_IF_H */ #ifndef __USBD_CCID_SC_IF_H #include "usbd_ccid_sc_if_template.h" -#endif +#endif /* __USBD_CCID_SC_IF_H */ /* Exported types ------------------------------------------------------------*/ @@ -54,6 +54,10 @@ extern "C" { positive number (1-127). For instance, if the CCID receives an ICC command to an unimplemented slot, then the Slot Error register shall be set to 5 (index of bSlot field) */ +/* + * CCID Class specification revsion 1.1 + */ + /* Following Parameters used in PC_to_RDR_XfrBlock */ #define SLOTERROR_BAD_LENTGH 0x01U #define SLOTERROR_BAD_SLOT 0x05U @@ -97,25 +101,25 @@ extern "C" { /* DEFAULT_FIDI_VALUE */ #ifndef DEFAULT_FIDI #define DEFAULT_FIDI 0x11U -#endif +#endif /* DEFAULT_FIDI */ #ifndef DEFAULT_T01CONVCHECKSUM #define DEFAULT_T01CONVCHECKSUM 0x00U -#endif +#endif /* DEFAULT_T01CONVCHECKSUM */ #ifndef DEFAULT_EXTRA_GUARDTIME #define DEFAULT_EXTRA_GUARDTIME 0x00U -#endif +#endif /* DEFAULT_EXTRA_GUARDTIME */ #ifndef DEFAULT_WAITINGINTEGER #define DEFAULT_WAITINGINTEGER 0x0AU -#endif +#endif /* DEFAULT_WAITINGINTEGER */ #ifndef DEFAULT_CLOCKSTOP #define DEFAULT_CLOCKSTOP 0x00U -#endif +#endif /* DEFAULT_CLOCKSTOP */ #ifndef DEFAULT_IFSC #define DEFAULT_IFSC 0x20U -#endif +#endif /* DEFAULT_IFSC */ #ifndef DEFAULT_NAD #define DEFAULT_NAD 0x00U -#endif +#endif /* DEFAULT_NAD */ /* Following Parameters used in PC_to_RDR_IccPowerOn */ #define VOLTAGE_SELECTION_AUTOMATIC 0xFFU @@ -151,10 +155,9 @@ Offset=6 bmCommandStatus 2 bits 0, 1, 2 #define SIZE_OF_ATR 19U #else #define SIZE_OF_ATR 15U -#endif +#endif /* (ATR_T01 == 0) */ /* defines for the CCID_CMD Layers */ -#define LEN_RDR_TO_PC_SLOTSTATUS 10U #define LEN_PROTOCOL_STRUCT_T0 5U #define LEN_PROTOCOL_STRUCT_T1 7U @@ -174,8 +177,8 @@ Offset=6 bmCommandStatus 2 bits 0, 1, 2 #define CHK_PARAM_SLOT 0x01U #define CHK_PARAM_DWLENGTH 0x02U -#define CHK_PARAM_abRFU2 0x04U -#define CHK_PARAM_abRFU3 0x08U +#define CHK_PARAM_ABRFU2 0x04U +#define CHK_PARAM_ABRFU3 0x08U #define CHK_PARAM_CARD_PRESENT 0x10U #define CHK_PARAM_ABORT 0x20U #define CHK_ACTIVE_STATE 0x40U @@ -207,7 +210,7 @@ void RDR_to_PC_DataRateAndClockFrequency(uint8_t errorCode, USBD_HandleTypeDef * void CCID_UpdSlotStatus(USBD_HandleTypeDef *pdev, uint8_t slotStatus); void CCID_UpdSlotChange(USBD_HandleTypeDef *pdev, uint8_t changeStatus); uint8_t CCID_IsSlotStatusChange(USBD_HandleTypeDef *pdev); -uint8_t CCID_CmdAbort(uint8_t slot, uint8_t seq); +uint8_t CCID_CmdAbort(USBD_HandleTypeDef *pdev, uint8_t slot, uint8_t seq); uint8_t USBD_CCID_Transfer_Data_Request(USBD_HandleTypeDef *pdev, uint8_t *dataPointer, uint16_t dataLen); diff --git a/Class/CCID/Inc/usbd_ccid_if_template.h b/Class/CCID/Inc/usbd_ccid_if_template.h index e690077..af75689 100644 --- a/Class/CCID/Inc/usbd_ccid_if_template.h +++ b/Class/CCID/Inc/usbd_ccid_if_template.h @@ -30,7 +30,7 @@ extern "C" { #ifndef __USBD_CCID_SMARTCARD_H #include "usbd_ccid_smartcard_template.h" -#endif +#endif /* __USBD_CCID_SMARTCARD_H */ /* Exported defines ----------------------------------------------------------*/ @@ -49,11 +49,11 @@ extern "C" { #define BOTH_DIR 2U /************ Value of the Interrupt transfer status to set ******************/ -#define IntrStatus_Complete 1U -#define IntrStatus_Reset 0U +#define INTRSTATUS_COMPLETE 1U +#define INTRSTATUS_RESET 0U /************** slot change status *******************************************/ -#define SlotStatus_Changed 1U -#define SlotStatus_Reset 0U +#define SLOTSTATUS_CHANGED 1U +#define SLOTSTATUS_RESET 0U /* Exported types ------------------------------------------------------------*/ extern USBD_HandleTypeDef USBD_Device; diff --git a/Class/CCID/Inc/usbd_ccid_sc_if_template.h b/Class/CCID/Inc/usbd_ccid_sc_if_template.h index 29ba8b4..0072f8b 100644 --- a/Class/CCID/Inc/usbd_ccid_sc_if_template.h +++ b/Class/CCID/Inc/usbd_ccid_sc_if_template.h @@ -30,7 +30,7 @@ extern "C" { #ifndef __USBD_CCID_SMARTCARD_H #include "usbd_ccid_smartcard_template.h" -#endif +#endif /* __USBD_CCID_SMARTCARD_H */ /* Exported constants --------------------------------------------------------*/ /* Exported types ------------------------------------------------------------*/ diff --git a/Class/CCID/Inc/usbd_ccid_smartcard_template.h b/Class/CCID/Inc/usbd_ccid_smartcard_template.h index ac97a14..7730180 100644 --- a/Class/CCID/Inc/usbd_ccid_smartcard_template.h +++ b/Class/CCID/Inc/usbd_ccid_smartcard_template.h @@ -28,7 +28,7 @@ extern "C" { /* Includes ------------------------------------------------------------------*/ #ifndef __USBD_CCID_IF_H #include "usbd_ccid_if_template.h" -#endif +#endif /* __USBD_CCID_IF_H */ /* Exported constants --------------------------------------------------------*/ #define T0_PROTOCOL 0x00U /* T0 protocol */ @@ -162,29 +162,29 @@ typedef enum /* Interface Byte structure - TA(i), TB(i), TC(i) and TD(i) ------------------*/ typedef struct { - uint8_t Status; /* The Presence of the Interface byte */ - uint8_t Value; /* The Value of the Interface byte */ -} SC_InterfaceByte; + uint8_t Status; /* The Presence of the Interface byte */ + uint8_t Value; /* The Value of the Interface byte */ +} SC_InterfaceByteTypeDef; /* Protocol Level structure - ------------------------------------------------*/ typedef struct { - SC_InterfaceByte InterfaceByte[MAX_INTERFACEBYTE]; /* The Values of the Interface byte TA(i), TB(i), TC(i)and TD(i) */ -} SC_ProtocolLevel; + SC_InterfaceByteTypeDef InterfaceByte[MAX_INTERFACEBYTE]; /* The Values of the Interface byte + TA(i), TB(i), TC(i)and TD(i) */ +} SC_ProtocolLevelTypeDef; /* ATR structure - Answer To Reset -------------------------------------------*/ typedef struct { - uint8_t TS; /* Bit Convention Direct/Indirect */ - uint8_t T0; /* Each bit in the high nibble = Presence of the further interface byte; - Low nibble = Number of historical byte */ - - SC_ProtocolLevel T[MAX_PROTOCOLLEVEL]; /* Setup array */ - uint8_t H[HIST_LENGTH]; /* Historical array */ - uint8_t Tlength; /* Setup array dimension */ - uint8_t Hlength; /* Historical array dimension */ + uint8_t TS; /* Bit Convention Direct/Indirect */ + uint8_t T0; /* Each bit in the high nibble = Presence of the further interface byte; + Low nibble = Number of historical byte */ + SC_ProtocolLevelTypeDef T[MAX_PROTOCOLLEVEL]; /* Setup array */ + uint8_t Historical[HIST_LENGTH]; /* Historical array */ + uint8_t Tlength; /* Setup array dimension */ + uint8_t Hlength; /* Historical array dimension */ uint8_t TCK; -} SC_ATR; +} SC_ATRTypeDef; /* ADPU-Header command structure ---------------------------------------------*/ typedef struct @@ -193,7 +193,7 @@ typedef struct uint8_t INS; /* Operation code */ uint8_t P1; /* Selection Mode */ uint8_t P2; /* Selection Option */ -} SC_Header; +} SC_HeaderTypeDef; /* ADPU-Body command structure -----------------------------------------------*/ typedef struct @@ -201,22 +201,22 @@ typedef struct uint8_t LC; /* Data field length */ uint8_t Data[LC_MAX]; /* Command parameters */ uint8_t LE; /* Expected length of data to be returned */ -} SC_Body; +} SC_BodyTypeDef; /* ADPU Command structure ----------------------------------------------------*/ typedef struct { - SC_Header Header; - SC_Body Body; -} SC_ADPU_Commands; + SC_HeaderTypeDef Header; + SC_BodyTypeDef Body; +} SC_ADPU_CommandsTypeDef; /* SC response structure -----------------------------------------------------*/ typedef struct { uint8_t Data[LC_MAX]; /* Data returned from the card */ - uint8_t SW1; /* Command Processing status */ - uint8_t SW2; /* Command Processing qualification */ -} SC_ADPU_Response; + uint8_t SW1; /* Command Processing status */ + uint8_t SW2; /* Command Processing qualification */ +} SC_ADPU_ResponseTypeDef; /* SC Command Status -----------------------------------------------------*/ typedef enum @@ -255,7 +255,7 @@ typedef enum /* Exported macro ------------------------------------------------------------*/ /* Exported functions ------------------------------------------------------- */ /* APPLICATION LAYER ---------------------------------------------------------*/ -void SC_Handler(SC_State *SCState, SC_ADPU_Commands *SC_ADPU, SC_ADPU_Response *SC_Response); +void SC_Handler(SC_State *SCState, SC_ADPU_CommandsTypeDef *SC_ADPU, SC_ADPU_ResponseTypeDef *SC_Response); void SC_PowerCmd(SCPowerState NewState); void SC_ParityErrorHandler(void); void SC_PTSConfig(void); @@ -266,11 +266,11 @@ void SC_SetState(SC_State scState); void SC_IOConfig(void); extern uint8_t SC_ATR_Table[40]; -extern SC_ATR SC_A2R; -extern SC_ADPU_Response SC_Response; +extern SC_ATRTypeDef SC_A2R; +extern SC_ADPU_ResponseTypeDef SC_Response; extern uint8_t ProtocolNUM_OUT; -extern SC_ADPU_Commands SC_ADPU; +extern SC_ADPU_CommandsTypeDef SC_ADPU; #ifdef __cplusplus } diff --git a/Class/CCID/Src/usbd_ccid.c b/Class/CCID/Src/usbd_ccid.c index 0f1c973..9b91dbd 100644 --- a/Class/CCID/Src/usbd_ccid.c +++ b/Class/CCID/Src/usbd_ccid.c @@ -85,11 +85,12 @@ static uint8_t USBD_CCID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum); static uint8_t USBD_CCID_DispatchCommand(USBD_HandleTypeDef *pdev); static uint8_t USBD_CCID_ReceiveCmdHeader(USBD_HandleTypeDef *pdev, uint8_t *pDst, uint16_t u8length); - +#ifndef USE_USBD_COMPOSITE static uint8_t *USBD_CCID_GetHSCfgDesc(uint16_t *length); static uint8_t *USBD_CCID_GetFSCfgDesc(uint16_t *length); static uint8_t *USBD_CCID_GetOtherSpeedCfgDesc(uint16_t *length); static uint8_t *USBD_CCID_GetDeviceQualifierDescriptor(uint16_t *length); +#endif /* USE_USBD_COMPOSITE */ /** * @} @@ -99,6 +100,10 @@ static uint8_t *USBD_CCID_GetDeviceQualifierDescriptor(uint16_t *length); * @{ */ +static uint8_t CCIDInEpAdd = CCID_IN_EP; +static uint8_t CCIDOutEpAdd = CCID_OUT_EP; +static uint8_t CCIDCmdEpAdd = CCID_CMD_EP; + /* CCID interface class callbacks structure */ USBD_ClassTypeDef USBD_CCID = @@ -113,14 +118,23 @@ USBD_ClassTypeDef USBD_CCID = NULL, /*SOF */ NULL, /*ISOIn*/ NULL, /*ISOOut*/ +#ifdef USE_USBD_COMPOSITE + NULL, + NULL, + NULL, + NULL, +#else USBD_CCID_GetHSCfgDesc, USBD_CCID_GetFSCfgDesc, USBD_CCID_GetOtherSpeedCfgDesc, USBD_CCID_GetDeviceQualifierDescriptor, +#endif /* USE_USBD_COMPOSITE */ }; +#ifndef USE_USBD_COMPOSITE + /* USB CCID device Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_CCID_CfgHSDesc[USB_CCID_CONFIG_DESC_SIZ] __ALIGN_END = +__ALIGN_BEGIN static uint8_t USBD_CCID_CfgDesc[USB_CCID_CONFIG_DESC_SIZ] __ALIGN_END = { /* Configuration Descriptor */ 0x09, /* bLength: Configuration Descriptor size */ @@ -134,7 +148,7 @@ __ALIGN_BEGIN static uint8_t USBD_CCID_CfgHSDesc[USB_CCID_CONFIG_DESC_SIZ] __ALI 0xC0, /* bmAttributes: Bus Powered according to user configuration */ #else 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif +#endif /* USBD_SELF_POWERED */ USBD_MAX_POWER, /* MaxPower (mA) */ /******************** CCID **** interface ********************/ @@ -144,112 +158,8 @@ __ALIGN_BEGIN static uint8_t USBD_CCID_CfgHSDesc[USB_CCID_CONFIG_DESC_SIZ] __ALI 0x00, /* bAlternateSetting: Alternate setting */ 0x03, /* bNumEndpoints: 3 endpoints used */ USB_DEVICE_CLASS_CCID, /* bInterfaceClass: user's interface for CCID */ - 0x00, /* bInterfaceSubClass : No subclass, can be changed but no description in USB 2.0 Spec */ - 0x00, /* nInterfaceProtocol : None */ - 0x00, /* iInterface */ - - /******************* CCID class descriptor ********************/ - CCID_CLASS_DESC_SIZE, /* bLength: CCID Descriptor size */ - CCID_DESC_TYPE, /* bDescriptorType: Functional Descriptor type. */ - 0x10, /* bcdCCID(LSB): CCID Class Spec release number (1.1) */ - 0x01, /* bcdCCID(MSB) */ - - 0x00, /* bMaxSlotIndex :highest available slot on this device */ - CCID_VOLTAGE_SUPP, /* bVoltageSupport: bVoltageSupport: 5v, 3v and 1.8v */ - LOBYTE(USBD_CCID_PROTOCOL), /* dwProtocols: supports T=0 and T=1 */ - HIBYTE(USBD_CCID_PROTOCOL), - 0x00, - 0x00, - LOBYTE(USBD_CCID_DEFAULT_CLOCK_FREQ), /* dwDefaultClock: 3.6Mhz */ - HIBYTE(USBD_CCID_DEFAULT_CLOCK_FREQ), - 0x00, - 0x00, - LOBYTE(USBD_CCID_MAX_CLOCK_FREQ), /* dwMaximumClock */ - HIBYTE(USBD_CCID_MAX_CLOCK_FREQ), - 0x00, - 0x00, - 0x00, /* bNumClockSupported */ - LOBYTE(USBD_CCID_DEFAULT_DATA_RATE), /* dwDataRate: 9677 bps */ - HIBYTE(USBD_CCID_DEFAULT_DATA_RATE), - 0x00, - 0x00, - - LOBYTE(USBD_CCID_MAX_DATA_RATE), /* dwMaxDataRate: */ - HIBYTE(USBD_CCID_MAX_DATA_RATE), - 0x00, - 0x00, - 0x35, /* bNumDataRatesSupported */ - - LOBYTE(USBD_CCID_MAX_INF_FIELD_SIZE), /* dwMaxIFSD: maximum IFSD supported for T=1 */ - HIBYTE(USBD_CCID_MAX_INF_FIELD_SIZE), - 0x00, - 0x00, - 0x00, 0x00, 0x00, 0x00, /* dwSynchProtocols */ - 0x00, 0x00, 0x00, 0x00, /* dwMechanical: no special characteristics */ - - 0xBA, 0x04, EXCHANGE_LEVEL_FEATURE, 0x00, /* dwFeatures */ - LOBYTE(CCID_MAX_BLOCK_SIZE_HEADER), /* dwMaxCCIDMessageLength: Maximum block size + header*/ - HIBYTE(CCID_MAX_BLOCK_SIZE_HEADER), - 0x00, - 0x00, - 0x00, /* bClassGetResponse*/ - 0x00, /* bClassEnvelope */ - 0x00, 0x00, /* wLcdLayout : 0000h no LCD. */ - 0x03, /* bPINSupport : PIN verification and PIN modification */ - 0x01, /* bMaxCCIDBusySlots */ - - /******************** CCID Endpoints ********************/ - CCID_ENDPOINT_DESC_SIZE, /* Endpoint descriptor length = 7 */ - USB_DESC_TYPE_ENDPOINT, /* Endpoint descriptor type */ - CCID_IN_EP, /* Endpoint address (IN, address 1) */ - USBD_EP_TYPE_BULK, /* Bulk endpoint type */ - - LOBYTE(CCID_DATA_HS_MAX_PACKET_SIZE), - HIBYTE(CCID_DATA_HS_MAX_PACKET_SIZE), - 0x00, /* Polling interval in milliseconds */ - CCID_ENDPOINT_DESC_SIZE, /* Endpoint descriptor length = 7 */ - USB_DESC_TYPE_ENDPOINT, /* Endpoint descriptor type */ - CCID_OUT_EP, /* Endpoint address (OUT, address 1) */ - USBD_EP_TYPE_BULK, /* Bulk endpoint type */ - - LOBYTE(CCID_DATA_HS_MAX_PACKET_SIZE), - HIBYTE(CCID_DATA_HS_MAX_PACKET_SIZE), - 0x00, /* Polling interval in milliseconds */ - CCID_ENDPOINT_DESC_SIZE, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType:*/ - CCID_CMD_EP, /* bEndpointAddress: Endpoint Address (IN) */ - USBD_EP_TYPE_INTR, /* bmAttributes: Interrupt endpoint */ - LOBYTE(CCID_CMD_PACKET_SIZE), - HIBYTE(CCID_CMD_PACKET_SIZE), - CCID_CMD_HS_BINTERVAL /* Polling interval in milliseconds */ -}; - -/* USB CCID device Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_CCID_CfgFSDesc[USB_CCID_CONFIG_DESC_SIZ] __ALIGN_END = -{ - /* Configuration Descriptor */ - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - USB_CCID_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */ - 0x00, - 0x01, /* bNumInterfaces: 1 interface */ - 0x01, /* bConfigurationValue: */ - 0x00, /* iConfiguration: */ -#if (USBD_SELF_POWERED == 1U) - 0xC0, /* bmAttributes: Bus Powered according to user configuration */ -#else - 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif - USBD_MAX_POWER, /* MaxPower (mA) */ - - /******************** CCID **** interface ********************/ - CCID_INTERFACE_DESC_SIZE, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x03, /* bNumEndpoints: 3 endpoints used */ - USB_DEVICE_CLASS_CCID, /* bInterfaceClass: user's interface for CCID */ - 0x00, /* bInterfaceSubClass : No subclass, can be changed but no description in USB 2.0 Spec */ + 0x00, /* bInterfaceSubClass : No subclass, + can be changed but no description in USB 2.0 Spec */ 0x00, /* nInterfaceProtocol : None */ 0x00, /* iInterface */ @@ -343,7 +253,7 @@ __ALIGN_BEGIN static uint8_t USBD_CCID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER 0x01, 0x00, }; - +#endif /* USE_USBD_COMPOSITE */ /** * @} @@ -370,11 +280,19 @@ static uint8_t USBD_CCID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) if (hccid == NULL) { - pdev->pClassData = NULL; + pdev->pClassDataCmsit[pdev->classId] = NULL; return (uint8_t)USBD_EMEM; } - pdev->pClassData = (void *)hccid; + pdev->pClassDataCmsit[pdev->classId] = (void *)hccid; + pdev->pClassData = pdev->pClassDataCmsit[pdev->classId]; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + CCIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); + CCIDOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); + CCIDCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR); +#endif /* USE_USBD_COMPOSITE */ /* Init the CCID parameters into a state where it can receive a new command message */ hccid->USBD_CCID_Param.bAbortRequestFlag = 0U; @@ -384,23 +302,23 @@ static uint8_t USBD_CCID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) CCID_DATA_HS_MAX_PACKET_SIZE : CCID_DATA_FS_MAX_PACKET_SIZE; /* Open EP IN */ - (void)USBD_LL_OpenEP(pdev, CCID_IN_EP, USBD_EP_TYPE_BULK, (uint16_t)hccid->MaxPcktLen); - pdev->ep_in[CCID_IN_EP & 0xFU].is_used = 1U; + (void)USBD_LL_OpenEP(pdev, CCIDInEpAdd, USBD_EP_TYPE_BULK, (uint16_t)hccid->MaxPcktLen); + pdev->ep_in[CCIDInEpAdd & 0xFU].is_used = 1U; /* Open EP OUT */ - (void)USBD_LL_OpenEP(pdev, CCID_OUT_EP, USBD_EP_TYPE_BULK, (uint16_t)hccid->MaxPcktLen); - pdev->ep_out[CCID_OUT_EP & 0xFU].is_used = 1U; + (void)USBD_LL_OpenEP(pdev, CCIDOutEpAdd, USBD_EP_TYPE_BULK, (uint16_t)hccid->MaxPcktLen); + pdev->ep_out[CCIDOutEpAdd & 0xFU].is_used = 1U; /* Open INTR EP IN */ - (void)USBD_LL_OpenEP(pdev, CCID_CMD_EP, + (void)USBD_LL_OpenEP(pdev, CCIDCmdEpAdd, USBD_EP_TYPE_INTR, CCID_CMD_PACKET_SIZE); - pdev->ep_in[CCID_CMD_EP & 0xFU].is_used = 1U; + pdev->ep_in[CCIDCmdEpAdd & 0xFU].is_used = 1U; /* Init physical Interface components */ - ((USBD_CCID_ItfTypeDef *)pdev->pUserData)->Init(pdev); + ((USBD_CCID_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init(pdev); /* Prepare Out endpoint to receive next packet */ - (void)USBD_LL_PrepareReceive(pdev, CCID_OUT_EP, + (void)USBD_LL_PrepareReceive(pdev, CCIDOutEpAdd, hccid->data, hccid->MaxPcktLen); return (uint8_t)USBD_OK; @@ -417,23 +335,31 @@ static uint8_t USBD_CCID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { UNUSED(cfgidx); +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + CCIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); + CCIDOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); + CCIDCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR); +#endif /* USE_USBD_COMPOSITE */ + /* Close EP IN */ - (void)USBD_LL_CloseEP(pdev, CCID_IN_EP); - pdev->ep_in[CCID_IN_EP & 0xFU].is_used = 0U; + (void)USBD_LL_CloseEP(pdev, CCIDInEpAdd); + pdev->ep_in[CCIDInEpAdd & 0xFU].is_used = 0U; /* Close EP OUT */ - (void)USBD_LL_CloseEP(pdev, CCID_OUT_EP); - pdev->ep_out[CCID_OUT_EP & 0xFU].is_used = 0U; + (void)USBD_LL_CloseEP(pdev, CCIDOutEpAdd); + pdev->ep_out[CCIDOutEpAdd & 0xFU].is_used = 0U; /* Close EP Command */ - (void)USBD_LL_CloseEP(pdev, CCID_CMD_EP); - pdev->ep_in[CCID_CMD_EP & 0xFU].is_used = 0U; + (void)USBD_LL_CloseEP(pdev, CCIDCmdEpAdd); + pdev->ep_in[CCIDCmdEpAdd & 0xFU].is_used = 0U; /* DeInit physical Interface components */ - if (pdev->pClassData != NULL) + if (pdev->pClassDataCmsit[pdev->classId] != NULL) { - ((USBD_CCID_ItfTypeDef *)pdev->pUserData)->DeInit(pdev); - (void)USBD_free(pdev->pClassData); + ((USBD_CCID_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit(pdev); + (void)USBD_free(pdev->pClassDataCmsit[pdev->classId]); + pdev->pClassDataCmsit[pdev->classId] = NULL; pdev->pClassData = NULL; } @@ -449,8 +375,8 @@ static uint8_t USBD_CCID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) */ static uint8_t USBD_CCID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; - USBD_CCID_ItfTypeDef *hCCIDitf = (USBD_CCID_ItfTypeDef *)pdev->pUserData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_CCID_ItfTypeDef *hCCIDitf = (USBD_CCID_ItfTypeDef *)pdev->pUserData[pdev->classId]; USBD_StatusTypeDef ret = USBD_OK; uint8_t ifalt = 0U; uint16_t status_info = 0U; @@ -544,9 +470,15 @@ static uint8_t USBD_CCID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *r */ static uint8_t USBD_CCID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; - if (epnum == (CCID_IN_EP & 0x7FU)) +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + CCIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); + CCIDCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR); +#endif /* USE_USBD_COMPOSITE */ + + if (epnum == (CCIDInEpAdd & 0x7FU)) { /* Filter the epnum by masking with 0x7f (mask of IN Direction) */ @@ -561,14 +493,14 @@ static uint8_t USBD_CCID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) /* Prepare EP to Receive Cmd */ (void)USBD_LL_PrepareReceive(pdev, CCID_OUT_EP, - hccid->data, CCID_DATA_FS_MAX_PACKET_SIZE); + hccid->data, hccid->MaxPcktLen); break; default: break; } } - else if (epnum == (CCID_CMD_EP & 0x7FU)) + else if (epnum == (CCIDCmdEpAdd & 0x7FU)) { /* Filter the epnum by masking with 0x7f (mask of IN Direction) */ @@ -593,15 +525,20 @@ static uint8_t USBD_CCID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) */ static uint8_t USBD_CCID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint16_t CurrPcktLen; +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + CCIDOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ + if (hccid == NULL) { return (uint8_t)USBD_EMEM; } - if (epnum == CCID_OUT_EP) + if (epnum == CCIDOutEpAdd) { CurrPcktLen = (uint16_t)USBD_GetRxCount(pdev, epnum); @@ -735,7 +672,7 @@ static uint8_t USBD_CCID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) */ static uint8_t USBD_CCID_DispatchCommand(USBD_HandleTypeDef *pdev) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint8_t errorCode; switch (hccid->UsbBlkOutData.bMessageType) @@ -828,13 +765,13 @@ static uint8_t USBD_CCID_DispatchCommand(USBD_HandleTypeDef *pdev) uint8_t USBD_CCID_Transfer_Data_Request(USBD_HandleTypeDef *pdev, uint8_t *dataPointer, uint16_t dataLen) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; - USBD_CCID_ItfTypeDef *hCCIDitf = (USBD_CCID_ItfTypeDef *)pdev->pUserData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_CCID_ItfTypeDef *hCCIDitf = (USBD_CCID_ItfTypeDef *)pdev->pUserData[pdev->classId]; UNUSED(dataPointer); hccid->blkt_state = CCID_STATE_SEND_RESP; - hccid->UsbMessageLength = hccid->UsbBlkInData.dwLength + (uint32_t)dataLen; /* Store for future use */ + hccid->UsbMessageLength = (uint32_t)dataLen; /* Store for future use */ /* use the header declared size packet must be well formed */ hCCIDitf->Response_SendData(pdev, (uint8_t *)&hccid->UsbBlkInData, @@ -854,7 +791,7 @@ uint8_t USBD_CCID_Transfer_Data_Request(USBD_HandleTypeDef *pdev, static uint8_t USBD_CCID_ReceiveCmdHeader(USBD_HandleTypeDef *pdev, uint8_t *pDst, uint16_t u8length) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint8_t *pdst = pDst; uint32_t Counter; @@ -875,7 +812,12 @@ static uint8_t USBD_CCID_ReceiveCmdHeader(USBD_HandleTypeDef *pdev, */ uint8_t USBD_CCID_IntMessage(USBD_HandleTypeDef *pdev) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + CCIDCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR); +#endif /* USE_USBD_COMPOSITE */ /* Check if there is change in Smartcard Slot status */ if (CCID_IsSlotStatusChange(pdev) != 0U) @@ -884,19 +826,20 @@ uint8_t USBD_CCID_IntMessage(USBD_HandleTypeDef *pdev) RDR_to_PC_NotifySlotChange(pdev); /* Set the Slot status */ - ((USBD_CCID_ItfTypeDef *)pdev->pUserData)->SetSlotStatus(pdev); + ((USBD_CCID_ItfTypeDef *)pdev->pUserData[pdev->classId])->SetSlotStatus(pdev); - (void)USBD_LL_Transmit(pdev, CCID_CMD_EP, hccid->UsbIntData, 2U); + (void)USBD_LL_Transmit(pdev, CCIDCmdEpAdd, hccid->UsbIntData, 2U); } else { /* Set the Slot status */ - ((USBD_CCID_ItfTypeDef *)pdev->pUserData)->SetSlotStatus(pdev); + ((USBD_CCID_ItfTypeDef *)pdev->pUserData[pdev->classId])->SetSlotStatus(pdev); } return (uint8_t)USBD_OK; } +#ifndef USE_USBD_COMPOSITE /** * @brief USBD_CCID_GetHSCfgDesc * Return configuration descriptor @@ -905,8 +848,27 @@ uint8_t USBD_CCID_IntMessage(USBD_HandleTypeDef *pdev) */ static uint8_t *USBD_CCID_GetHSCfgDesc(uint16_t *length) { - *length = (uint16_t)sizeof(USBD_CCID_CfgHSDesc); - return USBD_CCID_CfgHSDesc; + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_IN_EP); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_OUT_EP); + USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_CMD_EP); + + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = CCID_DATA_HS_MAX_PACKET_SIZE; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = CCID_DATA_HS_MAX_PACKET_SIZE; + } + + if (pEpCmdDesc != NULL) + { + pEpCmdDesc->bInterval = CCID_CMD_HS_BINTERVAL; + } + + *length = (uint16_t)sizeof(USBD_CCID_CfgDesc); + return USBD_CCID_CfgDesc; } /** * @brief USBD_CCID_GetFSCfgDesc @@ -916,8 +878,27 @@ static uint8_t *USBD_CCID_GetHSCfgDesc(uint16_t *length) */ static uint8_t *USBD_CCID_GetFSCfgDesc(uint16_t *length) { - *length = (uint16_t)sizeof(USBD_CCID_CfgFSDesc); - return USBD_CCID_CfgFSDesc; + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_IN_EP); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_OUT_EP); + USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_CMD_EP); + + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = CCID_DATA_FS_MAX_PACKET_SIZE; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = CCID_DATA_FS_MAX_PACKET_SIZE; + } + + if (pEpCmdDesc != NULL) + { + pEpCmdDesc->bInterval = CCID_CMD_FS_BINTERVAL; + } + + *length = (uint16_t)sizeof(USBD_CCID_CfgDesc); + return USBD_CCID_CfgDesc; } /** @@ -928,8 +909,27 @@ static uint8_t *USBD_CCID_GetFSCfgDesc(uint16_t *length) */ static uint8_t *USBD_CCID_GetOtherSpeedCfgDesc(uint16_t *length) { - *length = (uint16_t)sizeof(USBD_CCID_CfgFSDesc); - return USBD_CCID_CfgFSDesc; + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_IN_EP); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_OUT_EP); + USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_CMD_EP); + + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = CCID_DATA_FS_MAX_PACKET_SIZE; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = CCID_DATA_FS_MAX_PACKET_SIZE; + } + + if (pEpCmdDesc != NULL) + { + pEpCmdDesc->bInterval = CCID_CMD_FS_BINTERVAL; + } + + *length = (uint16_t)sizeof(USBD_CCID_CfgDesc); + return USBD_CCID_CfgDesc; } /** @@ -943,6 +943,7 @@ static uint8_t *USBD_CCID_GetDeviceQualifierDescriptor(uint16_t *length) *length = (uint16_t)(sizeof(USBD_CCID_DeviceQualifierDesc)); return USBD_CCID_DeviceQualifierDesc; } +#endif /* USE_USBD_COMPOSITE */ /** * @brief USBD_CCID_RegisterInterface @@ -958,7 +959,7 @@ uint8_t USBD_CCID_RegisterInterface(USBD_HandleTypeDef *pdev, return (uint8_t)USBD_FAIL; } - pdev->pUserData = fops; + pdev->pUserData[pdev->classId] = fops; return (uint8_t)USBD_OK; } diff --git a/Class/CCID/Src/usbd_ccid_cmd.c b/Class/CCID/Src/usbd_ccid_cmd.c index 7212bd9..b91cb1f 100644 --- a/Class/CCID/Src/usbd_ccid_cmd.c +++ b/Class/CCID/Src/usbd_ccid_cmd.c @@ -25,7 +25,7 @@ /* Private macro -------------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ static uint8_t CCID_CheckCommandParams(USBD_HandleTypeDef *pdev, uint32_t param_type); -static void CCID_UpdateCommandStatus(uint8_t cmd_status, uint8_t icc_status); +static void CCID_UpdateCommandStatus(USBD_HandleTypeDef *pdev, uint8_t cmd_status, uint8_t icc_status); /* Private functions ---------------------------------------------------------*/ @@ -45,7 +45,7 @@ uint8_t PC_to_RDR_IccPowerOn(USBD_HandleTypeDef *pdev) Fills the Response buffer with ICC ATR This Command is returned with RDR_to_PC_DataBlock(); */ - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint8_t voltage; uint8_t sc_voltage = 0U; uint8_t index; @@ -54,7 +54,7 @@ uint8_t PC_to_RDR_IccPowerOn(USBD_HandleTypeDef *pdev) hccid->UsbBlkInData.dwLength = 0U; /* Reset Number of Bytes in abData */ error = CCID_CheckCommandParams(pdev, CHK_PARAM_SLOT | CHK_PARAM_DWLENGTH | - CHK_PARAM_abRFU2 | CHK_PARAM_CARD_PRESENT | + CHK_PARAM_ABRFU2 | CHK_PARAM_CARD_PRESENT | CHK_PARAM_ABORT); if (error != 0U) { @@ -71,7 +71,7 @@ uint8_t PC_to_RDR_IccPowerOn(USBD_HandleTypeDef *pdev) voltage = hccid->UsbBlkOutData.bSpecific_0; if (voltage >= VOLTAGE_SELECTION_1V8) { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); return SLOTERROR_BAD_POWERSELECT; /* The Voltage specified is out of Spec */ } @@ -120,7 +120,7 @@ uint8_t PC_to_RDR_IccPowerOn(USBD_HandleTypeDef *pdev) else { /* Voltage requested from Host was 5V already*/ - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_INACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_INACTIVE)); return error; } } /* Voltage Selection was automatic */ @@ -128,7 +128,7 @@ uint8_t PC_to_RDR_IccPowerOn(USBD_HandleTypeDef *pdev) /* ATR is received, No Error Condition Found */ hccid->UsbBlkInData.dwLength = SIZE_OF_ATR; - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); for (index = 0U; index < SIZE_OF_ATR; index++) { @@ -150,7 +150,7 @@ uint8_t PC_to_RDR_IccPowerOff(USBD_HandleTypeDef *pdev) /* The response to this command is the RDR_to_PC_SlotStatus*/ uint8_t error; - error = CCID_CheckCommandParams(pdev, CHK_PARAM_SLOT | CHK_PARAM_abRFU3 | + error = CCID_CheckCommandParams(pdev, CHK_PARAM_SLOT | CHK_PARAM_ABRFU3 | CHK_PARAM_DWLENGTH); if (error != 0U) { @@ -159,11 +159,11 @@ uint8_t PC_to_RDR_IccPowerOff(USBD_HandleTypeDef *pdev) /* Command is ok, Check for Card Presence */ if (SC_Detect() != 0U) { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_INACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_INACTIVE)); } else { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_NO_ICC_PRESENT)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_NO_ICC_PRESENT)); } /* Power OFF the card */ @@ -183,13 +183,13 @@ uint8_t PC_to_RDR_GetSlotStatus(USBD_HandleTypeDef *pdev) uint8_t error; error = CCID_CheckCommandParams(pdev, CHK_PARAM_SLOT | CHK_PARAM_DWLENGTH | - CHK_PARAM_CARD_PRESENT | CHK_PARAM_abRFU3); + CHK_PARAM_CARD_PRESENT | CHK_PARAM_ABRFU3); if (error != 0U) { return error; } - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); return SLOT_NO_ERROR; } @@ -203,13 +203,13 @@ uint8_t PC_to_RDR_GetSlotStatus(USBD_HandleTypeDef *pdev) */ uint8_t PC_to_RDR_XfrBlock(USBD_HandleTypeDef *pdev) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint16_t expectedLength; uint8_t error; error = CCID_CheckCommandParams(pdev, CHK_PARAM_SLOT | CHK_PARAM_CARD_PRESENT | - CHK_PARAM_abRFU3 | CHK_PARAM_ABORT | CHK_ACTIVE_STATE); + CHK_PARAM_ABRFU3 | CHK_PARAM_ABORT | CHK_ACTIVE_STATE); if (error != 0U) { return error; @@ -234,11 +234,11 @@ uint8_t PC_to_RDR_XfrBlock(USBD_HandleTypeDef *pdev) if (error != SLOT_NO_ERROR) { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); } else { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); error = SLOT_NO_ERROR; } @@ -257,12 +257,12 @@ uint8_t PC_to_RDR_GetParameters(USBD_HandleTypeDef *pdev) uint8_t error; error = CCID_CheckCommandParams(pdev, CHK_PARAM_SLOT | CHK_PARAM_DWLENGTH | - CHK_PARAM_CARD_PRESENT | CHK_PARAM_abRFU3); + CHK_PARAM_CARD_PRESENT | CHK_PARAM_ABRFU3); if (error != 0U) { return error; } - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); return SLOT_NO_ERROR; } @@ -276,11 +276,11 @@ uint8_t PC_to_RDR_GetParameters(USBD_HandleTypeDef *pdev) */ uint8_t PC_to_RDR_ResetParameters(USBD_HandleTypeDef *pdev) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint8_t error; error = CCID_CheckCommandParams(pdev, CHK_PARAM_SLOT | CHK_PARAM_DWLENGTH | - CHK_PARAM_CARD_PRESENT | CHK_PARAM_abRFU3 | + CHK_PARAM_CARD_PRESENT | CHK_PARAM_ABRFU3 | CHK_ACTIVE_STATE); if (error != 0U) { @@ -302,11 +302,11 @@ uint8_t PC_to_RDR_ResetParameters(USBD_HandleTypeDef *pdev) if (error != SLOT_NO_ERROR) { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); } else { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); error = SLOT_NO_ERROR; } @@ -321,11 +321,11 @@ uint8_t PC_to_RDR_ResetParameters(USBD_HandleTypeDef *pdev) */ uint8_t PC_to_RDR_SetParameters(USBD_HandleTypeDef *pdev) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint8_t error; error = CCID_CheckCommandParams(pdev, CHK_PARAM_SLOT | CHK_PARAM_CARD_PRESENT | - CHK_PARAM_abRFU2 | CHK_ACTIVE_STATE); + CHK_PARAM_ABRFU2 | CHK_ACTIVE_STATE); if (error != 0U) { return error; @@ -345,7 +345,7 @@ uint8_t PC_to_RDR_SetParameters(USBD_HandleTypeDef *pdev) } if (error != SLOT_NO_ERROR) { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); } (void)USBD_memcpy(&ProtocolData, (void const *)(&hccid->UsbBlkOutData.abData[0]), @@ -355,11 +355,11 @@ uint8_t PC_to_RDR_SetParameters(USBD_HandleTypeDef *pdev) if (error != SLOT_NO_ERROR) { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); } else { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); error = SLOT_NO_ERROR; } @@ -374,12 +374,12 @@ uint8_t PC_to_RDR_SetParameters(USBD_HandleTypeDef *pdev) */ uint8_t PC_to_RDR_Escape(USBD_HandleTypeDef *pdev) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint8_t error; uint32_t size; error = CCID_CheckCommandParams(pdev, CHK_PARAM_SLOT | CHK_PARAM_CARD_PRESENT | - CHK_PARAM_abRFU3 | CHK_PARAM_ABORT | CHK_ACTIVE_STATE); + CHK_PARAM_ABRFU3 | CHK_PARAM_ABORT | CHK_ACTIVE_STATE); if (error != 0U) { @@ -392,11 +392,11 @@ uint8_t PC_to_RDR_Escape(USBD_HandleTypeDef *pdev) if (error != SLOT_NO_ERROR) { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); } else { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); } return error; @@ -410,11 +410,11 @@ uint8_t PC_to_RDR_Escape(USBD_HandleTypeDef *pdev) */ uint8_t PC_to_RDR_IccClock(USBD_HandleTypeDef *pdev) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint8_t error; error = CCID_CheckCommandParams(pdev, CHK_PARAM_SLOT | CHK_PARAM_CARD_PRESENT | - CHK_PARAM_abRFU2 | CHK_PARAM_DWLENGTH | CHK_ACTIVE_STATE); + CHK_PARAM_ABRFU2 | CHK_PARAM_DWLENGTH | CHK_ACTIVE_STATE); if (error != 0U) { return error; @@ -424,7 +424,7 @@ uint8_t PC_to_RDR_IccClock(USBD_HandleTypeDef *pdev) 01h Stops Clock in the state shown in the bClockStop field */ if (hccid->UsbBlkOutData.bSpecific_0 > 1U) { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); return SLOTERROR_BAD_CLOCKCOMMAND; } @@ -432,11 +432,11 @@ uint8_t PC_to_RDR_IccClock(USBD_HandleTypeDef *pdev) if (error != SLOT_NO_ERROR) { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); } else { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); } return error; @@ -451,17 +451,17 @@ uint8_t PC_to_RDR_IccClock(USBD_HandleTypeDef *pdev) */ uint8_t PC_to_RDR_Abort(USBD_HandleTypeDef *pdev) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint8_t error; - error = CCID_CheckCommandParams(pdev, CHK_PARAM_SLOT | CHK_PARAM_abRFU3 | + error = CCID_CheckCommandParams(pdev, CHK_PARAM_SLOT | CHK_PARAM_ABRFU3 | CHK_PARAM_DWLENGTH); if (error != 0U) { return error; } - (void)CCID_CmdAbort(hccid->UsbBlkOutData.bSlot, hccid->UsbBlkOutData.bSeq); - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); + (void)CCID_CmdAbort(pdev, hccid->UsbBlkOutData.bSlot, hccid->UsbBlkOutData.bSeq); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); return SLOT_NO_ERROR; } @@ -469,13 +469,14 @@ uint8_t PC_to_RDR_Abort(USBD_HandleTypeDef *pdev) * @brief CCID_CmdAbort * Execute the Abort command from Bulk EP or from Control EP, * This stops all Bulk transfers from host and ICC + * @param pdev: device instance * @param slot: slot number that host wants to abort * @param seq : Seq number for PC_to_RDR_Abort * @retval status of the command execution */ -uint8_t CCID_CmdAbort(uint8_t slot, uint8_t seq) +uint8_t CCID_CmdAbort(USBD_HandleTypeDef *pdev, uint8_t slot, uint8_t seq) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)(USBD_Device.pClassData); + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint8_t BSlot = hccid->USBD_CCID_Param.bSlot; /* This function is called for REQUEST_ABORT & PC_to_RDR_Abort */ @@ -483,7 +484,7 @@ uint8_t CCID_CmdAbort(uint8_t slot, uint8_t seq) if (slot >= CCID_NUMBER_OF_SLOTS) { /* error from CLASS_REQUEST*/ - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_FAILED), (BM_ICC_NO_ICC_PRESENT)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_NO_ICC_PRESENT)); return SLOTERROR_BAD_SLOT; } @@ -517,7 +518,7 @@ uint8_t CCID_CmdAbort(uint8_t slot, uint8_t seq) */ uint8_t PC_TO_RDR_T0Apdu(USBD_HandleTypeDef *pdev) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint8_t error; error = CCID_CheckCommandParams(pdev, CHK_PARAM_SLOT | CHK_PARAM_CARD_PRESENT | @@ -531,7 +532,7 @@ uint8_t PC_TO_RDR_T0Apdu(USBD_HandleTypeDef *pdev) /* Bit 0 is associated with bClassGetResponse Bit 1 is associated with bClassEnvelope */ - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); return SLOTERROR_BAD_BMCHANGES; } @@ -541,11 +542,11 @@ uint8_t PC_TO_RDR_T0Apdu(USBD_HandleTypeDef *pdev) if (error != SLOT_NO_ERROR) { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); } else { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); } return error; @@ -560,11 +561,11 @@ uint8_t PC_TO_RDR_T0Apdu(USBD_HandleTypeDef *pdev) */ uint8_t PC_TO_RDR_Mechanical(USBD_HandleTypeDef *pdev) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint8_t error; error = CCID_CheckCommandParams(pdev, CHK_PARAM_SLOT | CHK_PARAM_CARD_PRESENT | - CHK_PARAM_abRFU2 | CHK_PARAM_DWLENGTH); + CHK_PARAM_ABRFU2 | CHK_PARAM_DWLENGTH); if (error != 0U) { return error; @@ -579,7 +580,7 @@ uint8_t PC_TO_RDR_Mechanical(USBD_HandleTypeDef *pdev) 05h Unlock Card */ - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); return SLOTERROR_BAD_BFUNCTION_MECHANICAL; } @@ -587,11 +588,11 @@ uint8_t PC_TO_RDR_Mechanical(USBD_HandleTypeDef *pdev) if (error != SLOT_NO_ERROR) { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); } else { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); } return error; @@ -607,21 +608,21 @@ uint8_t PC_TO_RDR_Mechanical(USBD_HandleTypeDef *pdev) */ uint8_t PC_TO_RDR_SetDataRateAndClockFrequency(USBD_HandleTypeDef *pdev) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint8_t error; uint32_t clockFrequency; uint32_t dataRate; uint32_t temp; error = CCID_CheckCommandParams(pdev, CHK_PARAM_SLOT | CHK_PARAM_CARD_PRESENT | - CHK_PARAM_abRFU3); + CHK_PARAM_ABRFU3); if (error != 0U) { return error; } if (hccid->UsbBlkOutData.dwLength != 0x08U) { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); return SLOTERROR_BAD_LENTGH; } @@ -656,7 +657,7 @@ uint8_t PC_TO_RDR_SetDataRateAndClockFrequency(USBD_HandleTypeDef *pdev) if (error != SLOT_NO_ERROR) { hccid->UsbBlkInData.dwLength = 0; - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); } else { @@ -678,7 +679,7 @@ uint8_t PC_TO_RDR_SetDataRateAndClockFrequency(USBD_HandleTypeDef *pdev) (hccid->UsbBlkInData.abData[7]) = (uint8_t)((dataRate & 0xFF000000U) >> 24); - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); } return error; @@ -693,7 +694,7 @@ uint8_t PC_TO_RDR_SetDataRateAndClockFrequency(USBD_HandleTypeDef *pdev) */ uint8_t PC_TO_RDR_Secure(USBD_HandleTypeDef *pdev) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint8_t error; uint8_t bBWI; uint16_t wLevelParameter; @@ -717,7 +718,7 @@ uint8_t PC_TO_RDR_Secure(USBD_HandleTypeDef *pdev) /* TPDU level & short APDU level, wLevelParameter is RFU, = 0000h */ if (wLevelParameter != 0U) { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); error = SLOTERROR_BAD_LEVELPARAMETER; return error; } @@ -730,11 +731,11 @@ uint8_t PC_TO_RDR_Secure(USBD_HandleTypeDef *pdev) if (error != SLOT_NO_ERROR) { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); } else { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); } return error; @@ -754,7 +755,7 @@ uint8_t PC_TO_RDR_Secure(USBD_HandleTypeDef *pdev) */ void RDR_to_PC_DataBlock(uint8_t errorCode, USBD_HandleTypeDef *pdev) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint32_t length = CCID_RESPONSE_HEADER_SIZE; hccid->UsbBlkInData.bMessageType = RDR_TO_PC_DATABLOCK; @@ -786,8 +787,8 @@ void RDR_to_PC_DataBlock(uint8_t errorCode, USBD_HandleTypeDef *pdev) */ void RDR_to_PC_SlotStatus(uint8_t errorCode, USBD_HandleTypeDef *pdev) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; - UNUSED(errorCode); + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + uint16_t length = CCID_RESPONSE_HEADER_SIZE; hccid->UsbBlkInData.bMessageType = RDR_TO_PC_SLOTSTATUS; hccid->UsbBlkInData.dwLength = 0U; @@ -797,9 +798,12 @@ void RDR_to_PC_SlotStatus(uint8_t errorCode, USBD_HandleTypeDef *pdev) 02h Clock stopped in state H 03h Clock stopped in an unknown state */ - (void)USBD_CCID_Transfer_Data_Request(pdev, (uint8_t *)(&hccid->UsbBlkInData), - LEN_RDR_TO_PC_SLOTSTATUS); + if (errorCode == SLOT_NO_ERROR) + { + length += (uint16_t)hccid->UsbBlkInData.dwLength; + } + (void)USBD_CCID_Transfer_Data_Request(pdev, (uint8_t *)(&hccid->UsbBlkInData), length); } /** @@ -813,7 +817,7 @@ void RDR_to_PC_SlotStatus(uint8_t errorCode, USBD_HandleTypeDef *pdev) */ void RDR_to_PC_Parameters(uint8_t errorCode, USBD_HandleTypeDef *pdev) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint16_t length = CCID_RESPONSE_HEADER_SIZE; hccid->UsbBlkInData.bMessageType = RDR_TO_PC_PARAMETERS; @@ -824,12 +828,12 @@ void RDR_to_PC_Parameters(uint8_t errorCode, USBD_HandleTypeDef *pdev) if (ProtocolNUM_OUT == 0x00U) { hccid->UsbBlkInData.dwLength = LEN_PROTOCOL_STRUCT_T0; - length += LEN_PROTOCOL_STRUCT_T0; + length += (uint16_t)hccid->UsbBlkInData.dwLength; } else { hccid->UsbBlkInData.dwLength = LEN_PROTOCOL_STRUCT_T1; - length += LEN_PROTOCOL_STRUCT_T1; + length += (uint16_t)hccid->UsbBlkInData.dwLength; } } else @@ -867,7 +871,7 @@ void RDR_to_PC_Parameters(uint8_t errorCode, USBD_HandleTypeDef *pdev) */ void RDR_to_PC_Escape(uint8_t errorCode, USBD_HandleTypeDef *pdev) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint32_t length = CCID_RESPONSE_HEADER_SIZE; hccid->UsbBlkInData.bMessageType = RDR_TO_PC_ESCAPE; @@ -893,7 +897,7 @@ void RDR_to_PC_Escape(uint8_t errorCode, USBD_HandleTypeDef *pdev) */ void RDR_to_PC_DataRateAndClockFrequency(uint8_t errorCode, USBD_HandleTypeDef *pdev) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint32_t length = CCID_RESPONSE_HEADER_SIZE; hccid->UsbBlkInData.bMessageType = RDR_TO_PC_DATARATEANDCLOCKFREQUENCY; @@ -917,7 +921,7 @@ void RDR_to_PC_DataRateAndClockFrequency(uint8_t errorCode, USBD_HandleTypeDef */ void RDR_to_PC_NotifySlotChange(USBD_HandleTypeDef *pdev) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; hccid->UsbIntData[OFFSET_INT_BMESSAGETYPE] = RDR_TO_PC_NOTIFYSLOTCHANGE; @@ -948,7 +952,7 @@ void RDR_to_PC_NotifySlotChange(USBD_HandleTypeDef *pdev) */ void CCID_UpdSlotStatus(USBD_HandleTypeDef *pdev, uint8_t slotStatus) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; hccid->SlotStatus.SlotStatus = slotStatus; } @@ -961,7 +965,7 @@ void CCID_UpdSlotStatus(USBD_HandleTypeDef *pdev, uint8_t slotStatus) */ void CCID_UpdSlotChange(USBD_HandleTypeDef *pdev, uint8_t changeStatus) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; hccid->SlotStatus.SlotStatusChange = changeStatus; } @@ -973,20 +977,21 @@ void CCID_UpdSlotChange(USBD_HandleTypeDef *pdev, uint8_t changeStatus) */ uint8_t CCID_IsSlotStatusChange(USBD_HandleTypeDef *pdev) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; return hccid->SlotStatus.SlotStatusChange; } /** * @brief CCID_UpdateCommandStatus * Updates the variable for the BulkIn status + * @param pdev: device instance * @param cmd_status : Command change status from the calling function * @param icc_status : Slot change status from the calling function * @retval None */ -static void CCID_UpdateCommandStatus(uint8_t cmd_status, uint8_t icc_status) +static void CCID_UpdateCommandStatus(USBD_HandleTypeDef *pdev, uint8_t cmd_status, uint8_t icc_status) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)USBD_Device.pClassData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; hccid->UsbBlkInData.bStatus = (cmd_status | icc_status); } /** @@ -1000,7 +1005,7 @@ static void CCID_UpdateCommandStatus(uint8_t cmd_status, uint8_t icc_status) */ static uint8_t CCID_CheckCommandParams(USBD_HandleTypeDef *pdev, uint32_t param_type) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint32_t parameter; uint8_t GetState = SC_GetState(); @@ -1019,7 +1024,7 @@ static uint8_t CCID_CheckCommandParams(USBD_HandleTypeDef *pdev, uint32_t param if (hccid->UsbBlkOutData.bSlot >= CCID_NUMBER_OF_SLOTS) { /* Slot requested is more than supported by Firmware */ - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_FAILED), (BM_ICC_NO_ICC_PRESENT)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_NO_ICC_PRESENT)); return SLOTERROR_BAD_SLOT; } } @@ -1030,7 +1035,7 @@ static uint8_t CCID_CheckCommandParams(USBD_HandleTypeDef *pdev, uint32_t param if (SC_Detect() == 0U) { /* Card is Not detected */ - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_FAILED), (BM_ICC_NO_ICC_PRESENT)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_NO_ICC_PRESENT)); return SLOTERROR_ICC_MUTE; } } @@ -1040,30 +1045,30 @@ static uint8_t CCID_CheckCommandParams(USBD_HandleTypeDef *pdev, uint32_t param { if (hccid->UsbBlkOutData.dwLength != 0U) { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); return SLOTERROR_BAD_LENTGH; } } /* abRFU 2 : Reserved for Future Use*/ - if ((parameter & CHK_PARAM_abRFU2) != 0U) + if ((parameter & CHK_PARAM_ABRFU2) != 0U) { if ((hccid->UsbBlkOutData.bSpecific_1 != 0U) || (hccid->UsbBlkOutData.bSpecific_2 != 0U)) { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); return SLOTERROR_BAD_ABRFU_2B; /* bSpecific_1 */ } } - if ((parameter & CHK_PARAM_abRFU3) != 0U) + if ((parameter & CHK_PARAM_ABRFU3) != 0U) { /* abRFU 3 : Reserved for Future Use*/ if ((hccid->UsbBlkOutData.bSpecific_0 != 0U) || (hccid->UsbBlkOutData.bSpecific_1 != 0U) || (hccid->UsbBlkOutData.bSpecific_2 != 0U)) { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); return SLOTERROR_BAD_ABRFU_3B; } } @@ -1072,7 +1077,7 @@ static uint8_t CCID_CheckCommandParams(USBD_HandleTypeDef *pdev, uint32_t param { if (hccid->USBD_CCID_Param.bAbortRequestFlag != 0U) { - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_INACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_INACTIVE)); return SLOTERROR_CMD_ABORTED; } } @@ -1085,7 +1090,7 @@ static uint8_t CCID_CheckCommandParams(USBD_HandleTypeDef *pdev, uint32_t param if ((GetState != (uint8_t)SC_ACTIVE_ON_T0) && (GetState != (uint8_t)SC_ACTIVE_ON_T1)) { /* Check that from Lower Layers, the SmartCard come to known state */ - CCID_UpdateCommandStatus((BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_INACTIVE)); + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_INACTIVE)); return SLOTERROR_HW_ERROR; } } diff --git a/Class/CCID/Src/usbd_ccid_if_template.c b/Class/CCID/Src/usbd_ccid_if_template.c index 3592ee9..ea3f162 100644 --- a/Class/CCID/Src/usbd_ccid_if_template.c +++ b/Class/CCID/Src/usbd_ccid_if_template.c @@ -59,7 +59,11 @@ USBD_CCID_ItfTypeDef USBD_CCID_If_fops = */ uint8_t CCID_Init(USBD_HandleTypeDef *pdev) { +#ifdef USE_USBD_COMPOSITE + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; +#else USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; +#endif /* USE_USBD_COMPOSITE */ /* CCID Related Initialization */ @@ -76,8 +80,11 @@ uint8_t CCID_Init(USBD_HandleTypeDef *pdev) */ uint8_t CCID_DeInit(USBD_HandleTypeDef *pdev) { - +#ifdef USE_USBD_COMPOSITE + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; +#else USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; +#endif /* USE_USBD_COMPOSITE */ hccid->blkt_state = CCID_STATE_IDLE; @@ -94,7 +101,12 @@ uint8_t CCID_DeInit(USBD_HandleTypeDef *pdev) */ static uint8_t CCID_ControlReq(uint8_t req, uint8_t *pbuf, uint16_t *length) { - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)(USBD_Device.pClassData); +#ifdef USE_USBD_COMPOSITE + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)USBD_Device.pClassDataCmsit[USBD_Device.classId]; +#else + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)USBD_Device.pClassData; +#endif /* USE_USBD_COMPOSITE */ + UNUSED(length); switch (req) @@ -105,7 +117,7 @@ static uint8_t CCID_ControlReq(uint8_t req, uint8_t *pbuf, uint16_t *length) hccid->slot_nb = ((uint16_t) * pbuf & 0x0fU); hccid->seq_nb = (((uint16_t) * pbuf & 0xf0U) >> 8); - if (CCID_CmdAbort((uint8_t)hccid->slot_nb, (uint8_t)hccid->seq_nb) != 0U) + if (CCID_CmdAbort(&USBD_Device, (uint8_t)hccid->slot_nb, (uint8_t)hccid->seq_nb) != 0U) { /* If error is returned by lower layer : Generally Slot# may not have matched */ @@ -238,7 +250,11 @@ static uint8_t CCID_Response_Process(void) uint8_t CCID_SetSlotStatus(USBD_HandleTypeDef *pdev) { /* Get the CCID handler pointer */ +#ifdef USE_USBD_COMPOSITE + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; +#else USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData; +#endif /* USE_USBD_COMPOSITE */ if ((hccid->SlotStatus.SlotStatus) == 1U) /* Transfer Complete Status of previous Interrupt transfer */ diff --git a/Class/CCID/Src/usbd_ccid_sc_if_template.c b/Class/CCID/Src/usbd_ccid_sc_if_template.c index d64416e..fddf2d0 100644 --- a/Class/CCID/Src/usbd_ccid_sc_if_template.c +++ b/Class/CCID/Src/usbd_ccid_sc_if_template.c @@ -27,8 +27,8 @@ static SC_State SCState = SC_POWER_OFF; /* APDU Transport Structures */ -SC_ADPU_Commands SC_ADPU; -SC_ADPU_Response SC_Response; +SC_ADPU_CommandsTypeDef SC_ADPU; +SC_ADPU_ResponseTypeDef SC_Response; SC_Param_t SC_Param; Protocol_01_DataTypeDef ProtocolData; diff --git a/Class/CCID/Src/usbd_ccid_smartcard_template.c b/Class/CCID/Src/usbd_ccid_smartcard_template.c index 10b33e0..aec4bdb 100644 --- a/Class/CCID/Src/usbd_ccid_smartcard_template.c +++ b/Class/CCID/Src/usbd_ccid_smartcard_template.c @@ -54,7 +54,7 @@ __IO uint8_t IMSI_Content[9] = {0x01, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, static uint32_t D_Table[16] = {0, 1, 2, 4, 8, 16, 32, 64, 12, 20, 0, 0, 0, 0, 0, 0}; /* Global variables definition and initialization ----------------------------*/ -SC_ATR SC_A2R; +SC_ATRTypeDef SC_A2R; uint8_t SC_ATR_Table[40]; uint8_t ProtocolNUM_OUT; @@ -63,7 +63,7 @@ static void SC_Init(void); static void SC_DeInit(void); static void SC_AnswerReq(SC_State *SC_state, uint8_t *card, uint8_t length); /* Ask ATR */ static uint8_t SC_decode_Answer2reset(uint8_t *card); /* Decode ATR */ -static void SC_SendData(SC_ADPU_Commands *SCADPU, SC_ADPU_Response *SC_ResponseStatus); +static void SC_SendData(SC_ADPU_CommandsTypeDef *SCADPU, SC_ADPU_ResponseTypeDef *SC_ResponseStatus); /* static void SC_Reset(GPIO_PinState ResetState); */ /* Private functions ---------------------------------------------------------*/ @@ -77,7 +77,7 @@ static void SC_SendData(SC_ADPU_Commands *SCADPU, SC_ADPU_Response *SC_ResponseS * @param SC_Response: pointer to a SC_ADPU_Response structure which will be initialized. * @retval None */ -void SC_Handler(SC_State *SCState, SC_ADPU_Commands *SC_ADPU, SC_ADPU_Response *SC_Response) +void SC_Handler(SC_State *SCState, SC_ADPU_CommandsTypeDef *SC_ADPU, SC_ADPU_ResponseTypeDef *SC_Response) { uint32_t i, j; @@ -110,7 +110,7 @@ void SC_Handler(SC_State *SCState, SC_ADPU_Commands *SC_ADPU, SC_ADPU_Response * for (i = 0U; i < HIST_LENGTH; i++) { - SC_A2R.H[i] = 0U; + SC_A2R.Historical[i] = 0U; } SC_A2R.Tlength = 0U; @@ -245,7 +245,7 @@ void SC_PTSConfig(void) * @param SC_Response: pointer to a SC_ADPU_Response structure which will be initialized. * @retval None */ -static void SC_SendData(SC_ADPU_Commands *SCADPU, SC_ADPU_Response *SC_ResponseStatus) +static void SC_SendData(SC_ADPU_CommandsTypeDef *SCADPU, SC_ADPU_ResponseTypeDef *SC_ResponseStatus) { uint8_t i; uint8_t SC_Command[5]; @@ -391,7 +391,7 @@ static uint8_t SC_decode_Answer2reset(uint8_t *card) for (i = 0U; i < SC_A2R.Hlength; i++) { - SC_A2R.H[i] = card[i + 2U + SC_A2R.Tlength]; + SC_A2R.Historical[i] = card[i + 2U + SC_A2R.Tlength]; } /*************************************TCK Decode*******************************/ SC_A2R.TCK = card[SC_A2R.Hlength + 2U + SC_A2R.Tlength]; diff --git a/Class/CDC/Inc/usbd_cdc.h b/Class/CDC/Inc/usbd_cdc.h index 36348c8..242352c 100644 --- a/Class/CDC/Inc/usbd_cdc.h +++ b/Class/CDC/Inc/usbd_cdc.h @@ -40,9 +40,15 @@ extern "C" { /** @defgroup usbd_cdc_Exported_Defines * @{ */ +#ifndef CDC_IN_EP #define CDC_IN_EP 0x81U /* EP1 for data IN */ +#endif /* CDC_IN_EP */ +#ifndef CDC_OUT_EP #define CDC_OUT_EP 0x01U /* EP1 for data OUT */ +#endif /* CDC_OUT_EP */ +#ifndef CDC_CMD_EP #define CDC_CMD_EP 0x82U /* EP2 for CDC commands */ +#endif /* CDC_CMD_EP */ #ifndef CDC_HS_BINTERVAL #define CDC_HS_BINTERVAL 0x10U diff --git a/Class/CDC/Src/usbd_cdc.c b/Class/CDC/Src/usbd_cdc.c index fb985c5..e25cdfa 100644 --- a/Class/CDC/Src/usbd_cdc.c +++ b/Class/CDC/Src/usbd_cdc.c @@ -105,13 +105,15 @@ static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *re static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum); static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev); - +#ifndef USE_USBD_COMPOSITE static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length); static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length); static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length); static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length); uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length); +#endif /* USE_USBD_COMPOSITE */ +#ifndef USE_USBD_COMPOSITE /* USB Standard Device Descriptor */ __ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = { @@ -126,7 +128,7 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_ 0x01, 0x00, }; - +#endif /* USE_USBD_COMPOSITE */ /** * @} */ @@ -149,113 +151,22 @@ USBD_ClassTypeDef USBD_CDC = NULL, NULL, NULL, +#ifdef USE_USBD_COMPOSITE + NULL, + NULL, + NULL, + NULL, +#else USBD_CDC_GetHSCfgDesc, USBD_CDC_GetFSCfgDesc, USBD_CDC_GetOtherSpeedCfgDesc, USBD_CDC_GetDeviceQualifierDescriptor, +#endif /* USE_USBD_COMPOSITE */ }; +#ifndef USE_USBD_COMPOSITE /* USB CDC device Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = -{ - /* Configuration Descriptor */ - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */ - 0x00, - 0x02, /* bNumInterfaces: 2 interfaces */ - 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ -#if (USBD_SELF_POWERED == 1U) - 0xC0, /* bmAttributes: Bus Powered according to user configuration */ -#else - 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif - USBD_MAX_POWER, /* MaxPower (mA) */ - - /*---------------------------------------------------------------------------*/ - - /* Interface Descriptor */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints: One endpoints used */ - 0x02, /* bInterfaceClass: Communication Interface Class */ - 0x02, /* bInterfaceSubClass: Abstract Control Model */ - 0x01, /* bInterfaceProtocol: Common AT commands */ - 0x00, /* iInterface */ - - /* Header Functional Descriptor */ - 0x05, /* bLength: Endpoint Descriptor size */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x00, /* bDescriptorSubtype: Header Func Desc */ - 0x10, /* bcdCDC: spec release number */ - 0x01, - - /* Call Management Functional Descriptor */ - 0x05, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x01, /* bDescriptorSubtype: Call Management Func Desc */ - 0x00, /* bmCapabilities: D0+D1 */ - 0x01, /* bDataInterface: 1 */ - - /* ACM Functional Descriptor */ - 0x04, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ - 0x02, /* bmCapabilities */ - - /* Union Functional Descriptor */ - 0x05, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x06, /* bDescriptorSubtype: Union func desc */ - 0x00, /* bMasterInterface: Communication class interface */ - 0x01, /* bSlaveInterface0: Data Class Interface */ - - /* Endpoint 2 Descriptor */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_CMD_EP, /* bEndpointAddress */ - 0x03, /* bmAttributes: Interrupt */ - LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize */ - HIBYTE(CDC_CMD_PACKET_SIZE), - CDC_HS_BINTERVAL, /* bInterval */ - /*---------------------------------------------------------------------------*/ - - /* Data class interface descriptor */ - 0x09, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ - 0x01, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints: Two endpoints used */ - 0x0A, /* bInterfaceClass: CDC */ - 0x00, /* bInterfaceSubClass */ - 0x00, /* bInterfaceProtocol */ - 0x00, /* iInterface */ - - /* Endpoint OUT Descriptor */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_OUT_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize */ - HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), - 0x00, /* bInterval */ - - /* Endpoint IN Descriptor */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_IN_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize */ - HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), - 0x00 /* bInterval */ -}; - - -/* USB CDC device Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = +__ALIGN_BEGIN static uint8_t USBD_CDC_CfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = { /* Configuration Descriptor */ 0x09, /* bLength: Configuration Descriptor size */ @@ -264,12 +175,13 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN 0x00, 0x02, /* bNumInterfaces: 2 interfaces */ 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ + 0x00, /* iConfiguration: Index of string descriptor + describing the configuration */ #if (USBD_SELF_POWERED == 1U) 0xC0, /* bmAttributes: Bus Powered according to user configuration */ #else 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif +#endif /* USBD_SELF_POWERED */ USBD_MAX_POWER, /* MaxPower (mA) */ /*---------------------------------------------------------------------------*/ @@ -352,102 +264,11 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), 0x00 /* bInterval */ }; +#endif /* USE_USBD_COMPOSITE */ -__ALIGN_BEGIN static uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = -{ - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, - USB_CDC_CONFIG_DESC_SIZ, - 0x00, - 0x02, /* bNumInterfaces: 2 interfaces */ - 0x01, /* bConfigurationValue */ - 0x04, /* iConfiguration */ -#if (USBD_SELF_POWERED == 1U) - 0xC0, /* bmAttributes: Bus Powered according to user configuration */ -#else - 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif - USBD_MAX_POWER, /* MaxPower (mA) */ - - /* Interface Descriptor */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ - /* Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints: One endpoints used */ - 0x02, /* bInterfaceClass: Communication Interface Class */ - 0x02, /* bInterfaceSubClass: Abstract Control Model */ - 0x01, /* bInterfaceProtocol: Common AT commands */ - 0x00, /* iInterface */ - - /* Header Functional Descriptor */ - 0x05, /* bLength: Endpoint Descriptor size */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x00, /* bDescriptorSubtype: Header Func Desc */ - 0x10, /* bcdCDC: spec release number */ - 0x01, - - /* Call Management Functional Descriptor */ - 0x05, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x01, /* bDescriptorSubtype: Call Management Func Desc */ - 0x00, /* bmCapabilities */ - 0x01, /* bDataInterface */ - - /* ACM Functional Descriptor */ - 0x04, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ - 0x02, /* bmCapabilities */ - - /* Union Functional Descriptor */ - 0x05, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x06, /* bDescriptorSubtype: Union func desc */ - 0x00, /* bMasterInterface: Communication class interface */ - 0x01, /* bSlaveInterface0: Data Class Interface */ - - /* Endpoint 2 Descriptor */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_CMD_EP, /* bEndpointAddress */ - 0x03, /* bmAttributes: Interrupt */ - LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize */ - HIBYTE(CDC_CMD_PACKET_SIZE), - CDC_FS_BINTERVAL, /* bInterval */ - - /*---------------------------------------------------------------------------*/ - - /*Data class interface descriptor*/ - 0x09, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ - 0x01, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints: Two endpoints used */ - 0x0A, /* bInterfaceClass: CDC */ - 0x00, /* bInterfaceSubClass */ - 0x00, /* bInterfaceProtocol */ - 0x00, /* iInterface */ - - /*Endpoint OUT Descriptor*/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_OUT_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - 0x40, /* wMaxPacketSize */ - 0x00, - 0x00, /* bInterval */ - - /*Endpoint IN Descriptor*/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_IN_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - 0x40, /* wMaxPacketSize */ - 0x00, - 0x00 /* bInterval */ -}; +static uint8_t CDCInEpAdd = CDC_IN_EP; +static uint8_t CDCOutEpAdd = CDC_OUT_EP; +static uint8_t CDCCmdEpAdd = CDC_CMD_EP; /** * @} @@ -473,68 +294,85 @@ static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) if (hcdc == NULL) { - pdev->pClassData = NULL; + pdev->pClassDataCmsit[pdev->classId] = NULL; return (uint8_t)USBD_EMEM; } - pdev->pClassData = (void *)hcdc; + (void)USBD_memset(hcdc, 0, sizeof(USBD_CDC_HandleTypeDef)); + + pdev->pClassDataCmsit[pdev->classId] = (void *)hcdc; + pdev->pClassData = pdev->pClassDataCmsit[pdev->classId]; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + CDCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); + CDCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); + CDCCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR); +#endif /* USE_USBD_COMPOSITE */ if (pdev->dev_speed == USBD_SPEED_HIGH) { /* Open EP IN */ - (void)USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK, + (void)USBD_LL_OpenEP(pdev, CDCInEpAdd, USBD_EP_TYPE_BULK, CDC_DATA_HS_IN_PACKET_SIZE); - pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U; + pdev->ep_in[CDCInEpAdd & 0xFU].is_used = 1U; /* Open EP OUT */ - (void)USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK, + (void)USBD_LL_OpenEP(pdev, CDCOutEpAdd, USBD_EP_TYPE_BULK, CDC_DATA_HS_OUT_PACKET_SIZE); - pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U; + pdev->ep_out[CDCOutEpAdd & 0xFU].is_used = 1U; /* Set bInterval for CDC CMD Endpoint */ - pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = CDC_HS_BINTERVAL; + pdev->ep_in[CDCCmdEpAdd & 0xFU].bInterval = CDC_HS_BINTERVAL; } else { /* Open EP IN */ - (void)USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK, + (void)USBD_LL_OpenEP(pdev, CDCInEpAdd, USBD_EP_TYPE_BULK, CDC_DATA_FS_IN_PACKET_SIZE); - pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U; + pdev->ep_in[CDCInEpAdd & 0xFU].is_used = 1U; /* Open EP OUT */ - (void)USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK, + (void)USBD_LL_OpenEP(pdev, CDCOutEpAdd, USBD_EP_TYPE_BULK, CDC_DATA_FS_OUT_PACKET_SIZE); - pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U; + pdev->ep_out[CDCOutEpAdd & 0xFU].is_used = 1U; /* Set bInterval for CMD Endpoint */ - pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = CDC_FS_BINTERVAL; + pdev->ep_in[CDCCmdEpAdd & 0xFU].bInterval = CDC_FS_BINTERVAL; } /* Open Command IN EP */ - (void)USBD_LL_OpenEP(pdev, CDC_CMD_EP, USBD_EP_TYPE_INTR, CDC_CMD_PACKET_SIZE); - pdev->ep_in[CDC_CMD_EP & 0xFU].is_used = 1U; + (void)USBD_LL_OpenEP(pdev, CDCCmdEpAdd, USBD_EP_TYPE_INTR, CDC_CMD_PACKET_SIZE); + pdev->ep_in[CDCCmdEpAdd & 0xFU].is_used = 1U; + + hcdc->RxBuffer = NULL; /* Init physical Interface components */ - ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init(); + ((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init(); /* Init Xfer states */ hcdc->TxState = 0U; hcdc->RxState = 0U; + if (hcdc->RxBuffer == NULL) + { + return (uint8_t)USBD_EMEM; + } + if (pdev->dev_speed == USBD_SPEED_HIGH) { /* Prepare Out endpoint to receive next packet */ - (void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer, + (void)USBD_LL_PrepareReceive(pdev, CDCOutEpAdd, hcdc->RxBuffer, CDC_DATA_HS_OUT_PACKET_SIZE); } else { /* Prepare Out endpoint to receive next packet */ - (void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer, + (void)USBD_LL_PrepareReceive(pdev, CDCOutEpAdd, hcdc->RxBuffer, CDC_DATA_FS_OUT_PACKET_SIZE); } @@ -552,24 +390,33 @@ static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { UNUSED(cfgidx); + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this CDC class instance */ + CDCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); + CDCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); + CDCCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR); +#endif /* USE_USBD_COMPOSITE */ + /* Close EP IN */ - (void)USBD_LL_CloseEP(pdev, CDC_IN_EP); - pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 0U; + (void)USBD_LL_CloseEP(pdev, CDCInEpAdd); + pdev->ep_in[CDCInEpAdd & 0xFU].is_used = 0U; /* Close EP OUT */ - (void)USBD_LL_CloseEP(pdev, CDC_OUT_EP); - pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 0U; + (void)USBD_LL_CloseEP(pdev, CDCOutEpAdd); + pdev->ep_out[CDCOutEpAdd & 0xFU].is_used = 0U; /* Close Command IN EP */ - (void)USBD_LL_CloseEP(pdev, CDC_CMD_EP); - pdev->ep_in[CDC_CMD_EP & 0xFU].is_used = 0U; - pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = 0U; + (void)USBD_LL_CloseEP(pdev, CDCCmdEpAdd); + pdev->ep_in[CDCCmdEpAdd & 0xFU].is_used = 0U; + pdev->ep_in[CDCCmdEpAdd & 0xFU].bInterval = 0U; /* DeInit physical Interface components */ - if (pdev->pClassData != NULL) + if (pdev->pClassDataCmsit[pdev->classId] != NULL) { - ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->DeInit(); - (void)USBD_free(pdev->pClassData); + ((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit(); + (void)USBD_free(pdev->pClassDataCmsit[pdev->classId]); + pdev->pClassDataCmsit[pdev->classId] = NULL; pdev->pClassData = NULL; } @@ -586,7 +433,7 @@ static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { - USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint16_t len; uint8_t ifalt = 0U; uint16_t status_info = 0U; @@ -604,9 +451,9 @@ static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, { if ((req->bmRequest & 0x80U) != 0U) { - ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, - (uint8_t *)hcdc->data, - req->wLength); + ((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Control(req->bRequest, + (uint8_t *)hcdc->data, + req->wLength); len = MIN(CDC_REQ_MAX_DATA_SIZE, req->wLength); (void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data, len); @@ -621,8 +468,8 @@ static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, } else { - ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, - (uint8_t *)req, 0U); + ((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Control(req->bRequest, + (uint8_t *)req, 0U); } break; @@ -692,18 +539,18 @@ static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) USBD_CDC_HandleTypeDef *hcdc; PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef *)pdev->pData; - if (pdev->pClassData == NULL) + if (pdev->pClassDataCmsit[pdev->classId] == NULL) { return (uint8_t)USBD_FAIL; } - hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; + hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; - if ((pdev->ep_in[epnum].total_length > 0U) && - ((pdev->ep_in[epnum].total_length % hpcd->IN_ep[epnum].maxpacket) == 0U)) + if ((pdev->ep_in[epnum & 0xFU].total_length > 0U) && + ((pdev->ep_in[epnum & 0xFU].total_length % hpcd->IN_ep[epnum & 0xFU].maxpacket) == 0U)) { /* Update the packet total length */ - pdev->ep_in[epnum].total_length = 0U; + pdev->ep_in[epnum & 0xFU].total_length = 0U; /* Send ZLP */ (void)USBD_LL_Transmit(pdev, epnum, NULL, 0U); @@ -712,9 +559,9 @@ static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) { hcdc->TxState = 0U; - if (((USBD_CDC_ItfTypeDef *)pdev->pUserData)->TransmitCplt != NULL) + if (((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->TransmitCplt != NULL) { - ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum); + ((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum); } } @@ -730,9 +577,9 @@ static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) */ static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) { - USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; - if (pdev->pClassData == NULL) + if (pdev->pClassDataCmsit[pdev->classId] == NULL) { return (uint8_t)USBD_FAIL; } @@ -743,7 +590,7 @@ static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) /* USB data will be immediately processed, this allow next USB traffic being NAKed till the end of the application Xfer */ - ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength); + ((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Receive(hcdc->RxBuffer, &hcdc->RxLength); return (uint8_t)USBD_OK; } @@ -756,24 +603,24 @@ static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) */ static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev) { - USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hcdc == NULL) { return (uint8_t)USBD_FAIL; } - if ((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFFU)) + if ((pdev->pUserData[pdev->classId] != NULL) && (hcdc->CmdOpCode != 0xFFU)) { - ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode, - (uint8_t *)hcdc->data, - (uint16_t)hcdc->CmdLength); + ((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Control(hcdc->CmdOpCode, + (uint8_t *)hcdc->data, + (uint16_t)hcdc->CmdLength); hcdc->CmdOpCode = 0xFFU; } return (uint8_t)USBD_OK; } - +#ifndef USE_USBD_COMPOSITE /** * @brief USBD_CDC_GetFSCfgDesc * Return configuration descriptor @@ -782,9 +629,27 @@ static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev) */ static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length) { - *length = (uint16_t)sizeof(USBD_CDC_CfgFSDesc); + USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_CMD_EP); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_OUT_EP); + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_IN_EP); - return USBD_CDC_CfgFSDesc; + if (pEpCmdDesc != NULL) + { + pEpCmdDesc->bInterval = CDC_FS_BINTERVAL; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE; + } + + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE; + } + + *length = (uint16_t)sizeof(USBD_CDC_CfgDesc); + return USBD_CDC_CfgDesc; } /** @@ -795,9 +660,27 @@ static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length) */ static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length) { - *length = (uint16_t)sizeof(USBD_CDC_CfgHSDesc); + USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_CMD_EP); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_OUT_EP); + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_IN_EP); - return USBD_CDC_CfgHSDesc; + if (pEpCmdDesc != NULL) + { + pEpCmdDesc->bInterval = CDC_HS_BINTERVAL; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = CDC_DATA_HS_MAX_PACKET_SIZE; + } + + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = CDC_DATA_HS_MAX_PACKET_SIZE; + } + + *length = (uint16_t)sizeof(USBD_CDC_CfgDesc); + return USBD_CDC_CfgDesc; } /** @@ -808,9 +691,27 @@ static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length) */ static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length) { - *length = (uint16_t)sizeof(USBD_CDC_OtherSpeedCfgDesc); + USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_CMD_EP); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_OUT_EP); + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_IN_EP); - return USBD_CDC_OtherSpeedCfgDesc; + if (pEpCmdDesc != NULL) + { + pEpCmdDesc->bInterval = CDC_FS_BINTERVAL; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE; + } + + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE; + } + + *length = (uint16_t)sizeof(USBD_CDC_CfgDesc); + return USBD_CDC_CfgDesc; } /** @@ -825,7 +726,7 @@ uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length) return USBD_CDC_DeviceQualifierDesc; } - +#endif /* USE_USBD_COMPOSITE */ /** * @brief USBD_CDC_RegisterInterface * @param pdev: device instance @@ -840,7 +741,7 @@ uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, return (uint8_t)USBD_FAIL; } - pdev->pUserData = fops; + pdev->pUserData[pdev->classId] = fops; return (uint8_t)USBD_OK; } @@ -855,7 +756,7 @@ uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uint32_t length) { - USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hcdc == NULL) { @@ -876,7 +777,7 @@ uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, */ uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff) { - USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hcdc == NULL) { @@ -896,10 +797,14 @@ uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff) */ uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev) { - USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; USBD_StatusTypeDef ret = USBD_BUSY; - if (pdev->pClassData == NULL) +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + CDCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ + if (pdev->pClassDataCmsit[pdev->classId] == NULL) { return (uint8_t)USBD_FAIL; } @@ -910,10 +815,10 @@ uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev) hcdc->TxState = 1U; /* Update the packet total length */ - pdev->ep_in[CDC_IN_EP & 0xFU].total_length = hcdc->TxLength; + pdev->ep_in[CDCInEpAdd & 0xFU].total_length = hcdc->TxLength; /* Transmit next packet */ - (void)USBD_LL_Transmit(pdev, CDC_IN_EP, hcdc->TxBuffer, hcdc->TxLength); + (void)USBD_LL_Transmit(pdev, CDCInEpAdd, hcdc->TxBuffer, hcdc->TxLength); ret = USBD_OK; } @@ -929,9 +834,14 @@ uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev) */ uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev) { - USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; - if (pdev->pClassData == NULL) +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + CDCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ + + if (pdev->pClassDataCmsit[pdev->classId] == NULL) { return (uint8_t)USBD_FAIL; } @@ -939,13 +849,13 @@ uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev) if (pdev->dev_speed == USBD_SPEED_HIGH) { /* Prepare Out endpoint to receive next packet */ - (void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer, + (void)USBD_LL_PrepareReceive(pdev, CDCOutEpAdd, hcdc->RxBuffer, CDC_DATA_HS_OUT_PACKET_SIZE); } else { /* Prepare Out endpoint to receive next packet */ - (void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer, + (void)USBD_LL_PrepareReceive(pdev, CDCOutEpAdd, hcdc->RxBuffer, CDC_DATA_FS_OUT_PACKET_SIZE); } diff --git a/Class/CDC/Src/usbd_cdc_if_template.c b/Class/CDC/Src/usbd_cdc_if_template.c index 301cf20..df16834 100644 --- a/Class/CDC/Src/usbd_cdc_if_template.c +++ b/Class/CDC/Src/usbd_cdc_if_template.c @@ -127,6 +127,8 @@ static int8_t TEMPLATE_DeInit(void) */ static int8_t TEMPLATE_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length) { + UNUSED(length); + switch (cmd) { case CDC_SEND_ENCAPSULATED_COMMAND: diff --git a/Class/CDC_ECM/Inc/usbd_cdc_ecm.h b/Class/CDC_ECM/Inc/usbd_cdc_ecm.h index 36b34b9..d519667 100644 --- a/Class/CDC_ECM/Inc/usbd_cdc_ecm.h +++ b/Class/CDC_ECM/Inc/usbd_cdc_ecm.h @@ -42,10 +42,15 @@ extern "C" { */ /* Comment this define in order to disable the CDC ECM Notification pipe */ - +#ifndef CDC_ECM_IN_EP #define CDC_ECM_IN_EP 0x81U /* EP1 for data IN */ +#endif /* CDC_ECM_IN_EP */ +#ifndef CDC_ECM_OUT_EP #define CDC_ECM_OUT_EP 0x01U /* EP1 for data OUT */ +#endif /* CDC_ECM_OUT_EP */ +#ifndef CDC_ECM_CMD_EP #define CDC_ECM_CMD_EP 0x82U /* EP2 for CDC ECM commands */ +#endif /* CDC_ECM_CMD_EP */ #ifndef CDC_ECM_CMD_ITF_NBR #define CDC_ECM_CMD_ITF_NBR 0x00U /* Command Interface Number 0 */ @@ -172,6 +177,26 @@ typedef struct uint8_t data[8]; } USBD_CDC_ECM_NotifTypeDef; +/* + * ECM Class specification revision 1.2 + * Table 3: Ethernet Networking Functional Descriptor + */ + +typedef struct +{ + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t iMacAddress; + uint8_t bEthernetStatistics3; + uint8_t bEthernetStatistics2; + uint8_t bEthernetStatistics1; + uint8_t bEthernetStatistics0; + uint16_t wMaxSegmentSize; + uint16_t bNumberMCFiltes; + uint8_t bNumberPowerFiltes; +} __PACKED USBD_ECMFuncDescTypeDef; + typedef struct { uint32_t data[CDC_ECM_DATA_BUFFER_SIZE / 4U]; /* Force 32-bit alignment */ @@ -193,12 +218,6 @@ typedef struct USBD_CDC_ECM_NotifTypeDef Req; } USBD_CDC_ECM_HandleTypeDef; -typedef enum -{ - NETWORK_CONNECTION = 0x00, - RESPONSE_AVAILABLE = 0x01, - CONNECTION_SPEED_CHANGE = 0x2A -} USBD_CDC_ECM_NotifCodeTypeDef; /** @defgroup USBD_CORE_Exported_Macros * @{ @@ -234,7 +253,7 @@ uint8_t USBD_CDC_ECM_ReceivePacket(USBD_HandleTypeDef *pdev); uint8_t USBD_CDC_ECM_TransmitPacket(USBD_HandleTypeDef *pdev); uint8_t USBD_CDC_ECM_SendNotification(USBD_HandleTypeDef *pdev, - USBD_CDC_ECM_NotifCodeTypeDef Notif, + USBD_CDC_NotifCodeTypeDef Notif, uint16_t bVal, uint8_t *pData); /** * @} diff --git a/Class/CDC_ECM/Src/usbd_cdc_ecm.c b/Class/CDC_ECM/Src/usbd_cdc_ecm.c index d26f8a7..4eaa662 100644 --- a/Class/CDC_ECM/Src/usbd_cdc_ecm.c +++ b/Class/CDC_ECM/Src/usbd_cdc_ecm.c @@ -34,7 +34,7 @@ EndBSPDependencies */ #ifndef __USBD_CDC_ECM_IF_H #include "usbd_cdc_ecm_if_template.h" -#endif +#endif /* __USBD_CDC_ECM_IF_H */ /** @addtogroup STM32_USB_DEVICE_LIBRARY @@ -83,19 +83,20 @@ static uint8_t USBD_CDC_ECM_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum); static uint8_t USBD_CDC_ECM_EP0_RxReady(USBD_HandleTypeDef *pdev); static uint8_t USBD_CDC_ECM_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); - +#ifndef USE_USBD_COMPOSITE static uint8_t *USBD_CDC_ECM_GetFSCfgDesc(uint16_t *length); static uint8_t *USBD_CDC_ECM_GetHSCfgDesc(uint16_t *length); static uint8_t *USBD_CDC_ECM_GetOtherSpeedCfgDesc(uint16_t *length); static uint8_t *USBD_CDC_ECM_GetOtherSpeedCfgDesc(uint16_t *length); - +#endif /* USE_USBD_COMPOSITE */ #if (USBD_SUPPORT_USER_STRING_DESC == 1U) static uint8_t *USBD_CDC_ECM_USRStringDescriptor(USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length); -#endif - +#endif /* USBD_SUPPORT_USER_STRING_DESC */ +#ifndef USE_USBD_COMPOSITE uint8_t *USBD_CDC_ECM_GetDeviceQualifierDescriptor(uint16_t *length); - +#endif /* USE_USBD_COMPOSITE */ +#ifndef USE_USBD_COMPOSITE /* USB Standard Device Descriptor */ __ALIGN_BEGIN static uint8_t USBD_CDC_ECM_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = { @@ -110,7 +111,7 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_ECM_DeviceQualifierDesc[USB_LEN_DEV_QUALIF 0x01, 0x00, }; - +#endif /* USE_USBD_COMPOSITE */ static uint32_t ConnSpeedTab[2] = {CDC_ECM_CONNECT_SPEED_UPSTREAM, CDC_ECM_CONNECT_SPEED_DOWNSTREAM }; @@ -137,129 +138,25 @@ USBD_ClassTypeDef USBD_CDC_ECM = NULL, NULL, NULL, +#ifdef USE_USBD_COMPOSITE + NULL, + NULL, + NULL, + NULL, +#else USBD_CDC_ECM_GetHSCfgDesc, USBD_CDC_ECM_GetFSCfgDesc, USBD_CDC_ECM_GetOtherSpeedCfgDesc, USBD_CDC_ECM_GetDeviceQualifierDescriptor, +#endif /* USE_USBD_COMPOSITE */ #if (USBD_SUPPORT_USER_STRING_DESC == 1U) USBD_CDC_ECM_USRStringDescriptor, -#endif +#endif /* USBD_SUPPORT_USER_STRING_DESC */ }; +#ifndef USE_USBD_COMPOSITE /* USB CDC_ECM device Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_CDC_ECM_CfgHSDesc[] __ALIGN_END = -{ - /* Configuration Descriptor */ - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - LOBYTE(CDC_ECM_CONFIG_DESC_SIZ), /* wTotalLength:no of returned bytes */ - HIBYTE(CDC_ECM_CONFIG_DESC_SIZ), - 0x02, /* bNumInterfaces: 2 interfaces */ - 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ -#if (USBD_SELF_POWERED == 1U) - 0xC0, /* bmAttributes: Bus Powered according to user configuration */ -#else - 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif - USBD_MAX_POWER, /* MaxPower (mA) */ - - /*---------------------------------------------------------------------------*/ - - /* IAD descriptor */ - 0x08, /* bLength */ - 0x0B, /* bDescriptorType */ - 0x00, /* bFirstInterface */ - 0x02, /* bInterfaceCount */ - 0x02, /* bFunctionClass (Wireless Controller) */ - 0x06, /* bFunctionSubClass */ - 0x00, /* bFunctionProtocol */ - 0x00, /* iFunction */ - - /* Interface Descriptor */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - CDC_ECM_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints: One endpoint used */ - 0x02, /* bInterfaceClass: Communication Interface Class */ - 0x06, /* bInterfaceSubClass: Ethernet Control Model */ - 0x00, /* bInterfaceProtocol: No specific protocol required */ - 0x00, /* iInterface */ - - /* Header Functional Descriptor */ - 0x05, /* bLength: Endpoint Descriptor size */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x00, /* bDescriptorSubtype: Header functional descriptor */ - 0x10, /* bcd CDC_ECM: spec release number: 1.10 */ - 0x01, - - /* CDC_ECM Functional Descriptor */ - 0x0D, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x0F, /* Ethernet Networking functional descriptor subtype */ - CDC_ECM_MAC_STRING_INDEX, /* Device's MAC string index */ - CDC_ECM_ETH_STATS_BYTE3, /* Ethernet statistics byte 3 (bitmap) */ - CDC_ECM_ETH_STATS_BYTE2, /* Ethernet statistics byte 2 (bitmap) */ - CDC_ECM_ETH_STATS_BYTE1, /* Ethernet statistics byte 1 (bitmap) */ - CDC_ECM_ETH_STATS_BYTE0, /* Ethernet statistics byte 0 (bitmap) */ - LOBYTE(CDC_ECM_ETH_MAX_SEGSZE), - HIBYTE(CDC_ECM_ETH_MAX_SEGSZE), /* wMaxSegmentSize: Ethernet Maximum Segment size, typically 1514 bytes */ - LOBYTE(CDC_ECM_ETH_NBR_MACFILTERS), - HIBYTE(CDC_ECM_ETH_NBR_MACFILTERS), /* wNumberMCFilters: the number of multicast filters */ - CDC_ECM_ETH_NBR_PWRFILTERS, /* bNumberPowerFilters: the number of wakeup power filters */ - - /* Union Functional Descriptor */ - 0x05, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x06, /* bDescriptorSubtype: Union functional descriptor */ - 0x00, /* bMasterInterface: Communication class interface */ - 0x01, /* bSlaveInterface0: Data Class Interface */ - - /* Communication Endpoint Descriptor */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_ECM_CMD_EP, /* bEndpointAddress */ - 0x03, /* bmAttributes: Interrupt */ - LOBYTE(CDC_ECM_CMD_PACKET_SIZE), /* wMaxPacketSize */ - HIBYTE(CDC_ECM_CMD_PACKET_SIZE), - CDC_ECM_HS_BINTERVAL, /* bInterval */ - - /*----------------------*/ - - /* Data class interface descriptor */ - 0x09, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ - CDC_ECM_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints: Two endpoints used */ - 0x0A, /* bInterfaceClass: CDC */ - 0x00, /* bInterfaceSubClass */ - 0x00, /* bInterfaceProtocol */ - 0x00, /* iInterface */ - - /* Endpoint OUT Descriptor */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_ECM_OUT_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - LOBYTE(CDC_ECM_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize */ - HIBYTE(CDC_ECM_DATA_HS_MAX_PACKET_SIZE), - 0x00, /* bInterval */ - - /* Endpoint IN Descriptor */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_ECM_IN_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - LOBYTE(CDC_ECM_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize */ - HIBYTE(CDC_ECM_DATA_HS_MAX_PACKET_SIZE), - 0x00 /* bInterval */ -}; - - -/* USB CDC_ECM device Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_CDC_ECM_CfgFSDesc[] __ALIGN_END = +__ALIGN_BEGIN static uint8_t USBD_CDC_ECM_CfgDesc[] __ALIGN_END = { /* Configuration Descriptor */ 0x09, /* bLength: Configuration Descriptor size */ @@ -268,12 +165,13 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_ECM_CfgFSDesc[] __ALIGN_END = HIBYTE(CDC_ECM_CONFIG_DESC_SIZ), 0x02, /* bNumInterfaces: 2 interfaces */ 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ + 0x00, /* iConfiguration: Index of string descriptor + describing the configuration */ #if (USBD_SELF_POWERED == 1U) 0xC0, /* bmAttributes: Bus Powered according to user configuration */ #else 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif +#endif /* USBD_SELF_POWERED */ USBD_MAX_POWER, /* MaxPower (mA) */ /*---------------------------------------------------------------------------*/ @@ -368,115 +266,11 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_ECM_CfgFSDesc[] __ALIGN_END = HIBYTE(CDC_ECM_DATA_FS_MAX_PACKET_SIZE), 0x00 /* bInterval */ } ; +#endif /* USE_USBD_COMPOSITE */ -__ALIGN_BEGIN static uint8_t USBD_CDC_ECM_OtherSpeedCfgDesc[] __ALIGN_END = -{ - /* Configuration Descriptor */ - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - LOBYTE(CDC_ECM_CONFIG_DESC_SIZ), /* wTotalLength */ - HIBYTE(CDC_ECM_CONFIG_DESC_SIZ), - 0x02, /* bNumInterfaces: 2 interfaces */ - 0x01, /* bConfigurationValue: Configuration value */ - 0x04, /* iConfiguration: Index of string descriptor describing the configuration */ -#if (USBD_SELF_POWERED == 1U) - 0xC0, /* bmAttributes: Bus Powered according to user configuration */ -#else - 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif - USBD_MAX_POWER, /* MaxPower (mA) */ - - /*--------------------------------------- ------------------------------------*/ - /* IAD descriptor */ - 0x08, /* bLength */ - 0x0B, /* bDescriptorType */ - 0x00, /* bFirstInterface */ - 0x02, /* bInterfaceCount */ - 0x02, /* bFunctionClass (Wireless Controller) */ - 0x06, /* bFunctionSubClass */ - 0x00, /* bFunctionProtocol */ - 0x00, /* iFunction */ - - /* Interface Descriptor */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints: One endpoint used */ - 0x02, /* bInterfaceClass: Communication Interface Class */ - 0x06, /* bInterfaceSubClass: Ethernet Control Model */ - 0x00, /* bInterfaceProtocol: No specific protocol required */ - 0x00, /* iInterface: */ - - /* Header Functional Descriptor */ - 0x05, /* bLength: Endpoint Descriptor size */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x00, /* bDescriptorSubtype: Header functional descriptor */ - 0x10, /* bcd CDC_ECM : spec release number: 1.20 */ - 0x01, - - /* CDC_ECM Functional Descriptor */ - 0x0D, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x0F, /* Ethernet Networking functional descriptor subtype */ - CDC_ECM_MAC_STRING_INDEX, /* Device's MAC string index */ - CDC_ECM_ETH_STATS_BYTE3, /* Ethernet statistics byte 3 (bitmap) */ - CDC_ECM_ETH_STATS_BYTE2, /* Ethernet statistics byte 2 (bitmap) */ - CDC_ECM_ETH_STATS_BYTE1, /* Ethernet statistics byte 1 (bitmap) */ - CDC_ECM_ETH_STATS_BYTE0, /* Ethernet statistics byte 0 (bitmap) */ - LOBYTE(CDC_ECM_ETH_MAX_SEGSZE), - HIBYTE(CDC_ECM_ETH_MAX_SEGSZE), /* wMaxSegmentSize: Ethernet Maximum Segment size, typically 1514 bytes */ - LOBYTE(CDC_ECM_ETH_NBR_MACFILTERS), - HIBYTE(CDC_ECM_ETH_NBR_MACFILTERS), /* wNumberMCFilters: the number of multicast filters */ - CDC_ECM_ETH_NBR_PWRFILTERS, /* bNumberPowerFilters: the number of wakeup power filters */ - - /* Union Functional Descriptor */ - 0x05, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x06, /* bDescriptorSubtype: Union functional descriptor */ - 0x00, /* bMasterInterface: Communication class interface */ - 0x01, /* bSlaveInterface0: Data Class Interface */ - - /* Communication Endpoint Descriptor */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_ECM_CMD_EP, /* bEndpointAddress */ - 0x03, /* bmAttributes: Interrupt */ - LOBYTE(CDC_ECM_CMD_PACKET_SIZE), /* wMaxPacketSize */ - HIBYTE(CDC_ECM_CMD_PACKET_SIZE), - CDC_ECM_FS_BINTERVAL, /* bInterval */ - - /*----------------------*/ - - /* Data class interface descriptor */ - 0x09, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: interface */ - 0x01, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints: Two endpoints used */ - 0x0A, /* bInterfaceClass: CDC */ - 0x00, /* bInterfaceSubClass */ - 0x00, /* bInterfaceProtocol */ - 0x00, /* iInterface: */ - - /* Endpoint OUT Descriptor */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_ECM_OUT_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - 0x40, /* wMaxPacketSize */ - 0x00, - 0x00, /* bInterval */ - - /* Endpoint IN Descriptor */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_ECM_IN_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - 0x40, /* wMaxPacketSize */ - 0x00, - 0x00 /* bInterval */ -}; +static uint8_t ECMInEpAdd = CDC_ECM_IN_EP; +static uint8_t ECMOutEpAdd = CDC_ECM_OUT_EP; +static uint8_t ECMCmdEpAdd = CDC_ECM_CMD_EP; /** * @} @@ -499,57 +293,69 @@ static uint8_t USBD_CDC_ECM_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) USBD_CDC_ECM_HandleTypeDef *hcdc; +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + ECMInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); + ECMOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); + ECMCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR); +#endif /* USE_USBD_COMPOSITE */ + hcdc = (USBD_CDC_ECM_HandleTypeDef *)USBD_malloc(sizeof(USBD_CDC_ECM_HandleTypeDef)); if (hcdc == NULL) { - pdev->pClassData = NULL; + pdev->pClassDataCmsit[pdev->classId] = NULL; return (uint8_t)USBD_EMEM; } - pdev->pClassData = (void *)hcdc; + (void)USBD_memset(hcdc, 0, sizeof(USBD_CDC_ECM_HandleTypeDef)); + + pdev->pClassDataCmsit[pdev->classId] = (void *)hcdc; + pdev->pClassData = pdev->pClassDataCmsit[pdev->classId]; if (pdev->dev_speed == USBD_SPEED_HIGH) { /* Open EP IN */ - (void)USBD_LL_OpenEP(pdev, CDC_ECM_IN_EP, USBD_EP_TYPE_BULK, + (void)USBD_LL_OpenEP(pdev, ECMInEpAdd, USBD_EP_TYPE_BULK, CDC_ECM_DATA_HS_IN_PACKET_SIZE); - pdev->ep_in[CDC_ECM_IN_EP & 0xFU].is_used = 1U; + pdev->ep_in[ECMInEpAdd & 0xFU].is_used = 1U; /* Open EP OUT */ - (void)USBD_LL_OpenEP(pdev, CDC_ECM_OUT_EP, USBD_EP_TYPE_BULK, + (void)USBD_LL_OpenEP(pdev, ECMOutEpAdd, USBD_EP_TYPE_BULK, CDC_ECM_DATA_HS_OUT_PACKET_SIZE); - pdev->ep_out[CDC_ECM_OUT_EP & 0xFU].is_used = 1U; + pdev->ep_out[ECMOutEpAdd & 0xFU].is_used = 1U; /* Set bInterval for CDC ECM CMD Endpoint */ - pdev->ep_in[CDC_ECM_CMD_EP & 0xFU].bInterval = CDC_ECM_HS_BINTERVAL; + pdev->ep_in[ECMCmdEpAdd & 0xFU].bInterval = CDC_ECM_HS_BINTERVAL; } else { /* Open EP IN */ - (void)USBD_LL_OpenEP(pdev, CDC_ECM_IN_EP, USBD_EP_TYPE_BULK, + (void)USBD_LL_OpenEP(pdev, ECMInEpAdd, USBD_EP_TYPE_BULK, CDC_ECM_DATA_FS_IN_PACKET_SIZE); - pdev->ep_in[CDC_ECM_IN_EP & 0xFU].is_used = 1U; + pdev->ep_in[ECMInEpAdd & 0xFU].is_used = 1U; /* Open EP OUT */ - (void)USBD_LL_OpenEP(pdev, CDC_ECM_OUT_EP, USBD_EP_TYPE_BULK, + (void)USBD_LL_OpenEP(pdev, ECMOutEpAdd, USBD_EP_TYPE_BULK, CDC_ECM_DATA_FS_OUT_PACKET_SIZE); - pdev->ep_out[CDC_ECM_OUT_EP & 0xFU].is_used = 1U; + pdev->ep_out[ECMOutEpAdd & 0xFU].is_used = 1U; /* Set bInterval for CDC ECM CMD Endpoint */ - pdev->ep_in[CDC_ECM_CMD_EP & 0xFU].bInterval = CDC_ECM_FS_BINTERVAL; + pdev->ep_in[ECMCmdEpAdd & 0xFU].bInterval = CDC_ECM_FS_BINTERVAL; } /* Open Command IN EP */ - (void)USBD_LL_OpenEP(pdev, CDC_ECM_CMD_EP, USBD_EP_TYPE_INTR, CDC_ECM_CMD_PACKET_SIZE); - pdev->ep_in[CDC_ECM_CMD_EP & 0xFU].is_used = 1U; + (void)USBD_LL_OpenEP(pdev, ECMCmdEpAdd, USBD_EP_TYPE_INTR, CDC_ECM_CMD_PACKET_SIZE); + pdev->ep_in[ECMCmdEpAdd & 0xFU].is_used = 1U; + + hcdc->RxBuffer = NULL; /* Init physical Interface components */ - ((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData)->Init(); + ((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init(); /* Init Xfer states */ hcdc->TxState = 0U; @@ -560,8 +366,13 @@ static uint8_t USBD_CDC_ECM_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) hcdc->NotificationStatus = 0U; hcdc->MaxPcktLen = (pdev->dev_speed == USBD_SPEED_HIGH) ? CDC_ECM_DATA_HS_MAX_PACKET_SIZE : CDC_ECM_DATA_FS_MAX_PACKET_SIZE; + if (hcdc->RxBuffer == NULL) + { + return (uint8_t)USBD_EMEM; + } + /* Prepare Out endpoint to receive next packet */ - (void)USBD_LL_PrepareReceive(pdev, CDC_ECM_OUT_EP, hcdc->RxBuffer, hcdc->MaxPcktLen); + (void)USBD_LL_PrepareReceive(pdev, ECMOutEpAdd, hcdc->RxBuffer, hcdc->MaxPcktLen); return (uint8_t)USBD_OK; } @@ -577,24 +388,32 @@ static uint8_t USBD_CDC_ECM_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { UNUSED(cfgidx); +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + ECMInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); + ECMOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); + ECMCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR); +#endif /* USE_USBD_COMPOSITE */ + /* Close EP IN */ - (void)USBD_LL_CloseEP(pdev, CDC_ECM_IN_EP); - pdev->ep_in[CDC_ECM_IN_EP & 0xFU].is_used = 0U; + (void)USBD_LL_CloseEP(pdev, ECMInEpAdd); + pdev->ep_in[ECMInEpAdd & 0xFU].is_used = 0U; /* Close EP OUT */ - (void)USBD_LL_CloseEP(pdev, CDC_ECM_OUT_EP); - pdev->ep_out[CDC_ECM_OUT_EP & 0xFU].is_used = 0U; + (void)USBD_LL_CloseEP(pdev, ECMOutEpAdd); + pdev->ep_out[ECMOutEpAdd & 0xFU].is_used = 0U; /* Close Command IN EP */ - (void)USBD_LL_CloseEP(pdev, CDC_ECM_CMD_EP); - pdev->ep_in[CDC_ECM_CMD_EP & 0xFU].is_used = 0U; - pdev->ep_in[CDC_ECM_CMD_EP & 0xFU].bInterval = 0U; + (void)USBD_LL_CloseEP(pdev, ECMCmdEpAdd); + pdev->ep_in[ECMCmdEpAdd & 0xFU].is_used = 0U; + pdev->ep_in[ECMCmdEpAdd & 0xFU].bInterval = 0U; /* DeInit physical Interface components */ - if (pdev->pClassData != NULL) + if (pdev->pClassDataCmsit[pdev->classId] != NULL) { - ((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData)->DeInit(); - USBD_free(pdev->pClassData); + ((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit(); + USBD_free(pdev->pClassDataCmsit[pdev->classId]); + pdev->pClassDataCmsit[pdev->classId] = NULL; pdev->pClassData = NULL; } @@ -611,8 +430,8 @@ static uint8_t USBD_CDC_ECM_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) static uint8_t USBD_CDC_ECM_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { - USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *) pdev->pClassData; - USBD_CDC_ECM_ItfTypeDef *EcmInterface = (USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData; + USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *) pdev->pClassDataCmsit[pdev->classId]; + USBD_CDC_ECM_ItfTypeDef *EcmInterface = (USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData[pdev->classId]; USBD_StatusTypeDef ret = USBD_OK; uint16_t len; uint16_t status_info = 0U; @@ -713,21 +532,26 @@ static uint8_t USBD_CDC_ECM_Setup(USBD_HandleTypeDef *pdev, */ static uint8_t USBD_CDC_ECM_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) { - USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData; + USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef *)pdev->pData; - if (pdev->pClassData == NULL) +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + ECMInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ + + if (pdev->pClassDataCmsit[pdev->classId] == NULL) { return (uint8_t)USBD_FAIL; } - if (epnum == (CDC_ECM_IN_EP & 0x7FU)) + if (epnum == (ECMInEpAdd & 0x7FU)) { - if ((pdev->ep_in[epnum].total_length > 0U) && - ((pdev->ep_in[epnum].total_length % hpcd->IN_ep[epnum].maxpacket) == 0U)) + if ((pdev->ep_in[epnum & 0xFU].total_length > 0U) && + ((pdev->ep_in[epnum & 0xFU].total_length % hpcd->IN_ep[epnum & 0xFU].maxpacket) == 0U)) { /* Update the packet total length */ - pdev->ep_in[epnum].total_length = 0U; + pdev->ep_in[epnum & 0xFU].total_length = 0U; /* Send ZLP */ (void)USBD_LL_Transmit(pdev, epnum, NULL, 0U); @@ -735,13 +559,13 @@ static uint8_t USBD_CDC_ECM_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) else { hcdc->TxState = 0U; - if (((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData)->TransmitCplt != NULL) + if (((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData[pdev->classId])->TransmitCplt != NULL) { - ((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData)->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum); + ((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData[pdev->classId])->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum); } } } - else if (epnum == (CDC_ECM_CMD_EP & 0x7FU)) + else if (epnum == (ECMCmdEpAdd & 0x7FU)) { if (hcdc->NotificationStatus != 0U) { @@ -768,15 +592,20 @@ static uint8_t USBD_CDC_ECM_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) */ static uint8_t USBD_CDC_ECM_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) { - USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData; + USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint32_t CurrPcktLen; - if (pdev->pClassData == NULL) +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + ECMOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ + + if (pdev->pClassDataCmsit[pdev->classId] == NULL) { return (uint8_t)USBD_FAIL; } - if (epnum == CDC_ECM_OUT_EP) + if (epnum == ECMOutEpAdd) { /* Get the received data length */ CurrPcktLen = USBD_LL_GetRxDataSize(pdev, epnum); @@ -792,12 +621,12 @@ static uint8_t USBD_CDC_ECM_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) /* Process data by application (ie. copy to app buffer or notify user) hcdc->RxLength must be reset to zero at the end of the call of this function */ - ((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength); + ((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData[pdev->classId])->Receive(hcdc->RxBuffer, &hcdc->RxLength); } else { /* Prepare Out endpoint to receive next packet in current/new frame */ - (void)USBD_LL_PrepareReceive(pdev, CDC_ECM_OUT_EP, + (void)USBD_LL_PrepareReceive(pdev, ECMOutEpAdd, (uint8_t *)(hcdc->RxBuffer + hcdc->RxLength), hcdc->MaxPcktLen); } @@ -818,24 +647,24 @@ static uint8_t USBD_CDC_ECM_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) */ static uint8_t USBD_CDC_ECM_EP0_RxReady(USBD_HandleTypeDef *pdev) { - USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData; + USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hcdc == NULL) { return (uint8_t)USBD_FAIL; } - if ((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFFU)) + if ((pdev->pUserData[pdev->classId] != NULL) && (hcdc->CmdOpCode != 0xFFU)) { - ((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode, - (uint8_t *)hcdc->data, - (uint16_t)hcdc->CmdLength); + ((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData[pdev->classId])->Control(hcdc->CmdOpCode, + (uint8_t *)hcdc->data, + (uint16_t)hcdc->CmdLength); hcdc->CmdOpCode = 0xFFU; } return (uint8_t)USBD_OK; } - +#ifndef USE_USBD_COMPOSITE /** * @brief USBD_CDC_ECM_GetFSCfgDesc * Return configuration descriptor @@ -844,9 +673,27 @@ static uint8_t USBD_CDC_ECM_EP0_RxReady(USBD_HandleTypeDef *pdev) */ static uint8_t *USBD_CDC_ECM_GetFSCfgDesc(uint16_t *length) { - *length = (uint16_t)sizeof(USBD_CDC_ECM_CfgFSDesc); + USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_ECM_CfgDesc, CDC_ECM_CMD_EP); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_ECM_CfgDesc, CDC_ECM_OUT_EP); + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_ECM_CfgDesc, CDC_ECM_IN_EP); - return USBD_CDC_ECM_CfgFSDesc; + if (pEpCmdDesc != NULL) + { + pEpCmdDesc->bInterval = CDC_ECM_FS_BINTERVAL; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = CDC_ECM_DATA_FS_MAX_PACKET_SIZE; + } + + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = CDC_ECM_DATA_FS_MAX_PACKET_SIZE; + } + + *length = (uint16_t) sizeof(USBD_CDC_ECM_CfgDesc); + return USBD_CDC_ECM_CfgDesc; } /** @@ -857,9 +704,27 @@ static uint8_t *USBD_CDC_ECM_GetFSCfgDesc(uint16_t *length) */ static uint8_t *USBD_CDC_ECM_GetHSCfgDesc(uint16_t *length) { - *length = (uint16_t) sizeof(USBD_CDC_ECM_CfgHSDesc); + USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_ECM_CfgDesc, CDC_ECM_CMD_EP); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_ECM_CfgDesc, CDC_ECM_OUT_EP); + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_ECM_CfgDesc, CDC_ECM_IN_EP); - return USBD_CDC_ECM_CfgHSDesc; + if (pEpCmdDesc != NULL) + { + pEpCmdDesc->bInterval = CDC_ECM_HS_BINTERVAL; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = CDC_ECM_DATA_HS_MAX_PACKET_SIZE; + } + + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = CDC_ECM_DATA_HS_MAX_PACKET_SIZE; + } + + *length = (uint16_t) sizeof(USBD_CDC_ECM_CfgDesc); + return USBD_CDC_ECM_CfgDesc; } /** @@ -870,9 +735,27 @@ static uint8_t *USBD_CDC_ECM_GetHSCfgDesc(uint16_t *length) */ static uint8_t *USBD_CDC_ECM_GetOtherSpeedCfgDesc(uint16_t *length) { - *length = (uint16_t)sizeof(USBD_CDC_ECM_OtherSpeedCfgDesc); + USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_ECM_CfgDesc, CDC_ECM_CMD_EP); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_ECM_CfgDesc, CDC_ECM_OUT_EP); + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_ECM_CfgDesc, CDC_ECM_IN_EP); - return USBD_CDC_ECM_OtherSpeedCfgDesc; + if (pEpCmdDesc != NULL) + { + pEpCmdDesc->bInterval = CDC_ECM_FS_BINTERVAL; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = CDC_ECM_DATA_FS_MAX_PACKET_SIZE; + } + + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = CDC_ECM_DATA_FS_MAX_PACKET_SIZE; + } + + *length = (uint16_t) sizeof(USBD_CDC_ECM_CfgDesc); + return USBD_CDC_ECM_CfgDesc; } /** @@ -887,7 +770,7 @@ uint8_t *USBD_CDC_ECM_GetDeviceQualifierDescriptor(uint16_t *length) return USBD_CDC_ECM_DeviceQualifierDesc; } - +#endif /* USE_USBD_COMPOSITE */ /** * @brief USBD_CDC_ECM_RegisterInterface * @param pdev: device instance @@ -902,7 +785,7 @@ uint8_t USBD_CDC_ECM_RegisterInterface(USBD_HandleTypeDef *pdev, return (uint8_t)USBD_FAIL; } - pdev->pUserData = fops; + pdev->pUserData[pdev->classId] = fops; return (uint8_t)USBD_OK; } @@ -924,7 +807,7 @@ static uint8_t *USBD_CDC_ECM_USRStringDescriptor(USBD_HandleTypeDef *pdev, uint8 /* Check if the requested string interface is supported */ if (index == CDC_ECM_MAC_STRING_INDEX) { - USBD_GetString((uint8_t *)((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData)->pStrDesc, USBD_StrDesc, length); + USBD_GetString((uint8_t *)((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData[pdev->classId])->pStrDesc, USBD_StrDesc, length); return USBD_StrDesc; } /* Not supported Interface Descriptor index */ @@ -933,7 +816,7 @@ static uint8_t *USBD_CDC_ECM_USRStringDescriptor(USBD_HandleTypeDef *pdev, uint8 return NULL; } } -#endif +#endif /* USBD_SUPPORT_USER_STRING_DESC */ /** * @brief USBD_CDC_ECM_SetTxBuffer @@ -944,7 +827,7 @@ static uint8_t *USBD_CDC_ECM_USRStringDescriptor(USBD_HandleTypeDef *pdev, uint8 */ uint8_t USBD_CDC_ECM_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uint32_t length) { - USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData; + USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hcdc == NULL) { @@ -966,7 +849,7 @@ uint8_t USBD_CDC_ECM_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uint3 */ uint8_t USBD_CDC_ECM_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff) { - USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData; + USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hcdc == NULL) { @@ -986,10 +869,15 @@ uint8_t USBD_CDC_ECM_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff) */ uint8_t USBD_CDC_ECM_TransmitPacket(USBD_HandleTypeDef *pdev) { - USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData; + USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; USBD_StatusTypeDef ret = USBD_BUSY; - if (pdev->pClassData == NULL) +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + ECMInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ + + if (pdev->pClassDataCmsit[pdev->classId] == NULL) { return (uint8_t)USBD_FAIL; } @@ -1000,10 +888,10 @@ uint8_t USBD_CDC_ECM_TransmitPacket(USBD_HandleTypeDef *pdev) hcdc->TxState = 1U; /* Update the packet total length */ - pdev->ep_in[CDC_ECM_IN_EP & 0xFU].total_length = hcdc->TxLength; + pdev->ep_in[ECMInEpAdd & 0xFU].total_length = hcdc->TxLength; /* Transmit next packet */ - (void)USBD_LL_Transmit(pdev, CDC_ECM_IN_EP, hcdc->TxBuffer, hcdc->TxLength); + (void)USBD_LL_Transmit(pdev, ECMInEpAdd, hcdc->TxBuffer, hcdc->TxLength); ret = USBD_OK; } @@ -1020,15 +908,20 @@ uint8_t USBD_CDC_ECM_TransmitPacket(USBD_HandleTypeDef *pdev) */ uint8_t USBD_CDC_ECM_ReceivePacket(USBD_HandleTypeDef *pdev) { - USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData; + USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; - if (pdev->pClassData == NULL) +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + ECMOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ + + if (pdev->pClassDataCmsit[pdev->classId] == NULL) { return (uint8_t)USBD_FAIL; } /* Prepare Out endpoint to receive next packet */ - (void)USBD_LL_PrepareReceive(pdev, CDC_ECM_OUT_EP, hcdc->RxBuffer, hcdc->MaxPcktLen); + (void)USBD_LL_PrepareReceive(pdev, ECMOutEpAdd, hcdc->RxBuffer, hcdc->MaxPcktLen); return (uint8_t)USBD_OK; } @@ -1043,12 +936,12 @@ uint8_t USBD_CDC_ECM_ReceivePacket(USBD_HandleTypeDef *pdev) * @retval status */ uint8_t USBD_CDC_ECM_SendNotification(USBD_HandleTypeDef *pdev, - USBD_CDC_ECM_NotifCodeTypeDef Notif, + USBD_CDC_NotifCodeTypeDef Notif, uint16_t bVal, uint8_t *pData) { uint32_t Idx; uint32_t ReqSize = 0U; - USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData; + USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; USBD_StatusTypeDef ret = USBD_OK; if (hcdc == NULL) @@ -1056,6 +949,11 @@ uint8_t USBD_CDC_ECM_SendNotification(USBD_HandleTypeDef *pdev, return (uint8_t)USBD_FAIL; } +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + ECMCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR); +#endif /* USE_USBD_COMPOSITE */ + /* Initialize the request fields */ (hcdc->Req).bmRequest = CDC_ECM_BMREQUEST_TYPE_ECM; (hcdc->Req).bRequest = (uint8_t)Notif; @@ -1109,7 +1007,7 @@ uint8_t USBD_CDC_ECM_SendNotification(USBD_HandleTypeDef *pdev, /* Transmit notification packet */ if (ReqSize != 0U) { - (void)USBD_LL_Transmit(pdev, CDC_ECM_CMD_EP, (uint8_t *)&hcdc->Req, ReqSize); + (void)USBD_LL_Transmit(pdev, ECMCmdEpAdd, (uint8_t *)&hcdc->Req, ReqSize); } return (uint8_t)ret; diff --git a/Class/CDC_ECM/Src/usbd_cdc_ecm_if_template.c b/Class/CDC_ECM/Src/usbd_cdc_ecm_if_template.c index 9c28c63..e89a892 100644 --- a/Class/CDC_ECM/Src/usbd_cdc_ecm_if_template.c +++ b/Class/CDC_ECM/Src/usbd_cdc_ecm_if_template.c @@ -18,7 +18,7 @@ /* Includes ------------------------------------------------------------------*/ -#include "main.h" +#include "usbd_cdc_ecm_if_template.h" /* Include here LwIP files if used @@ -32,13 +32,13 @@ /* Received Data over USB are stored in this buffer */ #if defined ( __ICCARM__ ) /*!< IAR Compiler */ #pragma data_alignment=4 -#endif +#endif /* ( __ICCARM__ ) */ __ALIGN_BEGIN static uint8_t UserRxBuffer[CDC_ECM_ETH_MAX_SEGSZE + 100]__ALIGN_END; /* Transmitted Data over CDC_ECM (CDC_ECM interface) are stored in this buffer */ #if defined ( __ICCARM__ ) /*!< IAR Compiler */ #pragma data_alignment=4 -#endif +#endif /* ( __ICCARM__ ) */ __ALIGN_BEGIN static uint8_t UserTxBuffer[CDC_ECM_ETH_MAX_SEGSZE + 100]__ALIGN_END; static uint8_t CDC_ECMInitialized = 0U; @@ -99,7 +99,11 @@ static int8_t CDC_ECM_Itf_Init(void) */ static int8_t CDC_ECM_Itf_DeInit(void) { +#ifdef USE_USBD_COMPOSITE + USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *)(USBD_Device.pClassDataCmsit[USBD_Device.classId]); +#else USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *)(USBD_Device.pClassData); +#endif /* USE_USBD_COMPOSITE */ /* Notify application layer that link is down */ hcdc_cdc_ecm->LinkStatus = 0U; @@ -117,7 +121,11 @@ static int8_t CDC_ECM_Itf_DeInit(void) */ static int8_t CDC_ECM_Itf_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length) { +#ifdef USE_USBD_COMPOSITE + USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *)(USBD_Device.pClassDataCmsit[USBD_Device.classId]); +#else USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *)(USBD_Device.pClassData); +#endif /* USE_USBD_COMPOSITE */ switch (cmd) { @@ -188,7 +196,11 @@ static int8_t CDC_ECM_Itf_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length) static int8_t CDC_ECM_Itf_Receive(uint8_t *Buf, uint32_t *Len) { /* Get the CDC_ECM handler pointer */ +#ifdef USE_USBD_COMPOSITE + USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *)(USBD_Device.pClassDataCmsit[USBD_Device.classId]); +#else USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *)(USBD_Device.pClassData); +#endif /* USE_USBD_COMPOSITE */ /* Call Eth buffer processing */ hcdc_cdc_ecm->RxState = 1U; @@ -230,9 +242,18 @@ static int8_t CDC_ECM_Itf_TransmitCplt(uint8_t *Buf, uint32_t *Len, uint8_t epnu static int8_t CDC_ECM_Itf_Process(USBD_HandleTypeDef *pdev) { /* Get the CDC_ECM handler pointer */ +#ifdef USE_USBD_COMPOSITE + USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *)(pdev->pClassDataCmsit[pdev->classId]); +#else USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *)(pdev->pClassData); +#endif /* USE_USBD_COMPOSITE */ - if ((hcdc_cdc_ecm != NULL) && (hcdc_cdc_ecm->LinkStatus != 0U)) + if (hcdc_cdc_ecm == NULL) + { + return (-1); + } + + if (hcdc_cdc_ecm->LinkStatus != 0U) { /* Read a received packet from the Ethernet buffers and send it diff --git a/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h b/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h index f294c01..1f5aba5 100644 --- a/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h +++ b/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h @@ -40,10 +40,15 @@ extern "C" { /** @defgroup usbd_cdc_rndis_Exported_Defines * @{ */ - +#ifndef CDC_RNDIS_IN_EP #define CDC_RNDIS_IN_EP 0x81U /* EP1 for data IN */ +#endif /* CDC_RNDIS_IN_EP */ +#ifndef CDC_RNDIS_OUT_EP #define CDC_RNDIS_OUT_EP 0x01U /* EP1 for data OUT */ +#endif /* CDC_RNDIS_OUT_EP */ +#ifndef CDC_RNDIS_CMD_EP #define CDC_RNDIS_CMD_EP 0x82U /* EP2 for CDC_RNDIS commands */ +#endif /* CDC_RNDIS_CMD_EP */ #ifndef CDC_RNDIS_CMD_ITF_NBR #define CDC_RNDIS_CMD_ITF_NBR 0x00U /* Command Interface Number 0 */ @@ -264,15 +269,6 @@ typedef struct __IO uint32_t PacketFilter; } USBD_CDC_RNDIS_HandleTypeDef; - -typedef enum -{ - NETWORK_CONNECTION = 0x00, - RESPONSE_AVAILABLE = 0x01, - CONNECTION_SPEED_CHANGE = 0x2A -} USBD_CDC_RNDIS_NotifCodeTypeDef; - - /* Messages Sent by the Host ---------------------*/ /* Type define for a CDC_RNDIS Initialize command message */ @@ -506,7 +502,7 @@ uint8_t USBD_CDC_RNDIS_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uint32_t length); uint8_t USBD_CDC_RNDIS_SendNotification(USBD_HandleTypeDef *pdev, - USBD_CDC_RNDIS_NotifCodeTypeDef Notif, + USBD_CDC_NotifCodeTypeDef Notif, uint16_t bVal, uint8_t *pData); /** * @} diff --git a/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c b/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c index b7f064f..e48ae4a 100644 --- a/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c +++ b/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c @@ -56,7 +56,7 @@ #ifndef __USBD_CDC_RNDIS_IF_H #include "usbd_cdc_rndis_if_template.h" -#endif +#endif /* __USBD_CDC_RNDIS_IF_H */ /** @addtogroup STM32_USB_DEVICE_LIBRARY * @{ */ @@ -105,17 +105,18 @@ static uint8_t USBD_CDC_RNDIS_Setup(USBD_HandleTypeDef *pdev, static uint8_t USBD_CDC_RNDIS_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); static uint8_t USBD_CDC_RNDIS_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum); static uint8_t USBD_CDC_RNDIS_EP0_RxReady(USBD_HandleTypeDef *pdev); +#ifndef USE_USBD_COMPOSITE static uint8_t *USBD_CDC_RNDIS_GetFSCfgDesc(uint16_t *length); static uint8_t *USBD_CDC_RNDIS_GetHSCfgDesc(uint16_t *length); static uint8_t *USBD_CDC_RNDIS_GetOtherSpeedCfgDesc(uint16_t *length); static uint8_t *USBD_CDC_RNDIS_GetOtherSpeedCfgDesc(uint16_t *length); - +#endif /* USE_USBD_COMPOSITE */ #if (USBD_SUPPORT_USER_STRING_DESC == 1U) static uint8_t *USBD_CDC_RNDIS_USRStringDescriptor(USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length); -#endif - +#endif /* USBD_SUPPORT_USER_STRING_DESC */ +#ifndef USE_USBD_COMPOSITE uint8_t *USBD_CDC_RNDIS_GetDeviceQualifierDescriptor(uint16_t *length); - +#endif /* USE_USBD_COMPOSITE */ /* CDC_RNDIS Internal messages parsing and construction functions */ static uint8_t USBD_CDC_RNDIS_MsgParsing(USBD_HandleTypeDef *pdev, uint8_t *RxBuff); @@ -129,6 +130,7 @@ static uint8_t USBD_CDC_RNDIS_ProcessPacketMsg(USBD_HandleTypeDef *pdev, USBD_CD static uint8_t USBD_CDC_RNDIS_ProcessUnsupportedMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_CtrlMsgTypeDef *Msg); /* USB Standard Device Descriptor */ +#ifndef USE_USBD_COMPOSITE __ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = { USB_LEN_DEV_QUALIFIER_DESC, @@ -142,7 +144,7 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_DeviceQualifierDesc[USB_LEN_DEV_QUAL 0x01, 0x00, }; - +#endif /* USE_USBD_COMPOSITE */ static uint8_t MAC_StrDesc[6] = {CDC_RNDIS_MAC_ADDR0, CDC_RNDIS_MAC_ADDR1, CDC_RNDIS_MAC_ADDR2, CDC_RNDIS_MAC_ADDR3, CDC_RNDIS_MAC_ADDR4, CDC_RNDIS_MAC_ADDR5 }; @@ -175,126 +177,25 @@ USBD_ClassTypeDef USBD_CDC_RNDIS = NULL, NULL, NULL, +#ifdef USE_USBD_COMPOSITE + NULL, + NULL, + NULL, + NULL, +#else USBD_CDC_RNDIS_GetHSCfgDesc, USBD_CDC_RNDIS_GetFSCfgDesc, USBD_CDC_RNDIS_GetOtherSpeedCfgDesc, USBD_CDC_RNDIS_GetDeviceQualifierDescriptor, +#endif /* USE_USBD_COMPOSITE */ #if (USBD_SUPPORT_USER_STRING_DESC == 1U) USBD_CDC_RNDIS_USRStringDescriptor, -#endif +#endif /* USBD_SUPPORT_USER_STRING_DESC */ }; - -/* USB CDC_RNDIS device Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_CfgHSDesc[] __ALIGN_END = -{ - /* Configuration Descriptor */ - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - LOBYTE(CDC_RNDIS_CONFIG_DESC_SIZ), /* wTotalLength: Total size of the Config descriptor */ - HIBYTE(CDC_RNDIS_CONFIG_DESC_SIZ), - 0x02, /* bNumInterfaces: 2 interfaces */ - 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ -#if (USBD_SELF_POWERED == 1U) - 0xC0, /* bmAttributes: Bus Powered according to user configuration */ -#else - 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif - USBD_MAX_POWER, /* MaxPower (mA) */ - - /*---------------------------------------------------------------------------*/ - /* IAD descriptor */ - 0x08, /* bLength */ - 0x0B, /* bDescriptorType */ - 0x00, /* bFirstInterface */ - 0x02, /* bInterfaceCount */ - 0xE0, /* bFunctionClass (Wireless Controller) */ - 0x01, /* bFunctionSubClass */ - 0x03, /* bFunctionProtocol */ - 0x00, /* iFunction */ - - /*---------------------------------------------------------------------------*/ - /* Interface Descriptor */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - CDC_RNDIS_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints: One endpoint used */ - 0x02, /* bInterfaceClass: Communication Interface Class */ - 0x02, /* bInterfaceSubClass:Abstract Control Model */ - 0xFF, /* bInterfaceProtocol: Common AT commands */ - 0x00, /* iInterface */ - - /* Header Functional Descriptor */ - 0x05, /* bLength: Endpoint Descriptor size */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x00, /* bDescriptorSubtype: Header functional descriptor */ - 0x10, /* bcdCDC: spec release number: 1.20 */ - 0x01, - - /* Call Management Functional Descriptor */ - 0x05, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x01, /* bDescriptorSubtype: Call Management Func Desc */ - 0x00, /* bmCapabilities: D0+D1 */ - CDC_RNDIS_COM_ITF_NBR, /* bDataInterface: 1 */ - - /* ACM Functional Descriptor */ - 0x04, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ - 0x00, /* bmCapabilities */ - - /* Union Functional Descriptor */ - 0x05, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x06, /* bDescriptorSubtype: Union functional descriptor */ - CDC_RNDIS_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */ - CDC_RNDIS_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */ - - /* Notification Endpoint Descriptor */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_RNDIS_CMD_EP, /* bEndpointAddress */ - 0x03, /* bmAttributes: Interrupt */ - LOBYTE(CDC_RNDIS_CMD_PACKET_SIZE), /* wMaxPacketSize */ - HIBYTE(CDC_RNDIS_CMD_PACKET_SIZE), - CDC_RNDIS_HS_BINTERVAL, /* bInterval */ - - /*---------------------------------------------------------------------------*/ - /* Data class interface descriptor */ - 0x09, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ - CDC_RNDIS_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints: Two endpoints used */ - 0x0A, /* bInterfaceClass: CDC */ - 0x00, /* bInterfaceSubClass */ - 0x00, /* bInterfaceProtocol */ - 0x00, /* iInterface */ - - /* Endpoint OUT Descriptor */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_RNDIS_OUT_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - LOBYTE(CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize */ - HIBYTE(CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE), - 0x00, /* bInterval */ - - /* Endpoint IN Descriptor */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_RNDIS_IN_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - LOBYTE(CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ - HIBYTE(CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE), - 0x00 /* bInterval */ -}; - +#ifndef USE_USBD_COMPOSITE /* USB CDC device Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_CfgFSDesc[] __ALIGN_END = +__ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_CfgDesc[] __ALIGN_END = { /* Configuration Descriptor */ 0x09, /* bLength: Configuration Descriptor size */ @@ -303,12 +204,13 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_CfgFSDesc[] __ALIGN_END = HIBYTE(CDC_RNDIS_CONFIG_DESC_SIZ), 0x02, /* bNumInterfaces: 2 interfaces */ 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ + 0x00, /* iConfiguration: Index of string descriptor + describing the configuration */ #if (USBD_SELF_POWERED == 1U) 0xC0, /* bmAttributes: Bus Powered according to user configuration */ #else 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif +#endif /* USBD_SELF_POWERED */ USBD_MAX_POWER, /* MaxPower (mA) */ /*---------------------------------------------------------------------------*/ @@ -400,114 +302,11 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_CfgFSDesc[] __ALIGN_END = HIBYTE(CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE), 0x00 /* bInterval */ } ; +#endif /* USE_USBD_COMPOSITE */ -__ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_OtherSpeedCfgDesc[] __ALIGN_END = -{ - /* Configuration Descriptor */ - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - LOBYTE(CDC_RNDIS_CONFIG_DESC_SIZ), /* wTotalLength:no of returned bytes */ - HIBYTE(CDC_RNDIS_CONFIG_DESC_SIZ), - 0x02, /* bNumInterfaces: 2 interfaces */ - 0x01, /* bConfigurationValue: Configuration value */ - 0x04, /* iConfiguration: Index of string descriptor describing the configuration */ -#if (USBD_SELF_POWERED == 1U) - 0xC0, /* bmAttributes: Bus Powered according to user configuration */ -#else - 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif - USBD_MAX_POWER, /* MaxPower (mA) */ - - /*---------------------------------------------------------------------------*/ - /* IAD descriptor */ - 0x08, /* bLength */ - 0x0B, /* bDescriptorType */ - 0x00, /* bFirstInterface */ - 0x02, /* bInterfaceCount */ - 0xE0, /* bFunctionClass (Wireless Controller) */ - 0x01, /* bFunctionSubClass */ - 0x03, /* bFunctionProtocol */ - 0x00, /* iFunction */ - - /*---------------------------------------------------------------------------*/ - /* Interface Descriptor */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - CDC_RNDIS_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints: One endpoint used */ - 0x02, /* bInterfaceClass: Communication Interface Class */ - 0x02, /* bInterfaceSubClass:Abstract Control Model */ - 0xFF, /* bInterfaceProtocol: Common AT commands */ - 0x00, /* iInterface */ - - /* Header Functional Descriptor */ - 0x05, /* bLength: Endpoint Descriptor size */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x00, /* bDescriptorSubtype: Header functional descriptor */ - 0x10, /* bcdCDC: spec release number: 1.20 */ - 0x01, - - /* Call Management Functional Descriptor */ - 0x05, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x01, /* bDescriptorSubtype: Call Management Func Desc */ - 0x00, /* bmCapabilities: D0+D1 */ - CDC_RNDIS_COM_ITF_NBR, /* bDataInterface: 1 */ - - /* ACM Functional Descriptor */ - 0x04, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ - 0x00, /* bmCapabilities */ - - /* Union Functional Descriptor */ - 0x05, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x06, /* bDescriptorSubtype: Union functional descriptor */ - CDC_RNDIS_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */ - CDC_RNDIS_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */ - - /* Communication Endpoint Descriptor */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_RNDIS_CMD_EP, /* bEndpointAddress */ - 0x03, /* bmAttributes: Interrupt */ - LOBYTE(CDC_RNDIS_CMD_PACKET_SIZE), /* wMaxPacketSize */ - HIBYTE(CDC_RNDIS_CMD_PACKET_SIZE), - CDC_RNDIS_FS_BINTERVAL, /* bInterval */ - - /*---------------------------------------------------------------------------*/ - /* Data class interface descriptor */ - 0x09, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ - CDC_RNDIS_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints: Two endpoints used */ - 0x0A, /* bInterfaceClass: CDC */ - 0x00, /* bInterfaceSubClass */ - 0x00, /* bInterfaceProtocol */ - 0x00, /* iInterface */ - - /* Endpoint OUT Descriptor */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_RNDIS_OUT_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - 0x40, /* wMaxPacketSize */ - 0x00, - 0x00, /* bInterval */ - - /* Endpoint IN Descriptor */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_RNDIS_IN_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - 0x40, /* wMaxPacketSize */ - 0x00, - 0x00 /* bInterval */ -}; - +static uint8_t RNDISInEpAdd = CDC_RNDIS_IN_EP; +static uint8_t RNDISOutEpAdd = CDC_RNDIS_OUT_EP; +static uint8_t RNDISCmdEpAdd = CDC_RNDIS_CMD_EP; static const uint32_t CDC_RNDIS_SupportedOIDs[] = { @@ -556,55 +355,67 @@ static uint8_t USBD_CDC_RNDIS_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)USBD_malloc(sizeof(USBD_CDC_RNDIS_HandleTypeDef)); +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + RNDISInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); + RNDISOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); + RNDISCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR); +#endif /* USE_USBD_COMPOSITE */ + if (hcdc == NULL) { - pdev->pClassData = NULL; + pdev->pClassDataCmsit[pdev->classId] = NULL; return (uint8_t)USBD_EMEM; } - pdev->pClassData = (void *)hcdc; + (void)USBD_memset(hcdc, 0, sizeof(USBD_CDC_RNDIS_HandleTypeDef)); + + pdev->pClassDataCmsit[pdev->classId] = (void *)hcdc; + pdev->pClassData = pdev->pClassDataCmsit[pdev->classId]; if (pdev->dev_speed == USBD_SPEED_HIGH) { /* Open EP IN */ - (void)USBD_LL_OpenEP(pdev, CDC_RNDIS_IN_EP, USBD_EP_TYPE_BULK, + (void)USBD_LL_OpenEP(pdev, RNDISInEpAdd, USBD_EP_TYPE_BULK, CDC_RNDIS_DATA_HS_IN_PACKET_SIZE); - pdev->ep_in[CDC_RNDIS_IN_EP & 0xFU].is_used = 1U; + pdev->ep_in[RNDISInEpAdd & 0xFU].is_used = 1U; /* Open EP OUT */ - (void)USBD_LL_OpenEP(pdev, CDC_RNDIS_OUT_EP, USBD_EP_TYPE_BULK, + (void)USBD_LL_OpenEP(pdev, RNDISOutEpAdd, USBD_EP_TYPE_BULK, CDC_RNDIS_DATA_HS_OUT_PACKET_SIZE); - pdev->ep_out[CDC_RNDIS_OUT_EP & 0xFU].is_used = 1U; + pdev->ep_out[RNDISOutEpAdd & 0xFU].is_used = 1U; /* Set bInterval for CDC RNDIS CMD Endpoint */ - pdev->ep_in[CDC_RNDIS_CMD_EP & 0xFU].bInterval = CDC_RNDIS_HS_BINTERVAL; + pdev->ep_in[RNDISCmdEpAdd & 0xFU].bInterval = CDC_RNDIS_HS_BINTERVAL; } else { /* Open EP IN */ - (void)USBD_LL_OpenEP(pdev, CDC_RNDIS_IN_EP, USBD_EP_TYPE_BULK, + (void)USBD_LL_OpenEP(pdev, RNDISInEpAdd, USBD_EP_TYPE_BULK, CDC_RNDIS_DATA_FS_IN_PACKET_SIZE); - pdev->ep_in[CDC_RNDIS_IN_EP & 0xFU].is_used = 1U; + pdev->ep_in[RNDISInEpAdd & 0xFU].is_used = 1U; /* Open EP OUT */ - (void)USBD_LL_OpenEP(pdev, CDC_RNDIS_OUT_EP, USBD_EP_TYPE_BULK, + (void)USBD_LL_OpenEP(pdev, RNDISOutEpAdd, USBD_EP_TYPE_BULK, CDC_RNDIS_DATA_FS_OUT_PACKET_SIZE); - pdev->ep_out[CDC_RNDIS_OUT_EP & 0xFU].is_used = 1U; + pdev->ep_out[RNDISOutEpAdd & 0xFU].is_used = 1U; /* Set bInterval for CDC RNDIS CMD Endpoint */ - pdev->ep_in[CDC_RNDIS_CMD_EP & 0xFU].bInterval = CDC_RNDIS_FS_BINTERVAL; + pdev->ep_in[RNDISCmdEpAdd & 0xFU].bInterval = CDC_RNDIS_FS_BINTERVAL; } /* Open Command IN EP */ - (void)USBD_LL_OpenEP(pdev, CDC_RNDIS_CMD_EP, USBD_EP_TYPE_INTR, CDC_RNDIS_CMD_PACKET_SIZE); - pdev->ep_in[CDC_RNDIS_CMD_EP & 0xFU].is_used = 1U; + (void)USBD_LL_OpenEP(pdev, RNDISCmdEpAdd, USBD_EP_TYPE_INTR, CDC_RNDIS_CMD_PACKET_SIZE); + pdev->ep_in[RNDISCmdEpAdd & 0xFU].is_used = 1U; + + hcdc->RxBuffer = NULL; /* Init physical Interface components */ - ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->Init(); + ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init(); /* Init the CDC_RNDIS state */ hcdc->State = CDC_RNDIS_STATE_BUS_INITIALIZED; @@ -618,8 +429,13 @@ static uint8_t USBD_CDC_RNDIS_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) hcdc->NotificationStatus = 0U; hcdc->MaxPcktLen = (pdev->dev_speed == USBD_SPEED_HIGH) ? CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE : CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE; + if (hcdc->RxBuffer == NULL) + { + return (uint8_t)USBD_EMEM; + } + /* Prepare Out endpoint to receive next packet */ - (void)USBD_LL_PrepareReceive(pdev, CDC_RNDIS_OUT_EP, + (void)USBD_LL_PrepareReceive(pdev, RNDISOutEpAdd, hcdc->RxBuffer, hcdc->MaxPcktLen); return (uint8_t)USBD_OK; @@ -636,24 +452,32 @@ static uint8_t USBD_CDC_RNDIS_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { UNUSED(cfgidx); +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + RNDISInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); + RNDISOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); + RNDISCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR); +#endif /* USE_USBD_COMPOSITE */ + /* Close EP IN */ - (void)USBD_LL_CloseEP(pdev, CDC_RNDIS_IN_EP); - pdev->ep_in[CDC_RNDIS_IN_EP & 0xFU].is_used = 0U; + (void)USBD_LL_CloseEP(pdev, RNDISInEpAdd); + pdev->ep_in[RNDISInEpAdd & 0xFU].is_used = 0U; /* Close EP OUT */ - (void)USBD_LL_CloseEP(pdev, CDC_RNDIS_OUT_EP); - pdev->ep_out[CDC_RNDIS_OUT_EP & 0xFU].is_used = 0U; + (void)USBD_LL_CloseEP(pdev, RNDISOutEpAdd); + pdev->ep_out[RNDISOutEpAdd & 0xFU].is_used = 0U; /* Close Command IN EP */ - (void)USBD_LL_CloseEP(pdev, CDC_RNDIS_CMD_EP); - pdev->ep_in[CDC_RNDIS_CMD_EP & 0xFU].is_used = 0U; - pdev->ep_in[CDC_RNDIS_CMD_EP & 0xFU].bInterval = 0U; + (void)USBD_LL_CloseEP(pdev, RNDISCmdEpAdd); + pdev->ep_in[RNDISCmdEpAdd & 0xFU].is_used = 0U; + pdev->ep_in[RNDISCmdEpAdd & 0xFU].bInterval = 0U; /* DeInit physical Interface components */ - if (pdev->pClassData != NULL) + if (pdev->pClassDataCmsit[pdev->classId] != NULL) { - ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->DeInit(); - USBD_free(pdev->pClassData); + ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit(); + USBD_free(pdev->pClassDataCmsit[pdev->classId]); + pdev->pClassDataCmsit[pdev->classId] = NULL; pdev->pClassData = NULL; } @@ -670,8 +494,8 @@ static uint8_t USBD_CDC_RNDIS_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) static uint8_t USBD_CDC_RNDIS_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { - USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; - USBD_CDC_RNDIS_CtrlMsgTypeDef *Msg = (USBD_CDC_RNDIS_CtrlMsgTypeDef *)(void *)hcdc->data; + USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_CDC_RNDIS_CtrlMsgTypeDef *Msg; uint8_t ifalt = 0U; uint16_t status_info = 0U; USBD_StatusTypeDef ret = USBD_OK; @@ -681,6 +505,8 @@ static uint8_t USBD_CDC_RNDIS_Setup(USBD_HandleTypeDef *pdev, return (uint8_t)USBD_FAIL; } + Msg = (USBD_CDC_RNDIS_CtrlMsgTypeDef *)(void *)hcdc->data; + switch (req->bmRequest & USB_REQ_TYPE_MASK) { case USB_REQ_TYPE_CLASS : @@ -703,9 +529,9 @@ static uint8_t USBD_CDC_RNDIS_Setup(USBD_HandleTypeDef *pdev, } /* Allow application layer to pre-process data or add own processing before sending response */ - ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, - (uint8_t *)hcdc->data, - req->wLength); + ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData[pdev->classId])->Control(req->bRequest, + (uint8_t *)hcdc->data, + req->wLength); /* Check if Response is ready */ if (hcdc->ResponseRdy != 0U) { @@ -738,8 +564,8 @@ static uint8_t USBD_CDC_RNDIS_Setup(USBD_HandleTypeDef *pdev, so let application layer manage this case */ else { - ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, - (uint8_t *)req, 0U); + ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData[pdev->classId])->Control(req->bRequest, + (uint8_t *)req, 0U); } break; @@ -809,14 +635,19 @@ static uint8_t USBD_CDC_RNDIS_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) USBD_CDC_RNDIS_HandleTypeDef *hcdc; PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef *)pdev->pData; - if (pdev->pClassData == NULL) +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + RNDISInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ + + if (pdev->pClassDataCmsit[pdev->classId] == NULL) { return (uint8_t)USBD_FAIL; } - hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; - if (epnum == (CDC_RNDIS_IN_EP & 0x7FU)) + if (epnum == (RNDISInEpAdd & 0x7FU)) { if ((pdev->ep_in[epnum & 0xFU].total_length > 0U) && ((pdev->ep_in[epnum & 0xFU].total_length % hpcd->IN_ep[epnum & 0xFU].maxpacket) == 0U)) @@ -831,13 +662,13 @@ static uint8_t USBD_CDC_RNDIS_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) { hcdc->TxState = 0U; - if (((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->TransmitCplt != NULL) + if (((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData[pdev->classId])->TransmitCplt != NULL) { - ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum); + ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData[pdev->classId])->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum); } } } - else if (epnum == (CDC_RNDIS_CMD_EP & 0x7FU)) + else if (epnum == (RNDISCmdEpAdd & 0x7FU)) { if (hcdc->NotificationStatus != 0U) { @@ -867,14 +698,18 @@ static uint8_t USBD_CDC_RNDIS_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) USBD_CDC_RNDIS_HandleTypeDef *hcdc; uint32_t CurrPcktLen; - if (pdev->pClassData == NULL) +#ifdef USE_USBD_COMPOSITE /* Get the Endpoints addresses allocated for this class instance */ + RNDISOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ + + if (pdev->pClassDataCmsit[pdev->classId] == NULL) { return (uint8_t)USBD_FAIL; } - hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; - if (epnum == CDC_RNDIS_OUT_EP) + if (epnum == RNDISOutEpAdd) { /* Get the received data length */ CurrPcktLen = USBD_LL_GetRxDataSize(pdev, epnum); @@ -895,7 +730,7 @@ static uint8_t USBD_CDC_RNDIS_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) else { /* Prepare Out endpoint to receive next packet in current/new frame */ - (void)USBD_LL_PrepareReceive(pdev, CDC_RNDIS_OUT_EP, + (void)USBD_LL_PrepareReceive(pdev, RNDISOutEpAdd, (uint8_t *)(hcdc->RxBuffer + hcdc->RxLength), hcdc->MaxPcktLen); } @@ -916,14 +751,14 @@ static uint8_t USBD_CDC_RNDIS_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) */ static uint8_t USBD_CDC_RNDIS_EP0_RxReady(USBD_HandleTypeDef *pdev) { - USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hcdc == NULL) { return (uint8_t)USBD_FAIL; } - if ((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFFU)) + if ((pdev->pUserData[pdev->classId] != NULL) && (hcdc->CmdOpCode != 0xFFU)) { /* Check if the received command is SendEncapsulated command */ if (hcdc->CmdOpCode == CDC_RNDIS_SEND_ENCAPSULATED_COMMAND) @@ -946,7 +781,7 @@ static uint8_t USBD_CDC_RNDIS_EP0_RxReady(USBD_HandleTypeDef *pdev) return (uint8_t)USBD_OK; } - +#ifndef USE_USBD_COMPOSITE /** * @brief USBD_CDC_RNDIS_GetFSCfgDesc * Return configuration descriptor @@ -955,9 +790,27 @@ static uint8_t USBD_CDC_RNDIS_EP0_RxReady(USBD_HandleTypeDef *pdev) */ static uint8_t *USBD_CDC_RNDIS_GetFSCfgDesc(uint16_t *length) { - *length = (uint16_t)(sizeof(USBD_CDC_RNDIS_CfgFSDesc)); + USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_RNDIS_CfgDesc, CDC_RNDIS_CMD_EP); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_RNDIS_CfgDesc, CDC_RNDIS_OUT_EP); + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_RNDIS_CfgDesc, CDC_RNDIS_IN_EP); - return USBD_CDC_RNDIS_CfgFSDesc; + if (pEpCmdDesc != NULL) + { + pEpCmdDesc->bInterval = CDC_RNDIS_FS_BINTERVAL; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE; + } + + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE; + } + + *length = (uint16_t)(sizeof(USBD_CDC_RNDIS_CfgDesc)); + return USBD_CDC_RNDIS_CfgDesc; } /** @@ -968,9 +821,27 @@ static uint8_t *USBD_CDC_RNDIS_GetFSCfgDesc(uint16_t *length) */ static uint8_t *USBD_CDC_RNDIS_GetHSCfgDesc(uint16_t *length) { - *length = (uint16_t)(sizeof(USBD_CDC_RNDIS_CfgHSDesc)); + USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_RNDIS_CfgDesc, CDC_RNDIS_CMD_EP); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_RNDIS_CfgDesc, CDC_RNDIS_OUT_EP); + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_RNDIS_CfgDesc, CDC_RNDIS_IN_EP); - return USBD_CDC_RNDIS_CfgHSDesc; + if (pEpCmdDesc != NULL) + { + pEpCmdDesc->bInterval = CDC_RNDIS_HS_BINTERVAL; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE; + } + + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE; + } + + *length = (uint16_t)(sizeof(USBD_CDC_RNDIS_CfgDesc)); + return USBD_CDC_RNDIS_CfgDesc; } /** @@ -981,9 +852,27 @@ static uint8_t *USBD_CDC_RNDIS_GetHSCfgDesc(uint16_t *length) */ static uint8_t *USBD_CDC_RNDIS_GetOtherSpeedCfgDesc(uint16_t *length) { - *length = (uint16_t)(sizeof(USBD_CDC_RNDIS_OtherSpeedCfgDesc)); + USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_RNDIS_CfgDesc, CDC_RNDIS_CMD_EP); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_RNDIS_CfgDesc, CDC_RNDIS_OUT_EP); + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_RNDIS_CfgDesc, CDC_RNDIS_IN_EP); - return USBD_CDC_RNDIS_OtherSpeedCfgDesc; + if (pEpCmdDesc != NULL) + { + pEpCmdDesc->bInterval = CDC_RNDIS_FS_BINTERVAL; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE; + } + + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE; + } + + *length = (uint16_t)(sizeof(USBD_CDC_RNDIS_CfgDesc)); + return USBD_CDC_RNDIS_CfgDesc; } /** @@ -998,7 +887,7 @@ uint8_t *USBD_CDC_RNDIS_GetDeviceQualifierDescriptor(uint16_t *length) return USBD_CDC_RNDIS_DeviceQualifierDesc; } - +#endif /* USE_USBD_COMPOSITE */ /** * @brief USBD_CDC_RNDIS_RegisterInterface * @param pdev: device instance @@ -1013,7 +902,7 @@ uint8_t USBD_CDC_RNDIS_RegisterInterface(USBD_HandleTypeDef *pdev, return (uint8_t)USBD_FAIL; } - pdev->pUserData = fops; + pdev->pUserData[pdev->classId] = fops; return (uint8_t)USBD_OK; } @@ -1035,7 +924,8 @@ static uint8_t *USBD_CDC_RNDIS_USRStringDescriptor(USBD_HandleTypeDef *pdev, uin /* Check if the requested string interface is supported */ if (index == CDC_RNDIS_MAC_STRING_INDEX) { - USBD_GetString((uint8_t *)((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->pStrDesc, USBD_StrDesc, length); + USBD_GetString((uint8_t *)((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData[pdev->classId])->pStrDesc, USBD_StrDesc, + length); return USBD_StrDesc; } /* Not supported Interface Descriptor index */ @@ -1055,7 +945,7 @@ static uint8_t *USBD_CDC_RNDIS_USRStringDescriptor(USBD_HandleTypeDef *pdev, uin */ uint8_t USBD_CDC_RNDIS_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uint32_t length) { - USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hcdc == NULL) { @@ -1077,7 +967,7 @@ uint8_t USBD_CDC_RNDIS_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uin */ uint8_t USBD_CDC_RNDIS_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff) { - USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hcdc == NULL) { @@ -1102,12 +992,17 @@ uint8_t USBD_CDC_RNDIS_TransmitPacket(USBD_HandleTypeDef *pdev) USBD_CDC_RNDIS_PacketMsgTypeDef *PacketMsg; USBD_StatusTypeDef ret = USBD_BUSY; - if (pdev->pClassData == NULL) +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + RNDISInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ + + if (pdev->pClassDataCmsit[pdev->classId] == NULL) { return (uint8_t)USBD_FAIL; } - hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; PacketMsg = (USBD_CDC_RNDIS_PacketMsgTypeDef *)(void *)hcdc->TxBuffer; if (hcdc->TxState == 0U) @@ -1129,10 +1024,10 @@ uint8_t USBD_CDC_RNDIS_TransmitPacket(USBD_HandleTypeDef *pdev) PacketMsg->Reserved = 0U; /* Update the packet total length */ - pdev->ep_in[CDC_RNDIS_IN_EP & 0xFU].total_length = hcdc->TxLength; + pdev->ep_in[RNDISInEpAdd & 0xFU].total_length = hcdc->TxLength; /* Transmit next packet */ - (void)USBD_LL_Transmit(pdev, CDC_RNDIS_IN_EP, hcdc->TxBuffer, hcdc->TxLength); + (void)USBD_LL_Transmit(pdev, RNDISInEpAdd, hcdc->TxBuffer, hcdc->TxLength); ret = USBD_OK; } @@ -1151,15 +1046,20 @@ uint8_t USBD_CDC_RNDIS_ReceivePacket(USBD_HandleTypeDef *pdev) { USBD_CDC_RNDIS_HandleTypeDef *hcdc; - if (pdev->pClassData == NULL) +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + RNDISOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ + + if (pdev->pClassDataCmsit[pdev->classId] == NULL) { return (uint8_t)USBD_FAIL; } - hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; /* Prepare Out endpoint to receive next packet */ - (void)USBD_LL_PrepareReceive(pdev, CDC_RNDIS_OUT_EP, + (void)USBD_LL_PrepareReceive(pdev, RNDISOutEpAdd, hcdc->RxBuffer, hcdc->MaxPcktLen); return (uint8_t)USBD_OK; @@ -1176,12 +1076,12 @@ uint8_t USBD_CDC_RNDIS_ReceivePacket(USBD_HandleTypeDef *pdev) * @retval status */ uint8_t USBD_CDC_RNDIS_SendNotification(USBD_HandleTypeDef *pdev, - USBD_CDC_RNDIS_NotifCodeTypeDef Notif, + USBD_CDC_NotifCodeTypeDef Notif, uint16_t bVal, uint8_t *pData) { uint32_t Idx; uint16_t ReqSize = 0U; - USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; USBD_StatusTypeDef ret = USBD_OK; UNUSED(bVal); @@ -1192,6 +1092,11 @@ uint8_t USBD_CDC_RNDIS_SendNotification(USBD_HandleTypeDef *pdev, return (uint8_t)USBD_FAIL; } +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + RNDISCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR); +#endif /* USE_USBD_COMPOSITE */ + /* Initialize the request fields */ (hcdc->Req).bmRequest = CDC_RNDIS_BMREQUEST_TYPE_RNDIS; (hcdc->Req).bRequest = (uint8_t)Notif; @@ -1219,7 +1124,7 @@ uint8_t USBD_CDC_RNDIS_SendNotification(USBD_HandleTypeDef *pdev, /* Transmit notification packet */ if (ReqSize != 0U) { - (void)USBD_LL_Transmit(pdev, CDC_RNDIS_CMD_EP, (uint8_t *)&hcdc->Req, ReqSize); + (void)USBD_LL_Transmit(pdev, RNDISCmdEpAdd, (uint8_t *)&hcdc->Req, ReqSize); } return (uint8_t)ret; @@ -1293,7 +1198,7 @@ static uint8_t USBD_CDC_RNDIS_ProcessInitMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_InitMsgTypeDef *Msg) { /* Get the CDC_RNDIS handle pointer */ - USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; /* Get and format the Msg input */ USBD_CDC_RNDIS_InitMsgTypeDef *InitMessage = (USBD_CDC_RNDIS_InitMsgTypeDef *)Msg; @@ -1358,7 +1263,7 @@ static uint8_t USBD_CDC_RNDIS_ProcessHaltMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_HaltMsgTypeDef *Msg) { /* Get the CDC_RNDIS handle pointer */ - USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hcdc == NULL) { @@ -1387,7 +1292,7 @@ static uint8_t USBD_CDC_RNDIS_ProcessKeepAliveMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_KpAliveMsgTypeDef *Msg) { /* Get the CDC_RNDIS handle pointer */ - USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; /* Use same Msg input buffer as response buffer */ USBD_CDC_RNDIS_KpAliveCpltMsgTypeDef *InitResponse = (USBD_CDC_RNDIS_KpAliveCpltMsgTypeDef *)(void *)Msg; @@ -1437,7 +1342,7 @@ static uint8_t USBD_CDC_RNDIS_ProcessQueryMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_QueryMsgTypeDef *Msg) { /* Get the CDC_RNDIS handle pointer */ - USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; /* Use same Msg input buffer as response buffer */ USBD_CDC_RNDIS_QueryCpltMsgTypeDef *QueryResponse = (USBD_CDC_RNDIS_QueryCpltMsgTypeDef *)(void *)Msg; @@ -1582,7 +1487,7 @@ static uint8_t USBD_CDC_RNDIS_ProcessSetMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_SetMsgTypeDef *Msg) { /* Get the CDC_RNDIS handle pointer */ - USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; /* Get and format the Msg input */ USBD_CDC_RNDIS_SetMsgTypeDef *SetMessage = (USBD_CDC_RNDIS_SetMsgTypeDef *)Msg; @@ -1645,7 +1550,7 @@ static uint8_t USBD_CDC_RNDIS_ProcessResetMsg(USBD_HandleTypeDef *pdev, /* Get and format the Msg input */ USBD_CDC_RNDIS_ResetMsgTypeDef *ResetMessage = (USBD_CDC_RNDIS_ResetMsgTypeDef *)Msg; /* Get the CDC_RNDIS handle pointer */ - USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; /* Use same Msg input buffer as response buffer */ USBD_CDC_RNDIS_ResetCpltMsgTypeDef *ResetResponse = (USBD_CDC_RNDIS_ResetCpltMsgTypeDef *)(void *)Msg; @@ -1696,7 +1601,7 @@ static uint8_t USBD_CDC_RNDIS_ProcessPacketMsg(USBD_HandleTypeDef *pdev, uint32_t tmp1, tmp2; /* Get the CDC_RNDIS handle pointer */ - USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; /* Get and format the Msg input */ USBD_CDC_RNDIS_PacketMsgTypeDef *PacketMsg = (USBD_CDC_RNDIS_PacketMsgTypeDef *)Msg; @@ -1721,7 +1626,7 @@ static uint8_t USBD_CDC_RNDIS_ProcessPacketMsg(USBD_HandleTypeDef *pdev, hcdc->RxLength = PacketMsg->DataLength; /* Process data by application */ - ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength); + ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData[pdev->classId])->Receive(hcdc->RxBuffer, &hcdc->RxLength); return (uint8_t)USBD_OK; } @@ -1738,7 +1643,7 @@ static uint8_t USBD_CDC_RNDIS_ProcessUnsupportedMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_CtrlMsgTypeDef *Msg) { /* Get the CDC_RNDIS handle pointer */ - USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; /* Use same Msg input buffer as response buffer */ USBD_CDC_RNDIS_StsChangeMsgTypeDef *Response = (USBD_CDC_RNDIS_StsChangeMsgTypeDef *)(void *)Msg; diff --git a/Class/CDC_RNDIS/Src/usbd_cdc_rndis_if_template.c b/Class/CDC_RNDIS/Src/usbd_cdc_rndis_if_template.c index f59c0b7..9be1fe8 100644 --- a/Class/CDC_RNDIS/Src/usbd_cdc_rndis_if_template.c +++ b/Class/CDC_RNDIS/Src/usbd_cdc_rndis_if_template.c @@ -30,7 +30,7 @@ #include "ethernetif.h" */ -#include "main.h" +#include "usbd_cdc_rndis_if_template.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ @@ -39,13 +39,13 @@ /* Received Data over USB are stored in this buffer */ #if defined ( __ICCARM__ ) /*!< IAR Compiler */ #pragma data_alignment=4 -#endif +#endif /* __ICCARM__ */ __ALIGN_BEGIN uint8_t UserRxBuffer[CDC_RNDIS_ETH_MAX_SEGSZE + 100] __ALIGN_END; /* Transmitted Data over CDC_RNDIS (CDC_RNDIS interface) are stored in this buffer */ #if defined ( __ICCARM__ ) /*!< IAR Compiler */ #pragma data_alignment=4 -#endif +#endif /* __ICCARM__ */ __ALIGN_BEGIN static uint8_t UserTxBuffer[CDC_RNDIS_ETH_MAX_SEGSZE + 100] __ALIGN_END; static uint8_t CDC_RNDISInitialized = 0U; @@ -109,7 +109,11 @@ static int8_t CDC_RNDIS_Itf_Init(void) */ static int8_t CDC_RNDIS_Itf_DeInit(void) { +#ifdef USE_USBD_COMPOSITE + USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *)(USBD_Device.pClassDataCmsit[USBD_Device.classId]); +#else USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *)(USBD_Device.pClassData); +#endif /* USE_USBD_COMPOSITE */ /* Add your code here @@ -131,7 +135,11 @@ static int8_t CDC_RNDIS_Itf_DeInit(void) */ static int8_t CDC_RNDIS_Itf_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length) { +#ifdef USE_USBD_COMPOSITE + USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *)(USBD_Device.pClassDataCmsit[USBD_Device.classId]); +#else USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *)(USBD_Device.pClassData); +#endif /* USE_USBD_COMPOSITE */ switch (cmd) { @@ -174,7 +182,11 @@ static int8_t CDC_RNDIS_Itf_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length) static int8_t CDC_RNDIS_Itf_Receive(uint8_t *Buf, uint32_t *Len) { /* Get the CDC_RNDIS handler pointer */ +#ifdef USE_USBD_COMPOSITE + USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *)(USBD_Device.pClassDataCmsit[USBD_Device.classId]); +#else USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *)(USBD_Device.pClassData); +#endif /* USE_USBD_COMPOSITE */ /* Call Eth buffer processing */ hcdc_cdc_rndis->RxState = 1U; @@ -217,9 +229,18 @@ static int8_t CDC_RNDIS_Itf_TransmitCplt(uint8_t *Buf, uint32_t *Len, uint8_t ep static int8_t CDC_RNDIS_Itf_Process(USBD_HandleTypeDef *pdev) { /* Get the CDC_RNDIS handler pointer */ - USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *)(pdev->pClassData); +#ifdef USE_USBD_COMPOSITE + USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *)(pdev->pClassDataCmsit[pdev->classId]); +#else + USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *)(pdev->pClassData); +#endif /* USE_USBD_COMPOSITE */ - if ((hcdc_cdc_rndis != NULL) && (hcdc_cdc_rndis->LinkStatus != 0U)) + if (hcdc_cdc_rndis == NULL) + { + return (-1); + } + + if (hcdc_cdc_rndis->LinkStatus != 0U) { /* Add your code here diff --git a/Class/CompositeBuilder/Inc/usbd_composite_builder.h b/Class/CompositeBuilder/Inc/usbd_composite_builder.h new file mode 100644 index 0000000..6d61755 --- /dev/null +++ b/Class/CompositeBuilder/Inc/usbd_composite_builder.h @@ -0,0 +1,289 @@ +/** + ****************************************************************************** + * @file usbd_composite_builder.h + * @author MCD Application Team + * @brief Header for the usbd_composite_builder.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_COMPOSITE_BUILDER_H__ +#define __USBD_COMPOSITE_BUILDER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" + +#if USBD_CMPSIT_ACTIVATE_HID == 1U +#include "usbd_hid.h" +#endif /* USBD_CMPSIT_ACTIVATE_HID */ + +#if USBD_CMPSIT_ACTIVATE_MSC == 1U +#include "usbd_msc.h" +#endif /* USBD_CMPSIT_ACTIVATE_MSC */ + +#if USBD_CMPSIT_ACTIVATE_CDC == 1U +#include "usbd_cdc.h" +#endif /* USBD_CMPSIT_ACTIVATE_CDC */ + +#if USBD_CMPSIT_ACTIVATE_DFU == 1U +#include "usbd_dfu.h" +#endif /* USBD_CMPSIT_ACTIVATE_DFU */ + +#if USBD_CMPSIT_ACTIVATE_RNDIS == 1U +#include "usbd_cdc_rndis.h" +#endif /* USBD_CMPSIT_ACTIVATE_RNDIS */ + +#if USBD_CMPSIT_ACTIVATE_CDC_ECM == 1U +#include "usbd_cdc_ecm.h" + +#ifndef __USBD_CDC_ECM_IF_H +#include "usbd_cdc_ecm_if_template.h" +#endif /* __USBD_CDC_ECM_IF_H */ +#endif /* USBD_CMPSIT_ACTIVATE_CDC_ECM */ + +#if USBD_CMPSIT_ACTIVATE_AUDIO == 1 +#include "usbd_audio.h" +#endif /* USBD_CMPSIT_ACTIVATE_AUDIO */ + +#if USBD_CMPSIT_ACTIVATE_CUSTOMHID == 1 +#include "usbd_customhid.h" +#endif /* USBD_CMPSIT_ACTIVATE_CUSTOMHID */ + +#if USBD_CMPSIT_ACTIVATE_VIDEO == 1 +#include "usbd_video.h" +#endif /* USBD_CMPSIT_ACTIVATE_VIDEO */ + +#if USBD_CMPSIT_ACTIVATE_PRINTER == 1 +#include "usbd_printer.h" +#endif /* USBD_CMPSIT_ACTIVATE_PRINTER */ + +#if USBD_CMPSIT_ACTIVATE_CCID == 1U +#include "usbd_ccid.h" +#endif /* USBD_CMPSIT_ACTIVATE_CCID */ + +#if USBD_CMPSIT_ACTIVATE_MTP == 1U +#include "usbd_mtp.h" +#endif /* USBD_CMPSIT_ACTIVATE_MTP */ + +/* Private defines -----------------------------------------------------------*/ +/* By default all classes are deactivated, in order to activate a class + define its value to zero */ +#ifndef USBD_CMPSIT_ACTIVATE_HID +#define USBD_CMPSIT_ACTIVATE_HID 0U +#endif /* USBD_CMPSIT_ACTIVATE_HID */ + +#ifndef USBD_CMPSIT_ACTIVATE_MSC +#define USBD_CMPSIT_ACTIVATE_MSC 0U +#endif /* USBD_CMPSIT_ACTIVATE_MSC */ + +#ifndef USBD_CMPSIT_ACTIVATE_DFU +#define USBD_CMPSIT_ACTIVATE_DFU 0U +#endif /* USBD_CMPSIT_ACTIVATE_DFU */ + +#ifndef USBD_CMPSIT_ACTIVATE_CDC +#define USBD_CMPSIT_ACTIVATE_CDC 0U +#endif /* USBD_CMPSIT_ACTIVATE_CDC */ + +#ifndef USBD_CMPSIT_ACTIVATE_CDC_ECM +#define USBD_CMPSIT_ACTIVATE_CDC_ECM 0U +#endif /* USBD_CMPSIT_ACTIVATE_CDC_ECM */ + +#ifndef USBD_CMPSIT_ACTIVATE_RNDIS +#define USBD_CMPSIT_ACTIVATE_RNDIS 0U +#endif /* USBD_CMPSIT_ACTIVATE_RNDIS */ + +#ifndef USBD_CMPSIT_ACTIVATE_AUDIO +#define USBD_CMPSIT_ACTIVATE_AUDIO 0U +#endif /* USBD_CMPSIT_ACTIVATE_AUDIO */ + +#ifndef USBD_CMPSIT_ACTIVATE_CUSTOMHID +#define USBD_CMPSIT_ACTIVATE_CUSTOMHID 0U +#endif /* USBD_CMPSIT_ACTIVATE_CUSTOMHID */ + +#ifndef USBD_CMPSIT_ACTIVATE_VIDEO +#define USBD_CMPSIT_ACTIVATE_VIDEO 0U +#endif /* USBD_CMPSIT_ACTIVATE_VIDEO */ + +#ifndef USBD_CMPSIT_ACTIVATE_PRINTER +#define USBD_CMPSIT_ACTIVATE_PRINTER 0U +#endif /* USBD_CMPSIT_ACTIVATE_PRINTER */ + +#ifndef USBD_CMPSIT_ACTIVATE_CCID +#define USBD_CMPSIT_ACTIVATE_CCID 0U +#endif /* USBD_CMPSIT_ACTIVATE_CCID */ + +#ifndef USBD_CMPSIT_ACTIVATE_MTP +#define USBD_CMPSIT_ACTIVATE_MTP 0U +#endif /* USBD_CMPSIT_ACTIVATE_MTP */ + + +/* This is the maximum supported configuration descriptor size + User may define this value in usbd_conf.h in order to optimize footprint */ +#ifndef USBD_CMPST_MAX_CONFDESC_SZ +#define USBD_CMPST_MAX_CONFDESC_SZ 300U +#endif /* USBD_CMPST_MAX_CONFDESC_SZ */ + +#ifndef USBD_CONFIG_STR_DESC_IDX +#define USBD_CONFIG_STR_DESC_IDX 4U +#endif /* USBD_CONFIG_STR_DESC_IDX */ + +/* Exported types ------------------------------------------------------------*/ +/* USB Iad descriptors structure */ +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bFirstInterface; + uint8_t bInterfaceCount; + uint8_t bFunctionClass; + uint8_t bFunctionSubClass; + uint8_t bFunctionProtocol; + uint8_t iFunction; +} USBD_IadDescTypeDef; + +/* USB interface descriptors structure */ +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; +} USBD_IfDescTypeDef; + +#if (USBD_CMPSIT_ACTIVATE_CDC == 1) || (USBD_CMPSIT_ACTIVATE_RNDIS == 1) || (USBD_CMPSIT_ACTIVATE_CDC_ECM == 1) +typedef struct +{ +/* + * CDC Class specification revision 1.2 + * Table 15: Class-Specific Descriptor Header Format + */ + /* Header Functional Descriptor */ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint16_t bcdCDC; +} __PACKED USBD_CDCHeaderFuncDescTypeDef; + +typedef struct +{ + /* Call Management Functional Descriptor */ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmCapabilities; + uint8_t bDataInterface; +} USBD_CDCCallMgmFuncDescTypeDef; + +typedef struct +{ + /* ACM Functional Descriptor */ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmCapabilities; +} USBD_CDCACMFuncDescTypeDef; + +typedef struct +{ +/* + * CDC Class specification revision 1.2 + * Table 16: Union Interface Functional Descriptor + */ + /* Union Functional Descriptor */ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bMasterInterface; + uint8_t bSlaveInterface; +} USBD_CDCUnionFuncDescTypeDef; + +#endif /* (USBD_CMPSIT_ACTIVATE_CDC == 1) || (USBD_CMPSIT_ACTIVATE_RNDIS == 1) || (USBD_CMPSIT_ACTIVATE_CDC_ECM == 1)*/ + +extern USBD_ClassTypeDef USBD_CMPSIT; + +/* Exported functions prototypes ---------------------------------------------*/ +uint8_t USBD_CMPSIT_AddToConfDesc(USBD_HandleTypeDef *pdev); + +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_CMPSIT_AddClass(USBD_HandleTypeDef *pdev, + USBD_ClassTypeDef *pclass, + USBD_CompositeClassTypeDef class, + uint8_t cfgidx); + +uint32_t USBD_CMPSIT_SetClassID(USBD_HandleTypeDef *pdev, + USBD_CompositeClassTypeDef Class, + uint32_t Instance); + +uint32_t USBD_CMPSIT_GetClassID(USBD_HandleTypeDef *pdev, + USBD_CompositeClassTypeDef Class, + uint32_t Instance); +#endif /* USE_USBD_COMPOSITE */ + +uint8_t USBD_CMPST_ClearConfDesc(USBD_HandleTypeDef *pdev); + +/* Private macro -----------------------------------------------------------*/ +#define __USBD_CMPSIT_SET_EP(epadd, eptype, epsize, HSinterval, FSinterval) \ + do { \ + /* Append Endpoint descriptor to Configuration descriptor */ \ + pEpDesc = ((USBD_EpDescTypeDef*)((uint32_t)pConf + *Sze)); \ + pEpDesc->bLength = (uint8_t)sizeof(USBD_EpDescTypeDef); \ + pEpDesc->bDescriptorType = USB_DESC_TYPE_ENDPOINT; \ + pEpDesc->bEndpointAddress = (epadd); \ + pEpDesc->bmAttributes = (eptype); \ + pEpDesc->wMaxPacketSize = (epsize); \ + if(speed == (uint8_t)USBD_SPEED_HIGH) \ + { \ + pEpDesc->bInterval = HSinterval; \ + } \ + else \ + { \ + pEpDesc->bInterval = FSinterval; \ + } \ + *Sze += (uint32_t)sizeof(USBD_EpDescTypeDef); \ + } while(0) + +#define __USBD_CMPSIT_SET_IF(ifnum, alt, eps, class, subclass, protocol, istring) \ + do { \ + /* Interface Descriptor */ \ + pIfDesc = ((USBD_IfDescTypeDef*)((uint32_t)pConf + *Sze)); \ + pIfDesc->bLength = (uint8_t)sizeof(USBD_IfDescTypeDef); \ + pIfDesc->bDescriptorType = USB_DESC_TYPE_INTERFACE; \ + pIfDesc->bInterfaceNumber = ifnum; \ + pIfDesc->bAlternateSetting = alt; \ + pIfDesc->bNumEndpoints = eps; \ + pIfDesc->bInterfaceClass = class; \ + pIfDesc->bInterfaceSubClass = subclass; \ + pIfDesc->bInterfaceProtocol = protocol; \ + pIfDesc->iInterface = istring; \ + *Sze += (uint32_t)sizeof(USBD_IfDescTypeDef); \ + } while(0) + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_COMPOSITE_BUILDER_H__ */ + +/** + * @} + */ + diff --git a/Class/CompositeBuilder/Src/usbd_composite_builder.c b/Class/CompositeBuilder/Src/usbd_composite_builder.c new file mode 100644 index 0000000..76ce567 --- /dev/null +++ b/Class/CompositeBuilder/Src/usbd_composite_builder.c @@ -0,0 +1,1878 @@ +/** + ****************************************************************************** + * @file usbd_composite_builder.c + * @author MCD Application Team + * @brief This file provides all the composite builder functions. + ****************************************************************************** + * @attention + * + * Copyright (c) 2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + * @verbatim + * + * =================================================================== + * Composite Builder Description + * =================================================================== + * + * The composite builder builds the configuration descriptors based on + * the selection of classes by user. + * It includes all USB Device classes in order to instantiate their + * descriptors, but for better management, it is possible to optimize + * footprint by removing unused classes. It is possible to do so by + * commenting the relative define in usbd_conf.h. + * + * @endverbatim + * + ****************************************************************************** + */ + +/* BSPDependencies +- None +EndBSPDependencies */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_composite_builder.h" + +#ifdef USE_USBD_COMPOSITE + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup CMPSIT_CORE + * @brief Mass storage core module + * @{ + */ + +/** @defgroup CMPSIT_CORE_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup CMPSIT_CORE_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup CMPSIT_CORE_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup CMPSIT_CORE_Private_FunctionPrototypes + * @{ + */ +/* uint8_t USBD_CMPSIT_Init (USBD_HandleTypeDef *pdev, + uint8_t cfgidx); */ /* Function not used for the moment */ + +/* uint8_t USBD_CMPSIT_DeInit (USBD_HandleTypeDef *pdev, + uint8_t cfgidx); */ /* Function not used for the moment */ + +uint8_t *USBD_CMPSIT_GetFSCfgDesc(uint16_t *length); +#ifdef USE_USB_HS +uint8_t *USBD_CMPSIT_GetHSCfgDesc(uint16_t *length); +#endif /* USE_USB_HS */ + +uint8_t *USBD_CMPSIT_GetOtherSpeedCfgDesc(uint16_t *length); + +uint8_t *USBD_CMPSIT_GetDeviceQualifierDescriptor(uint16_t *length); + +static uint8_t USBD_CMPSIT_FindFreeIFNbr(USBD_HandleTypeDef *pdev); + +static void USBD_CMPSIT_AddConfDesc(uint32_t Conf, __IO uint32_t *pSze); + +static void USBD_CMPSIT_AssignEp(USBD_HandleTypeDef *pdev, uint8_t Add, uint8_t Type, uint32_t Sze); + + +#if USBD_CMPSIT_ACTIVATE_HID == 1U +static void USBD_CMPSIT_HIDMouseDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed); +#endif /* USBD_CMPSIT_ACTIVATE_HID == 1U */ + +#if USBD_CMPSIT_ACTIVATE_MSC == 1U +static void USBD_CMPSIT_MSCDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed); +#endif /* USBD_CMPSIT_ACTIVATE_MSC == 1U */ + +#if USBD_CMPSIT_ACTIVATE_CDC == 1U +static void USBD_CMPSIT_CDCDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed); +#endif /* USBD_CMPSIT_ACTIVATE_CDC == 1U */ + +#if USBD_CMPSIT_ACTIVATE_DFU == 1U +static void USBD_CMPSIT_DFUDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed); +#endif /* USBD_CMPSIT_ACTIVATE_DFU == 1U */ + +#if USBD_CMPSIT_ACTIVATE_RNDIS == 1U +static void USBD_CMPSIT_RNDISDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed); +#endif /* USBD_CMPSIT_ACTIVATE_RNDIS == 1U */ + +#if USBD_CMPSIT_ACTIVATE_CDC_ECM == 1U +static void USBD_CMPSIT_CDC_ECMDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed); +#endif /* USBD_CMPSIT_ACTIVATE_CDC_ECM == 1U */ + +#if USBD_CMPSIT_ACTIVATE_AUDIO == 1U +static void USBD_CMPSIT_AUDIODesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed); +#endif /* USBD_CMPSIT_ACTIVATE_AUDIO == 1U */ + +#if USBD_CMPSIT_ACTIVATE_CUSTOMHID == 1 +static void USBD_CMPSIT_CUSTOMHIDDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed); +#endif /* USBD_CMPSIT_ACTIVATE_CUSTOMHID == 1U */ + +#if USBD_CMPSIT_ACTIVATE_VIDEO == 1U +static void USBD_CMPSIT_VIDEODesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed); +#endif /* USBD_CMPSIT_ACTIVATE_VIDEO == 1U */ + +#if USBD_CMPSIT_ACTIVATE_PRINTER == 1U +static void USBD_CMPSIT_PRNTDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed); +#endif /* USBD_CMPSIT_ACTIVATE_PRINTER == 1U */ + +#if USBD_CMPSIT_ACTIVATE_CCID == 1U +static void USBD_CMPSIT_CCIDDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed); +#endif /* USBD_CMPSIT_ACTIVATE_CCID == 1U */ + +#if USBD_CMPSIT_ACTIVATE_MTP == 1U +static void USBD_CMPSIT_MTPDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed); +#endif /* USBD_CMPSIT_ACTIVATE_MTP == 1U */ + +/** + * @} + */ + + +/** @defgroup CMPSIT_CORE_Private_Variables + * @{ + */ +/* This structure is used only for the Configuration descriptors and Device Qualifier */ +USBD_ClassTypeDef USBD_CMPSIT = +{ + NULL, /* Init, */ + NULL, /* DeInit, */ + NULL, /* Setup, */ + NULL, /* EP0_TxSent, */ + NULL, /* EP0_RxReady, */ + NULL, /* DataIn, */ + NULL, /* DataOut, */ + NULL, /* SOF, */ + NULL, + NULL, +#ifdef USE_USB_HS + USBD_CMPSIT_GetHSCfgDesc, +#else + NULL, +#endif /* USE_USB_HS */ + USBD_CMPSIT_GetFSCfgDesc, + USBD_CMPSIT_GetOtherSpeedCfgDesc, + USBD_CMPSIT_GetDeviceQualifierDescriptor, +#if (USBD_SUPPORT_USER_STRING_DESC == 1U) + NULL, +#endif /* USBD_SUPPORT_USER_STRING_DESC */ +}; + +/* The generic configuration descriptor buffer that will be filled by builder + Size of the buffer is the maximum possible configuration descriptor size. */ +__ALIGN_BEGIN static uint8_t USBD_CMPSIT_FSCfgDesc[USBD_CMPST_MAX_CONFDESC_SZ] __ALIGN_END = {0}; +static uint8_t *pCmpstFSConfDesc = USBD_CMPSIT_FSCfgDesc; +/* Variable that dynamically holds the current size of the configuration descriptor */ +static __IO uint32_t CurrFSConfDescSz = 0U; + +#ifdef USE_USB_HS +__ALIGN_BEGIN static uint8_t USBD_CMPSIT_HSCfgDesc[USBD_CMPST_MAX_CONFDESC_SZ] __ALIGN_END = {0}; +static uint8_t *pCmpstHSConfDesc = USBD_CMPSIT_HSCfgDesc; +/* Variable that dynamically holds the current size of the configuration descriptor */ +static __IO uint32_t CurrHSConfDescSz = 0U; +#endif /* USE_USB_HS */ + +/* USB Standard Device Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_CMPSIT_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = +{ + USB_LEN_DEV_QUALIFIER_DESC, /* bLength */ + USB_DESC_TYPE_DEVICE_QUALIFIER, /* bDescriptorType */ + 0x00, /* bcdDevice low */ + 0x02, /* bcdDevice high */ + 0xEF, /* Class */ + 0x02, /* SubClass */ + 0x01, /* Protocol */ + 0x40, /* bMaxPacketSize0 */ + 0x01, /* bNumConfigurations */ + 0x00, /* bReserved */ +}; + +/** + * @} + */ + + +/** @defgroup CMPSIT_CORE_Private_Functions + * @{ + */ + +/** + * @brief USBD_CMPSIT_AddClass + * Register a class in the class builder + * @param pdev: device instance + * @param pclass: pointer to the class structure to be added + * @param class: type of the class to be added (from USBD_CompositeClassTypeDef) + * @param cfgidx: configuration index + * @retval status + */ +uint8_t USBD_CMPSIT_AddClass(USBD_HandleTypeDef *pdev, + USBD_ClassTypeDef *pclass, + USBD_CompositeClassTypeDef class, + uint8_t cfgidx) +{ + if ((pdev->classId < USBD_MAX_SUPPORTED_CLASS) && (pdev->tclasslist[pdev->classId].Active == 0U)) + { + /* Store the class parameters in the global tab */ + pdev->pClass[pdev->classId] = pclass; + pdev->tclasslist[pdev->classId].ClassId = pdev->classId; + pdev->tclasslist[pdev->classId].Active = 1U; + pdev->tclasslist[pdev->classId].ClassType = class; + + /* Call configuration descriptor builder and endpoint configuration builder */ + if (USBD_CMPSIT_AddToConfDesc(pdev) != (uint8_t)USBD_OK) + { + return (uint8_t)USBD_FAIL; + } + } + + UNUSED(cfgidx); + + return (uint8_t)USBD_OK; +} + + +/** + * @brief USBD_CMPSIT_AddToConfDesc + * Add a new class to the configuration descriptor + * @param pdev: device instance + * @retval status + */ +uint8_t USBD_CMPSIT_AddToConfDesc(USBD_HandleTypeDef *pdev) +{ + uint8_t idxIf = 0U; + uint8_t iEp = 0U; + + /* For the first class instance, start building the config descriptor common part */ + if (pdev->classId == 0U) + { + /* Add configuration and IAD descriptors */ + USBD_CMPSIT_AddConfDesc((uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz); +#ifdef USE_USB_HS + USBD_CMPSIT_AddConfDesc((uint32_t)pCmpstHSConfDesc, &CurrHSConfDescSz); +#endif /* USE_USB_HS */ + } + + switch (pdev->tclasslist[pdev->classId].ClassType) + { +#if USBD_CMPSIT_ACTIVATE_HID == 1 + case CLASS_TYPE_HID: + /* Setup Max packet sizes (for HID, no dependency on USB Speed, both HS/FS have same packet size) */ + pdev->tclasslist[pdev->classId].CurrPcktSze = HID_EPIN_SIZE; + + /* Find the first available interface slot and Assign number of interfaces */ + idxIf = USBD_CMPSIT_FindFreeIFNbr(pdev); + pdev->tclasslist[pdev->classId].NumIf = 1U; + pdev->tclasslist[pdev->classId].Ifs[0] = idxIf; + + /* Assign endpoint numbers */ + pdev->tclasslist[pdev->classId].NumEps = 1U; /* EP1_IN */ + + /* Set IN endpoint slot */ + iEp = pdev->tclasslist[pdev->classId].EpAdd[0]; + + /* Assign IN Endpoint */ + USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_INTR, pdev->tclasslist[pdev->classId].CurrPcktSze); + + /* Configure and Append the Descriptor */ + USBD_CMPSIT_HIDMouseDesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL); + +#ifdef USE_USB_HS + USBD_CMPSIT_HIDMouseDesc(pdev, (uint32_t)pCmpstHSConfDesc, &CurrHSConfDescSz, (uint8_t)USBD_SPEED_HIGH); +#endif /* USE_USB_HS */ + + break; +#endif /* USBD_CMPSIT_ACTIVATE_HID */ + +#if USBD_CMPSIT_ACTIVATE_MSC == 1 + case CLASS_TYPE_MSC: + /* Setup default Max packet size */ + pdev->tclasslist[pdev->classId].CurrPcktSze = MSC_MAX_FS_PACKET; + + /* Find the first available interface slot and Assign number of interfaces */ + idxIf = USBD_CMPSIT_FindFreeIFNbr(pdev); + pdev->tclasslist[pdev->classId].NumIf = 1U; + pdev->tclasslist[pdev->classId].Ifs[0] = idxIf; + + /* Assign endpoint numbers */ + pdev->tclasslist[pdev->classId].NumEps = 2U; /* EP1_IN, EP1_OUT */ + + /* Set IN endpoint slot */ + iEp = pdev->tclasslist[pdev->classId].EpAdd[0]; + USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze); + + /* Set OUT endpoint slot */ + iEp = pdev->tclasslist[pdev->classId].EpAdd[1]; + USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze); + + /* Configure and Append the Descriptor */ + USBD_CMPSIT_MSCDesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL); + +#ifdef USE_USB_HS + USBD_CMPSIT_MSCDesc(pdev, (uint32_t)pCmpstHSConfDesc, &CurrHSConfDescSz, (uint8_t)USBD_SPEED_HIGH); +#endif /* USE_USB_HS */ + + break; +#endif /* USBD_CMPSIT_ACTIVATE_MSC */ + +#if USBD_CMPSIT_ACTIVATE_CDC == 1 + case CLASS_TYPE_CDC: + /* Setup default Max packet size for FS device */ + pdev->tclasslist[pdev->classId].CurrPcktSze = CDC_DATA_FS_MAX_PACKET_SIZE; + + /* Find the first available interface slot and Assign number of interfaces */ + idxIf = USBD_CMPSIT_FindFreeIFNbr(pdev); + pdev->tclasslist[pdev->classId].NumIf = 2U; + pdev->tclasslist[pdev->classId].Ifs[0] = idxIf; + pdev->tclasslist[pdev->classId].Ifs[1] = (uint8_t)(idxIf + 1U); + + /* Assign endpoint numbers */ + pdev->tclasslist[pdev->classId].NumEps = 3U; + + /* Set IN endpoint slot */ + iEp = pdev->tclasslist[pdev->classId].EpAdd[0]; + USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze); + + /* Set OUT endpoint slot */ + iEp = pdev->tclasslist[pdev->classId].EpAdd[1]; + USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze); + + /* Set the second IN endpoint slot */ + iEp = pdev->tclasslist[pdev->classId].EpAdd[2]; + USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_INTR, CDC_CMD_PACKET_SIZE); + + /* Configure and Append the Descriptor */ + USBD_CMPSIT_CDCDesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL); + +#ifdef USE_USB_HS + USBD_CMPSIT_CDCDesc(pdev, (uint32_t)pCmpstHSConfDesc, &CurrHSConfDescSz, (uint8_t)USBD_SPEED_HIGH); +#endif /* USE_USB_HS */ + + break; +#endif /* USBD_CMPSIT_ACTIVATE_CDC */ + +#if USBD_CMPSIT_ACTIVATE_DFU == 1 + case CLASS_TYPE_DFU: + /* Setup Max packet sizes (for DFU, no dependency on USB Speed, both HS/FS have same packet size) */ + pdev->tclasslist[pdev->classId].CurrPcktSze = 64U; + + /* Find the first available interface slot and Assign number of interfaces */ + idxIf = USBD_CMPSIT_FindFreeIFNbr(pdev); + pdev->tclasslist[pdev->classId].NumIf = 1U; + pdev->tclasslist[pdev->classId].Ifs[0] = idxIf; + + /* Assign endpoint numbers */ + pdev->tclasslist[pdev->classId].NumEps = 0U; /* only EP0 is used */ + + /* Configure and Append the Descriptor */ + USBD_CMPSIT_DFUDesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL); + +#ifdef USE_USB_HS + USBD_CMPSIT_DFUDesc(pdev, (uint32_t)pCmpstHSConfDesc, &CurrHSConfDescSz, (uint8_t)USBD_SPEED_HIGH); +#endif /* USE_USB_HS */ + + break; +#endif /* USBD_CMPSIT_ACTIVATE_DFU */ + +#if USBD_CMPSIT_ACTIVATE_RNDIS == 1 + case CLASS_TYPE_RNDIS: + /* Setup default Max packet size */ + pdev->tclasslist[pdev->classId].CurrPcktSze = CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE; + + /* Find the first available interface slot and Assign number of interfaces */ + idxIf = USBD_CMPSIT_FindFreeIFNbr(pdev); + pdev->tclasslist[pdev->classId].NumIf = 2U; + pdev->tclasslist[pdev->classId].Ifs[0] = idxIf; + pdev->tclasslist[pdev->classId].Ifs[1] = (uint8_t)(idxIf + 1U); + + /* Assign endpoint numbers */ + pdev->tclasslist[pdev->classId].NumEps = 3U; + + /* Set IN endpoint slot */ + iEp = pdev->tclasslist[pdev->classId].EpAdd[0]; + USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze); + + /* Set OUT endpoint slot */ + iEp = pdev->tclasslist[pdev->classId].EpAdd[1]; + USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze); + + /* Set the second IN endpoint slot */ + iEp = pdev->tclasslist[pdev->classId].EpAdd[2]; + USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_INTR, CDC_RNDIS_CMD_PACKET_SIZE); + + /* Configure and Append the Descriptor */ + USBD_CMPSIT_RNDISDesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL); + +#ifdef USE_USB_HS + USBD_CMPSIT_RNDISDesc(pdev, (uint32_t)pCmpstHSConfDesc, &CurrHSConfDescSz, (uint8_t)USBD_SPEED_HIGH); +#endif /* USE_USB_HS */ + + break; +#endif /* USBD_CMPSIT_ACTIVATE_RNDIS */ + +#if USBD_CMPSIT_ACTIVATE_CDC_ECM == 1 + case CLASS_TYPE_ECM: + /* Setup default Max packet size */ + pdev->tclasslist[pdev->classId].CurrPcktSze = CDC_ECM_DATA_FS_MAX_PACKET_SIZE; + + /* Find the first available interface slot and Assign number of interfaces */ + idxIf = USBD_CMPSIT_FindFreeIFNbr(pdev); + pdev->tclasslist[pdev->classId].NumIf = 2U; + pdev->tclasslist[pdev->classId].Ifs[0] = idxIf; + pdev->tclasslist[pdev->classId].Ifs[1] = (uint8_t)(idxIf + 1U); + + /* Assign endpoint numbers */ + pdev->tclasslist[pdev->classId].NumEps = 3U; /* EP1_IN, EP1_OUT,CMD_EP2 */ + + /* Set IN endpoint slot */ + iEp = pdev->tclasslist[pdev->classId].EpAdd[0]; + USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze); + + /* Set OUT endpoint slot */ + iEp = pdev->tclasslist[pdev->classId].EpAdd[1]; + USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze); + + /* Set the second IN endpoint slot */ + iEp = pdev->tclasslist[pdev->classId].EpAdd[2]; + USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_INTR, CDC_ECM_CMD_PACKET_SIZE); + + /* Configure and Append the Descriptor */ + USBD_CMPSIT_CDC_ECMDesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL); + +#ifdef USE_USB_HS + USBD_CMPSIT_CDC_ECMDesc(pdev, (uint32_t)pCmpstHSConfDesc, &CurrHSConfDescSz, (uint8_t)USBD_SPEED_HIGH); +#endif /* USE_USB_HS */ + + break; +#endif /* USBD_CMPSIT_ACTIVATE_CDC_ECM */ + +#if USBD_CMPSIT_ACTIVATE_AUDIO == 1 + case CLASS_TYPE_AUDIO: + /* Setup Max packet sizes*/ + pdev->tclasslist[pdev->classId].CurrPcktSze = USBD_AUDIO_GetEpPcktSze(pdev, 0U, 0U); + + /* Find the first available interface slot and Assign number of interfaces */ + idxIf = USBD_CMPSIT_FindFreeIFNbr(pdev); + pdev->tclasslist[pdev->classId].NumIf = 2U; + pdev->tclasslist[pdev->classId].Ifs[0] = idxIf; + pdev->tclasslist[pdev->classId].Ifs[1] = (uint8_t)(idxIf + 1U); + + /* Assign endpoint numbers */ + pdev->tclasslist[pdev->classId].NumEps = 1U; /* EP1_OUT*/ + + /* Set OUT endpoint slot */ + iEp = pdev->tclasslist[pdev->classId].EpAdd[0]; + + /* Assign OUT Endpoint */ + USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_ISOC, pdev->tclasslist[pdev->classId].CurrPcktSze); + + /* Configure and Append the Descriptor (only FS mode supported) */ + USBD_CMPSIT_AUDIODesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL); + + break; +#endif /* USBD_CMPSIT_ACTIVATE_AUDIO */ + +#if USBD_CMPSIT_ACTIVATE_CUSTOMHID == 1 + case CLASS_TYPE_CHID: + /* Setup Max packet sizes */ + pdev->tclasslist[pdev->classId].CurrPcktSze = CUSTOM_HID_EPOUT_SIZE; + + /* Find the first available interface slot and Assign number of interfaces */ + idxIf = USBD_CMPSIT_FindFreeIFNbr(pdev); + pdev->tclasslist[pdev->classId].NumIf = 1U; + pdev->tclasslist[pdev->classId].Ifs[0] = idxIf; + + /* Assign endpoint numbers */ + pdev->tclasslist[pdev->classId].NumEps = 2U; /* EP1_IN, EP1_OUT */ + + /* Set IN endpoint slot */ + iEp = pdev->tclasslist[pdev->classId].EpAdd[0]; + USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_INTR, pdev->tclasslist[pdev->classId].CurrPcktSze); + + /* Set OUT endpoint slot */ + iEp = pdev->tclasslist[pdev->classId].EpAdd[1]; + USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_INTR, pdev->tclasslist[pdev->classId].CurrPcktSze); + + /* Configure and Append the Descriptor */ + USBD_CMPSIT_CUSTOMHIDDesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL); + +#ifdef USE_USB_HS + USBD_CMPSIT_CUSTOMHIDDesc(pdev, (uint32_t)pCmpstHSConfDesc, &CurrHSConfDescSz, (uint8_t)USBD_SPEED_HIGH); +#endif /* USE_USB_HS */ + + break; +#endif /* USBD_CMPSIT_ACTIVATE_CUSTOMHID */ + +#if USBD_CMPSIT_ACTIVATE_VIDEO == 1 + case CLASS_TYPE_VIDEO: + /* Setup default Max packet size */ + pdev->tclasslist[pdev->classId].CurrPcktSze = UVC_ISO_FS_MPS; + + /* Find the first available interface slot and Assign number of interfaces */ + idxIf = USBD_CMPSIT_FindFreeIFNbr(pdev); + pdev->tclasslist[pdev->classId].NumIf = 2U; + pdev->tclasslist[pdev->classId].Ifs[0] = idxIf; + pdev->tclasslist[pdev->classId].Ifs[1] = (uint8_t)(idxIf + 1U); + + /* Assign endpoint numbers */ + pdev->tclasslist[pdev->classId].NumEps = 1U; /* EP1_IN */ + + /* Set IN endpoint slot */ + iEp = pdev->tclasslist[pdev->classId].EpAdd[0]; + + /* Assign IN Endpoint */ + USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_ISOC, pdev->tclasslist[pdev->classId].CurrPcktSze); + + /* Configure and Append the Descriptor */ + USBD_CMPSIT_VIDEODesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL); + +#ifdef USE_USB_HS + USBD_CMPSIT_VIDEODesc(pdev, (uint32_t)pCmpstHSConfDesc, &CurrHSConfDescSz, (uint8_t)USBD_SPEED_HIGH); +#endif /* USE_USB_HS */ + + break; +#endif /* USBD_CMPSIT_ACTIVATE_VIDEO */ + +#if USBD_CMPSIT_ACTIVATE_PRINTER == 1 + case CLASS_TYPE_PRINTER: + + /* Setup default Max packet size */ + pdev->tclasslist[pdev->classId].CurrPcktSze = PRNT_DATA_FS_MAX_PACKET_SIZE; + + /* Find the first available interface slot and Assign number of interfaces */ + idxIf = USBD_CMPSIT_FindFreeIFNbr(pdev); + pdev->tclasslist[pdev->classId].NumIf = 1U; + pdev->tclasslist[pdev->classId].Ifs[0] = idxIf; + + /* Assign endpoint numbers */ + pdev->tclasslist[pdev->classId].NumEps = 2U; + + /* Set IN endpoint slot */ + iEp = pdev->tclasslist[pdev->classId].EpAdd[0]; + USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze); + + /* Set OUT endpoint slot */ + iEp = pdev->tclasslist[pdev->classId].EpAdd[1]; + USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze); + + /* Configure and Append the Descriptor */ + USBD_CMPSIT_PRNTDesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL); + +#ifdef USE_USB_HS + USBD_CMPSIT_PRNTDesc(pdev, (uint32_t)pCmpstHSConfDesc, &CurrHSConfDescSz, (uint8_t)USBD_SPEED_HIGH); +#endif /* USE_USB_HS */ + + break; +#endif /* USBD_CMPSIT_ACTIVATE_PRINTER */ + +#if USBD_CMPSIT_ACTIVATE_CCID == 1 + + case CLASS_TYPE_CCID: + /* Setup default Max packet size */ + pdev->tclasslist[pdev->classId].CurrPcktSze = CCID_DATA_FS_MAX_PACKET_SIZE; + + /* Find the first available interface slot and Assign number of interfaces */ + idxIf = USBD_CMPSIT_FindFreeIFNbr(pdev); + pdev->tclasslist[pdev->classId].NumIf = 1U; + pdev->tclasslist[pdev->classId].Ifs[0] = idxIf; + + /* Assign endpoint numbers */ + pdev->tclasslist[pdev->classId].NumEps = 3U; + + /* Set IN endpoint slot */ + iEp = pdev->tclasslist[pdev->classId].EpAdd[0]; + USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze); + + /* Set OUT endpoint slot */ + iEp = pdev->tclasslist[pdev->classId].EpAdd[1]; + USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze); + + /* Set the second IN endpoint slot */ + iEp = pdev->tclasslist[pdev->classId].EpAdd[2]; + USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_INTR, CCID_CMD_PACKET_SIZE); + + /* Configure and Append the Descriptor */ + USBD_CMPSIT_CCIDDesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL); + +#ifdef USE_USB_HS + USBD_CMPSIT_CCIDDesc(pdev, (uint32_t)pCmpstHSConfDesc, &CurrHSConfDescSz, (uint8_t)USBD_SPEED_HIGH); +#endif /* USE_USB_HS */ + + break; +#endif /* USBD_CMPSIT_ACTIVATE_CCID */ + +#if USBD_CMPSIT_ACTIVATE_MTP == 1 + + case CLASS_TYPE_MTP: + /* Setup default Max packet sizes */ + pdev->tclasslist[pdev->classId].CurrPcktSze = MTP_DATA_MAX_FS_PACKET_SIZE; + + /* Find the first available interface slot and Assign number of interfaces */ + idxIf = USBD_CMPSIT_FindFreeIFNbr(pdev); + pdev->tclasslist[pdev->classId].NumIf = 1U; + pdev->tclasslist[pdev->classId].Ifs[0] = idxIf; + + /* Assign endpoint numbers */ + pdev->tclasslist[pdev->classId].NumEps = 3U; + + /* Set IN endpoint slot */ + iEp = pdev->tclasslist[pdev->classId].EpAdd[0]; + USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze); + + /* Set OUT endpoint slot */ + iEp = pdev->tclasslist[pdev->classId].EpAdd[1]; + USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze); + + /* Set the second IN endpoint slot */ + iEp = pdev->tclasslist[pdev->classId].EpAdd[2]; + USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_INTR, MTP_CMD_PACKET_SIZE); + + /* Configure and Append the Descriptor */ + USBD_CMPSIT_MTPDesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL); + +#ifdef USE_USB_HS + USBD_CMPSIT_MTPDesc(pdev, (uint32_t)pCmpstHSConfDesc, &CurrHSConfDescSz, (uint8_t)USBD_SPEED_HIGH); +#endif /* USE_USB_HS */ + + break; +#endif /* USBD_CMPSIT_ACTIVATE_MTP */ + + default: + UNUSED(idxIf); + UNUSED(iEp); + UNUSED(USBD_CMPSIT_FindFreeIFNbr); + UNUSED(USBD_CMPSIT_AssignEp); + break; + } + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_CMPSIT_GetFSCfgDesc + * return configuration descriptor for both FS and HS modes + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +uint8_t *USBD_CMPSIT_GetFSCfgDesc(uint16_t *length) +{ + *length = (uint16_t)CurrFSConfDescSz; + + return USBD_CMPSIT_FSCfgDesc; +} + +#ifdef USE_USB_HS +/** + * @brief USBD_CMPSIT_GetHSCfgDesc + * return configuration descriptor for both FS and HS modes + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +uint8_t *USBD_CMPSIT_GetHSCfgDesc(uint16_t *length) +{ + *length = (uint16_t)CurrHSConfDescSz; + + return USBD_CMPSIT_HSCfgDesc; +} +#endif /* USE_USB_HS */ + +/** + * @brief USBD_CMPSIT_GetOtherSpeedCfgDesc + * return other speed configuration descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +uint8_t *USBD_CMPSIT_GetOtherSpeedCfgDesc(uint16_t *length) +{ + *length = (uint16_t)CurrFSConfDescSz; + + return USBD_CMPSIT_FSCfgDesc; +} + +/** + * @brief DeviceQualifierDescriptor + * return Device Qualifier descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +uint8_t *USBD_CMPSIT_GetDeviceQualifierDescriptor(uint16_t *length) +{ + *length = (uint16_t)(sizeof(USBD_CMPSIT_DeviceQualifierDesc)); + return USBD_CMPSIT_DeviceQualifierDesc; +} + +/** + * @brief USBD_CMPSIT_FindFreeIFNbr + * Find the first interface available slot + * @param pdev: device instance + * @retval The interface number to be used + */ +static uint8_t USBD_CMPSIT_FindFreeIFNbr(USBD_HandleTypeDef *pdev) +{ + uint32_t idx = 0U; + + /* Unroll all already activated classes */ + for (uint32_t i = 0U; i < pdev->NumClasses; i++) + { + /* Unroll each class interfaces */ + for (uint32_t j = 0U; j < pdev->tclasslist[i].NumIf; j++) + { + /* Increment the interface counter index */ + idx++; + } + } + + /* Return the first available interface slot */ + return (uint8_t)idx; +} + +/** + * @brief USBD_CMPSIT_AddToConfDesc + * Add a new class to the configuration descriptor + * @param pdev: device instance + * @retval none + */ +static void USBD_CMPSIT_AddConfDesc(uint32_t Conf, __IO uint32_t *pSze) +{ + /* Intermediate variable to comply with MISRA-C Rule 11.3 */ + USBD_ConfigDescTypeDef *ptr = (USBD_ConfigDescTypeDef *)Conf; + + ptr->bLength = (uint8_t)sizeof(USBD_ConfigDescTypeDef); + ptr->bDescriptorType = USB_DESC_TYPE_CONFIGURATION; + ptr->wTotalLength = 0U; + ptr->bNumInterfaces = 0U; + ptr->bConfigurationValue = 1U; + ptr->iConfiguration = USBD_CONFIG_STR_DESC_IDX; + +#if (USBD_SELF_POWERED == 1U) + ptr->bmAttributes = 0xC0U; /* bmAttributes: Self Powered according to user configuration */ +#else + ptr->bmAttributes = 0x80U; /* bmAttributes: Bus Powered according to user configuration */ +#endif /* USBD_SELF_POWERED */ + + ptr->bMaxPower = USBD_MAX_POWER; + + *pSze += sizeof(USBD_ConfigDescTypeDef); +} + +/** + * @brief USBD_CMPSIT_AssignEp + * Assign and endpoint + * @param pdev: device instance + * @param Add: Endpoint address + * @param Type: Endpoint type + * @param Sze: Endpoint max packet size + * @retval none + */ +static void USBD_CMPSIT_AssignEp(USBD_HandleTypeDef *pdev, uint8_t Add, uint8_t Type, uint32_t Sze) +{ + uint32_t idx = 0U; + + /* Find the first available endpoint slot */ + while (((idx < (pdev->tclasslist[pdev->classId]).NumEps) && \ + ((pdev->tclasslist[pdev->classId].Eps[idx].is_used) != 0U))) + { + /* Increment the index */ + idx++; + } + + /* Configure the endpoint */ + pdev->tclasslist[pdev->classId].Eps[idx].add = Add; + pdev->tclasslist[pdev->classId].Eps[idx].type = Type; + pdev->tclasslist[pdev->classId].Eps[idx].size = (uint8_t)Sze; + pdev->tclasslist[pdev->classId].Eps[idx].is_used = 1U; +} + +#if USBD_CMPSIT_ACTIVATE_HID == 1 +/** + * @brief USBD_CMPSIT_HIDMouseDesc + * Configure and Append the HID Mouse Descriptor + * @param pdev: device instance + * @param pConf: Configuration descriptor pointer + * @param Sze: pointer to the current configuration descriptor size + * @retval None + */ +static void USBD_CMPSIT_HIDMouseDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, + __IO uint32_t *Sze, uint8_t speed) +{ + static USBD_IfDescTypeDef *pIfDesc; + static USBD_EpDescTypeDef *pEpDesc; + static USBD_HIDDescTypeDef *pHidMouseDesc; + + /* Append HID Interface descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[0], 0U, \ + (uint8_t)(pdev->tclasslist[pdev->classId].NumEps), 0x03U, 0x01U, 0x02U, 0U); + + /* Append HID Functional descriptor to Configuration descriptor */ + pHidMouseDesc = ((USBD_HIDDescTypeDef *)(pConf + *Sze)); + pHidMouseDesc->bLength = (uint8_t)sizeof(USBD_HIDDescTypeDef); + pHidMouseDesc->bDescriptorType = HID_DESCRIPTOR_TYPE; + pHidMouseDesc->bcdHID = 0x0111U; + pHidMouseDesc->bCountryCode = 0x00U; + pHidMouseDesc->bNumDescriptors = 0x01U; + pHidMouseDesc->bHIDDescriptorType = 0x22U; + pHidMouseDesc->wItemLength = HID_MOUSE_REPORT_DESC_SIZE; + *Sze += (uint32_t)sizeof(USBD_HIDDescTypeDef); + + /* Append Endpoint descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_EP(pdev->tclasslist[pdev->classId].Eps[0].add, USBD_EP_TYPE_INTR, HID_EPIN_SIZE, \ + HID_HS_BINTERVAL, HID_FS_BINTERVAL); + + /* Update Config Descriptor and IAD descriptor */ + ((USBD_ConfigDescTypeDef *)pConf)->bNumInterfaces += 1U; + ((USBD_ConfigDescTypeDef *)pConf)->wTotalLength = *Sze; +} +#endif /* USBD_CMPSIT_ACTIVATE_HID == 1 */ + +#if USBD_CMPSIT_ACTIVATE_MSC == 1 +/** + * @brief USBD_CMPSIT_MSCDesc + * Configure and Append the MSC Descriptor + * @param pdev: device instance + * @param pConf: Configuration descriptor pointer + * @param Sze: pointer to the current configuration descriptor size + * @retval None + */ +static void USBD_CMPSIT_MSCDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed) +{ + USBD_IfDescTypeDef *pIfDesc; + USBD_EpDescTypeDef *pEpDesc; + + /* Append MSC Interface descriptor */ + __USBD_CMPSIT_SET_IF((pdev->tclasslist[pdev->classId].Ifs[0]), (0U), \ + (uint8_t)(pdev->tclasslist[pdev->classId].NumEps), (0x08U), (0x06U), (0x50U), (0U)); + + if (speed == (uint8_t)USBD_SPEED_HIGH) + { + pdev->tclasslist[pdev->classId].CurrPcktSze = MSC_MAX_HS_PACKET; + } + + /* Append Endpoint descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[0].add), (USBD_EP_TYPE_BULK), \ + (pdev->tclasslist[pdev->classId].CurrPcktSze), (0U), (0U)); + + /* Append Endpoint descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[1].add), (USBD_EP_TYPE_BULK), \ + (pdev->tclasslist[pdev->classId].CurrPcktSze), (0U), (0U)); + + /* Update Config Descriptor and IAD descriptor */ + ((USBD_ConfigDescTypeDef *)pConf)->bNumInterfaces += 1U; + ((USBD_ConfigDescTypeDef *)pConf)->wTotalLength = *Sze; +} +#endif /* USBD_CMPSIT_ACTIVATE_MSC == 1 */ + +#if USBD_CMPSIT_ACTIVATE_CDC == 1 +/** + * @brief USBD_CMPSIT_MSCDesc + * Configure and Append the HID Mouse Descriptor + * @param pdev: device instance + * @param pConf: Configuration descriptor pointer + * @param Sze: pointer to the current configuration descriptor size + * @retval None + */ +static void USBD_CMPSIT_CDCDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed) +{ + static USBD_IfDescTypeDef *pIfDesc; + static USBD_EpDescTypeDef *pEpDesc; + static USBD_CDCHeaderFuncDescTypeDef *pHeadDesc; + static USBD_CDCCallMgmFuncDescTypeDef *pCallMgmDesc; + static USBD_CDCACMFuncDescTypeDef *pACMDesc; + static USBD_CDCUnionFuncDescTypeDef *pUnionDesc; +#if USBD_COMPOSITE_USE_IAD == 1 + static USBD_IadDescTypeDef *pIadDesc; +#endif /* USBD_COMPOSITE_USE_IAD == 1 */ + +#if USBD_COMPOSITE_USE_IAD == 1 + pIadDesc = ((USBD_IadDescTypeDef *)(pConf + *Sze)); + pIadDesc->bLength = (uint8_t)sizeof(USBD_IadDescTypeDef); + pIadDesc->bDescriptorType = USB_DESC_TYPE_IAD; /* IAD descriptor */ + pIadDesc->bFirstInterface = pdev->tclasslist[pdev->classId].Ifs[0]; + pIadDesc->bInterfaceCount = 2U; /* 2 interfaces */ + pIadDesc->bFunctionClass = 0x02U; + pIadDesc->bFunctionSubClass = 0x02U; + pIadDesc->bFunctionProtocol = 0x01U; + pIadDesc->iFunction = 0U; /* String Index */ + *Sze += (uint32_t)sizeof(USBD_IadDescTypeDef); +#endif /* USBD_COMPOSITE_USE_IAD == 1 */ + + /* Control Interface Descriptor */ + __USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[0], 0U, 1U, 0x02, 0x02U, 0x01U, 0U); + + /* Control interface headers */ + pHeadDesc = ((USBD_CDCHeaderFuncDescTypeDef *)((uint32_t)pConf + *Sze)); + /* Header Functional Descriptor*/ + pHeadDesc->bLength = 0x05U; + pHeadDesc->bDescriptorType = 0x24U; + pHeadDesc->bDescriptorSubtype = 0x00U; + pHeadDesc->bcdCDC = 0x0110U; + *Sze += (uint32_t)sizeof(USBD_CDCHeaderFuncDescTypeDef); + + /* Call Management Functional Descriptor */ + pCallMgmDesc = ((USBD_CDCCallMgmFuncDescTypeDef *)((uint32_t)pConf + *Sze)); + pCallMgmDesc->bLength = 0x05U; + pCallMgmDesc->bDescriptorType = 0x24U; + pCallMgmDesc->bDescriptorSubtype = 0x01U; + pCallMgmDesc->bmCapabilities = 0x00U; + pCallMgmDesc->bDataInterface = pdev->tclasslist[pdev->classId].Ifs[1]; + *Sze += (uint32_t)sizeof(USBD_CDCCallMgmFuncDescTypeDef); + + /* ACM Functional Descriptor*/ + pACMDesc = ((USBD_CDCACMFuncDescTypeDef *)((uint32_t)pConf + *Sze)); + pACMDesc->bLength = 0x04U; + pACMDesc->bDescriptorType = 0x24U; + pACMDesc->bDescriptorSubtype = 0x02U; + pACMDesc->bmCapabilities = 0x02U; + *Sze += (uint32_t)sizeof(USBD_CDCACMFuncDescTypeDef); + + /* Union Functional Descriptor*/ + pUnionDesc = ((USBD_CDCUnionFuncDescTypeDef *)((uint32_t)pConf + *Sze)); + pUnionDesc->bLength = 0x05U; + pUnionDesc->bDescriptorType = 0x24U; + pUnionDesc->bDescriptorSubtype = 0x06U; + pUnionDesc->bMasterInterface = pdev->tclasslist[pdev->classId].Ifs[0]; + pUnionDesc->bSlaveInterface = pdev->tclasslist[pdev->classId].Ifs[1]; + *Sze += (uint32_t)sizeof(USBD_CDCUnionFuncDescTypeDef); + + /* Append Endpoint descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_EP(pdev->tclasslist[pdev->classId].Eps[2].add, \ + USBD_EP_TYPE_INTR, CDC_CMD_PACKET_SIZE, CDC_HS_BINTERVAL, CDC_FS_BINTERVAL); + + /* Data Interface Descriptor */ + __USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[1], 0U, 2U, 0x0A, 0U, 0U, 0U); + + if (speed == (uint8_t)USBD_SPEED_HIGH) + { + pdev->tclasslist[pdev->classId].CurrPcktSze = CDC_DATA_HS_MAX_PACKET_SIZE; + } + + /* Append Endpoint descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[0].add), \ + (USBD_EP_TYPE_BULK), (pdev->tclasslist[pdev->classId].CurrPcktSze), (0U), (0U)); + + /* Append Endpoint descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[1].add), \ + (USBD_EP_TYPE_BULK), (pdev->tclasslist[pdev->classId].CurrPcktSze), (0U), (0U)); + + /* Update Config Descriptor and IAD descriptor */ + ((USBD_ConfigDescTypeDef *)pConf)->bNumInterfaces += 2U; + ((USBD_ConfigDescTypeDef *)pConf)->wTotalLength = *Sze; +} +#endif /* USBD_CMPSIT_ACTIVATE_CDC == 1 */ + +#if USBD_CMPSIT_ACTIVATE_DFU == 1 +/** + * @brief USBD_CMPSIT_DFUDesc + * Configure and Append the DFU Descriptor + * @param pdev: device instance + * @param pConf: Configuration descriptor pointer + * @param Sze: pointer to the current configuration descriptor size + * @retval None + */ +static void USBD_CMPSIT_DFUDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed) +{ + static USBD_IfDescTypeDef *pIfDesc; + static USBD_DFUFuncDescTypeDef *pDFUFuncDesc; + uint32_t idx; + UNUSED(speed); + + for (idx = 0U; idx < USBD_DFU_MAX_ITF_NUM; idx++) + { + /* Append DFU Interface descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[0], (uint8_t)idx, 0U, 0xFEU, 0x01U, 0x02U, \ + (uint8_t)USBD_IDX_INTERFACE_STR + 1U + (uint8_t)idx); + } + + /* Append DFU Functional descriptor to Configuration descriptor */ + pDFUFuncDesc = ((USBD_DFUFuncDescTypeDef *)(pConf + *Sze)); + pDFUFuncDesc->bLength = (uint8_t)sizeof(USBD_DFUFuncDescTypeDef); + pDFUFuncDesc->bDescriptorType = DFU_DESCRIPTOR_TYPE; + pDFUFuncDesc->bmAttributes = USBD_DFU_BM_ATTRIBUTES; + pDFUFuncDesc->wDetachTimeout = USBD_DFU_DETACH_TIMEOUT; + pDFUFuncDesc->wTransferSze = USBD_DFU_XFER_SIZE; + pDFUFuncDesc->bcdDFUVersion = 0x011AU; + *Sze += (uint32_t)sizeof(USBD_DFUFuncDescTypeDef); + + /* Update Config Descriptor and IAD descriptor */ + ((USBD_ConfigDescTypeDef *)pConf)->bNumInterfaces += 1U; + ((USBD_ConfigDescTypeDef *)pConf)->wTotalLength = *Sze; + + UNUSED(idx); +} +#endif /* USBD_CMPSIT_ACTIVATE_DFU == 1 */ + +#if USBD_CMPSIT_ACTIVATE_CDC_ECM == 1 +/** + * @brief USBD_CMPSIT_CDC_ECMDesc + * Configure and Append the CDC_ECM Descriptor + * @param pdev: device instance + * @param pConf: Configuration descriptor pointer + * @param Sze: pointer to the current configuration descriptor size + * @retval None + */ +static void USBD_CMPSIT_CDC_ECMDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed) +{ + static USBD_IfDescTypeDef *pIfDesc; + static USBD_EpDescTypeDef *pEpDesc; + static USBD_ECMFuncDescTypeDef *pFuncDesc; + static USBD_IadDescTypeDef *pIadDesc; + + static USBD_CDCHeaderFuncDescTypeDef *pHeadDesc; + static USBD_CDCUnionFuncDescTypeDef *pUnionDesc; + +#if USBD_COMPOSITE_USE_IAD == 1 + pIadDesc = ((USBD_IadDescTypeDef *)(pConf + *Sze)); + pIadDesc->bLength = (uint8_t)sizeof(USBD_IadDescTypeDef); + pIadDesc->bDescriptorType = USB_DESC_TYPE_IAD; /* IAD descriptor */ + pIadDesc->bFirstInterface = pdev->tclasslist[pdev->classId].Ifs[0]; + pIadDesc->bInterfaceCount = 2U; /* 2 interfaces */ + pIadDesc->bFunctionClass = 0x02U; + pIadDesc->bFunctionSubClass = 0x06U; + pIadDesc->bFunctionProtocol = 0x00U; + pIadDesc->iFunction = 0U; /* String Index */ + *Sze += (uint32_t)sizeof(USBD_IadDescTypeDef); +#endif /* USBD_COMPOSITE_USE_IAD == 1 */ + + /* Append ECM Interface descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[0], 0U, 1U, 0x02U, 0x06U, 0U, 0U); + + /* Append ECM header functional descriptor to Configuration descriptor */ + pHeadDesc = ((USBD_CDCHeaderFuncDescTypeDef *)(pConf + *Sze)); + pHeadDesc->bLength = (uint8_t)sizeof(USBD_CDCHeaderFuncDescTypeDef); + pHeadDesc->bDescriptorType = USBD_FUNC_DESCRIPTOR_TYPE; + pHeadDesc->bDescriptorSubtype = 0x00U; + pHeadDesc->bcdCDC = 0x1000U; + *Sze += (uint32_t)sizeof(USBD_CDCHeaderFuncDescTypeDef); + + /* Append ECM functional descriptor to Configuration descriptor */ + pFuncDesc = ((USBD_ECMFuncDescTypeDef *)(pConf + *Sze)); + pFuncDesc->bFunctionLength = (uint8_t)sizeof(USBD_ECMFuncDescTypeDef); + pFuncDesc->bDescriptorType = USBD_FUNC_DESCRIPTOR_TYPE; + pFuncDesc->bDescriptorSubType = USBD_DESC_SUBTYPE_ACM; + pFuncDesc->iMacAddress = CDC_ECM_MAC_STRING_INDEX; + pFuncDesc->bEthernetStatistics3 = CDC_ECM_ETH_STATS_BYTE3; + pFuncDesc->bEthernetStatistics2 = CDC_ECM_ETH_STATS_BYTE2; + pFuncDesc->bEthernetStatistics1 = CDC_ECM_ETH_STATS_BYTE1; + pFuncDesc->bEthernetStatistics0 = CDC_ECM_ETH_STATS_BYTE0; + pFuncDesc->wMaxSegmentSize = CDC_ECM_ETH_MAX_SEGSZE; + pFuncDesc->bNumberMCFiltes = CDC_ECM_ETH_NBR_MACFILTERS; + pFuncDesc->bNumberPowerFiltes = CDC_ECM_ETH_NBR_PWRFILTERS; + *Sze += (uint32_t)sizeof(USBD_ECMFuncDescTypeDef); + + /* Append ECM Union functional descriptor to Configuration descriptor */ + pUnionDesc = ((USBD_CDCUnionFuncDescTypeDef *)(pConf + *Sze)); + pUnionDesc->bLength = (uint8_t)sizeof(USBD_CDCUnionFuncDescTypeDef); + pUnionDesc->bDescriptorType = 0x24U; + pUnionDesc->bDescriptorSubtype = 0x06U; + pUnionDesc->bMasterInterface = pdev->tclasslist[pdev->classId].Ifs[0]; + pUnionDesc->bSlaveInterface = pdev->tclasslist[pdev->classId].Ifs[1]; + *Sze += (uint32_t)sizeof(USBD_CDCUnionFuncDescTypeDef); + + /* Append ECM Communication IN Endpoint Descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_EP(pdev->tclasslist[pdev->classId].Eps[2].add, USBD_EP_TYPE_INTR, CDC_ECM_CMD_PACKET_SIZE, \ + CDC_ECM_HS_BINTERVAL, CDC_ECM_FS_BINTERVAL); + + /* Append ECM Data class interface descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[1], 0U, 2U, 0x0AU, 0U, 0U, 0U); + + if (speed == (uint8_t)USBD_SPEED_HIGH) + { + pdev->tclasslist[pdev->classId].CurrPcktSze = CDC_ECM_DATA_HS_MAX_PACKET_SIZE; + } + + /* Append ECM OUT Endpoint Descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[0].add), (USBD_EP_TYPE_BULK), \ + (pdev->tclasslist[pdev->classId].CurrPcktSze), (CDC_ECM_HS_BINTERVAL), (CDC_ECM_FS_BINTERVAL)); + + /* Append ECM IN Endpoint Descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[1].add), (USBD_EP_TYPE_BULK), \ + (pdev->tclasslist[pdev->classId].CurrPcktSze), (CDC_ECM_HS_BINTERVAL), (CDC_ECM_FS_BINTERVAL)); + + /* Update Config Descriptor and IAD descriptor */ + ((USBD_ConfigDescTypeDef *)pConf)->bNumInterfaces += 2U; + ((USBD_ConfigDescTypeDef *)pConf)->wTotalLength = *Sze; +} +#endif /* USBD_CMPSIT_ACTIVATE_CDC_ECM */ + +#if USBD_CMPSIT_ACTIVATE_AUDIO == 1 +/** + * @brief USBD_CMPSIT_AUDIODesc + * Configure and Append the AUDIO Descriptor + * @param pdev: device instance + * @param pConf: Configuration descriptor pointer + * @param Sze: pointer to the current configuration descriptor size + * @retval None + */ +static void USBD_CMPSIT_AUDIODesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed) +{ + static USBD_IfDescTypeDef *pIfDesc; + static USBD_IadDescTypeDef *pIadDesc; + UNUSED(speed); + + /* Append AUDIO Interface descriptor to Configuration descriptor */ + USBD_SpeakerIfDescTypeDef *pSpIfDesc; + USBD_SpeakerInDescTypeDef *pSpInDesc; + USBD_SpeakerFeatureDescTypeDef *pSpFDesc; + USBD_SpeakerOutDescTypeDef *pSpOutDesc; + USBD_SpeakerStreamIfDescTypeDef *pSpStrDesc; + USBD_SpeakerIIIFormatIfDescTypeDef *pSpIIIDesc; + USBD_SpeakerEndDescTypeDef *pSpEpDesc; + USBD_SpeakerEndStDescTypeDef *pSpEpStDesc; + +#if USBD_COMPOSITE_USE_IAD == 1 + pIadDesc = ((USBD_IadDescTypeDef *)(pConf + *Sze)); + pIadDesc->bLength = (uint8_t)sizeof(USBD_IadDescTypeDef); + pIadDesc->bDescriptorType = USB_DESC_TYPE_IAD; /* IAD descriptor */ + pIadDesc->bFirstInterface = pdev->tclasslist[pdev->classId].Ifs[0]; + pIadDesc->bInterfaceCount = 2U; /* 2 interfaces */ + pIadDesc->bFunctionClass = USB_DEVICE_CLASS_AUDIO; + pIadDesc->bFunctionSubClass = AUDIO_SUBCLASS_AUDIOCONTROL; + pIadDesc->bFunctionProtocol = AUDIO_PROTOCOL_UNDEFINED; + pIadDesc->iFunction = 0U; /* String Index */ + *Sze += (uint32_t)sizeof(USBD_IadDescTypeDef); +#endif /* USBD_COMPOSITE_USE_IAD == 1 */ + + /* Append AUDIO Interface descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[0], 0U, 0U, USB_DEVICE_CLASS_AUDIO, \ + AUDIO_SUBCLASS_AUDIOCONTROL, AUDIO_PROTOCOL_UNDEFINED, 0U); + + /* Append AUDIO USB Speaker Class-specific AC Interface descriptor to Configuration descriptor */ + pSpIfDesc = ((USBD_SpeakerIfDescTypeDef *)(pConf + *Sze)); + pSpIfDesc->bLength = (uint8_t)sizeof(USBD_IfDescTypeDef); + pSpIfDesc->bDescriptorType = AUDIO_INTERFACE_DESCRIPTOR_TYPE; + pSpIfDesc->bDescriptorSubtype = AUDIO_CONTROL_HEADER; + pSpIfDesc->bcdADC = 0x0100U; + pSpIfDesc->wTotalLength = 0x0027U; + pSpIfDesc->bInCollection = 0x01U; + pSpIfDesc->baInterfaceNr = 0x01U; + *Sze += (uint32_t)sizeof(USBD_IfDescTypeDef); + + /* Append USB Speaker Input Terminal Descriptor to Configuration descriptor*/ + pSpInDesc = ((USBD_SpeakerInDescTypeDef *)(pConf + *Sze)); + pSpInDesc->bLength = (uint8_t)sizeof(USBD_SpeakerInDescTypeDef); + pSpInDesc->bDescriptorType = AUDIO_INTERFACE_DESCRIPTOR_TYPE; + pSpInDesc->bDescriptorSubtype = AUDIO_CONTROL_INPUT_TERMINAL; + pSpInDesc->bTerminalID = 0x01U; + pSpInDesc->wTerminalType = 0x0101U; + pSpInDesc->bAssocTerminal = 0x00U; + pSpInDesc->bNrChannels = 0x01U; + pSpInDesc->wChannelConfig = 0x0000U; + pSpInDesc->iChannelNames = 0x00U; + pSpInDesc->iTerminal = 0x00U; + *Sze += (uint32_t)sizeof(USBD_SpeakerInDescTypeDef); + + /*Append USB Speaker Audio Feature Unit Descriptor to Configuration descriptor */ + pSpFDesc = ((USBD_SpeakerFeatureDescTypeDef *)(pConf + *Sze)); + pSpFDesc->bLength = (uint8_t)sizeof(USBD_SpeakerFeatureDescTypeDef); + pSpFDesc->bDescriptorType = AUDIO_INTERFACE_DESCRIPTOR_TYPE; + pSpFDesc->bDescriptorSubtype = AUDIO_CONTROL_FEATURE_UNIT; + pSpFDesc->bUnitID = AUDIO_OUT_STREAMING_CTRL; + pSpFDesc->bSourceID = 0x01U; + pSpFDesc->bControlSize = 0x01U; + pSpFDesc->bmaControls = AUDIO_CONTROL_MUTE; + pSpFDesc->iTerminal = 0x00U; + *Sze += (uint32_t)sizeof(USBD_SpeakerFeatureDescTypeDef); + + /*Append USB Speaker Output Terminal Descriptor to Configuration descriptor*/ + pSpOutDesc = ((USBD_SpeakerOutDescTypeDef *)(pConf + *Sze)); + pSpOutDesc->bLength = (uint8_t)sizeof(USBD_SpeakerOutDescTypeDef); + pSpOutDesc->bDescriptorType = AUDIO_INTERFACE_DESCRIPTOR_TYPE; + pSpOutDesc->bDescriptorSubtype = AUDIO_CONTROL_OUTPUT_TERMINAL; + pSpOutDesc->bTerminalID = 0x03U; + pSpOutDesc->wTerminalType = 0x0301U; + pSpOutDesc->bAssocTerminal = 0x00U; + pSpOutDesc->bSourceID = 0x02U; + pSpOutDesc->iTerminal = 0x00U; + *Sze += (uint32_t)sizeof(USBD_SpeakerOutDescTypeDef); + + /* USB Speaker Standard AS Interface Descriptor - Audio Streaming Zero Bandwidth */ + /* Interface 1, Alternate Setting 0*/ + __USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[1], 0U, 0U, USB_DEVICE_CLASS_AUDIO, \ + AUDIO_SUBCLASS_AUDIOSTREAMING, AUDIO_PROTOCOL_UNDEFINED, 0U); + + /* USB Speaker Standard AS Interface Descriptor -Audio Streaming Operational */ + /* Interface 1, Alternate Setting 1*/ + __USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[1], 0x01U, 0x01U, USB_DEVICE_CLASS_AUDIO, \ + AUDIO_SUBCLASS_AUDIOSTREAMING, AUDIO_PROTOCOL_UNDEFINED, 0U); + + /* USB Speaker Audio Streaming Interface Descriptor */ + pSpStrDesc = ((USBD_SpeakerStreamIfDescTypeDef *)(pConf + *Sze)); + pSpStrDesc->bLength = (uint8_t)sizeof(USBD_SpeakerStreamIfDescTypeDef); + pSpStrDesc->bDescriptorType = AUDIO_INTERFACE_DESCRIPTOR_TYPE; + pSpStrDesc->bDescriptorSubtype = AUDIO_STREAMING_GENERAL; + pSpStrDesc->bTerminalLink = 0x01U; + pSpStrDesc->bDelay = 0x01U; + pSpStrDesc->wFormatTag = 0x0001U; + *Sze += (uint32_t)sizeof(USBD_SpeakerStreamIfDescTypeDef); + + /* USB Speaker Audio Type III Format Interface Descriptor */ + pSpIIIDesc = ((USBD_SpeakerIIIFormatIfDescTypeDef *)(pConf + *Sze)); + pSpIIIDesc->bLength = (uint8_t)sizeof(USBD_SpeakerIIIFormatIfDescTypeDef); + pSpIIIDesc->bDescriptorType = AUDIO_INTERFACE_DESCRIPTOR_TYPE; + pSpIIIDesc->bDescriptorSubtype = AUDIO_STREAMING_FORMAT_TYPE; + pSpIIIDesc->bFormatType = AUDIO_FORMAT_TYPE_I; + pSpIIIDesc->bNrChannels = 0x02U; + pSpIIIDesc->bSubFrameSize = 0x02U; + pSpIIIDesc->bBitResolution = 16U; + pSpIIIDesc->bSamFreqType = 1U; + pSpIIIDesc->tSamFreq2 = 0x80U; + pSpIIIDesc->tSamFreq1 = 0xBBU; + pSpIIIDesc->tSamFreq0 = 0x00U; + *Sze += (uint32_t)sizeof(USBD_SpeakerIIIFormatIfDescTypeDef); + + /* Endpoint 1 - Standard Descriptor */ + pSpEpDesc = ((USBD_SpeakerEndDescTypeDef *)(pConf + *Sze)); + pSpEpDesc->bLength = 0x09U; + pSpEpDesc->bDescriptorType = USB_DESC_TYPE_ENDPOINT; + pSpEpDesc->bEndpointAddress = pdev->tclasslist[pdev->classId].Eps[0].add; + pSpEpDesc->bmAttributes = USBD_EP_TYPE_ISOC; + pSpEpDesc->wMaxPacketSize = USBD_AUDIO_GetEpPcktSze(pdev, 0U, 0U); + pSpEpDesc->bInterval = 0x01U; + pSpEpDesc->bRefresh = 0x00U; + pSpEpDesc->bSynchAddress = 0x00U; + *Sze += 0x09U; + + /* Endpoint - Audio Streaming Descriptor*/ + pSpEpStDesc = ((USBD_SpeakerEndStDescTypeDef *)(pConf + *Sze)); + pSpEpStDesc->bLength = (uint8_t)sizeof(USBD_SpeakerEndStDescTypeDef); + pSpEpStDesc->bDescriptorType = AUDIO_ENDPOINT_DESCRIPTOR_TYPE; + pSpEpStDesc->bDescriptor = AUDIO_ENDPOINT_GENERAL; + pSpEpStDesc->bmAttributes = 0x00U; + pSpEpStDesc->bLockDelayUnits = 0x00U; + pSpEpStDesc->wLockDelay = 0x0000U; + *Sze += (uint32_t)sizeof(USBD_SpeakerEndStDescTypeDef); + + /* Update Config Descriptor and IAD descriptor */ + ((USBD_ConfigDescTypeDef *)pConf)->bNumInterfaces += 2U; + ((USBD_ConfigDescTypeDef *)pConf)->wTotalLength = *Sze; +} +#endif /* USBD_CMPSIT_ACTIVATE_AUDIO */ + +#if USBD_CMPSIT_ACTIVATE_RNDIS == 1 +/** + * @brief USBD_CMPSIT_MSCDesc + * Configure and Append the CDC_RNDIS Descriptor + * @param pdev: device instance + * @param pConf: Configuration descriptor pointer + * @param Sze: pointer to the current configuration descriptor size + * @retval None + */ +static void USBD_CMPSIT_RNDISDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed) +{ + static USBD_IfDescTypeDef *pIfDesc; + static USBD_EpDescTypeDef *pEpDesc; + static USBD_CDCHeaderFuncDescTypeDef *pHeadDesc; + static USBD_CDCCallMgmFuncDescTypeDef *pCallMgmDesc; + static USBD_CDCACMFuncDescTypeDef *pACMDesc; + static USBD_CDCUnionFuncDescTypeDef *pUnionDesc; + static USBD_IadDescTypeDef *pIadDesc; + +#if USBD_COMPOSITE_USE_IAD == 1 + pIadDesc = ((USBD_IadDescTypeDef *)(pConf + *Sze)); + pIadDesc->bLength = (uint8_t)sizeof(USBD_IadDescTypeDef); + pIadDesc->bDescriptorType = USB_DESC_TYPE_IAD; /* IAD descriptor */ + pIadDesc->bFirstInterface = pdev->tclasslist[pdev->classId].Ifs[0]; + pIadDesc->bInterfaceCount = 2U; /* 2 interfaces */ + pIadDesc->bFunctionClass = 0xE0U; + pIadDesc->bFunctionSubClass = 0x01U; + pIadDesc->bFunctionProtocol = 0x03U; + pIadDesc->iFunction = 0U; /* String Index */ + *Sze += (uint32_t)sizeof(USBD_IadDescTypeDef); +#endif /* USBD_COMPOSITE_USE_IAD == 1 */ + + /* Control Interface Descriptor */ + __USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[0], 0U, 1U, 0x02, 0x02, 0xFF, 0U); + + /* Control interface headers */ + pHeadDesc = ((USBD_CDCHeaderFuncDescTypeDef *)(pConf + *Sze)); + /* Header Functional Descriptor*/ + pHeadDesc->bLength = (uint8_t)sizeof(USBD_CDCHeaderFuncDescTypeDef); + pHeadDesc->bDescriptorType = 0x24U; + pHeadDesc->bDescriptorSubtype = 0x00U; + pHeadDesc->bcdCDC = 0x0110U; + *Sze += (uint32_t)sizeof(USBD_CDCHeaderFuncDescTypeDef); + + /* Call Management Functional Descriptor*/ + pCallMgmDesc = ((USBD_CDCCallMgmFuncDescTypeDef *)(pConf + *Sze)); + pCallMgmDesc->bLength = (uint8_t)sizeof(USBD_CDCCallMgmFuncDescTypeDef); + pCallMgmDesc->bDescriptorType = 0x24U; + pCallMgmDesc->bDescriptorSubtype = 0x01U; + pCallMgmDesc->bmCapabilities = 0x00U; + pCallMgmDesc->bDataInterface = pdev->tclasslist[pdev->classId].Ifs[1]; + *Sze += (uint32_t)sizeof(USBD_CDCCallMgmFuncDescTypeDef); + + /* ACM Functional Descriptor*/ + pACMDesc = ((USBD_CDCACMFuncDescTypeDef *)(pConf + *Sze)); + pACMDesc->bLength = (uint8_t)sizeof(USBD_CDCACMFuncDescTypeDef); + pACMDesc->bDescriptorType = 0x24U; + pACMDesc->bDescriptorSubtype = 0x02U; + pACMDesc->bmCapabilities = 0x00U; + *Sze += (uint32_t)sizeof(USBD_CDCACMFuncDescTypeDef); + + /* Union Functional Descriptor*/ + pUnionDesc = ((USBD_CDCUnionFuncDescTypeDef *)(pConf + *Sze)); + pUnionDesc->bLength = (uint8_t)sizeof(USBD_CDCUnionFuncDescTypeDef); + pUnionDesc->bDescriptorType = 0x24U; + pUnionDesc->bDescriptorSubtype = 0x06U; + pUnionDesc->bMasterInterface = pdev->tclasslist[pdev->classId].Ifs[0]; + pUnionDesc->bSlaveInterface = pdev->tclasslist[pdev->classId].Ifs[1]; + *Sze += (uint32_t)sizeof(USBD_CDCUnionFuncDescTypeDef); + + /* Append Endpoint descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_EP(pdev->tclasslist[pdev->classId].Eps[2].add, USBD_EP_TYPE_INTR, \ + CDC_RNDIS_CMD_PACKET_SIZE, CDC_RNDIS_HS_BINTERVAL, CDC_RNDIS_FS_BINTERVAL); + + /* Data Interface Descriptor */ + __USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[1], 0U, 2U, 0x0AU, 0x00U, 0x00U, 0U); + + if (speed == (uint8_t)USBD_SPEED_HIGH) + { + pdev->tclasslist[pdev->classId].CurrPcktSze = CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE; + } + + /* Append Endpoint descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[0].add), (USBD_EP_TYPE_BULK), \ + (pdev->tclasslist[pdev->classId].CurrPcktSze), (0U), (0U)); + + /* Append Endpoint descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[1].add), (USBD_EP_TYPE_BULK), \ + (pdev->tclasslist[pdev->classId].CurrPcktSze), (0U), (0U)); + + /* Update Config Descriptor and IAD descriptor */ + ((USBD_ConfigDescTypeDef *)pConf)->bNumInterfaces += 2U; + ((USBD_ConfigDescTypeDef *)pConf)->wTotalLength = *Sze; +} +#endif /* USBD_CMPSIT_ACTIVATE_RNDIS == 1 */ + +#if USBD_CMPSIT_ACTIVATE_CUSTOMHID == 1 +/** + * @brief USBD_CMPSIT_CUSTOMHIDDesc + * Configure and Append the MSC Descriptor + * @param pdev: device instance + * @param pConf: Configuration descriptor pointer + * @param Sze: pointer to the current configuration descriptor size + * @retval None + */ +static void USBD_CMPSIT_CUSTOMHIDDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed) +{ + static USBD_IfDescTypeDef *pIfDesc; + static USBD_EpDescTypeDef *pEpDesc; + static USBD_DescTypeDef *pDesc; + + /* Control Interface Descriptor */ + __USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[0], 0U, 2U, 3U, 0U, 0U, 0U); + + /* Descriptor of CUSTOM_HID */ + pDesc = ((USBD_DescTypeDef *)((uint32_t)pConf + *Sze)); + pDesc->bLength = 0x09U; + pDesc->bDescriptorTypeCHID = CUSTOM_HID_DESCRIPTOR_TYPE; + pDesc->bcdCUSTOM_HID = 0x0111U; + pDesc->bCountryCode = 0x00U; + pDesc->bNumDescriptors = 0x01U; + pDesc->bDescriptorType = 0x22U; + pDesc->wItemLength = USBD_CUSTOM_HID_REPORT_DESC_SIZE; + *Sze += (uint32_t)sizeof(USBD_DescTypeDef); + + /* Descriptor of Custom HID endpoints */ + /* Append Endpoint descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_EP(pdev->tclasslist[pdev->classId].Eps[0].add, \ + USBD_EP_TYPE_INTR, CUSTOM_HID_EPIN_SIZE, CUSTOM_HID_HS_BINTERVAL, CUSTOM_HID_FS_BINTERVAL); + + /* Append Endpoint descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_EP(pdev->tclasslist[pdev->classId].Eps[1].add, \ + USBD_EP_TYPE_INTR, CUSTOM_HID_EPIN_SIZE, CUSTOM_HID_HS_BINTERVAL, CUSTOM_HID_FS_BINTERVAL); + + /* Update Config Descriptor and IAD descriptor */ + ((USBD_ConfigDescTypeDef *)pConf)->bNumInterfaces += 1U; + ((USBD_ConfigDescTypeDef *)pConf)->wTotalLength = *Sze; +} +#endif /* USBD_CMPSIT_ACTIVATE_CUSTOMHID == 1U */ + +#if USBD_CMPSIT_ACTIVATE_VIDEO == 1 +/** + * @brief USBD_CMPSIT_VIDEODesc + * Configure and Append the VIDEO Descriptor + * @param pdev: device instance + * @param pConf: Configuration descriptor pointer + * @param Sze: pointer to the current configuration descriptor size + * @retval None + */ +static void USBD_CMPSIT_VIDEODesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed) +{ +#ifdef USBD_UVC_FORMAT_UNCOMPRESSED + __ALIGN_BEGIN static uint8_t usbd_uvc_guid[16] __ALIGN_END = {DBVAL(UVC_UNCOMPRESSED_GUID), 0x00, 0x00, 0x10, + 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71 + }; +#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */ + static USBD_IfDescTypeDef *pIfDesc; + static USBD_IadDescTypeDef *pIadDesc; + + /* Append AUDIO Interface descriptor to Configuration descriptor */ + USBD_specificVCInDescTypeDef *pSVCInDesc; + USBD_InputTerminalDescTypeDef *pInTerDesc; + USBD_OutputTerminalDescTypeDef *pOuTerDesc; + USBD_ClassSpecificVsHeaderDescTypeDef *pSpHeaDesc; + USBD_PayloadFormatDescTypeDef *pPayForDesc; +#ifdef USBD_UVC_FORMAT_UNCOMPRESSED + USBD_ColorMatchingDescTypeDef *pColMaDesc; +#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */ + USBD_StandardVCDataEPDescTypeDef *pSVCDEP; + USBD_VIDEO_VSFrameDescTypeDef *pClassSpecVS; + +#if USBD_COMPOSITE_USE_IAD == 1 + pIadDesc = ((USBD_IadDescTypeDef *)(pConf + *Sze)); + pIadDesc->bLength = (uint8_t)sizeof(USBD_IadDescTypeDef); + pIadDesc->bDescriptorType = USB_DESC_TYPE_IAD; /* IAD descriptor */ + pIadDesc->bFirstInterface = pdev->tclasslist[pdev->classId].Ifs[0]; + pIadDesc->bInterfaceCount = 2U; /* 2 interfaces */ + pIadDesc->bFunctionClass = UVC_CC_VIDEO; + pIadDesc->bFunctionSubClass = SC_VIDEO_INTERFACE_COLLECTION; + pIadDesc->bFunctionProtocol = PC_PROTOCOL_UNDEFINED; + pIadDesc->iFunction = 0U; /* String Index */ + *Sze += (uint32_t)sizeof(USBD_IadDescTypeDef); +#endif /* USBD_COMPOSITE_USE_IAD == 1 */ + + /* Append VIDEO Interface descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[0], 0U, 0U, UVC_CC_VIDEO, 1U, PC_PROTOCOL_UNDEFINED, 0U); + + /* Append Class-specific VC Interface Descriptor to Configuration descriptor*/ + pSVCInDesc = ((USBD_specificVCInDescTypeDef *)(pConf + *Sze)); + pSVCInDesc->bLength = (uint8_t)sizeof(USBD_specificVCInDescTypeDef); + pSVCInDesc->bDescriptorType = CS_INTERFACE; + pSVCInDesc->bDescriptorSubtype = VC_HEADER; + pSVCInDesc->bcdUVC = UVC_VERSION; + pSVCInDesc->wTotalLength = 0x001EU; + pSVCInDesc->dwClockFrequency = 0x02DC6C00U; + pSVCInDesc->baInterfaceNr = 0x01U; + pSVCInDesc->iTerminal = 0x01U; + *Sze += (uint32_t)sizeof(USBD_specificVCInDescTypeDef); + + /*Append Input Terminal Descriptor to Configuration descriptor */ + pInTerDesc = ((USBD_InputTerminalDescTypeDef *)(pConf + *Sze)); + pInTerDesc->bLength = (uint8_t)sizeof(USBD_InputTerminalDescTypeDef); + pInTerDesc->bDescriptorType = CS_INTERFACE; + pInTerDesc->bDescriptorSubtype = VC_INPUT_TERMINAL; + pInTerDesc->bTerminalID = 0x01U; + pInTerDesc->wTerminalType = ITT_VENDOR_SPECIFIC; + pInTerDesc->bAssocTerminal = 0x00U; + pInTerDesc->iTerminal = 0x00U; + *Sze += (uint32_t)sizeof(USBD_InputTerminalDescTypeDef); + + /* Append Output Terminal Descriptor to Configuration descriptor */ + pOuTerDesc = ((USBD_OutputTerminalDescTypeDef *)(pConf + *Sze)); + pOuTerDesc->bLength = (uint8_t)sizeof(USBD_OutputTerminalDescTypeDef); + pOuTerDesc->bDescriptorType = CS_INTERFACE; + pOuTerDesc->bDescriptorSubtype = VC_OUTPUT_TERMINAL; + pOuTerDesc->bTerminalID = 0x02U; + pOuTerDesc->wTerminalType = TT_STREAMING; + pOuTerDesc->bAssocTerminal = 0x00U; + pOuTerDesc->bSourceID = 0x01U; + pOuTerDesc->iTerminal = 0x00U; + *Sze += (uint32_t)sizeof(USBD_OutputTerminalDescTypeDef); + + /* Standard VS (Video Streaming) Interface Descriptor */ + /* Interface 1, Alternate Setting 0 = Zero Bandwidth*/ + __USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[1], 0U, 0U, UVC_CC_VIDEO, \ + SC_VIDEOSTREAMING, PC_PROTOCOL_UNDEFINED, 0U); + + /* Append Class-specific VS Header Descriptor (Input) to Configuration descriptor */ + pSpHeaDesc = ((USBD_ClassSpecificVsHeaderDescTypeDef *)(pConf + *Sze)); + pSpHeaDesc->bLength = (uint8_t)sizeof(USBD_ClassSpecificVsHeaderDescTypeDef); + pSpHeaDesc->bDescriptorType = CS_INTERFACE; + pSpHeaDesc->bDescriptorSubtype = VS_INPUT_HEADER; + pSpHeaDesc->bNumFormats = 0x4D01U; + pSpHeaDesc->bVideoControlSize = 0x00U; + pSpHeaDesc->bEndPointAddress = UVC_IN_EP; + pSpHeaDesc->bmInfo = 0x00U; + pSpHeaDesc->bTerminalLink = 0x02U; + pSpHeaDesc->bStillCaptureMethod = 0x00U; + pSpHeaDesc->bTriggerSupport = 0x00U; + pSpHeaDesc->bTriggerUsage = 0x00U; + pSpHeaDesc->bControlSize = 0x01U; + pSpHeaDesc->bmaControls = 0x00U; + *Sze += (uint32_t)sizeof(USBD_ClassSpecificVsHeaderDescTypeDef); + + /* Append Payload Format Descriptor to Configuration descriptor */ + pPayForDesc = ((USBD_PayloadFormatDescTypeDef *)(pConf + *Sze)); + pPayForDesc->bLength = (uint8_t)sizeof(USBD_PayloadFormatDescTypeDef); + pPayForDesc->bDescriptorType = CS_INTERFACE; + pPayForDesc->bDescriptorSubType = VS_FORMAT_SUBTYPE; + pPayForDesc->bFormatIndex = 0x01U; + pPayForDesc->bNumFrameDescriptor = 0x01U; +#ifdef USBD_UVC_FORMAT_UNCOMPRESSED + (void)USBD_memcpy(pPayForDesc->pGiudFormat, usbd_uvc_guid, 16); + pPayForDesc->bBitsPerPixel = UVC_BITS_PER_PIXEL; +#else + pPayForDesc->bmFlags = 0x01U; +#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */ + pPayForDesc->bDefaultFrameIndex = 0x01U; + pPayForDesc->bAspectRatioX = 0x00U; + pPayForDesc->bAspectRatioY = 0x00U; + pPayForDesc->bInterlaceFlags = 0x00U; + pPayForDesc->bCopyProtect = 0x00U; + *Sze += (uint32_t)sizeof(USBD_PayloadFormatDescTypeDef); + + /* Append Class-specific VS (Video Streaming) Frame Descriptor to Configuration descriptor */ + pClassSpecVS = ((USBD_VIDEO_VSFrameDescTypeDef *)(pConf + *Sze)); + pClassSpecVS->bLength = (uint8_t)sizeof(USBD_VIDEO_VSFrameDescTypeDef); + pClassSpecVS->bDescriptorType = CS_INTERFACE; + pClassSpecVS->bDescriptorSubType = VS_FRAME_SUBTYPE; + pClassSpecVS->bFrameIndex = 0x01U; + +#ifdef USBD_UVC_FORMAT_UNCOMPRESSED + pClassSpecVS->bmCapabilities = 0x00U; +#else + pClassSpecVS->bmCapabilities = 0x02U; +#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */ + + pClassSpecVS->wWidth = UVC_WIDTH; + pClassSpecVS->wHeight = UVC_HEIGHT; + + if (speed == (uint8_t)USBD_SPEED_HIGH) + { + pClassSpecVS->dwMinBitRate = UVC_MIN_BIT_RATE(UVC_CAM_FPS_HS); + pClassSpecVS->dwMaxBitRate = UVC_MAX_BIT_RATE(UVC_CAM_FPS_HS); + pClassSpecVS->dwDefaultFrameInterval = UVC_INTERVAL(UVC_CAM_FPS_HS); + pClassSpecVS->dwMinFrameInterval = UVC_INTERVAL(UVC_CAM_FPS_HS); + } + else + { + pClassSpecVS->dwMinBitRate = UVC_MIN_BIT_RATE(UVC_CAM_FPS_FS); + pClassSpecVS->dwMaxBitRate = UVC_MAX_BIT_RATE(UVC_CAM_FPS_FS); + pClassSpecVS->dwDefaultFrameInterval = UVC_INTERVAL(UVC_CAM_FPS_FS); + pClassSpecVS->dwMinFrameInterval = UVC_INTERVAL(UVC_CAM_FPS_FS); + } + + pClassSpecVS->dwMaxVideoFrameBufSize = UVC_MAX_FRAME_SIZE; + pClassSpecVS->bFrameIntervalType = 0x01U; + + *Sze += (uint32_t)sizeof(USBD_VIDEO_VSFrameDescTypeDef); + +#ifdef USBD_UVC_FORMAT_UNCOMPRESSED + /* Append Color Matching Descriptor to Configuration descriptor */ + pColMaDesc = ((USBD_ColorMatchingDescTypeDef *)(pConf + *Sze)); + pColMaDesc->bLength = (uint8_t)sizeof(USBD_ColorMatchingDescTypeDef); + pColMaDesc->bDescriptorType = CS_INTERFACE; + pColMaDesc->bDescriptorSubType = VS_COLORFORMAT; + pColMaDesc->bColorPrimarie = UVC_COLOR_PRIMARIE; + pColMaDesc->bTransferCharacteristics = UVC_TFR_CHARACTERISTICS; + pColMaDesc->bMatrixCoefficients = UVC_MATRIX_COEFFICIENTS; + *Sze += (uint32_t)sizeof(USBD_ColorMatchingDescTypeDef); +#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */ + + /* USB Standard VS Interface Descriptor - data transfer mode */ + /* Interface 1, Alternate Setting 1*/ + __USBD_CMPSIT_SET_IF(1U, 1U, 1U, UVC_CC_VIDEO, \ + SC_VIDEOSTREAMING, PC_PROTOCOL_UNDEFINED, 0U); + + /* Standard VS (Video Streaming) data Endpoint */ + pSVCDEP = ((USBD_StandardVCDataEPDescTypeDef *)(pConf + *Sze)); + pSVCDEP->bLength = (uint8_t)sizeof(USBD_StandardVCDataEPDescTypeDef); + pSVCDEP->bDescriptorType = USB_DESC_TYPE_ENDPOINT; + pSVCDEP->bEndpointAddress = UVC_IN_EP; + pSVCDEP->bmAttributes = 0x05U; + pSVCDEP->bInterval = 0x01U; + + if (speed == (uint8_t)USBD_SPEED_HIGH) + { + pSVCDEP->wMaxPacketSize = UVC_ISO_HS_MPS; + } + else + { + pSVCDEP->wMaxPacketSize = UVC_ISO_FS_MPS; + } + + *Sze += (uint32_t)sizeof(USBD_StandardVCDataEPDescTypeDef); + + /* Update Config Descriptor and IAD descriptor */ + ((USBD_ConfigDescTypeDef *)pConf)->bNumInterfaces += 2U; + ((USBD_ConfigDescTypeDef *)pConf)->wTotalLength = *Sze; +} +#endif /* USBD_CMPSIT_ACTIVATE_VIDEO == 1 */ + +#if USBD_CMPSIT_ACTIVATE_PRINTER == 1 +/** + * @brief USBD_CMPSIT_PRINTERDesc + * Configure and Append the PRINTER Descriptor + * @param pdev: device instance + * @param pConf: Configuration descriptor pointer + * @param Sze: pointer to the current configuration descriptor size + * @retval None + */ +static void USBD_CMPSIT_PRNTDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed) +{ + static USBD_IfDescTypeDef *pIfDesc; + static USBD_EpDescTypeDef *pEpDesc; + + /* Control Interface Descriptor */ + __USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[0], 0U, 0x02, 0x07, 0x01U, USB_PRNT_BIDIRECTIONAL, 0U); + + if (speed == (uint8_t)USBD_SPEED_HIGH) + { + pdev->tclasslist[pdev->classId].CurrPcktSze = PRNT_DATA_HS_MAX_PACKET_SIZE; + } + + /* Append Endpoint descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[1].add), \ + (USBD_EP_TYPE_BULK), (pdev->tclasslist[pdev->classId].CurrPcktSze), (0U), (0U)); + + /* Append Endpoint descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[0].add), \ + (USBD_EP_TYPE_BULK), (pdev->tclasslist[pdev->classId].CurrPcktSze), (0U), (0U)); + + /* Update Config Descriptor and IAD descriptor */ + ((USBD_ConfigDescTypeDef *)pConf)->bNumInterfaces += 1U; + ((USBD_ConfigDescTypeDef *)pConf)->wTotalLength = *Sze; +} +#endif /* USBD_CMPSIT_ACTIVATE_PRINTER == 1 */ + +#if USBD_CMPSIT_ACTIVATE_CCID == 1 +/** + * @brief USBD_CMPSIT_CCIDDesc + * Configure and Append the CCID Descriptor + * @param pdev: device instance + * @param pConf: Configuration descriptor pointer + * @param Sze: pointer to the current configuration descriptor size + * @retval None + */ +static void USBD_CMPSIT_CCIDDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed) +{ + static USBD_IfDescTypeDef *pIfDesc; + static USBD_EpDescTypeDef *pEpDesc; + static USBD_CCID_DescTypeDef *pDesc; + + /* Control Interface Descriptor */ + __USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[0], 0U, 0x03, 0x0BU, 0U, 0U, 0U); + + /* Control interface headers */ + pDesc = ((USBD_CCID_DescTypeDef *)((uint32_t)pConf + *Sze)); + + /* Device Descriptor */ + pDesc->bLength = 0x36U; + pDesc->bDescriptorType = 0x21U; + pDesc->bcdCCID = 0x0110U; + pDesc->bMaxSlotIndex = 0x00U; + pDesc->bVoltageSupport = CCID_VOLTAGE_SUPP; + pDesc->dwProtocols = USBD_CCID_PROTOCOL; + pDesc->dwDefaultClock = USBD_CCID_DEFAULT_CLOCK_FREQ; + pDesc->dwMaximumClock = USBD_CCID_MAX_CLOCK_FREQ; + pDesc->bNumClockSupported = 0x00U; + pDesc->dwDataRate = USBD_CCID_DEFAULT_DATA_RATE; + pDesc->dwMaxDataRate = USBD_CCID_MAX_DATA_RATE; + pDesc->bNumDataRatesSupported = 0x35U; + pDesc->dwMaxIFSD = USBD_CCID_MAX_INF_FIELD_SIZE; + pDesc->dwSynchProtocols = 0U; + pDesc->dwMechanical = 0U; + pDesc->dwFeatures = 0x000104BAU; + pDesc->dwMaxCCIDMessageLength = CCID_MAX_BLOCK_SIZE_HEADER; + pDesc->bClassGetResponse = 0U; + pDesc->bClassEnvelope = 0U; + pDesc->wLcdLayout = 0U; + pDesc->bPINSupport = 0x03U; + pDesc->bMaxCCIDBusySlots = 0x01U; + + *Sze += (uint32_t)sizeof(USBD_CCID_DescTypeDef); + + if (speed == (uint8_t)USBD_SPEED_HIGH) + { + pdev->tclasslist[pdev->classId].CurrPcktSze = CCID_DATA_HS_MAX_PACKET_SIZE; + } + + /* Append Endpoint descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[0].add), \ + (USBD_EP_TYPE_BULK), (pdev->tclasslist[pdev->classId].CurrPcktSze), (0U), (0U)); + + /* Append Endpoint descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[1].add), \ + (USBD_EP_TYPE_BULK), (pdev->tclasslist[pdev->classId].CurrPcktSze), (0U), (0U)); + + /* Append Endpoint descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_EP(pdev->tclasslist[pdev->classId].Eps[2].add, \ + USBD_EP_TYPE_INTR, CCID_CMD_PACKET_SIZE, CCID_CMD_HS_BINTERVAL, CCID_CMD_FS_BINTERVAL); + + /* Update Config Descriptor and IAD descriptor */ + ((USBD_ConfigDescTypeDef *)pConf)->bNumInterfaces += 1U; + ((USBD_ConfigDescTypeDef *)pConf)->wTotalLength = *Sze; +} +#endif /* USBD_CMPSIT_ACTIVATE_CCID == 1 */ + +#if USBD_CMPSIT_ACTIVATE_MTP == 1 +/** + * @brief USBD_CMPSIT_MTPDesc + * Configure and Append the MTP Descriptor + * @param pdev: device instance + * @param pConf: Configuration descriptor pointer + * @param Sze: pointer to the current configuration descriptor size + * @retval None + */ +static void USBD_CMPSIT_MTPDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed) +{ + USBD_IfDescTypeDef *pIfDesc; + USBD_EpDescTypeDef *pEpDesc; + + /* Append MTP Interface descriptor */ + __USBD_CMPSIT_SET_IF((pdev->tclasslist[pdev->classId].Ifs[0]), (0U), \ + (uint8_t)(pdev->tclasslist[pdev->classId].NumEps), USB_MTP_INTRERFACE_CLASS, USB_MTP_INTRERFACE_SUB_CLASS, + USB_MTP_INTRERFACE_PROTOCOL, (0U)); + + if (speed == (uint8_t)USBD_SPEED_HIGH) + { + pdev->tclasslist[pdev->classId].CurrPcktSze = MTP_DATA_MAX_HS_PACKET_SIZE; + } + + /* Append Endpoint descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[0].add), (USBD_EP_TYPE_BULK), \ + (pdev->tclasslist[pdev->classId].CurrPcktSze), (0U), (0U)); + + /* Append Endpoint descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[1].add), (USBD_EP_TYPE_BULK), \ + (pdev->tclasslist[pdev->classId].CurrPcktSze), (0U), (0U)); + + /* Append Endpoint descriptor to Configuration descriptor */ + __USBD_CMPSIT_SET_EP(pdev->tclasslist[pdev->classId].Eps[2].add, \ + USBD_EP_TYPE_INTR, MTP_CMD_PACKET_SIZE, MTP_HS_BINTERVAL, MTP_FS_BINTERVAL); + + /* Update Config Descriptor and IAD descriptor */ + ((USBD_ConfigDescTypeDef *)pConf)->bNumInterfaces += 1U; + ((USBD_ConfigDescTypeDef *)pConf)->wTotalLength = *Sze; +} +#endif /* USBD_CMPSIT_ACTIVATE_MTP == 1 */ + +/** + * @brief USBD_CMPSIT_SetClassID + * Find and set the class ID relative to selected class type and instance + * @param pdev: device instance + * @param Class: Class type, can be CLASS_TYPE_NONE if requested to find class from setup request + * @param Instance: Instance number of the class (0 if first/unique instance, >0 otherwise) + * @retval The Class ID, The pdev->classId is set with the value of the selected class ID. + */ +uint32_t USBD_CMPSIT_SetClassID(USBD_HandleTypeDef *pdev, USBD_CompositeClassTypeDef Class, uint32_t Instance) +{ + uint32_t idx; + uint32_t inst = 0U; + + /* Unroll all already activated classes */ + for (idx = 0U; idx < pdev->NumClasses; idx++) + { + /* Check if the class correspond to the requested type and if it is active */ + if (((USBD_CompositeClassTypeDef)(pdev->tclasslist[idx].ClassType) == Class) && ((pdev->tclasslist[idx].Active) == 1U)) + { + if (inst == Instance) + { + /* Set the new class ID */ + pdev->classId = idx; + + /* Return the class ID value */ + return (idx); + } + else + { + /* Increment instance index and look for next instance */ + inst++; + } + } + } + + /* No class found, return 0xFF */ + return 0xFFU; +} + +/** + * @brief USBD_CMPSIT_GetClassID + * Returns the class ID relative to selected class type and instance + * @param pdev: device instance + * @param Class: Class type, can be CLASS_TYPE_NONE if requested to find class from setup request + * @param Instance: Instance number of the class (0 if first/unique instance, >0 otherwise) + * @retval The Class ID (this function does not set the pdev->classId field. + */ +uint32_t USBD_CMPSIT_GetClassID(USBD_HandleTypeDef *pdev, USBD_CompositeClassTypeDef Class, uint32_t Instance) +{ + uint32_t idx; + uint32_t inst = 0U; + + /* Unroll all already activated classes */ + for (idx = 0U; idx < pdev->NumClasses; idx++) + { + /* Check if the class correspond to the requested type and if it is active */ + if (((USBD_CompositeClassTypeDef)(pdev->tclasslist[idx].ClassType) == Class) && ((pdev->tclasslist[idx].Active) == 1U)) + { + if (inst == Instance) + { + /* Return the class ID value */ + return (idx); + } + else + { + /* Increment instance index and look for next instance */ + inst++; + } + } + } + + /* No class found, return 0xFF */ + return 0xFFU; +} + +/** + * @brief USBD_CMPST_ClearConfDesc + * Reset the configuration descriptor + * @param pdev: device instance (reserved for future use) + * @retval Status. + */ +uint8_t USBD_CMPST_ClearConfDesc(USBD_HandleTypeDef *pdev) +{ + UNUSED(pdev); + + /* Reset the configuration descriptor pointer to default value and its size to zero */ + pCmpstFSConfDesc = USBD_CMPSIT_FSCfgDesc; + CurrFSConfDescSz = 0U; + +#ifdef USE_USB_HS + pCmpstHSConfDesc = USBD_CMPSIT_HSCfgDesc; + CurrHSConfDescSz = 0U; +#endif /* USE_USB_HS */ + + /* All done, can't fail */ + return (uint8_t)USBD_OK; +} + +#endif /* USE_USBD_COMPOSITE */ + +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + + diff --git a/Class/CustomHID/Inc/usbd_customhid.h b/Class/CustomHID/Inc/usbd_customhid.h index 3276fac..d5e599e 100644 --- a/Class/CustomHID/Inc/usbd_customhid.h +++ b/Class/CustomHID/Inc/usbd_customhid.h @@ -40,17 +40,21 @@ extern "C" { /** @defgroup USBD_CUSTOM_HID_Exported_Defines * @{ */ +#ifndef CUSTOM_HID_EPIN_ADDR #define CUSTOM_HID_EPIN_ADDR 0x81U +#endif /* CUSTOM_HID_EPIN_ADDR */ #ifndef CUSTOM_HID_EPIN_SIZE #define CUSTOM_HID_EPIN_SIZE 0x02U -#endif +#endif /* CUSTOM_HID_EPIN_SIZE */ +#ifndef CUSTOM_HID_EPOUT_ADDR #define CUSTOM_HID_EPOUT_ADDR 0x01U +#endif /* CUSTOM_HID_EPOUT_ADDR */ #ifndef CUSTOM_HID_EPOUT_SIZE #define CUSTOM_HID_EPOUT_SIZE 0x02U -#endif +#endif /* CUSTOM_HID_EPOUT_SIZE*/ #define USB_CUSTOM_HID_CONFIG_DESC_SIZ 41U #define USB_CUSTOM_HID_DESC_SIZ 9U @@ -114,6 +118,23 @@ typedef struct uint32_t IsReportAvailable; CUSTOM_HID_StateTypeDef state; } USBD_CUSTOM_HID_HandleTypeDef; + +/* + * HID Class specification version 1.1 + * 6.2.1 HID Descriptor + */ + +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorTypeCHID; + uint16_t bcdCUSTOM_HID; + uint8_t bCountryCode; + uint8_t bNumDescriptors; + uint8_t bDescriptorType; + uint16_t wItemLength; +} __PACKED USBD_DescTypeDef; + /** * @} */ diff --git a/Class/CustomHID/Src/usbd_customhid.c b/Class/CustomHID/Src/usbd_customhid.c index 7a9ca65..b6cdc37 100644 --- a/Class/CustomHID/Src/usbd_customhid.c +++ b/Class/CustomHID/Src/usbd_customhid.c @@ -91,12 +91,12 @@ static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqType static uint8_t USBD_CUSTOM_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); static uint8_t USBD_CUSTOM_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum); static uint8_t USBD_CUSTOM_HID_EP0_RxReady(USBD_HandleTypeDef *pdev); - +#ifndef USE_USBD_COMPOSITE static uint8_t *USBD_CUSTOM_HID_GetFSCfgDesc(uint16_t *length); static uint8_t *USBD_CUSTOM_HID_GetHSCfgDesc(uint16_t *length); static uint8_t *USBD_CUSTOM_HID_GetOtherSpeedCfgDesc(uint16_t *length); static uint8_t *USBD_CUSTOM_HID_GetDeviceQualifierDesc(uint16_t *length); - +#endif /* USE_USBD_COMPOSITE */ /** * @} */ @@ -117,14 +117,22 @@ USBD_ClassTypeDef USBD_CUSTOM_HID = NULL, /*SOF */ NULL, NULL, +#ifdef USE_USBD_COMPOSITE + NULL, + NULL, + NULL, + NULL, +#else USBD_CUSTOM_HID_GetHSCfgDesc, USBD_CUSTOM_HID_GetFSCfgDesc, USBD_CUSTOM_HID_GetOtherSpeedCfgDesc, USBD_CUSTOM_HID_GetDeviceQualifierDesc, +#endif /* USE_USBD_COMPOSITE */ }; +#ifndef USE_USBD_COMPOSITE /* USB CUSTOM_HID device FS Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgFSDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END = +__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END = { 0x09, /* bLength: Configuration Descriptor size */ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ @@ -132,12 +140,13 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgFSDesc[USB_CUSTOM_HID_CONFIG_DES 0x00, 0x01, /* bNumInterfaces: 1 interface */ 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ + 0x00, /* iConfiguration: Index of string descriptor + describing the configuration */ #if (USBD_SELF_POWERED == 1U) 0xC0, /* bmAttributes: Bus Powered according to user configuration */ #else 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif +#endif /* USBD_SELF_POWERED */ USBD_MAX_POWER, /* MaxPower (mA) */ /************** Descriptor of CUSTOM HID interface ****************/ @@ -158,7 +167,8 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgFSDesc[USB_CUSTOM_HID_CONFIG_DES 0x11, /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */ 0x01, 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */ + 0x01, /* bNumDescriptors: Number of CUSTOM_HID class descriptors + to follow */ 0x22, /* bDescriptorType */ USBD_CUSTOM_HID_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ 0x00, @@ -183,128 +193,7 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgFSDesc[USB_CUSTOM_HID_CONFIG_DES CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval */ /* 41 */ }; - -/* USB CUSTOM_HID device HS Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgHSDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END = -{ - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - USB_CUSTOM_HID_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ - 0x00, - 0x01, /* bNumInterfaces: 1 interface */ - 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ -#if (USBD_SELF_POWERED == 1U) - 0xC0, /* bmAttributes: Bus Powered according to user configuration */ -#else - 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif - USBD_MAX_POWER, /* MaxPower (mA) */ - - /************** Descriptor of CUSTOM HID interface ****************/ - /* 09 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: CUSTOM_HID */ - 0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /******************** Descriptor of CUSTOM_HID *************************/ - /* 18 */ - 0x09, /* bLength: CUSTOM_HID Descriptor size */ - CUSTOM_HID_DESCRIPTOR_TYPE, /* bDescriptorType: CUSTOM_HID */ - 0x11, /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - USBD_CUSTOM_HID_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ - 0x00, - /******************** Descriptor of Custom HID endpoints ********************/ - /* 27 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType */ - - CUSTOM_HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - CUSTOM_HID_EPIN_SIZE, /* wMaxPacketSize: 2 Bytes max */ - 0x00, - CUSTOM_HID_HS_BINTERVAL, /* bInterval: Polling Interval */ - /* 34 */ - - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ - CUSTOM_HID_EPOUT_ADDR, /* bEndpointAddress: Endpoint Address (OUT) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - CUSTOM_HID_EPOUT_SIZE, /* wMaxPacketSize: 2 Bytes max */ - 0x00, - CUSTOM_HID_HS_BINTERVAL, /* bInterval: Polling Interval */ - /* 41 */ -}; - -/* USB CUSTOM_HID device Other Speed Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_OtherSpeedCfgDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END = -{ - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - USB_CUSTOM_HID_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ - 0x00, - 0x01, /* bNumInterfaces: 1 interface */ - 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ -#if (USBD_SELF_POWERED == 1U) - 0xC0, /* bmAttributes: Bus Powered according to user configuration */ -#else - 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif - USBD_MAX_POWER, /* MaxPower (mA) */ - - /************** Descriptor of CUSTOM HID interface ****************/ - /* 09 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: CUSTOM_HID */ - 0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /******************** Descriptor of CUSTOM_HID *************************/ - /* 18 */ - 0x09, /* bLength: CUSTOM_HID Descriptor size */ - CUSTOM_HID_DESCRIPTOR_TYPE, /* bDescriptorType: CUSTOM_HID */ - 0x11, /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - USBD_CUSTOM_HID_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ - 0x00, - /******************** Descriptor of Custom HID endpoints ********************/ - /* 27 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ - - CUSTOM_HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - CUSTOM_HID_EPIN_SIZE, /* wMaxPacketSize: 2 Bytes max */ - 0x00, - CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval */ - /* 34 */ - - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ - CUSTOM_HID_EPOUT_ADDR, /* bEndpointAddress: Endpoint Address (OUT) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - CUSTOM_HID_EPOUT_SIZE, /* wMaxPacketSize: 2 Bytes max */ - 0x00, - CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval */ - /* 41 */ -}; +#endif /* USE_USBD_COMPOSITE */ /* USB CUSTOM_HID device Configuration Descriptor */ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_Desc[USB_CUSTOM_HID_DESC_SIZ] __ALIGN_END = @@ -315,12 +204,14 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_Desc[USB_CUSTOM_HID_DESC_SIZ] __ALI 0x11, /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */ 0x01, 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */ + 0x01, /* bNumDescriptors: Number of CUSTOM_HID class descriptors + to follow */ 0x22, /* bDescriptorType */ USBD_CUSTOM_HID_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ 0x00, }; +#ifndef USE_USBD_COMPOSITE /* USB Standard Device Descriptor */ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = { @@ -335,7 +226,10 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_DeviceQualifierDesc[USB_LEN_DEV_QUA 0x01, 0x00, }; +#endif /* USE_USBD_COMPOSITE */ +static uint8_t CUSTOMHIDInEpAdd = CUSTOM_HID_EPIN_ADDR; +static uint8_t CUSTOMHIDOutEpAdd = CUSTOM_HID_EPOUT_ADDR; /** * @} */ @@ -360,41 +254,48 @@ static uint8_t USBD_CUSTOM_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) if (hhid == NULL) { - pdev->pClassData = NULL; + pdev->pClassDataCmsit[pdev->classId] = NULL; return (uint8_t)USBD_EMEM; } - pdev->pClassData = (void *)hhid; + pdev->pClassDataCmsit[pdev->classId] = (void *)hhid; + pdev->pClassData = pdev->pClassDataCmsit[pdev->classId]; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + CUSTOMHIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR); + CUSTOMHIDOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_INTR); +#endif /* USE_USBD_COMPOSITE */ if (pdev->dev_speed == USBD_SPEED_HIGH) { - pdev->ep_in[CUSTOM_HID_EPIN_ADDR & 0xFU].bInterval = CUSTOM_HID_HS_BINTERVAL; - pdev->ep_out[CUSTOM_HID_EPOUT_ADDR & 0xFU].bInterval = CUSTOM_HID_HS_BINTERVAL; + pdev->ep_in[CUSTOMHIDInEpAdd & 0xFU].bInterval = CUSTOM_HID_HS_BINTERVAL; + pdev->ep_out[CUSTOMHIDOutEpAdd & 0xFU].bInterval = CUSTOM_HID_HS_BINTERVAL; } else /* LOW and FULL-speed endpoints */ { - pdev->ep_in[CUSTOM_HID_EPIN_ADDR & 0xFU].bInterval = CUSTOM_HID_FS_BINTERVAL; - pdev->ep_out[CUSTOM_HID_EPOUT_ADDR & 0xFU].bInterval = CUSTOM_HID_FS_BINTERVAL; + pdev->ep_in[CUSTOMHIDInEpAdd & 0xFU].bInterval = CUSTOM_HID_FS_BINTERVAL; + pdev->ep_out[CUSTOMHIDOutEpAdd & 0xFU].bInterval = CUSTOM_HID_FS_BINTERVAL; } /* Open EP IN */ - (void)USBD_LL_OpenEP(pdev, CUSTOM_HID_EPIN_ADDR, USBD_EP_TYPE_INTR, + (void)USBD_LL_OpenEP(pdev, CUSTOMHIDInEpAdd, USBD_EP_TYPE_INTR, CUSTOM_HID_EPIN_SIZE); - pdev->ep_in[CUSTOM_HID_EPIN_ADDR & 0xFU].is_used = 1U; + pdev->ep_in[CUSTOMHIDInEpAdd & 0xFU].is_used = 1U; /* Open EP OUT */ - (void)USBD_LL_OpenEP(pdev, CUSTOM_HID_EPOUT_ADDR, USBD_EP_TYPE_INTR, + (void)USBD_LL_OpenEP(pdev, CUSTOMHIDOutEpAdd, USBD_EP_TYPE_INTR, CUSTOM_HID_EPOUT_SIZE); - pdev->ep_out[CUSTOM_HID_EPOUT_ADDR & 0xFU].is_used = 1U; + pdev->ep_out[CUSTOMHIDOutEpAdd & 0xFU].is_used = 1U; hhid->state = CUSTOM_HID_IDLE; - ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->Init(); + ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init(); /* Prepare Out endpoint to receive 1st packet */ - (void)USBD_LL_PrepareReceive(pdev, CUSTOM_HID_EPOUT_ADDR, hhid->Report_buf, + (void)USBD_LL_PrepareReceive(pdev, CUSTOMHIDOutEpAdd, hhid->Report_buf, USBD_CUSTOMHID_OUTREPORT_BUF_SIZE); return (uint8_t)USBD_OK; @@ -411,21 +312,28 @@ static uint8_t USBD_CUSTOM_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { UNUSED(cfgidx); +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + CUSTOMHIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR); + CUSTOMHIDOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_INTR); +#endif /* USE_USBD_COMPOSITE */ + /* Close CUSTOM_HID EP IN */ - (void)USBD_LL_CloseEP(pdev, CUSTOM_HID_EPIN_ADDR); - pdev->ep_in[CUSTOM_HID_EPIN_ADDR & 0xFU].is_used = 0U; - pdev->ep_in[CUSTOM_HID_EPIN_ADDR & 0xFU].bInterval = 0U; + (void)USBD_LL_CloseEP(pdev, CUSTOMHIDInEpAdd); + pdev->ep_in[CUSTOMHIDInEpAdd & 0xFU].is_used = 0U; + pdev->ep_in[CUSTOMHIDInEpAdd & 0xFU].bInterval = 0U; /* Close CUSTOM_HID EP OUT */ - (void)USBD_LL_CloseEP(pdev, CUSTOM_HID_EPOUT_ADDR); - pdev->ep_out[CUSTOM_HID_EPOUT_ADDR & 0xFU].is_used = 0U; - pdev->ep_out[CUSTOM_HID_EPOUT_ADDR & 0xFU].bInterval = 0U; + (void)USBD_LL_CloseEP(pdev, CUSTOMHIDOutEpAdd); + pdev->ep_out[CUSTOMHIDOutEpAdd & 0xFU].is_used = 0U; + pdev->ep_out[CUSTOMHIDOutEpAdd & 0xFU].bInterval = 0U; /* Free allocated memory */ - if (pdev->pClassData != NULL) + if (pdev->pClassDataCmsit[pdev->classId] != NULL) { - ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->DeInit(); - USBD_free(pdev->pClassData); + ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit(); + USBD_free(pdev->pClassDataCmsit[pdev->classId]); + pdev->pClassDataCmsit[pdev->classId] = NULL; pdev->pClassData = NULL; } @@ -442,7 +350,7 @@ static uint8_t USBD_CUSTOM_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { - USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData; + USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint16_t len = 0U; uint8_t *pbuf = NULL; uint16_t status_info = 0U; @@ -506,7 +414,7 @@ static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev, if ((req->wValue >> 8) == CUSTOM_HID_REPORT_DESC) { len = MIN(USBD_CUSTOM_HID_REPORT_DESC_SIZE, req->wLength); - pbuf = ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->pReport; + pbuf = ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->pReport; } else { @@ -574,19 +482,24 @@ uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev, { USBD_CUSTOM_HID_HandleTypeDef *hhid; - if (pdev->pClassData == NULL) + if (pdev->pClassDataCmsit[pdev->classId] == NULL) { return (uint8_t)USBD_FAIL; } - hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData; +#ifdef USE_USBD_COMPOSITE + /* Get Endpoint IN address allocated for this class instance */ + CUSTOMHIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR); +#endif /* USE_USBD_COMPOSITE */ + + hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (pdev->dev_state == USBD_STATE_CONFIGURED) { if (hhid->state == CUSTOM_HID_IDLE) { hhid->state = CUSTOM_HID_BUSY; - (void)USBD_LL_Transmit(pdev, CUSTOM_HID_EPIN_ADDR, report, len); + (void)USBD_LL_Transmit(pdev, CUSTOMHIDInEpAdd, report, len); } else { @@ -595,7 +508,7 @@ uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev, } return (uint8_t)USBD_OK; } - +#ifndef USE_USBD_COMPOSITE /** * @brief USBD_CUSTOM_HID_GetFSCfgDesc * return FS configuration descriptor @@ -605,9 +518,23 @@ uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev, */ static uint8_t *USBD_CUSTOM_HID_GetFSCfgDesc(uint16_t *length) { - *length = (uint16_t)sizeof(USBD_CUSTOM_HID_CfgFSDesc); + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CUSTOM_HID_CfgDesc, CUSTOM_HID_EPIN_ADDR); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CUSTOM_HID_CfgDesc, CUSTOM_HID_EPOUT_ADDR); - return USBD_CUSTOM_HID_CfgFSDesc; + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = CUSTOM_HID_EPIN_SIZE; + pEpInDesc->bInterval = CUSTOM_HID_FS_BINTERVAL; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = CUSTOM_HID_EPOUT_SIZE; + pEpOutDesc->bInterval = CUSTOM_HID_FS_BINTERVAL; + } + + *length = (uint16_t)sizeof(USBD_CUSTOM_HID_CfgDesc); + return USBD_CUSTOM_HID_CfgDesc; } /** @@ -619,9 +546,23 @@ static uint8_t *USBD_CUSTOM_HID_GetFSCfgDesc(uint16_t *length) */ static uint8_t *USBD_CUSTOM_HID_GetHSCfgDesc(uint16_t *length) { - *length = (uint16_t)sizeof(USBD_CUSTOM_HID_CfgHSDesc); + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CUSTOM_HID_CfgDesc, CUSTOM_HID_EPIN_ADDR); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CUSTOM_HID_CfgDesc, CUSTOM_HID_EPOUT_ADDR); - return USBD_CUSTOM_HID_CfgHSDesc; + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = CUSTOM_HID_EPIN_SIZE; + pEpInDesc->bInterval = CUSTOM_HID_HS_BINTERVAL; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = CUSTOM_HID_EPOUT_SIZE; + pEpOutDesc->bInterval = CUSTOM_HID_HS_BINTERVAL; + } + + *length = (uint16_t)sizeof(USBD_CUSTOM_HID_CfgDesc); + return USBD_CUSTOM_HID_CfgDesc; } /** @@ -633,10 +574,25 @@ static uint8_t *USBD_CUSTOM_HID_GetHSCfgDesc(uint16_t *length) */ static uint8_t *USBD_CUSTOM_HID_GetOtherSpeedCfgDesc(uint16_t *length) { - *length = (uint16_t)sizeof(USBD_CUSTOM_HID_OtherSpeedCfgDesc); + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CUSTOM_HID_CfgDesc, CUSTOM_HID_EPIN_ADDR); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CUSTOM_HID_CfgDesc, CUSTOM_HID_EPOUT_ADDR); - return USBD_CUSTOM_HID_OtherSpeedCfgDesc; + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = CUSTOM_HID_EPIN_SIZE; + pEpInDesc->bInterval = CUSTOM_HID_FS_BINTERVAL; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = CUSTOM_HID_EPOUT_SIZE; + pEpOutDesc->bInterval = CUSTOM_HID_FS_BINTERVAL; + } + + *length = (uint16_t)sizeof(USBD_CUSTOM_HID_CfgDesc); + return USBD_CUSTOM_HID_CfgDesc; } +#endif /* USE_USBD_COMPOSITE */ /** * @brief USBD_CUSTOM_HID_DataIn @@ -651,7 +607,7 @@ static uint8_t USBD_CUSTOM_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) /* Ensure that the FIFO is empty before a new transfer, this condition could be caused by a new transfer before the end of the previous transfer */ - ((USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData)->state = CUSTOM_HID_IDLE; + ((USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId])->state = CUSTOM_HID_IDLE; return (uint8_t)USBD_OK; } @@ -668,17 +624,17 @@ static uint8_t USBD_CUSTOM_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) UNUSED(epnum); USBD_CUSTOM_HID_HandleTypeDef *hhid; - if (pdev->pClassData == NULL) + if (pdev->pClassDataCmsit[pdev->classId] == NULL) { return (uint8_t)USBD_FAIL; } - hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData; + hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; /* USB data will be immediately processed, this allow next USB traffic being NAKed till the end of the application processing */ - ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->OutEvent(hhid->Report_buf[0], - hhid->Report_buf[1]); + ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->OutEvent(hhid->Report_buf[0], + hhid->Report_buf[1]); return (uint8_t)USBD_OK; } @@ -694,15 +650,20 @@ uint8_t USBD_CUSTOM_HID_ReceivePacket(USBD_HandleTypeDef *pdev) { USBD_CUSTOM_HID_HandleTypeDef *hhid; - if (pdev->pClassData == NULL) + if (pdev->pClassDataCmsit[pdev->classId] == NULL) { return (uint8_t)USBD_FAIL; } - hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData; +#ifdef USE_USBD_COMPOSITE + /* Get OUT Endpoint address allocated for this class instance */ + CUSTOMHIDOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_INTR); +#endif /* USE_USBD_COMPOSITE */ + + hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; /* Resume USB Out process */ - (void)USBD_LL_PrepareReceive(pdev, CUSTOM_HID_EPOUT_ADDR, hhid->Report_buf, + (void)USBD_LL_PrepareReceive(pdev, CUSTOMHIDOutEpAdd, hhid->Report_buf, USBD_CUSTOMHID_OUTREPORT_BUF_SIZE); return (uint8_t)USBD_OK; @@ -717,7 +678,7 @@ uint8_t USBD_CUSTOM_HID_ReceivePacket(USBD_HandleTypeDef *pdev) */ static uint8_t USBD_CUSTOM_HID_EP0_RxReady(USBD_HandleTypeDef *pdev) { - USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData; + USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hhid == NULL) { @@ -726,14 +687,15 @@ static uint8_t USBD_CUSTOM_HID_EP0_RxReady(USBD_HandleTypeDef *pdev) if (hhid->IsReportAvailable == 1U) { - ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->OutEvent(hhid->Report_buf[0], - hhid->Report_buf[1]); + ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->OutEvent(hhid->Report_buf[0], + hhid->Report_buf[1]); hhid->IsReportAvailable = 0U; } return (uint8_t)USBD_OK; } +#ifndef USE_USBD_COMPOSITE /** * @brief DeviceQualifierDescriptor * return Device Qualifier descriptor @@ -746,7 +708,7 @@ static uint8_t *USBD_CUSTOM_HID_GetDeviceQualifierDesc(uint16_t *length) return USBD_CUSTOM_HID_DeviceQualifierDesc; } - +#endif /* USE_USBD_COMPOSITE */ /** * @brief USBD_CUSTOM_HID_RegisterInterface * @param pdev: device instance @@ -761,7 +723,7 @@ uint8_t USBD_CUSTOM_HID_RegisterInterface(USBD_HandleTypeDef *pdev, return (uint8_t)USBD_FAIL; } - pdev->pUserData = fops; + pdev->pUserData[pdev->classId] = fops; return (uint8_t)USBD_OK; } diff --git a/Class/CustomHID/Src/usbd_customhid_if_template.c b/Class/CustomHID/Src/usbd_customhid_if_template.c index 678da92..1f4d15b 100644 --- a/Class/CustomHID/Src/usbd_customhid_if_template.c +++ b/Class/CustomHID/Src/usbd_customhid_if_template.c @@ -34,6 +34,10 @@ static int8_t TEMPLATE_CUSTOM_HID_Init(void); static int8_t TEMPLATE_CUSTOM_HID_DeInit(void); static int8_t TEMPLATE_CUSTOM_HID_OutEvent(uint8_t event_idx, uint8_t state); /* Private variables ---------------------------------------------------------*/ +extern USBD_HandleTypeDef USBD_Device; + +__ALIGN_BEGIN static uint8_t TEMPLATE_CUSTOM_HID_ReportDesc[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END = {0}; + USBD_CUSTOM_HID_ItfTypeDef USBD_CustomHID_template_fops = { TEMPLATE_CUSTOM_HID_ReportDesc, @@ -83,7 +87,10 @@ static int8_t TEMPLATE_CUSTOM_HID_OutEvent(uint8_t event_idx, uint8_t state) UNUSED(state); /* Start next USB packet transfer once data processing is completed */ - USBD_CUSTOM_HID_ReceivePacket(&USBD_Device); + if (USBD_CUSTOM_HID_ReceivePacket(&USBD_Device) != (uint8_t)USBD_OK) + { + return -1; + } return (0); } diff --git a/Class/DFU/Inc/usbd_dfu.h b/Class/DFU/Inc/usbd_dfu.h index e91605a..7858394 100644 --- a/Class/DFU/Inc/usbd_dfu.h +++ b/Class/DFU/Inc/usbd_dfu.h @@ -52,6 +52,14 @@ extern "C" { #define USBD_DFU_APP_DEFAULT_ADD 0x08008000U /* The first sector (32 KB) is reserved for DFU code */ #endif /* USBD_DFU_APP_DEFAULT_ADD */ +#ifndef USBD_DFU_BM_ATTRIBUTES +#define USBD_DFU_BM_ATTRIBUTES 0x0BU +#endif /* USBD_DFU_BM_ATTRIBUTES */ + +#ifndef USBD_DFU_DETACH_TIMEOUT +#define USBD_DFU_DETACH_TIMEOUT 0xFFU +#endif /* USBD_DFU_DETACH_TIMEOUT */ + #define USB_DFU_CONFIG_DESC_SIZ (18U + (9U * USBD_DFU_MAX_ITF_NUM)) #define USB_DFU_DESC_SIZ 9U @@ -114,7 +122,8 @@ extern "C" { /* Other defines */ /**************************************************/ /* Bit Detach capable = bit 3 in bmAttributes field */ -#define DFU_DETACH_MASK (1U << 4) +#define DFU_DETACH_MASK (1U << 3) +#define DFU_MANIFEST_MASK (1U << 2) #define DFU_STATUS_DEPTH 6U typedef enum @@ -185,6 +194,17 @@ typedef struct uint8_t *(* Read)(uint8_t *src, uint8_t *dest, uint32_t Len); uint16_t (* GetStatus)(uint32_t Add, uint8_t cmd, uint8_t *buff); } USBD_DFU_MediaTypeDef; + +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bmAttributes; + uint16_t wDetachTimeout; + uint16_t wTransferSze; + uint16_t bcdDFUVersion; +} __PACKED USBD_DFUFuncDescTypeDef; + /** * @} */ diff --git a/Class/DFU/Src/usbd_dfu.c b/Class/DFU/Src/usbd_dfu.c index effc85d..5895497 100644 --- a/Class/DFU/Src/usbd_dfu.c +++ b/Class/DFU/Src/usbd_dfu.c @@ -104,13 +104,15 @@ static uint8_t USBD_DFU_EP0_RxReady(USBD_HandleTypeDef *pdev); static uint8_t USBD_DFU_EP0_TxReady(USBD_HandleTypeDef *pdev); static uint8_t USBD_DFU_SOF(USBD_HandleTypeDef *pdev); +#ifndef USE_USBD_COMPOSITE static uint8_t *USBD_DFU_GetCfgDesc(uint16_t *length); static uint8_t *USBD_DFU_GetDeviceQualifierDesc(uint16_t *length); +#endif /* USE_USBD_COMPOSITE */ #if (USBD_SUPPORT_USER_STRING_DESC == 1U) static uint8_t *USBD_DFU_GetUsrStringDesc(USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length); -#endif +#endif /* USBD_SUPPORT_USER_STRING_DESC */ static void DFU_Detach(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); static void DFU_Download(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); @@ -120,6 +122,7 @@ static void DFU_ClearStatus(USBD_HandleTypeDef *pdev); static void DFU_GetState(USBD_HandleTypeDef *pdev); static void DFU_Abort(USBD_HandleTypeDef *pdev); static void DFU_Leave(USBD_HandleTypeDef *pdev); +static void *USBD_DFU_GetDfuFuncDesc(uint8_t *pConfDesc); /** * @} @@ -141,15 +144,23 @@ USBD_ClassTypeDef USBD_DFU = USBD_DFU_SOF, NULL, NULL, +#ifdef USE_USBD_COMPOSITE + NULL, + NULL, + NULL, + NULL, +#else USBD_DFU_GetCfgDesc, USBD_DFU_GetCfgDesc, USBD_DFU_GetCfgDesc, USBD_DFU_GetDeviceQualifierDesc, +#endif /* USE_USBD_COMPOSITE */ #if (USBD_SUPPORT_USER_STRING_DESC == 1U) USBD_DFU_GetUsrStringDesc -#endif +#endif /* USBD_SUPPORT_USER_STRING_DESC */ }; +#ifndef USE_USBD_COMPOSITE /* USB DFU device Configuration Descriptor */ __ALIGN_BEGIN static uint8_t USBD_DFU_CfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END = { @@ -159,12 +170,13 @@ __ALIGN_BEGIN static uint8_t USBD_DFU_CfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_E 0x00, 0x01, /* bNumInterfaces: 1 interface */ 0x01, /* bConfigurationValue: Configuration value */ - 0x02, /* iConfiguration: Index of string descriptor describing the configuration */ + 0x02, /* iConfiguration: Index of string descriptor + describing the configuration */ #if (USBD_SELF_POWERED == 1U) 0xC0, /* bmAttributes: Bus Powered according to user configuration */ #else 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif +#endif /* USBD_SELF_POWERED */ USBD_MAX_POWER, /* MaxPower (mA) */ /* 09 */ @@ -235,6 +247,7 @@ __ALIGN_BEGIN static uint8_t USBD_DFU_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_ 0x01, 0x00, }; +#endif /* USE_USBD_COMPOSITE */ /** * @} @@ -262,11 +275,12 @@ static uint8_t USBD_DFU_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) if (hdfu == NULL) { - pdev->pClassData = NULL; + pdev->pClassDataCmsit[pdev->classId] = NULL; return (uint8_t)USBD_EMEM; } - pdev->pClassData = (void *)hdfu; + pdev->pClassDataCmsit[pdev->classId] = (void *)hdfu; + pdev->pClassData = pdev->pClassDataCmsit[pdev->classId]; hdfu->alt_setting = 0U; hdfu->data_ptr = USBD_DFU_APP_DEFAULT_ADD; @@ -284,7 +298,7 @@ static uint8_t USBD_DFU_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) hdfu->dev_status[5] = 0U; /* Initialize Hardware layer */ - if (((USBD_DFU_MediaTypeDef *)pdev->pUserData)->Init() != USBD_OK) + if (((USBD_DFU_MediaTypeDef *)pdev->pUserData[pdev->classId])->Init() != USBD_OK) { return (uint8_t)USBD_FAIL; } @@ -293,7 +307,7 @@ static uint8_t USBD_DFU_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) } /** - * @brief USBD_DFU_Init + * @brief USBD_DFU_DeInit * De-Initialize the DFU layer * @param pdev: device instance * @param cfgidx: Configuration index @@ -304,12 +318,12 @@ static uint8_t USBD_DFU_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) UNUSED(cfgidx); USBD_DFU_HandleTypeDef *hdfu; - if (pdev->pClassData == NULL) + if (pdev->pClassDataCmsit[pdev->classId] == NULL) { return (uint8_t)USBD_EMEM; } - hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; + hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; hdfu->wblock_num = 0U; hdfu->wlength = 0U; @@ -318,8 +332,9 @@ static uint8_t USBD_DFU_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) hdfu->dev_status[4] = DFU_STATE_IDLE; /* DeInit physical Interface components and Hardware Layer */ - ((USBD_DFU_MediaTypeDef *)pdev->pUserData)->DeInit(); - USBD_free(pdev->pClassData); + ((USBD_DFU_MediaTypeDef *)pdev->pUserData[pdev->classId])->DeInit(); + USBD_free(pdev->pClassDataCmsit[pdev->classId]); + pdev->pClassDataCmsit[pdev->classId] = NULL; pdev->pClassData = NULL; return (uint8_t)USBD_OK; @@ -334,10 +349,10 @@ static uint8_t USBD_DFU_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) */ static uint8_t USBD_DFU_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { - USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; USBD_StatusTypeDef ret = USBD_OK; - uint8_t *pbuf = NULL; - uint16_t len = 0U; + uint8_t *pbuf; + uint16_t len; uint16_t status_info = 0U; if (hdfu == NULL) @@ -403,11 +418,19 @@ static uint8_t USBD_DFU_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *re case USB_REQ_GET_DESCRIPTOR: if ((req->wValue >> 8) == DFU_DESCRIPTOR_TYPE) { - pbuf = USBD_DFU_CfgDesc + (9U * (USBD_DFU_MAX_ITF_NUM + 1U)); - len = MIN(USB_DFU_DESC_SIZ, req->wLength); - } + pbuf = (uint8_t *)USBD_DFU_GetDfuFuncDesc(pdev->pConfDesc); - (void)USBD_CtlSendData(pdev, pbuf, len); + if (pbuf != NULL) + { + len = MIN(USB_DFU_DESC_SIZ, req->wLength); + (void)USBD_CtlSendData(pdev, pbuf, len); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + } break; case USB_REQ_GET_INTERFACE: @@ -462,7 +485,7 @@ static uint8_t USBD_DFU_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *re return (uint8_t)ret; } - +#ifndef USE_USBD_COMPOSITE /** * @brief USBD_DFU_GetCfgDesc * return configuration descriptor @@ -475,7 +498,7 @@ static uint8_t *USBD_DFU_GetCfgDesc(uint16_t *length) return USBD_DFU_CfgDesc; } - +#endif /* USE_USBD_COMPOSITE */ /** * @brief USBD_DFU_EP0_RxReady @@ -499,8 +522,8 @@ static uint8_t USBD_DFU_EP0_TxReady(USBD_HandleTypeDef *pdev) { USBD_SetupReqTypedef req; uint32_t addr; - USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; - USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData; + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData[pdev->classId]; if (hdfu == NULL) { @@ -609,7 +632,7 @@ static uint8_t USBD_DFU_SOF(USBD_HandleTypeDef *pdev) return (uint8_t)USBD_OK; } - +#ifndef USE_USBD_COMPOSITE /** * @brief DeviceQualifierDescriptor * return Device Qualifier descriptor @@ -622,6 +645,7 @@ static uint8_t *USBD_DFU_GetDeviceQualifierDesc(uint16_t *length) return USBD_DFU_DeviceQualifierDesc; } +#endif /* USE_USBD_COMPOSITE */ /** * @brief USBD_DFU_GetUsrStringDesc @@ -635,7 +659,7 @@ static uint8_t *USBD_DFU_GetDeviceQualifierDesc(uint16_t *length) static uint8_t *USBD_DFU_GetUsrStringDesc(USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length) { static uint8_t USBD_StrDesc[255]; - USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData; + USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData[pdev->classId]; /* Check if the requested string interface is supported */ if (index <= (USBD_IDX_INTERFACE_STR + USBD_DFU_MAX_ITF_NUM)) @@ -646,10 +670,11 @@ static uint8_t *USBD_DFU_GetUsrStringDesc(USBD_HandleTypeDef *pdev, uint8_t inde else { /* Not supported Interface Descriptor index */ + length = 0U; return NULL; } } -#endif +#endif /* USBD_SUPPORT_USER_STRING_DESC */ /** * @brief USBD_MSC_RegisterStorage @@ -665,7 +690,7 @@ uint8_t USBD_DFU_RegisterMedia(USBD_HandleTypeDef *pdev, return (uint8_t)USBD_FAIL; } - pdev->pUserData = fops; + pdev->pUserData[pdev->classId] = fops; return (uint8_t)USBD_OK; } @@ -682,9 +707,10 @@ uint8_t USBD_DFU_RegisterMedia(USBD_HandleTypeDef *pdev, */ static void DFU_Detach(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { - USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_DFUFuncDescTypeDef *pDfuFunc = (USBD_DFUFuncDescTypeDef *)USBD_DFU_GetDfuFuncDesc(pdev->pConfDesc); - if (hdfu == NULL) + if ((hdfu == NULL) || (pDfuFunc == NULL)) { return; } @@ -708,7 +734,7 @@ static void DFU_Detach(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) } /* Check the detach capability in the DFU functional descriptor */ - if (((USBD_DFU_CfgDesc[12U + (9U * USBD_DFU_MAX_ITF_NUM)]) & DFU_DETACH_MASK) != 0U) + if ((pDfuFunc->bmAttributes & DFU_DETACH_MASK) != 0U) { /* Perform an Attach-Detach operation on USB bus */ (void)USBD_Stop(pdev); @@ -730,7 +756,7 @@ static void DFU_Detach(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) */ static void DFU_Download(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { - USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hdfu == NULL) { @@ -790,8 +816,8 @@ static void DFU_Download(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) */ static void DFU_Upload(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { - USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; - USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData; + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData[pdev->classId]; uint8_t *phaddr; uint32_t addr; @@ -888,10 +914,11 @@ static void DFU_Upload(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) */ static void DFU_GetStatus(USBD_HandleTypeDef *pdev) { - USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; - USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData; + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData[pdev->classId]; + USBD_DFUFuncDescTypeDef *pDfuFunc = (USBD_DFUFuncDescTypeDef *)USBD_DFU_GetDfuFuncDesc(pdev->pConfDesc); - if (hdfu == NULL) + if ((hdfu == NULL) || (DfuInterface == NULL) || (pDfuFunc == NULL)) { return; } @@ -941,7 +968,7 @@ static void DFU_GetStatus(USBD_HandleTypeDef *pdev) else { if ((hdfu->manif_state == DFU_MANIFEST_COMPLETE) && - (((USBD_DFU_CfgDesc[(11U + (9U * USBD_DFU_MAX_ITF_NUM))]) & 0x04U) != 0U)) + ((pDfuFunc->bmAttributes & DFU_MANIFEST_MASK) != 0U)) { hdfu->dev_state = DFU_STATE_IDLE; @@ -969,7 +996,7 @@ static void DFU_GetStatus(USBD_HandleTypeDef *pdev) */ static void DFU_ClearStatus(USBD_HandleTypeDef *pdev) { - USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hdfu == NULL) { @@ -1007,7 +1034,7 @@ static void DFU_ClearStatus(USBD_HandleTypeDef *pdev) */ static void DFU_GetState(USBD_HandleTypeDef *pdev) { - USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hdfu == NULL) { @@ -1026,7 +1053,7 @@ static void DFU_GetState(USBD_HandleTypeDef *pdev) */ static void DFU_Abort(USBD_HandleTypeDef *pdev) { - USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hdfu == NULL) { @@ -1060,16 +1087,17 @@ static void DFU_Abort(USBD_HandleTypeDef *pdev) */ static void DFU_Leave(USBD_HandleTypeDef *pdev) { - USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_DFUFuncDescTypeDef *pDfuFunc = (USBD_DFUFuncDescTypeDef *)USBD_DFU_GetDfuFuncDesc(pdev->pConfDesc); - if (hdfu == NULL) + if ((hdfu == NULL) || (pDfuFunc == NULL)) { return; } hdfu->manif_state = DFU_MANIFEST_COMPLETE; - if (((USBD_DFU_CfgDesc[(11U + (9U * USBD_DFU_MAX_ITF_NUM))]) & 0x04U) != 0U) + if ((pDfuFunc->bmAttributes & DFU_MANIFEST_MASK) != 0U) { hdfu->dev_state = DFU_STATE_MANIFEST_SYNC; @@ -1098,6 +1126,38 @@ static void DFU_Leave(USBD_HandleTypeDef *pdev) } } +/** + * @brief USBD_DFU_GetDfuFuncDesc + * This function return the DFU descriptor + * @param pdev: device instance + * @param pConfDesc: pointer to Bos descriptor + * @retval pointer to the DFU descriptor + */ +static void *USBD_DFU_GetDfuFuncDesc(uint8_t *pConfDesc) +{ + USBD_ConfigDescTypeDef *desc = (USBD_ConfigDescTypeDef *)(void *)pConfDesc; + USBD_DescHeaderTypeDef *pdesc = (USBD_DescHeaderTypeDef *)(void *)pConfDesc; + uint8_t *pDfuDesc = NULL; + uint16_t ptr; + + if (desc->wTotalLength > desc->bLength) + { + ptr = desc->bLength; + + while (ptr < desc->wTotalLength) + { + pdesc = USBD_GetNextDesc((uint8_t *)pdesc, &ptr); + + if (pdesc->bDescriptorType == DFU_DESCRIPTOR_TYPE) + { + pDfuDesc = (uint8_t *)pdesc; + break; + } + } + } + return pDfuDesc; +} + /** * @} */ diff --git a/Class/DFU/Src/usbd_dfu_media_template.c b/Class/DFU/Src/usbd_dfu_media_template.c index f2f55d0..679d326 100644 --- a/Class/DFU/Src/usbd_dfu_media_template.c +++ b/Class/DFU/Src/usbd_dfu_media_template.c @@ -80,6 +80,8 @@ uint16_t MEM_If_DeInit(void) */ uint16_t MEM_If_Erase(uint32_t Add) { + UNUSED(Add); + return 0; } @@ -92,6 +94,10 @@ uint16_t MEM_If_Erase(uint32_t Add) */ uint16_t MEM_If_Write(uint8_t *src, uint8_t *dest, uint32_t Len) { + UNUSED(src); + UNUSED(dest); + UNUSED(Len); + return 0; } @@ -104,6 +110,10 @@ uint16_t MEM_If_Write(uint8_t *src, uint8_t *dest, uint32_t Len) */ uint8_t *MEM_If_Read(uint8_t *src, uint8_t *dest, uint32_t Len) { + UNUSED(src); + UNUSED(dest); + UNUSED(Len); + /* Return a valid address to avoid HardFault */ return (uint8_t *)(0); } @@ -117,6 +127,9 @@ uint8_t *MEM_If_Read(uint8_t *src, uint8_t *dest, uint32_t Len) */ uint16_t MEM_If_GetStatus(uint32_t Add, uint8_t Cmd, uint8_t *buffer) { + UNUSED(Add); + UNUSED(buffer); + switch (Cmd) { case DFU_MEDIA_PROGRAM: diff --git a/Class/HID/Inc/usbd_hid.h b/Class/HID/Inc/usbd_hid.h index 4b9a0ca..ed0c9bb 100644 --- a/Class/HID/Inc/usbd_hid.h +++ b/Class/HID/Inc/usbd_hid.h @@ -40,7 +40,9 @@ extern "C" { /** @defgroup USBD_HID_Exported_Defines * @{ */ +#ifndef HID_EPIN_ADDR #define HID_EPIN_ADDR 0x81U +#endif /* HID_EPIN_ADDR */ #define HID_EPIN_SIZE 0x04U #define USB_HID_CONFIG_DESC_SIZ 34U @@ -88,6 +90,23 @@ typedef struct uint32_t AltSetting; HID_StateTypeDef state; } USBD_HID_HandleTypeDef; + +/* + * HID Class specification version 1.1 + * 6.2.1 HID Descriptor + */ + +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdHID; + uint8_t bCountryCode; + uint8_t bNumDescriptors; + uint8_t bHIDDescriptorType; + uint16_t wItemLength; +} __PACKED USBD_HIDDescTypeDef; + /** * @} */ diff --git a/Class/HID/Src/usbd_hid.c b/Class/HID/Src/usbd_hid.c index 9da7650..075a660 100644 --- a/Class/HID/Src/usbd_hid.c +++ b/Class/HID/Src/usbd_hid.c @@ -91,12 +91,12 @@ static uint8_t USBD_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx); static uint8_t USBD_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx); static uint8_t USBD_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); static uint8_t USBD_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); - +#ifndef USE_USBD_COMPOSITE static uint8_t *USBD_HID_GetFSCfgDesc(uint16_t *length); static uint8_t *USBD_HID_GetHSCfgDesc(uint16_t *length); static uint8_t *USBD_HID_GetOtherSpeedCfgDesc(uint16_t *length); static uint8_t *USBD_HID_GetDeviceQualifierDesc(uint16_t *length); - +#endif /* USE_USBD_COMPOSITE */ /** * @} */ @@ -117,14 +117,22 @@ USBD_ClassTypeDef USBD_HID = NULL, /* SOF */ NULL, NULL, +#ifdef USE_USBD_COMPOSITE + NULL, + NULL, + NULL, + NULL, +#else USBD_HID_GetHSCfgDesc, USBD_HID_GetFSCfgDesc, USBD_HID_GetOtherSpeedCfgDesc, USBD_HID_GetDeviceQualifierDesc, +#endif /* USE_USBD_COMPOSITE */ }; +#ifndef USE_USBD_COMPOSITE /* USB HID device FS Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_HID_CfgFSDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END = +__ALIGN_BEGIN static uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END = { 0x09, /* bLength: Configuration Descriptor size */ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ @@ -132,12 +140,13 @@ __ALIGN_BEGIN static uint8_t USBD_HID_CfgFSDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN 0x00, 0x01, /* bNumInterfaces: 1 interface */ 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ + 0x00, /* iConfiguration: Index of string descriptor + describing the configuration */ #if (USBD_SELF_POWERED == 1U) 0xE0, /* bmAttributes: Bus Powered according to user configuration */ #else 0xA0, /* bmAttributes: Bus Powered according to user configuration */ -#endif +#endif /* USBD_SELF_POWERED */ USBD_MAX_POWER, /* MaxPower (mA) */ /************** Descriptor of Joystick Mouse interface ****************/ @@ -174,111 +183,7 @@ __ALIGN_BEGIN static uint8_t USBD_HID_CfgFSDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN HID_FS_BINTERVAL, /* bInterval: Polling Interval */ /* 34 */ }; - -/* USB HID device HS Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_HID_CfgHSDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END = -{ - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - USB_HID_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ - 0x00, - 0x01, /* bNumInterfaces: 1 interface */ - 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ -#if (USBD_SELF_POWERED == 1U) - 0xE0, /* bmAttributes: Bus Powered according to user configuration */ -#else - 0xA0, /* bmAttributes: Bus Powered according to user configuration */ -#endif - USBD_MAX_POWER, /* MaxPower (mA) */ - - /************** Descriptor of Joystick Mouse interface ****************/ - /* 09 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /******************** Descriptor of Joystick Mouse HID ********************/ - /* 18 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ - 0x00, - /******************** Descriptor of Mouse endpoint ********************/ - /* 27 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ - - HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_EPIN_SIZE, /* wMaxPacketSize: 4 Bytes max */ - 0x00, - HID_HS_BINTERVAL, /* bInterval: Polling Interval */ - /* 34 */ -}; - -/* USB HID device Other Speed Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_HID_OtherSpeedCfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END = -{ - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - USB_HID_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ - 0x00, - 0x01, /* bNumInterfaces: 1 interface */ - 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ -#if (USBD_SELF_POWERED == 1U) - 0xE0, /* bmAttributes: Bus Powered according to user configuration */ -#else - 0xA0, /* bmAttributes: Bus Powered according to user configuration */ -#endif - USBD_MAX_POWER, /* MaxPower (mA) */ - - /************** Descriptor of Joystick Mouse interface ****************/ - /* 09 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /******************** Descriptor of Joystick Mouse HID ********************/ - /* 18 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ - 0x00, - /******************** Descriptor of Mouse endpoint ********************/ - /* 27 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ - - HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_EPIN_SIZE, /* wMaxPacketSize: 4 Bytes max */ - 0x00, - HID_FS_BINTERVAL, /* bInterval: Polling Interval */ - /* 34 */ -}; - +#endif /* USE_USBD_COMPOSITE */ /* USB HID device Configuration Descriptor */ __ALIGN_BEGIN static uint8_t USBD_HID_Desc[USB_HID_DESC_SIZ] __ALIGN_END = @@ -295,6 +200,7 @@ __ALIGN_BEGIN static uint8_t USBD_HID_Desc[USB_HID_DESC_SIZ] __ALIGN_END = 0x00, }; +#ifndef USE_USBD_COMPOSITE /* USB Standard Device Descriptor */ __ALIGN_BEGIN static uint8_t USBD_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = { @@ -309,6 +215,7 @@ __ALIGN_BEGIN static uint8_t USBD_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_ 0x01, 0x00, }; +#endif /* USE_USBD_COMPOSITE */ __ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END = { @@ -352,6 +259,8 @@ __ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ 0xC0 /* End Collection */ }; +static uint8_t HIDInEpAdd = HID_EPIN_ADDR; + /** * @} */ @@ -377,24 +286,30 @@ static uint8_t USBD_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) if (hhid == NULL) { - pdev->pClassData = NULL; + pdev->pClassDataCmsit[pdev->classId] = NULL; return (uint8_t)USBD_EMEM; } - pdev->pClassData = (void *)hhid; + pdev->pClassDataCmsit[pdev->classId] = (void *)hhid; + pdev->pClassData = pdev->pClassDataCmsit[pdev->classId]; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + HIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR); +#endif /* USE_USBD_COMPOSITE */ if (pdev->dev_speed == USBD_SPEED_HIGH) { - pdev->ep_in[HID_EPIN_ADDR & 0xFU].bInterval = HID_HS_BINTERVAL; + pdev->ep_in[HIDInEpAdd & 0xFU].bInterval = HID_HS_BINTERVAL; } else /* LOW and FULL-speed endpoints */ { - pdev->ep_in[HID_EPIN_ADDR & 0xFU].bInterval = HID_FS_BINTERVAL; + pdev->ep_in[HIDInEpAdd & 0xFU].bInterval = HID_FS_BINTERVAL; } /* Open EP IN */ - (void)USBD_LL_OpenEP(pdev, HID_EPIN_ADDR, USBD_EP_TYPE_INTR, HID_EPIN_SIZE); - pdev->ep_in[HID_EPIN_ADDR & 0xFU].is_used = 1U; + (void)USBD_LL_OpenEP(pdev, HIDInEpAdd, USBD_EP_TYPE_INTR, HID_EPIN_SIZE); + pdev->ep_in[HIDInEpAdd & 0xFU].is_used = 1U; hhid->state = HID_IDLE; @@ -412,16 +327,21 @@ static uint8_t USBD_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { UNUSED(cfgidx); +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + HIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR); +#endif /* USE_USBD_COMPOSITE */ + /* Close HID EPs */ - (void)USBD_LL_CloseEP(pdev, HID_EPIN_ADDR); - pdev->ep_in[HID_EPIN_ADDR & 0xFU].is_used = 0U; - pdev->ep_in[HID_EPIN_ADDR & 0xFU].bInterval = 0U; + (void)USBD_LL_CloseEP(pdev, HIDInEpAdd); + pdev->ep_in[HIDInEpAdd & 0xFU].is_used = 0U; + pdev->ep_in[HIDInEpAdd & 0xFU].bInterval = 0U; /* Free allocated memory */ - if (pdev->pClassData != NULL) + if (pdev->pClassDataCmsit[pdev->classId] != NULL) { - (void)USBD_free(pdev->pClassData); - pdev->pClassData = NULL; + (void)USBD_free(pdev->pClassDataCmsit[pdev->classId]); + pdev->pClassDataCmsit[pdev->classId] = NULL; } return (uint8_t)USBD_OK; @@ -436,7 +356,7 @@ static uint8_t USBD_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) */ static uint8_t USBD_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { - USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)pdev->pClassData; + USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; USBD_StatusTypeDef ret = USBD_OK; uint16_t len; uint8_t *pbuf; @@ -561,19 +481,24 @@ static uint8_t USBD_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *re */ uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len) { - USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)pdev->pClassData; + USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hhid == NULL) { return (uint8_t)USBD_FAIL; } +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + HIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR); +#endif /* USE_USBD_COMPOSITE */ + if (pdev->dev_state == USBD_STATE_CONFIGURED) { if (hhid->state == HID_IDLE) { hhid->state = HID_BUSY; - (void)USBD_LL_Transmit(pdev, HID_EPIN_ADDR, report, len); + (void)USBD_LL_Transmit(pdev, HIDInEpAdd, report, len); } } @@ -608,6 +533,7 @@ uint32_t USBD_HID_GetPollingInterval(USBD_HandleTypeDef *pdev) return ((uint32_t)(polling_interval)); } +#ifndef USE_USBD_COMPOSITE /** * @brief USBD_HID_GetCfgFSDesc * return FS configuration descriptor @@ -617,9 +543,15 @@ uint32_t USBD_HID_GetPollingInterval(USBD_HandleTypeDef *pdev) */ static uint8_t *USBD_HID_GetFSCfgDesc(uint16_t *length) { - *length = (uint16_t)sizeof(USBD_HID_CfgFSDesc); + USBD_EpDescTypeDef *pEpDesc = USBD_GetEpDesc(USBD_HID_CfgDesc, HID_EPIN_ADDR); - return USBD_HID_CfgFSDesc; + if (pEpDesc != NULL) + { + pEpDesc->bInterval = HID_FS_BINTERVAL; + } + + *length = (uint16_t)sizeof(USBD_HID_CfgDesc); + return USBD_HID_CfgDesc; } /** @@ -631,9 +563,15 @@ static uint8_t *USBD_HID_GetFSCfgDesc(uint16_t *length) */ static uint8_t *USBD_HID_GetHSCfgDesc(uint16_t *length) { - *length = (uint16_t)sizeof(USBD_HID_CfgHSDesc); + USBD_EpDescTypeDef *pEpDesc = USBD_GetEpDesc(USBD_HID_CfgDesc, HID_EPIN_ADDR); - return USBD_HID_CfgHSDesc; + if (pEpDesc != NULL) + { + pEpDesc->bInterval = HID_HS_BINTERVAL; + } + + *length = (uint16_t)sizeof(USBD_HID_CfgDesc); + return USBD_HID_CfgDesc; } /** @@ -645,10 +583,17 @@ static uint8_t *USBD_HID_GetHSCfgDesc(uint16_t *length) */ static uint8_t *USBD_HID_GetOtherSpeedCfgDesc(uint16_t *length) { - *length = (uint16_t)sizeof(USBD_HID_OtherSpeedCfgDesc); + USBD_EpDescTypeDef *pEpDesc = USBD_GetEpDesc(USBD_HID_CfgDesc, HID_EPIN_ADDR); - return USBD_HID_OtherSpeedCfgDesc; + if (pEpDesc != NULL) + { + pEpDesc->bInterval = HID_FS_BINTERVAL; + } + + *length = (uint16_t)sizeof(USBD_HID_CfgDesc); + return USBD_HID_CfgDesc; } +#endif /* USE_USBD_COMPOSITE */ /** * @brief USBD_HID_DataIn @@ -662,12 +607,12 @@ static uint8_t USBD_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) UNUSED(epnum); /* Ensure that the FIFO is empty before a new transfer, this condition could be caused by a new transfer before the end of the previous transfer */ - ((USBD_HID_HandleTypeDef *)pdev->pClassData)->state = HID_IDLE; + ((USBD_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId])->state = HID_IDLE; return (uint8_t)USBD_OK; } - +#ifndef USE_USBD_COMPOSITE /** * @brief DeviceQualifierDescriptor * return Device Qualifier descriptor @@ -680,7 +625,7 @@ static uint8_t *USBD_HID_GetDeviceQualifierDesc(uint16_t *length) return USBD_HID_DeviceQualifierDesc; } - +#endif /* USE_USBD_COMPOSITE */ /** * @} */ diff --git a/Class/MSC/Inc/usbd_msc.h b/Class/MSC/Inc/usbd_msc.h index 56e6c79..e55fef4 100644 --- a/Class/MSC/Inc/usbd_msc.h +++ b/Class/MSC/Inc/usbd_msc.h @@ -54,9 +54,13 @@ extern "C" { #define BOT_RESET 0xFF #define USB_MSC_CONFIG_DESC_SIZ 32 - +#ifndef MSC_EPIN_ADDR #define MSC_EPIN_ADDR 0x81U +#endif /* MSC_EPIN_ADDR */ + +#ifndef MSC_EPOUT_ADDR #define MSC_EPOUT_ADDR 0x01U +#endif /* MSC_EPOUT_ADDR */ /** * @} @@ -100,8 +104,7 @@ typedef struct uint32_t scsi_blk_addr; uint32_t scsi_blk_len; -} -USBD_MSC_BOT_HandleTypeDef; +} USBD_MSC_BOT_HandleTypeDef; /* Structure for MSC process */ extern USBD_ClassTypeDef USBD_MSC; diff --git a/Class/MSC/Inc/usbd_msc_bot.h b/Class/MSC/Inc/usbd_msc_bot.h index f8b667f..8550a39 100644 --- a/Class/MSC/Inc/usbd_msc_bot.h +++ b/Class/MSC/Inc/usbd_msc_bot.h @@ -86,8 +86,7 @@ typedef struct uint8_t bCBLength; uint8_t CB[16]; uint8_t ReservedForAlign; -} -USBD_MSC_BOT_CBWTypeDef; +} USBD_MSC_BOT_CBWTypeDef; typedef struct @@ -97,8 +96,7 @@ typedef struct uint32_t dDataResidue; uint8_t bStatus; uint8_t ReservedForAlign[3]; -} -USBD_MSC_BOT_CSWTypeDef; +} USBD_MSC_BOT_CSWTypeDef; /** * @} diff --git a/Class/MSC/Src/usbd_msc.c b/Class/MSC/Src/usbd_msc.c index 9a80df4..ad5daeb 100644 --- a/Class/MSC/Src/usbd_msc.c +++ b/Class/MSC/Src/usbd_msc.c @@ -86,11 +86,12 @@ uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); uint8_t USBD_MSC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); uint8_t USBD_MSC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum); +#ifndef USE_USBD_COMPOSITE uint8_t *USBD_MSC_GetHSCfgDesc(uint16_t *length); uint8_t *USBD_MSC_GetFSCfgDesc(uint16_t *length); uint8_t *USBD_MSC_GetOtherSpeedCfgDesc(uint16_t *length); uint8_t *USBD_MSC_GetDeviceQualifierDescriptor(uint16_t *length); - +#endif /* USE_USBD_COMPOSITE */ /** * @} */ @@ -113,62 +114,24 @@ USBD_ClassTypeDef USBD_MSC = NULL, /*SOF */ NULL, NULL, +#ifdef USE_USBD_COMPOSITE + NULL, + NULL, + NULL, + NULL, +#else USBD_MSC_GetHSCfgDesc, USBD_MSC_GetFSCfgDesc, USBD_MSC_GetOtherSpeedCfgDesc, USBD_MSC_GetDeviceQualifierDescriptor, +#endif /* USE_USBD_COMPOSITE */ }; /* USB Mass storage device Configuration Descriptor */ -/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */ -__ALIGN_BEGIN static uint8_t USBD_MSC_CfgHSDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END = -{ - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - USB_MSC_CONFIG_DESC_SIZ, - - 0x00, - 0x01, /* bNumInterfaces: 1 interface */ - 0x01, /* bConfigurationValue */ - 0x04, /* iConfiguration */ -#if (USBD_SELF_POWERED == 1U) - 0xC0, /* bmAttributes: Bus Powered according to user configuration */ -#else - 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif - USBD_MAX_POWER, /* MaxPower (mA) */ - - /******************** Mass Storage interface ********************/ - 0x09, /* bLength: Interface Descriptor size */ - 0x04, /* bDescriptorType: */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints */ - 0x08, /* bInterfaceClass: MSC Class */ - 0x06, /* bInterfaceSubClass : SCSI transparent */ - 0x50, /* nInterfaceProtocol */ - 0x05, /* iInterface */ - /******************** Mass Storage Endpoints ********************/ - 0x07, /* Endpoint descriptor length = 7 */ - 0x05, /* Endpoint descriptor type */ - MSC_EPIN_ADDR, /* Endpoint address (IN, address 1) */ - 0x02, /* Bulk endpoint type */ - LOBYTE(MSC_MAX_HS_PACKET), - HIBYTE(MSC_MAX_HS_PACKET), - 0x00, /* Polling interval in milliseconds */ - - 0x07, /* Endpoint descriptor length = 7 */ - 0x05, /* Endpoint descriptor type */ - MSC_EPOUT_ADDR, /* Endpoint address (OUT, address 1) */ - 0x02, /* Bulk endpoint type */ - LOBYTE(MSC_MAX_HS_PACKET), - HIBYTE(MSC_MAX_HS_PACKET), - 0x00 /* Polling interval in milliseconds */ -}; - +#ifndef USE_USBD_COMPOSITE /* USB Mass storage device Configuration Descriptor */ /* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */ -__ALIGN_BEGIN static uint8_t USBD_MSC_CfgFSDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END = +__ALIGN_BEGIN static uint8_t USBD_MSC_CfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END = { 0x09, /* bLength: Configuration Descriptor size */ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ @@ -182,7 +145,7 @@ __ALIGN_BEGIN static uint8_t USBD_MSC_CfgFSDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIG 0xC0, /* bmAttributes: Bus Powered according to user configuration */ #else 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif +#endif /* USBD_SELF_POWERED */ USBD_MAX_POWER, /* MaxPower (mA) */ /******************** Mass Storage interface ********************/ @@ -213,51 +176,6 @@ __ALIGN_BEGIN static uint8_t USBD_MSC_CfgFSDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIG 0x00 /* Polling interval in milliseconds */ }; -__ALIGN_BEGIN static uint8_t USBD_MSC_OtherSpeedCfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END = -{ - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, - USB_MSC_CONFIG_DESC_SIZ, - - 0x00, - 0x01, /* bNumInterfaces: 1 interface */ - 0x01, /* bConfigurationValue */ - 0x04, /* iConfiguration */ -#if (USBD_SELF_POWERED == 1U) - 0xC0, /* bmAttributes: Bus Powered according to user configuration */ -#else - 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif - USBD_MAX_POWER, /* MaxPower (mA) */ - - /******************** Mass Storage interface ********************/ - 0x09, /* bLength: Interface Descriptor size */ - 0x04, /* bDescriptorType */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints */ - 0x08, /* bInterfaceClass: MSC Class */ - 0x06, /* bInterfaceSubClass : SCSI transparent command set */ - 0x50, /* nInterfaceProtocol */ - 0x05, /* iInterface */ - /******************** Mass Storage Endpoints ********************/ - 0x07, /* Endpoint descriptor length = 7 */ - 0x05, /* Endpoint descriptor type */ - MSC_EPIN_ADDR, /* Endpoint address (IN, address 1) */ - 0x02, /* Bulk endpoint type */ - 0x40, - 0x00, - 0x00, /* Polling interval in milliseconds */ - - 0x07, /* Endpoint descriptor length = 7 */ - 0x05, /* Endpoint descriptor type */ - MSC_EPOUT_ADDR, /* Endpoint address (OUT, address 1) */ - 0x02, /* Bulk endpoint type */ - 0x40, - 0x00, - 0x00 /* Polling interval in milliseconds */ -}; - /* USB Standard Device Descriptor */ __ALIGN_BEGIN static uint8_t USBD_MSC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = { @@ -272,6 +190,11 @@ __ALIGN_BEGIN static uint8_t USBD_MSC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_ 0x01, 0x00, }; +#endif /* USE_USBD_COMPOSITE */ + +uint8_t MSCInEpAdd = MSC_EPIN_ADDR; +uint8_t MSCOutEpAdd = MSC_EPOUT_ADDR; + /** * @} */ @@ -297,31 +220,38 @@ uint8_t USBD_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) if (hmsc == NULL) { - pdev->pClassData = NULL; + pdev->pClassDataCmsit[pdev->classId] = NULL; return (uint8_t)USBD_EMEM; } - pdev->pClassData = (void *)hmsc; + pdev->pClassDataCmsit[pdev->classId] = (void *)hmsc; + pdev->pClassData = pdev->pClassDataCmsit[pdev->classId]; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + MSCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); + MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ if (pdev->dev_speed == USBD_SPEED_HIGH) { /* Open EP OUT */ - (void)USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET); - pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 1U; + (void)USBD_LL_OpenEP(pdev, MSCOutEpAdd, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET); + pdev->ep_out[MSCOutEpAdd & 0xFU].is_used = 1U; /* Open EP IN */ - (void)USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET); - pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 1U; + (void)USBD_LL_OpenEP(pdev, MSCInEpAdd, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET); + pdev->ep_in[MSCInEpAdd & 0xFU].is_used = 1U; } else { /* Open EP OUT */ - (void)USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET); - pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 1U; + (void)USBD_LL_OpenEP(pdev, MSCOutEpAdd, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET); + pdev->ep_out[MSCOutEpAdd & 0xFU].is_used = 1U; /* Open EP IN */ - (void)USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET); - pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 1U; + (void)USBD_LL_OpenEP(pdev, MSCInEpAdd, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET); + pdev->ep_in[MSCInEpAdd & 0xFU].is_used = 1U; } /* Init the BOT layer */ @@ -341,21 +271,28 @@ uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { UNUSED(cfgidx); +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + MSCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); + MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ + /* Close MSC EPs */ - (void)USBD_LL_CloseEP(pdev, MSC_EPOUT_ADDR); - pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 0U; + (void)USBD_LL_CloseEP(pdev, MSCOutEpAdd); + pdev->ep_out[MSCOutEpAdd & 0xFU].is_used = 0U; /* Close EP IN */ - (void)USBD_LL_CloseEP(pdev, MSC_EPIN_ADDR); - pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 0U; + (void)USBD_LL_CloseEP(pdev, MSCInEpAdd); + pdev->ep_in[MSCInEpAdd & 0xFU].is_used = 0U; /* Free MSC Class Resources */ - if (pdev->pClassData != NULL) + if (pdev->pClassDataCmsit[pdev->classId] != NULL) { /* De-Init the BOT layer */ MSC_BOT_DeInit(pdev); - (void)USBD_free(pdev->pClassData); + (void)USBD_free(pdev->pClassDataCmsit[pdev->classId]); + pdev->pClassDataCmsit[pdev->classId] = NULL; pdev->pClassData = NULL; } @@ -370,10 +307,16 @@ uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) */ uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; USBD_StatusTypeDef ret = USBD_OK; uint16_t status_info = 0U; +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + MSCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); + MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ + if (hmsc == NULL) { return (uint8_t)USBD_FAIL; @@ -389,7 +332,7 @@ uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) if ((req->wValue == 0U) && (req->wLength == 1U) && ((req->bmRequest & 0x80U) == 0x80U)) { - hmsc->max_lun = (uint32_t)((USBD_StorageTypeDef *)pdev->pUserData)->GetMaxLun(); + hmsc->max_lun = (uint32_t)((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetMaxLun(); (void)USBD_CtlSendData(pdev, (uint8_t *)&hmsc->max_lun, 1U); } else @@ -515,7 +458,7 @@ uint8_t USBD_MSC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) return (uint8_t)USBD_OK; } - +#ifndef USE_USBD_COMPOSITE /** * @brief USBD_MSC_GetHSCfgDesc * return configuration descriptor @@ -524,9 +467,21 @@ uint8_t USBD_MSC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) */ uint8_t *USBD_MSC_GetHSCfgDesc(uint16_t *length) { - *length = (uint16_t)sizeof(USBD_MSC_CfgHSDesc); + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_MSC_CfgDesc, MSC_EPIN_ADDR); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_MSC_CfgDesc, MSC_EPOUT_ADDR); - return USBD_MSC_CfgHSDesc; + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = MSC_MAX_HS_PACKET; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = MSC_MAX_HS_PACKET; + } + + *length = (uint16_t)sizeof(USBD_MSC_CfgDesc); + return USBD_MSC_CfgDesc; } /** @@ -537,9 +492,21 @@ uint8_t *USBD_MSC_GetHSCfgDesc(uint16_t *length) */ uint8_t *USBD_MSC_GetFSCfgDesc(uint16_t *length) { - *length = (uint16_t)sizeof(USBD_MSC_CfgFSDesc); + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_MSC_CfgDesc, MSC_EPIN_ADDR); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_MSC_CfgDesc, MSC_EPOUT_ADDR); - return USBD_MSC_CfgFSDesc; + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = MSC_MAX_FS_PACKET; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = MSC_MAX_FS_PACKET; + } + + *length = (uint16_t)sizeof(USBD_MSC_CfgDesc); + return USBD_MSC_CfgDesc; } /** @@ -550,9 +517,21 @@ uint8_t *USBD_MSC_GetFSCfgDesc(uint16_t *length) */ uint8_t *USBD_MSC_GetOtherSpeedCfgDesc(uint16_t *length) { - *length = (uint16_t)sizeof(USBD_MSC_OtherSpeedCfgDesc); + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_MSC_CfgDesc, MSC_EPIN_ADDR); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_MSC_CfgDesc, MSC_EPOUT_ADDR); - return USBD_MSC_OtherSpeedCfgDesc; + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = MSC_MAX_FS_PACKET; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = MSC_MAX_FS_PACKET; + } + + *length = (uint16_t)sizeof(USBD_MSC_CfgDesc); + return USBD_MSC_CfgDesc; } /** * @brief DeviceQualifierDescriptor @@ -566,7 +545,7 @@ uint8_t *USBD_MSC_GetDeviceQualifierDescriptor(uint16_t *length) return USBD_MSC_DeviceQualifierDesc; } - +#endif /* USE_USBD_COMPOSITE */ /** * @brief USBD_MSC_RegisterStorage * @param fops: storage callback @@ -579,7 +558,7 @@ uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev, USBD_StorageTypeDef * return (uint8_t)USBD_FAIL; } - pdev->pUserData = fops; + pdev->pUserData[pdev->classId] = fops; return (uint8_t)USBD_OK; } diff --git a/Class/MSC/Src/usbd_msc_bot.c b/Class/MSC/Src/usbd_msc_bot.c index e67c5af..0816de9 100644 --- a/Class/MSC/Src/usbd_msc_bot.c +++ b/Class/MSC/Src/usbd_msc_bot.c @@ -66,7 +66,8 @@ EndBSPDependencies */ /** @defgroup MSC_BOT_Private_Variables * @{ */ - +extern uint8_t MSCInEpAdd; +extern uint8_t MSCOutEpAdd; /** * @} */ @@ -96,7 +97,13 @@ static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev); */ void MSC_BOT_Init(USBD_HandleTypeDef *pdev) { - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + MSCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); + MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ if (hmsc == NULL) { @@ -110,13 +117,13 @@ void MSC_BOT_Init(USBD_HandleTypeDef *pdev) hmsc->scsi_sense_head = 0U; hmsc->scsi_medium_state = SCSI_MEDIUM_UNLOCKED; - ((USBD_StorageTypeDef *)pdev->pUserData)->Init(0U); + ((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->Init(0U); - (void)USBD_LL_FlushEP(pdev, MSC_EPOUT_ADDR); - (void)USBD_LL_FlushEP(pdev, MSC_EPIN_ADDR); + (void)USBD_LL_FlushEP(pdev, MSCOutEpAdd); + (void)USBD_LL_FlushEP(pdev, MSCInEpAdd); /* Prepare EP to Receive First BOT Cmd */ - (void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)&hmsc->cbw, + (void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, (uint8_t *)&hmsc->cbw, USBD_BOT_CBW_LENGTH); } @@ -128,7 +135,13 @@ void MSC_BOT_Init(USBD_HandleTypeDef *pdev) */ void MSC_BOT_Reset(USBD_HandleTypeDef *pdev) { - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + MSCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); + MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ if (hmsc == NULL) { @@ -138,11 +151,11 @@ void MSC_BOT_Reset(USBD_HandleTypeDef *pdev) hmsc->bot_state = USBD_BOT_IDLE; hmsc->bot_status = USBD_BOT_STATUS_RECOVERY; - (void)USBD_LL_ClearStallEP(pdev, MSC_EPIN_ADDR); - (void)USBD_LL_ClearStallEP(pdev, MSC_EPOUT_ADDR); + (void)USBD_LL_ClearStallEP(pdev, MSCInEpAdd); + (void)USBD_LL_ClearStallEP(pdev, MSCOutEpAdd); /* Prepare EP to Receive First BOT Cmd */ - (void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)&hmsc->cbw, + (void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, (uint8_t *)&hmsc->cbw, USBD_BOT_CBW_LENGTH); } @@ -154,7 +167,7 @@ void MSC_BOT_Reset(USBD_HandleTypeDef *pdev) */ void MSC_BOT_DeInit(USBD_HandleTypeDef *pdev) { - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hmsc != NULL) { @@ -173,7 +186,7 @@ void MSC_BOT_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) { UNUSED(epnum); - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hmsc == NULL) { @@ -209,7 +222,7 @@ void MSC_BOT_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) { UNUSED(epnum); - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hmsc == NULL) { @@ -242,7 +255,13 @@ void MSC_BOT_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) */ static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef *pdev) { - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + MSCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); + MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ if (hmsc == NULL) { @@ -252,7 +271,7 @@ static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef *pdev) hmsc->csw.dTag = hmsc->cbw.dTag; hmsc->csw.dDataResidue = hmsc->cbw.dDataLength; - if ((USBD_LL_GetRxDataSize(pdev, MSC_EPOUT_ADDR) != USBD_BOT_CBW_LENGTH) || + if ((USBD_LL_GetRxDataSize(pdev, MSCOutEpAdd) != USBD_BOT_CBW_LENGTH) || (hmsc->cbw.dSignature != USBD_BOT_CBW_SIGNATURE) || (hmsc->cbw.bLUN > 1U) || (hmsc->cbw.bCBLength < 1U) || (hmsc->cbw.bCBLength > 16U)) @@ -310,20 +329,28 @@ static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef *pdev) */ static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t len) { - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; - uint32_t length = MIN(hmsc->cbw.dDataLength, len); + uint32_t length; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + MSCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); + MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ if (hmsc == NULL) { return; } + length = MIN(hmsc->cbw.dDataLength, len); + hmsc->csw.dDataResidue -= len; hmsc->csw.bStatus = USBD_CSW_CMD_PASSED; hmsc->bot_state = USBD_BOT_SEND_DATA; - (void)USBD_LL_Transmit(pdev, MSC_EPIN_ADDR, pbuf, length); + (void)USBD_LL_Transmit(pdev, MSCInEpAdd, pbuf, length); } /** @@ -335,7 +362,13 @@ static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t */ void MSC_BOT_SendCSW(USBD_HandleTypeDef *pdev, uint8_t CSW_Status) { - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + MSCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); + MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ if (hmsc == NULL) { @@ -346,11 +379,11 @@ void MSC_BOT_SendCSW(USBD_HandleTypeDef *pdev, uint8_t CSW_Status) hmsc->csw.bStatus = CSW_Status; hmsc->bot_state = USBD_BOT_IDLE; - (void)USBD_LL_Transmit(pdev, MSC_EPIN_ADDR, (uint8_t *)&hmsc->csw, + (void)USBD_LL_Transmit(pdev, MSCInEpAdd, (uint8_t *)&hmsc->csw, USBD_BOT_CSW_LENGTH); /* Prepare EP to Receive next Cmd */ - (void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)&hmsc->cbw, + (void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, (uint8_t *)&hmsc->cbw, USBD_BOT_CBW_LENGTH); } @@ -363,7 +396,13 @@ void MSC_BOT_SendCSW(USBD_HandleTypeDef *pdev, uint8_t CSW_Status) static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev) { - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + MSCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); + MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ if (hmsc == NULL) { @@ -374,15 +413,15 @@ static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev) (hmsc->cbw.dDataLength != 0U) && (hmsc->bot_status == USBD_BOT_STATUS_NORMAL)) { - (void)USBD_LL_StallEP(pdev, MSC_EPOUT_ADDR); + (void)USBD_LL_StallEP(pdev, MSCOutEpAdd); } - (void)USBD_LL_StallEP(pdev, MSC_EPIN_ADDR); + (void)USBD_LL_StallEP(pdev, MSCInEpAdd); if (hmsc->bot_status == USBD_BOT_STATUS_ERROR) { - (void)USBD_LL_StallEP(pdev, MSC_EPIN_ADDR); - (void)USBD_LL_StallEP(pdev, MSC_EPOUT_ADDR); + (void)USBD_LL_StallEP(pdev, MSCInEpAdd); + (void)USBD_LL_StallEP(pdev, MSCOutEpAdd); } } @@ -396,7 +435,13 @@ static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev) void MSC_BOT_CplClrFeature(USBD_HandleTypeDef *pdev, uint8_t epnum) { - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + MSCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); + MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ if (hmsc == NULL) { @@ -405,8 +450,8 @@ void MSC_BOT_CplClrFeature(USBD_HandleTypeDef *pdev, uint8_t epnum) if (hmsc->bot_status == USBD_BOT_STATUS_ERROR) /* Bad CBW Signature */ { - (void)USBD_LL_StallEP(pdev, MSC_EPIN_ADDR); - (void)USBD_LL_StallEP(pdev, MSC_EPOUT_ADDR); + (void)USBD_LL_StallEP(pdev, MSCInEpAdd); + (void)USBD_LL_StallEP(pdev, MSCOutEpAdd); } else if (((epnum & 0x80U) == 0x80U) && (hmsc->bot_status != USBD_BOT_STATUS_RECOVERY)) { diff --git a/Class/MSC/Src/usbd_msc_scsi.c b/Class/MSC/Src/usbd_msc_scsi.c index f482e3d..af7a0d5 100644 --- a/Class/MSC/Src/usbd_msc_scsi.c +++ b/Class/MSC/Src/usbd_msc_scsi.c @@ -67,7 +67,8 @@ EndBSPDependencies */ /** @defgroup MSC_SCSI_Private_Variables * @{ */ - +extern uint8_t MSCInEpAdd; +extern uint8_t MSCOutEpAdd; /** * @} */ @@ -120,7 +121,7 @@ static int8_t SCSI_UpdateBotData(USBD_MSC_BOT_HandleTypeDef *hmsc, int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd) { int8_t ret; - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hmsc == NULL) { @@ -210,7 +211,7 @@ int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd) static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { UNUSED(params); - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hmsc == NULL) { @@ -232,7 +233,7 @@ static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t return -1; } - if (((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) != 0) + if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsReady(lun) != 0) { SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT); hmsc->bot_state = USBD_BOT_NO_DATA; @@ -256,7 +257,7 @@ static int8_t SCSI_Inquiry(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param { uint8_t *pPage; uint16_t len; - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hmsc == NULL) { @@ -289,7 +290,8 @@ static int8_t SCSI_Inquiry(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param } else { - pPage = (uint8_t *) & ((USBD_StorageTypeDef *)pdev->pUserData)->pInquiry[lun * STANDARD_INQUIRY_DATA_LEN]; + + pPage = (uint8_t *) & ((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->pInquiry[lun * STANDARD_INQUIRY_DATA_LEN]; len = (uint16_t)pPage[4] + 5U; if (params[4] <= len) @@ -315,14 +317,14 @@ static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t { UNUSED(params); int8_t ret; - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hmsc == NULL) { return -1; } - ret = ((USBD_StorageTypeDef *)pdev->pUserData)->GetCapacity(lun, &hmsc->scsi_blk_nbr, &hmsc->scsi_blk_size); + ret = ((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetCapacity(lun, &hmsc->scsi_blk_nbr, &hmsc->scsi_blk_size); if ((ret != 0) || (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED)) { @@ -359,14 +361,14 @@ static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t UNUSED(params); uint8_t idx; int8_t ret; - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hmsc == NULL) { return -1; } - ret = ((USBD_StorageTypeDef *)pdev->pUserData)->GetCapacity(lun, &hmsc->scsi_blk_nbr, &hmsc->scsi_blk_size); + ret = ((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetCapacity(lun, &hmsc->scsi_blk_nbr, &hmsc->scsi_blk_size); if ((ret != 0) || (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED)) { @@ -417,14 +419,14 @@ static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uin uint32_t blk_nbr; uint16_t i; int8_t ret; - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hmsc == NULL) { return -1; } - ret = ((USBD_StorageTypeDef *)pdev->pUserData)->GetCapacity(lun, &blk_nbr, &blk_size); + ret = ((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetCapacity(lun, &blk_nbr, &blk_size); if ((ret != 0) || (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED)) { @@ -464,7 +466,7 @@ static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uin static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { UNUSED(lun); - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint16_t len = MODE_SENSE6_LEN; if (hmsc == NULL) @@ -493,7 +495,7 @@ static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *pa static int8_t SCSI_ModeSense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { UNUSED(lun); - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint16_t len = MODE_SENSE10_LEN; if (hmsc == NULL) @@ -523,7 +525,7 @@ static int8_t SCSI_RequestSense(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t * { UNUSED(lun); uint8_t i; - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hmsc == NULL) { @@ -580,7 +582,7 @@ static int8_t SCSI_RequestSense(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t * void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey, uint8_t ASC) { UNUSED(lun); - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hmsc == NULL) { @@ -609,7 +611,7 @@ void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey, uint8_t static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { UNUSED(lun); - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hmsc == NULL) { @@ -655,7 +657,7 @@ static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t static int8_t SCSI_AllowPreventRemovable(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { UNUSED(lun); - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hmsc == NULL) { @@ -686,7 +688,7 @@ static int8_t SCSI_AllowPreventRemovable(USBD_HandleTypeDef *pdev, uint8_t lun, */ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hmsc == NULL) { @@ -709,7 +711,7 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params return -1; } - if (((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) != 0) + if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsReady(lun) != 0) { SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT); return -1; @@ -752,7 +754,7 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params */ static int8_t SCSI_Read12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hmsc == NULL) { @@ -774,7 +776,7 @@ static int8_t SCSI_Read12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params return -1; } - if (((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) != 0) + if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsReady(lun) != 0) { SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT); return -1; @@ -820,7 +822,7 @@ static int8_t SCSI_Read12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params */ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint32_t len; if (hmsc == NULL) @@ -828,6 +830,11 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param return -1; } +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ + if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */ { if (hmsc->cbw.dDataLength == 0U) @@ -844,14 +851,14 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param } /* Check whether Media is ready */ - if (((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) != 0) + if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsReady(lun) != 0) { SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT); return -1; } /* Check If media is write-protected */ - if (((USBD_StorageTypeDef *)pdev->pUserData)->IsWriteProtected(lun) != 0) + if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsWriteProtected(lun) != 0) { SCSI_SenseCode(pdev, lun, NOT_READY, WRITE_PROTECTED); return -1; @@ -885,7 +892,7 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param /* Prepare EP to receive first data packet */ hmsc->bot_state = USBD_BOT_DATA_OUT; - (void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, hmsc->bot_data, len); + (void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, hmsc->bot_data, len); } else /* Write Process ongoing */ { @@ -905,13 +912,17 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param */ static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint32_t len; if (hmsc == NULL) { return -1; } +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */ { @@ -929,7 +940,7 @@ static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param } /* Check whether Media is ready */ - if (((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) != 0) + if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsReady(lun) != 0) { SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT); hmsc->bot_state = USBD_BOT_NO_DATA; @@ -937,7 +948,7 @@ static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param } /* Check If media is write-protected */ - if (((USBD_StorageTypeDef *)pdev->pUserData)->IsWriteProtected(lun) != 0) + if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsWriteProtected(lun) != 0) { SCSI_SenseCode(pdev, lun, NOT_READY, WRITE_PROTECTED); hmsc->bot_state = USBD_BOT_NO_DATA; @@ -974,7 +985,7 @@ static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param /* Prepare EP to receive first data packet */ hmsc->bot_state = USBD_BOT_DATA_OUT; - (void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, hmsc->bot_data, len); + (void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, hmsc->bot_data, len); } else /* Write Process ongoing */ { @@ -994,7 +1005,7 @@ static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param */ static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hmsc == NULL) { @@ -1028,7 +1039,7 @@ static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *para static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun, uint32_t blk_offset, uint32_t blk_nbr) { - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hmsc == NULL) { @@ -1052,25 +1063,32 @@ static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun, */ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun) { - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; - uint32_t len = hmsc->scsi_blk_len * hmsc->scsi_blk_size; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + uint32_t len; if (hmsc == NULL) { return -1; } + len = hmsc->scsi_blk_len * hmsc->scsi_blk_size; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + MSCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ + len = MIN(len, MSC_MEDIA_PACKET); - if (((USBD_StorageTypeDef *)pdev->pUserData)->Read(lun, hmsc->bot_data, - hmsc->scsi_blk_addr, - (len / hmsc->scsi_blk_size)) < 0) + if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->Read(lun, hmsc->bot_data, + hmsc->scsi_blk_addr, + (len / hmsc->scsi_blk_size)) < 0) { SCSI_SenseCode(pdev, lun, HARDWARE_ERROR, UNRECOVERED_READ_ERROR); return -1; } - (void)USBD_LL_Transmit(pdev, MSC_EPIN_ADDR, hmsc->bot_data, len); + (void)USBD_LL_Transmit(pdev, MSCInEpAdd, hmsc->bot_data, len); hmsc->scsi_blk_addr += (len / hmsc->scsi_blk_size); hmsc->scsi_blk_len -= (len / hmsc->scsi_blk_size); @@ -1094,19 +1112,26 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun) */ static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun) { - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; - uint32_t len = hmsc->scsi_blk_len * hmsc->scsi_blk_size; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + uint32_t len; if (hmsc == NULL) { return -1; } + len = hmsc->scsi_blk_len * hmsc->scsi_blk_size; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ + len = MIN(len, MSC_MEDIA_PACKET); - if (((USBD_StorageTypeDef *)pdev->pUserData)->Write(lun, hmsc->bot_data, - hmsc->scsi_blk_addr, - (len / hmsc->scsi_blk_size)) < 0) + if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->Write(lun, hmsc->bot_data, + hmsc->scsi_blk_addr, + (len / hmsc->scsi_blk_size)) < 0) { SCSI_SenseCode(pdev, lun, HARDWARE_ERROR, WRITE_FAULT); return -1; @@ -1127,7 +1152,7 @@ static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun) len = MIN((hmsc->scsi_blk_len * hmsc->scsi_blk_size), MSC_MEDIA_PACKET); /* Prepare EP to Receive next packet */ - (void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, hmsc->bot_data, len); + (void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, hmsc->bot_data, len); } return 0; diff --git a/Class/MSC/Src/usbd_msc_storage_template.c b/Class/MSC/Src/usbd_msc_storage_template.c index bc0ac3a..2163943 100644 --- a/Class/MSC/Src/usbd_msc_storage_template.c +++ b/Class/MSC/Src/usbd_msc_storage_template.c @@ -86,87 +86,103 @@ USBD_StorageTypeDef USBD_MSC_Template_fops = STORAGE_Inquirydata, }; -/******************************************************************************* - * Function Name : Read_Memory - * Description : Handle the Read operation from the microSD card. - * Input : None. - * Output : None. - * Return : None. - *******************************************************************************/ + +/** + * @brief Initializes the storage unit (medium) + * @param lun: Logical unit number + * @retval Status (0 : OK / -1 : Error) + */ int8_t STORAGE_Init(uint8_t lun) { + UNUSED(lun); + return (0); } -/******************************************************************************* - * Function Name : Read_Memory - * Description : Handle the Read operation from the STORAGE card. - * Input : None. - * Output : None. - * Return : None. - *******************************************************************************/ +/** + * @brief Returns the medium capacity. + * @param lun: Logical unit number + * @param block_num: Number of total block number + * @param block_size: Block size + * @retval Status (0: OK / -1: Error) + */ int8_t STORAGE_GetCapacity(uint8_t lun, uint32_t *block_num, uint16_t *block_size) { + UNUSED(lun); + *block_num = STORAGE_BLK_NBR; *block_size = STORAGE_BLK_SIZ; return (0); } -/******************************************************************************* - * Function Name : Read_Memory - * Description : Handle the Read operation from the STORAGE card. - * Input : None. - * Output : None. - * Return : None. - *******************************************************************************/ + +/** + * @brief Checks whether the medium is ready. + * @param lun: Logical unit number + * @retval Status (0: OK / -1: Error) + */ int8_t STORAGE_IsReady(uint8_t lun) { + UNUSED(lun); + return (0); } -/******************************************************************************* - * Function Name : Read_Memory - * Description : Handle the Read operation from the STORAGE card. - * Input : None. - * Output : None. - * Return : None. - *******************************************************************************/ +/** + * @brief Checks whether the medium is write protected. + * @param lun: Logical unit number + * @retval Status (0: write enabled / -1: otherwise) + */ int8_t STORAGE_IsWriteProtected(uint8_t lun) { + UNUSED(lun); + return 0; } -/******************************************************************************* - * Function Name : Read_Memory - * Description : Handle the Read operation from the STORAGE card. - * Input : None. - * Output : None. - * Return : None. - *******************************************************************************/ +/** + * @brief Reads data from the medium. + * @param lun: Logical unit number + * @param buf: data buffer + * @param blk_addr: Logical block address + * @param blk_len: Blocks number + * @retval Status (0: OK / -1: Error) + */ int8_t STORAGE_Read(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) { + UNUSED(lun); + UNUSED(buf); + UNUSED(blk_addr); + UNUSED(blk_len); + return 0; } -/******************************************************************************* - * Function Name : Write_Memory - * Description : Handle the Write operation to the STORAGE card. - * Input : None. - * Output : None. - * Return : None. - *******************************************************************************/ + +/** + * @brief Writes data into the medium. + * @param lun: Logical unit number + * @param buf: data buffer + * @param blk_addr: Logical block address + * @param blk_len: Blocks number + * @retval Status (0 : OK / -1 : Error) + */ int8_t STORAGE_Write(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) { + UNUSED(lun); + UNUSED(buf); + UNUSED(blk_addr); + UNUSED(blk_len); + return (0); } -/******************************************************************************* - * Function Name : Write_Memory - * Description : Handle the Write operation to the STORAGE card. - * Input : None. - * Output : None. - * Return : None. - *******************************************************************************/ + +/** + * @brief Returns the Max Supported LUNs. + * @param None + * @retval Lun(s) number + */ int8_t STORAGE_GetMaxLun(void) { return (STORAGE_LUN_NBR - 1); diff --git a/Class/MTP/Inc/usbd_mtp.h b/Class/MTP/Inc/usbd_mtp.h index 0732863..df2644f 100644 --- a/Class/MTP/Inc/usbd_mtp.h +++ b/Class/MTP/Inc/usbd_mtp.h @@ -41,10 +41,15 @@ extern "C" { /** @defgroup USBD_MTP_Exported_Defines * @{ */ - +#ifndef MTP_IN_EP #define MTP_IN_EP 0x81U /* EP1 for data IN */ +#endif /* MTP_IN_EP */ +#ifndef MTP_OUT_EP #define MTP_OUT_EP 0x01U /* EP1 for data OUT */ +#endif /* MTP_OUT_EP */ +#ifndef MTP_CMD_EP #define MTP_CMD_EP 0x82U /* EP2 for MTP commands */ +#endif /* MTP_CMD_EP */ #ifndef MTP_CMD_ITF_NBR #define MTP_CMD_ITF_NBR 0x00U /* Command Interface Number 0 */ @@ -117,6 +122,11 @@ extern "C" { #define MTP_RESPONSE_SPECIFICATION_BY_GROUP_UNSUPPORTED 0xA807U #define MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED 0xA80AU +/* + * MTP Class specification Revision 1.1 + * Appendix A. Object Formats + */ + /* MTP Object format codes */ #define MTP_OBJ_FORMAT_UNDEFINED 0x3000U #define MTP_OBJ_FORMAT_ASSOCIATION 0x3001U @@ -220,7 +230,7 @@ typedef struct uint32_t Param3; uint32_t Param4; uint32_t Param5; -} MTP_OperationsTypedef; +} MTP_OperationsTypeDef; typedef struct { @@ -235,7 +245,7 @@ typedef struct typedef __PACKED_STRUCT #else __packed typedef struct -#endif +#endif /* __GNUC__ */ { uint32_t Storage_id; uint16_t ObjectFormat; @@ -270,7 +280,7 @@ typedef struct MTP_ResponsePhaseTypeDef MTP_ResponsePhase; MTP_SessionStateTypeDef MTP_SessionState; MTP_RECEIVE_DATA_STATUS RECEIVE_DATA_STATUS; - MTP_OperationsTypedef OperationsContainer; + MTP_OperationsTypeDef OperationsContainer; MTP_GenericContainerTypeDef GenericContainer; } USBD_MTP_HandleTypeDef; diff --git a/Class/MTP/Inc/usbd_mtp_if_template.h b/Class/MTP/Inc/usbd_mtp_if_template.h index bfdcad0..d86e250 100644 --- a/Class/MTP/Inc/usbd_mtp_if_template.h +++ b/Class/MTP/Inc/usbd_mtp_if_template.h @@ -37,25 +37,25 @@ extern "C" { #define SUPP_EVENTS_LEN (uint8_t)((uint8_t)sizeof(SuppEvents) / 2U) #else #define SUPP_EVENTS_LEN 0U -#endif +#endif /* USBD_MTP_EVENTS_SUPPORTED */ #if USBD_MTP_VEND_EXT_DESC_SUPPORTED == 1 #define VEND_EXT_DESC_LEN (sizeof(VendExtDesc) / 2U) #else #define VEND_EXT_DESC_LEN 0U -#endif +#endif /* USBD_MTP_VEND_EXT_DESC_SUPPORTED */ #if USBD_MTP_CAPTURE_FORMAT_SUPPORTED == 1 #define SUPP_CAPT_FORMAT_LEN (uint8_t)((uint8_t)sizeof(SuppCaptFormat) / 2U) #else #define SUPP_CAPT_FORMAT_LEN 0U -#endif +#endif /* USBD_MTP_CAPTURE_FORMAT_SUPPORTED */ #if USBD_MTP_DEVICE_PROP_SUPPORTED == 1 #define SUPP_DEVICE_PROP_LEN (uint8_t)((uint8_t)sizeof(DevicePropSupp) / 2U) #else #define SUPP_DEVICE_PROP_LEN 0U -#endif +#endif /* USBD_MTP_DEVICE_PROP_SUPPORTED */ #define MTP_IF_SCRATCH_BUFF_SZE 1024U @@ -73,7 +73,8 @@ static const uint16_t VendExtDesc[] = {'m', 'i', 'c', 'r', 'o', 's', 'o', 'f', ' }; /* last 2 bytes must be 0*/ /*SerialNbr shall be 32 character hexadecimal string for legacy compatibility reasons */ static const uint16_t SerialNbr[] = {'0', '0', '0', '0', '1', '0', '0', '0', '0', '1', '0', '0', '0', '0', - '1', '0', '0', '0', '0', '1', '0', '0', '0', '0', '1', '0', '0', '0', '0', '1', '0', '0', 0 + '1', '0', '0', '0', '0', '1', '0', '0', '0', '0', '1', '0', '0', '0', + '0', '1', '0', '0', 0 }; /* last 2 bytes must be 0*/ static const uint16_t DeviceVers[] = {'V', '1', '.', '0', '0', 0}; /* last 2 bytes must be 0*/ diff --git a/Class/MTP/Inc/usbd_mtp_opt.h b/Class/MTP/Inc/usbd_mtp_opt.h index 73498ab..4dee923 100644 --- a/Class/MTP/Inc/usbd_mtp_opt.h +++ b/Class/MTP/Inc/usbd_mtp_opt.h @@ -27,7 +27,7 @@ extern "C" { /* Includes ------------------------------------------------------------------*/ #ifndef __USBD_MTP_IF_H #include "usbd_mtp_if_template.h" -#endif +#endif /* __USBD_MTP_IF_H */ #include "usbd_mtp.h" /** @addtogroup STM32_USB_DEVICE_LIBRARY @@ -43,6 +43,12 @@ extern "C" { /** @defgroup USBD_MTP_OPT_Exported_Defines * @{ */ + +/* + * MTP Class specification Revision 1.1 + * Appendix B. Object Properties + */ + /* MTP OBJECT PROPERTIES supported*/ #define MTP_OB_PROP_STORAGE_ID 0xDC01U #define MTP_OB_PROP_OBJECT_FORMAT 0xDC02U @@ -231,6 +237,11 @@ extern "C" { #define MTP_EVENT_OBJECTPROPDESCCHANGED 0xC802U #define MTP_EVENT_OBJECTREFERENCESCHANGED 0xC803U +/* + * MTP Class specification Revision 1.1 + * Appendix D. Operations + */ + /* Operations code */ #define MTP_OP_GET_DEVICE_INFO 0x1001U #define MTP_OP_OPEN_SESSION 0x1002U @@ -267,6 +278,11 @@ extern "C" { #define MTP_OP_GETSERVICECAPABILITIES 0x9303U #define MTP_OP_GETSERVICEPROPDESC 0x9304U +/* + * MTP Class specification Revision 1.1 + * Appendix C. Device Properties + */ + /* MTP device properties code*/ #define MTP_DEV_PROP_UNDEFINED 0x5000U #define MTP_DEV_PROP_BATTERY_LEVEL 0x5001U @@ -327,22 +343,22 @@ extern "C" { #define FREE_SPACE_IN_OBJ_NOT_USED 0xFFFFFFFFU /* MTP storage type */ -#define MTP_STORAGE_UNDEFINED 0U -#define MTP_STORAGE_FIXED_ROM 0x0001U -#define MTP_STORAGE_REMOVABLE_ROM 0x0002U -#define MTP_STORAGE_FIXED_RAM 0x0003U -#define MTP_STORAGE_REMOVABLE_RAM 0x0004U +#define MTP_STORAGE_UNDEFINED 0U +#define MTP_STORAGE_FIXED_ROM 0x0001U +#define MTP_STORAGE_REMOVABLE_ROM 0x0002U +#define MTP_STORAGE_FIXED_RAM 0x0003U +#define MTP_STORAGE_REMOVABLE_RAM 0x0004U /* MTP file system type */ -#define MTP_FILESYSTEM_UNDEFINED 0U +#define MTP_FILESYSTEM_UNDEFINED 0U #define MTP_FILESYSTEM_GENERIC_FLAT 0x0001U -#define MTP_FILESYSTEM_GENERIC_HIERARCH 0x0002U -#define MTP_FILESYSTEM_DCF 0x0003U +#define MTP_FILESYSTEM_GENERIC_HIERARCH 0x0002U +#define MTP_FILESYSTEM_DCF 0x0003U /* MTP access capability */ -#define MTP_ACCESS_CAP_RW 0U /* read write */ -#define MTP_ACCESS_CAP_RO_WITHOUT_DEL 0x0001U -#define MTP_ACCESS_CAP_RO_WITH_DEL 0x0002U +#define MTP_ACCESS_CAP_RW 0U /* read write */ +#define MTP_ACCESS_CAP_RO_WITHOUT_DEL 0x0001U +#define MTP_ACCESS_CAP_RO_WITH_DEL 0x0002U /* MTP standard data types supported */ #define MTP_DATATYPE_INT8 0x0001U @@ -411,24 +427,31 @@ extern "C" { * @} */ -static const uint16_t SuppOP[] = { MTP_OP_GET_DEVICE_INFO, MTP_OP_OPEN_SESSION, MTP_OP_CLOSE_SESSION, MTP_OP_GET_STORAGE_IDS, MTP_OP_GET_STORAGE_INFO, - MTP_OP_GET_NUM_OBJECTS, MTP_OP_GET_OBJECT_HANDLES, MTP_OP_GET_OBJECT_INFO, MTP_OP_GET_OBJECT, MTP_OP_DELETE_OBJECT, - MTP_OP_SEND_OBJECT_INFO, MTP_OP_SEND_OBJECT, MTP_OP_GET_DEVICE_PROP_DESC, MTP_OP_GET_DEVICE_PROP_VALUE, - MTP_OP_SET_OBJECT_PROP_VALUE, MTP_OP_GET_OBJECT_PROP_VALUE, MTP_OP_GET_OBJECT_PROPS_SUPPORTED, MTP_OP_GET_OBJECT_PROPLIST, +static const uint16_t SuppOP[] = { MTP_OP_GET_DEVICE_INFO, MTP_OP_OPEN_SESSION, MTP_OP_CLOSE_SESSION, + MTP_OP_GET_STORAGE_IDS, MTP_OP_GET_STORAGE_INFO, MTP_OP_GET_NUM_OBJECTS, + MTP_OP_GET_OBJECT_HANDLES, MTP_OP_GET_OBJECT_INFO, MTP_OP_GET_OBJECT, + MTP_OP_DELETE_OBJECT, MTP_OP_SEND_OBJECT_INFO, MTP_OP_SEND_OBJECT, + MTP_OP_GET_DEVICE_PROP_DESC, MTP_OP_GET_DEVICE_PROP_VALUE, + MTP_OP_SET_OBJECT_PROP_VALUE, MTP_OP_GET_OBJECT_PROP_VALUE, + MTP_OP_GET_OBJECT_PROPS_SUPPORTED, MTP_OP_GET_OBJECT_PROPLIST, MTP_OP_GET_OBJECT_PROP_DESC, MTP_OP_GET_OBJECT_PROP_REFERENCES }; static const uint16_t SuppEvents[] = {MTP_EVENT_OBJECTADDED}; -static const uint16_t SuppImgFormat[] = {MTP_OBJ_FORMAT_UNDEFINED, MTP_OBJ_FORMAT_TEXT, MTP_OBJ_FORMAT_ASSOCIATION, MTP_OBJ_FORMAT_EXECUTABLE, MTP_OBJ_FORMAT_WAV, - MTP_OBJ_FORMAT_MP3, MTP_OBJ_FORMAT_EXIF_JPEG, MTP_OBJ_FORMAT_MPEG, MTP_OBJ_FORMAT_MP4_CONTAINER, - MTP_OBJ_FORMAT_WINDOWS_IMAGE_FORMAT, MTP_OBJ_FORMAT_PNG, MTP_OBJ_FORMAT_WMA, MTP_OBJ_FORMAT_WMV +static const uint16_t SuppImgFormat[] = {MTP_OBJ_FORMAT_UNDEFINED, MTP_OBJ_FORMAT_TEXT, MTP_OBJ_FORMAT_ASSOCIATION, + MTP_OBJ_FORMAT_EXECUTABLE, MTP_OBJ_FORMAT_WAV, MTP_OBJ_FORMAT_MP3, + MTP_OBJ_FORMAT_EXIF_JPEG, MTP_OBJ_FORMAT_MPEG, MTP_OBJ_FORMAT_MP4_CONTAINER, + MTP_OBJ_FORMAT_WINDOWS_IMAGE_FORMAT, MTP_OBJ_FORMAT_PNG, MTP_OBJ_FORMAT_WMA, + MTP_OBJ_FORMAT_WMV }; static const uint16_t SuppCaptFormat[] = {MTP_OBJ_FORMAT_UNDEFINED, MTP_OBJ_FORMAT_ASSOCIATION, MTP_OBJ_FORMAT_TEXT}; -/* required for all object format : storageID, objectFormat, ObjectCompressedSize, persistent unique object identifier, name*/ -static const uint16_t ObjectPropSupp[] = {MTP_OB_PROP_STORAGE_ID, MTP_OB_PROP_OBJECT_FORMAT, MTP_OB_PROP_OBJECT_SIZE, MTP_OB_PROP_OBJ_FILE_NAME, - MTP_OB_PROP_PARENT_OBJECT, MTP_OB_PROP_NAME, MTP_OB_PROP_PERS_UNIQ_OBJ_IDEN, MTP_OB_PROP_PROTECTION_STATUS +/* required for all object format : storageID, objectFormat, ObjectCompressedSize, +persistent unique object identifier, name*/ +static const uint16_t ObjectPropSupp[] = {MTP_OB_PROP_STORAGE_ID, MTP_OB_PROP_OBJECT_FORMAT, MTP_OB_PROP_OBJECT_SIZE, + MTP_OB_PROP_OBJ_FILE_NAME, MTP_OB_PROP_PARENT_OBJECT, MTP_OB_PROP_NAME, + MTP_OB_PROP_PERS_UNIQ_OBJ_IDEN, MTP_OB_PROP_PROTECTION_STATUS }; static const uint16_t DevicePropSupp[] = {MTP_DEV_PROP_DEVICE_FRIENDLY_NAME, MTP_DEV_PROP_BATTERY_LEVEL}; @@ -444,7 +467,7 @@ typedef struct typedef __PACKED_STRUCT #else __packed typedef struct -#endif +#endif /* __GNUC__ */ { uint8_t FileName_len; uint16_t FileName[MAX_FILE_NAME]; @@ -461,7 +484,7 @@ typedef struct typedef __PACKED_STRUCT #else __packed typedef struct -#endif +#endif /* __GNUC__ */ { uint32_t ObjectPropSupp_len; uint16_t ObjectPropSupp[SUPP_OBJ_PROP_LEN]; @@ -472,7 +495,7 @@ __packed typedef struct typedef __PACKED_STRUCT #else __packed typedef struct -#endif +#endif /* __GNUC__ */ { uint16_t StorageType; uint16_t FilesystemType; @@ -501,7 +524,7 @@ typedef union typedef __PACKED_STRUCT #else __packed typedef struct -#endif +#endif /* __GNUC__ */ { uint16_t ObjectPropertyCode; uint16_t DataType; @@ -516,7 +539,7 @@ __packed typedef struct typedef __PACKED_STRUCT #else __packed typedef struct -#endif +#endif /* __GNUC__ */ { uint32_t ObjectHandle; uint16_t PropertyCode; @@ -528,7 +551,7 @@ __packed typedef struct typedef __PACKED_STRUCT #else __packed typedef struct -#endif +#endif /* __GNUC__ */ { uint32_t MTP_Properties_len; MTP_PropertiesTypedef MTP_Properties[SUPP_OBJ_PROP_LEN]; @@ -539,7 +562,7 @@ __packed typedef struct typedef __PACKED_STRUCT #else __packed typedef struct -#endif +#endif /* __GNUC__ */ { uint32_t ref_len; uint32_t ref[1]; @@ -549,7 +572,7 @@ __packed typedef struct typedef __PACKED_STRUCT #else __packed typedef struct -#endif +#endif /* __GNUC__ */ { uint16_t DevicePropertyCode; uint16_t DataType; @@ -566,7 +589,7 @@ __packed typedef struct typedef __PACKED_STRUCT #else __packed typedef struct -#endif +#endif /* __GNUC__ */ { uint16_t StandardVersion; uint32_t VendorExtensionID; @@ -574,22 +597,22 @@ __packed typedef struct uint8_t VendorExtensionDesc_len; #if USBD_MTP_VEND_EXT_DESC_SUPPORTED == 1 uint16_t VendorExtensionDesc[VEND_EXT_DESC_LEN]; -#endif +#endif /* USBD_MTP_VEND_EXT_DESC_SUPPORTED */ uint16_t FunctionalMode; uint32_t OperationsSupported_len; uint16_t OperationsSupported[SUPP_OP_LEN]; uint32_t EventsSupported_len; #if USBD_MTP_EVENTS_SUPPORTED == 1 uint16_t EventsSupported[SUPP_EVENTS_LEN]; -#endif +#endif /* USBD_MTP_EVENTS_SUPPORTED */ uint32_t DevicePropertiesSupported_len; #if USBD_MTP_DEVICE_PROP_SUPPORTED == 1 uint16_t DevicePropertiesSupported[SUPP_DEVICE_PROP_LEN]; -#endif +#endif /* USBD_MTP_DEVICE_PROP_SUPPORTED */ uint32_t CaptureFormats_len; #if USBD_MTP_CAPTURE_FORMAT_SUPPORTED == 1 uint16_t CaptureFormats[SUPP_CAPT_FORMAT_LEN]; -#endif +#endif /* USBD_MTP_CAPTURE_FORMAT_SUPPORTED */ uint32_t ImageFormats_len; uint16_t ImageFormats[SUPP_IMG_FORMAT_LEN]; uint8_t Manufacturer_len; diff --git a/Class/MTP/Src/usbd_mtp.c b/Class/MTP/Src/usbd_mtp.c index 1407b4a..03762ce 100644 --- a/Class/MTP/Src/usbd_mtp.c +++ b/Class/MTP/Src/usbd_mtp.c @@ -87,11 +87,13 @@ static uint8_t USBD_MTP_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx); static uint8_t USBD_MTP_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); static uint8_t USBD_MTP_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); static uint8_t USBD_MTP_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum); + +#ifndef USE_USBD_COMPOSITE static uint8_t *USBD_MTP_GetHSCfgDesc(uint16_t *length); static uint8_t *USBD_MTP_GetFSCfgDesc(uint16_t *length); static uint8_t *USBD_MTP_GetOtherSpeedCfgDesc(uint16_t *length); static uint8_t *USBD_MTP_GetDeviceQualifierDescriptor(uint16_t *length); - +#endif /* USE_USBD_COMPOSITE */ /** * @} @@ -115,14 +117,23 @@ USBD_ClassTypeDef USBD_MTP = NULL, /*SOF */ NULL, /*ISOIn*/ NULL, /*ISOOut*/ +#ifdef USE_USBD_COMPOSITE + NULL, + NULL, + NULL, + NULL, +#else USBD_MTP_GetHSCfgDesc, USBD_MTP_GetFSCfgDesc, USBD_MTP_GetOtherSpeedCfgDesc, USBD_MTP_GetDeviceQualifierDescriptor, +#endif /* USE_USBD_COMPOSITE */ }; +#ifndef USE_USBD_COMPOSITE + /* USB MTP device Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_MTP_CfgHSDesc[MTP_CONFIG_DESC_SIZ] __ALIGN_END = +__ALIGN_BEGIN static uint8_t USBD_MTP_CfgDesc[MTP_CONFIG_DESC_SIZ] __ALIGN_END = { /* Configuration Descriptor */ 0x09, /* bLength: Configuration Descriptor size */ @@ -131,67 +142,13 @@ __ALIGN_BEGIN static uint8_t USBD_MTP_CfgHSDesc[MTP_CONFIG_DESC_SIZ] __ALIGN_END HIBYTE(MTP_CONFIG_DESC_SIZ), 0x01, /* bNumInterfaces: 1 interface */ 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ -#if (USBD_SELF_POWERED == 1U) - 0xC0, /* bmAttributes: Bus Powered according to user configuration */ -#else - 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif - USBD_MAX_POWER, /* MaxPower (mA) */ - - /******************** MTP **** interface ********************/ - MTP_INTERFACE_DESC_SIZE, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - MTP_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x03, /* bNumEndpoints: */ - USB_MTP_INTRERFACE_CLASS, /* bInterfaceClass: bInterfaceClass: user's interface for MTP */ - USB_MTP_INTRERFACE_SUB_CLASS, /* bInterfaceSubClass:Abstract Control Model */ - USB_MTP_INTRERFACE_PROTOCOL, /* bInterfaceProtocol: Common AT commands */ - 0x00, /* iInterface: */ - - /******************** MTP Endpoints ********************/ - MTP_ENDPOINT_DESC_SIZE, /* Endpoint descriptor length = 7 */ - USB_DESC_TYPE_ENDPOINT, /* Endpoint descriptor type */ - MTP_IN_EP, /* Endpoint address (IN, address 1) */ - USBD_EP_TYPE_BULK, /* Bulk endpoint type */ - LOBYTE(MTP_DATA_MAX_HS_PACKET_SIZE), - HIBYTE(MTP_DATA_MAX_HS_PACKET_SIZE), - 0x00, /* Polling interval in milliseconds */ - - MTP_ENDPOINT_DESC_SIZE, /* Endpoint descriptor length = 7 */ - USB_DESC_TYPE_ENDPOINT, /* Endpoint descriptor type */ - MTP_OUT_EP, /* Endpoint address (OUT, address 1) */ - USBD_EP_TYPE_BULK, /* Bulk endpoint type */ - LOBYTE(MTP_DATA_MAX_HS_PACKET_SIZE), - HIBYTE(MTP_DATA_MAX_HS_PACKET_SIZE), - 0x00, /* Polling interval in milliseconds */ - - MTP_ENDPOINT_DESC_SIZE, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType:*/ - MTP_CMD_EP, /* bEndpointAddress: Endpoint Address (IN) */ - USBD_EP_TYPE_INTR, /* bmAttributes: Interrupt endpoint */ - LOBYTE(MTP_CMD_PACKET_SIZE), - HIBYTE(MTP_CMD_PACKET_SIZE), - MTP_HS_BINTERVAL /* Polling interval in milliseconds */ -}; - -/* USB MTP device Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_MTP_CfgFSDesc[MTP_CONFIG_DESC_SIZ] __ALIGN_END = -{ - /* Configuration Descriptor */ - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - LOBYTE(MTP_CONFIG_DESC_SIZ), /* wTotalLength: Total size of the Config descriptor */ - HIBYTE(MTP_CONFIG_DESC_SIZ), - 0x01, /* bNumInterfaces: 1 interface */ - 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ + 0x00, /* iConfiguration: Index of string descriptor + describing the configuration */ #if (USBD_SELF_POWERED == 1U) 0xC0, /* bmAttributes: Bus Powered according to user configuration */ #else 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif +#endif /* USBD_SELF_POWERED */ USBD_MAX_POWER, /* MaxPower (mA) */ /******************** MTP **** interface ********************/ @@ -245,6 +202,11 @@ __ALIGN_BEGIN static uint8_t USBD_MTP_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_ 0x01, 0x00, }; +#endif /* USE_USBD_COMPOSITE */ + +uint8_t MTPInEpAdd = MTP_IN_EP; +uint8_t MTPOutEpAdd = MTP_OUT_EP; +uint8_t MTPCmdEpAdd = MTP_CMD_EP; /** * @} @@ -270,30 +232,46 @@ static uint8_t USBD_MTP_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) if (hmtp == NULL) { - pdev->pClassData = NULL; + pdev->pClassDataCmsit[pdev->classId] = NULL; return (uint8_t)USBD_EMEM; } /* Setup the pClassData pointer */ - pdev->pClassData = (void *)hmtp; + pdev->pClassDataCmsit[pdev->classId] = (void *)hmtp; + pdev->pClassData = pdev->pClassDataCmsit[pdev->classId]; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + MTPInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); + MTPOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); + MTPCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR); +#endif /* USE_USBD_COMPOSITE */ + /* Initialize all variables */ (void)USBD_memset(hmtp, 0, sizeof(USBD_MTP_HandleTypeDef)); /* Setup the max packet size according to selected speed */ - hmtp->MaxPcktLen = (pdev->dev_speed == USBD_SPEED_HIGH) ? MTP_DATA_MAX_HS_PACKET_SIZE : MTP_DATA_MAX_FS_PACKET_SIZE; + if (pdev->dev_speed == USBD_SPEED_HIGH) + { + hmtp->MaxPcktLen = MTP_DATA_MAX_HS_PACKET_SIZE; + } + else + { + hmtp->MaxPcktLen = MTP_DATA_MAX_FS_PACKET_SIZE; + } /* Open EP IN */ - (void)USBD_LL_OpenEP(pdev, MTP_IN_EP, USBD_EP_TYPE_BULK, hmtp->MaxPcktLen); - pdev->ep_in[MTP_IN_EP & 0xFU].is_used = 1U; + (void)USBD_LL_OpenEP(pdev, MTPInEpAdd, USBD_EP_TYPE_BULK, hmtp->MaxPcktLen); + pdev->ep_in[MTPInEpAdd & 0xFU].is_used = 1U; /* Open EP OUT */ - (void)USBD_LL_OpenEP(pdev, MTP_OUT_EP, USBD_EP_TYPE_BULK, hmtp->MaxPcktLen); - pdev->ep_out[MTP_OUT_EP & 0xFU].is_used = 1U; + (void)USBD_LL_OpenEP(pdev, MTPOutEpAdd, USBD_EP_TYPE_BULK, hmtp->MaxPcktLen); + pdev->ep_out[MTPOutEpAdd & 0xFU].is_used = 1U; /* Open INTR EP IN */ - (void)USBD_LL_OpenEP(pdev, MTP_CMD_EP, USBD_EP_TYPE_INTR, MTP_CMD_PACKET_SIZE); - pdev->ep_in[MTP_CMD_EP & 0xFU].is_used = 1U; + (void)USBD_LL_OpenEP(pdev, MTPCmdEpAdd, USBD_EP_TYPE_INTR, MTP_CMD_PACKET_SIZE); + pdev->ep_in[MTPCmdEpAdd & 0xFU].is_used = 1U; /* Init the MTP layer */ (void)USBD_MTP_STORAGE_Init(pdev); @@ -312,25 +290,33 @@ static uint8_t USBD_MTP_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { UNUSED(cfgidx); +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this MTP class instance */ + MTPInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); + MTPOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); + MTPCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR); +#endif /* USE_USBD_COMPOSITE */ + /* Close EP IN */ - (void)USBD_LL_CloseEP(pdev, MTP_IN_EP); - pdev->ep_in[MTP_IN_EP & 0xFU].is_used = 0U; + (void)USBD_LL_CloseEP(pdev, MTPInEpAdd); + pdev->ep_in[MTPInEpAdd & 0xFU].is_used = 0U; /* Close EP OUT */ - (void)USBD_LL_CloseEP(pdev, MTP_OUT_EP); - pdev->ep_out[MTP_OUT_EP & 0xFU].is_used = 0U; + (void)USBD_LL_CloseEP(pdev, MTPOutEpAdd); + pdev->ep_out[MTPOutEpAdd & 0xFU].is_used = 0U; /* Close EP Command */ - (void)USBD_LL_CloseEP(pdev, MTP_CMD_EP); - pdev->ep_in[MTP_CMD_EP & 0xFU].is_used = 0U; - - /* De-Init the MTP layer */ - (void)USBD_MTP_STORAGE_DeInit(pdev); + (void)USBD_LL_CloseEP(pdev, MTPCmdEpAdd); + pdev->ep_in[MTPCmdEpAdd & 0xFU].is_used = 0U; /* Free MTP Class Resources */ - if (pdev->pClassData != NULL) + if (pdev->pClassDataCmsit[pdev->classId] != NULL) { - (void)USBD_free(pdev->pClassData); + /* De-Init the MTP layer */ + (void)USBD_MTP_STORAGE_DeInit(pdev); + + (void)USBD_free(pdev->pClassDataCmsit[pdev->classId]); + pdev->pClassDataCmsit[pdev->classId] = NULL; pdev->pClassData = NULL; } @@ -346,10 +332,15 @@ static uint8_t USBD_MTP_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) */ static uint8_t USBD_MTP_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; USBD_StatusTypeDef ret = USBD_OK; uint16_t len = 0U; +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this MTP class instance */ + MTPOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ + if (hmtp == NULL) { return (uint8_t)USBD_FAIL; @@ -373,7 +364,7 @@ static uint8_t USBD_MTP_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *re /* Stop low layer file system operations if any */ USBD_MTP_STORAGE_Cancel(pdev, MTP_PHASE_IDLE); - (void)USBD_LL_PrepareReceive(pdev, MTP_OUT_EP, (uint8_t *)&hmtp->rx_buff, hmtp->MaxPcktLen); + (void)USBD_LL_PrepareReceive(pdev, MTPOutEpAdd, (uint8_t *)&hmtp->rx_buff, hmtp->MaxPcktLen); break; case MTP_REQ_GET_DEVICE_STATUS: @@ -464,10 +455,16 @@ static uint8_t USBD_MTP_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *re static uint8_t USBD_MTP_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) { UNUSED(epnum); - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint16_t len; - if (epnum == (MTP_IN_EP & 0x7FU)) +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this MTP class instance */ + MTPInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); + MTPOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ + + if (epnum == (MTPInEpAdd & 0x7FU)) { switch (hmtp->MTP_ResponsePhase) { @@ -477,22 +474,24 @@ static uint8_t USBD_MTP_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) /* prepare to receive next operation */ len = MIN(hmtp->MaxPcktLen, pdev->request.wLength); - (void)USBD_LL_PrepareReceive(pdev, MTP_OUT_EP, (uint8_t *)&hmtp->rx_buff, len); + (void)USBD_LL_PrepareReceive(pdev, MTPOutEpAdd, (uint8_t *)&hmtp->rx_buff, len); hmtp->MTP_ResponsePhase = MTP_PHASE_IDLE; break; + case MTP_READ_DATA : (void)USBD_MTP_STORAGE_ReadData(pdev); /* prepare to receive next operation */ len = MIN(hmtp->MaxPcktLen, pdev->request.wLength); - (void)USBD_LL_PrepareReceive(pdev, MTP_IN_EP, (uint8_t *)&hmtp->rx_buff, len); + (void)USBD_LL_PrepareReceive(pdev, MTPInEpAdd, (uint8_t *)&hmtp->rx_buff, len); break; + case MTP_PHASE_IDLE : /* prepare to receive next operation */ len = MIN(hmtp->MaxPcktLen, pdev->request.wLength); - (void)USBD_LL_PrepareReceive(pdev, MTP_OUT_EP, (uint8_t *)&hmtp->rx_buff, len); + (void)USBD_LL_PrepareReceive(pdev, MTPOutEpAdd, (uint8_t *)&hmtp->rx_buff, len); break; default: @@ -512,9 +511,14 @@ static uint8_t USBD_MTP_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) static uint8_t USBD_MTP_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) { UNUSED(epnum); - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint16_t len; +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this MTP class instance */ + MTPOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ + (void)USBD_MTP_STORAGE_ReceiveOpt(pdev); switch (hmtp->MTP_ResponsePhase) @@ -542,14 +546,14 @@ static uint8_t USBD_MTP_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) /* prepare endpoint to receive operations */ len = MIN(hmtp->MaxPcktLen, pdev->request.wLength); - (void)USBD_LL_PrepareReceive(pdev, MTP_OUT_EP, (uint8_t *)&hmtp->rx_buff, len); + (void)USBD_LL_PrepareReceive(pdev, MTPOutEpAdd, (uint8_t *)&hmtp->rx_buff, len); break; case MTP_PHASE_IDLE : /* prepare to receive next operation */ len = MIN(hmtp->MaxPcktLen, pdev->request.wLength); - (void)USBD_LL_PrepareReceive(pdev, MTP_OUT_EP, (uint8_t *)&hmtp->rx_buff, len); + (void)USBD_LL_PrepareReceive(pdev, MTPOutEpAdd, (uint8_t *)&hmtp->rx_buff, len); break; default: @@ -559,7 +563,7 @@ static uint8_t USBD_MTP_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) return (uint8_t)USBD_OK; } - +#ifndef USE_USBD_COMPOSITE /** * @brief USBD_MTP_GetHSCfgDesc * Return configuration descriptor @@ -569,8 +573,27 @@ static uint8_t USBD_MTP_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) */ static uint8_t *USBD_MTP_GetHSCfgDesc(uint16_t *length) { - *length = (uint16_t)sizeof(USBD_MTP_CfgHSDesc); - return USBD_MTP_CfgHSDesc; + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_MTP_CfgDesc, MTP_IN_EP); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_MTP_CfgDesc, MTP_OUT_EP); + USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_MTP_CfgDesc, MTP_CMD_EP); + + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = MTP_DATA_MAX_HS_PACKET_SIZE; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = MTP_DATA_MAX_HS_PACKET_SIZE; + } + + if (pEpCmdDesc != NULL) + { + pEpCmdDesc->bInterval = MTP_HS_BINTERVAL; + } + + *length = (uint16_t)sizeof(USBD_MTP_CfgDesc); + return USBD_MTP_CfgDesc; } /** @@ -582,8 +605,27 @@ static uint8_t *USBD_MTP_GetHSCfgDesc(uint16_t *length) */ static uint8_t *USBD_MTP_GetFSCfgDesc(uint16_t *length) { - *length = (uint16_t)sizeof(USBD_MTP_CfgFSDesc); - return USBD_MTP_CfgFSDesc; + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_MTP_CfgDesc, MTP_IN_EP); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_MTP_CfgDesc, MTP_OUT_EP); + USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_MTP_CfgDesc, MTP_CMD_EP); + + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = MTP_DATA_MAX_FS_PACKET_SIZE; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = MTP_DATA_MAX_FS_PACKET_SIZE; + } + + if (pEpCmdDesc != NULL) + { + pEpCmdDesc->bInterval = MTP_FS_BINTERVAL; + } + + *length = (uint16_t)sizeof(USBD_MTP_CfgDesc); + return USBD_MTP_CfgDesc; } /** @@ -595,8 +637,27 @@ static uint8_t *USBD_MTP_GetFSCfgDesc(uint16_t *length) */ static uint8_t *USBD_MTP_GetOtherSpeedCfgDesc(uint16_t *length) { - *length = (uint16_t)sizeof(USBD_MTP_CfgFSDesc); - return USBD_MTP_CfgFSDesc; + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_MTP_CfgDesc, MTP_IN_EP); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_MTP_CfgDesc, MTP_OUT_EP); + USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_MTP_CfgDesc, MTP_CMD_EP); + + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = MTP_DATA_MAX_FS_PACKET_SIZE; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = MTP_DATA_MAX_FS_PACKET_SIZE; + } + + if (pEpCmdDesc != NULL) + { + pEpCmdDesc->bInterval = MTP_FS_BINTERVAL; + } + + *length = (uint16_t)sizeof(USBD_MTP_CfgDesc); + return USBD_MTP_CfgDesc; } /** @@ -610,6 +671,7 @@ static uint8_t *USBD_MTP_GetDeviceQualifierDescriptor(uint16_t *length) *length = (uint16_t)(sizeof(USBD_MTP_DeviceQualifierDesc)); return USBD_MTP_DeviceQualifierDesc; } +#endif /* USE_USBD_COMPOSITE */ /** * @brief USBD_MTP_RegisterInterface @@ -624,7 +686,7 @@ uint8_t USBD_MTP_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_MTP_ItfTypeDef return (uint8_t)USBD_FAIL; } - pdev->pUserData = fops; + pdev->pUserData[pdev->classId] = fops; return (uint8_t)USBD_OK; } diff --git a/Class/MTP/Src/usbd_mtp_opt.c b/Class/MTP/Src/usbd_mtp_opt.c index b5090eb..9a49717 100644 --- a/Class/MTP/Src/usbd_mtp_opt.c +++ b/Class/MTP/Src/usbd_mtp_opt.c @@ -73,7 +73,7 @@ static uint32_t MTP_build_data_proplist(USBD_HandleTypeDef *pdev, */ void USBD_MTP_OPT_CreateObjectHandle(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hmtp->OperationsContainer.Param1 == 0U) /* Param1 == Session ID*/ { @@ -104,12 +104,13 @@ void USBD_MTP_OPT_CreateObjectHandle(USBD_HandleTypeDef *pdev) */ void USBD_MTP_OPT_GetDeviceInfo(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hmtp->MTP_SessionState == MTP_SESSION_NOT_OPENED) /* no session opened */ { /* if GetDevice Info called outside a session then SessionID and Transaction_ID shall be 0x00000000*/ - if ((hmtp->OperationsContainer.Param1 == 0U) && (hmtp->OperationsContainer.trans_id == 0U)) /* Param1 == session ID*/ + /* Param1 == session ID*/ + if ((hmtp->OperationsContainer.Param1 == 0U) && (hmtp->OperationsContainer.trans_id == 0U)) { hmtp->ResponseCode = MTP_RESPONSE_OK; } @@ -147,7 +148,7 @@ void USBD_MTP_OPT_GetDeviceInfo(USBD_HandleTypeDef *pdev) */ void USBD_MTP_OPT_GetStorageIDS(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; hmtp->GenericContainer.code = MTP_OP_GET_STORAGE_IDS; hmtp->GenericContainer.trans_id = hmtp->OperationsContainer.trans_id; hmtp->GenericContainer.type = MTP_CONT_TYPE_DATA; @@ -168,7 +169,7 @@ void USBD_MTP_OPT_GetStorageIDS(USBD_HandleTypeDef *pdev) */ void USBD_MTP_OPT_GetStorageInfo(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; hmtp->GenericContainer.code = MTP_OP_GET_STORAGE_INFO; hmtp->GenericContainer.trans_id = hmtp->OperationsContainer.trans_id; hmtp->GenericContainer.type = MTP_CONT_TYPE_DATA; @@ -189,7 +190,7 @@ void USBD_MTP_OPT_GetStorageInfo(USBD_HandleTypeDef *pdev) */ void USBD_MTP_OPT_GetObjectHandle(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; hmtp->GenericContainer.code = MTP_OP_GET_OBJECT_HANDLES; hmtp->GenericContainer.trans_id = hmtp->OperationsContainer.trans_id; hmtp->GenericContainer.type = MTP_CONT_TYPE_DATA; @@ -210,7 +211,7 @@ void USBD_MTP_OPT_GetObjectHandle(USBD_HandleTypeDef *pdev) */ void USBD_MTP_OPT_GetObjectInfo(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; hmtp->GenericContainer.code = MTP_OP_GET_OBJECT_INFO; hmtp->GenericContainer.trans_id = hmtp->OperationsContainer.trans_id; @@ -232,7 +233,7 @@ void USBD_MTP_OPT_GetObjectInfo(USBD_HandleTypeDef *pdev) */ void USBD_MTP_OPT_GetObjectReferences(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; hmtp->GenericContainer.code = MTP_OP_GET_OBJECT_PROP_REFERENCES; hmtp->GenericContainer.trans_id = hmtp->OperationsContainer.trans_id; @@ -254,7 +255,7 @@ void USBD_MTP_OPT_GetObjectReferences(USBD_HandleTypeDef *pdev) */ void USBD_MTP_OPT_GetObjectPropSupp(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; hmtp->GenericContainer.code = MTP_OP_GET_OBJECT_PROPS_SUPPORTED; hmtp->GenericContainer.trans_id = hmtp->OperationsContainer.trans_id; @@ -276,7 +277,7 @@ void USBD_MTP_OPT_GetObjectPropSupp(USBD_HandleTypeDef *pdev) */ void USBD_MTP_OPT_GetObjectPropDesc(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; hmtp->GenericContainer.code = MTP_OP_GET_OBJECT_PROP_DESC; hmtp->GenericContainer.trans_id = hmtp->OperationsContainer.trans_id; @@ -298,7 +299,7 @@ void USBD_MTP_OPT_GetObjectPropDesc(USBD_HandleTypeDef *pdev) */ void USBD_MTP_OPT_GetObjectPropList(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; hmtp->GenericContainer.code = MTP_OP_GET_OBJECT_PROPLIST; hmtp->GenericContainer.trans_id = hmtp->OperationsContainer.trans_id; @@ -320,7 +321,7 @@ void USBD_MTP_OPT_GetObjectPropList(USBD_HandleTypeDef *pdev) */ void USBD_MTP_OPT_GetObjectPropValue(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; hmtp->GenericContainer.code = MTP_OP_GET_OBJECT_PROP_VALUE; hmtp->GenericContainer.trans_id = hmtp->OperationsContainer.trans_id; @@ -342,8 +343,8 @@ void USBD_MTP_OPT_GetObjectPropValue(USBD_HandleTypeDef *pdev) */ void USBD_MTP_OPT_GetObject(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; - USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId]; hmtp->GenericContainer.length = hmtpif->GetContainerLength(hmtp->OperationsContainer.Param1); hmtp->GenericContainer.trans_id = hmtp->OperationsContainer.trans_id; @@ -360,7 +361,7 @@ void USBD_MTP_OPT_GetObject(USBD_HandleTypeDef *pdev) */ void USBD_MTP_OPT_GetDevicePropDesc(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; hmtp->GenericContainer.code = MTP_OP_GET_DEVICE_PROP_DESC; hmtp->GenericContainer.trans_id = hmtp->OperationsContainer.trans_id; @@ -382,8 +383,8 @@ void USBD_MTP_OPT_GetDevicePropDesc(USBD_HandleTypeDef *pdev) */ void USBD_MTP_OPT_SendObject(USBD_HandleTypeDef *pdev, uint8_t *buff, uint32_t len) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; - USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId]; static uint32_t tmp = 0U; switch (hmtp->RECEIVE_DATA_STATUS) @@ -443,8 +444,8 @@ void USBD_MTP_OPT_SendObject(USBD_HandleTypeDef *pdev, uint8_t *buff, uint32_t */ void USBD_MTP_OPT_SendObjectInfo(USBD_HandleTypeDef *pdev, uint8_t *buff, uint32_t len) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; - USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId]; MTP_ObjectInfoTypeDef ObjectInfo; uint8_t dataLength = offsetof(MTP_ObjectInfoTypeDef, Filename); uint8_t *tmp; @@ -516,8 +517,8 @@ void USBD_MTP_OPT_SendObjectInfo(USBD_HandleTypeDef *pdev, uint8_t *buff, uint3 */ void USBD_MTP_OPT_DeleteObject(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; - USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId]; hmtp->GenericContainer.trans_id = hmtp->OperationsContainer.trans_id; hmtp->GenericContainer.type = MTP_CONT_TYPE_RESPONSE; @@ -534,8 +535,8 @@ void USBD_MTP_OPT_DeleteObject(USBD_HandleTypeDef *pdev) */ static void MTP_Get_PayloadContent(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; - USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId]; uint8_t *buffer = hmtp->GenericContainer.data; uint32_t i; uint32_t n_idx; @@ -744,7 +745,7 @@ static void MTP_Get_DeviceInfo(void) */ static void MTP_Get_StorageInfo(USBD_HandleTypeDef *pdev) { - USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData; + USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId]; MTP_StorageInfo.StorageType = MTP_STORAGE_REMOVABLE_RAM; MTP_StorageInfo.FilesystemType = MTP_FILESYSTEM_GENERIC_FLAT; @@ -764,8 +765,8 @@ static void MTP_Get_StorageInfo(USBD_HandleTypeDef *pdev) */ static void MTP_Get_ObjectHandle(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; - USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId]; MTP_ObjectHandle.ObjectHandle_len = (uint32_t)(hmtpif->GetIdx(hmtp->OperationsContainer.Param3, MTP_ObjectHandle.ObjectHandle)); @@ -799,7 +800,7 @@ static void MTP_Get_ObjectPropSupp(void) */ static void MTP_Get_ObjectPropDesc(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint16_t undef_format = MTP_OBJ_FORMAT_UNDEFINED; uint32_t storageid = MTP_STORAGE_ID; @@ -896,8 +897,8 @@ static void MTP_Get_ObjectPropDesc(USBD_HandleTypeDef *pdev) */ static uint8_t *MTP_Get_ObjectPropValue(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; - USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId]; static uint8_t buf[512]; /* Add all other supported object properties */ @@ -950,8 +951,8 @@ static uint8_t *MTP_Get_ObjectPropValue(USBD_HandleTypeDef *pdev) */ static void MTP_Get_ObjectPropList(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; - USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId]; uint16_t filename[255]; uint32_t storageid = MTP_STORAGE_ID; uint32_t default_val = 0U; @@ -990,7 +991,7 @@ static void MTP_Get_ObjectPropList(USBD_HandleTypeDef *pdev) /* MTP_FileName.FileName_len value shall be set before USBD_MTP_FS_GetObjectName */ MTP_FileName.FileName_len = hmtpif->GetObjectName_len(hmtp->OperationsContainer.Param1); hmtpif->GetObjectName(hmtp->OperationsContainer.Param1, MTP_FileName.FileName_len, filename); - (void)USBD_memcpy(MTP_FileName.FileName, filename, ((uint32_t)MTP_FileName.FileName_len * 2U) + 1U ); + (void)USBD_memcpy(MTP_FileName.FileName, filename, ((uint32_t)MTP_FileName.FileName_len * 2U) + 1U); MTP_PropertiesList.MTP_Properties[i].propval = (uint8_t *)&MTP_FileName; break; @@ -1014,7 +1015,7 @@ static void MTP_Get_ObjectPropList(USBD_HandleTypeDef *pdev) /* MTP_FileName.FileName_len value shall be set before USBD_MTP_FS_GetObjectName */ MTP_FileName.FileName_len = hmtpif->GetObjectName_len(hmtp->OperationsContainer.Param1); hmtpif->GetObjectName(hmtp->OperationsContainer.Param1, MTP_FileName.FileName_len, filename); - (void)USBD_memcpy(MTP_FileName.FileName, filename, ((uint32_t)MTP_FileName.FileName_len * 2U) + 1U ); + (void)USBD_memcpy(MTP_FileName.FileName, filename, ((uint32_t)MTP_FileName.FileName_len * 2U) + 1U); MTP_PropertiesList.MTP_Properties[i].propval = (uint8_t *)&MTP_FileName; break; @@ -1075,8 +1076,8 @@ static void MTP_Get_DevicePropDesc(void) */ static void MTP_Get_ObjectInfo(USBD_HandleTypeDef *pdev) { - USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData; - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId]; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint16_t filename[255]; MTP_ObjectInfo.Storage_id = MTP_STORAGE_ID; @@ -1126,7 +1127,7 @@ static void MTP_Get_StorageIDS(void) */ static uint32_t MTP_build_data_propdesc(USBD_HandleTypeDef *pdev, MTP_ObjectPropDescTypeDef def) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint8_t DefValue_size = (MTP_FileName.FileName_len * 2U) + 1U; uint32_t dataLength = offsetof(MTP_ObjectPropDescTypeDef, DefValue); @@ -1185,7 +1186,7 @@ static uint32_t MTP_build_data_propdesc(USBD_HandleTypeDef *pdev, MTP_ObjectPro static uint32_t MTP_build_data_proplist(USBD_HandleTypeDef *pdev, MTP_PropertiesListTypedef proplist, uint32_t idx) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint8_t propval_size = (MTP_FileName.FileName_len * 2U) + 1U; uint32_t dataLength; @@ -1248,7 +1249,7 @@ static uint32_t MTP_build_data_proplist(USBD_HandleTypeDef *pdev, */ static uint32_t MTP_build_data_ObjInfo(USBD_HandleTypeDef *pdev, MTP_ObjectInfoTypeDef objinfo) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint32_t ObjInfo_len = offsetof(MTP_ObjectInfoTypeDef, Filename); (void)USBD_memcpy(hmtp->GenericContainer.data, (const uint8_t *)&objinfo, ObjInfo_len); diff --git a/Class/MTP/Src/usbd_mtp_storage.c b/Class/MTP/Src/usbd_mtp_storage.c index bfbcc32..afe234b 100644 --- a/Class/MTP/Src/usbd_mtp_storage.c +++ b/Class/MTP/Src/usbd_mtp_storage.c @@ -22,6 +22,9 @@ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ +extern uint8_t MTPInEpAdd; +extern uint8_t MTPOutEpAdd; + /* Private variables ---------------------------------------------------------*/ static MTP_DataLengthTypeDef MTP_DataLength; static MTP_READ_DATA_STATUS ReadDataStatus; @@ -44,13 +47,17 @@ static uint8_t USBD_MTP_STORAGE_SendData(USBD_HandleTypeDef *pdev, uint8_t *buf */ uint8_t USBD_MTP_STORAGE_Init(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + MTPOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ /* Initialize the HW layyer of the file system */ - (void)((USBD_MTP_ItfTypeDef *)pdev->pUserData)->Init(); + (void)((USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init(); /* Prepare EP to Receive First Operation */ - (void)USBD_LL_PrepareReceive(pdev, MTP_OUT_EP, (uint8_t *)&hmtp->rx_buff, + (void)USBD_LL_PrepareReceive(pdev, MTPOutEpAdd, (uint8_t *)&hmtp->rx_buff, hmtp->MaxPcktLen); return (uint8_t)USBD_OK; @@ -64,7 +71,7 @@ uint8_t USBD_MTP_STORAGE_Init(USBD_HandleTypeDef *pdev) */ uint8_t USBD_MTP_STORAGE_DeInit(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; /* DeInit physical Interface components */ hmtp->MTP_SessionState = MTP_SESSION_NOT_OPENED; @@ -73,7 +80,7 @@ uint8_t USBD_MTP_STORAGE_DeInit(USBD_HandleTypeDef *pdev) USBD_MTP_STORAGE_Cancel(pdev, MTP_PHASE_IDLE); /* Free low layer file system resources */ - (void)((USBD_MTP_ItfTypeDef *)pdev->pUserData)->DeInit(); + (void)((USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit(); return (uint8_t)USBD_OK; } @@ -86,11 +93,11 @@ uint8_t USBD_MTP_STORAGE_DeInit(USBD_HandleTypeDef *pdev) */ uint8_t USBD_MTP_STORAGE_ReadData(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint32_t *data_buff; /* Get the data buffer pointer from the low layer interface */ - data_buff = ((USBD_MTP_ItfTypeDef *)pdev->pUserData)->ScratchBuff; + data_buff = ((USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId])->ScratchBuff; switch (ReadDataStatus) { @@ -99,8 +106,8 @@ uint8_t USBD_MTP_STORAGE_ReadData(USBD_HandleTypeDef *pdev) MTP_DataLength.temp_length = 0U; /* Perform the low layer read operation on the scratch buffer */ - (void)((USBD_MTP_ItfTypeDef *)pdev->pUserData)->ReadData(hmtp->OperationsContainer.Param1, - (uint8_t *)data_buff, &MTP_DataLength); + (void)((USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId])->ReadData(hmtp->OperationsContainer.Param1, + (uint8_t *)data_buff, &MTP_DataLength); /* Add the container header to the data buffer */ (void)USBD_memcpy((uint8_t *)data_buff, (uint8_t *)&hmtp->GenericContainer, MTP_CONT_HEADER_SIZE); @@ -124,8 +131,8 @@ uint8_t USBD_MTP_STORAGE_ReadData(USBD_HandleTypeDef *pdev) case READ_REST_OF_DATA: /* Perform the low layer read operation on the scratch buffer */ - (void)((USBD_MTP_ItfTypeDef *)pdev->pUserData)->ReadData(hmtp->OperationsContainer.Param1, - (uint8_t *)data_buff, &MTP_DataLength); + (void)((USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId])->ReadData(hmtp->OperationsContainer.Param1, + (uint8_t *)data_buff, &MTP_DataLength); /* Check if more data need to be sent */ if (MTP_DataLength.temp_length == MTP_DataLength.totallen) @@ -164,7 +171,7 @@ uint8_t USBD_MTP_STORAGE_ReadData(USBD_HandleTypeDef *pdev) */ uint8_t USBD_MTP_STORAGE_SendContainer(USBD_HandleTypeDef *pdev, MTP_CONTAINER_TYPE CONT_TYPE) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; switch (CONT_TYPE) { case DATA_TYPE: @@ -194,9 +201,14 @@ uint8_t USBD_MTP_STORAGE_SendContainer(USBD_HandleTypeDef *pdev, MTP_CONTAINER_ */ uint8_t USBD_MTP_STORAGE_ReceiveOpt(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint32_t *pMsgBuffer; - MTP_DataLength.rx_length = USBD_GetRxCount(pdev, MTP_OUT_EP); +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + MTPOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ + MTP_DataLength.rx_length = USBD_GetRxCount(pdev, MTPOutEpAdd); + switch (hmtp->RECEIVE_DATA_STATUS) { case RECEIVE_REST_OF_DATA: @@ -233,7 +245,7 @@ uint8_t USBD_MTP_STORAGE_ReceiveOpt(USBD_HandleTypeDef *pdev) */ uint8_t USBD_MTP_STORAGE_ReceiveData(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; switch (hmtp->RECEIVE_DATA_STATUS) { case RECEIVE_COMMAND_DATA : @@ -297,7 +309,7 @@ uint8_t USBD_MTP_STORAGE_ReceiveData(USBD_HandleTypeDef *pdev) */ static uint8_t USBD_MTP_STORAGE_DecodeOperations(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; switch (hmtp->OperationsContainer.code) { case MTP_OP_GET_DEVICE_INFO: @@ -398,7 +410,7 @@ static uint8_t USBD_MTP_STORAGE_DecodeOperations(USBD_HandleTypeDef *pdev) static uint8_t USBD_MTP_STORAGE_ReceiveContainer(USBD_HandleTypeDef *pdev, uint32_t *pDst, uint32_t len) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint32_t Counter; uint32_t *pdst = pDst; @@ -420,7 +432,7 @@ static uint8_t USBD_MTP_STORAGE_ReceiveContainer(USBD_HandleTypeDef *pdev, void USBD_MTP_STORAGE_Cancel(USBD_HandleTypeDef *pdev, MTP_ResponsePhaseTypeDef MTP_ResponsePhase) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; hmtp->MTP_ResponsePhase = MTP_PHASE_IDLE; ReadDataStatus = READ_FIRST_DATA; @@ -428,11 +440,11 @@ void USBD_MTP_STORAGE_Cancel(USBD_HandleTypeDef *pdev, if (MTP_ResponsePhase == MTP_RECEIVE_DATA) { - ((USBD_MTP_ItfTypeDef *)pdev->pUserData)->Cancel(1U); + ((USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId])->Cancel(1U); } else { - ((USBD_MTP_ItfTypeDef *)pdev->pUserData)->Cancel(0U); + ((USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId])->Cancel(0U); } } @@ -447,10 +459,14 @@ void USBD_MTP_STORAGE_Cancel(USBD_HandleTypeDef *pdev, static uint8_t USBD_MTP_STORAGE_SendData(USBD_HandleTypeDef *pdev, uint8_t *buf, uint32_t len) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassData; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint32_t length = MIN(hmtp->GenericContainer.length, len); +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + MTPInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ - (void)USBD_LL_Transmit(pdev, MTP_IN_EP, buf, length); + (void)USBD_LL_Transmit(pdev, MTPInEpAdd, buf, length); return (uint8_t)USBD_OK; } diff --git a/Class/Printer/Inc/usbd_printer.h b/Class/Printer/Inc/usbd_printer.h index b93cda7..bf00b9c 100644 --- a/Class/Printer/Inc/usbd_printer.h +++ b/Class/Printer/Inc/usbd_printer.h @@ -113,8 +113,7 @@ typedef struct __IO uint32_t TxState; __IO uint32_t RxState; -} -USBD_PRNT_HandleTypeDef; +} USBD_PRNT_HandleTypeDef; diff --git a/Class/Printer/Src/usbd_printer.c b/Class/Printer/Src/usbd_printer.c index 25a7433..9c37f23 100644 --- a/Class/Printer/Src/usbd_printer.c +++ b/Class/Printer/Src/usbd_printer.c @@ -102,27 +102,13 @@ static uint8_t USBD_PRNT_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *r static uint8_t USBD_PRNT_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); static uint8_t USBD_PRNT_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum); +#ifndef USE_USBD_COMPOSITE static uint8_t *USBD_PRNT_GetFSCfgDesc(uint16_t *length); static uint8_t *USBD_PRNT_GetHSCfgDesc(uint16_t *length); static uint8_t *USBD_PRNT_GetOtherSpeedCfgDesc(uint16_t *length); static uint8_t *USBD_PRNT_GetOtherSpeedCfgDesc(uint16_t *length); uint8_t *USBD_PRNT_GetDeviceQualifierDescriptor(uint16_t *length); - -/* USB Standard Device Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_PRNT_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = -{ - USB_LEN_DEV_QUALIFIER_DESC, - USB_DESC_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x01, - 0x00, -}; - +#endif /* USE_USBD_COMPOSITE */ /** * @} */ @@ -144,14 +130,22 @@ USBD_ClassTypeDef USBD_PRNT = NULL, NULL, NULL, +#ifdef USE_USBD_COMPOSITE + NULL, + NULL, + NULL, + NULL, +#else USBD_PRNT_GetHSCfgDesc, USBD_PRNT_GetFSCfgDesc, USBD_PRNT_GetOtherSpeedCfgDesc, USBD_PRNT_GetDeviceQualifierDescriptor, +#endif /* USE_USBD_COMPOSITE */ }; +#ifndef USE_USBD_COMPOSITE /* USB PRNT device Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_PRNT_CfgHSDesc[] __ALIGN_END = +__ALIGN_BEGIN static uint8_t USBD_PRNT_CfgDesc[] __ALIGN_END = { /*Configuration Descriptor*/ 0x09, /* bLength: Configuration Descriptor size */ @@ -165,56 +159,7 @@ __ALIGN_BEGIN static uint8_t USBD_PRNT_CfgHSDesc[] __ALIGN_END = 0xC0, /* bmAttributes: Self Powered according to user configuration */ #else 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif - USBD_MAX_POWER, /* MaxPower in mA */ - - /* Interface Descriptor */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints: 2 endpoints used */ - 0x07, /* bInterfaceClass: Communication Interface Class */ - 0x01, /* bInterfaceSubClass: Abstract Control Model */ - USB_PRNT_BIDIRECTIONAL, /* bDeviceProtocol */ - 0x00, /* iInterface */ - - /* Endpoint IN Descriptor */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - PRNT_IN_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - LOBYTE(PRNT_DATA_HS_IN_PACKET_SIZE), /* wMaxPacketSize */ - HIBYTE(PRNT_DATA_HS_IN_PACKET_SIZE), - 0x00, /* bInterval */ - - /* Endpoint OUT Descriptor */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - PRNT_OUT_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - LOBYTE(PRNT_DATA_HS_OUT_PACKET_SIZE),/* wMaxPacketSize */ - HIBYTE(PRNT_DATA_HS_OUT_PACKET_SIZE), - 0x00 /* bInterval */ -}; - - -/* USB PRNT device Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_PRNT_CfgFSDesc[] __ALIGN_END = -{ - /*Configuration Descriptor*/ - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - USB_PRNT_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */ - 0x00, - 0x01, /* bNumInterfaces: 1 interface */ - 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ -#if (USBD_SELF_POWERED == 1U) - 0xC0, /* bmAttributes: Self Powered according to user configuration */ -#else - 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif +#endif /* USBD_SELF_POWERED */ USBD_MAX_POWER, /* MaxPower in mA */ /*Interface Descriptor */ @@ -247,52 +192,24 @@ __ALIGN_BEGIN static uint8_t USBD_PRNT_CfgFSDesc[] __ALIGN_END = 0x00 /* bInterval */ }; -__ALIGN_BEGIN static uint8_t USBD_PRNT_OtherSpeedCfgDesc[] __ALIGN_END = +/* USB Standard Device Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_PRNT_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = { - /*Configuration Descriptor*/ - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - USB_PRNT_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */ + USB_LEN_DEV_QUALIFIER_DESC, + USB_DESC_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x01, 0x00, - 0x01, /* bNumInterfaces: 1 interface */ - 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ -#if (USBD_SELF_POWERED == 1U) - 0xC0, /* bmAttributes: Self Powered according to user configuration */ -#else - 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif - USBD_MAX_POWER, /* MaxPower in mA */ - - /*Interface Descriptor */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints: 2 endpoints used */ - 0x07, /* bInterfaceClass: Communication Interface Class */ - 0x01, /* bInterfaceSubClass: Abstract Control Model */ - USB_PRNT_BIDIRECTIONAL, /* bDeviceProtocol */ - 0x00, /* iInterface */ - - /*Endpoint IN Descriptor*/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - PRNT_IN_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - LOBYTE(PRNT_DATA_FS_IN_PACKET_SIZE), /* wMaxPacketSize */ - HIBYTE(PRNT_DATA_FS_IN_PACKET_SIZE), - 0x00, /* bInterval */ - - /*Endpoint OUT Descriptor*/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - PRNT_OUT_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - LOBYTE(PRNT_DATA_FS_OUT_PACKET_SIZE),/* wMaxPacketSize */ - HIBYTE(PRNT_DATA_FS_OUT_PACKET_SIZE), - 0x00 /* bInterval */ }; +#endif /* USE_USBD_COMPOSITE */ + +static uint8_t PRNTInEpAdd = PRNT_IN_EP; +static uint8_t PRNTOutEpAdd = PRNT_OUT_EP; /** * @} @@ -315,16 +232,26 @@ static uint8_t USBD_PRNT_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) USBD_PRNT_HandleTypeDef *hPRNT; uint16_t mps; + hPRNT = (USBD_PRNT_HandleTypeDef *)USBD_malloc(sizeof(USBD_PRNT_HandleTypeDef)); if (hPRNT == NULL) { - pdev->pClassData = NULL; + pdev->pClassDataCmsit[pdev->classId] = NULL; return (uint8_t)USBD_EMEM; } + (void)USBD_memset(hPRNT, 0, sizeof(USBD_PRNT_HandleTypeDef)); + /* Setup the pClassData pointer */ - pdev->pClassData = (void *)hPRNT; + pdev->pClassDataCmsit[pdev->classId] = (void *)hPRNT; + pdev->pClassData = pdev->pClassDataCmsit[pdev->classId]; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + PRNTInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); + PRNTOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ /* Setup the max packet size according to selected speed */ if (pdev->dev_speed == USBD_SPEED_HIGH) @@ -337,22 +264,29 @@ static uint8_t USBD_PRNT_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) } /* Open EP IN */ - (void)USBD_LL_OpenEP(pdev, PRNT_IN_EP, USBD_EP_TYPE_BULK, mps); + (void)USBD_LL_OpenEP(pdev, PRNTInEpAdd, USBD_EP_TYPE_BULK, mps); /* Set endpoint as used */ - pdev->ep_in[PRNT_IN_EP & 0xFU].is_used = 1U; + pdev->ep_in[PRNTInEpAdd & 0xFU].is_used = 1U; /* Open EP OUT */ - (void)USBD_LL_OpenEP(pdev, PRNT_OUT_EP, USBD_EP_TYPE_BULK, mps); + (void)USBD_LL_OpenEP(pdev, PRNTOutEpAdd, USBD_EP_TYPE_BULK, mps); /* Set endpoint as used */ - pdev->ep_out[PRNT_OUT_EP & 0xFU].is_used = 1U; + pdev->ep_out[PRNTOutEpAdd & 0xFU].is_used = 1U; + + hPRNT->RxBuffer = NULL; /* Init physical Interface components */ - ((USBD_PRNT_ItfTypeDef *)pdev->pUserData)->Init(); + ((USBD_PRNT_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init(); + + if (hPRNT->RxBuffer == NULL) + { + return (uint8_t)USBD_EMEM; + } /* Prepare Out endpoint to receive next packet */ - (void)USBD_LL_PrepareReceive(pdev, PRNT_OUT_EP, hPRNT->RxBuffer, mps); + (void)USBD_LL_PrepareReceive(pdev, PRNTOutEpAdd, hPRNT->RxBuffer, mps); /* End of initialization phase */ return (uint8_t)USBD_OK; @@ -369,19 +303,26 @@ static uint8_t USBD_PRNT_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { UNUSED(cfgidx); +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + PRNTInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); + PRNTOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ + /* Close EP IN */ - (void)USBD_LL_CloseEP(pdev, PRNT_IN_EP); - pdev->ep_in[PRNT_IN_EP & 0xFU].is_used = 0U; + (void)USBD_LL_CloseEP(pdev, PRNTInEpAdd); + pdev->ep_in[PRNTInEpAdd & 0xFU].is_used = 0U; /* Close EP OUT */ - (void)USBD_LL_CloseEP(pdev, PRNT_OUT_EP); - pdev->ep_out[PRNT_OUT_EP & 0xFU].is_used = 0U; + (void)USBD_LL_CloseEP(pdev, PRNTOutEpAdd); + pdev->ep_out[PRNTOutEpAdd & 0xFU].is_used = 0U; /* DeInit physical Interface components */ - if (pdev->pClassData != NULL) + if (pdev->pClassDataCmsit[pdev->classId] != NULL) { - ((USBD_PRNT_ItfTypeDef *)pdev->pUserData)->DeInit(); - (void)USBD_free(pdev->pClassData); + ((USBD_PRNT_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit(); + (void)USBD_free(pdev->pClassDataCmsit[pdev->classId]); + pdev->pClassDataCmsit[pdev->classId] = NULL; pdev->pClassData = NULL; } @@ -397,8 +338,8 @@ static uint8_t USBD_PRNT_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) */ static uint8_t USBD_PRNT_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { - USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *)pdev->pClassData; - USBD_PRNT_ItfTypeDef *hPRNTitf = (USBD_PRNT_ItfTypeDef *)pdev->pUserData; + USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_PRNT_ItfTypeDef *hPRNTitf = (USBD_PRNT_ItfTypeDef *)pdev->pUserData[pdev->classId]; USBD_StatusTypeDef ret = USBD_OK; uint16_t status_info = 0U; @@ -495,7 +436,7 @@ static uint8_t USBD_PRNT_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *r */ static uint8_t USBD_PRNT_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) { - USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *)pdev->pClassData; + USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; PCD_HandleTypeDef *hpcd = pdev->pData; if (hPRNT == NULL) @@ -503,11 +444,11 @@ static uint8_t USBD_PRNT_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) return (uint8_t)USBD_FAIL; } - if ((pdev->ep_in[epnum].total_length > 0U) && - ((pdev->ep_in[epnum].total_length % hpcd->IN_ep[epnum].maxpacket) == 0U)) + if ((pdev->ep_in[epnum & 0xFU].total_length > 0U) && + ((pdev->ep_in[epnum & 0xFU].total_length % hpcd->IN_ep[epnum & 0xFU].maxpacket) == 0U)) { /* Update the packet total length */ - pdev->ep_in[epnum].total_length = 0U; + pdev->ep_in[epnum & 0xFU].total_length = 0U; /* Send ZLP */ (void) USBD_LL_Transmit(pdev, epnum, NULL, 0U); @@ -528,7 +469,7 @@ static uint8_t USBD_PRNT_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) */ static uint8_t USBD_PRNT_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) { - USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *)pdev->pClassData; + USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if (hPRNT == NULL) { @@ -540,11 +481,12 @@ static uint8_t USBD_PRNT_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) /* USB data will be immediately processed, this allow next USB traffic being NAKed till the end of the application Xfer */ - ((USBD_PRNT_ItfTypeDef *)pdev->pUserData)->Receive(hPRNT->RxBuffer, &hPRNT->RxLength); + ((USBD_PRNT_ItfTypeDef *)pdev->pUserData[pdev->classId])->Receive(hPRNT->RxBuffer, &hPRNT->RxLength); return (uint8_t)USBD_OK; } +#ifndef USE_USBD_COMPOSITE /** * @brief USBD_PRNT_GetFSCfgDesc * Return configuration descriptor @@ -553,8 +495,21 @@ static uint8_t USBD_PRNT_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) */ static uint8_t *USBD_PRNT_GetFSCfgDesc(uint16_t *length) { - *length = (uint16_t) sizeof(USBD_PRNT_CfgFSDesc); - return USBD_PRNT_CfgFSDesc; + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_PRNT_CfgDesc, PRNT_IN_EP); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_PRNT_CfgDesc, PRNT_OUT_EP); + + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = PRNT_DATA_FS_IN_PACKET_SIZE; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = PRNT_DATA_FS_OUT_PACKET_SIZE; + } + + *length = (uint16_t) sizeof(USBD_PRNT_CfgDesc); + return USBD_PRNT_CfgDesc; } /** @@ -565,8 +520,21 @@ static uint8_t *USBD_PRNT_GetFSCfgDesc(uint16_t *length) */ static uint8_t *USBD_PRNT_GetHSCfgDesc(uint16_t *length) { - *length = (uint16_t) sizeof(USBD_PRNT_CfgHSDesc); - return USBD_PRNT_CfgHSDesc; + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_PRNT_CfgDesc, PRNT_IN_EP); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_PRNT_CfgDesc, PRNT_OUT_EP); + + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = PRNT_DATA_HS_IN_PACKET_SIZE; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = PRNT_DATA_HS_OUT_PACKET_SIZE; + } + + *length = (uint16_t) sizeof(USBD_PRNT_CfgDesc); + return USBD_PRNT_CfgDesc; } /** @@ -577,8 +545,21 @@ static uint8_t *USBD_PRNT_GetHSCfgDesc(uint16_t *length) */ static uint8_t *USBD_PRNT_GetOtherSpeedCfgDesc(uint16_t *length) { - *length = (uint16_t) sizeof(USBD_PRNT_OtherSpeedCfgDesc); - return USBD_PRNT_OtherSpeedCfgDesc; + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_PRNT_CfgDesc, PRNT_IN_EP); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_PRNT_CfgDesc, PRNT_OUT_EP); + + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = PRNT_DATA_FS_IN_PACKET_SIZE; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = PRNT_DATA_FS_OUT_PACKET_SIZE; + } + + *length = (uint16_t) sizeof(USBD_PRNT_CfgDesc); + return USBD_PRNT_CfgDesc; } /** @@ -592,6 +573,7 @@ uint8_t *USBD_PRNT_GetDeviceQualifierDescriptor(uint16_t *length) *length = (uint16_t)sizeof(USBD_PRNT_DeviceQualifierDesc); return USBD_PRNT_DeviceQualifierDesc; } +#endif /* USE_USBD_COMPOSITE */ /** * @brief USBD_PRNT_RegisterInterface @@ -608,7 +590,7 @@ uint8_t USBD_PRNT_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_PRNT_ItfTypeD } /* Setup the fops pointer */ - pdev->pUserData = fops; + pdev->pUserData[pdev->classId] = fops; return (uint8_t)USBD_OK; } @@ -621,7 +603,7 @@ uint8_t USBD_PRNT_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_PRNT_ItfTypeD */ uint8_t USBD_PRNT_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff) { - USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *) pdev->pClassData; + USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *) pdev->pClassDataCmsit[pdev->classId]; hPRNT->RxBuffer = pbuff; @@ -636,7 +618,13 @@ uint8_t USBD_PRNT_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff) */ uint8_t USBD_PRNT_ReceivePacket(USBD_HandleTypeDef *pdev) { - USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *)pdev->pClassData; + USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + PRNTInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); + PRNTOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); +#endif /* USE_USBD_COMPOSITE */ if (hPRNT == NULL) { @@ -646,18 +634,19 @@ uint8_t USBD_PRNT_ReceivePacket(USBD_HandleTypeDef *pdev) if (pdev->dev_speed == USBD_SPEED_HIGH) { /* Prepare Out endpoint to receive next packet */ - (void)USBD_LL_PrepareReceive(pdev, PRNT_OUT_EP, hPRNT->RxBuffer, + (void)USBD_LL_PrepareReceive(pdev, PRNTOutEpAdd, hPRNT->RxBuffer, PRNT_DATA_HS_OUT_PACKET_SIZE); } else { /* Prepare Out endpoint to receive next packet */ - (void)USBD_LL_PrepareReceive(pdev, PRNT_OUT_EP, hPRNT->RxBuffer, + (void)USBD_LL_PrepareReceive(pdev, PRNTOutEpAdd, hPRNT->RxBuffer, PRNT_DATA_FS_OUT_PACKET_SIZE); } return (uint8_t)USBD_OK; } + /** * @} */ diff --git a/Class/Template/Src/usbd_template.c b/Class/Template/Src/usbd_template.c index 4075334..947ae91 100644 --- a/Class/Template/Src/usbd_template.c +++ b/Class/Template/Src/usbd_template.c @@ -124,7 +124,7 @@ USBD_ClassTypeDef USBD_TEMPLATE_ClassDriver = #if defined ( __ICCARM__ ) /*!< IAR Compiler */ #pragma data_alignment=4 -#endif +#endif /* __ICCARM__ */ /* USB TEMPLATE device Configuration Descriptor */ __ALIGN_BEGIN static uint8_t USBD_TEMPLATE_CfgDesc[USB_TEMPLATE_CONFIG_DESC_SIZ] __ALIGN_END = { @@ -146,7 +146,7 @@ __ALIGN_BEGIN static uint8_t USBD_TEMPLATE_CfgDesc[USB_TEMPLATE_CONFIG_DESC_SIZ] #if defined ( __ICCARM__ ) /*!< IAR Compiler */ #pragma data_alignment=4 -#endif +#endif /* __ICCARM__ */ /* USB Standard Device Descriptor */ __ALIGN_BEGIN static uint8_t USBD_TEMPLATE_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = { @@ -252,12 +252,12 @@ static uint8_t *USBD_TEMPLATE_GetCfgDesc(uint16_t *length) } /** - * @brief DeviceQualifierDescriptor + * @brief USBD_TEMPLATE_GetDeviceQualifierDesc * return Device Qualifier descriptor * @param length : pointer data length * @retval pointer to descriptor buffer */ -uint8_t *USBD_TEMPLATE_DeviceQualifierDescriptor(uint16_t *length) +uint8_t *USBD_TEMPLATE_GetDeviceQualifierDesc(uint16_t *length) { *length = (uint16_t)sizeof(USBD_TEMPLATE_DeviceQualifierDesc); return USBD_TEMPLATE_DeviceQualifierDesc; @@ -350,19 +350,6 @@ static uint8_t USBD_TEMPLATE_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) return (uint8_t)USBD_OK; } -/** - * @brief DeviceQualifierDescriptor - * return Device Qualifier descriptor - * @param length : pointer data length - * @retval pointer to descriptor buffer - */ -uint8_t *USBD_TEMPLATE_GetDeviceQualifierDesc(uint16_t *length) -{ - *length = (uint16_t)sizeof(USBD_TEMPLATE_DeviceQualifierDesc); - - return USBD_TEMPLATE_DeviceQualifierDesc; -} - /** * @} */ diff --git a/Class/VIDEO/Inc/usbd_video.h b/Class/VIDEO/Inc/usbd_video.h index 64826ff..8ece002 100644 --- a/Class/VIDEO/Inc/usbd_video.h +++ b/Class/VIDEO/Inc/usbd_video.h @@ -46,12 +46,12 @@ extern "C" { #define UVC_VERSION 0x0100U /* UVC 1.0 */ #else #define UVC_VERSION 0x0110U /* UVC 1.1 */ -#endif +#endif /* UVC_1_0 */ /* bEndpointAddress in Endpoint Descriptor */ #ifndef UVC_IN_EP #define UVC_IN_EP 0x81U -#endif /* VIDEO_IN_EP */ +#endif /* UVC_IN_EP */ /* These defines shall be updated in the usbd_conf.h file */ #ifndef UVC_WIDTH @@ -110,15 +110,15 @@ extern "C" { #ifndef UVC_ISO_FS_MPS #define UVC_ISO_FS_MPS 256U -#endif +#endif /* UVC_ISO_FS_MPS */ #ifndef UVC_ISO_HS_MPS #define UVC_ISO_HS_MPS 512U -#endif +#endif /* UVC_ISO_HS_MPS */ #ifndef UVC_HEADER_PACKET_CNT #define UVC_HEADER_PACKET_CNT 0x01U -#endif +#endif /* UVC_HEADER_PACKET_CNT */ #define UVC_REQ_READ_MASK 0x80U @@ -130,7 +130,9 @@ extern "C" { #define UVC_CONFIG_DESC_SIZ (0x88U + 0x16U) #else #define UVC_CONFIG_DESC_SIZ 0x88U -#endif +#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */ + +#define USBD_VC_GIUD_FORMAT_SIZE 16U #define UVC_TOTAL_BUF_SIZE 0x04U @@ -147,10 +149,10 @@ extern "C" { #ifndef WBVAL #define WBVAL(x) ((x) & 0xFFU),(((x) >> 8) & 0xFFU) -#endif +#endif /* WBVAL */ #ifndef DBVAL #define DBVAL(x) ((x)& 0xFFU),(((x) >> 8) & 0xFFU),(((x)>> 16) & 0xFFU),(((x) >> 24) & 0xFFU) -#endif +#endif /* DBVAL */ /* Video Interface Protocol Codes */ #define PC_PROTOCOL_UNDEFINED 0x00U @@ -182,7 +184,7 @@ extern "C" { #define VC_HEADER_SIZE (VIDEO_VS_IF_IN_HEADER_DESC_SIZE + \ VS_FORMAT_DESC_SIZE + \ VS_FRAME_DESC_SIZE) -#endif +#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */ /* * Video Class specification release 1.1 @@ -363,32 +365,6 @@ typedef enum VIDEO_OFFSET_UNKNOWN, } VIDEO_OffsetTypeDef; -typedef struct _VIDEO_DescHeader -{ - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bDescriptorSubType; -} USBD_VIDEO_DescHeader_t; - -typedef struct -{ - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bDescriptorSubType; - uint8_t bFrameIndex; - uint8_t bmCapabilities; - uint16_t wWidth; - uint16_t wHeight; - uint32_t dwMinBitRate; - uint32_t dwMaxBitRate; - uint32_t dwMaxVideoFrameBufSize; - uint32_t dwDefaultFrameInterval; - uint8_t bFrameIntervalType; - uint32_t dwMinFrameInterval; - uint32_t dwMaxFrameInterval; - uint32_t dwFrameIntervalStep; -} __PACKED USBD_VIDEO_VSFrameDescTypeDef; - typedef struct { uint8_t cmd; @@ -435,6 +411,130 @@ typedef struct uint8_t bMaxVersion; } __PACKED USBD_VideoControlTypeDef; +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iFunction; +} __PACKED USBD_StandardVCIfDescTypeDef; + +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint16_t bcdUVC; + uint16_t wTotalLength; + uint32_t dwClockFrequency; + uint8_t baInterfaceNr; + uint8_t iTerminal; +} __PACKED USBD_specificVCInDescTypeDef; + +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bTerminalID; + uint16_t wTerminalType; + uint8_t bAssocTerminal; + uint8_t iTerminal; +} __PACKED USBD_InputTerminalDescTypeDef; + +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bTerminalID; + uint16_t wTerminalType; + uint8_t bAssocTerminal; + uint8_t bSourceID; + uint8_t iTerminal; +} __PACKED USBD_OutputTerminalDescTypeDef; + +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint16_t bNumFormats; + uint8_t bVideoControlSize; + uint8_t bEndPointAddress; + uint8_t bmInfo; + uint8_t bTerminalLink; + uint8_t bStillCaptureMethod; + uint8_t bTriggerSupport; + uint8_t bTriggerUsage; + uint8_t bControlSize; + uint8_t bmaControls; +} __PACKED USBD_ClassSpecificVsHeaderDescTypeDef; + +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bFormatIndex; + uint8_t bNumFrameDescriptor; +#ifdef USBD_UVC_FORMAT_UNCOMPRESSED + uint8_t pGiudFormat[USBD_VC_GIUD_FORMAT_SIZE]; + uint8_t bBitsPerPixel; +#else + uint8_t bmFlags; +#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */ + uint8_t bDefaultFrameIndex; + uint8_t bAspectRatioX; + uint8_t bAspectRatioY; + uint8_t bInterlaceFlags; + uint8_t bCopyProtect; +} __PACKED USBD_PayloadFormatDescTypeDef; + +#ifdef USBD_UVC_FORMAT_UNCOMPRESSED +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bColorPrimarie; + uint8_t bTransferCharacteristics; + uint8_t bMatrixCoefficients; +} __PACKED USBD_ColorMatchingDescTypeDef; +#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */ + +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint16_t wMaxPacketSize; + uint8_t bInterval; +} __PACKED USBD_StandardVCDataEPDescTypeDef; + +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bFrameIndex; + uint8_t bmCapabilities; + uint16_t wWidth; + uint16_t wHeight; + uint32_t dwMinBitRate; + uint32_t dwMaxBitRate; + uint32_t dwMaxVideoFrameBufSize; + uint32_t dwDefaultFrameInterval; + uint8_t bFrameIntervalType; + uint32_t dwMinFrameInterval; +} __PACKED USBD_VIDEO_VSFrameDescTypeDef; + extern USBD_ClassTypeDef USBD_VIDEO; #define USBD_VIDEO_CLASS &USBD_VIDEO /** diff --git a/Class/VIDEO/Src/usbd_video.c b/Class/VIDEO/Src/usbd_video.c index 6a782ef..e5a1b0d 100644 --- a/Class/VIDEO/Src/usbd_video.c +++ b/Class/VIDEO/Src/usbd_video.c @@ -87,10 +87,14 @@ static uint8_t USBD_VIDEO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx); static uint8_t USBD_VIDEO_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx); static uint8_t USBD_VIDEO_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); + +#ifndef USE_USBD_COMPOSITE static uint8_t *USBD_VIDEO_GetFSCfgDesc(uint16_t *length); static uint8_t *USBD_VIDEO_GetHSCfgDesc(uint16_t *length); static uint8_t *USBD_VIDEO_GetOtherSpeedCfgDesc(uint16_t *length); static uint8_t *USBD_VIDEO_GetDeviceQualifierDesc(uint16_t *length); +#endif /* USE_USBD_COMPOSITE */ + static uint8_t USBD_VIDEO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); static uint8_t USBD_VIDEO_SOF(USBD_HandleTypeDef *pdev); static uint8_t USBD_VIDEO_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); @@ -99,10 +103,11 @@ static uint8_t USBD_VIDEO_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnu static void VIDEO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); static void VIDEO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); -static USBD_VIDEO_DescHeader_t *USBD_VIDEO_GetNextDesc(uint8_t *pbuf, uint16_t *ptr); -static void *USBD_VIDEO_GetEpDesc(uint8_t *pConfDesc, uint8_t EpAddr); +#ifndef USE_USBD_COMPOSITE static void *USBD_VIDEO_GetVSFrameDesc(uint8_t *pConfDesc); +#endif /* USE_USBD_COMPOSITE */ +static void *USBD_VIDEO_GetVideoHeaderDesc(uint8_t *pConfDesc); /** * @} @@ -124,10 +129,17 @@ USBD_ClassTypeDef USBD_VIDEO = USBD_VIDEO_SOF, USBD_VIDEO_IsoINIncomplete, NULL, +#ifdef USE_USBD_COMPOSITE + NULL, + NULL, + NULL, + NULL, +#else USBD_VIDEO_GetHSCfgDesc, USBD_VIDEO_GetFSCfgDesc, USBD_VIDEO_GetOtherSpeedCfgDesc, USBD_VIDEO_GetDeviceQualifierDesc, +#endif /* USE_USBD_COMPOSITE */ }; /* USB VIDEO device Configuration Descriptor (same for all speeds thanks to user defines) */ @@ -140,12 +152,13 @@ __ALIGN_BEGIN static uint8_t USBD_VIDEO_CfgDesc[] __ALIGN_END = HIBYTE(UVC_CONFIG_DESC_SIZ), 0x02, /* bNumInterfaces: 2 interfaces */ 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ + 0x00, /* iConfiguration: Index of string descriptor + describing the configuration */ #if (USBD_SELF_POWERED == 1U) 0xC0, /* bmAttributes: Bus Powered according to user configuration */ #else 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif +#endif /* USBD_SELF_POWERED */ USBD_MAX_POWER, /* bMaxPower in mA according to user configuration */ /* Interface Association Descriptor */ @@ -182,8 +195,8 @@ __ALIGN_BEGIN static uint8_t USBD_VIDEO_CfgDesc[] __ALIGN_END = 0xDC, 0x02, 0x01, /* bInCollection: number of streaming interfaces */ - 0x01, /* baInterfaceNr(1): VideoStreaming interface 1 is part of VC interface */ - + 0x01, /* baInterfaceNr(1): VideoStreaming interface 1 is part + of VC interface */ /* Input Terminal Descriptor */ VIDEO_IN_TERMINAL_DESC_SIZE, /* bLength: Input terminal descriptor size */ CS_INTERFACE, /* bDescriptorType: INTERFACE */ @@ -248,8 +261,9 @@ __ALIGN_BEGIN static uint8_t USBD_VIDEO_CfgDesc[] __ALIGN_END = UVC_BITS_PER_PIXEL, /* bBitsPerPixel : Number of bits per pixel */ #else 0x01, /* bmFlags: FixedSizeSamples */ -#endif - 0x01, /* bDefaultFrameIndex: default frame used is frame 1 (only one frame used) */ +#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */ + 0x01, /* bDefaultFrameIndex: default frame used is frame 1 + (only one frame used) */ 0x00, /* bAspectRatioX: not required by specification */ 0x00, /* bAspectRatioY: not required by specification */ 0x00, /* bInterlaceFlags: non interlaced stream */ @@ -264,7 +278,7 @@ __ALIGN_BEGIN static uint8_t USBD_VIDEO_CfgDesc[] __ALIGN_END = 0x00, /* bmCapabilities: no till image capture */ #else 0x02, /* bmCapabilities: fixed frame rate supported */ -#endif +#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */ WBVAL(UVC_WIDTH), /* wWidth: Image Frame Width */ WBVAL(UVC_HEIGHT), /* wHeight: Image Frame Height */ DBVAL(UVC_MIN_BIT_RATE(UVC_CAM_FPS_FS)), /* dwMinBitRate: Minimum supported bit rate in bits/s */ @@ -282,7 +296,7 @@ __ALIGN_BEGIN static uint8_t USBD_VIDEO_CfgDesc[] __ALIGN_END = UVC_COLOR_PRIMARIE, /* bColorPrimarie: 1: BT.709, sRGB (default) */ UVC_TFR_CHARACTERISTICS, /* bTransferCharacteristics: 1: BT.709 (default) */ UVC_MATRIX_COEFFICIENTS, /* bMatrixCoefficients: 4: BT.601, (default) */ -#endif +#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */ /* Standard VS Interface Descriptor = interface 1, alternate setting 1 = data transfer mode */ USB_IF_DESC_SIZE, /* bLength */ @@ -305,6 +319,7 @@ __ALIGN_BEGIN static uint8_t USBD_VIDEO_CfgDesc[] __ALIGN_END = 0x01, /* bInterval: 1 frame interval */ }; +#ifndef USE_USBD_COMPOSITE /* USB Standard Device Descriptor */ __ALIGN_BEGIN static uint8_t USBD_VIDEO_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = { @@ -319,6 +334,9 @@ __ALIGN_BEGIN static uint8_t USBD_VIDEO_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIE 0x01, 0x00, }; +#endif /* USE_USBD_COMPOSITE */ + +static uint8_t VIDEOinEpAdd = UVC_IN_EP; /* Video Commit data structure */ static USBD_VideoControlTypeDef video_Commit_Control = @@ -377,7 +395,7 @@ static USBD_VideoControlTypeDef video_Probe_Control = * @param cfgidx: Configuration index * @retval status */ -static uint8_t USBD_VIDEO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +static uint8_t USBD_VIDEO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { USBD_VIDEO_HandleTypeDef *hVIDEO; @@ -391,26 +409,32 @@ static uint8_t USBD_VIDEO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) } /* Assign the pClassData pointer to the allocated structure */ - pdev->pClassData = (void *)hVIDEO; + pdev->pClassDataCmsit[pdev->classId] = (void *)hVIDEO; + pdev->pClassData = pdev->pClassDataCmsit[pdev->classId]; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + VIDEOinEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_ISOC); +#endif /* USE_USBD_COMPOSITE */ /* Open EP IN */ if (pdev->dev_speed == USBD_SPEED_HIGH) { - (void)USBD_LL_OpenEP(pdev, UVC_IN_EP, USBD_EP_TYPE_ISOC, UVC_ISO_HS_MPS); + (void)USBD_LL_OpenEP(pdev, VIDEOinEpAdd, USBD_EP_TYPE_ISOC, UVC_ISO_HS_MPS); - pdev->ep_in[UVC_IN_EP & 0xFU].is_used = 1U; - pdev->ep_in[UVC_IN_EP & 0xFU].maxpacket = UVC_ISO_HS_MPS; + pdev->ep_in[VIDEOinEpAdd & 0xFU].is_used = 1U; + pdev->ep_in[VIDEOinEpAdd & 0xFU].maxpacket = UVC_ISO_HS_MPS; } else { - (void)USBD_LL_OpenEP(pdev, UVC_IN_EP, USBD_EP_TYPE_ISOC, UVC_ISO_FS_MPS); + (void)USBD_LL_OpenEP(pdev, VIDEOinEpAdd, USBD_EP_TYPE_ISOC, UVC_ISO_FS_MPS); - pdev->ep_in[UVC_IN_EP & 0xFU].is_used = 1U; - pdev->ep_in[UVC_IN_EP & 0xFU].maxpacket = UVC_ISO_FS_MPS; + pdev->ep_in[VIDEOinEpAdd & 0xFU].is_used = 1U; + pdev->ep_in[VIDEOinEpAdd & 0xFU].maxpacket = UVC_ISO_FS_MPS; } /* Init physical Interface components */ - ((USBD_VIDEO_ItfTypeDef *)pdev->pUserData)->Init(); + ((USBD_VIDEO_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init(); /* Init Xfer states */ hVIDEO->interface = 0U; @@ -430,23 +454,29 @@ static uint8_t USBD_VIDEO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) * @param cfgidx: Configuration index * @retval status */ -static uint8_t USBD_VIDEO_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +static uint8_t USBD_VIDEO_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { UNUSED(cfgidx); /* Check if the video structure pointer is valid */ - if (pdev->pClassData == NULL) + if (pdev->pClassDataCmsit[pdev->classId] == NULL) { return (uint8_t)USBD_FAIL; } +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + VIDEOinEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_ISOC); +#endif /* USE_USBD_COMPOSITE */ + /* Close EP IN */ - (void)USBD_LL_CloseEP(pdev, UVC_IN_EP); - pdev->ep_in[UVC_IN_EP & 0xFU].is_used = 0U; + (void)USBD_LL_CloseEP(pdev, VIDEOinEpAdd); + pdev->ep_in[VIDEOinEpAdd & 0xFU].is_used = 0U; /* DeInit physical Interface components */ - ((USBD_VIDEO_ItfTypeDef *)pdev->pUserData)->DeInit(); - USBD_free(pdev->pClassData); + ((USBD_VIDEO_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit(); + USBD_free(pdev->pClassDataCmsit[pdev->classId]); + pdev->pClassDataCmsit[pdev->classId] = NULL; pdev->pClassData = NULL; /* Exit with no error code */ @@ -460,13 +490,13 @@ static uint8_t USBD_VIDEO_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) * @param req: usb requests * @retval status */ -static uint8_t USBD_VIDEO_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +static uint8_t USBD_VIDEO_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { - USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *) pdev->pClassData; + USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *) pdev->pClassDataCmsit[pdev->classId]; uint8_t ret = (uint8_t)USBD_OK; - uint16_t len = 0U; - uint8_t *pbuf = NULL; uint16_t status_info = 0U; + uint16_t len; + uint8_t *pbuf; switch (req->bmRequest & USB_REQ_TYPE_MASK) { @@ -480,13 +510,16 @@ static uint8_t USBD_VIDEO_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef case UVC_GET_MAX: VIDEO_REQ_GetCurrent(pdev, req); break; + case UVC_GET_RES: case UVC_GET_LEN: case UVC_GET_INFO: break; + case UVC_SET_CUR: VIDEO_REQ_SetCurrent(pdev, req); break; + default: (void) USBD_CtlError(pdev, req); ret = (uint8_t)USBD_FAIL; @@ -513,10 +546,18 @@ static uint8_t USBD_VIDEO_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef case USB_REQ_GET_DESCRIPTOR: if ((req->wValue >> 8) == CS_DEVICE) { - pbuf = USBD_VIDEO_CfgDesc + 18; - len = MIN((uint16_t)USB_CONF_DESC_SIZE, (uint16_t)req->wLength); + pbuf = (uint8_t *)USBD_VIDEO_GetVideoHeaderDesc(pdev->pConfDesc); + if (pbuf != NULL) + { + len = MIN((uint16_t)USB_CONF_DESC_SIZE, (uint16_t)req->wLength); + (void)USBD_CtlSendData(pdev, pbuf, len); + } + else + { + USBD_CtlError(pdev, req); + ret = (uint8_t)USBD_FAIL; + } } - (void)USBD_CtlSendData(pdev, pbuf, len); break; case USB_REQ_GET_INTERFACE : @@ -540,14 +581,14 @@ static uint8_t USBD_VIDEO_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef if (hVIDEO->interface == 1U) { /* Start Streaming (First endpoint writing will be done on next SOF) */ - (void)USBD_LL_FlushEP(pdev, UVC_IN_EP); + (void)USBD_LL_FlushEP(pdev, VIDEOinEpAdd); hVIDEO->uvc_state = UVC_PLAY_STATUS_READY; } else { /* Stop Streaming */ hVIDEO->uvc_state = UVC_PLAY_STATUS_STOP; - (void)USBD_LL_FlushEP(pdev, UVC_IN_EP); + (void)USBD_LL_FlushEP(pdev, VIDEOinEpAdd); } } else @@ -592,7 +633,7 @@ static uint8_t USBD_VIDEO_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef */ static uint8_t USBD_VIDEO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) { - USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *) pdev->pClassData; + USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *) pdev->pClassDataCmsit[pdev->classId]; static uint8_t packet[UVC_PACKET_SIZE + (UVC_HEADER_PACKET_CNT * 2U)] = {0x00U}; static uint8_t *Pcktdata = packet; static uint16_t PcktIdx = 0U; @@ -605,7 +646,7 @@ static uint8_t USBD_VIDEO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) if (hVIDEO->uvc_state == UVC_PLAY_STATUS_STREAMING) { /* Get the current packet buffer, index and size from the application layer */ - ((USBD_VIDEO_ItfTypeDef *)pdev->pUserData)->Data(&Pcktdata, &PcktSze, &PcktIdx); + ((USBD_VIDEO_ItfTypeDef *)pdev->pUserData[pdev->classId])->Data(&Pcktdata, &PcktSze, &PcktIdx); /* Check if end of current image has been reached */ if (PcktSze > 2U) @@ -624,9 +665,10 @@ static uint8_t USBD_VIDEO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) { packet[((DataOffset + 0U) * i)] = payload_header[0]; packet[((DataOffset + 0U) * i) + 1U] = payload_header[1]; - if (RemainData > pdev->ep_in[UVC_IN_EP & 0xFU].maxpacket) + + if (RemainData > pdev->ep_in[VIDEOinEpAdd & 0xFU].maxpacket) { - DataOffset = pdev->ep_in[UVC_IN_EP & 0xFU].maxpacket; + DataOffset = pdev->ep_in[VIDEOinEpAdd & 0xFU].maxpacket; (void)USBD_memcpy((packet + ((DataOffset + 0U) * i) + 2U), Pcktdata + ((DataOffset - 2U) * i), (DataOffset - 2U)); @@ -666,14 +708,14 @@ static uint8_t USBD_VIDEO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) */ static uint8_t USBD_VIDEO_SOF(USBD_HandleTypeDef *pdev) { - USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *) pdev->pClassData; + USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *) pdev->pClassDataCmsit[pdev->classId]; uint8_t payload[2] = {0x02U, 0x00U}; /* Check if the Streaming has already been started by SetInterface AltSetting 1 */ if (hVIDEO->uvc_state == UVC_PLAY_STATUS_READY) { /* Transmit the first packet indicating that Streaming is starting */ - (void)USBD_LL_Transmit(pdev, UVC_IN_EP, (uint8_t *)payload, 2U); + (void)USBD_LL_Transmit(pdev, VIDEOinEpAdd, (uint8_t *)payload, 2U); /* Enable Streaming state */ hVIDEO->uvc_state = UVC_PLAY_STATUS_STREAMING; @@ -708,7 +750,7 @@ static uint8_t USBD_VIDEO_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnu static void VIDEO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { USBD_VIDEO_HandleTypeDef *hVIDEO; - hVIDEO = (USBD_VIDEO_HandleTypeDef *)(pdev->pClassData); + hVIDEO = (USBD_VIDEO_HandleTypeDef *)(pdev->pClassDataCmsit[pdev->classId]); static __IO uint8_t EntityStatus[8] = {0}; /* Reset buffer to zeros */ @@ -794,7 +836,7 @@ static void VIDEO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef */ static void VIDEO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { - USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *)(pdev->pClassData); + USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *)(pdev->pClassDataCmsit[pdev->classId]); /* Check that the request has control data */ if (req->wLength > 0U) @@ -821,6 +863,7 @@ static void VIDEO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef } } +#ifndef USE_USBD_COMPOSITE /** * @brief USBD_VIDEO_GetFSCfgDesc * return configuration descriptor @@ -829,7 +872,7 @@ static void VIDEO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef */ static uint8_t *USBD_VIDEO_GetFSCfgDesc(uint16_t *length) { - USBD_EpDescTypedef *pEpDesc = USBD_VIDEO_GetEpDesc(USBD_VIDEO_CfgDesc, UVC_IN_EP); + USBD_EpDescTypeDef *pEpDesc = USBD_GetEpDesc(USBD_VIDEO_CfgDesc, VIDEOinEpAdd); USBD_VIDEO_VSFrameDescTypeDef *pVSFrameDesc = USBD_VIDEO_GetVSFrameDesc(USBD_VIDEO_CfgDesc); if (pEpDesc != NULL) @@ -857,7 +900,7 @@ static uint8_t *USBD_VIDEO_GetFSCfgDesc(uint16_t *length) */ static uint8_t *USBD_VIDEO_GetHSCfgDesc(uint16_t *length) { - USBD_EpDescTypedef *pEpDesc = USBD_VIDEO_GetEpDesc(USBD_VIDEO_CfgDesc, UVC_IN_EP); + USBD_EpDescTypeDef *pEpDesc = USBD_GetEpDesc(USBD_VIDEO_CfgDesc, VIDEOinEpAdd); USBD_VIDEO_VSFrameDescTypeDef *pVSFrameDesc = USBD_VIDEO_GetVSFrameDesc(USBD_VIDEO_CfgDesc); if (pEpDesc != NULL) @@ -885,7 +928,7 @@ static uint8_t *USBD_VIDEO_GetHSCfgDesc(uint16_t *length) */ static uint8_t *USBD_VIDEO_GetOtherSpeedCfgDesc(uint16_t *length) { - USBD_EpDescTypedef *pEpDesc = USBD_VIDEO_GetEpDesc(USBD_VIDEO_CfgDesc, UVC_IN_EP); + USBD_EpDescTypeDef *pEpDesc = USBD_GetEpDesc(USBD_VIDEO_CfgDesc, VIDEOinEpAdd); USBD_VIDEO_VSFrameDescTypeDef *pVSFrameDesc = USBD_VIDEO_GetVSFrameDesc(USBD_VIDEO_CfgDesc); if (pEpDesc != NULL) @@ -917,23 +960,6 @@ static uint8_t *USBD_VIDEO_GetDeviceQualifierDesc(uint16_t *length) return USBD_VIDEO_DeviceQualifierDesc; } -/** - * @brief USBD_VIDEO_GetNextDesc - * This function return the next descriptor header - * @param buf: Buffer where the descriptor is available - * @param ptr: data pointer inside the descriptor - * @retval next header - */ -static USBD_VIDEO_DescHeader_t *USBD_VIDEO_GetNextDesc(uint8_t *pbuf, uint16_t *ptr) -{ - USBD_VIDEO_DescHeader_t *pnext = (USBD_VIDEO_DescHeader_t *)(void *)pbuf; - - *ptr += pnext->bLength; - pnext = (USBD_VIDEO_DescHeader_t *)(void *)(pbuf + pnext->bLength); - - return (pnext); -} - /** * @brief USBD_VIDEO_GetVSFrameDesc * This function return the Video Endpoint descriptor @@ -943,8 +969,8 @@ static USBD_VIDEO_DescHeader_t *USBD_VIDEO_GetNextDesc(uint8_t *pbuf, uint16_t * */ static void *USBD_VIDEO_GetVSFrameDesc(uint8_t *pConfDesc) { - USBD_VIDEO_DescHeader_t *pdesc = (USBD_VIDEO_DescHeader_t *)(void *)pConfDesc; - USBD_ConfigDescTypedef *desc = (USBD_ConfigDescTypedef *)(void *)pConfDesc; + USBD_DescHeaderTypeDef *pdesc = (USBD_DescHeaderTypeDef *)(void *)pConfDesc; + USBD_ConfigDescTypeDef *desc = (USBD_ConfigDescTypeDef *)(void *)pConfDesc; USBD_VIDEO_VSFrameDescTypeDef *pVSFrameDesc = NULL; uint16_t ptr; @@ -954,7 +980,7 @@ static void *USBD_VIDEO_GetVSFrameDesc(uint8_t *pConfDesc) while (ptr < desc->wTotalLength) { - pdesc = USBD_VIDEO_GetNextDesc((uint8_t *)pdesc, &ptr); + pdesc = USBD_GetNextDesc((uint8_t *)pdesc, &ptr); if (((pdesc->bDescriptorSubType == VS_FRAME_MJPEG) || (pdesc->bDescriptorSubType == VS_FRAME_UNCOMPRESSED)) && @@ -968,20 +994,20 @@ static void *USBD_VIDEO_GetVSFrameDesc(uint8_t *pConfDesc) return (void *)pVSFrameDesc; } +#endif /* USE_USBD_COMPOSITE */ /** - * @brief USBD_VIDEO_GetEpDesc - * This function return the Video Endpoint descriptor + * @brief USBD_VIDEO_GetVideoHeaderDesc + * This function return the Video Header descriptor * @param pdev: device instance * @param pConfDesc: pointer to Bos descriptor - * @param EpAddr: endpoint address - * @retval pointer to video endpoint descriptor + * @retval pointer to the Video Header descriptor */ -static void *USBD_VIDEO_GetEpDesc(uint8_t *pConfDesc, uint8_t EpAddr) +static void *USBD_VIDEO_GetVideoHeaderDesc(uint8_t *pConfDesc) { - USBD_VIDEO_DescHeader_t *pdesc = (USBD_VIDEO_DescHeader_t *)(void *)pConfDesc; - USBD_ConfigDescTypedef *desc = (USBD_ConfigDescTypedef *)(void *)pConfDesc; - USBD_EpDescTypedef *pEpDesc = NULL; + USBD_ConfigDescTypeDef *desc = (USBD_ConfigDescTypeDef *)(void *)pConfDesc; + USBD_DescHeaderTypeDef *pdesc = (USBD_DescHeaderTypeDef *)(void *)pConfDesc; + uint8_t *pVideoDesc = NULL; uint16_t ptr; if (desc->wTotalLength > desc->bLength) @@ -990,25 +1016,16 @@ static void *USBD_VIDEO_GetEpDesc(uint8_t *pConfDesc, uint8_t EpAddr) while (ptr < desc->wTotalLength) { - pdesc = USBD_VIDEO_GetNextDesc((uint8_t *)pdesc, &ptr); - - if (pdesc->bDescriptorType == USB_DESC_TYPE_ENDPOINT) + pdesc = USBD_GetNextDesc((uint8_t *)pdesc, &ptr); + if ((pdesc->bDescriptorType == CS_INTERFACE) && + (pdesc->bDescriptorSubType == VC_HEADER)) { - pEpDesc = (USBD_EpDescTypedef *)(void *)pdesc; - - if (pEpDesc->bEndpointAddress == EpAddr) - { - break; - } - else - { - pEpDesc = NULL; - } + pVideoDesc = (uint8_t *)pdesc; + break; } } } - - return (void *)pEpDesc; + return pVideoDesc; } /** @@ -1026,7 +1043,7 @@ uint8_t USBD_VIDEO_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_VIDEO_ItfT } /* Assign the FOPS pointer */ - pdev->pUserData = fops; + pdev->pUserData[pdev->classId] = fops; /* Exit with no error code */ return (uint8_t)USBD_OK; diff --git a/Core/Inc/usbd_conf_template.h b/Core/Inc/usbd_conf_template.h index b502071..fe5d6be 100644 --- a/Core/Inc/usbd_conf_template.h +++ b/Core/Inc/usbd_conf_template.h @@ -90,7 +90,7 @@ extern "C" { #define UVC_COLOR_PRIMARIE 0x01U #define UVC_TFR_CHARACTERISTICS 0x01U #define UVC_MATRIX_COEFFICIENTS 0x04U -#endif +#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */ /* Video Stream frame width and height */ #define UVC_WIDTH 176U @@ -140,7 +140,7 @@ extern "C" { } while (0) #else #define USBD_UsrLog(...) do {} while (0) -#endif +#endif /* (USBD_DEBUG_LEVEL > 0U) */ #if (USBD_DEBUG_LEVEL > 1U) @@ -151,7 +151,7 @@ extern "C" { } while (0) #else #define USBD_ErrLog(...) do {} while (0) -#endif +#endif /* (USBD_DEBUG_LEVEL > 1U) */ #if (USBD_DEBUG_LEVEL > 2U) #define USBD_DbgLog(...) do { \ @@ -161,7 +161,7 @@ extern "C" { } while (0) #else #define USBD_DbgLog(...) do {} while (0) -#endif +#endif /* (USBD_DEBUG_LEVEL > 2U) */ /** * @} diff --git a/Core/Inc/usbd_core.h b/Core/Inc/usbd_core.h index 360561d..7b7dff5 100644 --- a/Core/Inc/usbd_core.h +++ b/Core/Inc/usbd_core.h @@ -87,6 +87,17 @@ USBD_StatusTypeDef USBD_Start(USBD_HandleTypeDef *pdev); USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev); USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass); +#ifdef USE_USBD_COMPOSITE +USBD_StatusTypeDef USBD_RegisterClassComposite(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass, + USBD_CompositeClassTypeDef classtype, uint8_t *EpAddr); + +USBD_StatusTypeDef USBD_UnRegisterClassComposite(USBD_HandleTypeDef *pdev); +uint8_t USBD_CoreGetEPAdd(USBD_HandleTypeDef *pdev, uint8_t ep_dir, uint8_t ep_type); +#endif /* USE_USBD_COMPOSITE */ + +uint8_t USBD_CoreFindIF(USBD_HandleTypeDef *pdev, uint8_t index); +uint8_t USBD_CoreFindEP(USBD_HandleTypeDef *pdev, uint8_t index); + USBD_StatusTypeDef USBD_RunTestMode(USBD_HandleTypeDef *pdev); USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx); USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx); @@ -128,11 +139,18 @@ USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr, USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint32_t size); +#ifdef USBD_HS_TESTMODE_ENABLE +USBD_StatusTypeDef USBD_LL_SetTestMode(USBD_HandleTypeDef *pdev, uint8_t testmode); +#endif /* USBD_HS_TESTMODE_ENABLE */ + uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr); void USBD_LL_Delay(uint32_t Delay); +void *USBD_GetEpDesc(uint8_t *pConfDesc, uint8_t EpAddr); +USBD_DescHeaderTypeDef *USBD_GetNextDesc(uint8_t *pbuf, uint16_t *ptr); + /** * @} */ diff --git a/Core/Inc/usbd_def.h b/Core/Inc/usbd_def.h index 53f831d..3c1902f 100644 --- a/Core/Inc/usbd_def.h +++ b/Core/Inc/usbd_def.h @@ -52,6 +52,24 @@ extern "C" { #define USBD_MAX_NUM_CONFIGURATION 1U #endif /* USBD_MAX_NUM_CONFIGURATION */ +#ifdef USE_USBD_COMPOSITE +#ifndef USBD_MAX_SUPPORTED_CLASS +#define USBD_MAX_SUPPORTED_CLASS 4U +#endif /* USBD_MAX_SUPPORTED_CLASS */ +#else +#ifndef USBD_MAX_SUPPORTED_CLASS +#define USBD_MAX_SUPPORTED_CLASS 1U +#endif /* USBD_MAX_SUPPORTED_CLASS */ +#endif /* USE_USBD_COMPOSITE */ + +#ifndef USBD_MAX_CLASS_ENDPOINTS +#define USBD_MAX_CLASS_ENDPOINTS 5U +#endif /* USBD_MAX_CLASS_ENDPOINTS */ + +#ifndef USBD_MAX_CLASS_INTERFACES +#define USBD_MAX_CLASS_INTERFACES 5U +#endif /* USBD_MAX_CLASS_INTERFACES */ + #ifndef USBD_LPM_ENABLED #define USBD_LPM_ENABLED 0U #endif /* USBD_LPM_ENABLED */ @@ -159,6 +177,14 @@ extern "C" { #define USBD_EP_TYPE_BULK 0x02U #define USBD_EP_TYPE_INTR 0x03U +#ifdef USE_USBD_COMPOSITE +#define USBD_EP_IN 0x80U +#define USBD_EP_OUT 0x00U +#define USBD_FUNC_DESCRIPTOR_TYPE 0x24U +#define USBD_DESC_SUBTYPE_ACM 0x0FU +#define USBD_DESC_ECM_BCD_LOW 0x00U +#define USBD_DESC_ECM_BCD_HIGH 0x10U +#endif /* USE_USBD_COMPOSITE */ /** * @} */ @@ -187,7 +213,7 @@ typedef struct uint8_t iConfiguration; uint8_t bmAttributes; uint8_t bMaxPower; -} USBD_ConfigDescTypedef; +} __PACKED USBD_ConfigDescTypeDef; typedef struct { @@ -195,7 +221,7 @@ typedef struct uint8_t bDescriptorType; uint16_t wTotalLength; uint8_t bNumDeviceCaps; -} USBD_BosDescTypedef; +} USBD_BosDescTypeDef; typedef struct { @@ -205,7 +231,14 @@ typedef struct uint8_t bmAttributes; uint16_t wMaxPacketSize; uint8_t bInterval; -} __PACKED USBD_EpDescTypedef; +} __PACKED USBD_EpDescTypeDef; + +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; +} USBD_DescHeaderTypeDef; struct _USBD_HandleTypeDef; @@ -230,7 +263,7 @@ typedef struct _Device_cb uint8_t *(*GetDeviceQualifierDescriptor)(uint16_t *length); #if (USBD_SUPPORT_USER_STRING_DESC == 1U) uint8_t *(*GetUsrStrDescriptor)(struct _USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length); -#endif +#endif /* USBD_SUPPORT_USER_STRING_DESC */ } USBD_ClassTypeDef; @@ -263,10 +296,10 @@ typedef struct uint8_t *(*GetInterfaceStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); #if (USBD_CLASS_USER_STRING_DESC == 1) uint8_t *(*GetUserStrDescriptor)(USBD_SpeedTypeDef speed, uint8_t idx, uint16_t *length); -#endif +#endif /* USBD_CLASS_USER_STRING_DESC */ #if ((USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1)) uint8_t *(*GetBOSDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); -#endif +#endif /* (USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1) */ } USBD_DescriptorsTypeDef; /* USB Device handle structure */ @@ -280,6 +313,49 @@ typedef struct uint16_t bInterval; } USBD_EndpointTypeDef; +#ifdef USE_USBD_COMPOSITE +typedef enum +{ + CLASS_TYPE_NONE = 0, + CLASS_TYPE_HID = 1, + CLASS_TYPE_CDC = 2, + CLASS_TYPE_MSC = 3, + CLASS_TYPE_DFU = 4, + CLASS_TYPE_CHID = 5, + CLASS_TYPE_AUDIO = 6, + CLASS_TYPE_ECM = 7, + CLASS_TYPE_RNDIS = 8, + CLASS_TYPE_MTP = 9, + CLASS_TYPE_VIDEO = 10, + CLASS_TYPE_PRINTER = 11, + CLASS_TYPE_CCID = 12, +} USBD_CompositeClassTypeDef; + + +/* USB Device handle structure */ +typedef struct +{ + uint8_t add; + uint8_t type; + uint8_t size; + uint8_t is_used; +} USBD_EPTypeDef; + +/* USB Device handle structure */ +typedef struct +{ + USBD_CompositeClassTypeDef ClassType; + uint32_t ClassId; + uint32_t Active; + uint32_t NumEps; + USBD_EPTypeDef Eps[USBD_MAX_CLASS_ENDPOINTS]; + uint8_t *EpAdd; + uint32_t NumIf; + uint8_t Ifs[USBD_MAX_CLASS_INTERFACES]; + uint32_t CurrPcktSze; +} USBD_CompositeElementTypeDef; +#endif /* USE_USBD_COMPOSITE */ + /* USB Device handle structure */ typedef struct _USBD_HandleTypeDef { @@ -302,14 +378,33 @@ typedef struct _USBD_HandleTypeDef USBD_SetupReqTypedef request; USBD_DescriptorsTypeDef *pDesc; - USBD_ClassTypeDef *pClass; + USBD_ClassTypeDef *pClass[USBD_MAX_SUPPORTED_CLASS]; void *pClassData; - void *pUserData; + void *pClassDataCmsit[USBD_MAX_SUPPORTED_CLASS]; + void *pUserData[USBD_MAX_SUPPORTED_CLASS]; void *pData; void *pBosDesc; void *pConfDesc; + uint32_t classId; + uint32_t NumClasses; +#ifdef USE_USBD_COMPOSITE + USBD_CompositeElementTypeDef tclasslist[USBD_MAX_SUPPORTED_CLASS]; +#endif /* USE_USBD_COMPOSITE */ } USBD_HandleTypeDef; +/* USB Device endpoint direction */ +typedef enum +{ + OUT = 0x00, + IN = 0x80, +} USBD_EPDirectionTypeDef; + +typedef enum +{ + NETWORK_CONNECTION = 0x00, + RESPONSE_AVAILABLE = 0x01, + CONNECTION_SPEED_CHANGE = 0x2A +} USBD_CDC_NotifCodeTypeDef; /** * @} */ @@ -335,19 +430,19 @@ __STATIC_INLINE uint16_t SWAPBYTE(uint8_t *addr) #ifndef LOBYTE #define LOBYTE(x) ((uint8_t)((x) & 0x00FFU)) -#endif +#endif /* LOBYTE */ #ifndef HIBYTE #define HIBYTE(x) ((uint8_t)(((x) & 0xFF00U) >> 8U)) -#endif +#endif /* HIBYTE */ #ifndef MIN #define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif +#endif /* MIN */ #ifndef MAX #define MAX(a, b) (((a) > (b)) ? (a) : (b)) -#endif +#endif /* MAX */ #if defined ( __GNUC__ ) #ifndef __weak diff --git a/Core/Inc/usbd_desc_template.h b/Core/Inc/usbd_desc_template.h index 0e5e3d6..e392305 100644 --- a/Core/Inc/usbd_desc_template.h +++ b/Core/Inc/usbd_desc_template.h @@ -43,7 +43,7 @@ #define USBD_BB_URL_STR_DESC (uint8_t *)"www.st.com" #define USBD_BB_ALTMODE0_STR_DESC (uint8_t *)"STM32 Alternate0 Mode" #define USBD_BB_ALTMODE1_STR_DESC (uint8_t *)"STM32 Alternate1 Mode" -#endif +#endif /* USBD_CLASS_USER_STRING_DESC */ #define USB_SIZ_STRING_SERIAL 0x1AU @@ -51,7 +51,7 @@ #define USB_SIZ_BOS_DESC 0x0CU #elif (USBD_CLASS_BOS_ENABLED == 1) #define USB_SIZ_BOS_DESC 0x5DU -#endif +#endif /* USBD_LPM_ENABLED */ /* Exported macro ------------------------------------------------------------*/ /* Exported functions ------------------------------------------------------- */ diff --git a/Core/Src/usbd_conf_template.c b/Core/Src/usbd_conf_template.c index 3cd06f1..c99b528 100644 --- a/Core/Src/usbd_conf_template.c +++ b/Core/Src/usbd_conf_template.c @@ -233,6 +233,22 @@ uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr) return 0U; } +#ifdef USBD_HS_TESTMODE_ENABLE +/** + * @brief Set High speed Test mode. + * @param pdev: Device handle + * @param testmode: test mode + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_SetTestMode(USBD_HandleTypeDef *pdev, uint8_t testmode) +{ + UNUSED(pdev); + UNUSED(testmode); + + return USBD_OK; +} +#endif /* USBD_HS_TESTMODE_ENABLE */ + /** * @brief Static single allocation. * @param size: Size of allocated memory diff --git a/Core/Src/usbd_core.c b/Core/Src/usbd_core.c index 772a819..544c2a9 100644 --- a/Core/Src/usbd_core.c +++ b/Core/Src/usbd_core.c @@ -19,6 +19,10 @@ /* Includes ------------------------------------------------------------------*/ #include "usbd_core.h" +#ifdef USE_USBD_COMPOSITE +#include "usbd_composite_builder.h" +#endif /* USE_USBD_COMPOSITE */ + /** @addtogroup STM32_USBD_DEVICE_LIBRARY * @{ */ @@ -95,13 +99,29 @@ USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, { #if (USBD_DEBUG_LEVEL > 1U) USBD_ErrLog("Invalid Device handle"); -#endif +#endif /* (USBD_DEBUG_LEVEL > 1U) */ return USBD_FAIL; } - /* Unlink previous class resources */ - pdev->pClass = NULL; - pdev->pUserData = NULL; +#ifdef USE_USBD_COMPOSITE + /* Parse the table of classes in use */ + for (uint32_t i = 0; i < USBD_MAX_SUPPORTED_CLASS; i++) + { + /* Unlink previous class*/ + pdev->pClass[i] = NULL; + pdev->pUserData[i] = NULL; + + /* Set class as inactive */ + pdev->tclasslist[i].Active = 0; + pdev->NumClasses = 0; + pdev->classId = 0; + } +#else + /* Unlink previous class*/ + pdev->pClass[0] = NULL; + pdev->pUserData[0] = NULL; +#endif /* USE_USBD_COMPOSITE */ + pdev->pConfDesc = NULL; /* Assign USBD Descriptors */ @@ -136,13 +156,31 @@ USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev) /* Set Default State */ pdev->dev_state = USBD_STATE_DEFAULT; - /* Free Class Resources */ - if (pdev->pClass != NULL) +#ifdef USE_USBD_COMPOSITE + /* Parse the table of classes in use */ + for (uint32_t i = 0; i < USBD_MAX_SUPPORTED_CLASS; i++) { - pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); - pdev->pClass = NULL; - pdev->pUserData = NULL; + /* Check if current class is in use */ + if ((pdev->tclasslist[i].Active) == 1U) + { + if (pdev->pClass[i] != NULL) + { + pdev->classId = i; + /* Free Class Resources */ + pdev->pClass[i]->DeInit(pdev, (uint8_t)pdev->dev_config); + } + } } +#else + /* Free Class Resources */ + if (pdev->pClass[0] != NULL) + { + pdev->pClass[0]->DeInit(pdev, (uint8_t)pdev->dev_config); + } + + pdev->pUserData[0] = NULL; + +#endif /* USE_USBD_COMPOSITE */ /* Free Device descriptors resources */ pdev->pDesc = NULL; @@ -169,29 +207,161 @@ USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDe { #if (USBD_DEBUG_LEVEL > 1U) USBD_ErrLog("Invalid Class handle"); -#endif +#endif /* (USBD_DEBUG_LEVEL > 1U) */ return USBD_FAIL; } /* link the class to the USB Device handle */ - pdev->pClass = pclass; + pdev->pClass[0] = pclass; /* Get Device Configuration Descriptor */ #ifdef USE_USB_HS - if (pdev->pClass->GetHSConfigDescriptor != NULL) + if (pdev->pClass[pdev->classId]->GetHSConfigDescriptor != NULL) { - pdev->pConfDesc = (void *)pdev->pClass->GetHSConfigDescriptor(&len); + pdev->pConfDesc = (void *)pdev->pClass[pdev->classId]->GetHSConfigDescriptor(&len); } #else /* Default USE_USB_FS */ - if (pdev->pClass->GetFSConfigDescriptor != NULL) + if (pdev->pClass[pdev->classId]->GetFSConfigDescriptor != NULL) { - pdev->pConfDesc = (void *)pdev->pClass->GetFSConfigDescriptor(&len); + pdev->pConfDesc = (void *)pdev->pClass[pdev->classId]->GetFSConfigDescriptor(&len); } #endif /* USE_USB_FS */ + /* Increment the NumClasses */ + pdev->NumClasses ++; + return USBD_OK; } +#ifdef USE_USBD_COMPOSITE +/** + * @brief USBD_RegisterClassComposite + * Link class driver to Device Core. + * @param pdev : Device Handle + * @param pclass: Class handle + * @param classtype: Class type + * @param EpAddr: Endpoint Address handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_RegisterClassComposite(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass, + USBD_CompositeClassTypeDef classtype, uint8_t *EpAddr) +{ + USBD_StatusTypeDef ret = USBD_OK; + uint16_t len = 0U; + + if ((pdev->classId < USBD_MAX_SUPPORTED_CLASS) && (pdev->NumClasses < USBD_MAX_SUPPORTED_CLASS)) + { + if ((uint32_t)pclass != 0U) + { + /* Link the class to the USB Device handle */ + pdev->pClass[pdev->classId] = pclass; + ret = USBD_OK; + + pdev->tclasslist[pdev->classId].EpAdd = EpAddr; + + /* Call the composite class builder */ + (void)USBD_CMPSIT_AddClass(pdev, pclass, classtype, 0); + + /* Increment the ClassId for the next occurrence */ + pdev->classId ++; + pdev->NumClasses ++; + } + else + { +#if (USBD_DEBUG_LEVEL > 1U) + USBD_ErrLog("Invalid Class handle"); +#endif /* (USBD_DEBUG_LEVEL > 1U) */ + ret = USBD_FAIL; + } + } + + if (ret == USBD_OK) + { + /* Get Device Configuration Descriptor */ +#ifdef USE_USB_HS + pdev->pConfDesc = USBD_CMPSIT.GetHSConfigDescriptor(&len); +#else /* Default USE_USB_FS */ + pdev->pConfDesc = USBD_CMPSIT.GetFSConfigDescriptor(&len); +#endif /* USE_USB_FS */ + } + + return ret; +} + +/** + * @brief USBD_UnRegisterClassComposite + * UnLink all composite class drivers from Device Core. + * @param pDevice : Device Handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_UnRegisterClassComposite(USBD_HandleTypeDef *pdev) +{ + USBD_StatusTypeDef ret = USBD_FAIL; + uint8_t idx1; + uint8_t idx2; + + /* Unroll all activated classes */ + for (idx1 = 0; idx1 < pdev->NumClasses; idx1++) + { + /* Check if the class correspond to the requested type and if it is active */ + if (pdev->tclasslist[idx1].Active == 1U) + { + /* Set the new class ID */ + pdev->classId = idx1; + + /* Free resources used by the selected class */ + if (pdev->pClass[pdev->classId] != NULL) + { + /* Free Class Resources */ + if (pdev->pClass[pdev->classId]->DeInit(pdev, (uint8_t)pdev->dev_config) != 0U) + { +#if (USBD_DEBUG_LEVEL > 1U) + USBD_ErrLog("Class DeInit didn't succeed!, can't unregister selected class"); +#endif /* (USBD_DEBUG_LEVEL > 1U) */ + + ret = USBD_FAIL; + } + } + + /* Free the class pointer */ + pdev->pClass[pdev->classId] = NULL; + + /* Free the class location in classes table and reset its parameters to zero */ + pdev->tclasslist[pdev->classId].ClassType = CLASS_TYPE_NONE; + pdev->tclasslist[pdev->classId].ClassId = 0U; + pdev->tclasslist[pdev->classId].Active = 0U; + pdev->tclasslist[pdev->classId].NumEps = 0U; + pdev->tclasslist[pdev->classId].NumIf = 0U; + pdev->tclasslist[pdev->classId].CurrPcktSze = 0U; + + for (idx2 = 0U; idx2 < USBD_MAX_CLASS_ENDPOINTS; idx2++) + { + pdev->tclasslist[pdev->classId].Eps[idx2].add = 0U; + pdev->tclasslist[pdev->classId].Eps[idx2].type = 0U; + pdev->tclasslist[pdev->classId].Eps[idx2].size = 0U; + pdev->tclasslist[pdev->classId].Eps[idx2].is_used = 0U; + } + + for (idx2 = 0U; idx2 < USBD_MAX_CLASS_INTERFACES; idx2++) + { + pdev->tclasslist[pdev->classId].Ifs[idx2] = 0U; + } + } + } + + /* Reset the configuration descriptor */ + (void)USBD_CMPST_ClearConfDesc(pdev); + + /* Reset the class ID and number of classes */ + pdev->classId = 0U; + pdev->NumClasses = 0U; + + return ret; +} + + +#endif /* USE_USBD_COMPOSITE */ + /** * @brief USBD_Start * Start the USB Device Core. @@ -200,6 +370,10 @@ USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDe */ USBD_StatusTypeDef USBD_Start(USBD_HandleTypeDef *pdev) { +#ifdef USE_USBD_COMPOSITE + pdev->classId = 0U; +#endif /* USE_USBD_COMPOSITE */ + /* Start the low level driver */ return USBD_LL_Start(pdev); } @@ -216,11 +390,31 @@ USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev) (void)USBD_LL_Stop(pdev); /* Free Class Resources */ - if (pdev->pClass != NULL) +#ifdef USE_USBD_COMPOSITE + /* Parse the table of classes in use */ + for (uint32_t i = 0U; i < USBD_MAX_SUPPORTED_CLASS; i++) { - (void)pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); + /* Check if current class is in use */ + if ((pdev->tclasslist[i].Active) == 1U) + { + if (pdev->pClass[i] != NULL) + { + pdev->classId = i; + /* Free Class Resources */ + (void)pdev->pClass[i]->DeInit(pdev, (uint8_t)pdev->dev_config); + } + } } + /* Reset the class ID */ + pdev->classId = 0U; +#else + if (pdev->pClass[0] != NULL) + { + (void)pdev->pClass[0]->DeInit(pdev, (uint8_t)pdev->dev_config); + } +#endif /* USE_USBD_COMPOSITE */ + return USBD_OK; } @@ -230,12 +424,21 @@ USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev) * @param pdev: device instance * @retval status */ -USBD_StatusTypeDef USBD_RunTestMode(USBD_HandleTypeDef *pdev) +USBD_StatusTypeDef USBD_RunTestMode(USBD_HandleTypeDef *pdev) { +#ifdef USBD_HS_TESTMODE_ENABLE + USBD_StatusTypeDef ret; + + /* Run USB HS test mode */ + ret = USBD_LL_SetTestMode(pdev, pdev->dev_test_mode); + + return ret; +#else /* Prevent unused argument compilation warning */ UNUSED(pdev); return USBD_OK; +#endif /* USBD_HS_TESTMODE_ENABLE */ } /** @@ -248,13 +451,33 @@ USBD_StatusTypeDef USBD_RunTestMode(USBD_HandleTypeDef *pdev) USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { - USBD_StatusTypeDef ret = USBD_FAIL; + USBD_StatusTypeDef ret = USBD_OK; - if (pdev->pClass != NULL) +#ifdef USE_USBD_COMPOSITE + /* Parse the table of classes in use */ + for (uint32_t i = 0U; i < USBD_MAX_SUPPORTED_CLASS; i++) + { + /* Check if current class is in use */ + if ((pdev->tclasslist[i].Active) == 1U) + { + if (pdev->pClass[i] != NULL) + { + pdev->classId = i; + /* Set configuration and Start the Class*/ + if (pdev->pClass[i]->Init(pdev, cfgidx) != 0U) + { + ret = USBD_FAIL; + } + } + } + } +#else + if (pdev->pClass[0] != NULL) { /* Set configuration and Start the Class */ - ret = (USBD_StatusTypeDef)pdev->pClass->Init(pdev, cfgidx); + ret = (USBD_StatusTypeDef)pdev->pClass[0]->Init(pdev, cfgidx); } +#endif /* USE_USBD_COMPOSITE */ return ret; } @@ -268,13 +491,35 @@ USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) */ USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { - /* Clear configuration and De-initialize the Class process */ - if (pdev->pClass != NULL) - { - pdev->pClass->DeInit(pdev, cfgidx); - } + USBD_StatusTypeDef ret = USBD_OK; - return USBD_OK; +#ifdef USE_USBD_COMPOSITE + /* Parse the table of classes in use */ + for (uint32_t i = 0U; i < USBD_MAX_SUPPORTED_CLASS; i++) + { + /* Check if current class is in use */ + if ((pdev->tclasslist[i].Active) == 1U) + { + if (pdev->pClass[i] != NULL) + { + pdev->classId = i; + /* Clear configuration and De-initialize the Class process */ + if (pdev->pClass[i]->DeInit(pdev, cfgidx) != 0U) + { + ret = USBD_FAIL; + } + } + } + } +#else + /* Clear configuration and De-initialize the Class process */ + if (pdev->pClass[0]->DeInit(pdev, cfgidx) != 0U) + { + ret = USBD_FAIL; + } +#endif /* USE_USBD_COMPOSITE */ + + return ret; } @@ -328,7 +573,8 @@ USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, uint8_t epnum, uint8_t *pdata) { USBD_EndpointTypeDef *pep; - USBD_StatusTypeDef ret; + USBD_StatusTypeDef ret = USBD_OK; + uint8_t idx; if (epnum == 0U) { @@ -344,11 +590,39 @@ USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, } else { - if (pdev->dev_state == USBD_STATE_CONFIGURED) + /* Find the class ID relative to the current request */ + switch (pdev->request.bmRequest & 0x1FU) { - if (pdev->pClass->EP0_RxReady != NULL) + case USB_REQ_RECIPIENT_DEVICE: + /* Device requests must be managed by the first instantiated class + (or duplicated by all classes for simplicity) */ + idx = 0U; + break; + + case USB_REQ_RECIPIENT_INTERFACE: + idx = USBD_CoreFindIF(pdev, LOBYTE(pdev->request.wIndex)); + break; + + case USB_REQ_RECIPIENT_ENDPOINT: + idx = USBD_CoreFindEP(pdev, LOBYTE(pdev->request.wIndex)); + break; + + default: + /* Back to the first class in case of doubt */ + idx = 0U; + break; + } + + if (idx < USBD_MAX_SUPPORTED_CLASS) + { + /* Setup the class ID and route the request to the relative class function */ + if (pdev->dev_state == USBD_STATE_CONFIGURED) { - pdev->pClass->EP0_RxReady(pdev); + if (pdev->pClass[idx]->EP0_RxReady != NULL) + { + pdev->classId = idx; + pdev->pClass[idx]->EP0_RxReady(pdev); + } } } @@ -371,17 +645,24 @@ USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, } else { - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - if (pdev->pClass->DataOut != NULL) - { - ret = (USBD_StatusTypeDef)pdev->pClass->DataOut(pdev, epnum); + /* Get the class index relative to this interface */ + idx = USBD_CoreFindEP(pdev, (epnum & 0x7FU)); - if (ret != USBD_OK) + if (((uint16_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS)) + { + /* Call the class data out function to manage the request */ + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + if (pdev->pClass[idx]->DataOut != NULL) { - return ret; + pdev->classId = idx; + ret = (USBD_StatusTypeDef)pdev->pClass[idx]->DataOut(pdev, epnum); } } + if (ret != USBD_OK) + { + return ret; + } } } @@ -400,6 +681,7 @@ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, { USBD_EndpointTypeDef *pep; USBD_StatusTypeDef ret; + uint8_t idx; if (epnum == 0U) { @@ -433,9 +715,10 @@ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, { if (pdev->dev_state == USBD_STATE_CONFIGURED) { - if (pdev->pClass->EP0_TxSent != NULL) + if (pdev->pClass[0]->EP0_TxSent != NULL) { - pdev->pClass->EP0_TxSent(pdev); + pdev->classId = 0U; + pdev->pClass[0]->EP0_TxSent(pdev); } } (void)USBD_LL_StallEP(pdev, 0x80U); @@ -454,7 +737,7 @@ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, #endif } - if (pdev->dev_test_mode == 1U) + if (pdev->dev_test_mode != 0U) { (void)USBD_RunTestMode(pdev); pdev->dev_test_mode = 0U; @@ -462,15 +745,23 @@ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, } else { - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - if (pdev->pClass->DataIn != NULL) - { - ret = (USBD_StatusTypeDef)pdev->pClass->DataIn(pdev, epnum); + /* Get the class index relative to this interface */ + idx = USBD_CoreFindEP(pdev, ((uint8_t)epnum | 0x80U)); - if (ret != USBD_OK) + if (((uint16_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS)) + { + /* Call the class data out function to manage the request */ + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + if (pdev->pClass[idx]->DataIn != NULL) { - return ret; + pdev->classId = idx; + ret = (USBD_StatusTypeDef)pdev->pClass[idx]->DataIn(pdev, epnum); + + if (ret != USBD_OK) + { + return ret; + } } } } @@ -488,24 +779,50 @@ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev) { + USBD_StatusTypeDef ret = USBD_OK; + /* Upon Reset call user call back */ pdev->dev_state = USBD_STATE_DEFAULT; pdev->ep0_state = USBD_EP0_IDLE; pdev->dev_config = 0U; pdev->dev_remote_wakeup = 0U; + pdev->dev_test_mode = 0U; - if (pdev->pClass == NULL) +#ifdef USE_USBD_COMPOSITE + /* Parse the table of classes in use */ + for (uint32_t i = 0U; i < USBD_MAX_SUPPORTED_CLASS; i++) { - return USBD_FAIL; - } - - if (pdev->pClassData != NULL) - { - if (pdev->pClass->DeInit != NULL) + /* Check if current class is in use */ + if ((pdev->tclasslist[i].Active) == 1U) { - (void)pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); + if (pdev->pClass[i] != NULL) + { + pdev->classId = i; + /* Clear configuration and De-initialize the Class process*/ + + if (pdev->pClass[i]->DeInit != NULL) + { + if (pdev->pClass[i]->DeInit(pdev, (uint8_t)pdev->dev_config) != USBD_OK) + { + ret = USBD_FAIL; + } + } + } } } +#else + + if (pdev->pClass[0] != NULL) + { + if (pdev->pClass[0]->DeInit != NULL) + { + if (pdev->pClass[0]->DeInit(pdev, (uint8_t)pdev->dev_config) != USBD_OK) + { + ret = USBD_FAIL; + } + } + } +#endif /* USE_USBD_COMPOSITE */ /* Open EP0 OUT */ (void)USBD_LL_OpenEP(pdev, 0x00U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE); @@ -519,7 +836,7 @@ USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev) pdev->ep_in[0].maxpacket = USB_MAX_EP0_SIZE; - return USBD_OK; + return ret; } /** @@ -577,17 +894,35 @@ USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev) USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev) { - if (pdev->pClass == NULL) - { - return USBD_FAIL; - } - + /* The SOF event can be distributed for all classes that support it */ if (pdev->dev_state == USBD_STATE_CONFIGURED) { - if (pdev->pClass->SOF != NULL) +#ifdef USE_USBD_COMPOSITE + /* Parse the table of classes in use */ + for (uint32_t i = 0; i < USBD_MAX_SUPPORTED_CLASS; i++) { - (void)pdev->pClass->SOF(pdev); + /* Check if current class is in use */ + if ((pdev->tclasslist[i].Active) == 1U) + { + if (pdev->pClass[i] != NULL) + { + if (pdev->pClass[i]->SOF != NULL) + { + pdev->classId = i; + (void)pdev->pClass[i]->SOF(pdev); + } + } + } } +#else + if (pdev->pClass[0] != NULL) + { + if (pdev->pClass[0]->SOF != NULL) + { + (void)pdev->pClass[0]->SOF(pdev); + } + } +#endif /* USE_USBD_COMPOSITE */ } return USBD_OK; @@ -602,16 +937,16 @@ USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev) USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) { - if (pdev->pClass == NULL) + if (pdev->pClass[pdev->classId] == NULL) { return USBD_FAIL; } if (pdev->dev_state == USBD_STATE_CONFIGURED) { - if (pdev->pClass->IsoINIncomplete != NULL) + if (pdev->pClass[pdev->classId]->IsoINIncomplete != NULL) { - (void)pdev->pClass->IsoINIncomplete(pdev, epnum); + (void)pdev->pClass[pdev->classId]->IsoINIncomplete(pdev, epnum); } } @@ -627,16 +962,16 @@ USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) { - if (pdev->pClass == NULL) + if (pdev->pClass[pdev->classId] == NULL) { return USBD_FAIL; } if (pdev->dev_state == USBD_STATE_CONFIGURED) { - if (pdev->pClass->IsoOUTIncomplete != NULL) + if (pdev->pClass[pdev->classId]->IsoOUTIncomplete != NULL) { - (void)pdev->pClass->IsoOUTIncomplete(pdev, epnum); + (void)pdev->pClass[pdev->classId]->IsoOUTIncomplete(pdev, epnum); } } @@ -665,16 +1000,210 @@ USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev) */ USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev) { + USBD_StatusTypeDef ret = USBD_OK; + /* Free Class Resources */ pdev->dev_state = USBD_STATE_DEFAULT; - if (pdev->pClass != NULL) +#ifdef USE_USBD_COMPOSITE + /* Parse the table of classes in use */ + for (uint32_t i = 0; i < USBD_MAX_SUPPORTED_CLASS; i++) { - (void)pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); + /* Check if current class is in use */ + if ((pdev->tclasslist[i].Active) == 1U) + { + if (pdev->pClass[i] != NULL) + { + pdev->classId = i; + /* Clear configuration and De-initialize the Class process*/ + if (pdev->pClass[i]->DeInit(pdev, (uint8_t)pdev->dev_config) != 0U) + { + ret = USBD_FAIL; + } + } + } + } +#else + if (pdev->pClass[0] != NULL) + { + if (pdev->pClass[0]->DeInit(pdev, (uint8_t)pdev->dev_config) != 0U) + { + ret = USBD_FAIL; + } + } +#endif /* USE_USBD_COMPOSITE */ + + return ret; +} + +/** + * @brief USBD_CoreFindIF + * return the class index relative to the selected interface + * @param pdev: device instance + * @param index : selected interface number + * @retval index of the class using the selected interface number. OxFF if no class found. + */ +uint8_t USBD_CoreFindIF(USBD_HandleTypeDef *pdev, uint8_t index) +{ +#ifdef USE_USBD_COMPOSITE + /* Parse the table of classes in use */ + for (uint32_t i = 0U; i < USBD_MAX_SUPPORTED_CLASS; i++) + { + /* Check if current class is in use */ + if ((pdev->tclasslist[i].Active) == 1U) + { + /* Parse all interfaces listed in the current class */ + for (uint32_t j = 0U; j < pdev->tclasslist[i].NumIf; j++) + { + /* Check if requested Interface matches the current class interface */ + if (pdev->tclasslist[i].Ifs[j] == index) + { + if (pdev->pClass[i]->Setup != NULL) + { + return (uint8_t)i; + } + } + } + } } - return USBD_OK; + return 0xFFU; +#else + UNUSED(pdev); + UNUSED(index); + + return 0x00U; +#endif /* USE_USBD_COMPOSITE */ } + +/** + * @brief USBD_CoreFindEP + * return the class index relative to the selected endpoint + * @param pdev: device instance + * @param index : selected endpoint number + * @retval index of the class using the selected endpoint number. 0xFF if no class found. + */ +uint8_t USBD_CoreFindEP(USBD_HandleTypeDef *pdev, uint8_t index) +{ +#ifdef USE_USBD_COMPOSITE + /* Parse the table of classes in use */ + for (uint32_t i = 0U; i < USBD_MAX_SUPPORTED_CLASS; i++) + { + /* Check if current class is in use */ + if ((pdev->tclasslist[i].Active) == 1U) + { + /* Parse all endpoints listed in the current class */ + for (uint32_t j = 0U; j < pdev->tclasslist[i].NumEps; j++) + { + /* Check if requested endpoint matches the current class endpoint */ + if (pdev->tclasslist[i].Eps[j].add == index) + { + if (pdev->pClass[i]->Setup != NULL) + { + return (uint8_t)i; + } + } + } + } + } + + return 0xFFU; +#else + UNUSED(pdev); + UNUSED(index); + + return 0x00U; +#endif /* USE_USBD_COMPOSITE */ +} + +#ifdef USE_USBD_COMPOSITE +/** + * @brief USBD_CoreGetEPAdd + * Get the endpoint address relative to a selected class + * @param pdev: device instance + * @param ep_dir: USBD_EP_IN or USBD_EP_OUT + * @param ep_type: USBD_EP_TYPE_CTRL, USBD_EP_TYPE_ISOC, USBD_EP_TYPE_BULK or USBD_EP_TYPE_INTR + * @retval Address of the selected endpoint or 0xFFU if no endpoint found. + */ +uint8_t USBD_CoreGetEPAdd(USBD_HandleTypeDef *pdev, uint8_t ep_dir, uint8_t ep_type) +{ + uint8_t idx; + + /* Find the EP address in the selected class table */ + for (idx = 0; idx < pdev->tclasslist[pdev->classId].NumEps; idx++) + { + if (((pdev->tclasslist[pdev->classId].Eps[idx].add & USBD_EP_IN) == ep_dir) && \ + (pdev->tclasslist[pdev->classId].Eps[idx].type == ep_type) && \ + (pdev->tclasslist[pdev->classId].Eps[idx].is_used != 0U)) + { + return (pdev->tclasslist[pdev->classId].Eps[idx].add); + } + } + + /* If reaching this point, then no endpoint was found */ + return 0xFFU; +} +#endif /* USE_USBD_COMPOSITE */ + +/** + * @brief USBD_GetEpDesc + * This function return the Endpoint descriptor + * @param pdev: device instance + * @param pConfDesc: pointer to Bos descriptor + * @param EpAddr: endpoint address + * @retval pointer to video endpoint descriptor + */ +void *USBD_GetEpDesc(uint8_t *pConfDesc, uint8_t EpAddr) +{ + USBD_DescHeaderTypeDef *pdesc = (USBD_DescHeaderTypeDef *)(void *)pConfDesc; + USBD_ConfigDescTypeDef *desc = (USBD_ConfigDescTypeDef *)(void *)pConfDesc; + USBD_EpDescTypeDef *pEpDesc = NULL; + uint16_t ptr; + + if (desc->wTotalLength > desc->bLength) + { + ptr = desc->bLength; + + while (ptr < desc->wTotalLength) + { + pdesc = USBD_GetNextDesc((uint8_t *)pdesc, &ptr); + + if (pdesc->bDescriptorType == USB_DESC_TYPE_ENDPOINT) + { + pEpDesc = (USBD_EpDescTypeDef *)(void *)pdesc; + + if (pEpDesc->bEndpointAddress == EpAddr) + { + break; + } + else + { + pEpDesc = NULL; + } + } + } + } + + return (void *)pEpDesc; +} + +/** + * @brief USBD_GetNextDesc + * This function return the next descriptor header + * @param buf: Buffer where the descriptor is available + * @param ptr: data pointer inside the descriptor + * @retval next header + */ +USBD_DescHeaderTypeDef *USBD_GetNextDesc(uint8_t *pbuf, uint16_t *ptr) +{ + USBD_DescHeaderTypeDef *pnext = (USBD_DescHeaderTypeDef *)(void *)pbuf; + + *ptr += pnext->bLength; + pnext = (USBD_DescHeaderTypeDef *)(void *)(pbuf + pnext->bLength); + + return (pnext); +} + /** * @} */ diff --git a/Core/Src/usbd_ctlreq.c b/Core/Src/usbd_ctlreq.c index 8054d27..c733647 100644 --- a/Core/Src/usbd_ctlreq.c +++ b/Core/Src/usbd_ctlreq.c @@ -20,6 +20,9 @@ #include "usbd_ctlreq.h" #include "usbd_ioreq.h" +#ifdef USE_USBD_COMPOSITE +#include "usbd_composite_builder.h" +#endif /* USE_USBD_COMPOSITE */ /** @addtogroup STM32_USBD_STATE_DEVICE_LIBRARY * @{ @@ -104,7 +107,7 @@ USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef { case USB_REQ_TYPE_CLASS: case USB_REQ_TYPE_VENDOR: - ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req); + ret = (USBD_StatusTypeDef)pdev->pClass[pdev->classId]->Setup(pdev, req); break; case USB_REQ_TYPE_STANDARD: @@ -162,6 +165,7 @@ USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef USBD_StatusTypeDef USBD_StdItfReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { USBD_StatusTypeDef ret = USBD_OK; + uint8_t idx; switch (req->bmRequest & USB_REQ_TYPE_MASK) { @@ -176,7 +180,27 @@ USBD_StatusTypeDef USBD_StdItfReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES) { - ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req); + /* Get the class index relative to this interface */ + idx = USBD_CoreFindIF(pdev, LOBYTE(req->wIndex)); + if (((uint8_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS)) + { + /* Call the class data out function to manage the request */ + if (pdev->pClass[idx]->Setup != NULL) + { + pdev->classId = idx; + ret = (USBD_StatusTypeDef)(pdev->pClass[idx]->Setup(pdev, req)); + } + else + { + /* should never reach this condition */ + ret = USBD_FAIL; + } + } + else + { + /* No relative interface found */ + ret = USBD_FAIL; + } if ((req->wLength == 0U) && (ret == USBD_OK)) { @@ -214,14 +238,26 @@ USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef { USBD_EndpointTypeDef *pep; uint8_t ep_addr; + uint8_t idx; USBD_StatusTypeDef ret = USBD_OK; + ep_addr = LOBYTE(req->wIndex); switch (req->bmRequest & USB_REQ_TYPE_MASK) { case USB_REQ_TYPE_CLASS: case USB_REQ_TYPE_VENDOR: - ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req); + /* Get the class index relative to this endpoint */ + idx = USBD_CoreFindEP(pdev, ep_addr); + if (((uint8_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS)) + { + pdev->classId = idx; + /* Call the class data out function to manage the request */ + if (pdev->pClass[idx]->Setup != NULL) + { + ret = (USBD_StatusTypeDef)pdev->pClass[idx]->Setup(pdev, req); + } + } break; case USB_REQ_TYPE_STANDARD: @@ -284,7 +320,18 @@ USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef (void)USBD_LL_ClearStallEP(pdev, ep_addr); } (void)USBD_CtlSendStatus(pdev); - ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req); + + /* Get the class index relative to this interface */ + idx = USBD_CoreFindEP(pdev, ep_addr); + if (((uint8_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS)) + { + pdev->classId = idx; + /* Call the class data out function to manage the request */ + if (pdev->pClass[idx]->Setup != NULL) + { + ret = (USBD_StatusTypeDef)(pdev->pClass[idx]->Setup(pdev, req)); + } + } } break; @@ -396,7 +443,7 @@ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *r err++; } break; -#endif +#endif /* (USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1U) */ case USB_DESC_TYPE_DEVICE: pbuf = pdev->pDesc->GetDeviceDescriptor(pdev->dev_speed, &len); break; @@ -404,12 +451,30 @@ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *r case USB_DESC_TYPE_CONFIGURATION: if (pdev->dev_speed == USBD_SPEED_HIGH) { - pbuf = pdev->pClass->GetHSConfigDescriptor(&len); +#ifdef USE_USBD_COMPOSITE + if ((uint8_t)(pdev->NumClasses) > 0U) + { + pbuf = (uint8_t *)USBD_CMPSIT.GetHSConfigDescriptor(&len); + } + else +#endif /* USE_USBD_COMPOSITE */ + { + pbuf = (uint8_t *)pdev->pClass[0]->GetHSConfigDescriptor(&len); + } pbuf[1] = USB_DESC_TYPE_CONFIGURATION; } else { - pbuf = pdev->pClass->GetFSConfigDescriptor(&len); +#ifdef USE_USBD_COMPOSITE + if ((uint8_t)(pdev->NumClasses) > 0U) + { + pbuf = (uint8_t *)USBD_CMPSIT.GetFSConfigDescriptor(&len); + } + else +#endif /* USE_USBD_COMPOSITE */ + { + pbuf = (uint8_t *)pdev->pClass[0]->GetFSConfigDescriptor(&len); + } pbuf[1] = USB_DESC_TYPE_CONFIGURATION; } break; @@ -491,16 +556,28 @@ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *r default: #if (USBD_SUPPORT_USER_STRING_DESC == 1U) - if (pdev->pClass->GetUsrStrDescriptor != NULL) + pbuf = NULL; + + + for (uint32_t idx = 0U; (idx < pdev->NumClasses); idx++) { - pbuf = pdev->pClass->GetUsrStrDescriptor(pdev, (req->wValue), &len); + if (pdev->pClass[idx]->GetUsrStrDescriptor != NULL) + { + pdev->classId = idx; + pbuf = pdev->pClass[idx]->GetUsrStrDescriptor(pdev, LOBYTE(req->wValue), &len); + + if (pbuf == NULL) /* This means that no class recognized the string index */ + { + continue; + } + else + { + break; + } + } } - else - { - USBD_CtlError(pdev, req); - err++; - } -#endif + +#endif /* USBD_SUPPORT_USER_STRING_DESC */ #if (USBD_CLASS_USER_STRING_DESC == 1U) if (pdev->pDesc->GetUserStrDescriptor != NULL) @@ -512,12 +589,12 @@ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *r USBD_CtlError(pdev, req); err++; } -#endif +#endif /* USBD_SUPPORT_USER_STRING_DESC */ #if ((USBD_CLASS_USER_STRING_DESC == 0U) && (USBD_SUPPORT_USER_STRING_DESC == 0U)) USBD_CtlError(pdev, req); err++; -#endif +#endif /* (USBD_CLASS_USER_STRING_DESC == 0U) && (USBD_SUPPORT_USER_STRING_DESC == 0U) */ break; } break; @@ -525,7 +602,16 @@ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *r case USB_DESC_TYPE_DEVICE_QUALIFIER: if (pdev->dev_speed == USBD_SPEED_HIGH) { - pbuf = pdev->pClass->GetDeviceQualifierDescriptor(&len); +#ifdef USE_USBD_COMPOSITE + if ((uint8_t)(pdev->NumClasses) > 0U) + { + pbuf = (uint8_t *)USBD_CMPSIT.GetDeviceQualifierDescriptor(&len); + } + else +#endif /* USE_USBD_COMPOSITE */ + { + pbuf = (uint8_t *)pdev->pClass[0]->GetDeviceQualifierDescriptor(&len); + } } else { @@ -537,7 +623,16 @@ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *r case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION: if (pdev->dev_speed == USBD_SPEED_HIGH) { - pbuf = pdev->pClass->GetOtherSpeedConfigDescriptor(&len); +#ifdef USE_USBD_COMPOSITE + if ((uint8_t)(pdev->NumClasses) > 0U) + { + pbuf = (uint8_t *)USBD_CMPSIT.GetOtherSpeedConfigDescriptor(&len); + } + else +#endif /* USE_USBD_COMPOSITE */ + { + pbuf = (uint8_t *)pdev->pClass[0]->GetOtherSpeedConfigDescriptor(&len); + } pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION; } else @@ -650,6 +745,7 @@ static USBD_StatusTypeDef USBD_SetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReq if (ret != USBD_OK) { USBD_CtlError(pdev, req); + pdev->dev_state = USBD_STATE_ADDRESSED; } else { @@ -766,7 +862,7 @@ static void USBD_GetStatus(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) pdev->dev_config_status = USB_CONFIG_SELF_POWERED; #else pdev->dev_config_status = 0U; -#endif +#endif /* USBD_SELF_POWERED */ if (pdev->dev_remote_wakeup != 0U) { @@ -797,6 +893,15 @@ static void USBD_SetFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) pdev->dev_remote_wakeup = 1U; (void)USBD_CtlSendStatus(pdev); } + else if (req->wValue == USB_FEATURE_TEST_MODE) + { + pdev->dev_test_mode = req->wIndex >> 8; + (void)USBD_CtlSendStatus(pdev); + } + else + { + USBD_CtlError(pdev, req); + } } diff --git a/Core/Src/usbd_desc_template.c b/Core/Src/usbd_desc_template.c index 94564be..b80f511 100644 --- a/Core/Src/usbd_desc_template.c +++ b/Core/Src/usbd_desc_template.c @@ -52,7 +52,7 @@ uint8_t *USBD_Class_UserStrDescriptor(USBD_SpeedTypeDef speed, uint8_t idx, uint #if ((USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1)) uint8_t *USBD_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); -#endif +#endif /* (USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1) */ /* Private variables ---------------------------------------------------------*/ USBD_DescriptorsTypeDef Class_Desc = @@ -66,17 +66,17 @@ USBD_DescriptorsTypeDef Class_Desc = USBD_Class_InterfaceStrDescriptor, #if (USBD_CLASS_USER_STRING_DESC == 1) USBD_CLASS_UserStrDescriptor, -#endif +#endif /* USB_CLASS_USER_STRING_DESC */ #if ((USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1)) USBD_USR_BOSDescriptor, -#endif +#endif /* (USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1) */ }; /* USB Standard Device Descriptor */ #if defined ( __ICCARM__ ) /*!< IAR Compiler */ #pragma data_alignment=4 -#endif +#endif /* __ICCARM__ */ __ALIGN_BEGIN uint8_t USBD_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = { 0x12, /* bLength */ @@ -86,7 +86,7 @@ __ALIGN_BEGIN uint8_t USBD_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = in order to support BOS Desc */ #else 0x00, /* bcdUSB */ -#endif +#endif /* (USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1) */ 0x02, 0x00, /* bDeviceClass */ 0x00, /* bDeviceSubClass */ @@ -109,7 +109,7 @@ __ALIGN_BEGIN uint8_t USBD_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = #if (USBD_LPM_ENABLED == 1) #if defined ( __ICCARM__ ) /*!< IAR Compiler */ #pragma data_alignment=4 -#endif +#endif /* __ICCARM__ */ __ALIGN_BEGIN uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = { 0x5, @@ -126,13 +126,13 @@ __ALIGN_BEGIN uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = 0x0, 0x0 }; -#endif +#endif /* USBD_LPM_ENABLED */ /* USB Device Billboard BOS descriptor Template */ #if (USBD_CLASS_BOS_ENABLED == 1) #if defined ( __ICCARM__ ) /*!< IAR Compiler */ #pragma data_alignment=4 -#endif +#endif /* __ICCARM__ */ __ALIGN_BEGIN uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = { 0x05, /* bLength */ @@ -155,14 +155,16 @@ __ALIGN_BEGIN uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = 0x34, /* bLength */ 0x10, /* bDescriptorType: DEVICE CAPABILITY Type */ 0x0D, /* bDevCapabilityType: BILLBOARD_CAPABILITY */ - USBD_BB_URL_STRING_INDEX, /* iAddtionalInfoURL: Index of string descriptor providing a URL where the user can go to get more - detailed information about the product and the various Alternate Modes it supports */ + USBD_BB_URL_STRING_INDEX, /* iAddtionalInfoURL: Index of string descriptor providing a URL where the user + can go to get more detailed information about the product and the various + Alternate Modes it supports */ 0x02, /* bNumberOfAlternateModes: Number of Alternate modes supported. The maximum value that this field can be set to is MAX_NUM_ALT_MODE. */ 0x00, /* bPreferredAlternateMode: Index of the preferred Alternate Mode. System - software may use this information to provide the user with a better user experience. */ + software may use this information to provide the user with a better + user experience. */ 0x00, 0x00, /* VCONN Power needed by the adapter for full functionality 000b = 1W */ @@ -205,21 +207,23 @@ __ALIGN_BEGIN uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = 0x10, /* bDescriptorType: Device Descriptor Type */ 0x0F, /* bDevCapabilityType: BILLBOARD ALTERNATE MODE CAPABILITY */ 0x00, /* bIndex: Index of Alternate Mode described in the Billboard Capability Desc */ - 0x10, 0x00, 0x00, 0x00, /* dwAlternateModeVdo: contents of the Mode VDO for the alternate mode identified by bIndex */ + 0x10, 0x00, 0x00, 0x00, /* dwAlternateModeVdo: contents of the Mode VDO for the alternate mode + identified by bIndex */ 0x08, /* bLength */ 0x10, /* bDescriptorType: Device Descriptor Type */ 0x0F, /* bDevCapabilityType: BILLBOARD ALTERNATE MODE CAPABILITY */ 0x01, /* bIndex: Index of Alternate Mode described in the Billboard Capability Desc */ - 0x20, 0x00, 0x00, 0x00, /* dwAlternateModeVdo: contents of the Mode VDO for the alternate mode identified by bIndex */ + 0x20, 0x00, 0x00, 0x00, /* dwAlternateModeVdo: contents of the Mode VDO for the alternate mode + identified by bIndex */ }; -#endif +#endif /* USBD_CLASS_BOS_ENABLED */ /* USB Standard Device Descriptor */ #if defined ( __ICCARM__ ) /*!< IAR Compiler */ #pragma data_alignment=4 -#endif +#endif /* __ICCARM__ */ __ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = { USB_LEN_LANGID_STR_DESC, @@ -230,7 +234,7 @@ __ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = #if defined ( __ICCARM__ ) /*!< IAR Compiler */ #pragma data_alignment=4 -#endif +#endif /* __ICCARM__ */ __ALIGN_BEGIN uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] = { USB_SIZ_STRING_SERIAL, @@ -239,7 +243,7 @@ __ALIGN_BEGIN uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] = #if defined ( __ICCARM__ ) /*!< IAR Compiler */ #pragma data_alignment=4 -#endif +#endif /* __ICCARM__ */ __ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END; /* Private functions ---------------------------------------------------------*/ @@ -399,7 +403,7 @@ uint8_t *USBD_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) *length = sizeof(USBD_BOSDesc); return (uint8_t *)USBD_BOSDesc; } -#endif +#endif /* (USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1) */ #if (USBD_CLASS_USER_STRING_DESC == 1) @@ -416,7 +420,7 @@ uint8_t *USBD_Class_UserStrDescriptor(USBD_SpeedTypeDef speed, uint8_t idx, uint return USBD_StrDesc; } -#endif +#endif /* USBD_CLASS_USER_STRING_DESC */ /** diff --git a/Core/Src/usbd_ioreq.c b/Core/Src/usbd_ioreq.c index c4021ec..7c8004a 100644 --- a/Core/Src/usbd_ioreq.c +++ b/Core/Src/usbd_ioreq.c @@ -94,7 +94,7 @@ USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev, pdev->ep_in[0].rem_length = 0U; #else pdev->ep_in[0].rem_length = len; -#endif +#endif /* USBD_AVOID_PACKET_SPLIT_MPS */ /* Start the transfer */ (void)USBD_LL_Transmit(pdev, 0x00U, pbuf, len); @@ -138,7 +138,7 @@ USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev, pdev->ep_out[0].rem_length = 0U; #else pdev->ep_out[0].rem_length = len; -#endif +#endif /* USBD_AVOID_PACKET_SPLIT_MPS */ /* Start the transfer */ (void)USBD_LL_PrepareReceive(pdev, 0U, pbuf, len); diff --git a/Release_Notes.html b/Release_Notes.html index bda657f..1b9535d 100644 --- a/Release_Notes.html +++ b/Release_Notes.html @@ -7,118 +7,65 @@ + Release Notes for STM32 USB Device Library + 110 false + false false false + EN-US X-NONE X-NONE + + + + MicrosoftInternetExplorer4 + + + + @@ -789,7 +731,7 @@ ul

Release + style="font-size: 20pt; font-family: "Verdana","sans-serif"; color: rgb(51, 102, 255);">Release Notes for STM32 USB Device Library

Copyright @@ -810,25 +752,45 @@ ul

Update + name="History">Update History

V2.9.0 + style="font-size: 10pt; font-family: Arial; color: white;">V2.10.0 + / 03-Sept-2021

+

Main + Changes

+ +

V2.9.0 / 06-July-2021

Main + style="">Main Changes

V2.8.0 + style="font-size: 10pt; font-family: Arial; color: white;">V2.8.0 / 10-Mars-2021

Main + style="">Main Changes

V2.7.1 + style="font-size: 10pt; font-family: Arial; color: white;">V2.7.1 / 18-August-2020

Main + style="">Main Changes

  • USB All Class:
  • @@ -889,10 +849,10 @@ ul

V2.7.0 + style="font-size: 10pt; font-family: Arial; color: white;">V2.7.0 / 12-August-2020

Main + style="">Main Changes

  • Integration of  new USB device Class driver:
  • @@ -910,11 +870,9 @@ ul
  • Add support of USB controller which handles packet-size splitting by hardware
  • Avoid compilation warning due macro redefinition
  • -
  • change - added to USBD_HandleTypeDef structure: dev_state, - old_dev_state and - ep0_state declaration become volatile to disable - compiler optimization
  • +
  • change added to USBD_HandleTypeDef structure: + dev_state, old_dev_state and ep0_state declaration + become volatile to disable compiler optimization
  • Word spelling correction and file indentation improved
  • usbd_conf.h/c Template file updated to suggest @@ -952,10 +910,10 @@ ul

V2.6.1 + style="font-size: 10pt; font-family: Arial; color: white;">V2.6.1 / 05-June-2020

Main + style="">Main Changes

  • USB Core:
  • @@ -970,9 +928,8 @@ ul
  • Fix file indentation
  • Avoid accessing to NULL pointer in case TransmitCplt() user fops is not defined to allow - application - compatibility with device library version below - v2.6.0
    + application compatibility with device library + version below v2.6.0
@@ -981,10 +938,10 @@ ul
  • Fix minor misra-c 2012 violations
  • V2.6.0 + style="font-size: 10pt; font-family: Arial; color: white;">V2.6.0 / 27-December-2019

    Main + style="">Main Changes

    • Integration of three new USB device Class drivers:
    • @@ -1033,10 +990,10 @@ ul

    V2.5.3 + style="font-size: 10pt; font-family: Arial; color: white;">V2.5.3 / 30-April-2019

    Main + style="">Main Changes

    • Fix misra-c 2012 high severity violations
    • @@ -1055,41 +1012,41 @@ ul

    V2.5.2 + style="font-size: 10pt; font-family: Arial; color: white;">V2.5.2 / 27-Mars-2019

    Main + style="">Main Changes

      -
    • DFU +
    • DFU Class:
      • fix + lang="EN-US">fix compilation warning due to unreachable - instruction code introduced with CMSIS - V5.4.0 NVIC_SystemReset() prototype change
      • + lang="EN-US">unreachable instruction + code introduced with CMSIS V5.4.0 + NVIC_SystemReset() prototype change

    V2.5.1 + style="font-size: 10pt; font-family: Arial; color: white;">V2.5.1 / 03-August-2018

    Main + style="">Main Changes

      -
    • Update +
    • Update license section by adding path to get copy of ST Ultimate Liberty license
    • -
    • Core: +
    • Core: Fix unexpected stall during status OUT phase
    • -
    • DFU +
    • DFU Class:
      • -
      • rework +
      • rework hdfu struct to prevent unaligned addresses
      • @@ -1106,217 +1063,215 @@ ul

    V2.5.0 + style="font-size: 10pt; font-family: Arial; color: white;">V2.5.0 / 15-December-2017

    Main + style="">Main Changes

      -
    • Update +
    • Update license section
    • Update some - functions to be MISRAC + style="font-size: 10pt; font-family: Verdana;"> some + functions to be MISRAC 2004 compliant
    • -
    • Add +
    • Add HS and OtherSpeed configuration descriptor for HID and CustomHID classes
    • -
    • Correct +
    • Correct error handling in all class setup function
    • -
    • Add +
    • Add usbd_desc_template.c/ usbd_desc_template.h templates files
    • -
    • Add +
    • Add support of class and vendor request
    • -
    • CDC - Class: fix +
    • CDC + Class: fix zero-length packet issue in bulk IN transfer
    • -
    • Fix +
    • Fix compilation warning with unused arguments for some functions
    • -
    • Improve +
    • Improve USB Core enumeration state machine

    V2.4.2 + style="font-size: 10pt; font-family: Arial; color: white;">V2.4.2 / 11-December-2015

    Main + style="">Main Changes

      -
    • CDC +
    • CDC Class
      • -
      • usbd_cdc.c: - change #include - "USBD_CDC.h" by #include +
      • usbd_cdc.c: + change #include + "USBD_CDC.h" by #include "usbd_cdc.h"

    V2.4.1 + style="font-size: 10pt; font-family: Arial; color: white;">V2.4.1 / 19-June-2015

    Main + style="">Main Changes

      -
    • CDC +
    • CDC Class
      • -
      • usbd_cdc.c: +
      • usbd_cdc.c: comments update
      -
    • MSC +
    • MSC Class
      • -
      • usbd_msc_bot.h: +
      • usbd_msc_bot.h: update to be C++ compliant
      -
    • AUDIO +
    • AUDIO Class
      • -
      • usbd_audio.c: +
      • usbd_audio.c: fix issue when Host sends GetInterface command it gets a wrong value
        -
      • usbd_audio.c: +
      • usbd_audio.c: remove useless management of DMA half transfer

    V2.4.0 + style="font-size: 10pt; font-family: Arial; color: white;">V2.4.0 / 28-February-2015

    Main + style="">Main Changes

      -
    • Core +
    • Core Driver
      • -
      • Add +
      • Add support of Link - Power Management (LPM): add + style="font-weight: bold; font-style: italic;">Link + Power Management (LPM): add new API GetBOSDescriptor(), that is used only if USBD_LPM_ENABLED switch is enabled in usbd_conf.h file
      • usbd_core.c: -Fix +Fix bug of unsupported premature Host Out stage - during data In stage - (ie. when endpoint 0 maximum data size is 8 and - Host requests + during data In stage (ie. when endpoint 0 + maximum data size is 8 and Host requests GetDeviceDescriptor for the first time)
      • -
      • usbd_ctlreq.c: +
      • usbd_ctlreq.c: Fix bug of unsupported Endpoint Class requests (ie. Audio SetCurrent request for endpoint sampling rate setting)
      -
    • HID +
    • HID Class
      • -
      • Updating +
      • Updating Polling time API USBD_HID_GetPollingInterval() to query this period for HS and FS
      • -
      • usbd_hid.c: +
      • usbd_hid.c: Fix USBD_LL_CloseEP() function call in USBD_HID_DeInit() replacing endpoint size by endpoint address.
      -
    • CDC +
    • CDC Class
      • usbd_cdc.c: 
        • -
        • Add +
        • Add missing GetInterface request management in USBD_CDC_Setup() function
        • Update -USBD_CDC_Setup() +USBD_CDC_Setup() function to allow correct user implementation - of - CDC_SET_CONTROL_LINE_STATE and similar no-data - setup requests.
          + of CDC_SET_CONTROL_LINE_STATE and similar + no-data setup requests.

    V2.3.0 + style="font-size: 10pt; font-family: Arial; color: white;">V2.3.0 / 04-November-2014

    Main + style="">Main Changes

      -
    • Update +
    • Update all drivers to be C++ compliant
    • -
    • CDC +
    • CDC Class
      • -
      • usbd_cdc.c: +
      • usbd_cdc.c: fix clear flag issue in USBD_CDC_TransmitPacket() function
        -
      • usbd_cdc_if_template.c: - update +
      • usbd_cdc_if_template.c: + update TEMPLATE_Receive() function header comment
      -
    • Miscellaneous +
    • Miscellaneous source code comments update

    V2.2.0 + style="font-size: 10pt; font-family: Arial; color: white;">V2.2.0 / 13-June-2014

    Main + style="">Main Changes

      -
    • Source +
    • Source code comments review and update
    • -
    • HID +
    • HID class
      • -
      • Remove +
      • Remove unused API USBD_HID_DeviceQualifierDescriptor()
      • -
      • Add +
      • Add a new API in the HID class to query the poll time USBD_HID_GetPollingInterval()
      -
    • CDC +
    • CDC class
      • -
      • Bug +
      • Bug fix: missing handling ZeroLength Setup request
      -
    • All +
    • All classes
      • -
      • Add +
      • Add alias for the class definition, it's defined as macro with capital letter
    -
    ex. +
    ex. for the HID, the USBD_HID_CLASS macro is defined this way #define @@ -1326,73 +1281,72 @@ USBD_CDC_Setup() style="font-size: 10pt; font-family: Verdana;">and the application code can use the previous definition: &USBD_HID - ex. USBD_RegisterClass(&USBD_Device, + ex. USBD_RegisterClass(&USBD_Device, &USBD_HID) or the new USBD_HID_CLASS - ex. USBD_RegisterClass(&USBD_Device, + ex. USBD_RegisterClass(&USBD_Device, USBD_HID_CLASS)

    V2.1.0 + style="font-size: 10pt; font-family: Arial; color: white;">V2.1.0 / 22-April-2014

    Main + style="">Main Changes

      -
    • usbd_conf_template.c: +
    • usbd_conf_template.c: update file with the right content (it was using MSC memory management layer)
    • -
    • usbd_conf_template.h: - change include of stm32f4xx.h +
    • usbd_conf_template.h: + change include of stm32f4xx.h by stm32xxx.h and add comment to inform user to adapt it to the device used
    • -
    • Several +
    • Several enhancements in CustomHID class
      • -
      • Update +
      • Update the Custom HID class driver to simplify the link with user processes
      • -
      • Optimize +
      • Optimize the Custom HID class driver and reduce footprint
      • -
      • Add - USBD_CUSTOM_HID_RegisterInterface() +
      • Add + USBD_CUSTOM_HID_RegisterInterface() API to link user process to custom HID class
      • -
      • Add +
      • Add Custom HID interface template file usbd_customhid_if_template.c/h
      -
    • Miscellaneous +
    • Miscellaneous comments update

    V2.0.0 + style="font-size: 10pt; font-family: Arial; color: white;">V2.0.0 / 18-February-2014

    Main + style="">Main Changes

      -
    • Major - update - based on STM32Cube specification: Library Core, - Classes architecture and APIs - modified vs. V1.1.0, and thus the 2 versions are - not compatible.
      +
    • Major + update based on STM32Cube specification: Library + Core, Classes architecture and APIs modified vs. + V1.1.0, and thus the 2 versions are not + compatible.
    • -
    • This +
    • This version has to be used only with STM32Cube based development

    V1.1.0 + style="font-size: 10pt; font-family: Arial; color: white;">V1.1.0 / 19-March-2012

    Main + style="">Main Changes

    • Official + style="font-size: 10pt; font-family: Verdana;">Official support of STM32F4xx devices
    • @@ -1402,28 +1356,28 @@ USBD_CDC_Setup() add link to the License file on ST Internet.
    • Handle + style="font-size: 10pt; font-family: Verdana;">Handle test mode in the set feature request
    • Handle + style="font-size: 10pt; font-family: Verdana;">Handle dynamically the USB SELF POWERED feature
    • Handle + style="font-size: 10pt; font-family: Verdana;">Handle correctly the USBD_CtlError process to take into account error during Control OUT stage
    • Miscellaneous + style="font-size: 10pt; font-family: Verdana;">Miscellaneous bug fix

    V1.0.0 + style="font-size: 10pt; font-family: Arial; color: white;">V1.0.0 / 22-July-2011

    Main + style="">Main Changes

    • First + style="font-size: 10pt; font-family: Verdana;">First official version for STM32F105/7xx and STM32F2xx devices
    • @@ -1432,13 +1386,11 @@ USBD_CDC_Setup()

      License

      -

      This - software component is licensed by ST under Ultimate - Liberty license - SLA0044, the "License"; You may not use this - component except in - compliance with the License. You may obtain a copy of - the License at:

      +

      This software component is licensed by ST under + Ultimate Liberty license SLA0044, the "License"; + You may not use this component except in compliance + with the License. You may obtain a copy of the License + at:

      http://www.st.com/SLA0044