diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Inc/usbd_audio.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Inc/usbd_audio.h
index a082d19046..177c84a411 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Inc/usbd_audio.h
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Inc/usbd_audio.h
@@ -71,6 +71,7 @@ extern "C" {
#define USB_DEVICE_CLASS_AUDIO 0x01U
#define AUDIO_SUBCLASS_AUDIOCONTROL 0x01U
#define AUDIO_SUBCLASS_AUDIOSTREAMING 0x02U
+#define AUDIO_SUBCLASS_MIDISTREAMING 0x03U
#define AUDIO_PROTOCOL_UNDEFINED 0x00U
#define AUDIO_STREAMING_GENERAL 0x01U
#define AUDIO_STREAMING_FORMAT_TYPE 0x02U
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Src/usbd_audio.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Src/usbd_audio.c
index 05153b1647..fa4c826d15 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Src/usbd_audio.c
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Src/usbd_audio.c
@@ -162,6 +162,9 @@ USBD_ClassTypeDef USBD_AUDIO =
USBD_AUDIO_GetCfgDesc,
USBD_AUDIO_GetDeviceQualifierDesc,
#endif /* USE_USBD_COMPOSITE */
+#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
+ NULL,
+#endif /* USBD_SUPPORT_USER_STRING_DESC */
};
#ifndef USE_USBD_COMPOSITE
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Inc/usbd_ccid.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Inc/usbd_ccid.h
index d3b96a536a..e8d12beffc 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Inc/usbd_ccid.h
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Inc/usbd_ccid.h
@@ -60,10 +60,12 @@ extern "C" {
#define CCID_CMD_FS_BINTERVAL 0x10U
#endif /* CCID_CMD_FS_BINTERVAL */
+#ifndef CCID_CMD_PACKET_SIZE
+#define CCID_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */
+#endif /* CCID_CMD_PACKET_SIZE */
#define CCID_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */
#define CCID_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */
-#define CCID_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */
#define USB_CCID_CONFIG_DESC_SIZ 93U
#define CCID_DATA_HS_IN_PACKET_SIZE CCID_DATA_HS_MAX_PACKET_SIZE
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid.c
index 4c77b135d7..c9285922f1 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid.c
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid.c
@@ -129,6 +129,9 @@ USBD_ClassTypeDef USBD_CCID =
USBD_CCID_GetOtherSpeedCfgDesc,
USBD_CCID_GetDeviceQualifierDescriptor,
#endif /* USE_USBD_COMPOSITE */
+#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
+ NULL,
+#endif /* USBD_SUPPORT_USER_STRING_DESC */
};
#ifndef USE_USBD_COMPOSITE
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid_cmd.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid_cmd.c
index b91cb1f157..c65ac5aa54 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid_cmd.c
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid_cmd.c
@@ -42,10 +42,10 @@ static void CCID_UpdateCommandStatus(USBD_HandleTypeDef *pdev, uint8_t cmd_stat
uint8_t PC_to_RDR_IccPowerOn(USBD_HandleTypeDef *pdev)
{
/* Apply the ICC VCC
- Fills the Response buffer with ICC ATR
- This Command is returned with RDR_to_PC_DataBlock();
- */
- USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
+ * Fills the Response buffer with ICC ATR
+ * This Command is returned with RDR_to_PC_DataBlock();
+ */
+ USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint8_t voltage;
uint8_t sc_voltage = 0U;
uint8_t index;
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h
index aeac6bf588..42ff56c6bc 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h
@@ -58,10 +58,13 @@ extern "C" {
#define CDC_FS_BINTERVAL 0x10U
#endif /* CDC_FS_BINTERVAL */
+#ifndef CDC_CMD_PACKET_SIZE
+#define CDC_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */
+#endif /* CDC_CMD_PACKET_SIZE */
+
/* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */
#define CDC_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */
#define CDC_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */
-#define CDC_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */
#define USB_CDC_CONFIG_DESC_SIZ 67U
#define CDC_DATA_HS_IN_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c
index ad8da254e0..050d996674 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c
@@ -161,6 +161,9 @@ USBD_ClassTypeDef USBD_CDC =
USBD_CDC_GetOtherSpeedCfgDesc,
USBD_CDC_GetDeviceQualifierDescriptor,
#endif /* USE_USBD_COMPOSITE */
+#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
+ NULL,
+#endif /* USBD_SUPPORT_USER_STRING_DESC */
};
#ifndef USE_USBD_COMPOSITE
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Inc/usbd_cdc_ecm.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Inc/usbd_cdc_ecm.h
index a69c4fd2e6..1284d4d608 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Inc/usbd_cdc_ecm.h
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Inc/usbd_cdc_ecm.h
@@ -68,6 +68,10 @@ extern "C" {
#define CDC_ECM_FS_BINTERVAL 0x10U
#endif /* CDC_ECM_FS_BINTERVAL */
+#ifndef CDC_ECM_CMD_PACKET_SIZE
+#define CDC_ECM_CMD_PACKET_SIZE 16U /* Control Endpoint Packet size */
+#endif /* CDC_ECM_CMD_PACKET_SIZE */
+
#ifndef USBD_SUPPORT_USER_STRING_DESC
#define USBD_SUPPORT_USER_STRING_DESC 1U
#endif /* USBD_SUPPORT_USER_STRING_DESC */
@@ -75,7 +79,6 @@ extern "C" {
/* CDC_ECM Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */
#define CDC_ECM_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */
#define CDC_ECM_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */
-#define CDC_ECM_CMD_PACKET_SIZE 16U /* Control Endpoint Packet size */
#define CDC_ECM_CONFIG_DESC_SIZ 79U
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h
index 50d18c42dd..3a262c3b80 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h
@@ -66,12 +66,14 @@ extern "C" {
#define CDC_RNDIS_FS_BINTERVAL 0x10U
#endif /* CDC_RNDIS_FS_BINTERVAL */
+#ifndef CDC_RNDIS_CMD_PACKET_SIZE
+#define CDC_RNDIS_CMD_PACKET_SIZE 16U /* Control Endpoint Packet size */
+#endif /* CDC_RNDIS_CMD_PACKET_SIZE */
/* CDC_RNDIS Endpoints parameters: you can fine tune these values
depending on the needed baudrates and performance. */
#define CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */
#define CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */
-#define CDC_RNDIS_CMD_PACKET_SIZE 16U /* Control Endpoint Packet size */
#define CDC_RNDIS_CONFIG_DESC_SIZ 75U
#define CDC_RNDIS_DATA_HS_IN_PACKET_SIZE CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c
index f04f2c222e..af56ca5ae0 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c
@@ -1414,7 +1414,7 @@ static uint8_t USBD_CDC_RNDIS_ProcessQueryMsg(USBD_HandleTypeDef *pdev,
case OID_GEN_VENDOR_DESCRIPTION:
QueryResponse->InfoBufLength = (strlen(USBD_CDC_RNDIS_VENDOR_DESC) + 1U);
(void)USBD_memcpy(QueryResponse->InfoBuf, USBD_CDC_RNDIS_VENDOR_DESC,
- strlen(USBD_CDC_RNDIS_VENDOR_DESC));
+ strlen(USBD_CDC_RNDIS_VENDOR_DESC) + 1U);
QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS;
break;
@@ -1452,7 +1452,7 @@ static uint8_t USBD_CDC_RNDIS_ProcessQueryMsg(USBD_HandleTypeDef *pdev,
case OID_GEN_CURRENT_PACKET_FILTER:
QueryResponse->InfoBufLength = sizeof(uint32_t);
- QueryResponse->InfoBuf[0] = 0xFFFFFFU; /* USBD_CDC_RNDIS_DEVICE.packetFilter; */
+ QueryResponse->InfoBuf[0] = 0xFFFFFFU; /* USBD_CDC_RNDIS_DEVICE.packetFilter */
QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS;
break;
@@ -1641,6 +1641,13 @@ static uint8_t USBD_CDC_RNDIS_ProcessPacketMsg(USBD_HandleTypeDef *pdev,
/* Use temporary storage variables to comply with MISRA-C 2012 rule of (+) operand allowed types */
tmp1 = (uint32_t)PacketMsg;
tmp2 = (uint32_t)(PacketMsg->DataOffset);
+
+ /* Validate DataOffset and DataLength against the received MsgLength */
+ if ((tmp2 + CDC_RNDIS_PCKTMSG_DATAOFFSET_OFFSET + PacketMsg->DataLength) > PacketMsg->MsgLength)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
hcdc->RxBuffer = (uint8_t *)(tmp1 + tmp2 + CDC_RNDIS_PCKTMSG_DATAOFFSET_OFFSET);
hcdc->RxLength = PacketMsg->DataLength;
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CompositeBuilder/Src/usbd_composite_builder.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CompositeBuilder/Src/usbd_composite_builder.c
index e14c5cd817..dc4bae9454 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CompositeBuilder/Src/usbd_composite_builder.c
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CompositeBuilder/Src/usbd_composite_builder.c
@@ -511,11 +511,11 @@ uint8_t USBD_CMPSIT_AddToConfDesc(USBD_HandleTypeDef *pdev)
/* Set IN endpoint slot */
iEp = pdev->tclasslist[pdev->classId].EpAdd[0];
- USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_INTR, pdev->tclasslist[pdev->classId].CurrPcktSze);
+ USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_INTR,CUSTOM_HID_EPIN_SIZE);
/* Set OUT endpoint slot */
iEp = pdev->tclasslist[pdev->classId].EpAdd[1];
- USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_INTR, pdev->tclasslist[pdev->classId].CurrPcktSze);
+ USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_INTR, CUSTOM_HID_EPOUT_SIZE);
/* Configure and Append the Descriptor */
USBD_CMPSIT_CUSTOMHIDDesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL);
@@ -1393,7 +1393,12 @@ static void USBD_CMPSIT_CUSTOMHIDDesc(USBD_HandleTypeDef *pdev, uint32_t pConf,
pDesc->bCountryCode = 0x00U;
pDesc->bNumDescriptors = 0x01U;
pDesc->bDescriptorType = 0x22U;
+#ifdef USBD_CUSTOMHID_REPORT_DESC_SIZE_ENABLED
+ pDesc->wItemLength = ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->wReportDescLen;
+#else
pDesc->wItemLength = USBD_CUSTOM_HID_REPORT_DESC_SIZE;
+#endif /* USBD_CUSTOMHID_REPORT_DESC_SIZE_ENABLED */
+
*Sze += (uint32_t)sizeof(USBD_DescTypeDef);
/* Descriptor of Custom HID endpoints */
@@ -1403,7 +1408,7 @@ static void USBD_CMPSIT_CUSTOMHIDDesc(USBD_HandleTypeDef *pdev, uint32_t pConf,
/* Append Endpoint descriptor to Configuration descriptor */
__USBD_CMPSIT_SET_EP(pdev->tclasslist[pdev->classId].Eps[1].add, \
- USBD_EP_TYPE_INTR, CUSTOM_HID_EPIN_SIZE, CUSTOM_HID_HS_BINTERVAL, CUSTOM_HID_FS_BINTERVAL);
+ USBD_EP_TYPE_INTR, CUSTOM_HID_EPOUT_SIZE, CUSTOM_HID_HS_BINTERVAL, CUSTOM_HID_FS_BINTERVAL);
/* Update Config Descriptor and IAD descriptor */
((USBD_ConfigDescTypeDef *)pConf)->bNumInterfaces += 1U;
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Inc/usbd_customhid.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Inc/usbd_customhid.h
index 2f4c6344f3..f81a708a07 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Inc/usbd_customhid.h
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Inc/usbd_customhid.h
@@ -103,9 +103,16 @@ typedef enum
typedef struct _USBD_CUSTOM_HID_Itf
{
uint8_t *pReport;
+#ifdef USBD_CUSTOMHID_REPORT_DESC_SIZE_ENABLED
+ uint16_t wReportDescLen;
+#endif /* USBD_CUSTOMHID_REPORT_DESC_SIZE_ENABLED */
int8_t (* Init)(void);
int8_t (* DeInit)(void);
+#ifdef USBD_CUSTOMHID_REPORT_BUFFER_EVENT_ENABLED
+ int8_t (* OutEvent)(uint8_t *report_buffer);
+#else
int8_t (* OutEvent)(uint8_t event_idx, uint8_t state);
+#endif /* USBD_CUSTOMHID_REPORT_BUFFER_EVENT_ENABLED */
#ifdef USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED
int8_t (* CtrlReqComplete)(uint8_t request, uint16_t wLength);
#endif /* USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid.c
index c64ba9913b..7ca8464db3 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid.c
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid.c
@@ -128,6 +128,9 @@ USBD_ClassTypeDef USBD_CUSTOM_HID =
USBD_CUSTOM_HID_GetOtherSpeedCfgDesc,
USBD_CUSTOM_HID_GetDeviceQualifierDesc,
#endif /* USE_USBD_COMPOSITE */
+#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
+ NULL,
+#endif /* USBD_SUPPORT_USER_STRING_DESC */
};
#ifndef USE_USBD_COMPOSITE
@@ -284,6 +287,11 @@ static uint8_t USBD_CUSTOM_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
pdev->ep_in[CUSTOMHIDInEpAdd & 0xFU].is_used = 1U;
+ if (USBD_CUSTOMHID_OUTREPORT_BUF_SIZE < CUSTOM_HID_EPOUT_SIZE)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
/* Open EP OUT */
(void)USBD_LL_OpenEP(pdev, CUSTOMHIDOutEpAdd, USBD_EP_TYPE_INTR,
CUSTOM_HID_EPOUT_SIZE);
@@ -397,9 +405,17 @@ static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev,
}
#endif /* USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */
#ifndef USBD_CUSTOMHID_EP0_OUT_PREPARE_RECEIVE_DISABLED
+
+ if (req->wLength > USBD_CUSTOMHID_OUTREPORT_BUF_SIZE)
+ {
+ /* Stall EP0 */
+ USBD_CtlError(pdev, req);
+ return USBD_FAIL;
+ }
+
hhid->IsReportAvailable = 1U;
- (void)USBD_CtlPrepareRx(pdev, hhid->Report_buf,
- MIN(req->wLength, USBD_CUSTOMHID_OUTREPORT_BUF_SIZE));
+
+ (void)USBD_CtlPrepareRx(pdev, hhid->Report_buf, req->wLength);
#endif /* USBD_CUSTOMHID_EP0_OUT_PREPARE_RECEIVE_DISABLED */
break;
#ifdef USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED
@@ -675,6 +691,11 @@ static uint8_t USBD_CUSTOM_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
/* Ensure that the FIFO is empty before a new transfer, this condition could
be caused by a new transfer before the end of the previous transfer */
+ if (pdev->pClassDataCmsit[pdev->classId] == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
((USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId])->state = CUSTOM_HID_IDLE;
return (uint8_t)USBD_OK;
@@ -701,8 +722,13 @@ static uint8_t USBD_CUSTOM_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
/* USB data will be immediately processed, this allow next USB traffic being
NAKed till the end of the application processing */
+
+#ifdef USBD_CUSTOMHID_REPORT_BUFFER_EVENT_ENABLED
+ ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->OutEvent(hhid->Report_buf);
+#else
((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->OutEvent(hhid->Report_buf[0],
hhid->Report_buf[1]);
+#endif /* USBD_CUSTOMHID_REPORT_BUFFER_EVENT_ENABLED */
return (uint8_t)USBD_OK;
}
@@ -755,8 +781,12 @@ static uint8_t USBD_CUSTOM_HID_EP0_RxReady(USBD_HandleTypeDef *pdev)
if (hhid->IsReportAvailable == 1U)
{
+#ifdef USBD_CUSTOMHID_REPORT_BUFFER_EVENT_ENABLED
+ ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->OutEvent(hhid->Report_buf);
+#else
((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->OutEvent(hhid->Report_buf[0],
hhid->Report_buf[1]);
+#endif /* USBD_CUSTOMHID_REPORT_BUFFER_EVENT_ENABLED */
hhid->IsReportAvailable = 0U;
}
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid_if_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid_if_template.c
index 85881bdc5b..e5a7e73f11 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid_if_template.c
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid_if_template.c
@@ -32,7 +32,11 @@ EndBSPDependencies */
static int8_t TEMPLATE_CUSTOM_HID_Init(void);
static int8_t TEMPLATE_CUSTOM_HID_DeInit(void);
+#ifdef USBD_CUSTOMHID_REPORT_BUFFER_EVENT_ENABLED
+static int8_t TEMPLATE_CUSTOM_HID_OutEvent(uint8_t *report_buffer);
+#else
static int8_t TEMPLATE_CUSTOM_HID_OutEvent(uint8_t event_idx, uint8_t state);
+#endif /* USBD_CUSTOMHID_REPORT_BUFFER_EVENT_ENABLED */
#ifdef USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED
static int8_t TEMPLATE_CUSTOM_HID_CtrlReqComplete(uint8_t request, uint16_t wLength);
@@ -49,6 +53,9 @@ __ALIGN_BEGIN static uint8_t TEMPLATE_CUSTOM_HID_ReportDesc[USBD_CUSTOM_HID_REPO
USBD_CUSTOM_HID_ItfTypeDef USBD_CustomHID_template_fops =
{
TEMPLATE_CUSTOM_HID_ReportDesc,
+#ifdef USBD_CUSTOMHID_REPORT_DESC_SIZE_ENABLED
+ USBD_CUSTOM_HID_REPORT_DESC_SIZE,
+#endif /* USBD_CUSTOMHID_REPORT_DESC_SIZE_ENABLED */
TEMPLATE_CUSTOM_HID_Init,
TEMPLATE_CUSTOM_HID_DeInit,
TEMPLATE_CUSTOM_HID_OutEvent,
@@ -95,10 +102,17 @@ static int8_t TEMPLATE_CUSTOM_HID_DeInit(void)
* @param state: event state
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
+
+#ifdef USBD_CUSTOMHID_REPORT_BUFFER_EVENT_ENABLED
+static int8_t TEMPLATE_CUSTOM_HID_OutEvent(uint8_t *report_buffer)
+{
+ UNUSED(report_buffer);
+#else
static int8_t TEMPLATE_CUSTOM_HID_OutEvent(uint8_t event_idx, uint8_t state)
{
UNUSED(event_idx);
UNUSED(state);
+#endif /* USBD_CUSTOMHID_REPORT_BUFFER_EVENT_ENABLED */
/* Start next USB packet transfer once data processing is completed */
if (USBD_CUSTOM_HID_ReceivePacket(&USBD_Device) != (uint8_t)USBD_OK)
@@ -151,7 +165,7 @@ static int8_t TEMPLATE_CUSTOM_HID_CtrlReqComplete(uint8_t request, uint16_t wLen
static uint8_t *TEMPLATE_CUSTOM_HID_GetReport(uint16_t *ReportLength)
{
UNUSED(ReportLength);
- uint8_t *pbuff;
+ uint8_t *pbuff = NULL;
return (pbuff);
}
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Src/usbd_dfu.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Src/usbd_dfu.c
index 67ba12c48e..4f0bac1e52 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Src/usbd_dfu.c
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Src/usbd_dfu.c
@@ -940,6 +940,12 @@ static void DFU_Download(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
if ((hdfu->dev_state == DFU_STATE_DNLOAD_IDLE) || (hdfu->dev_state == DFU_STATE_IDLE))
{
#if (USBD_DFU_VENDOR_CHECK_ENABLED == 1U)
+ /* Fill the buffer to be checked with the address stored in data buffer */
+ hdfu->buffer.d8[1] = (uint8_t)(hdfu->data_ptr & 0xFFU);
+ hdfu->buffer.d8[2] = (uint8_t)((hdfu->data_ptr & 0xFF00U) >> 8U);
+ hdfu->buffer.d8[3] = (uint8_t)((hdfu->data_ptr & 0xFF0000U) >> 16U);
+ hdfu->buffer.d8[4] = (uint8_t)((hdfu->data_ptr & 0xFF000000U) >> 24U);
+
if (DfuInterface->VendorCheck(hdfu->buffer.d8, IS_DFU_SETADDRESSPOINTER, &VendorStatus) != USBD_OK)
{
/* Update the state machine */
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c
index fdf757810a..f226b0bba7 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c
@@ -128,6 +128,9 @@ USBD_ClassTypeDef USBD_HID =
USBD_HID_GetOtherSpeedCfgDesc,
USBD_HID_GetDeviceQualifierDesc,
#endif /* USE_USBD_COMPOSITE */
+#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
+ NULL,
+#endif /* USBD_SUPPORT_USER_STRING_DESC */
};
#ifndef USE_USBD_COMPOSITE
@@ -615,6 +618,11 @@ static uint8_t USBD_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
UNUSED(epnum);
/* Ensure that the FIFO is empty before a new transfer, this condition could
be caused by a new transfer before the end of the previous transfer */
+ if (pdev->pClassDataCmsit[pdev->classId] == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
((USBD_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId])->state = USBD_HID_IDLE;
return (uint8_t)USBD_OK;
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc.h
index e55fef48d9..1f1ad10f48 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc.h
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc.h
@@ -62,6 +62,10 @@ extern "C" {
#define MSC_EPOUT_ADDR 0x01U
#endif /* MSC_EPOUT_ADDR */
+#ifndef MSC_BOT_MAX_LUN
+#define MSC_BOT_MAX_LUN 0x2U
+#endif /* MSC_BOT_MAX_LUN */
+
/**
* @}
*/
@@ -82,6 +86,13 @@ typedef struct _USBD_STORAGE
} USBD_StorageTypeDef;
+typedef struct
+{
+ uint16_t size;
+ uint32_t nbr;
+ uint32_t addr;
+ uint32_t len;
+} USBD_MSC_BOT_LUN_TypeDef;
typedef struct
{
@@ -99,11 +110,7 @@ typedef struct
uint8_t scsi_sense_tail;
uint8_t scsi_medium_state;
- uint16_t scsi_blk_size;
- uint32_t scsi_blk_nbr;
-
- uint32_t scsi_blk_addr;
- uint32_t scsi_blk_len;
+ USBD_MSC_BOT_LUN_TypeDef scsi_blk[MSC_BOT_MAX_LUN + 1U];
} USBD_MSC_BOT_HandleTypeDef;
/* Structure for MSC process */
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_data.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_data.h
index c96d2b84ed..a321c91fb3 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_data.h
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_data.h
@@ -44,6 +44,8 @@ extern "C" {
#define LENGTH_INQUIRY_PAGE00 0x06U
#define LENGTH_INQUIRY_PAGE80 0x08U
#define LENGTH_FORMAT_CAPACITIES 0x14U
+#define DIAGNOSTIC_DATA_LEN 0x08U
+#define LOG_PAGE_DATA_LEN 0x10U
/**
* @}
@@ -74,6 +76,8 @@ extern uint8_t MSC_Page00_Inquiry_Data[LENGTH_INQUIRY_PAGE00];
extern uint8_t MSC_Page80_Inquiry_Data[LENGTH_INQUIRY_PAGE80];
extern uint8_t MSC_Mode_Sense6_data[MODE_SENSE6_LEN];
extern uint8_t MSC_Mode_Sense10_data[MODE_SENSE10_LEN];
+extern uint8_t MSC_Diagnostic_Data[DIAGNOSTIC_DATA_LEN];
+extern uint8_t MSC_Log_Page_Data[LOG_PAGE_DATA_LEN];
/**
* @}
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_scsi.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_scsi.h
index 477affbb48..6000c2b5bd 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_scsi.h
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_scsi.h
@@ -70,8 +70,10 @@ extern "C" {
#define SCSI_VERIFY12 0xAFU
#define SCSI_VERIFY16 0x8FU
-#define SCSI_SEND_DIAGNOSTIC 0x1DU
#define SCSI_READ_FORMAT_CAPACITIES 0x23U
+#define SCSI_RECEIVE_DIAGNOSTIC_RESULTS 0x1CU
+#define SCSI_SEND_DIAGNOSTIC 0x1DU
+#define SCSI_REPORT_LUNS 0xA0U
#define NO_SENSE 0U
#define RECOVERED_ERROR 1U
@@ -88,9 +90,8 @@ extern "C" {
#define VOLUME_OVERFLOW 13U
#define MISCOMPARE 14U
-
#define INVALID_CDB 0x20U
-#define INVALID_FIELED_IN_COMMAND 0x24U
+#define INVALID_FIELD_IN_COMMAND 0x24U
#define PARAMETER_LIST_LENGTH_ERROR 0x1AU
#define INVALID_FIELD_IN_PARAMETER_LIST 0x26U
#define ADDRESS_OUT_OF_RANGE 0x21U
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc.c
index 7f2152f38b..eafb8bafa4 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc.c
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc.c
@@ -125,6 +125,9 @@ USBD_ClassTypeDef USBD_MSC =
USBD_MSC_GetOtherSpeedCfgDesc,
USBD_MSC_GetDeviceQualifierDescriptor,
#endif /* USE_USBD_COMPOSITE */
+#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
+ NULL,
+#endif /* USBD_SUPPORT_USER_STRING_DESC */
};
/* USB Mass storage device Configuration Descriptor */
@@ -309,6 +312,7 @@ uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
USBD_StatusTypeDef ret = USBD_OK;
+ uint32_t max_lun;
uint16_t status_info = 0U;
#ifdef USE_USBD_COMPOSITE
@@ -332,7 +336,8 @@ uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
if ((req->wValue == 0U) && (req->wLength == 1U) &&
((req->bmRequest & 0x80U) == 0x80U))
{
- hmsc->max_lun = (uint32_t)((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetMaxLun();
+ max_lun = (uint32_t)((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetMaxLun();
+ hmsc->max_lun = (max_lun > MSC_BOT_MAX_LUN) ? MSC_BOT_MAX_LUN : max_lun;
(void)USBD_CtlSendData(pdev, (uint8_t *)&hmsc->max_lun, 1U);
}
else
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_bot.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_bot.c
index c51b01361f..4dab4c8edc 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_bot.c
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_bot.c
@@ -273,7 +273,7 @@ static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef *pdev)
if ((USBD_LL_GetRxDataSize(pdev, MSCOutEpAdd) != USBD_BOT_CBW_LENGTH) ||
(hmsc->cbw.dSignature != USBD_BOT_CBW_SIGNATURE) ||
- (hmsc->cbw.bLUN > 1U) || (hmsc->cbw.bCBLength < 1U) ||
+ (hmsc->cbw.bLUN > hmsc->max_lun) || (hmsc->cbw.bCBLength < 1U) ||
(hmsc->cbw.bCBLength > 16U))
{
SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
@@ -346,7 +346,7 @@ static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t
length = MIN(hmsc->cbw.dDataLength, len);
- hmsc->csw.dDataResidue -= len;
+ hmsc->csw.dDataResidue -= length;
hmsc->csw.bStatus = USBD_CSW_CMD_PASSED;
hmsc->bot_state = USBD_BOT_SEND_DATA;
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_data.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_data.c
index 1641c20fec..b7acde32b5 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_data.c
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_data.c
@@ -81,7 +81,7 @@ uint8_t MSC_Page80_Inquiry_Data[LENGTH_INQUIRY_PAGE80] =
0x00,
0x80,
0x00,
- LENGTH_INQUIRY_PAGE80,
+ (LENGTH_INQUIRY_PAGE80 - 4U),
0x20, /* Put Product Serial number */
0x20,
0x20,
@@ -118,6 +118,19 @@ uint8_t MSC_Mode_Sense10_data[MODE_SENSE10_LEN] =
0x00, /* BLOCK DESCRIPTOR LENGTH MSB. */
0x00 /* BLOCK DESCRIPTOR LENGTH LSB. */
};
+
+uint8_t MSC_Diagnostic_Data[DIAGNOSTIC_DATA_LEN] =
+{
+ 0x00, /* Byte 0: ADDITIONAL LENGTH (MSB) */
+ 0x00, /* Byte 1: ADDITIONAL LENGTH (LSB) */
+ 0x00, /* Byte 2: FRU CODE (most probable) */
+ 0x00, /* Byte 3: FRU CODE */
+ 0x00, /* Byte 4: FRU CODE */
+ 0x00, /* Byte 5: FRU CODE (least probable) */
+ 0x00, /* Byte 6: ERROR CODE (MSB) */
+ 0x00, /* Byte 7: ERROR CODE (LSB) */
+};
+
/**
* @}
*/
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c
index 3c0fe2f487..3ca57a5bea 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c
@@ -85,6 +85,10 @@ static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
static int8_t SCSI_RequestSense(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
static int8_t SCSI_AllowPreventRemovable(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_ProcessModeSelect(USBD_HandleTypeDef *pdev, uint8_t lun,
+ uint32_t param_list_length);
+static int8_t SCSI_ModeSelect6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_ModeSelect10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
static int8_t SCSI_ModeSense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
@@ -92,6 +96,8 @@ static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param
static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
static int8_t SCSI_Read12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_ReportLuns(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_ReceiveDiagnosticResults(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun,
uint32_t blk_offset, uint32_t blk_nbr);
@@ -150,6 +156,14 @@ int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd)
ret = SCSI_AllowPreventRemovable(pdev, lun, cmd);
break;
+ case SCSI_MODE_SELECT6:
+ ret = SCSI_ModeSelect6(pdev, lun, cmd);
+ break;
+
+ case SCSI_MODE_SELECT10:
+ ret = SCSI_ModeSelect10(pdev, lun, cmd);
+ break;
+
case SCSI_MODE_SENSE6:
ret = SCSI_ModeSense6(pdev, lun, cmd);
break;
@@ -190,9 +204,17 @@ int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd)
ret = SCSI_Verify10(pdev, lun, cmd);
break;
+ case SCSI_REPORT_LUNS:
+ ret = SCSI_ReportLuns(pdev, lun, cmd);
+ break;
+
+ case SCSI_RECEIVE_DIAGNOSTIC_RESULTS:
+ ret = SCSI_ReceiveDiagnosticResults(pdev, lun, cmd);
+ break;
+
default:
SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_CDB);
- hmsc->bot_status = USBD_BOT_STATUS_ERROR;
+ hmsc->bot_state = USBD_BOT_NO_DATA;
ret = -1;
break;
}
@@ -283,7 +305,7 @@ static int8_t SCSI_Inquiry(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param
else /* Request Not supported */
{
SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST,
- INVALID_FIELED_IN_COMMAND);
+ INVALID_FIELD_IN_COMMAND);
return -1;
}
@@ -319,14 +341,17 @@ static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
UNUSED(params);
int8_t ret;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
+ USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk;
if (hmsc == NULL)
{
return -1;
}
- ret = ((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetCapacity(lun, &hmsc->scsi_blk_nbr,
- &hmsc->scsi_blk_size);
+ p_scsi_blk = &hmsc->scsi_blk[lun];
+
+ ret = ((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetCapacity(lun, &p_scsi_blk->nbr,
+ &p_scsi_blk->size);
if ((ret != 0) || (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED))
{
@@ -334,20 +359,19 @@ static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
return -1;
}
- hmsc->bot_data[0] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 24);
- hmsc->bot_data[1] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 16);
- hmsc->bot_data[2] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 8);
- hmsc->bot_data[3] = (uint8_t)(hmsc->scsi_blk_nbr - 1U);
+ hmsc->bot_data[0] = (uint8_t)((p_scsi_blk->nbr - 1U) >> 24);
+ hmsc->bot_data[1] = (uint8_t)((p_scsi_blk->nbr - 1U) >> 16);
+ hmsc->bot_data[2] = (uint8_t)((p_scsi_blk->nbr - 1U) >> 8);
+ hmsc->bot_data[3] = (uint8_t)(p_scsi_blk->nbr - 1U);
- hmsc->bot_data[4] = (uint8_t)(hmsc->scsi_blk_size >> 24);
- hmsc->bot_data[5] = (uint8_t)(hmsc->scsi_blk_size >> 16);
- hmsc->bot_data[6] = (uint8_t)(hmsc->scsi_blk_size >> 8);
- hmsc->bot_data[7] = (uint8_t)(hmsc->scsi_blk_size);
+ hmsc->bot_data[4] = (uint8_t)(p_scsi_blk->size >> 24);
+ hmsc->bot_data[5] = (uint8_t)(p_scsi_blk->size >> 16);
+ hmsc->bot_data[6] = (uint8_t)(p_scsi_blk->size >> 8);
+ hmsc->bot_data[7] = (uint8_t)(p_scsi_blk->size);
hmsc->bot_data_length = 8U;
return 0;
-
}
@@ -360,18 +384,21 @@ static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
*/
static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
- UNUSED(params);
uint32_t idx;
+ uint32_t alloc_len;
int8_t ret;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
+ USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk;
if (hmsc == NULL)
{
return -1;
}
- ret = ((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetCapacity(lun, &hmsc->scsi_blk_nbr,
- &hmsc->scsi_blk_size);
+ p_scsi_blk = &hmsc->scsi_blk[lun];
+
+ ret = ((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetCapacity(lun, &p_scsi_blk->nbr,
+ &p_scsi_blk->size);
if ((ret != 0) || (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED))
{
@@ -379,30 +406,29 @@ static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
return -1;
}
- hmsc->bot_data_length = ((uint32_t)params[10] << 24) |
- ((uint32_t)params[11] << 16) |
- ((uint32_t)params[12] << 8) |
- (uint32_t)params[13];
-
- for (idx = 0U; idx < hmsc->bot_data_length; idx++)
+ /* READ CAPACITY(16) response is 32 bytes per SBC-3 */
+ for (idx = 0U; idx < 32U; idx++)
{
hmsc->bot_data[idx] = 0U;
}
- hmsc->bot_data[4] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 24);
- hmsc->bot_data[5] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 16);
- hmsc->bot_data[6] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 8);
- hmsc->bot_data[7] = (uint8_t)(hmsc->scsi_blk_nbr - 1U);
+ hmsc->bot_data[4] = (uint8_t)((p_scsi_blk->nbr - 1U) >> 24);
+ hmsc->bot_data[5] = (uint8_t)((p_scsi_blk->nbr - 1U) >> 16);
+ hmsc->bot_data[6] = (uint8_t)((p_scsi_blk->nbr - 1U) >> 8);
+ hmsc->bot_data[7] = (uint8_t)(p_scsi_blk->nbr - 1U);
+
+ hmsc->bot_data[8] = (uint8_t)(p_scsi_blk->size >> 24);
+ hmsc->bot_data[9] = (uint8_t)(p_scsi_blk->size >> 16);
+ hmsc->bot_data[10] = (uint8_t)(p_scsi_blk->size >> 8);
+ hmsc->bot_data[11] = (uint8_t)(p_scsi_blk->size);
- hmsc->bot_data[8] = (uint8_t)(hmsc->scsi_blk_size >> 24);
- hmsc->bot_data[9] = (uint8_t)(hmsc->scsi_blk_size >> 16);
- hmsc->bot_data[10] = (uint8_t)(hmsc->scsi_blk_size >> 8);
- hmsc->bot_data[11] = (uint8_t)(hmsc->scsi_blk_size);
+ /* Clamp transfer length to actual response size (32 bytes) */
+ alloc_len = ((uint32_t)params[10] << 24) |
+ ((uint32_t)params[11] << 16) |
+ ((uint32_t)params[12] << 8) |
+ (uint32_t)params[13];
- hmsc->bot_data_length = ((uint32_t)params[10] << 24) |
- ((uint32_t)params[11] << 16) |
- ((uint32_t)params[12] << 8) |
- (uint32_t)params[13];
+ hmsc->bot_data_length = MIN(alloc_len, 32U);
return 0;
}
@@ -417,8 +443,8 @@ static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
*/
static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
- UNUSED(params);
uint16_t blk_size;
+ uint16_t alloc_len;
uint32_t blk_nbr;
uint16_t i;
int8_t ret;
@@ -453,12 +479,116 @@ static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uin
hmsc->bot_data[10] = (uint8_t)(blk_size >> 8);
hmsc->bot_data[11] = (uint8_t)(blk_size);
- hmsc->bot_data_length = 12U;
+ alloc_len = ((uint16_t)params[7] << 8) | (uint16_t)params[8];
+ hmsc->bot_data_length = MIN(alloc_len, READ_FORMAT_CAPACITY_DATA_LEN);
+
+ return 0;
+}
+
+
+/**
+ * @brief SCSI_ProcessModeSelect
+ * Drain MODE SELECT parameter data without applying mode pages
+ * @param lun: Logical unit number
+ * @param param_list_length: Mode parameter list length from the CDB
+ * @retval status
+ */
+static int8_t SCSI_ProcessModeSelect(USBD_HandleTypeDef *pdev, uint8_t lun,
+ uint32_t param_list_length)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
+ USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk;
+ uint32_t packet_length;
+ uint32_t rx_length;
+
+ UNUSED(param_list_length);
+
+ if (hmsc == NULL)
+ {
+ return -1;
+ }
+
+ p_scsi_blk = &hmsc->scsi_blk[lun];
+
+#ifdef USE_USBD_COMPOSITE
+ /* Get the Endpoints addresses allocated for this class instance */
+ MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
+#endif /* USE_USBD_COMPOSITE */
+
+ if (hmsc->bot_state == USBD_BOT_IDLE)
+ {
+ if ((hmsc->cbw.bmFlags & 0x80U) == 0x80U)
+ {
+ hmsc->bot_state = USBD_BOT_NO_DATA;
+ hmsc->bot_data_length = 0U;
+ return 0;
+ }
+
+ if (hmsc->cbw.dDataLength == 0U)
+ {
+ hmsc->bot_data_length = 0U;
+ return 0;
+ }
+
+ p_scsi_blk->len = hmsc->cbw.dDataLength;
+ hmsc->bot_state = USBD_BOT_DATA_OUT;
+
+ packet_length = MIN(p_scsi_blk->len, MSC_MEDIA_PACKET);
+ (void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, hmsc->bot_data, packet_length);
+
+ return 0;
+ }
+
+ rx_length = USBD_LL_GetRxDataSize(pdev, MSCOutEpAdd);
+
+ if (rx_length >= p_scsi_blk->len)
+ {
+ hmsc->csw.dDataResidue -= p_scsi_blk->len;
+ p_scsi_blk->len = 0U;
+ MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_PASSED);
+ }
+ else
+ {
+ p_scsi_blk->len -= rx_length;
+ hmsc->csw.dDataResidue -= rx_length;
+ packet_length = MIN(p_scsi_blk->len, MSC_MEDIA_PACKET);
+ (void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, hmsc->bot_data, packet_length);
+ }
return 0;
}
+/**
+ * @brief SCSI_ModeSelect6
+ * Process Mode Select6 command
+ * @param lun: Logical unit number
+ * @param params: Command parameters
+ * @retval status
+ */
+static int8_t SCSI_ModeSelect6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
+{
+ return SCSI_ProcessModeSelect(pdev, lun, params[4]);
+}
+
+
+/**
+ * @brief SCSI_ModeSelect10
+ * Process Mode Select10 command
+ * @param lun: Logical unit number
+ * @param params: Command parameters
+ * @retval status
+ */
+static int8_t SCSI_ModeSelect10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
+{
+ uint32_t param_list_length;
+
+ param_list_length = ((uint32_t)params[7] << 8) | (uint32_t)params[8];
+
+ return SCSI_ProcessModeSelect(pdev, lun, param_list_length);
+}
+
+
/**
* @brief SCSI_ModeSense6
* Process Mode Sense6 command
@@ -468,7 +598,6 @@ static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uin
*/
static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
- UNUSED(lun);
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint16_t len = MODE_SENSE6_LEN;
@@ -480,7 +609,11 @@ static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *pa
/* Check If media is write-protected */
if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsWriteProtected(lun) != 0)
{
- MSC_Mode_Sense6_data[2] |= 0x80U;
+ MSC_Mode_Sense6_data[2] |= (0x1U << 7); /* Set the WP (write protection) bit */
+ }
+ else
+ {
+ MSC_Mode_Sense6_data[2] &= ~(0x1U << 7); /* Clear the WP (write protection) bit */
}
if (params[4] <= len)
@@ -503,9 +636,9 @@ static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *pa
*/
static int8_t SCSI_ModeSense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
- UNUSED(lun);
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint16_t len = MODE_SENSE10_LEN;
+ uint16_t alloc_len;
if (hmsc == NULL)
{
@@ -515,12 +648,19 @@ static int8_t SCSI_ModeSense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *p
/* Check If media is write-protected */
if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsWriteProtected(lun) != 0)
{
- MSC_Mode_Sense10_data[3] |= 0x80U;
+ MSC_Mode_Sense10_data[3] |= (0x1U << 7); /* Set the WP (write protection) bit */
+ }
+ else
+ {
+ MSC_Mode_Sense10_data[3] &= ~(0x1U << 7); /* Clear the WP (write protection) bit */
}
- if (params[8] <= len)
+ /* Allocation length is a 16-bit field: CDB bytes 7-8 */
+ alloc_len = ((uint16_t)params[7] << 8) | (uint16_t)params[8];
+
+ if (alloc_len < len)
{
- len = params[8];
+ len = alloc_len;
}
(void)SCSI_UpdateBotData(hmsc, MSC_Mode_Sense10_data, len);
@@ -613,6 +753,16 @@ void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey, uint8_t
{
hmsc->scsi_sense_tail = 0U;
}
+
+ if (hmsc->scsi_sense_tail == hmsc->scsi_sense_head)
+ {
+ hmsc->scsi_sense_head++;
+
+ if (hmsc->scsi_sense_head == SENSE_LIST_DEEPTH)
+ {
+ hmsc->scsi_sense_head = 0U;
+ }
+ }
}
@@ -635,7 +785,7 @@ static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
if ((hmsc->scsi_medium_state == SCSI_MEDIUM_LOCKED) && ((params[4] & 0x3U) == 2U))
{
- SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
+ SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_FIELD_IN_COMMAND);
return -1;
}
@@ -704,12 +854,15 @@ static int8_t SCSI_AllowPreventRemovable(USBD_HandleTypeDef *pdev, uint8_t lun,
static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
+ USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk;
if (hmsc == NULL)
{
return -1;
}
+ p_scsi_blk = &hmsc->scsi_blk[lun];
+
if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */
{
/* case 10 : Ho <> Di */
@@ -732,21 +885,20 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params
return -1;
}
- hmsc->scsi_blk_addr = ((uint32_t)params[2] << 24) |
- ((uint32_t)params[3] << 16) |
- ((uint32_t)params[4] << 8) |
- (uint32_t)params[5];
+ p_scsi_blk->addr = ((uint32_t)params[2] << 24) |
+ ((uint32_t)params[3] << 16) |
+ ((uint32_t)params[4] << 8) |
+ (uint32_t)params[5];
- hmsc->scsi_blk_len = ((uint32_t)params[7] << 8) | (uint32_t)params[8];
+ p_scsi_blk->len = ((uint32_t)params[7] << 8) | (uint32_t)params[8];
- if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr,
- hmsc->scsi_blk_len) < 0)
+ if (SCSI_CheckAddressRange(pdev, lun, p_scsi_blk->addr, p_scsi_blk->len) < 0)
{
return -1; /* error */
}
/* cases 4,5 : Hi <> Dn */
- if (hmsc->cbw.dDataLength != (hmsc->scsi_blk_len * hmsc->scsi_blk_size))
+ if (hmsc->cbw.dDataLength != (p_scsi_blk->len * p_scsi_blk->size))
{
SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
return -1;
@@ -770,12 +922,15 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params
static int8_t SCSI_Read12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
+ USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk;
if (hmsc == NULL)
{
return -1;
}
+ p_scsi_blk = &hmsc->scsi_blk[lun];
+
if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */
{
/* case 10 : Ho <> Di */
@@ -797,24 +952,23 @@ static int8_t SCSI_Read12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params
return -1;
}
- hmsc->scsi_blk_addr = ((uint32_t)params[2] << 24) |
- ((uint32_t)params[3] << 16) |
- ((uint32_t)params[4] << 8) |
- (uint32_t)params[5];
+ p_scsi_blk->addr = ((uint32_t)params[2] << 24) |
+ ((uint32_t)params[3] << 16) |
+ ((uint32_t)params[4] << 8) |
+ (uint32_t)params[5];
- hmsc->scsi_blk_len = ((uint32_t)params[6] << 24) |
- ((uint32_t)params[7] << 16) |
- ((uint32_t)params[8] << 8) |
- (uint32_t)params[9];
+ p_scsi_blk->len = ((uint32_t)params[6] << 24) |
+ ((uint32_t)params[7] << 16) |
+ ((uint32_t)params[8] << 8) |
+ (uint32_t)params[9];
- if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr,
- hmsc->scsi_blk_len) < 0)
+ if (SCSI_CheckAddressRange(pdev, lun, p_scsi_blk->addr, p_scsi_blk->len) < 0)
{
return -1; /* error */
}
/* cases 4,5 : Hi <> Dn */
- if (hmsc->cbw.dDataLength != (hmsc->scsi_blk_len * hmsc->scsi_blk_size))
+ if (hmsc->cbw.dDataLength != (p_scsi_blk->len * p_scsi_blk->size))
{
SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
return -1;
@@ -838,6 +992,7 @@ static int8_t SCSI_Read12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params
static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
+ USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk;
uint32_t len;
if (hmsc == NULL)
@@ -845,6 +1000,8 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param
return -1;
}
+ p_scsi_blk = &hmsc->scsi_blk[lun];
+
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
@@ -865,10 +1022,18 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param
return -1;
}
+ if (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED)
+ {
+ SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+ hmsc->bot_state = USBD_BOT_NO_DATA;
+ return -1;
+ }
+
/* Check whether Media is ready */
if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsReady(lun) != 0)
{
SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+ hmsc->bot_state = USBD_BOT_NO_DATA;
return -1;
}
@@ -876,25 +1041,25 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param
if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsWriteProtected(lun) != 0)
{
SCSI_SenseCode(pdev, lun, NOT_READY, WRITE_PROTECTED);
+ hmsc->bot_state = USBD_BOT_NO_DATA;
return -1;
}
- hmsc->scsi_blk_addr = ((uint32_t)params[2] << 24) |
- ((uint32_t)params[3] << 16) |
- ((uint32_t)params[4] << 8) |
- (uint32_t)params[5];
+ p_scsi_blk->addr = ((uint32_t)params[2] << 24) |
+ ((uint32_t)params[3] << 16) |
+ ((uint32_t)params[4] << 8) |
+ (uint32_t)params[5];
- hmsc->scsi_blk_len = ((uint32_t)params[7] << 8) |
- (uint32_t)params[8];
+ p_scsi_blk->len = ((uint32_t)params[7] << 8) |
+ (uint32_t)params[8];
/* check if LBA address is in the right range */
- if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr,
- hmsc->scsi_blk_len) < 0)
+ if (SCSI_CheckAddressRange(pdev, lun, p_scsi_blk->addr, p_scsi_blk->len) < 0)
{
return -1; /* error */
}
- len = hmsc->scsi_blk_len * hmsc->scsi_blk_size;
+ len = p_scsi_blk->len * p_scsi_blk->size;
/* cases 3,11,13 : Hn,Ho <> D0 */
if (hmsc->cbw.dDataLength != len)
@@ -928,12 +1093,16 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param
static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
+ USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk;
uint32_t len;
if (hmsc == NULL)
{
return -1;
}
+
+ p_scsi_blk = &hmsc->scsi_blk[lun];
+
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
@@ -954,6 +1123,13 @@ static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param
return -1;
}
+ if (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED)
+ {
+ SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+ hmsc->bot_state = USBD_BOT_NO_DATA;
+ return -1;
+ }
+
/* Check whether Media is ready */
if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsReady(lun) != 0)
{
@@ -970,24 +1146,23 @@ static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param
return -1;
}
- hmsc->scsi_blk_addr = ((uint32_t)params[2] << 24) |
- ((uint32_t)params[3] << 16) |
- ((uint32_t)params[4] << 8) |
- (uint32_t)params[5];
+ p_scsi_blk->addr = ((uint32_t)params[2] << 24) |
+ ((uint32_t)params[3] << 16) |
+ ((uint32_t)params[4] << 8) |
+ (uint32_t)params[5];
- hmsc->scsi_blk_len = ((uint32_t)params[6] << 24) |
- ((uint32_t)params[7] << 16) |
- ((uint32_t)params[8] << 8) |
- (uint32_t)params[9];
+ p_scsi_blk->len = ((uint32_t)params[6] << 24) |
+ ((uint32_t)params[7] << 16) |
+ ((uint32_t)params[8] << 8) |
+ (uint32_t)params[9];
/* check if LBA address is in the right range */
- if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr,
- hmsc->scsi_blk_len) < 0)
+ if (SCSI_CheckAddressRange(pdev, lun, p_scsi_blk->addr, p_scsi_blk->len) < 0)
{
return -1; /* error */
}
- len = hmsc->scsi_blk_len * hmsc->scsi_blk_size;
+ len = p_scsi_blk->len * p_scsi_blk->size;
/* cases 3,11,13 : Hn,Ho <> D0 */
if (hmsc->cbw.dDataLength != len)
@@ -1021,19 +1196,51 @@ static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param
static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
+ uint32_t blk_offset;
+ uint32_t blk_nbr;
if (hmsc == NULL)
{
return -1;
}
+ if (hmsc->cbw.dDataLength != 0U)
+ {
+ SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_CDB);
+ hmsc->bot_state = USBD_BOT_NO_DATA;
+ return -1;
+ }
+
+ if (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED)
+ {
+ SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+ hmsc->bot_state = USBD_BOT_NO_DATA;
+ return -1;
+ }
+
+ if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsReady(lun) != 0)
+ {
+ SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+ hmsc->bot_state = USBD_BOT_NO_DATA;
+ return -1;
+ }
+
if ((params[1] & 0x02U) == 0x02U)
{
- SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
+ SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_FIELD_IN_COMMAND);
+ hmsc->bot_state = USBD_BOT_NO_DATA;
return -1; /* Error, Verify Mode Not supported*/
}
- if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, hmsc->scsi_blk_len) < 0)
+ /* Decode LBA and verification length from current CDB */
+ blk_offset = ((uint32_t)params[2] << 24) |
+ ((uint32_t)params[3] << 16) |
+ ((uint32_t)params[4] << 8) |
+ (uint32_t)params[5];
+
+ blk_nbr = ((uint32_t)params[7] << 8) | (uint32_t)params[8];
+
+ if (SCSI_CheckAddressRange(pdev, lun, blk_offset, blk_nbr) < 0)
{
return -1; /* error */
}
@@ -1043,6 +1250,111 @@ static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *para
return 0;
}
+/**
+ * @brief SCSI_ReportLuns12
+ * Process ReportLuns command
+ * @retval status
+ */
+static int8_t SCSI_ReportLuns(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc;
+ uint32_t report_idx;
+ uint32_t lun_list_length;
+ uint32_t total_length;
+ uint32_t alloc_len;
+ uint8_t lun_idx;
+
+ UNUSED(lun);
+
+ /* Define the report LUNs buffer: 8-byte header + 8 bytes per LUN entry */
+ static uint8_t lun_report[8U + (8U * (MSC_BOT_MAX_LUN + 1U))];
+
+ hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
+
+ if (hmsc == NULL)
+ {
+ return -1;
+ }
+
+ /* Initialize the report LUNs buffer */
+ for (report_idx = 0U; report_idx < sizeof(lun_report); report_idx++)
+ {
+ lun_report[report_idx] = 0U;
+ }
+
+ /* Set the LUN list length in the first 4 bytes */
+ lun_list_length = 8U * (hmsc->max_lun + 1U);
+ lun_report[0] = (uint8_t)(lun_list_length >> 24);
+ lun_report[1] = (uint8_t)(lun_list_length >> 16);
+ lun_report[2] = (uint8_t)(lun_list_length >> 8);
+ lun_report[3] = (uint8_t)(lun_list_length & 0xFFU);
+
+ /* Update the LUN list */
+ for (lun_idx = 0U; lun_idx <= hmsc->max_lun; lun_idx++)
+ {
+ /* LUN identifier is placed at the second byte of each 8-byte entry */
+ lun_report[(8U * (lun_idx + 1U)) + 1U] = lun_idx;
+ }
+
+ /* Calculate the total length of the report LUNs buffer */
+ total_length = lun_list_length + 8U;
+
+ /* Clamp to allocation length from CDB bytes 6-9 */
+ alloc_len = ((uint32_t)params[6] << 24) |
+ ((uint32_t)params[7] << 16) |
+ ((uint32_t)params[8] << 8) |
+ (uint32_t)params[9];
+
+ if (alloc_len < total_length)
+ {
+ total_length = alloc_len;
+ }
+
+ /* Update the BOT data with the report LUNs buffer */
+ (void)SCSI_UpdateBotData(hmsc, lun_report, (uint16_t)total_length);
+
+ return 0;
+}
+
+/**
+ * @brief SCSI_ReceiveDiagnosticResults
+ * Process SCSI_Receive Diagnostic Results command
+ * @param lun: Logical unit number
+ * @param params: Command parameters
+ * @retval status
+ */
+static int8_t SCSI_ReceiveDiagnosticResults(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
+{
+ UNUSED(lun);
+ USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
+ uint16_t allocation_length;
+
+ if (hmsc == NULL)
+ {
+ return -1;
+ }
+
+ /* Extract the allocation length from the CDB */
+ allocation_length = (((uint16_t)params[3] << 8) | (uint16_t)params[4]);
+
+ if (allocation_length == 0U)
+ {
+ hmsc->bot_data_length = 0U;
+ return 0;
+ }
+
+ /* Ensure the allocation length does not exceed the diagnostic data length */
+ if (allocation_length > DIAGNOSTIC_DATA_LEN)
+ {
+ allocation_length = DIAGNOSTIC_DATA_LEN;
+ }
+
+ /* Send the diagnostic data to the host */
+ (void)SCSI_UpdateBotData(hmsc, MSC_Diagnostic_Data, allocation_length);
+
+ return 0;
+}
+
/**
* @brief SCSI_CheckAddressRange
* Check address range
@@ -1055,13 +1367,21 @@ static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun,
uint32_t blk_offset, uint32_t blk_nbr)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
+ USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk;
if (hmsc == NULL)
{
return -1;
}
- if ((blk_offset + blk_nbr) > hmsc->scsi_blk_nbr)
+ p_scsi_blk = &hmsc->scsi_blk[lun];
+
+ /* Refresh cached capacity for this LUN so multi-LUN configs
+ with different sizes use the correct block count. */
+ (void)((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetCapacity(lun, &p_scsi_blk->nbr,
+ &p_scsi_blk->size);
+
+ if ((blk_nbr > p_scsi_blk->nbr) || (blk_offset > (p_scsi_blk->nbr - blk_nbr)))
{
SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, ADDRESS_OUT_OF_RANGE);
return -1;
@@ -1079,6 +1399,7 @@ static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun,
static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
+ USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk;
uint32_t len;
if (hmsc == NULL)
@@ -1086,7 +1407,9 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun)
return -1;
}
- len = hmsc->scsi_blk_len * hmsc->scsi_blk_size;
+ p_scsi_blk = &hmsc->scsi_blk[lun];
+
+ len = p_scsi_blk->len * p_scsi_blk->size;
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
@@ -1096,8 +1419,8 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun)
len = MIN(len, MSC_MEDIA_PACKET);
if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->Read(lun, hmsc->bot_data,
- hmsc->scsi_blk_addr,
- (len / hmsc->scsi_blk_size)) < 0)
+ p_scsi_blk->addr,
+ (len / p_scsi_blk->size)) < 0)
{
SCSI_SenseCode(pdev, lun, HARDWARE_ERROR, UNRECOVERED_READ_ERROR);
return -1;
@@ -1105,13 +1428,13 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun)
(void)USBD_LL_Transmit(pdev, MSCInEpAdd, hmsc->bot_data, len);
- hmsc->scsi_blk_addr += (len / hmsc->scsi_blk_size);
- hmsc->scsi_blk_len -= (len / hmsc->scsi_blk_size);
+ p_scsi_blk->addr += (len / p_scsi_blk->size);
+ p_scsi_blk->len -= (len / p_scsi_blk->size);
/* case 6 : Hi = Di */
hmsc->csw.dDataResidue -= len;
- if (hmsc->scsi_blk_len == 0U)
+ if (p_scsi_blk->len == 0U)
{
hmsc->bot_state = USBD_BOT_LAST_DATA_IN;
}
@@ -1128,6 +1451,7 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun)
static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
+ USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk;
uint32_t len;
if (hmsc == NULL)
@@ -1135,7 +1459,9 @@ static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun)
return -1;
}
- len = hmsc->scsi_blk_len * hmsc->scsi_blk_size;
+ p_scsi_blk = &hmsc->scsi_blk[lun];
+
+ len = p_scsi_blk->len * p_scsi_blk->size;
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
@@ -1144,27 +1470,26 @@ static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun)
len = MIN(len, MSC_MEDIA_PACKET);
- if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->Write(lun, hmsc->bot_data,
- hmsc->scsi_blk_addr,
- (len / hmsc->scsi_blk_size)) < 0)
+ if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->Write(lun, hmsc->bot_data, p_scsi_blk->addr,
+ (len / p_scsi_blk->size)) < 0)
{
SCSI_SenseCode(pdev, lun, HARDWARE_ERROR, WRITE_FAULT);
return -1;
}
- hmsc->scsi_blk_addr += (len / hmsc->scsi_blk_size);
- hmsc->scsi_blk_len -= (len / hmsc->scsi_blk_size);
+ p_scsi_blk->addr += (len / p_scsi_blk->size);
+ p_scsi_blk->len -= (len / p_scsi_blk->size);
/* case 12 : Ho = Do */
hmsc->csw.dDataResidue -= len;
- if (hmsc->scsi_blk_len == 0U)
+ if (p_scsi_blk->len == 0U)
{
MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_PASSED);
}
else
{
- len = MIN((hmsc->scsi_blk_len * hmsc->scsi_blk_size), MSC_MEDIA_PACKET);
+ len = MIN((p_scsi_blk->len * p_scsi_blk->size), MSC_MEDIA_PACKET);
/* Prepare EP to Receive next packet */
(void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, hmsc->bot_data, len);
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp.h
index df2644fdd0..77807f3442 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp.h
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp.h
@@ -67,9 +67,12 @@ extern "C" {
#define MTP_FS_BINTERVAL 0x10U
#endif /* MTP_FS_BINTERVAL */
+#ifndef MTP_CMD_PACKET_SIZE
+#define MTP_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */
+#endif /* MTP_CMD_PACKET_SIZE */
+
#define MTP_DATA_MAX_HS_PACKET_SIZE 512U
#define MTP_DATA_MAX_FS_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */
-#define MTP_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */
#define MTP_MEDIA_PACKET 512U
#define MTP_CONT_HEADER_SIZE 12U
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp_opt.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp_opt.h
index 4dee923d6b..55de393359 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp_opt.h
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp_opt.h
@@ -283,7 +283,7 @@ extern "C" {
* Appendix C. Device Properties
*/
-/* MTP device properties code*/
+/* MTP device properties code */
#define MTP_DEV_PROP_UNDEFINED 0x5000U
#define MTP_DEV_PROP_BATTERY_LEVEL 0x5001U
#define MTP_DEV_PROP_FUNCTIONAL_MODE 0x5002U
@@ -336,7 +336,7 @@ extern "C" {
#define MTP_CONT_TYPE_EVENT 4U
#ifndef MTP_STORAGE_ID
-#define MTP_STORAGE_ID 0x00010001U /* SD card is inserted*/
+#define MTP_STORAGE_ID 0x00010001U /* SD card is inserted */
#endif /* MTP_STORAGE_ID */
#define MTP_NBR_STORAGE_ID 1U
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp_storage.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp_storage.h
index ba01901e75..f77670c786 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp_storage.h
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp_storage.h
@@ -53,15 +53,16 @@ extern "C" {
typedef enum
{
- DATA_TYPE = 0x00,
- REP_TYPE = 0x01,
+ DATA_TYPE = 0x00U,
+ REP_TYPE = 0x01U,
} MTP_CONTAINER_TYPE;
typedef enum
{
- READ_FIRST_DATA = 0x00,
- READ_REST_OF_DATA = 0x01,
+ READ_FIRST_DATA = 0x00U,
+ READ_REST_OF_DATA = 0x01U,
+ READ_SEND_ZLP_DATA = 0x02U
} MTP_READ_DATA_STATUS;
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp.c
index b0950e8eaa..adf8e0aeb0 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp.c
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp.c
@@ -128,6 +128,9 @@ USBD_ClassTypeDef USBD_MTP =
USBD_MTP_GetOtherSpeedCfgDesc,
USBD_MTP_GetDeviceQualifierDescriptor,
#endif /* USE_USBD_COMPOSITE */
+#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
+ NULL,
+#endif /* USBD_SUPPORT_USER_STRING_DESC */
};
#ifndef USE_USBD_COMPOSITE
@@ -484,7 +487,7 @@ static uint8_t USBD_MTP_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
/* prepare to receive next operation */
len = MIN(hmtp->MaxPcktLen, pdev->request.wLength);
- (void)USBD_LL_PrepareReceive(pdev, MTPInEpAdd, (uint8_t *)&hmtp->rx_buff, len);
+ (void)USBD_LL_PrepareReceive(pdev, MTPOutEpAdd, (uint8_t *)&hmtp->rx_buff, len);
break;
case MTP_PHASE_IDLE :
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp_opt.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp_opt.c
index 9a49717bb7..df154aebec 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp_opt.c
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp_opt.c
@@ -23,7 +23,7 @@
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
-static uint8_t ObjInfo_buff[255];
+static uint8_t ObjInfo_buff[576];
static uint32_t objhandle;
static uint16_t obj_format;
static uint32_t storage_id;
@@ -385,7 +385,6 @@ void USBD_MTP_OPT_SendObject(USBD_HandleTypeDef *pdev, uint8_t *buff, uint32_t
{
USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId];
- static uint32_t tmp = 0U;
switch (hmtp->RECEIVE_DATA_STATUS)
{
@@ -410,8 +409,7 @@ void USBD_MTP_OPT_SendObject(USBD_HandleTypeDef *pdev, uint8_t *buff, uint32_t
{
hmtp->RECEIVE_DATA_STATUS = RECEIVE_REST_OF_DATA;
}
- tmp = (uint32_t)buff;
- hmtpif->WriteData(len, (uint8_t *)(tmp + 12U));
+ hmtpif->WriteData(len, (buff + 12U));
break;
case RECEIVE_REST_OF_DATA:
@@ -474,21 +472,26 @@ void USBD_MTP_OPT_SendObjectInfo(USBD_HandleTypeDef *pdev, uint8_t *buff, uint3
tmp = buff;
(void)USBD_memcpy(ObjInfo_buff, tmp + 12U,
- (uint16_t)(hmtp->MaxPcktLen - MTP_CONT_HEADER_SIZE));
+ (uint16_t)MIN(hmtp->MaxPcktLen - MTP_CONT_HEADER_SIZE,
+ sizeof(ObjInfo_buff)));
hmtp->RECEIVE_DATA_STATUS = RECEIVE_REST_OF_DATA;
break;
case RECEIVE_REST_OF_DATA:
-
- (void)USBD_memcpy(ObjInfo_buff + len, buff, hmtp->MaxPcktLen);
-
+ if (len < (uint32_t)sizeof(ObjInfo_buff))
+ {
+ (void)USBD_memcpy(ObjInfo_buff + len, buff,
+ (uint16_t)MIN(hmtp->MaxPcktLen,
+ sizeof(ObjInfo_buff) - len));
+ }
break;
case SEND_RESPONSE:
(void)USBD_memcpy((uint8_t *)&ObjectInfo, ObjInfo_buff, dataLength);
(void)USBD_memcpy((uint8_t *)&ObjectInfo.Filename, (ObjInfo_buff + dataLength),
- ((uint32_t)(ObjectInfo.Filename_len) * 2U));
+ MIN((uint32_t)(ObjectInfo.Filename_len) * 2U,
+ (uint32_t)(sizeof(ObjInfo_buff) - dataLength)));
obj_format = ObjectInfo.ObjectFormat;
@@ -537,50 +540,31 @@ static void MTP_Get_PayloadContent(USBD_HandleTypeDef *pdev)
{
USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId];
- uint8_t *buffer = hmtp->GenericContainer.data;
- uint32_t i;
+ uint8_t *buffer;
uint32_t n_idx;
switch (hmtp->OperationsContainer.code)
{
case MTP_OP_GET_DEVICE_INFO:
(void)MTP_Get_DeviceInfo();
- (void)USBD_memcpy(buffer, (const uint8_t *)&MTP_DeviceInfo, sizeof(MTP_DeviceInfo));
-
- for (i = 0U; i < sizeof(MTP_StorageIDS); i++)
- {
- hmtp->GenericContainer.data[i] = buffer[i];
- }
+ (void)USBD_memcpy(hmtp->GenericContainer.data, (const uint8_t *)&MTP_DeviceInfo,
+ MIN(sizeof(MTP_DeviceInfo), MTP_MEDIA_PACKET));
break;
case MTP_OP_GET_STORAGE_IDS:
(void)MTP_Get_StorageIDS();
- (void)USBD_memcpy(buffer, (const uint8_t *)&MTP_StorageIDS, sizeof(MTP_StorageIDS));
-
- for (i = 0U; i < sizeof(MTP_StorageIDS); i++)
- {
- hmtp->GenericContainer.data[i] = buffer[i];
- }
+ (void)USBD_memcpy(hmtp->GenericContainer.data, (const uint8_t *)&MTP_StorageIDS, sizeof(MTP_StorageIDS));
break;
case MTP_OP_GET_STORAGE_INFO:
(void)MTP_Get_StorageInfo(pdev);
- (void)USBD_memcpy(buffer, (const uint8_t *)&MTP_StorageInfo, sizeof(MTP_StorageInfo));
-
- for (i = 0U; i < sizeof(MTP_StorageInfo); i++)
- {
- hmtp->GenericContainer.data[i] = buffer[i];
- }
+ (void)USBD_memcpy(hmtp->GenericContainer.data, (const uint8_t *)&MTP_StorageInfo, sizeof(MTP_StorageInfo));
break;
case MTP_OP_GET_OBJECT_HANDLES:
(void)MTP_Get_ObjectHandle(pdev);
- (void)USBD_memcpy(buffer, (const uint8_t *)&MTP_ObjectHandle, hmtp->ResponseLength);
-
- for (i = 0U; i < hmtp->ResponseLength; i++)
- {
- hmtp->GenericContainer.data[i] = buffer[i];
- }
+ (void)USBD_memcpy(hmtp->GenericContainer.data, (const uint8_t *)&MTP_ObjectHandle,
+ MIN(hmtp->ResponseLength, MTP_MEDIA_PACKET));
break;
case MTP_OP_GET_OBJECT_INFO:
@@ -589,12 +573,7 @@ static void MTP_Get_PayloadContent(USBD_HandleTypeDef *pdev)
case MTP_OP_GET_OBJECT_PROPS_SUPPORTED:
(void)MTP_Get_ObjectPropSupp();
- (void)USBD_memcpy(buffer, (const uint8_t *)&MTP_ObjectPropSupp, sizeof(MTP_ObjectPropSupp));
-
- for (i = 0U; i < sizeof(MTP_ObjectPropSupp); i++)
- {
- hmtp->GenericContainer.data[i] = buffer[i];
- }
+ (void)USBD_memcpy(hmtp->GenericContainer.data, (const uint8_t *)&MTP_ObjectPropSupp, sizeof(MTP_ObjectPropSupp));
break;
case MTP_OP_GET_OBJECT_PROP_DESC:
@@ -604,12 +583,7 @@ static void MTP_Get_PayloadContent(USBD_HandleTypeDef *pdev)
case MTP_OP_GET_OBJECT_PROP_REFERENCES:
MTP_Ref.ref_len = 0U;
- (void)USBD_memcpy(buffer, (const uint8_t *)&MTP_Ref.ref_len, sizeof(MTP_Ref.ref_len));
-
- for (i = 0U; i < sizeof(MTP_Ref.ref_len); i++)
- {
- hmtp->GenericContainer.data[i] = buffer[i];
- }
+ (void)USBD_memcpy(hmtp->GenericContainer.data, (const uint8_t *)&MTP_Ref.ref_len, sizeof(MTP_Ref.ref_len));
break;
case MTP_OP_GET_OBJECT_PROPLIST:
@@ -618,20 +592,14 @@ static void MTP_Get_PayloadContent(USBD_HandleTypeDef *pdev)
case MTP_OP_GET_OBJECT_PROP_VALUE:
buffer = MTP_Get_ObjectPropValue(pdev);
- for (i = 0U; i < hmtp->ResponseLength; i++)
- {
- hmtp->GenericContainer.data[i] = buffer[i];
- }
-
+ (void)USBD_memcpy(hmtp->GenericContainer.data, (const uint8_t *)buffer,
+ MIN(hmtp->ResponseLength, MTP_MEDIA_PACKET));
break;
case MTP_OP_GET_DEVICE_PROP_DESC:
(void)MTP_Get_DevicePropDesc();
- (void)USBD_memcpy(buffer, (const uint8_t *)&MTP_DevicePropDesc, sizeof(MTP_DevicePropDesc));
- for (i = 0U; i < sizeof(MTP_DevicePropDesc); i++)
- {
- hmtp->GenericContainer.data[i] = buffer[i];
- }
+ (void)USBD_memcpy(hmtp->GenericContainer.data, (const uint8_t *)&MTP_DevicePropDesc,
+ MIN(sizeof(MTP_DevicePropDesc), MTP_MEDIA_PACKET));
break;
case MTP_OP_SEND_OBJECT_INFO:
@@ -837,7 +805,7 @@ static void MTP_Get_ObjectPropDesc(USBD_HandleTypeDef *pdev)
case MTP_OB_PROP_PARENT_OBJECT :
MTP_ObjectPropDesc.ObjectPropertyCode = (uint16_t)(hmtp->OperationsContainer.Param1);
- MTP_ObjectPropDesc.DataType = MTP_DATATYPE_STR;
+ MTP_ObjectPropDesc.DataType = MTP_DATATYPE_UINT32;
MTP_ObjectPropDesc.GetSet = MTP_PROP_GET;
MTP_ObjectPropDesc.DefValue = 0U;
MTP_ObjectPropDesc.GroupCode = 0U;
@@ -919,9 +887,12 @@ static uint8_t *MTP_Get_ObjectPropValue(USBD_HandleTypeDef *pdev)
case MTP_OB_PROP_OBJ_FILE_NAME:
MTP_FileName.FileName_len = hmtpif->GetObjectName_len(hmtp->OperationsContainer.Param1);
hmtpif->GetObjectName(hmtp->OperationsContainer.Param1, MTP_FileName.FileName_len, (uint16_t *)buf);
- (void)USBD_memcpy(MTP_FileName.FileName, (uint16_t *)buf, ((uint32_t)MTP_FileName.FileName_len * 2U) + 1U);
+ (void)USBD_memcpy(MTP_FileName.FileName, (uint16_t *)buf,
+ MIN(((uint32_t)MTP_FileName.FileName_len * 2U) + 1U,
+ sizeof(MTP_FileName.FileName)));
- hmtp->ResponseLength = ((uint32_t)MTP_FileName.FileName_len * 2U) + 1U;
+ hmtp->ResponseLength = MIN(((uint32_t)MTP_FileName.FileName_len * 2U) + 1U,
+ sizeof(MTP_FileName.FileName));
break;
case MTP_OB_PROP_PARENT_OBJECT :
@@ -951,8 +922,8 @@ static uint8_t *MTP_Get_ObjectPropValue(USBD_HandleTypeDef *pdev)
*/
static void MTP_Get_ObjectPropList(USBD_HandleTypeDef *pdev)
{
- USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
- USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId];
+ USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
+ USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId];
uint16_t filename[255];
uint32_t storageid = MTP_STORAGE_ID;
uint32_t default_val = 0U;
@@ -960,6 +931,7 @@ static void MTP_Get_ObjectPropList(USBD_HandleTypeDef *pdev)
uint16_t format;
uint64_t objsize;
uint32_t parent_proval;
+ uint8_t mtp_pers_uniq_obj_id[16] = {0};
MTP_PropertiesList.MTP_Properties_len = SUPP_OBJ_PROP_LEN;
hmtp->ResponseLength = 4U; /* size of MTP_PropertiesList.MTP_Properties_len */
@@ -991,7 +963,9 @@ static void MTP_Get_ObjectPropList(USBD_HandleTypeDef *pdev)
/* MTP_FileName.FileName_len value shall be set before USBD_MTP_FS_GetObjectName */
MTP_FileName.FileName_len = hmtpif->GetObjectName_len(hmtp->OperationsContainer.Param1);
hmtpif->GetObjectName(hmtp->OperationsContainer.Param1, MTP_FileName.FileName_len, filename);
- (void)USBD_memcpy(MTP_FileName.FileName, filename, ((uint32_t)MTP_FileName.FileName_len * 2U) + 1U);
+ (void)USBD_memcpy(MTP_FileName.FileName, filename,
+ MIN(((uint32_t)MTP_FileName.FileName_len * 2U) + 1U,
+ sizeof(MTP_FileName.FileName)));
MTP_PropertiesList.MTP_Properties[i].propval = (uint8_t *)&MTP_FileName;
break;
@@ -1015,14 +989,20 @@ static void MTP_Get_ObjectPropList(USBD_HandleTypeDef *pdev)
/* MTP_FileName.FileName_len value shall be set before USBD_MTP_FS_GetObjectName */
MTP_FileName.FileName_len = hmtpif->GetObjectName_len(hmtp->OperationsContainer.Param1);
hmtpif->GetObjectName(hmtp->OperationsContainer.Param1, MTP_FileName.FileName_len, filename);
- (void)USBD_memcpy(MTP_FileName.FileName, filename, ((uint32_t)MTP_FileName.FileName_len * 2U) + 1U);
+ (void)USBD_memcpy(MTP_FileName.FileName, filename,
+ MIN(((uint32_t)MTP_FileName.FileName_len * 2U) + 1U,
+ sizeof(MTP_FileName.FileName)));
MTP_PropertiesList.MTP_Properties[i].propval = (uint8_t *)&MTP_FileName;
break;
case MTP_OB_PROP_PERS_UNIQ_OBJ_IDEN :
+ /* Fill in the first 4 bytes with Param1 (Object ID) */
+ (void)USBD_memcpy(mtp_pers_uniq_obj_id, &hmtp->OperationsContainer.Param1,
+ sizeof(hmtp->OperationsContainer.Param1));
+
MTP_PropertiesList.MTP_Properties[i].PropertyCode = MTP_OB_PROP_PERS_UNIQ_OBJ_IDEN;
MTP_PropertiesList.MTP_Properties[i].Datatype = MTP_DATATYPE_UINT128;
- MTP_PropertiesList.MTP_Properties[i].propval = (uint8_t *)&hmtp->OperationsContainer.Param1;
+ MTP_PropertiesList.MTP_Properties[i].propval = (uint8_t *)mtp_pers_uniq_obj_id;
break;
case MTP_OB_PROP_PROTECTION_STATUS :
@@ -1099,7 +1079,9 @@ static void MTP_Get_ObjectInfo(USBD_HandleTypeDef *pdev)
/* we have to get this value before MTP_ObjectInfo.Filename */
MTP_ObjectInfo.Filename_len = hmtpif->GetObjectName_len(hmtp->OperationsContainer.Param1);
hmtpif->GetObjectName(hmtp->OperationsContainer.Param1, MTP_ObjectInfo.Filename_len, filename);
- (void)USBD_memcpy(MTP_ObjectInfo.Filename, filename, ((uint32_t)MTP_FileName.FileName_len * 2U) + 1U);
+ (void)USBD_memcpy(MTP_ObjectInfo.Filename, filename,
+ MIN(((uint32_t)MTP_ObjectInfo.Filename_len * 2U) + 1U,
+ sizeof(MTP_ObjectInfo.Filename)));
MTP_ObjectInfo.CaptureDate = 0U;
MTP_ObjectInfo.ModificationDate = 0U;
@@ -1128,42 +1110,55 @@ static void MTP_Get_StorageIDS(void)
static uint32_t MTP_build_data_propdesc(USBD_HandleTypeDef *pdev, MTP_ObjectPropDescTypeDef def)
{
USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
- uint8_t DefValue_size = (MTP_FileName.FileName_len * 2U) + 1U;
+ uint32_t DefValue_size;
uint32_t dataLength = offsetof(MTP_ObjectPropDescTypeDef, DefValue);
+ uint32_t totalLength;
- (void)USBD_memcpy(hmtp->GenericContainer.data, (const uint8_t *)&def, dataLength);
-
+ /* Determine DefValue size based on data type */
switch (def.DataType)
{
case MTP_DATATYPE_UINT16:
- (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, def.DefValue, sizeof(uint16_t));
- dataLength += sizeof(uint16_t);
+ DefValue_size = sizeof(uint16_t);
break;
case MTP_DATATYPE_UINT32:
- (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, def.DefValue, sizeof(uint32_t));
- dataLength += sizeof(uint32_t);
+ DefValue_size = sizeof(uint32_t);
break;
case MTP_DATATYPE_UINT64:
- (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, def.DefValue, sizeof(uint64_t));
- dataLength += sizeof(uint64_t);
+ DefValue_size = sizeof(uint64_t);
break;
case MTP_DATATYPE_STR:
- (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, def.DefValue, DefValue_size);
- dataLength += DefValue_size;
+ DefValue_size = ((uint32_t)MTP_FileName.FileName_len * 2U) + 1U;
break;
case MTP_DATATYPE_UINT128:
- (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, def.DefValue, (sizeof(uint64_t) * 2U));
- dataLength += (sizeof(uint64_t) * 2U);
+ DefValue_size = (sizeof(uint64_t) * 2U);
break;
default:
+ DefValue_size = 0U;
break;
}
+ /* Check if there is enough room in GenericContainer.data */
+ totalLength = dataLength + DefValue_size + sizeof(MTP_ObjectPropDesc.GroupCode)
+ + sizeof(MTP_ObjectPropDesc.FormFlag);
+
+ if (totalLength > MTP_MEDIA_PACKET)
+ {
+ return 0U;
+ }
+
+ (void)USBD_memcpy(hmtp->GenericContainer.data, (const uint8_t *)&def, dataLength);
+
+ if ((DefValue_size > 0U) && (def.DefValue != NULL))
+ {
+ (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, def.DefValue, DefValue_size);
+ dataLength += DefValue_size;
+ }
+
(void)USBD_memcpy(hmtp->GenericContainer.data + dataLength,
(const uint8_t *)&MTP_ObjectPropDesc.GroupCode, sizeof(MTP_ObjectPropDesc.GroupCode));
@@ -1187,57 +1182,59 @@ static uint32_t MTP_build_data_proplist(USBD_HandleTypeDef *pdev,
MTP_PropertiesListTypedef proplist, uint32_t idx)
{
USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
- uint8_t propval_size = (MTP_FileName.FileName_len * 2U) + 1U;
+ uint8_t *propval = proplist.MTP_Properties[idx].propval;
uint32_t dataLength;
+ uint32_t payloadSize;
dataLength = offsetof(MTP_PropertiesTypedef, propval);
- (void)USBD_memcpy(hmtp->GenericContainer.data + hmtp->ResponseLength,
- (const uint8_t *)&proplist.MTP_Properties[idx], dataLength);
-
- dataLength += hmtp->ResponseLength;
-
+ /* Determine the payload size based on data type */
switch (proplist.MTP_Properties[idx].Datatype)
{
case MTP_DATATYPE_UINT16:
- (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength,
- proplist.MTP_Properties[idx].propval, sizeof(uint16_t));
-
- dataLength += sizeof(uint16_t);
+ payloadSize = sizeof(uint16_t);
break;
case MTP_DATATYPE_UINT32:
- (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength,
- proplist.MTP_Properties[idx].propval, sizeof(uint32_t));
-
- dataLength += sizeof(uint32_t);
+ payloadSize = sizeof(uint32_t);
break;
case MTP_DATATYPE_STR:
- (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength,
- proplist.MTP_Properties[idx].propval, propval_size);
-
- dataLength += propval_size;
+ payloadSize = ((uint32_t)propval[0] * 2U) + 1U;
break;
case MTP_DATATYPE_UINT64:
- (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength,
- proplist.MTP_Properties[idx].propval, sizeof(uint64_t));
-
- dataLength += sizeof(uint64_t);
+ payloadSize = sizeof(uint64_t);
break;
case MTP_DATATYPE_UINT128:
- (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength,
- proplist.MTP_Properties[idx].propval, (sizeof(uint64_t) * 2U));
-
- dataLength += (sizeof(uint64_t) * 2U);
+ payloadSize = (sizeof(uint64_t) * 2U);
break;
default:
+ payloadSize = 0U;
break;
}
+ /* Check if there is enough room in GenericContainer.data for header + payload */
+ if ((hmtp->ResponseLength + dataLength + payloadSize) > MTP_MEDIA_PACKET)
+ {
+ return hmtp->ResponseLength;
+ }
+
+ (void)USBD_memcpy(hmtp->GenericContainer.data + hmtp->ResponseLength,
+ (const uint8_t *)&proplist.MTP_Properties[idx], dataLength);
+
+ dataLength += hmtp->ResponseLength;
+
+ if (payloadSize > 0U)
+ {
+ (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength,
+ proplist.MTP_Properties[idx].propval, payloadSize);
+
+ dataLength += payloadSize;
+ }
+
return dataLength;
}
@@ -1251,17 +1248,25 @@ static uint32_t MTP_build_data_ObjInfo(USBD_HandleTypeDef *pdev, MTP_ObjectInfoT
{
USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint32_t ObjInfo_len = offsetof(MTP_ObjectInfoTypeDef, Filename);
+ uint32_t fname_size;
(void)USBD_memcpy(hmtp->GenericContainer.data, (const uint8_t *)&objinfo, ObjInfo_len);
- (void)USBD_memcpy(hmtp->GenericContainer.data + ObjInfo_len,
- (const uint8_t *)&objinfo.Filename, objinfo.Filename_len * sizeof(uint16_t));
- ObjInfo_len = ObjInfo_len + (objinfo.Filename_len * sizeof(uint16_t));
+ fname_size = MIN((uint32_t)objinfo.Filename_len * sizeof(uint16_t),
+ (uint32_t)(MTP_MEDIA_PACKET - ObjInfo_len));
- (void)USBD_memcpy(hmtp->GenericContainer.data + ObjInfo_len,
- (const uint8_t *)&objinfo.CaptureDate, sizeof(objinfo.CaptureDate));
+ (void)USBD_memcpy(hmtp->GenericContainer.data + ObjInfo_len,
+ (const uint8_t *)&objinfo.Filename, fname_size);
- ObjInfo_len = ObjInfo_len + sizeof(objinfo.CaptureDate);
+ ObjInfo_len = ObjInfo_len + fname_size;
+
+ if ((ObjInfo_len + sizeof(objinfo.CaptureDate)) <= MTP_MEDIA_PACKET)
+ {
+ (void)USBD_memcpy(hmtp->GenericContainer.data + ObjInfo_len,
+ (const uint8_t *)&objinfo.CaptureDate, sizeof(objinfo.CaptureDate));
+
+ ObjInfo_len = ObjInfo_len + sizeof(objinfo.CaptureDate);
+ }
return ObjInfo_len;
}
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp_storage.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp_storage.c
index e09cd39226..b1f4bbf5e0 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp_storage.c
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp_storage.c
@@ -95,26 +95,38 @@ uint8_t USBD_MTP_STORAGE_ReadData(USBD_HandleTypeDef *pdev)
{
USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint32_t *data_buff;
+ uint32_t buffer_size;
/* Get the data buffer pointer from the low layer interface */
data_buff = ((USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId])->ScratchBuff;
+ /* Get Data Buffer Size */
+ buffer_size = ((USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId])->ScratchBuffSze;
+
+ if ((data_buff == NULL) || (buffer_size < MTP_CONT_HEADER_SIZE))
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
switch (ReadDataStatus)
{
case READ_FIRST_DATA:
/* Reset the data length */
MTP_DataLength.temp_length = 0U;
- /* Perform the low layer read operation on the scratch buffer */
- (void)((USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId])->ReadData(hmtp->OperationsContainer.Param1,
- (uint8_t *)data_buff, &MTP_DataLength);
-
/* Add the container header to the data buffer */
(void)USBD_memcpy((uint8_t *)data_buff, (uint8_t *)&hmtp->GenericContainer, MTP_CONT_HEADER_SIZE);
+ /* Perform the low layer read operation on the scratch buffer
+ * first packet expected data length: MPS - MTP_CONT_HEADER_SIZE
+ */
+ (void)((USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId])->ReadData(hmtp->OperationsContainer.Param1,
+ (uint8_t *)data_buff +
+ MTP_CONT_HEADER_SIZE, &MTP_DataLength);
+
/* Start USB data transmission to the host */
(void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)data_buff,
- MTP_DataLength.readbytes + MTP_CONT_HEADER_SIZE);
+ MIN((MTP_DataLength.readbytes + MTP_CONT_HEADER_SIZE), buffer_size));
/* Check if this will be the last packet to send ? */
if (MTP_DataLength.readbytes < ((uint32_t)hmtp->MaxPcktLen - MTP_CONT_HEADER_SIZE))
@@ -138,24 +150,45 @@ uint8_t USBD_MTP_STORAGE_ReadData(USBD_HandleTypeDef *pdev)
if (MTP_DataLength.temp_length == MTP_DataLength.totallen)
{
/* Start USB data transmission to the host */
- (void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)data_buff, MTP_DataLength.readbytes);
+ (void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)data_buff, MIN(MTP_DataLength.readbytes, buffer_size));
- /* Move to response phase */
- hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE;
+ if (((MTP_DataLength.totallen + MTP_CONT_HEADER_SIZE) % hmtp->MaxPcktLen) == 0U)
+ {
+ /* Send ZLP Packet */
+ ReadDataStatus = READ_SEND_ZLP_DATA;
+ }
+ else
+ {
+ /* Move to response phase */
+ hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE;
- /* Reset the stat machine */
- ReadDataStatus = READ_FIRST_DATA;
+ /* Reset the state machine */
+ ReadDataStatus = READ_FIRST_DATA;
+ }
}
else
{
/* Start USB data transmission to the host */
- (void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)data_buff, MTP_DataLength.readbytes);
+ (void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)data_buff, MIN(MTP_DataLength.readbytes, buffer_size));
/* Keep the state machine into sending next packet of data */
ReadDataStatus = READ_REST_OF_DATA;
}
break;
+ case READ_SEND_ZLP_DATA:
+
+ /* Send ZLP to the host */
+ (void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)data_buff, 0U);
+
+ /* Move to response phase */
+ hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE;
+
+ /* Reset the state machine */
+ ReadDataStatus = READ_FIRST_DATA;
+
+ break;
+
default:
break;
}
@@ -176,7 +209,8 @@ uint8_t USBD_MTP_STORAGE_SendContainer(USBD_HandleTypeDef *pdev, MTP_CONTAINER_
{
case DATA_TYPE:
/* send header + data : hmtp->ResponseLength = header size + data size */
- (void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)&hmtp->GenericContainer, hmtp->ResponseLength);
+ (void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)&hmtp->GenericContainer, MIN(sizeof(MTP_GenericContainerTypeDef),
+ hmtp->ResponseLength));
break;
case REP_TYPE:
/* send header without data */
@@ -185,7 +219,8 @@ uint8_t USBD_MTP_STORAGE_SendContainer(USBD_HandleTypeDef *pdev, MTP_CONTAINER_
hmtp->GenericContainer.length = hmtp->ResponseLength;
hmtp->GenericContainer.type = MTP_CONT_TYPE_RESPONSE;
- (void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)&hmtp->GenericContainer, hmtp->ResponseLength);
+ (void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)&hmtp->GenericContainer, MIN(sizeof(MTP_GenericContainerTypeDef),
+ hmtp->ResponseLength));
break;
default:
break;
@@ -245,7 +280,7 @@ uint8_t USBD_MTP_STORAGE_ReceiveOpt(USBD_HandleTypeDef *pdev)
*/
uint8_t USBD_MTP_STORAGE_ReceiveData(USBD_HandleTypeDef *pdev)
{
- USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
+ USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
switch (hmtp->RECEIVE_DATA_STATUS)
{
case RECEIVE_COMMAND_DATA :
@@ -410,15 +445,30 @@ static uint8_t USBD_MTP_STORAGE_DecodeOperations(USBD_HandleTypeDef *pdev)
static uint8_t USBD_MTP_STORAGE_ReceiveContainer(USBD_HandleTypeDef *pdev,
uint32_t *pDst, uint32_t len)
{
- USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
+ USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint32_t Counter;
uint32_t *pdst = pDst;
- for (Counter = 0; Counter < len; Counter++)
+ if ((pDst == NULL) || (len > MTP_MEDIA_PACKET))
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ /* Convert byte count to uint32_t element count */
+ len = len / sizeof(uint32_t);
+
+ /* Clamp copy length to the size of OperationsContainer */
+ if (len > (sizeof(MTP_OperationsTypeDef) / sizeof(uint32_t)))
+ {
+ len = (sizeof(MTP_OperationsTypeDef) / sizeof(uint32_t));
+ }
+
+ for (Counter = 0U; Counter < len; Counter++)
{
*pdst = (hmtp->rx_buff[Counter]);
pdst++;
}
+
return (uint8_t)USBD_OK;
}
@@ -456,17 +506,14 @@ void USBD_MTP_STORAGE_Cancel(USBD_HandleTypeDef *pdev,
* @param len: Data Length
* @retval status value
*/
-static uint8_t USBD_MTP_STORAGE_SendData(USBD_HandleTypeDef *pdev, uint8_t *buf,
- uint32_t len)
+static uint8_t USBD_MTP_STORAGE_SendData(USBD_HandleTypeDef *pdev, uint8_t *buf, uint32_t len)
{
- USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
- uint32_t length = MIN(hmtp->GenericContainer.length, len);
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
MTPInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
- (void)USBD_LL_Transmit(pdev, MTPInEpAdd, buf, length);
+ (void)USBD_LL_Transmit(pdev, MTPInEpAdd, buf, len);
return (uint8_t)USBD_OK;
}
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Src/usbd_printer.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Src/usbd_printer.c
index 7c1a4ba830..a8f6d5f5aa 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Src/usbd_printer.c
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Src/usbd_printer.c
@@ -141,6 +141,9 @@ USBD_ClassTypeDef USBD_PRNT =
USBD_PRNT_GetOtherSpeedCfgDesc,
USBD_PRNT_GetDeviceQualifierDescriptor,
#endif /* USE_USBD_COMPOSITE */
+#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
+ NULL,
+#endif /* USBD_SUPPORT_USER_STRING_DESC */
};
#ifndef USE_USBD_COMPOSITE
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/Template/Src/usbd_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Template/Src/usbd_template.c
index 947ae911e3..cd08a0ae2c 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/Template/Src/usbd_template.c
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Template/Src/usbd_template.c
@@ -76,13 +76,10 @@
*/
-
-
/** @defgroup USBD_TEMPLATE_Private_FunctionPrototypes
* @{
*/
-
static uint8_t USBD_TEMPLATE_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
static uint8_t USBD_TEMPLATE_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
static uint8_t USBD_TEMPLATE_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Src/usbd_video.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Src/usbd_video.c
index 0e580ba59b..c4aef9ae29 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Src/usbd_video.c
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Src/usbd_video.c
@@ -140,6 +140,9 @@ USBD_ClassTypeDef USBD_VIDEO =
USBD_VIDEO_GetOtherSpeedCfgDesc,
USBD_VIDEO_GetDeviceQualifierDesc,
#endif /* USE_USBD_COMPOSITE */
+#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
+ NULL,
+#endif /* USBD_SUPPORT_USER_STRING_DESC */
};
/* USB VIDEO device Configuration Descriptor (same for all speeds thanks to user defines) */
@@ -315,7 +318,7 @@ __ALIGN_BEGIN static uint8_t USBD_VIDEO_CfgDesc[] __ALIGN_END =
UVC_IN_EP, /* bEndpointAddress */
0x05, /* bmAttributes: ISO transfer */
LOBYTE(UVC_ISO_FS_MPS), /* wMaxPacketSize */
- LOBYTE(UVC_ISO_FS_MPS),
+ HIBYTE(UVC_ISO_FS_MPS),
0x01, /* bInterval: 1 frame interval */
};
@@ -688,8 +691,11 @@ static uint8_t USBD_VIDEO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
}
else
{
- (void)USBD_memcpy((packet + ((DataOffset + 0U) * i) + 2U),
- Pcktdata + ((DataOffset - 2U) * i), (RemainData - 2U));
+ if (RemainData > 2U)
+ {
+ (void)USBD_memcpy((packet + ((DataOffset + 0U) * i) + 2U),
+ Pcktdata + ((DataOffset - 2U) * i), (RemainData - 2U));
+ }
RemainData = 0U;
}
@@ -723,7 +729,7 @@ static uint8_t USBD_VIDEO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
static uint8_t USBD_VIDEO_SOF(USBD_HandleTypeDef *pdev)
{
USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *) pdev->pClassDataCmsit[pdev->classId];
- uint8_t payload[2] = {0x02U, 0x00U};
+ static uint8_t payload[2] = {0x02U, 0x00U};
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_conf_template.h b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_conf_template.h
index 8d61e7a0d6..73d4f3d7e5 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_conf_template.h
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_conf_template.h
@@ -79,10 +79,12 @@ extern "C" {
#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE 0x02U
#define USBD_CUSTOM_HID_REPORT_DESC_SIZE 163U
+/* #define USBD_CUSTOMHID_REPORT_DESC_SIZE_ENABLED */
/* #define USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED */
/* #define USBD_CUSTOMHID_OUT_PREPARE_RECEIVE_DISABLED */
/* #define USBD_CUSTOMHID_EP0_OUT_PREPARE_RECEIVE_DISABLED */
/* #define USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */
+/* #define USBD_CUSTOMHID_REPORT_BUFFER_EVENT_ENABLED */
/* VIDEO Class Config */
#define UVC_1_1 /* #define UVC_1_0 */
@@ -175,8 +177,6 @@ extern "C" {
* @}
*/
-
-
/**
* @}
*/
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h
index 4672921be1..8388e326a8 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h
@@ -55,13 +55,11 @@ extern "C" {
* @{
*/
-
/**
* @}
*/
-
/** @defgroup USBD_CORE_Exported_Macros
* @{
*/
@@ -171,5 +169,3 @@ USBD_DescHeaderTypeDef *USBD_GetNextDesc(uint8_t *pbuf, uint16_t *ptr);
/**
* @}
*/
-
-
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h
index 6c45d6ce3d..efb78a728c 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h
@@ -53,7 +53,6 @@ extern "C" {
*/
-
/** @defgroup USBD_REQ_Exported_Macros
* @{
*/
@@ -97,5 +96,3 @@ void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len);
/**
* @}
*/
-
-
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h
index 2a295d78b4..7025f69367 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h
@@ -305,12 +305,13 @@ typedef struct
/* USB Device handle structure */
typedef struct
{
- uint32_t status;
uint32_t total_length;
uint32_t rem_length;
- uint32_t maxpacket;
- uint16_t is_used;
- uint16_t bInterval;
+ uint32_t bInterval;
+ uint16_t maxpacket;
+ uint8_t status;
+ uint8_t is_used;
+ uint8_t *pbuffer;
} USBD_EndpointTypeDef;
#ifdef USE_USBD_COMPOSITE
@@ -417,7 +418,6 @@ typedef enum
*/
-
/** @defgroup USBD_DEF_Exported_Macros
* @{
*/
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_desc_template.h b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_desc_template.h
index e3923055ad..7be13cebec 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_desc_template.h
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_desc_template.h
@@ -25,6 +25,10 @@
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
+/*
+ * User to provide a unique ID to define the USB device serial number
+ * The use of UID_BASE register can be considered as an example
+ */
#define DEVICE_ID1 (UID_BASE)
#define DEVICE_ID2 (UID_BASE + 0x4U)
#define DEVICE_ID3 (UID_BASE + 0x8U)
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h
index 15197b92ca..1a574b8e5d 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h
@@ -40,6 +40,7 @@ extern "C" {
/** @defgroup USBD_IOREQ_Exported_Defines
* @{
*/
+
/**
* @}
*/
@@ -49,13 +50,11 @@ extern "C" {
* @{
*/
-
/**
* @}
*/
-
/** @defgroup USBD_IOREQ_Exported_Macros
* @{
*/
@@ -110,4 +109,3 @@ uint32_t USBD_GetRxCount(USBD_HandleTypeDef *pdev, uint8_t ep_addr);
/**
* @}
*/
-
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c
index 0576c877cd..3b664a9b23 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c
@@ -105,21 +105,22 @@ USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev,
#ifdef USE_USBD_COMPOSITE
/* Parse the table of classes in use */
- for (uint32_t i = 0; i < USBD_MAX_SUPPORTED_CLASS; i++)
+ for (uint32_t i = 0U; i < USBD_MAX_SUPPORTED_CLASS; i++)
{
/* Unlink previous class*/
pdev->pClass[i] = NULL;
pdev->pUserData[i] = NULL;
/* Set class as inactive */
- pdev->tclasslist[i].Active = 0;
- pdev->NumClasses = 0;
- pdev->classId = 0;
+ pdev->tclasslist[i].Active = 0U;
+ pdev->NumClasses = 0U;
+ pdev->classId = 0U;
}
#else
/* Unlink previous class*/
pdev->pClass[0] = NULL;
pdev->pUserData[0] = NULL;
+ pdev->NumClasses = 0U;
#endif /* USE_USBD_COMPOSITE */
pdev->pConfDesc = NULL;
@@ -296,7 +297,7 @@ USBD_StatusTypeDef USBD_RegisterClassComposite(USBD_HandleTypeDef *pdev, USBD_Cl
*/
USBD_StatusTypeDef USBD_UnRegisterClassComposite(USBD_HandleTypeDef *pdev)
{
- USBD_StatusTypeDef ret = USBD_FAIL;
+ USBD_StatusTypeDef ret = USBD_OK;
uint8_t idx1;
uint8_t idx2;
@@ -590,6 +591,8 @@ USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev,
USBD_StatusTypeDef ret = USBD_OK;
uint8_t idx;
+ UNUSED(pdata);
+
if (epnum == 0U)
{
pep = &pdev->ep_out[0];
@@ -599,8 +602,9 @@ USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev,
if (pep->rem_length > pep->maxpacket)
{
pep->rem_length -= pep->maxpacket;
+ pep->pbuffer += pep->maxpacket;
- (void)USBD_CtlContinueRx(pdev, pdata, MIN(pep->rem_length, pep->maxpacket));
+ (void)USBD_CtlContinueRx(pdev, pep->pbuffer, MAX(pep->rem_length, pep->maxpacket));
}
else
{
@@ -685,6 +689,8 @@ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev,
USBD_StatusTypeDef ret;
uint8_t idx;
+ UNUSED(pdata);
+
if (epnum == 0U)
{
pep = &pdev->ep_in[0];
@@ -694,8 +700,9 @@ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev,
if (pep->rem_length > pep->maxpacket)
{
pep->rem_length -= pep->maxpacket;
+ pep->pbuffer += pep->maxpacket;
- (void)USBD_CtlContinueSendData(pdev, pdata, pep->rem_length);
+ (void)USBD_CtlContinueSendData(pdev, pep->pbuffer, pep->rem_length);
/* Prepare endpoint for premature end of transfer */
(void)USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U);
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c
index 814b810c5b..584a8cb9c2 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c
@@ -361,6 +361,12 @@ USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef
break;
case USBD_STATE_CONFIGURED:
+ if ((ep_addr & 0x7FU) > 0x0FU)
+ {
+ USBD_CtlError(pdev, req);
+ break;
+ }
+
if ((ep_addr & 0x80U) == 0x80U)
{
if (pdev->ep_in[ep_addr & 0xFU].is_used == 0U)
@@ -378,8 +384,8 @@ USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef
}
}
- pep = ((ep_addr & 0x80U) == 0x80U) ? &pdev->ep_in[ep_addr & 0x7FU] : \
- &pdev->ep_out[ep_addr & 0x7FU];
+ pep = ((ep_addr & 0x80U) == 0x80U) ? &pdev->ep_in[ep_addr & 0xFU] : \
+ &pdev->ep_out[ep_addr & 0xFU];
if ((ep_addr == 0x00U) || (ep_addr == 0x80U))
{
@@ -1011,7 +1017,7 @@ void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len)
unicode[idx] = USB_DESC_TYPE_STRING;
idx++;
- while (*pdesc != (uint8_t)'\0')
+ while ((*pdesc != (uint8_t)'\0') && (idx < *len))
{
unicode[idx] = *pdesc;
pdesc++;
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_desc_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_desc_template.c
index a9f995fa45..503eb13d7f 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_desc_template.c
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_desc_template.c
@@ -65,7 +65,7 @@ USBD_DescriptorsTypeDef Class_Desc =
USBD_Class_ConfigStrDescriptor,
USBD_Class_InterfaceStrDescriptor,
#if (USBD_CLASS_USER_STRING_DESC == 1)
- USBD_CLASS_UserStrDescriptor,
+ USBD_Class_UserStrDescriptor,
#endif /* USB_CLASS_USER_STRING_DESC */
#if ((USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1))
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c
index 7c8004ad80..2171398b19 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c
@@ -89,6 +89,7 @@ USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev,
/* Set EP0 State */
pdev->ep0_state = USBD_EP0_DATA_IN;
pdev->ep_in[0].total_length = len;
+ pdev->ep_in[0].pbuffer = pbuf;
#ifdef USBD_AVOID_PACKET_SPLIT_MPS
pdev->ep_in[0].rem_length = 0U;
@@ -133,6 +134,7 @@ USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev,
/* Set EP0 State */
pdev->ep0_state = USBD_EP0_DATA_OUT;
pdev->ep_out[0].total_length = len;
+ pdev->ep_out[0].pbuffer = pbuf;
#ifdef USBD_AVOID_PACKET_SPLIT_MPS
pdev->ep_out[0].rem_length = 0U;
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/LICENSE.md b/system/Middlewares/ST/STM32_USB_Device_Library/LICENSE.md
index 1af5233078..5f9caee9ff 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/LICENSE.md
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/LICENSE.md
@@ -1,80 +1,94 @@
-SLA0044 Rev5/February 2018
+This software component is provided to you as part of a software package and
+applicable license terms are in the Package_license file. If you received this
+software component outside of a package or without applicable license terms,
+the terms of the SLA0044 license shall apply and are fully reproduced below:
+
+SLA0044 Rev6/October 2025
## Software license agreement
### __ULTIMATE LIBERTY SOFTWARE LICENSE AGREEMENT__
-BY INSTALLING, COPYING, DOWNLOADING, ACCESSING OR OTHERWISE USING THIS SOFTWARE
-OR ANY PART THEREOF (AND THE RELATED DOCUMENTATION) FROM STMICROELECTRONICS
-INTERNATIONAL N.V, SWISS BRANCH AND/OR ITS AFFILIATED COMPANIES
-(STMICROELECTRONICS), THE RECIPIENT, ON BEHALF OF HIMSELF OR HERSELF, OR ON
-BEHALF OF ANY ENTITY BY WHICH SUCH RECIPIENT IS EMPLOYED AND/OR ENGAGED AGREES
-TO BE BOUND BY THIS SOFTWARE LICENSE AGREEMENT.
+BY CLICKING ON THE "I ACCEPT" BUTTON OR BY UNZIPPING, INSTALLING, COPYING,
+DOWNLOADING, ACCESSING OR OTHERWISE USING THIS SOFTWARE OR ANY PART THEREOF,
+INCLUDING ANY RELATED DOCUMENTATION (collectively the “SOFTWARE”)
+FROM STMICROELECTRONICS INTERNATIONAL N.V, SWISS BRANCH AND/OR
+ITS AFFILIATED COMPANIES (collectively “STMICROELECTRONICS”),
+YOU (hereinafter referred also to as “THE RECIPIENT”), ON BEHALF OF YOURSELF,
+OR ON BEHALF OF ANY ENTITY BY WHICH YOU ARE EMPLOYED AND/OR ENGAGED,
+AGREE TO BE BOUND BY THIS AGREEMENT.
-Under STMicroelectronics’ intellectual property rights, the redistribution,
-reproduction and use in source and binary forms of the software or any part
+Under STMICROELECTRONICS’ intellectual property rights, the redistribution,
+reproduction and use in source and binary forms of the SOFTWARE or any part
thereof, with or without modification, are permitted provided that the following
conditions are met:
1. Redistribution of source code (modified or not) must retain any copyright
-notice, this list of conditions and the disclaimer set forth below as items 10
-and 11.
-
-2. Redistributions in binary form, except as embedded into microcontroller or
-microprocessor device manufactured by or for STMicroelectronics or a software
-update for such device, must reproduce any copyright notice provided with the
-binary code, this list of conditions, and the disclaimer set forth below as
-items 10 and 11, in documentation and/or other materials provided with the
-distribution.
-
-3. Neither the name of STMicroelectronics nor the names of other contributors to
-this software may be used to endorse or promote products derived from this
-software or part thereof without specific written permission.
-
-4. This software or any part thereof, including modifications and/or derivative
-works of this software, must be used and execute solely and exclusively on or in
-combination with a microcontroller or microprocessor device manufactured by or
-for STMicroelectronics.
-
-5. No use, reproduction or redistribution of this software partially or totally
-may be done in any manner that would subject this software to any Open Source
-Terms. “Open Source Terms” shall mean any open source license which requires as
-part of distribution of software that the source code of such software is
-distributed therewith or otherwise made available, or open source license that
-substantially complies with the Open Source definition specified at
-www.opensource.org and any other comparable open source license such as for
-example GNU General Public License (GPL), Eclipse Public License (EPL), Apache
-Software License, BSD license or MIT license.
-
-6. STMicroelectronics has no obligation to provide any maintenance, support or
-updates for the software.
-
-7. The software is and will remain the exclusive property of STMicroelectronics
-and its licensors. The recipient will not take any action that jeopardizes
-STMicroelectronics and its licensors' proprietary rights or acquire any rights
-in the software, except the limited rights specified hereunder.
-
-8. The recipient shall comply with all applicable laws and regulations affecting
-the use of the software or any part thereof including any applicable export
-control law or regulation.
-
-9. Redistribution and use of this software or any part thereof other than as
-permitted under this license is void and will automatically terminate your
-rights under this license.
-
-10. THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY RIGHTS, WHICH ARE
-DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT SHALL
-STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-11. EXCEPT AS EXPRESSLY PERMITTED HEREUNDER, NO LICENSE OR OTHER RIGHTS, WHETHER
-EXPRESS OR IMPLIED, ARE GRANTED UNDER ANY PATENT OR OTHER INTELLECTUAL PROPERTY
-RIGHTS OF STMICROELECTRONICS OR ANY THIRD PARTY.
+notice accompanying the SOFTWARE, this list of conditions and the disclaimer below.
+
+2. Redistributions in binary form, except as embedded into a processing unit device
+manufactured by or for STMicroelectronics or a software update for any such device,
+must reproduce the accompanying copyright notice, this list of conditions,
+and the below disclaimer in capital type, in the documentation and/or
+other materials provided with the distribution.
+
+3. Neither the name of STMicroelectronics nor the names of other contributors
+to the SOFTWARE may be used to endorse or promote products derived
+from the SOFTWARE or part thereof without specific written permission.
+
+4. The SOFTWARE or any part thereof, including modifications and/or
+derivative works of the SOFTWARE, must be used and execute solely
+and exclusively on or in combination with a processing unit device
+manufactured by or for STMicroelectronics.
+
+5. No use, reproduction or redistribution of the SOFTWARE partially
+or totally may be done in any manner that would subject the SOFTWARE
+to any Open Source Terms. “Open Source Terms” shall mean
+any open source license which requires as part of distribution
+of software that the source code of such software is distributed
+therewith or otherwise made available, or open source license
+that substantially complies with the Open Source definition specified
+at www.opensource.org and any other comparable open source license
+such as for example GNU General Public License (GPL),
+Eclipse Public License (EPL), Apache Software License, BSD license
+or MIT license.
+
+6. STMicroelectronics has no obligation to provide any maintenance,
+support or updates for the SOFTWARE.
+
+7. The SOFTWARE is and will remain the exclusive property of
+STMicroelectronics and its licensors. The RECIPIENT will not take
+any action that jeopardizes STMicroelectronics and its
+licensors' proprietary rights or acquire any rights in the SOFTWARE,
+except the limited rights specified hereunder.
+
+8. The RECIPIENT shall comply with all applicable laws and regulations
+affecting the use of the SOFTWARE or any part thereof including
+any applicable export control law or regulation.
+
+9. Redistribution and use of the SOFTWARE or any part thereof other
+than as permitted under this AGREEMENT is void and will automatically
+terminate RECIPIENT’s rights under this AGREEMENT.
+
+10. The RECIPIENT shall be solely liable to determine and verify that
+the SOFTWARE is fit for the RECIPIENT intended use, environment or
+application and comply with all regulatory, safety and security
+related requirements concerning any use.
+
+DISCLAIMER:
+
+THE SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING,BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY RIGHTS, ARE
+DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW.
+IN NO EVENT SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+EXCEPT AS EXPRESSLY PERMITTED HEREUNDER, NO LICENSE OR OTHER RIGHTS,
+WHETHER EXPRESS OR IMPLIED, ARE GRANTED UNDER ANY PATENT OR OTHER INTELLECTUAL
+PROPERTY RIGHTS OF STMICROELECTRONICS OR ANY THIRD PARTY.
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Release_Notes.html b/system/Middlewares/ST/STM32_USB_Device_Library/Release_Notes.html
index 94390d06ab..622f1ece3a 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/Release_Notes.html
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/Release_Notes.html
@@ -6,19 +6,23 @@
Release Notes for STM32Cube USB Device Library
-
-
-
+code{white-space: pre-wrap;}
+span.smallcaps{font-variant: small-caps;}
+div.columns{display: flex; gap: min(4vw, 1.5em);}
+div.column{flex: auto; overflow-x: auto;}
+div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
+
+ul.task-list[class]{list-style: none;}
+ul.task-list li input[type="checkbox"] {
+font-size: inherit;
+width: 0.8em;
+margin: 0 0.8em 0.2em -1.6em;
+vertical-align: middle;
+}
+.display.math{display: block; text-align: center; margin: 0.5rem auto;}
+
+
+
@@ -28,12 +32,11 @@
Release Notes
for STM32Cube USB Device Library
Copyright © 2015 STMicroelectronics
-
+
Purpose
The USB device library comes on top of the STM32Cube™ USB device HAL
-driver and offers all the APIs required to develop an USB device
+driver and offers all the APIs required to develop a USB device
application.
The main USB device library features are:
@@ -49,8 +52,7 @@ Purpose
Here is the list of references to user documents:
-UM1734
+UM1734
: STM32Cube USB device library User Manual
Wiki
Page : STM32Cube USB Wiki Page
@@ -59,29 +61,160 @@ Purpose
Update History
+
+
+
V2.11.5 /
+26-September-2025
+
+
+Main Changes
+
+
+
+
+Headline
+
+
+
+
+USB Core:
+
+
+SLA0044 Legal terms updated to latest revision (Rev 6 / October
+2025)
+
+
+USB Classes:
+
+
+Add missing NULL pointer for user string descriptor
+
+
+USB MTP Class:
+
+
+Minor enhancement; remove useless data copy and add support of
+ZLP
+
+
+
+
+
+
+
+
V2.11.4 /
+11-April-2025
+
+
+Main Changes
+
+
+
+
+Headline
+
+
+
+
+USB Core:
+
+
+Fix return value of USBD_UnRegisterClassComposite function
+
+
+Increment EP0 data buffer inside HAL data callbacks
+
+
+USB MSC Class:
+
+
+Adding multi LUN support
+
+
+USB CustomHID Class:
+
+
+Adding support of different CustomHID report descriptor sizes
+
+
+Fix composite builder CustomHID EP size
+
+
+USB MTP Class:
+
+
+Minor enhancement; improve device data buffer management
+
+
+
+
+
+
+
+
V2.11.3 /
20-December-2023
-
Main Changes
+
+Main Changes
+
-
+Headline
-
-USB Core:
+
+USB Core:
-
-Minor enhancement; add a check on device string descriptor length
+
+Minor enhancement; add a check on device string descriptor
+length
-
-USB DFU Class:
+
+USB DFU Class:
-
-Improve DFU Vendor Commands support
+
+Improve DFU Vendor Commands support
@@ -90,45 +223,47 @@
Main Changes
V2.11.2 /
-17-April-2023
+27-September-2022
-
Main Changes
+
+Main Changes
+
-
+Headline
-
-USB Core:
+
+USB Core:
-
-Adding user callback to get device configuration state
+
+Adding user callback to get device configuration state
-
-USB DFU Class:
+
+USB DFU Class:
-
-Adding DFU Vendor Commands support
+
+Adding DFU Vendor Commands support
-
-USB MSC Class:
+
+USB MSC Class:
-
-fix data sense response to be aligned with SBC-3 specification
+
+Fix data sense response to be aligned with SBC-3 specification
-
-USB AUDIO Class:
+
+USB AUDIO Class:
-
-restart AUDIO ISO endpoint during ISO incomplete event
+
+Restart AUDIO ISO endpoint during ISO incomplete event
-
-USB VIDEO Class:
+
+USB VIDEO Class:
-
-restart VIDEO ISO endpoint during ISO incomplete event
+
+Restart VIDEO ISO endpoint during ISO incomplete event
@@ -139,45 +274,45 @@
Main Changes
V2.11.1 /
27-September-2022
-
Main Changes
+
+Main Changes
+
-
+Headline
-
- Improvement of the memory management
-
+
+Improvement of the memory management
-
-USB Core:
+
+USB Core:
-
-Fix some compilation warnings related
-to unused parameters
+
+Fix some compilation warnings related to unused parameters
-
-Improve some code parts style
+
+Improve some code parts style
-
-Add check on the USB Device status in
-USBD_LL_Suspend before suspending it
+
+Add check on the USB Device status in USBD_LL_Suspend before
+suspending it
-
-USB CDC-ACM Class:
+
+USB CDC-ACM Class:
-
-Remove redundant prototype declaration of
+
+Remove redundant prototype declaration of
USBD_CDC_GetOtherSpeedCfgDesc()
-
-USB CompositeBuilder, CCID, CDC_ECM, CDC_RNDIS,
-CustomHID, MSC & Video Classes:
+
+USB CompositeBuilder, CCID, CDC_ECM, CDC_RNDIS, CustomHID,
+MSC & Video Classes:
-
- Improve some code parts style
+
+Improve some code parts style
@@ -188,70 +323,69 @@
Main Changes
V2.11.0 /
25-March-2022
-
Main Changes
+
+Main Changes
+
-
+Headline
-
-USB VIDEO Class:
+
+USB VIDEO Class:
-
-Correction of the support of
-VS_PROBE_CONTROL & VS_COMMIT_CONTROL requests
+
+Correction of the support of VS_PROBE_CONTROL &
+VS_COMMIT_CONTROL requests
-
-USB AUDIO Class:
+
+USB AUDIO Class:
-
-Correction of the check on
-AUDIO_TOTAL_BUF_SIZE to avoid vulnerabilities
+
+Correction of the check on AUDIO_TOTAL_BUF_SIZE to avoid
+vulnerabilities
-
-USB HID Class:
+
+USB HID Class:
-
-Modification of some constants names to
-avoid duplication versus USB host library
+
+Modification of some constants names to avoid duplication versus USB
+host library
-
-USB CustomHID Class:
+
+USB CustomHID Class:
-
-Add support of Get Report control
-request
+
+Add support of Get Report control request
-
-Allow disabling EP OUT prepare receive
-using a dedicated macros that can be defined in usbd_conf.h application
-file
+
+Allow disabling EP OUT prepare receive using a dedicated macro that
+can be defined in usbd_conf.h application file
-
-Add support of Report Descriptor with
-length greater than 255 bytes
+
+Add support of Report Descriptor with length greater than 255
+bytes
-
-USB CCID Class:
+
+USB CCID Class:
-
-Fix minor Code Spelling warning
+
+Fix minor Code Spelling warning
-
-USB All Classes:
+
+USB All Classes:
-
-Update all classes to support composite
-multi-instance using the class id parameter
+
+Update all classes to support composite multi-instance using the
+class id parameter
-
-Fix code spelling and improve code
-style
+
+Fix code spelling and improve code style
-
-fix misraC 2012 rule 10.3
+
+Fix misraC 2012 rule 10.3
@@ -262,37 +396,35 @@
Main Changes
V2.10.0 /
03-Sept-2021
-
Main Changes
+
+Main Changes
+
-
+Headline
-
-Integration of new USB device
-Class driver:
+
+Integration of new USB device Class driver:
-
-Adding support of Composite devices with
-an auto generation of composite device configuration descriptors
+
+Adding support of Composite devices with an auto generation of
+composite device configuration descriptors
-
-USB All Classes:
+
+USB All Classes:
-
-Fix Code Spelling and improve Code
-Style
+
+Fix Code Spelling and improve Code Style
-
-Update device class drivers to support
-Composite devices
+
+Update device class drivers to support Composite devices
-
-Improve declaration of USB configuration
-descriptor table which is allocated if the composite builder is not
-selected
+
+Improve declaration of USB configuration descriptor table which is
+allocated if the composite builder is not selected
@@ -303,44 +435,43 @@
Main Changes
V2.9.0 /
06-July-2021
-
Main Changes
+
+Main Changes
+
-
+Headline
-
-Integration of new USB device
-Class driver:
+
+Integration of new USB device Class driver:
-
-USB CCID Class driver based on Universal
-Serial Bus Device Class Definition for Integrated Circuit(s) Cards
-Interface Devices Revision 1.1
+
+USB CCID Class driver based on Universal Serial Bus Device Class
+Definition for Integrated Circuit(s) Cards Interface Devices Revision
+1.1
-
-USB MTP Class driver based on Universal
-Serial Bus Device Class Media Transfer Protocol Revision 1.1
+
+USB MTP Class driver based on Universal Serial Bus Device Class
+Media Transfer Protocol Revision 1.1
-
-USB All Classes:
+
+USB All Classes:
-
-Fix Code Spelling and improve Code
-Style
+
+Fix Code Spelling and improve Code Style
-
-Update the way to declare licenses
+
+Update the way to declare Legal terms
-
-USB CDC/RNDIS/ECM
-Classes:
+
+USB CDC/RNDIS/ECM Classes:
-
-Fix compilation warning with C++ due to
-missing casting during class handler allocation
+
+Fix compilation warning with C++ due to missing casting during class
+handler allocation
@@ -349,50 +480,47 @@
Main Changes
V2.8.0 /
-10-Mars-2021
+10-March-2021
-
Main Changes
+
+Main Changes
+
-
+Headline
-
-Integration of new USB device
-Class driver:
+
+Integration of new USB device Class driver:
-
-USB Printer Class driver based on
-Universal Serial Bus Device Class Definition for Printing Devices
-Version 1.1
+
+USB Printer Class driver based on Universal Serial Bus Device Class
+Definition for Printing Devices Version 1.1
-
-USB All Classes:
+
+USB All Classes:
-
-Fix USB buffer overflow vulnerability for
-CDC, CDC-ECM, CDC-RNDIS, DFU, AUDIO, CustomHID, and Video Classes
+
+Fix USB buffer overflow vulnerability for CDC, CDC-ECM, CDC-RNDIS,
+DFU, AUDIO, CustomHID, and Video Classes
-
-Fix compilation warning with C++ due to
-missing casting during class handler allocation
+
+Fix compilation warning with C++ due to missing casting during class
+handler allocation
-
-Enhance comments of USB configuration
-descriptors fields
+
+Enhance comments of USB configuration descriptors fields
-
-USB Video Class:
+
+USB Video Class:
-
-Fix missing closing bracket for extern “C”
-in usbd_video.h
+
+Fix missing closing bracket for extern “C” in usbd_video.h
-
-Fix USBCV test with Uncompressed video
-format support
+
+Fix USBCV test with Uncompressed video format support
@@ -403,17 +531,18 @@
Main Changes
V2.7.1 /
18-August-2020
-
Main Changes
+
+Main Changes
+
-
+Headline
-
-USB All Class: Add NULL pointer access
-check to Class handler
+
+USB All Class: Add NULL pointer access check to Class handler
@@ -424,83 +553,77 @@
Main Changes
V2.7.0 /
12-August-2020
-
Main Changes
+
+Main Changes
+
-
+Headline
-
-Integration of new USB device
-Class driver:
+
+Integration of new USB device Class driver:
-
-USB video Class driver based on USB-IF
-video class definition version 1.1
+
+USB video Class driver based on USB-IF video class definition
+version 1.1
-
-USB Core:
+
+USB Core:
-
-Enhance NULL pointer check in Core
-APIs
+
+Enhance NULL pointer check in Core APIs
-
-Allow supporting both USER and USER Class
-string desc
+
+Allow supporting both USER and USER Class string desc
-
-Add support of USB controller which
-handles packet-size splitting by hardware
+
+Add support of USB controller which handles packet-size splitting by
+hardware
-
-Avoid compilation warning due macro
-redefinition
+
+Avoid compilation warning due to macro redefinition
-
-change added to USBD_HandleTypeDef
-structure: dev_state, old_dev_state and ep0_state declaration become
-volatile to disable compiler optimization
+
+Change added to USBD_HandleTypeDef structure: dev_state,
+old_dev_state and ep0_state declaration become volatile to disable
+compiler optimization
-
-Word spelling correction and file
-indentation improved
+
+Word spelling correction and file indentation improved
-
-usbd_conf.h/c Template file updated to
-suggest using by default a static memory allocation for Class
-handler
+
+usbd_conf.h/c Template file updated to suggest using by default a
+static memory allocation for Class handler
-
-USB All Classes:
+
+USB All Classes:
-
-Word spelling correction and file
-indentation improved
+
+Word spelling correction and file indentation improved
-
-Allow updating device config descriptor
-Max power from user code usbd_conf.h using USBD_MAX_POWER define
+
+Allow updating device config descriptor Max power from user code
+usbd_conf.h using USBD_MAX_POWER define
-
-Fix device config descriptor bmAttributes
-value which depends on user code define USBD_SELF_POWERED
+
+Fix device config descriptor bmAttributes value which depends on
+user code define USBD_SELF_POWERED
-
-USB CDC Class:
+
+USB CDC Class:
-
-Class specific request, add protection to
-limit the maximum data length to be sent by the CDC device
+
+Class specific request, add protection to limit the maximum data
+length to be sent by the CDC device
-
-USB CustomHID Class:
+
+USB CustomHID Class:
-
-Allow changing CustomHID data EP size from
-user code
+
+Allow changing CustomHID data EP size from user code
@@ -511,38 +634,39 @@
Main Changes
V2.6.1 /
05-June-2020
-
Main Changes
+
+Main Changes
+
-
+Headline
-
-Fix minor misra-c 2012 violations
+
+Fix minor misra-c 2012 violations
-
-USB Core:
+
+USB Core:
-
-minor rework on USBD_Init()
-USBD_DeInit()
+
+Minor rework on USBD_Init() USBD_DeInit()
-
-Fix warning issue with Keil due to missing
-return value of setup API
+
+Fix warning issue with Keil due to missing return value of setup
+API
-
-USB CDC Class:
+
+USB CDC Class:
-
-Fix file indentation
+
+Fix file indentation
-
-Avoid accessing to NULL pointer in case
-TransmitCplt() user fops is not defined to allow application
-compatibility with device library version below v2.6.0
+
+Avoid accessing NULL pointer in case TransmitCplt() user fops is not
+defined to allow application compatibility with device library version
+below v2.6.0
@@ -553,81 +677,78 @@
Main Changes
V2.6.0 /
27-December-2019
-
Main Changes
+
+Main Changes
+
-
+Headline
-
-Integration of three new USB device Class
-drivers:CDC ECM , CDC RNDIS Microsoft, USB Billboard
+
+Integration of three new USB device Class drivers: CDC ECM, CDC
+RNDIS Microsoft, USB Billboard
-
-Fix mandatory misra-c 2012 violations
+
+Fix mandatory misra-c 2012 violations
-
-update user core and class template
-files
+
+Update user core and class template files
-
-USB Core:
+
+USB Core:
-
-Fix unexpected EP0 stall during
-enumeration phase
+
+Fix unexpected EP0 stall during enumeration phase
-
-Improve APIs error management and prevent
-accessing NULL pointers
+
+Improve APIs error management and prevent accessing NULL
+pointers
-
-USB MSC Class:
+
+USB MSC Class:
-
-Fix USBCV specific class tests
+
+Fix USBCV specific class tests
-
-Fix multiple error with SCSI commands
-handling
+
+Fix multiple errors with SCSI commands handling
-
-Protect medium access when host ask for
-medium ejection
+
+Protect medium access when host asks for medium ejection
-
-USB CDC Class:
+
+USB CDC Class:
-
-Add new function to inform user that
-current IN transfer is completed
+
+Add new function to inform user that current IN transfer is
+completed
-
-update transmit and receive APIs to
-transfer up to 64KB
+
+Update transmit and receive APIs to transfer up to 64KB
-
-USB AUDIO Class:
+
+USB AUDIO Class:
-
-Fix audio sync start buffer size
+
+Fix audio sync start buffer size
-
-update user callback periodicTC args by
-adding pointer to user buffer and size
+
+Update user callback periodicTC args by adding pointer to user
+buffer and size
-
-USB CustomHID Class:
+
+USB CustomHID Class:
-
-Rework the OUT transfer complete and
-prevent automatically re-enabling the OUT EP
+
+Rework the OUT transfer complete and prevent automatically
+re-enabling the OUT EP
-
-Add new user API to restart the OUT
-transfer: USBD_CUSTOM_HID_ReceivePacket()
+
+Add new user API to restart the OUT transfer:
+USBD_CUSTOM_HID_ReceivePacket()
@@ -638,37 +759,37 @@
Main Changes
V2.5.3 /
30-April-2019
-
Main Changes
+
+Main Changes
+
-
+Headline
-
-Fix misra-c 2012 high severity
-violations
+
+Fix misra-c 2012 high severity violations
-
-Core driver:
+
+Core driver:
-
-protect shared macros __ALIGN_BEGIN,
-__ALIGN_END with C directive #ifndef
+
+Protect shared macros __ALIGN_BEGIN, __ALIGN_END with C directive
+#ifndef
-
-update Core driver and DFU Class driver to
-use USBD_SUPPORT_USER_STRING_DESC instead of
-USBD_SUPPORT_USER_STRING
+
+Update Core driver and DFU Class driver to use
+USBD_SUPPORT_USER_STRING_DESC instead of USBD_SUPPORT_USER_STRING
-
-prevent accessing to NULL pointer if the
-get descriptor functions are not defined
+
+Prevent accessing NULL pointer if the get descriptor functions are
+not defined
-
-Update on USBD_LL_Resume(), restore the
-device state only if the current state is USBD_STATE_SUSPENDED
+
+Update on USBD_LL_Resume(), restore the device state only if the
+current state is USBD_STATE_SUSPENDED
@@ -677,20 +798,22 @@
Main Changes
V2.5.2 /
-27-Mars-2019
+27-March-2019
-
Main Changes
+
+Main Changes
+
-
+Headline
-
-DFU Class: fix compilation warning due to
-unreachable instruction code introduced with CMSIS V5.4.0
-NVIC_SystemReset() prototype change
+
+DFU Class: fix compilation warning due to unreachable instruction
+code introduced with CMSIS V5.4.0 NVIC_SystemReset() prototype
+change
@@ -701,33 +824,33 @@
Main Changes
V2.5.1 /
03-August-2018
-
Main Changes
+
+Main Changes
+
-
+Headline
-
-Update license section by adding path to
-get copy of ST Ultimate Liberty license
+
+Update Legal terms section by adding path to get copy of ST Ultimate
+Liberty Legal terms
-
-Core: Fix unexpected stall during status
-OUT phase
+
+Core: Fix unexpected stall during status OUT phase
-
-DFU Class: rework hdfu struct to prevent
-unaligned addresses
+
+DFU Class: rework hdfu struct to prevent unaligned addresses
-
-MSC Class: fix lba address overflow during
-large file transfers greater than 4Go
+
+MSC Class: fix lba address overflow during large file transfers
+greater than 4 GB
-
-Template Class: add missing Switch case
-Break on USBD_Template_Setup API
+
+Template Class: add missing Switch case Break on USBD_Template_Setup
+API
@@ -738,48 +861,44 @@
Main Changes
V2.5.0 /
15-December-2017
-
Main Changes
+
+Main Changes
+
-
+Headline
-
-Update license section
+
+Update Legal terms section
-
-Update some functions to be MISRAC 2004
-compliant
+
+Update some functions to be MISRAC 2004 compliant
-
-Add HS and OtherSpeed configuration
-descriptor for HID and CustomHID classes
+
+Add HS and OtherSpeed configuration descriptor for HID and CustomHID
+classes
-
-Correct error handling in all class setup
-function
+
+Correct error handling in all class setup function
-
-Add usbd_desc_template.c/
-usbd_desc_template.h templates files
+
+Add usbd_desc_template.c/ usbd_desc_template.h templates files
-
-Add support of class and vendor
-request
+
+Add support of class and vendor request
-
-CDC Class: fix zero-length packet issue in
-bulk IN transfer
+
+CDC Class: fix zero-length packet issue in bulk IN transfer
-
-Fix compilation warning with unused
-arguments for some functions
+
+Fix compilation warning with unused arguments for some
+functions
-
-Improve USB Core enumeration state
-machine
+
+Improve USB Core enumeration state machine
@@ -790,20 +909,22 @@
Main Changes
V2.4.2 /
11-December-2015
-
Main Changes
+
+Main Changes
+
-
+Headline
-
-CDC Class
+
+CDC Class
-
-usbd_cdc.c: change #include “USBD_CDC.h”
-by #include “usbd_cdc.h”
+
+usbd_cdc.c: change #include “USBD_CDC.h” by #include
+“usbd_cdc.h”
@@ -814,37 +935,37 @@
Main Changes
V2.4.1 /
19-June-2015
-
Main Changes
+
+Main Changes
+
-
+Headline
-
-CDC Class
+
+CDC Class
-
-usbd_cdc.c: comments update
+
+usbd_cdc.c: comments update
-
-MSC Class
+
+MSC Class
-
-usbd_msc_bot.h: update to be C++
-compliant
+
+usbd_msc_bot.h: update to be C++ compliant
-
-AUDIO Class
+
+AUDIO Class
-
-usbd_audio.c: fix issue when Host sends
-GetInterface command it gets a wrong value
+
+usbd_audio.c: fix issue when Host sends GetInterface command it gets
+a wrong value
-
-usbd_audio.c: remove useless management of
-DMA half transfer
+
+usbd_audio.c: remove useless management of DMA half transfer
@@ -855,56 +976,55 @@
Main Changes
V2.4.0 /
28-February-2015
-
Main Changes
+
+Main Changes
+
-
+Headline
-
-Core Driver
+
+Core Driver
-
-Add support of Link Power Management
-(LPM): add new API GetBOSDescriptor(), that is used only if
-USBD_LPM_ENABLED switch is enabled in usbd_conf.h file
+
+Add support of Link Power Management (LPM): add new API
+GetBOSDescriptor(), that is used only if USBD_LPM_ENABLED switch is
+enabled in usbd_conf.h file
-
-usbd_core.c: Fix bug of unsupported
-premature Host Out stage during data In stage (ie. when endpoint 0
-maximum data size is 8 and Host requests GetDeviceDescriptor for the
-first time)
+
+usbd_core.c: Fix bug of unsupported premature Host Out stage during
+data In stage (ie. when endpoint 0 maximum data size is 8 and Host
+requests GetDeviceDescriptor for the first time)
-
-usbd_ctlreq.c: Fix bug of unsupported
-Endpoint Class requests (ie. Audio SetCurrent request for endpoint
-sampling rate setting)
+
+usbd_ctlreq.c: Fix bug of unsupported Endpoint Class requests (ie.
+Audio SetCurrent request for endpoint sampling rate setting)
-
-HID Class
+
+HID Class
-
-Updating Polling time API
-USBD_HID_GetPollingInterval() to query this period for HS and FS
+
+Updating Polling time API USBD_HID_GetPollingInterval() to query
+this period for HS and FS
-
-usbd_hid.c: Fix USBD_LL_CloseEP() function
-call in USBD_HID_DeInit() replacing endpoint size by endpoint
-address.
+
+usbd_hid.c: Fix USBD_LL_CloseEP() function call in USBD_HID_DeInit()
+replacing endpoint size by endpoint address.
-
-CDC Class
+
+CDC Class
-
-usbd_cdc.c: Add missing GetInterface
-request management in USBD_CDC_Setup() function
+
+usbd_cdc.c: Add missing GetInterface request management in
+USBD_CDC_Setup() function
-
-usbd_cdc.c: Update USBD_CDC_Setup()
-function to allow correct user implementation of
-CDC_SET_CONTROL_LINE_STATE and similar no-data setup requests.
+
+usbd_cdc.c: Update USBD_CDC_Setup() function to allow correct user
+implementation of CDC_SET_CONTROL_LINE_STATE and similar no-data setup
+requests.
@@ -915,32 +1035,32 @@
Main Changes
V2.3.0 /
04-November-2014
-
Main Changes
+
+Main Changes
+
-
+Headline
-
-Update all drivers to be C++
-compliant
+
+Update all drivers to be C++ compliant
-
-CDC Class
+
+CDC Class
-
-usbd_cdc.c: fix clear flag issue in
-USBD_CDC_TransmitPacket() function
+
+usbd_cdc.c: fix clear flag issue in USBD_CDC_TransmitPacket()
+function
-
-usbd_cdc_if_template.c: update
-TEMPLATE_Receive() function header comment
+
+usbd_cdc_if_template.c: update TEMPLATE_Receive() function header
+comment
-
-Miscellaneous source code comments
-update
+
+Miscellaneous source code comments update
@@ -951,52 +1071,50 @@
Main Changes
V2.2.0 /
13-June-2014
-
Main Changes
+
+Main Changes
+
-
+Headline
-
-Source code comments review and
-update
+
+Source code comments review and update
-
-HID class
+
+HID class
-
-Remove unused API
-USBD_HID_DeviceQualifierDescriptor()
+
+Remove unused API USBD_HID_DeviceQualifierDescriptor()
-
-Add a new API in the HID class to query
-the poll time USBD_HID_GetPollingInterval()
+
+Add a new API in the HID class to query the poll time
+USBD_HID_GetPollingInterval()
-
-CDC class
+
+CDC class
-
-Bug fix: missing handling ZeroLength Setup
-request
+
+Bug fix: missing handling ZeroLength Setup request
-
-All classes
+
+All classes
-
-Add alias for the class definition, it’s
-defined as macro with capital letter
+
+Add alias for the class definition, it’s defined as macro with
+capital letter
-
-ex. for the HID, the USBD_HID_CLASS macro
-is defined this way #define USBD_HID_CLASS &USBD_HID
+
+ex. for the HID, the USBD_HID_CLASS macro is defined this way
+#define USBD_HID_CLASS &USBD_HID
-
-and the application code can use the
-previous definition: &USBD_HID ex.
-USBD_RegisterClass(&USBD_Device, &USBD_HID) or the new
-USBD_HID_CLASS ex. USBD_RegisterClass(&USBD_Device,
+
+and the application code can use the previous definition:
+&USBD_HID ex. USBD_RegisterClass(&USBD_Device, &USBD_HID) or
+the new USBD_HID_CLASS ex. USBD_RegisterClass(&USBD_Device,
USBD_HID_CLASS)
@@ -1008,45 +1126,44 @@ Main Changes
V2.1.0 /
22-April-2014
-
Main Changes
+
+Main Changes
+
-
+Headline
-
-usbd_conf_template.c: update file with the
-right content (it was using MSC memory management layer)
+
+usbd_conf_template.c: update file with the right content (it was
+using MSC memory management layer)
-
-usbd_conf_template.h: change include of
-stm32f4xx.h by stm32xxx.h and add comment to inform user to adapt it to
-the device used
+
+usbd_conf_template.h: change include of stm32f4xx.h by stm32xxx.h
+and add comment to inform user to adapt it to the device used
-
-Several enhancements in CustomHID
-class
+
+Several enhancements in CustomHID class
-
-Update the Custom HID class driver to
-simplify the link with user processes
+
+Update the Custom HID class driver to simplify the link with user
+processes
-
-Optimize the Custom HID class driver and
-reduce footprint
+
+Optimize the Custom HID class driver and reduce footprint
-
-Add USBD_CUSTOM_HID_RegisterInterface()
-API to link user process to custom HID class
+
+Add USBD_CUSTOM_HID_RegisterInterface() API to link user process to
+custom HID class
-
-Add Custom HID interface template file
+
+Add Custom HID interface template file
usbd_customhid_if_template.c/h
-
-Miscellaneous comments update
+
+Miscellaneous comments update
@@ -1057,24 +1174,27 @@
Main Changes
V2.0.0 /
18-February-2014
-
Main Changes
+
+Main Changes
+
Major update based on STM32Cube specification.
-
+Headline
-
-Library Core, Classes architecture and
-APIs modified vs. V1.1.0, and thus the 2 versions are not
-compatible.
+
+Library Core, Classes architecture and APIs modified vs. V1.1.0, and
+thus the 2 versions are not compatible.
-
This version has to be used only with STM32Cube based
-development
+
+This version has to be used only with STM32Cube based
+development
+
@@ -1082,35 +1202,35 @@
Main Changes
V1.1.0 /
19-March-2012
-
Main Changes
+
+Main Changes
+
-
+Headline
-
-Official support of STM32F4xx devices
+
+Official support of STM32F4xx devices
-
-All source files: license disclaimer text
-update and add link to the License file on ST Internet.
+
+All source files: Legal terms disclaimer text update and add link to
+the Legal terms file on ST Internet.
-
-Handle test mode in the set feature
-request
+
+Handle test mode in the set feature request
-
-Handle dynamically the USB SELF POWERED
-feature
+
+Handle dynamically the USB SELF POWERED feature
-
-Handle correctly the USBD_CtlError process
-to take into account error during Control OUT stage
+
+Handle correctly the USBD_CtlError process to take into account
+error during Control OUT stage
-
-Miscellaneous bug fix
+
+Miscellaneous bug fix
@@ -1121,11 +1241,13 @@
Main Changes
V1.0.0 /
22-July-2011
-
Main Changes
+
+Main Changes
+
First official version for STM32F105/7xx and STM32F2xx devices
-
+
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/SW_Security_Level.html b/system/Middlewares/ST/STM32_USB_Device_Library/SW_Security_Level.html
new file mode 100644
index 0000000000..d46ebecd3c
--- /dev/null
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/SW_Security_Level.html
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
SW_Security_Level
+
+
+
+
+
+
Copyright (c) 2026
+STMicroelectronics.
+
All rights reserved
+
+
SW Security Classification
+
STM32Trust
+software security policies define four levels of SW Security
+classification, each level defines a set of security policies for the
+applicable SW.
+
+
+
+SW
+SW Security Level
+
+
+
+
+STM32Cube USB Device Library
+Medium
+
+
+
+
+
IMPORTANT SECURITY NOTICE
+
The STMicroelectronics group of companies (ST) places a high value on
+product security, which is why the ST product(s) identified in this
+documentation may be certified by various security certification bodies
+and/or may implement our own security measures as set forth herein.
+However, no level of security certification and/or built-in security
+measures can guarantee that ST products are resistant to all forms of
+attacks. As such, it is the responsibility of each of ST’s customers to
+determine if the level of security provided in an ST product meets the
+customer needs both in relation to the ST product alone, as well as when
+combined with other components and/or software for the customer end
+product or application. In particular, take note that:
+
+ST products may have been certified by one or more security
+certification bodies, such as Platform Security Architecture
+(www.psacertified.org) and/or Security Evaluation standard for IoT
+Platforms (www.trustcb.com). For details concerning whether the ST
+product(s) referenced herein have received security certification along
+with the level and current status of such certification, either visit
+the relevant certification standards website or go to the relevant
+product page on www.st.com for the most up to date information. As the
+status and/or level of security certification for an ST product can
+change from time to time, customers should re-check security
+certification status/level as needed. If an ST product is not shown to
+be certified under a particular security standard, customers should not
+assume it is certified.
+Certification bodies have the right to evaluate, grant and revoke
+security certification in relation to ST products. These certification
+bodies are therefore independently responsible for granting or revoking
+security certification for an ST product, and ST does not take any
+responsibility for mistakes, evaluations, assessments, testing, or other
+activity carried out by the certification body with respect to any ST
+product.
+Industry-based cryptographic algorithms (such as AES, DES, or
+MD5) and other open standard technologies which may be used in
+conjunction with an ST product are based on standards which were not
+developed by ST. ST does not take responsibility for any flaws in such
+cryptographic algorithms or open technologies or for any methods which
+have been or may be developed to bypass, decrypt or crack such
+algorithms or technologies.
+While robust security testing may be done, no level of
+certification can absolutely guarantee protections against all attacks,
+including, for example, against advanced attacks which have not been
+tested for, against new or unidentified forms of attack, or against any
+form of attack when using an ST product outside of its specification or
+intended use, or in conjunction with other components or software which
+are used by customer to create their end product or application. ST is
+not responsible for resistance against such attacks. As such, regardless
+of the incorporated security features and/or any information or support
+that may be provided by ST, each customer is solely responsible for
+determining if the level of attacks tested for meets their needs, both
+in relation to the ST product alone and when incorporated into a
+customer end product or application.
+All security features of ST products (inclusive of any hardware,
+software, documentation, and the like), including but not limited to any
+enhanced security features added by ST, are provided on an “AS IS”
+BASIS.
+
+
AS SUCH, TO THE EXTENT PERMITTED BY APPLICABLE LAW, ST DISCLAIMS ALL
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE,
+unless the applicable written and signed contract terms specifically
+provide otherwise.
+
+
IMPORTANT NOTICE - READ
+CAREFULLY
+
STMicroelectronics NV and its subsidiaries (“ST”) reserve the right
+to make changes, corrections, enhancements, modifications, and
+improvements to ST products and/or to this document at any time without
+notice. Purchasers should obtain the latest relevant information on ST
+products before placing orders. ST products are sold pursuant to ST’s
+terms and conditions of sale in place at the time of order
+acknowledgment.
+
Purchasers are solely responsible for the choice, selection, and use
+of ST products and ST assumes no liability for application assistance or
+the design of purchasers’ products. No license, express or implied, to
+any intellectual property right is granted by ST herein. Resale of ST
+products with provisions different from the information set forth herein
+shall void any warranty granted by ST for such product. ST and the ST
+logo are trademarks of ST. For additional information about ST
+trademarks, refer to www.st.com/trademarks. All other product or service
+names are the property of their respective owners. Information in this
+document supersedes and replaces information previously supplied in any
+prior versions of this document.
+
Copyright (c) 2026 STMicroelectronics - All rights reserved
+
+
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/SW_Security_Level.md b/system/Middlewares/ST/STM32_USB_Device_Library/SW_Security_Level.md
new file mode 100644
index 0000000000..9701595cad
--- /dev/null
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/SW_Security_Level.md
@@ -0,0 +1,47 @@
+
+
+## Copyright (c) 2026 STMicroelectronics.
+## All rights reserved
+
+
+
+## SW Security Classification
+
+[STM32Trust software security policies](https://wiki.st.com/stm32mcu/wiki/Security:STM32Trust_software_security_policies) define four levels of SW Security classification, each level defines a set of security policies for the applicable SW.
+
+| SW | SW Security Level
+|:-------------------------------- |:-------|
+| **STM32Cube USB Device Library** | Medium|
+
+
+
+
+## IMPORTANT SECURITY NOTICE
+
+The STMicroelectronics group of companies (ST) places a high value on product security, which is why the ST product(s) identified in this documentation may be certified by various security certification bodies and/or may implement our own security measures as set forth herein. However, no level of security certification and/or built-in security measures can guarantee that ST products are resistant to all forms of attacks. As such, it is the responsibility of each of ST's customers to determine if the level of security provided in an ST product meets the customer needs both in relation to the ST product alone, as well as when combined with other components and/or software for the customer end product or application. In particular, take note that:
+
+- ST products may have been certified by one or more security certification bodies, such as Platform Security Architecture (www.psacertified.org) and/or Security Evaluation standard for IoT Platforms (www.trustcb.com). For details concerning whether the ST product(s) referenced herein have received security certification along with the level and current status of such certification, either visit the relevant certification standards website or go to the relevant product page on www.st.com for the most up to date information. As the status and/or level of security certification for an ST product can change from time to time, customers should re-check security certification status/level as needed. If an ST product is not shown to be certified under a particular security standard, customers should not assume it is certified.
+
+- Certification bodies have the right to evaluate, grant and revoke security certification in relation to ST products. These certification bodies are therefore independently responsible for granting or revoking security certification for an ST product, and ST does not take any responsibility for mistakes, evaluations, assessments, testing, or other activity carried out by the certification body with respect to any ST product.
+
+- Industry-based cryptographic algorithms (such as AES, DES, or MD5) and other open standard technologies which may be used in conjunction with an ST product are based on standards which were not developed by ST. ST does not take responsibility for any flaws in such cryptographic algorithms or open technologies or for any methods which have been or may be developed to bypass, decrypt or crack such algorithms or technologies.
+
+- While robust security testing may be done, no level of certification can absolutely guarantee protections against all attacks, including, for example, against advanced attacks which have not been tested for, against new or unidentified forms of attack, or against any form of attack when using an ST product outside of its specification or intended use, or in conjunction with other components or software which are used by customer to create their end product or application. ST is not responsible for resistance against such attacks. As such, regardless of the incorporated security features and/or any information or support that may be provided by ST, each customer is solely responsible for determining if the level of attacks tested for meets their needs, both in relation to the ST product alone and when incorporated into a customer end product or application.
+
+- All security features of ST products (inclusive of any hardware, software, documentation, and the like), including but not limited to any enhanced security features added by ST, are provided on an "AS IS" BASIS.
+
+AS SUCH, TO THE EXTENT PERMITTED BY APPLICABLE LAW, ST DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, unless the applicable written and signed contract terms specifically provide otherwise.
+
+
+
+## IMPORTANT NOTICE - READ CAREFULLY
+
+STMicroelectronics NV and its subsidiaries ("ST") reserve the right to make changes, corrections, enhancements, modifications, and improvements to ST products and/or to this document at any time without notice. Purchasers should obtain the latest relevant information on ST products before placing orders. ST products are sold pursuant to ST's terms and conditions of sale in place at the time of order acknowledgment.
+
+Purchasers are solely responsible for the choice, selection, and use of ST products and ST assumes no liability for application assistance or the design of purchasers' products.
+No license, express or implied, to any intellectual property right is granted by ST herein.
+Resale of ST products with provisions different from the information set forth herein shall void any warranty granted by ST for such product.
+ST and the ST logo are trademarks of ST. For additional information about ST trademarks, refer to www.st.com/trademarks. All other product or service names are the property of their respective owners.
+Information in this document supersedes and replaces information previously supplied in any prior versions of this document.
+
+Copyright (c) 2026 STMicroelectronics - All rights reserved
\ No newline at end of file
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/_htmresc/Add_button.svg b/system/Middlewares/ST/STM32_USB_Device_Library/_htmresc/Add_button.svg
new file mode 100644
index 0000000000..c211545dad
--- /dev/null
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/_htmresc/Add_button.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/_htmresc/Update.svg b/system/Middlewares/ST/STM32_USB_Device_Library/_htmresc/Update.svg
new file mode 100644
index 0000000000..f88381f1e6
--- /dev/null
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/_htmresc/Update.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/_htmresc/mini-st.css b/system/Middlewares/ST/STM32_USB_Device_Library/_htmresc/mini-st_2020.css
similarity index 99%
rename from system/Middlewares/ST/STM32_USB_Device_Library/_htmresc/mini-st.css
rename to system/Middlewares/ST/STM32_USB_Device_Library/_htmresc/mini-st_2020.css
index 986f4d4205..7c8c3e1df7 100644
--- a/system/Middlewares/ST/STM32_USB_Device_Library/_htmresc/mini-st.css
+++ b/system/Middlewares/ST/STM32_USB_Device_Library/_htmresc/mini-st_2020.css
@@ -45,8 +45,16 @@ body {
@background: var(--back-color);
background: var(--back-color) linear-gradient(#ffd200, #ffd200) repeat-y left top;
background-size: var(--background-margin);
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
}
+footer.sticky,
+.sticky {
+ margin-top: auto;
+}
+
details {
display: block; }
@@ -78,7 +86,7 @@ h1 {
h2 {
font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio) );
- border-style: none none solid none ;
+ border-style: none none solid none ;
border-width: thin;
border-color: var(--border-color); }
h3 {
@@ -1597,7 +1605,7 @@ span.icon-user {
span.icon-st-update {
background-image: url("Update.svg"); }
span.icon-st-add {
- background-image: url("Add button.svg"); }
+ background-image: url("Add_button.svg"); }
/*
Definitions for utilities and helper classes.