diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc.c b/cores/arduino/stm32/usb/cdc/usbd_cdc.c index 027189cdc9..e1c9a5085e 100644 --- a/cores/arduino/stm32/usb/cdc/usbd_cdc.c +++ b/cores/arduino/stm32/usb/cdc/usbd_cdc.c @@ -10,6 +10,17 @@ * - Command IN transfer (class requests management) * - Error management * + ****************************************************************************** + * @attention + * + * Copyright (c) 2015 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 * * =================================================================== @@ -37,17 +48,6 @@ * @endverbatim * ****************************************************************************** - * @attention - * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** */ #ifdef USBCON @@ -103,13 +103,14 @@ 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); - -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); - +#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); + 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 = { USB_LEN_DEV_QUALIFIER_DESC, @@ -123,7 +124,7 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_ 0x01, 0x00, }; - +#endif /* USE_USBD_COMPOSITE */ /** * @} */ @@ -132,6 +133,8 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_ * @{ */ +/* Prevent dynamic allocation */ +USBD_CDC_HandleTypeDef _hcdc; /* CDC interface class callbacks structure */ USBD_ClassTypeDef USBD_CDC = { @@ -145,12 +148,20 @@ 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 */ @@ -258,12 +269,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) */ /*---------------------------------------------------------------------------*/ @@ -440,6 +452,11 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] 0x00, 0x00 /* bInterval */ }; +#endif /* USE_USBD_COMPOSITE */ + +static uint8_t CDCInEpAdd = CDC_IN_EP; +static uint8_t CDCOutEpAdd = CDC_OUT_EP; +static uint8_t CDCCmdEpAdd = CDC_CMD_EP; /** * @} @@ -461,65 +478,82 @@ static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) UNUSED(cfgidx); USBD_CDC_HandleTypeDef *hcdc; - hcdc = (USBD_CDC_HandleTypeDef *)USBD_malloc(sizeof(USBD_CDC_HandleTypeDef)); + // hcdc = (USBD_CDC_HandleTypeDef *)USBD_malloc(sizeof(USBD_CDC_HandleTypeDef)); + hcdc = &_hcdc; 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, (uint8_t)pdev->classId); + CDCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); + CDCCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId); +#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); } @@ -537,23 +571,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, (uint8_t)pdev->classId); + CDCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); + CDCCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId); +#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) { - ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->DeInit(); - (void)USBD_free(pdev->pClassData); + if (pdev->pClassDataCmsit[pdev->classId] != NULL) { + ((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit(); + /* No need to free as hhid is no more dynamically allocated */ + // (void)USBD_free(pdev->pClassDataCmsit[pdev->classId]); + pdev->pClassDataCmsit[pdev->classId] = NULL; pdev->pClassData = NULL; } @@ -570,7 +614,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; @@ -584,9 +628,9 @@ static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, case USB_REQ_TYPE_CLASS: if (req->wLength != 0U) { 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); @@ -597,8 +641,8 @@ static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, (void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data, hcdc->CmdLength); } } 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; @@ -657,25 +701,27 @@ static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, */ static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) { - USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; - PCD_HandleTypeDef *hpcd = pdev->pData; + USBD_CDC_HandleTypeDef *hcdc; + PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef *)pdev->pData; - if (hcdc == NULL) { + if (pdev->pClassDataCmsit[pdev->classId] == NULL) { 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)) { + hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + + 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); } else { hcdc->TxState = 0U; - if (((USBD_CDC_ItfTypeDef *)pdev->pUserData)->TransmitCplt != NULL) { - ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum); + if (((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->TransmitCplt != NULL) { + ((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum); } } @@ -691,9 +737,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 (hcdc == NULL) { + if (pdev->pClassDataCmsit[pdev->classId] == NULL) { return (uint8_t)USBD_FAIL; } @@ -703,7 +749,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; } @@ -716,31 +762,46 @@ 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)) { - ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode, - (uint8_t *)hcdc->data, - (uint16_t)hcdc->CmdLength); + if ((pdev->pUserData[pdev->classId] != NULL) && (hcdc->CmdOpCode != 0xFFU)) { + ((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 - * @param speed : current device speed * @param length : pointer data length * @retval pointer to descriptor buffer */ static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length) { + USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_CfgFSDesc, CDC_CMD_EP); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_CfgFSDesc, CDC_OUT_EP); + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_CfgFSDesc, CDC_IN_EP); + + 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_CfgFSDesc); return USBD_CDC_CfgFSDesc; @@ -749,12 +810,27 @@ static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length) /** * @brief USBD_CDC_GetHSCfgDesc * Return configuration descriptor - * @param speed : current device speed * @param length : pointer data length * @retval pointer to descriptor buffer */ static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length) { + USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_CfgHSDesc, CDC_CMD_EP); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_CfgHSDesc, CDC_OUT_EP); + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_CfgHSDesc, CDC_IN_EP); + + 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_CfgHSDesc); return USBD_CDC_CfgHSDesc; @@ -763,12 +839,27 @@ static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length) /** * @brief USBD_CDC_GetOtherSpeedCfgDesc * Return configuration descriptor - * @param speed : current device speed * @param length : pointer data length * @retval pointer to descriptor buffer */ static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length) { + USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_OtherSpeedCfgDesc, CDC_CMD_EP); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_OtherSpeedCfgDesc, CDC_OUT_EP); + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_OtherSpeedCfgDesc, CDC_IN_EP); + + 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_OtherSpeedCfgDesc); return USBD_CDC_OtherSpeedCfgDesc; @@ -786,7 +877,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 @@ -800,7 +891,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; } @@ -809,12 +900,21 @@ uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, * @brief USBD_CDC_SetTxBuffer * @param pdev: device instance * @param pbuff: Tx Buffer + * @param length: length of data to be sent + * @param ClassId: The Class ID * @retval status */ +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, + uint8_t *pbuff, uint32_t length, uint8_t ClassId) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[ClassId]; +#else 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]; +#endif /* USE_USBD_COMPOSITE */ if (hcdc == NULL) { return (uint8_t)USBD_FAIL; @@ -834,7 +934,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) { return (uint8_t)USBD_FAIL; @@ -849,13 +949,26 @@ uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff) * @brief USBD_CDC_TransmitPacket * Transmit packet on IN endpoint * @param pdev: device instance + * @param ClassId: The Class ID * @retval status */ +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t ClassId) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[ClassId]; +#else 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]; +#endif /* USE_USBD_COMPOSITE */ + USBD_StatusTypeDef ret = USBD_BUSY; +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + CDCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, ClassId); +#endif /* USE_USBD_COMPOSITE */ + if (hcdc == NULL) { return (uint8_t)USBD_FAIL; } @@ -865,10 +978,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; } @@ -884,29 +997,40 @@ 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 (hcdc == 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, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ + + if (pdev->pClassDataCmsit[pdev->classId] == NULL) { return (uint8_t)USBD_FAIL; } 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); } return (uint8_t)USBD_OK; } - +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_CDC_ClearBuffer(USBD_HandleTypeDef *pdev, uint8_t ClassId) +{ + /* Suspend or Resume USB Out process */ + if (pdev->pClassDataCmsit[classId] != NULL) { +#else uint8_t USBD_CDC_ClearBuffer(USBD_HandleTypeDef *pdev) { /* Suspend or Resume USB Out process */ - if (pdev->pClassData != NULL) { + if (pdev->pClassDataCmsit[pdev->classId] != NULL) { +#endif /* USE_USBD_COMPOSITE */ /* Prepare Out endpoint to receive next packet */ USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, 0, 0); return (uint8_t)USBD_OK; diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc.h b/cores/arduino/stm32/usb/cdc/usbd_cdc.h index 4e39780760..3c32c7c9c2 100644 --- a/cores/arduino/stm32/usb/cdc/usbd_cdc.h +++ b/cores/arduino/stm32/usb/cdc/usbd_cdc.h @@ -144,13 +144,19 @@ extern USBD_ClassTypeDef USBD_CDC; uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_CDC_ItfTypeDef *fops); +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, + uint32_t length, uint8_t ClassId); +uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t ClassId); +uint8_t USBD_CDC_ClearBuffer(USBD_HandleTypeDef *pdev, uint8_t ClassId); +#else uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uint32_t length); - +uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev); +uint8_t USBD_CDC_ClearBuffer(USBD_HandleTypeDef *pdev); +#endif /* USE_USBD_COMPOSITE */ uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff); uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev); -uint8_t USBD_CDC_ClearBuffer(USBD_HandleTypeDef *pdev); -uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev); /** * @} */ diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c b/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c index e19a26e0d0..326ef3216d 100644 --- a/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c +++ b/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c @@ -48,6 +48,9 @@ USBD_HandleTypeDef hUSBD_Device_CDC; static bool CDC_initialized = false; static bool CDC_DTR_enabled = true; +#if defined(ICACHE) && defined (HAL_ICACHE_MODULE_ENABLED) && !defined(HAL_ICACHE_MODULE_DISABLED) + static bool icache_enabled = false; +#endif /* ICACHE && HAL_ICACHE_MODULE_ENABLED && !HAL_ICACHE_MODULE_DISABLED */ /* Received Data over USB are stored in this buffer */ CDC_TransmitQueue_TypeDef TransmitQueue; @@ -270,6 +273,15 @@ static int8_t USBD_CDC_TransmitCplt(uint8_t *Buf, uint32_t *Len, uint8_t epnum) void CDC_init(void) { +#if defined(ICACHE) && defined (HAL_ICACHE_MODULE_ENABLED) && !defined(HAL_ICACHE_MODULE_DISABLED) + if (HAL_ICACHE_IsEnabled() == 1) { + icache_enabled = true; + /* Disable instruction cache prior to internal cacheable memory update */ + if (HAL_ICACHE_Disable() != HAL_OK) { + Error_Handler(); + } + } +#endif /* ICACHE && HAL_ICACHE_MODULE_ENABLED && !HAL_ICACHE_MODULE_DISABLED */ if (!CDC_initialized) { /* Init Device Library */ if (USBD_Init(&hUSBD_Device_CDC, &USBD_Desc, 0) == USBD_OK) { @@ -294,6 +306,14 @@ void CDC_deInit(void) USBD_DeInit(&hUSBD_Device_CDC); CDC_initialized = false; } +#if defined(ICACHE) && defined (HAL_ICACHE_MODULE_ENABLED) && !defined(HAL_ICACHE_MODULE_DISABLED) + if (icache_enabled) { + /* Re-enable instruction cache */ + if (HAL_ICACHE_Enable() != HAL_OK) { + Error_Handler(); + } + } +#endif /* ICACHE && HAL_ICACHE_MODULE_ENABLED && !HAL_ICACHE_MODULE_DISABLED */ } bool CDC_connected() diff --git a/cores/arduino/stm32/usb/hid/usbd_hid_composite.c b/cores/arduino/stm32/usb/hid/usbd_hid_composite.c index 51f3369e9d..75fee40ea1 100644 --- a/cores/arduino/stm32/usb/hid/usbd_hid_composite.c +++ b/cores/arduino/stm32/usb/hid/usbd_hid_composite.c @@ -90,13 +90,13 @@ static uint8_t USBD_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx); static uint8_t USBD_COMPOSITE_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); static uint8_t USBD_HID_MOUSE_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); static uint8_t USBD_HID_KEYBOARD_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); - -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); 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 */ /** * @} */ @@ -105,6 +105,9 @@ static uint8_t USBD_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); * @{ */ +/* Prevent dynamic allocation */ +USBD_HID_HandleTypeDef _hhid; + USBD_ClassTypeDef USBD_COMPOSITE_HID = { USBD_HID_Init, USBD_HID_DeInit, @@ -116,14 +119,22 @@ USBD_ClassTypeDef USBD_COMPOSITE_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_COMPOSITE_HID_CONFIG_DESC_SIZ] __ALIGN_END = { +__ALIGN_BEGIN static uint8_t USBD_HID_CfgFSDesc[USB_COMPOSITE_HID_CONFIG_DESC_SIZ] __ALIGN_END = { 0x09, /* bLength: Configuration Descriptor size */ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ LOBYTE(USB_COMPOSITE_HID_CONFIG_DESC_SIZ), /* wTotalLength: Bytes returned */ @@ -135,7 +146,7 @@ __ALIGN_BEGIN static uint8_t USBD_HID_CfgFSDesc[USB_COMPOSITE_HID_CONFIG_DESC_SI 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 Joystick Mouse interface ****************/ @@ -219,7 +230,7 @@ __ALIGN_BEGIN static uint8_t USBD_HID_CfgHSDesc[USB_COMPOSITE_HID_CONFIG_DESC_SI 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 Joystick Mouse interface ****************/ @@ -375,9 +386,10 @@ __ALIGN_BEGIN static uint8_t USBD_HID_OtherSpeedCfgDesc[USB_COMPOSITE_HID_CONFIG HID_FS_BINTERVAL /* bInterval: Polling Interval */ /* 59 */ } ; +#endif /* USE_USBD_COMPOSITE */ /* USB HID device Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_MOUSE_HID_Desc[USB_HID_DESC_SIZ] __ALIGN_END = { +__ALIGN_BEGIN static uint8_t USBD_MOUSE_HID_Desc[USB_HID_DESC_SIZ] __ALIGN_END = { 0x09, /* bLength: HID Descriptor size */ HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */ 0x11, /* bcdHID: HID Class Spec release number */ @@ -402,6 +414,7 @@ __ALIGN_BEGIN static uint8_t USBD_KEYBOARD_HID_Desc[USB_HID_DESC_SIZ] __ALIGN_E 0x00, }; +#ifndef USE_USBD_COMPOSITE /* USB Standard Device Descriptor */ __ALIGN_BEGIN static uint8_t USBD_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = { USB_LEN_DEV_QUALIFIER_DESC, @@ -415,6 +428,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 = { 0x05, 0x01, /* Usage Page (Generic Desktop Ctrls) */ @@ -487,6 +501,9 @@ __ALIGN_BEGIN static uint8_t HID_KEYBOARD_ReportDesc[HID_KEYBOARD_REPORT_DESC_SI 0xC0 // End Collection }; +static uint8_t HIDMInEpAdd = HID_MOUSE_EPIN_ADDR; +static uint8_t HIDKInEpAdd = HID_KEYBOARD_EPIN_ADDR; + /** * @} */ @@ -509,33 +526,40 @@ static uint8_t USBD_HID_Init(USBD_HandleTypeDef *pdev, USBD_HID_HandleTypeDef *hhid; - hhid = (USBD_HID_HandleTypeDef *)USBD_malloc(sizeof(USBD_HID_HandleTypeDef)); + // hhid = (USBD_HID_HandleTypeDef *)USBD_malloc(sizeof(USBD_HID_HandleTypeDef)); + hhid = &_hhid; 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, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ if (pdev->dev_speed == USBD_SPEED_HIGH) { - pdev->ep_in[HID_MOUSE_EPIN_ADDR & 0xFU].bInterval = HID_HS_BINTERVAL; - pdev->ep_in[HID_KEYBOARD_EPIN_ADDR & 0xFU].bInterval = HID_HS_BINTERVAL; + pdev->ep_in[HIDMInEpAdd & 0xFU].bInterval = HID_HS_BINTERVAL; + pdev->ep_in[HIDKInEpAdd & 0xFU].bInterval = HID_HS_BINTERVAL; } else { /* LOW and FULL-speed endpoints */ - pdev->ep_in[HID_MOUSE_EPIN_ADDR & 0xFU].bInterval = HID_FS_BINTERVAL; - pdev->ep_in[HID_KEYBOARD_EPIN_ADDR & 0xFU].bInterval = HID_FS_BINTERVAL; + pdev->ep_in[HIDMInEpAdd & 0xFU].bInterval = HID_FS_BINTERVAL; + pdev->ep_in[HIDKInEpAdd & 0xFU].bInterval = HID_FS_BINTERVAL; } /* Open EP IN */ - (void)USBD_LL_OpenEP(pdev, HID_MOUSE_EPIN_ADDR, USBD_EP_TYPE_INTR, + (void)USBD_LL_OpenEP(pdev, HIDMInEpAdd, USBD_EP_TYPE_INTR, HID_MOUSE_EPIN_SIZE); - pdev->ep_in[HID_MOUSE_EPIN_ADDR & 0xFU].is_used = 1U; + pdev->ep_in[HIDMInEpAdd & 0xFU].is_used = 1U; /* Open EP IN */ - (void)USBD_LL_OpenEP(pdev, HID_KEYBOARD_EPIN_ADDR, USBD_EP_TYPE_INTR, + (void)USBD_LL_OpenEP(pdev, HIDKInEpAdd, USBD_EP_TYPE_INTR, HID_KEYBOARD_EPIN_SIZE); - pdev->ep_in[HID_KEYBOARD_EPIN_ADDR & 0xFU].is_used = 1U; + pdev->ep_in[HIDKInEpAdd & 0xFU].is_used = 1U; hhid->Mousestate = HID_IDLE; hhid->Keyboardstate = HID_IDLE; @@ -554,18 +578,24 @@ static uint8_t USBD_HID_DeInit(USBD_HandleTypeDef *pdev, { 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, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ + /* Close HID EPs */ - (void)USBD_LL_CloseEP(pdev, HID_MOUSE_EPIN_ADDR); - pdev->ep_in[HID_MOUSE_EPIN_ADDR & 0xFU].is_used = 0U; - pdev->ep_in[HID_MOUSE_EPIN_ADDR & 0xFU].bInterval = 0U; - USBD_LL_CloseEP(pdev, HID_KEYBOARD_EPIN_ADDR); - pdev->ep_in[HID_KEYBOARD_EPIN_ADDR & 0xFU].is_used = 0U; - pdev->ep_in[HID_KEYBOARD_EPIN_ADDR & 0xFU].bInterval = 0U; + (void)USBD_LL_CloseEP(pdev, HIDMInEpAdd); + pdev->ep_in[HIDMInEpAdd & 0xFU].is_used = 0U; + pdev->ep_in[HIDMInEpAdd & 0xFU].bInterval = 0U; + (void)USBD_LL_CloseEP(pdev, HIDKInEpAdd); + pdev->ep_in[HIDKInEpAdd & 0xFU].is_used = 0U; + pdev->ep_in[HIDKInEpAdd & 0xFU].bInterval = 0U; /* Free allocated memory */ - if (pdev->pClassData != NULL) { - (void)USBD_free(pdev->pClassData); - pdev->pClassData = NULL; + if (pdev->pClassDataCmsit[pdev->classId] != NULL) { + /* No need to free as hhid is no more dynamically allocated */ + // (void)USBD_free(pdev->pClassDataCmsit[pdev->classId]); + pdev->pClassDataCmsit[pdev->classId] = NULL; } return (uint8_t)USBD_OK; @@ -599,7 +629,7 @@ static uint8_t USBD_COMPOSITE_HID_Setup(USBD_HandleTypeDef *pdev, static uint8_t USBD_HID_MOUSE_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 = 0U; uint8_t *pbuf = NULL; @@ -708,7 +738,7 @@ static uint8_t USBD_HID_MOUSE_Setup(USBD_HandleTypeDef *pdev, static uint8_t USBD_HID_KEYBOARD_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]; uint16_t len = 0U; uint8_t *pbuf = NULL; uint16_t status_info = 0U; @@ -811,26 +841,42 @@ static uint8_t USBD_HID_KEYBOARD_Setup(USBD_HandleTypeDef *pdev, * Send HID Report * @param pdev: device instance * @param buff: pointer to report + * @param ClassId: The Class ID * @retval status */ +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_HID_MOUSE_SendReport(USBD_HandleTypeDef *pdev, + uint8_t *report, + uint16_t len, + uint8_t ClassId) +{ + USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)pdev->pClassDataCmsit[ClassId]; +#else uint8_t USBD_HID_MOUSE_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]; +#endif /* USE_USBD_COMPOSITE */ 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, ClassId); +#endif /* USE_USBD_COMPOSITE */ + if (pdev->dev_state == USBD_STATE_CONFIGURED) { if (hhid->Mousestate == HID_IDLE) { hhid->Mousestate = HID_BUSY; - (void)USBD_LL_Transmit(pdev, HID_MOUSE_EPIN_ADDR, report, len); + (void)USBD_LL_Transmit(pdev, HIDMInEpAdd, report, len); } else { return (uint8_t)USBD_BUSY; } } + return (uint8_t)USBD_OK; } @@ -839,27 +885,42 @@ uint8_t USBD_HID_MOUSE_SendReport(USBD_HandleTypeDef *pdev, * Send HID Report * @param pdev: device instance * @param buff: pointer to report + * @param ClassId: The Class ID * @retval status */ +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_HID_KEYBOARD_SendReport(USBD_HandleTypeDef *pdev, + uint8_t *report, + uint16_t len, + uint8_t ClassId) +{ + USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)pdev->pClassDataCmsit[ClassId]; +#else uint8_t USBD_HID_KEYBOARD_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]; +#endif /* USE_USBD_COMPOSITE */ 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, ClassId); +#endif /* USE_USBD_COMPOSITE */ if (pdev->dev_state == USBD_STATE_CONFIGURED) { if (hhid->Keyboardstate == HID_IDLE) { hhid->Keyboardstate = HID_BUSY; - (void)USBD_LL_Transmit(pdev, HID_KEYBOARD_EPIN_ADDR, report, len); + (void)USBD_LL_Transmit(pdev, HIDKInEpAdd, report, len); } else { return (uint8_t)USBD_BUSY; } } + return (uint8_t)USBD_OK; } @@ -888,6 +949,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 @@ -897,8 +959,18 @@ 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_CfgFSDesc, HID_MOUSE_EPIN_ADDR); + if (pEpDesc != NULL) { + pEpDesc->bInterval = HID_FS_BINTERVAL; + } + + pEpDesc = USBD_GetEpDesc(USBD_HID_CfgFSDesc, HID_KEYBOARD_EPIN_ADDR); + if (pEpDesc != NULL) { + pEpDesc->bInterval = HID_FS_BINTERVAL; + } + + *length = (uint16_t)sizeof(USBD_HID_CfgFSDesc); return USBD_HID_CfgFSDesc; } @@ -911,8 +983,18 @@ 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_CfgHSDesc, HID_MOUSE_EPIN_ADDR); + + if (pEpDesc != NULL) { + pEpDesc->bInterval = HID_HS_BINTERVAL; + } + pEpDesc = USBD_GetEpDesc(USBD_HID_CfgHSDesc, HID_KEYBOARD_EPIN_ADDR); + if (pEpDesc != NULL) { + pEpDesc->bInterval = HID_HS_BINTERVAL; + } + + *length = (uint16_t)sizeof(USBD_HID_CfgHSDesc); return USBD_HID_CfgHSDesc; } @@ -925,10 +1007,21 @@ 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_OtherSpeedCfgDesc, HID_MOUSE_EPIN_ADDR); + + if (pEpDesc != NULL) { + pEpDesc->bInterval = HID_FS_BINTERVAL; + } + pEpDesc = USBD_GetEpDesc(USBD_HID_OtherSpeedCfgDesc, HID_KEYBOARD_EPIN_ADDR); + + if (pEpDesc != NULL) { + pEpDesc->bInterval = HID_FS_BINTERVAL; + } + *length = (uint16_t)sizeof(USBD_HID_OtherSpeedCfgDesc); return USBD_HID_OtherSpeedCfgDesc; } +#endif /* USE_USBD_COMPOSITE */ /** * @brief USBD_HID_DataIn @@ -944,14 +1037,14 @@ static uint8_t USBD_HID_DataIn(USBD_HandleTypeDef *pdev, /* 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 */ if (epnum == (HID_KEYBOARD_EPIN_ADDR & 0x7F)) { - ((USBD_HID_HandleTypeDef *)pdev->pClassData)->Keyboardstate = HID_IDLE; + ((USBD_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId])->Keyboardstate = HID_IDLE; } else if (epnum == (HID_MOUSE_EPIN_ADDR & 0x7F)) { - ((USBD_HID_HandleTypeDef *)pdev->pClassData)->Mousestate = HID_IDLE; + ((USBD_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId])->Mousestate = HID_IDLE; } return (uint8_t)USBD_OK; } - +#ifndef USE_USBD_COMPOSITE /** * @brief DeviceQualifierDescriptor * return Device Qualifier descriptor @@ -964,6 +1057,7 @@ static uint8_t *USBD_HID_GetDeviceQualifierDesc(uint16_t *length) return USBD_HID_DeviceQualifierDesc; } +#endif /* USE_USBD_COMPOSITE */ #endif /* USBD_USE_HID_COMPOSITE */ #endif /* USBCON */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/cores/arduino/stm32/usb/hid/usbd_hid_composite.h b/cores/arduino/stm32/usb/hid/usbd_hid_composite.h index 7ff3d58657..c5d4aaab4c 100644 --- a/cores/arduino/stm32/usb/hid/usbd_hid_composite.h +++ b/cores/arduino/stm32/usb/hid/usbd_hid_composite.h @@ -92,6 +92,22 @@ typedef struct { HID_StateTypeDef Mousestate; HID_StateTypeDef Keyboardstate; } 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; + /** * @} */ @@ -119,12 +135,23 @@ extern USBD_ClassTypeDef USBD_COMPOSITE_HID; /** @defgroup USB_CORE_Exported_Functions * @{ */ +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_HID_MOUSE_SendReport(USBD_HandleTypeDef *pdev, + uint8_t *report, + uint16_t len, + uint8_t ClassId); +uint8_t USBD_HID_KEYBOARD_SendReport(USBD_HandleTypeDef *pdev, + uint8_t *report, + uint16_t len, + uint8_t ClassId); +#else uint8_t USBD_HID_MOUSE_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len); uint8_t USBD_HID_KEYBOARD_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len); +#endif /* USE_USBD_COMPOSITE */ uint32_t USBD_HID_GetPollingInterval(USBD_HandleTypeDef *pdev); diff --git a/cores/arduino/stm32/usb/hid/usbd_hid_composite_if.c b/cores/arduino/stm32/usb/hid/usbd_hid_composite_if.c index 5f716e6637..9355bbac91 100644 --- a/cores/arduino/stm32/usb/hid/usbd_hid_composite_if.c +++ b/cores/arduino/stm32/usb/hid/usbd_hid_composite_if.c @@ -23,15 +23,14 @@ #include "usbd_hid_composite_if.h" #include "usbd_hid_composite.h" -#ifdef __cplusplus -extern "C" { -#endif - /* USB Device Core HID composite handle declaration */ USBD_HandleTypeDef hUSBD_Device_HID; static bool HID_keyboard_initialized = false; static bool HID_mouse_initialized = false; +#if defined(ICACHE) && defined (HAL_ICACHE_MODULE_ENABLED) && !defined(HAL_ICACHE_MODULE_DISABLED) + static bool icache_enabled = false; +#endif /** * @brief Initialize USB devices @@ -40,6 +39,15 @@ static bool HID_mouse_initialized = false; */ void HID_Composite_Init(HID_Interface device) { +#if defined(ICACHE) && defined (HAL_ICACHE_MODULE_ENABLED) && !defined(HAL_ICACHE_MODULE_DISABLED) + if (HAL_ICACHE_IsEnabled() == 1) { + icache_enabled = true; + /* Disable instruction cache prior to internal cacheable memory update */ + if (HAL_ICACHE_Disable() != HAL_OK) { + Error_Handler(); + } + } +#endif /* ICACHE && HAL_ICACHE_MODULE_ENABLED && !HAL_ICACHE_MODULE_DISABLED */ if (IS_HID_INTERFACE(device) && !HID_keyboard_initialized && !HID_mouse_initialized) { /* Init Device Library */ @@ -76,6 +84,14 @@ void HID_Composite_DeInit(HID_Interface device) /* DeInit Device Library */ USBD_DeInit(&hUSBD_Device_HID); } +#if defined(ICACHE) && defined (HAL_ICACHE_MODULE_ENABLED) && !defined(HAL_ICACHE_MODULE_DISABLED) + if (icache_enabled) { + /* Re-enable instruction cache */ + if (HAL_ICACHE_Enable() != HAL_OK) { + Error_Handler(); + } + } +#endif /* ICACHE && HAL_ICACHE_MODULE_ENABLED && !HAL_ICACHE_MODULE_DISABLED */ if (device == HID_KEYBOARD) { HID_keyboard_initialized = false; } @@ -106,9 +122,6 @@ void HID_Composite_keyboard_sendReport(uint8_t *report, uint16_t len) USBD_HID_KEYBOARD_SendReport(&hUSBD_Device_HID, report, len); } -#ifdef __cplusplus -} -#endif #endif /* USBD_USE_HID_COMPOSITE */ #endif /* USBCON */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/cores/arduino/stm32/usb/usbd_conf.c b/cores/arduino/stm32/usb/usbd_conf.c index 4ecd5a7b6e..86571852a5 100644 --- a/cores/arduino/stm32/usb/usbd_conf.c +++ b/cores/arduino/stm32/usb/usbd_conf.c @@ -57,16 +57,18 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) pinMode(PIN_UCPD_TCPP, OUTPUT_OPEN_DRAIN); digitalWriteFast(digitalPinToPinName(PIN_UCPD_TCPP), LOW); #endif - +#if defined(PWR_CR3_USB33DEN) || defined(PWR_USBSCR_USB33DEN) + HAL_PWREx_EnableUSBVoltageDetector(); +#endif +#if defined(PWR_CR3_USB33RDY) + while (!LL_PWR_IsActiveFlag_USB()); +#elif defined(PWR_VMSR_USB33RDY) + while (!LL_PWR_IsActiveFlag_VDDUSB()); +#endif #if defined(PWR_CR2_USV) || defined(PWR_SVMCR_USV) || defined(PWR_USBSCR_USB33SV) - /* Enable VDDUSB on Pwrctrl CR2 register*/ + /* Enable VDDUSB */ HAL_PWREx_EnableVddUSB(); #endif -#ifdef STM32H7xx - if (!LL_PWR_IsActiveFlag_USB()) { - HAL_PWREx_EnableUSBVoltageDetector(); - } -#endif #if defined (USB) if (hpcd->Instance == USB) { @@ -647,7 +649,8 @@ uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) * @param dev_addr: Endpoint Number * @retval USBD Status */ -USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr) +USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, + uint8_t dev_addr) { HAL_PCD_SetAddress(pdev->pData, dev_addr); return USBD_OK; @@ -661,10 +664,8 @@ USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_a * @param size: Data size * @retval USBD Status */ -USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, - uint8_t ep_addr, - uint8_t *pbuf, - uint32_t size) +USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr, + uint8_t *pbuf, uint32_t size) { HAL_PCD_EP_Transmit(pdev->pData, ep_addr, pbuf, size); return USBD_OK; @@ -679,8 +680,7 @@ USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, * @retval USBD Status */ USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, - uint8_t ep_addr, - uint8_t *pbuf, + uint8_t ep_addr, uint8_t *pbuf, uint32_t size) { HAL_PCD_EP_Receive(pdev->pData, ep_addr, pbuf, size); diff --git a/cores/arduino/stm32/usb/usbd_conf.h b/cores/arduino/stm32/usb/usbd_conf.h index 4584330667..03578c3c14 100644 --- a/cores/arduino/stm32/usb/usbd_conf.h +++ b/cores/arduino/stm32/usb/usbd_conf.h @@ -198,7 +198,7 @@ extern "C" { #ifndef UVC_MATRIX_COEFFICIENTS #define UVC_MATRIX_COEFFICIENTS 0x04U #endif /* UVC_MATRIX_COEFFICIENTS */ -#endif +#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */ /* Video Stream frame width and height */ #ifndef UVC_WIDTH @@ -282,7 +282,7 @@ extern "C" { } while (0) #else #define USBD_UsrLog(...) do {} while (0) -#endif +#endif /* (USBD_DEBUG_LEVEL > 0U) */ #if (USBD_DEBUG_LEVEL > 1U) @@ -293,7 +293,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 { \ @@ -303,7 +303,7 @@ extern "C" { } while (0) #else #define USBD_DbgLog(...) do {} while (0) -#endif +#endif /* (USBD_DEBUG_LEVEL > 2U) */ /* Exported functions -------------------------------------------------------*/ void *USBD_static_malloc(uint32_t size); diff --git a/cores/arduino/stm32/usb/usbd_desc.c b/cores/arduino/stm32/usb/usbd_desc.c index 6474dba238..651bb9cfd7 100644 --- a/cores/arduino/stm32/usb/usbd_desc.c +++ b/cores/arduino/stm32/usb/usbd_desc.c @@ -110,7 +110,7 @@ uint8_t *USBD_Class_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *le #endif /* USB_CLASS_USER_STRING_DESC */ #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 USBD_Desc = { USBD_Class_DeviceDescriptor, @@ -122,11 +122,11 @@ USBD_DescriptorsTypeDef USBD_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) */ }; #ifdef USBD_USE_HID_COMPOSITE @@ -139,7 +139,7 @@ __ALIGN_BEGIN uint8_t USBD_Class_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 */ @@ -149,8 +149,8 @@ __ALIGN_BEGIN uint8_t USBD_Class_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = { HIBYTE(USBD_VID), /* idVendor */ LOBYTE(USBD_PID), /* idProduct */ HIBYTE(USBD_PID), /* idProduct */ - 0x00, /* bcdDevice rel. 0.00 */ - 0x00, + 0x00, /* bcdDevice rel. 2.00 */ + 0x02, USBD_IDX_MFC_STR, /* Index of manufacturer string */ USBD_IDX_PRODUCT_STR, /* Index of product string */ USBD_IDX_SERIAL_STR, /* Index of serial number string */ @@ -178,8 +178,8 @@ __ALIGN_BEGIN uint8_t USBD_Class_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = { HIBYTE(USBD_VID), /* idVendor */ LOBYTE(USBD_PID), /* idProduct */ HIBYTE(USBD_PID), /* idProduct */ - 0x00, /* bcdDevice rel. 0.00 */ - 0x00, + 0x00, /* bcdDevice rel. 2.00 */ + 0x02, USBD_IDX_MFC_STR, /* Index of manufacturer string */ USBD_IDX_PRODUCT_STR, /* Index of product string */ USBD_IDX_SERIAL_STR, /* Index of serial number string */ @@ -204,7 +204,7 @@ __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) @@ -229,14 +229,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 */ @@ -271,7 +273,7 @@ __ALIGN_BEGIN uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = { 0 first Mode entry 1 second Mode entry */ - USBD_BB_ALTMODE1_STRING_INDEX, /* iAlternateModeString[1]: Index of string descriptor describing protocol. + USBD_BB_ALTMODE1_STRING_INDEX, /* iAlternateModeString[1]: Index of string descriptor describing protocol. It is optional to support this string. */ /* Alternate Mode Desc */ /* ----------- Device Capability Descriptor: BillBoard Alternate Mode Desc ---------- */ @@ -279,18 +281,21 @@ __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 */ -__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = { +__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = { USB_LEN_LANGID_STR_DESC, USB_DESC_TYPE_STRING, LOBYTE(USBD_LANGID_STRING), @@ -372,6 +377,7 @@ uint8_t *USBD_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *lengt uint8_t *USBD_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) { UNUSED(speed); + *length = USB_SIZ_STRING_SERIAL; /* Update the serial number string descriptor with the data from the unique ID*/ @@ -419,7 +425,9 @@ uint8_t *USBD_Class_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *le */ static void Get_SerialNum(void) { - uint32_t deviceserial0, deviceserial1, deviceserial2; + uint32_t deviceserial0; + uint32_t deviceserial1; + uint32_t deviceserial2; deviceserial0 = *(uint32_t *)DEVICE_ID1; deviceserial1 = *(uint32_t *)DEVICE_ID2; @@ -448,7 +456,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) @@ -467,7 +475,7 @@ uint8_t *USBD_Class_UserStrDescriptor(USBD_SpeedTypeDef speed, uint8_t idx, uint UNUSED(length); return USBD_StrDesc; } -#endif +#endif /* USBD_CLASS_USER_STRING_DESC */ /** diff --git a/cores/arduino/stm32/usb/usbd_desc.h b/cores/arduino/stm32/usb/usbd_desc.h index bb757e939a..aa832b2772 100644 --- a/cores/arduino/stm32/usb/usbd_desc.h +++ b/cores/arduino/stm32/usb/usbd_desc.h @@ -44,7 +44,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 @@ -52,7 +52,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/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Inc/usbd_audio.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Inc/usbd_audio.h index dbb71cd7ad..a082d19046 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Inc/usbd_audio.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Inc/usbd_audio.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -58,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 @@ -167,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; + /** * @} */ @@ -198,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 */ + /** * @} */ @@ -214,5 +330,3 @@ void USBD_AUDIO_Sync(USBD_HandleTypeDef *pdev, AUDIO_OffsetTypeDef offset); /** * @} */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Inc/usbd_audio_if_template.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Inc/usbd_audio_if_template.h index 21cee0d720..02aa1b6445 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Inc/usbd_audio_if_template.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Inc/usbd_audio_if_template.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -41,5 +40,3 @@ extern USBD_AUDIO_ItfTypeDef USBD_AUDIO_Template_fops; #endif #endif /* __USBD_AUDIO_IF_TEMPLATE_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Src/usbd_audio.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Src/usbd_audio.c index acaaf053c0..a0a094163f 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Src/usbd_audio.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Src/usbd_audio.c @@ -4,6 +4,18 @@ * @author MCD Application Team * @brief This file provides the Audio core functions. * + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2015 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 * * =================================================================== @@ -38,18 +50,6 @@ * * * @endverbatim - * - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * ****************************************************************************** */ @@ -93,11 +93,15 @@ EndBSPDependencies */ /** @defgroup USBD_AUDIO_Private_Macros * @{ */ -#define AUDIO_SAMPLE_FREQ(frq) (uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16)) +#define AUDIO_SAMPLE_FREQ(frq) \ + (uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16)) -#define AUDIO_PACKET_SZE(frq) (uint8_t)(((frq * 2U * 2U)/1000U) & 0xFFU), \ - (uint8_t)((((frq * 2U * 2U)/1000U) >> 8) & 0xFFU) +#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 */ /** * @} */ @@ -111,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); @@ -124,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); /** * @} @@ -145,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 = { @@ -166,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*/ @@ -317,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; /** * @} */ @@ -343,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, (uint8_t)pdev->classId); +#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; @@ -369,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; @@ -394,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, (uint8_t)pdev->classId); +#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; } @@ -426,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) { @@ -471,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; @@ -529,11 +564,10 @@ static uint8_t USBD_AUDIO_Setup(USBD_HandleTypeDef *pdev, return (uint8_t)ret; } - +#ifndef USE_USBD_COMPOSITE /** * @brief USBD_AUDIO_GetCfgDesc * return configuration descriptor - * @param speed : current device speed * @param length : pointer data length * @retval pointer to descriptor buffer */ @@ -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; } @@ -620,6 +654,7 @@ static uint8_t USBD_AUDIO_SOF(USBD_HandleTypeDef *pdev) * @brief USBD_AUDIO_SOF * handle SOF event * @param pdev: device instance + * @param offset: audio offset * @retval status */ void USBD_AUDIO_Sync(USBD_HandleTypeDef *pdev, AUDIO_OffsetTypeDef offset) @@ -627,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; @@ -678,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; } } @@ -724,35 +759,40 @@ 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, (uint8_t)pdev->classId); +#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; - if (haudio->wr_ptr == AUDIO_TOTAL_BUF_SIZE) + if (haudio->wr_ptr >= AUDIO_TOTAL_BUF_SIZE) { /* All buffers are full: roll back */ haudio->wr_ptr = 0U; 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; } } @@ -766,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); } @@ -777,14 +817,14 @@ static uint8_t USBD_AUDIO_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) /** * @brief AUDIO_Req_GetCurrent * Handles the GET_CUR Audio control request. - * @param pdev: instance + * @param pdev: device instance * @param req: setup class request * @retval status */ 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) { @@ -801,14 +841,14 @@ static void AUDIO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef /** * @brief AUDIO_Req_SetCurrent * Handles the SET_CUR Audio control request. - * @param pdev: instance + * @param pdev: device instance * @param req: setup class request * @retval status */ 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) { @@ -826,7 +866,7 @@ static void AUDIO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef } } - +#ifndef USE_USBD_COMPOSITE /** * @brief DeviceQualifierDescriptor * return Device Qualifier descriptor @@ -839,9 +879,10 @@ 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 * @param fops: Audio interface callback * @retval status */ @@ -853,14 +894,65 @@ 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; +} /** * @} @@ -871,4 +963,7 @@ uint8_t USBD_AUDIO_RegisterInterface(USBD_HandleTypeDef *pdev, * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + +/** + * @} + */ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Src/usbd_audio_if_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Src/usbd_audio_if_template.c index 7c97c751ca..c9db989fc3 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Src/usbd_audio_if_template.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Src/usbd_audio_if_template.c @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -197,5 +196,3 @@ static int8_t TEMPLATE_GetState(void) * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/BillBoard/Inc/usbd_billboard.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/BillBoard/Inc/usbd_billboard.h index 8bff7b3550..8045140417 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/BillBoard/Inc/usbd_billboard.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/BillBoard/Inc/usbd_billboard.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2019 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -141,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) */ /** * @} @@ -159,5 +158,3 @@ void *USBD_BB_GetAltModeDesc(USBD_HandleTypeDef *pdev, uint8_t *buf, uint8_t idx /** * @} */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/BillBoard/Src/usbd_billboard.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/BillBoard/Src/usbd_billboard.c index e0bacaa047..f86c003bd2 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/BillBoard/Src/usbd_billboard.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/BillBoard/Src/usbd_billboard.c @@ -7,6 +7,17 @@ * - Initialization and Configuration of high and low layer * - Enumeration as BillBoard Device * - Error management + ****************************************************************************** + * @attention + * + * Copyright (c) 2019 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 * * =================================================================== @@ -23,17 +34,6 @@ * @endverbatim * ****************************************************************************** - * @attention - * - *

© Copyright (c) 2019 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ @@ -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 */ /** * @} @@ -500,5 +500,3 @@ void *USBD_BB_GetAltModeDesc(USBD_HandleTypeDef *pdev, uint8_t *pBosDesc, uint8_ /** * @} */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Inc/usbd_ccid.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Inc/usbd_ccid.h new file mode 100644 index 0000000000..d3b96a536a --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Inc/usbd_ccid.h @@ -0,0 +1,373 @@ +/** + ****************************************************************************** + * @file usbd_ccid.h + * @author MCD Application Team + * @brief header file for the usbd_ccid.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_CCID_H +#define __USBD_CCID_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup usbd_cdc + * @brief This file is the Header file for usbd_ccid.c + * @{ + */ + + +/** @defgroup usbd_cdc_Exported_Defines + * @{ + */ +#ifndef CCID_IN_EP +#define CCID_IN_EP 0x81U /* EP1 for data IN */ +#endif /* CCID_IN_EP */ + +#ifndef CCID_OUT_EP +#define CCID_OUT_EP 0x01U /* EP1 for data OUT */ +#endif /* CCID_OUT_EP */ + +#ifndef CCID_CMD_EP +#define CCID_CMD_EP 0x82U /* EP2 for CCID commands */ +#endif /* CCID_CMD_EP */ + +#ifndef CCID_CMD_HS_BINTERVAL +#define CCID_CMD_HS_BINTERVAL 0x10U +#endif /* CCID_CMD_HS_BINTERVAL */ + +#ifndef CCID_CMD_FS_BINTERVAL +#define CCID_CMD_FS_BINTERVAL 0x10U +#endif /* CCID_CMD_FS_BINTERVAL */ + + +#define CCID_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */ +#define CCID_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */ +#define CCID_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */ + +#define USB_CCID_CONFIG_DESC_SIZ 93U +#define CCID_DATA_HS_IN_PACKET_SIZE CCID_DATA_HS_MAX_PACKET_SIZE +#define CCID_DATA_HS_OUT_PACKET_SIZE CCID_DATA_HS_MAX_PACKET_SIZE + +#define CCID_DATA_FS_IN_PACKET_SIZE CCID_DATA_FS_MAX_PACKET_SIZE +#define CCID_DATA_FS_OUT_PACKET_SIZE CCID_DATA_FS_MAX_PACKET_SIZE + +/*---------------------------------------------------------------------*/ +/* CCID definitions */ +/*---------------------------------------------------------------------*/ +#define CCID_SEND_ENCAPSULATED_COMMAND 0x00U +#define CCID_GET_ENCAPSULATED_RESPONSE 0x01U +#define CCID_SET_COMM_FEATURE 0x02U +#define CCID_GET_COMM_FEATURE 0x03U +#define CCID_CLEAR_COMM_FEATURE 0x04U +#define CCID_SET_LINE_CODING 0x20U +#define CCID_GET_LINE_CODING 0x21U +#define CCID_SET_CONTROL_LINE_STATE 0x22U +#define CCID_SEND_BREAK 0x23U + +/*---------------------------------------------------------------------*/ +#define REQUEST_ABORT 0x01U +#define REQUEST_GET_CLOCK_FREQUENCIES 0x02U +#define REQUEST_GET_DATA_RATES 0x03U + +/*---------------------------------------------------------------------*/ +/* The Smart Card Device Class Descriptor definitions */ +/*---------------------------------------------------------------------*/ + +#define CCID_INTERFACE_DESC_SIZE 0x09U +#define USB_DEVICE_CLASS_CCID 0x0BU +#define CCID_CLASS_DESC_SIZE 0x36U +#define CCID_DESC_TYPE 0x21U + +#ifndef CCID_VOLTAGE_SUPP +#define CCID_VOLTAGE_SUPP 0x07U +#endif /* CCID_VOLTAGE_SUPP */ +#ifndef USBD_CCID_PROTOCOL +#define USBD_CCID_PROTOCOL 0x03U +#endif /* USBD_CCID_PROTOCOL */ +#ifndef USBD_CCID_DEFAULT_CLOCK_FREQ +#define USBD_CCID_DEFAULT_CLOCK_FREQ 3600U +#endif /* USBD_CCID_DEFAULT_CLOCK_FREQ */ +#ifndef USBD_CCID_MAX_CLOCK_FREQ +#define USBD_CCID_MAX_CLOCK_FREQ USBD_CCID_DEFAULT_CLOCK_FREQ +#endif /* USBD_CCID_MAX_CLOCK_FREQ */ +#ifndef USBD_CCID_DEFAULT_DATA_RATE +#define USBD_CCID_DEFAULT_DATA_RATE 9677U +#endif /* USBD_CCID_DEFAULT_DATA_RATE */ +#ifndef USBD_CCID_MAX_DATA_RATE +#define USBD_CCID_MAX_DATA_RATE USBD_CCID_DEFAULT_DATA_RATE +#endif /* USBD_CCID_MAX_DATA_RATE */ +#ifndef USBD_CCID_MAX_INF_FIELD_SIZE +#define USBD_CCID_MAX_INF_FIELD_SIZE 254U +#endif /* USBD_CCID_MAX_INF_FIELD_SIZE */ +#ifndef CCID_MAX_BLOCK_SIZE_HEADER +#define CCID_MAX_BLOCK_SIZE_HEADER 271U +#endif /* CCID_MAX_BLOCK_SIZE_HEADER */ + +#define TPDU_EXCHANGE 0x01U +#define SHORT_APDU_EXCHANGE 0x02U +#define EXTENDED_APDU_EXCHANGE 0x04U +#define CHARACTER_EXCHANGE 0x00U + +#ifndef EXCHANGE_LEVEL_FEATURE +#define EXCHANGE_LEVEL_FEATURE TPDU_EXCHANGE +#endif /* EXCHANGE_LEVEL_FEATURE */ + +#define CCID_ENDPOINT_DESC_SIZE 0x07U + +#ifndef CCID_EP0_BUFF_SIZ +#define CCID_EP0_BUFF_SIZ 64U +#endif /* CCID_EP0_BUFF_SIZ */ + +#ifndef CCID_BULK_EPIN_SIZE +#define CCID_BULK_EPIN_SIZE 64U +#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 +#define PC_TO_RDR_ICCPOWEROFF 0x63U +#define PC_TO_RDR_GETSLOTSTATUS 0x65U +#define PC_TO_RDR_XFRBLOCK 0x6FU +#define PC_TO_RDR_GETPARAMETERS 0x6CU +#define PC_TO_RDR_RESETPARAMETERS 0x6DU +#define PC_TO_RDR_SETPARAMETERS 0x61U +#define PC_TO_RDR_ESCAPE 0x6BU +#define PC_TO_RDR_ICCCLOCK 0x6EU +#define PC_TO_RDR_T0APDU 0x6AU +#define PC_TO_RDR_SECURE 0x69U +#define PC_TO_RDR_MECHANICAL 0x71U +#define PC_TO_RDR_ABORT 0x72U +#define PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY 0x73U + +/* CCID Bulk In Command definitions */ +#define RDR_TO_PC_DATABLOCK 0x80U +#define RDR_TO_PC_SLOTSTATUS 0x81U +#define RDR_TO_PC_PARAMETERS 0x82U +#define RDR_TO_PC_ESCAPE 0x83U +#define RDR_TO_PC_DATARATEANDCLOCKFREQUENCY 0x84U + +/* CCID Interrupt In Command definitions */ +#define RDR_TO_PC_NOTIFYSLOTCHANGE 0x50U +#define RDR_TO_PC_HARDWAREERROR 0x51U + +/* Bulk-only Command Block Wrapper */ +#define ABDATA_SIZE 261U +#define CCID_CMD_HEADER_SIZE 10U +#define CCID_RESPONSE_HEADER_SIZE 10U + +/* Number of SLOTS. For single card, this value is 1 */ +#define CCID_NUMBER_OF_SLOTS 1U + +#define CARD_SLOT_FITTED 1U +#define CARD_SLOT_REMOVED 0U + +#define OFFSET_INT_BMESSAGETYPE 0x00U +#define OFFSET_INT_BMSLOTICCSTATE 0x01U +#define SLOT_ICC_PRESENT 0x01U +/* LSb : (0b = no ICC present, 1b = ICC present) */ +#define SLOT_ICC_CHANGE 0x02U +/* MSb : (0b = no change, 1b = change) */ + + +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +typedef struct +{ + uint32_t bitrate; + uint8_t format; + uint8_t paritytype; + uint8_t datatype; +} USBD_CCID_LineCodingTypeDef; + +typedef struct +{ + uint8_t bMessageType; /* Offset = 0*/ + uint32_t dwLength; /* Offset = 1, The length field (dwLength) is the length + of the message not including the 10-byte header.*/ + uint8_t bSlot; /* Offset = 5*/ + uint8_t bSeq; /* Offset = 6*/ + uint8_t bSpecific_0; /* Offset = 7*/ + uint8_t bSpecific_1; /* Offset = 8*/ + uint8_t bSpecific_2; /* Offset = 9*/ + uint8_t abData [ABDATA_SIZE]; /* Offset = 10, For reference, the absolute + maximum block size for a TPDU T=0 block is 260 bytes + (5 bytes command; 255 bytes data), + 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.*/ +} __PACKED USBD_CCID_BulkOut_DataTypeDef; + +typedef struct +{ + uint8_t bMessageType; /* Offset = 0 */ + uint32_t dwLength; /* Offset = 1 */ + uint8_t bSlot; /* Offset = 5, Same as Bulk-OUT message */ + uint8_t bSeq; /* Offset = 6, Same as Bulk-OUT message */ + uint8_t bStatus; /* Offset = 7, Slot status as defined in section 6.2.6 */ + uint8_t bError; /* Offset = 8, Slot error as defined in section 6.2.6 */ + uint8_t bSpecific; /* Offset = 9 */ + uint8_t abData[ABDATA_SIZE]; /* Offset = 10 */ + uint16_t u16SizeToSend; +} __PACKED USBD_CCID_BulkIn_DataTypeDef; + +typedef struct +{ + __IO uint8_t SlotStatus; + __IO uint8_t SlotStatusChange; +} USBD_CCID_SlotStatusTypeDef; + + +typedef struct +{ + __IO uint8_t bAbortRequestFlag; + __IO uint8_t bSeq; + __IO uint8_t bSlot; +} USBD_CCID_ParamTypeDef; + +/* + * CCID Class specification revision 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 +{ + uint8_t data[CCID_DATA_HS_MAX_PACKET_SIZE / 4U]; /* Force 32-bit alignment */ + uint32_t UsbMessageLength; + uint8_t UsbIntData[CCID_CMD_PACKET_SIZE]; /* Buffer for the Interrupt In Data */ + uint32_t alt_setting; + + USBD_CCID_BulkIn_DataTypeDef UsbBlkInData; /* Buffer for the Out Data */ + USBD_CCID_BulkOut_DataTypeDef UsbBlkOutData; /* Buffer for the In Data */ + USBD_CCID_SlotStatusTypeDef SlotStatus; + USBD_CCID_ParamTypeDef USBD_CCID_Param; + + __IO uint32_t MaxPcktLen; + __IO uint8_t blkt_state; /* Bulk transfer state */ + + uint16_t slot_nb; + uint16_t seq_nb; +} USBD_CCID_HandleTypeDef; + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ + +extern USBD_ClassTypeDef USBD_CCID; +#define USBD_CCID_CLASS &USBD_CCID +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ +typedef struct _USBD_CCID_Itf +{ + uint8_t (* Init)(USBD_HandleTypeDef *pdev); + uint8_t (* DeInit)(USBD_HandleTypeDef *pdev); + uint8_t (* Control)(uint8_t req, uint8_t *pbuf, uint16_t *length); + uint8_t (* Response_SendData)(USBD_HandleTypeDef *pdev, uint8_t *buf, uint16_t len); + uint8_t (* Send_Process)(uint8_t *Command, uint8_t *Data); + uint8_t (* SetSlotStatus)(USBD_HandleTypeDef *pdev); +} USBD_CCID_ItfTypeDef; + +/** + * @} + */ +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ +uint8_t USBD_CCID_RegisterInterface(USBD_HandleTypeDef *pdev, + USBD_CCID_ItfTypeDef *fops); + +uint8_t USBD_CCID_IntMessage(USBD_HandleTypeDef *pdev); + + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_CCID_H */ +/** + * @} + */ + +/** + * @} + */ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Inc/usbd_ccid_cmd.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Inc/usbd_ccid_cmd.h new file mode 100644 index 0000000000..91e2720760 --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Inc/usbd_ccid_cmd.h @@ -0,0 +1,222 @@ +/** + ****************************************************************************** + * @file usbd_ccid_cmd.h + * @author MCD Application Team + * @brief header file for the usbd_ccid_cmd.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_CCID_CMD_H +#define __USBD_CCID_CMD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#ifndef __USBD_CCID_IF_H +#include "usbd_ccid_if_template.h" +#endif /* __USBD_CCID_IF_H */ + +#ifndef __USBD_CCID_SC_IF_H +#include "usbd_ccid_sc_if_template.h" +#endif /* __USBD_CCID_SC_IF_H */ + + +/* Exported types ------------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ + +/******************************************************************************/ +/* ERROR CODES for USB Bulk In Messages : bError */ +/******************************************************************************/ + +#define SLOT_NO_ERROR 0x81U +#define SLOTERROR_UNKNOWN 0x82U +/*----------------------------------------------------------------------------*/ + +/* Index of not supported / incorrect message parameter : 7Fh to 01h */ +/* These Values are used for Return Types between Firmware Layers */ +/* + Failure of a command + The CCID cannot parse one parameter or the ICC is not supporting one parameter. + Then the Slot Error register contains the index of the first bad parameter as a + 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 revision 1.1 + */ + +/* Following Parameters used in PC_to_RDR_XfrBlock */ +#define SLOTERROR_BAD_LENTGH 0x01U +#define SLOTERROR_BAD_SLOT 0x05U +#define SLOTERROR_BAD_POWERSELECT 0x07U +#define SLOTERROR_BAD_PROTOCOLNUM 0x07U +#define SLOTERROR_BAD_CLOCKCOMMAND 0x07U +#define SLOTERROR_BAD_ABRFU_3B 0x07U +#define SLOTERROR_BAD_BMCHANGES 0x07U +#define SLOTERROR_BAD_BFUNCTION_MECHANICAL 0x07U +#define SLOTERROR_BAD_ABRFU_2B 0x08U +#define SLOTERROR_BAD_LEVELPARAMETER 0x08U +#define SLOTERROR_BAD_FIDI 0x0AU +#define SLOTERROR_BAD_T01CONVCHECKSUM 0x0BU +#define SLOTERROR_BAD_GUARDTIME 0x0CU +#define SLOTERROR_BAD_WAITINGINTEGER 0x0DU +#define SLOTERROR_BAD_CLOCKSTOP 0x0EU +#define SLOTERROR_BAD_IFSC 0x0FU +#define SLOTERROR_BAD_NAD 0x10U +#define SLOTERROR_BAD_DWLENGTH 0x08U + + +/*---------- Table 6.2-2 Slot error register when bmCommandStatus = 1 */ +#define SLOTERROR_CMD_ABORTED 0xFFU +#define SLOTERROR_ICC_MUTE 0xFEU +#define SLOTERROR_XFR_PARITY_ERROR 0xFDU +#define SLOTERROR_XFR_OVERRUN 0xFCU +#define SLOTERROR_HW_ERROR 0xFBU +#define SLOTERROR_BAD_ATR_TS 0xF8U +#define SLOTERROR_BAD_ATR_TCK 0xF7U +#define SLOTERROR_ICC_PROTOCOL_NOT_SUPPORTED 0xF6U +#define SLOTERROR_ICC_CLASS_NOT_SUPPORTED 0xF5U +#define SLOTERROR_PROCEDURE_BYTE_CONFLICT 0xF4U +#define SLOTERROR_DEACTIVATED_PROTOCOL 0xF3U +#define SLOTERROR_BUSY_WITH_AUTO_SEQUENCE 0xF2U +#define SLOTERROR_PIN_TIMEOUT 0xF0U +#define SLOTERROR_PIN_CANCELLED 0xEFU +#define SLOTERROR_CMD_SLOT_BUSY 0xE0U +#define SLOTERROR_CMD_NOT_SUPPORTED 0x00U + +/* Following Parameters used in PC_to_RDR_ResetParameters */ +/* DEFAULT_FIDI_VALUE */ +#ifndef DEFAULT_FIDI +#define DEFAULT_FIDI 0x11U +#endif /* DEFAULT_FIDI */ +#ifndef DEFAULT_T01CONVCHECKSUM +#define DEFAULT_T01CONVCHECKSUM 0x00U +#endif /* DEFAULT_T01CONVCHECKSUM */ +#ifndef DEFAULT_EXTRA_GUARDTIME +#define DEFAULT_EXTRA_GUARDTIME 0x00U +#endif /* DEFAULT_EXTRA_GUARDTIME */ +#ifndef DEFAULT_WAITINGINTEGER +#define DEFAULT_WAITINGINTEGER 0x0AU +#endif /* DEFAULT_WAITINGINTEGER */ +#ifndef DEFAULT_CLOCKSTOP +#define DEFAULT_CLOCKSTOP 0x00U +#endif /* DEFAULT_CLOCKSTOP */ +#ifndef DEFAULT_IFSC +#define DEFAULT_IFSC 0x20U +#endif /* DEFAULT_IFSC */ +#ifndef DEFAULT_NAD +#define DEFAULT_NAD 0x00U +#endif /* DEFAULT_NAD */ + +/* Following Parameters used in PC_to_RDR_IccPowerOn */ +#define VOLTAGE_SELECTION_AUTOMATIC 0xFFU +#define VOLTAGE_SELECTION_3V 0x02U +#define VOLTAGE_SELECTION_5V 0x01U +#define VOLTAGE_SELECTION_1V8 0x03U + +/* +Offset=0 bmICCStatus 2 bit 0, 1, 2 + 0 - An ICC is present and active (power is on and stable, RST is inactive) + 1 - An ICC is present and inactive (not activated or shut down by hardware error) + 2 - No ICC is present + 3 - RFU +Offset=0 bmRFU 4 bits 0 RFU +Offset=6 bmCommandStatus 2 bits 0, 1, 2 + 0 - Processed without error + 1 - Failed (error code provided by the error register) + 2 - Time Extension is requested + 3 - RFU + */ + +#define BM_ICC_PRESENT_ACTIVE 0x00U +#define BM_ICC_PRESENT_INACTIVE 0x01U +#define BM_ICC_NO_ICC_PRESENT 0x02U + +#define BM_COMMAND_STATUS_OFFSET 0x06U +#define BM_COMMAND_STATUS_NO_ERROR 0x00U +#define BM_COMMAND_STATUS_FAILED (0x01U << BM_COMMAND_STATUS_OFFSET) +#define BM_COMMAND_STATUS_TIME_EXTN (0x02 << BM_COMMAND_STATUS_OFFSET) + + +#if (ATR_T01 == 0) +#define SIZE_OF_ATR 19U +#else +#define SIZE_OF_ATR 15U +#endif /* (ATR_T01 == 0) */ + +/* defines for the CCID_CMD Layers */ +#define LEN_PROTOCOL_STRUCT_T0 5U +#define LEN_PROTOCOL_STRUCT_T1 7U + +#define BPROTOCOL_NUM_T0 0U +#define BPROTOCOL_NUM_T1 1U + +/************************************************************************************/ +/* ERROR CODES for RDR_TO_PC_HARDWAREERROR Message : bHardwareErrorCode */ +/************************************************************************************/ + +#define HARDWAREERRORCODE_OVERCURRENT 0x01U +#define HARDWAREERRORCODE_VOLTAGEERROR 0x02U +#define HARDWAREERRORCODE_OVERCURRENT_IT 0x04U +#define HARDWAREERRORCODE_VOLTAGEERROR_IT 0x08U + + + +#define CHK_PARAM_SLOT 0x01U +#define CHK_PARAM_DWLENGTH 0x02U +#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 + + +/* Exported functions ------------------------------------------------------- */ +uint8_t PC_to_RDR_IccPowerOn(USBD_HandleTypeDef *pdev); +uint8_t PC_to_RDR_IccPowerOff(USBD_HandleTypeDef *pdev); +uint8_t PC_to_RDR_GetSlotStatus(USBD_HandleTypeDef *pdev); +uint8_t PC_to_RDR_XfrBlock(USBD_HandleTypeDef *pdev); +uint8_t PC_to_RDR_GetParameters(USBD_HandleTypeDef *pdev); +uint8_t PC_to_RDR_ResetParameters(USBD_HandleTypeDef *pdev); +uint8_t PC_to_RDR_SetParameters(USBD_HandleTypeDef *pdev); +uint8_t PC_to_RDR_Escape(USBD_HandleTypeDef *pdev); +uint8_t PC_to_RDR_IccClock(USBD_HandleTypeDef *pdev); +uint8_t PC_to_RDR_Abort(USBD_HandleTypeDef *pdev); +uint8_t PC_TO_RDR_T0Apdu(USBD_HandleTypeDef *pdev); +uint8_t PC_TO_RDR_Mechanical(USBD_HandleTypeDef *pdev); +uint8_t PC_TO_RDR_SetDataRateAndClockFrequency(USBD_HandleTypeDef *pdev); +uint8_t PC_TO_RDR_Secure(USBD_HandleTypeDef *pdev); + +void RDR_to_PC_DataBlock(uint8_t errorCode, USBD_HandleTypeDef *pdev); +void RDR_to_PC_NotifySlotChange(USBD_HandleTypeDef *pdev); +void RDR_to_PC_SlotStatus(uint8_t errorCode, USBD_HandleTypeDef *pdev); +void RDR_to_PC_Parameters(uint8_t errorCode, USBD_HandleTypeDef *pdev); +void RDR_to_PC_Escape(uint8_t errorCode, USBD_HandleTypeDef *pdev); +void RDR_to_PC_DataRateAndClockFrequency(uint8_t errorCode, USBD_HandleTypeDef *pdev); + +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(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); + + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_CCID_CMD_H */ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Inc/usbd_ccid_if_template.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Inc/usbd_ccid_if_template.h new file mode 100644 index 0000000000..af75689644 --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Inc/usbd_ccid_if_template.h @@ -0,0 +1,76 @@ +/** + ****************************************************************************** + * @file usbd_ccid_if_template.h + * @author MCD Application Team + * @brief header file for the usbd_ccid_if_template.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_CCID_IF_TEMPLATE_H +#define __USBD_CCID_IF_TEMPLATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ccid.h" +#include "usbd_ccid_cmd.h" + +#ifndef __USBD_CCID_SMARTCARD_H +#include "usbd_ccid_smartcard_template.h" +#endif /* __USBD_CCID_SMARTCARD_H */ + +/* Exported defines ----------------------------------------------------------*/ + +/*****************************************************************************/ +/*********************** CCID Bulk Transfer State machine ********************/ +/*****************************************************************************/ +#define CCID_STATE_IDLE 0U +#define CCID_STATE_DATA_OUT 1U +#define CCID_STATE_RECEIVE_DATA 2U +#define CCID_STATE_SEND_RESP 3U +#define CCID_STATE_DATAIN 4U +#define CCID_STATE_UNCORRECT_LENGTH 5U + +#define DIR_IN 0U +#define DIR_OUT 1U +#define BOTH_DIR 2U + +/************ Value of the Interrupt transfer status to set ******************/ +#define INTRSTATUS_COMPLETE 1U +#define INTRSTATUS_RESET 0U +/************** slot change status *******************************************/ +#define SLOTSTATUS_CHANGED 1U +#define SLOTSTATUS_RESET 0U + +/* Exported types ------------------------------------------------------------*/ +extern USBD_HandleTypeDef USBD_Device; + +/* CCID Interface callback */ +extern USBD_CCID_ItfTypeDef USBD_CCID_If_fops; + +/* Exported macros -----------------------------------------------------------*/ +/* Exported variables --------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_CCID_IF_TEMPLATE_H */ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Inc/usbd_ccid_sc_if_template.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Inc/usbd_ccid_sc_if_template.h new file mode 100644 index 0000000000..0072f8be65 --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Inc/usbd_ccid_sc_if_template.h @@ -0,0 +1,100 @@ +/** + ****************************************************************************** + * @file usbd_ccid_sc_if_template.h + * @author MCD Application Team + * @brief header file for the usbd_ccid_sc_if_template.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_CCID_SC_IF_TEMPLATE_H +#define __USBD_CCID_SC_IF_TEMPLATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ccid.h" +#include "usbd_ccid_cmd.h" + +#ifndef __USBD_CCID_SMARTCARD_H +#include "usbd_ccid_smartcard_template.h" +#endif /* __USBD_CCID_SMARTCARD_H */ + +/* Exported constants --------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +typedef struct +{ + uint8_t voltage; /* Voltage for the Card Already Selected */ + uint8_t USART_GuardTime; + uint8_t SC_A2R_FiDi; + uint8_t SC_hostFiDi; + uint8_t USART_DefaultGuardTime; + uint32_t USART_BaudRate; +} SC_Param_t; + +#pragma pack(1) +typedef struct +{ + uint8_t bmFindexDindex; + uint8_t bmTCCKST0; + uint8_t bGuardTimeT0; + uint8_t bWaitingIntegerT0; + uint8_t bClockStop; + uint8_t bIfsc; + uint8_t bNad; +} Protocol_01_DataTypeDef; +#pragma pack() + +extern Protocol_01_DataTypeDef ProtocolData; +extern SC_Param_t SC_Param; + +/* Exported macro ------------------------------------------------------------*/ +#define MAX_EXTRA_GUARD_TIME (0xFF - DEFAULT_EXTRA_GUARDTIME) + +/* Following macros are used for SC_XferBlock command */ +#define XFER_BLK_SEND_DATA 1U /* Command is for issuing the data */ +#define XFER_BLK_RECEIVE_DATA 2U /* Command is for receiving the data */ +#define XFER_BLK_NO_DATA 3U /* Command type is No data exchange */ + +/* Exported functions ------------------------------------------------------- */ +/* APPLICATION LAYER ---------------------------------------------------------*/ +void SC_Itf_InitParams(void); +void SC_Itf_IccPowerOn(uint8_t voltage); +void SC_Itf_IccPowerOff(void); +uint8_t SC_GetState(void); +uint8_t SC_Itf_XferBlock(uint8_t *ptrBlock, uint32_t blockLen, + uint16_t expectedLen, + USBD_CCID_BulkIn_DataTypeDef *CCID_BulkIn_Data); + +uint8_t SC_Itf_SetParams(Protocol_01_DataTypeDef *pPtr, uint8_t T_01); +uint8_t SC_Itf_Escape(uint8_t *escapePtr, uint32_t escapeLen, + uint8_t *responseBuff, uint32_t *responseLen); + +uint8_t SC_Itf_SetClock(uint8_t bClockCommand); +uint8_t SC_Itf_T0Apdu(uint8_t bmChanges, uint8_t bClassGetResponse, + uint8_t bClassEnvelope); + +uint8_t SC_Itf_Mechanical(uint8_t bFunction); +uint8_t SC_Itf_SetDataRateAndClockFrequency(uint32_t dwClockFrequency, + uint32_t dwDataRate); + +uint8_t SC_Itf_Secure(uint32_t dwLength, uint8_t bBWI, uint16_t wLevelParameter, + uint8_t *pbuf, uint32_t *returnLen); + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_CCID_SC_IF_TEMPLATE_H */ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Inc/usbd_ccid_smartcard_template.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Inc/usbd_ccid_smartcard_template.h new file mode 100644 index 0000000000..7730180a8b --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Inc/usbd_ccid_smartcard_template.h @@ -0,0 +1,279 @@ +/** + ****************************************************************************** + * @file usbd_ccid_smartcard_template.h + * @author MCD Application Team + * @brief header file for the usbd_ccid_smartcard_template.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_CCID_SMARTCARD_TEMPLATE_H +#define __USBD_CCID_SMARTCARD_TEMPLATE_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#ifndef __USBD_CCID_IF_H +#include "usbd_ccid_if_template.h" +#endif /* __USBD_CCID_IF_H */ + +/* Exported constants --------------------------------------------------------*/ +#define T0_PROTOCOL 0x00U /* T0 protocol */ +#define T1_PROTOCOL 0x01U /* T1 protocol */ +#define DIRECT 0x3BU /* Direct bit convention */ +#define INDIRECT 0x3FU /* Indirect bit convention */ +#define SETUP_LENGTH 20U +#define HIST_LENGTH 20U + +#define SC_TRANSMIT_TIMEOUT 200U /* Direction to transmit */ +#define MAX_PROTOCOLLEVEL 7U /* Maximum levels of protocol */ +#define MAX_INTERFACEBYTE 4U /* Maximum number of interface bytes per protocol */ +#define LC_MAX 24U +#define SC_RECEIVE_TIMEOUT 0x8000U /* Direction to reader */ + +/* T=1 protocol constants */ +#define T1_I_BLOCK 0x00U /* PCB (I-block: b8 = 0) */ +#define T1_R_BLOCK 0x80U /* PCB (R-block: b8 b7 = 10) */ +#define T1_S_BLOCK 0xC0U /* PCB (S-block: b8 b7 = 11) */ + +/* I block */ +#define T1_I_SEQ_SHIFT 6U /* N(S) position (bit 7) */ + +/* R block */ +#define T1_IS_ERROR(pcb) ((pcb) & 0x0FU) +#define T1_EDC_ERROR 0x01U /* [b6..b1] = 0-N(R)-0001 */ +#define T1_OTHER_ERROR 0x02U /* [b6..b1] = 0-N(R)-0010 */ +#define T1_R_SEQ_SHIFT 4U /* N(R) position (b5) */ + +/* S block */ +#define T1_S_RESPONSE 0x20U /* If response: set bit b6, if request reset b6 in PCB S-Block */ +#define T1_S_RESYNC 0x00U /* RESYNCH: b6->b1: 000000 of PCB S-Block */ +#define T1_S_IFS 0x01U /* IFS: b6->b1: 000001 of PCB S-Block */ +#define T1_S_ABORT 0x02U /* ABORT: b6->b1: 000010 of PCB S-Block */ +#define T1_S_WTX 0x03U /* WTX: b6->b1: 000011 of PCB S-Block */ + +#define NAD 0U /* NAD byte position in the block */ +#define PCB 1U /* PCB byte position in the block */ +#define LEN 2U /* LEN byte position in the block */ +#define DATA 3U /* The position of the first byte of INF field in the block */ + +/* Modifiable parameters */ +#define SAD 0x0U /* Source address: reader (allowed values 0 -> 7) */ +#define DAD 0x0U /* Destination address: card (allowed values 0 -> 7) */ +#define IFSD_VALUE 254U /* Max length of INF field Supported by the reader */ +#define SC_FILE_SIZE 0x100U /* File size */ +#define SC_FILE_ID 0x0001U /* File identifier */ +#define SC_CLASS 0x00U + +/* Constant parameters */ +#define INS_SELECT_FILE 0xA4U /* Select file instruction */ +#define INS_READ_FILE 0xB0U /* Read file instruction */ +#define INS_WRITE_FILE 0xD6U /* Write file instruction */ +#define TRAILER_LENGTH 2U /* Trailer length (SW1 and SW2: 2 bytes) */ + +#define SC_T1_RECEIVE_SUCCESS 0U +#define SC_T1_BWT_TIMEOUT 1U +#define SC_T1_CWT_TIMEOUT 2U + +#define DEFAULT_FIDI_VALUE 0x11U +#define PPS_REQUEST 0xFFU + +/* SC Tree Structure ----------------------------------------------------------- + MasterFile + ________|___________ + | | | + System UserData Note +------------------------------------------------------------------------------*/ + +/* SC ADPU Command: Operation Code -------------------------------------------*/ +#define SC_CLA_NAME 0x00U + +/*------------------------ Data Area Management Commands ---------------------*/ +#define SC_SELECT_FILE 0xA4U +#define SC_GET_RESPONCE 0xC0U +#define SC_STATUS 0xF2U +#define SC_UPDATE_BINARY 0xD6U +#define SC_READ_BINARY 0xB0U +#define SC_WRITE_BINARY 0xD0U +#define SC_UPDATE_RECORD 0xDCU +#define SC_READ_RECORD 0xB2U + +/*-------------------------- Administrative Commands -------------------------*/ +#define SC_CREATE_FILE 0xE0U + +/*-------------------------- Safety Management Commands ----------------------*/ +#define SC_VERIFY 0x20U +#define SC_CHANGE 0x24U +#define SC_DISABLE 0x26U +#define SC_ENABLE 0x28U +#define SC_UNBLOCK 0x2CU +#define SC_EXTERNAL_AUTH 0x82U +#define SC_GET_CHALLENGE 0x84U + +/*-------------------------- Smartcard Interface Byte-------------------------*/ +#define SC_INTERFACEBYTE_TA 0U /* Interface byte TA(i) */ +#define SC_INTERFACEBYTE_TB 1U /* Interface byte TB(i) */ +#define SC_INTERFACEBYTE_TC 2U /* Interface byte TC(i) */ +#define SC_INTERFACEBYTE_TD 3U /* Interface byte TD(i) */ + +/*-------------------------- Answer to reset Commands ------------------------*/ +#define SC_GET_A2R 0x00U + +/* SC STATUS: Status Code ----------------------------------------------------*/ +#define SC_EF_SELECTED 0x9FU +#define SC_DF_SELECTED 0x9FU +#define SC_OP_TERMINATED 0x9000U + +/* Smartcard Voltage */ +#define SC_VOLTAGE_5V 0x00U +#define SC_VOLTAGE_3V 0x01U +#define SC_VOLTAGE_NOINIT 0xFFU +/*----------------- ATR Protocole supported ----------------------------------*/ +#define ATR_T01 0x00U + + +/* Exported types ------------------------------------------------------------*/ +typedef enum +{ + SC_POWER_ON = 0x00, + SC_RESET_LOW = 0x01, + SC_RESET_HIGH = 0x02, + SC_ACTIVE = 0x03, + SC_ACTIVE_ON_T0 = 0x04, + SC_ACTIVE_ON_T1 = 0x05, + SC_POWER_OFF = 0x06, + SC_NO_INIT = 0x07 + +} SC_State; + +/* 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_InterfaceByteTypeDef; + +/* Protocol Level structure - ------------------------------------------------*/ +typedef struct +{ + 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_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_ATRTypeDef; + +/* ADPU-Header command structure ---------------------------------------------*/ +typedef struct +{ + uint8_t CLA; /* Command class */ + uint8_t INS; /* Operation code */ + uint8_t P1; /* Selection Mode */ + uint8_t P2; /* Selection Option */ +} SC_HeaderTypeDef; + +/* ADPU-Body command structure -----------------------------------------------*/ +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_BodyTypeDef; + +/* ADPU Command structure ----------------------------------------------------*/ +typedef struct +{ + 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_ResponseTypeDef; + +/* SC Command Status -----------------------------------------------------*/ +typedef enum +{ + SC_CS_FAILED = 0x00, + SC_CS_PIN_ENABLED = 0x01, + SC_CS_PIN_VERIFIED = 0x02, + SC_CS_READ = 0x03, + SC_CS_PIN_CHANGED = 0x04 + +} SC_Command_State; +/* SC Response Status -----------------------------------------------------*/ +typedef enum +{ + REP_OK = 0x00, + REP_NOT_OK = 0x01, + REP_NOT_SUPP = 0x02, + REP_ENABLED = 0x03, + REP_CHANGE = 0x04 + +} REP_Command_t; +/* Conforming of Command with ICC APP -----------------------------------------------------*/ +typedef enum +{ + Command_OK = 0x00, + Command_NOT_OK = 0x01, + +} Command_State_t; + +typedef enum +{ + SC_DISABLED = 0U, + SC_ENABLED = !SC_DISABLED +} SCPowerState; + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +/* APPLICATION LAYER ---------------------------------------------------------*/ +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); +uint8_t SC_Detect(void); +uint32_t SC_GetDTableValue(uint32_t idx); +void SC_VoltageConfig(uint32_t SC_Voltage); +void SC_SetState(SC_State scState); +void SC_IOConfig(void); + +extern uint8_t SC_ATR_Table[40]; +extern SC_ATRTypeDef SC_A2R; +extern SC_ADPU_ResponseTypeDef SC_Response; + +extern uint8_t ProtocolNUM_OUT; +extern SC_ADPU_CommandsTypeDef SC_ADPU; + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_CCID_SMARTCARD_TEMPLATE_H */ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid.c new file mode 100644 index 0000000000..4c77b135d7 --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid.c @@ -0,0 +1,969 @@ +/** + ****************************************************************************** + * @file usbd_ccid.c + * @author MCD Application Team + * @brief This file provides the high layer firmware functions to manage + * all the functionalities of the USB CCID Class: + * + ****************************************************************************** + * @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 + * + * =================================================================== + * CCID Class Driver Description + * =================================================================== + * This module manages the Specification for Integrated Circuit(s) + * Cards Interface Revision 1.1 + * This driver implements the following aspects of the specification: + * - Device descriptor management + * - Configuration descriptor management + * - Enumeration as CCID device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN) + * and enumeration for each implemented memory interface + * - Bulk OUT/IN data Transfers + * - Requests management + * + * @endverbatim + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ccid.h" +#include "usbd_ccid_cmd.h" +#include "usbd_ctlreq.h" +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_CCID + * @brief usbd core module + * @{ + */ + +/** @defgroup USBD_CCID_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_CCID_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_CCID_Private_Macros + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_CCID_Private_FunctionPrototypes + * @{ + */ +static uint8_t USBD_CCID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +static uint8_t USBD_CCID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +static uint8_t USBD_CCID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static uint8_t USBD_CCID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); +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 */ + +/** + * @} + */ + +/** @defgroup USBD_CCID_Private_Variables + * @{ + */ + +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 = +{ + USBD_CCID_Init, + USBD_CCID_DeInit, + USBD_CCID_Setup, + NULL, /*EP0_TxSent*/ + NULL, /*EP0_RxReady*/ + USBD_CCID_DataIn, + USBD_CCID_DataOut, + 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_CfgDesc[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_SELF_POWERED */ + 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, /* 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_FS_MAX_PACKET_SIZE), + HIBYTE(CCID_DATA_FS_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_FS_MAX_PACKET_SIZE), + HIBYTE(CCID_DATA_FS_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_FS_BINTERVAL /* Polling interval in milliseconds */ +}; + +/* USB Standard Device Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_CCID_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 */ + +/** + * @} + */ + +/** @defgroup USBD_CCID_Private_Functions + * @{ + */ + +/** + * @brief USBD_CCID_Init + * Initialize the CCID interface + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_CCID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + USBD_CCID_HandleTypeDef *hccid; + UNUSED(cfgidx); + + /* Allocate CCID structure */ + hccid = (USBD_CCID_HandleTypeDef *)USBD_malloc(sizeof(USBD_CCID_HandleTypeDef)); + + if (hccid == NULL) + { + pdev->pClassDataCmsit[pdev->classId] = NULL; + return (uint8_t)USBD_EMEM; + } + + 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, (uint8_t)pdev->classId); + CCIDOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); + CCIDCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId); +#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; + hccid->USBD_CCID_Param.bSeq = 0U; + hccid->USBD_CCID_Param.bSlot = 0U; + hccid->MaxPcktLen = (pdev->dev_speed == USBD_SPEED_HIGH) ? \ + CCID_DATA_HS_MAX_PACKET_SIZE : CCID_DATA_FS_MAX_PACKET_SIZE; + + /* Open EP IN */ + (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, 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, CCIDCmdEpAdd, + USBD_EP_TYPE_INTR, CCID_CMD_PACKET_SIZE); + pdev->ep_in[CCIDCmdEpAdd & 0xFU].is_used = 1U; + + /* Init physical Interface components */ + ((USBD_CCID_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init(pdev); + + /* Prepare Out endpoint to receive next packet */ + (void)USBD_LL_PrepareReceive(pdev, CCIDOutEpAdd, + hccid->data, hccid->MaxPcktLen); + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_CCID_DeInit + * DeInitialize the CCID layer + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +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, (uint8_t)pdev->classId); + CCIDOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); + CCIDCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ + + /* Close EP IN */ + (void)USBD_LL_CloseEP(pdev, CCIDInEpAdd); + pdev->ep_in[CCIDInEpAdd & 0xFU].is_used = 0U; + + /* Close EP OUT */ + (void)USBD_LL_CloseEP(pdev, CCIDOutEpAdd); + pdev->ep_out[CCIDOutEpAdd & 0xFU].is_used = 0U; + + /* Close EP Command */ + (void)USBD_LL_CloseEP(pdev, CCIDCmdEpAdd); + pdev->ep_in[CCIDCmdEpAdd & 0xFU].is_used = 0U; + + /* DeInit physical Interface components */ + if (pdev->pClassDataCmsit[pdev->classId] != NULL) + { + ((USBD_CCID_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit(pdev); + (void)USBD_free(pdev->pClassDataCmsit[pdev->classId]); + pdev->pClassDataCmsit[pdev->classId] = NULL; + pdev->pClassData = NULL; + } + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_CCID_Setup + * Handle the CCID specific requests + * @param pdev: instance + * @param req: usb requests + * @retval status + */ +static uint8_t USBD_CCID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + 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; + uint16_t len; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + /* Class request */ + case USB_REQ_TYPE_CLASS : + if (req->wLength != 0U) + { + len = MIN(CCID_EP0_BUFF_SIZ, req->wLength); + if ((req->bmRequest & 0x80U) != 0U) + { + hCCIDitf->Control(req->bRequest, hccid->data, &len); + (void)USBD_CtlSendData(pdev, hccid->data, len); + } + else + { + (void)USBD_CtlPrepareRx(pdev, hccid->data, len); + } + } + else + { + len = 0U; + hCCIDitf->Control(req->bRequest, (uint8_t *)&req->wValue, &len); + } + break; + + /* Interface & Endpoint request */ + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_GET_STATUS: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_GET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, &ifalt, 1U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_SET_INTERFACE: + if (pdev->dev_state != USBD_STATE_CONFIGURED) + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_CLEAR_FEATURE: + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + } + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + } + + return (uint8_t)ret; +} + +/** + * @brief USBD_CCID_DataIn + * Data sent on non-control IN endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +static uint8_t USBD_CCID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)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, (uint8_t)pdev->classId); + CCIDCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ + + if (epnum == (CCIDInEpAdd & 0x7FU)) + { + /* Filter the epnum by masking with 0x7f (mask of IN Direction) */ + + /*************** Handle Bulk Transfer IN data completion *****************/ + + switch (hccid->blkt_state) + { + case CCID_STATE_SEND_RESP: + + /* won't wait ack to avoid missing a command */ + hccid->blkt_state = CCID_STATE_IDLE; + + /* Prepare EP to Receive Cmd */ + (void)USBD_LL_PrepareReceive(pdev, CCID_OUT_EP, + hccid->data, hccid->MaxPcktLen); + break; + + default: + break; + } + } + else if (epnum == (CCIDCmdEpAdd & 0x7FU)) + { + /* Filter the epnum by masking with 0x7f (mask of IN Direction) */ + + /*************** Handle Interrupt Transfer IN data completion *****************/ + + (void)USBD_CCID_IntMessage(pdev); + } + else + { + return (uint8_t)USBD_FAIL; + } + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_CCID_DataOut + * Data received on non-control Out endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +static uint8_t USBD_CCID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + 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, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ + + if (hccid == NULL) + { + return (uint8_t)USBD_EMEM; + } + + if (epnum == CCIDOutEpAdd) + { + CurrPcktLen = (uint16_t)USBD_GetRxCount(pdev, epnum); + + switch (hccid->blkt_state) + { + case CCID_STATE_IDLE: + + if (CurrPcktLen >= (uint16_t)CCID_CMD_HEADER_SIZE) + { + hccid->UsbMessageLength = CurrPcktLen; /* Store for future use */ + + /* Fill CCID_BulkOut Data Buffer from USB Buffer */ + (void)USBD_CCID_ReceiveCmdHeader(pdev, (uint8_t *)&hccid->UsbBlkOutData.bMessageType, + (uint16_t)CurrPcktLen); + + /* + Refer : 6 CCID Messages + The response messages always contain the exact same slot number, + and sequence number fields from the header that was contained in + the Bulk-OUT command message. + */ + hccid->UsbBlkInData.bSlot = hccid->UsbBlkOutData.bSlot; + hccid->UsbBlkInData.bSeq = hccid->UsbBlkOutData.bSeq; + + if (CurrPcktLen < hccid->MaxPcktLen) + { + /* Short message, less than the EP Out Size, execute the command, + if parameter like dwLength is too big, the appropriate command will + give an error */ + (void)USBD_CCID_DispatchCommand(pdev); + } + else + { + /* Check if length of data to be sent by host is > buffer size */ + if (hccid->UsbBlkOutData.dwLength > (uint32_t)ABDATA_SIZE) + { + /* Too long data received.... Error ! */ + hccid->blkt_state = CCID_STATE_UNCORRECT_LENGTH; + } + + else + { + /* Expect more data on OUT EP */ + hccid->blkt_state = CCID_STATE_RECEIVE_DATA; + + /* Prepare EP to Receive next Cmd */ + (void)USBD_LL_PrepareReceive(pdev, CCID_OUT_EP, + hccid->data, hccid->MaxPcktLen); + + } /* if (CurrPcktLen == CCID_DATA_MAX_PACKET_SIZE) ends */ + } /* if (CurrPcktLen >= CCID_DATA_MAX_PACKET_SIZE) ends */ + } /* if (CurrPcktLen >= CCID_CMD_HEADER_SIZE) ends */ + else + { + if (CurrPcktLen == 0x00U) /* Zero Length Packet Received */ + { + hccid->blkt_state = CCID_STATE_IDLE; + } + } + + break; + + case CCID_STATE_RECEIVE_DATA: + hccid->UsbMessageLength += CurrPcktLen; + + if (CurrPcktLen < hccid->MaxPcktLen) + { + /* Short message, less than the EP Out Size, execute the command, + if parameter like dwLength is too big, the appropriate command will + give an error */ + + /* Full command is received, process the Command */ + (void)USBD_CCID_ReceiveCmdHeader(pdev, (uint8_t *)&hccid->UsbBlkOutData.bMessageType, + (uint16_t)CurrPcktLen); + + (void)USBD_CCID_DispatchCommand(pdev); + } + else if (CurrPcktLen == hccid->MaxPcktLen) + { + if (hccid->UsbMessageLength < (hccid->UsbBlkOutData.dwLength + (uint32_t)CCID_CMD_HEADER_SIZE)) + { + (void)USBD_CCID_ReceiveCmdHeader(pdev, (uint8_t *)&hccid->UsbBlkOutData.bMessageType, + (uint16_t)CurrPcktLen); /* Copy data */ + + /* Prepare EP to Receive next Cmd */ + (void)USBD_LL_PrepareReceive(pdev, CCID_OUT_EP, + hccid->data, hccid->MaxPcktLen); + } + else if (hccid->UsbMessageLength == (hccid->UsbBlkOutData.dwLength + (uint32_t)CCID_CMD_HEADER_SIZE)) + { + /* Full command is received, process the Command */ + (void)USBD_CCID_ReceiveCmdHeader(pdev, (uint8_t *)&hccid->UsbBlkOutData.bMessageType, + (uint16_t)CurrPcktLen); + + (void)USBD_CCID_DispatchCommand(pdev); + } + else + { + /* Too long data received.... Error ! */ + hccid->blkt_state = CCID_STATE_UNCORRECT_LENGTH; + } + } + else + { + /* Too long data received.... Error ! */ + hccid->blkt_state = CCID_STATE_UNCORRECT_LENGTH; + } + break; + + case CCID_STATE_UNCORRECT_LENGTH: + hccid->blkt_state = CCID_STATE_IDLE; + break; + + default: + break; + } + } + else + { + return (uint8_t)USBD_FAIL; + } + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_CCID_DispatchCommand + * Parse the commands and Process command + * @param pdev: device instance + * @retval status value + */ +static uint8_t USBD_CCID_DispatchCommand(USBD_HandleTypeDef *pdev) +{ + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + uint8_t errorCode; + + switch (hccid->UsbBlkOutData.bMessageType) + { + case PC_TO_RDR_ICCPOWERON: + errorCode = PC_to_RDR_IccPowerOn(pdev); + RDR_to_PC_DataBlock(errorCode, pdev); + break; + + case PC_TO_RDR_ICCPOWEROFF: + errorCode = PC_to_RDR_IccPowerOff(pdev); + RDR_to_PC_SlotStatus(errorCode, pdev); + break; + + case PC_TO_RDR_GETSLOTSTATUS: + errorCode = PC_to_RDR_GetSlotStatus(pdev); + RDR_to_PC_SlotStatus(errorCode, pdev); + break; + + case PC_TO_RDR_XFRBLOCK: + errorCode = PC_to_RDR_XfrBlock(pdev); + RDR_to_PC_DataBlock(errorCode, pdev); + break; + + case PC_TO_RDR_GETPARAMETERS: + errorCode = PC_to_RDR_GetParameters(pdev); + RDR_to_PC_Parameters(errorCode, pdev); + break; + + case PC_TO_RDR_RESETPARAMETERS: + errorCode = PC_to_RDR_ResetParameters(pdev); + RDR_to_PC_Parameters(errorCode, pdev); + break; + + case PC_TO_RDR_SETPARAMETERS: + errorCode = PC_to_RDR_SetParameters(pdev); + RDR_to_PC_Parameters(errorCode, pdev); + break; + + case PC_TO_RDR_ESCAPE: + errorCode = PC_to_RDR_Escape(pdev); + RDR_to_PC_Escape(errorCode, pdev); + break; + + case PC_TO_RDR_ICCCLOCK: + errorCode = PC_to_RDR_IccClock(pdev); + RDR_to_PC_SlotStatus(errorCode, pdev); + break; + + case PC_TO_RDR_ABORT: + errorCode = PC_to_RDR_Abort(pdev); + RDR_to_PC_SlotStatus(errorCode, pdev); + break; + + case PC_TO_RDR_T0APDU: + errorCode = PC_TO_RDR_T0Apdu(pdev); + RDR_to_PC_SlotStatus(errorCode, pdev); + break; + + case PC_TO_RDR_MECHANICAL: + errorCode = PC_TO_RDR_Mechanical(pdev); + RDR_to_PC_SlotStatus(errorCode, pdev); + break; + + case PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY: + errorCode = PC_TO_RDR_SetDataRateAndClockFrequency(pdev); + RDR_to_PC_DataRateAndClockFrequency(errorCode, pdev); + break; + + case PC_TO_RDR_SECURE: + errorCode = PC_TO_RDR_Secure(pdev); + RDR_to_PC_DataBlock(errorCode, pdev); + break; + + default: + RDR_to_PC_SlotStatus(SLOTERROR_CMD_NOT_SUPPORTED, pdev); + break; + } + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_CCID_Transfer_Data_Request + * Prepare the request response to be sent to the host + * @param pdev: device instance + * @param dataPointer: Pointer to the data buffer to send + * @param dataLen : number of bytes to send + * @retval status value + */ +uint8_t USBD_CCID_Transfer_Data_Request(USBD_HandleTypeDef *pdev, + uint8_t *dataPointer, uint16_t dataLen) +{ + 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 = (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, + (uint16_t)MIN(CCID_DATA_FS_MAX_PACKET_SIZE, hccid->UsbMessageLength)); + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_CCID_ReceiveCmdHeader + * Receive the Data from USB BulkOut Buffer to Pointer + * @param pdev: device instance + * @param pDst: destination address to copy the buffer + * @param u8length: length of data to copy + * @retval status + */ +static uint8_t USBD_CCID_ReceiveCmdHeader(USBD_HandleTypeDef *pdev, + uint8_t *pDst, uint16_t u8length) +{ + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + uint8_t *pdst = pDst; + uint32_t Counter; + + for (Counter = 0U; Counter < u8length; Counter++) + { + *pdst = hccid->data[Counter]; + pdst++; + } + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_CCID_IntMessage + * Send the Interrupt-IN data to the host + * @param pdev: device instance + * @retval None + */ +uint8_t USBD_CCID_IntMessage(USBD_HandleTypeDef *pdev) +{ + 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, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ + + /* Check if there is change in Smartcard Slot status */ + if (CCID_IsSlotStatusChange(pdev) != 0U) + { + /* Check Slot Status is changed. Card is Removed/Fitted */ + RDR_to_PC_NotifySlotChange(pdev); + + /* Set the Slot status */ + ((USBD_CCID_ItfTypeDef *)pdev->pUserData[pdev->classId])->SetSlotStatus(pdev); + + (void)USBD_LL_Transmit(pdev, CCIDCmdEpAdd, hccid->UsbIntData, 2U); + } + else + { + /* Set the Slot status */ + ((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 + * @param length pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_CCID_GetHSCfgDesc(uint16_t *length) +{ + 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 + * Return configuration descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_CCID_GetFSCfgDesc(uint16_t *length) +{ + 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; +} + +/** + * @brief USBD_CCID_GetOtherSpeedCfgDesc + * Return configuration descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_CCID_GetOtherSpeedCfgDesc(uint16_t *length) +{ + 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; +} + +/** + * @brief USBD_CCID_GetDeviceQualifierDescriptor + * return Device Qualifier descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +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 + * @param pdev: device instance + * @param fops: CD Interface callback + * @retval status + */ +uint8_t USBD_CCID_RegisterInterface(USBD_HandleTypeDef *pdev, + USBD_CCID_ItfTypeDef *fops) +{ + if (fops == NULL) + { + return (uint8_t)USBD_FAIL; + } + + pdev->pUserData[pdev->classId] = fops; + + return (uint8_t)USBD_OK; +} + +/** + * @} + */ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid_cmd.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid_cmd.c new file mode 100644 index 0000000000..b91cb1f157 --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid_cmd.c @@ -0,0 +1,1099 @@ +/** + ****************************************************************************** + * @file usbd_ccid_cmd.c + * @author MCD Application Team + * @brief CCID command (Bulk-OUT Messages / Bulk-IN Messages) handling + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ccid.h" +#include "usbd_ccid_cmd.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static uint8_t CCID_CheckCommandParams(USBD_HandleTypeDef *pdev, uint32_t param_type); +static void CCID_UpdateCommandStatus(USBD_HandleTypeDef *pdev, uint8_t cmd_status, uint8_t icc_status); + +/* Private functions ---------------------------------------------------------*/ + +/******************************************************************************/ +/* BULK OUT ROUTINES */ +/******************************************************************************/ + +/** + * @brief PC_to_RDR_IccPowerOn + * PC_TO_RDR_ICCPOWERON message execution, apply voltage and get ATR + * @param pdev: device instance + * @retval status of the command execution + */ +uint8_t PC_to_RDR_IccPowerOn(USBD_HandleTypeDef *pdev) +{ + /* Apply the ICC VCC + Fills the Response buffer with ICC ATR + This Command is returned with RDR_to_PC_DataBlock(); + */ + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + uint8_t voltage; + uint8_t sc_voltage = 0U; + uint8_t index; + uint8_t error; + + 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_ABORT); + if (error != 0U) + { + return error; + } + + /* Voltage that is applied to the ICC + 00h Automatic Voltage Selection + 01h 5.0 volts + 02h 3.0 volts + 03h 1.8 volts + */ + /* UsbBlkOutData.bSpecific_0 Contains bPowerSelect */ + voltage = hccid->UsbBlkOutData.bSpecific_0; + if (voltage >= VOLTAGE_SELECTION_1V8) + { + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + return SLOTERROR_BAD_POWERSELECT; /* The Voltage specified is out of Spec */ + } + + /* Correct Voltage Requested by the Host */ + if ((voltage == VOLTAGE_SELECTION_AUTOMATIC) || (voltage == VOLTAGE_SELECTION_3V)) + { + sc_voltage = SC_VOLTAGE_3V; + } + else + { + if (voltage == VOLTAGE_SELECTION_5V) + { + sc_voltage = SC_VOLTAGE_5V; + } + } + SC_Itf_IccPowerOn(sc_voltage); + + /* Check if the Card has come to Active State*/ + error = CCID_CheckCommandParams(pdev, (uint32_t)CHK_ACTIVE_STATE); + + if (error != 0U) + { + /* Check if Voltage is not Automatic */ + if (voltage != 0U) + { + /* If Specific Voltage requested by Host i.e 3V or 5V*/ + return error; + } + else + { + /* Automatic Voltage selection requested by Host */ + + if (sc_voltage != SC_VOLTAGE_5V) + { + /* If voltage selected was Automatic and 5V is not yet tried */ + sc_voltage = SC_VOLTAGE_5V; + SC_Itf_IccPowerOn(sc_voltage); + + /* Check again the State */ + error = CCID_CheckCommandParams(pdev, (uint32_t)CHK_ACTIVE_STATE); + if (error != 0U) + { + return error; + } + } + else + { + /* Voltage requested from Host was 5V already*/ + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_INACTIVE)); + return error; + } + } /* Voltage Selection was automatic */ + } /* If Active State */ + + /* ATR is received, No Error Condition Found */ + hccid->UsbBlkInData.dwLength = SIZE_OF_ATR; + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); + + for (index = 0U; index < SIZE_OF_ATR; index++) + { + /* Copy the ATR to the Response Buffer */ + hccid->UsbBlkInData.abData[index] = SC_ATR_Table[index]; + } + + return SLOT_NO_ERROR; +} + +/** + * @brief PC_to_RDR_IccPowerOff + * Icc VCC is switched Off + * @param pdev: device instance + * @retval error: status of the command execution + */ +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 | + CHK_PARAM_DWLENGTH); + if (error != 0U) + { + return error; + } + /* Command is ok, Check for Card Presence */ + if (SC_Detect() != 0U) + { + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_INACTIVE)); + } + else + { + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_NO_ICC_PRESENT)); + } + + /* Power OFF the card */ + SC_Itf_IccPowerOff(); + + return SLOT_NO_ERROR; +} + +/** + * @brief PC_to_RDR_GetSlotStatus + * Provides the Slot status to the host + * @param pdev: device instance + * @retval status of the command execution + */ +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); + if (error != 0U) + { + return error; + } + + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); + return SLOT_NO_ERROR; +} + + +/** + * @brief PC_to_RDR_XfrBlock + * Handles the Block transfer from Host. + * Response to this command message is the RDR_to_PC_DataBlock + * @param pdev: device instance + * @retval status of the command execution + */ +uint8_t PC_to_RDR_XfrBlock(USBD_HandleTypeDef *pdev) +{ + 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); + if (error != 0U) + { + return error; + } + if (hccid->UsbBlkOutData.dwLength > ABDATA_SIZE) + { + /* Check amount of Data Sent by Host is > than memory allocated ? */ + + return SLOTERROR_BAD_DWLENGTH; + } + + /* wLevelParameter = Size of expected data to be returned by the + bulk-IN endpoint */ + expectedLength = (uint8_t)((hccid->UsbBlkOutData.bSpecific_2 << 8) | + hccid->UsbBlkOutData.bSpecific_1); + + hccid->UsbBlkInData.dwLength = (uint16_t)expectedLength; + + error = SC_Itf_XferBlock(&(hccid->UsbBlkOutData.abData[0]), + hccid->UsbBlkOutData.dwLength, + expectedLength, &hccid->UsbBlkInData); + + if (error != SLOT_NO_ERROR) + { + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + } + else + { + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); + error = SLOT_NO_ERROR; + } + + return error; +} + +/** + * @brief PC_to_RDR_GetParameters + * Provides the ICC parameters to the host + * Response to this command message is the RDR_to_PC_Parameters + * @param pdev: device instance + * @retval status of the command execution + */ +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); + if (error != 0U) + { + return error; + } + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); + + return SLOT_NO_ERROR; +} + +/** + * @brief PC_to_RDR_ResetParameters + * Set the ICC parameters to the default + * Response to this command message is the RDR_to_PC_Parameters + * @param pdev: device instance + * @retval status of the command execution + */ +uint8_t PC_to_RDR_ResetParameters(USBD_HandleTypeDef *pdev) +{ + 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_ACTIVE_STATE); + if (error != 0U) + { + return error; + } + /* This command resets the slot parameters to their default values */ + hccid->UsbBlkOutData.abData[0] = DEFAULT_FIDI; + hccid->UsbBlkOutData.abData[1] = DEFAULT_T01CONVCHECKSUM; + hccid->UsbBlkOutData.abData[2] = DEFAULT_EXTRA_GUARDTIME; + hccid->UsbBlkOutData.abData[3] = DEFAULT_WAITINGINTEGER; + hccid->UsbBlkOutData.abData[4] = DEFAULT_CLOCKSTOP; + hccid->UsbBlkOutData.abData[5] = 0x00U; + hccid->UsbBlkOutData.abData[6] = 0x00U; + + (void)USBD_memcpy(&ProtocolData, (void const *)(&hccid->UsbBlkOutData.abData[0]), + sizeof(ProtocolData)); + + error = SC_Itf_SetParams(&ProtocolData, ProtocolNUM_OUT); + + if (error != SLOT_NO_ERROR) + { + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + } + else + { + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); + error = SLOT_NO_ERROR; + } + + return error; +} +/** + * @brief PC_to_RDR_SetParameters + * Set the ICC parameters to the host defined parameters + * Response to this command message is the RDR_to_PC_Parameters + * @param pdev: device instance + * @retval status of the command execution + */ +uint8_t PC_to_RDR_SetParameters(USBD_HandleTypeDef *pdev) +{ + 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); + if (error != 0U) + { + return error; + } + error = SLOT_NO_ERROR; + + /* for Protocol T=0 (dwLength=00000005h) */ + /* for Protocol T=1 (dwLength=00000007h) */ + if (((hccid->UsbBlkOutData.dwLength == 5U) && (hccid->UsbBlkOutData.bSpecific_0 != 0U)) + || ((hccid->UsbBlkOutData.dwLength == 7U) && (hccid->UsbBlkOutData.bSpecific_0 != 1U))) + { + error = SLOTERROR_BAD_PROTOCOLNUM; + } + if (hccid->UsbBlkOutData.abData[4] != DEFAULT_CLOCKSTOP) + { + error = SLOTERROR_BAD_CLOCKSTOP; + } + if (error != SLOT_NO_ERROR) + { + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + } + + (void)USBD_memcpy(&ProtocolData, (void const *)(&hccid->UsbBlkOutData.abData[0]), + sizeof(ProtocolData)); + + error = SC_Itf_SetParams(&ProtocolData, ProtocolNUM_OUT); + + if (error != SLOT_NO_ERROR) + { + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + } + else + { + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); + error = SLOT_NO_ERROR; + } + + return error; +} +/** + * @brief PC_to_RDR_Escape + * Execute the Escape command. This is user specific Implementation + * Response to this command message is the RDR_to_PC_Escape + * @param pdev: device instance + * @retval status of the command execution + */ +uint8_t PC_to_RDR_Escape(USBD_HandleTypeDef *pdev) +{ + 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); + + if (error != 0U) + { + return error; + } + error = SC_Itf_Escape(&hccid->UsbBlkOutData.abData[0], hccid->UsbBlkOutData.dwLength, + &hccid->UsbBlkInData.abData[0], &size); + + hccid->UsbBlkInData.dwLength = size; + + if (error != SLOT_NO_ERROR) + { + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + } + else + { + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); + } + + return error; +} +/** + * @brief PC_to_RDR_IccClock + * Execute the Clock specific command from host + * Response to this command message is the RDR_to_PC_SlotStatus + * @param pdev: device instance + * @retval status of the command execution + */ +uint8_t PC_to_RDR_IccClock(USBD_HandleTypeDef *pdev) +{ + 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); + if (error != 0U) + { + return error; + } + /* bClockCommand : + 00h restarts Clock + 01h Stops Clock in the state shown in the bClockStop field */ + if (hccid->UsbBlkOutData.bSpecific_0 > 1U) + { + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + return SLOTERROR_BAD_CLOCKCOMMAND; + } + + error = SC_Itf_SetClock(hccid->UsbBlkOutData.bSpecific_0); + + if (error != SLOT_NO_ERROR) + { + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + } + else + { + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); + } + + return error; +} +/** + * @brief PC_to_RDR_Abort + * Execute the Abort command from host, This stops all Bulk transfers + * from host and ICC + * Response to this command message is the RDR_to_PC_SlotStatus + * @param pdev: device instance + * @retval status of the command execution + */ +uint8_t PC_to_RDR_Abort(USBD_HandleTypeDef *pdev) +{ + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + uint8_t error; + + error = CCID_CheckCommandParams(pdev, CHK_PARAM_SLOT | CHK_PARAM_ABRFU3 | + CHK_PARAM_DWLENGTH); + if (error != 0U) + { + return error; + } + (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; +} + +/** + * @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(USBD_HandleTypeDef *pdev, uint8_t slot, uint8_t seq) +{ + 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 */ + + if (slot >= CCID_NUMBER_OF_SLOTS) + { + /* error from CLASS_REQUEST*/ + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_NO_ICC_PRESENT)); + return SLOTERROR_BAD_SLOT; + } + + if (hccid->USBD_CCID_Param.bAbortRequestFlag == 1U) + { + /* Abort Command was already received from ClassReq or PC_to_RDR */ + if ((hccid->USBD_CCID_Param.bSeq == seq) && (BSlot == slot)) + { + /* CLASS Specific request is already Received, Reset the abort flag */ + hccid->USBD_CCID_Param.bAbortRequestFlag = 0; + } + } + else + { + /* Abort Command was NOT received from ClassReq or PC_to_RDR, + so save them for next ABORT command to verify */ + hccid->USBD_CCID_Param.bAbortRequestFlag = 1U; + hccid->USBD_CCID_Param.bSeq = seq; + hccid->USBD_CCID_Param.bSlot = slot; + } + + return 0; +} + +/** + * @brief PC_TO_RDR_T0Apdu + * Execute the PC_TO_RDR_T0APDU command from host + * Response to this command message is the RDR_to_PC_SlotStatus + * @param pdev: device instance + * @retval status of the command execution + */ +uint8_t PC_TO_RDR_T0Apdu(USBD_HandleTypeDef *pdev) +{ + 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_DWLENGTH | CHK_PARAM_ABORT); + if (error != 0U) + { + return error; + } + if (hccid->UsbBlkOutData.bSpecific_0 > 0x03U) + { + /* Bit 0 is associated with bClassGetResponse + Bit 1 is associated with bClassEnvelope */ + + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + return SLOTERROR_BAD_BMCHANGES; + } + + error = SC_Itf_T0Apdu(hccid->UsbBlkOutData.bSpecific_0, + hccid->UsbBlkOutData.bSpecific_1, + hccid->UsbBlkOutData.bSpecific_2); + + if (error != SLOT_NO_ERROR) + { + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + } + else + { + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); + } + + return error; +} + +/** + * @brief PC_TO_RDR_Mechanical + * Execute the PC_TO_RDR_MECHANICAL command from host + * Response to this command message is the RDR_to_PC_SlotStatus + * @param pdev: device instance + * @retval status of the command execution + */ +uint8_t PC_TO_RDR_Mechanical(USBD_HandleTypeDef *pdev) +{ + 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); + if (error != 0U) + { + return error; + } + if (hccid->UsbBlkOutData.bSpecific_0 > 0x05U) + { + /* + 01h Accept Card + 02h Eject Card + 03h Capture Card + 04h Lock Card + 05h Unlock Card + */ + + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + return SLOTERROR_BAD_BFUNCTION_MECHANICAL; + } + + error = SC_Itf_Mechanical(hccid->UsbBlkOutData.bSpecific_0); + + if (error != SLOT_NO_ERROR) + { + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + } + else + { + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); + } + + return error; +} + +/** + * @brief PC_TO_RDR_SetDataRateAndClockFrequency + * Set the required Card Frequency and Data rate from the host. + * Response to this command message is the + * RDR_to_PC_DataRateAndClockFrequency + * @param pdev: device instance + * @retval status of the command execution + */ +uint8_t PC_TO_RDR_SetDataRateAndClockFrequency(USBD_HandleTypeDef *pdev) +{ + 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); + if (error != 0U) + { + return error; + } + if (hccid->UsbBlkOutData.dwLength != 0x08U) + { + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + return SLOTERROR_BAD_LENTGH; + } + + /* HERE we avoiding to an unaligned memory access*/ + temp = (uint32_t)(hccid->UsbBlkOutData.abData[0]) & 0x000000FFU; + clockFrequency = temp; + + temp = (uint32_t)(hccid->UsbBlkOutData.abData[1]) & 0x000000FFU; + clockFrequency |= temp << 8; + + temp = (uint32_t)(hccid->UsbBlkOutData.abData[2]) & 0x000000FFU; + clockFrequency |= temp << 16; + + temp = (uint32_t)(hccid->UsbBlkOutData.abData[3]) & 0x000000FFU; + clockFrequency |= temp << 24; + + temp = (uint32_t)(hccid->UsbBlkOutData.abData[4]) & 0x000000FFU; + dataRate = temp; + + temp = (uint32_t)(hccid->UsbBlkOutData.abData[5]) & 0x000000FFU; + dataRate |= temp << 8; + + temp = (uint32_t)(hccid->UsbBlkOutData.abData[6]) & 0x000000FFU; + dataRate |= temp << 16; + + temp = (uint32_t)(hccid->UsbBlkOutData.abData[7]) & 0x000000FFU; + dataRate |= temp << 24; + + error = SC_Itf_SetDataRateAndClockFrequency(clockFrequency, dataRate); + hccid->UsbBlkInData.bError = error; + + if (error != SLOT_NO_ERROR) + { + hccid->UsbBlkInData.dwLength = 0; + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + } + else + { + hccid->UsbBlkInData.dwLength = 8; + + (hccid->UsbBlkInData.abData[0]) = (uint8_t)(clockFrequency & 0x000000FFU) ; + + (hccid->UsbBlkInData.abData[1]) = (uint8_t)((clockFrequency & 0x0000FF00U) >> 8); + + (hccid->UsbBlkInData.abData[2]) = (uint8_t)((clockFrequency & 0x00FF0000U) >> 16); + + (hccid->UsbBlkInData.abData[3]) = (uint8_t)((clockFrequency & 0xFF000000U) >> 24); + + (hccid->UsbBlkInData.abData[4]) = (uint8_t)(dataRate & 0x000000FFU) ; + + (hccid->UsbBlkInData.abData[5]) = (uint8_t)((dataRate & 0x0000FF00U) >> 8); + + (hccid->UsbBlkInData.abData[6]) = (uint8_t)((dataRate & 0x00FF0000U) >> 16); + + (hccid->UsbBlkInData.abData[7]) = (uint8_t)((dataRate & 0xFF000000U) >> 24); + + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); + } + + return error; +} + +/** + * @brief PC_TO_RDR_Secure + * Execute the Secure Command from the host. + * Response to this command message is the RDR_to_PC_DataBlock + * @param pdev: device instance + * @retval status of the command execution + */ +uint8_t PC_TO_RDR_Secure(USBD_HandleTypeDef *pdev) +{ + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + uint8_t error; + uint8_t bBWI; + uint16_t wLevelParameter; + uint32_t responseLen; + + hccid->UsbBlkInData.dwLength = 0; + + error = CCID_CheckCommandParams(pdev, CHK_PARAM_SLOT | CHK_PARAM_CARD_PRESENT | + CHK_PARAM_ABORT); + + if (error != 0U) + { + return error; + } + bBWI = hccid->UsbBlkOutData.bSpecific_0; + wLevelParameter = (hccid->UsbBlkOutData.bSpecific_1 + ((uint16_t)hccid->UsbBlkOutData.bSpecific_2 << 8)); + + if ((EXCHANGE_LEVEL_FEATURE == TPDU_EXCHANGE) || + (EXCHANGE_LEVEL_FEATURE == SHORT_APDU_EXCHANGE)) + { + /* TPDU level & short APDU level, wLevelParameter is RFU, = 0000h */ + if (wLevelParameter != 0U) + { + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + error = SLOTERROR_BAD_LEVELPARAMETER; + return error; + } + } + + error = SC_Itf_Secure(hccid->UsbBlkOutData.dwLength, bBWI, wLevelParameter, + &(hccid->UsbBlkOutData.abData[0]), &responseLen); + + hccid->UsbBlkInData.dwLength = responseLen; + + if (error != SLOT_NO_ERROR) + { + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + } + else + { + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_NO_ERROR), (BM_ICC_PRESENT_ACTIVE)); + } + + return error; +} + +/******************************************************************************/ +/* BULK IN ROUTINES */ +/******************************************************************************/ + +/** + * @brief RDR_to_PC_DataBlock + * Provide the data block response to the host + * Response for PC_to_RDR_IccPowerOn, PC_to_RDR_XfrBlock + * @param errorCode: code to be returned to the host + * @param pdev: device instance + * @retval None + */ +void RDR_to_PC_DataBlock(uint8_t errorCode, USBD_HandleTypeDef *pdev) +{ + 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; + hccid->UsbBlkInData.bError = 0U; + hccid->UsbBlkInData.bSpecific = 0U; /* bChainParameter */ + + if (errorCode == SLOT_NO_ERROR) + { + length += hccid->UsbBlkInData.dwLength; /* Length Specified in Command */ + } + + (void)USBD_CCID_Transfer_Data_Request(pdev, (uint8_t *)&hccid->UsbBlkInData, (uint16_t)length); +} + +/** + * @brief RDR_to_PC_SlotStatus + * Provide the Slot status response to the host + * Response for PC_to_RDR_IccPowerOff + * PC_to_RDR_GetSlotStatus + * PC_to_RDR_IccClock + * PC_to_RDR_T0APDU + * PC_to_RDR_Mechanical + * Also the device sends this response message when it has completed + * aborting a slot after receiving both the Class Specific ABORT request + * and PC_to_RDR_Abort command message. + * @param errorCode: code to be returned to the host + * @param pdev: device instance + * @retval None + */ +void RDR_to_PC_SlotStatus(uint8_t errorCode, USBD_HandleTypeDef *pdev) +{ + 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; + hccid->UsbBlkInData.bError = 0U; + hccid->UsbBlkInData.bSpecific = 0U; /* bClockStatus = 00h Clock running + 01h Clock stopped in state L + 02h Clock stopped in state H + 03h Clock stopped in an unknown state */ + + if (errorCode == SLOT_NO_ERROR) + { + length += (uint16_t)hccid->UsbBlkInData.dwLength; + } + + (void)USBD_CCID_Transfer_Data_Request(pdev, (uint8_t *)(&hccid->UsbBlkInData), length); +} + +/** + * @brief RDR_to_PC_Parameters + * Provide the data block response to the host + * Response for PC_to_RDR_GetParameters, PC_to_RDR_ResetParameters + * PC_to_RDR_SetParameters + * @param errorCode: code to be returned to the host + * @param pdev: device instance + * @retval None + */ +void RDR_to_PC_Parameters(uint8_t errorCode, USBD_HandleTypeDef *pdev) +{ + 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; + hccid->UsbBlkInData.bError = 0U; + + if (errorCode == SLOT_NO_ERROR) + { + if (ProtocolNUM_OUT == 0x00U) + { + hccid->UsbBlkInData.dwLength = LEN_PROTOCOL_STRUCT_T0; + length += (uint16_t)hccid->UsbBlkInData.dwLength; + } + else + { + hccid->UsbBlkInData.dwLength = LEN_PROTOCOL_STRUCT_T1; + length += (uint16_t)hccid->UsbBlkInData.dwLength; + } + } + else + { + hccid->UsbBlkInData.dwLength = 0; + } + + hccid->UsbBlkInData.abData[0] = ProtocolData.bmFindexDindex; + hccid->UsbBlkInData.abData[1] = ProtocolData.bmTCCKST0; + hccid->UsbBlkInData.abData[2] = ProtocolData.bGuardTimeT0; + hccid->UsbBlkInData.abData[3] = ProtocolData.bWaitingIntegerT0; + hccid->UsbBlkInData.abData[4] = ProtocolData.bClockStop; + hccid->UsbBlkInData.abData[5] = ProtocolData.bIfsc; + hccid->UsbBlkInData.abData[6] = ProtocolData.bNad; + + /* bProtocolNum */ + if (ProtocolNUM_OUT == 0x00U) + { + hccid->UsbBlkInData.bSpecific = BPROTOCOL_NUM_T0; + } + else + { + hccid->UsbBlkInData.bSpecific = BPROTOCOL_NUM_T1; + } + (void)USBD_CCID_Transfer_Data_Request(pdev, (uint8_t *)(&hccid->UsbBlkInData), length); +} + +/** + * @brief RDR_to_PC_Escape + * Provide the Escaped data block response to the host + * Response for PC_to_RDR_Escape + * @param errorCode: code to be returned to the host + * @param pdev: device instance + * @retval None + */ +void RDR_to_PC_Escape(uint8_t errorCode, USBD_HandleTypeDef *pdev) +{ + 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; + + hccid->UsbBlkInData.bSpecific = 0U; /* Reserved for Future Use */ + hccid->UsbBlkInData.bError = errorCode; + + if (errorCode == SLOT_NO_ERROR) + { + length += hccid->UsbBlkInData.dwLength; /* Length Specified in Command */ + } + + (void)USBD_CCID_Transfer_Data_Request(pdev, (uint8_t *)(&hccid->UsbBlkInData), (uint16_t)length); +} + +/** + * @brief RDR_to_PC_DataRateAndClockFrequency + * Provide the Clock and Data Rate information to host + * Response for PC_TO_RDR_SetDataRateAndClockFrequency + * @param errorCode: code to be returned to the host + * @param pdev: device instance + * @retval None + */ +void RDR_to_PC_DataRateAndClockFrequency(uint8_t errorCode, USBD_HandleTypeDef *pdev) +{ + 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; + hccid->UsbBlkInData.bError = errorCode; + hccid->UsbBlkInData.bSpecific = 0U; /* Reserved for Future Use */ + + if (errorCode == SLOT_NO_ERROR) + { + length += hccid->UsbBlkInData.dwLength; /* Length Specified in Command */ + } + + (void)USBD_CCID_Transfer_Data_Request(pdev, (uint8_t *)(&hccid->UsbBlkInData), (uint16_t)length); +} + +/** + * @brief RDR_to_PC_NotifySlotChange + * Interrupt message to be sent to the host, Checks the card presence + * status and update the buffer accordingly + * @param pdev: device instance + * @retval None + */ +void RDR_to_PC_NotifySlotChange(USBD_HandleTypeDef *pdev) +{ + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + + hccid->UsbIntData[OFFSET_INT_BMESSAGETYPE] = RDR_TO_PC_NOTIFYSLOTCHANGE; + + if (SC_Detect() != 0U) + { + /* + SLOT_ICC_PRESENT 0x01 : LSb : (0b = no ICC present, 1b = ICC present) + SLOT_ICC_CHANGE 0x02 : MSb : (0b = no change, 1b = change). + */ + hccid->UsbIntData[OFFSET_INT_BMSLOTICCSTATE] = SLOT_ICC_PRESENT | SLOT_ICC_CHANGE; + } + else + { + hccid->UsbIntData[OFFSET_INT_BMSLOTICCSTATE] = SLOT_ICC_CHANGE; + + /* Power OFF the card */ + SC_Itf_IccPowerOff(); + } +} + + +/** + * @brief CCID_UpdSlotStatus + * Updates the variable for the slot status + * @param pdev: device instance + * @param slotStatus : slot status from the calling function + * @retval None + */ +void CCID_UpdSlotStatus(USBD_HandleTypeDef *pdev, uint8_t slotStatus) +{ + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + hccid->SlotStatus.SlotStatus = slotStatus; +} + +/** + * @brief CCID_UpdSlotChange + * Updates the variable for the slot change status + * @param pdev: device instance + * @param changeStatus : slot change status from the calling function + * @retval None + */ +void CCID_UpdSlotChange(USBD_HandleTypeDef *pdev, uint8_t changeStatus) +{ + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + hccid->SlotStatus.SlotStatusChange = changeStatus; +} + +/** + * @brief CCID_IsSlotStatusChange + * Provides the value of the variable for the slot change status + * @param pdev: device instance + * @retval slot change status + */ +uint8_t CCID_IsSlotStatusChange(USBD_HandleTypeDef *pdev) +{ + 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(USBD_HandleTypeDef *pdev, uint8_t cmd_status, uint8_t icc_status) +{ + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + hccid->UsbBlkInData.bStatus = (cmd_status | icc_status); +} +/** + * @brief CCID_CheckCommandParams + * Checks the specific parameters requested by the function and update + * status accordingly. This function is called from all + * PC_to_RDR functions + * @param pdev: device instance + * @param param_type : Parameter enum to be checked by calling function + * @retval status + */ +static uint8_t CCID_CheckCommandParams(USBD_HandleTypeDef *pdev, uint32_t param_type) +{ + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + uint32_t parameter; + uint8_t GetState = SC_GetState(); + + hccid->UsbBlkInData.bStatus = BM_ICC_PRESENT_ACTIVE | BM_COMMAND_STATUS_NO_ERROR; + + parameter = (uint32_t)param_type; + + if ((parameter & CHK_PARAM_SLOT) != 0U) + { + /* + The slot number (bSlot) identifies which ICC slot is being addressed + by the message*/ + + /* SLOT Number is 0 onwards, so always < CCID_NUMBER_OF_SLOTs */ + /* Error Condition !!! */ + if (hccid->UsbBlkOutData.bSlot >= CCID_NUMBER_OF_SLOTS) + { + /* Slot requested is more than supported by Firmware */ + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_NO_ICC_PRESENT)); + return SLOTERROR_BAD_SLOT; + } + } + + if ((parameter & CHK_PARAM_CARD_PRESENT) != 0U) + { + /* Commands Parameters ok, Check the Card Status */ + if (SC_Detect() == 0U) + { + /* Card is Not detected */ + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_NO_ICC_PRESENT)); + return SLOTERROR_ICC_MUTE; + } + } + + /* Check that DwLength is 0 */ + if ((parameter & CHK_PARAM_DWLENGTH) != 0U) + { + if (hccid->UsbBlkOutData.dwLength != 0U) + { + 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 ((hccid->UsbBlkOutData.bSpecific_1 != 0U) || (hccid->UsbBlkOutData.bSpecific_2 != 0U)) + { + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + return SLOTERROR_BAD_ABRFU_2B; /* bSpecific_1 */ + } + } + + 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(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_ACTIVE)); + return SLOTERROR_BAD_ABRFU_3B; + } + } + + if ((parameter & CHK_PARAM_ABORT) != 0U) + { + if (hccid->USBD_CCID_Param.bAbortRequestFlag != 0U) + { + CCID_UpdateCommandStatus(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_INACTIVE)); + return SLOTERROR_CMD_ABORTED; + } + } + + if ((parameter & CHK_ACTIVE_STATE) != 0U) + { + /* Commands Parameters ok, Check the Card Status */ + /* Card is detected */ + + 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(pdev, (BM_COMMAND_STATUS_FAILED), (BM_ICC_PRESENT_INACTIVE)); + return SLOTERROR_HW_ERROR; + } + } + + return 0U; +} diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid_if_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid_if_template.c new file mode 100644 index 0000000000..ea3f1628e3 --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid_if_template.c @@ -0,0 +1,270 @@ +/** + ****************************************************************************** + * @file usbd_ccid_if_template.c + * @author MCD Application Team + * @brief This file provides all the functions for USB Interface for CCID + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ccid.h" +#include "usbd_ccid_if_template.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +static REP_Command_t REP_command; + +/* Private function prototypes -----------------------------------------------*/ +static uint8_t CCID_Init(USBD_HandleTypeDef *pdev); +static uint8_t CCID_DeInit(USBD_HandleTypeDef *pdev); +static uint8_t CCID_ControlReq(uint8_t req, uint8_t *pbuf, uint16_t *length); +static uint8_t CCID_Response_SendData(USBD_HandleTypeDef *pdev, uint8_t *buf, uint16_t len); +static uint8_t CCID_Send_Process(uint8_t *Command, uint8_t *Data); +static uint8_t CCID_Response_Process(void); +static uint8_t CCID_SetSlotStatus(USBD_HandleTypeDef *pdev); + +/* Private functions ---------------------------------------------------------*/ + +/** + * @} + */ + +USBD_CCID_ItfTypeDef USBD_CCID_If_fops = +{ + CCID_Init, + CCID_DeInit, + CCID_ControlReq, + CCID_Response_SendData, + CCID_Send_Process, + CCID_SetSlotStatus, +}; + +/** + * @brief CCID_Init + * Initialize the CCID USB Layer + * @param pdev: device instance + * @retval status value + */ +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 */ + + hccid->blkt_state = CCID_STATE_IDLE; + + return (uint8_t)USBD_OK; +} + +/** + * @brief CCID_DeInit + * Uninitialize the CCID Machine + * @param pdev: device instance + * @retval status value + */ +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; + + return (uint8_t)USBD_OK; +} + +/** + * @brief CCID_ControlReq + * Manage the CCID class requests + * @param Cmd: Command code + * @param Buf: Buffer containing command data (request parameters) + * @param Len: Number of data to be sent (in bytes) + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static uint8_t CCID_ControlReq(uint8_t req, uint8_t *pbuf, uint16_t *length) +{ +#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) + { + case REQUEST_ABORT: + /* The wValue field contains the slot number (bSlot) in the low byte + and the sequence number (bSeq) in the high byte.*/ + hccid->slot_nb = ((uint16_t) * pbuf & 0x0fU); + hccid->seq_nb = (((uint16_t) * pbuf & 0xf0U) >> 8); + + 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 */ + return (int8_t)USBD_FAIL; + } + break; + + case REQUEST_GET_CLOCK_FREQUENCIES: + + /* User have to fill the pbuf with the GetClockFrequency data buffer */ + + break; + + case REQUEST_GET_DATA_RATES: + + /* User have to fill the pbuf with the GetDataRates data buffer */ + + break; + + default: + break; + } + + UNUSED(pbuf); + + return ((int8_t)USBD_OK); +} + +/** + * @brief CCID_Response_SendData + * Send the data on bulk-in EP + * @param pdev: device instance + * @param buf: pointer to data buffer + * @param len: Data Length + * @retval status value + */ +uint8_t CCID_Response_SendData(USBD_HandleTypeDef *pdev, uint8_t *buf, uint16_t len) +{ + (void)USBD_LL_Transmit(pdev, CCID_IN_EP, buf, len); + return (uint8_t)USBD_OK; +} + +/** + * @brief CCID_SEND_Process + * @param Command: pointer to a buffer containing command header + * @param Data: pointer to a buffer containing data sent from Host + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static uint8_t CCID_Send_Process(uint8_t *Command, uint8_t *Data) +{ + Command_State_t Command_State = Command_NOT_OK; + + /* Initialize ICC APP header */ + uint8_t SC_Command[5] = {0}; + UNUSED(Data); + UNUSED(Command_State); + UNUSED(SC_Command); + + /* Start SC Demo ---------------------------------------------------------*/ + switch (Command[1]) /* type of instruction */ + { + case SC_ENABLE: + /* Add your code here */ + break; + + case SC_VERIFY: + /* Add your code here */ + break; + + case SC_READ_BINARY : + /* Add your code here */ + break; + + case SC_CHANGE : + /* Add your code here */ + break; + + default: + break; + } + + /* check if Command header is OK */ + (void)CCID_Response_Process(); /* Get ICC response */ + + return ((uint8_t)USBD_OK); +} + +/** + * @brief CCID_Response_Process + * @param None + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static uint8_t CCID_Response_Process(void) +{ + switch (REP_command) + { + case REP_OK: + /* Add your code here */ + break; + + case REP_NOT_OK : + /* Add your code here */ + break; + + case REP_NOT_SUPP : + /* Add your code here */ + break; + + case REP_ENABLED : + /* Add your code here */ + break; + + case REP_CHANGE : + /* Add your code here */ + break; + + default: + break; + } + + return ((uint8_t)USBD_OK); +} + +/** + * @brief CCID_SetSlotStatus + * Set Slot Status of the Interrupt Transfer + * @param pdev: device instance + * @retval status + */ +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 */ + { + /* Add your code here */ + } + else + { + /* Add your code here */ + } + + return (uint8_t)USBD_OK; +} diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid_sc_if_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid_sc_if_template.c new file mode 100644 index 0000000000..fddf2d0453 --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid_sc_if_template.c @@ -0,0 +1,473 @@ +/** + ****************************************************************************** + * @file usbd_ccid_sc_if_template.c + * @author MCD Application Team + * @brief SmartCard Interface 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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ccid_sc_if_template.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* State Machine for the SmartCard Interface */ +static SC_State SCState = SC_POWER_OFF; + +/* APDU Transport Structures */ +SC_ADPU_CommandsTypeDef SC_ADPU; +SC_ADPU_ResponseTypeDef SC_Response; +SC_Param_t SC_Param; +Protocol_01_DataTypeDef ProtocolData; + +/* Extern variables ----------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static void SC_SaveVoltage(uint8_t voltage); +static void SC_Itf_UpdateParams(void); + +/* Private functions ---------------------------------------------------------*/ +/** + * @brief SC_Itf_IccPowerOn Manages the Warm and Cold Reset + and get the Answer to Reset from ICC + * @param voltage: required by host + * @retval None + */ +void SC_Itf_IccPowerOn(uint8_t voltage) +{ + SCState = SC_POWER_ON; + SC_ADPU.Header.CLA = 0x00U; + SC_ADPU.Header.INS = SC_GET_A2R; + SC_ADPU.Header.P1 = 0x00U; + SC_ADPU.Header.P2 = 0x00U; + SC_ADPU.Body.LC = 0x00U; + + /* Power ON the card */ + SC_PowerCmd(SC_ENABLED); + + /* Configure the Voltage, Even if IO is still not configured */ + SC_VoltageConfig(voltage); + + while ((SCState != SC_ACTIVE_ON_T0) && (SCState != SC_ACTIVE_ON_T1) + && (SCState != SC_NO_INIT)) + { + /* If Either The Card has become Active or Become De-Active */ + SC_Handler(&SCState, &SC_ADPU, &SC_Response); + } + + if ((SCState == SC_ACTIVE_ON_T0) || (SCState == SC_ACTIVE_ON_T1)) + { + SC_Itf_UpdateParams(); + /* Apply the Procedure Type Selection (PTS) */ + SC_PTSConfig(); + + /* Save Voltage for Future use */ + SC_SaveVoltage(voltage); + } + + return; +} + +/** + * @brief SC_Itf_IccPowerOff Power OFF the card + * @param None + * @retval None + */ +void SC_Itf_IccPowerOff(void) +{ + SC_PowerCmd(SC_DISABLED); + SC_SetState(SC_POWER_OFF); + + return; +} + +/** + * @brief Initialize the parameters structures to the default value + * @param None + * @retval None + */ +void SC_Itf_InitParams(void) +{ + /* + FI, the reference to a clock rate conversion factor + over the bits b8 to b5 + - DI, the reference to a baud rate adjustment factor + over the bits b4 to bl + */ + SC_Param.SC_A2R_FiDi = DEFAULT_FIDI; + SC_Param.SC_hostFiDi = DEFAULT_FIDI; + + ProtocolData.bmFindexDindex = DEFAULT_FIDI; + + /* Placeholder, Ignored */ + /* 0 = Direct, first byte of the ICC ATR data. */ + ProtocolData.bmTCCKST0 = DEFAULT_T01CONVCHECKSUM; + + /* Extra GuardTime = 0 etu */ + ProtocolData.bGuardTimeT0 = DEFAULT_EXTRA_GUARDTIME; + ProtocolData.bWaitingIntegerT0 = DEFAULT_WAITINGINTEGER; + ProtocolData.bClockStop = 0U; /* Stopping the Clock is not allowed */ + + /*T=1 protocol */ + ProtocolData.bIfsc = DEFAULT_IFSC; + ProtocolData.bNad = DEFAULT_NAD; + + return; +} + +/** + * @brief Save the A2R Parameters for further usage + * @param None + * @retval None + */ +static void SC_Itf_UpdateParams(void) +{ + /* + FI, the reference to a clock rate conversion factor + over the bits b8 to b5 + DI, the reference to a baud rate adjustment factor + over the bits b4 to bl + */ + SC_Param.SC_A2R_FiDi = SC_A2R.T[0].InterfaceByte[0].Value; + SC_Param.SC_hostFiDi = SC_A2R.T[0].InterfaceByte[0].Value; + + ProtocolData.bmFindexDindex = SC_A2R.T[0].InterfaceByte[0].Value; + + return; +} + +/** + * @brief SC_Itf_SetParams + * Set the parameters for CCID/USART interface + * @param pPtr: pointer to buffer containing the + * parameters to be set in USART + * @param T_01: type of protocol, T=1 or T=0 + * @retval status value + */ +uint8_t SC_Itf_SetParams(Protocol_01_DataTypeDef *pPtr, uint8_t T_01) +{ + /* uint16_t guardTime; */ /* Keep it 16b for handling 8b additions */ + uint32_t fi_new; + uint32_t di_new; + Protocol_01_DataTypeDef New_DataStructure; + fi_new = pPtr->bmFindexDindex; + di_new = pPtr->bmFindexDindex; + + New_DataStructure.bmTCCKST0 = pPtr->bmTCCKST0; + + New_DataStructure.bGuardTimeT0 = pPtr->bGuardTimeT0; + New_DataStructure.bWaitingIntegerT0 = pPtr->bWaitingIntegerT0; + New_DataStructure.bClockStop = pPtr->bClockStop; + if (T_01 == 0x01U) + { + New_DataStructure.bIfsc = pPtr->bIfsc; + New_DataStructure.bNad = pPtr->bNad; + } + else + { + New_DataStructure.bIfsc = 0x00U; + New_DataStructure.bNad = 0x00U; + } + + /* Check for the FIDI Value set by Host */ + di_new &= (uint8_t)0x0F; + if (SC_GetDTableValue(di_new) == 0U) + { + return SLOTERROR_BAD_FIDI; + } + + fi_new >>= 4U; + fi_new &= 0x0FU; + + if (SC_GetDTableValue(fi_new) == 0U) + { + return SLOTERROR_BAD_FIDI; + } + + if ((T_01 == 0x00U) + && (New_DataStructure.bmTCCKST0 != 0x00U) + && (New_DataStructure.bmTCCKST0 != 0x02U)) + { + return SLOTERROR_BAD_T01CONVCHECKSUM; + } + + if ((T_01 == 0x01U) + && (New_DataStructure.bmTCCKST0 != 0x10U) + && (New_DataStructure.bmTCCKST0 != 0x11U) + && (New_DataStructure.bmTCCKST0 != 0x12U) + && (New_DataStructure.bmTCCKST0 != 0x13U)) + { + return SLOTERROR_BAD_T01CONVCHECKSUM; + } + + if ((New_DataStructure.bWaitingIntegerT0 >= 0xA0U) + && ((New_DataStructure.bmTCCKST0 & 0x10U) == 0x10U)) + { + return SLOTERROR_BAD_WAITINGINTEGER; + } + if ((New_DataStructure.bClockStop != 0x00U) + && (New_DataStructure.bClockStop != 0x03U)) + { + return SLOTERROR_BAD_CLOCKSTOP; + } + if (New_DataStructure.bNad != 0x00U) + { + return SLOTERROR_BAD_NAD; + } + /* Put Total GuardTime in USART Settings */ + /* USART_SetGuardTime(SC_USART, (uint8_t)(guardTime + DEFAULT_EXTRA_GUARDTIME)); */ + + /* Save Extra GuardTime Value */ + ProtocolData.bGuardTimeT0 = New_DataStructure.bGuardTimeT0; + ProtocolData.bmTCCKST0 = New_DataStructure.bmTCCKST0; + ProtocolData.bWaitingIntegerT0 = New_DataStructure.bWaitingIntegerT0; + ProtocolData.bClockStop = New_DataStructure.bClockStop; + ProtocolData.bIfsc = New_DataStructure.bIfsc; + ProtocolData.bNad = New_DataStructure.bNad; + + /* Save New bmFindexDindex */ + SC_Param.SC_hostFiDi = pPtr->bmFindexDindex; + SC_PTSConfig(); + + ProtocolData.bmFindexDindex = pPtr->bmFindexDindex; + + return SLOT_NO_ERROR; +} + +/** + * @brief SC_Itf_Escape function from the host + * This is user implementable + * @param ptrEscape: pointer to buffer containing the Escape data + * @param escapeLen: length of escaped data + * @param responseBuff: pointer containing escape buffer response + * @param responseLen: length of escape response buffer + * @retval status value + */ +uint8_t SC_Itf_Escape(uint8_t *ptrEscape, uint32_t escapeLen, + uint8_t *responseBuff, uint32_t *responseLen) +{ + UNUSED(ptrEscape); + UNUSED(escapeLen); + UNUSED(responseBuff); + UNUSED(responseLen); + + /* Manufacturer specific implementation ... */ + /* + uint32_t idx; + uint8_t *pResBuff = responseBuff; + uint8_t *pEscape = ptrEscape; + + for(idx = 0; idx < escapeLen; idx++) + { + *pResBuff = *pEscape; + pResBuff++; + pEscape++; + } + + *responseLen = escapeLen; + */ + return SLOT_NO_ERROR; +} + +/** + * @brief SC_Itf_SetClock function to define Clock Status request from the host. + * This is user implementable + * @param bClockCommand: Clock status from the host + * @retval status value + */ +uint8_t SC_Itf_SetClock(uint8_t bClockCommand) +{ + /* bClockCommand + 00h restarts Clock + 01h Stops Clock in the state shown in the bClockStop + field of the PC_to_RDR_SetParameters command + and RDR_to_PC_Parameters message.*/ + + if (bClockCommand == 0U) + { + /* 00h restarts Clock : Since Clock is always running, PASS this command */ + return SLOT_NO_ERROR; + } + else + { + if (bClockCommand == 1U) + { + return SLOTERROR_BAD_CLOCKCOMMAND; + } + } + + return SLOTERROR_CMD_NOT_SUPPORTED; +} + +/** + * @brief SC_Itf_XferBlock function from the host. + * This is user implementable + * @param ptrBlock : Pointer containing the data from host + * @param blockLen : length of block data for the data transfer + * @param expectedLen: expected length of data transfer + * @param CCID_BulkIn_Data: Pointer containing the CCID Bulk In Data Structure + * @retval status value + */ +uint8_t SC_Itf_XferBlock(uint8_t *ptrBlock, uint32_t blockLen, uint16_t expectedLen, + USBD_CCID_BulkIn_DataTypeDef *CCID_BulkIn_Data) +{ + uint8_t ErrorCode = SLOT_NO_ERROR; + UNUSED(CCID_BulkIn_Data); + UNUSED(expectedLen); + UNUSED(blockLen); + UNUSED(ptrBlock); + + if (ProtocolNUM_OUT == 0x00U) + { + /* Add your code here */ + } + + if (ProtocolNUM_OUT == 0x01U) + { + /* Add your code here */ + } + + if (ErrorCode != SLOT_NO_ERROR) + { + return ErrorCode; + } + + return ErrorCode; +} + + +/** + * @brief SC_Itf_T0Apdu + Class Specific Request from the host to provide supported data rates + * This is Optional function & user implementable + * @param bmChanges : value specifying which parameter is valid in + * command among next bClassGetResponse, bClassEnvelope + * @param bClassGetResponse : Value to force the class byte of the + * header in a Get Response command. + * @param bClassEnvelope : Value to force the class byte of the header + * in a Envelope command. + * @retval status value + */ +uint8_t SC_Itf_T0Apdu(uint8_t bmChanges, uint8_t bClassGetResponse, + uint8_t bClassEnvelope) +{ + UNUSED(bClassEnvelope); + UNUSED(bClassGetResponse); + + /* User have to fill the pbuf with the GetDataRates data buffer */ + + if (bmChanges == 0U) + { + /* Bit cleared indicates that the associated field is not significant and + that default behaviour defined in CCID class descriptor is selected */ + return SLOT_NO_ERROR; + } + + return SLOTERROR_CMD_NOT_SUPPORTED; +} + +/** + * @brief SC_Itf_Mechanical + Mechanical Function being requested by Host + * This is Optional function & user implementable + * @param bFunction : value corresponds to the mechanical function + * being requested by host + * @retval status value + */ +uint8_t SC_Itf_Mechanical(uint8_t bFunction) +{ + UNUSED(bFunction); + + return SLOTERROR_CMD_NOT_SUPPORTED; +} + +/** + * @brief SC_Itf_SetDataRateAndClockFrequency + * Set the Clock and data Rate of the Interface + * This is Optional function & user implementable + * @param dwClockFrequency : value of clock in kHz requested by host + * @param dwDataRate : value of data rate requested by host + * @retval status value + */ +uint8_t SC_Itf_SetDataRateAndClockFrequency(uint32_t dwClockFrequency, + uint32_t dwDataRate) +{ + /* User have to fill the pbuf with the GetDataRates data buffer */ + + if ((dwDataRate == USBD_CCID_DEFAULT_DATA_RATE) && + (dwClockFrequency == USBD_CCID_DEFAULT_CLOCK_FREQ)) + { + return SLOT_NO_ERROR; + } + + return SLOTERROR_CMD_NOT_SUPPORTED; +} + +/** + * @brief SC_Itf_Secure + * Process the Secure command + * This is Optional function & user implementable + * @param dwLength : length of data from the host + * @param bBWI : Block Waiting Timeout sent by host + * @param wLevelParameter : Parameters sent by host + * @param pbuf : buffer containing the data + * @param returnLen : Length of data expected to return + * @retval status value + */ +uint8_t SC_Itf_Secure(uint32_t dwLength, uint8_t bBWI, uint16_t wLevelParameter, + uint8_t *pbuf, uint32_t *returnLen) +{ + UNUSED(pbuf); + UNUSED(wLevelParameter); + UNUSED(bBWI); + UNUSED(dwLength); + *returnLen = 0U; + + return SLOTERROR_CMD_NOT_SUPPORTED; +} + +/** + * @brief SC_SaveVoltage + Saves the voltage value to be saved for further usage + * @param voltage: voltage value to be saved for further usage + * @retval None + */ +static void SC_SaveVoltage(uint8_t voltage) +{ + SC_Param.voltage = voltage; + + return; +} + +/** + * @brief Provides the value of SCState variable + * @param None + * @retval uint8_t SCState + */ +uint8_t SC_GetState(void) +{ + return (uint8_t)SCState; +} + +/** + * @brief Set the value of SCState variable to Off + * @param scState: value of SCState to be updated + * @retval None + */ +void SC_SetState(SC_State scState) +{ + SCState = scState; + + return; +} diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid_smartcard_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid_smartcard_template.c new file mode 100644 index 0000000000..059aef4e33 --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid_smartcard_template.c @@ -0,0 +1,486 @@ +/** + ****************************************************************************** + * @file usbd_ccid_smartcard_template.c + * @author MCD Application Team + * @brief This file provides all the Smartcard firmware 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. + * + ****************************************************************************** + */ + +/** @addtogroup usbd_ccid_Smartcard + * @{ + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ccid_smartcard_template.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Directories & Files ID */ +/*The following Directories & Files ID can take any of following Values and can + be used in the smartcard application */ +/* +const uint8_t MasterRoot[2] = {0x3F, 0x00}; +const uint8_t GSMDir[2] = {0x7F, 0x20}; +const uint8_t ICCID[2] = {0x2F, 0xE2}; +const uint8_t IMSI[2] = {0x6F, 0x07}; + +__IO uint8_t ICCID_Content[10] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +uint32_t CHV1Status = 0U; + +uint8_t CHV1[8] = {'0', '0', '0', '0', '0', '0', '0', '0'}; +__IO uint8_t IMSI_Content[9] = {0x01, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +*/ + +/* F Table: Clock Rate Conversion Table from ISO/IEC 7816-3 */ +/* static uint32_t F_Table[16] = {372, 372, 558, 744, 1116, 1488, 1860, 0, 0, 512, 768, + 1024, 1536, 2048, 0, 0 + }; */ + + +/* D Table: Baud Rate Adjustment Factor Table from ISO/IEC 7816-3 */ +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_ATRTypeDef SC_A2R; +uint8_t SC_ATR_Table[40]; +uint8_t ProtocolNUM_OUT; + +/* Private function prototypes -----------------------------------------------*/ +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_CommandsTypeDef *SCADPU, SC_ADPU_ResponseTypeDef *SC_ResponseStatus); +/* static void SC_Reset(GPIO_PinState ResetState); */ + +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief Handles all Smartcard states and serves to send and receive all + * communication data between Smartcard and reader. + * @param SCState: pointer to an SC_State enumeration that will contain the + * Smartcard state. + * @param SC_ADPU: pointer to an SC_ADPU_Commands structure that will be initialized. + * @param SC_Response: pointer to a SC_ADPU_Response structure which will be initialized. + * @retval None + */ +void SC_Handler(SC_State *SCState, SC_ADPU_CommandsTypeDef *SC_ADPU, SC_ADPU_ResponseTypeDef *SC_Response) +{ + uint32_t i; + uint32_t j; + + switch (*SCState) + { + case SC_POWER_ON: + if (SC_ADPU->Header.INS == SC_GET_A2R) + { + /* Smartcard initialization */ + SC_Init(); + + /* Reset Data from SC buffer */ + for (i = 0U; i < 40U; i++) + { + SC_ATR_Table[i] = 0; + } + + /* Reset SC_A2R Structure */ + SC_A2R.TS = 0U; + SC_A2R.T0 = 0U; + + for (i = 0U; i < MAX_PROTOCOLLEVEL; i++) + { + for (j = 0U; j < MAX_INTERFACEBYTE; j++) + { + SC_A2R.T[i].InterfaceByte[j].Status = 0U; + SC_A2R.T[i].InterfaceByte[j].Value = 0U; + } + } + + for (i = 0U; i < HIST_LENGTH; i++) + { + SC_A2R.Historical[i] = 0U; + } + + SC_A2R.Tlength = 0U; + SC_A2R.Hlength = 0U; + + /* Next State */ + *SCState = SC_RESET_LOW; + } + break; + + case SC_RESET_LOW: + if (SC_ADPU->Header.INS == SC_GET_A2R) + { + /* If card is detected then Power ON, Card Reset and wait for an answer) */ + if (SC_Detect() != 0U) + { + while (((*SCState) != SC_POWER_OFF) && ((*SCState) != SC_ACTIVE)) + { + SC_AnswerReq(SCState, &SC_ATR_Table[0], 40U); /* Check for answer to reset */ + } + } + else + { + (*SCState) = SC_POWER_OFF; + } + } + break; + + case SC_ACTIVE: + if (SC_ADPU->Header.INS == SC_GET_A2R) + { + uint8_t protocol = SC_decode_Answer2reset(&SC_ATR_Table[0]); + if (protocol == T0_PROTOCOL) + { + (*SCState) = SC_ACTIVE_ON_T0; + ProtocolNUM_OUT = T0_PROTOCOL; + } + else if (protocol == T1_PROTOCOL) + { + (*SCState) = SC_ACTIVE_ON_T1; + ProtocolNUM_OUT = T1_PROTOCOL; + } + else + { + (*SCState) = SC_POWER_OFF; + } + } + break; + + case SC_ACTIVE_ON_T0: + /* process commands other than ATR */ + SC_SendData(SC_ADPU, SC_Response); + break; + + case SC_ACTIVE_ON_T1: + /* process commands other than ATR */ + SC_SendData(SC_ADPU, SC_Response); + break; + + case SC_POWER_OFF: + SC_DeInit(); /* Disable Smartcard interface */ + break; + + default: + (*SCState) = SC_POWER_OFF; + break; + } +} + +/** + * @brief Enables or disables the power to the Smartcard. + * @param NewState: new state of the Smartcard power supply. + * This parameter can be: SC_ENABLED or SC_DISABLED. + * @retval None + */ +void SC_PowerCmd(SCPowerState NewState) +{ + UNUSED(NewState); + /* enable or disable smartcard pin */ + + return; +} + +/** + * @brief Sets or clears the Smartcard reset pin. + * @param ResetState: this parameter specifies the state of the Smartcard + * reset pin. BitVal must be one of the BitAction enum values: + * @arg Bit_RESET: to clear the port pin. + * @arg Bit_SET: to set the port pin. + * @retval None + */ +/* static void SC_Reset(GPIO_PinState ResetState) +{ + UNUSED(ResetState); + + return; +} +*/ + + +/** + * @brief Resends the byte that failed to be received (by the Smartcard) correctly. + * @param None + * @retval None + */ + +void SC_ParityErrorHandler(void) +{ + /* Add your code here */ + + return; +} + +/** + * @brief Configures the IO speed (BaudRate) communication. + * @param None + * @retval None + */ + +void SC_PTSConfig(void) +{ + /* Add your code here */ + + return; +} + + +/** + * @brief Manages the Smartcard transport layer: send APDU commands and receives + * the APDU response. + * @param SC_ADPU: pointer to a SC_ADPU_Commands structure which will be initialized. + * @param SC_Response: pointer to a SC_ADPU_Response structure which will be initialized. + * @retval None + */ +static void SC_SendData(SC_ADPU_CommandsTypeDef *SCADPU, SC_ADPU_ResponseTypeDef *SC_ResponseStatus) +{ + uint8_t i; + uint8_t SC_Command[5]; + uint8_t SC_DATA[LC_MAX]; + + UNUSED(SCADPU); + + /* Reset response buffer */ + for (i = 0U; i < LC_MAX; i++) + { + SC_ResponseStatus->Data[i] = 0U; + SC_DATA[i] = 0U; + } + + /* User to add code here */ + + /* send command to ICC and get response status */ + USBD_CCID_If_fops.Send_Process((uint8_t *)&SC_Command, (uint8_t *)&SC_DATA); + +} + +/** + * @brief SC_AnswerReq + Requests the reset answer from card. + * @param SC_state: pointer to an SC_State enumeration that will contain the Smartcard state. + * @param atr_buffer: pointer to a buffer which will contain the card ATR. + * @param length: maximum ATR length + * @retval None + */ +static void SC_AnswerReq(SC_State *SC_state, uint8_t *atr_buffer, uint8_t length) +{ + UNUSED(length); + UNUSED(atr_buffer); + + /* to be implemented by USER */ + switch (*SC_state) + { + case SC_RESET_LOW: + /* Check response with reset low */ + (*SC_state) = SC_ACTIVE; + break; + + case SC_ACTIVE: + break; + case SC_RESET_HIGH: + /* Check response with reset high */ + + break; + + case SC_POWER_OFF: + /* Close Connection if no answer received */ + + break; + + default: + (*SC_state) = SC_RESET_LOW; + break; + } + + return; +} + +/** + * @brief SC_decode_Answer2reset + Decodes the Answer to reset received from card. + * @param card: pointer to the buffer containing the card ATR. + * @retval None + */ +static uint8_t SC_decode_Answer2reset(uint8_t *card) +{ + uint32_t i = 0U; + uint32_t flag = 0U; + uint32_t protocol; + uint8_t index = 0U; + uint8_t level = 0U; + + /******************************TS/T0 Decode************************************/ + index++; + SC_A2R.TS = card[index]; /* Initial character */ + + index++; + SC_A2R.T0 = card[index]; /* Format character */ + + /*************************Historical Table Length Decode***********************/ + SC_A2R.Hlength = SC_A2R.T0 & 0x0FU; + + /******************************Protocol Level(1) Decode************************/ + /* Check TD(1) if present */ + if ((SC_A2R.T0 & 0x80U) == 0x80U) + { + flag = 1U; + } + + /* Each bits in the T0 high nibble(b8 to b5) equal to 1 indicates the presence + of a further interface byte */ + for (i = 0U; i < 4U; i++) + { + if ((((SC_A2R.T0 & 0xF0U) >> (4U + i)) & 0x1U) != 0U) + { + SC_A2R.T[level].InterfaceByte[i].Status = 1U; + index++; + SC_A2R.T[level].InterfaceByte[i].Value = card[index]; + SC_A2R.Tlength++; + } + } + + /*****************************T Decode*****************************************/ + if (SC_A2R.T[level].InterfaceByte[3].Status == 1U) + { + /* Only the protocol(parameter T) present in TD(1) is detected + if two or more values of parameter T are present in TD(1), TD(2)..., so the + firmware should be updated to support them */ + protocol = (uint8_t)(SC_A2R.T[level].InterfaceByte[SC_INTERFACEBYTE_TD].Value & 0x0FU); + } + else + { + protocol = 0U; + } + + /* Protocol Level Increment */ + /******************************Protocol Level(n>1) Decode**********************/ + while (flag != 0U) + { + if ((SC_A2R.T[level].InterfaceByte[SC_INTERFACEBYTE_TD].Value & 0x80U) == 0x80U) + { + flag = 1U; + } + else + { + flag = 0U; + } + /* Each bits in the high nibble(b8 to b5) for the TD(i) equal to 1 indicates + the presence of a further interface byte */ + for (i = 0U; i < 4U; i++) + { + if ((((SC_A2R.T[level].InterfaceByte[SC_INTERFACEBYTE_TD].Value & 0xF0U) >> (4U + i)) & 0x1U) != 0U) + { + SC_A2R.T[level + 1U].InterfaceByte[i].Status = 1U; + index++; + SC_A2R.T[level + 1U].InterfaceByte[i].Value = card[index]; + SC_A2R.Tlength++; + } + } + level++; + } + + for (i = 0U; i < SC_A2R.Hlength; i++) + { + SC_A2R.Historical[i] = card[i + 2U + SC_A2R.Tlength]; + } + /*************************************TCK Decode*******************************/ + SC_A2R.TCK = card[SC_A2R.Hlength + 2U + SC_A2R.Tlength]; + + return (uint8_t)protocol; +} + +/** + * @brief Initializes all peripheral used for Smartcard interface. + * @param None + * @retval None + */ +static void SC_Init(void) +{ + /* + Add your initialization code here + */ + + return; +} + + +/** + * @brief Deinitializes all resources used by the Smartcard interface. + * @param None + * @retval None + */ +static void SC_DeInit(void) +{ + /* + Add your deinitialization code here + */ + + return; +} + +/** + * @brief Configures the card power voltage. + * @param SC_Voltage: specifies the card power voltage. + * This parameter can be one of the following values: + * @arg SC_VOLTAGE_5V: 5V cards. + * @arg SC_VOLTAGE_3V: 3V cards. + * @retval None + */ +void SC_VoltageConfig(uint32_t SC_Voltage) +{ + UNUSED(SC_Voltage); + /* Add your code here */ + + return; +} + +/** + * @brief Configures GPIO hardware resources used for Samrtcard. + * @param None + * @retval None + */ +void SC_IOConfig(void) +{ + /* Add your code here */ + + return; +} + +/** + * @brief Detects whether the Smartcard is present or not. + * @param None. + * @retval 1 - Smartcard inserted + * 0 - Smartcard not inserted + */ +uint8_t SC_Detect(void) +{ + uint8_t PIN_State = 0U; + + /* Add your code here */ + + return PIN_State; +} + +/** + * @brief Get the Right Value from the D_Table Index + * @param idx : Index to Read from the Table + * @retval Value read from the Table + */ +uint32_t SC_GetDTableValue(uint32_t idx) +{ + return D_Table[idx]; +} diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h index cb5c6d8ae8..aeac6bf588 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -41,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 @@ -149,12 +154,17 @@ extern USBD_ClassTypeDef USBD_CDC; uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_CDC_ItfTypeDef *fops); +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, + uint32_t length, uint8_t ClassId); +uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t ClassId); +#else uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uint32_t length); - +uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev); +#endif /* USE_USBD_COMPOSITE */ uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff); uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev); -uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev); /** * @} */ @@ -172,4 +182,3 @@ uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev); * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc_if_template.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc_if_template.h index 158ad40c2f..6a1c0abf3d 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc_if_template.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc_if_template.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -42,4 +41,3 @@ extern USBD_CDC_ItfTypeDef USBD_CDC_Template_fops; #endif /* __USBD_CDC_IF_TEMPLATE_H */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c index d6ed6ce316..ad8da254e0 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c @@ -10,6 +10,17 @@ * - Command IN transfer (class requests management) * - Error management * + ****************************************************************************** + * @attention + * + * Copyright (c) 2015 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 * * =================================================================== @@ -37,17 +48,6 @@ * @endverbatim * ****************************************************************************** - * @attention - * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** */ /* BSPDependencies @@ -105,13 +105,14 @@ 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 +127,7 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_ 0x01, 0x00, }; - +#endif /* USE_USBD_COMPOSITE */ /** * @} */ @@ -149,113 +150,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 +174,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 +263,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 +293,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, (uint8_t)pdev->classId); + CDCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); + CDCCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId); +#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 +389,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, (uint8_t)pdev->classId); + CDCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); + CDCCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId); +#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 +432,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 +450,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 +467,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; @@ -690,20 +536,20 @@ static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) { USBD_CDC_HandleTypeDef *hcdc; - PCD_HandleTypeDef *hpcd = pdev->pData; + 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 +558,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 +576,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 +589,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,64 +602,115 @@ 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 - * @param speed : current device speed * @param length : pointer data length * @retval pointer to descriptor buffer */ 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); + + if (pEpCmdDesc != NULL) + { + pEpCmdDesc->bInterval = CDC_FS_BINTERVAL; + } - return USBD_CDC_CfgFSDesc; + 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; } /** * @brief USBD_CDC_GetHSCfgDesc * Return configuration descriptor - * @param speed : current device speed * @param length : pointer data length * @retval pointer to descriptor buffer */ 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; } /** * @brief USBD_CDC_GetOtherSpeedCfgDesc * Return configuration descriptor - * @param speed : current device speed * @param length : pointer data length * @retval pointer to descriptor buffer */ 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; } /** @@ -828,7 +725,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 @@ -843,21 +740,31 @@ 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; } + /** * @brief USBD_CDC_SetTxBuffer * @param pdev: device instance * @param pbuff: Tx Buffer + * @param length: length of data to be sent + * @param ClassId: The Class ID * @retval status */ +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, + uint8_t *pbuff, uint32_t length, uint8_t ClassId) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[ClassId]; +#else 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]; +#endif /* USE_USBD_COMPOSITE */ if (hcdc == NULL) { @@ -878,7 +785,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) { @@ -890,18 +797,32 @@ uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff) return (uint8_t)USBD_OK; } + /** * @brief USBD_CDC_TransmitPacket * Transmit packet on IN endpoint * @param pdev: device instance + * @param ClassId: The Class ID * @retval status */ +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t ClassId) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[ClassId]; +#else 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]; +#endif /* USE_USBD_COMPOSITE */ + 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, ClassId); +#endif /* USE_USBD_COMPOSITE */ + + if (hcdc == NULL) { return (uint8_t)USBD_FAIL; } @@ -912,10 +833,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; } @@ -931,9 +852,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]; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + CDCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ - if (pdev->pClassData == NULL) + if (pdev->pClassDataCmsit[pdev->classId] == NULL) { return (uint8_t)USBD_FAIL; } @@ -941,13 +867,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); } @@ -965,4 +891,3 @@ uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev) * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc_if_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc_if_template.c index f863ce1bbb..df16834bbb 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc_if_template.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc_if_template.c @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -128,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: @@ -244,5 +245,3 @@ static int8_t TEMPLATE_TransmitCplt(uint8_t *Buf, uint32_t *Len, uint8_t epnum) * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Inc/usbd_cdc_ecm.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Inc/usbd_cdc_ecm.h index 1cd71fa17f..a69c4fd2e6 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Inc/usbd_cdc_ecm.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Inc/usbd_cdc_ecm.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2019 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -43,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 */ @@ -173,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 */ @@ -194,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 * @{ @@ -225,17 +243,21 @@ extern USBD_ClassTypeDef USBD_CDC_ECM; uint8_t USBD_CDC_ECM_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_CDC_ECM_ItfTypeDef *fops); -uint8_t USBD_CDC_ECM_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, - uint32_t length); - uint8_t USBD_CDC_ECM_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff); uint8_t USBD_CDC_ECM_ReceivePacket(USBD_HandleTypeDef *pdev); +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_CDC_ECM_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t ClassId); +uint8_t USBD_CDC_ECM_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, + uint32_t length, uint8_t ClassId); +#else uint8_t USBD_CDC_ECM_TransmitPacket(USBD_HandleTypeDef *pdev); - +uint8_t USBD_CDC_ECM_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, + uint32_t length); +#endif /* USE_USBD_COMPOSITE */ uint8_t USBD_CDC_ECM_SendNotification(USBD_HandleTypeDef *pdev, - USBD_CDC_ECM_NotifCodeTypeDef Notif, + USBD_CDC_NotifCodeTypeDef Notif, uint16_t bVal, uint8_t *pData); /** * @} @@ -254,4 +276,3 @@ uint8_t USBD_CDC_ECM_SendNotification(USBD_HandleTypeDef *pdev, * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Inc/usbd_cdc_ecm_if_template.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Inc/usbd_cdc_ecm_if_template.h index 7ce8714dfb..c08f0f3fcb 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Inc/usbd_cdc_ecm_if_template.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Inc/usbd_cdc_ecm_if_template.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2019 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -79,4 +78,3 @@ extern USBD_CDC_ECM_ItfTypeDef USBD_CDC_ECM_fops; /* Exported functions ------------------------------------------------------- */ #endif /* __USBD_CDC_ECM_IF_H */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Src/usbd_cdc_ecm.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Src/usbd_cdc_ecm.c index 4b34d7c937..ec63252663 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Src/usbd_cdc_ecm.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Src/usbd_cdc_ecm.c @@ -13,13 +13,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2019 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -35,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 @@ -84,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 = { @@ -111,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 }; @@ -138,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 -}; - -/* 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 */ +#endif /* USBD_SUPPORT_USER_STRING_DESC */ }; - +#ifndef USE_USBD_COMPOSITE /* 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 */ @@ -269,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) */ /*---------------------------------------------------------------------------*/ @@ -369,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; /** * @} @@ -500,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, (uint8_t)pdev->classId); + ECMOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); + ECMCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId); +#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; @@ -559,10 +364,16 @@ static uint8_t USBD_CDC_ECM_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) hcdc->TxLength = 0U; hcdc->LinkStatus = 0U; 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; + 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; } @@ -578,24 +389,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, (uint8_t)pdev->classId); + ECMOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); + ECMCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId); +#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; } @@ -609,11 +428,10 @@ static uint8_t USBD_CDC_ECM_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) * @param req: usb requests * @retval status */ -static uint8_t USBD_CDC_ECM_Setup(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req) +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; @@ -631,8 +449,7 @@ static uint8_t USBD_CDC_ECM_Setup(USBD_HandleTypeDef *pdev, { if ((req->bmRequest & 0x80U) != 0U) { - EcmInterface->Control(req->bRequest, - (uint8_t *)hcdc->data, req->wLength); + EcmInterface->Control(req->bRequest, (uint8_t *)hcdc->data, req->wLength); len = MIN(CDC_ECM_DATA_BUFFER_SIZE, req->wLength); (void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data, len); @@ -714,21 +531,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; - PCD_HandleTypeDef *hpcd = pdev->pData; + 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, (uint8_t)pdev->classId); +#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); @@ -736,18 +558,18 @@ 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) { - (void)USBD_CDC_ECM_SendNotification(pdev, CONNECTION_SPEED_CHANGE, - 0U, (uint8_t *)ConnSpeedTab); + (void)USBD_CDC_ECM_SendNotification(pdev, CONNECTION_SPEED_CHANGE, 0U, (uint8_t *)ConnSpeedTab); hcdc->NotificationStatus = 0U; } @@ -769,15 +591,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, (uint8_t)pdev->classId); +#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); @@ -793,12 +620,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); } @@ -819,64 +646,115 @@ 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 - * @param speed : current device speed * @param length : pointer data length * @retval pointer to descriptor buffer */ 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); + + 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; + } - return USBD_CDC_ECM_CfgFSDesc; + *length = (uint16_t) sizeof(USBD_CDC_ECM_CfgDesc); + return USBD_CDC_ECM_CfgDesc; } /** * @brief USBD_CDC_ECM_GetHSCfgDesc * Return configuration descriptor - * @param speed : current device speed * @param length : pointer data length * @retval pointer to descriptor buffer */ 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; } /** * @brief USBD_CDC_ECM_GetCfgDesc * Return configuration descriptor - * @param speed : current device speed * @param length : pointer data length * @retval pointer to descriptor buffer */ 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); + + if (pEpCmdDesc != NULL) + { + pEpCmdDesc->bInterval = CDC_ECM_FS_BINTERVAL; + } - return USBD_CDC_ECM_OtherSpeedCfgDesc; + 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; } /** @@ -891,7 +769,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 @@ -906,7 +784,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; } @@ -915,7 +793,7 @@ uint8_t USBD_CDC_ECM_RegisterInterface(USBD_HandleTypeDef *pdev, /** * @brief USBD_CDC_ECM_USRStringDescriptor * Manages the transfer of user string descriptors. - * @param speed : current device speed + * @param pdev: device instance * @param index: descriptor index * @param length : pointer data length * @retval pointer to the descriptor table or NULL if the descriptor is not supported. @@ -928,7 +806,10 @@ 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 */ @@ -937,17 +818,25 @@ 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 * @param pdev: device instance * @param pbuff: Tx Buffer + * @param length: Tx Buffer length + * @param ClassId: The Class ID * @retval status */ +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_CDC_ECM_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uint32_t length, uint8_t ClassId) +{ + USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassDataCmsit[ClassId]; +#else 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]; +#endif /* USE_USBD_COMPOSITE */ if (hcdc == NULL) { @@ -969,7 +858,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) { @@ -981,18 +870,32 @@ uint8_t USBD_CDC_ECM_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff) return (uint8_t)USBD_OK; } + /** * @brief USBD_CDC_ECM_TransmitPacket * Transmit packet on IN endpoint * @param pdev: device instance + * @param ClassId: The Class ID * @retval status */ +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_CDC_ECM_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t ClassId) +{ + USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassDataCmsit[ClassId]; +#else 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]; +#endif /* USE_USBD_COMPOSITE */ + 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, ClassId); +#endif /* USE_USBD_COMPOSITE */ + + if (hcdc == NULL) { return (uint8_t)USBD_FAIL; } @@ -1003,10 +906,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; } @@ -1023,15 +926,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]; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + ECMOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ - if (pdev->pClassData == NULL) + 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; } @@ -1046,12 +954,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) @@ -1059,6 +967,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, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ + /* Initialize the request fields */ (hcdc->Req).bmRequest = CDC_ECM_BMREQUEST_TYPE_ECM; (hcdc->Req).bRequest = (uint8_t)Notif; @@ -1112,7 +1025,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; @@ -1131,4 +1044,3 @@ uint8_t USBD_CDC_ECM_SendNotification(USBD_HandleTypeDef *pdev, * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Src/usbd_cdc_ecm_if_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Src/usbd_cdc_ecm_if_template.c index cab0056584..ebe2d0b5f6 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Src/usbd_cdc_ecm_if_template.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Src/usbd_cdc_ecm_if_template.c @@ -6,20 +6,19 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2019 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ -#include "main.h" +#include "usbd_cdc_ecm_if_template.h" /* Include here LwIP files if used @@ -30,16 +29,17 @@ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ - +/* Received Data over USB are stored in this buffer */ #if defined ( __ICCARM__ ) /*!< IAR Compiler */ #pragma data_alignment=4 -#endif -__ALIGN_BEGIN static uint8_t UserRxBuffer[CDC_ECM_ETH_MAX_SEGSZE + 100]__ALIGN_END; /* Received Data over USB are stored in this buffer */ +#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 -__ALIGN_BEGIN static uint8_t UserTxBuffer[CDC_ECM_ETH_MAX_SEGSZE + 100]__ALIGN_END; /* Received Data over CDC_ECM (CDC_ECM interface) are stored in this buffer */ +#endif /* ( __ICCARM__ ) */ +__ALIGN_BEGIN static uint8_t UserTxBuffer[CDC_ECM_ETH_MAX_SEGSZE + 100]__ALIGN_END; static uint8_t CDC_ECMInitialized = 0U; @@ -85,7 +85,11 @@ static int8_t CDC_ECM_Itf_Init(void) } /* Set Application Buffers */ +#ifdef USE_USBD_COMPOSITE + (void)USBD_CDC_ECM_SetTxBuffer(&USBD_Device, UserTxBuffer, 0U, 0U); +#else (void)USBD_CDC_ECM_SetTxBuffer(&USBD_Device, UserTxBuffer, 0U); +#endif /* USE_USBD_COMPOSITE */ (void)USBD_CDC_ECM_SetRxBuffer(&USBD_Device, UserRxBuffer); return (0); @@ -99,7 +103,12 @@ 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 +126,12 @@ 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 +202,12 @@ 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 +249,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) + { + return (-1); + } - if ((hcdc_cdc_ecm != NULL) && (hcdc_cdc_ecm->LinkStatus != 0U)) + if (hcdc_cdc_ecm->LinkStatus != 0U) { /* Read a received packet from the Ethernet buffers and send it @@ -244,4 +272,3 @@ static int8_t CDC_ECM_Itf_Process(USBD_HandleTypeDef *pdev) return (0); } -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h index a2fb432357..50d18c42dd 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -41,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 */ @@ -265,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 */ @@ -498,16 +493,20 @@ extern USBD_ClassTypeDef USBD_CDC_RNDIS; */ uint8_t USBD_CDC_RNDIS_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff); uint8_t USBD_CDC_RNDIS_ReceivePacket(USBD_HandleTypeDef *pdev); -uint8_t USBD_CDC_RNDIS_TransmitPacket(USBD_HandleTypeDef *pdev); uint8_t USBD_CDC_RNDIS_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_ItfTypeDef *fops); - +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_CDC_RNDIS_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t ClassId); +uint8_t USBD_CDC_RNDIS_SetTxBuffer(USBD_HandleTypeDef *pdev, + uint8_t *pbuff, uint32_t length, uint8_t ClassId); +#else +uint8_t USBD_CDC_RNDIS_TransmitPacket(USBD_HandleTypeDef *pdev); uint8_t USBD_CDC_RNDIS_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uint32_t length); - +#endif /* USE_USBD_COMPOSITE */ uint8_t USBD_CDC_RNDIS_SendNotification(USBD_HandleTypeDef *pdev, - USBD_CDC_RNDIS_NotifCodeTypeDef Notif, + USBD_CDC_NotifCodeTypeDef Notif, uint16_t bVal, uint8_t *pData); /** * @} @@ -526,4 +525,3 @@ uint8_t USBD_CDC_RNDIS_SendNotification(USBD_HandleTypeDef *pdev, * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Inc/usbd_cdc_rndis_if_template.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Inc/usbd_cdc_rndis_if_template.h index 3cf0271654..14474c6274 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Inc/usbd_cdc_rndis_if_template.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Inc/usbd_cdc_rndis_if_template.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2019 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -57,4 +56,3 @@ extern USBD_CDC_RNDIS_ItfTypeDef USBD_CDC_RNDIS_fops; #endif /* __USBD_CDC_RNDIS_IF_H */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c index a7c2cbc7c6..f04f2c222e 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c @@ -10,6 +10,17 @@ * - Command IN transfer (class requests management) * - Error management * + ****************************************************************************** + * @attention + * + * Copyright (c) 2019 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 * * =================================================================== @@ -37,17 +48,6 @@ * @endverbatim * ****************************************************************************** - * @attention - * - *

© Copyright (c) 2019 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ @@ -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 -}; - -/* 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 */ +#endif /* USBD_SUPPORT_USER_STRING_DESC */ }; - +#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, (uint8_t)pdev->classId); + RNDISOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); + RNDISCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId); +#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; @@ -616,10 +427,16 @@ static uint8_t USBD_CDC_RNDIS_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) hcdc->TxLength = 0U; hcdc->LinkStatus = 0U; 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; + 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 +453,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, (uint8_t)pdev->classId); + RNDISOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); + RNDISCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId); +#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 +495,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 +506,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 +530,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) { @@ -729,7 +556,7 @@ static uint8_t USBD_CDC_RNDIS_Setup(USBD_HandleTypeDef *pdev, else { hcdc->CmdOpCode = req->bRequest; - hcdc->CmdLength = (uint8_t)MIN(CDC_RNDIS_CMD_PACKET_SIZE, req->wLength); + hcdc->CmdLength = (uint8_t)MIN(CDC_RNDIS_MAX_INFO_BUFF_SZ, req->wLength); (void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data, hcdc->CmdLength); } @@ -738,8 +565,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; @@ -807,16 +634,21 @@ static uint8_t USBD_CDC_RNDIS_Setup(USBD_HandleTypeDef *pdev, static uint8_t USBD_CDC_RNDIS_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) { USBD_CDC_RNDIS_HandleTypeDef *hcdc; - PCD_HandleTypeDef *hpcd = pdev->pData; + PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef *)pdev->pData; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + RNDISInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ - if (pdev->pClassData == NULL) + 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 +663,14 @@ 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 +700,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, (uint8_t)pdev->classId); +#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 +732,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 +753,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,47 +783,98 @@ 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 - * @param speed : current device speed * @param length : pointer data length * @retval pointer to descriptor buffer */ 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; } /** * @brief USBD_CDC_RNDIS_GetHSCfgDesc * Return configuration descriptor - * @param speed : current device speed * @param length : pointer data length * @retval pointer to descriptor buffer */ 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; } /** * @brief USBD_CDC_RNDIS_GetOtherSpeedCfgDesc * Return configuration descriptor - * @param speed : current device speed * @param length : pointer data length * @retval pointer to descriptor buffer */ 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); + + 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; + } - return USBD_CDC_RNDIS_OtherSpeedCfgDesc; + *length = (uint16_t)(sizeof(USBD_CDC_RNDIS_CfgDesc)); + return USBD_CDC_RNDIS_CfgDesc; } /** @@ -1001,7 +889,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 @@ -1016,7 +904,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; } @@ -1025,7 +913,7 @@ uint8_t USBD_CDC_RNDIS_RegisterInterface(USBD_HandleTypeDef *pdev, /** * @brief USBD_CDC_RNDIS_USRStringDescriptor * Manages the transfer of user string descriptors. - * @param speed : current device speed + * @param pdev: device instance * @param index: descriptor index * @param length : pointer data length * @retval pointer to the descriptor table or NULL if the descriptor is not supported. @@ -1038,7 +926,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 */ @@ -1049,15 +938,25 @@ static uint8_t *USBD_CDC_RNDIS_USRStringDescriptor(USBD_HandleTypeDef *pdev, uin } #endif /* USBD_SUPPORT_USER_STRING_DESC */ + /** * @brief USBD_CDC_RNDIS_SetTxBuffer * @param pdev: device instance * @param pbuff: Tx Buffer + * @param length: Tx Buffer length + * @param ClassId: The Class ID * @retval status */ +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_CDC_RNDIS_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uint32_t length, uint8_t ClassId) +{ + USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[ClassId]; +#else 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]; +#endif /* USE_USBD_COMPOSITE */ if (hcdc == NULL) { @@ -1079,7 +978,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) { @@ -1096,20 +995,32 @@ uint8_t USBD_CDC_RNDIS_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff) * @brief USBD_CDC_RNDIS_TransmitPacket * Transmit packet on IN endpoint * @param pdev: device instance + * @param ClassId: The Class ID * @retval status */ +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_CDC_RNDIS_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t ClassId) +{ + USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[ClassId]; +#else uint8_t USBD_CDC_RNDIS_TransmitPacket(USBD_HandleTypeDef *pdev) { - USBD_CDC_RNDIS_HandleTypeDef *hcdc; + USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; +#endif /* USE_USBD_COMPOSITE */ + 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, ClassId); +#endif /* USE_USBD_COMPOSITE */ + + if (hcdc == NULL) { return (uint8_t)USBD_FAIL; } - hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; PacketMsg = (USBD_CDC_RNDIS_PacketMsgTypeDef *)(void *)hcdc->TxBuffer; if (hcdc->TxState == 0U) @@ -1131,10 +1042,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; } @@ -1153,15 +1064,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, (uint8_t)pdev->classId); +#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; @@ -1178,12 +1094,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); @@ -1194,6 +1110,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, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ + /* Initialize the request fields */ (hcdc->Req).bmRequest = CDC_RNDIS_BMREQUEST_TYPE_RNDIS; (hcdc->Req).bRequest = (uint8_t)Notif; @@ -1221,7 +1142,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; @@ -1295,7 +1216,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; @@ -1360,7 +1281,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) { @@ -1389,7 +1310,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; @@ -1439,7 +1360,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; @@ -1584,7 +1505,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; @@ -1647,7 +1568,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; @@ -1695,10 +1616,11 @@ static uint8_t USBD_CDC_RNDIS_ProcessResetMsg(USBD_HandleTypeDef *pdev, static uint8_t USBD_CDC_RNDIS_ProcessPacketMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_PacketMsgTypeDef *Msg) { - uint32_t tmp1, tmp2; + uint32_t tmp1; + uint32_t 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; @@ -1723,7 +1645,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; } @@ -1740,7 +1662,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; @@ -1780,5 +1702,3 @@ static uint8_t USBD_CDC_RNDIS_ProcessUnsupportedMsg(USBD_HandleTypeDef *pdev, /** * @} */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Src/usbd_cdc_rndis_if_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Src/usbd_cdc_rndis_if_template.c index ad88c320a8..6cffddd0ef 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Src/usbd_cdc_rndis_if_template.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Src/usbd_cdc_rndis_if_template.c @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2019 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -31,21 +30,23 @@ #include "ethernetif.h" */ -#include "main.h" +#include "usbd_cdc_rndis_if_template.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ +/* Received Data over USB are stored in this buffer */ #if defined ( __ICCARM__ ) /*!< IAR Compiler */ #pragma data_alignment=4 -#endif -__ALIGN_BEGIN uint8_t UserRxBuffer[CDC_RNDIS_ETH_MAX_SEGSZE + 100] __ALIGN_END; /* Received Data over USB are stored in this buffer */ +#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 -__ALIGN_BEGIN static uint8_t UserTxBuffer[CDC_RNDIS_ETH_MAX_SEGSZE + 100] __ALIGN_END; /* Received Data over CDC_RNDIS (CDC_RNDIS interface) are stored in this buffer */ +#endif /* __ICCARM__ */ +__ALIGN_BEGIN static uint8_t UserTxBuffer[CDC_RNDIS_ETH_MAX_SEGSZE + 100] __ALIGN_END; static uint8_t CDC_RNDISInitialized = 0U; @@ -94,7 +95,11 @@ static int8_t CDC_RNDIS_Itf_Init(void) } /* Set Application Buffers */ +#ifdef USE_USBD_COMPOSITE + (void)USBD_CDC_RNDIS_SetTxBuffer(&USBD_Device, UserTxBuffer, 0U, 0U); +#else (void)USBD_CDC_RNDIS_SetTxBuffer(&USBD_Device, UserTxBuffer, 0U); +#endif /* USE_USBD_COMPOSITE */ (void)USBD_CDC_RNDIS_SetRxBuffer(&USBD_Device, UserRxBuffer); return (0); @@ -108,7 +113,12 @@ 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 @@ -130,7 +140,12 @@ 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) { @@ -173,7 +188,12 @@ 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; @@ -216,9 +236,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 @@ -230,4 +259,3 @@ static int8_t CDC_RNDIS_Itf_Process(USBD_HandleTypeDef *pdev) return (0); } -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CompositeBuilder/Inc/usbd_composite_builder.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CompositeBuilder/Inc/usbd_composite_builder.h new file mode 100644 index 0000000000..3a8aac3f9f --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/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 = (uint16_t)(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/system/Middlewares/ST/STM32_USB_Device_Library/Class/CompositeBuilder/Src/usbd_composite_builder.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CompositeBuilder/Src/usbd_composite_builder.c new file mode 100644 index 0000000000..e14c5cd817 --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CompositeBuilder/Src/usbd_composite_builder.c @@ -0,0 +1,1879 @@ +/** + ****************************************************************************** + * @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 = (uint16_t)(*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 = (uint16_t)(*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 = (uint16_t)(*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 = (uint16_t)(*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 = (uint16_t)(*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 = (uint16_t)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 = (uint16_t)(*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 = (uint16_t)(*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 = (uint16_t)(*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 = (uint16_t)(*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 = (uint16_t)(*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 = (uint16_t)(*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 = (uint16_t)(*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/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Inc/usbd_customhid.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Inc/usbd_customhid.h index da01685017..2f4c6344f3 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Inc/usbd_customhid.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Inc/usbd_customhid.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -41,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 @@ -103,7 +106,12 @@ typedef struct _USBD_CUSTOM_HID_Itf int8_t (* Init)(void); int8_t (* DeInit)(void); int8_t (* OutEvent)(uint8_t event_idx, uint8_t state); - +#ifdef USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED + int8_t (* CtrlReqComplete)(uint8_t request, uint16_t wLength); +#endif /* USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */ +#ifdef USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED + uint8_t *(* GetReport)(uint16_t *ReportLength); +#endif /* USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED */ } USBD_CUSTOM_HID_ItfTypeDef; typedef struct @@ -115,6 +123,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; + /** * @} */ @@ -142,9 +167,13 @@ extern USBD_ClassTypeDef USBD_CUSTOM_HID; /** @defgroup USB_CORE_Exported_Functions * @{ */ +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev, + uint8_t *report, uint16_t len, uint8_t ClassId); +#else uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len); - +#endif /* USE_USBD_COMPOSITE */ uint8_t USBD_CUSTOM_HID_ReceivePacket(USBD_HandleTypeDef *pdev); uint8_t USBD_CUSTOM_HID_RegisterInterface(USBD_HandleTypeDef *pdev, @@ -167,4 +196,3 @@ uint8_t USBD_CUSTOM_HID_RegisterInterface(USBD_HandleTypeDef *pdev, * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Inc/usbd_customhid_if_template.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Inc/usbd_customhid_if_template.h index e39069383a..e2a04af9b7 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Inc/usbd_customhid_if_template.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Inc/usbd_customhid_if_template.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -40,4 +39,3 @@ extern USBD_CUSTOM_HID_ItfTypeDef USBD_CustomHID_template_fops; #endif /* __USBD_CUSTOMHID_IF_TEMPLATE_H */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid.c index 2fbc0570ef..6add68a856 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid.c @@ -4,6 +4,17 @@ * @author MCD Application Team * @brief This file provides the CUSTOM_HID core functions. * + ****************************************************************************** + * @attention + * + * Copyright (c) 2015 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 * * =================================================================== @@ -24,17 +35,6 @@ * @endverbatim * ****************************************************************************** - * @attention - * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** */ /* BSPDependencies @@ -45,6 +45,7 @@ EndBSPDependencies */ /* Includes ------------------------------------------------------------------*/ #include "usbd_customhid.h" #include "usbd_ctlreq.h" +#include "usbd_def.h" /** @addtogroup STM32_USB_DEVICE_LIBRARY @@ -91,12 +92,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,27 +118,36 @@ 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 */ - USB_CUSTOM_HID_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ - 0x00, + LOBYTE(USB_CUSTOM_HID_CONFIG_DESC_SIZ), /* wTotalLength: Bytes returned */ + HIBYTE(USB_CUSTOM_HID_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) */ /************** Descriptor of CUSTOM HID interface ****************/ @@ -160,8 +170,8 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgFSDesc[USB_CUSTOM_HID_CONFIG_DES 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, + LOBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE), /* wItemLength: Total length of Report descriptor */ + HIBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE), /******************** Descriptor of Custom HID endpoints ********************/ /* 27 */ 0x07, /* bLength: Endpoint Descriptor size */ @@ -169,8 +179,8 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgFSDesc[USB_CUSTOM_HID_CONFIG_DES CUSTOM_HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ 0x03, /* bmAttributes: Interrupt endpoint */ - CUSTOM_HID_EPIN_SIZE, /* wMaxPacketSize: 2 Bytes max */ - 0x00, + LOBYTE(CUSTOM_HID_EPIN_SIZE), /* wMaxPacketSize: 2 Bytes max */ + HIBYTE(CUSTOM_HID_EPIN_SIZE), CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval */ /* 34 */ @@ -178,8 +188,8 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgFSDesc[USB_CUSTOM_HID_CONFIG_DES 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, + LOBYTE(CUSTOM_HID_EPOUT_SIZE), /* wMaxPacketSize: 2 Bytes max */ + HIBYTE(CUSTOM_HID_EPOUT_SIZE), CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval */ /* 41 */ }; @@ -189,8 +199,8 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgHSDesc[USB_CUSTOM_HID_CONFIG_DES { 0x09, /* bLength: Configuration Descriptor size */ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - USB_CUSTOM_HID_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ - 0x00, + LOBYTE(USB_CUSTOM_HID_CONFIG_DESC_SIZ), /* wTotalLength: Bytes returned */ + HIBYTE(USB_CUSTOM_HID_CONFIG_DESC_SIZ), 0x01, /* bNumInterfaces: 1 interface */ 0x01, /* bConfigurationValue: Configuration value */ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ @@ -221,8 +231,8 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgHSDesc[USB_CUSTOM_HID_CONFIG_DES 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, + LOBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE), /* wItemLength: Total length of Report descriptor */ + HIBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE), /******************** Descriptor of Custom HID endpoints ********************/ /* 27 */ 0x07, /* bLength: Endpoint Descriptor size */ @@ -230,8 +240,8 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgHSDesc[USB_CUSTOM_HID_CONFIG_DES CUSTOM_HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ 0x03, /* bmAttributes: Interrupt endpoint */ - CUSTOM_HID_EPIN_SIZE, /* wMaxPacketSize: 2 Bytes max */ - 0x00, + LOBYTE(CUSTOM_HID_EPIN_SIZE), /* wMaxPacketSize: 2 Bytes max */ + HIBYTE(CUSTOM_HID_EPIN_SIZE), CUSTOM_HID_HS_BINTERVAL, /* bInterval: Polling Interval */ /* 34 */ @@ -239,8 +249,8 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgHSDesc[USB_CUSTOM_HID_CONFIG_DES 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, + LOBYTE(CUSTOM_HID_EPOUT_SIZE), /* wMaxPacketSize: 2 Bytes max */ + HIBYTE(CUSTOM_HID_EPOUT_SIZE), CUSTOM_HID_HS_BINTERVAL, /* bInterval: Polling Interval */ /* 41 */ }; @@ -250,8 +260,8 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_OtherSpeedCfgDesc[USB_CUSTOM_HID_CO { 0x09, /* bLength: Configuration Descriptor size */ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - USB_CUSTOM_HID_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ - 0x00, + LOBYTE(USB_CUSTOM_HID_CONFIG_DESC_SIZ), /* wTotalLength: Bytes returned */ + HIBYTE(USB_CUSTOM_HID_CONFIG_DESC_SIZ), 0x01, /* bNumInterfaces: 1 interface */ 0x01, /* bConfigurationValue: Configuration value */ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ @@ -282,8 +292,8 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_OtherSpeedCfgDesc[USB_CUSTOM_HID_CO 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, + LOBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE), /* wItemLength: Total length of Report descriptor */ + HIBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE), /******************** Descriptor of Custom HID endpoints ********************/ /* 27 */ 0x07, /* bLength: Endpoint Descriptor size */ @@ -291,8 +301,8 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_OtherSpeedCfgDesc[USB_CUSTOM_HID_CO CUSTOM_HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ 0x03, /* bmAttributes: Interrupt endpoint */ - CUSTOM_HID_EPIN_SIZE, /* wMaxPacketSize: 2 Bytes max */ - 0x00, + LOBYTE(CUSTOM_HID_EPIN_SIZE), /* wMaxPacketSize: 2 Bytes max */ + HIBYTE(CUSTOM_HID_EPIN_SIZE), CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval */ /* 34 */ @@ -300,11 +310,12 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_OtherSpeedCfgDesc[USB_CUSTOM_HID_CO 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, + LOBYTE(CUSTOM_HID_EPOUT_SIZE), /* wMaxPacketSize: 2 Bytes max */ + HIBYTE(CUSTOM_HID_EPOUT_SIZE), 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 +326,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, + LOBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE), /* wItemLength: Total length of Report descriptor */ + HIBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE), }; +#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 +348,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,42 +376,51 @@ 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, (uint8_t)pdev->classId); + CUSTOMHIDOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId); +#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(); +#ifndef USBD_CUSTOMHID_OUT_PREPARE_RECEIVE_DISABLED /* 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); +#endif /* USBD_CUSTOMHID_OUT_PREPARE_RECEIVE_DISABLED */ return (uint8_t)USBD_OK; } @@ -411,21 +436,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, (uint8_t)pdev->classId); + CUSTOMHIDOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId); +#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,8 +474,11 @@ 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; +#ifdef USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED + uint16_t ReportLength = 0U; +#endif /* USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED */ uint8_t *pbuf = NULL; uint16_t status_info = 0U; USBD_StatusTypeDef ret = USBD_OK; @@ -475,10 +510,59 @@ static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev, break; case CUSTOM_HID_REQ_SET_REPORT: +#ifdef USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED + if (((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->CtrlReqComplete != NULL) + { + /* Let the application decide when to enable EP0 to receive the next report */ + ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->CtrlReqComplete(req->bRequest, + req->wLength); + } +#endif /* USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */ +#ifndef USBD_CUSTOMHID_EP0_OUT_PREPARE_RECEIVE_DISABLED hhid->IsReportAvailable = 1U; (void)USBD_CtlPrepareRx(pdev, hhid->Report_buf, MIN(req->wLength, USBD_CUSTOMHID_OUTREPORT_BUF_SIZE)); +#endif /* USBD_CUSTOMHID_EP0_OUT_PREPARE_RECEIVE_DISABLED */ + break; +#ifdef USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED + case CUSTOM_HID_REQ_GET_REPORT: + if (((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->GetReport != NULL) + { + ReportLength = req->wLength; + + /* Get report data buffer */ + pbuf = ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->GetReport(&ReportLength); + } + + if ((pbuf != NULL) && (ReportLength != 0U)) + { + len = MIN(ReportLength, req->wLength); + + /* Send the report data over EP0 */ + (void)USBD_CtlSendData(pdev, pbuf, len); + } + else + { +#ifdef USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED + if (((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->CtrlReqComplete != NULL) + { + /* Let the application decide what to do, keep EP0 data phase in NAK state and + use USBD_CtlSendData() when data become available or stall the EP0 data phase */ + ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->CtrlReqComplete(req->bRequest, + req->wLength); + } + else + { + /* Stall EP0 if no data available */ + USBD_CtlError(pdev, req); + } +#else + /* Stall EP0 if no data available */ + USBD_CtlError(pdev, req); +#endif /* USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */ + } break; +#endif /* USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED */ default: USBD_CtlError(pdev, req); @@ -506,7 +590,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 { @@ -567,26 +651,37 @@ static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev, * Send CUSTOM_HID Report * @param pdev: device instance * @param buff: pointer to report + * @param ClassId: The Class ID * @retval status */ +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev, + uint8_t *report, uint16_t len, uint8_t ClassId) +{ + USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassDataCmsit[ClassId]; +#else uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len) { - USBD_CUSTOM_HID_HandleTypeDef *hhid; + USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; +#endif /* USE_USBD_COMPOSITE */ - if (pdev->pClassData == NULL) + if (hhid == 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, ClassId); +#endif /* USE_USBD_COMPOSITE */ 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 +690,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 +700,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 +728,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); + + 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; + } - return USBD_CUSTOM_HID_CfgHSDesc; + *length = (uint16_t)sizeof(USBD_CUSTOM_HID_CfgDesc); + return USBD_CUSTOM_HID_CfgDesc; } /** @@ -633,10 +756,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); + + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = CUSTOM_HID_EPIN_SIZE; + pEpInDesc->bInterval = CUSTOM_HID_FS_BINTERVAL; + } - return USBD_CUSTOM_HID_OtherSpeedCfgDesc; + 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 +789,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 +806,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 +832,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, (uint8_t)pdev->classId); +#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 +860,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 +869,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 +890,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 +905,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; } @@ -779,4 +923,3 @@ uint8_t USBD_CUSTOM_HID_RegisterInterface(USBD_HandleTypeDef *pdev, * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid_if_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid_if_template.c index 97e4337987..85881bdc5b 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid_if_template.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid_if_template.c @@ -8,13 +8,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -34,13 +33,31 @@ EndBSPDependencies */ 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); + +#ifdef USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED +static int8_t TEMPLATE_CUSTOM_HID_CtrlReqComplete(uint8_t request, uint16_t wLength); +#endif /* USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */ + +#ifdef USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED +static uint8_t *TEMPLATE_CUSTOM_HID_GetReport(uint16_t *ReportLength); +#endif /* USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED */ /* 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, TEMPLATE_CUSTOM_HID_Init, TEMPLATE_CUSTOM_HID_DeInit, TEMPLATE_CUSTOM_HID_OutEvent, +#ifdef USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED + TEMPLATE_CUSTOM_HID_CtrlReqComplete, +#endif /* USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */ +#ifdef USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED + TEMPLATE_CUSTOM_HID_GetReport, +#endif /* USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED */ }; /* Private functions ---------------------------------------------------------*/ @@ -84,8 +101,58 @@ 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); +} + +#ifdef USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED +/** + * @brief TEMPLATE_CUSTOM_HID_CtrlReqComplete + * Manage the CUSTOM HID control request complete + * @param request: control request + * @param wLength: request wLength + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t TEMPLATE_CUSTOM_HID_CtrlReqComplete(uint8_t request, uint16_t wLength) +{ + UNUSED(wLength); + + switch (request) + { + case CUSTOM_HID_REQ_SET_REPORT: + + break; + + case CUSTOM_HID_REQ_GET_REPORT: + + break; + + default: + break; + } return (0); } -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +#endif /* USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */ + + +#ifdef USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED +/** + * @brief TEMPLATE_CUSTOM_HID_GetReport + * Manage the CUSTOM HID control Get Report request + * @param event_idx: event index + * @param state: event state + * @retval return pointer to HID report + */ +static uint8_t *TEMPLATE_CUSTOM_HID_GetReport(uint16_t *ReportLength) +{ + UNUSED(ReportLength); + uint8_t *pbuff; + + return (pbuff); +} +#endif /* USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED */ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Inc/usbd_dfu.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Inc/usbd_dfu.h index 307c96d931..7858394a07 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Inc/usbd_dfu.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Inc/usbd_dfu.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -53,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 @@ -115,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 @@ -133,20 +141,20 @@ typedef void (*pFunction)(void); /********** Descriptor of DFU interface 0 Alternate setting n ****************/ -#define USBD_DFU_IF_DESC(n) 0x09, /* bLength: Interface Descriptor size */ \ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType */ \ - 0x00, /* bInterfaceNumber: Number of Interface */ \ - (n), /* bAlternateSetting: Alternate setting */ \ - 0x00, /* bNumEndpoints*/ \ - 0xFE, /* bInterfaceClass: Application Specific Class Code */ \ - 0x01, /* bInterfaceSubClass : Device Firmware Upgrade Code */ \ - 0x02, /* nInterfaceProtocol: DFU mode protocol */ \ - USBD_IDX_INTERFACE_STR + (n) + 1U /* iInterface: Index of string descriptor */ \ +#define USBD_DFU_IF_DESC(n) \ + 0x09, /* bLength: Interface Descriptor size */ \ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType */ \ + 0x00, /* bInterfaceNumber: Number of Interface */ \ + (n), /* bAlternateSetting: Alternate setting */ \ + 0x00, /* bNumEndpoints*/ \ + 0xFE, /* bInterfaceClass: Application Specific Class Code */ \ + 0x01, /* bInterfaceSubClass : Device Firmware Upgrade Code */ \ + 0x02, /* nInterfaceProtocol: DFU mode protocol */ \ + USBD_IDX_INTERFACE_STR + (n) + 1U /* iInterface: Index of string descriptor */ -#define TRANSFER_SIZE_BYTES(size) ((uint8_t)(size)), /* XFERSIZEB0 */\ - ((uint8_t)((size) >> 8)) /* XFERSIZEB1 */ +#define TRANSFER_SIZE_BYTES(size) ((uint8_t)(size)), ((uint8_t)((size) >> 8)) -#define IS_PROTECTED_AREA(add) (uint8_t)((((add) >= 0x08000000) && ((add) < (APP_DEFAULT_ADD)))? 1:0) +#define IS_PROTECTED_AREA(add) (uint8_t)((((add) >= 0x08000000) && ((add) < (APP_DEFAULT_ADD))) ? 1 : 0) /** * @} @@ -186,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; + /** * @} */ @@ -231,5 +250,3 @@ uint8_t USBD_DFU_RegisterMedia(USBD_HandleTypeDef *pdev, /** * @} */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Inc/usbd_dfu_media_template.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Inc/usbd_dfu_media_template.h index 25efe526aa..7be25d4801 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Inc/usbd_dfu_media_template.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Inc/usbd_dfu_media_template.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -94,4 +93,3 @@ extern USBD_DFU_MediaTypeDef USBD_DFU_MEDIA_Template_fops; /** * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Src/usbd_dfu.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Src/usbd_dfu.c index fc942a76d0..58954970c3 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Src/usbd_dfu.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Src/usbd_dfu.c @@ -4,6 +4,17 @@ * @author MCD Application Team * @brief This file provides the DFU core functions. * + ****************************************************************************** + * @attention + * + * Copyright (c) 2015 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 * * =================================================================== @@ -34,17 +45,6 @@ * @endverbatim * ****************************************************************************** - * @attention - * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** */ /* BSPDependencies @@ -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,11 +485,10 @@ 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 - * @param speed : current device speed * @param length : pointer data length * @retval pointer to descriptor buffer */ @@ -476,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 @@ -500,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) { @@ -610,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 @@ -623,11 +645,12 @@ static uint8_t *USBD_DFU_GetDeviceQualifierDesc(uint16_t *length) return USBD_DFU_DeviceQualifierDesc; } +#endif /* USE_USBD_COMPOSITE */ /** * @brief USBD_DFU_GetUsrStringDesc * Manages the transfer of memory interfaces string descriptors. - * @param speed : current device speed + * @param pdev: device instance * @param index: descriptor index * @param length : pointer data length * @retval pointer to the descriptor table or NULL if the descriptor is not supported. @@ -636,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)) @@ -647,13 +670,15 @@ 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 + * @param pdev: device instance * @param fops: storage callback * @retval status */ @@ -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; +} + /** * @} */ @@ -1112,4 +1172,3 @@ static void DFU_Leave(USBD_HandleTypeDef *pdev) * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Src/usbd_dfu_media_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Src/usbd_dfu_media_template.c index b40a10cb8a..679d32644f 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Src/usbd_dfu_media_template.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Src/usbd_dfu_media_template.c @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -81,6 +80,8 @@ uint16_t MEM_If_DeInit(void) */ uint16_t MEM_If_Erase(uint32_t Add) { + UNUSED(Add); + return 0; } @@ -93,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; } @@ -105,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); } @@ -118,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: @@ -131,5 +143,4 @@ uint16_t MEM_If_GetStatus(uint32_t Add, uint8_t Cmd, uint8_t *buffer) } return (0); } -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Inc/usbd_hid.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Inc/usbd_hid.h index 76fcdc7c68..8b22a8df9f 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Inc/usbd_hid.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Inc/usbd_hid.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -41,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 @@ -59,14 +60,14 @@ extern "C" { #define HID_FS_BINTERVAL 0x0AU #endif /* HID_FS_BINTERVAL */ -#define HID_REQ_SET_PROTOCOL 0x0BU -#define HID_REQ_GET_PROTOCOL 0x03U +#define USBD_HID_REQ_SET_PROTOCOL 0x0BU +#define USBD_HID_REQ_GET_PROTOCOL 0x03U -#define HID_REQ_SET_IDLE 0x0AU -#define HID_REQ_GET_IDLE 0x02U +#define USBD_HID_REQ_SET_IDLE 0x0AU +#define USBD_HID_REQ_GET_IDLE 0x02U -#define HID_REQ_SET_REPORT 0x09U -#define HID_REQ_GET_REPORT 0x01U +#define USBD_HID_REQ_SET_REPORT 0x09U +#define USBD_HID_REQ_GET_REPORT 0x01U /** * @} */ @@ -77,9 +78,9 @@ extern "C" { */ typedef enum { - HID_IDLE = 0, - HID_BUSY, -} HID_StateTypeDef; + USBD_HID_IDLE = 0, + USBD_HID_BUSY, +} USBD_HID_StateTypeDef; typedef struct @@ -87,8 +88,25 @@ typedef struct uint32_t Protocol; uint32_t IdleState; uint32_t AltSetting; - HID_StateTypeDef state; + USBD_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; + /** * @} */ @@ -116,7 +134,11 @@ extern USBD_ClassTypeDef USBD_HID; /** @defgroup USB_CORE_Exported_Functions * @{ */ +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len, uint8_t ClassId); +#else uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len); +#endif /* USE_USBD_COMPOSITE */ uint32_t USBD_HID_GetPollingInterval(USBD_HandleTypeDef *pdev); /** @@ -136,4 +158,3 @@ uint32_t USBD_HID_GetPollingInterval(USBD_HandleTypeDef *pdev); * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c index 75256d20fa..fdf757810a 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c @@ -4,6 +4,17 @@ * @author MCD Application Team * @brief This file provides the HID core functions. * + ****************************************************************************** + * @attention + * + * Copyright (c) 2015 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 * * =================================================================== @@ -25,17 +36,6 @@ * @endverbatim * ****************************************************************************** - * @attention - * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** */ /* BSPDependencies @@ -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,26 +286,32 @@ 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, (uint8_t)pdev->classId); +#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; + hhid->state = USBD_HID_IDLE; return (uint8_t)USBD_OK; } @@ -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, (uint8_t)pdev->classId); +#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; @@ -452,19 +372,19 @@ static uint8_t USBD_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *re case USB_REQ_TYPE_CLASS : switch (req->bRequest) { - case HID_REQ_SET_PROTOCOL: + case USBD_HID_REQ_SET_PROTOCOL: hhid->Protocol = (uint8_t)(req->wValue); break; - case HID_REQ_GET_PROTOCOL: + case USBD_HID_REQ_GET_PROTOCOL: (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->Protocol, 1U); break; - case HID_REQ_SET_IDLE: + case USBD_HID_REQ_SET_IDLE: hhid->IdleState = (uint8_t)(req->wValue >> 8); break; - case HID_REQ_GET_IDLE: + case USBD_HID_REQ_GET_IDLE: (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->IdleState, 1U); break; @@ -552,28 +472,41 @@ static uint8_t USBD_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *re return (uint8_t)ret; } + /** * @brief USBD_HID_SendReport * Send HID Report * @param pdev: device instance * @param buff: pointer to report + * @param ClassId: The Class ID * @retval status */ +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len, uint8_t ClassId) +{ + USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)pdev->pClassDataCmsit[ClassId]; +#else 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]; +#endif /* USE_USBD_COMPOSITE */ 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, ClassId); +#endif /* USE_USBD_COMPOSITE */ + if (pdev->dev_state == USBD_STATE_CONFIGURED) { - if (hhid->state == HID_IDLE) + if (hhid->state == USBD_HID_IDLE) { - hhid->state = HID_BUSY; - (void)USBD_LL_Transmit(pdev, HID_EPIN_ADDR, report, len); + hhid->state = USBD_HID_BUSY; + (void)USBD_LL_Transmit(pdev, HIDInEpAdd, report, len); } } @@ -608,6 +541,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 +551,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); + + if (pEpDesc != NULL) + { + pEpDesc->bInterval = HID_FS_BINTERVAL; + } - return USBD_HID_CfgFSDesc; + *length = (uint16_t)sizeof(USBD_HID_CfgDesc); + return USBD_HID_CfgDesc; } /** @@ -631,9 +571,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 +591,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); + + if (pEpDesc != NULL) + { + pEpDesc->bInterval = HID_FS_BINTERVAL; + } - return USBD_HID_OtherSpeedCfgDesc; + *length = (uint16_t)sizeof(USBD_HID_CfgDesc); + return USBD_HID_CfgDesc; } +#endif /* USE_USBD_COMPOSITE */ /** * @brief USBD_HID_DataIn @@ -662,12 +615,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 = USBD_HID_IDLE; return (uint8_t)USBD_OK; } - +#ifndef USE_USBD_COMPOSITE /** * @brief DeviceQualifierDescriptor * return Device Qualifier descriptor @@ -680,7 +633,7 @@ static uint8_t *USBD_HID_GetDeviceQualifierDesc(uint16_t *length) return USBD_HID_DeviceQualifierDesc; } - +#endif /* USE_USBD_COMPOSITE */ /** * @} */ @@ -695,4 +648,3 @@ static uint8_t *USBD_HID_GetDeviceQualifierDesc(uint16_t *length) * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc.h index a0bbab9065..e55fef48d9 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -55,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 */ /** * @} @@ -101,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; @@ -126,5 +128,3 @@ uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev, /** * @} */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_bot.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_bot.h index fb99095cd8..8550a390f0 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_bot.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_bot.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -87,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 @@ -98,8 +96,7 @@ typedef struct uint32_t dDataResidue; uint8_t bStatus; uint8_t ReservedForAlign[3]; -} -USBD_MSC_BOT_CSWTypeDef; +} USBD_MSC_BOT_CSWTypeDef; /** * @} @@ -146,5 +143,4 @@ void MSC_BOT_CplClrFeature(USBD_HandleTypeDef *pdev, /** * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_data.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_data.h index 3aacf04a4c..f946b957ad 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_data.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_data.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -101,5 +100,3 @@ extern uint8_t MSC_Mode_Sense10_data[MODE_SENSE10_LEN]; /** * @} */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_scsi.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_scsi.h index 9bf10a9e6b..477affbb48 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_scsi.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_scsi.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -83,7 +82,7 @@ extern "C" { #define UNIT_ATTENTION 6U #define DATA_PROTECT 7U #define BLANK_CHECK 8U -#define VENDOR_SPECIFIC 9U +#define MSC_VENDOR_SPECIFIC 9U #define COPY_ABORTED 10U #define ABORTED_COMMAND 11U #define VOLUME_OVERFLOW 13U @@ -181,5 +180,3 @@ void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey, * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_storage_template.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_storage_template.h index 9591a3ba9d..cb8b89adb2 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_storage_template.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_storage_template.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -94,4 +93,4 @@ extern USBD_StorageTypeDef USBD_MSC_Template_fops; /** * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc.c index 09a61a6d36..7f2152f38b 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc.c @@ -4,6 +4,17 @@ * @author MCD Application Team * @brief This file provides all the MSC core functions. * + ****************************************************************************** + * @attention + * + * Copyright (c) 2015 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 * * =================================================================== @@ -19,17 +30,6 @@ * @endverbatim * ****************************************************************************** - * @attention - * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** */ /* BSPDependencies @@ -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, (uint8_t)pdev->classId); + MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); +#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, (uint8_t)pdev->classId); + MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); +#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, (uint8_t)pdev->classId); + MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); +#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); + + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = MSC_MAX_HS_PACKET; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = MSC_MAX_HS_PACKET; + } - return USBD_MSC_CfgHSDesc; + *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; } @@ -598,4 +577,3 @@ uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev, USBD_StorageTypeDef * * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_bot.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_bot.c index bbe94303e6..c51b01361f 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_bot.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_bot.c @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -67,7 +66,8 @@ EndBSPDependencies */ /** @defgroup MSC_BOT_Private_Variables * @{ */ - +extern uint8_t MSCInEpAdd; +extern uint8_t MSCOutEpAdd; /** * @} */ @@ -97,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, (uint8_t)pdev->classId); + MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ if (hmsc == NULL) { @@ -111,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); } @@ -129,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, (uint8_t)pdev->classId); + MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ if (hmsc == NULL) { @@ -139,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); } @@ -155,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) { @@ -174,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) { @@ -210,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) { @@ -243,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, (uint8_t)pdev->classId); + MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ if (hmsc == NULL) { @@ -253,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)) @@ -311,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; - uint32_t length = MIN(hmsc->cbw.dDataLength, len); +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + MSCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); + MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); +#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); } /** @@ -336,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, (uint8_t)pdev->classId); + MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ if (hmsc == NULL) { @@ -347,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); } @@ -364,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, (uint8_t)pdev->classId); + MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ if (hmsc == NULL) { @@ -375,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); } } @@ -397,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, (uint8_t)pdev->classId); + MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ if (hmsc == NULL) { @@ -406,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)) { @@ -432,4 +476,3 @@ void MSC_BOT_CplClrFeature(USBD_HandleTypeDef *pdev, uint8_t epnum) * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_data.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_data.c index 34ef4438df..fabd835c29 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_data.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_data.c @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -180,4 +179,3 @@ uint8_t MSC_Mode_Sense10_data[MODE_SENSE10_LEN] = * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c index 02fdc833a3..efa85a40d4 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -68,7 +67,8 @@ EndBSPDependencies */ /** @defgroup MSC_SCSI_Private_Variables * @{ */ - +extern uint8_t MSCInEpAdd; +extern uint8_t MSCOutEpAdd; /** * @} */ @@ -121,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) { @@ -211,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) { @@ -233,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; @@ -257,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) { @@ -290,7 +290,9 @@ 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) @@ -316,14 +318,15 @@ 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)) { @@ -358,16 +361,17 @@ static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { UNUSED(params); - uint8_t idx; + uint32_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)) { @@ -418,14 +422,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)) { @@ -465,7 +469,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) @@ -494,7 +498,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) @@ -524,7 +528,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) { @@ -581,7 +585,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) { @@ -610,7 +614,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) { @@ -656,7 +660,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) { @@ -687,7 +691,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) { @@ -710,7 +714,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; @@ -753,7 +757,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) { @@ -775,7 +779,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; @@ -821,7 +825,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) @@ -829,6 +833,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, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ + if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */ { if (hmsc->cbw.dDataLength == 0U) @@ -845,14 +854,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; @@ -886,7 +895,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 */ { @@ -906,13 +915,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, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */ { @@ -930,7 +943,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; @@ -938,7 +951,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; @@ -975,7 +988,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 */ { @@ -995,7 +1008,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) { @@ -1029,7 +1042,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) { @@ -1053,25 +1066,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, (uint8_t)pdev->classId); +#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); @@ -1095,19 +1115,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, (uint8_t)pdev->classId); +#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; @@ -1128,7 +1155,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; @@ -1177,4 +1204,3 @@ static int8_t SCSI_UpdateBotData(USBD_MSC_BOT_HandleTypeDef *hmsc, * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_storage_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_storage_template.c index 875c1f9d63..2163943d0c 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_storage_template.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_storage_template.c @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -87,91 +86,106 @@ 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); } -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp.h new file mode 100644 index 0000000000..df2644fdd0 --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp.h @@ -0,0 +1,358 @@ +/** + ****************************************************************************** + * @file usbd_mtp.h + * @author MCD Application Team + * @brief header file for the usbd_mtp.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 __USB_MTP_H +#define __USB_MTP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" +#include "usbd_ctlreq.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_MTP + * @brief This file is the header file for usbd_mtp.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 */ +#endif /* MTP_CMD_ITF_NBR */ + +#ifndef MTP_COM_ITF_NBR +#define MTP_COM_ITF_NBR 0x01U /* Communication Interface Number 0 */ +#endif /* MTP_CMD_ITF_NBR */ + +#ifndef MTP_HS_BINTERVAL +#define MTP_HS_BINTERVAL 0x10U +#endif /* MTP_HS_BINTERVAL */ + +#ifndef MTP_FS_BINTERVAL +#define MTP_FS_BINTERVAL 0x10U +#endif /* MTP_FS_BINTERVAL */ + +#define MTP_DATA_MAX_HS_PACKET_SIZE 512U +#define MTP_DATA_MAX_FS_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */ +#define MTP_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */ + +#define MTP_MEDIA_PACKET 512U +#define MTP_CONT_HEADER_SIZE 12U + +#define MTP_CONFIG_DESC_SIZ 39U +#define MTP_INTERFACE_DESC_SIZE 0x09U +#define USB_MTP_INTRERFACE_CLASS 0x06U +#define USB_MTP_INTRERFACE_SUB_CLASS 0x01U +#define USB_MTP_INTRERFACE_PROTOCOL 0x01U +#define MTP_ENDPOINT_DESC_SIZE 0x07U + +/*---------------------------------------------------------------------*/ +/* MTP definitions */ +/*---------------------------------------------------------------------*/ + +/* MTP class requests */ +#define MTP_REQ_CANCEL 0x64U +#define MTP_REQ_GET_EXT_EVENT_DATA 0x65U +#define MTP_REQ_RESET 0x66U +#define MTP_REQ_GET_DEVICE_STATUS 0x67U + + +/* Max info items size */ +#define MTP_SUPPORTED_OPERATIONS_NBR 100U +#define MTP_SUPPORTED_EVENTS_NBR 100U +#define MTP_SUPPORTED_PROPRIETIES_NBR 100U +#define MTP_CAPTURE_FORMATS_NBR 100U +#define MTP_IMAGE_FORMATS_NBR 100U +#define MTP_MAX_STR_SIZE 255U + +/* MTP response code */ +#define MTP_RESPONSE_OK 0x2001U +#define MTP_RESPONSE_GENERAL_ERROR 0x2002U +#define MTP_RESPONSE_PARAMETER_NOT_SUPPORTED 0x2006U +#define MTP_RESPONSE_INCOMPLETE_TRANSFER 0x2007U +#define MTP_RESPONSE_INVALID_STORAGE_ID 0x2008U +#define MTP_RESPONSE_INVALID_OBJECT_HANDLE 0x2009U +#define MTP_RESPONSE_DEVICEPROP_NOT_SUPPORTED 0x200AU +#define MTP_RESPONSE_STORE_FULL 0x200CU +#define MTP_RESPONSE_ACCESS_DENIED 0x200FU +#define MTP_RESPONSE_STORE_NOT_AVAILABLE 0x2013U +#define MTP_RESPONSE_SPECIFICATION_BY_FORMAT_NOT_SUPPORTED 0x2014U +#define MTP_RESPONSE_NO_VALID_OBJECT_INFO 0x2015U +#define MTP_RESPONSE_DEVICE_BUSY 0x2019U +#define MTP_RESPONSE_INVALID_PARENT_OBJECT 0x201AU +#define MTP_RESPONSE_INVALID_PARAMETER 0x201DU +#define MTP_RESPONSE_SESSION_ALREADY_OPEN 0x201EU +#define MTP_RESPONSE_TRANSACTION_CANCELLED 0x201FU +#define MTP_RESPONSE_INVALID_OBJECT_PROP_CODE 0xA801U +#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 +#define MTP_OBJ_FORMAT_SCRIPT 0x3002U +#define MTP_OBJ_FORMAT_EXECUTABLE 0x3003U +#define MTP_OBJ_FORMAT_TEXT 0x3004U +#define MTP_OBJ_FORMAT_HTML 0x3005U +#define MTP_OBJ_FORMAT_DPOF 0x3006U +#define MTP_OBJ_FORMAT_AIFF 0x3007U +#define MTP_OBJ_FORMAT_WAV 0x3008U +#define MTP_OBJ_FORMAT_MP3 0x3009U +#define MTP_OBJ_FORMAT_AVI 0x300AU +#define MTP_OBJ_FORMAT_MPEG 0x300BU +#define MTP_OBJ_FORMAT_ASF 0x300CU +#define MTP_OBJ_FORMAT_DEFINED 0x3800U +#define MTP_OBJ_FORMAT_EXIF_JPEG 0x3801U +#define MTP_OBJ_FORMAT_TIFF_EP 0x3802U +#define MTP_OBJ_FORMAT_FLASHPIX 0x3803U +#define MTP_OBJ_FORMAT_BMP 0x3804U +#define MTP_OBJ_FORMAT_CIFF 0x3805U +#define MTP_OBJ_FORMAT_UNDEFINED_RESERVED0 0x3806U +#define MTP_OBJ_FORMAT_GIF 0x3807U +#define MTP_OBJ_FORMAT_JFIF 0x3808U +#define MTP_OBJ_FORMAT_CD 0x3809U +#define MTP_OBJ_FORMAT_PICT 0x380AU +#define MTP_OBJ_FORMAT_PNG 0x380BU +#define MTP_OBJ_FORMAT_UNDEFINED_RESERVED1 0x380CU +#define MTP_OBJ_FORMAT_TIFF 0x380DU +#define MTP_OBJ_FORMAT_TIFF_IT 0x380EU +#define MTP_OBJ_FORMAT_JP2 0x380FU +#define MTP_OBJ_FORMAT_JPX 0x3810U +#define MTP_OBJ_FORMAT_UNDEFINED_FIRMWARE 0xB802U +#define MTP_OBJ_FORMAT_WINDOWS_IMAGE_FORMAT 0xB881U +#define MTP_OBJ_FORMAT_UNDEFINED_AUDIO 0xB900U +#define MTP_OBJ_FORMAT_WMA 0xB901U +#define MTP_OBJ_FORMAT_OGG 0xB902U +#define MTP_OBJ_FORMAT_AAC 0xB903U +#define MTP_OBJ_FORMAT_AUDIBLE 0xB904U +#define MTP_OBJ_FORMAT_FLAC 0xB906U +#define MTP_OBJ_FORMAT_UNDEFINED_VIDEO 0xB980U +#define MTP_OBJ_FORMAT_WMV 0xB981U +#define MTP_OBJ_FORMAT_MP4_CONTAINER 0xB982U +#define MTP_OBJ_FORMAT_MP2 0xB983U +#define MTP_OBJ_FORMAT_3GP_CONTAINER 0xB984U +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ + +/** + * @} + */ + + +/* MTP Session state */ +typedef enum +{ + MTP_SESSION_NOT_OPENED = 0x00, + MTP_SESSION_OPENED = 0x01, +} MTP_SessionStateTypeDef; + +/* MTP response phases */ +typedef enum +{ + MTP_PHASE_IDLE = 0x00, + MTP_RESPONSE_PHASE = 0x01, + MTP_READ_DATA = 0x02, + MTP_RECEIVE_DATA = 0x03, +} MTP_ResponsePhaseTypeDef; + +typedef struct +{ + uint32_t temp_length; + uint32_t prv_len; + uint32_t totallen; + uint32_t rx_length; + uint32_t readbytes; /* File write/read counts */ +} MTP_DataLengthTypeDef; + +typedef enum +{ + RECEIVE_IDLE_STATE = 0x00U, + RECEIVE_COMMAND_DATA = 0x01U, + RECEIVE_FIRST_DATA = 0x02U, + RECEIVE_REST_OF_DATA = 0x03U, + SEND_RESPONSE = 0x04U, +} MTP_RECEIVE_DATA_STATUS; + +typedef struct +{ + uint32_t length; + uint16_t type; + uint16_t code; + uint32_t trans_id; + uint32_t Param1; + uint32_t Param2; + uint32_t Param3; + uint32_t Param4; + uint32_t Param5; +} MTP_OperationsTypeDef; + +typedef struct +{ + uint32_t length; + uint16_t type; + uint16_t code; + uint32_t trans_id; + uint8_t data[MTP_MEDIA_PACKET]; +} MTP_GenericContainerTypeDef; + +#if defined ( __GNUC__ ) +typedef __PACKED_STRUCT +#else +__packed typedef struct +#endif /* __GNUC__ */ +{ + uint32_t Storage_id; + uint16_t ObjectFormat; + uint16_t ProtectionStatus; + uint32_t ObjectCompressedSize; + uint16_t ThumbFormat; + uint32_t ThumbCompressedSize; + uint32_t ThumbPixWidth; + uint32_t ThumbPixHeight; + uint32_t ImagePixWidth; + uint32_t ImagePixHeight; + uint32_t ImageBitDepth; + uint32_t ParentObject; + uint16_t AssociationType; + uint32_t AssociationDesc; + uint32_t SequenceNumber; + uint8_t Filename_len; + uint16_t Filename[255]; + uint32_t CaptureDate; + uint32_t ModificationDate; + uint8_t Keywords; +} MTP_ObjectInfoTypeDef; + +typedef struct +{ + uint32_t alt_setting; + uint32_t dev_status; + uint32_t ResponseLength; + uint32_t ResponseCode; + __IO uint16_t MaxPcktLen; + uint32_t rx_buff[MTP_MEDIA_PACKET / 4U]; /* Force 32-bit alignment */ + MTP_ResponsePhaseTypeDef MTP_ResponsePhase; + MTP_SessionStateTypeDef MTP_SessionState; + MTP_RECEIVE_DATA_STATUS RECEIVE_DATA_STATUS; + MTP_OperationsTypeDef OperationsContainer; + MTP_GenericContainerTypeDef GenericContainer; +} USBD_MTP_HandleTypeDef; + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ + +extern USBD_ClassTypeDef USBD_MTP; +#define USBD_MTP_CLASS &USBD_MTP + +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ + +typedef struct _USBD_MTP_ItfTypeDef +{ + uint8_t (*Init)(void); + uint8_t (*DeInit)(void); + uint32_t (*ReadData)(uint32_t Param1, uint8_t *buff, MTP_DataLengthTypeDef *data_length); + uint16_t (*Create_NewObject)(MTP_ObjectInfoTypeDef ObjectInfo, uint32_t objhandle); + + uint32_t (*GetIdx)(uint32_t Param3, uint32_t *obj_handle); + uint32_t (*GetParentObject)(uint32_t Param); + uint16_t (*GetObjectFormat)(uint32_t Param); + uint8_t (*GetObjectName_len)(uint32_t Param); + void (*GetObjectName)(uint32_t Param, uint8_t obj_len, uint16_t *buf); + uint32_t (*GetObjectSize)(uint32_t Param); + uint64_t (*GetMaxCapability)(void); + uint64_t (*GetFreeSpaceInBytes)(void); + uint32_t (*GetNewIndex)(uint16_t objformat); + void (*WriteData)(uint16_t len, uint8_t buff[]); + uint32_t (*GetContainerLength)(uint32_t Param1); + uint16_t (*DeleteObject)(uint32_t Param1); + void (*Cancel)(uint32_t Phase); + uint32_t *ScratchBuff; + uint32_t ScratchBuffSze; +} USBD_MTP_ItfTypeDef; + +/** + * @} + */ +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ +uint8_t USBD_MTP_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_MTP_ItfTypeDef *fops); + + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_MTP_H */ +/** + * @} + */ + +/** + * @} + */ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp_if_template.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp_if_template.h new file mode 100644 index 0000000000..d86e250506 --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp_if_template.h @@ -0,0 +1,96 @@ +/** + ****************************************************************************** + * @file usbd_mtp_if_template.h + * @author MCD Application Team + * @brief Header file for the usbd_mtp_if_template.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_MTP_IF_TEMPLATE_H +#define __USBD_MTP_IF_TEMPLATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_mtp.h" + +/* Exported Define -----------------------------------------------------------*/ +#define USBD_MTP_DEVICE_PROP_SUPPORTED 1U +#define USBD_MTP_CAPTURE_FORMAT_SUPPORTED 1U +#define USBD_MTP_VEND_EXT_DESC_SUPPORTED 1U +#define USBD_MTP_EVENTS_SUPPORTED 1U + +#if USBD_MTP_EVENTS_SUPPORTED == 1 +#define SUPP_EVENTS_LEN (uint8_t)((uint8_t)sizeof(SuppEvents) / 2U) +#else +#define SUPP_EVENTS_LEN 0U +#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 /* 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 /* 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 /* USBD_MTP_DEVICE_PROP_SUPPORTED */ + +#define MTP_IF_SCRATCH_BUFF_SZE 1024U + +/* Exported types ------------------------------------------------------------*/ +extern USBD_MTP_ItfTypeDef USBD_MTP_fops; + +/* Exported macros -----------------------------------------------------------*/ +/* Exported variables --------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +static const uint16_t Manuf[] = {'S', 'T', 'M', 0}; /* last 2 bytes must be 0*/ +static const uint16_t Model[] = {'S', 'T', 'M', '3', '2', 0}; /* last 2 bytes must be 0*/ +static const uint16_t VendExtDesc[] = {'m', 'i', 'c', 'r', 'o', 's', 'o', 'f', 't', '.', + 'c', 'o', 'm', ':', ' ', '1', '.', '0', ';', ' ', 0 + }; /* 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 + }; /* last 2 bytes must be 0*/ +static const uint16_t DeviceVers[] = {'V', '1', '.', '0', '0', 0}; /* last 2 bytes must be 0*/ + +static const uint16_t DefaultFileName[] = {'N', 'e', 'w', ' ', 'F', 'o', 'l', 'd', 'e', 'r', 0}; + +static const uint16_t DevicePropDefVal[] = {'S', 'T', 'M', '3', '2', 0}; /* last 2 bytes must be 0*/ +static const uint16_t DevicePropCurDefVal[] = {'S', 'T', 'M', '3', '2', ' ', 'V', '1', '.', '0', 0}; + + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_MTP_IF_TEMPLATE_H */ + diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp_opt.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp_opt.h new file mode 100644 index 0000000000..4dee923d6b --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp_opt.h @@ -0,0 +1,681 @@ +/** + ****************************************************************************** + * @file usbd_mtp_opt.h + * @author MCD Application Team + * @brief header file for the usbd_mtp_opt.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_MTP_OPT_H__ +#define __USBD_MTP_OPT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#ifndef __USBD_MTP_IF_H +#include "usbd_mtp_if_template.h" +#endif /* __USBD_MTP_IF_H */ +#include "usbd_mtp.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_MTP_OPT + * @brief This file is the header file for usbd_mtp_opt.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 +#define MTP_OB_PROP_PROTECTION_STATUS 0xDC03U +#define MTP_OB_PROP_OBJECT_SIZE 0xDC04U +#define MTP_OB_PROP_ASSOC_TYPE 0xDC05U +#define MTP_OB_PROP_ASSOC_DESC 0xDC06U +#define MTP_OB_PROP_OBJ_FILE_NAME 0xDC07U +#define MTP_OB_PROP_DATE_CREATED 0xDC08U +#define MTP_OB_PROP_DATE_MODIFIED 0xDC09U +#define MTP_OB_PROP_KEYWORDS 0xDC0AU +#define MTP_OB_PROP_PARENT_OBJECT 0xDC0BU +#define MTP_OB_PROP_ALLOWED_FOLD_CONTENTS 0xDC0CU +#define MTP_OB_PROP_HIDDEN 0xDC0DU +#define MTP_OB_PROP_SYSTEM_OBJECT 0xDC0EU +#define MTP_OB_PROP_PERS_UNIQ_OBJ_IDEN 0xDC41U +#define MTP_OB_PROP_SYNCID 0xDC42U +#define MTP_OB_PROP_PROPERTY_BAG 0xDC43U +#define MTP_OB_PROP_NAME 0xDC44U +#define MTP_OB_PROP_CREATED_BY 0xDC45U +#define MTP_OB_PROP_ARTIST 0xDC46U +#define MTP_OB_PROP_DATE_AUTHORED 0xDC47U +#define MTP_OB_PROP_DESCRIPTION 0xDC48U +#define MTP_OB_PROP_URL_REFERENCE 0xDC49U +#define MTP_OB_PROP_LANGUAGELOCALE 0xDC4AU +#define MTP_OB_PROP_COPYRIGHT_INFORMATION 0xDC4BU +#define MTP_OB_PROP_SOURCE 0xDC4CU +#define MTP_OB_PROP_ORIGIN_LOCATION 0xDC4DU +#define MTP_OB_PROP_DATE_ADDED 0xDC4EU +#define MTP_OB_PROP_NON_CONSUMABLE 0xDC4FU +#define MTP_OB_PROP_CORRUPTUNPLAYABLE 0xDC50U +#define MTP_OB_PROP_PRODUCERSERIALNUMBER 0xDC51U +#define MTP_OB_PROP_REPRESENTATIVE_SAMPLE_FORMAT 0xDC81U +#define MTP_OB_PROP_REPRESENTATIVE_SAMPLE_SIZE 0xDC82U +#define MTP_OB_PROP_REPRESENTATIVE_SAMPLE_HEIGHT 0xDC83U +#define MTP_OB_PROP_REPRESENTATIVE_SAMPLE_WIDTH 0xDC84U +#define MTP_OB_PROP_REPRESENTATIVE_SAMPLE_DURATION 0xDC85U +#define MTP_OB_PROP_REPRESENTATIVE_SAMPLE_DATA 0xDC86U +#define MTP_OB_PROP_WIDTH 0xDC87U +#define MTP_OB_PROP_HEIGHT 0xDC88U +#define MTP_OB_PROP_DURATION 0xDC89U +#define MTP_OB_PROP_RATING 0xDC8AU +#define MTP_OB_PROP_TRACK 0xDC8BU +#define MTP_OB_PROP_GENRE 0xDC8CU +#define MTP_OB_PROP_CREDITS 0xDC8DU +#define MTP_OB_PROP_LYRICS 0xDC8EU +#define MTP_OB_PROP_SUBSCRIPTION_CONTENT_ID 0xDC8FU +#define MTP_OB_PROP_PRODUCED_BY 0xDC90U +#define MTP_OB_PROP_USE_COUNT 0xDC91U +#define MTP_OB_PROP_SKIP_COUNT 0xDC92U +#define MTP_OB_PROP_LAST_ACCESSED 0xDC93U +#define MTP_OB_PROP_PARENTAL_RATING 0xDC94U +#define MTP_OB_PROP_META_GENRE 0xDC95U +#define MTP_OB_PROP_COMPOSER 0xDC96U +#define MTP_OB_PROP_EFFECTIVE_RATING 0xDC97U +#define MTP_OB_PROP_SUBTITLE 0xDC98U +#define MTP_OB_PROP_ORIGINAL_RELEASE_DATE 0xDC99U +#define MTP_OB_PROP_ALBUM_NAME 0xDC9AU +#define MTP_OB_PROP_ALBUM_ARTIST 0xDC9BU +#define MTP_OB_PROP_MOOD 0xDC9CU +#define MTP_OB_PROP_DRM_STATUS 0xDC9DU +#define MTP_OB_PROP_SUB_DESCRIPTION 0xDC9EU +#define MTP_OB_PROP_IS_CROPPED 0xDCD1U +#define MTP_OB_PROP_IS_COLOUR_CORRECTED 0xDCD2U +#define MTP_OB_PROP_IMAGE_BIT_DEPTH 0xDCD3U +#define MTP_OB_PROP_FNUMBER 0xDCD4U +#define MTP_OB_PROP_EXPOSURE_TIME 0xDCD5U +#define MTP_OB_PROP_EXPOSURE_INDEX 0xDCD6U +#define MTP_OB_PROP_TOTAL_BITRATE 0xDE91U +#define MTP_OB_PROP_BITRATE_TYPE 0xDE92U +#define MTP_OB_PROP_SAMPLE_RATE 0xDE93U +#define MTP_OB_PROP_NUMBER_OF_CHANNELS 0xDE94U +#define MTP_OB_PROP_AUDIO_BITDEPTH 0xDE95U +#define MTP_OB_PROP_SCAN_TYPE 0xDE97U +#define MTP_OB_PROP_AUDIO_WAVE_CODEC 0xDE99U +#define MTP_OB_PROP_AUDIO_BITRATE 0xDE9AU +#define MTP_OB_PROP_VIDEO_FOURCC_CODEC 0xDE9BU +#define MTP_OB_PROP_VIDEO_BITRATE 0xDE9CU +#define MTP_OB_PROP_FRAMES_PER_THOUSAND_SECONDS 0xDE9DU +#define MTP_OB_PROP_KEYFRAME_DISTANCE 0xDE9EU +#define MTP_OB_PROP_BUFFER_SIZE 0xDE9FU +#define MTP_OB_PROP_ENCODING_QUALITY 0xDEA0U +#define MTP_OB_PROP_ENCODING_PROFILE 0xDEA1U +#define MTP_OB_PROP_DISPLAY_NAME 0xDCE0U +#define MTP_OB_PROP_BODY_TEXT 0xDCE1U +#define MTP_OB_PROP_SUBJECT 0xDCE2U +#define MTP_OB_PROP_PRIORITY 0xDCE3U +#define MTP_OB_PROP_GIVEN_NAME 0xDD00U +#define MTP_OB_PROP_MIDDLE_NAMES 0xDD01U +#define MTP_OB_PROP_FAMILY_NAME 0xDD02U +#define MTP_OB_PROP_PREFIX 0xDD03U +#define MTP_OB_PROP_SUFFIX 0xDD04U +#define MTP_OB_PROP_PHONETIC_GIVEN_NAME 0xDD05U +#define MTP_OB_PROP_PHONETIC_FAMILY_NAME 0xDD06U +#define MTP_OB_PROP_EMAIL_PRIMARY 0xDD07U +#define MTP_OB_PROP_EMAIL_PERSONAL_1 0xDD08U +#define MTP_OB_PROP_EMAIL_PERSONAL_2 0xDD09U +#define MTP_OB_PROP_EMAIL_BUSINESS_1 0xDD0AU +#define MTP_OB_PROP_EMAIL_BUSINESS_2 0xDD0BU +#define MTP_OB_PROP_EMAIL_OTHERS 0xDD0CU +#define MTP_OB_PROP_PHONE_NUMBER_PRIMARY 0xDD0DU +#define MTP_OB_PROP_PHONE_NUMBER_PERSONAL 0xDD0EU +#define MTP_OB_PROP_PHONE_NUMBER_PERSONAL_2 0xDD0FU +#define MTP_OB_PROP_PHONE_NUMBER_BUSINESS 0xDD10U +#define MTP_OB_PROP_PHONE_NUMBER_BUSINESS_2 0xDD11U +#define MTP_OB_PROP_PHONE_NUMBER_MOBILE 0xDD12U +#define MTP_OB_PROP_PHONE_NUMBER_MOBILE_2 0xDD13U +#define MTP_OB_PROP_FAX_NUMBER_PRIMARY 0xDD14U +#define MTP_OB_PROP_FAX_NUMBER_PERSONAL 0xDD15U +#define MTP_OB_PROP_FAX_NUMBER_BUSINESS 0xDD16U +#define MTP_OB_PROP_PAGER_NUMBER 0xDD17U +#define MTP_OB_PROP_PHONE_NUMBER_OTHERS 0xDD18U +#define MTP_OB_PROP_PRIMARY_WEB_ADDRESS 0xDD19U +#define MTP_OB_PROP_PERSONAL_WEB_ADDRESS 0xDD1AU +#define MTP_OB_PROP_BUSINESS_WEB_ADDRESS 0xDD1BU +#define MTP_OB_PROP_INSTANT_MESSENGER_ADDRESS 0xDD1CU +#define MTP_OB_PROP_INSTANT_MESSENGER_ADDRESS_2 0xDD1DU +#define MTP_OB_PROP_INSTANT_MESSENGER_ADDRESS_3 0xDD1EU +#define MTP_OB_PROP_POSTAL_ADDRESS_PERSONAL_FULL 0xDD1FU +#define MTP_OB_PROP_POSTAL_ADDRESS_PERSONAL_LINE_1 0xDD20U +#define MTP_OB_PROP_POSTAL_ADDRESS_PERSONAL_LINE_2 0xDD21U +#define MTP_OB_PROP_POSTAL_ADDRESS_PERSONAL_CITY 0xDD22U +#define MTP_OB_PROP_POSTAL_ADDRESS_PERSONAL_REGION 0xDD23U +#define MTP_OB_PROP_POSTAL_ADDRESS_PERSONAL_POSTAL_CODE 0xDD24U +#define MTP_OB_PROP_POSTAL_ADDRESS_PERSONAL_COUNTRY 0xDD25U +#define MTP_OB_PROP_POSTAL_ADDRESS_BUSINESS_FULL 0xDD26U +#define MTP_OB_PROP_POSTAL_ADDRESS_BUSINESS_LINE_1 0xDD27U +#define MTP_OB_PROP_POSTAL_ADDRESS_BUSINESS_LINE_2 0xDD28U +#define MTP_OB_PROP_POSTAL_ADDRESS_BUSINESS_CITY 0xDD29U +#define MTP_OB_PROP_POSTAL_ADDRESS_BUSINESS_REGION 0xDD2AU +#define MTP_OB_PROP_POSTAL_ADDRESS_BUSINESS_POSTAL_CODE 0xDD2BU +#define MTP_OB_PROP_POSTAL_ADDRESS_BUSINESS_COUNTRY 0xDD2CU +#define MTP_OB_PROP_POSTAL_ADDRESS_OTHER_FULL 0xDD2DU +#define MTP_OB_PROP_POSTAL_ADDRESS_OTHER_LINE_1 0xDD2EU +#define MTP_OB_PROP_POSTAL_ADDRESS_OTHER_LINE_2 0xDD2FU +#define MTP_OB_PROP_POSTAL_ADDRESS_OTHER_CITY 0xDD30U +#define MTP_OB_PROP_POSTAL_ADDRESS_OTHER_REGION 0xDD31U +#define MTP_OB_PROP_POSTAL_ADDRESS_OTHER_POSTAL_CODE 0xDD32U +#define MTP_OB_PROP_POSTAL_ADDRESS_OTHER_COUNTRY 0xDD33U +#define MTP_OB_PROP_ORGANIZATION_NAME 0xDD34U +#define MTP_OB_PROP_PHONETIC_ORGANIZATION_NAME 0xDD35U +#define MTP_OB_PROP_ROLE 0xDD36U +#define MTP_OB_PROP_BIRTHDATE 0xDD37U +#define MTP_OB_PROP_MESSAGE_TO 0xDD40U +#define MTP_OB_PROP_MESSAGE_CC 0xDD41U +#define MTP_OB_PROP_MESSAGE_BCC 0xDD42U +#define MTP_OB_PROP_MESSAGE_READ 0xDD43U +#define MTP_OB_PROP_MESSAGE_RECEIVED_TIME 0xDD44U +#define MTP_OB_PROP_MESSAGE_SENDER 0xDD45U +#define MTP_OB_PROP_ACT_BEGIN_TIME 0xDD50U +#define MTP_OB_PROP_ACT_END_TIME 0xDD51U +#define MTP_OB_PROP_ACT_LOCATION 0xDD52U +#define MTP_OB_PROP_ACT_REQUIRED_ATTENDEES 0xDD54U +#define MTP_OB_PROP_ACT_OPTIONAL_ATTENDEES 0xDD55U +#define MTP_OB_PROP_ACT_RESOURCES 0xDD56U +#define MTP_OB_PROP_ACT_ACCEPTED 0xDD57U +#define MTP_OB_PROP_OWNER 0xDD5DU +#define MTP_OB_PROP_EDITOR 0xDD5EU +#define MTP_OB_PROP_WEBMASTER 0xDD5FU +#define MTP_OB_PROP_URL_SOURCE 0xDD60U +#define MTP_OB_PROP_URL_DESTINATION 0xDD61U +#define MTP_OB_PROP_TIME_BOOKMARK 0xDD62U +#define MTP_OB_PROP_OBJECT_BOOKMARK 0xDD63U +#define MTP_OB_PROP_BYTE_BOOKMARK 0xDD64U +#define MTP_OB_PROP_LAST_BUILD_DATE 0xDD70U +#define MTP_OB_PROP_TIME_TO_LIVE 0xDD71U +#define MTP_OB_PROP_MEDIA_GUID 0xDD72U + +/* MTP event codes*/ +#define MTP_EVENT_UNDEFINED 0x4000U +#define MTP_EVENT_CANCELTRANSACTION 0x4001U +#define MTP_EVENT_OBJECTADDED 0x4002U +#define MTP_EVENT_OBJECTREMOVED 0x4003U +#define MTP_EVENT_STOREADDED 0x4004U +#define MTP_EVENT_STOREREMOVED 0x4005U +#define MTP_EVENT_DEVICEPROPCHANGED 0x4006U +#define MTP_EVENT_OBJECTINFOCHANGED 0x4007U +#define MTP_EVENT_DEVICEINFOCHANGED 0x4008U +#define MTP_EVENT_REQUESTOBJECTTRANSFER 0x4009U +#define MTP_EVENT_STOREFULL 0x400AU +#define MTP_EVENT_DEVICERESET 0x400BU +#define MTP_EVENT_STORAGEINFOCHANGED 0x400CU +#define MTP_EVENT_CAPTURECOMPLETE 0x400DU +#define MTP_EVENT_UNREPORTEDSTATUS 0x400EU +#define MTP_EVENT_OBJECTPROPCHANGED 0xC801U +#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 +#define MTP_OP_CLOSE_SESSION 0x1003U +#define MTP_OP_GET_STORAGE_IDS 0x1004U +#define MTP_OP_GET_STORAGE_INFO 0x1005U +#define MTP_OP_GET_NUM_OBJECTS 0x1006U +#define MTP_OP_GET_OBJECT_HANDLES 0x1007U +#define MTP_OP_GET_OBJECT_INFO 0x1008U +#define MTP_OP_GET_OBJECT 0x1009U +#define MTP_OP_GET_THUMB 0x100AU +#define MTP_OP_DELETE_OBJECT 0x100BU +#define MTP_OP_SEND_OBJECT_INFO 0x100CU +#define MTP_OP_SEND_OBJECT 0x100DU +#define MTP_OP_FORMAT_STORE 0x100FU +#define MTP_OP_RESET_DEVICE 0x1010U +#define MTP_OP_GET_DEVICE_PROP_DESC 0x1014U +#define MTP_OP_GET_DEVICE_PROP_VALUE 0x1015U +#define MTP_OP_SET_DEVICE_PROP_VALUE 0x1016U +#define MTP_OP_RESET_DEVICE_PROP_VALUE 0x1017U +#define MTP_OP_TERMINATE_OPEN_CAPTURE 0x1018U +#define MTP_OP_MOVE_OBJECT 0x1019U +#define MTP_OP_COPY_OBJECT 0x101AU +#define MTP_OP_GET_PARTIAL_OBJECT 0x101BU +#define MTP_OP_INITIATE_OPEN_CAPTURE 0x101CU +#define MTP_OP_GET_OBJECT_PROPS_SUPPORTED 0x9801U +#define MTP_OP_GET_OBJECT_PROP_DESC 0x9802U +#define MTP_OP_GET_OBJECT_PROP_VALUE 0x9803U +#define MTP_OP_SET_OBJECT_PROP_VALUE 0x9804U +#define MTP_OP_GET_OBJECT_PROPLIST 0x9805U +#define MTP_OP_GET_OBJECT_PROP_REFERENCES 0x9810U +#define MTP_OP_GETSERVICEIDS 0x9301U +#define MTP_OP_GETSERVICEINFO 0x9302U +#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 +#define MTP_DEV_PROP_FUNCTIONAL_MODE 0x5002U +#define MTP_DEV_PROP_IMAGE_SIZE 0x5003U +#define MTP_DEV_PROP_COMPRESSION_SETTING 0x5004U +#define MTP_DEV_PROP_WHITE_BALANCE 0x5005U +#define MTP_DEV_PROP_RGB_GAIN 0x5006U +#define MTP_DEV_PROP_F_NUMBER 0x5007U +#define MTP_DEV_PROP_FOCAL_LENGTH 0x5008U +#define MTP_DEV_PROP_FOCUS_DISTANCE 0x5009U +#define MTP_DEV_PROP_FOCUS_MODE 0x500AU +#define MTP_DEV_PROP_EXPOSURE_METERING_MODE 0x500BU +#define MTP_DEV_PROP_FLASH_MODE 0x500CU +#define MTP_DEV_PROP_EXPOSURE_TIME 0x500DU +#define MTP_DEV_PROP_EXPOSURE_PROGRAM_MODE 0x500EU +#define MTP_DEV_PROP_EXPOSURE_INDEX 0x500FU +#define MTP_DEV_PROP_EXPOSURE_BIAS_COMPENSATION 0x5010U +#define MTP_DEV_PROP_DATETIME 0x5011U +#define MTP_DEV_PROP_CAPTURE_DELAY 0x5012U +#define MTP_DEV_PROP_STILL_CAPTURE_MODE 0x5013U +#define MTP_DEV_PROP_CONTRAST 0x5014U +#define MTP_DEV_PROP_SHARPNESS 0x5015U +#define MTP_DEV_PROP_DIGITAL_ZOOM 0x5016U +#define MTP_DEV_PROP_EFFECT_MODE 0x5017U +#define MTP_DEV_PROP_BURST_NUMBER 0x5018U +#define MTP_DEV_PROP_BURST_INTERVAL 0x5019U +#define MTP_DEV_PROP_TIMELAPSE_NUMBER 0x501AU +#define MTP_DEV_PROP_TIMELAPSE_INTERVAL 0x501BU +#define MTP_DEV_PROP_FOCUS_METERING_MODE 0x501CU +#define MTP_DEV_PROP_UPLOAD_URL 0x501DU +#define MTP_DEV_PROP_ARTIST 0x501EU +#define MTP_DEV_PROP_COPYRIGHT_INFO 0x501FU +#define MTP_DEV_PROP_SYNCHRONIZATION_PARTNER 0xD401U +#define MTP_DEV_PROP_DEVICE_FRIENDLY_NAME 0xD402U +#define MTP_DEV_PROP_VOLUME 0xD403U +#define MTP_DEV_PROP_SUPPORTEDFORMATSORDERED 0xD404U +#define MTP_DEV_PROP_DEVICEICON 0xD405U +#define MTP_DEV_PROP_PLAYBACK_RATE 0xD410U +#define MTP_DEV_PROP_PLAYBACK_OBJECT 0xD411U +#define MTP_DEV_PROP_PLAYBACK_CONTAINER 0xD412U +#define MTP_DEV_PROP_SESSION_INITIATOR_VERSION_INFO 0xD406U +#define MTP_DEV_PROP_PERCEIVED_DEVICE_TYPE 0xD407U + + +/* Container Types */ +#define MTP_CONT_TYPE_UNDEFINED 0U +#define MTP_CONT_TYPE_COMMAND 1U +#define MTP_CONT_TYPE_DATA 2U +#define MTP_CONT_TYPE_RESPONSE 3U +#define MTP_CONT_TYPE_EVENT 4U + +#ifndef MTP_STORAGE_ID +#define MTP_STORAGE_ID 0x00010001U /* SD card is inserted*/ +#endif /* MTP_STORAGE_ID */ + +#define MTP_NBR_STORAGE_ID 1U +#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 + +/* MTP file system type */ +#define MTP_FILESYSTEM_UNDEFINED 0U +#define MTP_FILESYSTEM_GENERIC_FLAT 0x0001U +#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 + +/* MTP standard data types supported */ +#define MTP_DATATYPE_INT8 0x0001U +#define MTP_DATATYPE_UINT8 0x0002U +#define MTP_DATATYPE_INT16 0x0003U +#define MTP_DATATYPE_UINT16 0x0004U +#define MTP_DATATYPE_INT32 0x0005U +#define MTP_DATATYPE_UINT32 0x0006U +#define MTP_DATATYPE_INT64 0x0007U +#define MTP_DATATYPE_UINT64 0x0008U +#define MTP_DATATYPE_UINT128 0x000AU +#define MTP_DATATYPE_STR 0xFFFFU + +/* MTP reading only or reading/writing */ +#define MTP_PROP_GET 0x00U +#define MTP_PROP_GET_SET 0x01U + + +/* MTP functional mode */ +#define STANDARD_MODE 0U +#define SLEEP_STATE 1U +#define FUNCTIONAL_MODE STANDARD_MODE + +/* MTP device info */ +#define STANDARD_VERSION 100U +#define VEND_EXT_ID 0x06U +#define VEND_EXT_VERSION 100U +#define MANUF_LEN (sizeof(Manuf) / 2U) +#define MODEL_LEN (sizeof(Model) / 2U) +#define SUPP_OP_LEN (sizeof(SuppOP) / 2U) +#define SERIAL_NBR_LEN (sizeof(SerialNbr) / 2U) +#define DEVICE_VERSION_LEN (sizeof(DeviceVers) / 2U) +#define SUPP_IMG_FORMAT_LEN (sizeof(SuppImgFormat) / 2U) +#define SUPP_OBJ_PROP_LEN (sizeof(ObjectPropSupp) / 2U) + +#ifndef MAX_FILE_NAME +#define MAX_FILE_NAME 255U +#endif /* MAX_FILE_NAME */ + +#ifndef MAX_OBJECT_HANDLE_LEN +#define MAX_OBJECT_HANDLE_LEN 100U +#endif /* MAX_OBJECT_HANDLE_LEN */ + +#ifndef DEVICE_PROP_DESC_DEF_LEN +#define DEVICE_PROP_DESC_DEF_LEN (uint8_t)(sizeof(DevicePropDefVal) / 2U) +#endif /* DEVICE_PROP_DESC_DEF_LEN */ + +#ifndef DEVICE_PROP_DESC_CUR_LEN +#define DEVICE_PROP_DESC_CUR_LEN (uint8_t)(sizeof(DevicePropCurDefVal) / 2U) +#endif /* DEVICE_PROP_DESC_CUR_LEN */ + +#ifndef DEFAULT_FILE_NAME_LEN +#define DEFAULT_FILE_NAME_LEN (uint8_t)(sizeof(DefaultFileName) / 2U) +#endif /* DEFAULT_FILE_NAME_LEN */ + +/** + * @} + */ + + +/** @defgroup USBD_MTP_OPT_Exported_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +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 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 + }; + +static const uint16_t DevicePropSupp[] = {MTP_DEV_PROP_DEVICE_FRIENDLY_NAME, MTP_DEV_PROP_BATTERY_LEVEL}; + +/* for all mtp struct */ +typedef struct +{ + uint32_t StorageIDS_len; + uint32_t StorageIDS[MTP_NBR_STORAGE_ID]; +} MTP_StorageIDSTypeDef; + +#if defined ( __GNUC__ ) +typedef __PACKED_STRUCT +#else +__packed typedef struct +#endif /* __GNUC__ */ +{ + uint8_t FileName_len; + uint16_t FileName[MAX_FILE_NAME]; +} MTP_FileNameTypeDef; + + +typedef struct +{ + uint32_t ObjectHandle_len; + uint32_t ObjectHandle[MAX_OBJECT_HANDLE_LEN]; +} MTP_ObjectHandleTypeDef; + +#if defined ( __GNUC__ ) +typedef __PACKED_STRUCT +#else +__packed typedef struct +#endif /* __GNUC__ */ +{ + uint32_t ObjectPropSupp_len; + uint16_t ObjectPropSupp[SUPP_OBJ_PROP_LEN]; +} MTP_ObjectPropSuppTypeDef; + + +#if defined ( __GNUC__ ) +typedef __PACKED_STRUCT +#else +__packed typedef struct +#endif /* __GNUC__ */ +{ + uint16_t StorageType; + uint16_t FilesystemType; + uint16_t AccessCapability; + uint64_t MaxCapability; + uint64_t FreeSpaceInBytes; + uint32_t FreeSpaceInObjects; + uint8_t StorageDescription; + uint8_t VolumeLabel; +} MTP_StorageInfoTypedef; + +typedef union +{ + uint16_t str[100]; + uint8_t u8; + int8_t i8; + uint16_t u16; + int16_t i16; + uint32_t u32; + int32_t i32; + uint64_t u64; + int64_t i64; +} MTP_PropertyValueTypedef; + +#if defined ( __GNUC__ ) +typedef __PACKED_STRUCT +#else +__packed typedef struct +#endif /* __GNUC__ */ +{ + uint16_t ObjectPropertyCode; + uint16_t DataType; + uint8_t GetSet; + uint8_t *DefValue; + uint32_t GroupCode; + uint8_t FormFlag; +} MTP_ObjectPropDescTypeDef; + + +#if defined ( __GNUC__ ) +typedef __PACKED_STRUCT +#else +__packed typedef struct +#endif /* __GNUC__ */ +{ + uint32_t ObjectHandle; + uint16_t PropertyCode; + uint16_t Datatype; + uint8_t *propval; +} MTP_PropertiesTypedef; + +#if defined ( __GNUC__ ) +typedef __PACKED_STRUCT +#else +__packed typedef struct +#endif /* __GNUC__ */ +{ + uint32_t MTP_Properties_len; + MTP_PropertiesTypedef MTP_Properties[SUPP_OBJ_PROP_LEN]; +} MTP_PropertiesListTypedef; + + +#if defined ( __GNUC__ ) +typedef __PACKED_STRUCT +#else +__packed typedef struct +#endif /* __GNUC__ */ +{ + uint32_t ref_len; + uint32_t ref[1]; +} MTP_RefTypeDef; + +#if defined ( __GNUC__ ) +typedef __PACKED_STRUCT +#else +__packed typedef struct +#endif /* __GNUC__ */ +{ + uint16_t DevicePropertyCode; + uint16_t DataType; + uint8_t GetSet; + uint8_t DefValue_len; + uint16_t DefValue[DEVICE_PROP_DESC_DEF_LEN]; + uint8_t curDefValue_len; + uint16_t curDefValue[DEVICE_PROP_DESC_CUR_LEN]; + uint8_t FormFlag; +} MTP_DevicePropDescTypeDef; + +/* MTP device info structure */ +#if defined ( __GNUC__ ) +typedef __PACKED_STRUCT +#else +__packed typedef struct +#endif /* __GNUC__ */ +{ + uint16_t StandardVersion; + uint32_t VendorExtensionID; + uint16_t VendorExtensionVersion; + uint8_t VendorExtensionDesc_len; +#if USBD_MTP_VEND_EXT_DESC_SUPPORTED == 1 + uint16_t VendorExtensionDesc[VEND_EXT_DESC_LEN]; +#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 /* USBD_MTP_EVENTS_SUPPORTED */ + uint32_t DevicePropertiesSupported_len; +#if USBD_MTP_DEVICE_PROP_SUPPORTED == 1 + uint16_t DevicePropertiesSupported[SUPP_DEVICE_PROP_LEN]; +#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 /* USBD_MTP_CAPTURE_FORMAT_SUPPORTED */ + uint32_t ImageFormats_len; + uint16_t ImageFormats[SUPP_IMG_FORMAT_LEN]; + uint8_t Manufacturer_len; + uint16_t Manufacturer[MANUF_LEN]; + uint8_t Model_len; + uint16_t Model[MODEL_LEN]; + uint8_t DeviceVersion_len; + uint16_t DeviceVersion[DEVICE_VERSION_LEN]; + uint8_t SerialNumber_len; + uint16_t SerialNumber[SERIAL_NBR_LEN]; +} MTP_DeviceInfoTypedef; + +/** @defgroup USBD_MTP_OPT_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_MTP_OPT_Exported_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_MTP_OPT_Exported_Functions + * @{ + */ + +void USBD_MTP_OPT_CreateObjectHandle(USBD_HandleTypeDef *pdev); +void USBD_MTP_OPT_GetDeviceInfo(USBD_HandleTypeDef *pdev); +void USBD_MTP_OPT_GetStorageIDS(USBD_HandleTypeDef *pdev); +void USBD_MTP_OPT_GetStorageInfo(USBD_HandleTypeDef *pdev); +void USBD_MTP_OPT_GetObjectHandle(USBD_HandleTypeDef *pdev); +void USBD_MTP_OPT_GetObjectInfo(USBD_HandleTypeDef *pdev); +void USBD_MTP_OPT_GetObjectReferences(USBD_HandleTypeDef *pdev); +void USBD_MTP_OPT_GetObjectPropSupp(USBD_HandleTypeDef *pdev); +void USBD_MTP_OPT_GetObjectPropDesc(USBD_HandleTypeDef *pdev); +void USBD_MTP_OPT_GetObjectPropValue(USBD_HandleTypeDef *pdev); +void USBD_MTP_OPT_GetObjectPropList(USBD_HandleTypeDef *pdev); +void USBD_MTP_OPT_GetDevicePropDesc(USBD_HandleTypeDef *pdev); +void USBD_MTP_OPT_SendObjectInfo(USBD_HandleTypeDef *pdev, uint8_t *buff, uint32_t len); +void USBD_MTP_OPT_SendObject(USBD_HandleTypeDef *pdev, uint8_t *buff, uint32_t len); +void USBD_MTP_OPT_GetObject(USBD_HandleTypeDef *pdev); +void USBD_MTP_OPT_DeleteObject(USBD_HandleTypeDef *pdev); + + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_MTP_OPT_H__ */ +/** + * @} + */ + +/** + * @} + */ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp_storage.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp_storage.h new file mode 100644 index 0000000000..ba01901e75 --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp_storage.h @@ -0,0 +1,118 @@ +/** + ****************************************************************************** + * @file usbd_mtp_storage.h + * @author MCD Application Team + * @brief header file for the usbd_mtp_storage.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_MTP_STORAGE_H__ +#define __USBD_MTP_STORAGE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ctlreq.h" +#include "usbd_mtp_opt.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_MTP_STORAGE + * @brief This file is the header file for usbd_template_core.c + * @{ + */ + + +/** @defgroup USBD_MTP_STORAGE_Exported_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_MTP_STORAGE_Exported_TypesDefinitions + * @{ + */ + +typedef enum +{ + DATA_TYPE = 0x00, + REP_TYPE = 0x01, +} MTP_CONTAINER_TYPE; + + +typedef enum +{ + READ_FIRST_DATA = 0x00, + READ_REST_OF_DATA = 0x01, +} MTP_READ_DATA_STATUS; + + +/** + * @} + */ + + + +/** @defgroup USBD_MTP_STORAGE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_MTP_STORAGE_Exported_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_MTP_STORAGE_Exported_Functions + * @{ + */ + +uint8_t USBD_MTP_STORAGE_Init(USBD_HandleTypeDef *pdev); +uint8_t USBD_MTP_STORAGE_DeInit(USBD_HandleTypeDef *pdev); +void USBD_MTP_STORAGE_Cancel(USBD_HandleTypeDef *pdev, MTP_ResponsePhaseTypeDef MTP_ResponsePhase); +uint8_t USBD_MTP_STORAGE_ReadData(USBD_HandleTypeDef *pdev); +uint8_t USBD_MTP_STORAGE_SendContainer(USBD_HandleTypeDef *pdev, MTP_CONTAINER_TYPE CONT_TYPE); +uint8_t USBD_MTP_STORAGE_ReceiveOpt(USBD_HandleTypeDef *pdev); +uint8_t USBD_MTP_STORAGE_ReceiveData(USBD_HandleTypeDef *pdev); + + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_MTP_STORAGE_H */ +/** + * @} + */ + +/** + * @} + */ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp.c new file mode 100644 index 0000000000..b0950e8eaa --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp.c @@ -0,0 +1,701 @@ +/** + ****************************************************************************** + * @file usbd_mtp.c + * @author MCD Application Team + * @brief This file provides the high layer firmware functions to manage the + * following functionalities of the USB MTP Class: + * - Initialization and Configuration of high and low layer + * - Enumeration as MTP Device (and enumeration for each implemented memory interface) + * - OUT/IN data transfer + * - Command IN transfer (class requests management) + * - Error management + * + ****************************************************************************** + * @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 + * + * =================================================================== + * MTP Class Driver Description + * =================================================================== + * This driver manages the "Universal Serial Bus Class Definitions for Media Transfer Protocol + * Revision 1.1 April 6, 2011" + * This driver implements the following aspects of the specification: + * - Device descriptor management + * - Configuration descriptor management + * - Enumeration as MTP device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN) + * - Requests management + * + * + * @endverbatim + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_mtp.h" +#include "usbd_mtp_storage.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_MTP + * @brief usbd core module + * @{ + */ + +/** @defgroup USBD_MTP_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_MTP_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_MTP_Private_Macros + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_MTP_Private_FunctionPrototypes + * @{ + */ +static uint8_t USBD_MTP_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +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 */ + +/** + * @} + */ + +/** @defgroup USBD_MTP_Private_Variables + * @{ + */ + + +/* MTP interface class callbacks structure */ +USBD_ClassTypeDef USBD_MTP = +{ + USBD_MTP_Init, + USBD_MTP_DeInit, + USBD_MTP_Setup, + NULL, /*EP0_TxSent*/ + NULL, /*EP0_RxReady*/ + USBD_MTP_DataIn, + USBD_MTP_DataOut, + 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_CfgDesc[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 */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif /* USBD_SELF_POWERED */ + 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_FS_PACKET_SIZE), + HIBYTE(MTP_DATA_MAX_FS_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_FS_PACKET_SIZE), + HIBYTE(MTP_DATA_MAX_FS_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_FS_BINTERVAL /* Polling interval in milliseconds */ +}; + +/* USB Standard Device Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_MTP_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 */ + +uint8_t MTPInEpAdd = MTP_IN_EP; +uint8_t MTPOutEpAdd = MTP_OUT_EP; +uint8_t MTPCmdEpAdd = MTP_CMD_EP; + +/** + * @} + */ + +/** @defgroup USBD_MTP_Private_Functions + * @{ + */ + +/** + * @brief USBD_MTP_Init + * Initialize the MTP interface + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_MTP_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + UNUSED(cfgidx); + USBD_MTP_HandleTypeDef *hmtp; + + hmtp = (USBD_MTP_HandleTypeDef *)USBD_malloc(sizeof(USBD_MTP_HandleTypeDef)); + + if (hmtp == NULL) + { + pdev->pClassDataCmsit[pdev->classId] = NULL; + return (uint8_t)USBD_EMEM; + } + + /* Setup the pClassData pointer */ + 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, (uint8_t)pdev->classId); + MTPOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); + MTPCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId); +#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 */ + 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, MTPInEpAdd, USBD_EP_TYPE_BULK, hmtp->MaxPcktLen); + pdev->ep_in[MTPInEpAdd & 0xFU].is_used = 1U; + + /* Open EP OUT */ + (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, 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); + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_MTP_DeInit + * DeInitialize the MTP layer + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +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, (uint8_t)pdev->classId); + MTPOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); + MTPCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ + + /* Close EP IN */ + (void)USBD_LL_CloseEP(pdev, MTPInEpAdd); + pdev->ep_in[MTPInEpAdd & 0xFU].is_used = 0U; + + /* Close EP OUT */ + (void)USBD_LL_CloseEP(pdev, MTPOutEpAdd); + pdev->ep_out[MTPOutEpAdd & 0xFU].is_used = 0U; + + /* Close EP Command */ + (void)USBD_LL_CloseEP(pdev, MTPCmdEpAdd); + pdev->ep_in[MTPCmdEpAdd & 0xFU].is_used = 0U; + + /* Free MTP Class Resources */ + if (pdev->pClassDataCmsit[pdev->classId] != NULL) + { + /* 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; + } + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_MTP_Setup + * Handle the MTP specific requests + * @param pdev: instance + * @param req: usb requests + * @retval status + */ +static uint8_t USBD_MTP_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + 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, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ + + if (hmtp == NULL) + { + return (uint8_t)USBD_FAIL; + } + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + /* Class request */ + case USB_REQ_TYPE_CLASS : + switch (req->bRequest) + { + case MTP_REQ_CANCEL: + len = MIN(hmtp->MaxPcktLen, req->wLength); + (void)USBD_CtlPrepareRx(pdev, (uint8_t *)(hmtp->rx_buff), len); + break; + + case MTP_REQ_GET_EXT_EVENT_DATA: + break; + + case MTP_REQ_RESET: + /* Stop low layer file system operations if any */ + USBD_MTP_STORAGE_Cancel(pdev, MTP_PHASE_IDLE); + + (void)USBD_LL_PrepareReceive(pdev, MTPOutEpAdd, (uint8_t *)&hmtp->rx_buff, hmtp->MaxPcktLen); + break; + + case MTP_REQ_GET_DEVICE_STATUS: + switch (hmtp->MTP_ResponsePhase) + { + case MTP_READ_DATA : + len = 4U; + hmtp->dev_status = ((uint32_t)MTP_RESPONSE_DEVICE_BUSY << 16) | len; + break; + + case MTP_RECEIVE_DATA : + len = 4U; + hmtp->dev_status = ((uint32_t)MTP_RESPONSE_TRANSACTION_CANCELLED << 16) | len; + break; + + case MTP_PHASE_IDLE : + len = 4U; + hmtp->dev_status = ((uint32_t)MTP_RESPONSE_OK << 16) | len; + break; + + default: + break; + } + (void)USBD_CtlSendData(pdev, (uint8_t *)&hmtp->dev_status, len); + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + } + break; + + /* Interface & Endpoint request */ + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_GET_INTERFACE : + + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + hmtp->alt_setting = 0U; + (void)USBD_CtlSendData(pdev, (uint8_t *)&hmtp->alt_setting, 1U); + } + break; + + case USB_REQ_SET_INTERFACE : + if (pdev->dev_state != USBD_STATE_CONFIGURED) + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_CLEAR_FEATURE: + + /* Re-activate the EP */ + (void)USBD_LL_CloseEP(pdev, (uint8_t)req->wIndex); + + if ((((uint8_t)req->wIndex) & 0x80U) == 0x80U) + { + (void)USBD_LL_OpenEP(pdev, ((uint8_t)req->wIndex), USBD_EP_TYPE_BULK, hmtp->MaxPcktLen); + } + else + { + (void)USBD_LL_OpenEP(pdev, ((uint8_t)req->wIndex), USBD_EP_TYPE_BULK, hmtp->MaxPcktLen); + } + break; + + default: + break; + } + break; + + default: + break; + } + return (uint8_t)ret; +} + +/** + * @brief USBD_MTP_DataIn + * Data sent on non-control IN endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +static uint8_t USBD_MTP_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + UNUSED(epnum); + 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 */ + MTPInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); + MTPOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ + + if (epnum == (MTPInEpAdd & 0x7FU)) + { + switch (hmtp->MTP_ResponsePhase) + { + case MTP_RESPONSE_PHASE : + (void)USBD_MTP_STORAGE_SendContainer(pdev, REP_TYPE); + + /* prepare to receive next operation */ + len = MIN(hmtp->MaxPcktLen, pdev->request.wLength); + + (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, 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, MTPOutEpAdd, (uint8_t *)&hmtp->rx_buff, len); + + break; + default: + break; + } + } + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_MTP_DataOut + * Data received on non-control Out endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +static uint8_t USBD_MTP_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + UNUSED(epnum); + 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, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ + + (void)USBD_MTP_STORAGE_ReceiveOpt(pdev); + + switch (hmtp->MTP_ResponsePhase) + { + case MTP_RESPONSE_PHASE : + + if (hmtp->ResponseLength == MTP_CONT_HEADER_SIZE) + { + (void)USBD_MTP_STORAGE_SendContainer(pdev, REP_TYPE); + hmtp->MTP_ResponsePhase = MTP_PHASE_IDLE; + } + else + { + (void)USBD_MTP_STORAGE_SendContainer(pdev, DATA_TYPE); + } + break; + + case MTP_READ_DATA : + (void)USBD_MTP_STORAGE_ReadData(pdev); + break; + + case MTP_RECEIVE_DATA : + (void)USBD_MTP_STORAGE_ReceiveData(pdev); + + /* prepare endpoint to receive operations */ + len = MIN(hmtp->MaxPcktLen, pdev->request.wLength); + + (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, MTPOutEpAdd, (uint8_t *)&hmtp->rx_buff, len); + break; + + default: + break; + } + + return (uint8_t)USBD_OK; +} + +#ifndef USE_USBD_COMPOSITE +/** + * @brief USBD_MTP_GetHSCfgDesc + * Return configuration descriptor + * @param speed : current device speed + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_MTP_GetHSCfgDesc(uint16_t *length) +{ + 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; +} + +/** + * @brief USBD_MTP_GetFSCfgDesc + * Return configuration descriptor + * @param speed : current device speed + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_MTP_GetFSCfgDesc(uint16_t *length) +{ + 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; +} + +/** + * @brief USBD_MTP_GetOtherSpeedCfgDesc + * Return configuration descriptor + * @param speed : current device speed + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_MTP_GetOtherSpeedCfgDesc(uint16_t *length) +{ + 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; +} + +/** + * @brief USBD_MTP_GetDeviceQualifierDescriptor + * return Device Qualifier descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +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 + * @param pdev: device instance + * @param fops: CD Interface callback + * @retval status + */ +uint8_t USBD_MTP_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_MTP_ItfTypeDef *fops) +{ + if (fops == NULL) + { + return (uint8_t)USBD_FAIL; + } + + pdev->pUserData[pdev->classId] = fops; + + return (uint8_t)USBD_OK; +} + +/** + * @} + */ + +/** + * @} + */ + diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp_if_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp_if_template.c new file mode 100644 index 0000000000..baeb9ca1bb --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp_if_template.c @@ -0,0 +1,347 @@ +/** + ****************************************************************************** + * @file usbd_mtp_if.c + * @author MCD Application Team + * @brief Source file for USBD MTP file list_files. + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_mtp_if_template.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* +static FILE MyFile; +static FATFS SDFatFs; +static char SDPath[4]; +static FolderLevel Fold_Lvl; +static FOLD_INFTypeDef FoldStruct; +static FILE_INFTypeDef FileStruct; +static SD_Object_TypeDef sd_object; +*/ +extern USBD_HandleTypeDef USBD_Device; + +uint32_t idx[200]; +uint32_t parent; +/* static char path[255]; */ +uint32_t sc_buff[MTP_IF_SCRATCH_BUFF_SZE / 4U]; +uint32_t sc_len = 0U; +uint32_t pckt_cnt = 1U; +uint32_t foldsize; + +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static uint8_t USBD_MTP_Itf_Init(void); +static uint8_t USBD_MTP_Itf_DeInit(void); +static uint32_t USBD_MTP_Itf_ReadData(uint32_t Param1, uint8_t *buff, MTP_DataLengthTypeDef *data_length); +static uint16_t USBD_MTP_Itf_Create_NewObject(MTP_ObjectInfoTypeDef ObjectInfo, uint32_t objhandle); + +static uint32_t USBD_MTP_Itf_GetIdx(uint32_t Param3, uint32_t *obj_handle); +static uint32_t USBD_MTP_Itf_GetParentObject(uint32_t Param); +static uint16_t USBD_MTP_Itf_GetObjectFormat(uint32_t Param); +static uint8_t USBD_MTP_Itf_GetObjectName_len(uint32_t Param); +static void USBD_MTP_Itf_GetObjectName(uint32_t Param, uint8_t obj_len, uint16_t *buf); +static uint32_t USBD_MTP_Itf_GetObjectSize(uint32_t Param); +static uint64_t USBD_MTP_Itf_GetMaxCapability(void); +static uint64_t USBD_MTP_Itf_GetFreeSpaceInBytes(void); +static uint32_t USBD_MTP_Itf_GetNewIndex(uint16_t objformat); +static void USBD_MTP_Itf_WriteData(uint16_t len, uint8_t *buff); +static uint32_t USBD_MTP_Itf_GetContainerLength(uint32_t Param1); +static uint16_t USBD_MTP_Itf_DeleteObject(uint32_t Param1); + +static void USBD_MTP_Itf_Cancel(uint32_t Phase); +/* static uint32_t USBD_MTP_Get_idx_to_delete(uint32_t Param, uint8_t *tab); */ + +USBD_MTP_ItfTypeDef USBD_MTP_fops = +{ + USBD_MTP_Itf_Init, + USBD_MTP_Itf_DeInit, + USBD_MTP_Itf_ReadData, + USBD_MTP_Itf_Create_NewObject, + USBD_MTP_Itf_GetIdx, + USBD_MTP_Itf_GetParentObject, + USBD_MTP_Itf_GetObjectFormat, + USBD_MTP_Itf_GetObjectName_len, + USBD_MTP_Itf_GetObjectName, + USBD_MTP_Itf_GetObjectSize, + USBD_MTP_Itf_GetMaxCapability, + USBD_MTP_Itf_GetFreeSpaceInBytes, + USBD_MTP_Itf_GetNewIndex, + USBD_MTP_Itf_WriteData, + USBD_MTP_Itf_GetContainerLength, + USBD_MTP_Itf_DeleteObject, + USBD_MTP_Itf_Cancel, + sc_buff, + MTP_IF_SCRATCH_BUFF_SZE, +}; + +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief USBD_MTP_Itf_Init + * Initialize the file system Layer + * @param None + * @retval status value + */ +static uint8_t USBD_MTP_Itf_Init(void) +{ + return 0; +} + +/** + * @brief USBD_MTP_Itf_DeInit + * Uninitialize the file system Layer + * @param None + * @retval status value + */ +static uint8_t USBD_MTP_Itf_DeInit(void) +{ + return 0; +} + +/** + * @brief USBD_MTP_Itf_GetIdx + * Get all object handle + * @param Param3: current object handle + * @param obj_handle: all objects handle (subfolders/files) in current object + * @retval number of object handle in current object + */ +static uint32_t USBD_MTP_Itf_GetIdx(uint32_t Param3, uint32_t *obj_handle) +{ + uint32_t count = 0U; + UNUSED(Param3); + UNUSED(obj_handle); + + return count; +} + +/** + * @brief USBD_MTP_Itf_GetParentObject + * Get parent object + * @param Param: object handle (object index) + * @retval parent object + */ +static uint32_t USBD_MTP_Itf_GetParentObject(uint32_t Param) +{ + uint32_t parentobj = 0U; + UNUSED(Param); + + return parentobj; +} + +/** + * @brief USBD_MTP_Itf_GetObjectFormat + * Get object format + * @param Param: object handle (object index) + * @retval object format + */ +static uint16_t USBD_MTP_Itf_GetObjectFormat(uint32_t Param) +{ + uint16_t objformat = 0U; + UNUSED(Param); + + return objformat; +} + +/** + * @brief USBD_MTP_Itf_GetObjectName_len + * Get object name length + * @param Param: object handle (object index) + * @retval object name length + */ +static uint8_t USBD_MTP_Itf_GetObjectName_len(uint32_t Param) +{ + uint8_t obj_len = 0U; + UNUSED(Param); + + return obj_len; +} + +/** + * @brief USBD_MTP_Itf_GetObjectName + * Get object name + * @param Param: object handle (object index) + * @param obj_len: length of object name + * @param buf: pointer to object name + * @retval object size in SD card + */ +static void USBD_MTP_Itf_GetObjectName(uint32_t Param, uint8_t obj_len, uint16_t *buf) +{ + UNUSED(Param); + UNUSED(obj_len); + UNUSED(buf); + + return; +} + +/** + * @brief USBD_MTP_Itf_GetObjectSize + * Get size of current object + * @param Param: object handle (object index) + * @retval object size in SD card + */ +static uint32_t USBD_MTP_Itf_GetObjectSize(uint32_t Param) +{ + uint32_t ObjCompSize = 0U; + UNUSED(Param); + + return ObjCompSize; +} + +/** + * @brief USBD_MTP_Itf_Create_NewObject + * Create new object in SD card and store necessary information for future use + * @param ObjectInfo: object information to use + * @param objhandle: object handle (object index) + * @retval None + */ +static uint16_t USBD_MTP_Itf_Create_NewObject(MTP_ObjectInfoTypeDef ObjectInfo, uint32_t objhandle) +{ + uint16_t rep_code = 0U; + UNUSED(ObjectInfo); + UNUSED(objhandle); + + return rep_code; +} + +/** + * @brief USBD_MTP_Itf_GetMaxCapability + * Get max capability in SD card + * @param None + * @retval max capability + */ +static uint64_t USBD_MTP_Itf_GetMaxCapability(void) +{ + uint64_t max_cap = 0U; + + return max_cap; +} + +/** + * @brief USBD_MTP_Itf_GetFreeSpaceInBytes + * Get free space in bytes in SD card + * @param None + * @retval free space in bytes + */ +static uint64_t USBD_MTP_Itf_GetFreeSpaceInBytes(void) +{ + uint64_t f_space_inbytes = 0U; + + return f_space_inbytes; +} + +/** + * @brief USBD_MTP_Itf_GetNewIndex + * Create new object handle + * @param objformat: object format + * @retval object handle + */ +static uint32_t USBD_MTP_Itf_GetNewIndex(uint16_t objformat) +{ + uint32_t n_index = 0U; + UNUSED(objformat); + + return n_index; +} + +/** + * @brief USBD_MTP_Itf_WriteData + * Write file data to SD card + * @param len: size of data to write + * @param buff: data to write in SD card + * @retval None + */ +static void USBD_MTP_Itf_WriteData(uint16_t len, uint8_t *buff) +{ + UNUSED(len); + UNUSED(buff); + + return; +} + +/** + * @brief USBD_MTP_Itf_GetContainerLength + * Get length of generic container + * @param Param1: object handle + * @retval length of generic container + */ +static uint32_t USBD_MTP_Itf_GetContainerLength(uint32_t Param1) +{ + uint32_t length = 0U; + UNUSED(Param1); + + return length; +} + +/** + * @brief USBD_MTP_Itf_DeleteObject + * delete object from SD card + * @param Param1: object handle (file/folder index) + * @retval response code + */ +static uint16_t USBD_MTP_Itf_DeleteObject(uint32_t Param1) +{ + uint16_t rep_code = 0U; + UNUSED(Param1); + + return rep_code; +} + +/** + * @brief USBD_MTP_Get_idx_to_delete + * Get all files/foldres index to delete with descending order ( max depth) + * @param Param: object handle (file/folder index) + * @param tab: pointer to list of files/folders to delete + * @retval Number of files/folders to delete + */ +/* static uint32_t USBD_MTP_Get_idx_to_delete(uint32_t Param, uint8_t *tab) +{ + uint32_t cnt = 0U; + + return cnt; +} +*/ + +/** + * @brief USBD_MTP_Itf_ReadData + * Read data from SD card + * @param Param1: object handle + * @param buff: pointer to data to be read + * @param temp_length: current data size read + * @retval necessary information for next read/finish reading + */ +static uint32_t USBD_MTP_Itf_ReadData(uint32_t Param1, uint8_t *buff, MTP_DataLengthTypeDef *data_length) +{ + UNUSED(Param1); + UNUSED(buff); + UNUSED(data_length); + + return 0U; +} + +/** + * @brief USBD_MTP_Itf_Cancel + * Close opened folder/file while cancelling transaction + * @param MTP_ResponsePhase: MTP current state + * @retval None + */ +static void USBD_MTP_Itf_Cancel(uint32_t Phase) +{ + UNUSED(Phase); + + /* Make sure to close open file while canceling transaction */ + + return; +} diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp_opt.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp_opt.c new file mode 100644 index 0000000000..9a49717bb7 --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp_opt.c @@ -0,0 +1,1267 @@ +/** + ****************************************************************************** + * @file usbd_mtp_opt.c + * @author MCD Application Team + * @brief This file includes the PTP operations layer + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_mtp_opt.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +static uint8_t ObjInfo_buff[255]; +static uint32_t objhandle; +static uint16_t obj_format; +static uint32_t storage_id; + +static MTP_DeviceInfoTypedef MTP_DeviceInfo; +static MTP_StorageIDSTypeDef MTP_StorageIDS; +static MTP_StorageInfoTypedef MTP_StorageInfo; +static MTP_ObjectHandleTypeDef MTP_ObjectHandle; +static MTP_ObjectInfoTypeDef MTP_ObjectInfo; +static MTP_ObjectPropSuppTypeDef MTP_ObjectPropSupp; +static MTP_ObjectPropDescTypeDef MTP_ObjectPropDesc; +static MTP_PropertiesListTypedef MTP_PropertiesList; +static MTP_RefTypeDef MTP_Ref; +static MTP_PropertyValueTypedef MTP_PropertyValue; +static MTP_FileNameTypeDef MTP_FileName; +static MTP_DevicePropDescTypeDef MTP_DevicePropDesc; + +/* Private function prototypes -----------------------------------------------*/ +static void MTP_Get_DeviceInfo(void); +static void MTP_Get_StorageIDS(void); +static void MTP_Get_PayloadContent(USBD_HandleTypeDef *pdev); +static void MTP_Get_ObjectInfo(USBD_HandleTypeDef *pdev); +static void MTP_Get_StorageInfo(USBD_HandleTypeDef *pdev); +static void MTP_Get_ObjectHandle(USBD_HandleTypeDef *pdev); +static void MTP_Get_ObjectPropSupp(void); +static void MTP_Get_ObjectPropDesc(USBD_HandleTypeDef *pdev); +static void MTP_Get_ObjectPropList(USBD_HandleTypeDef *pdev); +static void MTP_Get_DevicePropDesc(void); +static uint8_t *MTP_Get_ObjectPropValue(USBD_HandleTypeDef *pdev); +static uint32_t MTP_build_data_propdesc(USBD_HandleTypeDef *pdev, MTP_ObjectPropDescTypeDef def); +static uint32_t MTP_build_data_ObjInfo(USBD_HandleTypeDef *pdev, MTP_ObjectInfoTypeDef objinfo); +static uint32_t MTP_build_data_proplist(USBD_HandleTypeDef *pdev, + MTP_PropertiesListTypedef proplist, uint32_t idx); + +/* Private functions ---------------------------------------------------------*/ + +/** + * @} + */ + + +/** + * @brief USBD_MTP_OPT_CreateObjectHandle + * Open a new session + * @param pdev: device instance + * @retval None + */ +void USBD_MTP_OPT_CreateObjectHandle(USBD_HandleTypeDef *pdev) +{ + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + + if (hmtp->OperationsContainer.Param1 == 0U) /* Param1 == Session ID*/ + { + hmtp->ResponseCode = MTP_RESPONSE_INVALID_PARAMETER; + } + /* driver supports single session */ + else if (hmtp->MTP_SessionState == MTP_SESSION_OPENED) + { + hmtp->ResponseCode = MTP_RESPONSE_SESSION_ALREADY_OPEN; + } + else + { + hmtp->ResponseCode = MTP_RESPONSE_OK; + hmtp->MTP_SessionState = MTP_SESSION_OPENED; + } + + hmtp->GenericContainer.trans_id = hmtp->OperationsContainer.trans_id; + hmtp->GenericContainer.type = MTP_CONT_TYPE_RESPONSE; + hmtp->ResponseLength = MTP_CONT_HEADER_SIZE; + hmtp->GenericContainer.length = hmtp->ResponseLength; +} + +/** + * @brief USBD_MTP_OPT_GetDeviceInfo + * Get all device information + * @param pdev: device instance + * @retval None + */ +void USBD_MTP_OPT_GetDeviceInfo(USBD_HandleTypeDef *pdev) +{ + 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*/ + /* Param1 == session ID*/ + if ((hmtp->OperationsContainer.Param1 == 0U) && (hmtp->OperationsContainer.trans_id == 0U)) + { + hmtp->ResponseCode = MTP_RESPONSE_OK; + } + else + { + hmtp->GenericContainer.trans_id = hmtp->OperationsContainer.trans_id; + hmtp->GenericContainer.type = MTP_CONT_TYPE_RESPONSE; + hmtp->ResponseCode = MTP_RESPONSE_INVALID_PARAMETER; + hmtp->GenericContainer.length = MTP_CONT_HEADER_SIZE; + } + } + else + { + hmtp->ResponseCode = MTP_RESPONSE_OK; + } + + if (hmtp->ResponseCode == MTP_RESPONSE_OK) + { + hmtp->GenericContainer.code = MTP_OP_GET_DEVICE_INFO; + hmtp->GenericContainer.trans_id = hmtp->OperationsContainer.trans_id; + hmtp->GenericContainer.type = MTP_CONT_TYPE_DATA; + + (void)MTP_Get_PayloadContent(pdev); + + hmtp->ResponseLength = sizeof(MTP_DeviceInfo) + MTP_CONT_HEADER_SIZE; + hmtp->GenericContainer.length = hmtp->ResponseLength; + } +} + +/** + * @brief USBD_MTP_OPT_GetStorageIDS + * Get Storage IDs + * @param pdev: device instance + * @retval None + */ +void USBD_MTP_OPT_GetStorageIDS(USBD_HandleTypeDef *pdev) +{ + 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; + + (void)MTP_Get_PayloadContent(pdev); + + hmtp->ResponseLength = sizeof(MTP_StorageIDS) + MTP_CONT_HEADER_SIZE; + hmtp->GenericContainer.length = hmtp->ResponseLength; + + hmtp->ResponseCode = MTP_RESPONSE_OK; +} + +/** + * @brief USBD_MTP_OPT_GetStorageInfo + * Get Storage information + * @param pdev: device instance + * @retval None + */ +void USBD_MTP_OPT_GetStorageInfo(USBD_HandleTypeDef *pdev) +{ + 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; + + (void)MTP_Get_PayloadContent(pdev); + + hmtp->ResponseLength = sizeof(MTP_StorageInfo) + MTP_CONT_HEADER_SIZE; + hmtp->GenericContainer.length = hmtp->ResponseLength; + + hmtp->ResponseCode = MTP_RESPONSE_OK; +} + +/** + * @brief USBD_MTP_OPT_GetObjectHandle + * Get all object handles + * @param pdev: device instance + * @retval None + */ +void USBD_MTP_OPT_GetObjectHandle(USBD_HandleTypeDef *pdev) +{ + 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; + + (void)MTP_Get_PayloadContent(pdev); + + hmtp->ResponseLength = hmtp->ResponseLength + MTP_CONT_HEADER_SIZE; + hmtp->GenericContainer.length = hmtp->ResponseLength; + + hmtp->ResponseCode = MTP_RESPONSE_OK; +} + +/** + * @brief USBD_MTP_OPT_GetObjectInfo + * Get all information about the object + * @param pdev: device instance + * @retval None + */ +void USBD_MTP_OPT_GetObjectInfo(USBD_HandleTypeDef *pdev) +{ + 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; + hmtp->GenericContainer.type = MTP_CONT_TYPE_DATA; + + (void)MTP_Get_PayloadContent(pdev); + + hmtp->ResponseLength = hmtp->ResponseLength + MTP_CONT_HEADER_SIZE; + hmtp->GenericContainer.length = hmtp->ResponseLength; + + hmtp->ResponseCode = MTP_RESPONSE_OK; +} + +/** + * @brief USBD_MTP_OPT_GetObjectReferences + * Get object references + * @param pdev: device instance + * @retval None + */ +void USBD_MTP_OPT_GetObjectReferences(USBD_HandleTypeDef *pdev) +{ + 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; + hmtp->GenericContainer.type = MTP_CONT_TYPE_DATA; + + (void)MTP_Get_PayloadContent(pdev); + + hmtp->ResponseLength = sizeof(MTP_Ref) + MTP_CONT_HEADER_SIZE; + hmtp->GenericContainer.length = hmtp->ResponseLength; + + hmtp->ResponseCode = MTP_RESPONSE_OK; +} + +/** + * @brief USBD_MTP_OPT_GetObjectPropSupp + * Get all object properties supported + * @param pdev: device instance + * @retval None + */ +void USBD_MTP_OPT_GetObjectPropSupp(USBD_HandleTypeDef *pdev) +{ + 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; + hmtp->GenericContainer.type = MTP_CONT_TYPE_DATA; + + (void)MTP_Get_PayloadContent(pdev); + + hmtp->ResponseLength = sizeof(MTP_ObjectPropSupp) + MTP_CONT_HEADER_SIZE; + hmtp->GenericContainer.length = hmtp->ResponseLength; + + hmtp->ResponseCode = MTP_RESPONSE_OK; +} + +/** + * @brief USBD_MTP_OPT_GetObjectPropDesc + * Get all descriptions about object properties + * @param pdev: device instance + * @retval None + */ +void USBD_MTP_OPT_GetObjectPropDesc(USBD_HandleTypeDef *pdev) +{ + 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; + hmtp->GenericContainer.type = MTP_CONT_TYPE_DATA; + + (void)MTP_Get_PayloadContent(pdev); + + hmtp->ResponseLength = hmtp->ResponseLength + MTP_CONT_HEADER_SIZE; + hmtp->GenericContainer.length = hmtp->ResponseLength; + + hmtp->ResponseCode = MTP_RESPONSE_OK; +} + +/** + * @brief USBD_MTP_OPT_GetObjectPropList + * Get the list of object properties + * @param pdev: device instance + * @retval None + */ +void USBD_MTP_OPT_GetObjectPropList(USBD_HandleTypeDef *pdev) +{ + 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; + hmtp->GenericContainer.type = MTP_CONT_TYPE_DATA; + + (void)MTP_Get_PayloadContent(pdev); + + hmtp->ResponseLength = hmtp->ResponseLength + MTP_CONT_HEADER_SIZE; + hmtp->GenericContainer.length = hmtp->ResponseLength; + + hmtp->ResponseCode = MTP_RESPONSE_OK; +} + +/** + * @brief USBD_MTP_OPT_GetObjectPropValue + * Get current value of the object property + * @param pdev: device instance + * @retval None + */ +void USBD_MTP_OPT_GetObjectPropValue(USBD_HandleTypeDef *pdev) +{ + 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; + hmtp->GenericContainer.type = MTP_CONT_TYPE_DATA; + + (void)MTP_Get_PayloadContent(pdev); + + hmtp->ResponseLength = hmtp->ResponseLength + MTP_CONT_HEADER_SIZE; + hmtp->GenericContainer.length = hmtp->ResponseLength; + + hmtp->ResponseCode = MTP_RESPONSE_OK; +} + +/** + * @brief USBD_MTP_OPT_GetObject + * Get binary data from an object + * @param pdev: device instance + * @retval None + */ +void USBD_MTP_OPT_GetObject(USBD_HandleTypeDef *pdev) +{ + 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; + hmtp->GenericContainer.type = MTP_CONT_TYPE_DATA; + + hmtp->ResponseCode = MTP_RESPONSE_OK; +} + +/** + * @brief USBD_MTP_OPT_GetDevicePropDesc + * Get The DevicePropDesc dataset + * @param pdev: device instance + * @retval None + */ +void USBD_MTP_OPT_GetDevicePropDesc(USBD_HandleTypeDef *pdev) +{ + 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; + hmtp->GenericContainer.type = MTP_CONT_TYPE_DATA; + + (void)MTP_Get_PayloadContent(pdev); + + hmtp->ResponseLength = sizeof(MTP_DevicePropDesc) + MTP_CONT_HEADER_SIZE; + hmtp->GenericContainer.length = hmtp->ResponseLength; + + hmtp->ResponseCode = MTP_RESPONSE_OK; +} + +/** + * @brief USBD_MTP_OPT_SendObject + * Send object from host to MTP device + * @param pdev: device instance + * @retval None + */ +void USBD_MTP_OPT_SendObject(USBD_HandleTypeDef *pdev, uint8_t *buff, uint32_t len) +{ + 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) + { + case RECEIVE_IDLE_STATE: + hmtp->RECEIVE_DATA_STATUS = RECEIVE_COMMAND_DATA; + break; + case RECEIVE_COMMAND_DATA: + hmtp->RECEIVE_DATA_STATUS = RECEIVE_FIRST_DATA; + break; + case RECEIVE_FIRST_DATA: + if ((uint16_t)len < (hmtp->MaxPcktLen - MTP_CONT_HEADER_SIZE)) + { + hmtp->GenericContainer.code = MTP_RESPONSE_OK; + hmtp->GenericContainer.trans_id = hmtp->OperationsContainer.trans_id; + hmtp->GenericContainer.type = MTP_CONT_TYPE_RESPONSE; + hmtp->ResponseLength = MTP_CONT_HEADER_SIZE; + hmtp->GenericContainer.length = hmtp->ResponseLength; + + hmtp->RECEIVE_DATA_STATUS = RECEIVE_IDLE_STATE; + } + else + { + hmtp->RECEIVE_DATA_STATUS = RECEIVE_REST_OF_DATA; + } + tmp = (uint32_t)buff; + hmtpif->WriteData(len, (uint8_t *)(tmp + 12U)); + break; + + case RECEIVE_REST_OF_DATA: + hmtpif->WriteData(len, buff); + break; + + case SEND_RESPONSE: + hmtpif->WriteData(0, buff); /* send 0 length to stop write process */ + hmtp->GenericContainer.code = MTP_RESPONSE_OK; + hmtp->GenericContainer.trans_id = hmtp->OperationsContainer.trans_id; + hmtp->GenericContainer.type = MTP_CONT_TYPE_RESPONSE; + hmtp->ResponseLength = MTP_CONT_HEADER_SIZE; + hmtp->GenericContainer.length = hmtp->ResponseLength; + + hmtp->RECEIVE_DATA_STATUS = RECEIVE_IDLE_STATE; + break; + + default: + break; + } + + hmtp->ResponseCode = MTP_RESPONSE_OK; +} + +/** + * @brief USBD_MTP_OPT_SendObjectInfo + * Send the object information from host to MTP device + * @param pdev: device instance + * @retval None + */ +void USBD_MTP_OPT_SendObjectInfo(USBD_HandleTypeDef *pdev, uint8_t *buff, uint32_t len) +{ + 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; + + switch (hmtp->RECEIVE_DATA_STATUS) + { + case RECEIVE_IDLE_STATE: + hmtp->RECEIVE_DATA_STATUS = RECEIVE_COMMAND_DATA; + break; + + case RECEIVE_COMMAND_DATA: + /* store object handle and storage id for future use */ + if (hmtp->OperationsContainer.Param2 == 0xFFFFFFFFU) + { + objhandle = 0U; + } + else + { + objhandle = hmtp->OperationsContainer.Param2; + } + storage_id = hmtp->OperationsContainer.Param1; + hmtp->RECEIVE_DATA_STATUS = RECEIVE_FIRST_DATA; + break; + + case RECEIVE_FIRST_DATA: + tmp = buff; + + (void)USBD_memcpy(ObjInfo_buff, tmp + 12U, + (uint16_t)(hmtp->MaxPcktLen - MTP_CONT_HEADER_SIZE)); + + hmtp->RECEIVE_DATA_STATUS = RECEIVE_REST_OF_DATA; + break; + + case RECEIVE_REST_OF_DATA: + + (void)USBD_memcpy(ObjInfo_buff + len, buff, hmtp->MaxPcktLen); + + break; + + case SEND_RESPONSE: + (void)USBD_memcpy((uint8_t *)&ObjectInfo, ObjInfo_buff, dataLength); + (void)USBD_memcpy((uint8_t *)&ObjectInfo.Filename, (ObjInfo_buff + dataLength), + ((uint32_t)(ObjectInfo.Filename_len) * 2U)); + + obj_format = ObjectInfo.ObjectFormat; + + hmtp->ResponseCode = hmtpif->Create_NewObject(ObjectInfo, objhandle); + hmtp->GenericContainer.code = (uint16_t)hmtp->ResponseCode; + hmtp->ResponseLength = MTP_CONT_HEADER_SIZE + (sizeof(uint32_t) * 3U); /* Header + 3 Param */ + hmtp->GenericContainer.length = hmtp->ResponseLength; + hmtp->GenericContainer.type = MTP_CONT_TYPE_RESPONSE; + hmtp->GenericContainer.trans_id = hmtp->OperationsContainer.trans_id; + + (void)MTP_Get_PayloadContent(pdev); + + hmtp->RECEIVE_DATA_STATUS = RECEIVE_IDLE_STATE; + break; + + default: + break; + } +} + +/** + * @brief USBD_MTP_OPT_DeleteObject + * Delete the object from the device + * @param pdev: device instance + * @retval None + */ +void USBD_MTP_OPT_DeleteObject(USBD_HandleTypeDef *pdev) +{ + 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; + hmtp->ResponseLength = MTP_CONT_HEADER_SIZE; + hmtp->GenericContainer.length = hmtp->ResponseLength; + hmtp->ResponseCode = hmtpif->DeleteObject(hmtp->OperationsContainer.Param1); +} + +/** + * @brief MTP_Get_PayloadContent + * Get the payload data of generic container + * @param pdev: device instance + * @retval None + */ +static void MTP_Get_PayloadContent(USBD_HandleTypeDef *pdev) +{ + 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; + + switch (hmtp->OperationsContainer.code) + { + case MTP_OP_GET_DEVICE_INFO: + (void)MTP_Get_DeviceInfo(); + (void)USBD_memcpy(buffer, (const uint8_t *)&MTP_DeviceInfo, sizeof(MTP_DeviceInfo)); + + for (i = 0U; i < sizeof(MTP_StorageIDS); i++) + { + hmtp->GenericContainer.data[i] = buffer[i]; + } + break; + + case MTP_OP_GET_STORAGE_IDS: + (void)MTP_Get_StorageIDS(); + (void)USBD_memcpy(buffer, (const uint8_t *)&MTP_StorageIDS, sizeof(MTP_StorageIDS)); + + for (i = 0U; i < sizeof(MTP_StorageIDS); i++) + { + hmtp->GenericContainer.data[i] = buffer[i]; + } + break; + + case MTP_OP_GET_STORAGE_INFO: + (void)MTP_Get_StorageInfo(pdev); + (void)USBD_memcpy(buffer, (const uint8_t *)&MTP_StorageInfo, sizeof(MTP_StorageInfo)); + + for (i = 0U; i < sizeof(MTP_StorageInfo); i++) + { + hmtp->GenericContainer.data[i] = buffer[i]; + } + break; + + case MTP_OP_GET_OBJECT_HANDLES: + (void)MTP_Get_ObjectHandle(pdev); + (void)USBD_memcpy(buffer, (const uint8_t *)&MTP_ObjectHandle, hmtp->ResponseLength); + + for (i = 0U; i < hmtp->ResponseLength; i++) + { + hmtp->GenericContainer.data[i] = buffer[i]; + } + break; + + case MTP_OP_GET_OBJECT_INFO: + (void)MTP_Get_ObjectInfo(pdev); + break; + + case MTP_OP_GET_OBJECT_PROPS_SUPPORTED: + (void)MTP_Get_ObjectPropSupp(); + (void)USBD_memcpy(buffer, (const uint8_t *)&MTP_ObjectPropSupp, sizeof(MTP_ObjectPropSupp)); + + for (i = 0U; i < sizeof(MTP_ObjectPropSupp); i++) + { + hmtp->GenericContainer.data[i] = buffer[i]; + } + break; + + case MTP_OP_GET_OBJECT_PROP_DESC: + (void)MTP_Get_ObjectPropDesc(pdev); + hmtp->ResponseLength = MTP_build_data_propdesc(pdev, MTP_ObjectPropDesc); + break; + + case MTP_OP_GET_OBJECT_PROP_REFERENCES: + MTP_Ref.ref_len = 0U; + (void)USBD_memcpy(buffer, (const uint8_t *)&MTP_Ref.ref_len, sizeof(MTP_Ref.ref_len)); + + for (i = 0U; i < sizeof(MTP_Ref.ref_len); i++) + { + hmtp->GenericContainer.data[i] = buffer[i]; + } + break; + + case MTP_OP_GET_OBJECT_PROPLIST: + (void)MTP_Get_ObjectPropList(pdev); + break; + + case MTP_OP_GET_OBJECT_PROP_VALUE: + buffer = MTP_Get_ObjectPropValue(pdev); + for (i = 0U; i < hmtp->ResponseLength; i++) + { + hmtp->GenericContainer.data[i] = buffer[i]; + } + + break; + + case MTP_OP_GET_DEVICE_PROP_DESC: + (void)MTP_Get_DevicePropDesc(); + (void)USBD_memcpy(buffer, (const uint8_t *)&MTP_DevicePropDesc, sizeof(MTP_DevicePropDesc)); + for (i = 0U; i < sizeof(MTP_DevicePropDesc); i++) + { + hmtp->GenericContainer.data[i] = buffer[i]; + } + break; + + case MTP_OP_SEND_OBJECT_INFO: + n_idx = hmtpif->GetNewIndex(obj_format); + (void)USBD_memcpy(hmtp->GenericContainer.data, (const uint8_t *)&storage_id, sizeof(uint32_t)); + (void)USBD_memcpy(hmtp->GenericContainer.data + 4U, (const uint8_t *)&objhandle, sizeof(uint32_t)); + (void)USBD_memcpy(hmtp->GenericContainer.data + 8U, (const uint8_t *)&n_idx, sizeof(uint32_t)); + break; + + case MTP_OP_GET_OBJECT: + break; + + default: + break; + } +} + +/** + * @brief MTP_Get_DeviceInfo + * Fill the MTP_DeviceInfo struct + * @param pdev: device instance + * @retval None + */ +static void MTP_Get_DeviceInfo(void) +{ + MTP_DeviceInfo.StandardVersion = STANDARD_VERSION; + MTP_DeviceInfo.VendorExtensionID = VEND_EXT_ID; + MTP_DeviceInfo.VendorExtensionVersion = VEND_EXT_VERSION; + MTP_DeviceInfo.VendorExtensionDesc_len = (uint8_t)VEND_EXT_DESC_LEN; + uint32_t i; + +#if USBD_MTP_VEND_EXT_DESC_SUPPORTED == 1 + for (i = 0U; i < VEND_EXT_DESC_LEN; i++) + { + MTP_DeviceInfo.VendorExtensionDesc[i] = VendExtDesc[i]; + } +#endif /* USBD_MTP_VEND_EXT_DESC_SUPPORTED */ + + MTP_DeviceInfo.FunctionalMode = FUNCTIONAL_MODE; /* device supports one mode , standard mode */ + + /* All supported operation */ + MTP_DeviceInfo.OperationsSupported_len = SUPP_OP_LEN; + for (i = 0U; i < SUPP_OP_LEN; i++) + { + MTP_DeviceInfo.OperationsSupported[i] = SuppOP[i]; + } + + MTP_DeviceInfo.EventsSupported_len = SUPP_EVENTS_LEN; /* event that are currently generated by the device*/ + +#if USBD_MTP_EVENTS_SUPPORTED == 1 + for (i = 0U; i < SUPP_EVENTS_LEN; i++) + { + MTP_DeviceInfo.EventsSupported[i] = SuppEvents[i]; + } +#endif /* USBD_MTP_EVENTS_SUPPORTED */ + + MTP_DeviceInfo.DevicePropertiesSupported_len = SUPP_DEVICE_PROP_LEN; + +#if USBD_MTP_DEVICE_PROP_SUPPORTED == 1 + for (i = 0U; i < SUPP_DEVICE_PROP_LEN; i++) + { + MTP_DeviceInfo.DevicePropertiesSupported[i] = DevicePropSupp[i]; + } +#endif /* USBD_MTP_DEVICE_PROP_SUPPORTED */ + + MTP_DeviceInfo.CaptureFormats_len = SUPP_CAPT_FORMAT_LEN; + +#if USBD_MTP_CAPTURE_FORMAT_SUPPORTED == 1 + for (i = 0U; i < SUPP_CAPT_FORMAT_LEN; i++) + { + MTP_DeviceInfo.CaptureFormats[i] = SuppCaptFormat[i]; + } +#endif /* USBD_MTP_CAPTURE_FORMAT_SUPPORTED */ + + MTP_DeviceInfo.ImageFormats_len = SUPP_IMG_FORMAT_LEN; /* number of image formats that are supported by the device*/ + for (i = 0U; i < SUPP_IMG_FORMAT_LEN; i++) + { + MTP_DeviceInfo.ImageFormats[i] = SuppImgFormat[i]; + } + + MTP_DeviceInfo.Manufacturer_len = (uint8_t)MANUF_LEN; + for (i = 0U; i < MANUF_LEN; i++) + { + MTP_DeviceInfo.Manufacturer[i] = Manuf[i]; + } + + MTP_DeviceInfo.Model_len = (uint8_t)MODEL_LEN; + for (i = 0U; i < MODEL_LEN; i++) + { + MTP_DeviceInfo.Model[i] = Model[i]; + } + + MTP_DeviceInfo.DeviceVersion_len = (uint8_t)DEVICE_VERSION_LEN; + for (i = 0U; i < DEVICE_VERSION_LEN; i++) + { + MTP_DeviceInfo.DeviceVersion[i] = DeviceVers[i]; + } + + MTP_DeviceInfo.SerialNumber_len = (uint8_t)SERIAL_NBR_LEN; + for (i = 0U; i < SERIAL_NBR_LEN; i++) + { + MTP_DeviceInfo.SerialNumber[i] = SerialNbr[i]; + } +} + +/** + * @brief MTP_Get_StorageInfo + * Fill the MTP_StorageInfo struct + * @param pdev: device instance + * @retval None + */ +static void MTP_Get_StorageInfo(USBD_HandleTypeDef *pdev) +{ + 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; + MTP_StorageInfo.AccessCapability = MTP_ACCESS_CAP_RW; + MTP_StorageInfo.MaxCapability = hmtpif->GetMaxCapability(); + MTP_StorageInfo.FreeSpaceInBytes = hmtpif->GetFreeSpaceInBytes(); + MTP_StorageInfo.FreeSpaceInObjects = FREE_SPACE_IN_OBJ_NOT_USED; /* not used */ + MTP_StorageInfo.StorageDescription = 0U; + MTP_StorageInfo.VolumeLabel = 0U; +} + +/** + * @brief MTP_Get_ObjectHandle + * Fill the MTP_ObjectHandle struct + * @param pdev: device instance + * @retval None + */ +static void MTP_Get_ObjectHandle(USBD_HandleTypeDef *pdev) +{ + 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)); + + hmtp->ResponseLength = (MTP_ObjectHandle.ObjectHandle_len * sizeof(uint32_t)) + sizeof(uint32_t); +} + +/** + * @brief MTP_Get_ObjectPropSupp + * Fill the MTP_ObjectPropSupp struct + * @param pdev: device instance + * @retval None + */ +static void MTP_Get_ObjectPropSupp(void) +{ + uint32_t i; + + MTP_ObjectPropSupp.ObjectPropSupp_len = SUPP_OBJ_PROP_LEN; + + for (i = 0U; i < SUPP_OBJ_PROP_LEN; i++) + { + MTP_ObjectPropSupp.ObjectPropSupp[i] = ObjectPropSupp[i]; + } +} + +/** + * @brief MTP_Get_ObjectPropDesc + * Fill the MTP_ObjectPropDesc struct + * @param pdev: device instance + * @retval None + */ +static void MTP_Get_ObjectPropDesc(USBD_HandleTypeDef *pdev) +{ + 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; + + switch (hmtp->OperationsContainer.Param1) /* switch obj prop code */ + { + case MTP_OB_PROP_OBJECT_FORMAT : + MTP_ObjectPropDesc.ObjectPropertyCode = (uint16_t)(hmtp->OperationsContainer.Param1); + MTP_ObjectPropDesc.DataType = MTP_DATATYPE_UINT16; + MTP_ObjectPropDesc.GetSet = MTP_PROP_GET; + MTP_ObjectPropDesc.DefValue = (uint8_t *)&undef_format; + MTP_ObjectPropDesc.GroupCode = 0U; + MTP_ObjectPropDesc.FormFlag = 0U; + break; + + case MTP_OB_PROP_STORAGE_ID : + MTP_ObjectPropDesc.ObjectPropertyCode = (uint16_t)(hmtp->OperationsContainer.Param1); + MTP_ObjectPropDesc.DataType = MTP_DATATYPE_UINT32; + MTP_ObjectPropDesc.GetSet = MTP_PROP_GET; + MTP_ObjectPropDesc.DefValue = (uint8_t *)&storageid; + MTP_ObjectPropDesc.GroupCode = 0U; + MTP_ObjectPropDesc.FormFlag = 0U; + break; + + case MTP_OB_PROP_OBJ_FILE_NAME : + MTP_ObjectPropDesc.ObjectPropertyCode = (uint16_t)(hmtp->OperationsContainer.Param1); + MTP_ObjectPropDesc.DataType = MTP_DATATYPE_STR; + MTP_ObjectPropDesc.GetSet = MTP_PROP_GET; + MTP_FileName.FileName_len = DEFAULT_FILE_NAME_LEN; + (void)USBD_memcpy((void *) & (MTP_FileName.FileName), (const void *)DefaultFileName, sizeof(DefaultFileName)); + MTP_ObjectPropDesc.DefValue = (uint8_t *)&MTP_FileName; + MTP_ObjectPropDesc.GroupCode = 0U; + MTP_ObjectPropDesc.FormFlag = 0U; + break; + + case MTP_OB_PROP_PARENT_OBJECT : + MTP_ObjectPropDesc.ObjectPropertyCode = (uint16_t)(hmtp->OperationsContainer.Param1); + MTP_ObjectPropDesc.DataType = MTP_DATATYPE_STR; + MTP_ObjectPropDesc.GetSet = MTP_PROP_GET; + MTP_ObjectPropDesc.DefValue = 0U; + MTP_ObjectPropDesc.GroupCode = 0U; + MTP_ObjectPropDesc.FormFlag = 0U; + break; + + case MTP_OB_PROP_OBJECT_SIZE : + MTP_ObjectPropDesc.ObjectPropertyCode = (uint16_t)(hmtp->OperationsContainer.Param1); + MTP_ObjectPropDesc.DataType = MTP_DATATYPE_UINT64; + MTP_ObjectPropDesc.GetSet = MTP_PROP_GET; + MTP_ObjectPropDesc.DefValue = 0U; + MTP_ObjectPropDesc.GroupCode = 0U; + MTP_ObjectPropDesc.FormFlag = 0U; + break; + + case MTP_OB_PROP_NAME : + MTP_ObjectPropDesc.ObjectPropertyCode = (uint16_t)(hmtp->OperationsContainer.Param1); + MTP_ObjectPropDesc.DataType = MTP_DATATYPE_STR; + MTP_ObjectPropDesc.GetSet = MTP_PROP_GET; + MTP_FileName.FileName_len = DEFAULT_FILE_NAME_LEN; + (void)USBD_memcpy((void *) & (MTP_FileName.FileName), + (const void *)DefaultFileName, sizeof(DefaultFileName)); + + MTP_ObjectPropDesc.DefValue = (uint8_t *)&MTP_FileName; + MTP_ObjectPropDesc.GroupCode = 0U; + MTP_ObjectPropDesc.FormFlag = 0U; + break; + + case MTP_OB_PROP_PERS_UNIQ_OBJ_IDEN : + MTP_ObjectPropDesc.ObjectPropertyCode = (uint16_t)(hmtp->OperationsContainer.Param1); + MTP_ObjectPropDesc.DataType = MTP_DATATYPE_UINT128; + MTP_ObjectPropDesc.GetSet = MTP_PROP_GET; + MTP_ObjectPropDesc.DefValue = 0U; + MTP_ObjectPropDesc.GroupCode = 0U; + MTP_ObjectPropDesc.FormFlag = 0U; + break; + + case MTP_OB_PROP_PROTECTION_STATUS : + MTP_ObjectPropDesc.ObjectPropertyCode = (uint16_t)(hmtp->OperationsContainer.Param1); + MTP_ObjectPropDesc.DataType = MTP_DATATYPE_UINT16; + MTP_ObjectPropDesc.GetSet = MTP_PROP_GET_SET; + MTP_ObjectPropDesc.DefValue = 0U; + MTP_ObjectPropDesc.GroupCode = 0U; + MTP_ObjectPropDesc.FormFlag = 0U; + break; + + default: + break; + } +} + +/** + * @brief MTP_Get_ObjectPropValue + * Get the property value + * @param pdev: device instance + * @retval None + */ +static uint8_t *MTP_Get_ObjectPropValue(USBD_HandleTypeDef *pdev) +{ + 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 */ + switch (hmtp->OperationsContainer.Param2) + { + case MTP_OB_PROP_STORAGE_ID: + MTP_PropertyValue.u32 = MTP_STORAGE_ID; + (void)USBD_memcpy(buf, (const uint8_t *)&MTP_PropertyValue, sizeof(uint32_t)); + hmtp->ResponseLength = sizeof(uint32_t); + break; + + case MTP_OB_PROP_OBJECT_FORMAT: + MTP_PropertyValue.u16 = hmtpif->GetObjectFormat(hmtp->OperationsContainer.Param1); + (void)USBD_memcpy(buf, (const uint8_t *)&MTP_PropertyValue, sizeof(uint16_t)); + hmtp->ResponseLength = sizeof(uint16_t); + break; + + case MTP_OB_PROP_OBJ_FILE_NAME: + MTP_FileName.FileName_len = hmtpif->GetObjectName_len(hmtp->OperationsContainer.Param1); + hmtpif->GetObjectName(hmtp->OperationsContainer.Param1, MTP_FileName.FileName_len, (uint16_t *)buf); + (void)USBD_memcpy(MTP_FileName.FileName, (uint16_t *)buf, ((uint32_t)MTP_FileName.FileName_len * 2U) + 1U); + + hmtp->ResponseLength = ((uint32_t)MTP_FileName.FileName_len * 2U) + 1U; + break; + + case MTP_OB_PROP_PARENT_OBJECT : + MTP_PropertyValue.u32 = hmtpif->GetParentObject(hmtp->OperationsContainer.Param1); + (void)USBD_memcpy(buf, (const uint8_t *)&MTP_PropertyValue, sizeof(uint32_t)); + hmtp->ResponseLength = sizeof(uint32_t); + break; + + case MTP_OB_PROP_OBJECT_SIZE : + MTP_PropertyValue.u64 = hmtpif->GetObjectSize(hmtp->OperationsContainer.Param1); + (void)USBD_memcpy(buf, (const uint8_t *)&MTP_PropertyValue, sizeof(uint64_t)); + hmtp->ResponseLength = sizeof(uint64_t); + break; + + default: + break; + } + + return buf; +} + +/** + * @brief MTP_Get_ObjectPropList + * Get the object property list data to be transmitted + * @param pdev: device instance + * @retval None + */ +static void MTP_Get_ObjectPropList(USBD_HandleTypeDef *pdev) +{ + 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; + uint32_t i; + uint16_t format; + uint64_t objsize; + uint32_t parent_proval; + + MTP_PropertiesList.MTP_Properties_len = SUPP_OBJ_PROP_LEN; + hmtp->ResponseLength = 4U; /* size of MTP_PropertiesList.MTP_Properties_len */ + (void)USBD_memcpy(hmtp->GenericContainer.data, + (const uint8_t *)&MTP_PropertiesList.MTP_Properties_len, hmtp->ResponseLength); + + for (i = 0U; i < SUPP_OBJ_PROP_LEN; i++) + { + MTP_PropertiesList.MTP_Properties[i].ObjectHandle = hmtp->OperationsContainer.Param1; + + switch (ObjectPropSupp[i]) + { + case MTP_OB_PROP_STORAGE_ID : + MTP_PropertiesList.MTP_Properties[i].PropertyCode = MTP_OB_PROP_STORAGE_ID; + MTP_PropertiesList.MTP_Properties[i].Datatype = MTP_DATATYPE_UINT32; + MTP_PropertiesList.MTP_Properties[i].propval = (uint8_t *)&storageid; + break; + + case MTP_OB_PROP_OBJECT_FORMAT : + MTP_PropertiesList.MTP_Properties[i].PropertyCode = MTP_OB_PROP_OBJECT_FORMAT; + MTP_PropertiesList.MTP_Properties[i].Datatype = MTP_DATATYPE_UINT16; + format = hmtpif->GetObjectFormat(hmtp->OperationsContainer.Param1); + MTP_PropertiesList.MTP_Properties[i].propval = (uint8_t *)&format; + break; + + case MTP_OB_PROP_OBJ_FILE_NAME: + MTP_PropertiesList.MTP_Properties[i].PropertyCode = MTP_OB_PROP_OBJ_FILE_NAME; + MTP_PropertiesList.MTP_Properties[i].Datatype = MTP_DATATYPE_STR; + /* 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); + MTP_PropertiesList.MTP_Properties[i].propval = (uint8_t *)&MTP_FileName; + break; + + case MTP_OB_PROP_PARENT_OBJECT : + MTP_PropertiesList.MTP_Properties[i].PropertyCode = MTP_OB_PROP_PARENT_OBJECT; + MTP_PropertiesList.MTP_Properties[i].Datatype = MTP_DATATYPE_UINT32; + parent_proval = hmtpif->GetParentObject(hmtp->OperationsContainer.Param1); + MTP_PropertiesList.MTP_Properties[i].propval = (uint8_t *)&parent_proval; + break; + + case MTP_OB_PROP_OBJECT_SIZE : + MTP_PropertiesList.MTP_Properties[i].PropertyCode = MTP_OB_PROP_OBJECT_SIZE; + MTP_PropertiesList.MTP_Properties[i].Datatype = MTP_DATATYPE_UINT64; + objsize = hmtpif->GetObjectSize(hmtp->OperationsContainer.Param1); + MTP_PropertiesList.MTP_Properties[i].propval = (uint8_t *)&objsize; + break; + + case MTP_OB_PROP_NAME : + MTP_PropertiesList.MTP_Properties[i].PropertyCode = MTP_OB_PROP_NAME; + MTP_PropertiesList.MTP_Properties[i].Datatype = MTP_DATATYPE_STR; + /* 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); + MTP_PropertiesList.MTP_Properties[i].propval = (uint8_t *)&MTP_FileName; + break; + + case MTP_OB_PROP_PERS_UNIQ_OBJ_IDEN : + MTP_PropertiesList.MTP_Properties[i].PropertyCode = MTP_OB_PROP_PERS_UNIQ_OBJ_IDEN; + MTP_PropertiesList.MTP_Properties[i].Datatype = MTP_DATATYPE_UINT128; + MTP_PropertiesList.MTP_Properties[i].propval = (uint8_t *)&hmtp->OperationsContainer.Param1; + break; + + case MTP_OB_PROP_PROTECTION_STATUS : + MTP_PropertiesList.MTP_Properties[i].PropertyCode = MTP_OB_PROP_PROTECTION_STATUS; + MTP_PropertiesList.MTP_Properties[i].Datatype = MTP_DATATYPE_UINT16; + MTP_PropertiesList.MTP_Properties[i].propval = (uint8_t *)&default_val; + break; + + default: + break; + } + + hmtp->ResponseLength = MTP_build_data_proplist(pdev, MTP_PropertiesList, i); + } +} + +/** + * @brief MTP_Get_DevicePropDesc + * Fill the MTP_DevicePropDesc struct + * @param pdev: device instance + * @retval None + */ +static void MTP_Get_DevicePropDesc(void) +{ + MTP_DevicePropDesc.DevicePropertyCode = MTP_DEV_PROP_DEVICE_FRIENDLY_NAME; + MTP_DevicePropDesc.DataType = MTP_DATATYPE_STR; + MTP_DevicePropDesc.GetSet = MTP_PROP_GET_SET; + MTP_DevicePropDesc.DefValue_len = DEVICE_PROP_DESC_DEF_LEN; + uint32_t i; + + for (i = 0U; i < (sizeof(DevicePropDefVal) / 2U); i++) + { + MTP_DevicePropDesc.DefValue[i] = DevicePropDefVal[i]; + } + + MTP_DevicePropDesc.curDefValue_len = DEVICE_PROP_DESC_CUR_LEN; + + for (i = 0U; i < (sizeof(DevicePropCurDefVal) / 2U); i++) + { + MTP_DevicePropDesc.curDefValue[i] = DevicePropCurDefVal[i]; + } + + MTP_DevicePropDesc.FormFlag = 0U; +} + +/** + * @brief MTP_Get_ObjectInfo + * Fill the MTP_ObjectInfo struct + * @param pdev: device instance + * @retval None + */ +static void MTP_Get_ObjectInfo(USBD_HandleTypeDef *pdev) +{ + 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; + MTP_ObjectInfo.ObjectFormat = hmtpif->GetObjectFormat(hmtp->OperationsContainer.Param1); + MTP_ObjectInfo.ObjectCompressedSize = hmtpif->GetObjectSize(hmtp->OperationsContainer.Param1); + MTP_ObjectInfo.ProtectionStatus = 0U; + MTP_ObjectInfo.ThumbFormat = MTP_OBJ_FORMAT_UNDEFINED; + MTP_ObjectInfo.ThumbCompressedSize = 0U; + MTP_ObjectInfo.ThumbPixWidth = 0U; /* not supported or not an image */ + MTP_ObjectInfo.ThumbPixHeight = 0U; + MTP_ObjectInfo.ImagePixWidth = 0U; + MTP_ObjectInfo.ImagePixHeight = 0U; + MTP_ObjectInfo.ImageBitDepth = 0U; + MTP_ObjectInfo.ParentObject = hmtpif->GetParentObject(hmtp->OperationsContainer.Param1); + MTP_ObjectInfo.AssociationType = 0U; + MTP_ObjectInfo.AssociationDesc = 0U; + MTP_ObjectInfo.SequenceNumber = 0U; + + /* we have to get this value before MTP_ObjectInfo.Filename */ + MTP_ObjectInfo.Filename_len = hmtpif->GetObjectName_len(hmtp->OperationsContainer.Param1); + hmtpif->GetObjectName(hmtp->OperationsContainer.Param1, MTP_ObjectInfo.Filename_len, filename); + (void)USBD_memcpy(MTP_ObjectInfo.Filename, filename, ((uint32_t)MTP_FileName.FileName_len * 2U) + 1U); + + MTP_ObjectInfo.CaptureDate = 0U; + MTP_ObjectInfo.ModificationDate = 0U; + MTP_ObjectInfo.Keywords = 0U; + hmtp->ResponseLength = MTP_build_data_ObjInfo(pdev, MTP_ObjectInfo); +} + +/** + * @brief MTP_Get_StorageIDS + * Fill the MTP_StorageIDS struct + * @param pdev: device instance + * @retval None + */ +static void MTP_Get_StorageIDS(void) +{ + MTP_StorageIDS.StorageIDS_len = MTP_NBR_STORAGE_ID; + MTP_StorageIDS.StorageIDS[0] = MTP_STORAGE_ID; +} + +/** + * @brief MTP_build_data_propdesc + * Copy the MTP_ObjectPropDesc dataset to the payload data + * @param pdev: device instance + * @retval None + */ +static uint32_t MTP_build_data_propdesc(USBD_HandleTypeDef *pdev, MTP_ObjectPropDescTypeDef def) +{ + 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); + + (void)USBD_memcpy(hmtp->GenericContainer.data, (const uint8_t *)&def, dataLength); + + switch (def.DataType) + { + case MTP_DATATYPE_UINT16: + (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, def.DefValue, sizeof(uint16_t)); + dataLength += sizeof(uint16_t); + break; + + case MTP_DATATYPE_UINT32: + (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, def.DefValue, sizeof(uint32_t)); + dataLength += sizeof(uint32_t); + break; + + case MTP_DATATYPE_UINT64: + (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, def.DefValue, sizeof(uint64_t)); + dataLength += sizeof(uint64_t); + break; + + case MTP_DATATYPE_STR: + (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, def.DefValue, DefValue_size); + dataLength += DefValue_size; + break; + + case MTP_DATATYPE_UINT128: + (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, def.DefValue, (sizeof(uint64_t) * 2U)); + dataLength += (sizeof(uint64_t) * 2U); + break; + + default: + break; + } + + (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, + (const uint8_t *)&MTP_ObjectPropDesc.GroupCode, sizeof(MTP_ObjectPropDesc.GroupCode)); + + dataLength += sizeof(MTP_ObjectPropDesc.GroupCode); + + (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, + (const uint8_t *)&MTP_ObjectPropDesc.FormFlag, sizeof(MTP_ObjectPropDesc.FormFlag)); + + dataLength += sizeof(MTP_ObjectPropDesc.FormFlag); + + return dataLength; +} + +/** + * @brief MTP_build_data_proplist + * Copy the MTP_PropertiesList dataset to the payload data + * @param pdev: device instance + * @retval None + */ +static uint32_t MTP_build_data_proplist(USBD_HandleTypeDef *pdev, + MTP_PropertiesListTypedef proplist, uint32_t idx) +{ + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + uint8_t propval_size = (MTP_FileName.FileName_len * 2U) + 1U; + uint32_t dataLength; + + dataLength = offsetof(MTP_PropertiesTypedef, propval); + + (void)USBD_memcpy(hmtp->GenericContainer.data + hmtp->ResponseLength, + (const uint8_t *)&proplist.MTP_Properties[idx], dataLength); + + dataLength += hmtp->ResponseLength; + + switch (proplist.MTP_Properties[idx].Datatype) + { + case MTP_DATATYPE_UINT16: + (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, + proplist.MTP_Properties[idx].propval, sizeof(uint16_t)); + + dataLength += sizeof(uint16_t); + break; + + case MTP_DATATYPE_UINT32: + (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, + proplist.MTP_Properties[idx].propval, sizeof(uint32_t)); + + dataLength += sizeof(uint32_t); + break; + + case MTP_DATATYPE_STR: + (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, + proplist.MTP_Properties[idx].propval, propval_size); + + dataLength += propval_size; + break; + + case MTP_DATATYPE_UINT64: + (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, + proplist.MTP_Properties[idx].propval, sizeof(uint64_t)); + + dataLength += sizeof(uint64_t); + break; + + case MTP_DATATYPE_UINT128: + (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, + proplist.MTP_Properties[idx].propval, (sizeof(uint64_t) * 2U)); + + dataLength += (sizeof(uint64_t) * 2U); + break; + + default: + break; + } + + return dataLength; +} + +/** + * @brief MTP_build_data_ObjInfo + * Copy the MTP_ObjectInfo dataset to the payload data + * @param pdev: device instance + * @retval None + */ +static uint32_t MTP_build_data_ObjInfo(USBD_HandleTypeDef *pdev, MTP_ObjectInfoTypeDef objinfo) +{ + 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); + (void)USBD_memcpy(hmtp->GenericContainer.data + ObjInfo_len, + (const uint8_t *)&objinfo.Filename, objinfo.Filename_len * sizeof(uint16_t)); + + ObjInfo_len = ObjInfo_len + (objinfo.Filename_len * sizeof(uint16_t)); + + (void)USBD_memcpy(hmtp->GenericContainer.data + ObjInfo_len, + (const uint8_t *)&objinfo.CaptureDate, sizeof(objinfo.CaptureDate)); + + ObjInfo_len = ObjInfo_len + sizeof(objinfo.CaptureDate); + + return ObjInfo_len; +} diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp_storage.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp_storage.c new file mode 100644 index 0000000000..e09cd39226 --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp_storage.c @@ -0,0 +1,472 @@ +/** + ****************************************************************************** + * @file usbd_mtp_storage.c + * @author MCD Application Team + * @brief This file provides all the transfer command functions for MTP + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_mtp_storage.h" + +/* 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; + +/* Private function prototypes -----------------------------------------------*/ +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); +static uint8_t USBD_MTP_STORAGE_SendData(USBD_HandleTypeDef *pdev, uint8_t *buf, uint32_t len); + +/* Private functions ---------------------------------------------------------*/ +/** + * @} + */ + +/** + * @brief USBD_MTP_STORAGE_Init + * Initialize the MTP USB Layer + * @param pdev: device instance + * @retval status value + */ +uint8_t USBD_MTP_STORAGE_Init(USBD_HandleTypeDef *pdev) +{ + 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, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ + + /* Initialize the HW layyer of the file system */ + (void)((USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init(); + + /* Prepare EP to Receive First Operation */ + (void)USBD_LL_PrepareReceive(pdev, MTPOutEpAdd, (uint8_t *)&hmtp->rx_buff, + hmtp->MaxPcktLen); + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_MTP_STORAGE_DeInit + * Uninitialize the MTP Machine + * @param pdev: device instance + * @retval status value + */ +uint8_t USBD_MTP_STORAGE_DeInit(USBD_HandleTypeDef *pdev) +{ + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + + /* DeInit physical Interface components */ + hmtp->MTP_SessionState = MTP_SESSION_NOT_OPENED; + + /* Stop low layer file system operations if any */ + USBD_MTP_STORAGE_Cancel(pdev, MTP_PHASE_IDLE); + + /* Free low layer file system resources */ + (void)((USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit(); + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_MTP_STORAGE_ReadData + * Read data from device objects and send it to the host + * @param pdev: device instance + * @retval status value + */ +uint8_t USBD_MTP_STORAGE_ReadData(USBD_HandleTypeDef *pdev) +{ + 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[pdev->classId])->ScratchBuff; + + switch (ReadDataStatus) + { + case READ_FIRST_DATA: + /* Reset the data length */ + MTP_DataLength.temp_length = 0U; + + /* Perform the low layer read operation on the scratch buffer */ + (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); + + /* Start USB data transmission to the host */ + (void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)data_buff, + MTP_DataLength.readbytes + MTP_CONT_HEADER_SIZE); + + /* Check if this will be the last packet to send ? */ + if (MTP_DataLength.readbytes < ((uint32_t)hmtp->MaxPcktLen - MTP_CONT_HEADER_SIZE)) + { + /* Move to response phase */ + hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE; + } + else + { + /* Continue to the next packets sending */ + ReadDataStatus = READ_REST_OF_DATA; + } + break; + + case READ_REST_OF_DATA: + /* Perform the low layer read operation on the scratch buffer */ + (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) + { + /* Start USB data transmission to the host */ + (void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)data_buff, MTP_DataLength.readbytes); + + /* Move to response phase */ + hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE; + + /* Reset the stat machine */ + ReadDataStatus = READ_FIRST_DATA; + } + else + { + /* Start USB data transmission to the host */ + (void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)data_buff, MTP_DataLength.readbytes); + + /* Keep the state machine into sending next packet of data */ + ReadDataStatus = READ_REST_OF_DATA; + } + break; + + default: + break; + } + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_MTP_STORAGE_SendContainer + * Send generic container to the host + * @param pdev: device instance + * @retval status value + */ +uint8_t USBD_MTP_STORAGE_SendContainer(USBD_HandleTypeDef *pdev, MTP_CONTAINER_TYPE CONT_TYPE) +{ + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + switch (CONT_TYPE) + { + case DATA_TYPE: + /* send header + data : hmtp->ResponseLength = header size + data size */ + (void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)&hmtp->GenericContainer, hmtp->ResponseLength); + break; + case REP_TYPE: + /* send header without data */ + hmtp->GenericContainer.code = (uint16_t)hmtp->ResponseCode; + hmtp->ResponseLength = MTP_CONT_HEADER_SIZE; + hmtp->GenericContainer.length = hmtp->ResponseLength; + hmtp->GenericContainer.type = MTP_CONT_TYPE_RESPONSE; + + (void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)&hmtp->GenericContainer, hmtp->ResponseLength); + break; + default: + break; + } + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_MTP_STORAGE_ReceiveOpt + * Data length Packet Received from host + * @param pdev: device instance + * @retval status value + */ +uint8_t USBD_MTP_STORAGE_ReceiveOpt(USBD_HandleTypeDef *pdev) +{ + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + uint32_t *pMsgBuffer; +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + MTPOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ + MTP_DataLength.rx_length = USBD_GetRxCount(pdev, MTPOutEpAdd); + + switch (hmtp->RECEIVE_DATA_STATUS) + { + case RECEIVE_REST_OF_DATA: + /* we don't need to do anything here because we receive only data without operation header*/ + break; + + case RECEIVE_FIRST_DATA: + /* Expected Data Length Packet Received */ + pMsgBuffer = (uint32_t *) &hmtp->OperationsContainer; + + /* Fill hmtp->OperationsContainer Data Buffer from USB Buffer */ + (void)USBD_MTP_STORAGE_ReceiveContainer(pdev, pMsgBuffer, MTP_DataLength.rx_length); + break; + + default: + /* Expected Data Length Packet Received */ + pMsgBuffer = (uint32_t *) &hmtp->OperationsContainer; + + /* Fill hmtp->OperationsContainer Data Buffer from USB Buffer */ + (void)USBD_MTP_STORAGE_ReceiveContainer(pdev, pMsgBuffer, MTP_DataLength.rx_length); + (void)USBD_MTP_STORAGE_DecodeOperations(pdev); + break; + + } + return (uint8_t)USBD_OK; +} + + +/** + * @brief USBD_MTP_STORAGE_ReceiveData + * Receive objects or object info from host + * @param pdev: device instance + * @retval status value + */ +uint8_t USBD_MTP_STORAGE_ReceiveData(USBD_HandleTypeDef *pdev) +{ + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + switch (hmtp->RECEIVE_DATA_STATUS) + { + case RECEIVE_COMMAND_DATA : + if (hmtp->OperationsContainer.type == MTP_CONT_TYPE_COMMAND) + { + MTP_DataLength.temp_length = 0; + MTP_DataLength.prv_len = 0; + (void)USBD_MTP_STORAGE_DecodeOperations(pdev); + + } + break; + + case RECEIVE_FIRST_DATA : + if (hmtp->OperationsContainer.type == MTP_CONT_TYPE_DATA) + { + MTP_DataLength.totallen = hmtp->OperationsContainer.length; + MTP_DataLength.temp_length = MTP_DataLength.rx_length; + MTP_DataLength.rx_length = MTP_DataLength.temp_length - MTP_CONT_HEADER_SIZE; + (void)USBD_MTP_STORAGE_DecodeOperations(pdev); + + if (MTP_DataLength.temp_length < hmtp->MaxPcktLen) /* we received all data, we don't need to go to next state */ + { + hmtp->RECEIVE_DATA_STATUS = SEND_RESPONSE; + (void)USBD_MTP_STORAGE_DecodeOperations(pdev); + + /* send response header after receiving all data successfully */ + (void)USBD_MTP_STORAGE_SendContainer(pdev, DATA_TYPE); + } + } + + break; + + case RECEIVE_REST_OF_DATA : + MTP_DataLength.prv_len = MTP_DataLength.temp_length - MTP_CONT_HEADER_SIZE; + (void)USBD_MTP_STORAGE_DecodeOperations(pdev); + MTP_DataLength.temp_length = MTP_DataLength.temp_length + MTP_DataLength.rx_length; + + if (MTP_DataLength.temp_length == MTP_DataLength.totallen) /* we received all data*/ + { + hmtp->RECEIVE_DATA_STATUS = SEND_RESPONSE; + (void)USBD_MTP_STORAGE_DecodeOperations(pdev); + + /* send response header after receiving all data successfully */ + (void)USBD_MTP_STORAGE_SendContainer(pdev, DATA_TYPE); + } + break; + + default : + break; + } + + return (uint8_t)USBD_OK; +} + + +/** + * @brief USBD_MTP_STORAGE_DecodeOperations + * Parse the operations and Process operations + * @param pdev: device instance + * @retval status value + */ +static uint8_t USBD_MTP_STORAGE_DecodeOperations(USBD_HandleTypeDef *pdev) +{ + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + switch (hmtp->OperationsContainer.code) + { + case MTP_OP_GET_DEVICE_INFO: + USBD_MTP_OPT_GetDeviceInfo(pdev); + hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE; + break; + + case MTP_OP_OPEN_SESSION: + USBD_MTP_OPT_CreateObjectHandle(pdev); + hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE; + break; + + case MTP_OP_GET_STORAGE_IDS: + USBD_MTP_OPT_GetStorageIDS(pdev); + hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE; + break; + + case MTP_OP_GET_STORAGE_INFO: + USBD_MTP_OPT_GetStorageInfo(pdev); + hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE; + break; + + case MTP_OP_GET_OBJECT_HANDLES: + USBD_MTP_OPT_GetObjectHandle(pdev); + hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE; + break; + + case MTP_OP_GET_OBJECT_INFO: + USBD_MTP_OPT_GetObjectInfo(pdev); + hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE; + break; + + case MTP_OP_GET_OBJECT_PROP_REFERENCES: + USBD_MTP_OPT_GetObjectReferences(pdev); + hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE; + break; + + case MTP_OP_GET_OBJECT_PROPS_SUPPORTED: + USBD_MTP_OPT_GetObjectPropSupp(pdev); + hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE; + break; + + case MTP_OP_GET_OBJECT_PROP_DESC: + USBD_MTP_OPT_GetObjectPropDesc(pdev); + hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE; + break; + + case MTP_OP_GET_OBJECT_PROPLIST: + USBD_MTP_OPT_GetObjectPropList(pdev); + hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE; + break; + + case MTP_OP_GET_OBJECT_PROP_VALUE: + USBD_MTP_OPT_GetObjectPropValue(pdev); + hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE; + break; + + case MTP_OP_GET_DEVICE_PROP_DESC: + USBD_MTP_OPT_GetDevicePropDesc(pdev); + hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE; + break; + + case MTP_OP_GET_OBJECT: + USBD_MTP_OPT_GetObject(pdev); + hmtp->MTP_ResponsePhase = MTP_READ_DATA; + break; + + case MTP_OP_SEND_OBJECT_INFO: + USBD_MTP_OPT_SendObjectInfo(pdev, (uint8_t *)(hmtp->rx_buff), MTP_DataLength.prv_len); + hmtp->MTP_ResponsePhase = MTP_RECEIVE_DATA; + break; + + case MTP_OP_SEND_OBJECT: + USBD_MTP_OPT_SendObject(pdev, (uint8_t *)(hmtp->rx_buff), MTP_DataLength.rx_length); + hmtp->MTP_ResponsePhase = MTP_RECEIVE_DATA; + break; + + case MTP_OP_DELETE_OBJECT: + USBD_MTP_OPT_DeleteObject(pdev); + hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE; + break; + + default: + break; + } + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_MTP_STORAGE_ReceiveContainer + * Receive the Data from USB BulkOut Buffer to Pointer + * @param pdev: device instance + * @param pDst: destination address to copy the buffer + * @param len: length of data to copy + * @retval status value + */ +static uint8_t USBD_MTP_STORAGE_ReceiveContainer(USBD_HandleTypeDef *pdev, + uint32_t *pDst, uint32_t len) +{ + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + uint32_t Counter; + uint32_t *pdst = pDst; + + for (Counter = 0; Counter < len; Counter++) + { + *pdst = (hmtp->rx_buff[Counter]); + pdst++; + } + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_MTP_STORAGE_Cancel + * Reinitialize all states and cancel transfer through Bulk transfer + * @param pdev: device instance + * @param MTP_ResponsePhase: MTP current state + * @retval None + */ +void USBD_MTP_STORAGE_Cancel(USBD_HandleTypeDef *pdev, + MTP_ResponsePhaseTypeDef MTP_ResponsePhase) +{ + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + + hmtp->MTP_ResponsePhase = MTP_PHASE_IDLE; + ReadDataStatus = READ_FIRST_DATA; + hmtp->RECEIVE_DATA_STATUS = RECEIVE_IDLE_STATE; + + if (MTP_ResponsePhase == MTP_RECEIVE_DATA) + { + ((USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId])->Cancel(1U); + } + else + { + ((USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId])->Cancel(0U); + } +} + +/** + * @brief USBD_MTP_STORAGE_SendData + * Send the data on bulk-in EP + * @param pdev: device instance + * @param buf: pointer to data buffer + * @param len: Data Length + * @retval status value + */ +static uint8_t USBD_MTP_STORAGE_SendData(USBD_HandleTypeDef *pdev, uint8_t *buf, + uint32_t len) +{ + 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, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ + + (void)USBD_LL_Transmit(pdev, MTPInEpAdd, buf, length); + + return (uint8_t)USBD_OK; +} diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Inc/usbd_printer.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Inc/usbd_printer.h index ec73edcaef..bf00b9c1c7 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Inc/usbd_printer.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Inc/usbd_printer.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2021 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -114,8 +113,7 @@ typedef struct __IO uint32_t TxState; __IO uint32_t RxState; -} -USBD_PRNT_HandleTypeDef; +} USBD_PRNT_HandleTypeDef; @@ -161,4 +159,3 @@ uint8_t USBD_PRNT_ReceivePacket(USBD_HandleTypeDef *pdev); * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Inc/usbd_printer_if_template.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Inc/usbd_printer_if_template.h index 7037afad58..7765eed523 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Inc/usbd_printer_if_template.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Inc/usbd_printer_if_template.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2021 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * http://www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -42,4 +41,3 @@ extern USBD_PRNT_ItfTypeDef USBD_PRNT_Template_fops; #endif /* __USBD_PRNT_IF_TEMPLATE_H */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Src/usbd_printer.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Src/usbd_printer.c index 246674f7f9..7c1a4ba830 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Src/usbd_printer.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Src/usbd_printer.c @@ -10,6 +10,17 @@ * - Command OUT transfer (class requests management) * - Error management * + ****************************************************************************** + * @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 * * =================================================================== @@ -37,17 +48,6 @@ * @endverbatim * ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** */ /* BSPDependencies @@ -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,63 +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 = -{ - /*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 - 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 = +__ALIGN_BEGIN static uint8_t USBD_PRNT_CfgDesc[] __ALIGN_END = { /*Configuration Descriptor*/ 0x09, /* bLength: Configuration Descriptor size */ @@ -214,7 +159,7 @@ __ALIGN_BEGIN static uint8_t USBD_PRNT_CfgFSDesc[] __ALIGN_END = 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, (uint8_t)pdev->classId); + PRNTOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); +#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, (uint8_t)pdev->classId); + PRNTOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); +#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, (uint8_t)pdev->classId); + PRNTOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); +#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; } + /** * @} */ @@ -669,5 +658,3 @@ uint8_t USBD_PRNT_ReceivePacket(USBD_HandleTypeDef *pdev) /** * @} */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Src/usbd_printer_if_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Src/usbd_printer_if_template.c index 064c41e81f..8b63db060a 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Src/usbd_printer_if_template.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Src/usbd_printer_if_template.c @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2021 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * http://www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -71,11 +70,11 @@ USBD_PRNT_ItfTypeDef USBD_PRNT_Template_fops = { TEMPLATE_Init, TEMPLATE_DeInit, - TEMPLATE_Control_req + TEMPLATE_Control_req, TEMPLATE_Receive }; -static uint8_t PRNT_DEVICE_ID[DEVICE_ID_LEN] = +static uint8_t PRNT_DEVICE_ID[] = { 0x00, 0x6D, 'M', 'A', 'N', 'U', 'F', 'A', 'C', 'T', 'U', 'R', 'E', 'R', ':', @@ -128,7 +127,7 @@ static int8_t TEMPLATE_DeInit(void) * * @note * This function will issue a NAK packet on any OUT packet received on - * USB endpoint untill exiting this function. If you exit this function + * USB endpoint until exiting this function. If you exit this function * before transfer is complete on PRNT interface (ie. using DMA controller) * it will result in receiving more data while previous ones are still * not sent. @@ -147,16 +146,16 @@ static int8_t TEMPLATE_Receive(uint8_t *Buf, uint32_t *Len) /** - * @brief TEMPLATE_PRNT_Itf_Control_req + * @brief TEMPLATE_Control_req * Manage the PRNT class requests * @param req: Command code * @param pbuf: Buffer containing command data (request parameters) * @param length: Number of data to be sent (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL */ -static int8_t TEMPLATE_PRNT_Itf_Control_req(uint8_t req, uint8_t *pbuf, uint16_t *length) +static int8_t TEMPLATE_Control_req(uint8_t req, uint8_t *pbuf, uint16_t *length) { - uint32_t i = 0; + uint32_t i = 0U; /* Check on the setup request value */ switch (req) @@ -169,7 +168,7 @@ static int8_t TEMPLATE_PRNT_Itf_Control_req(uint8_t req, uint8_t *pbuf, uint16_t pbuf[i] = PRNT_DEVICE_ID[i]; i++; } - *length = i; + *length = (uint16_t)i; break; /* Get Printer current status */ @@ -183,25 +182,16 @@ static int8_t TEMPLATE_PRNT_Itf_Control_req(uint8_t req, uint8_t *pbuf, uint16_t /* Printer SOFT RESET request: cleanup pending tasks */ case PRNT_SOFT_RESET: - (void)f_close(&hSD.MyFile); break; default: - /* Unkown commands are not managed */ + /* Unknown commands are not managed */ break; -} + } -/** -* @brief TEMPLATE_PRNT_PageEndManager, defined by user -* Call this function frequently to check if data is received. -* @param Buf: Buffer of data to be received -* @param Len: Number of data received (in bytes) -*/ -void TEMPLATE_PRNT_PageEndManager(uint8_t *Buf, uint32_t Len) -{ - UNUSED(Buf); - UNUSED(Len); + return (0); } + /** * @} */ @@ -214,5 +204,3 @@ void TEMPLATE_PRNT_PageEndManager(uint8_t *Buf, uint32_t Len) * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/Template/Inc/usbd_template.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Template/Inc/usbd_template.h index 8e9163bb21..be314376f6 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/Template/Inc/usbd_template.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Template/Inc/usbd_template.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -97,5 +96,3 @@ extern USBD_ClassTypeDef USBD_TEMPLATE_ClassDriver; /** * @} */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/Template/Src/usbd_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Template/Src/usbd_template.c index 10ced3fc05..947ae911e3 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/Template/Src/usbd_template.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Template/Src/usbd_template.c @@ -4,6 +4,17 @@ * @author MCD Application Team * @brief This file provides the HID core functions. * + ****************************************************************************** + * @attention + * + * Copyright (c) 2015 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 * * =================================================================== @@ -22,17 +33,6 @@ * @endverbatim * ****************************************************************************** - * @attention - * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ @@ -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; -} - /** * @} */ @@ -376,5 +363,3 @@ uint8_t *USBD_TEMPLATE_GetDeviceQualifierDesc(uint16_t *length) /** * @} */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Inc/usbd_video.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Inc/usbd_video.h index c92ff76110..8ece002b99 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Inc/usbd_video.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Inc/usbd_video.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2020 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -47,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 @@ -111,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 @@ -131,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 @@ -148,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 @@ -183,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 @@ -364,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; @@ -413,7 +388,6 @@ typedef struct int8_t (* DeInit)(void); int8_t (* Control)(uint8_t, uint8_t *, uint16_t); int8_t (* Data)(uint8_t **, uint16_t *, uint16_t *); - uint8_t *pStrDesc; } USBD_VIDEO_ItfTypeDef; /* UVC uses only 26 first bytes */ @@ -437,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/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Inc/usbd_video_if_template.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Inc/usbd_video_if_template.h index 036c7aade2..bc5b8fafa6 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Inc/usbd_video_if_template.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Inc/usbd_video_if_template.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2020 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -114,6 +113,25 @@ void TransferComplete_CallBack_FS(void); */ void HalfTransfer_CallBack_FS(void); + + +#define IMG_NBR 1U +#define IMAGE_SIZE 0x1U + +const uint8_t image[] = {0x00}; +const uint8_t *tImagesList[] = {image}; +uint16_t tImagesSizes[] = {IMAGE_SIZE}; + +/* Time laps between video frames in ms. + Please adjust this value depending on required speed. + Please note that this define uses the system HAL_Delay() which uses the systick. + In case of changes on HAL_Delay, please ensure the values in ms correspond. */ +#ifdef USE_USB_HS +#define USBD_VIDEO_IMAGE_LAPS 160U +#else +#define USBD_VIDEO_IMAGE_LAPS 80U +#endif /* USE_USB_HS */ + /* USER CODE BEGIN EXPORTED_FUNCTIONS */ /* USER CODE END EXPORTED_FUNCTIONS */ @@ -136,7 +154,3 @@ void HalfTransfer_CallBack_FS(void); #endif /* USBD_VIDEO_IF_H_ */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - - - diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Src/usbd_video.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Src/usbd_video.c index a414ed6ff6..a2cb571d61 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Src/usbd_video.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Src/usbd_video.c @@ -4,6 +4,17 @@ * @author MCD Application Team * @brief This file provides the Video core functions. * + ****************************************************************************** + * @attention + * + * Copyright (c) 2020 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 * * =================================================================== @@ -35,17 +46,6 @@ * @endverbatim * ****************************************************************************** - * @attention - * - *

© Copyright (c) 2020 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ @@ -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, (uint8_t)pdev->classId); +#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, (uint8_t)pdev->classId); +#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,20 +633,21 @@ 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; static uint16_t PcktSze = UVC_PACKET_SIZE; static uint8_t payload_header[2] = {0x02U, 0x00U}; uint8_t i = 0U; - uint32_t RemainData, DataOffset = 0U; + uint32_t RemainData = 0U; + uint32_t DataOffset = 0U; /* Check if the Streaming has already been started */ 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 +666,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 +709,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 +751,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 */ @@ -757,7 +800,7 @@ static void VIDEO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef /* Probe Request */ (void)USBD_CtlSendData(pdev, (uint8_t *)&video_Probe_Control, - MIN(req->wLength, sizeof(USBD_VideoControlTypeDef))); + MIN(req->wLength, sizeof(USBD_VideoControlTypeDef))); } else if (LOBYTE(req->wValue) == (uint8_t)VS_COMMIT_CONTROL) { @@ -774,7 +817,7 @@ static void VIDEO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef /* Commit Request */ (void)USBD_CtlSendData(pdev, (uint8_t *)&video_Commit_Control, - MIN(req->wLength, sizeof(USBD_VideoControlTypeDef))); + MIN(req->wLength, sizeof(USBD_VideoControlTypeDef))); } else { @@ -794,19 +837,18 @@ 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); /* Check that the request has control data */ if (req->wLength > 0U) { /* Prepare the reception of the buffer over EP0 */ - if (LOBYTE(req->wValue) == (uint8_t)VS_PROBE_CONTROL) + if (req->wValue == (uint16_t)VS_PROBE_CONTROL) { /* Probe Request */ (void) USBD_CtlPrepareRx(pdev, (uint8_t *)&video_Probe_Control, MIN(req->wLength, sizeof(USBD_VideoControlTypeDef))); } - else if (LOBYTE(req->wValue) == (uint8_t)VS_COMMIT_CONTROL) + else if (req->wValue == (uint16_t)VS_COMMIT_CONTROL) { /* Commit Request */ (void) USBD_CtlPrepareRx(pdev, (uint8_t *)&video_Commit_Control, @@ -814,13 +856,12 @@ static void VIDEO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef } else { - /* Prepare the reception of the buffer over EP0 */ - (void) USBD_CtlPrepareRx(pdev, hVIDEO->control.data, - MIN(req->wLength, USB_MAX_EP0_SIZE)); + (void)USBD_LL_StallEP(pdev, 0x80U); } } } +#ifndef USE_USBD_COMPOSITE /** * @brief USBD_VIDEO_GetFSCfgDesc * return configuration descriptor @@ -829,7 +870,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 +898,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 +926,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 +958,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 +967,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,10 +978,10 @@ 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)) && + (pdesc->bDescriptorSubType == VS_FRAME_UNCOMPRESSED)) && (pdesc->bLength == VS_FRAME_DESC_SIZE)) { pVSFrameDesc = (USBD_VIDEO_VSFrameDescTypeDef *)(void *)pdesc; @@ -968,20 +992,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 +1014,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 +1041,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; @@ -1045,7 +1060,3 @@ uint8_t USBD_VIDEO_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_VIDEO_ItfT /** * @} */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - - diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Src/usbd_video_if_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Src/usbd_video_if_template.c index 70b8d3aacb..5b6f2aebd1 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Src/usbd_video_if_template.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Src/usbd_video_if_template.c @@ -6,19 +6,18 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2020 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ -#include "usbd_video_if.h" +#include "usbd_video_if_template.h" /* Include you image binary file here Binary image template shall provide: @@ -41,7 +40,7 @@ /* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/ - +uint8_t img_count; /* USER CODE END PV */ /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY @@ -189,6 +188,9 @@ static int8_t VIDEO_Itf_DeInit(void) */ static int8_t VIDEO_Itf_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length) { + UNUSED(cmd); + UNUSED(pbuf); + UNUSED(length); return (0); } @@ -221,9 +223,9 @@ static int8_t VIDEO_Itf_Data(uint8_t **pbuf, uint16_t *psize, uint16_t *pcktidx) */ const uint8_t *(*ImagePtr) = tImagesList; - uint32_t packet_count = (tImagesSizes[img_count]) / ((uint16_t)(UVC_PACKET_SIZE - (UVC_HEADER_PACKET_CNT * 2U))); - uint32_t packet_remainder = (tImagesSizes[img_count]) % ((uint16_t)(UVC_PACKET_SIZE - (UVC_HEADER_PACKET_CNT * 2U))); - static uint8_t packet_index = 0; + uint32_t packet_count = (tImagesSizes[img_count]) / ((UVC_PACKET_SIZE - (UVC_HEADER_PACKET_CNT * 2U))); + uint32_t packet_remainder = (tImagesSizes[img_count]) % ((UVC_PACKET_SIZE - (UVC_HEADER_PACKET_CNT * 2U))); + static uint8_t packet_index = 0U; /* Check if end of current image has been reached */ if (packet_index < packet_count) @@ -232,17 +234,19 @@ static int8_t VIDEO_Itf_Data(uint8_t **pbuf, uint16_t *psize, uint16_t *pcktidx) *psize = (uint16_t)UVC_PACKET_SIZE; /* Get the pointer to the next packet to be transmitted */ - *pbuf = (uint8_t *)(*(ImagePtr + img_count) + packet_index * ((uint16_t)(UVC_PACKET_SIZE - (UVC_HEADER_PACKET_CNT * 2U)))); + *pbuf = (uint8_t *)(*(ImagePtr + img_count) + \ + (packet_index * ((uint16_t)(UVC_PACKET_SIZE - (UVC_HEADER_PACKET_CNT * 2U))))); } else if ((packet_index == packet_count)) { if (packet_remainder != 0U) { /* Get the pointer to the next packet to be transmitted */ - *pbuf = (uint8_t *)(*(ImagePtr + img_count) + packet_index * ((uint16_t)(UVC_PACKET_SIZE - (UVC_HEADER_PACKET_CNT * 2U)))); + *pbuf = (uint8_t *)(*(ImagePtr + img_count) + \ + (packet_index * ((uint16_t)(UVC_PACKET_SIZE - (UVC_HEADER_PACKET_CNT * 2U))))); /* Set the current packet size */ - *psize = packet_remainder + (UVC_HEADER_PACKET_CNT * 2U); + *psize = (uint16_t)(packet_remainder + (UVC_HEADER_PACKET_CNT * 2U)); } else { @@ -262,7 +266,7 @@ static int8_t VIDEO_Itf_Data(uint8_t **pbuf, uint16_t *psize, uint16_t *pcktidx) *pcktidx = packet_index; /* Increment the packet count and check if it reached the end of current image buffer */ - if (packet_index++ >= (packet_count + 1)) + if (packet_index++ >= (packet_count + 1U)) { /* Reset the packet count to zero */ packet_index = 0U; @@ -270,7 +274,7 @@ static int8_t VIDEO_Itf_Data(uint8_t **pbuf, uint16_t *psize, uint16_t *pcktidx) /* Move to the next image in the images table */ img_count++; - HAL_Delay(USBD_VIDEO_IMAGE_LAPS); + USBD_Delay(USBD_VIDEO_IMAGE_LAPS); /* Check if images count has been reached, then reset to zero (go back to first image in circular loop) */ if (img_count == IMG_NBR) { @@ -292,5 +296,3 @@ static int8_t VIDEO_Itf_Data(uint8_t **pbuf, uint16_t *psize, uint16_t *pcktidx) /** * @} */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_conf_template.h b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_conf_template.h index 0527cf2758..b288b66c3f 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_conf_template.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_conf_template.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -77,6 +76,11 @@ extern "C" { #define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE 0x02U #define USBD_CUSTOM_HID_REPORT_DESC_SIZE 163U +/* #define USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED */ +/* #define USBD_CUSTOMHID_OUT_PREPARE_RECEIVE_DISABLED */ +/* #define USBD_CUSTOMHID_EP0_OUT_PREPARE_RECEIVE_DISABLED */ +/* #define USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */ + /* VIDEO Class Config */ #define UVC_1_1 /* #define UVC_1_0 */ @@ -91,7 +95,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 @@ -141,7 +145,7 @@ extern "C" { } while (0) #else #define USBD_UsrLog(...) do {} while (0) -#endif +#endif /* (USBD_DEBUG_LEVEL > 0U) */ #if (USBD_DEBUG_LEVEL > 1U) @@ -152,7 +156,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 { \ @@ -162,7 +166,7 @@ extern "C" { } while (0) #else #define USBD_DbgLog(...) do {} while (0) -#endif +#endif /* (USBD_DEBUG_LEVEL > 2U) */ /** * @} @@ -221,4 +225,3 @@ void USBD_static_free(void *p); /** * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h index 92f72705fd..d601672453 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -88,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, uint8_t ClassId); +#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); @@ -129,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); + /** * @} */ @@ -152,7 +169,4 @@ void USBD_LL_Delay(uint32_t Delay); * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - - diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h index 3495a97870..6c45d6ce3d 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -100,4 +99,3 @@ void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len); */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h index 4c4de6899a..894681958b 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -53,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 */ @@ -160,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 */ /** * @} */ @@ -188,7 +213,7 @@ typedef struct uint8_t iConfiguration; uint8_t bmAttributes; uint8_t bMaxPower; -} USBD_ConfigDescTypedef; +} __PACKED USBD_ConfigDescTypeDef; typedef struct { @@ -196,7 +221,7 @@ typedef struct uint8_t bDescriptorType; uint16_t wTotalLength; uint8_t bNumDeviceCaps; -} USBD_BosDescTypedef; +} USBD_BosDescTypeDef; typedef struct { @@ -206,7 +231,14 @@ typedef struct uint8_t bmAttributes; uint16_t wMaxPacketSize; uint8_t bInterval; -} USBD_EpDescTypedef; +} __PACKED USBD_EpDescTypeDef; + +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; +} USBD_DescHeaderTypeDef; struct _USBD_HandleTypeDef; @@ -231,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; @@ -264,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 */ @@ -281,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 { @@ -303,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; /** * @} */ @@ -322,7 +416,9 @@ typedef struct _USBD_HandleTypeDef */ __STATIC_INLINE uint16_t SWAPBYTE(uint8_t *addr) { - uint16_t _SwapVal, _Byte1, _Byte2; + uint16_t _SwapVal; + uint16_t _Byte1; + uint16_t _Byte2; uint8_t *_pbuff = addr; _Byte1 = *(uint8_t *)_pbuff; @@ -336,19 +432,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 @@ -417,4 +513,4 @@ __STATIC_INLINE uint16_t SWAPBYTE(uint8_t *addr) /** * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_desc_template.h b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_desc_template.h index 8fbbfaa634..e3923055ad 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_desc_template.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_desc_template.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -44,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 @@ -52,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 ------------------------------------------------------- */ @@ -60,4 +59,3 @@ extern USBD_DescriptorsTypeDef XXX_Desc; /* Replace 'XXX_Desc' with your active #endif /* __USBD_DESC_TEMPLATE_H*/ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h index c896b5ae33..15197b92ca 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -111,4 +110,4 @@ uint32_t USBD_GetRxCount(USBD_HandleTypeDef *pdev, uint8_t ep_addr); /** * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_conf_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_conf_template.c index 381988b4fe..74ff430203 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_conf_template.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_conf_template.c @@ -8,13 +8,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -234,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 @@ -241,6 +256,7 @@ uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr) */ void *USBD_static_malloc(uint32_t size) { + UNUSED(size); static uint32_t mem[(sizeof(USBD_HID_HandleTypeDef) / 4) + 1]; /* On 32-bit boundary */ return mem; } @@ -252,7 +268,7 @@ void *USBD_static_malloc(uint32_t size) */ void USBD_static_free(void *p) { - + UNUSED(p); } /** @@ -264,5 +280,4 @@ void USBD_LL_Delay(uint32_t Delay) { UNUSED(Delay); } -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c index a6154ea839..3c0610a102 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -20,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 * @{ */ @@ -96,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 */ @@ -137,14 +156,32 @@ USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev) /* Set Default State */ pdev->dev_state = USBD_STATE_DEFAULT; +#ifdef USE_USBD_COMPOSITE + /* Parse the table of classes in use */ + for (uint32_t i = 0; 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; + /* Free Class Resources */ + pdev->pClass[i]->DeInit(pdev, (uint8_t)pdev->dev_config); + } + } + } +#else /* Free Class Resources */ - if (pdev->pClass != NULL) + if (pdev->pClass[0] != NULL) { - pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); - pdev->pClass = NULL; - pdev->pUserData = 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; pdev->pConfDesc = NULL; @@ -170,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. @@ -201,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); } @@ -217,10 +390,30 @@ 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++) + { + /* 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->DeInit(pdev, (uint8_t)pdev->dev_config); + (void)pdev->pClass[0]->DeInit(pdev, (uint8_t)pdev->dev_config); } +#endif /* USE_USBD_COMPOSITE */ return USBD_OK; } @@ -231,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 */ } /** @@ -249,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; } @@ -269,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) + USBD_StatusTypeDef ret = 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) { - pdev->pClass->DeInit(pdev, cfgidx); + ret = USBD_FAIL; } +#endif /* USE_USBD_COMPOSITE */ - return USBD_OK; + return ret; } @@ -329,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) { @@ -345,44 +590,66 @@ 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) + { + 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) { - if (pdev->pClass->EP0_RxReady != NULL) + /* 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); + } } } (void)USBD_CtlSendStatus(pdev); } } - else - { -#if 0 - if (pdev->ep0_state == USBD_EP0_STATUS_OUT) - { - /* - * STATUS PHASE completed, update ep0_state to idle - */ - pdev->ep0_state = USBD_EP0_IDLE; - (void)USBD_LL_StallEP(pdev, 0U); - } -#endif - } } else { - if (pdev->dev_state == USBD_STATE_CONFIGURED) + /* Get the class index relative to this interface */ + idx = USBD_CoreFindEP(pdev, (epnum & 0x7FU)); + + if (((uint16_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS)) { - if (pdev->pClass->DataOut != NULL) + /* Call the class data out function to manage the request */ + if (pdev->dev_state == USBD_STATE_CONFIGURED) { - ret = (USBD_StatusTypeDef)pdev->pClass->DataOut(pdev, epnum); - - if (ret != USBD_OK) + 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; + } } } @@ -401,6 +668,7 @@ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, { USBD_EndpointTypeDef *pep; USBD_StatusTypeDef ret; + uint8_t idx; if (epnum == 0U) { @@ -434,33 +702,19 @@ 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); } } - /* - * Fix EPO STALL issue in STM32 USB Device library 2.5.1 - * Issue raised by @makarenya, see #388 - * USB Specification EP0 should never STALL. - */ - /* (void)USBD_LL_StallEP(pdev, 0x80U); */ + (void)USBD_LL_StallEP(pdev, 0x80U); (void)USBD_CtlReceiveStatus(pdev); } } } - else - { -#if 0 - if ((pdev->ep0_state == USBD_EP0_STATUS_IN) || - (pdev->ep0_state == USBD_EP0_IDLE)) - { - (void)USBD_LL_StallEP(pdev, 0x80U); - } -#endif - } - if (pdev->dev_test_mode == 1U) + if (pdev->dev_test_mode != 0U) { (void)USBD_RunTestMode(pdev); pdev->dev_test_mode = 0U; @@ -468,15 +722,23 @@ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, } else { - if (pdev->dev_state == USBD_STATE_CONFIGURED) + /* Get the class index relative to this interface */ + idx = USBD_CoreFindEP(pdev, ((uint8_t)epnum | 0x80U)); + + if (((uint16_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS)) { - if (pdev->pClass->DataIn != NULL) + /* Call the class data out function to manage the request */ + if (pdev->dev_state == USBD_STATE_CONFIGURED) { - ret = (USBD_StatusTypeDef)pdev->pClass->DataIn(pdev, epnum); - - if (ret != USBD_OK) + 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; + } } } } @@ -494,24 +756,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; + /* 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 != NULL) + { + if (pdev->pClass[i]->DeInit(pdev, (uint8_t)pdev->dev_config) != USBD_OK) + { + ret = USBD_FAIL; + } + } + } + } } +#else - if (pdev->pClassData != NULL) + if (pdev->pClass[0] != NULL) { - if (pdev->pClass->DeInit != NULL) + if (pdev->pClass[0]->DeInit != NULL) { - (void)pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); + 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); @@ -525,7 +813,7 @@ USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev) pdev->ep_in[0].maxpacket = USB_MAX_EP0_SIZE; - return USBD_OK; + return ret; } /** @@ -551,7 +839,11 @@ USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev) { - pdev->dev_old_state = pdev->dev_state; + if (pdev->dev_state != USBD_STATE_SUSPENDED) + { + pdev->dev_old_state = pdev->dev_state; + } + pdev->dev_state = USBD_STATE_SUSPENDED; return USBD_OK; @@ -583,17 +875,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; @@ -608,16 +918,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); } } @@ -633,16 +943,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); } } @@ -671,20 +981,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++) + { + /* 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) { - (void)pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); + if (pdev->pClass[0]->DeInit(pdev, (uint8_t)pdev->dev_config) != 0U) + { + ret = USBD_FAIL; + } } +#endif /* USE_USBD_COMPOSITE */ - return USBD_OK; + 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 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 + * @param ClassId: The Class ID + * @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 ClassId) +{ + uint8_t idx; + + /* Find the EP address in the selected class table */ + for (idx = 0; idx < pdev->tclasslist[ClassId].NumEps; idx++) + { + if (((pdev->tclasslist[ClassId].Eps[idx].add & USBD_EP_IN) == ep_dir) && \ + (pdev->tclasslist[ClassId].Eps[idx].type == ep_type) && \ + (pdev->tclasslist[ClassId].Eps[idx].is_used != 0U)) + { + return (pdev->tclasslist[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); +} /** * @} @@ -695,5 +1195,8 @@ USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev) * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + +/** + * @} + */ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c index b7098546c1..899bc706e0 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -21,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 * @{ @@ -105,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: @@ -163,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) { @@ -177,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)) { @@ -215,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: @@ -285,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; @@ -397,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; @@ -405,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; @@ -492,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 = pdev->pClass->GetUsrStrDescriptor(pdev, (req->wValue), &len); - } - else + pbuf = NULL; + + + for (uint32_t idx = 0U; (idx < pdev->NumClasses); idx++) { - USBD_CtlError(pdev, req); - err++; + 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; + } + } } -#endif + +#endif /* USBD_SUPPORT_USER_STRING_DESC */ #if (USBD_CLASS_USER_STRING_DESC == 1U) if (pdev->pDesc->GetUserStrDescriptor != NULL) @@ -513,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; @@ -526,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 { @@ -538,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 @@ -651,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 { @@ -767,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) { @@ -798,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 = (uint8_t)(req->wIndex >> 8); + (void)USBD_CtlSendStatus(pdev); + } + else + { + USBD_CtlError(pdev, req); + } } @@ -945,4 +1049,3 @@ static uint8_t USBD_GetLen(uint8_t *buf) * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_desc_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_desc_template.c index 8558ebd7d6..a9f995fa45 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_desc_template.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_desc_template.c @@ -8,13 +8,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -28,7 +27,7 @@ /* Private define ------------------------------------------------------------*/ #define USBD_VID 0x0483 #define USBD_PID 0xaaaa /* Replace '0xaaaa' with your device product ID */ -#define USBD_LANGID_STRING 0xbbb /* Replace '0xbbb' with your device language ID */ +#define USBD_LANGID_STRING 0xbbb /* Replace '0xbbb' with your device language ID */ #define USBD_MANUFACTURER_STRING "xxxxx" /* Add your manufacturer string */ #define USBD_PRODUCT_HS_STRING "xxxxx" /* Add your product High Speed string */ #define USBD_PRODUCT_FS_STRING "xxxxx" /* Add your product Full Speed string */ @@ -53,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 = @@ -67,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 */ @@ -87,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 */ @@ -110,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, @@ -127,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 */ @@ -156,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 */ @@ -184,8 +185,8 @@ __ALIGN_BEGIN uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = 0x00, /* bAlternateMode[0] Index of the Alternate Mode within the SVID as returned in response to a Discover Modes command. Example: - 0 first Mode entry - 1 second mode entry */ + 0 first Mode entry + 1 second mode entry */ USBD_BB_ALTMODE0_STRING_INDEX, /* iAlternateModeString[0]: Index of string descriptor describing protocol. It is optional to support this string. */ @@ -195,10 +196,10 @@ __ALIGN_BEGIN uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = 0x01, /* bAlternateMode[1] Index of the Alternate Mode within the SVID as returned in response to a Discover Modes command. Example: - 0 first Mode entry - 1 second Mode entry */ + 0 first Mode entry + 1 second Mode entry */ - USBD_BB_ALTMODE1_STRING_INDEX, /* iAlternateModeString[1]: Index of string descriptor describing protocol. + USBD_BB_ALTMODE1_STRING_INDEX, /* iAlternateModeString[1]: Index of string descriptor describing protocol. It is optional to support this string. */ /* Alternate Mode Desc */ /* ----------- Device Capability Descriptor: BillBoard Alternate Mode Desc ---------- */ @@ -206,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, @@ -231,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, @@ -240,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 ---------------------------------------------------------*/ @@ -371,7 +374,9 @@ uint8_t *USBD_Class_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *le */ static void Get_SerialNum(void) { - uint32_t deviceserial0, deviceserial1, deviceserial2; + uint32_t deviceserial0; + uint32_t deviceserial1; + uint32_t deviceserial2; deviceserial0 = *(uint32_t *)DEVICE_ID1; deviceserial1 = *(uint32_t *)DEVICE_ID2; @@ -400,7 +405,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) @@ -417,7 +422,7 @@ uint8_t *USBD_Class_UserStrDescriptor(USBD_SpeedTypeDef speed, uint8_t idx, uint return USBD_StrDesc; } -#endif +#endif /* USBD_CLASS_USER_STRING_DESC */ /** @@ -447,5 +452,3 @@ static void IntToUnicode(uint32_t value, uint8_t *pbuf, uint8_t len) pbuf[2U * idx + 1] = 0U; } } - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c index 1e7e62d451..7c8004ad80 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c @@ -6,13 +6,12 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2015 STMicroelectronics. - * All rights reserved.

+ * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 + * 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. * ****************************************************************************** */ @@ -95,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); @@ -139,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); @@ -223,4 +222,3 @@ uint32_t USBD_GetRxCount(USBD_HandleTypeDef *pdev, uint8_t ep_addr) * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/LICENSE.md b/system/Middlewares/ST/STM32_USB_Device_Library/LICENSE.md new file mode 100644 index 0000000000..1af5233078 --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/LICENSE.md @@ -0,0 +1,80 @@ +SLA0044 Rev5/February 2018 + +## Software license agreement + +### __ULTIMATE LIBERTY SOFTWARE LICENSE AGREEMENT__ + +BY INSTALLING, COPYING, DOWNLOADING, ACCESSING OR OTHERWISE USING THIS SOFTWARE +OR ANY PART THEREOF (AND THE RELATED DOCUMENTATION) FROM STMICROELECTRONICS +INTERNATIONAL N.V, SWISS BRANCH AND/OR ITS AFFILIATED COMPANIES +(STMICROELECTRONICS), THE RECIPIENT, ON BEHALF OF HIMSELF OR HERSELF, OR ON +BEHALF OF ANY ENTITY BY WHICH SUCH RECIPIENT IS EMPLOYED AND/OR ENGAGED AGREES +TO BE BOUND BY THIS SOFTWARE LICENSE AGREEMENT. + +Under STMicroelectronics’ intellectual property rights, the redistribution, +reproduction and use in source and binary forms of the software or any part +thereof, with or without modification, are permitted provided that the following +conditions are met: + +1. Redistribution of source code (modified or not) must retain any copyright +notice, this list of conditions and the disclaimer set forth below as items 10 +and 11. + +2. Redistributions in binary form, except as embedded into microcontroller or +microprocessor device manufactured by or for STMicroelectronics or a software +update for such device, must reproduce any copyright notice provided with the +binary code, this list of conditions, and the disclaimer set forth below as +items 10 and 11, in documentation and/or other materials provided with the +distribution. + +3. Neither the name of STMicroelectronics nor the names of other contributors to +this software may be used to endorse or promote products derived from this +software or part thereof without specific written permission. + +4. This software or any part thereof, including modifications and/or derivative +works of this software, must be used and execute solely and exclusively on or in +combination with a microcontroller or microprocessor device manufactured by or +for STMicroelectronics. + +5. No use, reproduction or redistribution of this software partially or totally +may be done in any manner that would subject this software to any Open Source +Terms. “Open Source Terms” shall mean any open source license which requires as +part of distribution of software that the source code of such software is +distributed therewith or otherwise made available, or open source license that +substantially complies with the Open Source definition specified at +www.opensource.org and any other comparable open source license such as for +example GNU General Public License (GPL), Eclipse Public License (EPL), Apache +Software License, BSD license or MIT license. + +6. STMicroelectronics has no obligation to provide any maintenance, support or +updates for the software. + +7. The software is and will remain the exclusive property of STMicroelectronics +and its licensors. The recipient will not take any action that jeopardizes +STMicroelectronics and its licensors' proprietary rights or acquire any rights +in the software, except the limited rights specified hereunder. + +8. The recipient shall comply with all applicable laws and regulations affecting +the use of the software or any part thereof including any applicable export +control law or regulation. + +9. Redistribution and use of this software or any part thereof other than as +permitted under this license is void and will automatically terminate your +rights under this license. + +10. THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY RIGHTS, WHICH ARE +DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT SHALL +STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +11. EXCEPT AS EXPRESSLY PERMITTED HEREUNDER, NO LICENSE OR OTHER RIGHTS, WHETHER +EXPRESS OR IMPLIED, ARE GRANTED UNDER ANY PATENT OR OTHER INTELLECTUAL PROPERTY +RIGHTS OF STMICROELECTRONICS OR ANY THIRD PARTY. diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/README.md b/system/Middlewares/ST/STM32_USB_Device_Library/README.md new file mode 100644 index 0000000000..c25a919135 --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/README.md @@ -0,0 +1,36 @@ +# Middleware USB Device MCU Component + +![latest tag](https://img.shields.io/github/v/tag/STMicroelectronics/stm32_mw_usb_device.svg?color=brightgreen) + +## Overview + +**STM32Cube** is an STMicroelectronics original initiative to ease developers' life by reducing efforts, time and cost. + +**STM32Cube** covers the overall STM32 products portfolio. It includes a comprehensive embedded software platform delivered for each STM32 series. + * The CMSIS modules (core and device) corresponding to the ARM(tm) core implemented in this STM32 product. + * The STM32 HAL-LL drivers, an abstraction layer offering a set of APIs ensuring maximized portability across the STM32 portfolio. + * The BSP drivers of each evaluation, demonstration or nucleo board provided for this STM32 series. + * A consistent set of middleware libraries such as RTOS, USB, FatFS, graphics, touch sensing library... + * A full set of software projects (basic examples, applications, and demonstrations) for each board provided for this STM32 series. + +Two models of publication are proposed for the STM32Cube embedded software: + * The monolithic **MCU Package**: all STM32Cube software modules of one STM32 series are present (Drivers, Middleware, Projects, Utilities) in the repository (usual name **STM32Cubexx**, xx corresponding to the STM32 series). + * The **MCU component**: each STM32Cube software module being part of the STM32Cube MCU Package, is delivered as an individual repository, allowing the user to select and get only the required software functions. + +## Description + +This **stm32_mw_usb_device** MCU component repository is one element **common to all** STM32Cube MCU embedded software packages, providing the **USB Device MCU Middleware** part. + +It represents ST offer to ensure the support of USB Devices on STM32 MCUs. +It includes two main modules: + * **Core** module for the USB device standard peripheral control APIs. It includes the files ensuring USB 2.0 standard code implementation for an USB device. +These files’ APIs will be called within every USB device application regardless of the desired functionality. + * **Class** module for the commonly supported classes APIs. it includes the files including different USB device classes. All STM32 USB classes are implemented according to the USB 2.0 and every class’s specifications. These files’ APIs will be called within USB device applications according to the desired functionality. + +## Release note + +Details about the content of this release are available in the release note [here](https://htmlpreview.github.io/?https://github.com/STMicroelectronics/stm32_mw_usb_device/blob/master/Release_Notes.html). + +## Troubleshooting + +Please refer to the [CONTRIBUTING.md](CONTRIBUTING.md) guide. \ No newline at end of file diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Release_Notes.html b/system/Middlewares/ST/STM32_USB_Device_Library/Release_Notes.html index cf3544b244..9744d73f72 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Release_Notes.html +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Release_Notes.html @@ -1,1517 +1,1020 @@ - - - - - - - - - - - - - - - - - - - - -Release Notes for STM32 USB Device Library - - - - - - - - - -
- -

 

- -
- - - - + + +
- - - - - - - -
-

Back to Release page

-
-

Release Notes for STM32 USB Device Library

-

Copyright - 2015 STMicroelectronics

-

-
-

 

- - - - -
-

Update History

- -

V2.8.0 / 10-Mars-2021

Main -Changes

  • Integration of  new USB device Class driver:
    • USB Printer Class driver based on Universal Serial Bus -Device Class Definition -for -Printing Devices Version 1.1
  • USB All Classes:
    • Fix USB buffer overflow vulnerability for CDC, CDC-ECM, CDC-RNDIS, DFU, AUDIO, CustomHID, and Video Classes
    • fix compilation warning with C++ due to missing casting during class handler allocation
    • Enhance comments of USB configuration descriptors fields
  • USB Video Class:
    • fix missing closing bracket for extern "C" in usbd_video.h
    • fix USBCV test with Uncompressed video format support

V2.7.1 / 18-August-2020

-

Main -Changes

-
    -
  • USB All Class:
  • -
      -
    • Add NULL pointer access check to Class handler
      -
    • -
    -
- -

V2.7.0 / 12-August-2020

-

Main -Changes

  • Integration of  new USB device Class driver:
    • USB video Class driver based on USB-IF video class definition version 1.1
- - - - - - - - - - - - - - - - - - - - - - - -
  • USB Core:
    • Enhance NULL pointer check in Core APIs
    • Allow supporting both USER and USER Class string desc
    • 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
    • Word spelling correction and file indentation improved
    • usbd_conf.h/c Template file updated to suggest using by default a static memory allocation for Class handler
  • USB All Classes
    • Word spelling correction and file indentation improved
    • Allow updating device config descriptor Max power from user code usbd_conf.h using USBD_MAX_POWER define
    • Fix device config descriptor bmAttributes value which depends on user code define USBD_SELF_POWERED
  • USB CDC Class:
    • Class specific request, add protection to limit the maximum data length to be sent by the CDC device
  • USB CustomHID Class:
    • Allow changing CustomHID data EP size from user code
-

V2.6.1 / 05-June-2020

- - - -

Main -Changes

- - - - - - - - - - - - - - - - - - - - - - - -
    -
  • USB Core:
  • -
      -
    • minor rework on USBD_Init() USBD_DeInit()
    • -
    • Fix warning issue with Keil due to missing return value of setup API
      -
    • -
    -
  • USB CDC Class:
  • -
      -
    • Fix file indentation
    • -
    • Avoid accessing to NULL pointer in case + + + + + + + Release Notes for STM32Cube USB Device Library + + + + + + +
      +
      +
      +

      Release Notes +for STM32Cube USB Device Library

      +

      Copyright © 2015 STMicroelectronics
      +

      + +
      +

      Purpose

      +

      The USB device library comes on top of the STM32Cube™ USB device HAL +driver and offers all the APIs required to develop an USB device +application.

      +

      The main USB device library features are:

      +
        +
      • Support of multi packet transfer features allowing sending big +amount of data without splitting it into max packet size transfers.
      • +
      • Support of most common USB Class drivers (HID, MSC, DFU, CDC-ACM, +CDC-ECM, RNDIS, MTP, AUDIO1.0, Printer, Video, Composite)
      • +
      • Configuration files to interface with Cube HAL and change the +library configuration without changing the library code (Read +Only).
      • +
      • 32-bits aligned data structures to handle DMA based transfer in High +speed modes.
      • +
      +

      Here is the list of references to user documents:

      +
        +
      • UM1734 +: STM32Cube USB device library User Manual
      • +
      • Wiki +Page : STM32Cube USB Wiki Page
      • +
      +
      +
      +

      Update History

      +
      + + +

      Main Changes

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Headline
      Improvement of the memory management +
      USB Core:
      Fix some compilation warnings related +to unused parameters
      Improve some code parts style
      Add check on the USB Device status in +USBD_LL_Suspend before suspending it
      USB CDC-ACM Class:
      Remove redundant prototype declaration of +USBD_CDC_GetOtherSpeedCfgDesc()
      USB CompositeBuilder, CCID, CDC_ECM, CDC_RNDIS, +CustomHID, MSC & Video Classes:
      Improve some code parts style
      +
      +
      + + +

      Main Changes

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Headline
      USB VIDEO Class:
      Correction of the support of +VS_PROBE_CONTROL & VS_COMMIT_CONTROL requets
      USB AUDIO Class:
      Correction of the check on +AUDIO_TOTAL_BUF_SIZE to avoid vulnerabilities
      USB HID Class:
      Modification of some constants names to +avoid duplication versus USB host library
      USB CustomHID Class:
      Add support of Get Report control +request
      Allow disabling EP OUT prepare receive +using a dedicated macros that can be defined in usbd_conf.h application +file
      Add support of Report Descriptor with +length greater than 255 bytes
      USB CCID Class:
      Fix minor Code Spelling warning
      USB All Classes:
      Update all classes to support composite +multi-instance using the class id parameter
      Fix code spelling and improve code +style
      fix misraC 2012 rule 10.3
      +
      +
      + + +

      Main Changes

      + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Headline
      Integration of new USB device +Class driver:
      Adding support of Composite devices with +an auto generation of composite device configuration descriptors
      USB All Classes:
      Fix Code Spelling and improve Code +Style
      Update device class drivers to support +Composite devices
      Improve declaration of USB configuration +descriptor table which is allocated if the composite builder is not +selected
      +
      +
      + + +

      Main Changes

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Headline
      Integration of new USB device +Class driver:
      USB CCID Class driver based on Universal +Serial Bus Device Class Definition for Integrated Circuit(s) Cards +Interface Devices Revision 1.1
      USB MTP Class driver based on Universal +Serial Bus Device Class Media Transfer Protocol Revision 1.1
      USB All Classes:
      Fix Code Spelling and improve Code +Style
      Update the way to declare licenses
      USB CDC/RNDIS/ECM +Classes:
      Fix compilation warning with C++ due to +missing casting during class handler allocation
      +
      +
      + + +

      Main Changes

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Headline
      Integration of new USB device +Class driver:
      USB Printer Class driver based on +Universal Serial Bus Device Class Definition for Printing Devices +Version 1.1
      USB All Classes:
      Fix USB buffer overflow vulnerability for +CDC, CDC-ECM, CDC-RNDIS, DFU, AUDIO, CustomHID, and Video Classes
      Fix compilation warning with C++ due to +missing casting during class handler allocation
      Enhance comments of USB configuration +descriptors fields
      USB Video Class:
      Fix missing closing bracket for extern “C” +in usbd_video.h
      Fix USBCV test with Uncompressed video +format support
      +
      +
      + + +

      Main Changes

      + + + + + + + + + + + +
      Headline
      USB All Class: Add NULL pointer access +check to Class handler
      +
      +
      + + +

      Main Changes

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Headline
      Integration of new USB device +Class driver:
      USB video Class driver based on USB-IF +video class definition version 1.1
      USB Core:
      Enhance NULL pointer check in Core +APIs
      Allow supporting both USER and USER Class +string desc
      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
      Word spelling correction and file +indentation improved
      usbd_conf.h/c Template file updated to +suggest using by default a static memory allocation for Class +handler
      USB All Classes:
      Word spelling correction and file +indentation improved
      Allow updating device config descriptor +Max power from user code usbd_conf.h using USBD_MAX_POWER define
      Fix device config descriptor bmAttributes +value which depends on user code define USBD_SELF_POWERED
      USB CDC Class:
      Class specific request, add protection to +limit the maximum data length to be sent by the CDC device
      USB CustomHID Class:
      Allow changing CustomHID data EP size from +user code
      +
      +
      + + +

      Main Changes

      + + + + + + + + + + + + + + + + + + + + + + + + + + + - -
      Headline
      Fix minor misra-c 2012 violations
      USB Core:
      minor rework on USBD_Init() +USBD_DeInit()
      Fix warning issue with Keil due to missing +return value of setup API
      USB CDC Class:
      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
      - - - -
      -
        -
      • Fix minor misra-c 2012 violations
      • -
      -

      V2.6.0 / 27-December-2019

      -

      Main -Changes

      - - - - - - - - - - - - - - - - - - - - - -
      • Integration of three new USB device Class drivers:
        • USB CDC ECM Class driver
        • USB CDC RNDIS Microsoft Class driver
        • USB Billboard Class driver
      • Fix mandatory misra-c 2012 violations
      • update user core and class template files
      • USB Core:
        • Fix unexpected EP0 stall during enumeration phase 
        • Improve APIs error management and prevent accessing NULL pointers
      • USB MSC Class:
        • Fix USBCV specific class tests
        • Fix multiple error with SCSI commands handling
        • Protect medium access when host ask for medium ejection
      • USB CDC Class:
        • Add new function to inform user that current IN transfer is completed
        • update transmit and receive APIs to transfer up to 64KB
      • USB AUDIO Class:
        • Fix audio sync start buffer size
        • update user callback periodicTC args by adding pointer to user buffer and size
      • USB CustomHID Class:
        • Rework the OUT transfer complete and prevent automatically re-enabling the OUT EP 
        • Add new user API to restart the OUT transfer: USBD_CUSTOM_HID_ReceivePacket()

      V2.5.3 / 30-April-2019

      Main -Changes

      - - - - - - - - - - - - - - - - - - - - - -
      • Fix misra-c 2012 high severity violations
      • Core driver:
        • protect shared macros __ALIGN_BEGIN, __ALIGN_END with C directive #ifndef
        • update Core driver and DFU Class driver to use USBD_SUPPORT_USER_STRING_DESC instead of  USBD_SUPPORT_USER_STRING
        •  prevent accessing to NULL pointer if the get descriptor functions are not defined
        • Update on USBD_LL_Resume(),  restore the device state only if the current state is USBD_STATE_SUSPENDED

      V2.5.2 / 27-Mars-2019

      Main -Changes

      - - - - - - - - - - - - - - - - - - - - - -
      • DFU Class:
        • fix compilation warning due to unreachable - instruction code introduced with CMSIS V5.4.0 NVIC_SystemReset() prototype change

      V2.5.1 / 03-August-2018
      -

      - - - - - - - - - - - - - - - - - -

      Main -Changes

      - - - - - - - - - - - - - - - - - - - - - -
      • Update license section by adding path to get copy of ST Ultimate Liberty license
      • Core: Fix unexpected stall during status OUT phase
      • DFU Class:
        • rework hdfu struct to prevent unaligned addresses
      • MSC Class:
        • fix lba address overflow during large file transfers > 4Go
      • Template Class:
        • add missing Switch case Break on USBD_Template_Setup API

      V2.5.0 / 15-December-2017
      -

      - - - - - - - - - - - - - - - - - -

      Main -Changes

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

      V2.4.2 / 11-December-2015
      -

      - - - - - - - - - - - - - - - - - -

      Main -Changes

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

      V2.4.1 / 19-June-2015
      -

      - - - - - - - - - - - - - - - -

      Main -Changes

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

      V2.4.0 / 28-February-2015
      -

      - - - - - - - - - - - - - -

      Main -Changes

      - - - - - - - - - - - - - - - - - -
        -
      • Core Driver
      • -
          -
        • Add support of 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 bug of unsupported premature Host Out stage during data In stage -(ie. when endpoint 0 maximum data size is 8 and Host requests -GetDeviceDescriptor for the first time)
        • usbd_ctlreq.c: Fix bug of unsupported Endpoint Class requests (ie. Audio SetCurrent request for endpoint sampling rate setting)
        • -
        -
      • HID Class
      • -
          -
        • Updating Polling time API USBD_HID_GetPollingInterval() to query this period for HS and FS
        • usbd_hid.c: Fix USBD_LL_CloseEP() function call in USBD_HID_DeInit() replacing endpoint size by endpoint address.
        • -
      • CDC Class
        • usbd_cdc.c: 
          • Add missing GetInterface request management in USBD_CDC_Setup() function
          • Update -USBD_CDC_Setup() function to allow correct user implementation of -CDC_SET_CONTROL_LINE_STATE and similar no-data setup requests.
        -
      - -

      V2.3.0 / 04-November-2014
      -

      - - - - - - - - - - - -

      Main -Changes

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

      V2.2.0 / 13-June-2014

      - - - - - - - - - -

      Main -Changes

      - - - - - - - - - - - - - -
        -
      • Source code comments review and update
      • -
      • HID class
      • -
          -
        • Remove unused API USBD_HID_DeviceQualifierDescriptor()
        • -
        • Add a new API in the HID class to query the poll time USBD_HID_GetPollingInterval()
          -
        • -
        - -
      • CDC class
      • -
          -
        • Bug fix: missing handling ZeroLength Setup request
        • -
        -
      • All classes
        -
      • - -
          -
        • Add alias for the class definition, it's defined as macro with capital letter
        • -
        -
      -
      ex. for the HID, the USBD_HID_CLASS macro is defined this way #define USBD_HID_CLASS  &USBD_HID
        and the application code can use the previous definition: &USBD_HID ex. USBD_RegisterClass(&USBD_Device, &USBD_HID) or the new USBD_HID_CLASS ex. USBD_RegisterClass(&USBD_Device, USBD_HID_CLASS)
      -

      V2.1.0 / 22-April-2014

      - - - - - - - - -

      Main -Changes

      - - - - - - - - - - - -
        -
      • 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 by stm32xxx.h and add comment to inform user to adapt it to the device used
      • -
      • Several enhancements in CustomHID class
      • -
          -
        • Update the Custom HID class driver to simplify the link with user processes
        • -
        • Optimize the Custom HID class driver and reduce footprint
        • -
        • Add USBD_CUSTOM_HID_RegisterInterface() API to link user process to custom HID class
        • -
        • Add Custom HID interface template file usbd_customhid_if_template.c/h
        • -
        -
      • Miscellaneous comments update
        -
      • - -
      - -

      V2.0.0 / 18-February-2014

      - - - - - -

      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.
        -
      • This version has to be used only with STM32Cube based development
      • -
      - - -

      V1.1.0 / 19-March-2012

      -

      Main -Changes

      - -
      • Official support of STM32F4xx devices
      • All source files: license disclaimer text update and add link to the License file on ST Internet.
      • Handle test mode in the set feature request
      • Handle dynamically the USB SELF POWERED feature
      • Handle correctly the USBD_CtlError process to take into account error during Control OUT stage
      • Miscellaneous bug fix

      V1.0.0 / 22-July-2011

      Main -Changes

      -
      • First official version for STM32F105/7xx and STM32F2xx devices

      -

      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:

      http://www.st.com/SLA0044

      - -
      -
      -
      -

      For - complete documentation on STM32 - Microcontrollers visit www.st.com/STM32

      -
      -

      -
- +compatibility with device library version below v2.6.0
- -

 

- +
+ + +

Main Changes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Headline
Integration of three new USB device Class +drivers:CDC ECM , CDC RNDIS Microsoft, USB Billboard
Fix mandatory misra-c 2012 violations
update user core and class template +files
USB Core:
Fix unexpected EP0 stall during +enumeration phase
Improve APIs error management and prevent +accessing NULL pointers
USB MSC Class:
Fix USBCV specific class tests
Fix multiple error with SCSI commands +handling
Protect medium access when host ask for +medium ejection
USB CDC Class:
Add new function to inform user that +current IN transfer is completed
update transmit and receive APIs to +transfer up to 64KB
USB AUDIO Class:
Fix audio sync start buffer size
update user callback periodicTC args by +adding pointer to user buffer and size
USB CustomHID Class:
Rework the OUT transfer complete and +prevent automatically re-enabling the OUT EP
Add new user API to restart the OUT +transfer: USBD_CUSTOM_HID_ReceivePacket()
+
+ + +

Main Changes

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Headline
Fix misra-c 2012 high severity +violations
Core driver:
protect shared macros __ALIGN_BEGIN, +__ALIGN_END with C directive #ifndef
update Core driver and DFU Class driver to +use USBD_SUPPORT_USER_STRING_DESC instead of +USBD_SUPPORT_USER_STRING
prevent accessing to NULL pointer if the +get descriptor functions are not defined
Update on USBD_LL_Resume(), restore the +device state only if the current state is USBD_STATE_SUSPENDED
+
+
+ + +

Main Changes

+ + + + + + + + + + + +
Headline
DFU Class: fix compilation warning due to +unreachable instruction code introduced with CMSIS V5.4.0 +NVIC_SystemReset() prototype change
+
+
+ + +

Main Changes

+ + + + + + + + + + + + + + + + + + + + + + + +
Headline
Update license section by adding path to +get copy of ST Ultimate Liberty license
Core: Fix unexpected stall during status +OUT phase
DFU Class: rework hdfu struct to prevent +unaligned addresses
MSC Class: fix lba address overflow during +large file transfers greater than 4Go
Template Class: add missing Switch case +Break on USBD_Template_Setup API
+
+
+ + +

Main Changes

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

Main Changes

+ + + + + + + + + + + + + + +
Headline
CDC Class
usbd_cdc.c: change #include “USBD_CDC.h” +by #include “usbd_cdc.h”
+
+
+ + +

Main Changes

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

Main Changes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Headline
Core Driver
Add support of 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 bug of unsupported +premature Host Out stage during data In stage (ie. when endpoint 0 +maximum data size is 8 and Host requests GetDeviceDescriptor for the +first time)
usbd_ctlreq.c: Fix bug of unsupported +Endpoint Class requests (ie. Audio SetCurrent request for endpoint +sampling rate setting)
HID Class
Updating Polling time API +USBD_HID_GetPollingInterval() to query this period for HS and FS
usbd_hid.c: Fix USBD_LL_CloseEP() function +call in USBD_HID_DeInit() replacing endpoint size by endpoint +address.
CDC Class
usbd_cdc.c: Add missing GetInterface +request management in USBD_CDC_Setup() function
usbd_cdc.c: Update USBD_CDC_Setup() +function to allow correct user implementation of +CDC_SET_CONTROL_LINE_STATE and similar no-data setup requests.
+
+
+ + +

Main Changes

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

Main Changes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Headline
Source code comments review and +update
HID class
Remove unused API +USBD_HID_DeviceQualifierDescriptor()
Add a new API in the HID class to query +the poll time USBD_HID_GetPollingInterval()
CDC class
Bug fix: missing handling ZeroLength Setup +request
All classes
Add alias for the class definition, it’s +defined as macro with capital letter
ex. for the HID, the USBD_HID_CLASS macro +is defined this way #define USBD_HID_CLASS &USBD_HID
and the application code can use the +previous definition: &USBD_HID ex. +USBD_RegisterClass(&USBD_Device, &USBD_HID) or the new +USBD_HID_CLASS ex. USBD_RegisterClass(&USBD_Device, +USBD_HID_CLASS)
+
+
+ + +

Main Changes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Headline
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 by stm32xxx.h and add comment to inform user to adapt it to +the device used
Several enhancements in CustomHID +class
Update the Custom HID class driver to +simplify the link with user processes
Optimize the Custom HID class driver and +reduce footprint
Add USBD_CUSTOM_HID_RegisterInterface() +API to link user process to custom HID class
Add Custom HID interface template file +usbd_customhid_if_template.c/h
Miscellaneous comments update
+
+
+ + +

Main Changes

+

Major update based on STM32Cube specification.

+ + + + + + + + + + + +
Headline
Library Core, Classes architecture and +APIs modified vs. V1.1.0, and thus the 2 versions are not +compatible.
+

This version has to be used only with STM32Cube based +development

+
+
+ + +

Main Changes

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Headline
Official support of STM32F4xx devices
All source files: license disclaimer text +update and add link to the License file on ST Internet.
Handle test mode in the set feature +request
Handle dynamically the USB SELF POWERED +feature
Handle correctly the USBD_CtlError process +to take into account error during Control OUT stage
Miscellaneous bug fix
+
+
+ + +

Main Changes

+

First official version for STM32F105/7xx and STM32F2xx devices

+
+ +
+ + +