diff --git a/Class/AUDIO/Inc/usbd_audio.h b/Class/AUDIO/Inc/usbd_audio.h index df6e63b..dbb71cd 100644 --- a/Class/AUDIO/Inc/usbd_audio.h +++ b/Class/AUDIO/Inc/usbd_audio.h @@ -50,6 +50,14 @@ extern "C" { #define USBD_MAX_NUM_INTERFACES 1U #endif /* USBD_AUDIO_FREQ */ +#ifndef AUDIO_HS_BINTERVAL +#define AUDIO_HS_BINTERVAL 0x01U +#endif /* AUDIO_HS_BINTERVAL */ + +#ifndef AUDIO_FS_BINTERVAL +#define AUDIO_FS_BINTERVAL 0x01U +#endif /* AUDIO_FS_BINTERVAL */ + #define AUDIO_OUT_EP 0x01U #define USB_AUDIO_CONFIG_DESC_SIZ 0x6DU #define AUDIO_INTERFACE_DESC_SIZE 0x09U @@ -91,6 +99,9 @@ extern "C" { #define AUDIO_OUT_STREAMING_CTRL 0x02U +#define AUDIO_OUT_TC 0x01U +#define AUDIO_IN_TC 0x02U + #define AUDIO_OUT_PACKET (uint16_t)(((USBD_AUDIO_FREQ * 2U * 2U) / 1000U)) #define AUDIO_DEFAULT_VOLUME 70U @@ -116,8 +127,7 @@ typedef enum AUDIO_OFFSET_HALF, AUDIO_OFFSET_FULL, AUDIO_OFFSET_UNKNOWN, -} -AUDIO_OffsetTypeDef; +} AUDIO_OffsetTypeDef; /** * @} */ @@ -132,32 +142,29 @@ typedef struct uint8_t data[USB_MAX_EP0_SIZE]; uint8_t len; uint8_t unit; -} -USBD_AUDIO_ControlTypeDef; - +} USBD_AUDIO_ControlTypeDef; typedef struct { - uint32_t alt_setting; - uint8_t buffer[AUDIO_TOTAL_BUF_SIZE]; - AUDIO_OffsetTypeDef offset; - uint8_t rd_enable; - uint16_t rd_ptr; - uint16_t wr_ptr; + uint32_t alt_setting; + uint8_t buffer[AUDIO_TOTAL_BUF_SIZE]; + AUDIO_OffsetTypeDef offset; + uint8_t rd_enable; + uint16_t rd_ptr; + uint16_t wr_ptr; USBD_AUDIO_ControlTypeDef control; -} -USBD_AUDIO_HandleTypeDef; +} USBD_AUDIO_HandleTypeDef; typedef struct { - int8_t (*Init)(uint32_t AudioFreq, uint32_t Volume, uint32_t options); + int8_t (*Init)(uint32_t AudioFreq, uint32_t Volume, uint32_t options); int8_t (*DeInit)(uint32_t options); int8_t (*AudioCmd)(uint8_t *pbuf, uint32_t size, uint8_t cmd); int8_t (*VolumeCtl)(uint8_t vol); int8_t (*MuteCtl)(uint8_t cmd); - int8_t (*PeriodicTC)(uint8_t cmd); + int8_t (*PeriodicTC)(uint8_t *pbuf, uint32_t size, uint8_t cmd); int8_t (*GetState)(void); } USBD_AUDIO_ItfTypeDef; /** @@ -178,8 +185,8 @@ typedef struct * @{ */ -extern USBD_ClassTypeDef USBD_AUDIO; -#define USBD_AUDIO_CLASS &USBD_AUDIO +extern USBD_ClassTypeDef USBD_AUDIO; +#define USBD_AUDIO_CLASS &USBD_AUDIO /** * @} */ @@ -187,10 +194,10 @@ extern USBD_ClassTypeDef USBD_AUDIO; /** @defgroup USB_CORE_Exported_Functions * @{ */ -uint8_t USBD_AUDIO_RegisterInterface(USBD_HandleTypeDef *pdev, - USBD_AUDIO_ItfTypeDef *fops); +uint8_t USBD_AUDIO_RegisterInterface(USBD_HandleTypeDef *pdev, + USBD_AUDIO_ItfTypeDef *fops); -void USBD_AUDIO_Sync(USBD_HandleTypeDef *pdev, AUDIO_OffsetTypeDef offset); +void USBD_AUDIO_Sync(USBD_HandleTypeDef *pdev, AUDIO_OffsetTypeDef offset); /** * @} */ diff --git a/Class/AUDIO/Src/usbd_audio.c b/Class/AUDIO/Src/usbd_audio.c index 877b5f7..1dce51a 100644 --- a/Class/AUDIO/Src/usbd_audio.c +++ b/Class/AUDIO/Src/usbd_audio.c @@ -133,7 +133,7 @@ static void AUDIO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef * @{ */ -USBD_ClassTypeDef USBD_AUDIO = +USBD_ClassTypeDef USBD_AUDIO = { USBD_AUDIO_Init, USBD_AUDIO_DeInit, @@ -231,8 +231,8 @@ __ALIGN_BEGIN static uint8_t USBD_AUDIO_CfgDesc[USB_AUDIO_CONFIG_DESC_SIZ] __ALI /* USB Speaker Standard AS Interface Descriptor - Audio Streaming Zero Bandwith */ /* Interface 1, Alternate Setting 0 */ - AUDIO_INTERFACE_DESC_SIZE, /* bLength */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType */ + AUDIO_INTERFACE_DESC_SIZE, /* bLength */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType */ 0x01, /* bInterfaceNumber */ 0x00, /* bAlternateSetting */ 0x00, /* bNumEndpoints */ @@ -244,8 +244,8 @@ __ALIGN_BEGIN static uint8_t USBD_AUDIO_CfgDesc[USB_AUDIO_CONFIG_DESC_SIZ] __ALI /* USB Speaker Standard AS Interface Descriptor - Audio Streaming Operational */ /* Interface 1, Alternate Setting 1 */ - AUDIO_INTERFACE_DESC_SIZE, /* bLength */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType */ + AUDIO_INTERFACE_DESC_SIZE, /* bLength */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType */ 0x01, /* bInterfaceNumber */ 0x01, /* bAlternateSetting */ 0x01, /* bNumEndpoints */ @@ -261,7 +261,7 @@ __ALIGN_BEGIN static uint8_t USBD_AUDIO_CfgDesc[USB_AUDIO_CONFIG_DESC_SIZ] __ALI AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */ 0x01, /* bTerminalLink */ 0x01, /* bDelay */ - 0x01, /* wFormatTag AUDIO_FORMAT_PCM 0x0001*/ + 0x01, /* wFormatTag AUDIO_FORMAT_PCM 0x0001 */ 0x00, /* 07 byte*/ @@ -269,21 +269,21 @@ __ALIGN_BEGIN static uint8_t USBD_AUDIO_CfgDesc[USB_AUDIO_CONFIG_DESC_SIZ] __ALI 0x0B, /* bLength */ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */ - AUDIO_FORMAT_TYPE_I, /* bFormatType */ + AUDIO_FORMAT_TYPE_I, /* bFormatType */ 0x02, /* bNrChannels */ 0x02, /* bSubFrameSize : 2 Bytes per frame (16bits) */ 16, /* bBitResolution (16-bits per sample) */ 0x01, /* bSamFreqType only one frequency supported */ - AUDIO_SAMPLE_FREQ(USBD_AUDIO_FREQ), /* Audio sampling frequency coded on 3 bytes */ + AUDIO_SAMPLE_FREQ(USBD_AUDIO_FREQ), /* Audio sampling frequency coded on 3 bytes */ /* 11 byte*/ /* Endpoint 1 - Standard Descriptor */ AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType */ - AUDIO_OUT_EP, /* bEndpointAddress 1 out endpoint*/ + AUDIO_OUT_EP, /* bEndpointAddress 1 out endpoint */ USBD_EP_TYPE_ISOC, /* bmAttributes */ AUDIO_PACKET_SZE(USBD_AUDIO_FREQ), /* wMaxPacketSize in Bytes (Freq(Samples)*2(Stereo)*2(HalfWord)) */ - 0x01, /* bInterval */ + AUDIO_FS_BINTERVAL, /* bInterval */ 0x00, /* bRefresh */ 0x00, /* bSynchAddress */ /* 09 byte*/ @@ -329,44 +329,54 @@ __ALIGN_BEGIN static uint8_t USBD_AUDIO_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIE * @param cfgidx: Configuration index * @retval status */ -static uint8_t USBD_AUDIO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +static uint8_t USBD_AUDIO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { - USBD_AUDIO_HandleTypeDef *haudio; + UNUSED(cfgidx); + USBD_AUDIO_HandleTypeDef *haudio; + + /* Allocate Audio structure */ + haudio = USBD_malloc(sizeof(USBD_AUDIO_HandleTypeDef)); + + if (haudio == NULL) + { + pdev->pClassData = NULL; + return (uint8_t)USBD_EMEM; + } + + pdev->pClassData = (void *)haudio; + + if (pdev->dev_speed == USBD_SPEED_HIGH) + { + pdev->ep_out[AUDIO_OUT_EP & 0xFU].bInterval = AUDIO_HS_BINTERVAL; + } + else /* LOW and FULL-speed endpoints */ + { + pdev->ep_out[AUDIO_OUT_EP & 0xFU].bInterval = AUDIO_FS_BINTERVAL; + } /* Open EP OUT */ - USBD_LL_OpenEP(pdev, AUDIO_OUT_EP, USBD_EP_TYPE_ISOC, AUDIO_OUT_PACKET); + (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; - /* Allocate Audio structure */ - pdev->pClassData = USBD_malloc(sizeof(USBD_AUDIO_HandleTypeDef)); + haudio->alt_setting = 0U; + haudio->offset = AUDIO_OFFSET_UNKNOWN; + haudio->wr_ptr = 0U; + haudio->rd_ptr = 0U; + haudio->rd_enable = 0U; - if (pdev->pClassData == NULL) + /* Initialize the Audio output Hardware layer */ + if (((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->Init(USBD_AUDIO_FREQ, + AUDIO_DEFAULT_VOLUME, + 0U) != 0U) { - return USBD_FAIL; - } - else - { - haudio = (USBD_AUDIO_HandleTypeDef *) pdev->pClassData; - haudio->alt_setting = 0U; - haudio->offset = AUDIO_OFFSET_UNKNOWN; - haudio->wr_ptr = 0U; - haudio->rd_ptr = 0U; - haudio->rd_enable = 0U; - - /* Initialize the Audio output Hardware layer */ - if (((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->Init(USBD_AUDIO_FREQ, - AUDIO_DEFAULT_VOLUME, - 0U) != 0) - { - return USBD_FAIL; - } - - /* Prepare Out endpoint to receive 1st packet */ - USBD_LL_PrepareReceive(pdev, AUDIO_OUT_EP, haudio->buffer, - AUDIO_OUT_PACKET); + return (uint8_t)USBD_FAIL; } - return USBD_OK; + /* Prepare Out endpoint to receive 1st packet */ + (void)USBD_LL_PrepareReceive(pdev, AUDIO_OUT_EP, haudio->buffer, + AUDIO_OUT_PACKET); + + return (uint8_t)USBD_OK; } /** @@ -376,22 +386,24 @@ static uint8_t USBD_AUDIO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) * @param cfgidx: Configuration index * @retval status */ -static uint8_t USBD_AUDIO_DeInit(USBD_HandleTypeDef *pdev, - uint8_t cfgidx) +static uint8_t USBD_AUDIO_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { + UNUSED(cfgidx); + /* Open EP OUT */ - USBD_LL_CloseEP(pdev, AUDIO_OUT_EP); + (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; /* DeInit physical Interface components */ if (pdev->pClassData != NULL) { ((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->DeInit(0U); - USBD_free(pdev->pClassData); + (void)USBD_free(pdev->pClassData); pdev->pClassData = NULL; } - return USBD_OK; + return (uint8_t)USBD_OK; } /** @@ -401,108 +413,111 @@ static uint8_t USBD_AUDIO_DeInit(USBD_HandleTypeDef *pdev, * @param req: usb requests * @retval status */ -static uint8_t USBD_AUDIO_Setup(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req) +static uint8_t USBD_AUDIO_Setup(USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req) { USBD_AUDIO_HandleTypeDef *haudio; uint16_t len; uint8_t *pbuf; uint16_t status_info = 0U; - uint8_t ret = USBD_OK; + USBD_StatusTypeDef ret = USBD_OK; haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassData; switch (req->bmRequest & USB_REQ_TYPE_MASK) { - case USB_REQ_TYPE_CLASS : - switch (req->bRequest) - { - case AUDIO_REQ_GET_CUR: - AUDIO_REQ_GetCurrent(pdev, req); - break; - - case AUDIO_REQ_SET_CUR: - AUDIO_REQ_SetCurrent(pdev, req); - break; - - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; - } + case USB_REQ_TYPE_CLASS: + switch (req->bRequest) + { + case AUDIO_REQ_GET_CUR: + AUDIO_REQ_GetCurrent(pdev, req); break; - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_STATUS: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - USBD_CtlSendData(pdev, (uint8_t *)(void *)&status_info, 2U); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; - - 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); - - USBD_CtlSendData(pdev, pbuf, len); - } - break; - - case USB_REQ_GET_INTERFACE : - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - USBD_CtlSendData(pdev, (uint8_t *)(void *)&haudio->alt_setting, 1U); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; - - case USB_REQ_SET_INTERFACE : - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - if ((uint8_t)(req->wValue) <= USBD_MAX_NUM_INTERFACES) - { - haudio->alt_setting = (uint8_t)(req->wValue); - } - else - { - /* Call the error management function (command will be nacked */ - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; - - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; - } + case AUDIO_REQ_SET_CUR: + AUDIO_REQ_SetCurrent(pdev, req); break; + default: USBD_CtlError(pdev, req); ret = USBD_FAIL; break; + } + break; + + 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_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); + } + break; + + case USB_REQ_GET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, (uint8_t *)&haudio->alt_setting, 1U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_SET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + if ((uint8_t)(req->wValue) <= USBD_MAX_NUM_INTERFACES) + { + haudio->alt_setting = (uint8_t)(req->wValue); + } + else + { + /* Call the error management function (command will be nacked */ + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + } + else + { + 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 ret; + return (uint8_t)ret; } @@ -513,9 +528,9 @@ static uint8_t USBD_AUDIO_Setup(USBD_HandleTypeDef *pdev, * @param length : pointer data length * @retval pointer to descriptor buffer */ -static uint8_t *USBD_AUDIO_GetCfgDesc(uint16_t *length) +static uint8_t *USBD_AUDIO_GetCfgDesc(uint16_t *length) { - *length = sizeof(USBD_AUDIO_CfgDesc); + *length = (uint16_t)sizeof(USBD_AUDIO_CfgDesc); return USBD_AUDIO_CfgDesc; } @@ -527,10 +542,13 @@ static uint8_t *USBD_AUDIO_GetCfgDesc(uint16_t *length) * @param epnum: endpoint index * @retval status */ -static uint8_t USBD_AUDIO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) +static uint8_t USBD_AUDIO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) { + UNUSED(pdev); + UNUSED(epnum); + /* Only OUT data are processed */ - return USBD_OK; + return (uint8_t)USBD_OK; } /** @@ -539,10 +557,10 @@ static uint8_t USBD_AUDIO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) * @param pdev: device instance * @retval status */ -static uint8_t USBD_AUDIO_EP0_RxReady(USBD_HandleTypeDef *pdev) +static uint8_t USBD_AUDIO_EP0_RxReady(USBD_HandleTypeDef *pdev) { - USBD_AUDIO_HandleTypeDef *haudio; - haudio = (USBD_AUDIO_HandleTypeDef *) pdev->pClassData; + USBD_AUDIO_HandleTypeDef *haudio; + haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassData; if (haudio->control.cmd == AUDIO_REQ_SET_CUR) { @@ -556,7 +574,7 @@ static uint8_t USBD_AUDIO_EP0_RxReady(USBD_HandleTypeDef *pdev) } } - return USBD_OK; + return (uint8_t)USBD_OK; } /** * @brief USBD_AUDIO_EP0_TxReady @@ -564,10 +582,12 @@ static uint8_t USBD_AUDIO_EP0_RxReady(USBD_HandleTypeDef *pdev) * @param pdev: device instance * @retval status */ -static uint8_t USBD_AUDIO_EP0_TxReady(USBD_HandleTypeDef *pdev) +static uint8_t USBD_AUDIO_EP0_TxReady(USBD_HandleTypeDef *pdev) { + UNUSED(pdev); + /* Only OUT control data are processed */ - return USBD_OK; + return (uint8_t)USBD_OK; } /** * @brief USBD_AUDIO_SOF @@ -575,9 +595,11 @@ static uint8_t USBD_AUDIO_EP0_TxReady(USBD_HandleTypeDef *pdev) * @param pdev: device instance * @retval status */ -static uint8_t USBD_AUDIO_SOF(USBD_HandleTypeDef *pdev) +static uint8_t USBD_AUDIO_SOF(USBD_HandleTypeDef *pdev) { - return USBD_OK; + UNUSED(pdev); + + return (uint8_t)USBD_OK; } /** @@ -586,17 +608,23 @@ static uint8_t USBD_AUDIO_SOF(USBD_HandleTypeDef *pdev) * @param pdev: device instance * @retval status */ -void USBD_AUDIO_Sync(USBD_HandleTypeDef *pdev, AUDIO_OffsetTypeDef offset) +void USBD_AUDIO_Sync(USBD_HandleTypeDef *pdev, AUDIO_OffsetTypeDef offset) { - uint32_t cmd = 0U; - USBD_AUDIO_HandleTypeDef *haudio; - haudio = (USBD_AUDIO_HandleTypeDef *) pdev->pClassData; + USBD_AUDIO_HandleTypeDef *haudio; + uint32_t BufferSize = AUDIO_TOTAL_BUF_SIZE / 2U; - haudio->offset = offset; + if (pdev->pClassData == NULL) + { + return; + } + + haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassData; + + haudio->offset = offset; if (haudio->rd_enable == 1U) { - haudio->rd_ptr += (uint16_t)(AUDIO_TOTAL_BUF_SIZE / 2U); + haudio->rd_ptr += (uint16_t)BufferSize; if (haudio->rd_ptr == AUDIO_TOTAL_BUF_SIZE) { @@ -609,13 +637,13 @@ void USBD_AUDIO_Sync(USBD_HandleTypeDef *pdev, AUDIO_OffsetTypeDef offset) { if ((haudio->rd_ptr - haudio->wr_ptr) < AUDIO_OUT_PACKET) { - cmd = AUDIO_TOTAL_BUF_SIZE / 2U + 4U; + BufferSize += 4U; } else { if ((haudio->rd_ptr - haudio->wr_ptr) > (AUDIO_TOTAL_BUF_SIZE - AUDIO_OUT_PACKET)) { - cmd = AUDIO_TOTAL_BUF_SIZE / 2U - 4U; + BufferSize -= 4U; } } } @@ -623,13 +651,13 @@ void USBD_AUDIO_Sync(USBD_HandleTypeDef *pdev, AUDIO_OffsetTypeDef offset) { if ((haudio->wr_ptr - haudio->rd_ptr) < AUDIO_OUT_PACKET) { - cmd = AUDIO_TOTAL_BUF_SIZE / 2U - 4U; + BufferSize -= 4U; } else { if ((haudio->wr_ptr - haudio->rd_ptr) > (AUDIO_TOTAL_BUF_SIZE - AUDIO_OUT_PACKET)) { - cmd = AUDIO_TOTAL_BUF_SIZE / 2U + 4U; + BufferSize += 4U; } } } @@ -637,8 +665,7 @@ 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], - cmd, - AUDIO_CMD_PLAY); + BufferSize, AUDIO_CMD_PLAY); haudio->offset = AUDIO_OFFSET_NONE; } } @@ -650,9 +677,12 @@ void USBD_AUDIO_Sync(USBD_HandleTypeDef *pdev, AUDIO_OffsetTypeDef offset) * @param epnum: endpoint index * @retval status */ -static uint8_t USBD_AUDIO_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) +static uint8_t USBD_AUDIO_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) { - return USBD_OK; + UNUSED(pdev); + UNUSED(epnum); + + return (uint8_t)USBD_OK; } /** * @brief USBD_AUDIO_IsoOutIncomplete @@ -661,9 +691,12 @@ static uint8_t USBD_AUDIO_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epn * @param epnum: endpoint index * @retval status */ -static uint8_t USBD_AUDIO_IsoOutIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) +static uint8_t USBD_AUDIO_IsoOutIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) { - return USBD_OK; + UNUSED(pdev); + UNUSED(epnum); + + return (uint8_t)USBD_OK; } /** * @brief USBD_AUDIO_DataOut @@ -672,16 +705,24 @@ static uint8_t USBD_AUDIO_IsoOutIncomplete(USBD_HandleTypeDef *pdev, uint8_t ep * @param epnum: endpoint index * @retval status */ -static uint8_t USBD_AUDIO_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) +static uint8_t USBD_AUDIO_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) { - USBD_AUDIO_HandleTypeDef *haudio; - haudio = (USBD_AUDIO_HandleTypeDef *) pdev->pClassData; + uint16_t PacketSize; + USBD_AUDIO_HandleTypeDef *haudio; + + haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassData; if (epnum == AUDIO_OUT_EP) { - /* Increment the Buffer pointer or roll it back when all buffers are full */ + /* Get received data packet length */ + PacketSize = (uint16_t)USBD_LL_GetRxDataSize(pdev, epnum); - haudio->wr_ptr += AUDIO_OUT_PACKET; + /* Packet received Callback */ + ((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->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) { @@ -706,11 +747,12 @@ static uint8_t USBD_AUDIO_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) } /* Prepare Out endpoint to receive next audio packet */ - USBD_LL_PrepareReceive(pdev, AUDIO_OUT_EP, &haudio->buffer[haudio->wr_ptr], - AUDIO_OUT_PACKET); + (void)USBD_LL_PrepareReceive(pdev, AUDIO_OUT_EP, + &haudio->buffer[haudio->wr_ptr], + AUDIO_OUT_PACKET); } - return USBD_OK; + return (uint8_t)USBD_OK; } /** @@ -722,13 +764,13 @@ static uint8_t USBD_AUDIO_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) */ static void AUDIO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { - USBD_AUDIO_HandleTypeDef *haudio; - haudio = (USBD_AUDIO_HandleTypeDef *) pdev->pClassData; + USBD_AUDIO_HandleTypeDef *haudio; + haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassData; - memset(haudio->control.data, 0, 64U); + (void)USBD_memset(haudio->control.data, 0, 64U); /* Send the current mute state */ - USBD_CtlSendData(pdev, haudio->control.data, req->wLength); + (void)USBD_CtlSendData(pdev, haudio->control.data, req->wLength); } /** @@ -740,13 +782,13 @@ static void AUDIO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef */ static void AUDIO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { - USBD_AUDIO_HandleTypeDef *haudio; - haudio = (USBD_AUDIO_HandleTypeDef *) pdev->pClassData; + USBD_AUDIO_HandleTypeDef *haudio; + haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassData; - if (req->wLength) + if (req->wLength != 0U) { /* Prepare the reception of the buffer over EP0 */ - USBD_CtlPrepareRx(pdev, haudio->control.data, req->wLength); + (void)USBD_CtlPrepareRx(pdev, haudio->control.data, req->wLength); haudio->control.cmd = AUDIO_REQ_SET_CUR; /* Set the request value */ haudio->control.len = (uint8_t)req->wLength; /* Set the request data length */ @@ -761,9 +803,9 @@ static void AUDIO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef * @param length : pointer data length * @retval pointer to descriptor buffer */ -static uint8_t *USBD_AUDIO_GetDeviceQualifierDesc(uint16_t *length) +static uint8_t *USBD_AUDIO_GetDeviceQualifierDesc(uint16_t *length) { - *length = sizeof(USBD_AUDIO_DeviceQualifierDesc); + *length = (uint16_t)sizeof(USBD_AUDIO_DeviceQualifierDesc); return USBD_AUDIO_DeviceQualifierDesc; } @@ -773,15 +815,17 @@ static uint8_t *USBD_AUDIO_GetDeviceQualifierDesc(uint16_t *length) * @param fops: Audio interface callback * @retval status */ -uint8_t USBD_AUDIO_RegisterInterface(USBD_HandleTypeDef *pdev, - USBD_AUDIO_ItfTypeDef *fops) +uint8_t USBD_AUDIO_RegisterInterface(USBD_HandleTypeDef *pdev, + USBD_AUDIO_ItfTypeDef *fops) { - if (fops != NULL) + if (fops == NULL) { - pdev->pUserData = fops; + return (uint8_t)USBD_FAIL; } - return USBD_OK; + pdev->pUserData = fops; + + return (uint8_t)USBD_OK; } /** * @} diff --git a/Class/AUDIO/Src/usbd_audio_if_template.c b/Class/AUDIO/Src/usbd_audio_if_template.c index 35515cc..7c97c75 100644 --- a/Class/AUDIO/Src/usbd_audio_if_template.c +++ b/Class/AUDIO/Src/usbd_audio_if_template.c @@ -70,7 +70,7 @@ static int8_t TEMPLATE_DeInit(uint32_t options); static int8_t TEMPLATE_AudioCmd(uint8_t *pbuf, uint32_t size, uint8_t cmd); static int8_t TEMPLATE_VolumeCtl(uint8_t vol); static int8_t TEMPLATE_MuteCtl(uint8_t cmd); -static int8_t TEMPLATE_PeriodicTC(uint8_t cmd); +static int8_t TEMPLATE_PeriodicTC(uint8_t *pbuf, uint32_t size, uint8_t cmd); static int8_t TEMPLATE_GetState(void); USBD_AUDIO_ItfTypeDef USBD_AUDIO_Template_fops = @@ -94,6 +94,10 @@ USBD_AUDIO_ItfTypeDef USBD_AUDIO_Template_fops = */ static int8_t TEMPLATE_Init(uint32_t AudioFreq, uint32_t Volume, uint32_t options) { + UNUSED(AudioFreq); + UNUSED(Volume); + UNUSED(options); + /* Add your initialization code here */ @@ -108,6 +112,8 @@ static int8_t TEMPLATE_Init(uint32_t AudioFreq, uint32_t Volume, uint32_t optio */ static int8_t TEMPLATE_DeInit(uint32_t options) { + UNUSED(options); + /* Add your deinitialization code here */ @@ -125,6 +131,10 @@ static int8_t TEMPLATE_DeInit(uint32_t options) */ static int8_t TEMPLATE_AudioCmd(uint8_t *pbuf, uint32_t size, uint8_t cmd) { + UNUSED(pbuf); + UNUSED(size); + UNUSED(cmd); + return (0); } @@ -135,6 +145,8 @@ static int8_t TEMPLATE_AudioCmd(uint8_t *pbuf, uint32_t size, uint8_t cmd) */ static int8_t TEMPLATE_VolumeCtl(uint8_t vol) { + UNUSED(vol); + return (0); } @@ -145,6 +157,8 @@ static int8_t TEMPLATE_VolumeCtl(uint8_t vol) */ static int8_t TEMPLATE_MuteCtl(uint8_t cmd) { + UNUSED(cmd); + return (0); } @@ -153,8 +167,12 @@ static int8_t TEMPLATE_MuteCtl(uint8_t cmd) * @param cmd * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL */ -static int8_t TEMPLATE_PeriodicTC(uint8_t cmd) +static int8_t TEMPLATE_PeriodicTC(uint8_t *pbuf, uint32_t size, uint8_t cmd) { + UNUSED(pbuf); + UNUSED(size); + UNUSED(cmd); + return (0); } diff --git a/Class/BillBoard/Inc/usbd_billboard.h b/Class/BillBoard/Inc/usbd_billboard.h new file mode 100644 index 0000000..8bff7b3 --- /dev/null +++ b/Class/BillBoard/Inc/usbd_billboard.h @@ -0,0 +1,163 @@ +/** + ****************************************************************************** + * @file usbd_billboard.h + * @author MCD Application Team + * @brief Header file for the usbd_billboard.c file. + ****************************************************************************** + * @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 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_BB_H +#define __USB_BB_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" +#include "usbd_desc.h" +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_BB + * @brief This file is the Header file for usbd_billboard.c + * @{ + */ + +/** @defgroup USBD_BB_Exported_Defines + * @{ + */ +#define USB_BB_CONFIG_DESC_SIZ 18U + +#ifndef USB_BB_MAX_NUM_ALT_MODE +#define USB_BB_MAX_NUM_ALT_MODE 0x2U +#endif /* USB_BB_MAX_NUM_ALT_MODE */ + +#ifndef USBD_BB_IF_STRING_INDEX +#define USBD_BB_IF_STRING_INDEX 0x10U +#endif /* USBD_BB_IF_STRING_INDEX */ + + +#define USBD_BILLBOARD_CAPABILITY 0x0DU +#define USBD_BILLBOARD_ALTMODE_CAPABILITY 0x0FU + +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ +typedef struct _BB_DescHeader +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDevCapabilityType; +} +USBD_BB_DescHeader_t; + +typedef struct +{ + uint16_t wSVID; + uint8_t bAlternateMode; + uint8_t iAlternateModeString; +} USBD_BB_AltModeTypeDef; + +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDevCapabilityType; + uint8_t bIndex; + uint32_t dwAlternateModeVdo; +} USBD_BB_AltModeCapDescTypeDef; + +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDevCapabilityType; + uint8_t iAddtionalInfoURL; + uint8_t bNbrOfAltModes; + uint8_t bPreferredAltMode; + uint16_t VconnPwr; + uint8_t bmConfigured[32]; + uint16_t bcdVersion; + uint8_t bAdditionalFailureInfo; + uint8_t bReserved; + USBD_BB_AltModeTypeDef wSVID[USB_BB_MAX_NUM_ALT_MODE]; +} USBD_BosBBCapDescTypedef; + +typedef enum +{ + UNSPECIFIED_ERROR = 0, + CONFIGURATION_NOT_ATTEMPTED, + CONFIGURATION_UNSUCCESSFUL, + CONFIGURATION_SUCCESSFUL, +} BB_AltModeState; + +/** + * @} + */ + + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ + +extern USBD_ClassTypeDef USBD_BB; +#define USBD_BB_CLASS &USBD_BB +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ + +#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 + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_BB_H */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Class/BillBoard/Src/usbd_billboard.c b/Class/BillBoard/Src/usbd_billboard.c new file mode 100644 index 0000000..b9e6d19 --- /dev/null +++ b/Class/BillBoard/Src/usbd_billboard.c @@ -0,0 +1,496 @@ +/** + ****************************************************************************** + * @file usbd_billboard.c + * @author MCD Application Team + * @brief This file provides the high layer firmware functions to manage the + * following functionalities of the USB BillBoard Class: + * - Initialization and Configuration of high and low layer + * - Enumeration as BillBoard Device + * - Error management + * @verbatim + * + * =================================================================== + * BillBoard Class Description + * =================================================================== + * This module manages the BillBoard class V1.2.1 following the "Device Class Definition + * for BillBoard Devices (BB) Version R1.2.1 Sept 08, 2016". + * This driver implements the following aspects of the specification: + * - Device descriptor management + * - Configuration descriptor management + * - Enumeration as an USB BillBoard device + * - Enumeration & management of BillBoard device supported alternate modes + * + * @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 ------------------------------------------------------------------*/ +#include "usbd_billboard.h" +#include "usbd_ctlreq.h" + + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_BB + * @brief usbd core module + * @{ + */ + +/** @defgroup USBD_BB_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_BB_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_BB_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_BB_Private_FunctionPrototypes + * @{ + */ + +static uint8_t USBD_BB_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +static uint8_t USBD_BB_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +static uint8_t USBD_BB_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static uint8_t USBD_BB_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); +static uint8_t USBD_BB_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum); +static uint8_t USBD_BB_EP0_RxReady(USBD_HandleTypeDef *pdev); + +static uint8_t *USBD_BB_GetCfgDesc(uint16_t *length); +static uint8_t *USBD_BB_GetDeviceQualifierDesc(uint16_t *length); +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 + + + +/** + * @} + */ + +/** @defgroup USBD_BB_Private_Variables + * @{ + */ +USBD_ClassTypeDef USBD_BB = +{ + USBD_BB_Init, /* Init */ + USBD_BB_DeInit, /* DeInit */ + USBD_BB_Setup, /* Setup */ + NULL, /* EP0_TxSent */ + USBD_BB_EP0_RxReady, /* EP0_RxReady */ + USBD_BB_DataIn, /* DataIn */ + USBD_BB_DataOut, /* DataOut */ + NULL, /* SOF */ + NULL, + NULL, + USBD_BB_GetCfgDesc, + USBD_BB_GetCfgDesc, + USBD_BB_GetOtherSpeedCfgDesc, + USBD_BB_GetDeviceQualifierDesc, +#if (USBD_SUPPORT_USER_STRING_DESC == 1U) + NULL, +#endif +}; + +/* USB Standard Device Qualifier Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_BB_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = +{ + USB_LEN_DEV_QUALIFIER_DESC, /* bLength */ + USB_DESC_TYPE_DEVICE_QUALIFIER, /* bDescriptorType */ + 0x01, /* bcdUSB */ + 0x20, + 0x11, /* bDeviceClass */ + 0x00, /* bDeviceSubClass */ + 0x00, /* bDeviceProtocol */ + 0x40, /* bMaxPacketSize0 */ + 0x01, /* bNumConfigurations */ + 0x00, /* bReserved */ +}; + +/* USB device Configuration Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_BB_CfgDesc[USB_BB_CONFIG_DESC_SIZ] __ALIGN_END = +{ + 0x09, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + USB_BB_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ + 0x00, + 0x01, /* bNumInterfaces: 1 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + USBD_IDX_CONFIG_STR, /* iConfiguration: Index of string descriptor describing the configuration */ + 0xC0, /* bmAttributes: bus powered and Support Remote Wake-up */ + 0x00, /* MaxPower 100 mA: this current is used for detecting Vbus */ + /* 09 */ + + /************** Descriptor of BillBoard interface ****************/ + /* 09 */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x00, /* bNumEndpoints */ + 0x11, /* bInterfaceClass: billboard */ + 0x00, /* bInterfaceSubClass */ + 0x00, /* nInterfaceProtocol */ + USBD_BB_IF_STRING_INDEX, /* iInterface: Index of string descriptor */ +}; + +/* USB device Other Speed Configuration Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_BB_OtherSpeedCfgDesc[USB_BB_CONFIG_DESC_SIZ] __ALIGN_END = +{ + 0x09, /* bLength: Configuation Descriptor size */ + USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, + USB_BB_CONFIG_DESC_SIZ, + 0x00, + 0x01, /* bNumInterfaces: 1 interface */ + 0x01, /* bConfigurationValue: */ + USBD_IDX_CONFIG_STR, /* iConfiguration: */ + 0xC0, /* bmAttributes: */ + 0x00, /* MaxPower 100 mA */ + + /************** Descriptor of BillBoard interface ****************/ + /* 09 */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x00, /* bNumEndpoints*/ + 0x11, /* bInterfaceClass: billboard */ + 0x00, /* bInterfaceSubClass */ + 0x00, /* nInterfaceProtocol */ + USBD_BB_IF_STRING_INDEX, /* iInterface: Index of string descriptor */ +} ; + +/** + * @} + */ + +/** @defgroup USBD_BB_Private_Functions + * @{ + */ + +/** + * @brief USBD_BB_Init + * Initialize the BB interface + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_BB_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + /* Prevent unused argument compilation warning */ + UNUSED(pdev); + UNUSED(cfgidx); + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_BB_Init + * DeInitialize the BB layer + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_BB_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + /* Prevent unused argument compilation warning */ + UNUSED(pdev); + UNUSED(cfgidx); + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_BB_Setup + * Handle the BB specific requests + * @param pdev: instance + * @param req: usb requests + * @retval status + */ +static uint8_t USBD_BB_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_StatusTypeDef ret = USBD_OK; + uint16_t status_info = 0U; + uint16_t AltSetting = 0U; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS: + break; + 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, (uint8_t *)&AltSetting, 1U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_SET_INTERFACE: + 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_BB_DataIn + * Data sent on non-control IN endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +static uint8_t USBD_BB_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + /* Prevent unused argument compilation warning */ + UNUSED(pdev); + UNUSED(epnum); + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_BB_DataOut + * Data received on non-control Out endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +static uint8_t USBD_BB_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + /* Prevent unused argument compilation warning */ + UNUSED(pdev); + UNUSED(epnum); + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_BB_EP0_RxReady + * Handle EP0 Rx Ready event + * @param pdev: device instance + * @retval status + */ +static uint8_t USBD_BB_EP0_RxReady(USBD_HandleTypeDef *pdev) +{ + /* Prevent unused argument compilation warning */ + UNUSED(pdev); + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_BB_GetCfgDesc + * return configuration descriptor + * @param speed : current device speed + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_BB_GetCfgDesc(uint16_t *length) +{ + *length = (uint16_t)sizeof(USBD_BB_CfgDesc); + return USBD_BB_CfgDesc; +} + +/** + * @brief USBD_BB_GetOtherSpeedCfgDesc + * return other speed configuration descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +uint8_t *USBD_BB_GetOtherSpeedCfgDesc(uint16_t *length) +{ + *length = (uint16_t)sizeof(USBD_BB_OtherSpeedCfgDesc); + return USBD_BB_OtherSpeedCfgDesc; +} + +/** + * @brief DeviceQualifierDescriptor + * return Device Qualifier descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_BB_GetDeviceQualifierDesc(uint16_t *length) +{ + *length = (uint16_t)sizeof(USBD_BB_DeviceQualifierDesc); + return USBD_BB_DeviceQualifierDesc; +} + + +#if (USBD_CLASS_BOS_ENABLED == 1U) +/** + * @brief USBD_BB_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_BB_DescHeader_t *USBD_BB_GetNextDesc(uint8_t *pbuf, uint16_t *ptr) +{ + USBD_BB_DescHeader_t *pnext = (USBD_BB_DescHeader_t *)pbuf; + + *ptr += pnext->bLength; + pnext = (USBD_BB_DescHeader_t *)(pbuf + pnext->bLength); + + return (pnext); +} + + +/** + * @brief USBD_BB_GetCapDesc + * This function return the Billboard Capability descriptor + * @param pdev: device instance + * @param pBosDesc: pointer to Bos descriptor + * @retval pointer to Billboard Capability descriptor + */ +void *USBD_BB_GetCapDesc(USBD_HandleTypeDef *pdev, uint8_t *pBosDesc) +{ + UNUSED(pdev); + + USBD_BB_DescHeader_t *pdesc = (USBD_BB_DescHeader_t *)pBosDesc; + USBD_BosDescTypedef *desc = (USBD_BosDescTypedef *)pBosDesc; + USBD_BosBBCapDescTypedef *pCapDesc = NULL; + uint16_t ptr; + + if (desc->wTotalLength > desc->bLength) + { + ptr = desc->bLength; + + while (ptr < desc->wTotalLength) + { + pdesc = USBD_BB_GetNextDesc((uint8_t *)pdesc, &ptr); + + if (pdesc->bDevCapabilityType == USBD_BILLBOARD_CAPABILITY) + { + pCapDesc = (USBD_BosBBCapDescTypedef *)pdesc; + break; + } + } + } + return (void *)pCapDesc; +} + + +/** + * @brief USBD_BB_GetAltModeDesc + * This function return the Billboard Alternate Mode descriptor + * @param pdev: device instance + * @param pBosDesc: pointer to Bos descriptor + * @param idx: Index of requested Alternate Mode descriptor + * @retval pointer to Alternate Mode descriptor + */ +void *USBD_BB_GetAltModeDesc(USBD_HandleTypeDef *pdev, uint8_t *pBosDesc, uint8_t idx) +{ + UNUSED(pdev); + + USBD_BB_DescHeader_t *pdesc = (USBD_BB_DescHeader_t *)pBosDesc; + USBD_BosDescTypedef *desc = (USBD_BosDescTypedef *)pBosDesc; + USBD_BB_AltModeCapDescTypeDef *pAltModDesc = NULL; + uint8_t cnt = 0U; + uint16_t ptr; + + if (desc->wTotalLength > desc->bLength) + { + ptr = desc->bLength; + + while (ptr < desc->wTotalLength) + { + pdesc = USBD_BB_GetNextDesc((uint8_t *)pdesc, &ptr); + + if (pdesc->bDevCapabilityType == USBD_BILLBOARD_ALTMODE_CAPABILITY) + { + if (cnt == idx) + { + pAltModDesc = (USBD_BB_AltModeCapDescTypeDef *)pdesc; + break; + } + else + { + cnt++; + } + } + } + } + return (void *)pAltModDesc; +} +#endif + +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Class/CDC/Inc/usbd_cdc.h b/Class/CDC/Inc/usbd_cdc.h index 121bdb5..b484218 100644 --- a/Class/CDC/Inc/usbd_cdc.h +++ b/Class/CDC/Inc/usbd_cdc.h @@ -46,11 +46,11 @@ extern "C" { #define CDC_CMD_EP 0x82U /* EP2 for CDC commands */ #ifndef CDC_HS_BINTERVAL -#define CDC_HS_BINTERVAL 0x10U +#define CDC_HS_BINTERVAL 0x10U #endif /* CDC_HS_BINTERVAL */ #ifndef CDC_FS_BINTERVAL -#define CDC_FS_BINTERVAL 0x10U +#define CDC_FS_BINTERVAL 0x10U #endif /* CDC_FS_BINTERVAL */ /* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */ @@ -104,7 +104,7 @@ typedef struct _USBD_CDC_Itf int8_t (* DeInit)(void); int8_t (* Control)(uint8_t cmd, uint8_t *pbuf, uint16_t length); int8_t (* Receive)(uint8_t *Buf, uint32_t *Len); - + int8_t (* TransmitCplt)(uint8_t *Buf, uint32_t *Len, uint8_t epnum); } USBD_CDC_ItfTypeDef; @@ -120,8 +120,7 @@ typedef struct __IO uint32_t TxState; __IO uint32_t RxState; -} -USBD_CDC_HandleTypeDef; +} USBD_CDC_HandleTypeDef; @@ -137,8 +136,8 @@ USBD_CDC_HandleTypeDef; * @{ */ -extern USBD_ClassTypeDef USBD_CDC; -#define USBD_CDC_CLASS &USBD_CDC +extern USBD_ClassTypeDef USBD_CDC; +#define USBD_CDC_CLASS &USBD_CDC /** * @} */ @@ -146,19 +145,15 @@ extern USBD_ClassTypeDef USBD_CDC; /** @defgroup USB_CORE_Exported_Functions * @{ */ -uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, - USBD_CDC_ItfTypeDef *fops); +uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, + USBD_CDC_ItfTypeDef *fops); -uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, - uint8_t *pbuff, - uint16_t length); +uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, + uint32_t length); -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); +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); /** * @} */ diff --git a/Class/CDC/Src/usbd_cdc.c b/Class/CDC/Src/usbd_cdc.c index 8332b22..017e4cd 100644 --- a/Class/CDC/Src/usbd_cdc.c +++ b/Class/CDC/Src/usbd_cdc.c @@ -99,33 +99,18 @@ EndBSPDependencies */ * @{ */ +static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +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_Init(USBD_HandleTypeDef *pdev, - uint8_t cfgidx); - -static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, - uint8_t cfgidx); - -static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req); - -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); +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); /* USB Standard Device Descriptor */ __ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = @@ -171,286 +156,286 @@ USBD_ClassTypeDef USBD_CDC = }; /* USB CDC device Configuration Descriptor */ -__ALIGN_BEGIN uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = +__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 */ + /* 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 interface */ - 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ - 0xC0, /* bmAttributes: self powered */ - 0x32, /* MaxPower 0 mA */ + 0x02, /* bNumInterfaces: 2 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ + 0xC0, /* bmAttributes: self powered */ + 0x32, /* MaxPower 0 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: */ + /* 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 */ + /* 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 */ + /* 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 */ + /* 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 */ + /* 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: */ + /* 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: */ + /* 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: */ + /* 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: ignore for Bulk transfer */ + 0x00, /* bInterval: ignore for Bulk transfer */ - /*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: */ + /* 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: ignore for Bulk transfer */ -} ; + 0x00 /* bInterval: ignore for Bulk transfer */ +}; /* USB CDC device Configuration Descriptor */ -__ALIGN_BEGIN uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = +__ALIGN_BEGIN static uint8_t USBD_CDC_CfgFSDesc[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 */ + /* 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 interface */ - 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ - 0xC0, /* bmAttributes: self powered */ - 0x32, /* MaxPower 0 mA */ + 0x02, /* bNumInterfaces: 2 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ + 0xC0, /* bmAttributes: self powered */ + 0x32, /* MaxPower 0 mA */ /*---------------------------------------------------------------------------*/ - /*Interface Descriptor */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ + /* 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: */ + 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 */ + /* 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 */ + /* 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 */ + /* 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 */ + /* 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: */ + /* 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: */ + /* 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_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + /* Endpoint OUT Descriptor */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_OUT_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), - 0x00, /* bInterval: ignore for Bulk transfer */ + 0x00, /* bInterval: ignore for Bulk transfer */ - /*Endpoint IN Descriptor*/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_IN_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + /* Endpoint IN Descriptor */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_IN_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), - 0x00 /* bInterval: ignore for Bulk transfer */ -} ; + 0x00 /* bInterval: ignore for Bulk transfer */ +}; -__ALIGN_BEGIN uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = +__ALIGN_BEGIN static uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = { - 0x09, /* bLength: Configuation Descriptor size */ + 0x09, /* bLength: Configuation Descriptor size */ USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, USB_CDC_CONFIG_DESC_SIZ, 0x00, - 0x02, /* bNumInterfaces: 2 interfaces */ - 0x01, /* bConfigurationValue: */ - 0x04, /* iConfiguration: */ - 0xC0, /* bmAttributes: */ - 0x32, /* MaxPower 100 mA */ + 0x02, /* bNumInterfaces: 2 interfaces */ + 0x01, /* bConfigurationValue: */ + 0x04, /* iConfiguration: */ + 0xC0, /* bmAttributes: */ + 0x32, /* MaxPower 100 mA */ /*Interface Descriptor */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ + 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: */ + 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 */ + /* 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 */ + 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 */ + 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 */ + 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: */ + 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: */ + 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: */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_OUT_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + 0x40, /* wMaxPacketSize: */ 0x00, - 0x00, /* bInterval: ignore for Bulk transfer */ + 0x00, /* bInterval: ignore for Bulk transfer */ /*Endpoint IN Descriptor*/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_IN_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - 0x40, /* wMaxPacketSize: */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_IN_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + 0x40, /* wMaxPacketSize: */ 0x00, - 0x00 /* bInterval */ + 0x00 /* bInterval */ }; /** @@ -468,75 +453,81 @@ __ALIGN_BEGIN uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIG * @param cfgidx: Configuration index * @retval status */ -static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { - uint8_t ret = 0U; - USBD_CDC_HandleTypeDef *hcdc; + UNUSED(cfgidx); + USBD_CDC_HandleTypeDef *hcdc; + + hcdc = USBD_malloc(sizeof(USBD_CDC_HandleTypeDef)); + + if (hcdc == NULL) + { + pdev->pClassData = NULL; + return (uint8_t)USBD_EMEM; + } + + pdev->pClassData = (void *)hcdc; if (pdev->dev_speed == USBD_SPEED_HIGH) { /* Open EP IN */ - USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK, - CDC_DATA_HS_IN_PACKET_SIZE); + (void)USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK, + CDC_DATA_HS_IN_PACKET_SIZE); - pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U; + pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U; - /* Open EP OUT */ - USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK, - CDC_DATA_HS_OUT_PACKET_SIZE); + /* Open EP OUT */ + (void)USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK, + CDC_DATA_HS_OUT_PACKET_SIZE); - pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U; + pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U; + /* Set bInterval for CDC CMD Endpoint */ + pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = CDC_HS_BINTERVAL; } else { /* Open EP IN */ - USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK, - CDC_DATA_FS_IN_PACKET_SIZE); + (void)USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK, + CDC_DATA_FS_IN_PACKET_SIZE); - pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U; + pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U; - /* Open EP OUT */ - USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK, - CDC_DATA_FS_OUT_PACKET_SIZE); + /* Open EP OUT */ + (void)USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK, + CDC_DATA_FS_OUT_PACKET_SIZE); - pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U; + pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U; + + /* Set bInterval for CMD Endpoint */ + pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = CDC_FS_BINTERVAL; } + /* Open Command IN EP */ - USBD_LL_OpenEP(pdev, CDC_CMD_EP, USBD_EP_TYPE_INTR, CDC_CMD_PACKET_SIZE); + (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; - pdev->pClassData = USBD_malloc(sizeof(USBD_CDC_HandleTypeDef)); + /* Init physical Interface components */ + ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init(); - if (pdev->pClassData == NULL) + /* Init Xfer states */ + hcdc->TxState = 0U; + hcdc->RxState = 0U; + + if (pdev->dev_speed == USBD_SPEED_HIGH) { - ret = 1U; + /* Prepare Out endpoint to receive next packet */ + (void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer, + CDC_DATA_HS_OUT_PACKET_SIZE); } else { - hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData; - - /* Init physical Interface components */ - ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init(); - - /* Init Xfer states */ - hcdc->TxState = 0U; - hcdc->RxState = 0U; - - if (pdev->dev_speed == USBD_SPEED_HIGH) - { - /* Prepare Out endpoint to receive next packet */ - USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer, - CDC_DATA_HS_OUT_PACKET_SIZE); - } - else - { - /* Prepare Out endpoint to receive next packet */ - USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer, - CDC_DATA_FS_OUT_PACKET_SIZE); - } + /* Prepare Out endpoint to receive next packet */ + (void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer, + CDC_DATA_FS_OUT_PACKET_SIZE); } - return ret; + + return (uint8_t)USBD_OK; } /** @@ -546,27 +537,29 @@ static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) * @param cfgidx: Configuration index * @retval status */ -static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { + UNUSED(cfgidx); uint8_t ret = 0U; /* Close EP IN */ - USBD_LL_CloseEP(pdev, CDC_IN_EP); + (void)USBD_LL_CloseEP(pdev, CDC_IN_EP); pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 0U; /* Close EP OUT */ - USBD_LL_CloseEP(pdev, CDC_OUT_EP); + (void)USBD_LL_CloseEP(pdev, CDC_OUT_EP); pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 0U; /* Close Command IN EP */ - USBD_LL_CloseEP(pdev, CDC_CMD_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; /* DeInit physical Interface components */ if (pdev->pClassData != NULL) { ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->DeInit(); - USBD_free(pdev->pClassData); + (void)USBD_free(pdev->pClassData); pdev->pClassData = NULL; } @@ -580,91 +573,94 @@ static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) * @param req: usb requests * @retval status */ -static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req) +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->pClassData; uint8_t ifalt = 0U; uint16_t status_info = 0U; - uint8_t ret = USBD_OK; + USBD_StatusTypeDef ret = USBD_OK; switch (req->bmRequest & USB_REQ_TYPE_MASK) { - case USB_REQ_TYPE_CLASS : - if (req->wLength) + case USB_REQ_TYPE_CLASS: + if (req->wLength != 0U) + { + if ((req->bmRequest & 0x80U) != 0U) { - if (req->bmRequest & 0x80U) - { - ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, - (uint8_t *)(void *)hcdc->data, - req->wLength); + ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, + (uint8_t *)hcdc->data, + req->wLength); - USBD_CtlSendData(pdev, (uint8_t *)(void *)hcdc->data, req->wLength); - } - else - { - hcdc->CmdOpCode = req->bRequest; - hcdc->CmdLength = (uint8_t)req->wLength; - - USBD_CtlPrepareRx(pdev, (uint8_t *)(void *)hcdc->data, req->wLength); - } + (void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data, req->wLength); } else { - ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, - (uint8_t *)(void *)req, 0U); + hcdc->CmdOpCode = req->bRequest; + hcdc->CmdLength = (uint8_t)req->wLength; + + (void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data, req->wLength); + } + } + else + { + ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, + (uint8_t *)req, 0U); + } + break; + + 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_TYPE_STANDARD: - switch (req->bRequest) + case USB_REQ_GET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) { - case USB_REQ_GET_STATUS: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - USBD_CtlSendData(pdev, (uint8_t *)(void *)&status_info, 2U); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; - - case USB_REQ_GET_INTERFACE: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - 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; - - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; + (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 ret; + return (uint8_t)ret; } /** @@ -674,31 +670,34 @@ static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, * @param epnum: endpoint number * @retval status */ -static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) +static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) { - USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; + USBD_CDC_HandleTypeDef *hcdc; PCD_HandleTypeDef *hpcd = pdev->pData; - if (pdev->pClassData != NULL) + if (pdev->pClassData == NULL) { - if ((pdev->ep_in[epnum].total_length > 0U) && ((pdev->ep_in[epnum].total_length % hpcd->IN_ep[epnum].maxpacket) == 0U)) - { - /* Update the packet total length */ - pdev->ep_in[epnum].total_length = 0U; + return (uint8_t)USBD_FAIL; + } - /* Send ZLP */ - USBD_LL_Transmit(pdev, epnum, NULL, 0U); - } - else - { - hcdc->TxState = 0U; - } - return USBD_OK; + hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; + + if ((pdev->ep_in[epnum].total_length > 0U) && + ((pdev->ep_in[epnum].total_length % hpcd->IN_ep[epnum].maxpacket) == 0U)) + { + /* Update the packet total length */ + pdev->ep_in[epnum].total_length = 0U; + + /* Send ZLP */ + (void)USBD_LL_Transmit(pdev, epnum, NULL, 0U); } else { - return USBD_FAIL; + hcdc->TxState = 0U; + ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum); } + + return (uint8_t)USBD_OK; } /** @@ -708,25 +707,24 @@ static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) * @param epnum: endpoint number * @retval status */ -static uint8_t USBD_CDC_DataOut(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->pClassData; + + if (pdev->pClassData == NULL) + { + return (uint8_t)USBD_FAIL; + } /* Get the received data length */ hcdc->RxLength = USBD_LL_GetRxDataSize(pdev, epnum); /* USB data will be immediately processed, this allow next USB traffic being NAKed till the end of the application Xfer */ - if (pdev->pClassData != NULL) - { - ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength); - return USBD_OK; - } - else - { - return USBD_FAIL; - } + ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength); + + return (uint8_t)USBD_OK; } /** @@ -735,19 +733,20 @@ static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) * @param pdev: device instance * @retval status */ -static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev) +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->pClassData; if ((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFFU)) { ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode, - (uint8_t *)(void *)hcdc->data, + (uint8_t *)hcdc->data, (uint16_t)hcdc->CmdLength); hcdc->CmdOpCode = 0xFFU; } - return USBD_OK; + + return (uint8_t)USBD_OK; } /** @@ -757,9 +756,10 @@ static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev) * @param length : pointer data length * @retval pointer to descriptor buffer */ -static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length) +static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length) { - *length = sizeof(USBD_CDC_CfgFSDesc); + *length = (uint16_t)sizeof(USBD_CDC_CfgFSDesc); + return USBD_CDC_CfgFSDesc; } @@ -770,9 +770,10 @@ static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length) * @param length : pointer data length * @retval pointer to descriptor buffer */ -static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length) +static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length) { - *length = sizeof(USBD_CDC_CfgHSDesc); + *length = (uint16_t)sizeof(USBD_CDC_CfgHSDesc); + return USBD_CDC_CfgHSDesc; } @@ -783,9 +784,10 @@ static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length) * @param length : pointer data length * @retval pointer to descriptor buffer */ -static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length) +static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length) { - *length = sizeof(USBD_CDC_OtherSpeedCfgDesc); + *length = (uint16_t)sizeof(USBD_CDC_OtherSpeedCfgDesc); + return USBD_CDC_OtherSpeedCfgDesc; } @@ -795,9 +797,10 @@ static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length) * @param length : pointer data length * @retval pointer to descriptor buffer */ -uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length) +uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length) { - *length = sizeof(USBD_CDC_DeviceQualifierDesc); + *length = (uint16_t)sizeof(USBD_CDC_DeviceQualifierDesc); + return USBD_CDC_DeviceQualifierDesc; } @@ -807,18 +810,17 @@ uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length) * @param fops: CD Interface callback * @retval status */ -uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, - USBD_CDC_ItfTypeDef *fops) +uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, + USBD_CDC_ItfTypeDef *fops) { - uint8_t ret = USBD_FAIL; - - if (fops != NULL) + if (fops == NULL) { - pdev->pUserData = fops; - ret = USBD_OK; + return (uint8_t)USBD_FAIL; } - return ret; + pdev->pUserData = fops; + + return (uint8_t)USBD_OK; } /** @@ -827,16 +829,15 @@ uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, * @param pbuff: Tx Buffer * @retval status */ -uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, - uint8_t *pbuff, - uint16_t length) +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->pClassData; hcdc->TxBuffer = pbuff; hcdc->TxLength = length; - return USBD_OK; + return (uint8_t)USBD_OK; } @@ -846,14 +847,13 @@ uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, * @param pbuff: Rx Buffer * @retval status */ -uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, - uint8_t *pbuff) +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->pClassData; hcdc->RxBuffer = pbuff; - return USBD_OK; + return (uint8_t)USBD_OK; } /** @@ -862,35 +862,31 @@ uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, * @param pdev: device instance * @retval status */ -uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev) +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->pClassData; + USBD_StatusTypeDef ret = USBD_BUSY; - if (pdev->pClassData != NULL) + if (pdev->pClassData == NULL) { - if (hcdc->TxState == 0U) - { - /* Tx Transfer in progress */ - hcdc->TxState = 1U; - - /* Update the packet total length */ - pdev->ep_in[CDC_IN_EP & 0xFU].total_length = hcdc->TxLength; - - /* Transmit next packet */ - USBD_LL_Transmit(pdev, CDC_IN_EP, hcdc->TxBuffer, - (uint16_t)hcdc->TxLength); - - return USBD_OK; - } - else - { - return USBD_BUSY; - } + return (uint8_t)USBD_FAIL; } - else + + if (hcdc->TxState == 0U) { - return USBD_FAIL; + /* Tx Transfer in progress */ + hcdc->TxState = 1U; + + /* Update the packet total length */ + pdev->ep_in[CDC_IN_EP & 0xFU].total_length = hcdc->TxLength; + + /* Transmit next packet */ + (void)USBD_LL_Transmit(pdev, CDC_IN_EP, hcdc->TxBuffer, hcdc->TxLength); + + ret = USBD_OK; } + + return (uint8_t)ret; } @@ -900,35 +896,29 @@ uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev) * @param pdev: device instance * @retval status */ -uint8_t USBD_CDC_ReceivePacket(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->pClassData; - /* Suspend or Resume USB Out process */ - if (pdev->pClassData != NULL) + if (pdev->pClassData == NULL) { - if (pdev->dev_speed == USBD_SPEED_HIGH) - { - /* Prepare Out endpoint to receive next packet */ - USBD_LL_PrepareReceive(pdev, - CDC_OUT_EP, - hcdc->RxBuffer, - CDC_DATA_HS_OUT_PACKET_SIZE); - } - else - { - /* Prepare Out endpoint to receive next packet */ - USBD_LL_PrepareReceive(pdev, - CDC_OUT_EP, - hcdc->RxBuffer, - CDC_DATA_FS_OUT_PACKET_SIZE); - } - return USBD_OK; + 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, + CDC_DATA_HS_OUT_PACKET_SIZE); } else { - return USBD_FAIL; + /* Prepare Out endpoint to receive next packet */ + (void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer, + CDC_DATA_FS_OUT_PACKET_SIZE); } + + return (uint8_t)USBD_OK; } /** * @} diff --git a/Class/CDC/Src/usbd_cdc_if_template.c b/Class/CDC/Src/usbd_cdc_if_template.c index 9ebf8fb..60748c3 100644 --- a/Class/CDC/Src/usbd_cdc_if_template.c +++ b/Class/CDC/Src/usbd_cdc_if_template.c @@ -68,13 +68,15 @@ static int8_t TEMPLATE_Init(void); static int8_t TEMPLATE_DeInit(void); static int8_t TEMPLATE_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length); static int8_t TEMPLATE_Receive(uint8_t *pbuf, uint32_t *Len); +static int8_t TEMPLATE_TransmitCplt(uint8_t *pbuf, uint32_t *Len, uint8_t epnum); USBD_CDC_ItfTypeDef USBD_CDC_Template_fops = { TEMPLATE_Init, TEMPLATE_DeInit, TEMPLATE_Control, - TEMPLATE_Receive + TEMPLATE_Receive, + TEMPLATE_TransmitCplt }; USBD_CDC_LineCodingTypeDef linecoding = @@ -192,7 +194,7 @@ static int8_t TEMPLATE_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length) * * @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 CDC interface (ie. using DMA controller) * it will result in receiving more data while previous ones are still * not sent. @@ -203,6 +205,29 @@ static int8_t TEMPLATE_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length) */ static int8_t TEMPLATE_Receive(uint8_t *Buf, uint32_t *Len) { + UNUSED(Buf); + UNUSED(Len); + + return (0); +} + +/** + * @brief TEMPLATE_TransmitCplt + * Data transmited callback + * + * @note + * This function is IN transfer complete callback used to inform user that + * the submitted Data is successfully sent over USB. + * + * @param Buf: Buffer of data to be received + * @param Len: Number of data received (in bytes) + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t TEMPLATE_TransmitCplt(uint8_t *Buf, uint32_t *Len, uint8_t epnum) +{ + UNUSED(Buf); + UNUSED(Len); + UNUSED(epnum); return (0); } diff --git a/Class/CDC_ECM/Inc/usbd_cdc_ecm.h b/Class/CDC_ECM/Inc/usbd_cdc_ecm.h new file mode 100644 index 0000000..f4bef2c --- /dev/null +++ b/Class/CDC_ECM/Inc/usbd_cdc_ecm.h @@ -0,0 +1,255 @@ +/** + ****************************************************************************** + * @file usbd_cdc_ecm.h + * @author MCD Application Team + * @brief header file for the usbd_cdc_ecm.c file. + ****************************************************************************** + * @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 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_CDC_ECM_H +#define __USB_CDC_ECM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup usbd_cdc_ecm + * @brief This file is the Header file for usbd_cdc_ecm.c + * @{ + */ + + +/** @defgroup usbd_cdc_ecm_Exported_Defines + * @{ + */ +/* Comment this define in order to disable the CDC ECM Notification pipe */ + + +#define CDC_ECM_IN_EP 0x81U /* EP1 for data IN */ +#define CDC_ECM_OUT_EP 0x01U /* EP1 for data OUT */ +#define CDC_ECM_CMD_EP 0x82U /* EP2 for CDC ECM commands */ + +#ifndef CDC_ECM_CMD_ITF_NBR +#define CDC_ECM_CMD_ITF_NBR 0x00U /* Command Interface Number 0 */ +#endif /* CDC_ECM_CMD_ITF_NBR */ + +#ifndef CDC_ECM_COM_ITF_NBR +#define CDC_ECM_COM_ITF_NBR 0x01U /* Communication Interface Number 0 */ +#endif /* CDC_ECM_CMD_ITF_NBR */ + +#ifndef CDC_ECM_HS_BINTERVAL +#define CDC_ECM_HS_BINTERVAL 0x10U +#endif /* CDC_ECM_HS_BINTERVAL */ + +#ifndef CDC_ECM_FS_BINTERVAL +#define CDC_ECM_FS_BINTERVAL 0x10U +#endif /* CDC_ECM_FS_BINTERVAL */ + +#ifndef USBD_SUPPORT_USER_STRING_DESC +#define USBD_SUPPORT_USER_STRING_DESC 1U +#endif /* USBD_SUPPORT_USER_STRING_DESC */ + +/* CDC_ECM Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */ +#define CDC_ECM_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */ +#define CDC_ECM_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */ +#define CDC_ECM_CMD_PACKET_SIZE 16U /* Control Endpoint Packet size */ + +#define CDC_ECM_CONFIG_DESC_SIZ 79U + +#define CDC_ECM_DATA_HS_IN_PACKET_SIZE CDC_ECM_DATA_HS_MAX_PACKET_SIZE +#define CDC_ECM_DATA_HS_OUT_PACKET_SIZE CDC_ECM_DATA_HS_MAX_PACKET_SIZE + +#define CDC_ECM_DATA_FS_IN_PACKET_SIZE CDC_ECM_DATA_FS_MAX_PACKET_SIZE +#define CDC_ECM_DATA_FS_OUT_PACKET_SIZE CDC_ECM_DATA_FS_MAX_PACKET_SIZE + +/*---------------------------------------------------------------------*/ +/* CDC_ECM definitions */ +/*---------------------------------------------------------------------*/ +#define CDC_ECM_SEND_ENCAPSULATED_COMMAND 0x00U +#define CDC_ECM_GET_ENCAPSULATED_RESPONSE 0x01U +#define CDC_ECM_SET_ETH_MULTICAST_FILTERS 0x40U +#define CDC_ECM_SET_ETH_PWRM_PATTERN_FILTER 0x41U +#define CDC_ECM_GET_ETH_PWRM_PATTERN_FILTER 0x42U +#define CDC_ECM_SET_ETH_PACKET_FILTER 0x43U +#define CDC_ECM_GET_ETH_STATISTIC 0x44U + +#define CDC_ECM_NET_DISCONNECTED 0x00U +#define CDC_ECM_NET_CONNECTED 0x01U + + +/* Ethernet statistics definitions */ +#define CDC_ECM_XMIT_OK_VAL CDC_ECM_ETH_STATS_VAL_ENABLED +#define CDC_ECM_XMIT_OK 0x01U +#define CDC_ECM_RVC_OK 0x02U +#define CDC_ECM_XMIT_ERROR 0x04U +#define CDC_ECM_RCV_ERROR 0x08U +#define CDC_ECM_RCV_NO_BUFFER 0x10U +#define CDC_ECM_DIRECTED_BYTES_XMIT 0x20U +#define CDC_ECM_DIRECTED_FRAMES_XMIT 0x40U +#define CDC_ECM_MULTICAST_BYTES_XMIT 0x80U + +#define CDC_ECM_MULTICAST_FRAMES_XMIT 0x01U +#define CDC_ECM_BROADCAST_BYTES_XMIT 0x02U +#define CDC_ECM_BROADCAST_FRAMES_XMIT 0x04U +#define CDC_ECM_DIRECTED_BYTES_RCV 0x08U +#define CDC_ECM_DIRECTED_FRAMES_RCV 0x10U +#define CDC_ECM_MULTICAST_BYTES_RCV 0x20U +#define CDC_ECM_MULTICAST_FRAMES_RCV 0x40U +#define CDC_ECM_BROADCAST_BYTES_RCV 0x80U + +#define CDC_ECM_BROADCAST_FRAMES_RCV 0x01U +#define CDC_ECM_RCV_CRC_ERROR 0x02U +#define CDC_ECM_TRANSMIT_QUEUE_LENGTH 0x04U +#define CDC_ECM_RCV_ERROR_ALIGNMENT 0x08U +#define CDC_ECM_XMIT_ONE_COLLISION 0x10U +#define CDC_ECM_XMIT_MORE_COLLISIONS 0x20U +#define CDC_ECM_XMIT_DEFERRED 0x40U +#define CDC_ECM_XMIT_MAX_COLLISIONS 0x80U + +#define CDC_ECM_RCV_OVERRUN 0x40U +#define CDC_ECM_XMIT_UNDERRUN 0x40U +#define CDC_ECM_XMIT_HEARTBEAT_FAILURE 0x40U +#define CDC_ECM_XMIT_TIMES_CRS_LOST 0x40U +#define CDC_ECM_XMIT_LATE_COLLISIONS 0x40U + +#define CDC_ECM_ETH_STATS_RESERVED 0xE0U +#define CDC_ECM_BMREQUEST_TYPE_ECM 0xA1U + +/* MAC String index */ +#define CDC_ECM_MAC_STRING_INDEX 6U + +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +typedef struct +{ + int8_t (* Init)(void); + int8_t (* DeInit)(void); + int8_t (* Control)(uint8_t cmd, uint8_t *pbuf, uint16_t length); + int8_t (* Receive)(uint8_t *Buf, uint32_t *Len); + int8_t (* TransmitCplt)(uint8_t *Buf, uint32_t *Len, uint8_t epnum); + int8_t (* Process)(USBD_HandleTypeDef *pdev); + const uint8_t *pStrDesc; +} USBD_CDC_ECM_ItfTypeDef; + +typedef struct +{ + uint8_t bmRequest; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; + uint8_t data[8]; +} USBD_CDC_ECM_NotifTypeDef; + +typedef struct +{ + uint32_t data[2000 / 4]; /* Force 32bits alignment */ + uint8_t CmdOpCode; + uint8_t CmdLength; + uint8_t Reserved1; /* Reserved Byte to force 4 bytes alignment of following fields */ + uint8_t Reserved2; /* Reserved Byte to force 4 bytes alignment of following fields */ + uint8_t *RxBuffer; + uint8_t *TxBuffer; + uint32_t RxLength; + uint32_t TxLength; + + __IO uint32_t TxState; + __IO uint32_t RxState; + + __IO uint32_t MaxPcktLen; + __IO uint32_t LinkStatus; + __IO uint32_t NotificationStatus; + 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 + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ + +extern USBD_ClassTypeDef USBD_CDC_ECM; +#define USBD_CDC_ECM_CLASS &USBD_CDC_ECM +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ +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); + +uint8_t USBD_CDC_ECM_TransmitPacket(USBD_HandleTypeDef *pdev); + +uint8_t USBD_CDC_ECM_SendNotification(USBD_HandleTypeDef *pdev, + USBD_CDC_ECM_NotifCodeTypeDef Notif, + uint16_t bVal, uint8_t *pData); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_CDC_ECM_H */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Class/CDC_ECM/Inc/usbd_cdc_ecm_if_template.h b/Class/CDC_ECM/Inc/usbd_cdc_ecm_if_template.h new file mode 100644 index 0000000..7ce8714 --- /dev/null +++ b/Class/CDC_ECM/Inc/usbd_cdc_ecm_if_template.h @@ -0,0 +1,82 @@ +/** + ****************************************************************************** + * @file Inc/usbd_cdc_ecm_if_template.h + * @author MCD Application Team + * @brief Header for usbd_cdc_ecm_if_template.c file. + ****************************************************************************** + * @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 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_CDC_ECM_IF_H +#define __USBD_CDC_ECM_IF_H + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_cdc_ecm.h" + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* Ensure this MAC address value is same as MAC_ADDRx declared in STM32xxx_conf.h */ +#define CDC_ECM_MAC_STR_DESC (uint8_t *)"000202030000" +#define CDC_ECM_MAC_ADDR0 0x00U /* 01 */ +#define CDC_ECM_MAC_ADDR1 0x02U /* 02 */ +#define CDC_ECM_MAC_ADDR2 0x02U /* 03 */ +#define CDC_ECM_MAC_ADDR3 0x03U /* 00 */ +#define CDC_ECM_MAC_ADDR4 0x00U /* 00 */ +#define CDC_ECM_MAC_ADDR5 0x00U /* 00 */ + +/* Max Number of Trials waiting for Tx ready */ +#define CDC_ECM_MAX_TX_WAIT_TRIALS 1000000U + +#define CDC_ECM_ETH_STATS_BYTE0 0U +/*(uint8_t)(CDC_ECM_XMIT_OK_VAL | CDC_ECM_RVC_OK_VAL | CDC_ECM_XMIT_ERROR_VAL | \ + CDC_ECM_RCV_ERROR_VAL | CDC_ECM_RCV_NO_BUFFER_VAL | CDC_ECM_DIRECTED_BYTES_XMIT_VAL | \ + CDC_ECM_DIRECTED_FRAMES_XMIT_VAL | CDC_ECM_MULTICAST_BYTES_XMIT_VAL) */ + +#define CDC_ECM_ETH_STATS_BYTE1 0U +/*(uint8_t)(CDC_ECM_MULTICAST_FRAMES_XMIT_VAL | CDC_ECM_BROADCAST_BYTES_XMIT_VAL | \ + CDC_ECM_BROADCAST_FRAMES_XMIT_VAL | CDC_ECM_DIRECTED_BYTES_RCV_VAL | \ + CDC_ECM_DIRECTED_FRAMES_RCV_VAL | CDC_ECM_MULTICAST_BYTES_RCV_VAL | \ + CDC_ECM_MULTICAST_FRAMES_RCV_VAL | CDC_ECM_BROADCAST_BYTES_RCV_VAL) */ + +#define CDC_ECM_ETH_STATS_BYTE2 0U +/*(uint8_t)(CDC_ECM_BROADCAST_FRAMES_RCV_VAL | CDC_ECM_RCV_CRC_ERROR_VAL | \ + CDC_ECM_TRANSMIT_QUEUE_LENGTH_VAL | CDC_ECM_RCV_ERROR_ALIGNMENT_VAL | \ + CDC_ECM_XMIT_ONE_COLLISION_VAL | CDC_ECM_XMIT_MORE_COLLISIONS_VAL | \ + CDC_ECM_XMIT_DEFERRED_VAL | CDC_ECM_XMIT_MAX_COLLISIONS_VAL) */ + +#define CDC_ECM_ETH_STATS_BYTE3 0U +/*(uint8_t)(CDC_ECM_RCV_OVERRUN_VAL | CDC_ECM_XMIT_UNDERRUN_VAL | CDC_ECM_XMIT_HEARTBEAT_FAILURE_VAL | \ + CDC_ECM_XMIT_TIMES_CRS_LOST_VAL | CDC_ECM_XMIT_LATE_COLLISIONS_VAL | CDC_ECM_ETH_STATS_RESERVED) */ + +/* Ethernet Maximum Segment size, typically 1514 bytes */ +#define CDC_ECM_ETH_MAX_SEGSZE 1514U + +/* Number of Ethernet multicast filters */ +#define CDC_ECM_ETH_NBR_MACFILTERS 0U + +/* Number of wakeup power filters */ +#define CDC_ECM_ETH_NBR_PWRFILTERS 0U + + +#define CDC_ECM_CONNECT_SPEED_UPSTREAM 0x004C4B40U /* 5Mbps */ +#define CDC_ECM_CONNECT_SPEED_DOWNSTREAM 0x004C4B40U /* 5Mbps */ + +extern USBD_CDC_ECM_ItfTypeDef USBD_CDC_ECM_fops; + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +#endif /* __USBD_CDC_ECM_IF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Class/CDC_ECM/Src/usbd_cdc_ecm.c b/Class/CDC_ECM/Src/usbd_cdc_ecm.c new file mode 100644 index 0000000..edc5d22 --- /dev/null +++ b/Class/CDC_ECM/Src/usbd_cdc_ecm.c @@ -0,0 +1,1091 @@ +/** + ****************************************************************************** + * @file usbd_cdc_ecm.c + * @author MCD Application Team + * @brief This file provides the high layer firmware functions to manage the + * following functionalities of the USB CDC_ECM Class: + * - Initialization and Configuration of high and low layer + * - Enumeration as CDC_ECM Device (and enumeration for each implemented memory interface) + * - OUT/IN data transfer + * - Command IN transfer (class requests management) + * - Error management + * + ****************************************************************************** + * @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 + * + ****************************************************************************** + */ + +/* BSPDependencies +- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c" +- "stm32xxxxx_{eval}{discovery}_io.c" +EndBSPDependencies */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_cdc_ecm.h" +#include "usbd_ctlreq.h" + +#ifndef __USBD_CDC_ECM_IF_H +#include "usbd_cdc_ecm_if_template.h" +#endif + + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_CDC_ECM + * @brief usbd core module + * @{ + */ + +/** @defgroup USBD_CDC_ECM_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_CDC_ECM_Private_Defines + * @{ + */ +/** + * @} + */ + +/** @defgroup USBD_CDC_ECM_Private_Macros + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_CDC_ECM_Private_FunctionPrototypes + * @{ + */ + +static uint8_t USBD_CDC_ECM_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +static uint8_t USBD_CDC_ECM_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +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); +static uint8_t USBD_CDC_ECM_EP0_RxReady(USBD_HandleTypeDef *pdev); +static uint8_t USBD_CDC_ECM_Setup(USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req); + +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); + +#if (USBD_SUPPORT_USER_STRING_DESC == 1U) +static uint8_t *USBD_CDC_ECM_USRStringDescriptor(USBD_HandleTypeDef *pdev, + uint8_t index, uint16_t *length); +#endif + +uint8_t *USBD_CDC_ECM_GetDeviceQualifierDescriptor(uint16_t *length); + +/* USB Standard Device Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_CDC_ECM_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, +}; + +static uint32_t ConnSpeedTab[2] = {CDC_ECM_CONNECT_SPEED_UPSTREAM, + CDC_ECM_CONNECT_SPEED_DOWNSTREAM}; + +/** + * @} + */ + +/** @defgroup USBD_CDC_ECM_Private_Variables + * @{ + */ + + +/* CDC_ECM interface class callbacks structure */ +USBD_ClassTypeDef USBD_CDC_ECM = +{ + USBD_CDC_ECM_Init, + USBD_CDC_ECM_DeInit, + USBD_CDC_ECM_Setup, + NULL, /* EP0_TxSent, */ + USBD_CDC_ECM_EP0_RxReady, + USBD_CDC_ECM_DataIn, + USBD_CDC_ECM_DataOut, + NULL, + NULL, + NULL, + USBD_CDC_ECM_GetHSCfgDesc, + USBD_CDC_ECM_GetFSCfgDesc, + USBD_CDC_ECM_GetOtherSpeedCfgDesc, + USBD_CDC_ECM_GetDeviceQualifierDescriptor, +#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 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ + 0xC0, /* bmAttributes: self powered */ + 0x32, /* MaxPower 0 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), + 0xFF, /* bInterval: ignore for Bulk transfer */ + + /* 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), + 0xFF /* bInterval: ignore for Bulk transfer */ +}; + + +/* USB CDC_ECM device Configuration Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_CDC_ECM_CfgFSDesc[] __ALIGN_END = +{ + /* Configuration Descriptor */ + 0x09, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + LOBYTE(CDC_ECM_CONFIG_DESC_SIZ), /* wTotalLength: Total size of the Config descriptor */ + HIBYTE(CDC_ECM_CONFIG_DESC_SIZ), + 0x02, /* bNumInterfaces: 2 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ + 0xC0, /* bmAttributes: self powered */ + 0x32, /* MaxPower 0 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.20 */ + 0x01, + + /* Union Functional Descriptor */ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x06, /* bDescriptorSubtype: Union functional descriptor */ + CDC_ECM_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */ + CDC_ECM_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */ + + /* 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 */ + + + /* 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: */ + CDC_ECM_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints: Two endpoints used */ + 0x0A, /* bInterfaceClass: CDC_ECM */ + 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_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_ECM_DATA_FS_MAX_PACKET_SIZE), + 0xFF, /* bInterval: ignore for Bulk transfer */ + + /* 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_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_ECM_DATA_FS_MAX_PACKET_SIZE), + 0xFF /* bInterval: ignore for Bulk transfer */ +} ; + +__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:no of returned bytes */ + HIBYTE(CDC_ECM_CONFIG_DESC_SIZ), + 0x02, /* bNumInterfaces: 2 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x04, /* iConfiguration: Index of string descriptor describing the configuration */ + 0xC0, /* bmAttributes: self powered */ + 0x32, /* MaxPower 0 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: */ + 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, + 0xFF, /* bInterval: ignore for Bulk transfer */ + + /* 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, + 0xFF /* bInterval: ignore for Bulk transfer */ +}; + +/** + * @} + */ + +/** @defgroup USBD_CDC_ECM_Private_Functions + * @{ + */ + +/** + * @brief USBD_CDC_ECM_Init + * Initialize the CDC_ECM interface + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_CDC_ECM_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + UNUSED(cfgidx); + + USBD_CDC_ECM_HandleTypeDef *hcdc; + + hcdc = USBD_malloc(sizeof(USBD_CDC_ECM_HandleTypeDef)); + + if (hcdc == NULL) + { + pdev->pClassData = NULL; + return (uint8_t)USBD_EMEM; + } + + pdev->pClassData = (void *)hcdc; + + if (pdev->dev_speed == USBD_SPEED_HIGH) + { + /* Open EP IN */ + (void)USBD_LL_OpenEP(pdev, CDC_ECM_IN_EP, USBD_EP_TYPE_BULK, + CDC_ECM_DATA_HS_IN_PACKET_SIZE); + + pdev->ep_in[CDC_ECM_IN_EP & 0xFU].is_used = 1U; + + /* Open EP OUT */ + (void)USBD_LL_OpenEP(pdev, CDC_ECM_OUT_EP, USBD_EP_TYPE_BULK, + CDC_ECM_DATA_HS_OUT_PACKET_SIZE); + + pdev->ep_out[CDC_ECM_OUT_EP & 0xFU].is_used = 1U; + + /* Set bInterval for CDC ECM CMD Endpoint */ + pdev->ep_in[CDC_ECM_CMD_EP & 0xFU].bInterval = CDC_ECM_HS_BINTERVAL; + } + else + { + /* Open EP IN */ + (void)USBD_LL_OpenEP(pdev, CDC_ECM_IN_EP, USBD_EP_TYPE_BULK, + CDC_ECM_DATA_FS_IN_PACKET_SIZE); + + pdev->ep_in[CDC_ECM_IN_EP & 0xFU].is_used = 1U; + + /* Open EP OUT */ + (void)USBD_LL_OpenEP(pdev, CDC_ECM_OUT_EP, USBD_EP_TYPE_BULK, + CDC_ECM_DATA_FS_OUT_PACKET_SIZE); + + pdev->ep_out[CDC_ECM_OUT_EP & 0xFU].is_used = 1U; + + /* Set bInterval for CDC ECM CMD Endpoint */ + pdev->ep_in[CDC_ECM_CMD_EP & 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; + + /* Init physical Interface components */ + ((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData)->Init(); + + /* Init Xfer states */ + hcdc->TxState = 0U; + hcdc->RxState = 0U; + hcdc->RxLength = 0U; + 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; + + /* Prepare Out endpoint to receive next packet */ + (void)USBD_LL_PrepareReceive(pdev, CDC_ECM_OUT_EP, hcdc->RxBuffer, hcdc->MaxPcktLen); + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_CDC_ECM_DeInit + * DeInitialize the CDC_ECM layer + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_CDC_ECM_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + UNUSED(cfgidx); + + /* Close EP IN */ + (void)USBD_LL_CloseEP(pdev, CDC_ECM_IN_EP); + pdev->ep_in[CDC_ECM_IN_EP & 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; + + /* 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; + + /* DeInit physical Interface components */ + if (pdev->pClassData != NULL) + { + ((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData)->DeInit(); + USBD_free(pdev->pClassData); + pdev->pClassData = NULL; + } + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_CDC_ECM_Setup + * Handle the CDC_ECM specific requests + * @param pdev: instance + * @param req: usb requests + * @retval status + */ +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_StatusTypeDef ret = USBD_OK; + uint8_t ifalt = 0U; + uint16_t status_info = 0U; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS : + if (req->wLength != 0U) + { + if ((req->bmRequest & 0x80U) != 0U) + { + EcmInterface->Control(req->bRequest, + (uint8_t *)hcdc->data, req->wLength); + + (void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data, req->wLength); + } + else + { + hcdc->CmdOpCode = req->bRequest; + hcdc->CmdLength = (uint8_t)req->wLength; + + (void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data, req->wLength); + } + } + else + { + EcmInterface->Control(req->bRequest, (uint8_t *)req, 0U); + } + break; + + 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_CDC_ECM_DataIn + * Data sent on non-control IN endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +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; + + if (pdev->pClassData == NULL) + { + return (uint8_t)USBD_FAIL; + } + + if (epnum == (CDC_ECM_IN_EP & 0x7FU)) + { + if ((pdev->ep_in[epnum].total_length > 0U) && + ((pdev->ep_in[epnum].total_length % hpcd->IN_ep[epnum].maxpacket) == 0U)) + { + /* Update the packet total length */ + pdev->ep_in[epnum].total_length = 0U; + + /* Send ZLP */ + (void)USBD_LL_Transmit(pdev, epnum, NULL, 0U); + } + else + { + hcdc->TxState = 0U; + ((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData)->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum); + } + } + else if (epnum == (CDC_ECM_CMD_EP & 0x7FU)) + { + if (hcdc->NotificationStatus != 0U) + { + (void)USBD_CDC_ECM_SendNotification(pdev, CONNECTION_SPEED_CHANGE, + 0U, (uint8_t *)ConnSpeedTab); + + hcdc->NotificationStatus = 0U; + } + } + else + { + return (uint8_t)USBD_FAIL; + } + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_CDC_ECM_DataOut + * Data received on non-control Out endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +static uint8_t USBD_CDC_ECM_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData; + uint32_t CurrPcktLen; + + if (pdev->pClassData == NULL) + { + return (uint8_t)USBD_FAIL; + } + + if (epnum == CDC_ECM_OUT_EP) + { + /* Get the received data length */ + CurrPcktLen = USBD_LL_GetRxDataSize(pdev, epnum); + + /* Increment the frame length */ + hcdc->RxLength += CurrPcktLen; + + /* If the buffer size is less than max packet size: it is the last packet in current frame */ + if ((CurrPcktLen < hcdc->MaxPcktLen) || (hcdc->RxLength >= CDC_ECM_ETH_MAX_SEGSZE)) + { + /* USB data will be immediately processed, this allow next USB traffic being + NACKed till the end of the application Xfer */ + + /* 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); + } + else + { + /* Prepare Out endpoint to receive next packet in current/new frame */ + (void)USBD_LL_PrepareReceive(pdev, CDC_ECM_OUT_EP, + (uint8_t *)(hcdc->RxBuffer + hcdc->RxLength), + hcdc->MaxPcktLen); + } + } + else + { + return (uint8_t)USBD_FAIL; + } + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_CDC_ECM_EP0_RxReady + * Handle EP0 Rx Ready event + * @param pdev: device instance + * @retval status + */ +static uint8_t USBD_CDC_ECM_EP0_RxReady(USBD_HandleTypeDef *pdev) +{ + USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData; + + if ((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFFU)) + { + ((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode, + (uint8_t *)hcdc->data, + (uint16_t)hcdc->CmdLength); + hcdc->CmdOpCode = 0xFFU; + + } + return (uint8_t)USBD_OK; +} + +/** + * @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); + + return USBD_CDC_ECM_CfgFSDesc; +} + +/** + * @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); + + return USBD_CDC_ECM_CfgHSDesc; +} + +/** + * @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); + + return USBD_CDC_ECM_OtherSpeedCfgDesc; +} + +/** + * @brief DeviceQualifierDescriptor + * return Device Qualifier descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +uint8_t *USBD_CDC_ECM_GetDeviceQualifierDescriptor(uint16_t *length) +{ + *length = (uint16_t)sizeof(USBD_CDC_ECM_DeviceQualifierDesc); + + return USBD_CDC_ECM_DeviceQualifierDesc; +} + +/** + * @brief USBD_CDC_ECM_RegisterInterface + * @param pdev: device instance + * @param fops: CD Interface callback + * @retval status + */ +uint8_t USBD_CDC_ECM_RegisterInterface(USBD_HandleTypeDef *pdev, + USBD_CDC_ECM_ItfTypeDef *fops) +{ + if (fops == NULL) + { + return (uint8_t)USBD_FAIL; + } + + pdev->pUserData = fops; + + return (uint8_t)USBD_OK; +} + + +/** + * @brief USBD_CDC_ECM_USRStringDescriptor + * Manages the transfer of user string descriptors. + * @param speed : current device speed + * @param index: descriptor index + * @param length : pointer data length + * @retval pointer to the descriptor table or NULL if the descriptor is not supported. + */ +#if (USBD_SUPPORT_USER_STRING_DESC == 1U) +static uint8_t *USBD_CDC_ECM_USRStringDescriptor(USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length) +{ + static uint8_t USBD_StrDesc[255]; + + /* 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); + return USBD_StrDesc; + } + /* Not supported Interface Descriptor index */ + else + { + return NULL; + } +} +#endif + +/** + * @brief USBD_CDC_ECM_SetTxBuffer + * @param pdev: device instance + * @param pbuff: Tx Buffer + * @retval status + */ +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; + + hcdc->TxBuffer = pbuff; + hcdc->TxLength = length; + + return (uint8_t)USBD_OK; +} + + +/** + * @brief USBD_CDC_ECM_SetRxBuffer + * @param pdev: device instance + * @param pbuff: Rx Buffer + * @retval status + */ +uint8_t USBD_CDC_ECM_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff) +{ + USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData; + + hcdc->RxBuffer = pbuff; + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_CDC_ECM_TransmitPacket + * Transmit packet on IN endpoint + * @param pdev: device instance + * @retval status + */ +uint8_t USBD_CDC_ECM_TransmitPacket(USBD_HandleTypeDef *pdev) +{ + USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData; + USBD_StatusTypeDef ret = USBD_BUSY; + + if (pdev->pClassData == NULL) + { + return (uint8_t)USBD_FAIL; + } + + if (hcdc->TxState == 0U) + { + /* Tx Transfer in progress */ + hcdc->TxState = 1U; + + /* Update the packet total length */ + pdev->ep_in[CDC_ECM_IN_EP & 0xFU].total_length = hcdc->TxLength; + + /* Transmit next packet */ + (void)USBD_LL_Transmit(pdev, CDC_ECM_IN_EP, hcdc->TxBuffer, hcdc->TxLength); + + ret = USBD_OK; + } + + return (uint8_t)ret; +} + + +/** + * @brief USBD_CDC_ECM_ReceivePacket + * prepare OUT Endpoint for reception + * @param pdev: device instance + * @retval status + */ +uint8_t USBD_CDC_ECM_ReceivePacket(USBD_HandleTypeDef *pdev) +{ + USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData; + + if (pdev->pClassData == 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); + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_CDC_ECM_SendNotification + * Transmit Notification packet on CMD IN interrupt endpoint + * @param pdev: device instance + * Notif: value of the notification type (from CDC_ECM_Notification_TypeDef enumeration list) + * bVal: value of the notification switch (ie. 0x00 or 0x01 for Network Connection notification) + * pData: pointer to data buffer (ie. upstream and downstream connection speed values) + * @retval status + */ +uint8_t USBD_CDC_ECM_SendNotification(USBD_HandleTypeDef *pdev, + USBD_CDC_ECM_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_StatusTypeDef ret = USBD_OK; + + /* Initialize the request fields */ + (hcdc->Req).bmRequest = CDC_ECM_BMREQUEST_TYPE_ECM; + (hcdc->Req).bRequest = (uint8_t)Notif; + + switch (Notif) + { + case NETWORK_CONNECTION: + (hcdc->Req).wValue = bVal; + (hcdc->Req).wIndex = CDC_ECM_CMD_ITF_NBR; + (hcdc->Req).wLength = 0U; + + for (Idx = 0U; Idx < 8U; Idx++) + { + (hcdc->Req).data[Idx] = 0U; + } + ReqSize = 8U; + break; + + case RESPONSE_AVAILABLE: + (hcdc->Req).wValue = 0U; + (hcdc->Req).wIndex = CDC_ECM_CMD_ITF_NBR; + (hcdc->Req).wLength = 0U; + for (Idx = 0U; Idx < 8U; Idx++) + { + (hcdc->Req).data[Idx] = 0U; + } + ReqSize = 8U; + break; + + case CONNECTION_SPEED_CHANGE: + (hcdc->Req).wValue = 0U; + (hcdc->Req).wIndex = CDC_ECM_CMD_ITF_NBR; + (hcdc->Req).wLength = 0x0008U; + ReqSize = 16U; + + /* Check pointer to data buffer */ + if (pData != NULL) + { + for (Idx = 0U; Idx < 8U; Idx++) + { + (hcdc->Req).data[Idx] = pData[Idx]; + } + } + break; + + default: + ret = USBD_FAIL; + break; + } + + /* Transmit notification packet */ + if (ReqSize != 0U) + { + (void)USBD_LL_Transmit(pdev, CDC_ECM_CMD_EP, (uint8_t *)&(hcdc->Req), ReqSize); + } + + return (uint8_t)ret; +} + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Class/CDC_ECM/Src/usbd_cdc_ecm_if_template.c b/Class/CDC_ECM/Src/usbd_cdc_ecm_if_template.c new file mode 100644 index 0000000..9b96de8 --- /dev/null +++ b/Class/CDC_ECM/Src/usbd_cdc_ecm_if_template.c @@ -0,0 +1,247 @@ +/** + ****************************************************************************** + * @file Src/usbd_cdc_ecm_if_template.c + * @author MCD Application Team + * @brief Source file for USBD CDC_ECM interface + ****************************************************************************** + * @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 ------------------------------------------------------------------*/ + +#include "main.h" +/* + + Include here LwIP files if used + +*/ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +#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 */ + +#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 */ + +static uint8_t CDC_ECMInitialized = 0U; + +/* USB handler declaration */ +extern USBD_HandleTypeDef USBD_Device; + +/* Private function prototypes -----------------------------------------------*/ +static int8_t CDC_ECM_Itf_Init(void); +static int8_t CDC_ECM_Itf_DeInit(void); +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 *pbuf, uint32_t *Len); +static int8_t CDC_ECM_Itf_TransmitCplt(uint8_t *pbuf, uint32_t *Len, uint8_t epnum); +static int8_t CDC_ECM_Itf_Process(USBD_HandleTypeDef *pdev); + +USBD_CDC_ECM_ItfTypeDef USBD_CDC_ECM_fops = +{ + CDC_ECM_Itf_Init, + CDC_ECM_Itf_DeInit, + CDC_ECM_Itf_Control, + CDC_ECM_Itf_Receive, + CDC_ECM_Itf_TransmitCplt, + CDC_ECM_Itf_Process, + (uint8_t *)CDC_ECM_MAC_STR_DESC, +}; + +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief CDC_ECM_Itf_Init + * Initializes the CDC_ECM media low layer + * @param None + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t CDC_ECM_Itf_Init(void) +{ + if (CDC_ECMInitialized == 0U) + { + /* + Initialize the TCP/IP stack here + */ + + CDC_ECMInitialized = 1U; + } + + /* Set Application Buffers */ + (void)USBD_CDC_ECM_SetTxBuffer(&USBD_Device, UserTxBuffer, 0U); + (void)USBD_CDC_ECM_SetRxBuffer(&USBD_Device, UserRxBuffer); + + return (0); +} + +/** + * @brief CDC_ECM_Itf_DeInit + * DeInitializes the CDC_ECM media low layer + * @param None + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t CDC_ECM_Itf_DeInit(void) +{ + USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *)(USBD_Device.pClassData); + + /* Notify application layer that link is down */ + hcdc_cdc_ecm->LinkStatus = 0U; + + return (0); +} + +/** + * @brief CDC_ECM_Itf_Control + * Manage the CDC_ECM 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 int8_t CDC_ECM_Itf_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length) +{ + USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *)(USBD_Device.pClassData); + + switch (cmd) + { + case CDC_ECM_SEND_ENCAPSULATED_COMMAND: + /* Add your code here */ + break; + + case CDC_ECM_GET_ENCAPSULATED_RESPONSE: + /* Add your code here */ + break; + + case CDC_ECM_SET_ETH_MULTICAST_FILTERS: + /* Add your code here */ + break; + + case CDC_ECM_SET_ETH_PWRM_PATTERN_FILTER: + /* Add your code here */ + break; + + case CDC_ECM_GET_ETH_PWRM_PATTERN_FILTER: + /* Add your code here */ + break; + + case CDC_ECM_SET_ETH_PACKET_FILTER: + /* Check if this is the first time we enter */ + if (hcdc_cdc_ecm->LinkStatus == 0U) + { + /* + Setup the Link up at TCP/IP level + */ + hcdc_cdc_ecm->LinkStatus = 1U; + + /* Modification for MacOS which doesn't send SetInterface before receiving INs */ + if (hcdc_cdc_ecm->NotificationStatus == 0U) + { + /* Send notification: NETWORK_CONNECTION Event */ + (void)USBD_CDC_ECM_SendNotification(&USBD_Device, NETWORK_CONNECTION, + CDC_ECM_NET_CONNECTED, NULL); + + /* Prepare for sending Connection Speed Change notification */ + hcdc_cdc_ecm->NotificationStatus = 1U; + } + } + /* Add your code here */ + break; + + case CDC_ECM_GET_ETH_STATISTIC: + /* Add your code here */ + break; + + default: + break; + } + UNUSED(length); + UNUSED(pbuf); + + return (0); +} + +/** + * @brief CDC_ECM_Itf_Receive + * Data received over USB OUT endpoint are sent over CDC_ECM interface + * through this function. + * @param Buf: Buffer of data to be transmitted + * @param Len: Number of data received (in bytes) + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t CDC_ECM_Itf_Receive(uint8_t *Buf, uint32_t *Len) +{ + /* Get the CDC_ECM handler pointer */ + USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *)(USBD_Device.pClassData); + + /* Call Eth buffer processing */ + hcdc_cdc_ecm->RxState = 1U; + + UNUSED(Len); + UNUSED(Buf); + + return (0); +} + +/** + * @brief CDC_ECM_Itf_TransmitCplt + * Data transmited callback + * + * @note + * This function is IN transfer complete callback used to inform user that + * the submitted Data is successfully sent over USB. + * + * @param Buf: Buffer of data to be received + * @param Len: Number of data received (in bytes) + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t CDC_ECM_Itf_TransmitCplt(uint8_t *Buf, uint32_t *Len, uint8_t epnum) +{ + UNUSED(Buf); + UNUSED(Len); + UNUSED(epnum); + + return (0); +} + +/** + * @brief CDC_ECM_Itf_Process + * Data received over USB OUT endpoint are sent over CDC_ECM interface + * through this function. + * @param pdef: pointer to the USB Device Handle + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t CDC_ECM_Itf_Process(USBD_HandleTypeDef *pdev) +{ + /* Get the CDC_ECM handler pointer */ + USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *)(pdev->pClassData); + + if ((hcdc_cdc_ecm != NULL) && (hcdc_cdc_ecm->LinkStatus != 0U)) + { + /* + Read a received packet from the Ethernet buffers and send it + to the lwIP for handling + Call here the TCP/IP background tasks. + */ + } + + return (0); +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h b/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h new file mode 100644 index 0000000..ef76894 --- /dev/null +++ b/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h @@ -0,0 +1,529 @@ +/** + ****************************************************************************** + * @file usbd_cdc_rndis.h + * @author MCD Application Team + * @brief header file for the usbd_cdc_rndis.c file. + ****************************************************************************** + * @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 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_CDC_RNDIS_H +#define __USB_CDC_RNDIS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup usbd_cdc_rndis + * @brief This file is the Header file for usbd_cdc_rndis.c + * @{ + */ + + +/** @defgroup usbd_cdc_rndis_Exported_Defines + * @{ + */ + +#define CDC_RNDIS_IN_EP 0x81U /* EP1 for data IN */ +#define CDC_RNDIS_OUT_EP 0x01U /* EP1 for data OUT */ +#define CDC_RNDIS_CMD_EP 0x82U /* EP2 for CDC_RNDIS commands */ + +#ifndef CDC_RNDIS_CMD_ITF_NBR +#define CDC_RNDIS_CMD_ITF_NBR 0x00U /* Command Interface Number 0 */ +#endif /* CDC_RNDIS_CMD_ITF_NBR */ + +#ifndef CDC_RNDIS_COM_ITF_NBR +#define CDC_RNDIS_COM_ITF_NBR 0x01U /* Communication Interface Number 0 */ +#endif /* CDC_RNDIS_CMD_ITF_NBR */ + +#ifndef CDC_RNDIS_HS_BINTERVAL +#define CDC_RNDIS_HS_BINTERVAL 0x10U +#endif /* CDC_RNDIS_HS_BINTERVAL */ + +#ifndef CDC_RNDIS_FS_BINTERVAL +#define CDC_RNDIS_FS_BINTERVAL 0x10U +#endif /* CDC_RNDIS_FS_BINTERVAL */ + + +/* CDC_RNDIS Endpoints parameters: you can fine tune these values + depending on the needed baudrates and performance. */ +#define CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */ +#define CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */ +#define CDC_RNDIS_CMD_PACKET_SIZE 16U /* Control Endpoint Packet size */ + +#define CDC_RNDIS_CONFIG_DESC_SIZ 75U +#define CDC_RNDIS_DATA_HS_IN_PACKET_SIZE CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE +#define CDC_RNDIS_DATA_HS_OUT_PACKET_SIZE CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE + +#define CDC_RNDIS_DATA_FS_IN_PACKET_SIZE CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE +#define CDC_RNDIS_DATA_FS_OUT_PACKET_SIZE CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE + +/*---------------------------------------------------------------------*/ +/* CDC_RNDIS definitions */ +/*---------------------------------------------------------------------*/ + +/** Implemented CDC_RNDIS Version Major */ +#define CDC_RNDIS_VERSION_MAJOR 0x01U + +/* Implemented CDC_RNDIS Version Minor */ +#define CDC_RNDIS_VERSION_MINOR 0x00U + +/* Maximum size in bytes of a CDC_RNDIS control message + which can be sent or received */ +#define CDC_RNDIS_MESSAGE_BUFFER_SIZE 128U + +/* Maximum size in bytes of an Ethernet frame + according to the Ethernet standard */ +#define CDC_RNDIS_ETH_FRAME_SIZE_MAX 1536U + +/* Maximum size allocated for buffer + inside Query messages structures */ +#define CDC_RNDIS_MAX_INFO_BUFF_SZ 200U +#define CDC_RNDIS_MAX_DATA_SZE 2000U + +/* Notification request value for a CDC_RNDIS + Response Available notification */ +#define CDC_RNDIS_NOTIFICATION_RESP_AVAILABLE 0x00000001UL + + +#define CDC_RNDIS_PACKET_MSG_ID 0x00000001UL +#define CDC_RNDIS_INITIALIZE_MSG_ID 0x00000002UL +#define CDC_RNDIS_HALT_MSG_ID 0x00000003UL +#define CDC_RNDIS_QUERY_MSG_ID 0x00000004UL +#define CDC_RNDIS_SET_MSG_ID 0x00000005UL +#define CDC_RNDIS_RESET_MSG_ID 0x00000006UL +#define CDC_RNDIS_INDICATE_STATUS_MSG_ID 0x00000007UL +#define CDC_RNDIS_KEEPALIVE_MSG_ID 0x00000008UL + +#define CDC_RNDIS_INITIALIZE_CMPLT_ID 0x80000002UL +#define CDC_RNDIS_QUERY_CMPLT_ID 0x80000004UL +#define CDC_RNDIS_SET_CMPLT_ID 0x80000005UL +#define CDC_RNDIS_RESET_CMPLT_ID 0x80000006UL +#define CDC_RNDIS_KEEPALIVE_CMPLT_ID 0x80000008UL + +#define CDC_RNDIS_STATUS_SUCCESS 0x00000000UL +#define CDC_RNDIS_STATUS_FAILURE 0xC0000001UL +#define CDC_RNDIS_STATUS_INVALID_DATA 0xC0010015UL +#define CDC_RNDIS_STATUS_NOT_SUPPORTED 0xC00000BBUL +#define CDC_RNDIS_STATUS_MEDIA_CONNECT 0x4001000BUL +#define CDC_RNDIS_STATUS_MEDIA_DISCONNECT 0x4001000CUL +/** Media state */ +#define CDC_RNDIS_MEDIA_STATE_CONNECTED 0x00000000UL +#define CDC_RNDIS_MEDIA_STATE_DISCONNECTED 0x00000001UL + +/** Media types */ +#define CDC_RNDIS_MEDIUM_802_3 0x00000000UL + +#define CDC_RNDIS_DF_CONNECTIONLESS 0x00000001UL +#define CDC_RNDIS_DF_CONNECTION_ORIENTED 0x00000002UL + +/** Hardware status of the underlying NIC */ +#define CDC_RNDIS_HW_STS_READY 0x00000000UL +#define CDC_RNDIS_HW_STS_INITIALIZING 0x00000001UL +#define CDC_RNDIS_HW_STS_RESET 0x00000002UL +#define CDC_RNDIS_HW_STS_CLOSING 0x00000003UL +#define CDC_RNDIS_HW_STS_NOT_READY 0x00000004UL + +/** Packet filter */ +#define CDC_RNDIS_PACKET_DIRECTED 0x00000001UL +#define CDC_RNDIS_PACKET_MULTICAST 0x00000002UL +#define CDC_RNDIS_PACKET_ALL_MULTICAST 0x00000004UL +#define CDC_RNDIS_PACKET_BROADCAST 0x00000008UL +#define CDC_RNDIS_PACKET_SOURCE_ROUTING 0x00000010UL +#define CDC_RNDIS_PACKET_PROMISCUOUS 0x00000020UL +#define CDC_RNDIS_PACKET_SMT 0x00000040UL +#define CDC_RNDIS_PACKET_ALL_LOCAL 0x00000080UL +#define CDC_RNDIS_PACKET_GROUP 0x00001000UL +#define CDC_RNDIS_PACKET_ALL_FUNCTIONAL 0x00002000UL +#define CDC_RNDIS_PACKET_FUNCTIONAL 0x00004000UL +#define CDC_RNDIS_PACKET_MAC_FRAME 0x00008000UL + +#define OID_GEN_SUPPORTED_LIST 0x00010101UL +#define OID_GEN_HARDWARE_STATUS 0x00010102UL +#define OID_GEN_MEDIA_SUPPORTED 0x00010103UL +#define OID_GEN_MEDIA_IN_USE 0x00010104UL +#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106UL +#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111UL +#define OID_GEN_LINK_SPEED 0x00010107UL +#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010AUL +#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010BUL +#define OID_GEN_VENDOR_ID 0x0001010CUL +#define OID_GEN_VENDOR_DESCRIPTION 0x0001010DUL +#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010EUL +#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114UL +#define OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115UL +#define OID_GEN_PHYSICAL_MEDIUM 0x00010202UL +#define OID_GEN_XMIT_OK 0x00020101UL +#define OID_GEN_RCV_OK 0x00020102UL +#define OID_GEN_XMIT_ERROR 0x00020103UL +#define OID_GEN_RCV_ERROR 0x00020104UL +#define OID_GEN_RCV_NO_BUFFER 0x00020105UL +#define OID_GEN_CDC_RNDIS_CONFIG_PARAMETER 0x0001021BUL +#define OID_802_3_PERMANENT_ADDRESS 0x01010101UL +#define OID_802_3_CURRENT_ADDRESS 0x01010102UL +#define OID_802_3_MULTICAST_LIST 0x01010103UL +#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104UL +#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101UL +#define OID_802_3_XMIT_ONE_COLLISION 0x01020102UL +#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103UL + + +#define CDC_RNDIS_SEND_ENCAPSULATED_COMMAND 0x00U +#define CDC_RNDIS_GET_ENCAPSULATED_RESPONSE 0x01U + +#define CDC_RNDIS_NET_DISCONNECTED 0x00U +#define CDC_RNDIS_NET_CONNECTED 0x01U + +#define CDC_RNDIS_BMREQUEST_TYPE_RNDIS 0xA1U +#define CDC_RNDIS_PCKTMSG_DATAOFFSET_OFFSET 8U + +/* MAC String index */ +#define CDC_RNDIS_MAC_STRING_INDEX 6U + +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +typedef struct _USBD_CDC_RNDIS_Itf +{ + int8_t (* Init)(void); + int8_t (* DeInit)(void); + int8_t (* Control)(uint8_t cmd, uint8_t *pbuf, uint16_t length); + int8_t (* Receive)(uint8_t *Buf, uint32_t *Len); + int8_t (* TransmitCplt)(uint8_t *Buf, uint32_t *Len, uint8_t epnum); + int8_t (* Process)(USBD_HandleTypeDef *pdev); + uint8_t *pStrDesc; +} USBD_CDC_RNDIS_ItfTypeDef; + +/* CDC_RNDIS State values */ +typedef enum +{ + CDC_RNDIS_STATE_UNINITIALIZED = 0, + CDC_RNDIS_STATE_BUS_INITIALIZED = 1, + CDC_RNDIS_STATE_INITIALIZED = 2, + CDC_RNDIS_STATE_DATA_INITIALIZED = 3 +} USBD_CDC_RNDIS_StateTypeDef; + +typedef struct +{ + uint8_t bmRequest; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; + uint8_t data[8]; +} USBD_CDC_RNDIS_NotifTypeDef; + +typedef struct +{ + uint32_t data[2000 / 4]; /* Force 32bits alignment */ + uint8_t CmdOpCode; + uint8_t CmdLength; + uint8_t ResponseRdy; /* Indicates if the Device Response to an CDC_RNDIS msg is ready */ + uint8_t Reserved1; /* Reserved Byte to force 4 bytes alignment of following fields */ + uint8_t *RxBuffer; + uint8_t *TxBuffer; + uint32_t RxLength; + uint32_t TxLength; + + USBD_CDC_RNDIS_NotifTypeDef Req; + USBD_CDC_RNDIS_StateTypeDef State; + + __IO uint32_t TxState; + __IO uint32_t RxState; + + __IO uint32_t MaxPcktLen; + __IO uint32_t LinkStatus; + __IO uint32_t NotificationStatus; + __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 */ +typedef struct +{ + uint32_t MsgType; + uint32_t MsgLength; + uint32_t ReqId; + uint32_t MajorVersion; + uint32_t MinorVersion; + uint32_t MaxTransferSize; +} USBD_CDC_RNDIS_InitMsgTypeDef; + +/* Type define for a CDC_RNDIS Halt Message */ +typedef struct +{ + uint32_t MsgType; + uint32_t MsgLength; + uint32_t ReqId; +} USBD_CDC_RNDIS_HaltMsgTypeDef; + +/* Type define for a CDC_RNDIS Query command message */ +typedef struct +{ + uint32_t MsgType; + uint32_t MsgLength; + uint32_t RequestId; + uint32_t Oid; + uint32_t InfoBufLength; + uint32_t InfoBufOffset; + uint32_t DeviceVcHandle; + uint32_t InfoBuf[CDC_RNDIS_MAX_INFO_BUFF_SZ]; +} USBD_CDC_RNDIS_QueryMsgTypeDef; + +/* Type define for a CDC_RNDIS Set command message */ +typedef struct +{ + uint32_t MsgType; + uint32_t MsgLength; + uint32_t ReqId; + uint32_t Oid; + uint32_t InfoBufLength; + uint32_t InfoBufOffset; + uint32_t DeviceVcHandle; + uint32_t InfoBuf[CDC_RNDIS_MAX_INFO_BUFF_SZ]; +} USBD_CDC_RNDIS_SetMsgTypeDef; + +/* Type define for a CDC_RNDIS Reset message */ +typedef struct +{ + uint32_t MsgType; + uint32_t MsgLength; + uint32_t Reserved; +} USBD_CDC_RNDIS_ResetMsgTypeDef; + +/* Type define for a CDC_RNDIS Keepalive command message */ +typedef struct +{ + uint32_t MsgType; + uint32_t MsgLength; + uint32_t ReqId; +} USBD_CDC_RNDIS_KpAliveMsgTypeDef; + + +/* Messages Sent by the Device ---------------------*/ + +/* Type define for a CDC_RNDIS Initialize complete response message */ +typedef struct +{ + uint32_t MsgType; + uint32_t MsgLength; + uint32_t ReqId; + uint32_t Status; + uint32_t MajorVersion; + uint32_t MinorVersion; + uint32_t DeviceFlags; + uint32_t Medium; + uint32_t MaxPacketsPerTransfer; + uint32_t MaxTransferSize; + uint32_t PacketAlignmentFactor; + uint32_t AFListOffset; + uint32_t AFListSize; +} USBD_CDC_RNDIS_InitCpltMsgTypeDef; + +/* Type define for a CDC_RNDIS Query complete response message */ +typedef struct +{ + uint32_t MsgType; + uint32_t MsgLength; + uint32_t ReqId; + uint32_t Status; + uint32_t InfoBufLength; + uint32_t InfoBufOffset; + uint32_t InfoBuf[CDC_RNDIS_MAX_INFO_BUFF_SZ]; +} USBD_CDC_RNDIS_QueryCpltMsgTypeDef; + +/* Type define for a CDC_RNDIS Set complete response message */ +typedef struct +{ + uint32_t MsgType; + uint32_t MsgLength; + uint32_t ReqId; + uint32_t Status; +} USBD_CDC_RNDIS_SetCpltMsgTypeDef; + +/* Type define for a CDC_RNDIS Reset complete message */ +typedef struct +{ + uint32_t MsgType; + uint32_t MsgLength; + uint32_t Status; + uint32_t AddrReset; +} USBD_CDC_RNDIS_ResetCpltMsgTypeDef; + +/* Type define for CDC_RNDIS struct to indicate a change + in the status of the device */ +typedef struct +{ + uint32_t MsgType; + uint32_t MsgLength; + uint32_t Status; + uint32_t StsBufLength; + uint32_t StsBufOffset; +} USBD_CDC_RNDIS_StsChangeMsgTypeDef; + +/* Type define for a CDC_RNDIS Keepalive complete message */ +typedef struct +{ + uint32_t MsgType; + uint32_t MsgLength; + uint32_t ReqId; + uint32_t Status; +} USBD_CDC_RNDIS_KpAliveCpltMsgTypeDef; + + +/* Messages Sent by both Host and Device ---------------------*/ + +/* Type define for a CDC_RNDIS packet message, used to encapsulate + Ethernet packets sent to and from the adapter */ +typedef struct +{ + uint32_t MsgType; + uint32_t MsgLength; + uint32_t DataOffset; + uint32_t DataLength; + uint32_t OOBDataOffset; + uint32_t OOBDataLength; + uint32_t NumOOBDataElements; + uint32_t PerPacketInfoOffset; + uint32_t PerPacketInfoLength; + uint32_t VcHandle; + uint32_t Reserved; +} USBD_CDC_RNDIS_PacketMsgTypeDef; + +/* Miscellaneous types used for parsing ---------------------*/ + +/* The common part for all CDC_RNDIS messages Complete response */ +typedef struct +{ + uint32_t MsgType; + uint32_t MsgLength; + uint32_t ReqId; + uint32_t Status; +} USBD_CDC_RNDIS_CommonCpltMsgTypeDef; + +/* Type define for a single parameter structure */ +typedef struct +{ + uint32_t ParamNameOffset; + uint32_t ParamNameLength; + uint32_t ParamType; + uint32_t ParamValueOffset; + uint32_t ParamValueLength; +} USBD_CDC_RNDIS_ParamStructTypeDef; + + +/* Type define of a single CDC_RNDIS OOB data record */ +typedef struct +{ + uint32_t Size; + uint32_t Type; + uint32_t ClassInfoType; + uint32_t OOBData[sizeof(uint32_t)]; +} USBD_CDC_RNDIS_OOBPacketTypeDef; + +/* Type define for notification structure */ +typedef struct +{ + uint32_t notification; + uint32_t reserved; +} USBD_CDC_RNDIS_NotifStructTypeDef; + +/* This structure will be used to store the type, the size and ID for any + received message from the control endpoint */ +typedef struct +{ + uint32_t MsgType; + uint32_t MsgLength; +} USBD_CDC_RNDIS_CtrlMsgTypeDef; + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ + +extern USBD_ClassTypeDef USBD_CDC_RNDIS; +#define USBD_CDC_RNDIS_CLASS &USBD_CDC_RNDIS +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ +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); + +uint8_t USBD_CDC_RNDIS_SetTxBuffer(USBD_HandleTypeDef *pdev, + uint8_t *pbuff, uint32_t length); + +uint8_t USBD_CDC_RNDIS_SendNotification(USBD_HandleTypeDef *pdev, + USBD_CDC_RNDIS_NotifCodeTypeDef Notif, + uint16_t bVal, uint8_t *pData); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_CDC_RNDIS_H */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Class/CDC_RNDIS/Inc/usbd_cdc_rndis_if_template.h b/Class/CDC_RNDIS/Inc/usbd_cdc_rndis_if_template.h new file mode 100644 index 0000000..3cf0271 --- /dev/null +++ b/Class/CDC_RNDIS/Inc/usbd_cdc_rndis_if_template.h @@ -0,0 +1,60 @@ +/** + ****************************************************************************** + * @file usbd_cdc_rndis_if_template.h + * @author MCD Application Team + * @brief Header for usbd_cdc_rndis_if.c file. + ****************************************************************************** + * @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 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_CDC_RNDIS_IF_H +#define __USBD_CDC_RNDIS_IF_H + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_cdc_rndis.h" + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* Ensure this MAC address value is same as MAC_ADDRx declared in STM32xxx_conf.h */ +#define CDC_RNDIS_MAC_STR_DESC (uint8_t *)"000202030000" +#define CDC_RNDIS_MAC_ADDR0 0x00U /* 01 */ +#define CDC_RNDIS_MAC_ADDR1 0x02U /* 02 */ +#define CDC_RNDIS_MAC_ADDR2 0x02U /* 03 */ +#define CDC_RNDIS_MAC_ADDR3 0x03U /* 00 */ +#define CDC_RNDIS_MAC_ADDR4 0x00U /* 00 */ +#define CDC_RNDIS_MAC_ADDR5 0x00U /* 00 */ + +#define USBD_CDC_RNDIS_VENDOR_DESC "STMicroelectronics" +#define USBD_CDC_RNDIS_LINK_SPEED 100000U /* 10Mbps */ +#define USBD_CDC_RNDIS_VID 0x0483U + +/* Max Number of Trials waiting for Tx ready */ +#define CDC_RNDIS_MAX_TX_WAIT_TRIALS 1000000U + +/* Ethernet Maximum Segment size, typically 1514 bytes */ +#define CDC_RNDIS_ETH_MAX_SEGSZE 1514U + +#define CDC_RNDIS_CONNECT_SPEED_UPSTREAM 0x1E000000U +#define CDC_RNDIS_CONNECT_SPEED_DOWNSTREAM 0x1E000000U + + +extern USBD_CDC_RNDIS_ItfTypeDef USBD_CDC_RNDIS_fops; + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +#endif /* __USBD_CDC_RNDIS_IF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c b/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c new file mode 100644 index 0000000..946ed50 --- /dev/null +++ b/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c @@ -0,0 +1,1698 @@ +/** + ****************************************************************************** + * @file usbd_cdc_rndis.c + * @author MCD Application Team + * @brief This file provides the high layer firmware functions to manage the + * following functionalities of the USB CDC_RNDIS Class: + * - Initialization and Configuration of high and low layer + * - Enumeration as CDC_RNDIS Device (and enumeration for each implemented memory interface) + * - OUT/IN data transfer + * - Command IN transfer (class requests management) + * - Error management + * + * @verbatim + * + * =================================================================== + * CDC_RNDIS Class Driver Description + * =================================================================== + * This driver manages the "Universal Serial Bus Class Definitions for Communications Devices + * Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus + * Communications Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007" + * This driver implements the following aspects of the specification: + * - Device descriptor management + * - Configuration descriptor management + * - Enumeration as CDC device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN) + * - Requests management (as described in section 6.2 in specification) + * - Abstract Control Model compliant + * - Union Functional collection (using 1 IN endpoint for control) + * - Data interface class + * + * These aspects may be enriched or modified for a specific user application. + * + * This driver doesn't implement the following aspects of the specification + * (but it is possible to manage these features with some modifications on this driver): + * - Any class-specific aspect relative to communication classes should be managed by user application. + * - All communication classes other than PSTN are not managed + * + * @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 ------------------------------------------------------------------*/ +#include "usbd_cdc_rndis.h" +#include "usbd_ctlreq.h" + +#ifndef __USBD_CDC_RNDIS_IF_H +#include "usbd_cdc_rndis_if_template.h" +#endif +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_CDC_RNDIS + * @brief usbd core module + * @{ + */ + +/** @defgroup USBD_CDC_RNDIS_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_CDC_RNDIS_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_CDC_RNDIS_Private_Macros + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_CDC_RNDIS_Private_FunctionPrototypes + * @{ + */ + +static uint8_t USBD_CDC_RNDIS_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +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); + +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); +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); + +#if (USBD_SUPPORT_USER_STRING_DESC == 1U) +static uint8_t *USBD_CDC_RNDIS_USRStringDescriptor(USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length); +#endif + +uint8_t *USBD_CDC_RNDIS_GetDeviceQualifierDescriptor(uint16_t *length); + + +/* CDC_RNDIS Internal messages parsing and construction functions */ +static uint8_t USBD_CDC_RNDIS_MsgParsing(USBD_HandleTypeDef *pdev, uint8_t *RxBuff); +static uint8_t USBD_CDC_RNDIS_ProcessInitMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_InitMsgTypeDef *Msg); +static uint8_t USBD_CDC_RNDIS_ProcessHaltMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_HaltMsgTypeDef *Msg); +static uint8_t USBD_CDC_RNDIS_ProcessKeepAliveMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_KpAliveMsgTypeDef *Msg); +static uint8_t USBD_CDC_RNDIS_ProcessQueryMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_QueryMsgTypeDef *Msg); +static uint8_t USBD_CDC_RNDIS_ProcessSetMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_SetMsgTypeDef *Msg); +static uint8_t USBD_CDC_RNDIS_ProcessResetMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_ResetMsgTypeDef *Msg); +static uint8_t USBD_CDC_RNDIS_ProcessPacketMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_PacketMsgTypeDef *Msg); +static uint8_t USBD_CDC_RNDIS_ProcessUnsupportedMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_CtrlMsgTypeDef *Msg); + +/* USB Standard Device Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_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, +}; + +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}; + +static uint32_t ConnSpeedTab[2] = {CDC_RNDIS_CONNECT_SPEED_UPSTREAM, + CDC_RNDIS_CONNECT_SPEED_DOWNSTREAM}; + +static uint8_t EmptyResponse = 0x00U; + +/** + * @} + */ + +/** @defgroup USBD_CDC_RNDIS_Private_Variables + * @{ + */ + + +/* CDC_RNDIS interface class callbacks structure */ +USBD_ClassTypeDef USBD_CDC_RNDIS = +{ + USBD_CDC_RNDIS_Init, + USBD_CDC_RNDIS_DeInit, + USBD_CDC_RNDIS_Setup, + NULL, /* EP0_TxSent, */ + USBD_CDC_RNDIS_EP0_RxReady, + USBD_CDC_RNDIS_DataIn, + USBD_CDC_RNDIS_DataOut, + NULL, + NULL, + NULL, + USBD_CDC_RNDIS_GetHSCfgDesc, + USBD_CDC_RNDIS_GetFSCfgDesc, + USBD_CDC_RNDIS_GetOtherSpeedCfgDesc, + USBD_CDC_RNDIS_GetDeviceQualifierDescriptor, +#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 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ + 0xC0, /* bmAttributes: self powered */ + 0x32, /* MaxPower 0 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), + 0xFF, /* bInterval: ignore for Bulk transfer */ + + /* 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), + 0xFF /* bInterval: ignore for Bulk transfer */ +}; + + +/* USB CDC device Configuration Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_CfgFSDesc[] __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 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ + 0xC0, /* bmAttributes: self powered */ + 0x32, /* MaxPower 0 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_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 */ + LOBYTE(CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE), + 0xFF, /* bInterval: ignore for Bulk transfer */ + + /* 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_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE), + 0xFF /* bInterval: ignore for Bulk transfer */ +} ; + +__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 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x04, /* iConfiguration: Index of string descriptor describing the configuration */ + 0xC0, /* bmAttributes: self powered */ + 0x32, /* MaxPower 0 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, + 0xFF, /* bInterval: ignore for Bulk transfer */ + + /* 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, + 0xFF /* bInterval: ignore for Bulk transfer */ +}; + + +static const uint32_t CDC_RNDIS_SupportedOIDs[] = +{ + OID_GEN_SUPPORTED_LIST, + OID_GEN_HARDWARE_STATUS, + OID_GEN_MEDIA_SUPPORTED, + OID_GEN_MEDIA_IN_USE, + OID_GEN_MAXIMUM_FRAME_SIZE, + OID_GEN_LINK_SPEED, + OID_GEN_TRANSMIT_BLOCK_SIZE, + OID_GEN_RECEIVE_BLOCK_SIZE, + OID_GEN_VENDOR_ID, + OID_GEN_VENDOR_DESCRIPTION, + OID_GEN_CURRENT_PACKET_FILTER, + OID_GEN_MAXIMUM_TOTAL_SIZE, + OID_GEN_MEDIA_CONNECT_STATUS, + OID_GEN_MAXIMUM_SEND_PACKETS, + OID_802_3_PERMANENT_ADDRESS, + OID_802_3_CURRENT_ADDRESS, + OID_802_3_MULTICAST_LIST, + OID_802_3_MAXIMUM_LIST_SIZE, + OID_802_3_RCV_ERROR_ALIGNMENT, + OID_802_3_XMIT_ONE_COLLISION, + OID_802_3_XMIT_MORE_COLLISIONS, +}; + +/** + * @} + */ + +/** @defgroup USBD_CDC_RNDIS_Private_Functions + * @{ + */ + +/** + * @brief USBD_CDC_RNDIS_Init + * Initialize the CDC CDC_RNDIS interface + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_CDC_RNDIS_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + UNUSED(cfgidx); + USBD_CDC_RNDIS_HandleTypeDef *hcdc; + + hcdc = USBD_malloc(sizeof(USBD_CDC_RNDIS_HandleTypeDef)); + + if (hcdc == NULL) + { + pdev->pClassData = NULL; + return (uint8_t)USBD_EMEM; + } + + pdev->pClassData = (void *)hcdc; + + if (pdev->dev_speed == USBD_SPEED_HIGH) + { + /* Open EP IN */ + (void)USBD_LL_OpenEP(pdev, CDC_RNDIS_IN_EP, USBD_EP_TYPE_BULK, + CDC_RNDIS_DATA_HS_IN_PACKET_SIZE); + + pdev->ep_in[CDC_RNDIS_IN_EP & 0xFU].is_used = 1U; + + /* Open EP OUT */ + (void)USBD_LL_OpenEP(pdev, CDC_RNDIS_OUT_EP, USBD_EP_TYPE_BULK, + CDC_RNDIS_DATA_HS_OUT_PACKET_SIZE); + + pdev->ep_out[CDC_RNDIS_OUT_EP & 0xFU].is_used = 1U; + + /* Set bInterval for CDC RNDIS CMD Endpoint */ + pdev->ep_in[CDC_RNDIS_CMD_EP & 0xFU].bInterval = CDC_RNDIS_HS_BINTERVAL; + } + else + { + /* Open EP IN */ + (void)USBD_LL_OpenEP(pdev, CDC_RNDIS_IN_EP, USBD_EP_TYPE_BULK, + CDC_RNDIS_DATA_FS_IN_PACKET_SIZE); + + pdev->ep_in[CDC_RNDIS_IN_EP & 0xFU].is_used = 1U; + + /* Open EP OUT */ + (void)USBD_LL_OpenEP(pdev, CDC_RNDIS_OUT_EP, USBD_EP_TYPE_BULK, + CDC_RNDIS_DATA_FS_OUT_PACKET_SIZE); + + pdev->ep_out[CDC_RNDIS_OUT_EP & 0xFU].is_used = 1U; + + /* Set bInterval for CDC RNDIS CMD Endpoint */ + pdev->ep_in[CDC_RNDIS_CMD_EP & 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; + + /* Init physical Interface components */ + ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->Init(); + + /* Init the CDC_RNDIS state */ + hcdc->State = CDC_RNDIS_STATE_BUS_INITIALIZED; + + /* Init Xfer states */ + hcdc->TxState = 0U; + hcdc->RxState = 0U; + hcdc->RxLength = 0U; + 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; + + /* Prepare Out endpoint to receive next packet */ + (void)USBD_LL_PrepareReceive(pdev, CDC_RNDIS_OUT_EP, + hcdc->RxBuffer, hcdc->MaxPcktLen); + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_CDC_RNDIS_DeInit + * DeInitialize the CDC layer + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_CDC_RNDIS_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + UNUSED(cfgidx); + + /* Close EP IN */ + (void)USBD_LL_CloseEP(pdev, CDC_RNDIS_IN_EP); + pdev->ep_in[CDC_RNDIS_IN_EP & 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; + + /* 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; + + /* DeInit physical Interface components */ + if (pdev->pClassData != NULL) + { + ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->DeInit(); + USBD_free(pdev->pClassData); + pdev->pClassData = NULL; + } + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_CDC_RNDIS_Setup + * Handle the CDC specific requests + * @param pdev: instance + * @param req: usb requests + * @retval status + */ +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 *)hcdc->data; + uint8_t ifalt = 0U; + uint16_t status_info = 0U; + USBD_StatusTypeDef ret = USBD_OK; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS : + if (req->wLength != 0U) + { + /* Control Request Data from Device to Host, send data prepared by device */ + if ((req->bmRequest & 0x80U) != 0U) + { + /* Update opcode and length */ + hcdc->CmdOpCode = req->bRequest; + hcdc->CmdLength = (uint8_t)req->wLength; + + if (hcdc->CmdOpCode == CDC_RNDIS_GET_ENCAPSULATED_RESPONSE) + { + /* Data of Response Message has already been prepared by USBD_CDC_RNDIS_MsgParsing. + Just check that length is corresponding to right expected value */ + if (req->wLength != Msg->MsgLength) + { + } + } + + /* 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); + /* Check if Response is ready */ + if (hcdc->ResponseRdy != 0U) + { + /* Clear Response Ready flag */ + hcdc->ResponseRdy = 0U; + + /* Send data on control endpoint */ + (void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data, Msg->MsgLength); + } + else + { + /* CDC_RNDIS Specification says: If for some reason the device receives a GET ENCAPSULATED RESPONSE + and is unable to respond with a valid data on the Control endpoint, + then it should return a one-byte packet set to 0x00, rather than + stalling the Control endpoint */ + (void)USBD_CtlSendData(pdev, &EmptyResponse, 1U); + } + } + /* Control Request Data from Host to Device: Prepare reception of control data stage */ + else + { + hcdc->CmdOpCode = req->bRequest; + hcdc->CmdLength = (uint8_t)req->wLength; + + (void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data, req->wLength); + } + } + /* No Data control request: there is no such request for CDC_RNDIS protocol, + so let application layer manage this case */ + else + { + ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, + (uint8_t *)req, 0U); + } + break; + + 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_CDC_RNDIS_DataIn + * Data sent on non-control IN endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +static uint8_t USBD_CDC_RNDIS_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + USBD_CDC_RNDIS_HandleTypeDef *hcdc; + PCD_HandleTypeDef *hpcd = pdev->pData; + + if (pdev->pClassData == NULL) + { + return (uint8_t)USBD_FAIL; + } + + hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + + if (epnum == (CDC_RNDIS_IN_EP & 0x7FU)) + { + 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 & 0xFU].total_length = 0U; + + /* Send ZLP */ + (void)USBD_LL_Transmit(pdev, epnum, NULL, 0U); + } + else + { + hcdc->TxState = 0U; + ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum); + } + } + else if (epnum == (CDC_RNDIS_CMD_EP & 0x7FU)) + { + if (hcdc->NotificationStatus != 0U) + { + (void)USBD_CDC_RNDIS_SendNotification(pdev, CONNECTION_SPEED_CHANGE, + 0U, (uint8_t *)ConnSpeedTab); + + hcdc->NotificationStatus = 0U; + } + } + else + { + return (uint8_t)USBD_FAIL; + } + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_CDC_RNDIS_DataOut + * Data received on non-control Out endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +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) + { + return (uint8_t)USBD_FAIL; + } + + hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + + if (epnum == CDC_RNDIS_OUT_EP) + { + /* Get the received data length */ + CurrPcktLen = USBD_LL_GetRxDataSize(pdev, epnum); + + /* Increment the frame length */ + hcdc->RxLength += CurrPcktLen; + + /* If the buffer size is less than max packet size: it is the last packet in current frame */ + if ((CurrPcktLen < hcdc->MaxPcktLen) || + (hcdc->RxLength >= (CDC_RNDIS_ETH_MAX_SEGSZE + sizeof(USBD_CDC_RNDIS_PacketMsgTypeDef)))) + { + /* USB data will be immediately processed, this allow next USB traffic being + NACKed till the end of the application Xfer */ + + /* Call data packet message parsing and processing function */ + (void)USBD_CDC_RNDIS_ProcessPacketMsg(pdev, (USBD_CDC_RNDIS_PacketMsgTypeDef *)hcdc->RxBuffer); + } + else + { + /* Prepare Out endpoint to receive next packet in current/new frame */ + (void)USBD_LL_PrepareReceive(pdev, CDC_RNDIS_OUT_EP, + (uint8_t *)(hcdc->RxBuffer + hcdc->RxLength), + hcdc->MaxPcktLen); + } + } + else + { + return (uint8_t)USBD_FAIL; + } + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_CDC_RNDIS_EP0_RxReady + * Handle EP0 Rx Ready event + * @param pdev: device instance + * @retval status + */ +static uint8_t USBD_CDC_RNDIS_EP0_RxReady(USBD_HandleTypeDef *pdev) +{ + USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + + if ((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFFU)) + { + /* Check if the received command is SendEncapsulated command */ + if (hcdc->CmdOpCode == CDC_RNDIS_SEND_ENCAPSULATED_COMMAND) + { + /* Process Received CDC_RNDIS Control Message */ + (void)USBD_CDC_RNDIS_MsgParsing(pdev, (uint8_t *)(hcdc->data)); + + /* Reset the command opcode for next processing */ + hcdc->CmdOpCode = 0xFFU; + } + else + { + /* Reset the command opcode for next processing */ + hcdc->CmdOpCode = 0xFFU; + + /* Ignore the command and return fail */ + return (uint8_t)USBD_FAIL; + } + } + + return (uint8_t)USBD_OK; +} + +/** + * @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)); + + return USBD_CDC_RNDIS_CfgFSDesc; +} + +/** + * @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)); + + return USBD_CDC_RNDIS_CfgHSDesc; +} + +/** + * @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)); + + return USBD_CDC_RNDIS_OtherSpeedCfgDesc; +} + +/** + * @brief DeviceQualifierDescriptor + * return Device Qualifier descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +uint8_t *USBD_CDC_RNDIS_GetDeviceQualifierDescriptor(uint16_t *length) +{ + *length = (uint16_t)(sizeof(USBD_CDC_RNDIS_DeviceQualifierDesc)); + + return USBD_CDC_RNDIS_DeviceQualifierDesc; +} + +/** + * @brief USBD_CDC_RNDIS_RegisterInterface + * @param pdev: device instance + * @param fops: CD Interface callback + * @retval status + */ +uint8_t USBD_CDC_RNDIS_RegisterInterface(USBD_HandleTypeDef *pdev, + USBD_CDC_RNDIS_ItfTypeDef *fops) +{ + if (fops == NULL) + { + return (uint8_t)USBD_FAIL; + } + + pdev->pUserData = fops; + + return (uint8_t)USBD_OK; +} + + +/** + * @brief USBD_CDC_RNDIS_USRStringDescriptor + * Manages the transfer of user string descriptors. + * @param speed : current device speed + * @param index: descriptor index + * @param length : pointer data length + * @retval pointer to the descriptor table or NULL if the descriptor is not supported. + */ +#if (USBD_SUPPORT_USER_STRING_DESC == 1U) +static uint8_t *USBD_CDC_RNDIS_USRStringDescriptor(USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length) +{ + static uint8_t USBD_StrDesc[255]; + + /* 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); + return USBD_StrDesc; + } + /* Not supported Interface Descriptor index */ + else + { + return NULL; + } +} +#endif /* USBD_SUPPORT_USER_STRING_DESC */ + +/** + * @brief USBD_CDC_RNDIS_SetTxBuffer + * @param pdev: device instance + * @param pbuff: Tx Buffer + * @retval status + */ +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; + + hcdc->TxBuffer = pbuff; + hcdc->TxLength = length; + + return (uint8_t)USBD_OK; +} + + +/** + * @brief USBD_CDC_RNDIS_SetRxBuffer + * @param pdev: device instance + * @param pbuff: Rx Buffer + * @retval status + */ +uint8_t USBD_CDC_RNDIS_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff) +{ + USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + + hcdc->RxBuffer = pbuff; + + return (uint8_t)USBD_OK; +} + + +/** + * @brief USBD_CDC_RNDIS_TransmitPacket + * Transmit packet on IN endpoint + * @param pdev: device instance + * @retval status + */ +uint8_t USBD_CDC_RNDIS_TransmitPacket(USBD_HandleTypeDef *pdev) +{ + USBD_CDC_RNDIS_HandleTypeDef *hcdc; + USBD_CDC_RNDIS_PacketMsgTypeDef *PacketMsg; + USBD_StatusTypeDef ret = USBD_BUSY; + + if (pdev->pClassData == NULL) + { + return (uint8_t)USBD_FAIL; + } + + hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + PacketMsg = (USBD_CDC_RNDIS_PacketMsgTypeDef *)hcdc->TxBuffer; + + if (hcdc->TxState == 0U) + { + /* Tx Transfer in progress */ + hcdc->TxState = 1U; + + /* Format the packet information */ + PacketMsg->MsgType = CDC_RNDIS_PACKET_MSG_ID; + PacketMsg->MsgLength = hcdc->TxLength; + PacketMsg->DataOffset = sizeof(USBD_CDC_RNDIS_PacketMsgTypeDef) - CDC_RNDIS_PCKTMSG_DATAOFFSET_OFFSET; + PacketMsg->DataLength = hcdc->TxLength - sizeof(USBD_CDC_RNDIS_PacketMsgTypeDef); + PacketMsg->OOBDataOffset = 0U; + PacketMsg->OOBDataLength = 0U; + PacketMsg->NumOOBDataElements = 0U; + PacketMsg->PerPacketInfoOffset = 0U; + PacketMsg->PerPacketInfoLength = 0U; + PacketMsg->VcHandle = 0U; + PacketMsg->Reserved = 0U; + + /* Update the packet total length */ + pdev->ep_in[CDC_RNDIS_IN_EP & 0xFU].total_length = hcdc->TxLength; + + /* Transmit next packet */ + (void)USBD_LL_Transmit(pdev, CDC_RNDIS_IN_EP, hcdc->TxBuffer, hcdc->TxLength); + + ret = USBD_OK; + } + + return (uint8_t)ret; +} + + +/** + * @brief USBD_CDC_RNDIS_ReceivePacket + * prepare OUT Endpoint for reception + * @param pdev: device instance + * @retval status + */ +uint8_t USBD_CDC_RNDIS_ReceivePacket(USBD_HandleTypeDef *pdev) +{ + USBD_CDC_RNDIS_HandleTypeDef *hcdc; + + if (pdev->pClassData == NULL) + { + return (uint8_t)USBD_FAIL; + } + + hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + + /* Prepare Out endpoint to receive next packet */ + (void)USBD_LL_PrepareReceive(pdev, CDC_RNDIS_OUT_EP, + hcdc->RxBuffer, hcdc->MaxPcktLen); + + return (uint8_t)USBD_OK; +} + + +/** + * @brief USBD_CDC_RNDIS_SendNotification + * Transmit Notification packet on CMD IN interrupt endpoint + * @param pdev: device instance + * Notif: value of the notification type (from CDC_RNDIS_Notification_TypeDef enumeration list) + * bVal: value of the notification switch (ie. 0x00 or 0x01 for Network Connection notification) + * pData: pointer to data buffer (ie. upstream and downstream connection speed values) + * @retval status + */ +uint8_t USBD_CDC_RNDIS_SendNotification(USBD_HandleTypeDef *pdev, + USBD_CDC_RNDIS_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_StatusTypeDef ret = USBD_OK; + + UNUSED(bVal); + UNUSED(pData); + + /* Initialize the request fields */ + (hcdc->Req).bmRequest = CDC_RNDIS_BMREQUEST_TYPE_RNDIS; + (hcdc->Req).bRequest = (uint8_t)Notif; + + switch (Notif) + { + case RESPONSE_AVAILABLE: + (hcdc->Req).wValue = 0U; + (hcdc->Req).wIndex = CDC_RNDIS_CMD_ITF_NBR; + (hcdc->Req).wLength = 0U; + for (Idx = 0U; Idx < 8U; Idx++) + { + (hcdc->Req).data[Idx] = 0U; + } + ReqSize = 8U; + break; + + default: + ret = USBD_FAIL; + break; + } + + /* Transmit notification packet */ + if (ReqSize != 0U) + { + (void)USBD_LL_Transmit(pdev, CDC_RNDIS_CMD_EP, (uint8_t *)&(hcdc->Req), ReqSize); + } + + return (uint8_t)ret; +} + + +/* ----------------------------- CDC_RNDIS Messages processing functions ----------------------- */ +/** + * @brief USBD_CDC_RNDIS_MsgParsing + * Parse received message and process it depending on its nature. + * @param pdev: USB Device Handle pointer + * @param RxBuff: Pointer to the message data extracted from SendEncapsulated command + * @retval status + */ +static uint8_t USBD_CDC_RNDIS_MsgParsing(USBD_HandleTypeDef *pdev, uint8_t *RxBuff) +{ + USBD_CDC_RNDIS_CtrlMsgTypeDef *Msg = (USBD_CDC_RNDIS_CtrlMsgTypeDef *)RxBuff; + static uint8_t ret = (uint8_t)USBD_OK; + + /* Check message type */ + switch (Msg->MsgType) + { + /* CDC_RNDIS Initialize message */ + case CDC_RNDIS_INITIALIZE_MSG_ID: + ret = USBD_CDC_RNDIS_ProcessInitMsg(pdev, (USBD_CDC_RNDIS_InitMsgTypeDef *)Msg); + break; + + /* CDC_RNDIS Halt message */ + case CDC_RNDIS_HALT_MSG_ID: + ret = USBD_CDC_RNDIS_ProcessHaltMsg(pdev, (USBD_CDC_RNDIS_HaltMsgTypeDef *)Msg); + break; + + /* CDC_RNDIS Query message */ + case CDC_RNDIS_QUERY_MSG_ID: + ret = USBD_CDC_RNDIS_ProcessQueryMsg(pdev, (USBD_CDC_RNDIS_QueryMsgTypeDef *)Msg); + break; + + /* CDC_RNDIS Set message */ + case CDC_RNDIS_SET_MSG_ID: + ret = USBD_CDC_RNDIS_ProcessSetMsg(pdev, (USBD_CDC_RNDIS_SetMsgTypeDef *)Msg); + break; + + /* CDC_RNDIS Reset message */ + case CDC_RNDIS_RESET_MSG_ID: + ret = USBD_CDC_RNDIS_ProcessResetMsg(pdev, (USBD_CDC_RNDIS_ResetMsgTypeDef *)Msg); + break; + + /* CDC_RNDIS Keep-Alive message */ + case CDC_RNDIS_KEEPALIVE_MSG_ID: + ret = USBD_CDC_RNDIS_ProcessKeepAliveMsg(pdev, (USBD_CDC_RNDIS_KpAliveMsgTypeDef *)Msg); + break; + + /* CDC_RNDIS unsupported message */ + default: + ret = USBD_CDC_RNDIS_ProcessUnsupportedMsg(pdev, (USBD_CDC_RNDIS_CtrlMsgTypeDef *)Msg); + break; + } + + return ret; +} + + +/** + * @brief USBD_CDC_RNDIS_ProcessInitMsg + * Parse, extract data and check correctness of CDC_RNDIS INIT_MSG command. + * @param pdev: USB Device Handle pointer + * @param Msg: Pointer to the message data extracted from SendEncapsulated command + * @retval status + */ +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; + + /* Get and format the Msg input */ + USBD_CDC_RNDIS_InitMsgTypeDef *InitMessage = (USBD_CDC_RNDIS_InitMsgTypeDef *)Msg; + + /* Use same Msg input buffer as response buffer */ + USBD_CDC_RNDIS_InitCpltMsgTypeDef *InitResponse = (USBD_CDC_RNDIS_InitCpltMsgTypeDef *)Msg; + + /* Store the Message Request ID */ + uint32_t ReqId = InitMessage->ReqId; + + /* Check correctness of the message (MsgType already checked by entry to this function) */ + if ((InitMessage->MsgLength != sizeof(USBD_CDC_RNDIS_InitMsgTypeDef)) || \ + (InitMessage->MajorVersion < CDC_RNDIS_VERSION_MAJOR)) + { + InitResponse->Status = CDC_RNDIS_STATUS_FAILURE; + } + else + { + InitResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + } + + /* Setup the response buffer content */ + InitResponse->MsgType = CDC_RNDIS_INITIALIZE_CMPLT_ID; + InitResponse->MsgLength = sizeof(USBD_CDC_RNDIS_InitCpltMsgTypeDef); + InitResponse->ReqId = ReqId; + InitResponse->MajorVersion = CDC_RNDIS_VERSION_MAJOR; + InitResponse->MinorVersion = CDC_RNDIS_VERSION_MINOR; + InitResponse->DeviceFlags = CDC_RNDIS_DF_CONNECTIONLESS; + InitResponse->Medium = CDC_RNDIS_MEDIUM_802_3; + InitResponse->MaxPacketsPerTransfer = 1U; + InitResponse->MaxTransferSize = (sizeof(USBD_CDC_RNDIS_PacketMsgTypeDef) + CDC_RNDIS_ETH_FRAME_SIZE_MAX); + InitResponse->PacketAlignmentFactor = 2U; /* Not needed as single packet by transfer set */ + InitResponse->AFListOffset = 0U; /* Reserved for connection-oriented devices. Set value to zero. */ + InitResponse->AFListSize = 0U; /* Reserved for connection-oriented devices. Set value to zero. */ + + /* Set CDC_RNDIS state to INITIALIZED */ + hcdc->State = CDC_RNDIS_STATE_INITIALIZED; + + /* Set Response Ready field in order to send response during next control request */ + hcdc->ResponseRdy = 1U; + + /* Send Notification on Interrupt EP to inform Host that response is ready */ + (void)USBD_CDC_RNDIS_SendNotification(pdev, RESPONSE_AVAILABLE, 0U, NULL); + + return (uint8_t)USBD_OK; +} + + +/** + * @brief USBD_CDC_RNDIS_ProcessHaltMsg + * Parse, extract data and check correctness of CDC_RNDIS Halt command. + * @param pdev: USB Device Handle pointer + * @param Msg: Pointer to the message data extracted from SendEncapsulated command + * @retval status + */ +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; + + /* Set CDC_RNDIS state to INITIALIZED */ + hcdc->State = CDC_RNDIS_STATE_UNINITIALIZED; + + /* No response required for this message, so no notification (RESPNSE_AVAILABLE) is sent */ + + UNUSED(Msg); + + return (uint8_t)USBD_OK; +} + + +/** + * @brief USBD_CDC_RNDIS_ProcessKeepAliveMsg + * Parse, extract data and check correctness of CDC_RNDIS KeepAlive command. + * @param pdev: USB Device Handle pointer + * @param Msg: Pointer to the message data extracted from SendEncapsulated command + * @retval status + */ +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; + + /* Use same Msg input buffer as response buffer */ + USBD_CDC_RNDIS_KpAliveCpltMsgTypeDef *InitResponse = (USBD_CDC_RNDIS_KpAliveCpltMsgTypeDef *)Msg; + + /* Store the Message Request ID */ + uint32_t ReqId = Msg->ReqId; + + /* Check correctness of the message (MsgType already checked by entry to this function) */ + if (Msg->MsgLength != sizeof(USBD_CDC_RNDIS_KpAliveMsgTypeDef)) + { + InitResponse->Status = CDC_RNDIS_STATUS_FAILURE; + } + else + { + InitResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + } + + /* Setup the response buffer content */ + InitResponse->MsgType = CDC_RNDIS_KEEPALIVE_CMPLT_ID; + InitResponse->MsgLength = sizeof(USBD_CDC_RNDIS_KpAliveCpltMsgTypeDef); + InitResponse->ReqId = ReqId; + InitResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + + /* Set Response Ready field in order to send response during next control request */ + hcdc->ResponseRdy = 1U; + + /* Send Notification on Interrupt EP to inform Host that response is ready */ + (void)USBD_CDC_RNDIS_SendNotification(pdev, RESPONSE_AVAILABLE, 0U, NULL); + + return (uint8_t)USBD_OK; +} + + +/** + * @brief USBD_CDC_RNDIS_ProcessQueryMsg + * Parse, extract data and check correctness of CDC_RNDIS Query command. + * @param pdev: USB Device Handle pointer + * @param Msg: Pointer to the message data extracted from SendEncapsulated command + * @retval status + */ +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; + + /* Use same Msg input buffer as response buffer */ + USBD_CDC_RNDIS_QueryCpltMsgTypeDef *QueryResponse = (USBD_CDC_RNDIS_QueryCpltMsgTypeDef *)Msg; + + /* Store the Message Request ID */ + uint32_t ReqId = Msg->RequestId; + + /* Process the OID depending on its code */ + switch (Msg->Oid) + { + case OID_GEN_SUPPORTED_LIST: + QueryResponse->InfoBufLength = sizeof(CDC_RNDIS_SupportedOIDs); + (void)USBD_memcpy(QueryResponse->InfoBuf, CDC_RNDIS_SupportedOIDs, + sizeof(CDC_RNDIS_SupportedOIDs)); + + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_GEN_HARDWARE_STATUS: + QueryResponse->InfoBufLength = sizeof(uint32_t); + QueryResponse->InfoBuf[0] = CDC_RNDIS_HW_STS_READY; + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_GEN_MEDIA_SUPPORTED: + case OID_GEN_MEDIA_IN_USE: + QueryResponse->InfoBufLength = sizeof(uint32_t); + QueryResponse->InfoBuf[0] = CDC_RNDIS_MEDIUM_802_3; + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_GEN_VENDOR_ID: + QueryResponse->InfoBufLength = sizeof(uint32_t); + QueryResponse->InfoBuf[0] = USBD_CDC_RNDIS_VID; + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_GEN_MAXIMUM_FRAME_SIZE: + case OID_GEN_TRANSMIT_BLOCK_SIZE: + case OID_GEN_RECEIVE_BLOCK_SIZE: + QueryResponse->InfoBufLength = sizeof(uint32_t); + QueryResponse->InfoBuf[0] = CDC_RNDIS_ETH_FRAME_SIZE_MAX; + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_GEN_VENDOR_DESCRIPTION: + QueryResponse->InfoBufLength = (strlen(USBD_CDC_RNDIS_VENDOR_DESC) + 1U); + (void)USBD_memcpy(QueryResponse->InfoBuf, USBD_CDC_RNDIS_VENDOR_DESC, + strlen(USBD_CDC_RNDIS_VENDOR_DESC)); + + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_GEN_MEDIA_CONNECT_STATUS: + QueryResponse->InfoBufLength = sizeof(uint32_t); + QueryResponse->InfoBuf[0] = CDC_RNDIS_MEDIA_STATE_CONNECTED; + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_GEN_MAXIMUM_SEND_PACKETS: + QueryResponse->InfoBufLength = sizeof(uint32_t); + QueryResponse->InfoBuf[0] = 1U; + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_GEN_LINK_SPEED: + QueryResponse->InfoBufLength = sizeof(uint32_t); + QueryResponse->InfoBuf[0] = USBD_CDC_RNDIS_LINK_SPEED; + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_802_3_PERMANENT_ADDRESS: + case OID_802_3_CURRENT_ADDRESS: + QueryResponse->InfoBufLength = 6U; + (void)USBD_memcpy(QueryResponse->InfoBuf, MAC_StrDesc, 6); + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_802_3_MAXIMUM_LIST_SIZE: + QueryResponse->InfoBufLength = sizeof(uint32_t); + QueryResponse->InfoBuf[0] = 1U; /* Only one multicast address supported */ + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_GEN_CURRENT_PACKET_FILTER: + QueryResponse->InfoBufLength = sizeof(uint32_t); + QueryResponse->InfoBuf[0] = 0xFFFFFFU; /* USBD_CDC_RNDIS_DEVICE.packetFilter; */ + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_802_3_RCV_ERROR_ALIGNMENT: + case OID_802_3_XMIT_ONE_COLLISION: + case OID_802_3_XMIT_MORE_COLLISIONS: + QueryResponse->InfoBufLength = sizeof(uint32_t); + QueryResponse->InfoBuf[0] = 0U; /* Unused OIDs, return zero */ + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_GEN_MAXIMUM_TOTAL_SIZE: + QueryResponse->InfoBufLength = sizeof(uint32_t); + /* Indicate maximum overall buffer (Ethernet frame and CDC_RNDIS header) the adapter can handle */ + QueryResponse->InfoBuf[0] = (CDC_RNDIS_MESSAGE_BUFFER_SIZE + CDC_RNDIS_ETH_FRAME_SIZE_MAX); + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + default: + /* Unknown or unsupported OID */ + QueryResponse->InfoBufLength = 0U; + QueryResponse->Status = CDC_RNDIS_STATUS_FAILURE; + break; + } + + /* Setup the response buffer content */ + QueryResponse->MsgType = CDC_RNDIS_QUERY_CMPLT_ID; + QueryResponse->MsgLength = QueryResponse->InfoBufLength + 24U; + QueryResponse->ReqId = ReqId; + QueryResponse->InfoBufOffset = 16U; + + /* Set Response Ready field in order to send response during next control request */ + hcdc->ResponseRdy = 1U; + + /* Send Notification on Interrupt EP to inform Host that response is ready */ + (void)USBD_CDC_RNDIS_SendNotification(pdev, RESPONSE_AVAILABLE, 0U, NULL); + + return(uint8_t)USBD_OK; +} + + +/** + * @brief USBD_CDC_RNDIS_ProcessSetMsg + * Parse, extract data and check correctness of CDC_RNDIS Set Message command. + * @param pdev: USB Device Handle pointer + * @param Msg: Pointer to the message data extracted from SendEncapsulated command + * @retval status + */ +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; + + /* Get and format the Msg input */ + USBD_CDC_RNDIS_SetMsgTypeDef *SetMessage = (USBD_CDC_RNDIS_SetMsgTypeDef *)Msg; + + /* Use same Msg input buffer as response buffer */ + USBD_CDC_RNDIS_SetCpltMsgTypeDef *SetResponse = (USBD_CDC_RNDIS_SetCpltMsgTypeDef *)Msg; + + /* Store the Message Request ID */ + uint32_t ReqId = SetMessage->ReqId; + + switch (SetMessage->Oid) + { + case OID_GEN_CURRENT_PACKET_FILTER: + /* Setup the packet filter value */ + hcdc->PacketFilter = SetMessage->InfoBuf[0]; + SetResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_802_3_MULTICAST_LIST: + /* List of multicast addresses on a miniport adapter */ + SetResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + default: + /* Report an error */ + SetResponse->Status = CDC_RNDIS_STATUS_FAILURE; + break; + } + + /* Prepare response buffer */ + SetResponse->MsgType = CDC_RNDIS_SET_CMPLT_ID; + SetResponse->MsgLength = sizeof(USBD_CDC_RNDIS_SetCpltMsgTypeDef); + SetResponse->ReqId = ReqId; + + /* Set Response Ready field in order to send response during next control request */ + hcdc->ResponseRdy = 1U; + + /* Send Notification on Interrupt EP to inform Host that response is ready */ + (void)USBD_CDC_RNDIS_SendNotification(pdev, RESPONSE_AVAILABLE, 0U, NULL); + + return (uint8_t)USBD_OK; +} + + +/** + * @brief USBD_CDC_RNDIS_ProcessResetMsg + * Parse, extract data and check correctness of CDC_RNDIS Set Message command. + * @param pdev: USB Device Handle pointer + * @param Msg: Pointer to the message data extracted from SendEncapsulated command + * @retval status + */ +static uint8_t USBD_CDC_RNDIS_ProcessResetMsg(USBD_HandleTypeDef *pdev, + USBD_CDC_RNDIS_ResetMsgTypeDef *Msg) +{ + /* 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; + /* Use same Msg input buffer as response buffer */ + USBD_CDC_RNDIS_ResetCpltMsgTypeDef *ResetResponse = (USBD_CDC_RNDIS_ResetCpltMsgTypeDef *)Msg; + + if ((ResetMessage->MsgLength != sizeof(USBD_CDC_RNDIS_ResetMsgTypeDef)) || \ + (ResetMessage->Reserved != 0U)) + { + ResetResponse->Status = CDC_RNDIS_STATUS_FAILURE; + } + else + { + ResetResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + } + + /* Prepare response buffer */ + ResetResponse->MsgType = CDC_RNDIS_RESET_CMPLT_ID; + ResetResponse->MsgLength = sizeof(USBD_CDC_RNDIS_ResetCpltMsgTypeDef); + ResetResponse->AddrReset = 0U; + + /* Set CDC_RNDIS state to INITIALIZED */ + hcdc->State = CDC_RNDIS_STATE_BUS_INITIALIZED; + hcdc->LinkStatus = 0U; + + /* Set Response Ready field in order to send response during next control request */ + hcdc->ResponseRdy = 1U; + + /* Send Notification on Interrupt EP to inform Host that response is ready */ + (void)USBD_CDC_RNDIS_SendNotification(pdev, RESPONSE_AVAILABLE, 0U, NULL); + + return (uint8_t)USBD_OK; +} + + +/** + * @brief USBD_CDC_RNDIS_ProcessPacketMsg + * Parse, extract data and check correctness of CDC_RNDIS Data Packet. + * @param pdev: USB Device Handle pointer + * @param Msg: Pointer to the message data extracted from Packet + * @retval status + */ +static uint8_t USBD_CDC_RNDIS_ProcessPacketMsg(USBD_HandleTypeDef *pdev, + USBD_CDC_RNDIS_PacketMsgTypeDef *Msg) +{ + uint32_t tmp1, tmp2; + + /* Get the CDC_RNDIS handle pointer */ + USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + + /* Get and format the Msg input */ + USBD_CDC_RNDIS_PacketMsgTypeDef *PacketMsg = (USBD_CDC_RNDIS_PacketMsgTypeDef *)Msg; + + /* Check correctness of the message */ + if ((PacketMsg->MsgType != CDC_RNDIS_PACKET_MSG_ID)) + { + return (uint8_t)USBD_FAIL; + } + + /* Point to the payload and udpate the message length */ + + /* Use temporary storage variables to comply with MISRA-C 2012 rule of (+) operand allowed types */ + tmp1 = (uint32_t)PacketMsg; + tmp2 = (uint32_t)(PacketMsg->DataOffset); + hcdc->RxBuffer = (uint8_t *)(tmp1 + tmp2 + CDC_RNDIS_PCKTMSG_DATAOFFSET_OFFSET); + hcdc->RxLength = PacketMsg->DataLength; + + /* Process data by application */ + ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength); + + return (uint8_t)USBD_OK; +} + + +/** +* @brief USBD_CDC_RNDIS_ProcessUnsupportedMsg +* Parse, extract data and check correctness of CDC_RNDIS KeepAlive command. +* @param pdev: USB Device Handle pointer +* @param Msg: Pointer to the message data extracted from SendEncapsulated command +* @retval status +*/ +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; + + /* Use same Msg input buffer as response buffer */ + USBD_CDC_RNDIS_StsChangeMsgTypeDef *Response = (USBD_CDC_RNDIS_StsChangeMsgTypeDef *)Msg; + + /* Setup the response buffer content */ + Response->MsgType = CDC_RNDIS_INDICATE_STATUS_MSG_ID; + Response->MsgLength = sizeof(USBD_CDC_RNDIS_StsChangeMsgTypeDef); + Response->Status = CDC_RNDIS_STATUS_NOT_SUPPORTED; + Response->StsBufLength = 0U; + Response->StsBufOffset = 20U; + + /* Set Response Ready field in order to send response during next control request */ + hcdc->ResponseRdy = 1U; + + /* Send Notification on Interrupt EP to inform Host that response is ready */ + (void)USBD_CDC_RNDIS_SendNotification(pdev, RESPONSE_AVAILABLE, 0U, NULL); + + UNUSED(Msg); + + return (uint8_t)USBD_OK; +} + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Class/CDC_RNDIS/Src/usbd_cdc_rndis_if_template.c b/Class/CDC_RNDIS/Src/usbd_cdc_rndis_if_template.c new file mode 100644 index 0000000..9408d43 --- /dev/null +++ b/Class/CDC_RNDIS/Src/usbd_cdc_rndis_if_template.c @@ -0,0 +1,233 @@ +/** + ****************************************************************************** + * @file usbd_cdc_rndis_if_template.c + * @author MCD Application Team + * @brief Source file for USBD CDC_RNDIS interface template + ****************************************************************************** + * @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 ------------------------------------------------------------------*/ + +/* Include TCP/IP stack header files */ +/* +#include "lwip/opt.h" +#include "lwip/init.h" +#include "lwip/dhcp.h" +#include "lwip/netif.h" +#include "lwip/timeouts.h" +#include "netif/etharp.h" +#include "http_cgi_ssi.h" +#include "ethernetif.h" +*/ + +#include "main.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +#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 */ + +#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 */ + +static uint8_t CDC_RNDISInitialized = 0U; + +/* USB handler declaration */ +extern USBD_HandleTypeDef USBD_Device; + + +/* Private function prototypes -----------------------------------------------*/ +static int8_t CDC_RNDIS_Itf_Init(void); +static int8_t CDC_RNDIS_Itf_DeInit(void); +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 *pbuf, uint32_t *Len); +static int8_t CDC_RNDIS_Itf_TransmitCplt(uint8_t *pbuf, uint32_t *Len, uint8_t epnum); +static int8_t CDC_RNDIS_Itf_Process(USBD_HandleTypeDef *pdev); + +USBD_CDC_RNDIS_ItfTypeDef USBD_CDC_RNDIS_fops = +{ + CDC_RNDIS_Itf_Init, + CDC_RNDIS_Itf_DeInit, + CDC_RNDIS_Itf_Control, + CDC_RNDIS_Itf_Receive, + CDC_RNDIS_Itf_TransmitCplt, + CDC_RNDIS_Itf_Process, + (uint8_t *)CDC_RNDIS_MAC_STR_DESC, +}; + +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief CDC_RNDIS_Itf_Init + * Initializes the CDC_RNDIS media low layer + * @param None + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t CDC_RNDIS_Itf_Init(void) +{ + if (CDC_RNDISInitialized == 0U) + { + /* + Initialize the LwIP stack + Add your code here + + */ + + CDC_RNDISInitialized = 1U; + } + + /* Set Application Buffers */ + (void)USBD_CDC_RNDIS_SetTxBuffer(&USBD_Device, UserTxBuffer, 0U); + (void)USBD_CDC_RNDIS_SetRxBuffer(&USBD_Device, UserRxBuffer); + + return (0); +} + +/** + * @brief CDC_RNDIS_Itf_DeInit + * DeInitializes the CDC_RNDIS media low layer + * @param None + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t CDC_RNDIS_Itf_DeInit(void) +{ + USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *)(USBD_Device.pClassData); + + /* + Add your code here + */ + + /* Notify application layer that link is down */ + hcdc_cdc_rndis->LinkStatus = 0U; + + return (0); +} + +/** + * @brief CDC_RNDIS_Itf_Control + * Manage the CDC_RNDIS 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 int8_t CDC_RNDIS_Itf_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length) +{ + USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *)(USBD_Device.pClassData); + + switch (cmd) + { + case CDC_RNDIS_SEND_ENCAPSULATED_COMMAND: + /* Add your code here */ + break; + + case CDC_RNDIS_GET_ENCAPSULATED_RESPONSE: + /* Check if this is the first time we enter */ + if (hcdc_cdc_rndis->LinkStatus == 0U) + { + /* Setup the Link up at TCP/IP stack level */ + hcdc_cdc_rndis->LinkStatus = 1U; + /* + Add your code here + */ + } + /* Add your code here */ + break; + + default: + /* Add your code here */ + break; + } + + UNUSED(length); + UNUSED(pbuf); + + return (0); +} + +/** + * @brief CDC_RNDIS_Itf_Receive + * Data received over USB OUT endpoint are sent over CDC_RNDIS interface + * through this function. + * @param Buf: Buffer of data to be transmitted + * @param Len: Number of data received (in bytes) + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t CDC_RNDIS_Itf_Receive(uint8_t *Buf, uint32_t *Len) +{ + /* Get the CDC_RNDIS handler pointer */ + USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *)(USBD_Device.pClassData); + + /* Call Eth buffer processing */ + hcdc_cdc_rndis->RxState = 1U; + + UNUSED(Buf); + UNUSED(Len); + + return (0); +} + +/** + * @brief CDC_RNDIS_Itf_TransmitCplt + * Data transmited callback + * + * @note + * This function is IN transfer complete callback used to inform user that + * the submitted Data is successfully sent over USB. + * + * @param Buf: Buffer of data to be received + * @param Len: Number of data received (in bytes) + * @param epnum: EP number + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t CDC_RNDIS_Itf_TransmitCplt(uint8_t *Buf, uint32_t *Len, uint8_t epnum) +{ + UNUSED(Buf); + UNUSED(Len); + UNUSED(epnum); + + return (0); +} + +/** + * @brief CDC_RNDIS_Itf_Process + * Data received over USB OUT endpoint are sent over CDC_RNDIS interface + * through this function. + * @param pdef: pointer to the USB Device Handle + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +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); + + if ((hcdc_cdc_rndis != NULL) && (hcdc_cdc_rndis->LinkStatus != 0U)) + { + /* + Add your code here + Read a received packet from the Ethernet buffers and send it + to the lwIP for handling + */ + } + + return (0); +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Class/CustomHID/Inc/usbd_customhid.h b/Class/CustomHID/Inc/usbd_customhid.h index d461c01..a1dcd7c 100644 --- a/Class/CustomHID/Inc/usbd_customhid.h +++ b/Class/CustomHID/Inc/usbd_customhid.h @@ -41,41 +41,42 @@ extern "C" { /** @defgroup USBD_CUSTOM_HID_Exported_Defines * @{ */ -#define CUSTOM_HID_EPIN_ADDR 0x81U -#define CUSTOM_HID_EPIN_SIZE 0x02U +#define CUSTOM_HID_EPIN_ADDR 0x81U +#define CUSTOM_HID_EPIN_SIZE 0x02U -#define CUSTOM_HID_EPOUT_ADDR 0x01U -#define CUSTOM_HID_EPOUT_SIZE 0x02U +#define CUSTOM_HID_EPOUT_ADDR 0x01U +#define CUSTOM_HID_EPOUT_SIZE 0x02U -#define USB_CUSTOM_HID_CONFIG_DESC_SIZ 41U -#define USB_CUSTOM_HID_DESC_SIZ 9U +#define USB_CUSTOM_HID_CONFIG_DESC_SIZ 41U +#define USB_CUSTOM_HID_DESC_SIZ 9U #ifndef CUSTOM_HID_HS_BINTERVAL -#define CUSTOM_HID_HS_BINTERVAL 0x05U +#define CUSTOM_HID_HS_BINTERVAL 0x05U #endif /* CUSTOM_HID_HS_BINTERVAL */ #ifndef CUSTOM_HID_FS_BINTERVAL -#define CUSTOM_HID_FS_BINTERVAL 0x05U +#define CUSTOM_HID_FS_BINTERVAL 0x05U #endif /* CUSTOM_HID_FS_BINTERVAL */ #ifndef USBD_CUSTOMHID_OUTREPORT_BUF_SIZE -#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE 0x02U +#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE 0x02U #endif /* USBD_CUSTOMHID_OUTREPORT_BUF_SIZE */ + #ifndef USBD_CUSTOM_HID_REPORT_DESC_SIZE -#define USBD_CUSTOM_HID_REPORT_DESC_SIZE 163U +#define USBD_CUSTOM_HID_REPORT_DESC_SIZE 163U #endif /* USBD_CUSTOM_HID_REPORT_DESC_SIZE */ -#define CUSTOM_HID_DESCRIPTOR_TYPE 0x21U -#define CUSTOM_HID_REPORT_DESC 0x22U +#define CUSTOM_HID_DESCRIPTOR_TYPE 0x21U +#define CUSTOM_HID_REPORT_DESC 0x22U -#define CUSTOM_HID_REQ_SET_PROTOCOL 0x0BU -#define CUSTOM_HID_REQ_GET_PROTOCOL 0x03U +#define CUSTOM_HID_REQ_SET_PROTOCOL 0x0BU +#define CUSTOM_HID_REQ_GET_PROTOCOL 0x03U -#define CUSTOM_HID_REQ_SET_IDLE 0x0AU -#define CUSTOM_HID_REQ_GET_IDLE 0x02U +#define CUSTOM_HID_REQ_SET_IDLE 0x0AU +#define CUSTOM_HID_REQ_GET_IDLE 0x02U -#define CUSTOM_HID_REQ_SET_REPORT 0x09U -#define CUSTOM_HID_REQ_GET_REPORT 0x01U +#define CUSTOM_HID_REQ_SET_REPORT 0x09U +#define CUSTOM_HID_REQ_GET_REPORT 0x01U /** * @} */ @@ -88,12 +89,11 @@ typedef enum { CUSTOM_HID_IDLE = 0U, CUSTOM_HID_BUSY, -} -CUSTOM_HID_StateTypeDef; +} CUSTOM_HID_StateTypeDef; typedef struct _USBD_CUSTOM_HID_Itf { - uint8_t *pReport; + uint8_t *pReport; int8_t (* Init)(void); int8_t (* DeInit)(void); int8_t (* OutEvent)(uint8_t event_idx, uint8_t state); @@ -102,14 +102,13 @@ typedef struct _USBD_CUSTOM_HID_Itf typedef struct { - uint8_t Report_buf[USBD_CUSTOMHID_OUTREPORT_BUF_SIZE]; - uint32_t Protocol; - uint32_t IdleState; - uint32_t AltSetting; - uint32_t IsReportAvailable; - CUSTOM_HID_StateTypeDef state; -} -USBD_CUSTOM_HID_HandleTypeDef; + uint8_t Report_buf[USBD_CUSTOMHID_OUTREPORT_BUF_SIZE]; + uint32_t Protocol; + uint32_t IdleState; + uint32_t AltSetting; + uint32_t IsReportAvailable; + CUSTOM_HID_StateTypeDef state; +} USBD_CUSTOM_HID_HandleTypeDef; /** * @} */ @@ -128,8 +127,8 @@ USBD_CUSTOM_HID_HandleTypeDef; * @{ */ -extern USBD_ClassTypeDef USBD_CUSTOM_HID; -#define USBD_CUSTOM_HID_CLASS &USBD_CUSTOM_HID +extern USBD_ClassTypeDef USBD_CUSTOM_HID; +#define USBD_CUSTOM_HID_CLASS &USBD_CUSTOM_HID /** * @} */ @@ -138,13 +137,12 @@ extern USBD_ClassTypeDef USBD_CUSTOM_HID; * @{ */ uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev, - uint8_t *report, - uint16_t len); + uint8_t *report, uint16_t len); +uint8_t USBD_CUSTOM_HID_ReceivePacket(USBD_HandleTypeDef *pdev); - -uint8_t USBD_CUSTOM_HID_RegisterInterface(USBD_HandleTypeDef *pdev, - USBD_CUSTOM_HID_ItfTypeDef *fops); +uint8_t USBD_CUSTOM_HID_RegisterInterface(USBD_HandleTypeDef *pdev, + USBD_CUSTOM_HID_ItfTypeDef *fops); /** * @} diff --git a/Class/CustomHID/Src/usbd_customhid.c b/Class/CustomHID/Src/usbd_customhid.c index 8998070..2680274 100644 --- a/Class/CustomHID/Src/usbd_customhid.c +++ b/Class/CustomHID/Src/usbd_customhid.c @@ -84,28 +84,19 @@ EndBSPDependencies */ * @{ */ +static uint8_t USBD_CUSTOM_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +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); -static uint8_t USBD_CUSTOM_HID_Init(USBD_HandleTypeDef *pdev, - uint8_t cfgidx); +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); -static uint8_t USBD_CUSTOM_HID_DeInit(USBD_HandleTypeDef *pdev, - uint8_t cfgidx); +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); -static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req); - -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); - -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); /** * @} */ @@ -135,177 +126,174 @@ USBD_ClassTypeDef USBD_CUSTOM_HID = /* USB CUSTOM_HID device FS Configuration Descriptor */ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgFSDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END = { - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + 0x09, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ USB_CUSTOM_HID_CONFIG_DESC_SIZ, - /* wTotalLength: Bytes returned */ + /* wTotalLength: Bytes returned */ 0x00, - 0x01, /*bNumInterfaces: 1 interface*/ - 0x01, /*bConfigurationValue: Configuration value*/ - 0x00, /*iConfiguration: Index of string descriptor describing - the configuration*/ - 0xC0, /*bmAttributes: bus powered */ - 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ + 0x01, /* bNumInterfaces: 1 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ + 0xC0, /* bmAttributes: bus powered */ + 0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */ /************** Descriptor of CUSTOM HID interface ****************/ /* 09 */ - 0x09, /*bLength: Interface Descriptor size*/ - USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/ - 0x00, /*bInterfaceNumber: Number of Interface*/ - 0x00, /*bAlternateSetting: Alternate setting*/ - 0x02, /*bNumEndpoints*/ - 0x03, /*bInterfaceClass: CUSTOM_HID*/ - 0x00, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/ - 0x00, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/ - 0, /*iInterface: Index of string descriptor*/ + 0x09, /* bLength: Interface Descriptor size*/ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints*/ + 0x03, /* bInterfaceClass: CUSTOM_HID */ + 0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ + 0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ + 0x00, /* iInterface: Index of string descriptor */ /******************** Descriptor of CUSTOM_HID *************************/ /* 18 */ - 0x09, /*bLength: CUSTOM_HID Descriptor size*/ - CUSTOM_HID_DESCRIPTOR_TYPE, /*bDescriptorType: CUSTOM_HID*/ - 0x11, /*bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number*/ + 0x09, /* bLength: CUSTOM_HID Descriptor size */ + CUSTOM_HID_DESCRIPTOR_TYPE, /* bDescriptorType: CUSTOM_HID */ + 0x11, /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */ 0x01, - 0x00, /*bCountryCode: Hardware target country*/ - 0x01, /*bNumDescriptors: Number of CUSTOM_HID class descriptors to follow*/ - 0x22, /*bDescriptorType*/ - USBD_CUSTOM_HID_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/ + 0x00, /* bCountryCode: Hardware target country */ + 0x01, /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */ + 0x22, /* bDescriptorType */ + USBD_CUSTOM_HID_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ 0x00, /******************** Descriptor of Custom HID endpoints ********************/ /* 27 */ - 0x07, /*bLength: Endpoint Descriptor size*/ - USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ - CUSTOM_HID_EPIN_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/ - 0x03, /*bmAttributes: Interrupt endpoint*/ - CUSTOM_HID_EPIN_SIZE, /*wMaxPacketSize: 2 Byte max */ + CUSTOM_HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ + 0x03, /* bmAttributes: Interrupt endpoint */ + CUSTOM_HID_EPIN_SIZE, /* wMaxPacketSize: 2 Byte max */ 0x00, - CUSTOM_HID_FS_BINTERVAL, /*bInterval: Polling Interval */ + CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval */ /* 34 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ - CUSTOM_HID_EPOUT_ADDR, /*bEndpointAddress: Endpoint Address (OUT)*/ - 0x03, /* bmAttributes: Interrupt endpoint */ - CUSTOM_HID_EPOUT_SIZE, /* wMaxPacketSize: 2 Bytes max */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ + CUSTOM_HID_EPOUT_ADDR, /* bEndpointAddress: Endpoint Address (OUT) */ + 0x03, /* bmAttributes: Interrupt endpoint */ + CUSTOM_HID_EPOUT_SIZE, /* wMaxPacketSize: 2 Bytes max */ 0x00, - CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval */ + CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval */ /* 41 */ }; /* USB CUSTOM_HID device HS Configuration Descriptor */ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgHSDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END = { - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + 0x09, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ USB_CUSTOM_HID_CONFIG_DESC_SIZ, - /* wTotalLength: Bytes returned */ + /* wTotalLength: Bytes returned */ 0x00, - 0x01, /*bNumInterfaces: 1 interface*/ - 0x01, /*bConfigurationValue: Configuration value*/ - 0x00, /*iConfiguration: Index of string descriptor describing - the configuration*/ - 0xC0, /*bmAttributes: bus powered */ - 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ + 0x01, /* bNumInterfaces: 1 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ + 0xC0, /* bmAttributes: bus powered */ + 0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */ /************** Descriptor of CUSTOM HID interface ****************/ /* 09 */ - 0x09, /*bLength: Interface Descriptor size*/ - USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/ - 0x00, /*bInterfaceNumber: Number of Interface*/ - 0x00, /*bAlternateSetting: Alternate setting*/ - 0x02, /*bNumEndpoints*/ - 0x03, /*bInterfaceClass: CUSTOM_HID*/ - 0x00, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/ - 0x00, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/ - 0, /*iInterface: Index of string descriptor*/ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints */ + 0x03, /* bInterfaceClass: CUSTOM_HID */ + 0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ + 0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ + 0, /* iInterface: Index of string descriptor */ /******************** Descriptor of CUSTOM_HID *************************/ /* 18 */ - 0x09, /*bLength: CUSTOM_HID Descriptor size*/ - CUSTOM_HID_DESCRIPTOR_TYPE, /*bDescriptorType: CUSTOM_HID*/ - 0x11, /*bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number*/ + 0x09, /* bLength: CUSTOM_HID Descriptor size */ + CUSTOM_HID_DESCRIPTOR_TYPE, /* bDescriptorType: CUSTOM_HID */ + 0x11, /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */ 0x01, - 0x00, /*bCountryCode: Hardware target country*/ - 0x01, /*bNumDescriptors: Number of CUSTOM_HID class descriptors to follow*/ - 0x22, /*bDescriptorType*/ - USBD_CUSTOM_HID_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/ + 0x00, /* bCountryCode: Hardware target country */ + 0x01, /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */ + 0x22, /* bDescriptorType */ + USBD_CUSTOM_HID_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ 0x00, /******************** Descriptor of Custom HID endpoints ********************/ /* 27 */ - 0x07, /*bLength: Endpoint Descriptor size*/ - USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ - CUSTOM_HID_EPIN_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/ - 0x03, /*bmAttributes: Interrupt endpoint*/ - CUSTOM_HID_EPIN_SIZE, /*wMaxPacketSize: 2 Byte max */ + CUSTOM_HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ + 0x03, /* bmAttributes: Interrupt endpoint */ + CUSTOM_HID_EPIN_SIZE, /* wMaxPacketSize: 2 Byte max */ 0x00, - CUSTOM_HID_HS_BINTERVAL, /*bInterval: Polling Interval */ + CUSTOM_HID_HS_BINTERVAL, /* bInterval: Polling Interval */ /* 34 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ - CUSTOM_HID_EPOUT_ADDR, /*bEndpointAddress: Endpoint Address (OUT)*/ - 0x03, /* bmAttributes: Interrupt endpoint */ - CUSTOM_HID_EPOUT_SIZE, /* wMaxPacketSize: 2 Bytes max */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ + CUSTOM_HID_EPOUT_ADDR, /* bEndpointAddress: Endpoint Address (OUT) */ + 0x03, /* bmAttributes: Interrupt endpoint */ + CUSTOM_HID_EPOUT_SIZE, /* wMaxPacketSize: 2 Bytes max */ 0x00, - CUSTOM_HID_HS_BINTERVAL, /* bInterval: Polling Interval */ + CUSTOM_HID_HS_BINTERVAL, /* bInterval: Polling Interval */ /* 41 */ }; /* USB CUSTOM_HID device Other Speed Configuration Descriptor */ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_OtherSpeedCfgDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END = { - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + 0x09, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ USB_CUSTOM_HID_CONFIG_DESC_SIZ, - /* wTotalLength: Bytes returned */ + /* wTotalLength: Bytes returned */ 0x00, - 0x01, /*bNumInterfaces: 1 interface*/ - 0x01, /*bConfigurationValue: Configuration value*/ - 0x00, /*iConfiguration: Index of string descriptor describing - the configuration*/ - 0xC0, /*bmAttributes: bus powered */ - 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ + 0x01, /* bNumInterfaces: 1 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ + 0xC0, /* bmAttributes: bus powered */ + 0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */ /************** Descriptor of CUSTOM HID interface ****************/ /* 09 */ - 0x09, /*bLength: Interface Descriptor size*/ - USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/ - 0x00, /*bInterfaceNumber: Number of Interface*/ - 0x00, /*bAlternateSetting: Alternate setting*/ - 0x02, /*bNumEndpoints*/ - 0x03, /*bInterfaceClass: CUSTOM_HID*/ - 0x00, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/ - 0x00, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/ - 0, /*iInterface: Index of string descriptor*/ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints */ + 0x03, /* bInterfaceClass: CUSTOM_HID */ + 0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ + 0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ + 0, /* iInterface: Index of string descriptor */ /******************** Descriptor of CUSTOM_HID *************************/ /* 18 */ - 0x09, /*bLength: CUSTOM_HID Descriptor size*/ - CUSTOM_HID_DESCRIPTOR_TYPE, /*bDescriptorType: CUSTOM_HID*/ - 0x11, /*bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number*/ + 0x09, /* bLength: CUSTOM_HID Descriptor size */ + CUSTOM_HID_DESCRIPTOR_TYPE, /* bDescriptorType: CUSTOM_HID */ + 0x11, /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */ 0x01, - 0x00, /*bCountryCode: Hardware target country*/ - 0x01, /*bNumDescriptors: Number of CUSTOM_HID class descriptors to follow*/ - 0x22, /*bDescriptorType*/ - USBD_CUSTOM_HID_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/ + 0x00, /* bCountryCode: Hardware target country */ + 0x01, /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */ + 0x22, /* bDescriptorType */ + USBD_CUSTOM_HID_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ 0x00, /******************** Descriptor of Custom HID endpoints ********************/ /* 27 */ - 0x07, /*bLength: Endpoint Descriptor size*/ - USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ - CUSTOM_HID_EPIN_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/ - 0x03, /*bmAttributes: Interrupt endpoint*/ - CUSTOM_HID_EPIN_SIZE, /*wMaxPacketSize: 2 Byte max */ + CUSTOM_HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ + 0x03, /* bmAttributes: Interrupt endpoint */ + CUSTOM_HID_EPIN_SIZE, /* wMaxPacketSize: 2 Byte max */ 0x00, - CUSTOM_HID_FS_BINTERVAL, /*bInterval: Polling Interval */ + CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval */ /* 34 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ - CUSTOM_HID_EPOUT_ADDR, /*bEndpointAddress: Endpoint Address (OUT)*/ - 0x03, /* bmAttributes: Interrupt endpoint */ - CUSTOM_HID_EPOUT_SIZE, /* wMaxPacketSize: 2 Bytes max */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ + CUSTOM_HID_EPOUT_ADDR, /* bEndpointAddress: Endpoint Address (OUT) */ + 0x03, /* bmAttributes: Interrupt endpoint */ + CUSTOM_HID_EPOUT_SIZE, /* wMaxPacketSize: 2 Bytes max */ 0x00, - CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval */ + CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval */ /* 41 */ }; @@ -313,14 +301,14 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_OtherSpeedCfgDesc[USB_CUSTOM_HID_CO __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_Desc[USB_CUSTOM_HID_DESC_SIZ] __ALIGN_END = { /* 18 */ - 0x09, /*bLength: CUSTOM_HID Descriptor size*/ - CUSTOM_HID_DESCRIPTOR_TYPE, /*bDescriptorType: CUSTOM_HID*/ - 0x11, /*bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number*/ + 0x09, /* bLength: CUSTOM_HID Descriptor size */ + CUSTOM_HID_DESCRIPTOR_TYPE, /* bDescriptorType: CUSTOM_HID */ + 0x11, /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */ 0x01, - 0x00, /*bCountryCode: Hardware target country*/ - 0x01, /*bNumDescriptors: Number of CUSTOM_HID class descriptors to follow*/ - 0x22, /*bDescriptorType*/ - USBD_CUSTOM_HID_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/ + 0x00, /* 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, }; @@ -354,43 +342,53 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_DeviceQualifierDesc[USB_LEN_DEV_QUA * @param cfgidx: Configuration index * @retval status */ -static uint8_t USBD_CUSTOM_HID_Init(USBD_HandleTypeDef *pdev, - uint8_t cfgidx) +static uint8_t USBD_CUSTOM_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { - uint8_t ret = 0U; - USBD_CUSTOM_HID_HandleTypeDef *hhid; + UNUSED(cfgidx); + USBD_CUSTOM_HID_HandleTypeDef *hhid; + + hhid = USBD_malloc(sizeof(USBD_CUSTOM_HID_HandleTypeDef)); + + if (hhid == NULL) + { + pdev->pClassData = NULL; + return (uint8_t)USBD_EMEM; + } + + pdev->pClassData = (void *)hhid; + + 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; + } + 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; + } /* Open EP IN */ - USBD_LL_OpenEP(pdev, CUSTOM_HID_EPIN_ADDR, USBD_EP_TYPE_INTR, - CUSTOM_HID_EPIN_SIZE); + (void)USBD_LL_OpenEP(pdev, CUSTOM_HID_EPIN_ADDR, USBD_EP_TYPE_INTR, + CUSTOM_HID_EPIN_SIZE); pdev->ep_in[CUSTOM_HID_EPIN_ADDR & 0xFU].is_used = 1U; /* Open EP OUT */ - USBD_LL_OpenEP(pdev, CUSTOM_HID_EPOUT_ADDR, USBD_EP_TYPE_INTR, - CUSTOM_HID_EPOUT_SIZE); + (void)USBD_LL_OpenEP(pdev, CUSTOM_HID_EPOUT_ADDR, USBD_EP_TYPE_INTR, + CUSTOM_HID_EPOUT_SIZE); pdev->ep_out[CUSTOM_HID_EPOUT_ADDR & 0xFU].is_used = 1U; - pdev->pClassData = USBD_malloc(sizeof(USBD_CUSTOM_HID_HandleTypeDef)); + hhid->state = CUSTOM_HID_IDLE; - if (pdev->pClassData == NULL) - { - ret = 1U; - } - else - { - hhid = (USBD_CUSTOM_HID_HandleTypeDef *) pdev->pClassData; + ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->Init(); - hhid->state = CUSTOM_HID_IDLE; - ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->Init(); + /* Prepare Out endpoint to receive 1st packet */ + (void)USBD_LL_PrepareReceive(pdev, CUSTOM_HID_EPOUT_ADDR, hhid->Report_buf, + USBD_CUSTOMHID_OUTREPORT_BUF_SIZE); - /* Prepare Out endpoint to receive 1st packet */ - USBD_LL_PrepareReceive(pdev, CUSTOM_HID_EPOUT_ADDR, hhid->Report_buf, - USBD_CUSTOMHID_OUTREPORT_BUF_SIZE); - } - - return ret; + return (uint8_t)USBD_OK; } /** @@ -400,16 +398,19 @@ static uint8_t USBD_CUSTOM_HID_Init(USBD_HandleTypeDef *pdev, * @param cfgidx: Configuration index * @retval status */ -static uint8_t USBD_CUSTOM_HID_DeInit(USBD_HandleTypeDef *pdev, - uint8_t cfgidx) +static uint8_t USBD_CUSTOM_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { + UNUSED(cfgidx); + /* Close CUSTOM_HID EP IN */ - USBD_LL_CloseEP(pdev, CUSTOM_HID_EPIN_ADDR); + (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; /* Close CUSTOM_HID EP OUT */ - USBD_LL_CloseEP(pdev, CUSTOM_HID_EPOUT_ADDR); + (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; /* FRee allocated memory */ if (pdev->pClassData != NULL) @@ -418,7 +419,8 @@ static uint8_t USBD_CUSTOM_HID_DeInit(USBD_HandleTypeDef *pdev, USBD_free(pdev->pClassData); pdev->pClassData = NULL; } - return USBD_OK; + + return (uint8_t)USBD_OK; } /** @@ -428,118 +430,121 @@ static uint8_t USBD_CUSTOM_HID_DeInit(USBD_HandleTypeDef *pdev, * @param req: usb requests * @retval status */ -static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req) +static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req) { USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData; uint16_t len = 0U; uint8_t *pbuf = NULL; uint16_t status_info = 0U; - uint8_t ret = USBD_OK; + USBD_StatusTypeDef ret = USBD_OK; switch (req->bmRequest & USB_REQ_TYPE_MASK) { - case USB_REQ_TYPE_CLASS : - switch (req->bRequest) - { - case CUSTOM_HID_REQ_SET_PROTOCOL: - hhid->Protocol = (uint8_t)(req->wValue); - break; - - case CUSTOM_HID_REQ_GET_PROTOCOL: - USBD_CtlSendData(pdev, (uint8_t *)(void *)&hhid->Protocol, 1U); - break; - - case CUSTOM_HID_REQ_SET_IDLE: - hhid->IdleState = (uint8_t)(req->wValue >> 8); - break; - - case CUSTOM_HID_REQ_GET_IDLE: - USBD_CtlSendData(pdev, (uint8_t *)(void *)&hhid->IdleState, 1U); - break; - - case CUSTOM_HID_REQ_SET_REPORT: - hhid->IsReportAvailable = 1U; - USBD_CtlPrepareRx(pdev, hhid->Report_buf, req->wLength); - break; - - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; - } + case USB_REQ_TYPE_CLASS: + switch (req->bRequest) + { + case CUSTOM_HID_REQ_SET_PROTOCOL: + hhid->Protocol = (uint8_t)(req->wValue); break; - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_STATUS: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - USBD_CtlSendData(pdev, (uint8_t *)(void *)&status_info, 2U); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; + case CUSTOM_HID_REQ_GET_PROTOCOL: + (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->Protocol, 1U); + break; - case USB_REQ_GET_DESCRIPTOR: - 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; - } - else - { - if (req->wValue >> 8 == CUSTOM_HID_DESCRIPTOR_TYPE) - { - pbuf = USBD_CUSTOM_HID_Desc; - len = MIN(USB_CUSTOM_HID_DESC_SIZ, req->wLength); - } - } + case CUSTOM_HID_REQ_SET_IDLE: + hhid->IdleState = (uint8_t)(req->wValue >> 8); + break; - USBD_CtlSendData(pdev, pbuf, len); - break; + case CUSTOM_HID_REQ_GET_IDLE: + (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->IdleState, 1U); + break; - case USB_REQ_GET_INTERFACE : - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - USBD_CtlSendData(pdev, (uint8_t *)(void *)&hhid->AltSetting, 1U); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; - - case USB_REQ_SET_INTERFACE : - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - hhid->AltSetting = (uint8_t)(req->wValue); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; - - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; - } + case CUSTOM_HID_REQ_SET_REPORT: + hhid->IsReportAvailable = 1U; + (void)USBD_CtlPrepareRx(pdev, hhid->Report_buf, req->wLength); break; default: USBD_CtlError(pdev, req); ret = USBD_FAIL; break; + } + break; + + 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_DESCRIPTOR: + 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; + } + else + { + if ((req->wValue >> 8) == CUSTOM_HID_DESCRIPTOR_TYPE) + { + pbuf = USBD_CUSTOM_HID_Desc; + len = MIN(USB_CUSTOM_HID_DESC_SIZ, req->wLength); + } + } + + (void)USBD_CtlSendData(pdev, pbuf, len); + break; + + case USB_REQ_GET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->AltSetting, 1U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_SET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + hhid->AltSetting = (uint8_t)(req->wValue); + } + else + { + 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 ret; + return (uint8_t)ret; } /** @@ -549,25 +554,31 @@ static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev, * @param buff: pointer to report * @retval status */ -uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev, - uint8_t *report, - uint16_t len) +uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev, + uint8_t *report, uint16_t len) { - USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData; + USBD_CUSTOM_HID_HandleTypeDef *hhid; + + if (pdev->pClassData == NULL) + { + return (uint8_t)USBD_FAIL; + } + + hhid = (USBD_CUSTOM_HID_HandleTypeDef*)pdev->pClassData; if (pdev->dev_state == USBD_STATE_CONFIGURED) { if (hhid->state == CUSTOM_HID_IDLE) { hhid->state = CUSTOM_HID_BUSY; - USBD_LL_Transmit(pdev, CUSTOM_HID_EPIN_ADDR, report, len); + (void)USBD_LL_Transmit(pdev, CUSTOM_HID_EPIN_ADDR, report, len); } else { - return USBD_BUSY; + return (uint8_t)USBD_BUSY; } } - return USBD_OK; + return (uint8_t)USBD_OK; } /** @@ -577,9 +588,10 @@ uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev, * @param length : pointer data length * @retval pointer to descriptor buffer */ -static uint8_t *USBD_CUSTOM_HID_GetFSCfgDesc(uint16_t *length) +static uint8_t *USBD_CUSTOM_HID_GetFSCfgDesc(uint16_t *length) { - *length = sizeof(USBD_CUSTOM_HID_CfgFSDesc); + *length = (uint16_t)sizeof(USBD_CUSTOM_HID_CfgFSDesc); + return USBD_CUSTOM_HID_CfgFSDesc; } @@ -590,9 +602,10 @@ static uint8_t *USBD_CUSTOM_HID_GetFSCfgDesc(uint16_t *length) * @param length : pointer data length * @retval pointer to descriptor buffer */ -static uint8_t *USBD_CUSTOM_HID_GetHSCfgDesc(uint16_t *length) +static uint8_t *USBD_CUSTOM_HID_GetHSCfgDesc(uint16_t *length) { - *length = sizeof(USBD_CUSTOM_HID_CfgHSDesc); + *length = (uint16_t)sizeof(USBD_CUSTOM_HID_CfgHSDesc); + return USBD_CUSTOM_HID_CfgHSDesc; } @@ -603,9 +616,10 @@ static uint8_t *USBD_CUSTOM_HID_GetHSCfgDesc(uint16_t *length) * @param length : pointer data length * @retval pointer to descriptor buffer */ -static uint8_t *USBD_CUSTOM_HID_GetOtherSpeedCfgDesc(uint16_t *length) +static uint8_t *USBD_CUSTOM_HID_GetOtherSpeedCfgDesc(uint16_t *length) { - *length = sizeof(USBD_CUSTOM_HID_OtherSpeedCfgDesc); + *length = (uint16_t)sizeof(USBD_CUSTOM_HID_OtherSpeedCfgDesc); + return USBD_CUSTOM_HID_OtherSpeedCfgDesc; } @@ -616,14 +630,15 @@ static uint8_t *USBD_CUSTOM_HID_GetOtherSpeedCfgDesc(uint16_t *length) * @param epnum: endpoint index * @retval status */ -static uint8_t USBD_CUSTOM_HID_DataIn(USBD_HandleTypeDef *pdev, - uint8_t epnum) +static uint8_t USBD_CUSTOM_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_CUSTOM_HID_HandleTypeDef *)pdev->pClassData)->state = CUSTOM_HID_IDLE; - return USBD_OK; + return (uint8_t)USBD_OK; } /** @@ -633,21 +648,52 @@ static uint8_t USBD_CUSTOM_HID_DataIn(USBD_HandleTypeDef *pdev, * @param epnum: endpoint index * @retval status */ -static uint8_t USBD_CUSTOM_HID_DataOut(USBD_HandleTypeDef *pdev, - uint8_t epnum) +static uint8_t USBD_CUSTOM_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) { + UNUSED(epnum); + USBD_CUSTOM_HID_HandleTypeDef *hhid; - USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData; + if (pdev->pClassData == NULL) + { + return (uint8_t)USBD_FAIL; + } + hhid = (USBD_CUSTOM_HID_HandleTypeDef*)pdev->pClassData; + + /* 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_LL_PrepareReceive(pdev, CUSTOM_HID_EPOUT_ADDR, hhid->Report_buf, - USBD_CUSTOMHID_OUTREPORT_BUF_SIZE); - - return USBD_OK; + return (uint8_t)USBD_OK; } + +/** + * @brief USBD_CUSTOM_HID_ReceivePacket + * prepare OUT Endpoint for reception + * @param pdev: device instance + * @retval status + */ +uint8_t USBD_CUSTOM_HID_ReceivePacket(USBD_HandleTypeDef *pdev) +{ + USBD_CUSTOM_HID_HandleTypeDef *hhid; + + if (pdev->pClassData == NULL) + { + return (uint8_t)USBD_FAIL; + } + + hhid = (USBD_CUSTOM_HID_HandleTypeDef*)pdev->pClassData; + + /* Resume USB Out process */ + (void)USBD_LL_PrepareReceive(pdev, CUSTOM_HID_EPOUT_ADDR, hhid->Report_buf, + USBD_CUSTOMHID_OUTREPORT_BUF_SIZE); + + return (uint8_t)USBD_OK; +} + + /** * @brief USBD_CUSTOM_HID_EP0_RxReady * Handles control request data. @@ -656,7 +702,7 @@ static uint8_t USBD_CUSTOM_HID_DataOut(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->pClassData; if (hhid->IsReportAvailable == 1U) { @@ -665,7 +711,7 @@ static uint8_t USBD_CUSTOM_HID_EP0_RxReady(USBD_HandleTypeDef *pdev) hhid->IsReportAvailable = 0U; } - return USBD_OK; + return (uint8_t)USBD_OK; } /** @@ -674,9 +720,10 @@ static uint8_t USBD_CUSTOM_HID_EP0_RxReady(USBD_HandleTypeDef *pdev) * @param length : pointer data length * @retval pointer to descriptor buffer */ -static uint8_t *USBD_CUSTOM_HID_GetDeviceQualifierDesc(uint16_t *length) +static uint8_t *USBD_CUSTOM_HID_GetDeviceQualifierDesc(uint16_t *length) { - *length = sizeof(USBD_CUSTOM_HID_DeviceQualifierDesc); + *length = (uint16_t)sizeof(USBD_CUSTOM_HID_DeviceQualifierDesc); + return USBD_CUSTOM_HID_DeviceQualifierDesc; } @@ -686,18 +733,17 @@ static uint8_t *USBD_CUSTOM_HID_GetDeviceQualifierDesc(uint16_t *length) * @param fops: CUSTOMHID Interface callback * @retval status */ -uint8_t USBD_CUSTOM_HID_RegisterInterface(USBD_HandleTypeDef *pdev, - USBD_CUSTOM_HID_ItfTypeDef *fops) +uint8_t USBD_CUSTOM_HID_RegisterInterface(USBD_HandleTypeDef *pdev, + USBD_CUSTOM_HID_ItfTypeDef *fops) { - uint8_t ret = USBD_FAIL; - - if (fops != NULL) + if (fops == NULL) { - pdev->pUserData = fops; - ret = USBD_OK; + return (uint8_t)USBD_FAIL; } - return ret; + pdev->pUserData = fops; + + return (uint8_t)USBD_OK; } /** * @} diff --git a/Class/CustomHID/Src/usbd_customhid_if_template.c b/Class/CustomHID/Src/usbd_customhid_if_template.c index 9f1fbf2..1fb6edd 100644 --- a/Class/CustomHID/Src/usbd_customhid_if_template.c +++ b/Class/CustomHID/Src/usbd_customhid_if_template.c @@ -53,7 +53,6 @@ USBD_CUSTOM_HID_ItfTypeDef USBD_CustomHID_template_fops = */ static int8_t TEMPLATE_CUSTOM_HID_Init(void) { - return (0); } @@ -81,6 +80,11 @@ static int8_t TEMPLATE_CUSTOM_HID_DeInit(void) */ static int8_t TEMPLATE_CUSTOM_HID_OutEvent(uint8_t event_idx, uint8_t state) { + UNUSED(event_idx); + UNUSED(state); + + /* Start next USB packet transfer once data processing is completed */ + USBD_CUSTOM_HID_ReceivePacket(&USBD_Device); return (0); } diff --git a/Class/DFU/Inc/usbd_dfu.h b/Class/DFU/Inc/usbd_dfu.h index 7b4035f..307c96d 100644 --- a/Class/DFU/Inc/usbd_dfu.h +++ b/Class/DFU/Inc/usbd_dfu.h @@ -115,7 +115,7 @@ extern "C" { /* Other defines */ /**************************************************/ /* Bit Detach capable = bit 3 in bmAttributes field */ -#define DFU_DETACH_MASK (uint8_t)(1 << 4) +#define DFU_DETACH_MASK (1U << 4) #define DFU_STATUS_DEPTH 6U typedef enum @@ -133,7 +133,7 @@ typedef void (*pFunction)(void); /********** Descriptor of DFU interface 0 Alternate setting n ****************/ -#define USBD_DFU_IF_DESC(n) 0x09, /* bLength: Interface Descriptor size */ \ +#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 */ \ @@ -162,20 +162,19 @@ typedef struct union { uint32_t d32[USBD_DFU_XFER_SIZE / 4U]; - uint8_t d8[USBD_DFU_XFER_SIZE]; + uint8_t d8[USBD_DFU_XFER_SIZE]; } buffer; - uint32_t wblock_num; - uint32_t wlength; - uint32_t data_ptr; - uint32_t alt_setting; + uint32_t wblock_num; + uint32_t wlength; + uint32_t data_ptr; + uint32_t alt_setting; - uint8_t dev_status[DFU_STATUS_DEPTH]; - uint8_t ReservedForAlign[2]; - uint8_t dev_state; - uint8_t manif_state; -} -USBD_DFU_HandleTypeDef; + uint8_t dev_status[DFU_STATUS_DEPTH]; + uint8_t ReservedForAlign[2]; + uint8_t dev_state; + uint8_t manif_state; +} USBD_DFU_HandleTypeDef; typedef struct { @@ -186,8 +185,7 @@ typedef struct uint16_t (* Write)(uint8_t *src, uint8_t *dest, uint32_t Len); 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; +} USBD_DFU_MediaTypeDef; /** * @} */ @@ -206,8 +204,8 @@ USBD_DFU_MediaTypeDef; * @{ */ -extern USBD_ClassTypeDef USBD_DFU; -#define USBD_DFU_CLASS &USBD_DFU +extern USBD_ClassTypeDef USBD_DFU; +#define USBD_DFU_CLASS &USBD_DFU /** * @} */ @@ -215,8 +213,8 @@ extern USBD_ClassTypeDef USBD_DFU; /** @defgroup USB_CORE_Exported_Functions * @{ */ -uint8_t USBD_DFU_RegisterMedia(USBD_HandleTypeDef *pdev, - USBD_DFU_MediaTypeDef *fops); +uint8_t USBD_DFU_RegisterMedia(USBD_HandleTypeDef *pdev, + USBD_DFU_MediaTypeDef *fops); /** * @} */ diff --git a/Class/DFU/Src/usbd_dfu.c b/Class/DFU/Src/usbd_dfu.c index dc85d61..d179650 100644 --- a/Class/DFU/Src/usbd_dfu.c +++ b/Class/DFU/Src/usbd_dfu.c @@ -93,61 +93,34 @@ EndBSPDependencies */ */ - - /** @defgroup USBD_DFU_Private_FunctionPrototypes * @{ */ +static uint8_t USBD_DFU_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +static uint8_t USBD_DFU_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +static uint8_t USBD_DFU_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +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); -static uint8_t USBD_DFU_Init(USBD_HandleTypeDef *pdev, - uint8_t cfgidx); - -static uint8_t USBD_DFU_DeInit(USBD_HandleTypeDef *pdev, - uint8_t cfgidx); - -static uint8_t USBD_DFU_Setup(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req); - -static uint8_t *USBD_DFU_GetCfgDesc(uint16_t *length); - -static uint8_t *USBD_DFU_GetDeviceQualifierDesc(uint16_t *length); - -static uint8_t USBD_DFU_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); - -static uint8_t USBD_DFU_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum); - -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); - -static uint8_t USBD_DFU_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); - -static uint8_t USBD_DFU_IsoOutIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); +static uint8_t *USBD_DFU_GetCfgDesc(uint16_t *length); +static uint8_t *USBD_DFU_GetDeviceQualifierDesc(uint16_t *length); #if (USBD_SUPPORT_USER_STRING_DESC == 1U) -static uint8_t *USBD_DFU_GetUsrStringDesc(USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length); +static uint8_t *USBD_DFU_GetUsrStringDesc(USBD_HandleTypeDef *pdev, + uint8_t index, uint16_t *length); #endif static void DFU_Detach(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); - static void DFU_Download(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); - static void DFU_Upload(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); - static void DFU_GetStatus(USBD_HandleTypeDef *pdev); - 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); - /** * @} */ @@ -156,18 +129,18 @@ static void DFU_Leave(USBD_HandleTypeDef *pdev); * @{ */ -USBD_ClassTypeDef USBD_DFU = +USBD_ClassTypeDef USBD_DFU = { USBD_DFU_Init, USBD_DFU_DeInit, USBD_DFU_Setup, USBD_DFU_EP0_TxReady, USBD_DFU_EP0_RxReady, - USBD_DFU_DataIn, - USBD_DFU_DataOut, + NULL, + NULL, USBD_DFU_SOF, - USBD_DFU_IsoINIncomplete, - USBD_DFU_IsoOutIncomplete, + NULL, + NULL, USBD_DFU_GetCfgDesc, USBD_DFU_GetCfgDesc, USBD_DFU_GetCfgDesc, @@ -180,20 +153,20 @@ USBD_ClassTypeDef USBD_DFU = /* USB DFU device Configuration Descriptor */ __ALIGN_BEGIN static uint8_t USBD_DFU_CfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END = { - 0x09, /* bLength: Configuation Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + 0x09, /* bLength: Configuation Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ USB_DFU_CONFIG_DESC_SIZ, - /* wTotalLength: Bytes returned */ + /* wTotalLength: Bytes returned */ 0x00, - 0x01, /*bNumInterfaces: 1 interface*/ - 0x01, /*bConfigurationValue: Configuration value*/ - 0x02, /*iConfiguration: Index of string descriptor describing the configuration*/ - 0xC0, /*bmAttributes: bus powered and Supprts Remote Wakeup */ - 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ + 0x01, /* bNumInterfaces: 1 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x02, /* iConfiguration: Index of string descriptor describing the configuration */ + 0xC0, /* bmAttributes: bus powered and Supprts Remote Wakeup */ + 0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */ /* 09 */ /********** Descriptor of DFU interface 0 Alternate setting 0 **************/ - USBD_DFU_IF_DESC(0U), /* This interface is mandatory for all devices */ + USBD_DFU_IF_DESC(0U), /* This interface is mandatory for all devices */ #if (USBD_DFU_MAX_ITF_NUM > 1U) /********** Descriptor of DFU interface 0 Alternate setting 1 **************/ @@ -225,21 +198,21 @@ __ALIGN_BEGIN static uint8_t USBD_DFU_CfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_E #endif /* (USBD_DFU_MAX_ITF_NUM > 6) */ /******************** DFU Functional Descriptor********************/ - 0x09, /*blength = 9 Bytes*/ - DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor*/ - 0x0B, /*bmAttribute - bitCanDnload = 1 (bit 0) - bitCanUpload = 1 (bit 1) - bitManifestationTolerant = 0 (bit 2) - bitWillDetach = 1 (bit 3) - Reserved (bit4-6) - bitAcceleratedST = 0 (bit 7)*/ - 0xFF, /*DetachTimeOut= 255 ms*/ + 0x09, /* blength = 9 Bytes */ + DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor */ + 0x0B, /* bmAttribute: + bitCanDnload = 1 (bit 0) + bitCanUpload = 1 (bit 1) + bitManifestationTolerant = 0 (bit 2) + bitWillDetach = 1 (bit 3) + Reserved (bit4-6) + bitAcceleratedST = 0 (bit 7) */ + 0xFF, /* DetachTimeOut= 255 ms*/ 0x00, - /*WARNING: In DMA mode the multiple MPS packets feature is still not supported + /* WARNING: In DMA mode the multiple MPS packets feature is still not supported ==> In this case, when using DMA USBD_DFU_XFER_SIZE should be set to 64 in usbd_conf.h */ - TRANSFER_SIZE_BYTES(USBD_DFU_XFER_SIZE), /* TransferSize = 1024 Byte*/ - 0x1A, /* bcdDFUVersion*/ + TRANSFER_SIZE_BYTES(USBD_DFU_XFER_SIZE), /* TransferSize = 1024 Byte */ + 0x1A, /* bcdDFUVersion */ 0x01 /***********************************************************/ /* 9*/ @@ -275,44 +248,45 @@ __ALIGN_BEGIN static uint8_t USBD_DFU_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_ * @param cfgidx: Configuration index * @retval status */ -static uint8_t USBD_DFU_Init(USBD_HandleTypeDef *pdev, - uint8_t cfgidx) +static uint8_t USBD_DFU_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { - USBD_DFU_HandleTypeDef *hdfu; + UNUSED(cfgidx); + + USBD_DFU_HandleTypeDef *hdfu; /* Allocate Audio structure */ - pdev->pClassData = USBD_malloc(sizeof(USBD_DFU_HandleTypeDef)); + hdfu = USBD_malloc(sizeof(USBD_DFU_HandleTypeDef)); - if (pdev->pClassData == NULL) + if (hdfu == NULL) { - return USBD_FAIL; + pdev->pClassData = NULL; + return (uint8_t)USBD_EMEM; } - else + + pdev->pClassData = (void *)hdfu; + + hdfu->alt_setting = 0U; + hdfu->data_ptr = USBD_DFU_APP_DEFAULT_ADD; + hdfu->wblock_num = 0U; + hdfu->wlength = 0U; + + hdfu->manif_state = DFU_MANIFEST_COMPLETE; + hdfu->dev_state = DFU_STATE_IDLE; + + hdfu->dev_status[0] = DFU_ERROR_NONE; + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = DFU_STATE_IDLE; + hdfu->dev_status[5] = 0U; + + /* Initialize Hardware layer */ + if (((USBD_DFU_MediaTypeDef *)pdev->pUserData)->Init() != USBD_OK) { - hdfu = (USBD_DFU_HandleTypeDef *) pdev->pClassData; - - hdfu->alt_setting = 0U; - hdfu->data_ptr = USBD_DFU_APP_DEFAULT_ADD; - hdfu->wblock_num = 0U; - hdfu->wlength = 0U; - - hdfu->manif_state = DFU_MANIFEST_COMPLETE; - hdfu->dev_state = DFU_STATE_IDLE; - - hdfu->dev_status[0] = DFU_ERROR_NONE; - hdfu->dev_status[1] = 0U; - hdfu->dev_status[2] = 0U; - hdfu->dev_status[3] = 0U; - hdfu->dev_status[4] = DFU_STATE_IDLE; - hdfu->dev_status[5] = 0U; - - /* Initialize Hardware layer */ - if (((USBD_DFU_MediaTypeDef *)pdev->pUserData)->Init() != USBD_OK) - { - return USBD_FAIL; - } + return (uint8_t)USBD_FAIL; } - return USBD_OK; + + return (uint8_t)USBD_OK; } /** @@ -322,12 +296,17 @@ static uint8_t USBD_DFU_Init(USBD_HandleTypeDef *pdev, * @param cfgidx: Configuration index * @retval status */ -static uint8_t USBD_DFU_DeInit(USBD_HandleTypeDef *pdev, - uint8_t cfgidx) +static uint8_t USBD_DFU_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { - USBD_DFU_HandleTypeDef *hdfu; - hdfu = (USBD_DFU_HandleTypeDef *) pdev->pClassData; + UNUSED(cfgidx); + USBD_DFU_HandleTypeDef *hdfu; + if (pdev->pClassData == NULL) + { + return (uint8_t)USBD_EMEM; + } + + hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; hdfu->wblock_num = 0U; hdfu->wlength = 0U; @@ -335,16 +314,12 @@ static uint8_t USBD_DFU_DeInit(USBD_HandleTypeDef *pdev, hdfu->dev_status[0] = DFU_ERROR_NONE; hdfu->dev_status[4] = DFU_STATE_IDLE; - /* DeInit physical Interface components */ - if (pdev->pClassData != NULL) - { - /* De-Initialize Hardware layer */ - ((USBD_DFU_MediaTypeDef *)pdev->pUserData)->DeInit(); - USBD_free(pdev->pClassData); - pdev->pClassData = NULL; - } + /* DeInit physical Interface components and Hardware Layer */ + ((USBD_DFU_MediaTypeDef *)pdev->pUserData)->DeInit(); + USBD_free(pdev->pClassData); + pdev->pClassData = NULL; - return USBD_OK; + return (uint8_t)USBD_OK; } /** @@ -354,129 +329,129 @@ static uint8_t USBD_DFU_DeInit(USBD_HandleTypeDef *pdev, * @param req: usb requests * @retval status */ -static uint8_t USBD_DFU_Setup(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req) +static uint8_t USBD_DFU_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { - USBD_DFU_HandleTypeDef *hdfu; - uint8_t *pbuf = 0U; + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; + USBD_StatusTypeDef ret = USBD_OK; + uint8_t *pbuf = NULL; uint16_t len = 0U; uint16_t status_info = 0U; - uint8_t ret = USBD_OK; - - hdfu = (USBD_DFU_HandleTypeDef *) pdev->pClassData; switch (req->bmRequest & USB_REQ_TYPE_MASK) { - case USB_REQ_TYPE_CLASS: - switch (req->bRequest) - { - case DFU_DNLOAD: - DFU_Download(pdev, req); - break; - - case DFU_UPLOAD: - DFU_Upload(pdev, req); - break; - - case DFU_GETSTATUS: - DFU_GetStatus(pdev); - break; - - case DFU_CLRSTATUS: - DFU_ClearStatus(pdev); - break; - - case DFU_GETSTATE: - DFU_GetState(pdev); - break; - - case DFU_ABORT: - DFU_Abort(pdev); - break; - - case DFU_DETACH: - DFU_Detach(pdev, req); - break; - - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; - } + case USB_REQ_TYPE_CLASS: + switch (req->bRequest) + { + case DFU_DNLOAD: + DFU_Download(pdev, req); break; - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_STATUS: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - USBD_CtlSendData(pdev, (uint8_t *)(void *)&status_info, 2U); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; + case DFU_UPLOAD: + DFU_Upload(pdev, req); + break; - 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); - } + case DFU_GETSTATUS: + DFU_GetStatus(pdev); + break; - USBD_CtlSendData(pdev, pbuf, len); - break; + case DFU_CLRSTATUS: + DFU_ClearStatus(pdev); + break; - case USB_REQ_GET_INTERFACE: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - USBD_CtlSendData(pdev, (uint8_t *)(void *)&hdfu->alt_setting, 1U); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; + case DFU_GETSTATE: + DFU_GetState(pdev); + break; - case USB_REQ_SET_INTERFACE: - if ((uint8_t)(req->wValue) < USBD_DFU_MAX_ITF_NUM) - { - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - hdfu->alt_setting = (uint8_t)(req->wValue); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - } - else - { - /* Call the error management function (command will be nacked */ - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; + case DFU_ABORT: + DFU_Abort(pdev); + break; - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; - } + case DFU_DETACH: + DFU_Detach(pdev, req); break; default: USBD_CtlError(pdev, req); ret = USBD_FAIL; break; + } + break; + + 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_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); + } + + (void)USBD_CtlSendData(pdev, pbuf, len); + break; + + case USB_REQ_GET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, (uint8_t *)hdfu->alt_setting, 1U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_SET_INTERFACE: + if ((uint8_t)(req->wValue) < USBD_DFU_MAX_ITF_NUM) + { + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + hdfu->alt_setting = (uint8_t)(req->wValue); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + } + else + { + /* Call the error management function (command will be nacked */ + 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 ret; + return (uint8_t)ret; } @@ -487,25 +462,13 @@ static uint8_t USBD_DFU_Setup(USBD_HandleTypeDef *pdev, * @param length : pointer data length * @retval pointer to descriptor buffer */ -static uint8_t *USBD_DFU_GetCfgDesc(uint16_t *length) +static uint8_t *USBD_DFU_GetCfgDesc(uint16_t *length) { - *length = sizeof(USBD_DFU_CfgDesc); + *length = (uint16_t)sizeof(USBD_DFU_CfgDesc); + return USBD_DFU_CfgDesc; } -/** - * @brief USBD_DFU_DataIn - * handle data IN Stage - * @param pdev: device instance - * @param epnum: endpoint index - * @retval status - */ -static uint8_t USBD_DFU_DataIn(USBD_HandleTypeDef *pdev, - uint8_t epnum) -{ - - return USBD_OK; -} /** * @brief USBD_DFU_EP0_RxReady @@ -513,10 +476,11 @@ static uint8_t USBD_DFU_DataIn(USBD_HandleTypeDef *pdev, * @param pdev: device instance * @retval status */ -static uint8_t USBD_DFU_EP0_RxReady(USBD_HandleTypeDef *pdev) +static uint8_t USBD_DFU_EP0_RxReady(USBD_HandleTypeDef *pdev) { + UNUSED(pdev); - return USBD_OK; + return (uint8_t)USBD_OK; } /** * @brief USBD_DFU_EP0_TxReady @@ -526,38 +490,47 @@ static uint8_t USBD_DFU_EP0_RxReady(USBD_HandleTypeDef *pdev) */ static uint8_t USBD_DFU_EP0_TxReady(USBD_HandleTypeDef *pdev) { + USBD_SetupReqTypedef req; uint32_t addr; - USBD_SetupReqTypedef req; - USBD_DFU_HandleTypeDef *hdfu; - - hdfu = (USBD_DFU_HandleTypeDef *) pdev->pClassData; + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; + USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData; if (hdfu->dev_state == DFU_STATE_DNLOAD_BUSY) { /* Decode the Special Command*/ if (hdfu->wblock_num == 0U) { - if ((hdfu->buffer.d8[0] == DFU_CMD_GETCOMMANDS) && (hdfu->wlength == 1U)) + if(hdfu->wlength == 1U) { - - } - else if ((hdfu->buffer.d8[0] == DFU_CMD_SETADDRESSPOINTER) && (hdfu->wlength == 5U)) - { - hdfu->data_ptr = hdfu->buffer.d8[1]; - hdfu->data_ptr += (uint32_t)hdfu->buffer.d8[2] << 8; - hdfu->data_ptr += (uint32_t)hdfu->buffer.d8[3] << 16; - hdfu->data_ptr += (uint32_t)hdfu->buffer.d8[4] << 24; - } - else if ((hdfu->buffer.d8[0] == DFU_CMD_ERASE) && (hdfu->wlength == 5U)) - { - hdfu->data_ptr = hdfu->buffer.d8[1]; - hdfu->data_ptr += (uint32_t)hdfu->buffer.d8[2] << 8; - hdfu->data_ptr += (uint32_t)hdfu->buffer.d8[3] << 16; - hdfu->data_ptr += (uint32_t)hdfu->buffer.d8[4] << 24; - - if (((USBD_DFU_MediaTypeDef *)pdev->pUserData)->Erase(hdfu->data_ptr) != USBD_OK) + if (hdfu->buffer.d8[0] == DFU_CMD_GETCOMMANDS) { - return USBD_FAIL; + /* nothink to do */ + } + } + else if (hdfu->wlength == 5U) + { + if (hdfu->buffer.d8[0] == DFU_CMD_SETADDRESSPOINTER) + { + hdfu->data_ptr = hdfu->buffer.d8[1]; + hdfu->data_ptr += (uint32_t)hdfu->buffer.d8[2] << 8; + hdfu->data_ptr += (uint32_t)hdfu->buffer.d8[3] << 16; + hdfu->data_ptr += (uint32_t)hdfu->buffer.d8[4] << 24; + } + else if (hdfu->buffer.d8[0] == DFU_CMD_ERASE) + { + hdfu->data_ptr = hdfu->buffer.d8[1]; + hdfu->data_ptr += (uint32_t)hdfu->buffer.d8[2] << 8; + hdfu->data_ptr += (uint32_t)hdfu->buffer.d8[3] << 16; + hdfu->data_ptr += (uint32_t)hdfu->buffer.d8[4] << 24; + + if (DfuInterface->Erase(hdfu->data_ptr) != USBD_OK) + { + return (uint8_t)USBD_FAIL; + } + } + else + { + /* .. */ } } else @@ -580,10 +553,9 @@ static uint8_t USBD_DFU_EP0_TxReady(USBD_HandleTypeDef *pdev) addr = ((hdfu->wblock_num - 2U) * USBD_DFU_XFER_SIZE) + hdfu->data_ptr; /* Preform the write operation */ - if (((USBD_DFU_MediaTypeDef *)pdev->pUserData)->Write(hdfu->buffer.d8, - (uint8_t *)addr, hdfu->wlength) != USBD_OK) + if (DfuInterface->Write(hdfu->buffer.d8, (uint8_t *)addr, hdfu->wlength) != USBD_OK) { - return USBD_FAIL; + return (uint8_t)USBD_FAIL; } } } @@ -599,18 +571,18 @@ static uint8_t USBD_DFU_EP0_TxReady(USBD_HandleTypeDef *pdev) hdfu->dev_status[2] = 0U; hdfu->dev_status[3] = 0U; hdfu->dev_status[4] = hdfu->dev_state; - return USBD_OK; + } + else if (hdfu->dev_state == DFU_STATE_MANIFEST)/* Manifestation in progress */ + { + /* Start leaving DFU mode */ + DFU_Leave(pdev); } else { - if (hdfu->dev_state == DFU_STATE_MANIFEST)/* Manifestation in progress */ - { - /* Start leaving DFU mode */ - DFU_Leave(pdev); - } + /* .. */ } - return USBD_OK; + return (uint8_t)USBD_OK; } /** * @brief USBD_DFU_SOF @@ -618,48 +590,13 @@ static uint8_t USBD_DFU_EP0_TxReady(USBD_HandleTypeDef *pdev) * @param pdev: device instance * @retval status */ -static uint8_t USBD_DFU_SOF(USBD_HandleTypeDef *pdev) +static uint8_t USBD_DFU_SOF(USBD_HandleTypeDef *pdev) { + UNUSED(pdev); - return USBD_OK; + return (uint8_t)USBD_OK; } -/** - * @brief USBD_DFU_IsoINIncomplete - * handle data ISO IN Incomplete event - * @param pdev: device instance - * @param epnum: endpoint index - * @retval status - */ -static uint8_t USBD_DFU_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) -{ - return USBD_OK; -} -/** - * @brief USBD_DFU_IsoOutIncomplete - * handle data ISO OUT Incomplete event - * @param pdev: device instance - * @param epnum: endpoint index - * @retval status - */ -static uint8_t USBD_DFU_IsoOutIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) -{ - - return USBD_OK; -} -/** - * @brief USBD_DFU_DataOut - * handle data OUT Stage - * @param pdev: device instance - * @param epnum: endpoint index - * @retval status - */ -static uint8_t USBD_DFU_DataOut(USBD_HandleTypeDef *pdev, - uint8_t epnum) -{ - - return USBD_OK; -} /** * @brief DeviceQualifierDescriptor @@ -667,9 +604,10 @@ static uint8_t USBD_DFU_DataOut(USBD_HandleTypeDef *pdev, * @param length : pointer data length * @retval pointer to descriptor buffer */ -static uint8_t *USBD_DFU_GetDeviceQualifierDesc(uint16_t *length) +static uint8_t *USBD_DFU_GetDeviceQualifierDesc(uint16_t *length) { - *length = sizeof(USBD_DFU_DeviceQualifierDesc); + *length = (uint16_t)sizeof(USBD_DFU_DeviceQualifierDesc); + return USBD_DFU_DeviceQualifierDesc; } @@ -685,15 +623,17 @@ 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; + /* Check if the requested string interface is supported */ if (index <= (USBD_IDX_INTERFACE_STR + USBD_DFU_MAX_ITF_NUM)) { - USBD_GetString((uint8_t *)((USBD_DFU_MediaTypeDef *)pdev->pUserData)->pStrDesc, USBD_StrDesc, length); + USBD_GetString((uint8_t *)DfuInterface->pStrDesc, USBD_StrDesc, length); return USBD_StrDesc; } - /* Not supported Interface Descriptor index */ else { + /* Not supported Interface Descriptor index */ return NULL; } } @@ -704,14 +644,17 @@ static uint8_t *USBD_DFU_GetUsrStringDesc(USBD_HandleTypeDef *pdev, uint8_t inde * @param fops: storage callback * @retval status */ -uint8_t USBD_DFU_RegisterMedia(USBD_HandleTypeDef *pdev, - USBD_DFU_MediaTypeDef *fops) +uint8_t USBD_DFU_RegisterMedia(USBD_HandleTypeDef *pdev, + USBD_DFU_MediaTypeDef *fops) { - if (fops != NULL) + if (fops == NULL) { - pdev->pUserData = fops; + return (uint8_t)USBD_FAIL; } - return 0U; + + pdev->pUserData = fops; + + return (uint8_t)USBD_OK; } /****************************************************************************** @@ -726,13 +669,13 @@ 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 *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; - hdfu = (USBD_DFU_HandleTypeDef *) pdev->pClassData; - - if (hdfu->dev_state == DFU_STATE_IDLE || hdfu->dev_state == DFU_STATE_DNLOAD_SYNC - || hdfu->dev_state == DFU_STATE_DNLOAD_IDLE || hdfu->dev_state == DFU_STATE_MANIFEST_SYNC - || hdfu->dev_state == DFU_STATE_UPLOAD_IDLE) + if ((hdfu->dev_state == DFU_STATE_IDLE) || + (hdfu->dev_state == DFU_STATE_DNLOAD_SYNC) || + (hdfu->dev_state == DFU_STATE_DNLOAD_IDLE) || + (hdfu->dev_state == DFU_STATE_MANIFEST_SYNC) || + (hdfu->dev_state == DFU_STATE_UPLOAD_IDLE)) { /* Update the state machine */ hdfu->dev_state = DFU_STATE_IDLE; @@ -747,11 +690,11 @@ 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) + if (((USBD_DFU_CfgDesc[12U + (9U * USBD_DFU_MAX_ITF_NUM)]) & DFU_DETACH_MASK) != 0U) { /* Perform an Attach-Detach operation on USB bus */ - USBD_Stop(pdev); - USBD_Start(pdev); + (void)USBD_Stop(pdev); + (void)USBD_Start(pdev); } else { @@ -769,9 +712,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; - - hdfu = (USBD_DFU_HandleTypeDef *) pdev->pClassData; + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; /* Data setup request */ if (req->wLength > 0U) @@ -787,8 +728,7 @@ static void DFU_Download(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) hdfu->dev_status[4] = hdfu->dev_state; /* Prepare the reception of the buffer over EP0 */ - USBD_CtlPrepareRx(pdev, (uint8_t *)hdfu->buffer.d8, - (uint16_t)hdfu->wlength); + (void)USBD_CtlPrepareRx(pdev, (uint8_t *)hdfu->buffer.d8, hdfu->wlength); } /* Unsupported state */ else @@ -801,7 +741,7 @@ static void DFU_Download(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) else { /* End of DNLOAD operation*/ - if (hdfu->dev_state == DFU_STATE_DNLOAD_IDLE || hdfu->dev_state == DFU_STATE_IDLE) + if ((hdfu->dev_state == DFU_STATE_DNLOAD_IDLE) || (hdfu->dev_state == DFU_STATE_IDLE)) { hdfu->manif_state = DFU_MANIFEST_IN_PROGRESS; hdfu->dev_state = DFU_STATE_MANIFEST_SYNC; @@ -827,12 +767,10 @@ static void DFU_Download(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) */ static void DFU_Upload(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { - USBD_DFU_HandleTypeDef *hdfu; - - hdfu = (USBD_DFU_HandleTypeDef *) pdev->pClassData; - - uint8_t *phaddr = NULL; - uint32_t addr = 0U; + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; + USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData; + uint8_t *phaddr; + uint32_t addr; /* Data setup request */ if (req->wLength > 0U) @@ -860,7 +798,7 @@ static void DFU_Upload(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) hdfu->buffer.d8[2] = DFU_CMD_ERASE; /* Send the status data over EP0 */ - USBD_CtlSendData(pdev, (uint8_t *)(&(hdfu->buffer.d8[0])), 3U); + (void)USBD_CtlSendData(pdev, (uint8_t *)(&(hdfu->buffer.d8[0])), 3U); } else if (hdfu->wblock_num > 1U) { @@ -871,13 +809,13 @@ static void DFU_Upload(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) hdfu->dev_status[3] = 0U; hdfu->dev_status[4] = hdfu->dev_state; - addr = ((hdfu->wblock_num - 2U) * USBD_DFU_XFER_SIZE) + hdfu->data_ptr; /* Change is Accelerated*/ + addr = ((hdfu->wblock_num - 2U) * USBD_DFU_XFER_SIZE) + hdfu->data_ptr; /* Return the physical address where data are stored */ - phaddr = ((USBD_DFU_MediaTypeDef *)pdev->pUserData)->Read((uint8_t *)addr, hdfu->buffer.d8, hdfu->wlength); + phaddr = DfuInterface->Read((uint8_t *)addr, hdfu->buffer.d8, hdfu->wlength); /* Send the status data over EP0 */ - USBD_CtlSendData(pdev, phaddr, (uint16_t)hdfu->wlength); + (void)USBD_CtlSendData(pdev, phaddr, hdfu->wlength); } else /* unsupported hdfu->wblock_num */ { @@ -897,6 +835,7 @@ static void DFU_Upload(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { hdfu->wlength = 0U; hdfu->wblock_num = 0U; + /* Call the error management function (command will be nacked */ USBD_CtlError(pdev, req); } @@ -921,73 +860,72 @@ static void DFU_Upload(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) */ static void DFU_GetStatus(USBD_HandleTypeDef *pdev) { - USBD_DFU_HandleTypeDef *hdfu; - - hdfu = (USBD_DFU_HandleTypeDef *) pdev->pClassData; + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; + USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData; switch (hdfu->dev_state) { - case DFU_STATE_DNLOAD_SYNC: - if (hdfu->wlength != 0U) + case DFU_STATE_DNLOAD_SYNC: + if (hdfu->wlength != 0U) + { + hdfu->dev_state = DFU_STATE_DNLOAD_BUSY; + + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = hdfu->dev_state; + + if ((hdfu->wblock_num == 0U) && (hdfu->buffer.d8[0] == DFU_CMD_ERASE)) { - hdfu->dev_state = DFU_STATE_DNLOAD_BUSY; - - hdfu->dev_status[1] = 0U; - hdfu->dev_status[2] = 0U; - hdfu->dev_status[3] = 0U; - hdfu->dev_status[4] = hdfu->dev_state; - - if ((hdfu->wblock_num == 0U) && (hdfu->buffer.d8[0] == DFU_CMD_ERASE)) - { - ((USBD_DFU_MediaTypeDef *)pdev->pUserData)->GetStatus(hdfu->data_ptr, DFU_MEDIA_ERASE, hdfu->dev_status); - } - else - { - ((USBD_DFU_MediaTypeDef *)pdev->pUserData)->GetStatus(hdfu->data_ptr, DFU_MEDIA_PROGRAM, hdfu->dev_status); - } - } - else /* (hdfu->wlength==0)*/ - { - hdfu->dev_state = DFU_STATE_DNLOAD_IDLE; - - hdfu->dev_status[1] = 0U; - hdfu->dev_status[2] = 0U; - hdfu->dev_status[3] = 0U; - hdfu->dev_status[4] = hdfu->dev_state; - } - break; - - case DFU_STATE_MANIFEST_SYNC : - if (hdfu->manif_state == DFU_MANIFEST_IN_PROGRESS) - { - hdfu->dev_state = DFU_STATE_MANIFEST; - - hdfu->dev_status[1] = 1U; /*bwPollTimeout = 1ms*/ - hdfu->dev_status[2] = 0U; - hdfu->dev_status[3] = 0U; - hdfu->dev_status[4] = hdfu->dev_state; + DfuInterface->GetStatus(hdfu->data_ptr, DFU_MEDIA_ERASE, hdfu->dev_status); } else { - if ((hdfu->manif_state == DFU_MANIFEST_COMPLETE) && - ((USBD_DFU_CfgDesc[(11U + (9U * USBD_DFU_MAX_ITF_NUM))]) & 0x04U)) - { - hdfu->dev_state = DFU_STATE_IDLE; - - hdfu->dev_status[1] = 0U; - hdfu->dev_status[2] = 0U; - hdfu->dev_status[3] = 0U; - hdfu->dev_status[4] = hdfu->dev_state; - } + DfuInterface->GetStatus(hdfu->data_ptr, DFU_MEDIA_PROGRAM, hdfu->dev_status); } - break; + } + else /* (hdfu->wlength==0)*/ + { + hdfu->dev_state = DFU_STATE_DNLOAD_IDLE; - default : - break; + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = hdfu->dev_state; + } + break; + + case DFU_STATE_MANIFEST_SYNC: + if (hdfu->manif_state == DFU_MANIFEST_IN_PROGRESS) + { + hdfu->dev_state = DFU_STATE_MANIFEST; + + hdfu->dev_status[1] = 1U; /*bwPollTimeout = 1ms*/ + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = hdfu->dev_state; + } + else + { + if ((hdfu->manif_state == DFU_MANIFEST_COMPLETE) && + (((USBD_DFU_CfgDesc[(11U + (9U * USBD_DFU_MAX_ITF_NUM))]) & 0x04U) != 0U)) + { + hdfu->dev_state = DFU_STATE_IDLE; + + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = hdfu->dev_state; + } + } + break; + + default: + break; } /* Send the status data over EP0 */ - USBD_CtlSendData(pdev, (uint8_t *)(&(hdfu->dev_status[0])), 6U); + (void)USBD_CtlSendData(pdev, (uint8_t *)(&(hdfu->dev_status[0])), 6U); } /** @@ -998,30 +936,28 @@ static void DFU_GetStatus(USBD_HandleTypeDef *pdev) */ static void DFU_ClearStatus(USBD_HandleTypeDef *pdev) { - USBD_DFU_HandleTypeDef *hdfu; - - hdfu = (USBD_DFU_HandleTypeDef *) pdev->pClassData; + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; if (hdfu->dev_state == DFU_STATE_ERROR) { hdfu->dev_state = DFU_STATE_IDLE; - hdfu->dev_status[0] = DFU_ERROR_NONE;/*bStatus*/ + hdfu->dev_status[0] = DFU_ERROR_NONE; /*bStatus*/ hdfu->dev_status[1] = 0U; hdfu->dev_status[2] = 0U; hdfu->dev_status[3] = 0U; /*bwPollTimeout=0ms*/ - hdfu->dev_status[4] = hdfu->dev_state;/*bState*/ - hdfu->dev_status[5] = 0U;/*iString*/ + hdfu->dev_status[4] = hdfu->dev_state; /*bState*/ + hdfu->dev_status[5] = 0U; /*iString*/ } else { /*State Error*/ hdfu->dev_state = DFU_STATE_ERROR; - hdfu->dev_status[0] = DFU_ERROR_UNKNOWN;/*bStatus*/ + hdfu->dev_status[0] = DFU_ERROR_UNKNOWN; /*bStatus*/ hdfu->dev_status[1] = 0U; hdfu->dev_status[2] = 0U; hdfu->dev_status[3] = 0U; /*bwPollTimeout=0ms*/ - hdfu->dev_status[4] = hdfu->dev_state;/*bState*/ - hdfu->dev_status[5] = 0U;/*iString*/ + hdfu->dev_status[4] = hdfu->dev_state; /*bState*/ + hdfu->dev_status[5] = 0U; /*iString*/ } } @@ -1033,12 +969,10 @@ static void DFU_ClearStatus(USBD_HandleTypeDef *pdev) */ static void DFU_GetState(USBD_HandleTypeDef *pdev) { - USBD_DFU_HandleTypeDef *hdfu; - - hdfu = (USBD_DFU_HandleTypeDef *) pdev->pClassData; + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; /* Return the current state of the DFU interface */ - USBD_CtlSendData(pdev, &hdfu->dev_state, 1U); + (void)USBD_CtlSendData(pdev, &hdfu->dev_state, 1U); } /** @@ -1049,13 +983,14 @@ static void DFU_GetState(USBD_HandleTypeDef *pdev) */ static void DFU_Abort(USBD_HandleTypeDef *pdev) { - USBD_DFU_HandleTypeDef *hdfu; + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; - hdfu = (USBD_DFU_HandleTypeDef *) pdev->pClassData; - if (hdfu->dev_state == DFU_STATE_IDLE || hdfu->dev_state == DFU_STATE_DNLOAD_SYNC - || hdfu->dev_state == DFU_STATE_DNLOAD_IDLE || hdfu->dev_state == DFU_STATE_MANIFEST_SYNC - || hdfu->dev_state == DFU_STATE_UPLOAD_IDLE) + if ((hdfu->dev_state == DFU_STATE_IDLE) || + (hdfu->dev_state == DFU_STATE_DNLOAD_SYNC) || + (hdfu->dev_state == DFU_STATE_DNLOAD_IDLE) || + (hdfu->dev_state == DFU_STATE_MANIFEST_SYNC) || + (hdfu->dev_state == DFU_STATE_UPLOAD_IDLE)) { hdfu->dev_state = DFU_STATE_IDLE; hdfu->dev_status[0] = DFU_ERROR_NONE; @@ -1078,13 +1013,11 @@ static void DFU_Abort(USBD_HandleTypeDef *pdev) */ static void DFU_Leave(USBD_HandleTypeDef *pdev) { - USBD_DFU_HandleTypeDef *hdfu; - - hdfu = (USBD_DFU_HandleTypeDef *) pdev->pClassData; + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; hdfu->manif_state = DFU_MANIFEST_COMPLETE; - if ((USBD_DFU_CfgDesc[(11U + (9U * USBD_DFU_MAX_ITF_NUM))]) & 0x04U) + if (((USBD_DFU_CfgDesc[(11U + (9U * USBD_DFU_MAX_ITF_NUM))]) & 0x04U) != 0U) { hdfu->dev_state = DFU_STATE_MANIFEST_SYNC; @@ -1104,10 +1037,7 @@ static void DFU_Leave(USBD_HandleTypeDef *pdev) hdfu->dev_status[4] = hdfu->dev_state; /* Disconnect the USB device */ - USBD_Stop(pdev); - - /* DeInitilialize the MAL(Media Access Layer) */ - ((USBD_DFU_MediaTypeDef *)pdev->pUserData)->DeInit(); + (void)USBD_Stop(pdev); /* Generate system reset to allow jumping to the user code */ NVIC_SystemReset(); diff --git a/Class/HID/Inc/usbd_hid.h b/Class/HID/Inc/usbd_hid.h index 3b533c0..40ed729 100644 --- a/Class/HID/Inc/usbd_hid.h +++ b/Class/HID/Inc/usbd_hid.h @@ -41,32 +41,32 @@ extern "C" { /** @defgroup USBD_HID_Exported_Defines * @{ */ -#define HID_EPIN_ADDR 0x81U -#define HID_EPIN_SIZE 0x04U +#define HID_EPIN_ADDR 0x81U +#define HID_EPIN_SIZE 0x04U -#define USB_HID_CONFIG_DESC_SIZ 34U -#define USB_HID_DESC_SIZ 9U -#define HID_MOUSE_REPORT_DESC_SIZE 74U +#define USB_HID_CONFIG_DESC_SIZ 34U +#define USB_HID_DESC_SIZ 9U +#define HID_MOUSE_REPORT_DESC_SIZE 74U -#define HID_DESCRIPTOR_TYPE 0x21U -#define HID_REPORT_DESC 0x22U +#define HID_DESCRIPTOR_TYPE 0x21U +#define HID_REPORT_DESC 0x22U #ifndef HID_HS_BINTERVAL -#define HID_HS_BINTERVAL 0x07U +#define HID_HS_BINTERVAL 0x07U #endif /* HID_HS_BINTERVAL */ #ifndef HID_FS_BINTERVAL -#define HID_FS_BINTERVAL 0x0AU +#define HID_FS_BINTERVAL 0x0AU #endif /* HID_FS_BINTERVAL */ -#define HID_REQ_SET_PROTOCOL 0x0BU -#define HID_REQ_GET_PROTOCOL 0x03U +#define HID_REQ_SET_PROTOCOL 0x0BU +#define HID_REQ_GET_PROTOCOL 0x03U -#define HID_REQ_SET_IDLE 0x0AU -#define HID_REQ_GET_IDLE 0x02U +#define HID_REQ_SET_IDLE 0x0AU +#define HID_REQ_GET_IDLE 0x02U -#define HID_REQ_SET_REPORT 0x09U -#define HID_REQ_GET_REPORT 0x01U +#define HID_REQ_SET_REPORT 0x09U +#define HID_REQ_GET_REPORT 0x01U /** * @} */ @@ -79,18 +79,16 @@ typedef enum { HID_IDLE = 0, HID_BUSY, -} -HID_StateTypeDef; +} HID_StateTypeDef; typedef struct { - uint32_t Protocol; - uint32_t IdleState; - uint32_t AltSetting; - HID_StateTypeDef state; -} -USBD_HID_HandleTypeDef; + uint32_t Protocol; + uint32_t IdleState; + uint32_t AltSetting; + HID_StateTypeDef state; +} USBD_HID_HandleTypeDef; /** * @} */ @@ -109,8 +107,8 @@ USBD_HID_HandleTypeDef; * @{ */ -extern USBD_ClassTypeDef USBD_HID; -#define USBD_HID_CLASS &USBD_HID +extern USBD_ClassTypeDef USBD_HID; +#define USBD_HID_CLASS &USBD_HID /** * @} */ @@ -118,10 +116,7 @@ extern USBD_ClassTypeDef USBD_HID; /** @defgroup USB_CORE_Exported_Functions * @{ */ -uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, - uint8_t *report, - uint16_t len); - +uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report,uint16_t len); uint32_t USBD_HID_GetPollingInterval(USBD_HandleTypeDef *pdev); /** diff --git a/Class/HID/Src/usbd_hid.c b/Class/HID/Src/usbd_hid.c index d9b4223..c73dace 100644 --- a/Class/HID/Src/usbd_hid.c +++ b/Class/HID/Src/usbd_hid.c @@ -83,31 +83,20 @@ EndBSPDependencies */ */ - - /** @defgroup USBD_HID_Private_FunctionPrototypes * @{ */ +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); -static uint8_t USBD_HID_Init(USBD_HandleTypeDef *pdev, - uint8_t cfgidx); +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_DeInit(USBD_HandleTypeDef *pdev, - uint8_t cfgidx); - -static uint8_t USBD_HID_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); /** * @} */ @@ -116,16 +105,15 @@ static uint8_t USBD_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); * @{ */ -USBD_ClassTypeDef USBD_HID = -{ +USBD_ClassTypeDef USBD_HID = { USBD_HID_Init, USBD_HID_DeInit, USBD_HID_Setup, - NULL, /*EP0_TxSent*/ - NULL, /*EP0_RxReady*/ - USBD_HID_DataIn, /*DataIn*/ - NULL, /*DataOut*/ - NULL, /*SOF */ + NULL, /* EP0_TxSent */ + NULL, /* EP0_RxReady */ + USBD_HID_DataIn, /* DataIn */ + NULL, /* DataOut */ + NULL, /* SOF */ NULL, NULL, USBD_HID_GetHSCfgDesc, @@ -135,174 +123,166 @@ USBD_ClassTypeDef USBD_HID = }; /* USB HID device FS Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_HID_CfgFSDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END = -{ - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ +__ALIGN_BEGIN static uint8_t USBD_HID_CfgFSDesc[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 */ + /* wTotalLength: Bytes returned */ 0x00, - 0x01, /*bNumInterfaces: 1 interface*/ - 0x01, /*bConfigurationValue: Configuration value*/ - 0x00, /*iConfiguration: Index of string descriptor describing - the configuration*/ - 0xE0, /*bmAttributes: bus powered and Support Remote Wake-up */ - 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ + 0x01, /* bNumInterfaces: 1 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ + 0xE0, /* bmAttributes: bus powered and Support Remote Wake-up */ + 0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */ /************** 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*/ + 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*/ + 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, /* 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:*/ + 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 Byte max */ + HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ + 0x03, /* bmAttributes: Interrupt endpoint */ + HID_EPIN_SIZE, /* wMaxPacketSize: 4 Byte max */ 0x00, - HID_FS_BINTERVAL, /*bInterval: Polling Interval */ + 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 */ +__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 */ + /* wTotalLength: Bytes returned */ 0x00, - 0x01, /*bNumInterfaces: 1 interface*/ - 0x01, /*bConfigurationValue: Configuration value*/ - 0x00, /*iConfiguration: Index of string descriptor describing - the configuration*/ - 0xE0, /*bmAttributes: bus powered and Support Remote Wake-up */ - 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ + 0x01, /* bNumInterfaces: 1 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ + 0xE0, /* bmAttributes: bus powered and Support Remote Wake-up */ + 0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */ /************** 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*/ + 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*/ + 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, /* 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:*/ + 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 Byte max */ + HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ + 0x03, /* bmAttributes: Interrupt endpoint */ + HID_EPIN_SIZE, /* wMaxPacketSize: 4 Byte max */ 0x00, - HID_HS_BINTERVAL, /*bInterval: Polling Interval */ + 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 */ +__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 */ + /* wTotalLength: Bytes returned */ 0x00, - 0x01, /*bNumInterfaces: 1 interface*/ - 0x01, /*bConfigurationValue: Configuration value*/ - 0x00, /*iConfiguration: Index of string descriptor describing - the configuration*/ - 0xE0, /*bmAttributes: bus powered and Support Remote Wake-up */ - 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ + 0x01, /* bNumInterfaces: 1 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ + 0xE0, /* bmAttributes: bus powered and Support Remote Wake-up */ + 0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */ /************** 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*/ + 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*/ + 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, /* 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:*/ + 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 Byte max */ + HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ + 0x03, /* bmAttributes: Interrupt endpoint */ + HID_EPIN_SIZE, /* wMaxPacketSize: 4 Byte max */ 0x00, - HID_FS_BINTERVAL, /*bInterval: Polling Interval */ + HID_FS_BINTERVAL, /* bInterval: Polling Interval */ /* 34 */ }; /* USB HID device Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_HID_Desc[USB_HID_DESC_SIZ] __ALIGN_END = -{ +__ALIGN_BEGIN static uint8_t USBD_HID_Desc[USB_HID_DESC_SIZ] __ALIGN_END = { /* 18 */ - 0x09, /*bLength: HID Descriptor size*/ - HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/ - 0x11, /*bcdHID: HID Class Spec release number*/ + 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, /* 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, }; /* USB Standard Device Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = -{ +__ALIGN_BEGIN static uint8_t USBD_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = { USB_LEN_DEV_QUALIFIER_DESC, USB_DESC_TYPE_DEVICE_QUALIFIER, 0x00, @@ -315,8 +295,7 @@ __ALIGN_BEGIN static uint8_t USBD_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_ 0x00, }; -__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END = -{ +__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END = { 0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, @@ -380,46 +359,64 @@ __ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] _ * @param cfgidx: Configuration index * @retval status */ -static uint8_t USBD_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +static uint8_t USBD_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { - /* Open EP IN */ - USBD_LL_OpenEP(pdev, HID_EPIN_ADDR, USBD_EP_TYPE_INTR, HID_EPIN_SIZE); - pdev->ep_in[HID_EPIN_ADDR & 0xFU].is_used = 1U; + UNUSED(cfgidx); - pdev->pClassData = USBD_malloc(sizeof(USBD_HID_HandleTypeDef)); + USBD_HID_HandleTypeDef *hhid; - if (pdev->pClassData == NULL) + hhid = USBD_malloc(sizeof(USBD_HID_HandleTypeDef)); + + if (hhid == NULL) { - return USBD_FAIL; + pdev->pClassData = NULL; + return (uint8_t)USBD_EMEM; } - ((USBD_HID_HandleTypeDef *)pdev->pClassData)->state = HID_IDLE; + pdev->pClassData = (void *)hhid; - return USBD_OK; + if (pdev->dev_speed == USBD_SPEED_HIGH) + { + pdev->ep_in[HID_EPIN_ADDR & 0xFU].bInterval = HID_HS_BINTERVAL; + } + else /* LOW and FULL-speed endpoints */ + { + pdev->ep_in[HID_EPIN_ADDR & 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; + + hhid->state = HID_IDLE; + + return (uint8_t)USBD_OK; } /** - * @brief USBD_HID_Init + * @brief USBD_HID_DeInit * DeInitialize the HID layer * @param pdev: device instance * @param cfgidx: Configuration index * @retval status */ -static uint8_t USBD_HID_DeInit(USBD_HandleTypeDef *pdev, - uint8_t cfgidx) +static uint8_t USBD_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { + UNUSED(cfgidx); + /* Close HID EPs */ - USBD_LL_CloseEP(pdev, HID_EPIN_ADDR); + (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; /* FRee allocated memory */ if (pdev->pClassData != NULL) { - USBD_free(pdev->pClassData); + (void)USBD_free(pdev->pClassData); pdev->pClassData = NULL; } - return USBD_OK; + return (uint8_t)USBD_OK; } /** @@ -429,115 +426,117 @@ static uint8_t USBD_HID_DeInit(USBD_HandleTypeDef *pdev, * @param req: usb requests * @retval status */ -static uint8_t USBD_HID_Setup(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req) +static uint8_t USBD_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { - USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *) pdev->pClassData; - uint16_t len = 0U; - uint8_t *pbuf = NULL; - uint16_t status_info = 0U; + USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)pdev->pClassData; USBD_StatusTypeDef ret = USBD_OK; + uint16_t len; + uint8_t *pbuf; + uint16_t status_info = 0U; switch (req->bmRequest & USB_REQ_TYPE_MASK) { - case USB_REQ_TYPE_CLASS : - switch (req->bRequest) - { - case HID_REQ_SET_PROTOCOL: - hhid->Protocol = (uint8_t)(req->wValue); - break; - - case HID_REQ_GET_PROTOCOL: - USBD_CtlSendData(pdev, (uint8_t *)(void *)&hhid->Protocol, 1U); - break; - - case HID_REQ_SET_IDLE: - hhid->IdleState = (uint8_t)(req->wValue >> 8); - break; - - case HID_REQ_GET_IDLE: - USBD_CtlSendData(pdev, (uint8_t *)(void *)&hhid->IdleState, 1U); - break; - - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; - } + case USB_REQ_TYPE_CLASS : + switch (req->bRequest) + { + case HID_REQ_SET_PROTOCOL: + hhid->Protocol = (uint8_t)(req->wValue); break; - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_STATUS: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - USBD_CtlSendData(pdev, (uint8_t *)(void *)&status_info, 2U); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; - case USB_REQ_GET_DESCRIPTOR: - if (req->wValue >> 8 == HID_REPORT_DESC) - { - len = MIN(HID_MOUSE_REPORT_DESC_SIZE, req->wLength); - pbuf = HID_MOUSE_ReportDesc; - } - else if (req->wValue >> 8 == HID_DESCRIPTOR_TYPE) - { - pbuf = USBD_HID_Desc; - len = MIN(USB_HID_DESC_SIZ, req->wLength); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; - } - USBD_CtlSendData(pdev, pbuf, len); - break; + case HID_REQ_GET_PROTOCOL: + (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->Protocol, 1U); + break; - case USB_REQ_GET_INTERFACE : - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - USBD_CtlSendData(pdev, (uint8_t *)(void *)&hhid->AltSetting, 1U); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; + case HID_REQ_SET_IDLE: + hhid->IdleState = (uint8_t)(req->wValue >> 8); + break; - case USB_REQ_SET_INTERFACE : - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - hhid->AltSetting = (uint8_t)(req->wValue); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; - - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; - } + case HID_REQ_GET_IDLE: + (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->IdleState, 1U); break; default: USBD_CtlError(pdev, req); ret = USBD_FAIL; break; + } + break; + 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_DESCRIPTOR: + if ((req->wValue >> 8) == HID_REPORT_DESC) + { + len = MIN(HID_MOUSE_REPORT_DESC_SIZE, req->wLength); + pbuf = HID_MOUSE_ReportDesc; + } + else if ((req->wValue >> 8) == HID_DESCRIPTOR_TYPE) + { + pbuf = USBD_HID_Desc; + len = MIN(USB_HID_DESC_SIZ, req->wLength); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + } + (void)USBD_CtlSendData(pdev, pbuf, len); + break; + + case USB_REQ_GET_INTERFACE : + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->AltSetting, 1U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_SET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + hhid->AltSetting = (uint8_t)(req->wValue); + } + else + { + 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 ret; + return (uint8_t)ret; } /** @@ -547,24 +546,20 @@ static uint8_t USBD_HID_Setup(USBD_HandleTypeDef *pdev, * @param buff: pointer to report * @retval status */ -uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, - uint8_t *report, - uint16_t len) +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->pClassData; if (pdev->dev_state == USBD_STATE_CONFIGURED) { if (hhid->state == HID_IDLE) { hhid->state = HID_BUSY; - USBD_LL_Transmit(pdev, - HID_EPIN_ADDR, - report, - len); + (void)USBD_LL_Transmit(pdev, HID_EPIN_ADDR, report, len); } } - return USBD_OK; + + return (uint8_t)USBD_OK; } /** @@ -575,7 +570,7 @@ uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, */ uint32_t USBD_HID_GetPollingInterval(USBD_HandleTypeDef *pdev) { - uint32_t polling_interval = 0U; + uint32_t polling_interval; /* HIGH-speed endpoints */ if (pdev->dev_speed == USBD_SPEED_HIGH) @@ -602,9 +597,10 @@ uint32_t USBD_HID_GetPollingInterval(USBD_HandleTypeDef *pdev) * @param length : pointer data length * @retval pointer to descriptor buffer */ -static uint8_t *USBD_HID_GetFSCfgDesc(uint16_t *length) +static uint8_t *USBD_HID_GetFSCfgDesc(uint16_t *length) { - *length = sizeof(USBD_HID_CfgFSDesc); + *length = (uint16_t)sizeof(USBD_HID_CfgFSDesc); + return USBD_HID_CfgFSDesc; } @@ -615,9 +611,10 @@ static uint8_t *USBD_HID_GetFSCfgDesc(uint16_t *length) * @param length : pointer data length * @retval pointer to descriptor buffer */ -static uint8_t *USBD_HID_GetHSCfgDesc(uint16_t *length) +static uint8_t *USBD_HID_GetHSCfgDesc(uint16_t *length) { - *length = sizeof(USBD_HID_CfgHSDesc); + *length = (uint16_t)sizeof(USBD_HID_CfgHSDesc); + return USBD_HID_CfgHSDesc; } @@ -628,9 +625,10 @@ static uint8_t *USBD_HID_GetHSCfgDesc(uint16_t *length) * @param length : pointer data length * @retval pointer to descriptor buffer */ -static uint8_t *USBD_HID_GetOtherSpeedCfgDesc(uint16_t *length) +static uint8_t *USBD_HID_GetOtherSpeedCfgDesc(uint16_t *length) { - *length = sizeof(USBD_HID_OtherSpeedCfgDesc); + *length = (uint16_t)sizeof(USBD_HID_OtherSpeedCfgDesc); + return USBD_HID_OtherSpeedCfgDesc; } @@ -641,14 +639,14 @@ static uint8_t *USBD_HID_GetOtherSpeedCfgDesc(uint16_t *length) * @param epnum: endpoint index * @retval status */ -static uint8_t USBD_HID_DataIn(USBD_HandleTypeDef *pdev, - uint8_t epnum) +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; - return USBD_OK; + + return (uint8_t)USBD_OK; } @@ -658,9 +656,10 @@ static uint8_t USBD_HID_DataIn(USBD_HandleTypeDef *pdev, * @param length : pointer data length * @retval pointer to descriptor buffer */ -static uint8_t *USBD_HID_GetDeviceQualifierDesc(uint16_t *length) +static uint8_t *USBD_HID_GetDeviceQualifierDesc(uint16_t *length) { - *length = sizeof(USBD_HID_DeviceQualifierDesc); + *length = (uint16_t)sizeof(USBD_HID_DeviceQualifierDesc); + return USBD_HID_DeviceQualifierDesc; } diff --git a/Class/MSC/Inc/usbd_msc.h b/Class/MSC/Inc/usbd_msc.h index 932bbba..a0bbab9 100644 --- a/Class/MSC/Inc/usbd_msc.h +++ b/Class/MSC/Inc/usbd_msc.h @@ -86,7 +86,7 @@ typedef struct uint32_t interface; uint8_t bot_state; uint8_t bot_status; - uint16_t bot_data_length; + uint32_t bot_data_length; uint8_t bot_data[MSC_MEDIA_PACKET]; USBD_MSC_BOT_CBWTypeDef cbw; USBD_MSC_BOT_CSWTypeDef csw; @@ -94,6 +94,7 @@ typedef struct USBD_SCSI_SenseTypeDef scsi_sense [SENSE_LIST_DEEPTH]; uint8_t scsi_sense_head; uint8_t scsi_sense_tail; + uint8_t scsi_medium_state; uint16_t scsi_blk_size; uint32_t scsi_blk_nbr; diff --git a/Class/MSC/Inc/usbd_msc_data.h b/Class/MSC/Inc/usbd_msc_data.h index 79dafbd..26838de 100644 --- a/Class/MSC/Inc/usbd_msc_data.h +++ b/Class/MSC/Inc/usbd_msc_data.h @@ -40,10 +40,11 @@ extern "C" { /** @defgroup USB_INFO_Exported_Defines * @{ */ -#define MODE_SENSE6_LEN 8U -#define MODE_SENSE10_LEN 8U -#define LENGTH_INQUIRY_PAGE00 7U -#define LENGTH_FORMAT_CAPACITIES 20U +#define MODE_SENSE6_LEN 0x17U +#define MODE_SENSE10_LEN 0x1BU +#define LENGTH_INQUIRY_PAGE00 0x06U +#define LENGTH_INQUIRY_PAGE80 0x08U +#define LENGTH_FORMAT_CAPACITIES 0x14U /** * @} @@ -70,9 +71,10 @@ extern "C" { /** @defgroup USBD_INFO_Exported_Variables * @{ */ -extern const uint8_t MSC_Page00_Inquiry_Data[]; -extern const uint8_t MSC_Mode_Sense6_data[]; -extern const uint8_t MSC_Mode_Sense10_data[] ; +extern uint8_t MSC_Page00_Inquiry_Data[LENGTH_INQUIRY_PAGE00]; +extern uint8_t MSC_Page80_Inquiry_Data[LENGTH_INQUIRY_PAGE80]; +extern uint8_t MSC_Mode_Sense6_data[MODE_SENSE6_LEN]; +extern uint8_t MSC_Mode_Sense10_data[MODE_SENSE10_LEN]; /** * @} diff --git a/Class/MSC/Inc/usbd_msc_scsi.h b/Class/MSC/Inc/usbd_msc_scsi.h index 1629d78..b32ded0 100644 --- a/Class/MSC/Inc/usbd_msc_scsi.h +++ b/Class/MSC/Inc/usbd_msc_scsi.h @@ -103,20 +103,13 @@ extern "C" { #define READ_FORMAT_CAPACITY_DATA_LEN 0x0CU #define READ_CAPACITY10_DATA_LEN 0x08U -#define MODE_SENSE10_DATA_LEN 0x08U -#define MODE_SENSE6_DATA_LEN 0x04U #define REQUEST_SENSE_DATA_LEN 0x12U #define STANDARD_INQUIRY_DATA_LEN 0x24U #define BLKVFY 0x04U -extern uint8_t Page00_Inquiry_Data[]; -extern uint8_t Standard_Inquiry_Data[]; -extern uint8_t Standard_Inquiry_Data2[]; -extern uint8_t Mode_Sense6_data[]; -extern uint8_t Mode_Sense10_data[]; -extern uint8_t Scsi_Sense_Data[]; -extern uint8_t ReadCapacity10_Data[]; -extern uint8_t ReadFormatCapacity_Data []; +#define SCSI_MEDIUM_UNLOCKED 0x00U +#define SCSI_MEDIUM_LOCKED 0x01U +#define SCSI_MEDIUM_EJECTED 0x02U /** * @} */ @@ -128,16 +121,16 @@ extern uint8_t ReadFormatCapacity_Data []; typedef struct _SENSE_ITEM { - char Skey; + uint8_t Skey; union { struct _ASCs { - char ASC; - char ASCQ; + uint8_t ASC; + uint8_t ASCQ; } b; uint8_t ASC; - char *pData; + uint8_t *pData; } w; } USBD_SCSI_SenseTypeDef; /** diff --git a/Class/MSC/Src/usbd_msc.c b/Class/MSC/Src/usbd_msc.c index fdf5314..fe6e1c6 100644 --- a/Class/MSC/Src/usbd_msc.c +++ b/Class/MSC/Src/usbd_msc.c @@ -80,16 +80,16 @@ EndBSPDependencies */ /** @defgroup MSC_CORE_Private_FunctionPrototypes * @{ */ -uint8_t USBD_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx); -uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx); -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); +uint8_t USBD_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +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); -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); +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); /** * @} @@ -121,134 +121,133 @@ USBD_ClassTypeDef USBD_MSC = /* USB Mass storage device Configuration Descriptor */ /* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */ -__ALIGN_BEGIN uint8_t USBD_MSC_CfgHSDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END = +__ALIGN_BEGIN static uint8_t USBD_MSC_CfgHSDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END = { - - 0x09, /* bLength: Configuation Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + 0x09, /* bLength: Configuation Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ USB_MSC_CONFIG_DESC_SIZ, 0x00, - 0x01, /* bNumInterfaces: 1 interface */ - 0x01, /* bConfigurationValue: */ - 0x04, /* iConfiguration: */ - 0xC0, /* bmAttributes: */ - 0x32, /* MaxPower 100 mA */ + 0x01, /* bNumInterfaces: 1 interface */ + 0x01, /* bConfigurationValue: */ + 0x04, /* iConfiguration: */ + 0xC0, /* bmAttributes: */ + 0x32, /* MaxPower 100 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: */ + 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 */ + 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 */ + 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 */ + 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*/ + 0x00 /* Polling interval in milliseconds */ }; /* USB Mass storage device Configuration Descriptor */ -/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */ -__ALIGN_BEGIN uint8_t USBD_MSC_CfgFSDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END = +/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */ +__ALIGN_BEGIN static uint8_t USBD_MSC_CfgFSDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END = { - 0x09, /* bLength: Configuation Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + 0x09, /* bLength: Configuation Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ USB_MSC_CONFIG_DESC_SIZ, 0x00, - 0x01, /* bNumInterfaces: 1 interface */ - 0x01, /* bConfigurationValue: */ - 0x04, /* iConfiguration: */ - 0xC0, /* bmAttributes: */ - 0x32, /* MaxPower 100 mA */ + 0x01, /* bNumInterfaces: 1 interface */ + 0x01, /* bConfigurationValue: */ + 0x04, /* iConfiguration: */ + 0xC0, /* bmAttributes: */ + 0x32, /* MaxPower 100 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: */ + 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 */ + 0x07, /* Endpoint descriptor length = 7 */ + 0x05, /* Endpoint descriptor type */ + MSC_EPIN_ADDR, /* Endpoint address (IN, address 1) */ + 0x02, /* Bulk endpoint type */ LOBYTE(MSC_MAX_FS_PACKET), HIBYTE(MSC_MAX_FS_PACKET), - 0x00, /*Polling interval in milliseconds */ + 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 */ + 0x07, /* Endpoint descriptor length = 7 */ + 0x05, /* Endpoint descriptor type */ + MSC_EPOUT_ADDR, /* Endpoint address (OUT, address 1) */ + 0x02, /* Bulk endpoint type */ LOBYTE(MSC_MAX_FS_PACKET), HIBYTE(MSC_MAX_FS_PACKET), - 0x00 /*Polling interval in milliseconds*/ + 0x00 /* Polling interval in milliseconds */ }; -__ALIGN_BEGIN uint8_t USBD_MSC_OtherSpeedCfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END = +__ALIGN_BEGIN static uint8_t USBD_MSC_OtherSpeedCfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END = { - 0x09, /* bLength: Configuation Descriptor size */ + 0x09, /* bLength: Configuation Descriptor size */ USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, USB_MSC_CONFIG_DESC_SIZ, 0x00, - 0x01, /* bNumInterfaces: 1 interface */ - 0x01, /* bConfigurationValue: */ - 0x04, /* iConfiguration: */ - 0xC0, /* bmAttributes: */ - 0x32, /* MaxPower 100 mA */ + 0x01, /* bNumInterfaces: 1 interface */ + 0x01, /* bConfigurationValue: */ + 0x04, /* iConfiguration: */ + 0xC0, /* bmAttributes: */ + 0x32, /* MaxPower 100 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: */ + 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 */ + 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 */ + 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 */ + 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*/ + 0x00 /* Polling interval in milliseconds */ }; /* USB Standard Device Descriptor */ -__ALIGN_BEGIN uint8_t USBD_MSC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = +__ALIGN_BEGIN static uint8_t USBD_MSC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = { USB_LEN_DEV_QUALIFIER_DESC, USB_DESC_TYPE_DEVICE_QUALIFIER, @@ -279,37 +278,44 @@ __ALIGN_BEGIN uint8_t USBD_MSC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] */ uint8_t USBD_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { + UNUSED(cfgidx); + USBD_MSC_BOT_HandleTypeDef *hmsc; + + hmsc = USBD_malloc(sizeof(USBD_MSC_BOT_HandleTypeDef)); + + if (hmsc == NULL) + { + pdev->pClassData = NULL; + return (uint8_t)USBD_EMEM; + } + + pdev->pClassData = (void *)hmsc; + if (pdev->dev_speed == USBD_SPEED_HIGH) { /* Open EP OUT */ - USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET); + (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; /* Open EP IN */ - USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET); + (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; } else { /* Open EP OUT */ - USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET); + (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; /* Open EP IN */ - USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET); + (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; } - pdev->pClassData = USBD_malloc(sizeof(USBD_MSC_BOT_HandleTypeDef)); - - if (pdev->pClassData == NULL) - { - return USBD_FAIL; - } /* Init the BOT layer */ MSC_BOT_Init(pdev); - return USBD_OK; + return (uint8_t)USBD_OK; } /** @@ -319,15 +325,16 @@ uint8_t USBD_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) * @param cfgidx: configuration index * @retval status */ -uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev, - uint8_t cfgidx) +uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { + UNUSED(cfgidx); + /* Close MSC EPs */ - USBD_LL_CloseEP(pdev, MSC_EPOUT_ADDR); + (void)USBD_LL_CloseEP(pdev, MSC_EPOUT_ADDR); pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 0U; /* Close EP IN */ - USBD_LL_CloseEP(pdev, MSC_EPIN_ADDR); + (void)USBD_LL_CloseEP(pdev, MSC_EPIN_ADDR); pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 0U; /* De-Init the BOT layer */ @@ -336,11 +343,11 @@ uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev, /* Free MSC Class Resources */ if (pdev->pClassData != NULL) { - USBD_free(pdev->pClassData); - pdev->pClassData = NULL; + (void)USBD_free(pdev->pClassData); + pdev->pClassData = NULL; } - return USBD_OK; + return (uint8_t)USBD_OK; } /** * @brief USBD_MSC_Setup @@ -351,139 +358,40 @@ uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev, */ uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *) pdev->pClassData; - uint8_t ret = USBD_OK; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + USBD_StatusTypeDef ret = USBD_OK; uint16_t status_info = 0U; switch (req->bmRequest & USB_REQ_TYPE_MASK) { /* Class request */ - case USB_REQ_TYPE_CLASS: - switch (req->bRequest) + case USB_REQ_TYPE_CLASS: + switch (req->bRequest) + { + case BOT_GET_MAX_LUN: + if ((req->wValue == 0U) && (req->wLength == 1U) && + ((req->bmRequest & 0x80U) == 0x80U)) { - case BOT_GET_MAX_LUN: - if ((req->wValue == 0U) && (req->wLength == 1U) && - ((req->bmRequest & 0x80U) == 0x80U)) - { - hmsc->max_lun = (uint32_t)((USBD_StorageTypeDef *)pdev->pUserData)->GetMaxLun(); - USBD_CtlSendData(pdev, (uint8_t *)(void *)&hmsc->max_lun, 1U); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; - - case BOT_RESET : - if ((req->wValue == 0U) && (req->wLength == 0U) && - ((req->bmRequest & 0x80U) != 0x80U)) - { - MSC_BOT_Reset(pdev); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; - - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; + hmsc->max_lun = (uint32_t)((USBD_StorageTypeDef *)pdev->pUserData)->GetMaxLun(); + (void)USBD_CtlSendData(pdev, (uint8_t *)&hmsc->max_lun, 1U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; } break; - /* Interface & Endpoint request */ - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) + + case BOT_RESET : + if ((req->wValue == 0U) && (req->wLength == 0U) && + ((req->bmRequest & 0x80U) != 0x80U)) { - case USB_REQ_GET_STATUS: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - USBD_CtlSendData(pdev, (uint8_t *)(void *)&status_info, 2U); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; - - case USB_REQ_GET_INTERFACE: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - USBD_CtlSendData(pdev, (uint8_t *)(void *)&hmsc->interface, 1U); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; - - case USB_REQ_SET_INTERFACE: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - hmsc->interface = (uint8_t)(req->wValue); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; - - case USB_REQ_CLEAR_FEATURE: - - /* Flush the FIFO and Clear the stall status */ - USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex); - - /* Reactivate the EP */ - USBD_LL_CloseEP(pdev, (uint8_t)req->wIndex); - if ((((uint8_t)req->wIndex) & 0x80U) == 0x80U) - { - pdev->ep_in[(uint8_t)req->wIndex & 0xFU].is_used = 0U; - if (pdev->dev_speed == USBD_SPEED_HIGH) - { - /* Open EP IN */ - USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, - MSC_MAX_HS_PACKET); - } - else - { - /* Open EP IN */ - 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; - } - else - { - pdev->ep_out[(uint8_t)req->wIndex & 0xFU].is_used = 0U; - if (pdev->dev_speed == USBD_SPEED_HIGH) - { - /* Open EP OUT */ - USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, - MSC_MAX_HS_PACKET); - } - else - { - /* Open EP OUT */ - 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; - } - - /* Handle BOT error */ - MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex); - break; - - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; + MSC_BOT_Reset(pdev); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; } break; @@ -491,9 +399,76 @@ uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) USBD_CtlError(pdev, req); ret = USBD_FAIL; break; + } + 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, (uint8_t *)&hmsc->interface, 1U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_SET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + hmsc->interface = (uint8_t)(req->wValue); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_CLEAR_FEATURE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + if (req->wValue == USB_FEATURE_EP_HALT) + { + /* Flush the FIFO */ + (void)USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex); + + /* Handle BOT error */ + MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex); + } + } + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + } + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; } - return ret; + return (uint8_t)ret; } /** @@ -507,7 +482,7 @@ uint8_t USBD_MSC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) { MSC_BOT_DataIn(pdev, epnum); - return USBD_OK; + return (uint8_t)USBD_OK; } /** @@ -521,7 +496,7 @@ uint8_t USBD_MSC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) { MSC_BOT_DataOut(pdev, epnum); - return USBD_OK; + return (uint8_t)USBD_OK; } /** @@ -532,7 +507,7 @@ uint8_t USBD_MSC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) */ uint8_t *USBD_MSC_GetHSCfgDesc(uint16_t *length) { - *length = sizeof(USBD_MSC_CfgHSDesc); + *length = (uint16_t)sizeof(USBD_MSC_CfgHSDesc); return USBD_MSC_CfgHSDesc; } @@ -545,7 +520,7 @@ uint8_t *USBD_MSC_GetHSCfgDesc(uint16_t *length) */ uint8_t *USBD_MSC_GetFSCfgDesc(uint16_t *length) { - *length = sizeof(USBD_MSC_CfgFSDesc); + *length = (uint16_t)sizeof(USBD_MSC_CfgFSDesc); return USBD_MSC_CfgFSDesc; } @@ -558,7 +533,7 @@ uint8_t *USBD_MSC_GetFSCfgDesc(uint16_t *length) */ uint8_t *USBD_MSC_GetOtherSpeedCfgDesc(uint16_t *length) { - *length = sizeof(USBD_MSC_OtherSpeedCfgDesc); + *length = (uint16_t)sizeof(USBD_MSC_OtherSpeedCfgDesc); return USBD_MSC_OtherSpeedCfgDesc; } @@ -570,7 +545,7 @@ uint8_t *USBD_MSC_GetOtherSpeedCfgDesc(uint16_t *length) */ uint8_t *USBD_MSC_GetDeviceQualifierDescriptor(uint16_t *length) { - *length = sizeof(USBD_MSC_DeviceQualifierDesc); + *length = (uint16_t)sizeof(USBD_MSC_DeviceQualifierDesc); return USBD_MSC_DeviceQualifierDesc; } @@ -580,15 +555,16 @@ uint8_t *USBD_MSC_GetDeviceQualifierDescriptor(uint16_t *length) * @param fops: storage callback * @retval status */ -uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev, - USBD_StorageTypeDef *fops) +uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev, USBD_StorageTypeDef *fops) { - if (fops != NULL) + if (fops == NULL) { - pdev->pUserData = fops; + return (uint8_t)USBD_FAIL; } - return USBD_OK; + pdev->pUserData = fops; + + return (uint8_t)USBD_OK; } /** diff --git a/Class/MSC/Src/usbd_msc_bot.c b/Class/MSC/Src/usbd_msc_bot.c index f8c1be8..ae68ac0 100644 --- a/Class/MSC/Src/usbd_msc_bot.c +++ b/Class/MSC/Src/usbd_msc_bot.c @@ -76,11 +76,9 @@ EndBSPDependencies */ /** @defgroup MSC_BOT_Private_FunctionPrototypes * @{ */ -static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef *pdev); -static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf, - uint16_t len); - -static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev); +static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t len); +static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef *pdev); +static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev); /** * @} */ @@ -91,31 +89,31 @@ static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev); */ - /** * @brief MSC_BOT_Init * Initialize the BOT Process * @param pdev: device instance * @retval None */ -void MSC_BOT_Init(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->pClassData; hmsc->bot_state = USBD_BOT_IDLE; hmsc->bot_status = USBD_BOT_STATUS_NORMAL; hmsc->scsi_sense_tail = 0U; hmsc->scsi_sense_head = 0U; + hmsc->scsi_medium_state = SCSI_MEDIUM_UNLOCKED; ((USBD_StorageTypeDef *)pdev->pUserData)->Init(0U); - USBD_LL_FlushEP(pdev, MSC_EPOUT_ADDR); - USBD_LL_FlushEP(pdev, MSC_EPIN_ADDR); + (void)USBD_LL_FlushEP(pdev, MSC_EPOUT_ADDR); + (void)USBD_LL_FlushEP(pdev, MSC_EPIN_ADDR); /* Prapare EP to Receive First BOT Cmd */ - USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)(void *)&hmsc->cbw, - USBD_BOT_CBW_LENGTH); + (void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)&hmsc->cbw, + USBD_BOT_CBW_LENGTH); } /** @@ -124,16 +122,19 @@ void MSC_BOT_Init(USBD_HandleTypeDef *pdev) * @param pdev: device instance * @retval None */ -void MSC_BOT_Reset(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->pClassData; 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); + /* Prapare EP to Receive First BOT Cmd */ - USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)(void *)&hmsc->cbw, - USBD_BOT_CBW_LENGTH); + (void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)&hmsc->cbw, + USBD_BOT_CBW_LENGTH); } /** @@ -144,7 +145,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->pClassData; hmsc->bot_state = USBD_BOT_IDLE; } @@ -155,27 +156,28 @@ void MSC_BOT_DeInit(USBD_HandleTypeDef *pdev) * @param epnum: endpoint index * @retval None */ -void MSC_BOT_DataIn(USBD_HandleTypeDef *pdev, - uint8_t epnum) +void MSC_BOT_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) { - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + UNUSED(epnum); + + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; switch (hmsc->bot_state) { - case USBD_BOT_DATA_IN: - if (SCSI_ProcessCmd(pdev, hmsc->cbw.bLUN, &hmsc->cbw.CB[0]) < 0) - { - MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED); - } - break; + case USBD_BOT_DATA_IN: + if (SCSI_ProcessCmd(pdev, hmsc->cbw.bLUN, &hmsc->cbw.CB[0]) < 0) + { + MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED); + } + break; - case USBD_BOT_SEND_DATA: - case USBD_BOT_LAST_DATA_IN: - MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_PASSED); - break; + case USBD_BOT_SEND_DATA: + case USBD_BOT_LAST_DATA_IN: + MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_PASSED); + break; - default: - break; + default: + break; } } /** @@ -185,10 +187,11 @@ void MSC_BOT_DataIn(USBD_HandleTypeDef *pdev, * @param epnum: endpoint index * @retval None */ -void MSC_BOT_DataOut(USBD_HandleTypeDef *pdev, - uint8_t epnum) +void MSC_BOT_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) { - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + UNUSED(epnum); + + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; switch (hmsc->bot_state) { @@ -197,7 +200,6 @@ void MSC_BOT_DataOut(USBD_HandleTypeDef *pdev, break; case USBD_BOT_DATA_OUT: - if (SCSI_ProcessCmd(pdev, hmsc->cbw.bLUN, &hmsc->cbw.CB[0]) < 0) { MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED); @@ -215,19 +217,18 @@ void MSC_BOT_DataOut(USBD_HandleTypeDef *pdev, * @param pdev: device instance * @retval None */ -static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef *pdev) +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->pClassData; hmsc->csw.dTag = hmsc->cbw.dTag; hmsc->csw.dDataResidue = hmsc->cbw.dDataLength; if ((USBD_LL_GetRxDataSize(pdev, MSC_EPOUT_ADDR) != USBD_BOT_CBW_LENGTH) || (hmsc->cbw.dSignature != USBD_BOT_CBW_SIGNATURE) || - (hmsc->cbw.bLUN > 1U) || - (hmsc->cbw.bCBLength < 1U) || (hmsc->cbw.bCBLength > 16U)) + (hmsc->cbw.bLUN > 1U) || (hmsc->cbw.bCBLength < 1U) || + (hmsc->cbw.bCBLength > 16U)) { - SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB); hmsc->bot_status = USBD_BOT_STATUS_ERROR; @@ -246,7 +247,7 @@ static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef *pdev) MSC_BOT_Abort(pdev); } } - /*Burst xfer handled internally*/ + /* Burst xfer handled internally */ else if ((hmsc->bot_state != USBD_BOT_DATA_IN) && (hmsc->bot_state != USBD_BOT_DATA_OUT) && (hmsc->bot_state != USBD_BOT_LAST_DATA_IN)) @@ -279,18 +280,17 @@ static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef *pdev) * @param len: Data Length * @retval None */ -static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf, - uint16_t len) +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->pClassData; - uint16_t length = (uint16_t)MIN(hmsc->cbw.dDataLength, len); + uint32_t length = MIN(hmsc->cbw.dDataLength, len); hmsc->csw.dDataResidue -= len; hmsc->csw.bStatus = USBD_CSW_CMD_PASSED; hmsc->bot_state = USBD_BOT_SEND_DATA; - USBD_LL_Transmit(pdev, MSC_EPIN_ADDR, pbuf, length); + (void)USBD_LL_Transmit(pdev, MSC_EPIN_ADDR, pbuf, length); } /** @@ -300,21 +300,20 @@ static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf, * @param status : CSW status * @retval None */ -void MSC_BOT_SendCSW(USBD_HandleTypeDef *pdev, - uint8_t CSW_Status) +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->pClassData; hmsc->csw.dSignature = USBD_BOT_CSW_SIGNATURE; hmsc->csw.bStatus = CSW_Status; hmsc->bot_state = USBD_BOT_IDLE; - USBD_LL_Transmit(pdev, MSC_EPIN_ADDR, (uint8_t *)(void *)&hmsc->csw, - USBD_BOT_CSW_LENGTH); + (void)USBD_LL_Transmit(pdev, MSC_EPIN_ADDR, (uint8_t *)&hmsc->csw, + USBD_BOT_CSW_LENGTH); /* Prepare EP to Receive next Cmd */ - USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)(void *)&hmsc->cbw, - USBD_BOT_CBW_LENGTH); + (void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)&hmsc->cbw, + USBD_BOT_CBW_LENGTH); } /** @@ -324,23 +323,23 @@ void MSC_BOT_SendCSW(USBD_HandleTypeDef *pdev, * @retval status */ -static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev) +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->pClassData; if ((hmsc->cbw.bmFlags == 0U) && (hmsc->cbw.dDataLength != 0U) && (hmsc->bot_status == USBD_BOT_STATUS_NORMAL)) { - USBD_LL_StallEP(pdev, MSC_EPOUT_ADDR); + (void)USBD_LL_StallEP(pdev, MSC_EPOUT_ADDR); } - USBD_LL_StallEP(pdev, MSC_EPIN_ADDR); + (void)USBD_LL_StallEP(pdev, MSC_EPIN_ADDR); if (hmsc->bot_status == USBD_BOT_STATUS_ERROR) { - USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)(void *)&hmsc->cbw, - USBD_BOT_CBW_LENGTH); + (void)USBD_LL_StallEP(pdev, MSC_EPIN_ADDR); + (void)USBD_LL_StallEP(pdev, MSC_EPOUT_ADDR); } } @@ -352,14 +351,14 @@ static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev) * @retval None */ -void MSC_BOT_CplClrFeature(USBD_HandleTypeDef *pdev, uint8_t epnum) +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->pClassData; if (hmsc->bot_status == USBD_BOT_STATUS_ERROR) /* Bad CBW Signature */ { - USBD_LL_StallEP(pdev, MSC_EPIN_ADDR); - hmsc->bot_status = USBD_BOT_STATUS_NORMAL; + (void)USBD_LL_StallEP(pdev, MSC_EPIN_ADDR); + (void)USBD_LL_StallEP(pdev, MSC_EPOUT_ADDR); } else if (((epnum & 0x80U) == 0x80U) && (hmsc->bot_status != USBD_BOT_STATUS_RECOVERY)) { diff --git a/Class/MSC/Src/usbd_msc_data.c b/Class/MSC/Src/usbd_msc_data.c index aaafc3a..d1c3a97 100644 --- a/Class/MSC/Src/usbd_msc_data.c +++ b/Class/MSC/Src/usbd_msc_data.c @@ -65,21 +65,48 @@ EndBSPDependencies */ * @{ */ - /* USB Mass storage Page 0 Inquiry Data */ -const uint8_t MSC_Page00_Inquiry_Data[] = +uint8_t MSC_Page00_Inquiry_Data[LENGTH_INQUIRY_PAGE00] = { 0x00, 0x00, 0x00, (LENGTH_INQUIRY_PAGE00 - 4U), 0x00, - 0x80, - 0x83 + 0x80 }; -/* USB Mass storage sense 6 Data */ -const uint8_t MSC_Mode_Sense6_data[] = + +/* USB Mass storage VPD Page 0x80 Inquiry Data for Unit Serial Number */ +uint8_t MSC_Page80_Inquiry_Data[LENGTH_INQUIRY_PAGE80] = { + 0x00, + 0x80, + 0x00, + LENGTH_INQUIRY_PAGE80, + 0x20, /* Put Product Serial number */ + 0x20, + 0x20, + 0x20 + }; + +/* USB Mass storage sense 6 Data */ +uint8_t MSC_Mode_Sense6_data[MODE_SENSE6_LEN] = +{ + 0x22, + 0x00, + 0x00, + 0x00, + 0x08, + 0x12, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, 0x00, 0x00, 0x00, @@ -89,11 +116,32 @@ const uint8_t MSC_Mode_Sense6_data[] = 0x00, 0x00 }; + + /* USB Mass storage sense 10 Data */ -const uint8_t MSC_Mode_Sense10_data[] = +uint8_t MSC_Mode_Sense10_data[MODE_SENSE10_LEN] = { 0x00, - 0x06, + 0x26, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x08, + 0x12, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, 0x00, 0x00, 0x00, diff --git a/Class/MSC/Src/usbd_msc_scsi.c b/Class/MSC/Src/usbd_msc_scsi.c index 78032c7..5c36a6e 100644 --- a/Class/MSC/Src/usbd_msc_scsi.c +++ b/Class/MSC/Src/usbd_msc_scsi.c @@ -30,7 +30,6 @@ EndBSPDependencies */ #include "usbd_msc_data.h" - /** @addtogroup STM32_USB_DEVICE_LIBRARY * @{ */ @@ -82,18 +81,25 @@ static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t static int8_t SCSI_Inquiry(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); static int8_t SCSI_RequestSense(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_AllowPreventRemovable(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); static int8_t SCSI_ModeSense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); 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); static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun, uint32_t blk_offset, uint32_t blk_nbr); static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun); static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun); + +static int8_t SCSI_UpdateBotData(USBD_MSC_BOT_HandleTypeDef *hmsc, + uint8_t *pBuff, uint16_t length); /** * @} */ @@ -114,61 +120,79 @@ static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun); */ 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; + switch (cmd[0]) { - case SCSI_TEST_UNIT_READY: - SCSI_TestUnitReady(pdev, lun, cmd); - break; + case SCSI_TEST_UNIT_READY: + ret = SCSI_TestUnitReady(pdev, lun, cmd); + break; - case SCSI_REQUEST_SENSE: - SCSI_RequestSense(pdev, lun, cmd); - break; - case SCSI_INQUIRY: - SCSI_Inquiry(pdev, lun, cmd); - break; + case SCSI_REQUEST_SENSE: + ret = SCSI_RequestSense(pdev, lun, cmd); + break; - case SCSI_START_STOP_UNIT: - SCSI_StartStopUnit(pdev, lun, cmd); - break; + case SCSI_INQUIRY: + ret = SCSI_Inquiry(pdev, lun, cmd); + break; - case SCSI_ALLOW_MEDIUM_REMOVAL: - SCSI_StartStopUnit(pdev, lun, cmd); - break; + case SCSI_START_STOP_UNIT: + ret = SCSI_StartStopUnit(pdev, lun, cmd); + break; - case SCSI_MODE_SENSE6: - SCSI_ModeSense6(pdev, lun, cmd); - break; + case SCSI_ALLOW_MEDIUM_REMOVAL: + ret = SCSI_AllowPreventRemovable(pdev, lun, cmd); + break; - case SCSI_MODE_SENSE10: - SCSI_ModeSense10(pdev, lun, cmd); - break; + case SCSI_MODE_SENSE6: + ret = SCSI_ModeSense6(pdev, lun, cmd); + break; - case SCSI_READ_FORMAT_CAPACITIES: - SCSI_ReadFormatCapacity(pdev, lun, cmd); - break; + case SCSI_MODE_SENSE10: + ret = SCSI_ModeSense10(pdev, lun, cmd); + break; - case SCSI_READ_CAPACITY10: - SCSI_ReadCapacity10(pdev, lun, cmd); - break; + case SCSI_READ_FORMAT_CAPACITIES: + ret = SCSI_ReadFormatCapacity(pdev, lun, cmd); + break; - case SCSI_READ10: - SCSI_Read10(pdev, lun, cmd); - break; + case SCSI_READ_CAPACITY10: + ret = SCSI_ReadCapacity10(pdev, lun, cmd); + break; - case SCSI_WRITE10: - SCSI_Write10(pdev, lun, cmd); - break; + case SCSI_READ_CAPACITY16: + ret = SCSI_ReadCapacity16(pdev, lun, cmd); + break; - case SCSI_VERIFY10: - SCSI_Verify10(pdev, lun, cmd); - break; + case SCSI_READ10: + ret = SCSI_Read10(pdev, lun, cmd); + break; - default: - SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_CDB); - return -1; + case SCSI_READ12: + ret = SCSI_Read12(pdev, lun, cmd); + break; + + case SCSI_WRITE10: + ret = SCSI_Write10(pdev, lun, cmd); + break; + + case SCSI_WRITE12: + ret = SCSI_Write12(pdev, lun, cmd); + break; + + case SCSI_VERIFY10: + ret = SCSI_Verify10(pdev, lun, cmd); + break; + + default: + SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_CDB); + hmsc->bot_status = USBD_BOT_STATUS_ERROR; + ret = -1; + break; } - return 0; + return ret; } @@ -179,9 +203,10 @@ int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd) * @param params: Command parameters * @retval status */ -static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + UNUSED(params); + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; /* case 9 : Hi > D0 */ if (hmsc->cbw.dDataLength != 0U) @@ -191,6 +216,13 @@ static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t return -1; } + if (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED) + { + SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT); + hmsc->bot_state = USBD_BOT_NO_DATA; + return -1; + } + if (((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) != 0) { SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT); @@ -203,6 +235,7 @@ static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t return 0; } + /** * @brief SCSI_Inquiry * Process Inquiry command @@ -210,44 +243,53 @@ static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t * @param params: Command parameters * @retval status */ -static int8_t SCSI_Inquiry(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +static int8_t SCSI_Inquiry(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { 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->pClassData; - if (params[1] & 0x01U)/*Evpd is set*/ + if (hmsc->cbw.dDataLength == 0U) { - len = LENGTH_INQUIRY_PAGE00; - hmsc->bot_data_length = len; + SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB); + return -1; + } - while (len) + if ((params[1] & 0x01U) != 0U) /* Evpd is set */ + { + if (params[2] == 0U) /* Request for Supported Vital Product Data Pages*/ { - len--; - hmsc->bot_data[len] = MSC_Page00_Inquiry_Data[len]; + (void)SCSI_UpdateBotData(hmsc, MSC_Page00_Inquiry_Data, LENGTH_INQUIRY_PAGE00); + } + else if (params[2] == 0x80U) /* Request for VPD page 0x80 Unit Serial Number */ + { + (void)SCSI_UpdateBotData(hmsc, MSC_Page80_Inquiry_Data, LENGTH_INQUIRY_PAGE80); + } + else /* Request Not supported */ + { + SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, + INVALID_FIELED_IN_COMMAND); + + return -1; } } else { - pPage = (uint8_t *)(void *) & ((USBD_StorageTypeDef *)pdev->pUserData)->pInquiry[lun * STANDARD_INQUIRY_DATA_LEN]; + pPage = (uint8_t *)&((USBD_StorageTypeDef *)pdev->pUserData)->pInquiry[lun * STANDARD_INQUIRY_DATA_LEN]; len = (uint16_t)pPage[4] + 5U; if (params[4] <= len) { len = params[4]; } - hmsc->bot_data_length = len; - while (len) - { - len--; - hmsc->bot_data[len] = pPage[len]; - } + (void)SCSI_UpdateBotData(hmsc, pPage, len); } return 0; } + /** * @brief SCSI_ReadCapacity10 * Process Read Capacity 10 command @@ -255,32 +297,88 @@ static int8_t SCSI_Inquiry(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *par * @param params: Command parameters * @retval status */ -static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + UNUSED(params); + int8_t ret; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; - if (((USBD_StorageTypeDef *)pdev->pUserData)->GetCapacity(lun, &hmsc->scsi_blk_nbr, &hmsc->scsi_blk_size) != 0) + ret = ((USBD_StorageTypeDef *)pdev->pUserData)->GetCapacity(lun, &hmsc->scsi_blk_nbr, &hmsc->scsi_blk_size); + + if ((ret != 0) || (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED)) { SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT); return -1; } - else - { - hmsc->bot_data[0] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 24); - hmsc->bot_data[1] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 16); - hmsc->bot_data[2] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 8); - hmsc->bot_data[3] = (uint8_t)(hmsc->scsi_blk_nbr - 1U); + hmsc->bot_data[0] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 24); + hmsc->bot_data[1] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 16); + hmsc->bot_data[2] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 8); + hmsc->bot_data[3] = (uint8_t)(hmsc->scsi_blk_nbr - 1U); - hmsc->bot_data[4] = (uint8_t)(hmsc->scsi_blk_size >> 24); - hmsc->bot_data[5] = (uint8_t)(hmsc->scsi_blk_size >> 16); - hmsc->bot_data[6] = (uint8_t)(hmsc->scsi_blk_size >> 8); - hmsc->bot_data[7] = (uint8_t)(hmsc->scsi_blk_size); + hmsc->bot_data[4] = (uint8_t)(hmsc->scsi_blk_size >> 24); + hmsc->bot_data[5] = (uint8_t)(hmsc->scsi_blk_size >> 16); + hmsc->bot_data[6] = (uint8_t)(hmsc->scsi_blk_size >> 8); + hmsc->bot_data[7] = (uint8_t)(hmsc->scsi_blk_size); + + hmsc->bot_data_length = 8U; + + return 0; - hmsc->bot_data_length = 8U; - return 0; - } } + + +/** +* @brief SCSI_ReadCapacity16 +* Process Read Capacity 16 command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ + UNUSED(params); + uint8_t idx; + int8_t ret; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + + ret = ((USBD_StorageTypeDef *)pdev->pUserData)->GetCapacity(lun, &hmsc->scsi_blk_nbr, &hmsc->scsi_blk_size); + + if ((ret != 0) || (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED)) + { + SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT); + return -1; + } + + hmsc->bot_data_length = ((uint32_t)params[10] << 24) | + ((uint32_t)params[11] << 16) | + ((uint32_t)params[12] << 8) | + (uint32_t)params[13]; + + for (idx = 0U; idx < hmsc->bot_data_length; idx++) + { + hmsc->bot_data[idx] = 0U; + } + + hmsc->bot_data[4] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 24); + hmsc->bot_data[5] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 16); + hmsc->bot_data[6] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 8); + hmsc->bot_data[7] = (uint8_t)(hmsc->scsi_blk_nbr - 1U); + + hmsc->bot_data[8] = (uint8_t)(hmsc->scsi_blk_size >> 24); + hmsc->bot_data[9] = (uint8_t)(hmsc->scsi_blk_size >> 16); + hmsc->bot_data[10] = (uint8_t)(hmsc->scsi_blk_size >> 8); + hmsc->bot_data[11] = (uint8_t)(hmsc->scsi_blk_size); + + hmsc->bot_data_length = ((uint32_t)params[10] << 24) | + ((uint32_t)params[11] << 16) | + ((uint32_t)params[12] << 8) | + (uint32_t)params[13]; + + return 0; +} + + /** * @brief SCSI_ReadFormatCapacity * Process Read Format Capacity command @@ -288,41 +386,45 @@ static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_ * @param params: Command parameters * @retval status */ -static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; - + UNUSED(params); uint16_t blk_size; uint32_t blk_nbr; uint16_t i; + int8_t ret; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + + ret = ((USBD_StorageTypeDef *)pdev->pUserData)->GetCapacity(lun, &blk_nbr, &blk_size); + + if ((ret != 0) || (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED)) + { + SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT); + return -1; + } for (i = 0U; i < 12U ; i++) { hmsc->bot_data[i] = 0U; } - if (((USBD_StorageTypeDef *)pdev->pUserData)->GetCapacity(lun, &blk_nbr, &blk_size) != 0U) - { - SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT); - return -1; - } - else - { - hmsc->bot_data[3] = 0x08U; - hmsc->bot_data[4] = (uint8_t)((blk_nbr - 1U) >> 24); - hmsc->bot_data[5] = (uint8_t)((blk_nbr - 1U) >> 16); - hmsc->bot_data[6] = (uint8_t)((blk_nbr - 1U) >> 8); - hmsc->bot_data[7] = (uint8_t)(blk_nbr - 1U); + hmsc->bot_data[3] = 0x08U; + hmsc->bot_data[4] = (uint8_t)((blk_nbr - 1U) >> 24); + hmsc->bot_data[5] = (uint8_t)((blk_nbr - 1U) >> 16); + hmsc->bot_data[6] = (uint8_t)((blk_nbr - 1U) >> 8); + hmsc->bot_data[7] = (uint8_t)(blk_nbr - 1U); - hmsc->bot_data[8] = 0x02U; - hmsc->bot_data[9] = (uint8_t)(blk_size >> 16); - hmsc->bot_data[10] = (uint8_t)(blk_size >> 8); - hmsc->bot_data[11] = (uint8_t)(blk_size); + hmsc->bot_data[8] = 0x02U; + hmsc->bot_data[9] = (uint8_t)(blk_size >> 16); + hmsc->bot_data[10] = (uint8_t)(blk_size >> 8); + hmsc->bot_data[11] = (uint8_t)(blk_size); - hmsc->bot_data_length = 12U; - return 0; - } + hmsc->bot_data_length = 12U; + + return 0; } + + /** * @brief SCSI_ModeSense6 * Process Mode Sense6 command @@ -330,20 +432,23 @@ static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, ui * @param params: Command parameters * @retval status */ -static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; - uint16_t len = 8U; - hmsc->bot_data_length = len; + UNUSED(lun); + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + uint16_t len = MODE_SENSE6_LEN; - while (len) + if (params[4] <= len) { - len--; - hmsc->bot_data[len] = MSC_Mode_Sense6_data[len]; + len = params[4]; } + + (void)SCSI_UpdateBotData(hmsc, MSC_Mode_Sense6_data, len); + return 0; } + /** * @brief SCSI_ModeSense10 * Process Mode Sense10 command @@ -351,22 +456,23 @@ static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *p * @param params: Command parameters * @retval status */ -static int8_t SCSI_ModeSense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +static int8_t SCSI_ModeSense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { - uint16_t len = 8U; - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + UNUSED(lun); + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + uint16_t len = MODE_SENSE10_LEN; - hmsc->bot_data_length = len; - - while (len) + if (params[8] <= len) { - len--; - hmsc->bot_data[len] = MSC_Mode_Sense10_data[len]; + len = params[8]; } + (void)SCSI_UpdateBotData(hmsc, MSC_Mode_Sense10_data, len); + return 0; } + /** * @brief SCSI_RequestSense * Process Request Sense command @@ -374,13 +480,19 @@ static int8_t SCSI_ModeSense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t * * @param params: Command parameters * @retval status */ - -static int8_t SCSI_RequestSense(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +static int8_t SCSI_RequestSense(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { + 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->pClassData; - for (i = 0U ; i < REQUEST_SENSE_DATA_LEN; i++) + if (hmsc->cbw.dDataLength == 0U) + { + SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB); + return -1; + } + + for (i = 0U; i < REQUEST_SENSE_DATA_LEN; i++) { hmsc->bot_data[i] = 0U; } @@ -390,10 +502,9 @@ static int8_t SCSI_RequestSense(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t if ((hmsc->scsi_sense_head != hmsc->scsi_sense_tail)) { - - hmsc->bot_data[2] = hmsc->scsi_sense[hmsc->scsi_sense_head].Skey; - hmsc->bot_data[12] = hmsc->scsi_sense[hmsc->scsi_sense_head].w.b.ASCQ; - hmsc->bot_data[13] = hmsc->scsi_sense[hmsc->scsi_sense_head].w.b.ASC; + hmsc->bot_data[2] = (uint8_t)hmsc->scsi_sense[hmsc->scsi_sense_head].Skey; + hmsc->bot_data[12] = (uint8_t)hmsc->scsi_sense[hmsc->scsi_sense_head].w.b.ASC; + hmsc->bot_data[13] = (uint8_t)hmsc->scsi_sense[hmsc->scsi_sense_head].w.b.ASCQ; hmsc->scsi_sense_head++; if (hmsc->scsi_sense_head == SENSE_LIST_DEEPTH) @@ -401,36 +512,44 @@ static int8_t SCSI_RequestSense(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t hmsc->scsi_sense_head = 0U; } } + hmsc->bot_data_length = REQUEST_SENSE_DATA_LEN; if (params[4] <= REQUEST_SENSE_DATA_LEN) { hmsc->bot_data_length = params[4]; } + return 0; } + /** * @brief SCSI_SenseCode * Load the last error code in the error list * @param lun: Logical unit number * @param sKey: Sense Key -* @param ASC: Additional Sense Key +* @param ASC: Additional Sense Code * @retval none */ -void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey, uint8_t ASC) +void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey, uint8_t ASC) { - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + UNUSED(lun); + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; - hmsc->scsi_sense[hmsc->scsi_sense_tail].Skey = sKey; - hmsc->scsi_sense[hmsc->scsi_sense_tail].w.ASC = ASC << 8; + hmsc->scsi_sense[hmsc->scsi_sense_tail].Skey = sKey; + hmsc->scsi_sense[hmsc->scsi_sense_tail].w.b.ASC = ASC; + hmsc->scsi_sense[hmsc->scsi_sense_tail].w.b.ASCQ = 0U; hmsc->scsi_sense_tail++; + if (hmsc->scsi_sense_tail == SENSE_LIST_DEEPTH) { hmsc->scsi_sense_tail = 0U; } } + + /** * @brief SCSI_StartStopUnit * Process Start Stop Unit command @@ -438,13 +557,67 @@ void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey, uint8_ * @param params: Command parameters * @retval status */ -static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { - USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *) pdev->pClassData; + UNUSED(lun); + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + + if ((hmsc->scsi_medium_state == SCSI_MEDIUM_LOCKED) && ((params[4] & 0x3U) == 2U)) + { + SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND); + + return -1; + } + + if ((params[4] & 0x3U) == 0x1U) /* START=1 */ + { + hmsc->scsi_medium_state = SCSI_MEDIUM_UNLOCKED; + } + else if ((params[4] & 0x3U) == 0x2U) /* START=0 and LOEJ Load Eject=1 */ + { + hmsc->scsi_medium_state = SCSI_MEDIUM_EJECTED; + } + else if ((params[4] & 0x3U) == 0x3U) /* START=1 and LOEJ Load Eject=1 */ + { + hmsc->scsi_medium_state = SCSI_MEDIUM_UNLOCKED; + } + else + { + /* .. */ + } hmsc->bot_data_length = 0U; + return 0; } + +/** +* @brief SCSI_AllowPreventRemovable +* Process Allow Prevent Removable medium command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +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; + + if (params[4] == 0U) + { + hmsc->scsi_medium_state = SCSI_MEDIUM_UNLOCKED; + } + else + { + hmsc->scsi_medium_state = SCSI_MEDIUM_LOCKED; + } + + hmsc->bot_data_length = 0U; + + return 0; +} + + /** * @brief SCSI_Read10 * Process Read10 command @@ -454,7 +627,7 @@ static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t */ 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->pClassData; if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */ { @@ -465,6 +638,13 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params return -1; } + if (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED) + { + SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT); + + return -1; + } + if (((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) != 0) { SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT); @@ -484,7 +664,68 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params return -1; /* error */ } + /* cases 4,5 : Hi <> Dn */ + if (hmsc->cbw.dDataLength != (hmsc->scsi_blk_len * hmsc->scsi_blk_size)) + { + SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB); + return -1; + } + hmsc->bot_state = USBD_BOT_DATA_IN; + } + hmsc->bot_data_length = MSC_MEDIA_PACKET; + + return SCSI_ProcessRead(pdev, lun); +} + + +/** +* @brief SCSI_Read12 +* Process Read12 command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +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; + + if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */ + { + /* case 10 : Ho <> Di */ + if ((hmsc->cbw.bmFlags & 0x80U) != 0x80U) + { + SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB); + return -1; + } + + if (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED) + { + SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT); + return -1; + } + + if (((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) != 0) + { + SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT); + return -1; + } + + hmsc->scsi_blk_addr = ((uint32_t)params[2] << 24) | + ((uint32_t)params[3] << 16) | + ((uint32_t)params[4] << 8) | + (uint32_t)params[5]; + + hmsc->scsi_blk_len = ((uint32_t)params[6] << 24) | + ((uint32_t)params[7] << 16) | + ((uint32_t)params[8] << 8) | + (uint32_t)params[9]; + + if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, + hmsc->scsi_blk_len) < 0) + { + return -1; /* error */ + } /* cases 4,5 : Hi <> Dn */ if (hmsc->cbw.dDataLength != (hmsc->scsi_blk_len * hmsc->scsi_blk_size)) @@ -492,12 +733,15 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB); return -1; } + + hmsc->bot_state = USBD_BOT_DATA_IN; } hmsc->bot_data_length = MSC_MEDIA_PACKET; return SCSI_ProcessRead(pdev, lun); } + /** * @brief SCSI_Write10 * Process Write10 command @@ -505,14 +749,19 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params * @param params: Command parameters * @retval status */ - -static int8_t SCSI_Write10(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->pClassData; uint32_t len; if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */ { + if (hmsc->cbw.dDataLength == 0U) + { + SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB); + return -1; + } + /* case 8 : Hi <> Do */ if ((hmsc->cbw.bmFlags & 0x80U) == 0x80U) { @@ -562,12 +811,97 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *para /* Prepare EP to receive first data packet */ hmsc->bot_state = USBD_BOT_DATA_OUT; - USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, hmsc->bot_data, len); + (void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, hmsc->bot_data, len); } else /* Write Process ongoing */ { return SCSI_ProcessWrite(pdev, lun); } + + return 0; +} + + +/** +* @brief SCSI_Write12 +* Process Write12 command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +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; + uint32_t len; + + if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */ + { + if (hmsc->cbw.dDataLength == 0U) + { + SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB); + return -1; + } + + /* case 8 : Hi <> Do */ + if ((hmsc->cbw.bmFlags & 0x80U) == 0x80U) + { + SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB); + return -1; + } + + /* Check whether Media is ready */ + if (((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) != 0) + { + SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT); + hmsc->bot_state = USBD_BOT_NO_DATA; + return -1; + } + + /* Check If media is write-protected */ + if (((USBD_StorageTypeDef *)pdev->pUserData)->IsWriteProtected(lun) != 0) + { + SCSI_SenseCode(pdev, lun, NOT_READY, WRITE_PROTECTED); + hmsc->bot_state = USBD_BOT_NO_DATA; + return -1; + } + + hmsc->scsi_blk_addr = ((uint32_t)params[2] << 24) | + ((uint32_t)params[3] << 16) | + ((uint32_t)params[4] << 8) | + (uint32_t)params[5]; + + hmsc->scsi_blk_len = ((uint32_t)params[6] << 24) | + ((uint32_t)params[7] << 16) | + ((uint32_t)params[8] << 8) | + (uint32_t)params[9]; + + /* check if LBA address is in the right range */ + if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, + hmsc->scsi_blk_len) < 0) + { + return -1; /* error */ + } + + len = hmsc->scsi_blk_len * hmsc->scsi_blk_size; + + /* cases 3,11,13 : Hn,Ho <> D0 */ + if (hmsc->cbw.dDataLength != len) + { + SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB); + return -1; + } + + len = MIN(len, MSC_MEDIA_PACKET); + + /* 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); + } + else /* Write Process ongoing */ + { + return SCSI_ProcessWrite(pdev, lun); + } + return 0; } @@ -579,10 +913,9 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *para * @param params: Command parameters * @retval status */ - -static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +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->pClassData; if ((params[1] & 0x02U) == 0x02U) { @@ -590,12 +923,13 @@ static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *par return -1; /* Error, Verify Mode Not supported*/ } - if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, - hmsc->scsi_blk_len) < 0) + if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, hmsc->scsi_blk_len) < 0) { return -1; /* error */ } + hmsc->bot_data_length = 0U; + return 0; } @@ -610,13 +944,14 @@ static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *par 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->pClassData; if ((blk_offset + blk_nbr) > hmsc->scsi_blk_nbr) { SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, ADDRESS_OUT_OF_RANGE); return -1; } + return 0; } @@ -626,15 +961,14 @@ static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun, * @param lun: Logical unit number * @retval status */ -static int8_t SCSI_ProcessRead(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; len = MIN(len, MSC_MEDIA_PACKET); - if (((USBD_StorageTypeDef *)pdev->pUserData)->Read(lun, - hmsc->bot_data, + if (((USBD_StorageTypeDef *)pdev->pUserData)->Read(lun, hmsc->bot_data, hmsc->scsi_blk_addr, (len / hmsc->scsi_blk_size)) < 0) { @@ -642,7 +976,7 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun) return -1; } - USBD_LL_Transmit(pdev, MSC_EPIN_ADDR, hmsc->bot_data, len); + (void)USBD_LL_Transmit(pdev, MSC_EPIN_ADDR, hmsc->bot_data, len); hmsc->scsi_blk_addr += (len / hmsc->scsi_blk_size); hmsc->scsi_blk_len -= (len / hmsc->scsi_blk_size); @@ -654,6 +988,7 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun) { hmsc->bot_state = USBD_BOT_LAST_DATA_IN; } + return 0; } @@ -663,10 +998,9 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun) * @param lun: Logical unit number * @retval status */ - -static int8_t SCSI_ProcessWrite(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; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; uint32_t len = hmsc->scsi_blk_len * hmsc->scsi_blk_size; len = MIN(len, MSC_MEDIA_PACKET); @@ -676,7 +1010,6 @@ static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun) (len / hmsc->scsi_blk_size)) < 0) { SCSI_SenseCode(pdev, lun, HARDWARE_ERROR, WRITE_FAULT); - return -1; } @@ -693,8 +1026,34 @@ static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun) else { len = MIN((hmsc->scsi_blk_len * hmsc->scsi_blk_size), MSC_MEDIA_PACKET); + /* Prepare EP to Receive next packet */ - USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, hmsc->bot_data, len); + (void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, hmsc->bot_data, len); + } + + return 0; +} + + +/** +* @brief SCSI_UpdateBotData +* fill the requested Data to transmit buffer +* @param hmsc handler +* @param params: Data buffer +* @param length: Data length +* @retval status +*/ +static int8_t SCSI_UpdateBotData(USBD_MSC_BOT_HandleTypeDef *hmsc, + uint8_t *pBuff, uint16_t length) +{ + uint16_t len = length; + + hmsc->bot_data_length = len; + + while (len != 0U) + { + len--; + hmsc->bot_data[len] = pBuff[len]; } return 0; diff --git a/Class/Template/Inc/usbd_template.h b/Class/Template/Inc/usbd_template.h index eee8a55..8e9163b 100644 --- a/Class/Template/Inc/usbd_template.h +++ b/Class/Template/Inc/usbd_template.h @@ -41,10 +41,10 @@ extern "C" { /** @defgroup USBD_TEMPLATE_Exported_Defines * @{ */ -#define TEMPLATE_EPIN_ADDR 0x81 -#define TEMPLATE_EPIN_SIZE 0x10 +#define TEMPLATE_EPIN_ADDR 0x81U +#define TEMPLATE_EPIN_SIZE 0x10U -#define USB_TEMPLATE_CONFIG_DESC_SIZ 64 +#define USB_TEMPLATE_CONFIG_DESC_SIZ 64U /** * @} @@ -73,7 +73,7 @@ extern "C" { * @{ */ -extern USBD_ClassTypeDef USBD_TEMPLATE_ClassDriver; +extern USBD_ClassTypeDef USBD_TEMPLATE_ClassDriver; /** * @} */ diff --git a/Class/Template/Src/usbd_template.c b/Class/Template/Src/usbd_template.c index 88a5a5a..1c8ea72 100644 --- a/Class/Template/Src/usbd_template.c +++ b/Class/Template/Src/usbd_template.c @@ -83,33 +83,19 @@ */ -static uint8_t USBD_TEMPLATE_Init(USBD_HandleTypeDef *pdev, - uint8_t cfgidx); - -static uint8_t USBD_TEMPLATE_DeInit(USBD_HandleTypeDef *pdev, - uint8_t cfgidx); - -static uint8_t USBD_TEMPLATE_Setup(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req); - -static uint8_t *USBD_TEMPLATE_GetCfgDesc(uint16_t *length); - -static uint8_t *USBD_TEMPLATE_GetDeviceQualifierDesc(uint16_t *length); - -static uint8_t USBD_TEMPLATE_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); - -static uint8_t USBD_TEMPLATE_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum); - -static uint8_t USBD_TEMPLATE_EP0_RxReady(USBD_HandleTypeDef *pdev); - -static uint8_t USBD_TEMPLATE_EP0_TxReady(USBD_HandleTypeDef *pdev); - -static uint8_t USBD_TEMPLATE_SOF(USBD_HandleTypeDef *pdev); - -static uint8_t USBD_TEMPLATE_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); - -static uint8_t USBD_TEMPLATE_IsoOutIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); +static uint8_t USBD_TEMPLATE_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +static uint8_t USBD_TEMPLATE_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +static uint8_t USBD_TEMPLATE_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static uint8_t USBD_TEMPLATE_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); +static uint8_t USBD_TEMPLATE_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum); +static uint8_t USBD_TEMPLATE_EP0_RxReady(USBD_HandleTypeDef *pdev); +static uint8_t USBD_TEMPLATE_EP0_TxReady(USBD_HandleTypeDef *pdev); +static uint8_t USBD_TEMPLATE_SOF(USBD_HandleTypeDef *pdev); +static uint8_t USBD_TEMPLATE_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); +static uint8_t USBD_TEMPLATE_IsoOutIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); +static uint8_t *USBD_TEMPLATE_GetCfgDesc(uint16_t *length); +static uint8_t *USBD_TEMPLATE_GetDeviceQualifierDesc(uint16_t *length); /** * @} */ @@ -118,7 +104,7 @@ static uint8_t USBD_TEMPLATE_IsoOutIncomplete(USBD_HandleTypeDef *pdev, uint8_t * @{ */ -USBD_ClassTypeDef USBD_TEMPLATE_ClassDriver = +USBD_ClassTypeDef USBD_TEMPLATE_ClassDriver = { USBD_TEMPLATE_Init, USBD_TEMPLATE_DeInit, @@ -140,7 +126,7 @@ USBD_ClassTypeDef USBD_TEMPLATE_ClassDriver = #pragma data_alignment=4 #endif /* USB TEMPLATE device Configuration Descriptor */ -static uint8_t USBD_TEMPLATE_CfgDesc[USB_TEMPLATE_CONFIG_DESC_SIZ] = +__ALIGN_BEGIN static uint8_t USBD_TEMPLATE_CfgDesc[USB_TEMPLATE_CONFIG_DESC_SIZ] __ALIGN_END = { 0x09, /* bLength: Configuation Descriptor size */ USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, /* bDescriptorType: Configuration */ @@ -162,7 +148,7 @@ static uint8_t USBD_TEMPLATE_CfgDesc[USB_TEMPLATE_CONFIG_DESC_SIZ] = #pragma data_alignment=4 #endif /* USB Standard Device Descriptor */ -static uint8_t USBD_TEMPLATE_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] = +__ALIGN_BEGIN static uint8_t USBD_TEMPLATE_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = { USB_LEN_DEV_QUALIFIER_DESC, USB_DESC_TYPE_DEVICE_QUALIFIER, @@ -191,13 +177,10 @@ static uint8_t USBD_TEMPLATE_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] = * @param cfgidx: Configuration index * @retval status */ -static uint8_t USBD_TEMPLATE_Init(USBD_HandleTypeDef *pdev, - uint8_t cfgidx) +static uint8_t USBD_TEMPLATE_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { - uint8_t ret = 0; - - return ret; + return (uint8_t)USBD_OK; } /** @@ -207,11 +190,10 @@ static uint8_t USBD_TEMPLATE_Init(USBD_HandleTypeDef *pdev, * @param cfgidx: Configuration index * @retval status */ -static uint8_t USBD_TEMPLATE_DeInit(USBD_HandleTypeDef *pdev, - uint8_t cfgidx) +static uint8_t USBD_TEMPLATE_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { - return USBD_OK; + return (uint8_t)USBD_OK; } /** @@ -221,40 +203,40 @@ static uint8_t USBD_TEMPLATE_DeInit(USBD_HandleTypeDef *pdev, * @param req: usb requests * @retval status */ -static uint8_t USBD_TEMPLATE_Setup(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req) +static uint8_t USBD_TEMPLATE_Setup(USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req) { USBD_StatusTypeDef ret = USBD_OK; switch (req->bmRequest & USB_REQ_TYPE_MASK) { - case USB_REQ_TYPE_CLASS : - switch (req->bRequest) - { - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; - } - break; - - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; - } - break; - + case USB_REQ_TYPE_CLASS : + switch (req->bRequest) + { default: USBD_CtlError(pdev, req); ret = USBD_FAIL; break; + } + break; + + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + } + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; } - return ret; + return (uint8_t)ret; } @@ -264,9 +246,9 @@ static uint8_t USBD_TEMPLATE_Setup(USBD_HandleTypeDef *pdev, * @param length : pointer data length * @retval pointer to descriptor buffer */ -static uint8_t *USBD_TEMPLATE_GetCfgDesc(uint16_t *length) +static uint8_t *USBD_TEMPLATE_GetCfgDesc(uint16_t *length) { - *length = sizeof(USBD_TEMPLATE_CfgDesc); + *length = (uint16_t)sizeof(USBD_TEMPLATE_CfgDesc); return USBD_TEMPLATE_CfgDesc; } @@ -276,9 +258,9 @@ static uint8_t *USBD_TEMPLATE_GetCfgDesc(uint16_t *length) * @param length : pointer data length * @retval pointer to descriptor buffer */ -uint8_t *USBD_TEMPLATE_DeviceQualifierDescriptor(uint16_t *length) +uint8_t *USBD_TEMPLATE_DeviceQualifierDescriptor(uint16_t *length) { - *length = sizeof(USBD_TEMPLATE_DeviceQualifierDesc); + *length = (uint16_t)sizeof(USBD_TEMPLATE_DeviceQualifierDesc); return USBD_TEMPLATE_DeviceQualifierDesc; } @@ -290,11 +272,10 @@ uint8_t *USBD_TEMPLATE_DeviceQualifierDescriptor(uint16_t *length) * @param epnum: endpoint index * @retval status */ -static uint8_t USBD_TEMPLATE_DataIn(USBD_HandleTypeDef *pdev, - uint8_t epnum) +static uint8_t USBD_TEMPLATE_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) { - return USBD_OK; + return (uint8_t)USBD_OK; } /** @@ -303,10 +284,10 @@ static uint8_t USBD_TEMPLATE_DataIn(USBD_HandleTypeDef *pdev, * @param pdev: device instance * @retval status */ -static uint8_t USBD_TEMPLATE_EP0_RxReady(USBD_HandleTypeDef *pdev) +static uint8_t USBD_TEMPLATE_EP0_RxReady(USBD_HandleTypeDef *pdev) { - return USBD_OK; + return (uint8_t)USBD_OK; } /** * @brief USBD_TEMPLATE_EP0_TxReady @@ -314,10 +295,10 @@ static uint8_t USBD_TEMPLATE_EP0_RxReady(USBD_HandleTypeDef *pdev) * @param pdev: device instance * @retval status */ -static uint8_t USBD_TEMPLATE_EP0_TxReady(USBD_HandleTypeDef *pdev) +static uint8_t USBD_TEMPLATE_EP0_TxReady(USBD_HandleTypeDef *pdev) { - return USBD_OK; + return (uint8_t)USBD_OK; } /** * @brief USBD_TEMPLATE_SOF @@ -325,10 +306,10 @@ static uint8_t USBD_TEMPLATE_EP0_TxReady(USBD_HandleTypeDef *pdev) * @param pdev: device instance * @retval status */ -static uint8_t USBD_TEMPLATE_SOF(USBD_HandleTypeDef *pdev) +static uint8_t USBD_TEMPLATE_SOF(USBD_HandleTypeDef *pdev) { - return USBD_OK; + return (uint8_t)USBD_OK; } /** * @brief USBD_TEMPLATE_IsoINIncomplete @@ -337,10 +318,10 @@ static uint8_t USBD_TEMPLATE_SOF(USBD_HandleTypeDef *pdev) * @param epnum: endpoint index * @retval status */ -static uint8_t USBD_TEMPLATE_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) +static uint8_t USBD_TEMPLATE_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) { - return USBD_OK; + return (uint8_t)USBD_OK; } /** * @brief USBD_TEMPLATE_IsoOutIncomplete @@ -349,10 +330,10 @@ static uint8_t USBD_TEMPLATE_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t * @param epnum: endpoint index * @retval status */ -static uint8_t USBD_TEMPLATE_IsoOutIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) +static uint8_t USBD_TEMPLATE_IsoOutIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) { - return USBD_OK; + return (uint8_t)USBD_OK; } /** * @brief USBD_TEMPLATE_DataOut @@ -361,11 +342,10 @@ static uint8_t USBD_TEMPLATE_IsoOutIncomplete(USBD_HandleTypeDef *pdev, uint8_t * @param epnum: endpoint index * @retval status */ -static uint8_t USBD_TEMPLATE_DataOut(USBD_HandleTypeDef *pdev, - uint8_t epnum) +static uint8_t USBD_TEMPLATE_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) { - return USBD_OK; + return (uint8_t)USBD_OK; } /** @@ -374,9 +354,10 @@ static uint8_t USBD_TEMPLATE_DataOut(USBD_HandleTypeDef *pdev, * @param length : pointer data length * @retval pointer to descriptor buffer */ -uint8_t *USBD_TEMPLATE_GetDeviceQualifierDesc(uint16_t *length) +uint8_t *USBD_TEMPLATE_GetDeviceQualifierDesc(uint16_t *length) { - *length = sizeof(USBD_TEMPLATE_DeviceQualifierDesc); + *length = (uint16_t)sizeof(USBD_TEMPLATE_DeviceQualifierDesc); + return USBD_TEMPLATE_DeviceQualifierDesc; } diff --git a/Core/Inc/usbd_conf_template.h b/Core/Inc/usbd_conf_template.h index e47c41c..85e18ab 100644 --- a/Core/Inc/usbd_conf_template.h +++ b/Core/Inc/usbd_conf_template.h @@ -44,12 +44,19 @@ extern "C" { * @{ */ -#define USBD_MAX_NUM_INTERFACES 1U -#define USBD_MAX_NUM_CONFIGURATION 1U -#define USBD_MAX_STR_DESC_SIZ 0x100U -#define USBD_SUPPORT_USER_STRING_DESC 0U -#define USBD_SELF_POWERED 1U -#define USBD_DEBUG_LEVEL 2U +#define USBD_MAX_NUM_INTERFACES 1U +#define USBD_MAX_NUM_CONFIGURATION 1U +#define USBD_MAX_STR_DESC_SIZ 0x100U +#define USBD_SELF_POWERED 1U +#define USBD_DEBUG_LEVEL 2U + +/* ECM, RNDIS, DFU Class Config */ +#define USBD_SUPPORT_USER_STRING_DESC 1U + +/* BillBoard Class Config */ +#define USBD_CLASS_USER_STRING_DESC 1U +#define USBD_CLASS_BOS_ENABLED 1U +#define USB_BB_MAX_NUM_ALT_MODE 0x2U /* MSC Class Config */ #define MSC_MEDIA_PACKET 8192U @@ -62,7 +69,7 @@ extern "C" { #define USBD_DFU_XFERS_IZE 1024U /* AUDIO Class Config */ -#define USBD_AUDIO_FREQ 22100U +#define USBD_AUDIO_FREQ 22100U /** @defgroup USBD_Exported_Macros * @{ @@ -73,6 +80,7 @@ extern "C" { #define USBD_free free #define USBD_memset memset #define USBD_memcpy memcpy +#define USBD_Delay HAL_Delay /* DEBUG macros */ #if (USBD_DEBUG_LEVEL > 0U) diff --git a/Core/Inc/usbd_core.h b/Core/Inc/usbd_core.h index 2392815..c7d2ba3 100644 --- a/Core/Inc/usbd_core.h +++ b/Core/Inc/usbd_core.h @@ -88,53 +88,50 @@ USBD_StatusTypeDef USBD_Start(USBD_HandleTypeDef *pdev); USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev); USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass); -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); +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); USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup); USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, uint8_t epnum, uint8_t *pdata); USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, uint8_t epnum, uint8_t *pdata); -USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev); -USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_SpeedTypeDef speed); -USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev); -USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_SpeedTypeDef speed); +USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev); USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev); -USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); -USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); +USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); +USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); -USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev); -USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev); /* USBD Low Level Driver */ -USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev); -USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev); -USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev); -USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev); -USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, - uint8_t ep_addr, - uint8_t ep_type, - uint16_t ep_mps); +USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev); -USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); -USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); -USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); -USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); -uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); -USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr); -USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, - uint8_t ep_addr, - uint8_t *pbuf, - uint16_t size); +USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr, + uint8_t ep_type, uint16_t ep_mps); -USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, - uint8_t ep_addr, - uint8_t *pbuf, - uint16_t size); +USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); +USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); +USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); +USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); +USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr); +USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr, + uint8_t *pbuf, uint32_t size); + +USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, uint8_t ep_addr, + uint8_t *pbuf, uint32_t size); + +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); /** diff --git a/Core/Inc/usbd_ctlreq.h b/Core/Inc/usbd_ctlreq.h index 047fe2e..f973a8b 100644 --- a/Core/Inc/usbd_ctlreq.h +++ b/Core/Inc/usbd_ctlreq.h @@ -73,16 +73,14 @@ extern "C" { * @{ */ -USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); -USBD_StatusTypeDef USBD_StdItfReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); -USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); - - -void USBD_CtlError(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +USBD_StatusTypeDef USBD_StdItfReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +void USBD_CtlError(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata); - void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len); + /** * @} */ diff --git a/Core/Inc/usbd_def.h b/Core/Inc/usbd_def.h index a805e8b..0463e2f 100644 --- a/Core/Inc/usbd_def.h +++ b/Core/Inc/usbd_def.h @@ -65,6 +65,10 @@ extern "C" { #define USBD_SUPPORT_USER_STRING_DESC 0U #endif /* USBD_SUPPORT_USER_STRING_DESC */ +#ifndef USBD_CLASS_USER_STRING_DESC +#define USBD_CLASS_USER_STRING_DESC 0U +#endif /* USBD_CLASS_USER_STRING_DESC */ + #define USB_LEN_DEV_QUALIFIER_DESC 0x0AU #define USB_LEN_DEV_DESC 0x12U #define USB_LEN_CFG_DESC 0x09U @@ -165,6 +169,28 @@ typedef struct usb_setup_req uint16_t wLength; } USBD_SetupReqTypedef; +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t wDescriptorLengthLow; + uint8_t wDescriptorLengthHigh; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; +} USBD_ConfigDescTypedef; + +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wTotalLength; + uint8_t bNumDeviceCaps; +} USBD_BosDescTypedef; + + struct _USBD_HandleTypeDef; typedef struct _Device_cb @@ -203,34 +229,39 @@ typedef enum /* Following USB Device status */ typedef enum { - USBD_OK = 0U, + USBD_OK = 0U, USBD_BUSY, + USBD_EMEM, USBD_FAIL, } USBD_StatusTypeDef; /* USB Device descriptors structure */ typedef struct { - uint8_t *(*GetDeviceDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); - uint8_t *(*GetLangIDStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); - uint8_t *(*GetManufacturerStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); - uint8_t *(*GetProductStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); - uint8_t *(*GetSerialStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); - uint8_t *(*GetConfigurationStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); - uint8_t *(*GetInterfaceStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); -#if (USBD_LPM_ENABLED == 1U) - uint8_t *(*GetBOSDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); + uint8_t *(*GetDeviceDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); + uint8_t *(*GetLangIDStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); + uint8_t *(*GetManufacturerStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); + uint8_t *(*GetProductStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); + uint8_t *(*GetSerialStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); + uint8_t *(*GetConfigurationStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); + 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 +#if ((USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1)) + uint8_t *(*GetBOSDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); #endif } USBD_DescriptorsTypeDef; /* USB Device handle structure */ typedef struct { - uint32_t status; - uint32_t is_used; - uint32_t total_length; - uint32_t rem_length; - uint32_t maxpacket; + uint32_t status; + uint32_t total_length; + uint32_t rem_length; + uint32_t maxpacket; + uint16_t is_used; + uint16_t bInterval; } USBD_EndpointTypeDef; /* USB Device handle structure */ @@ -251,6 +282,7 @@ typedef struct _USBD_HandleTypeDef uint8_t dev_connection_status; uint8_t dev_test_mode; uint32_t dev_remote_wakeup; + uint8_t ConfIdx; USBD_SetupReqTypedef request; USBD_DescriptorsTypeDef *pDesc; @@ -258,6 +290,8 @@ typedef struct _USBD_HandleTypeDef void *pClassData; void *pUserData; void *pData; + void *pBosDesc; + void *pConfDesc; } USBD_HandleTypeDef; /** @@ -269,8 +303,19 @@ typedef struct _USBD_HandleTypeDef /** @defgroup USBD_DEF_Exported_Macros * @{ */ -#define SWAPBYTE(addr) (((uint16_t)(*((uint8_t *)(addr)))) + \ - (((uint16_t)(*(((uint8_t *)(addr)) + 1U))) << 8U)) +__STATIC_INLINE uint16_t SWAPBYTE(uint8_t *addr) +{ + uint16_t _SwapVal, _Byte1, _Byte2; + uint8_t *_pbuff = addr; + + _Byte1 = *(uint8_t *)_pbuff; + _pbuff++; + _Byte2 = *(uint8_t *)_pbuff; + + _SwapVal = (_Byte2 << 8) | _Byte1; + + return _SwapVal; +} #define LOBYTE(x) ((uint8_t)((x) & 0x00FFU)) #define HIBYTE(x) ((uint8_t)(((x) & 0xFF00U) >> 8U)) diff --git a/Core/Inc/usbd_desc_template.h b/Core/Inc/usbd_desc_template.h index 35a5e63..8fbbfaa 100644 --- a/Core/Inc/usbd_desc_template.h +++ b/Core/Inc/usbd_desc_template.h @@ -26,11 +26,33 @@ /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ -#define DEVICE_ID1 (0x1FFF7A10) -#define DEVICE_ID2 (0x1FFF7A14) -#define DEVICE_ID3 (0x1FFF7A18) +#define DEVICE_ID1 (UID_BASE) +#define DEVICE_ID2 (UID_BASE + 0x4U) +#define DEVICE_ID3 (UID_BASE + 0x8U) -#define USB_SIZ_STRING_SERIAL 0x1A +/* + * USB Billboard Class USER string desc Defines Template + * index should start form 0x10 to avoid using the reserved device string desc indexes + */ +#if (USBD_CLASS_USER_STRING_DESC == 1) +#define USBD_BB_IF_STRING_INDEX 0x10U +#define USBD_BB_URL_STRING_INDEX 0x11U +#define USBD_BB_ALTMODE0_STRING_INDEX 0x12U +#define USBD_BB_ALTMODE1_STRING_INDEX 0x13U +/* Add Specific USER string Desc */ +#define USBD_BB_IF_STR_DESC (uint8_t *)"STM32 BillBoard Interface" +#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 + +#define USB_SIZ_STRING_SERIAL 0x1AU + +#if (USBD_LPM_ENABLED == 1) +#define USB_SIZ_BOS_DESC 0x0CU +#elif (USBD_CLASS_BOS_ENABLED == 1) +#define USB_SIZ_BOS_DESC 0x5DU +#endif /* Exported macro ------------------------------------------------------------*/ /* Exported functions ------------------------------------------------------- */ diff --git a/Core/Inc/usbd_ioreq.h b/Core/Inc/usbd_ioreq.h index 629369e..b7159d5 100644 --- a/Core/Inc/usbd_ioreq.h +++ b/Core/Inc/usbd_ioreq.h @@ -77,27 +77,22 @@ extern "C" { * @{ */ -USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev, - uint8_t *pbuf, - uint16_t len); +USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev, + uint8_t *pbuf, uint32_t len); -USBD_StatusTypeDef USBD_CtlContinueSendData(USBD_HandleTypeDef *pdev, - uint8_t *pbuf, - uint16_t len); +USBD_StatusTypeDef USBD_CtlContinueSendData(USBD_HandleTypeDef *pdev, + uint8_t *pbuf, uint32_t len); -USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev, - uint8_t *pbuf, - uint16_t len); +USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev, + uint8_t *pbuf, uint32_t len); -USBD_StatusTypeDef USBD_CtlContinueRx(USBD_HandleTypeDef *pdev, - uint8_t *pbuf, - uint16_t len); +USBD_StatusTypeDef USBD_CtlContinueRx(USBD_HandleTypeDef *pdev, + uint8_t *pbuf, uint32_t len); -USBD_StatusTypeDef USBD_CtlSendStatus(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_CtlSendStatus(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_CtlReceiveStatus(USBD_HandleTypeDef *pdev); -USBD_StatusTypeDef USBD_CtlReceiveStatus(USBD_HandleTypeDef *pdev); - -uint32_t USBD_GetRxCount(USBD_HandleTypeDef *pdev, uint8_t ep_addr); +uint32_t USBD_GetRxCount(USBD_HandleTypeDef *pdev, uint8_t ep_addr); /** * @} diff --git a/Core/Src/usbd_conf_template.c b/Core/Src/usbd_conf_template.c index dbc75d8..67b70aa 100644 --- a/Core/Src/usbd_conf_template.c +++ b/Core/Src/usbd_conf_template.c @@ -34,6 +34,8 @@ */ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev) { + UNUSED(pdev); + return USBD_OK; } @@ -44,6 +46,8 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev) */ USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev) { + UNUSED(pdev); + return USBD_OK; } @@ -54,6 +58,8 @@ USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev) */ USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev) { + UNUSED(pdev); + return USBD_OK; } @@ -64,6 +70,8 @@ USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev) */ USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev) { + UNUSED(pdev); + return USBD_OK; } @@ -78,6 +86,11 @@ USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev) USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps) { + UNUSED(pdev); + UNUSED(ep_addr); + UNUSED(ep_type); + UNUSED(ep_mps); + return USBD_OK; } @@ -89,6 +102,9 @@ USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr, */ USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) { + UNUSED(pdev); + UNUSED(ep_addr); + return USBD_OK; } @@ -100,6 +116,9 @@ USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) */ USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) { + UNUSED(pdev); + UNUSED(ep_addr); + return USBD_OK; } @@ -111,6 +130,9 @@ USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) */ USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) { + UNUSED(pdev); + UNUSED(ep_addr); + return USBD_OK; } @@ -123,6 +145,9 @@ USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) { + UNUSED(pdev); + UNUSED(ep_addr); + return USBD_OK; } @@ -134,7 +159,10 @@ USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, */ uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) { - return 0; + UNUSED(pdev); + UNUSED(ep_addr); + + return 0U; } /** @@ -146,6 +174,9 @@ uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr) { + UNUSED(pdev); + UNUSED(ep_addr); + return USBD_OK; } @@ -158,8 +189,13 @@ USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, * @retval USBD Status */ USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr, - uint8_t *pbuf, uint16_t size) + uint8_t *pbuf, uint32_t size) { + UNUSED(pdev); + UNUSED(ep_addr); + UNUSED(pbuf); + UNUSED(size); + return USBD_OK; } @@ -173,8 +209,13 @@ 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, - uint16_t size) + uint32_t size) { + UNUSED(pdev); + UNUSED(ep_addr); + UNUSED(pbuf); + UNUSED(size); + return USBD_OK; } @@ -186,6 +227,9 @@ USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, */ uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr) { + UNUSED(pdev); + UNUSED(ep_addr); + return 0U; } @@ -196,6 +240,7 @@ uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr) */ void USBD_LL_Delay(uint32_t Delay) { + UNUSED(Delay); } /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Core/Src/usbd_core.c b/Core/Src/usbd_core.c index ca87977..3faed35 100644 --- a/Core/Src/usbd_core.c +++ b/Core/Src/usbd_core.c @@ -89,6 +89,8 @@ USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id) { + USBD_StatusTypeDef ret; + /* Check whether the USB Host handle is valid */ if (pdev == NULL) { @@ -98,12 +100,17 @@ USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, return USBD_FAIL; } - /* Unlink previous class*/ + /* Unlink previous class */ if (pdev->pClass != NULL) { pdev->pClass = NULL; } + if (pdev->pConfDesc != NULL) + { + pdev->pConfDesc = NULL; + } + /* Assign USBD Descriptors */ if (pdesc != NULL) { @@ -113,10 +120,11 @@ USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, /* Set Device initial State */ pdev->dev_state = USBD_STATE_DEFAULT; pdev->id = id; - /* Initialize low level driver */ - USBD_LL_Init(pdev); - return USBD_OK; + /* Initialize low level driver */ + ret = USBD_LL_Init(pdev); + + return ret; } /** @@ -127,19 +135,34 @@ USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, */ USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev) { + USBD_StatusTypeDef ret; + /* Set Default State */ pdev->dev_state = USBD_STATE_DEFAULT; /* Free Class Resources */ - pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); + if (pdev->pClass != NULL) + { + pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); + } + + if (pdev->pConfDesc != NULL) + { + pdev->pConfDesc = NULL; + } /* Stop the low level driver */ - USBD_LL_Stop(pdev); + ret = USBD_LL_Stop(pdev); + + if (ret != USBD_OK) + { + return ret; + } /* Initialize low level driver */ - USBD_LL_DeInit(pdev); + ret = USBD_LL_DeInit(pdev); - return USBD_OK; + return ret; } /** @@ -149,24 +172,30 @@ USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev) * @param pclass: Class handle * @retval USBD Status */ -USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass) +USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass) { - USBD_StatusTypeDef status = USBD_OK; - if (pclass != NULL) - { - /* link the class to the USB Device handle */ - pdev->pClass = pclass; - status = USBD_OK; - } - else + uint16_t len = 0U; + + if (pclass == NULL) { #if (USBD_DEBUG_LEVEL > 1U) USBD_ErrLog("Invalid Class handle"); #endif - status = USBD_FAIL; + return USBD_FAIL; } - return status; + /* link the class to the USB Device handle */ + pdev->pClass = pclass; + + /* Get Device Configuration Descriptor */ +#ifdef USE_USB_FS + pdev->pConfDesc = (void *)pdev->pClass->GetFSConfigDescriptor(&len); +#else /* USE_USB_HS */ + pdev->pConfDesc = (void *)pdev->pClass->GetHSConfigDescriptor(&len); +#endif /* USE_USB_FS */ + + + return USBD_OK; } /** @@ -175,12 +204,10 @@ USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeD * @param pdev: Device Handle * @retval USBD Status */ -USBD_StatusTypeDef USBD_Start(USBD_HandleTypeDef *pdev) +USBD_StatusTypeDef USBD_Start(USBD_HandleTypeDef *pdev) { /* Start the low level driver */ - USBD_LL_Start(pdev); - - return USBD_OK; + return USBD_LL_Start(pdev); } /** @@ -189,15 +216,25 @@ USBD_StatusTypeDef USBD_Start(USBD_HandleTypeDef *pdev) * @param pdev: Device Handle * @retval USBD Status */ -USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev) +USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev) { + USBD_StatusTypeDef ret; + /* Free Class Resources */ - pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); + if (pdev->pClass != NULL) + { + pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); + } + + if (pdev->pConfDesc != NULL) + { + pdev->pConfDesc = NULL; + } /* Stop the low level driver */ - USBD_LL_Stop(pdev); + ret = USBD_LL_Stop(pdev); - return USBD_OK; + return ret; } /** @@ -206,7 +243,7 @@ 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) { /* Prevent unused argument compilation warning */ UNUSED(pdev); @@ -222,17 +259,14 @@ USBD_StatusTypeDef USBD_RunTestMode(USBD_HandleTypeDef *pdev) * @retval status */ -USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { USBD_StatusTypeDef ret = USBD_FAIL; if (pdev->pClass != NULL) { - /* Set configuration and Start the Class*/ - if (pdev->pClass->Init(pdev, cfgidx) == 0U) - { - ret = USBD_OK; - } + /* Set configuration and Start the Class */ + ret = (USBD_StatusTypeDef)pdev->pClass->Init(pdev, cfgidx); } return ret; @@ -245,10 +279,13 @@ USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx * @param cfgidx: configuration index * @retval status: USBD_StatusTypeDef */ -USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { - /* Clear configuration and De-initialize the Class process*/ - pdev->pClass->DeInit(pdev, cfgidx); + /* Clear configuration and De-initialize the Class process */ + if (pdev->pClass != NULL) + { + pdev->pClass->DeInit(pdev, cfgidx); + } return USBD_OK; } @@ -262,6 +299,8 @@ USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx */ USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup) { + USBD_StatusTypeDef ret; + USBD_ParseSetupRequest(&pdev->request, psetup); pdev->ep0_state = USBD_EP0_SETUP; @@ -271,23 +310,23 @@ USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup) switch (pdev->request.bmRequest & 0x1FU) { case USB_REQ_RECIPIENT_DEVICE: - USBD_StdDevReq(pdev, &pdev->request); + ret = USBD_StdDevReq(pdev, &pdev->request); break; case USB_REQ_RECIPIENT_INTERFACE: - USBD_StdItfReq(pdev, &pdev->request); + ret = USBD_StdItfReq(pdev, &pdev->request); break; case USB_REQ_RECIPIENT_ENDPOINT: - USBD_StdEPReq(pdev, &pdev->request); + ret = USBD_StdEPReq(pdev, &pdev->request); break; default: - USBD_LL_StallEP(pdev, (pdev->request.bmRequest & 0x80U)); + ret = USBD_LL_StallEP(pdev, (pdev->request.bmRequest & 0x80U)); break; } - return USBD_OK; + return ret; } /** @@ -301,6 +340,7 @@ USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, uint8_t epnum, uint8_t *pdata) { USBD_EndpointTypeDef *pep; + USBD_StatusTypeDef ret; if (epnum == 0U) { @@ -312,8 +352,7 @@ USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, { pep->rem_length -= pep->maxpacket; - USBD_CtlContinueRx(pdev, pdata, - (uint16_t)MIN(pep->rem_length, pep->maxpacket)); + (void)USBD_CtlContinueRx(pdev, pdata, MIN(pep->rem_length, pep->maxpacket)); } else { @@ -322,25 +361,32 @@ USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, { pdev->pClass->EP0_RxReady(pdev); } - USBD_CtlSendStatus(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; - USBD_LL_StallEP(pdev, 0U); + (void)USBD_LL_StallEP(pdev, 0U); } +#endif } } else if ((pdev->pClass->DataOut != NULL) && (pdev->dev_state == USBD_STATE_CONFIGURED)) { - pdev->pClass->DataOut(pdev, epnum); + ret = (USBD_StatusTypeDef)pdev->pClass->DataOut(pdev, epnum); + + if (ret != USBD_OK) + { + return ret; + } } else { @@ -362,6 +408,7 @@ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, uint8_t epnum, uint8_t *pdata) { USBD_EndpointTypeDef *pep; + USBD_StatusTypeDef ret; if (epnum == 0U) { @@ -373,23 +420,23 @@ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, { pep->rem_length -= pep->maxpacket; - USBD_CtlContinueSendData(pdev, pdata, (uint16_t)pep->rem_length); + (void)USBD_CtlContinueSendData(pdev, pdata, pep->rem_length); /* Prepare endpoint for premature end of transfer */ - USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U); + (void)USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U); } else { /* last packet is MPS multiple, so send ZLP packet */ - if ((pep->total_length % pep->maxpacket == 0U) && + if ((pep->maxpacket == pep->rem_length) && (pep->total_length >= pep->maxpacket) && (pep->total_length < pdev->ep0_data_len)) { - USBD_CtlContinueSendData(pdev, NULL, 0U); + (void)USBD_CtlContinueSendData(pdev, NULL, 0U); pdev->ep0_data_len = 0U; /* Prepare endpoint for premature end of transfer */ - USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U); + (void)USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U); } else { @@ -398,30 +445,37 @@ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, { pdev->pClass->EP0_TxSent(pdev); } - USBD_LL_StallEP(pdev, 0x80U); - USBD_CtlReceiveStatus(pdev); + (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)) { - USBD_LL_StallEP(pdev, 0x80U); + (void)USBD_LL_StallEP(pdev, 0x80U); } +#endif } if (pdev->dev_test_mode == 1U) { - USBD_RunTestMode(pdev); + (void)USBD_RunTestMode(pdev); pdev->dev_test_mode = 0U; } } else if ((pdev->pClass->DataIn != NULL) && (pdev->dev_state == USBD_STATE_CONFIGURED)) { - pdev->pClass->DataIn(pdev, epnum); + ret = (USBD_StatusTypeDef)pdev->pClass->DataIn(pdev, epnum); + + if (ret != USBD_OK) + { + return ret; + } } else { @@ -441,29 +495,29 @@ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev) { - /* Open EP0 OUT */ - USBD_LL_OpenEP(pdev, 0x00U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE); - pdev->ep_out[0x00U & 0xFU].is_used = 1U; - - pdev->ep_out[0].maxpacket = USB_MAX_EP0_SIZE; - - /* Open EP0 IN */ - USBD_LL_OpenEP(pdev, 0x80U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE); - pdev->ep_in[0x80U & 0xFU].is_used = 1U; - - pdev->ep_in[0].maxpacket = USB_MAX_EP0_SIZE; - /* 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; - if (pdev->pClassData) + if (pdev->pClassData != NULL) { pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); } + /* Open EP0 OUT */ + (void)USBD_LL_OpenEP(pdev, 0x00U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE); + pdev->ep_out[0x00U & 0xFU].is_used = 1U; + + pdev->ep_out[0].maxpacket = USB_MAX_EP0_SIZE; + + /* Open EP0 IN */ + (void)USBD_LL_OpenEP(pdev, 0x80U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE); + pdev->ep_in[0x80U & 0xFU].is_used = 1U; + + pdev->ep_in[0].maxpacket = USB_MAX_EP0_SIZE; + return USBD_OK; } @@ -490,8 +544,8 @@ USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev) { - pdev->dev_old_state = pdev->dev_state; - pdev->dev_state = USBD_STATE_SUSPENDED; + pdev->dev_old_state = pdev->dev_state; + pdev->dev_state = USBD_STATE_SUSPENDED; return USBD_OK; } @@ -589,7 +643,11 @@ USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev) { /* Free Class Resources */ pdev->dev_state = USBD_STATE_DEFAULT; - pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); + + if (pdev->pClass != NULL) + { + pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); + } return USBD_OK; } diff --git a/Core/Src/usbd_ctlreq.c b/Core/Src/usbd_ctlreq.c index 4561c8d..c31d40e 100644 --- a/Core/Src/usbd_ctlreq.c +++ b/Core/Src/usbd_ctlreq.c @@ -71,27 +71,13 @@ /** @defgroup USBD_REQ_Private_FunctionPrototypes * @{ */ -static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req); - -static void USBD_SetAddress(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req); - -static void USBD_SetConfig(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req); - -static void USBD_GetConfig(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req); - -static void USBD_GetStatus(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req); - -static void USBD_SetFeature(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req); - -static void USBD_ClrFeature(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req); - +static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static void USBD_SetAddress(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static USBD_StatusTypeDef USBD_SetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static void USBD_GetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static void USBD_GetStatus(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static void USBD_SetFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static void USBD_ClrFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); static uint8_t USBD_GetLen(uint8_t *buf); /** @@ -111,58 +97,57 @@ static uint8_t USBD_GetLen(uint8_t *buf); * @param req: usb request * @retval status */ -USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req) +USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { USBD_StatusTypeDef ret = USBD_OK; switch (req->bmRequest & USB_REQ_TYPE_MASK) { - case USB_REQ_TYPE_CLASS: - case USB_REQ_TYPE_VENDOR: - pdev->pClass->Setup(pdev, req); + case USB_REQ_TYPE_CLASS: + case USB_REQ_TYPE_VENDOR: + ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req); + break; + + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_GET_DESCRIPTOR: + USBD_GetDescriptor(pdev, req); break; - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_DESCRIPTOR: - USBD_GetDescriptor(pdev, req); - break; + case USB_REQ_SET_ADDRESS: + USBD_SetAddress(pdev, req); + break; - case USB_REQ_SET_ADDRESS: - USBD_SetAddress(pdev, req); - break; + case USB_REQ_SET_CONFIGURATION: + ret = USBD_SetConfig(pdev, req); + break; - case USB_REQ_SET_CONFIGURATION: - USBD_SetConfig(pdev, req); - break; + case USB_REQ_GET_CONFIGURATION: + USBD_GetConfig(pdev, req); + break; - case USB_REQ_GET_CONFIGURATION: - USBD_GetConfig(pdev, req); - break; + case USB_REQ_GET_STATUS: + USBD_GetStatus(pdev, req); + break; - case USB_REQ_GET_STATUS: - USBD_GetStatus(pdev, req); - break; + case USB_REQ_SET_FEATURE: + USBD_SetFeature(pdev, req); + break; - case USB_REQ_SET_FEATURE: - USBD_SetFeature(pdev, req); - break; - - case USB_REQ_CLEAR_FEATURE: - USBD_ClrFeature(pdev, req); - break; - - default: - USBD_CtlError(pdev, req); - break; - } + case USB_REQ_CLEAR_FEATURE: + USBD_ClrFeature(pdev, req); break; default: USBD_CtlError(pdev, req); break; + } + break; + + default: + USBD_CtlError(pdev, req); + break; } return ret; @@ -175,49 +160,48 @@ USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev, * @param req: usb request * @retval status */ -USBD_StatusTypeDef USBD_StdItfReq(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req) +USBD_StatusTypeDef USBD_StdItfReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { USBD_StatusTypeDef ret = USBD_OK; switch (req->bmRequest & USB_REQ_TYPE_MASK) { - case USB_REQ_TYPE_CLASS: - case USB_REQ_TYPE_VENDOR: - case USB_REQ_TYPE_STANDARD: - switch (pdev->dev_state) + case USB_REQ_TYPE_CLASS: + case USB_REQ_TYPE_VENDOR: + case USB_REQ_TYPE_STANDARD: + switch (pdev->dev_state) + { + case USBD_STATE_DEFAULT: + case USBD_STATE_ADDRESSED: + case USBD_STATE_CONFIGURED: + + if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES) { - case USBD_STATE_DEFAULT: - case USBD_STATE_ADDRESSED: - case USBD_STATE_CONFIGURED: + ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req); - if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES) - { - ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req); - - if ((req->wLength == 0U) && (ret == USBD_OK)) - { - USBD_CtlSendStatus(pdev); - } - } - else - { - USBD_CtlError(pdev, req); - } - break; - - default: - USBD_CtlError(pdev, req); - break; + if ((req->wLength == 0U) && (ret == USBD_OK)) + { + (void)USBD_CtlSendStatus(pdev); + } + } + else + { + USBD_CtlError(pdev, req); } break; default: USBD_CtlError(pdev, req); break; + } + break; + + default: + USBD_CtlError(pdev, req); + break; } - return USBD_OK; + return ret; } /** @@ -227,168 +211,159 @@ USBD_StatusTypeDef USBD_StdItfReq(USBD_HandleTypeDef *pdev, * @param req: usb request * @retval status */ -USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req) +USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { USBD_EndpointTypeDef *pep; - uint8_t ep_addr; + uint8_t ep_addr; USBD_StatusTypeDef ret = USBD_OK; - ep_addr = LOBYTE(req->wIndex); + ep_addr = LOBYTE(req->wIndex); switch (req->bmRequest & USB_REQ_TYPE_MASK) { - case USB_REQ_TYPE_CLASS: - case USB_REQ_TYPE_VENDOR: - pdev->pClass->Setup(pdev, req); + case USB_REQ_TYPE_CLASS: + case USB_REQ_TYPE_VENDOR: + ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req); + break; + + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_SET_FEATURE: + switch (pdev->dev_state) + { + case USBD_STATE_ADDRESSED: + if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) + { + (void)USBD_LL_StallEP(pdev, ep_addr); + (void)USBD_LL_StallEP(pdev, 0x80U); + } + else + { + USBD_CtlError(pdev, req); + } + break; + + case USBD_STATE_CONFIGURED: + if (req->wValue == USB_FEATURE_EP_HALT) + { + if ((ep_addr != 0x00U) && (ep_addr != 0x80U) && (req->wLength == 0x00U)) + { + (void)USBD_LL_StallEP(pdev, ep_addr); + } + } + (void)USBD_CtlSendStatus(pdev); + + break; + + default: + USBD_CtlError(pdev, req); + break; + } break; - case USB_REQ_TYPE_STANDARD: - /* Check if it is a class request */ - if ((req->bmRequest & 0x60U) == 0x20U) - { - ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req); + case USB_REQ_CLEAR_FEATURE: - return ret; + switch (pdev->dev_state) + { + case USBD_STATE_ADDRESSED: + if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) + { + (void)USBD_LL_StallEP(pdev, ep_addr); + (void)USBD_LL_StallEP(pdev, 0x80U); + } + else + { + USBD_CtlError(pdev, req); + } + break; + + case USBD_STATE_CONFIGURED: + if (req->wValue == USB_FEATURE_EP_HALT) + { + if ((ep_addr & 0x7FU) != 0x00U) + { + (void)USBD_LL_ClearStallEP(pdev, ep_addr); + } + (void)USBD_CtlSendStatus(pdev); + (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req); + } + break; + + default: + USBD_CtlError(pdev, req); + break; } + break; - switch (req->bRequest) + case USB_REQ_GET_STATUS: + switch (pdev->dev_state) { - case USB_REQ_SET_FEATURE: - switch (pdev->dev_state) - { - case USBD_STATE_ADDRESSED: - if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) - { - USBD_LL_StallEP(pdev, ep_addr); - USBD_LL_StallEP(pdev, 0x80U); - } - else - { - USBD_CtlError(pdev, req); - } - break; - - case USBD_STATE_CONFIGURED: - if (req->wValue == USB_FEATURE_EP_HALT) - { - if ((ep_addr != 0x00U) && - (ep_addr != 0x80U) && (req->wLength == 0x00U)) - { - USBD_LL_StallEP(pdev, ep_addr); - } - } - USBD_CtlSendStatus(pdev); - - break; - - default: - USBD_CtlError(pdev, req); - break; - } - break; - - case USB_REQ_CLEAR_FEATURE: - - switch (pdev->dev_state) - { - case USBD_STATE_ADDRESSED: - if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) - { - USBD_LL_StallEP(pdev, ep_addr); - USBD_LL_StallEP(pdev, 0x80U); - } - else - { - USBD_CtlError(pdev, req); - } - break; - - case USBD_STATE_CONFIGURED: - if (req->wValue == USB_FEATURE_EP_HALT) - { - if ((ep_addr & 0x7FU) != 0x00U) - { - USBD_LL_ClearStallEP(pdev, ep_addr); - } - USBD_CtlSendStatus(pdev); - } - break; - - default: - USBD_CtlError(pdev, req); - break; - } - break; - - case USB_REQ_GET_STATUS: - switch (pdev->dev_state) - { - case USBD_STATE_ADDRESSED: - if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) - { - USBD_CtlError(pdev, req); - break; - } - pep = ((ep_addr & 0x80U) == 0x80U) ? &pdev->ep_in[ep_addr & 0x7FU] : \ - &pdev->ep_out[ep_addr & 0x7FU]; - - pep->status = 0x0000U; - - USBD_CtlSendData(pdev, (uint8_t *)(void *)&pep->status, 2U); - break; - - case USBD_STATE_CONFIGURED: - if ((ep_addr & 0x80U) == 0x80U) - { - if (pdev->ep_in[ep_addr & 0xFU].is_used == 0U) - { - USBD_CtlError(pdev, req); - break; - } - } - else - { - if (pdev->ep_out[ep_addr & 0xFU].is_used == 0U) - { - USBD_CtlError(pdev, req); - break; - } - } - - pep = ((ep_addr & 0x80U) == 0x80U) ? &pdev->ep_in[ep_addr & 0x7FU] : \ - &pdev->ep_out[ep_addr & 0x7FU]; - - if ((ep_addr == 0x00U) || (ep_addr == 0x80U)) - { - pep->status = 0x0000U; - } - else if (USBD_LL_IsStallEP(pdev, ep_addr)) - { - pep->status = 0x0001U; - } - else - { - pep->status = 0x0000U; - } - - USBD_CtlSendData(pdev, (uint8_t *)(void *)&pep->status, 2U); - break; - - default: - USBD_CtlError(pdev, req); - break; - } - break; - - default: + case USBD_STATE_ADDRESSED: + if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) + { USBD_CtlError(pdev, req); break; + } + pep = ((ep_addr & 0x80U) == 0x80U) ? &pdev->ep_in[ep_addr & 0x7FU] : \ + &pdev->ep_out[ep_addr & 0x7FU]; + + pep->status = 0x0000U; + + (void)USBD_CtlSendData(pdev, (uint8_t *)&pep->status, 2U); + break; + + case USBD_STATE_CONFIGURED: + if ((ep_addr & 0x80U) == 0x80U) + { + if (pdev->ep_in[ep_addr & 0xFU].is_used == 0U) + { + USBD_CtlError(pdev, req); + break; + } + } + else + { + if (pdev->ep_out[ep_addr & 0xFU].is_used == 0U) + { + USBD_CtlError(pdev, req); + break; + } + } + + pep = ((ep_addr & 0x80U) == 0x80U) ? &pdev->ep_in[ep_addr & 0x7FU] : \ + &pdev->ep_out[ep_addr & 0x7FU]; + + if ((ep_addr == 0x00U) || (ep_addr == 0x80U)) + { + pep->status = 0x0000U; + } + else if (USBD_LL_IsStallEP(pdev, ep_addr) != 0U) + { + pep->status = 0x0001U; + } + else + { + pep->status = 0x0000U; + } + + (void)USBD_CtlSendData(pdev, (uint8_t *)&pep->status, 2U); + break; + + default: + USBD_CtlError(pdev, req); + break; } break; default: USBD_CtlError(pdev, req); break; + } + break; + + default: + USBD_CtlError(pdev, req); + break; } return ret; @@ -402,8 +377,7 @@ USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, * @param req: usb request * @retval status */ -static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req) +static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { uint16_t len = 0U; uint8_t *pbuf = NULL; @@ -411,134 +385,43 @@ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, switch (req->wValue >> 8) { -#if (USBD_LPM_ENABLED == 1U) - case USB_DESC_TYPE_BOS: - if (pdev->pDesc->GetBOSDescriptor != NULL) - { - pbuf = pdev->pDesc->GetBOSDescriptor(pdev->dev_speed, &len); - } - else - { - USBD_CtlError(pdev, req); - err++; - } - break; +#if ((USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1U)) + case USB_DESC_TYPE_BOS: + if (pdev->pDesc->GetBOSDescriptor != NULL) + { + pbuf = pdev->pDesc->GetBOSDescriptor(pdev->dev_speed, &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; #endif - case USB_DESC_TYPE_DEVICE: - pbuf = pdev->pDesc->GetDeviceDescriptor(pdev->dev_speed, &len); - break; + case USB_DESC_TYPE_DEVICE: + pbuf = pdev->pDesc->GetDeviceDescriptor(pdev->dev_speed, &len); + break; - case USB_DESC_TYPE_CONFIGURATION: - if (pdev->dev_speed == USBD_SPEED_HIGH) + case USB_DESC_TYPE_CONFIGURATION: + if (pdev->dev_speed == USBD_SPEED_HIGH) + { + pbuf = pdev->pClass->GetHSConfigDescriptor(&len); + pbuf[1] = USB_DESC_TYPE_CONFIGURATION; + } + else + { + pbuf = pdev->pClass->GetFSConfigDescriptor(&len); + pbuf[1] = USB_DESC_TYPE_CONFIGURATION; + } + break; + + case USB_DESC_TYPE_STRING: + switch ((uint8_t)(req->wValue)) + { + case USBD_IDX_LANGID_STR: + if (pdev->pDesc->GetLangIDStrDescriptor != NULL) { - pbuf = pdev->pClass->GetHSConfigDescriptor(&len); - pbuf[1] = USB_DESC_TYPE_CONFIGURATION; - } - else - { - pbuf = pdev->pClass->GetFSConfigDescriptor(&len); - pbuf[1] = USB_DESC_TYPE_CONFIGURATION; - } - break; - - case USB_DESC_TYPE_STRING: - switch ((uint8_t)(req->wValue)) - { - case USBD_IDX_LANGID_STR: - if (pdev->pDesc->GetLangIDStrDescriptor != NULL) - { - pbuf = pdev->pDesc->GetLangIDStrDescriptor(pdev->dev_speed, &len); - } - else - { - USBD_CtlError(pdev, req); - err++; - } - break; - - case USBD_IDX_MFC_STR: - if (pdev->pDesc->GetManufacturerStrDescriptor != NULL) - { - pbuf = pdev->pDesc->GetManufacturerStrDescriptor(pdev->dev_speed, &len); - } - else - { - USBD_CtlError(pdev, req); - err++; - } - break; - - case USBD_IDX_PRODUCT_STR: - if (pdev->pDesc->GetProductStrDescriptor != NULL) - { - pbuf = pdev->pDesc->GetProductStrDescriptor(pdev->dev_speed, &len); - } - else - { - USBD_CtlError(pdev, req); - err++; - } - break; - - case USBD_IDX_SERIAL_STR: - if (pdev->pDesc->GetSerialStrDescriptor != NULL) - { - pbuf = pdev->pDesc->GetSerialStrDescriptor(pdev->dev_speed, &len); - } - else - { - USBD_CtlError(pdev, req); - err++; - } - break; - - case USBD_IDX_CONFIG_STR: - if (pdev->pDesc->GetConfigurationStrDescriptor != NULL) - { - pbuf = pdev->pDesc->GetConfigurationStrDescriptor(pdev->dev_speed, &len); - } - else - { - USBD_CtlError(pdev, req); - err++; - } - break; - - case USBD_IDX_INTERFACE_STR: - if (pdev->pDesc->GetInterfaceStrDescriptor != NULL) - { - pbuf = pdev->pDesc->GetInterfaceStrDescriptor(pdev->dev_speed, &len); - } - else - { - USBD_CtlError(pdev, req); - err++; - } - break; - - default: -#if (USBD_SUPPORT_USER_STRING_DESC == 1U) - if (pdev->pClass->GetUsrStrDescriptor != NULL) - { - pbuf = pdev->pClass->GetUsrStrDescriptor(pdev, (req->wValue), &len); - } - else - { - USBD_CtlError(pdev, req); - err++; - } - break; -#else - USBD_CtlError(pdev, req); - err++; -#endif - } - break; - - case USB_DESC_TYPE_DEVICE_QUALIFIER: - if (pdev->dev_speed == USBD_SPEED_HIGH) - { - pbuf = pdev->pClass->GetDeviceQualifierDescriptor(&len); + pbuf = pdev->pDesc->GetLangIDStrDescriptor(pdev->dev_speed, &len); } else { @@ -547,11 +430,58 @@ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, } break; - case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION: - if (pdev->dev_speed == USBD_SPEED_HIGH) + case USBD_IDX_MFC_STR: + if (pdev->pDesc->GetManufacturerStrDescriptor != NULL) { - pbuf = pdev->pClass->GetOtherSpeedConfigDescriptor(&len); - pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION; + pbuf = pdev->pDesc->GetManufacturerStrDescriptor(pdev->dev_speed, &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USBD_IDX_PRODUCT_STR: + if (pdev->pDesc->GetProductStrDescriptor != NULL) + { + pbuf = pdev->pDesc->GetProductStrDescriptor(pdev->dev_speed, &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USBD_IDX_SERIAL_STR: + if (pdev->pDesc->GetSerialStrDescriptor != NULL) + { + pbuf = pdev->pDesc->GetSerialStrDescriptor(pdev->dev_speed, &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USBD_IDX_CONFIG_STR: + if (pdev->pDesc->GetConfigurationStrDescriptor != NULL) + { + pbuf = pdev->pDesc->GetConfigurationStrDescriptor(pdev->dev_speed, &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USBD_IDX_INTERFACE_STR: + if (pdev->pDesc->GetInterfaceStrDescriptor != NULL) + { + pbuf = pdev->pDesc->GetInterfaceStrDescriptor(pdev->dev_speed, &len); } else { @@ -561,9 +491,63 @@ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, break; default: +#if (USBD_SUPPORT_USER_STRING_DESC == 1U) + if (pdev->pClass->GetUsrStrDescriptor != NULL) + { + pbuf = pdev->pClass->GetUsrStrDescriptor(pdev, (req->wValue), &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } +#elif (USBD_CLASS_USER_STRING_DESC == 1U) + if (pdev->pDesc->GetUserStrDescriptor != NULL) + { + pbuf = pdev->pDesc->GetUserStrDescriptor(pdev->dev_speed, (req->wValue), &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } +#else USBD_CtlError(pdev, req); err++; +#endif break; + } + break; + + case USB_DESC_TYPE_DEVICE_QUALIFIER: + if (pdev->dev_speed == USBD_SPEED_HIGH) + { + pbuf = pdev->pClass->GetDeviceQualifierDescriptor(&len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION: + if (pdev->dev_speed == USBD_SPEED_HIGH) + { + pbuf = pdev->pClass->GetOtherSpeedConfigDescriptor(&len); + pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION; + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + default: + USBD_CtlError(pdev, req); + err++; + break; } if (err != 0U) @@ -572,13 +556,19 @@ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, } else { - if ((len != 0U) && (req->wLength != 0U)) + if (req->wLength != 0U) { - len = MIN(len, req->wLength); - (void)USBD_CtlSendData(pdev, pbuf, len); + if (len != 0U) + { + len = MIN(len, req->wLength); + (void)USBD_CtlSendData(pdev, pbuf, len); + } + else + { + USBD_CtlError(pdev, req); + } } - - if (req->wLength == 0U) + else { (void)USBD_CtlSendStatus(pdev); } @@ -592,8 +582,7 @@ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, * @param req: usb request * @retval status */ -static void USBD_SetAddress(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req) +static void USBD_SetAddress(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { uint8_t dev_addr; @@ -608,8 +597,8 @@ static void USBD_SetAddress(USBD_HandleTypeDef *pdev, else { pdev->dev_address = dev_addr; - USBD_LL_SetUSBAddress(pdev, dev_addr); - USBD_CtlSendStatus(pdev); + (void)USBD_LL_SetUSBAddress(pdev, dev_addr); + (void)USBD_CtlSendStatus(pdev); if (dev_addr != 0U) { @@ -634,8 +623,9 @@ static void USBD_SetAddress(USBD_HandleTypeDef *pdev, * @param req: usb request * @retval status */ -static void USBD_SetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +static USBD_StatusTypeDef USBD_SetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { + USBD_StatusTypeDef ret = USBD_OK; static uint8_t cfgidx; cfgidx = (uint8_t)(req->wValue); @@ -643,63 +633,77 @@ static void USBD_SetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) if (cfgidx > USBD_MAX_NUM_CONFIGURATION) { USBD_CtlError(pdev, req); + return USBD_FAIL; } - else + + switch (pdev->dev_state) { - switch (pdev->dev_state) + case USBD_STATE_ADDRESSED: + if (cfgidx != 0U) { - case USBD_STATE_ADDRESSED: - if (cfgidx) - { - pdev->dev_config = cfgidx; - pdev->dev_state = USBD_STATE_CONFIGURED; - if (USBD_SetClassConfig(pdev, cfgidx) == USBD_FAIL) - { - USBD_CtlError(pdev, req); - return; - } - USBD_CtlSendStatus(pdev); - } - else - { - USBD_CtlSendStatus(pdev); - } - break; + pdev->dev_config = cfgidx; - case USBD_STATE_CONFIGURED: - if (cfgidx == 0U) - { - pdev->dev_state = USBD_STATE_ADDRESSED; - pdev->dev_config = cfgidx; - USBD_ClrClassConfig(pdev, cfgidx); - USBD_CtlSendStatus(pdev); - } - else if (cfgidx != pdev->dev_config) - { - /* Clear old configuration */ - USBD_ClrClassConfig(pdev, (uint8_t)pdev->dev_config); + ret = USBD_SetClassConfig(pdev, cfgidx); - /* set new configuration */ - pdev->dev_config = cfgidx; - if (USBD_SetClassConfig(pdev, cfgidx) == USBD_FAIL) - { - USBD_CtlError(pdev, req); - return; - } - USBD_CtlSendStatus(pdev); - } - else - { - USBD_CtlSendStatus(pdev); - } - break; - - default: + if (ret != USBD_OK) + { USBD_CtlError(pdev, req); - USBD_ClrClassConfig(pdev, cfgidx); - break; + } + else + { + (void)USBD_CtlSendStatus(pdev); + pdev->dev_state = USBD_STATE_CONFIGURED; + } } + else + { + (void)USBD_CtlSendStatus(pdev); + } + break; + + case USBD_STATE_CONFIGURED: + if (cfgidx == 0U) + { + pdev->dev_state = USBD_STATE_ADDRESSED; + pdev->dev_config = cfgidx; + (void)USBD_ClrClassConfig(pdev, cfgidx); + (void)USBD_CtlSendStatus(pdev); + } + else if (cfgidx != pdev->dev_config) + { + /* Clear old configuration */ + (void)USBD_ClrClassConfig(pdev, (uint8_t)pdev->dev_config); + + /* set new configuration */ + pdev->dev_config = cfgidx; + + ret = USBD_SetClassConfig(pdev, cfgidx); + + if (ret != USBD_OK) + { + USBD_CtlError(pdev, req); + (void)USBD_ClrClassConfig(pdev, (uint8_t)pdev->dev_config); + pdev->dev_state = USBD_STATE_ADDRESSED; + } + else + { + (void)USBD_CtlSendStatus(pdev); + } + } + else + { + (void)USBD_CtlSendStatus(pdev); + } + break; + + default: + USBD_CtlError(pdev, req); + (void)USBD_ClrClassConfig(pdev, cfgidx); + ret = USBD_FAIL; + break; } + + return ret; } /** @@ -719,19 +723,19 @@ static void USBD_GetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { switch (pdev->dev_state) { - case USBD_STATE_DEFAULT: - case USBD_STATE_ADDRESSED: - pdev->dev_default_config = 0U; - USBD_CtlSendData(pdev, (uint8_t *)(void *)&pdev->dev_default_config, 1U); - break; + case USBD_STATE_DEFAULT: + case USBD_STATE_ADDRESSED: + pdev->dev_default_config = 0U; + (void)USBD_CtlSendData(pdev, (uint8_t *)&pdev->dev_default_config, 1U); + break; - case USBD_STATE_CONFIGURED: - USBD_CtlSendData(pdev, (uint8_t *)(void *)&pdev->dev_config, 1U); - break; + case USBD_STATE_CONFIGURED: + (void)USBD_CtlSendData(pdev, (uint8_t *)&pdev->dev_config, 1U); + break; - default: - USBD_CtlError(pdev, req); - break; + default: + USBD_CtlError(pdev, req); + break; } } } @@ -747,32 +751,32 @@ static void USBD_GetStatus(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { switch (pdev->dev_state) { - case USBD_STATE_DEFAULT: - case USBD_STATE_ADDRESSED: - case USBD_STATE_CONFIGURED: - if (req->wLength != 0x2U) - { - USBD_CtlError(pdev, req); - break; - } - -#if (USBD_SELF_POWERED == 1U) - pdev->dev_config_status = USB_CONFIG_SELF_POWERED; -#else - pdev->dev_config_status = 0U; -#endif - - if (pdev->dev_remote_wakeup) - { - pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP; - } - - USBD_CtlSendData(pdev, (uint8_t *)(void *)&pdev->dev_config_status, 2U); - break; - - default: + case USBD_STATE_DEFAULT: + case USBD_STATE_ADDRESSED: + case USBD_STATE_CONFIGURED: + if (req->wLength != 0x2U) + { USBD_CtlError(pdev, req); break; + } + +#if (USBD_SELF_POWERED == 1U) + pdev->dev_config_status = USB_CONFIG_SELF_POWERED; +#else + pdev->dev_config_status = 0U; +#endif + + if (pdev->dev_remote_wakeup != 0U) + { + pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP; + } + + (void)USBD_CtlSendData(pdev, (uint8_t *)&pdev->dev_config_status, 2U); + break; + + default: + USBD_CtlError(pdev, req); + break; } } @@ -784,13 +788,12 @@ static void USBD_GetStatus(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) * @param req: usb request * @retval status */ -static void USBD_SetFeature(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req) +static void USBD_SetFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) { pdev->dev_remote_wakeup = 1U; - USBD_CtlSendStatus(pdev); + (void)USBD_CtlSendStatus(pdev); } } @@ -802,8 +805,7 @@ static void USBD_SetFeature(USBD_HandleTypeDef *pdev, * @param req: usb request * @retval status */ -static void USBD_ClrFeature(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req) +static void USBD_ClrFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { switch (pdev->dev_state) { @@ -813,7 +815,7 @@ static void USBD_ClrFeature(USBD_HandleTypeDef *pdev, if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) { pdev->dev_remote_wakeup = 0U; - USBD_CtlSendStatus(pdev); + (void)USBD_CtlSendStatus(pdev); } break; @@ -833,12 +835,23 @@ static void USBD_ClrFeature(USBD_HandleTypeDef *pdev, void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata) { - req->bmRequest = *(uint8_t *)(pdata); - req->bRequest = *(uint8_t *)(pdata + 1U); - req->wValue = SWAPBYTE(pdata + 2U); - req->wIndex = SWAPBYTE(pdata + 4U); - req->wLength = SWAPBYTE(pdata + 6U); + uint8_t *pbuff = pdata; + req->bmRequest = *(uint8_t *)(pbuff); + + pbuff++; + req->bRequest = *(uint8_t *)(pbuff); + + pbuff++; + req->wValue = SWAPBYTE(pbuff); + + pbuff++; + pbuff++; + req->wIndex = SWAPBYTE(pbuff); + + pbuff++; + pbuff++; + req->wLength = SWAPBYTE(pbuff); } /** @@ -849,11 +862,12 @@ void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata) * @retval None */ -void USBD_CtlError(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req) +void USBD_CtlError(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { - USBD_LL_StallEP(pdev, 0x80U); - USBD_LL_StallEP(pdev, 0U); + UNUSED(req); + + (void)USBD_LL_StallEP(pdev, 0x80U); + (void)USBD_LL_StallEP(pdev, 0U); } @@ -868,18 +882,29 @@ void USBD_CtlError(USBD_HandleTypeDef *pdev, void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len) { uint8_t idx = 0U; + uint8_t *pdesc; - if (desc != NULL) + if (desc == NULL) { - *len = (uint16_t)USBD_GetLen(desc) * 2U + 2U; - unicode[idx++] = *(uint8_t *)(void *)len; - unicode[idx++] = USB_DESC_TYPE_STRING; + return; + } - while (*desc != '\0') - { - unicode[idx++] = *desc++; - unicode[idx++] = 0U; - } + pdesc = desc; + *len = ((uint16_t)USBD_GetLen(pdesc) * 2U) + 2U; + + unicode[idx] = *(uint8_t *)len; + idx++; + unicode[idx] = USB_DESC_TYPE_STRING; + idx++; + + while (*pdesc != (uint8_t)'\0') + { + unicode[idx] = *pdesc; + pdesc++; + idx++; + + unicode[idx] = 0U; + idx++; } } @@ -892,11 +917,12 @@ void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len) static uint8_t USBD_GetLen(uint8_t *buf) { uint8_t len = 0U; + uint8_t *pbuff = buf; - while (*buf != '\0') + while (*pbuff != (uint8_t)'\0') { len++; - buf++; + pbuff++; } return len; diff --git a/Core/Src/usbd_desc_template.c b/Core/Src/usbd_desc_template.c index ed0dfe2..403936d 100644 --- a/Core/Src/usbd_desc_template.c +++ b/Core/Src/usbd_desc_template.c @@ -46,9 +46,14 @@ uint8_t *USBD_Class_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *leng uint8_t *USBD_Class_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); uint8_t *USBD_Class_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); uint8_t *USBD_Class_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); -#ifdef USBD_SUPPORT_USER_STRING_DESC -uint8_t *USBD_Class_USRStringDesc(USBD_SpeedTypeDef speed, uint8_t idx, uint16_t *length); -#endif /* USBD_SUPPORT_USER_STRING_DESC */ + +#if (USBD_CLASS_USER_STRING_DESC == 1) +uint8_t *USBD_Class_UserStrDescriptor(USBD_SpeedTypeDef speed, uint8_t idx, uint16_t *length); +#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 /* Private variables ---------------------------------------------------------*/ USBD_DescriptorsTypeDef Class_Desc = @@ -60,17 +65,29 @@ USBD_DescriptorsTypeDef Class_Desc = USBD_Class_SerialStrDescriptor, USBD_Class_ConfigStrDescriptor, USBD_Class_InterfaceStrDescriptor, +#if (USBD_CLASS_USER_STRING_DESC == 1) + USBD_CLASS_UserStrDescriptor, +#endif + +#if ((USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1)) + USBD_USR_BOSDescriptor, +#endif }; /* USB Standard Device Descriptor */ #if defined ( __ICCARM__ ) /*!< IAR Compiler */ #pragma data_alignment=4 #endif -__ALIGN_BEGIN uint8_t USBD_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = +__ALIGN_BEGIN uint8_t USBD_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = { 0x12, /* bLength */ USB_DESC_TYPE_DEVICE, /* bDescriptorType */ +#if ((USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1)) + 0x01, /*bcdUSB */ /* changed to USB version 2.01 + in order to support BOS Desc */ +#else 0x00, /* bcdUSB */ +#endif 0x02, 0x00, /* bDeviceClass */ 0x00, /* bDeviceSubClass */ @@ -88,11 +105,123 @@ __ALIGN_BEGIN uint8_t USBD_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = USBD_MAX_NUM_CONFIGURATION /* bNumConfigurations */ }; /* USB_DeviceDescriptor */ + +/* USB Device LPM BOS descriptor */ +#if (USBD_LPM_ENABLED == 1) +#if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 +#endif +__ALIGN_BEGIN uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = +{ + 0x5, + USB_DESC_TYPE_BOS, + 0xC, + 0x0, + 0x1, /* 1 device capability */ + /* device capability */ + 0x7, + USB_DEVICE_CAPABITY_TYPE, + 0x2, + 0x6, /*LPM capability bit set */ + 0x0, + 0x0, + 0x0 +}; +#endif + +/* USB Device Billboard BOS descriptor Template */ +#if (USBD_CLASS_BOS_ENABLED == 1) +#if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 +#endif +__ALIGN_BEGIN uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = +{ +0x05, /* bLength */ +USB_DESC_TYPE_BOS, /* Device Descriptor Type */ +USB_SIZ_BOS_DESC, /* Total length of BOS descriptor and all of its sub descs */ +0x00, +0x04, /* The number of separate device capability descriptors in the BOS */ + + /* ----------- Device Capability Descriptor: CONTAINER_ID ---------- */ +0x14, /* bLength */ +0x10, /* bDescriptorType: DEVICE CAPABILITY Type */ +0x04, /* bDevCapabilityType: CONTAINER_ID */ +0x00, /* bReserved */ +0xa7, 0xd6, 0x1b, 0xfa, /* ContainerID: This is a Unique 128-bit number GUID */ +0x91, 0xa6, 0xa8, 0x4e, +0xa8, 0x21, 0x9f, 0x2b, +0xaf, 0xf7, 0x94, 0xd4, + + /* ----------- Device Capability Descriptor: BillBoard ---------- */ +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 */ + +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. */ + +0x00, 0x00, /* VCONN Power needed by the adapter for full functionality 000b = 1W */ + +0x01,0x00,0x00,0x00, /* bmConfigured. 01b: Alternate Mode configuration not attempted or exited */ +0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00, +0x21, 0x01, /* bcdVersion = 0x0121 */ +0x00, /* bAdditionalFailureInfo */ +0x00, /* bReserved */ +LOBYTE(USBD_VID), +HIBYTE(USBD_VID), /* wSVID[0]: Standard or Vendor ID. This shall match one of the SVIDs + returned in response to a USB PD Discover SVIDs command */ + +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 */ + +USBD_BB_ALTMODE0_STRING_INDEX, /* iAlternateModeString[0]: Index of string descriptor describing protocol. + It is optional to support this string. */ +LOBYTE(USBD_VID), +HIBYTE(USBD_VID), /* wSVID[1]: Standard or Vendor ID. This shall match one of the SVIDs + returned in response to a USB PD Discover SVIDs command */ + +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 */ + +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 ---------- */ +0x08, /* bLength */ +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 */ + +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 */ +}; +#endif + + /* USB Standard Device Descriptor */ #if defined ( __ICCARM__ ) /*!< IAR Compiler */ #pragma data_alignment=4 #endif -__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, @@ -100,7 +229,10 @@ __ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = HIBYTE(USBD_LANGID_STRING), }; -uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] = +#if defined ( __ICCARM__ ) /*!< IAR Compiler */ +#pragma data_alignment=4 +#endif +__ALIGN_BEGIN uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] = { USB_SIZ_STRING_SERIAL, USB_DESC_TYPE_STRING, @@ -123,6 +255,8 @@ static void Get_SerialNum(void); */ uint8_t *USBD_Class_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) { + UNUSED(speed); + *length = sizeof(USBD_DeviceDesc); return (uint8_t *)USBD_DeviceDesc; } @@ -135,6 +269,8 @@ uint8_t *USBD_Class_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) */ uint8_t *USBD_Class_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) { + UNUSED(speed); + *length = sizeof(USBD_LangIDDesc); return (uint8_t *)USBD_LangIDDesc; } @@ -166,6 +302,8 @@ uint8_t *USBD_Class_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *leng */ uint8_t *USBD_Class_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) { + UNUSED(speed); + USBD_GetString((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length); return USBD_StrDesc; } @@ -178,6 +316,8 @@ uint8_t *USBD_Class_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t */ uint8_t *USBD_Class_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*/ @@ -246,6 +386,40 @@ static void Get_SerialNum(void) } } + +#if ((USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1)) +/** + * @brief USBD_USR_BOSDescriptor + * return the BOS descriptor + * @param speed : current device speed + * @param length : pointer to data length variable + * @retval pointer to descriptor buffer + */ +uint8_t *USBD_USR_BOSDescriptor(USBD_SpeedTypeDef speed , uint16_t *length) +{ + *length = sizeof(USBD_BOSDesc); + return (uint8_t*)USBD_BOSDesc; +} +#endif + + +#if (USBD_CLASS_USER_STRING_DESC == 1) +/** + * @brief Returns the Class User string descriptor. + * @param speed: Current device speed + * @param idx: index of string descriptor + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +uint8_t *USBD_Class_UserStrDescriptor(USBD_SpeedTypeDef speed, uint8_t idx, uint16_t *length) +{ + static uint8_t USBD_StrDesc[255]; + + return USBD_StrDesc; +} +#endif + + /** * @brief Convert Hex 32Bits value into char * @param value: value to convert diff --git a/Core/Src/usbd_ioreq.c b/Core/Src/usbd_ioreq.c index 7e969de..8ac5491 100644 --- a/Core/Src/usbd_ioreq.c +++ b/Core/Src/usbd_ioreq.c @@ -85,15 +85,15 @@ * @retval status */ USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev, - uint8_t *pbuf, uint16_t len) + uint8_t *pbuf, uint32_t len) { /* Set EP0 State */ pdev->ep0_state = USBD_EP0_DATA_IN; pdev->ep_in[0].total_length = len; - pdev->ep_in[0].rem_length = len; + pdev->ep_in[0].rem_length = len; /* Start the transfer */ - USBD_LL_Transmit(pdev, 0x00U, pbuf, len); + (void)USBD_LL_Transmit(pdev, 0x00U, pbuf, len); return USBD_OK; } @@ -107,10 +107,10 @@ USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev, * @retval status */ USBD_StatusTypeDef USBD_CtlContinueSendData(USBD_HandleTypeDef *pdev, - uint8_t *pbuf, uint16_t len) + uint8_t *pbuf, uint32_t len) { /* Start the next transfer */ - USBD_LL_Transmit(pdev, 0x00U, pbuf, len); + (void)USBD_LL_Transmit(pdev, 0x00U, pbuf, len); return USBD_OK; } @@ -124,15 +124,15 @@ USBD_StatusTypeDef USBD_CtlContinueSendData(USBD_HandleTypeDef *pdev, * @retval status */ USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev, - uint8_t *pbuf, uint16_t len) + uint8_t *pbuf, uint32_t len) { /* Set EP0 State */ pdev->ep0_state = USBD_EP0_DATA_OUT; pdev->ep_out[0].total_length = len; - pdev->ep_out[0].rem_length = len; + pdev->ep_out[0].rem_length = len; /* Start the transfer */ - USBD_LL_PrepareReceive(pdev, 0U, pbuf, len); + (void)USBD_LL_PrepareReceive(pdev, 0U, pbuf, len); return USBD_OK; } @@ -146,9 +146,9 @@ USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev, * @retval status */ USBD_StatusTypeDef USBD_CtlContinueRx(USBD_HandleTypeDef *pdev, - uint8_t *pbuf, uint16_t len) + uint8_t *pbuf, uint32_t len) { - USBD_LL_PrepareReceive(pdev, 0U, pbuf, len); + (void)USBD_LL_PrepareReceive(pdev, 0U, pbuf, len); return USBD_OK; } @@ -165,7 +165,7 @@ USBD_StatusTypeDef USBD_CtlSendStatus(USBD_HandleTypeDef *pdev) pdev->ep0_state = USBD_EP0_STATUS_IN; /* Start the transfer */ - USBD_LL_Transmit(pdev, 0x00U, NULL, 0U); + (void)USBD_LL_Transmit(pdev, 0x00U, NULL, 0U); return USBD_OK; } @@ -182,7 +182,7 @@ USBD_StatusTypeDef USBD_CtlReceiveStatus(USBD_HandleTypeDef *pdev) pdev->ep0_state = USBD_EP0_STATUS_OUT; /* Start the transfer */ - USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U); + (void)USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U); return USBD_OK; } diff --git a/README.md b/README.md index 8584359..e279717 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ USB Device | HAL | Tag v2.5.1 | Tag v1.10.2 ([stm32l0xx_hal_driver](https://github.com/STMicroelectronics/stm32l0xx_hal_driver)) Tag v2.5.2 | Tag v1.4.0 ([stm32l1xx_hal_driver](https://github.com/STMicroelectronics/stm32l1xx_hal_driver)) Tag v2.5.3 | Tag v1.7.3 ([stm32f0xx_hal_driver](https://github.com/STMicroelectronics/stm32f0xx_hal_driver))
Tag v1.1.4 ([stm32f1xx_hal_driver](https://github.com/STMicroelectronics/stm32f1xx_hal_driver))
Tag v1.2.4 ([stm32f2xx_hal_driver](https://github.com/STMicroelectronics/stm32f2xx_hal_driver))
Tag v1.5.3 ([stm32f3xx_hal_driver](https://github.com/STMicroelectronics/stm32f3xx_hal_driver)) +Tag v2.6.0 | Tag v1.7.8 ([stm32f4xx_hal_driver](https://github.com/STMicroelectronics/stm32f4xx_hal_driver))
Tag v1.2.8 ([stm32f7xx_hal_driver](https://github.com/STMicroelectronics/stm32f7xx_hal_driver))
Tag v1.9.0 ([stm32h7xx_hal_driver](https://github.com/STMicroelectronics/stm32h7xx_hal_driver))
Tag v1.12.0 ([stm32l4xx_hal_driver](https://github.com/STMicroelectronics/stm32l4xx_hal_driver))
Tag v1.6.0 ([stm32wbxx_hal_driver](https://github.com/STMicroelectronics/stm32wbxx_hal_driver)) ## Troubleshooting diff --git a/Release_Notes.html b/Release_Notes.html index a7462bc..c1432a6 100644 --- a/Release_Notes.html +++ b/Release_Notes.html @@ -923,7 +923,30 @@ ul

Update History

-

V2.5.3 / 30-April-2019

Main +

V2.6.0 / 27-December-2019

Main +Changes

+ + + + + + + + + + + + + + + + + + + + + +

V2.5.3 / 30-April-2019

Main Changes