From 7b5e6886d2f11ad15d2b46364e8a96984358f639 Mon Sep 17 00:00:00 2001 From: slimih Date: Wed, 14 Jun 2023 09:59:01 +0100 Subject: [PATCH] Release v2.11.2 --- Class/AUDIO/Src/usbd_audio.c | 15 +- Class/CustomHID/Src/usbd_customhid.c | 128 +------------ Class/DFU/Inc/usbd_dfu.h | 19 ++ Class/DFU/Src/usbd_dfu.c | 232 +++++++++++++++++++++--- Class/DFU/Src/usbd_dfu_media_template.c | 108 ++++++++++- Class/MSC/Inc/usbd_msc_data.h | 4 +- Class/MSC/Src/usbd_msc_data.c | 72 +++----- Class/MSC/Src/usbd_msc_scsi.c | 12 ++ Class/VIDEO/Inc/usbd_video.h | 3 +- Class/VIDEO/Src/usbd_video.c | 38 +++- Core/Inc/usbd_conf_template.h | 3 + Core/Inc/usbd_core.h | 3 + Core/Inc/usbd_def.h | 7 + Core/Src/usbd_core.c | 16 +- Core/Src/usbd_ctlreq.c | 17 +- Release_Notes.html | 145 ++++++++++++--- Release_Notes.md | 79 +++++--- 17 files changed, 627 insertions(+), 274 deletions(-) diff --git a/Class/AUDIO/Src/usbd_audio.c b/Class/AUDIO/Src/usbd_audio.c index a0a0941..05153b1 100644 --- a/Class/AUDIO/Src/usbd_audio.c +++ b/Class/AUDIO/Src/usbd_audio.c @@ -742,8 +742,19 @@ static uint8_t USBD_AUDIO_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnu */ static uint8_t USBD_AUDIO_IsoOutIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) { - UNUSED(pdev); - UNUSED(epnum); + USBD_AUDIO_HandleTypeDef *haudio; + + if (pdev->pClassDataCmsit[pdev->classId] == NULL) + { + return (uint8_t)USBD_FAIL; + } + + haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + + /* Prepare Out endpoint to receive next audio packet */ + (void)USBD_LL_PrepareReceive(pdev, epnum, + &haudio->buffer[haudio->wr_ptr], + AUDIO_OUT_PACKET); return (uint8_t)USBD_OK; } diff --git a/Class/CustomHID/Src/usbd_customhid.c b/Class/CustomHID/Src/usbd_customhid.c index 6add68a..8207618 100644 --- a/Class/CustomHID/Src/usbd_customhid.c +++ b/Class/CustomHID/Src/usbd_customhid.c @@ -45,7 +45,6 @@ EndBSPDependencies */ /* Includes ------------------------------------------------------------------*/ #include "usbd_customhid.h" #include "usbd_ctlreq.h" -#include "usbd_def.h" /** @addtogroup STM32_USB_DEVICE_LIBRARY @@ -168,7 +167,8 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgDesc[USB_CUSTOM_HID_CONFIG_DESC_ 0x11, /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */ 0x01, 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */ + 0x01, /* bNumDescriptors: Number of CUSTOM_HID class descriptors + to follow */ 0x22, /* bDescriptorType */ LOBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE), /* wItemLength: Total length of Report descriptor */ HIBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE), @@ -193,128 +193,6 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgDesc[USB_CUSTOM_HID_CONFIG_DESC_ 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 */ - LOBYTE(USB_CUSTOM_HID_CONFIG_DESC_SIZ), /* wTotalLength: Bytes returned */ - HIBYTE(USB_CUSTOM_HID_CONFIG_DESC_SIZ), - 0x01, /* bNumInterfaces: 1 interface */ - 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ -#if (USBD_SELF_POWERED == 1U) - 0xC0, /* bmAttributes: Bus Powered according to user configuration */ -#else - 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif - USBD_MAX_POWER, /* MaxPower (mA) */ - - /************** Descriptor of CUSTOM HID interface ****************/ - /* 09 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: CUSTOM_HID */ - 0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /******************** Descriptor of CUSTOM_HID *************************/ - /* 18 */ - 0x09, /* bLength: CUSTOM_HID Descriptor size */ - CUSTOM_HID_DESCRIPTOR_TYPE, /* bDescriptorType: CUSTOM_HID */ - 0x11, /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - LOBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE), /* wItemLength: Total length of Report descriptor */ - HIBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE), - /******************** Descriptor of Custom HID endpoints ********************/ - /* 27 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType */ - - CUSTOM_HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - LOBYTE(CUSTOM_HID_EPIN_SIZE), /* wMaxPacketSize: 2 Bytes max */ - HIBYTE(CUSTOM_HID_EPIN_SIZE), - 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 */ - LOBYTE(CUSTOM_HID_EPOUT_SIZE), /* wMaxPacketSize: 2 Bytes max */ - HIBYTE(CUSTOM_HID_EPOUT_SIZE), - 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 */ - LOBYTE(USB_CUSTOM_HID_CONFIG_DESC_SIZ), /* wTotalLength: Bytes returned */ - HIBYTE(USB_CUSTOM_HID_CONFIG_DESC_SIZ), - 0x01, /* bNumInterfaces: 1 interface */ - 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ -#if (USBD_SELF_POWERED == 1U) - 0xC0, /* bmAttributes: Bus Powered according to user configuration */ -#else - 0x80, /* bmAttributes: Bus Powered according to user configuration */ -#endif - USBD_MAX_POWER, /* MaxPower (mA) */ - - /************** Descriptor of CUSTOM HID interface ****************/ - /* 09 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: CUSTOM_HID */ - 0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /******************** Descriptor of CUSTOM_HID *************************/ - /* 18 */ - 0x09, /* bLength: CUSTOM_HID Descriptor size */ - CUSTOM_HID_DESCRIPTOR_TYPE, /* bDescriptorType: CUSTOM_HID */ - 0x11, /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - LOBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE), /* wItemLength: Total length of Report descriptor */ - HIBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE), - /******************** Descriptor of Custom HID endpoints ********************/ - /* 27 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ - - CUSTOM_HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - LOBYTE(CUSTOM_HID_EPIN_SIZE), /* wMaxPacketSize: 2 Bytes max */ - HIBYTE(CUSTOM_HID_EPIN_SIZE), - 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 */ - LOBYTE(CUSTOM_HID_EPOUT_SIZE), /* wMaxPacketSize: 2 Bytes max */ - HIBYTE(CUSTOM_HID_EPOUT_SIZE), - CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval */ - /* 41 */ -}; #endif /* USE_USBD_COMPOSITE */ /* USB CUSTOM_HID device Configuration Descriptor */ @@ -329,7 +207,7 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_Desc[USB_CUSTOM_HID_DESC_SIZ] __ALI 0x01, /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */ 0x22, /* bDescriptorType */ - LOBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE), /* wItemLength: Total length of Report descriptor */ + LOBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE), /* wItemLength: Total length of Report descriptor */ HIBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE), }; diff --git a/Class/DFU/Inc/usbd_dfu.h b/Class/DFU/Inc/usbd_dfu.h index 7858394..ab74e24 100644 --- a/Class/DFU/Inc/usbd_dfu.h +++ b/Class/DFU/Inc/usbd_dfu.h @@ -65,6 +65,8 @@ extern "C" { #define DFU_DESCRIPTOR_TYPE 0x21U +#define DFU_VENDOR_CMD_MAX 32U + /**************************************************/ /* DFU Requests DFU states */ @@ -126,6 +128,11 @@ extern "C" { #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, @@ -176,6 +183,7 @@ typedef struct 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]; @@ -193,6 +201,17 @@ 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); +#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 diff --git a/Class/DFU/Src/usbd_dfu.c b/Class/DFU/Src/usbd_dfu.c index 5895497..3a1b29e 100644 --- a/Class/DFU/Src/usbd_dfu.c +++ b/Class/DFU/Src/usbd_dfu.c @@ -521,9 +521,13 @@ 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 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) + uint32_t VendorStatus = 0U; +#endif /* USBD_DFU_VENDOR_CMD_ENABLED */ if (hdfu == NULL) { @@ -541,11 +545,43 @@ static uint8_t USBD_DFU_EP0_TxReady(USBD_HandleTypeDef *pdev) { /* 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; @@ -553,20 +589,61 @@ static uint8_t USBD_DFU_EP0_TxReady(USBD_HandleTypeDef *pdev) } 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) +#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 { @@ -584,12 +661,33 @@ static uint8_t USBD_DFU_EP0_TxReady(USBD_HandleTypeDef *pdev) { 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; } } @@ -670,7 +768,7 @@ static uint8_t *USBD_DFU_GetUsrStringDesc(USBD_HandleTypeDef *pdev, uint8_t inde else { /* Not supported Interface Descriptor index */ - length = 0U; + *length = 0U; return NULL; } } @@ -758,6 +856,11 @@ 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_CMD_ENABLED == 1U) + USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData[pdev->classId]; + uint32_t VendorStatus = 0U; +#endif /* USBD_DFU_VENDOR_CMD_ENABLED */ + if (hdfu == NULL) { return; @@ -789,15 +892,30 @@ static void DFU_Download(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) /* 0 Data DNLOAD request */ else { - /* End of DNLOAD operation*/ + /* End of DNLOAD operation */ 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; - 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_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 { @@ -820,6 +938,13 @@ static void DFU_Upload(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) 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) { @@ -851,8 +976,24 @@ static void DFU_Upload(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) 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])), 3U); + (void)USBD_CtlSendData(pdev, (uint8_t *)(&(hdfu->buffer.d8[0])), CmdLength); } else if (hdfu->wblock_num > 1U) { @@ -863,13 +1004,48 @@ 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; +#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; - /* Return the physical address where data are stored */ - phaddr = DfuInterface->Read((uint8_t *)addr, hdfu->buffer.d8, hdfu->wlength); + /* Call the error management function (command will be NAKed) */ + USBD_CtlError(pdev, req); + } - /* Send the status data over EP0 */ - (void)USBD_CtlSendData(pdev, phaddr, hdfu->wlength); + 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 */ { @@ -880,7 +1056,7 @@ static void DFU_Upload(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) hdfu->dev_status[3] = 0U; hdfu->dev_status[4] = hdfu->dev_state; - /* Call the error management function (command will be NAKed */ + /* Call the error management function (command will be NAKed) */ USBD_CtlError(pdev, req); } } @@ -890,7 +1066,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 NAKed */ + /* Call the error management function (command will be NAKed) */ USBD_CtlError(pdev, req); } } @@ -944,7 +1120,7 @@ static void DFU_GetStatus(USBD_HandleTypeDef *pdev) DfuInterface->GetStatus(hdfu->data_ptr, DFU_MEDIA_PROGRAM, hdfu->dev_status); } } - else /* (hdfu->wlength==0)*/ + else /* (hdfu->wlength == 0U) */ { hdfu->dev_state = DFU_STATE_DNLOAD_IDLE; @@ -960,7 +1136,7 @@ static void DFU_GetStatus(USBD_HandleTypeDef *pdev) { hdfu->dev_state = DFU_STATE_MANIFEST; - hdfu->dev_status[1] = 1U; /*bwPollTimeout = 1ms*/ + hdfu->dev_status[1] = 1U; /* bwPollTimeout = 1ms */ hdfu->dev_status[2] = 0U; hdfu->dev_status[3] = 0U; hdfu->dev_status[4] = hdfu->dev_state; @@ -1088,9 +1264,10 @@ static void DFU_Abort(USBD_HandleTypeDef *pdev) 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) || (pDfuFunc == NULL)) + if ((hdfu == NULL) || (DfuInterface == NULL) || (pDfuFunc == NULL)) { return; } @@ -1119,8 +1296,13 @@ static void DFU_Leave(USBD_HandleTypeDef *pdev) /* 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) */ } diff --git a/Class/DFU/Src/usbd_dfu_media_template.c b/Class/DFU/Src/usbd_dfu_media_template.c index 679d326..3f961f6 100644 --- a/Class/DFU/Src/usbd_dfu_media_template.c +++ b/Class/DFU/Src/usbd_dfu_media_template.c @@ -38,6 +38,17 @@ uint16_t MEM_If_Write(uint8_t *src, uint8_t *dest, uint32_t Len); uint8_t *MEM_If_Read(uint8_t *src, uint8_t *dest, uint32_t Len); uint16_t MEM_If_DeInit(void); uint16_t MEM_If_GetStatus(uint32_t Add, uint8_t Cmd, uint8_t *buffer); +#if (USBD_DFU_VENDOR_CMD_ENABLED == 1U) +uint16_t MEM_If_GetVendorCMD(uint8_t *cmd, uint8_t *cmdlength); +uint16_t MEM_If_VendorDownloadCMD(uint8_t *pbuf, uint32_t BlockNumber, uint32_t wlength, uint32_t *status); +uint16_t MEM_If_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 MEM_If_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 MEM_If_LeaveDFU(uint32_t Add); +#endif /* USBD_DFU_VENDOR_EXIT_ENABLED */ USBD_DFU_MediaTypeDef USBD_DFU_MEDIA_Template_fops = { @@ -48,8 +59,19 @@ USBD_DFU_MediaTypeDef USBD_DFU_MEDIA_Template_fops = MEM_If_Write, MEM_If_Read, MEM_If_GetStatus, - +#if (USBD_DFU_VENDOR_CMD_ENABLED == 1U) + MEM_If_GetVendorCMD, + MEM_If_VendorDownloadCMD, + MEM_If_VendorUploadCMD, +#endif /* USBD_DFU_VENDOR_CMD_ENABLED */ +#if (USBD_DFU_VENDOR_CHECK_ENABLED == 1U) + MEM_If_VendorCheck, +#endif /* USBD_DFU_VENDOR_CHECK_ENABLED */ +#if (USBD_DFU_VENDOR_EXIT_ENABLED == 1U) + MEM_If_LeaveDFU +#endif /* USBD_DFU_VENDOR_EXIT_ENABLED */ }; + /** * @brief MEM_If_Init * Memory initialization routine. @@ -115,7 +137,7 @@ uint8_t *MEM_If_Read(uint8_t *src, uint8_t *dest, uint32_t Len) UNUSED(Len); /* Return a valid address to avoid HardFault */ - return (uint8_t *)(0); + return NULL; } /** @@ -144,3 +166,85 @@ uint16_t MEM_If_GetStatus(uint32_t Add, uint8_t Cmd, uint8_t *buffer) return (0); } +#if (USBD_DFU_VENDOR_CMD_ENABLED == 1U) +/** + * @brief Get supported vendor specific commands + * @param pointer to supported vendor commands + * @param pointer to length of supported vendor commands + * @retval 0 if operation is successful + */ +uint16_t MEM_If_GetVendorCMD(uint8_t *cmd, uint8_t *cmdlength) +{ + UNUSED(cmd); + UNUSED(cmdlength); + + return 0U; +} + +/** + * @brief Vendor specific download commands + * @param pbuf DFU data buffer + * @param BlockNumber DFU memory block number + * @param wLength DFU request length + * @param pointer to DFU status + * @retval 0 if operation is successful + */ +uint16_t MEM_If_VendorDownloadCMD(uint8_t *pbuf, uint32_t BlockNumber, uint32_t wlength, uint32_t *status) +{ + UNUSED(pbuf); + UNUSED(BlockNumber); + UNUSED(wlength); + UNUSED(status); + + return 0U; +} + + +/** + * @brief Vendor specific upload commands + * @param Add memory Address + * @param BlockNumber DFU memory block number + * @param pointer to DFU status + * @retval 0 if operation is successful + */ +uint16_t MEM_If_VendorUploadCMD(uint32_t Add, uint32_t BlockNumber, uint32_t *status) +{ + UNUSED(Add); + UNUSED(BlockNumber); + UNUSED(status); + + return 0U; +} +#endif /* USBD_DFU_VENDOR_CMD_ENABLED */ + +#if (USBD_DFU_VENDOR_CHECK_ENABLED == 1U) +/** + * @brief Vendor memory check + * @param pbuf DFU data buffer + * @param ReqType IS_DFU_SETADDRESSPOINTER/DOWNLOAD/UPLOAD + * @param pointer to DFU status + * @retval 0 if operation is successful + */ +uint16_t MEM_If_VendorCheck(uint8_t *pbuf, uint32_t ReqType, uint32_t *status) +{ + UNUSED(pbuf); + UNUSED(ReqType); + UNUSED(status); + + return 0U; +} +#endif /* USBD_DFU_VENDOR_CHECK_ENABLED */ + +#if (USBD_DFU_VENDOR_EXIT_ENABLED == 1U) +/** + * @brief Vendor Leave DFU + * @param Application address + * @retval 0 if operation is successful + */ +uint16_t MEM_If_LeaveDFU(uint32_t Add) +{ + UNUSED(Add); + + return 0U; +} +#endif /* USBD_DFU_VENDOR_EXIT_ENABLED */ diff --git a/Class/MSC/Inc/usbd_msc_data.h b/Class/MSC/Inc/usbd_msc_data.h index f946b95..c96d2b8 100644 --- a/Class/MSC/Inc/usbd_msc_data.h +++ b/Class/MSC/Inc/usbd_msc_data.h @@ -39,8 +39,8 @@ extern "C" { /** @defgroup USB_INFO_Exported_Defines * @{ */ -#define MODE_SENSE6_LEN 0x17U -#define MODE_SENSE10_LEN 0x1BU +#define MODE_SENSE6_LEN 0x04U +#define MODE_SENSE10_LEN 0x08U #define LENGTH_INQUIRY_PAGE00 0x06U #define LENGTH_INQUIRY_PAGE80 0x08U #define LENGTH_FORMAT_CAPACITIES 0x14U diff --git a/Class/MSC/Src/usbd_msc_data.c b/Class/MSC/Src/usbd_msc_data.c index fabd835..1641c20 100644 --- a/Class/MSC/Src/usbd_msc_data.c +++ b/Class/MSC/Src/usbd_msc_data.c @@ -91,62 +91,32 @@ uint8_t MSC_Page80_Inquiry_Data[LENGTH_INQUIRY_PAGE80] = /* 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, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00 + 0x03, /* MODE DATA LENGTH. The number of bytes that follow. */ + 0x00, /* MEDIUM TYPE. 00h for SBC devices. */ + 0x00, /* DEVICE-SPECIFIC PARAMETER. For SBC devices: + * bit 7: WP. Set to 1 if the media is write-protected. + * bits 6..5: reserved + * bit 4: DPOFUA. Set to 1 if the device supports the DPO and FUA bits + * bits 3..0: reserved */ + 0x00 /* BLOCK DESCRIPTOR LENGTH */ }; -/* USB Mass storage sense 10 Data */ +/* USB Mass storage sense 10 Data */ uint8_t MSC_Mode_Sense10_data[MODE_SENSE10_LEN] = { - 0x00, - 0x26, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x08, - 0x12, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00 + 0x00, /* MODE DATA LENGTH MSB. */ + 0x06, /* MODE DATA LENGTH LSB. The number of bytes that follow. */ + 0x00, /* MEDIUM TYPE. 00h for SBC devices. */ + 0x00, /* DEVICE-SPECIFIC PARAMETER. For SBC devices: + * bit 7: WP. Set to 1 if the media is write-protected. + * bits 6..5: reserved + * bit 4: DPOFUA. Set to 1 if the device supports the DPO and FUA bits + * bits 3..0: reserved */ + 0x00, /* LONGLBA Set to zero */ + 0x00, /* Reserved */ + 0x00, /* BLOCK DESCRIPTOR LENGTH MSB. */ + 0x00 /* BLOCK DESCRIPTOR LENGTH LSB. */ }; /** * @} diff --git a/Class/MSC/Src/usbd_msc_scsi.c b/Class/MSC/Src/usbd_msc_scsi.c index efa85a4..3c0fe2f 100644 --- a/Class/MSC/Src/usbd_msc_scsi.c +++ b/Class/MSC/Src/usbd_msc_scsi.c @@ -477,6 +477,12 @@ static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *pa return -1; } + /* Check If media is write-protected */ + if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsWriteProtected(lun) != 0) + { + MSC_Mode_Sense6_data[2] |= 0x80U; + } + if (params[4] <= len) { len = params[4]; @@ -506,6 +512,12 @@ static int8_t SCSI_ModeSense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *p return -1; } + /* Check If media is write-protected */ + if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsWriteProtected(lun) != 0) + { + MSC_Mode_Sense10_data[3] |= 0x80U; + } + if (params[8] <= len) { len = params[8]; diff --git a/Class/VIDEO/Inc/usbd_video.h b/Class/VIDEO/Inc/usbd_video.h index 8ece002..5c9c4fd 100644 --- a/Class/VIDEO/Inc/usbd_video.h +++ b/Class/VIDEO/Inc/usbd_video.h @@ -377,7 +377,8 @@ typedef struct { uint32_t interface; uint32_t uvc_state; - uint8_t buffer[UVC_TOTAL_BUF_SIZE]; + uint32_t uvc_size; + uint8_t *uvc_buffer; VIDEO_OffsetTypeDef offset; USBD_VIDEO_ControlTypeDef control; } USBD_VIDEO_HandleTypeDef; diff --git a/Class/VIDEO/Src/usbd_video.c b/Class/VIDEO/Src/usbd_video.c index a2cb571..0e580ba 100644 --- a/Class/VIDEO/Src/usbd_video.c +++ b/Class/VIDEO/Src/usbd_video.c @@ -498,6 +498,11 @@ static uint8_t USBD_VIDEO_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef * uint16_t len; uint8_t *pbuf; +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + VIDEOinEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_ISOC, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ + switch (req->bmRequest & USB_REQ_TYPE_MASK) { /* Class Requests -------------------------------*/ @@ -643,6 +648,11 @@ static uint8_t USBD_VIDEO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) uint32_t RemainData = 0U; uint32_t DataOffset = 0U; +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + VIDEOinEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_ISOC, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ + /* Check if the Streaming has already been started */ if (hVIDEO->uvc_state == UVC_PLAY_STATUS_STREAMING) { @@ -692,9 +702,12 @@ static uint8_t USBD_VIDEO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) packet[1] = payload_header[1]; } + hVIDEO->uvc_buffer = (uint8_t *)&packet; + hVIDEO->uvc_size = (uint32_t)PcktSze; + /* Transmit the packet on Endpoint */ (void)USBD_LL_Transmit(pdev, (uint8_t)(epnum | 0x80U), - (uint8_t *)&packet, (uint32_t)PcktSze); + hVIDEO->uvc_buffer, hVIDEO->uvc_size); } /* Exit with no error code */ @@ -712,11 +725,19 @@ static uint8_t USBD_VIDEO_SOF(USBD_HandleTypeDef *pdev) USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *) pdev->pClassDataCmsit[pdev->classId]; uint8_t payload[2] = {0x02U, 0x00U}; +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + VIDEOinEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_ISOC, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ + /* Check if the Streaming has already been started by SetInterface AltSetting 1 */ if (hVIDEO->uvc_state == UVC_PLAY_STATUS_READY) { + hVIDEO->uvc_buffer = (uint8_t *)&payload; + hVIDEO->uvc_size = 2U; + /* Transmit the first packet indicating that Streaming is starting */ - (void)USBD_LL_Transmit(pdev, VIDEOinEpAdd, (uint8_t *)payload, 2U); + (void)USBD_LL_Transmit(pdev, VIDEOinEpAdd, hVIDEO->uvc_buffer, hVIDEO->uvc_size); /* Enable Streaming state */ hVIDEO->uvc_state = UVC_PLAY_STATUS_STREAMING; @@ -735,8 +756,17 @@ static uint8_t USBD_VIDEO_SOF(USBD_HandleTypeDef *pdev) */ static uint8_t USBD_VIDEO_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) { - UNUSED(pdev); - UNUSED(epnum); + USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *) pdev->pClassDataCmsit[pdev->classId]; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + VIDEOinEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_ISOC, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ + + if (epnum == (VIDEOinEpAdd & 0xFU)) + { + (void)USBD_LL_Transmit(pdev, VIDEOinEpAdd, hVIDEO->uvc_buffer, hVIDEO->uvc_size); + } return (uint8_t)USBD_OK; } diff --git a/Core/Inc/usbd_conf_template.h b/Core/Inc/usbd_conf_template.h index b288b66..8d61e7a 100644 --- a/Core/Inc/usbd_conf_template.h +++ b/Core/Inc/usbd_conf_template.h @@ -48,6 +48,7 @@ extern "C" { #define USBD_MAX_STR_DESC_SIZ 0x100U #define USBD_SELF_POWERED 1U #define USBD_DEBUG_LEVEL 2U +/* #define USBD_USER_REGISTER_CALLBACK 1U */ /* ECM, RNDIS, DFU Class Config */ #define USBD_SUPPORT_USER_STRING_DESC 1U @@ -64,6 +65,8 @@ extern "C" { #define USBD_CDC_INTERVAL 2000U /* DFU Class Config */ +/* #define USBD_DFU_VENDOR_CMD_ENABLED 1U */ +/* #define USBD_DFU_VENDOR_EXIT_ENABLED 1U */ #define USBD_DFU_MAX_ITF_NUM 1U #define USBD_DFU_XFERS_IZE 1024U diff --git a/Core/Inc/usbd_core.h b/Core/Inc/usbd_core.h index d601672..4672921 100644 --- a/Core/Inc/usbd_core.h +++ b/Core/Inc/usbd_core.h @@ -86,6 +86,9 @@ USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev); USBD_StatusTypeDef USBD_Start(USBD_HandleTypeDef *pdev); USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev); USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass); +#if (USBD_USER_REGISTER_CALLBACK == 1U) +USBD_StatusTypeDef USBD_RegisterDevStateCallback(USBD_HandleTypeDef *pdev, USBD_DevStateCallbackTypeDef pUserCallback); +#endif /* USBD_USER_REGISTER_CALLBACK */ #ifdef USE_USBD_COMPOSITE USBD_StatusTypeDef USBD_RegisterClassComposite(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass, diff --git a/Core/Inc/usbd_def.h b/Core/Inc/usbd_def.h index 8946819..2a295d7 100644 --- a/Core/Inc/usbd_def.h +++ b/Core/Inc/usbd_def.h @@ -390,8 +390,15 @@ typedef struct _USBD_HandleTypeDef #ifdef USE_USBD_COMPOSITE USBD_CompositeElementTypeDef tclasslist[USBD_MAX_SUPPORTED_CLASS]; #endif /* USE_USBD_COMPOSITE */ +#if (USBD_USER_REGISTER_CALLBACK == 1U) + void (* DevStateCallback)(uint8_t dev_state, uint8_t cfgidx); /*!< User Notification callback */ +#endif /* USBD_USER_REGISTER_CALLBACK */ } USBD_HandleTypeDef; +#if (USBD_USER_REGISTER_CALLBACK == 1U) +typedef void (*USBD_DevStateCallbackTypeDef)(uint8_t dev_state, uint8_t cfgidx); /*!< pointer to User callback function */ +#endif /* USBD_USER_REGISTER_CALLBACK */ + /* USB Device endpoint direction */ typedef enum { diff --git a/Core/Src/usbd_core.c b/Core/Src/usbd_core.c index 3c0610a..186a309 100644 --- a/Core/Src/usbd_core.c +++ b/Core/Src/usbd_core.c @@ -358,10 +358,22 @@ USBD_StatusTypeDef USBD_UnRegisterClassComposite(USBD_HandleTypeDef *pdev) return ret; } - - #endif /* USE_USBD_COMPOSITE */ +#if (USBD_USER_REGISTER_CALLBACK == 1U) +/** + * @brief USBD_RegisterDevStateCallback + * @param pdev : Device Handle + * @param pUserCallback: User Callback + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_RegisterDevStateCallback(USBD_HandleTypeDef *pdev, USBD_DevStateCallbackTypeDef pUserCallback) +{ + pdev->DevStateCallback = pUserCallback; + + return USBD_OK; +} +#endif /* USBD_USER_REGISTER_CALLBACK */ /** * @brief USBD_Start * Start the USB Device Core. diff --git a/Core/Src/usbd_ctlreq.c b/Core/Src/usbd_ctlreq.c index 899bc70..af9a015 100644 --- a/Core/Src/usbd_ctlreq.c +++ b/Core/Src/usbd_ctlreq.c @@ -454,7 +454,7 @@ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *r #ifdef USE_USBD_COMPOSITE if ((uint8_t)(pdev->NumClasses) > 0U) { - pbuf = (uint8_t *)USBD_CMPSIT.GetHSConfigDescriptor(&len); + pbuf = (uint8_t *)USBD_CMPSIT.GetHSConfigDescriptor(&len); } else #endif /* USE_USBD_COMPOSITE */ @@ -468,12 +468,12 @@ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *r #ifdef USE_USBD_COMPOSITE if ((uint8_t)(pdev->NumClasses) > 0U) { - pbuf = (uint8_t *)USBD_CMPSIT.GetFSConfigDescriptor(&len); + pbuf = (uint8_t *)USBD_CMPSIT.GetFSConfigDescriptor(&len); } else #endif /* USE_USBD_COMPOSITE */ { - pbuf = (uint8_t *)pdev->pClass[0]->GetFSConfigDescriptor(&len); + pbuf = (uint8_t *)pdev->pClass[0]->GetFSConfigDescriptor(&len); } pbuf[1] = USB_DESC_TYPE_CONFIGURATION; } @@ -558,7 +558,6 @@ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *r #if (USBD_SUPPORT_USER_STRING_DESC == 1U) pbuf = NULL; - for (uint32_t idx = 0U; (idx < pdev->NumClasses); idx++) { if (pdev->pClass[idx]->GetUsrStrDescriptor != NULL) @@ -576,13 +575,12 @@ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *r } } } - #endif /* USBD_SUPPORT_USER_STRING_DESC */ #if (USBD_CLASS_USER_STRING_DESC == 1U) if (pdev->pDesc->GetUserStrDescriptor != NULL) { - pbuf = pdev->pDesc->GetUserStrDescriptor(pdev->dev_speed, (req->wValue), &len); + pbuf = pdev->pDesc->GetUserStrDescriptor(pdev->dev_speed, LOBYTE(req->wValue), &len); } else { @@ -751,6 +749,13 @@ static USBD_StatusTypeDef USBD_SetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReq { (void)USBD_CtlSendStatus(pdev); pdev->dev_state = USBD_STATE_CONFIGURED; + +#if (USBD_USER_REGISTER_CALLBACK == 1U) + if (pdev->DevStateCallback != NULL) + { + pdev->DevStateCallback(USBD_STATE_CONFIGURED, cfgidx); + } +#endif /* USBD_USER_REGISTER_CALLBACK */ } } else diff --git a/Release_Notes.html b/Release_Notes.html index 9744d73..31e63f7 100644 --- a/Release_Notes.html +++ b/Release_Notes.html @@ -60,8 +60,56 @@ Page : STM32Cube USB Wiki Page

