diff --git a/radio/src/targets/common/arm/stm32/usbd_conf.c b/radio/src/targets/common/arm/stm32/usbd_conf.c index 5f2908aaf..79967134d 100644 --- a/radio/src/targets/common/arm/stm32/usbd_conf.c +++ b/radio/src/targets/common/arm/stm32/usbd_conf.c @@ -48,7 +48,6 @@ PCD_HandleTypeDef hpcd_USB_OTG; void Error_Handler(void){} /* External functions --------------------------------------------------------*/ -void SystemClock_Config(void); /* USER CODE BEGIN 0 */ diff --git a/radio/src/thirdparty/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h b/radio/src/thirdparty/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h index d99da443e..3dc4369b1 100644 --- a/radio/src/thirdparty/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h +++ b/radio/src/thirdparty/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h @@ -155,12 +155,17 @@ extern USBD_ClassTypeDef USBD_CDC; uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_CDC_ItfTypeDef *fops); +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, + uint32_t length, uint8_t ClassId); +uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t ClassId); +#else uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uint32_t length); - +uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev); +#endif /* USE_USBD_COMPOSITE */ uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff); uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev); -uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev); /** * @} */ diff --git a/radio/src/thirdparty/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c b/radio/src/thirdparty/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c index f82308318..6c5f7e72d 100644 --- a/radio/src/thirdparty/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c +++ b/radio/src/thirdparty/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c @@ -110,7 +110,6 @@ static uint8_t USBD_CDC_SOF(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); #endif /* USE_USBD_COMPOSITE */ @@ -306,9 +305,9 @@ static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) #ifdef USE_USBD_COMPOSITE /* Get the Endpoints addresses allocated for this class instance */ - CDCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); - CDCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); - CDCCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR); + CDCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); + CDCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); + CDCCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId); #endif /* USE_USBD_COMPOSITE */ if (pdev->dev_speed == USBD_SPEED_HIGH) @@ -394,9 +393,9 @@ static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) #ifdef USE_USBD_COMPOSITE /* Get the Endpoints addresses allocated for this CDC class instance */ - CDCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); - CDCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); - CDCCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR); + CDCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); + CDCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); + CDCCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId); #endif /* USE_USBD_COMPOSITE */ /* Close EP IN */ @@ -774,13 +773,21 @@ uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, * @brief USBD_CDC_SetTxBuffer * @param pdev: device instance * @param pbuff: Tx Buffer - * @param length: Tx Buffer length + * @param length: length of data to be sent + * @param ClassId: The Class ID * @retval status */ +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, + uint8_t *pbuff, uint32_t length, uint8_t ClassId) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[ClassId]; +#else uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uint32_t length) { USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; +#endif /* USE_USBD_COMPOSITE */ if (hcdc == NULL) { @@ -813,22 +820,32 @@ uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff) return (uint8_t)USBD_OK; } + /** * @brief USBD_CDC_TransmitPacket * Transmit packet on IN endpoint * @param pdev: device instance + * @param ClassId: The Class ID * @retval status */ +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t ClassId) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[ClassId]; +#else uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev) { USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; +#endif /* USE_USBD_COMPOSITE */ + USBD_StatusTypeDef ret = USBD_BUSY; #ifdef USE_USBD_COMPOSITE /* Get the Endpoints addresses allocated for this class instance */ - CDCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK); -#endif /* USE_USBD_COMPOSITE */ - if (pdev->pClassDataCmsit[pdev->classId] == NULL) + CDCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, ClassId); +#endif /* USE_USBD_COMPOSITE */ + + if (hcdc == NULL) { return (uint8_t)USBD_FAIL; } @@ -862,7 +879,7 @@ uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev) #ifdef USE_USBD_COMPOSITE /* Get the Endpoints addresses allocated for this class instance */ - CDCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK); + CDCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); #endif /* USE_USBD_COMPOSITE */ if (pdev->pClassDataCmsit[pdev->classId] == NULL) diff --git a/radio/src/thirdparty/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid.c b/radio/src/thirdparty/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid.c index 8207618a1..c64ba9913 100644 --- a/radio/src/thirdparty/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid.c +++ b/radio/src/thirdparty/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid.c @@ -479,7 +479,15 @@ static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev, } } - (void)USBD_CtlSendData(pdev, pbuf, len); + if (pbuf != NULL) + { + (void)USBD_CtlSendData(pdev, pbuf, len); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } break; case USB_REQ_GET_INTERFACE: diff --git a/radio/src/thirdparty/STM32_USB_Device_Library/Class/DFU/Inc/usbd_dfu.h b/radio/src/thirdparty/STM32_USB_Device_Library/Class/DFU/Inc/usbd_dfu.h new file mode 100644 index 000000000..ab74e24ac --- /dev/null +++ b/radio/src/thirdparty/STM32_USB_Device_Library/Class/DFU/Inc/usbd_dfu.h @@ -0,0 +1,271 @@ +/** + ****************************************************************************** + * @file usbd_dfu.h + * @author MCD Application Team + * @brief Header file for the usbd_dfu.c file. + ****************************************************************************** + * @attention + * + * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_DFU_H +#define __USB_DFU_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_DFU + * @brief This file is the Header file for usbd_dfu.c + * @{ + */ + + +/** @defgroup USBD_DFU_Exported_Defines + * @{ + */ +#ifndef USBD_DFU_MAX_ITF_NUM +#define USBD_DFU_MAX_ITF_NUM 1U +#endif /* USBD_DFU_MAX_ITF_NUM */ + +#ifndef USBD_DFU_XFER_SIZE +#define USBD_DFU_XFER_SIZE 1024U +#endif /* USBD_DFU_XFER_SIZE */ + +#ifndef USBD_DFU_APP_DEFAULT_ADD +#define USBD_DFU_APP_DEFAULT_ADD 0x08008000U /* The first sector (32 KB) is reserved for DFU code */ +#endif /* USBD_DFU_APP_DEFAULT_ADD */ + +#ifndef USBD_DFU_BM_ATTRIBUTES +#define USBD_DFU_BM_ATTRIBUTES 0x0BU +#endif /* USBD_DFU_BM_ATTRIBUTES */ + +#ifndef USBD_DFU_DETACH_TIMEOUT +#define USBD_DFU_DETACH_TIMEOUT 0xFFU +#endif /* USBD_DFU_DETACH_TIMEOUT */ + +#define USB_DFU_CONFIG_DESC_SIZ (18U + (9U * USBD_DFU_MAX_ITF_NUM)) +#define USB_DFU_DESC_SIZ 9U + +#define DFU_DESCRIPTOR_TYPE 0x21U + +#define DFU_VENDOR_CMD_MAX 32U + + +/**************************************************/ +/* DFU Requests DFU states */ +/**************************************************/ +#define APP_STATE_IDLE 0U +#define APP_STATE_DETACH 1U +#define DFU_STATE_IDLE 2U +#define DFU_STATE_DNLOAD_SYNC 3U +#define DFU_STATE_DNLOAD_BUSY 4U +#define DFU_STATE_DNLOAD_IDLE 5U +#define DFU_STATE_MANIFEST_SYNC 6U +#define DFU_STATE_MANIFEST 7U +#define DFU_STATE_MANIFEST_WAIT_RESET 8U +#define DFU_STATE_UPLOAD_IDLE 9U +#define DFU_STATE_ERROR 10U + +/**************************************************/ +/* DFU errors */ +/**************************************************/ +#define DFU_ERROR_NONE 0x00U +#define DFU_ERROR_TARGET 0x01U +#define DFU_ERROR_FILE 0x02U +#define DFU_ERROR_WRITE 0x03U +#define DFU_ERROR_ERASE 0x04U +#define DFU_ERROR_CHECK_ERASED 0x05U +#define DFU_ERROR_PROG 0x06U +#define DFU_ERROR_VERIFY 0x07U +#define DFU_ERROR_ADDRESS 0x08U +#define DFU_ERROR_NOTDONE 0x09U +#define DFU_ERROR_FIRMWARE 0x0AU +#define DFU_ERROR_VENDOR 0x0BU +#define DFU_ERROR_USB 0x0CU +#define DFU_ERROR_POR 0x0DU +#define DFU_ERROR_UNKNOWN 0x0EU +#define DFU_ERROR_STALLEDPKT 0x0FU + +/**************************************************/ +/* DFU Manifestation State */ +/**************************************************/ +#define DFU_MANIFEST_COMPLETE 0x00U +#define DFU_MANIFEST_IN_PROGRESS 0x01U + + +/**************************************************/ +/* Special Commands with Download Request */ +/**************************************************/ +#define DFU_CMD_GETCOMMANDS 0x00U +#define DFU_CMD_SETADDRESSPOINTER 0x21U +#define DFU_CMD_ERASE 0x41U + +#define DFU_MEDIA_ERASE 0x00U +#define DFU_MEDIA_PROGRAM 0x01U + +/**************************************************/ +/* Other defines */ +/**************************************************/ +/* Bit Detach capable = bit 3 in bmAttributes field */ +#define DFU_DETACH_MASK (1U << 3) +#define DFU_MANIFEST_MASK (1U << 2) +#define DFU_STATUS_DEPTH 6U + +#define IS_DFU_DOWNLOAD 0x0DFDFU +#define IS_DFU_UPLOAD 0x1DFDFU +#define IS_DFU_SETADDRESSPOINTER 0x2DFDFU +#define IS_DFU_PHY_ADDRESS 0x3DFDFU + +typedef enum +{ + DFU_DETACH = 0U, + DFU_DNLOAD, + DFU_UPLOAD, + DFU_GETSTATUS, + DFU_CLRSTATUS, + DFU_GETSTATE, + DFU_ABORT +} DFU_RequestTypeDef; + +typedef void (*pFunction)(void); + + +/********** Descriptor of DFU interface 0 Alternate setting n ****************/ +#define USBD_DFU_IF_DESC(n) \ + 0x09, /* bLength: Interface Descriptor size */ \ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType */ \ + 0x00, /* bInterfaceNumber: Number of Interface */ \ + (n), /* bAlternateSetting: Alternate setting */ \ + 0x00, /* bNumEndpoints*/ \ + 0xFE, /* bInterfaceClass: Application Specific Class Code */ \ + 0x01, /* bInterfaceSubClass : Device Firmware Upgrade Code */ \ + 0x02, /* nInterfaceProtocol: DFU mode protocol */ \ + USBD_IDX_INTERFACE_STR + (n) + 1U /* iInterface: Index of string descriptor */ + +#define TRANSFER_SIZE_BYTES(size) ((uint8_t)(size)), ((uint8_t)((size) >> 8)) + +#define IS_PROTECTED_AREA(add) (uint8_t)((((add) >= 0x08000000) && ((add) < (APP_DEFAULT_ADD))) ? 1 : 0) + +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ + +typedef struct +{ + union + { + uint32_t d32[USBD_DFU_XFER_SIZE / 4U]; + uint8_t d8[USBD_DFU_XFER_SIZE]; + } buffer; + + uint32_t wblock_num; + uint32_t wlength; + uint32_t data_ptr; + uint32_t app_addr_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; + +typedef struct +{ + const uint8_t *pStrDesc; + uint16_t (* Init)(void); + uint16_t (* DeInit)(void); + uint16_t (* Erase)(uint32_t Add); + 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); +#if (USBD_DFU_VENDOR_CMD_ENABLED == 1U) + uint16_t (* GetVendorCMD)(uint8_t *cmd, uint8_t *cmdlength); + uint16_t (* VendorDownloadCMD)(uint8_t *pbuf, uint32_t BlockNumber, uint32_t wlength, uint32_t *status); + uint16_t (* VendorUploadCMD)(uint32_t Add, uint32_t BlockNumber, uint32_t *status); +#endif /* USBD_DFU_VENDOR_CMD_ENABLED */ +#if (USBD_DFU_VENDOR_CHECK_ENABLED == 1U) + uint16_t (* VendorCheck)(uint8_t *pbuf, uint32_t ReqType, uint32_t *status); +#endif /* USBD_DFU_VENDOR_CHECK_ENABLED */ +#if (USBD_DFU_VENDOR_EXIT_ENABLED == 1U) + uint16_t (* LeaveDFU)(uint32_t Add); +#endif /* USBD_DFU_VENDOR_EXIT_ENABLED */ +} USBD_DFU_MediaTypeDef; + +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bmAttributes; + uint16_t wDetachTimeout; + uint16_t wTransferSze; + uint16_t bcdDFUVersion; +} __PACKED USBD_DFUFuncDescTypeDef; + +/** + * @} + */ + + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ + +extern USBD_ClassTypeDef USBD_DFU; +#define USBD_DFU_CLASS &USBD_DFU +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ +uint8_t USBD_DFU_RegisterMedia(USBD_HandleTypeDef *pdev, + USBD_DFU_MediaTypeDef *fops); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_DFU_H */ +/** + * @} + */ + +/** + * @} + */ diff --git a/radio/src/thirdparty/STM32_USB_Device_Library/Class/DFU/Src/usbd_dfu.c b/radio/src/thirdparty/STM32_USB_Device_Library/Class/DFU/Src/usbd_dfu.c new file mode 100644 index 000000000..67ba12c48 --- /dev/null +++ b/radio/src/thirdparty/STM32_USB_Device_Library/Class/DFU/Src/usbd_dfu.c @@ -0,0 +1,1400 @@ +/** + ****************************************************************************** + * @file usbd_dfu.c + * @author MCD Application Team + * @brief This file provides the DFU core functions. + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + * @verbatim + * + * =================================================================== + * DFU Class Driver Description + * =================================================================== + * This driver manages the DFU class V1.1 following the "Device Class Specification for + * Device Firmware Upgrade Version 1.1 Aug 5, 2004". + * This driver implements the following aspects of the specification: + * - Device descriptor management + * - Configuration descriptor management + * - Enumeration as DFU device (in DFU mode only) + * - Requests management (supporting ST DFU sub-protocol) + * - Memory operations management (Download/Upload/Erase/Detach/GetState/GetStatus) + * - DFU state machine implementation. + * + * @note + * ST DFU sub-protocol is compliant with DFU protocol and use sub-requests to manage + * memory addressing, commands processing, specific memories operations (ie. Erase) ... + * As required by the DFU specification, only endpoint 0 is used in this application. + * Other endpoints and functions may be added to the application (ie. DFU ...) + * + * 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): + * - Manifestation Tolerant mode + * + * @endverbatim + * + ****************************************************************************** + */ + +/* BSPDependencies +- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c" +- "stm32xxxxx_{eval}{discovery}_io.c" +EndBSPDependencies */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_dfu.h" +#include "usbd_ctlreq.h" + + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_DFU + * @brief usbd core module + * @{ + */ + +/** @defgroup USBD_DFU_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_DFU_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_DFU_Private_Macros + * @{ + */ + +/** + * @} + */ + + +/** @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); + +#ifndef USE_USBD_COMPOSITE +static uint8_t *USBD_DFU_GetCfgDesc(uint16_t *length); +static uint8_t *USBD_DFU_GetDeviceQualifierDesc(uint16_t *length); +#endif /* USE_USBD_COMPOSITE */ + +#if (USBD_SUPPORT_USER_STRING_DESC == 1U) +static uint8_t *USBD_DFU_GetUsrStringDesc(USBD_HandleTypeDef *pdev, + uint8_t index, uint16_t *length); +#endif /* USBD_SUPPORT_USER_STRING_DESC */ + +static void DFU_Detach(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static void DFU_Download(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +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); +static void *USBD_DFU_GetDfuFuncDesc(uint8_t *pConfDesc); + +/** + * @} + */ + +/** @defgroup USBD_DFU_Private_Variables + * @{ + */ + +USBD_ClassTypeDef USBD_DFU = +{ + USBD_DFU_Init, + USBD_DFU_DeInit, + USBD_DFU_Setup, + USBD_DFU_EP0_TxReady, + USBD_DFU_EP0_RxReady, + NULL, + NULL, + USBD_DFU_SOF, + NULL, + NULL, +#ifdef USE_USBD_COMPOSITE + NULL, + NULL, + NULL, + NULL, +#else + USBD_DFU_GetCfgDesc, + USBD_DFU_GetCfgDesc, + USBD_DFU_GetCfgDesc, + USBD_DFU_GetDeviceQualifierDesc, +#endif /* USE_USBD_COMPOSITE */ +#if (USBD_SUPPORT_USER_STRING_DESC == 1U) + USBD_DFU_GetUsrStringDesc +#endif /* USBD_SUPPORT_USER_STRING_DESC */ +}; + +#ifndef USE_USBD_COMPOSITE +/* USB DFU device Configuration Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_DFU_CfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END = +{ + 0x09, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + USB_DFU_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ + 0x00, + 0x01, /* bNumInterfaces: 1 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x02, /* iConfiguration: Index of string descriptor + describing the configuration */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif /* USBD_SELF_POWERED */ + USBD_MAX_POWER, /* MaxPower (mA) */ + /* 09 */ + + /********** Descriptor of DFU interface 0 Alternate setting 0 **************/ + 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 **************/ + USBD_DFU_IF_DESC(1), +#endif /* (USBD_DFU_MAX_ITF_NUM > 1) */ + +#if (USBD_DFU_MAX_ITF_NUM > 2U) + /********** Descriptor of DFU interface 0 Alternate setting 2 **************/ + USBD_DFU_IF_DESC(2), +#endif /* (USBD_DFU_MAX_ITF_NUM > 2) */ + +#if (USBD_DFU_MAX_ITF_NUM > 3U) + /********** Descriptor of DFU interface 0 Alternate setting 3 **************/ + USBD_DFU_IF_DESC(3), +#endif /* (USBD_DFU_MAX_ITF_NUM > 3) */ + +#if (USBD_DFU_MAX_ITF_NUM > 4U) + /********** Descriptor of DFU interface 0 Alternate setting 4 **************/ + USBD_DFU_IF_DESC(4), +#endif /* (USBD_DFU_MAX_ITF_NUM > 4) */ + +#if (USBD_DFU_MAX_ITF_NUM > 5U) + /********** Descriptor of DFU interface 0 Alternate setting 5 **************/ + USBD_DFU_IF_DESC(5), +#endif /* (USBD_DFU_MAX_ITF_NUM > 5) */ + +#if (USBD_DFU_MAX_ITF_NUM > 6U) +#error "ERROR: usbd_dfu_core.c: Modify the file to support more descriptors!" +#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*/ + 0x00, + /* 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 */ + 0x01 + /***********************************************************/ + /* 9*/ +}; + +/* USB Standard Device Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_DFU_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = +{ + USB_LEN_DEV_QUALIFIER_DESC, + USB_DESC_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x01, + 0x00, +}; +#endif /* USE_USBD_COMPOSITE */ + +/** + * @} + */ + +/** @defgroup USBD_DFU_Private_Functions + * @{ + */ + +/** + * @brief USBD_DFU_Init + * Initialize the DFU interface + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_DFU_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + UNUSED(cfgidx); + + USBD_DFU_HandleTypeDef *hdfu; + + /* Allocate Audio structure */ + hdfu = (USBD_DFU_HandleTypeDef *)USBD_malloc(sizeof(USBD_DFU_HandleTypeDef)); + + if (hdfu == NULL) + { + pdev->pClassDataCmsit[pdev->classId] = NULL; + return (uint8_t)USBD_EMEM; + } + + pdev->pClassDataCmsit[pdev->classId] = (void *)hdfu; + pdev->pClassData = pdev->pClassDataCmsit[pdev->classId]; + + 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[pdev->classId])->Init() != USBD_OK) + { + return (uint8_t)USBD_FAIL; + } + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_DFU_DeInit + * De-Initialize the DFU layer + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_DFU_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + UNUSED(cfgidx); + USBD_DFU_HandleTypeDef *hdfu; + + if (pdev->pClassDataCmsit[pdev->classId] == NULL) + { + return (uint8_t)USBD_EMEM; + } + + hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + hdfu->wblock_num = 0U; + hdfu->wlength = 0U; + + hdfu->dev_state = DFU_STATE_IDLE; + hdfu->dev_status[0] = DFU_ERROR_NONE; + hdfu->dev_status[4] = DFU_STATE_IDLE; + + /* DeInit physical Interface components and Hardware Layer */ + ((USBD_DFU_MediaTypeDef *)pdev->pUserData[pdev->classId])->DeInit(); + USBD_free(pdev->pClassDataCmsit[pdev->classId]); + pdev->pClassDataCmsit[pdev->classId] = NULL; + pdev->pClassData = NULL; + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_DFU_Setup + * Handle the DFU specific requests + * @param pdev: instance + * @param req: usb requests + * @retval status + */ +static uint8_t USBD_DFU_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_StatusTypeDef ret = USBD_OK; + uint8_t *pbuf; + uint16_t len; + uint16_t status_info = 0U; + + if (hdfu == NULL) + { + return (uint8_t)USBD_FAIL; + } + + 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; + } + 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 = (uint8_t *)USBD_DFU_GetDfuFuncDesc(pdev->pConfDesc); + + if (pbuf != NULL) + { + len = MIN(USB_DFU_DESC_SIZ, req->wLength); + (void)USBD_CtlSendData(pdev, pbuf, len); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + } + break; + + case USB_REQ_GET_INTERFACE: + 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 NAKed */ + 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; +} + +#ifndef USE_USBD_COMPOSITE +/** + * @brief USBD_DFU_GetCfgDesc + * return configuration descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_DFU_GetCfgDesc(uint16_t *length) +{ + *length = (uint16_t)sizeof(USBD_DFU_CfgDesc); + + return USBD_DFU_CfgDesc; +} +#endif /* USE_USBD_COMPOSITE */ + +/** + * @brief USBD_DFU_EP0_RxReady + * handle EP0 Rx Ready event + * @param pdev: device instance + * @retval status + */ +static uint8_t USBD_DFU_EP0_RxReady(USBD_HandleTypeDef *pdev) +{ + UNUSED(pdev); + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_DFU_EP0_TxReady + * handle EP0 TRx Ready event + * @param pdev: device instance + * @retval status + */ +static uint8_t USBD_DFU_EP0_TxReady(USBD_HandleTypeDef *pdev) +{ + USBD_SetupReqTypedef req; + uint32_t app_addr_ptr; + uint32_t addr; + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData[pdev->classId]; +#if (USBD_DFU_VENDOR_CMD_ENABLED == 1U) || (USBD_DFU_VENDOR_CHECK_ENABLED == 1U) + uint32_t VendorStatus = 0U; +#endif /* USBD_DFU_VENDOR_CMD_ENABLED */ + + if (hdfu == NULL) + { + return (uint8_t)USBD_FAIL; + } + + if (hdfu->dev_state == DFU_STATE_DNLOAD_BUSY) + { + /* Decode the Special Command */ + if (hdfu->wblock_num == 0U) + { + if (hdfu->wlength == 1U) + { + if (hdfu->buffer.d8[0] == DFU_CMD_GETCOMMANDS) + { + /* Nothing to do */ + } +#if (USBD_DFU_VENDOR_CMD_ENABLED == 1U) + else + { + /* Vendor specific DFU CMD */ + if (DfuInterface->VendorDownloadCMD(hdfu->buffer.d8, hdfu->wblock_num, + hdfu->wlength, &VendorStatus) != USBD_OK) + { + /* Update the state machine */ + hdfu->dev_state = DFU_STATE_ERROR; + hdfu->dev_status[0] = (uint8_t)VendorStatus; + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = hdfu->dev_state; + return (uint8_t)USBD_FAIL; + } + } +#endif /* USBD_DFU_VENDOR_CMD_ENABLED */ + } + else if (hdfu->wlength == 5U) + { + if (hdfu->buffer.d8[0] == DFU_CMD_SETADDRESSPOINTER) + { +#if (USBD_DFU_VENDOR_CHECK_ENABLED == 1U) + if (DfuInterface->VendorCheck(hdfu->buffer.d8, IS_DFU_SETADDRESSPOINTER, &VendorStatus) != USBD_OK) + { + /* Update the state machine */ + hdfu->dev_state = DFU_STATE_ERROR; + hdfu->dev_status[0] = (uint8_t)VendorStatus; + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = hdfu->dev_state; + return (uint8_t)USBD_FAIL; + } +#endif /* USBD_DFU_VENDOR_CHECK_ENABLED */ + + 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) + { +#if (USBD_DFU_VENDOR_CHECK_ENABLED == 1U) + if (DfuInterface->VendorCheck(hdfu->buffer.d8, IS_DFU_DOWNLOAD, &VendorStatus) != USBD_OK) + { + /* Update the state machine */ + hdfu->dev_state = DFU_STATE_ERROR; + hdfu->dev_status[0] = (uint8_t)VendorStatus; + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = hdfu->dev_state; + return (uint8_t)USBD_FAIL; + } +#endif /* USBD_DFU_VENDOR_CHECK_ENABLED */ + + app_addr_ptr = hdfu->buffer.d8[1]; + app_addr_ptr += (uint32_t)hdfu->buffer.d8[2] << 8; + app_addr_ptr += (uint32_t)hdfu->buffer.d8[3] << 16; + app_addr_ptr += (uint32_t)hdfu->buffer.d8[4] << 24; + + if (DfuInterface->Erase(app_addr_ptr) != USBD_OK) + { + /* Update the state machine */ + hdfu->dev_state = DFU_STATE_ERROR; + hdfu->dev_status[0] = DFU_ERROR_VENDOR; + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = hdfu->dev_state; + return (uint8_t)USBD_FAIL; + } + } +#if (USBD_DFU_VENDOR_CMD_ENABLED == 1U) + else + { + /* Vendor specific DFU CMD */ + if (DfuInterface->VendorDownloadCMD(hdfu->buffer.d8, hdfu->wblock_num, + hdfu->wlength, &VendorStatus) != USBD_OK) + { + /* Update the state machine */ + hdfu->dev_state = DFU_STATE_ERROR; + hdfu->dev_status[0] = (uint8_t)VendorStatus; + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = hdfu->dev_state; + return (uint8_t)USBD_FAIL; + } + } +#else + else + { + return (uint8_t)USBD_FAIL; + } +#endif /* USBD_DFU_VENDOR_CMD_ENABLED */ + } + else + { +#if (USBD_DFU_VENDOR_CMD_ENABLED == 1U) + if (hdfu->wlength > 0U) + { +#if (USBD_DFU_VENDOR_CHECK_ENABLED == 1U) + if (DfuInterface->VendorCheck(hdfu->buffer.d8, IS_DFU_DOWNLOAD, &VendorStatus) != USBD_OK) + { + /* Update the state machine */ + hdfu->dev_state = DFU_STATE_ERROR; + hdfu->dev_status[0] = (uint8_t)VendorStatus; + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = hdfu->dev_state; + return (uint8_t)USBD_FAIL; + } +#endif /* USBD_DFU_VENDOR_CHECK_ENABLED */ + + /* Vendor specific DFU CMD */ + if (DfuInterface->VendorDownloadCMD(hdfu->buffer.d8, hdfu->wblock_num, + hdfu->wlength, &VendorStatus) != USBD_OK) + { + /* Update the state machine */ + hdfu->dev_state = DFU_STATE_ERROR; + hdfu->dev_status[0] = (uint8_t)VendorStatus; + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = hdfu->dev_state; + return (uint8_t)USBD_FAIL; + } + } + else + { + /* Reset the block number */ + hdfu->wblock_num = 0U; + + /* Call the error management function (command will be NAKed) */ + req.bmRequest = 0U; + req.wLength = 1U; + USBD_CtlError(pdev, &req); + } +#else + /* Reset the global length and block number */ + hdfu->wlength = 0U; + hdfu->wblock_num = 0U; + + /* Call the error management function (command will be NAKed) */ + req.bmRequest = 0U; + req.wLength = 1U; + USBD_CtlError(pdev, &req); +#endif /* USBD_DFU_VENDOR_CMD_ENABLED */ + } + } + /* Regular Download Command */ + else + { + if (hdfu->wblock_num > 1U) + { +#if (USBD_DFU_VENDOR_CHECK_ENABLED == 1U) + if (DfuInterface->VendorCheck(hdfu->buffer.d8, IS_DFU_DOWNLOAD, &VendorStatus) != USBD_OK) + { + /* Update the state machine */ + hdfu->dev_state = DFU_STATE_ERROR; + hdfu->dev_status[0] = (uint8_t)VendorStatus; + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = hdfu->dev_state; + return (uint8_t)USBD_FAIL; + } +#endif /* USBD_DFU_VENDOR_CHECK_ENABLED */ + + /* Decode the required address */ + addr = ((hdfu->wblock_num - 2U) * USBD_DFU_XFER_SIZE) + hdfu->data_ptr; + + /* Perform the write operation */ + if (DfuInterface->Write(hdfu->buffer.d8, (uint8_t *)addr, hdfu->wlength) != USBD_OK) + { + /* Update the state machine */ + hdfu->dev_state = DFU_STATE_ERROR; + hdfu->dev_status[0] = DFU_ERROR_VENDOR; + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = hdfu->dev_state; + return (uint8_t)USBD_FAIL; + } + } + } + + /* Reset the global length and block number */ + hdfu->wlength = 0U; + hdfu->wblock_num = 0U; + + /* Update the state machine */ + hdfu->dev_state = DFU_STATE_DNLOAD_SYNC; + + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = hdfu->dev_state; + } + else if (hdfu->dev_state == DFU_STATE_MANIFEST)/* Manifestation in progress */ + { + /* Start leaving DFU mode */ + DFU_Leave(pdev); + } + else + { + return (uint8_t)USBD_FAIL; + } + + return (uint8_t)USBD_OK; +} +/** + * @brief USBD_DFU_SOF + * handle SOF event + * @param pdev: device instance + * @retval status + */ +static uint8_t USBD_DFU_SOF(USBD_HandleTypeDef *pdev) +{ + UNUSED(pdev); + + return (uint8_t)USBD_OK; +} + +#ifndef USE_USBD_COMPOSITE +/** + * @brief DeviceQualifierDescriptor + * return Device Qualifier descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_DFU_GetDeviceQualifierDesc(uint16_t *length) +{ + *length = (uint16_t)sizeof(USBD_DFU_DeviceQualifierDesc); + + return USBD_DFU_DeviceQualifierDesc; +} +#endif /* USE_USBD_COMPOSITE */ + +/** + * @brief USBD_DFU_GetUsrStringDesc + * Manages the transfer of memory interfaces string descriptors. + * @param pdev: device instance + * @param index: descriptor index + * @param length : pointer data length + * @retval pointer to the descriptor table or NULL if the descriptor is not supported. + */ +#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_StrDesc[255]; + USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData[pdev->classId]; + + /* Check if the requested string interface is supported */ + if (index <= (USBD_IDX_INTERFACE_STR + USBD_DFU_MAX_ITF_NUM)) + { + USBD_GetString((uint8_t *)DfuInterface->pStrDesc, USBD_StrDesc, length); + return USBD_StrDesc; + } + else + { + /* Not supported Interface Descriptor index */ + *length = 0U; + return NULL; + } +} +#endif /* USBD_SUPPORT_USER_STRING_DESC */ + +/** + * @brief USBD_MSC_RegisterStorage + * @param pdev: device instance + * @param fops: storage callback + * @retval status + */ +uint8_t USBD_DFU_RegisterMedia(USBD_HandleTypeDef *pdev, + USBD_DFU_MediaTypeDef *fops) +{ + if (fops == NULL) + { + return (uint8_t)USBD_FAIL; + } + + pdev->pUserData[pdev->classId] = fops; + + return (uint8_t)USBD_OK; +} + +/****************************************************************************** + DFU Class requests management + ******************************************************************************/ +/** + * @brief DFU_Detach + * Handles the DFU DETACH request. + * @param pdev: device instance + * @param req: pointer to the request structure. + * @retval None. + */ +static void DFU_Detach(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_DFUFuncDescTypeDef *pDfuFunc = (USBD_DFUFuncDescTypeDef *)USBD_DFU_GetDfuFuncDesc(pdev->pConfDesc); + + if ((hdfu == NULL) || (pDfuFunc == NULL)) + { + return; + } + + 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; + hdfu->dev_status[0] = DFU_ERROR_NONE; + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; /*bwPollTimeout=0ms*/ + hdfu->dev_status[4] = hdfu->dev_state; + hdfu->dev_status[5] = 0U; /*iString*/ + hdfu->wblock_num = 0U; + hdfu->wlength = 0U; + } + + /* Check the detach capability in the DFU functional descriptor */ + if ((pDfuFunc->bmAttributes & DFU_DETACH_MASK) != 0U) + { + /* Perform an Attach-Detach operation on USB bus */ + (void)USBD_Stop(pdev); + (void)USBD_Start(pdev); + } + else + { + /* Wait for the period of time specified in Detach request */ + USBD_Delay((uint32_t)req->wValue); + } +} + +/** + * @brief DFU_Download + * Handles the DFU DNLOAD request. + * @param pdev: device instance + * @param req: pointer to the request structure + * @retval None + */ +static void DFU_Download(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + +#if (USBD_DFU_VENDOR_CHECK_ENABLED == 1U) + USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData[pdev->classId]; + uint32_t VendorStatus = 0U; +#endif /* USBD_DFU_VENDOR_CHECK_ENABLED */ + + if (hdfu == NULL) + { + return; + } + + /* Data setup request */ + if (req->wLength > 0U) + { + if ((hdfu->dev_state == DFU_STATE_IDLE) || (hdfu->dev_state == DFU_STATE_DNLOAD_IDLE)) + { + /* Update the global length and block number */ + hdfu->wblock_num = req->wValue; + hdfu->wlength = MIN(req->wLength, USBD_DFU_XFER_SIZE); + + /* Update the state machine */ + hdfu->dev_state = DFU_STATE_DNLOAD_SYNC; + hdfu->dev_status[4] = hdfu->dev_state; + + /* Prepare the reception of the buffer over EP0 */ + (void)USBD_CtlPrepareRx(pdev, (uint8_t *)hdfu->buffer.d8, hdfu->wlength); + } + /* Unsupported state */ + else + { + /* Call the error management function (command will be NAKed */ + USBD_CtlError(pdev, req); + } + } + /* 0 Data DNLOAD request */ + else + { + /* End of DNLOAD operation */ + if ((hdfu->dev_state == DFU_STATE_DNLOAD_IDLE) || (hdfu->dev_state == DFU_STATE_IDLE)) + { +#if (USBD_DFU_VENDOR_CHECK_ENABLED == 1U) + if (DfuInterface->VendorCheck(hdfu->buffer.d8, IS_DFU_SETADDRESSPOINTER, &VendorStatus) != USBD_OK) + { + /* Update the state machine */ + hdfu->dev_state = DFU_STATE_ERROR; + hdfu->dev_status[0] = (uint8_t)VendorStatus; + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = hdfu->dev_state; + } + else +#endif /* USBD_DFU_VENDOR_CHECK_ENABLED */ + { + hdfu->manif_state = DFU_MANIFEST_IN_PROGRESS; + hdfu->dev_state = DFU_STATE_MANIFEST_SYNC; + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = hdfu->dev_state; + } + } + else + { + /* Call the error management function (command will be NAKed */ + USBD_CtlError(pdev, req); + } + } +} + +/** + * @brief DFU_Upload + * Handles the DFU UPLOAD request. + * @param pdev: instance + * @param req: pointer to the request structure + * @retval status + */ +static void DFU_Upload(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData[pdev->classId]; + uint8_t *phaddr; + uint32_t addr; + uint32_t CmdLength; +#if (USBD_DFU_VENDOR_CMD_ENABLED == 1U) + uint32_t VendorStatus = 0U; + uint8_t VendorCmdLength = 0U; + uint8_t VendorCmdBuffer[DFU_VENDOR_CMD_MAX]; + uint8_t idx; +#endif /* USBD_DFU_VENDOR_CMD_ENABLED */ + + if (hdfu == NULL) + { + return; + } + + /* Data setup request */ + if (req->wLength > 0U) + { + if ((hdfu->dev_state == DFU_STATE_IDLE) || (hdfu->dev_state == DFU_STATE_UPLOAD_IDLE)) + { + /* Update the global length and block number */ + hdfu->wblock_num = req->wValue; + hdfu->wlength = MIN(req->wLength, USBD_DFU_XFER_SIZE); + + /* DFU Get Command */ + if (hdfu->wblock_num == 0U) + { + /* Update the state machine */ + hdfu->dev_state = (hdfu->wlength > 3U) ? DFU_STATE_IDLE : DFU_STATE_UPLOAD_IDLE; + + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = hdfu->dev_state; + + /* Store the values of all supported commands */ + hdfu->buffer.d8[0] = DFU_CMD_GETCOMMANDS; + hdfu->buffer.d8[1] = DFU_CMD_SETADDRESSPOINTER; + hdfu->buffer.d8[2] = DFU_CMD_ERASE; + + CmdLength = 3U; + +#if (USBD_DFU_VENDOR_CMD_ENABLED == 1U) + if (DfuInterface->GetVendorCMD != NULL) + { + (void)DfuInterface->GetVendorCMD(VendorCmdBuffer, (uint8_t *)&VendorCmdLength); + + for (idx = 0U; idx < MIN(VendorCmdLength, DFU_VENDOR_CMD_MAX); idx++) + { + hdfu->buffer.d8[idx + 3U] = VendorCmdBuffer[idx]; + } + + CmdLength += MIN(VendorCmdLength, DFU_VENDOR_CMD_MAX); + } +#endif /* USBD_DFU_VENDOR_CMD_ENABLED */ + + /* Send the status data over EP0 */ + (void)USBD_CtlSendData(pdev, (uint8_t *)(&(hdfu->buffer.d8[0])), CmdLength); + } + else if (hdfu->wblock_num > 1U) + { + hdfu->dev_state = DFU_STATE_UPLOAD_IDLE; + + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = hdfu->dev_state; + +#if (USBD_DFU_VENDOR_CMD_ENABLED == 1U) + /* Vendor specific DFU CMD */ + if (DfuInterface->VendorUploadCMD(hdfu->data_ptr, hdfu->wblock_num, &VendorStatus) != USBD_OK) + { + /* Update the state machine */ + hdfu->dev_state = DFU_ERROR_STALLEDPKT; + hdfu->dev_status[0] = (uint8_t)VendorStatus; + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = hdfu->dev_state; + + /* Call the error management function (command will be NAKed) */ + USBD_CtlError(pdev, req); + } + + if (VendorStatus == IS_DFU_PHY_ADDRESS) +#endif /* USBD_DFU_VENDOR_CMD_ENABLED */ + { + addr = ((hdfu->wblock_num - 2U) * USBD_DFU_XFER_SIZE) + hdfu->data_ptr; + + /* Return the physical address where data are stored */ + phaddr = DfuInterface->Read((uint8_t *)addr, hdfu->buffer.d8, hdfu->wlength); + + if (phaddr == NULL) + { + hdfu->dev_state = DFU_ERROR_STALLEDPKT; + + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = hdfu->dev_state; + + /* Call the error management function (command will be NAKed) */ + USBD_CtlError(pdev, req); + } + else + { + /* Send the status data over EP0 */ + (void)USBD_CtlSendData(pdev, phaddr, hdfu->wlength); + } + } + } + else /* unsupported hdfu->wblock_num */ + { + hdfu->dev_state = DFU_ERROR_STALLEDPKT; + + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = hdfu->dev_state; + + /* Call the error management function (command will be NAKed) */ + USBD_CtlError(pdev, req); + } + } + /* Unsupported state */ + else + { + hdfu->wlength = 0U; + hdfu->wblock_num = 0U; + + /* Call the error management function (command will be NAKed) */ + USBD_CtlError(pdev, req); + } + } + /* No Data setup request */ + else + { + 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; + } +} + +/** + * @brief DFU_GetStatus + * Handles the DFU GETSTATUS request. + * @param pdev: instance + * @retval status + */ +static void DFU_GetStatus(USBD_HandleTypeDef *pdev) +{ + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData[pdev->classId]; + USBD_DFUFuncDescTypeDef *pDfuFunc = (USBD_DFUFuncDescTypeDef *)USBD_DFU_GetDfuFuncDesc(pdev->pConfDesc); + + if ((hdfu == NULL) || (DfuInterface == NULL) || (pDfuFunc == NULL)) + { + return; + } + + switch (hdfu->dev_state) + { + 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)) + { + DfuInterface->GetStatus(hdfu->data_ptr, DFU_MEDIA_ERASE, hdfu->dev_status); + } + else + { + DfuInterface->GetStatus(hdfu->data_ptr, DFU_MEDIA_PROGRAM, hdfu->dev_status); + } + } + else /* (hdfu->wlength == 0U) */ + { + 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; + } + else + { + if ((hdfu->manif_state == DFU_MANIFEST_COMPLETE) && + ((pDfuFunc->bmAttributes & DFU_MANIFEST_MASK) != 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 */ + (void)USBD_CtlSendData(pdev, (uint8_t *)(&(hdfu->dev_status[0])), 6U); +} + +/** + * @brief DFU_ClearStatus + * Handles the DFU CLRSTATUS request. + * @param pdev: device instance + * @retval status + */ +static void DFU_ClearStatus(USBD_HandleTypeDef *pdev) +{ + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + + if (hdfu == NULL) + { + return; + } + + if (hdfu->dev_state == DFU_STATE_ERROR) + { + hdfu->dev_state = DFU_STATE_IDLE; + 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 */ + } + else + { + /* State Error */ + hdfu->dev_state = DFU_STATE_ERROR; + 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 */ + } +} + +/** + * @brief DFU_GetState + * Handles the DFU GETSTATE request. + * @param pdev: device instance + * @retval None + */ +static void DFU_GetState(USBD_HandleTypeDef *pdev) +{ + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + + if (hdfu == NULL) + { + return; + } + + /* Return the current state of the DFU interface */ + (void)USBD_CtlSendData(pdev, &hdfu->dev_state, 1U); +} + +/** + * @brief DFU_Abort + * Handles the DFU ABORT request. + * @param pdev: device instance + * @retval None + */ +static void DFU_Abort(USBD_HandleTypeDef *pdev) +{ + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + + if (hdfu == NULL) + { + return; + } + + 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; + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; /* bwPollTimeout=0ms */ + hdfu->dev_status[4] = hdfu->dev_state; + hdfu->dev_status[5] = 0U; /* iString */ + hdfu->wblock_num = 0U; + hdfu->wlength = 0U; + } +} + +/** + * @brief DFU_Leave + * Handles the sub-protocol DFU leave DFU mode request (leaves DFU mode + * and resets device to jump to user loaded code). + * @param pdev: device instance + * @retval None + */ +static void DFU_Leave(USBD_HandleTypeDef *pdev) +{ + USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData[pdev->classId]; + USBD_DFUFuncDescTypeDef *pDfuFunc = (USBD_DFUFuncDescTypeDef *)USBD_DFU_GetDfuFuncDesc(pdev->pConfDesc); + + if ((hdfu == NULL) || (DfuInterface == NULL) || (pDfuFunc == NULL)) + { + return; + } + + hdfu->manif_state = DFU_MANIFEST_COMPLETE; + + if ((pDfuFunc->bmAttributes & DFU_MANIFEST_MASK) != 0U) + { + hdfu->dev_state = DFU_STATE_MANIFEST_SYNC; + + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = hdfu->dev_state; + return; + } + else + { + hdfu->dev_state = DFU_STATE_MANIFEST_WAIT_RESET; + + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = hdfu->dev_state; + + /* Disconnect the USB device */ + (void)USBD_Stop(pdev); + +#if (USBD_DFU_VENDOR_EXIT_ENABLED == 1U) + /* Jump should be ensured by user application */ + DfuInterface->LeaveDFU(hdfu->data_ptr); +#else + /* Generate system reset to allow jumping to the user code */ + NVIC_SystemReset(); +#endif /* USBD_DFU_VENDOR_EXIT_ENABLED */ + + /* The next instructions will not be reached (system reset) */ + } +} + +/** + * @brief USBD_DFU_GetDfuFuncDesc + * This function return the DFU descriptor + * @param pdev: device instance + * @param pConfDesc: pointer to Bos descriptor + * @retval pointer to the DFU descriptor + */ +static void *USBD_DFU_GetDfuFuncDesc(uint8_t *pConfDesc) +{ + USBD_ConfigDescTypeDef *desc = (USBD_ConfigDescTypeDef *)(void *)pConfDesc; + USBD_DescHeaderTypeDef *pdesc = (USBD_DescHeaderTypeDef *)(void *)pConfDesc; + uint8_t *pDfuDesc = NULL; + uint16_t ptr; + + if (desc->wTotalLength > desc->bLength) + { + ptr = desc->bLength; + + while (ptr < desc->wTotalLength) + { + pdesc = USBD_GetNextDesc((uint8_t *)pdesc, &ptr); + + if (pdesc->bDescriptorType == DFU_DESCRIPTOR_TYPE) + { + pDfuDesc = (uint8_t *)pdesc; + break; + } + } + } + return pDfuDesc; +} + +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + diff --git a/radio/src/thirdparty/STM32_USB_Device_Library/Core/Src/usbd_core.c b/radio/src/thirdparty/STM32_USB_Device_Library/Core/Src/usbd_core.c index 186a309cc..0576c877c 100644 --- a/radio/src/thirdparty/STM32_USB_Device_Library/Core/Src/usbd_core.c +++ b/radio/src/thirdparty/STM32_USB_Device_Library/Core/Src/usbd_core.c @@ -83,11 +83,11 @@ /** * @brief USBD_Init - * Initializes the device stack and load the class driver + * Initialize the device stack and load the class driver * @param pdev: device instance * @param pdesc: Descriptor structure address * @param id: Low level core index - * @retval None + * @retval status: USBD Status */ USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id) @@ -142,9 +142,9 @@ USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, /** * @brief USBD_DeInit - * Re-Initialize the device library + * De-Initialize the device library * @param pdev: device instance - * @retval status: status + * @retval status: USBD Status */ USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev) { @@ -195,7 +195,7 @@ USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev) /** * @brief USBD_RegisterClass * Link class driver to Device Core. - * @param pDevice : Device Handle + * @param pdev: Device Handle * @param pclass: Class handle * @retval USBD Status */ @@ -228,7 +228,7 @@ USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDe #endif /* USE_USB_FS */ /* Increment the NumClasses */ - pdev->NumClasses ++; + pdev->NumClasses++; return USBD_OK; } @@ -243,10 +243,10 @@ USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDe * @param EpAddr: Endpoint Address handle * @retval USBD Status */ -USBD_StatusTypeDef USBD_RegisterClassComposite(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass, - USBD_CompositeClassTypeDef classtype, uint8_t *EpAddr) +USBD_StatusTypeDef USBD_RegisterClassComposite(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass, + USBD_CompositeClassTypeDef classtype, uint8_t *EpAddr) { - USBD_StatusTypeDef ret = USBD_OK; + USBD_StatusTypeDef ret = USBD_OK; uint16_t len = 0U; if ((pdev->classId < USBD_MAX_SUPPORTED_CLASS) && (pdev->NumClasses < USBD_MAX_SUPPORTED_CLASS)) @@ -291,7 +291,7 @@ USBD_StatusTypeDef USBD_RegisterClassComposite(USBD_HandleTypeDef *pdev, USBD_C /** * @brief USBD_UnRegisterClassComposite * UnLink all composite class drivers from Device Core. - * @param pDevice : Device Handle + * @param pdev: Device Handle * @retval USBD Status */ USBD_StatusTypeDef USBD_UnRegisterClassComposite(USBD_HandleTypeDef *pdev) @@ -374,6 +374,7 @@ USBD_StatusTypeDef USBD_RegisterDevStateCallback(USBD_HandleTypeDef *pdev, USBD_ return USBD_OK; } #endif /* USBD_USER_REGISTER_CALLBACK */ + /** * @brief USBD_Start * Start the USB Device Core. @@ -499,7 +500,7 @@ USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) * Clear current configuration * @param pdev: device instance * @param cfgidx: configuration index - * @retval status: USBD_StatusTypeDef + * @retval status */ USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { @@ -539,6 +540,7 @@ USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) * @brief USBD_LL_SetupStage * Handle the setup stage * @param pdev: device instance + * @param psetup: setup packet buffer pointer * @retval status */ USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup) @@ -673,6 +675,7 @@ USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, * Handle data in stage * @param pdev: device instance * @param epnum: endpoint index + * @param pdata: data pointer * @retval status */ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, @@ -765,7 +768,6 @@ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, * @param pdev: device instance * @retval status */ - USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev) { USBD_StatusTypeDef ret = USBD_OK; @@ -848,7 +850,6 @@ USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, * @param pdev: device instance * @retval status */ - USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev) { if (pdev->dev_state != USBD_STATE_SUSPENDED) @@ -867,7 +868,6 @@ USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev) * @param pdev: device instance * @retval status */ - USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev) { if (pdev->dev_state == USBD_STATE_SUSPENDED) @@ -884,7 +884,6 @@ USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev) * @param pdev: device instance * @retval status */ - USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev) { /* The SOF event can be distributed for all classes that support it */ @@ -925,6 +924,7 @@ USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev) * @brief USBD_LL_IsoINIncomplete * Handle iso in incomplete event * @param pdev: device instance + * @param epnum: Endpoint number * @retval status */ USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, @@ -950,6 +950,7 @@ USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, * @brief USBD_LL_IsoOUTIncomplete * Handle iso out incomplete event * @param pdev: device instance + * @param epnum: Endpoint number * @retval status */ USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, diff --git a/radio/src/thirdparty/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c b/radio/src/thirdparty/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c index af9a0154c..814b810c5 100644 --- a/radio/src/thirdparty/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c +++ b/radio/src/thirdparty/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c @@ -46,7 +46,9 @@ /** @defgroup USBD_REQ_Private_Defines * @{ */ - +#ifndef USBD_MAX_STR_DESC_SIZ +#define USBD_MAX_STR_DESC_SIZ 64U +#endif /* USBD_MAX_STR_DESC_SIZ */ /** * @} */ @@ -421,7 +423,7 @@ USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef * Handle Get Descriptor requests * @param pdev: device instance * @param req: usb request - * @retval status + * @retval None */ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { @@ -675,7 +677,7 @@ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *r * Set device address * @param pdev: device instance * @param req: usb request - * @retval status + * @retval None */ static void USBD_SetAddress(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { @@ -814,7 +816,7 @@ static USBD_StatusTypeDef USBD_SetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReq * Handle Get device configuration request * @param pdev: device instance * @param req: usb request - * @retval status + * @retval None */ static void USBD_GetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { @@ -848,7 +850,7 @@ static void USBD_GetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) * Handle Get Status request * @param pdev: device instance * @param req: usb request - * @retval status + * @retval None */ static void USBD_GetStatus(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { @@ -889,7 +891,7 @@ static void USBD_GetStatus(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) * Handle Set device feature request * @param pdev: device instance * @param req: usb request - * @retval status + * @retval None */ static void USBD_SetFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { @@ -915,7 +917,7 @@ static void USBD_SetFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) * Handle clear device feature request * @param pdev: device instance * @param req: usb request - * @retval status + * @retval None */ static void USBD_ClrFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { @@ -941,8 +943,8 @@ static void USBD_ClrFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) /** * @brief USBD_ParseSetupRequest * Copy buffer into setup structure - * @param pdev: device instance * @param req: usb request + * @param pdata: setup data pointer * @retval None */ void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata) @@ -1002,7 +1004,7 @@ void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len) } pdesc = desc; - *len = ((uint16_t)USBD_GetLen(pdesc) * 2U) + 2U; + *len = MIN(USBD_MAX_STR_DESC_SIZ, ((uint16_t)USBD_GetLen(pdesc) * 2U) + 2U); unicode[idx] = *(uint8_t *)len; idx++;