Update History

-
+
+ + +

Main Changes

@@ -105,10 +153,12 @@ CustomHID, MSC & Video Classes:
+
- -
- -
- -
- -
- + +

Main Changes

@@ -331,10 +389,12 @@ check to Class handler
+
- + +

Main Changes

@@ -416,10 +476,12 @@ user code
+
- + +

Main Changes

@@ -456,10 +518,12 @@ compatibility with device library version below v2.6.0
+
- + +

Main Changes

@@ -539,10 +603,12 @@ transfer: USBD_CUSTOM_HID_ReceivePacket()
+
- + +

Main Changes

@@ -578,10 +644,12 @@ device state only if the current state is USBD_STATE_SUSPENDED
+
- + +

Main Changes

@@ -598,10 +666,12 @@ NVIC_SystemReset() prototype change
+
- + +

Main Changes

@@ -633,10 +703,12 @@ Break on USBD_Template_Setup API
+
- + +

Main Changes

@@ -683,10 +755,12 @@ machine
+
- + +

Main Changes

@@ -705,10 +779,12 @@ by #include “usbd_cdc.h”
+
- + +

Main Changes

@@ -744,10 +820,12 @@ DMA half transfer
+
- + +

Main Changes

@@ -802,10 +880,12 @@ CDC_SET_CONTROL_LINE_STATE and similar no-data setup requests.
+
- + +

Main Changes

@@ -836,10 +916,12 @@ update
+
- + +

Main Changes

@@ -891,10 +973,12 @@ USBD_HID_CLASS)
+
- + +

Main Changes

@@ -938,10 +1022,12 @@ usbd_customhid_if_template.c/h
+
- + +

Main Changes

Major update based on STM32Cube specification.

@@ -961,10 +1047,12 @@ compatible.

This version has to be used only with STM32Cube based development

+
- + +

Main Changes

@@ -998,15 +1086,18 @@ to take into account error during Control OUT stage
+
- + +

Main Changes

First official version for STM32F105/7xx and STM32F2xx devices

+