4 Commits

Author SHA1 Message Date
slimih
2022e75b01 Release v2.11.1 2022-10-05 11:45:31 +01:00
slimih
555ce2b1f7 Release v2.11.0 2022-04-07 10:51:12 +01:00
slimih
69fa8a86ad Release v2.10.0 2021-09-16 17:30:01 +01:00
slimih
06808a92fe Release v2.9.0 2021-09-09 10:10:00 +01:00
87 changed files with 17681 additions and 4166 deletions

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -58,7 +57,10 @@ extern "C" {
#define AUDIO_FS_BINTERVAL 0x01U
#endif /* AUDIO_FS_BINTERVAL */
#ifndef AUDIO_OUT_EP
#define AUDIO_OUT_EP 0x01U
#endif /* AUDIO_OUT_EP */
#define USB_AUDIO_CONFIG_DESC_SIZ 0x6DU
#define AUDIO_INTERFACE_DESC_SIZE 0x09U
#define USB_AUDIO_DESC_SIZ 0x09U
@@ -167,6 +169,115 @@ typedef struct
int8_t (*PeriodicTC)(uint8_t *pbuf, uint32_t size, uint8_t cmd);
int8_t (*GetState)(void);
} USBD_AUDIO_ItfTypeDef;
/*
* Audio Class specification release 1.0
*/
/* Table 4-2: Class-Specific AC Interface Header Descriptor */
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint16_t bcdADC;
uint16_t wTotalLength;
uint8_t bInCollection;
uint8_t baInterfaceNr;
} __PACKED USBD_SpeakerIfDescTypeDef;
/* Table 4-3: Input Terminal Descriptor */
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bTerminalID;
uint16_t wTerminalType;
uint8_t bAssocTerminal;
uint8_t bNrChannels;
uint16_t wChannelConfig;
uint8_t iChannelNames;
uint8_t iTerminal;
} __PACKED USBD_SpeakerInDescTypeDef;
/* USB Speaker Audio Feature Unit Descriptor */
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bUnitID;
uint8_t bSourceID;
uint8_t bControlSize;
uint16_t bmaControls;
uint8_t iTerminal;
} __PACKED USBD_SpeakerFeatureDescTypeDef;
/* Table 4-4: Output Terminal Descriptor */
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bTerminalID;
uint16_t wTerminalType;
uint8_t bAssocTerminal;
uint8_t bSourceID;
uint8_t iTerminal;
} __PACKED USBD_SpeakerOutDescTypeDef;
/* Table 4-19: Class-Specific AS Interface Descriptor */
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bTerminalLink;
uint8_t bDelay;
uint16_t wFormatTag;
} __PACKED USBD_SpeakerStreamIfDescTypeDef;
/* USB Speaker Audio Type III Format Interface Descriptor */
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bFormatType;
uint8_t bNrChannels;
uint8_t bSubFrameSize;
uint8_t bBitResolution;
uint8_t bSamFreqType;
uint8_t tSamFreq2;
uint8_t tSamFreq1;
uint8_t tSamFreq0;
} USBD_SpeakerIIIFormatIfDescTypeDef;
/* Table 4-17: Standard AC Interrupt Endpoint Descriptor */
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint16_t wMaxPacketSize;
uint8_t bInterval;
uint8_t bRefresh;
uint8_t bSynchAddress;
} __PACKED USBD_SpeakerEndDescTypeDef;
/* Table 4-21: Class-Specific AS Isochronous Audio Data Endpoint Descriptor */
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptor;
uint8_t bmAttributes;
uint8_t bLockDelayUnits;
uint16_t wLockDelay;
} __PACKED USBD_SpeakerEndStDescTypeDef;
/**
* @}
*/
@@ -198,6 +309,11 @@ uint8_t USBD_AUDIO_RegisterInterface(USBD_HandleTypeDef *pdev,
USBD_AUDIO_ItfTypeDef *fops);
void USBD_AUDIO_Sync(USBD_HandleTypeDef *pdev, AUDIO_OffsetTypeDef offset);
#ifdef USE_USBD_COMPOSITE
uint32_t USBD_AUDIO_GetEpPcktSze(USBD_HandleTypeDef *pdev, uint8_t If, uint8_t Ep);
#endif /* USE_USBD_COMPOSITE */
/**
* @}
*/
@@ -214,5 +330,3 @@ void USBD_AUDIO_Sync(USBD_HandleTypeDef *pdev, AUDIO_OffsetTypeDef offset);
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -41,5 +40,3 @@ extern USBD_AUDIO_ItfTypeDef USBD_AUDIO_Template_fops;
#endif
#endif /* __USBD_AUDIO_IF_TEMPLATE_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -4,6 +4,18 @@
* @author MCD Application Team
* @brief This file provides the Audio core functions.
*
*
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
* @verbatim
*
* ===================================================================
@@ -38,18 +50,6 @@
*
*
* @endverbatim
*
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
@@ -93,11 +93,15 @@ EndBSPDependencies */
/** @defgroup USBD_AUDIO_Private_Macros
* @{
*/
#define AUDIO_SAMPLE_FREQ(frq) (uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16))
#define AUDIO_SAMPLE_FREQ(frq) \
(uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16))
#define AUDIO_PACKET_SZE(frq) (uint8_t)(((frq * 2U * 2U)/1000U) & 0xFFU), \
(uint8_t)((((frq * 2U * 2U)/1000U) >> 8) & 0xFFU)
#define AUDIO_PACKET_SZE(frq) \
(uint8_t)(((frq * 2U * 2U) / 1000U) & 0xFFU), (uint8_t)((((frq * 2U * 2U) / 1000U) >> 8) & 0xFFU)
#ifdef USE_USBD_COMPOSITE
#define AUDIO_PACKET_SZE_WORD(frq) (uint32_t)((((frq) * 2U * 2U)/1000U))
#endif /* USE_USBD_COMPOSITE */
/**
* @}
*/
@@ -111,9 +115,10 @@ static uint8_t USBD_AUDIO_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
static uint8_t USBD_AUDIO_Setup(USBD_HandleTypeDef *pdev,
USBD_SetupReqTypedef *req);
#ifndef USE_USBD_COMPOSITE
static uint8_t *USBD_AUDIO_GetCfgDesc(uint16_t *length);
static uint8_t *USBD_AUDIO_GetDeviceQualifierDesc(uint16_t *length);
#endif /* USE_USBD_COMPOSITE */
static uint8_t USBD_AUDIO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
static uint8_t USBD_AUDIO_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
static uint8_t USBD_AUDIO_EP0_RxReady(USBD_HandleTypeDef *pdev);
@@ -124,6 +129,7 @@ static uint8_t USBD_AUDIO_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnu
static uint8_t USBD_AUDIO_IsoOutIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum);
static void AUDIO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
static void AUDIO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
static void *USBD_AUDIO_GetAudioHeaderDesc(uint8_t *pConfDesc);
/**
* @}
@@ -145,12 +151,20 @@ USBD_ClassTypeDef USBD_AUDIO =
USBD_AUDIO_SOF,
USBD_AUDIO_IsoINIncomplete,
USBD_AUDIO_IsoOutIncomplete,
#ifdef USE_USBD_COMPOSITE
NULL,
NULL,
NULL,
NULL,
#else
USBD_AUDIO_GetCfgDesc,
USBD_AUDIO_GetCfgDesc,
USBD_AUDIO_GetCfgDesc,
USBD_AUDIO_GetDeviceQualifierDesc,
#endif /* USE_USBD_COMPOSITE */
};
#ifndef USE_USBD_COMPOSITE
/* USB AUDIO device Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_AUDIO_CfgDesc[USB_AUDIO_CONFIG_DESC_SIZ] __ALIGN_END =
{
@@ -166,7 +180,7 @@ __ALIGN_BEGIN static uint8_t USBD_AUDIO_CfgDesc[USB_AUDIO_CONFIG_DESC_SIZ] __ALI
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
#endif /* USBD_SELF_POWERED */
USBD_MAX_POWER, /* MaxPower (mA) */
/* 09 byte*/
@@ -317,7 +331,9 @@ __ALIGN_BEGIN static uint8_t USBD_AUDIO_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIE
0x01,
0x00,
};
#endif /* USE_USBD_COMPOSITE */
static uint8_t AUDIOOutEpAdd = AUDIO_OUT_EP;
/**
* @}
*/
@@ -343,24 +359,30 @@ static uint8_t USBD_AUDIO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
if (haudio == NULL)
{
pdev->pClassData = NULL;
pdev->pClassDataCmsit[pdev->classId] = NULL;
return (uint8_t)USBD_EMEM;
}
pdev->pClassData = (void *)haudio;
pdev->pClassDataCmsit[pdev->classId] = (void *)haudio;
pdev->pClassData = pdev->pClassDataCmsit[pdev->classId];
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
AUDIOOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_ISOC, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (pdev->dev_speed == USBD_SPEED_HIGH)
{
pdev->ep_out[AUDIO_OUT_EP & 0xFU].bInterval = AUDIO_HS_BINTERVAL;
pdev->ep_out[AUDIOOutEpAdd & 0xFU].bInterval = AUDIO_HS_BINTERVAL;
}
else /* LOW and FULL-speed endpoints */
{
pdev->ep_out[AUDIO_OUT_EP & 0xFU].bInterval = AUDIO_FS_BINTERVAL;
pdev->ep_out[AUDIOOutEpAdd & 0xFU].bInterval = AUDIO_FS_BINTERVAL;
}
/* Open EP OUT */
(void)USBD_LL_OpenEP(pdev, AUDIO_OUT_EP, USBD_EP_TYPE_ISOC, AUDIO_OUT_PACKET);
pdev->ep_out[AUDIO_OUT_EP & 0xFU].is_used = 1U;
(void)USBD_LL_OpenEP(pdev, AUDIOOutEpAdd, USBD_EP_TYPE_ISOC, AUDIO_OUT_PACKET);
pdev->ep_out[AUDIOOutEpAdd & 0xFU].is_used = 1U;
haudio->alt_setting = 0U;
haudio->offset = AUDIO_OFFSET_UNKNOWN;
@@ -369,7 +391,7 @@ static uint8_t USBD_AUDIO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
haudio->rd_enable = 0U;
/* Initialize the Audio output Hardware layer */
if (((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->Init(USBD_AUDIO_FREQ,
if (((USBD_AUDIO_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init(USBD_AUDIO_FREQ,
AUDIO_DEFAULT_VOLUME,
0U) != 0U)
{
@@ -377,7 +399,7 @@ static uint8_t USBD_AUDIO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
}
/* Prepare Out endpoint to receive 1st packet */
(void)USBD_LL_PrepareReceive(pdev, AUDIO_OUT_EP, haudio->buffer,
(void)USBD_LL_PrepareReceive(pdev, AUDIOOutEpAdd, haudio->buffer,
AUDIO_OUT_PACKET);
return (uint8_t)USBD_OK;
@@ -394,16 +416,22 @@ static uint8_t USBD_AUDIO_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
UNUSED(cfgidx);
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
AUDIOOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_ISOC, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
/* Open EP OUT */
(void)USBD_LL_CloseEP(pdev, AUDIO_OUT_EP);
pdev->ep_out[AUDIO_OUT_EP & 0xFU].is_used = 0U;
pdev->ep_out[AUDIO_OUT_EP & 0xFU].bInterval = 0U;
(void)USBD_LL_CloseEP(pdev, AUDIOOutEpAdd);
pdev->ep_out[AUDIOOutEpAdd & 0xFU].is_used = 0U;
pdev->ep_out[AUDIOOutEpAdd & 0xFU].bInterval = 0U;
/* DeInit physical Interface components */
if (pdev->pClassData != NULL)
if (pdev->pClassDataCmsit[pdev->classId] != NULL)
{
((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->DeInit(0U);
(void)USBD_free(pdev->pClassData);
((USBD_AUDIO_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit(0U);
(void)USBD_free(pdev->pClassDataCmsit[pdev->classId]);
pdev->pClassDataCmsit[pdev->classId] = NULL;
pdev->pClassData = NULL;
}
@@ -426,7 +454,7 @@ static uint8_t USBD_AUDIO_Setup(USBD_HandleTypeDef *pdev,
uint16_t status_info = 0U;
USBD_StatusTypeDef ret = USBD_OK;
haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassData;
haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (haudio == NULL)
{
@@ -471,11 +499,18 @@ static uint8_t USBD_AUDIO_Setup(USBD_HandleTypeDef *pdev,
case USB_REQ_GET_DESCRIPTOR:
if ((req->wValue >> 8) == AUDIO_DESCRIPTOR_TYPE)
{
pbuf = USBD_AUDIO_CfgDesc + 18;
pbuf = (uint8_t *)USBD_AUDIO_GetAudioHeaderDesc(pdev->pConfDesc);
if (pbuf != NULL)
{
len = MIN(USB_AUDIO_DESC_SIZ, req->wLength);
(void)USBD_CtlSendData(pdev, pbuf, len);
}
else
{
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
}
}
break;
case USB_REQ_GET_INTERFACE:
@@ -529,11 +564,10 @@ static uint8_t USBD_AUDIO_Setup(USBD_HandleTypeDef *pdev,
return (uint8_t)ret;
}
#ifndef USE_USBD_COMPOSITE
/**
* @brief USBD_AUDIO_GetCfgDesc
* return configuration descriptor
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
@@ -543,7 +577,7 @@ static uint8_t *USBD_AUDIO_GetCfgDesc(uint16_t *length)
return USBD_AUDIO_CfgDesc;
}
#endif /* USE_USBD_COMPOSITE */
/**
* @brief USBD_AUDIO_DataIn
* handle data IN Stage
@@ -569,7 +603,7 @@ static uint8_t USBD_AUDIO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
static uint8_t USBD_AUDIO_EP0_RxReady(USBD_HandleTypeDef *pdev)
{
USBD_AUDIO_HandleTypeDef *haudio;
haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassData;
haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (haudio == NULL)
{
@@ -582,7 +616,7 @@ static uint8_t USBD_AUDIO_EP0_RxReady(USBD_HandleTypeDef *pdev)
if (haudio->control.unit == AUDIO_OUT_STREAMING_CTRL)
{
((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->MuteCtl(haudio->control.data[0]);
((USBD_AUDIO_ItfTypeDef *)pdev->pUserData[pdev->classId])->MuteCtl(haudio->control.data[0]);
haudio->control.cmd = 0U;
haudio->control.len = 0U;
}
@@ -620,6 +654,7 @@ static uint8_t USBD_AUDIO_SOF(USBD_HandleTypeDef *pdev)
* @brief USBD_AUDIO_SOF
* handle SOF event
* @param pdev: device instance
* @param offset: audio offset
* @retval status
*/
void USBD_AUDIO_Sync(USBD_HandleTypeDef *pdev, AUDIO_OffsetTypeDef offset)
@@ -627,12 +662,12 @@ void USBD_AUDIO_Sync(USBD_HandleTypeDef *pdev, AUDIO_OffsetTypeDef offset)
USBD_AUDIO_HandleTypeDef *haudio;
uint32_t BufferSize = AUDIO_TOTAL_BUF_SIZE / 2U;
if (pdev->pClassData == NULL)
if (pdev->pClassDataCmsit[pdev->classId] == NULL)
{
return;
}
haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassData;
haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
haudio->offset = offset;
@@ -678,7 +713,7 @@ void USBD_AUDIO_Sync(USBD_HandleTypeDef *pdev, AUDIO_OffsetTypeDef offset)
if (haudio->offset == AUDIO_OFFSET_FULL)
{
((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->AudioCmd(&haudio->buffer[0],
((USBD_AUDIO_ItfTypeDef *)pdev->pUserData[pdev->classId])->AudioCmd(&haudio->buffer[0],
BufferSize, AUDIO_CMD_PLAY);
haudio->offset = AUDIO_OFFSET_NONE;
}
@@ -724,33 +759,38 @@ static uint8_t USBD_AUDIO_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
uint16_t PacketSize;
USBD_AUDIO_HandleTypeDef *haudio;
haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassData;
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
AUDIOOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_ISOC, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (haudio == NULL)
{
return (uint8_t)USBD_FAIL;
}
if (epnum == AUDIO_OUT_EP)
if (epnum == AUDIOOutEpAdd)
{
/* Get received data packet length */
PacketSize = (uint16_t)USBD_LL_GetRxDataSize(pdev, epnum);
/* Packet received Callback */
((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->PeriodicTC(&haudio->buffer[haudio->wr_ptr],
((USBD_AUDIO_ItfTypeDef *)pdev->pUserData[pdev->classId])->PeriodicTC(&haudio->buffer[haudio->wr_ptr],
PacketSize, AUDIO_OUT_TC);
/* Increment the Buffer pointer or roll it back when all buffers are full */
haudio->wr_ptr += PacketSize;
if (haudio->wr_ptr == AUDIO_TOTAL_BUF_SIZE)
if (haudio->wr_ptr >= AUDIO_TOTAL_BUF_SIZE)
{
/* All buffers are full: roll back */
haudio->wr_ptr = 0U;
if (haudio->offset == AUDIO_OFFSET_UNKNOWN)
{
((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->AudioCmd(&haudio->buffer[0],
((USBD_AUDIO_ItfTypeDef *)pdev->pUserData[pdev->classId])->AudioCmd(&haudio->buffer[0],
AUDIO_TOTAL_BUF_SIZE / 2U,
AUDIO_CMD_START);
haudio->offset = AUDIO_OFFSET_NONE;
@@ -766,7 +806,7 @@ static uint8_t USBD_AUDIO_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
}
/* Prepare Out endpoint to receive next audio packet */
(void)USBD_LL_PrepareReceive(pdev, AUDIO_OUT_EP,
(void)USBD_LL_PrepareReceive(pdev, AUDIOOutEpAdd,
&haudio->buffer[haudio->wr_ptr],
AUDIO_OUT_PACKET);
}
@@ -777,14 +817,14 @@ static uint8_t USBD_AUDIO_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
/**
* @brief AUDIO_Req_GetCurrent
* Handles the GET_CUR Audio control request.
* @param pdev: instance
* @param pdev: device instance
* @param req: setup class request
* @retval status
*/
static void AUDIO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
USBD_AUDIO_HandleTypeDef *haudio;
haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassData;
haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (haudio == NULL)
{
@@ -801,14 +841,14 @@ static void AUDIO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef
/**
* @brief AUDIO_Req_SetCurrent
* Handles the SET_CUR Audio control request.
* @param pdev: instance
* @param pdev: device instance
* @param req: setup class request
* @retval status
*/
static void AUDIO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
USBD_AUDIO_HandleTypeDef *haudio;
haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassData;
haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (haudio == NULL)
{
@@ -826,7 +866,7 @@ static void AUDIO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef
}
}
#ifndef USE_USBD_COMPOSITE
/**
* @brief DeviceQualifierDescriptor
* return Device Qualifier descriptor
@@ -839,9 +879,10 @@ static uint8_t *USBD_AUDIO_GetDeviceQualifierDesc(uint16_t *length)
return USBD_AUDIO_DeviceQualifierDesc;
}
#endif /* USE_USBD_COMPOSITE */
/**
* @brief USBD_AUDIO_RegisterInterface
* @param pdev: device instance
* @param fops: Audio interface callback
* @retval status
*/
@@ -853,10 +894,66 @@ uint8_t USBD_AUDIO_RegisterInterface(USBD_HandleTypeDef *pdev,
return (uint8_t)USBD_FAIL;
}
pdev->pUserData = fops;
pdev->pUserData[pdev->classId] = fops;
return (uint8_t)USBD_OK;
}
#ifdef USE_USBD_COMPOSITE
/**
* @brief USBD_AUDIO_GetEpPcktSze
* @param pdev: device instance (reserved for future use)
* @param If: Interface number (reserved for future use)
* @param Ep: Endpoint number (reserved for future use)
* @retval status
*/
uint32_t USBD_AUDIO_GetEpPcktSze(USBD_HandleTypeDef *pdev, uint8_t If, uint8_t Ep)
{
uint32_t mps;
UNUSED(pdev);
UNUSED(If);
UNUSED(Ep);
mps = AUDIO_PACKET_SZE_WORD(USBD_AUDIO_FREQ);
/* Return the wMaxPacketSize value in Bytes (Freq(Samples)*2(Stereo)*2(HalfWord)) */
return mps;
}
#endif /* USE_USBD_COMPOSITE */
/**
* @brief USBD_AUDIO_GetAudioHeaderDesc
* This function return the Audio descriptor
* @param pdev: device instance
* @param pConfDesc: pointer to Bos descriptor
* @retval pointer to the Audio AC Header descriptor
*/
static void *USBD_AUDIO_GetAudioHeaderDesc(uint8_t *pConfDesc)
{
USBD_ConfigDescTypeDef *desc = (USBD_ConfigDescTypeDef *)(void *)pConfDesc;
USBD_DescHeaderTypeDef *pdesc = (USBD_DescHeaderTypeDef *)(void *)pConfDesc;
uint8_t *pAudioDesc = NULL;
uint16_t ptr;
if (desc->wTotalLength > desc->bLength)
{
ptr = desc->bLength;
while (ptr < desc->wTotalLength)
{
pdesc = USBD_GetNextDesc((uint8_t *)pdesc, &ptr);
if ((pdesc->bDescriptorType == AUDIO_INTERFACE_DESCRIPTOR_TYPE) &&
(pdesc->bDescriptorSubType == AUDIO_CONTROL_HEADER))
{
pAudioDesc = (uint8_t *)pdesc;
break;
}
}
}
return pAudioDesc;
}
/**
* @}
*/
@@ -870,5 +967,3 @@ uint8_t USBD_AUDIO_RegisterInterface(USBD_HandleTypeDef *pdev,
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -197,5 +196,3 @@ static int8_t TEMPLATE_GetState(void)
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2019 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -141,7 +140,7 @@ extern USBD_ClassTypeDef USBD_BB;
#if (USBD_CLASS_BOS_ENABLED == 1)
void *USBD_BB_GetCapDesc(USBD_HandleTypeDef *pdev, uint8_t *buf);
void *USBD_BB_GetAltModeDesc(USBD_HandleTypeDef *pdev, uint8_t *buf, uint8_t idx);
#endif
#endif /* (USBD_CLASS_BOS_ENABLED == 1) */
/**
* @}
@@ -159,5 +158,3 @@ void *USBD_BB_GetAltModeDesc(USBD_HandleTypeDef *pdev, uint8_t *buf, uint8_t idx
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -7,6 +7,17 @@
* - Initialization and Configuration of high and low layer
* - Enumeration as BillBoard Device
* - Error management
******************************************************************************
* @attention
*
* Copyright (c) 2019 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
* @verbatim
*
* ===================================================================
@@ -23,17 +34,6 @@
* @endverbatim
*
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
@@ -93,7 +93,7 @@ static uint8_t *USBD_BB_GetOtherSpeedCfgDesc(uint16_t *length);
#if (USBD_CLASS_BOS_ENABLED == 1)
USBD_BB_DescHeader_t *USBD_BB_GetNextDesc(uint8_t *pbuf, uint16_t *ptr);
#endif
#endif /* USBD_CLASS_BOS_ENABLED */
@@ -122,7 +122,7 @@ USBD_ClassTypeDef USBD_BB =
USBD_BB_GetDeviceQualifierDesc,
#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
NULL,
#endif
#endif /* USBD_SUPPORT_USER_STRING_DESC */
};
/* USB Standard Device Qualifier Descriptor */
@@ -154,7 +154,7 @@ __ALIGN_BEGIN static uint8_t USBD_BB_CfgDesc[USB_BB_CONFIG_DESC_SIZ] __ALIGN_EN
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
#endif /* USBD_SELF_POWERED */
USBD_MAX_POWER, /* MaxPower (mA) */
/* 09 */
@@ -185,7 +185,7 @@ __ALIGN_BEGIN static uint8_t USBD_BB_OtherSpeedCfgDesc[USB_BB_CONFIG_DESC_SIZ]
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
#endif /* USBD_SELF_POWERED */
USBD_MAX_POWER, /* MaxPower (mA) */
/************** Descriptor of BillBoard interface ****************/
@@ -420,7 +420,7 @@ void *USBD_BB_GetCapDesc(USBD_HandleTypeDef *pdev, uint8_t *pBosDesc)
UNUSED(pdev);
USBD_BB_DescHeader_t *pdesc = (USBD_BB_DescHeader_t *)(void *)pBosDesc;
USBD_BosDescTypedef *desc = (USBD_BosDescTypedef *)(void *)pBosDesc;
USBD_BosDescTypeDef *desc = (USBD_BosDescTypeDef *)(void *)pBosDesc;
USBD_BosBBCapDescTypedef *pCapDesc = NULL;
uint16_t ptr;
@@ -456,7 +456,7 @@ void *USBD_BB_GetAltModeDesc(USBD_HandleTypeDef *pdev, uint8_t *pBosDesc, uint8_
UNUSED(pdev);
USBD_BB_DescHeader_t *pdesc = (USBD_BB_DescHeader_t *)(void *)pBosDesc;
USBD_BosDescTypedef *desc = (USBD_BosDescTypedef *)(void *)pBosDesc;
USBD_BosDescTypeDef *desc = (USBD_BosDescTypeDef *)(void *)pBosDesc;
USBD_BB_AltModeCapDescTypeDef *pAltModDesc = NULL;
uint8_t cnt = 0U;
uint16_t ptr;
@@ -485,7 +485,7 @@ void *USBD_BB_GetAltModeDesc(USBD_HandleTypeDef *pdev, uint8_t *pBosDesc, uint8_
}
return (void *)pAltModDesc;
}
#endif
#endif /* USBD_CLASS_BOS_ENABLED */
/**
* @}
@@ -500,5 +500,3 @@ void *USBD_BB_GetAltModeDesc(USBD_HandleTypeDef *pdev, uint8_t *pBosDesc, uint8_
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

373
Class/CCID/Inc/usbd_ccid.h Normal file
View File

@@ -0,0 +1,373 @@
/**
******************************************************************************
* @file usbd_ccid.h
* @author MCD Application Team
* @brief header file for the usbd_ccid.c file.
******************************************************************************
* @attention
*
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_CCID_H
#define __USBD_CCID_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbd_ioreq.h"
/** @addtogroup STM32_USB_DEVICE_LIBRARY
* @{
*/
/** @defgroup usbd_cdc
* @brief This file is the Header file for usbd_ccid.c
* @{
*/
/** @defgroup usbd_cdc_Exported_Defines
* @{
*/
#ifndef CCID_IN_EP
#define CCID_IN_EP 0x81U /* EP1 for data IN */
#endif /* CCID_IN_EP */
#ifndef CCID_OUT_EP
#define CCID_OUT_EP 0x01U /* EP1 for data OUT */
#endif /* CCID_OUT_EP */
#ifndef CCID_CMD_EP
#define CCID_CMD_EP 0x82U /* EP2 for CCID commands */
#endif /* CCID_CMD_EP */
#ifndef CCID_CMD_HS_BINTERVAL
#define CCID_CMD_HS_BINTERVAL 0x10U
#endif /* CCID_CMD_HS_BINTERVAL */
#ifndef CCID_CMD_FS_BINTERVAL
#define CCID_CMD_FS_BINTERVAL 0x10U
#endif /* CCID_CMD_FS_BINTERVAL */
#define CCID_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */
#define CCID_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */
#define CCID_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */
#define USB_CCID_CONFIG_DESC_SIZ 93U
#define CCID_DATA_HS_IN_PACKET_SIZE CCID_DATA_HS_MAX_PACKET_SIZE
#define CCID_DATA_HS_OUT_PACKET_SIZE CCID_DATA_HS_MAX_PACKET_SIZE
#define CCID_DATA_FS_IN_PACKET_SIZE CCID_DATA_FS_MAX_PACKET_SIZE
#define CCID_DATA_FS_OUT_PACKET_SIZE CCID_DATA_FS_MAX_PACKET_SIZE
/*---------------------------------------------------------------------*/
/* CCID definitions */
/*---------------------------------------------------------------------*/
#define CCID_SEND_ENCAPSULATED_COMMAND 0x00U
#define CCID_GET_ENCAPSULATED_RESPONSE 0x01U
#define CCID_SET_COMM_FEATURE 0x02U
#define CCID_GET_COMM_FEATURE 0x03U
#define CCID_CLEAR_COMM_FEATURE 0x04U
#define CCID_SET_LINE_CODING 0x20U
#define CCID_GET_LINE_CODING 0x21U
#define CCID_SET_CONTROL_LINE_STATE 0x22U
#define CCID_SEND_BREAK 0x23U
/*---------------------------------------------------------------------*/
#define REQUEST_ABORT 0x01U
#define REQUEST_GET_CLOCK_FREQUENCIES 0x02U
#define REQUEST_GET_DATA_RATES 0x03U
/*---------------------------------------------------------------------*/
/* The Smart Card Device Class Descriptor definitions */
/*---------------------------------------------------------------------*/
#define CCID_INTERFACE_DESC_SIZE 0x09U
#define USB_DEVICE_CLASS_CCID 0x0BU
#define CCID_CLASS_DESC_SIZE 0x36U
#define CCID_DESC_TYPE 0x21U
#ifndef CCID_VOLTAGE_SUPP
#define CCID_VOLTAGE_SUPP 0x07U
#endif /* CCID_VOLTAGE_SUPP */
#ifndef USBD_CCID_PROTOCOL
#define USBD_CCID_PROTOCOL 0x03U
#endif /* USBD_CCID_PROTOCOL */
#ifndef USBD_CCID_DEFAULT_CLOCK_FREQ
#define USBD_CCID_DEFAULT_CLOCK_FREQ 3600U
#endif /* USBD_CCID_DEFAULT_CLOCK_FREQ */
#ifndef USBD_CCID_MAX_CLOCK_FREQ
#define USBD_CCID_MAX_CLOCK_FREQ USBD_CCID_DEFAULT_CLOCK_FREQ
#endif /* USBD_CCID_MAX_CLOCK_FREQ */
#ifndef USBD_CCID_DEFAULT_DATA_RATE
#define USBD_CCID_DEFAULT_DATA_RATE 9677U
#endif /* USBD_CCID_DEFAULT_DATA_RATE */
#ifndef USBD_CCID_MAX_DATA_RATE
#define USBD_CCID_MAX_DATA_RATE USBD_CCID_DEFAULT_DATA_RATE
#endif /* USBD_CCID_MAX_DATA_RATE */
#ifndef USBD_CCID_MAX_INF_FIELD_SIZE
#define USBD_CCID_MAX_INF_FIELD_SIZE 254U
#endif /* USBD_CCID_MAX_INF_FIELD_SIZE */
#ifndef CCID_MAX_BLOCK_SIZE_HEADER
#define CCID_MAX_BLOCK_SIZE_HEADER 271U
#endif /* CCID_MAX_BLOCK_SIZE_HEADER */
#define TPDU_EXCHANGE 0x01U
#define SHORT_APDU_EXCHANGE 0x02U
#define EXTENDED_APDU_EXCHANGE 0x04U
#define CHARACTER_EXCHANGE 0x00U
#ifndef EXCHANGE_LEVEL_FEATURE
#define EXCHANGE_LEVEL_FEATURE TPDU_EXCHANGE
#endif /* EXCHANGE_LEVEL_FEATURE */
#define CCID_ENDPOINT_DESC_SIZE 0x07U
#ifndef CCID_EP0_BUFF_SIZ
#define CCID_EP0_BUFF_SIZ 64U
#endif /* CCID_EP0_BUFF_SIZ */
#ifndef CCID_BULK_EPIN_SIZE
#define CCID_BULK_EPIN_SIZE 64U
#endif /* CCID_BULK_EPIN_SIZE */
#define CCID_INT_BUFF_SIZ 2U
/*---------------------------------------------------------------------*/
/*
* CCID Class specification revision 1.1
* Command Pipe. Bulk Messages
*/
/* CCID Bulk Out Command definitions */
#define PC_TO_RDR_ICCPOWERON 0x62U
#define PC_TO_RDR_ICCPOWEROFF 0x63U
#define PC_TO_RDR_GETSLOTSTATUS 0x65U
#define PC_TO_RDR_XFRBLOCK 0x6FU
#define PC_TO_RDR_GETPARAMETERS 0x6CU
#define PC_TO_RDR_RESETPARAMETERS 0x6DU
#define PC_TO_RDR_SETPARAMETERS 0x61U
#define PC_TO_RDR_ESCAPE 0x6BU
#define PC_TO_RDR_ICCCLOCK 0x6EU
#define PC_TO_RDR_T0APDU 0x6AU
#define PC_TO_RDR_SECURE 0x69U
#define PC_TO_RDR_MECHANICAL 0x71U
#define PC_TO_RDR_ABORT 0x72U
#define PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY 0x73U
/* CCID Bulk In Command definitions */
#define RDR_TO_PC_DATABLOCK 0x80U
#define RDR_TO_PC_SLOTSTATUS 0x81U
#define RDR_TO_PC_PARAMETERS 0x82U
#define RDR_TO_PC_ESCAPE 0x83U
#define RDR_TO_PC_DATARATEANDCLOCKFREQUENCY 0x84U
/* CCID Interrupt In Command definitions */
#define RDR_TO_PC_NOTIFYSLOTCHANGE 0x50U
#define RDR_TO_PC_HARDWAREERROR 0x51U
/* Bulk-only Command Block Wrapper */
#define ABDATA_SIZE 261U
#define CCID_CMD_HEADER_SIZE 10U
#define CCID_RESPONSE_HEADER_SIZE 10U
/* Number of SLOTS. For single card, this value is 1 */
#define CCID_NUMBER_OF_SLOTS 1U
#define CARD_SLOT_FITTED 1U
#define CARD_SLOT_REMOVED 0U
#define OFFSET_INT_BMESSAGETYPE 0x00U
#define OFFSET_INT_BMSLOTICCSTATE 0x01U
#define SLOT_ICC_PRESENT 0x01U
/* LSb : (0b = no ICC present, 1b = ICC present) */
#define SLOT_ICC_CHANGE 0x02U
/* MSb : (0b = no change, 1b = change) */
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_TypesDefinitions
* @{
*/
/**
* @}
*/
typedef struct
{
uint32_t bitrate;
uint8_t format;
uint8_t paritytype;
uint8_t datatype;
} USBD_CCID_LineCodingTypeDef;
typedef struct
{
uint8_t bMessageType; /* Offset = 0*/
uint32_t dwLength; /* Offset = 1, The length field (dwLength) is the length
of the message not including the 10-byte header.*/
uint8_t bSlot; /* Offset = 5*/
uint8_t bSeq; /* Offset = 6*/
uint8_t bSpecific_0; /* Offset = 7*/
uint8_t bSpecific_1; /* Offset = 8*/
uint8_t bSpecific_2; /* Offset = 9*/
uint8_t abData [ABDATA_SIZE]; /* Offset = 10, For reference, the absolute
maximum block size for a TPDU T=0 block is 260 bytes
(5 bytes command; 255 bytes data),
or for a TPDU T=1 block is 259 bytes,
or for a short APDU T=1 block is 261 bytes,
or for an extended APDU T=1 block is 65544 bytes.*/
} __PACKED USBD_CCID_BulkOut_DataTypeDef;
typedef struct
{
uint8_t bMessageType; /* Offset = 0 */
uint32_t dwLength; /* Offset = 1 */
uint8_t bSlot; /* Offset = 5, Same as Bulk-OUT message */
uint8_t bSeq; /* Offset = 6, Same as Bulk-OUT message */
uint8_t bStatus; /* Offset = 7, Slot status as defined in section 6.2.6 */
uint8_t bError; /* Offset = 8, Slot error as defined in section 6.2.6 */
uint8_t bSpecific; /* Offset = 9 */
uint8_t abData[ABDATA_SIZE]; /* Offset = 10 */
uint16_t u16SizeToSend;
} __PACKED USBD_CCID_BulkIn_DataTypeDef;
typedef struct
{
__IO uint8_t SlotStatus;
__IO uint8_t SlotStatusChange;
} USBD_CCID_SlotStatusTypeDef;
typedef struct
{
__IO uint8_t bAbortRequestFlag;
__IO uint8_t bSeq;
__IO uint8_t bSlot;
} USBD_CCID_ParamTypeDef;
/*
* CCID Class specification revision 1.1
* Smart Card Device Class Descriptor Table
*/
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdCCID;
uint8_t bMaxSlotIndex;
uint8_t bVoltageSupport;
uint32_t dwProtocols;
uint32_t dwDefaultClock;
uint32_t dwMaximumClock;
uint8_t bNumClockSupported;
uint32_t dwDataRate;
uint32_t dwMaxDataRate;
uint8_t bNumDataRatesSupported;
uint32_t dwMaxIFSD;
uint32_t dwSynchProtocols;
uint32_t dwMechanical;
uint32_t dwFeatures;
uint32_t dwMaxCCIDMessageLength;
uint8_t bClassGetResponse;
uint8_t bClassEnvelope;
uint16_t wLcdLayout;
uint8_t bPINSupport;
uint8_t bMaxCCIDBusySlots;
} __PACKED USBD_CCID_DescTypeDef;
typedef struct
{
uint8_t data[CCID_DATA_HS_MAX_PACKET_SIZE / 4U]; /* Force 32-bit alignment */
uint32_t UsbMessageLength;
uint8_t UsbIntData[CCID_CMD_PACKET_SIZE]; /* Buffer for the Interrupt In Data */
uint32_t alt_setting;
USBD_CCID_BulkIn_DataTypeDef UsbBlkInData; /* Buffer for the Out Data */
USBD_CCID_BulkOut_DataTypeDef UsbBlkOutData; /* Buffer for the In Data */
USBD_CCID_SlotStatusTypeDef SlotStatus;
USBD_CCID_ParamTypeDef USBD_CCID_Param;
__IO uint32_t MaxPcktLen;
__IO uint8_t blkt_state; /* Bulk transfer state */
uint16_t slot_nb;
uint16_t seq_nb;
} USBD_CCID_HandleTypeDef;
/** @defgroup USBD_CORE_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_Variables
* @{
*/
extern USBD_ClassTypeDef USBD_CCID;
#define USBD_CCID_CLASS &USBD_CCID
/**
* @}
*/
/** @defgroup USB_CORE_Exported_Functions
* @{
*/
typedef struct _USBD_CCID_Itf
{
uint8_t (* Init)(USBD_HandleTypeDef *pdev);
uint8_t (* DeInit)(USBD_HandleTypeDef *pdev);
uint8_t (* Control)(uint8_t req, uint8_t *pbuf, uint16_t *length);
uint8_t (* Response_SendData)(USBD_HandleTypeDef *pdev, uint8_t *buf, uint16_t len);
uint8_t (* Send_Process)(uint8_t *Command, uint8_t *Data);
uint8_t (* SetSlotStatus)(USBD_HandleTypeDef *pdev);
} USBD_CCID_ItfTypeDef;
/**
* @}
*/
/** @defgroup USB_CORE_Exported_Functions
* @{
*/
uint8_t USBD_CCID_RegisterInterface(USBD_HandleTypeDef *pdev,
USBD_CCID_ItfTypeDef *fops);
uint8_t USBD_CCID_IntMessage(USBD_HandleTypeDef *pdev);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_CCID_H */
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,222 @@
/**
******************************************************************************
* @file usbd_ccid_cmd.h
* @author MCD Application Team
* @brief header file for the usbd_ccid_cmd.c file.
******************************************************************************
* @attention
*
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_CCID_CMD_H
#define __USBD_CCID_CMD_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#ifndef __USBD_CCID_IF_H
#include "usbd_ccid_if_template.h"
#endif /* __USBD_CCID_IF_H */
#ifndef __USBD_CCID_SC_IF_H
#include "usbd_ccid_sc_if_template.h"
#endif /* __USBD_CCID_SC_IF_H */
/* Exported types ------------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/******************************************************************************/
/* ERROR CODES for USB Bulk In Messages : bError */
/******************************************************************************/
#define SLOT_NO_ERROR 0x81U
#define SLOTERROR_UNKNOWN 0x82U
/*----------------------------------------------------------------------------*/
/* Index of not supported / incorrect message parameter : 7Fh to 01h */
/* These Values are used for Return Types between Firmware Layers */
/*
Failure of a command
The CCID cannot parse one parameter or the ICC is not supporting one parameter.
Then the Slot Error register contains the index of the first bad parameter as a
positive number (1-127). For instance, if the CCID receives an ICC command to
an unimplemented slot, then the Slot Error register shall be set to 5 (index of bSlot field) */
/*
* CCID Class specification revision 1.1
*/
/* Following Parameters used in PC_to_RDR_XfrBlock */
#define SLOTERROR_BAD_LENTGH 0x01U
#define SLOTERROR_BAD_SLOT 0x05U
#define SLOTERROR_BAD_POWERSELECT 0x07U
#define SLOTERROR_BAD_PROTOCOLNUM 0x07U
#define SLOTERROR_BAD_CLOCKCOMMAND 0x07U
#define SLOTERROR_BAD_ABRFU_3B 0x07U
#define SLOTERROR_BAD_BMCHANGES 0x07U
#define SLOTERROR_BAD_BFUNCTION_MECHANICAL 0x07U
#define SLOTERROR_BAD_ABRFU_2B 0x08U
#define SLOTERROR_BAD_LEVELPARAMETER 0x08U
#define SLOTERROR_BAD_FIDI 0x0AU
#define SLOTERROR_BAD_T01CONVCHECKSUM 0x0BU
#define SLOTERROR_BAD_GUARDTIME 0x0CU
#define SLOTERROR_BAD_WAITINGINTEGER 0x0DU
#define SLOTERROR_BAD_CLOCKSTOP 0x0EU
#define SLOTERROR_BAD_IFSC 0x0FU
#define SLOTERROR_BAD_NAD 0x10U
#define SLOTERROR_BAD_DWLENGTH 0x08U
/*---------- Table 6.2-2 Slot error register when bmCommandStatus = 1 */
#define SLOTERROR_CMD_ABORTED 0xFFU
#define SLOTERROR_ICC_MUTE 0xFEU
#define SLOTERROR_XFR_PARITY_ERROR 0xFDU
#define SLOTERROR_XFR_OVERRUN 0xFCU
#define SLOTERROR_HW_ERROR 0xFBU
#define SLOTERROR_BAD_ATR_TS 0xF8U
#define SLOTERROR_BAD_ATR_TCK 0xF7U
#define SLOTERROR_ICC_PROTOCOL_NOT_SUPPORTED 0xF6U
#define SLOTERROR_ICC_CLASS_NOT_SUPPORTED 0xF5U
#define SLOTERROR_PROCEDURE_BYTE_CONFLICT 0xF4U
#define SLOTERROR_DEACTIVATED_PROTOCOL 0xF3U
#define SLOTERROR_BUSY_WITH_AUTO_SEQUENCE 0xF2U
#define SLOTERROR_PIN_TIMEOUT 0xF0U
#define SLOTERROR_PIN_CANCELLED 0xEFU
#define SLOTERROR_CMD_SLOT_BUSY 0xE0U
#define SLOTERROR_CMD_NOT_SUPPORTED 0x00U
/* Following Parameters used in PC_to_RDR_ResetParameters */
/* DEFAULT_FIDI_VALUE */
#ifndef DEFAULT_FIDI
#define DEFAULT_FIDI 0x11U
#endif /* DEFAULT_FIDI */
#ifndef DEFAULT_T01CONVCHECKSUM
#define DEFAULT_T01CONVCHECKSUM 0x00U
#endif /* DEFAULT_T01CONVCHECKSUM */
#ifndef DEFAULT_EXTRA_GUARDTIME
#define DEFAULT_EXTRA_GUARDTIME 0x00U
#endif /* DEFAULT_EXTRA_GUARDTIME */
#ifndef DEFAULT_WAITINGINTEGER
#define DEFAULT_WAITINGINTEGER 0x0AU
#endif /* DEFAULT_WAITINGINTEGER */
#ifndef DEFAULT_CLOCKSTOP
#define DEFAULT_CLOCKSTOP 0x00U
#endif /* DEFAULT_CLOCKSTOP */
#ifndef DEFAULT_IFSC
#define DEFAULT_IFSC 0x20U
#endif /* DEFAULT_IFSC */
#ifndef DEFAULT_NAD
#define DEFAULT_NAD 0x00U
#endif /* DEFAULT_NAD */
/* Following Parameters used in PC_to_RDR_IccPowerOn */
#define VOLTAGE_SELECTION_AUTOMATIC 0xFFU
#define VOLTAGE_SELECTION_3V 0x02U
#define VOLTAGE_SELECTION_5V 0x01U
#define VOLTAGE_SELECTION_1V8 0x03U
/*
Offset=0 bmICCStatus 2 bit 0, 1, 2
0 - An ICC is present and active (power is on and stable, RST is inactive)
1 - An ICC is present and inactive (not activated or shut down by hardware error)
2 - No ICC is present
3 - RFU
Offset=0 bmRFU 4 bits 0 RFU
Offset=6 bmCommandStatus 2 bits 0, 1, 2
0 - Processed without error
1 - Failed (error code provided by the error register)
2 - Time Extension is requested
3 - RFU
*/
#define BM_ICC_PRESENT_ACTIVE 0x00U
#define BM_ICC_PRESENT_INACTIVE 0x01U
#define BM_ICC_NO_ICC_PRESENT 0x02U
#define BM_COMMAND_STATUS_OFFSET 0x06U
#define BM_COMMAND_STATUS_NO_ERROR 0x00U
#define BM_COMMAND_STATUS_FAILED (0x01U << BM_COMMAND_STATUS_OFFSET)
#define BM_COMMAND_STATUS_TIME_EXTN (0x02 << BM_COMMAND_STATUS_OFFSET)
#if (ATR_T01 == 0)
#define SIZE_OF_ATR 19U
#else
#define SIZE_OF_ATR 15U
#endif /* (ATR_T01 == 0) */
/* defines for the CCID_CMD Layers */
#define LEN_PROTOCOL_STRUCT_T0 5U
#define LEN_PROTOCOL_STRUCT_T1 7U
#define BPROTOCOL_NUM_T0 0U
#define BPROTOCOL_NUM_T1 1U
/************************************************************************************/
/* ERROR CODES for RDR_TO_PC_HARDWAREERROR Message : bHardwareErrorCode */
/************************************************************************************/
#define HARDWAREERRORCODE_OVERCURRENT 0x01U
#define HARDWAREERRORCODE_VOLTAGEERROR 0x02U
#define HARDWAREERRORCODE_OVERCURRENT_IT 0x04U
#define HARDWAREERRORCODE_VOLTAGEERROR_IT 0x08U
#define CHK_PARAM_SLOT 0x01U
#define CHK_PARAM_DWLENGTH 0x02U
#define CHK_PARAM_ABRFU2 0x04U
#define CHK_PARAM_ABRFU3 0x08U
#define CHK_PARAM_CARD_PRESENT 0x10U
#define CHK_PARAM_ABORT 0x20U
#define CHK_ACTIVE_STATE 0x40U
/* Exported functions ------------------------------------------------------- */
uint8_t PC_to_RDR_IccPowerOn(USBD_HandleTypeDef *pdev);
uint8_t PC_to_RDR_IccPowerOff(USBD_HandleTypeDef *pdev);
uint8_t PC_to_RDR_GetSlotStatus(USBD_HandleTypeDef *pdev);
uint8_t PC_to_RDR_XfrBlock(USBD_HandleTypeDef *pdev);
uint8_t PC_to_RDR_GetParameters(USBD_HandleTypeDef *pdev);
uint8_t PC_to_RDR_ResetParameters(USBD_HandleTypeDef *pdev);
uint8_t PC_to_RDR_SetParameters(USBD_HandleTypeDef *pdev);
uint8_t PC_to_RDR_Escape(USBD_HandleTypeDef *pdev);
uint8_t PC_to_RDR_IccClock(USBD_HandleTypeDef *pdev);
uint8_t PC_to_RDR_Abort(USBD_HandleTypeDef *pdev);
uint8_t PC_TO_RDR_T0Apdu(USBD_HandleTypeDef *pdev);
uint8_t PC_TO_RDR_Mechanical(USBD_HandleTypeDef *pdev);
uint8_t PC_TO_RDR_SetDataRateAndClockFrequency(USBD_HandleTypeDef *pdev);
uint8_t PC_TO_RDR_Secure(USBD_HandleTypeDef *pdev);
void RDR_to_PC_DataBlock(uint8_t errorCode, USBD_HandleTypeDef *pdev);
void RDR_to_PC_NotifySlotChange(USBD_HandleTypeDef *pdev);
void RDR_to_PC_SlotStatus(uint8_t errorCode, USBD_HandleTypeDef *pdev);
void RDR_to_PC_Parameters(uint8_t errorCode, USBD_HandleTypeDef *pdev);
void RDR_to_PC_Escape(uint8_t errorCode, USBD_HandleTypeDef *pdev);
void RDR_to_PC_DataRateAndClockFrequency(uint8_t errorCode, USBD_HandleTypeDef *pdev);
void CCID_UpdSlotStatus(USBD_HandleTypeDef *pdev, uint8_t slotStatus);
void CCID_UpdSlotChange(USBD_HandleTypeDef *pdev, uint8_t changeStatus);
uint8_t CCID_IsSlotStatusChange(USBD_HandleTypeDef *pdev);
uint8_t CCID_CmdAbort(USBD_HandleTypeDef *pdev, uint8_t slot, uint8_t seq);
uint8_t USBD_CCID_Transfer_Data_Request(USBD_HandleTypeDef *pdev,
uint8_t *dataPointer, uint16_t dataLen);
#ifdef __cplusplus
}
#endif
#endif /* __USBD_CCID_CMD_H */

View File

@@ -0,0 +1,76 @@
/**
******************************************************************************
* @file usbd_ccid_if_template.h
* @author MCD Application Team
* @brief header file for the usbd_ccid_if_template.c file.
******************************************************************************
* @attention
*
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_CCID_IF_TEMPLATE_H
#define __USBD_CCID_IF_TEMPLATE_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbd_ccid.h"
#include "usbd_ccid_cmd.h"
#ifndef __USBD_CCID_SMARTCARD_H
#include "usbd_ccid_smartcard_template.h"
#endif /* __USBD_CCID_SMARTCARD_H */
/* Exported defines ----------------------------------------------------------*/
/*****************************************************************************/
/*********************** CCID Bulk Transfer State machine ********************/
/*****************************************************************************/
#define CCID_STATE_IDLE 0U
#define CCID_STATE_DATA_OUT 1U
#define CCID_STATE_RECEIVE_DATA 2U
#define CCID_STATE_SEND_RESP 3U
#define CCID_STATE_DATAIN 4U
#define CCID_STATE_UNCORRECT_LENGTH 5U
#define DIR_IN 0U
#define DIR_OUT 1U
#define BOTH_DIR 2U
/************ Value of the Interrupt transfer status to set ******************/
#define INTRSTATUS_COMPLETE 1U
#define INTRSTATUS_RESET 0U
/************** slot change status *******************************************/
#define SLOTSTATUS_CHANGED 1U
#define SLOTSTATUS_RESET 0U
/* Exported types ------------------------------------------------------------*/
extern USBD_HandleTypeDef USBD_Device;
/* CCID Interface callback */
extern USBD_CCID_ItfTypeDef USBD_CCID_If_fops;
/* Exported macros -----------------------------------------------------------*/
/* Exported variables --------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_CCID_IF_TEMPLATE_H */

View File

@@ -0,0 +1,100 @@
/**
******************************************************************************
* @file usbd_ccid_sc_if_template.h
* @author MCD Application Team
* @brief header file for the usbd_ccid_sc_if_template.c file.
******************************************************************************
* @attention
*
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_CCID_SC_IF_TEMPLATE_H
#define __USBD_CCID_SC_IF_TEMPLATE_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbd_ccid.h"
#include "usbd_ccid_cmd.h"
#ifndef __USBD_CCID_SMARTCARD_H
#include "usbd_ccid_smartcard_template.h"
#endif /* __USBD_CCID_SMARTCARD_H */
/* Exported constants --------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef struct
{
uint8_t voltage; /* Voltage for the Card Already Selected */
uint8_t USART_GuardTime;
uint8_t SC_A2R_FiDi;
uint8_t SC_hostFiDi;
uint8_t USART_DefaultGuardTime;
uint32_t USART_BaudRate;
} SC_Param_t;
#pragma pack(1)
typedef struct
{
uint8_t bmFindexDindex;
uint8_t bmTCCKST0;
uint8_t bGuardTimeT0;
uint8_t bWaitingIntegerT0;
uint8_t bClockStop;
uint8_t bIfsc;
uint8_t bNad;
} Protocol_01_DataTypeDef;
#pragma pack()
extern Protocol_01_DataTypeDef ProtocolData;
extern SC_Param_t SC_Param;
/* Exported macro ------------------------------------------------------------*/
#define MAX_EXTRA_GUARD_TIME (0xFF - DEFAULT_EXTRA_GUARDTIME)
/* Following macros are used for SC_XferBlock command */
#define XFER_BLK_SEND_DATA 1U /* Command is for issuing the data */
#define XFER_BLK_RECEIVE_DATA 2U /* Command is for receiving the data */
#define XFER_BLK_NO_DATA 3U /* Command type is No data exchange */
/* Exported functions ------------------------------------------------------- */
/* APPLICATION LAYER ---------------------------------------------------------*/
void SC_Itf_InitParams(void);
void SC_Itf_IccPowerOn(uint8_t voltage);
void SC_Itf_IccPowerOff(void);
uint8_t SC_GetState(void);
uint8_t SC_Itf_XferBlock(uint8_t *ptrBlock, uint32_t blockLen,
uint16_t expectedLen,
USBD_CCID_BulkIn_DataTypeDef *CCID_BulkIn_Data);
uint8_t SC_Itf_SetParams(Protocol_01_DataTypeDef *pPtr, uint8_t T_01);
uint8_t SC_Itf_Escape(uint8_t *escapePtr, uint32_t escapeLen,
uint8_t *responseBuff, uint32_t *responseLen);
uint8_t SC_Itf_SetClock(uint8_t bClockCommand);
uint8_t SC_Itf_T0Apdu(uint8_t bmChanges, uint8_t bClassGetResponse,
uint8_t bClassEnvelope);
uint8_t SC_Itf_Mechanical(uint8_t bFunction);
uint8_t SC_Itf_SetDataRateAndClockFrequency(uint32_t dwClockFrequency,
uint32_t dwDataRate);
uint8_t SC_Itf_Secure(uint32_t dwLength, uint8_t bBWI, uint16_t wLevelParameter,
uint8_t *pbuf, uint32_t *returnLen);
#ifdef __cplusplus
}
#endif
#endif /* __USBD_CCID_SC_IF_TEMPLATE_H */

View File

@@ -0,0 +1,279 @@
/**
******************************************************************************
* @file usbd_ccid_smartcard_template.h
* @author MCD Application Team
* @brief header file for the usbd_ccid_smartcard_template.c file.
******************************************************************************
* @attention
*
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_CCID_SMARTCARD_TEMPLATE_H
#define __USBD_CCID_SMARTCARD_TEMPLATE_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#ifndef __USBD_CCID_IF_H
#include "usbd_ccid_if_template.h"
#endif /* __USBD_CCID_IF_H */
/* Exported constants --------------------------------------------------------*/
#define T0_PROTOCOL 0x00U /* T0 protocol */
#define T1_PROTOCOL 0x01U /* T1 protocol */
#define DIRECT 0x3BU /* Direct bit convention */
#define INDIRECT 0x3FU /* Indirect bit convention */
#define SETUP_LENGTH 20U
#define HIST_LENGTH 20U
#define SC_TRANSMIT_TIMEOUT 200U /* Direction to transmit */
#define MAX_PROTOCOLLEVEL 7U /* Maximum levels of protocol */
#define MAX_INTERFACEBYTE 4U /* Maximum number of interface bytes per protocol */
#define LC_MAX 24U
#define SC_RECEIVE_TIMEOUT 0x8000U /* Direction to reader */
/* T=1 protocol constants */
#define T1_I_BLOCK 0x00U /* PCB (I-block: b8 = 0) */
#define T1_R_BLOCK 0x80U /* PCB (R-block: b8 b7 = 10) */
#define T1_S_BLOCK 0xC0U /* PCB (S-block: b8 b7 = 11) */
/* I block */
#define T1_I_SEQ_SHIFT 6U /* N(S) position (bit 7) */
/* R block */
#define T1_IS_ERROR(pcb) ((pcb) & 0x0FU)
#define T1_EDC_ERROR 0x01U /* [b6..b1] = 0-N(R)-0001 */
#define T1_OTHER_ERROR 0x02U /* [b6..b1] = 0-N(R)-0010 */
#define T1_R_SEQ_SHIFT 4U /* N(R) position (b5) */
/* S block */
#define T1_S_RESPONSE 0x20U /* If response: set bit b6, if request reset b6 in PCB S-Block */
#define T1_S_RESYNC 0x00U /* RESYNCH: b6->b1: 000000 of PCB S-Block */
#define T1_S_IFS 0x01U /* IFS: b6->b1: 000001 of PCB S-Block */
#define T1_S_ABORT 0x02U /* ABORT: b6->b1: 000010 of PCB S-Block */
#define T1_S_WTX 0x03U /* WTX: b6->b1: 000011 of PCB S-Block */
#define NAD 0U /* NAD byte position in the block */
#define PCB 1U /* PCB byte position in the block */
#define LEN 2U /* LEN byte position in the block */
#define DATA 3U /* The position of the first byte of INF field in the block */
/* Modifiable parameters */
#define SAD 0x0U /* Source address: reader (allowed values 0 -> 7) */
#define DAD 0x0U /* Destination address: card (allowed values 0 -> 7) */
#define IFSD_VALUE 254U /* Max length of INF field Supported by the reader */
#define SC_FILE_SIZE 0x100U /* File size */
#define SC_FILE_ID 0x0001U /* File identifier */
#define SC_CLASS 0x00U
/* Constant parameters */
#define INS_SELECT_FILE 0xA4U /* Select file instruction */
#define INS_READ_FILE 0xB0U /* Read file instruction */
#define INS_WRITE_FILE 0xD6U /* Write file instruction */
#define TRAILER_LENGTH 2U /* Trailer length (SW1 and SW2: 2 bytes) */
#define SC_T1_RECEIVE_SUCCESS 0U
#define SC_T1_BWT_TIMEOUT 1U
#define SC_T1_CWT_TIMEOUT 2U
#define DEFAULT_FIDI_VALUE 0x11U
#define PPS_REQUEST 0xFFU
/* SC Tree Structure -----------------------------------------------------------
MasterFile
________|___________
| | |
System UserData Note
------------------------------------------------------------------------------*/
/* SC ADPU Command: Operation Code -------------------------------------------*/
#define SC_CLA_NAME 0x00U
/*------------------------ Data Area Management Commands ---------------------*/
#define SC_SELECT_FILE 0xA4U
#define SC_GET_RESPONCE 0xC0U
#define SC_STATUS 0xF2U
#define SC_UPDATE_BINARY 0xD6U
#define SC_READ_BINARY 0xB0U
#define SC_WRITE_BINARY 0xD0U
#define SC_UPDATE_RECORD 0xDCU
#define SC_READ_RECORD 0xB2U
/*-------------------------- Administrative Commands -------------------------*/
#define SC_CREATE_FILE 0xE0U
/*-------------------------- Safety Management Commands ----------------------*/
#define SC_VERIFY 0x20U
#define SC_CHANGE 0x24U
#define SC_DISABLE 0x26U
#define SC_ENABLE 0x28U
#define SC_UNBLOCK 0x2CU
#define SC_EXTERNAL_AUTH 0x82U
#define SC_GET_CHALLENGE 0x84U
/*-------------------------- Smartcard Interface Byte-------------------------*/
#define SC_INTERFACEBYTE_TA 0U /* Interface byte TA(i) */
#define SC_INTERFACEBYTE_TB 1U /* Interface byte TB(i) */
#define SC_INTERFACEBYTE_TC 2U /* Interface byte TC(i) */
#define SC_INTERFACEBYTE_TD 3U /* Interface byte TD(i) */
/*-------------------------- Answer to reset Commands ------------------------*/
#define SC_GET_A2R 0x00U
/* SC STATUS: Status Code ----------------------------------------------------*/
#define SC_EF_SELECTED 0x9FU
#define SC_DF_SELECTED 0x9FU
#define SC_OP_TERMINATED 0x9000U
/* Smartcard Voltage */
#define SC_VOLTAGE_5V 0x00U
#define SC_VOLTAGE_3V 0x01U
#define SC_VOLTAGE_NOINIT 0xFFU
/*----------------- ATR Protocole supported ----------------------------------*/
#define ATR_T01 0x00U
/* Exported types ------------------------------------------------------------*/
typedef enum
{
SC_POWER_ON = 0x00,
SC_RESET_LOW = 0x01,
SC_RESET_HIGH = 0x02,
SC_ACTIVE = 0x03,
SC_ACTIVE_ON_T0 = 0x04,
SC_ACTIVE_ON_T1 = 0x05,
SC_POWER_OFF = 0x06,
SC_NO_INIT = 0x07
} SC_State;
/* Interface Byte structure - TA(i), TB(i), TC(i) and TD(i) ------------------*/
typedef struct
{
uint8_t Status; /* The Presence of the Interface byte */
uint8_t Value; /* The Value of the Interface byte */
} SC_InterfaceByteTypeDef;
/* Protocol Level structure - ------------------------------------------------*/
typedef struct
{
SC_InterfaceByteTypeDef InterfaceByte[MAX_INTERFACEBYTE]; /* The Values of the Interface byte
TA(i), TB(i), TC(i)and TD(i) */
} SC_ProtocolLevelTypeDef;
/* ATR structure - Answer To Reset -------------------------------------------*/
typedef struct
{
uint8_t TS; /* Bit Convention Direct/Indirect */
uint8_t T0; /* Each bit in the high nibble = Presence of the further interface byte;
Low nibble = Number of historical byte */
SC_ProtocolLevelTypeDef T[MAX_PROTOCOLLEVEL]; /* Setup array */
uint8_t Historical[HIST_LENGTH]; /* Historical array */
uint8_t Tlength; /* Setup array dimension */
uint8_t Hlength; /* Historical array dimension */
uint8_t TCK;
} SC_ATRTypeDef;
/* ADPU-Header command structure ---------------------------------------------*/
typedef struct
{
uint8_t CLA; /* Command class */
uint8_t INS; /* Operation code */
uint8_t P1; /* Selection Mode */
uint8_t P2; /* Selection Option */
} SC_HeaderTypeDef;
/* ADPU-Body command structure -----------------------------------------------*/
typedef struct
{
uint8_t LC; /* Data field length */
uint8_t Data[LC_MAX]; /* Command parameters */
uint8_t LE; /* Expected length of data to be returned */
} SC_BodyTypeDef;
/* ADPU Command structure ----------------------------------------------------*/
typedef struct
{
SC_HeaderTypeDef Header;
SC_BodyTypeDef Body;
} SC_ADPU_CommandsTypeDef;
/* SC response structure -----------------------------------------------------*/
typedef struct
{
uint8_t Data[LC_MAX]; /* Data returned from the card */
uint8_t SW1; /* Command Processing status */
uint8_t SW2; /* Command Processing qualification */
} SC_ADPU_ResponseTypeDef;
/* SC Command Status -----------------------------------------------------*/
typedef enum
{
SC_CS_FAILED = 0x00,
SC_CS_PIN_ENABLED = 0x01,
SC_CS_PIN_VERIFIED = 0x02,
SC_CS_READ = 0x03,
SC_CS_PIN_CHANGED = 0x04
} SC_Command_State;
/* SC Response Status -----------------------------------------------------*/
typedef enum
{
REP_OK = 0x00,
REP_NOT_OK = 0x01,
REP_NOT_SUPP = 0x02,
REP_ENABLED = 0x03,
REP_CHANGE = 0x04
} REP_Command_t;
/* Conforming of Command with ICC APP -----------------------------------------------------*/
typedef enum
{
Command_OK = 0x00,
Command_NOT_OK = 0x01,
} Command_State_t;
typedef enum
{
SC_DISABLED = 0U,
SC_ENABLED = !SC_DISABLED
} SCPowerState;
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
/* APPLICATION LAYER ---------------------------------------------------------*/
void SC_Handler(SC_State *SCState, SC_ADPU_CommandsTypeDef *SC_ADPU, SC_ADPU_ResponseTypeDef *SC_Response);
void SC_PowerCmd(SCPowerState NewState);
void SC_ParityErrorHandler(void);
void SC_PTSConfig(void);
uint8_t SC_Detect(void);
uint32_t SC_GetDTableValue(uint32_t idx);
void SC_VoltageConfig(uint32_t SC_Voltage);
void SC_SetState(SC_State scState);
void SC_IOConfig(void);
extern uint8_t SC_ATR_Table[40];
extern SC_ATRTypeDef SC_A2R;
extern SC_ADPU_ResponseTypeDef SC_Response;
extern uint8_t ProtocolNUM_OUT;
extern SC_ADPU_CommandsTypeDef SC_ADPU;
#ifdef __cplusplus
}
#endif
#endif /* __USBD_CCID_SMARTCARD_TEMPLATE_H */

969
Class/CCID/Src/usbd_ccid.c Normal file
View File

@@ -0,0 +1,969 @@
/**
******************************************************************************
* @file usbd_ccid.c
* @author MCD Application Team
* @brief This file provides the high layer firmware functions to manage
* all the functionalities of the USB CCID Class:
*
******************************************************************************
* @attention
*
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
* @verbatim
*
* ===================================================================
* CCID Class Driver Description
* ===================================================================
* This module manages the Specification for Integrated Circuit(s)
* Cards Interface Revision 1.1
* This driver implements the following aspects of the specification:
* - Device descriptor management
* - Configuration descriptor management
* - Enumeration as CCID device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN)
* and enumeration for each implemented memory interface
* - Bulk OUT/IN data Transfers
* - Requests management
*
* @endverbatim
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_ccid.h"
#include "usbd_ccid_cmd.h"
#include "usbd_ctlreq.h"
/** @addtogroup STM32_USB_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_CCID
* @brief usbd core module
* @{
*/
/** @defgroup USBD_CCID_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CCID_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CCID_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CCID_Private_FunctionPrototypes
* @{
*/
static uint8_t USBD_CCID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
static uint8_t USBD_CCID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
static uint8_t USBD_CCID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
static uint8_t USBD_CCID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
static uint8_t USBD_CCID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
static uint8_t USBD_CCID_DispatchCommand(USBD_HandleTypeDef *pdev);
static uint8_t USBD_CCID_ReceiveCmdHeader(USBD_HandleTypeDef *pdev,
uint8_t *pDst, uint16_t u8length);
#ifndef USE_USBD_COMPOSITE
static uint8_t *USBD_CCID_GetHSCfgDesc(uint16_t *length);
static uint8_t *USBD_CCID_GetFSCfgDesc(uint16_t *length);
static uint8_t *USBD_CCID_GetOtherSpeedCfgDesc(uint16_t *length);
static uint8_t *USBD_CCID_GetDeviceQualifierDescriptor(uint16_t *length);
#endif /* USE_USBD_COMPOSITE */
/**
* @}
*/
/** @defgroup USBD_CCID_Private_Variables
* @{
*/
static uint8_t CCIDInEpAdd = CCID_IN_EP;
static uint8_t CCIDOutEpAdd = CCID_OUT_EP;
static uint8_t CCIDCmdEpAdd = CCID_CMD_EP;
/* CCID interface class callbacks structure */
USBD_ClassTypeDef USBD_CCID =
{
USBD_CCID_Init,
USBD_CCID_DeInit,
USBD_CCID_Setup,
NULL, /*EP0_TxSent*/
NULL, /*EP0_RxReady*/
USBD_CCID_DataIn,
USBD_CCID_DataOut,
NULL, /*SOF */
NULL, /*ISOIn*/
NULL, /*ISOOut*/
#ifdef USE_USBD_COMPOSITE
NULL,
NULL,
NULL,
NULL,
#else
USBD_CCID_GetHSCfgDesc,
USBD_CCID_GetFSCfgDesc,
USBD_CCID_GetOtherSpeedCfgDesc,
USBD_CCID_GetDeviceQualifierDescriptor,
#endif /* USE_USBD_COMPOSITE */
};
#ifndef USE_USBD_COMPOSITE
/* USB CCID device Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CCID_CfgDesc[USB_CCID_CONFIG_DESC_SIZ] __ALIGN_END =
{
/* Configuration Descriptor */
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
USB_CCID_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */
0x00,
0x01, /* bNumInterfaces: 1 interface */
0x01, /* bConfigurationValue: */
0x00, /* iConfiguration: */
#if (USBD_SELF_POWERED == 1U)
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif /* USBD_SELF_POWERED */
USBD_MAX_POWER, /* MaxPower (mA) */
/******************** CCID **** interface ********************/
CCID_INTERFACE_DESC_SIZE, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x03, /* bNumEndpoints: 3 endpoints used */
USB_DEVICE_CLASS_CCID, /* bInterfaceClass: user's interface for CCID */
0x00, /* bInterfaceSubClass : No subclass,
can be changed but no description in USB 2.0 Spec */
0x00, /* nInterfaceProtocol : None */
0x00, /* iInterface */
/******************* CCID class descriptor ********************/
CCID_CLASS_DESC_SIZE, /* bLength: CCID Descriptor size */
CCID_DESC_TYPE, /* bDescriptorType: Functional Descriptor type. */
0x10, /* bcdCCID(LSB): CCID Class Spec release number (1.1) */
0x01, /* bcdCCID(MSB) */
0x00, /* bMaxSlotIndex :highest available slot on this device */
CCID_VOLTAGE_SUPP, /* bVoltageSupport: bVoltageSupport: 5v, 3v and 1.8v */
LOBYTE(USBD_CCID_PROTOCOL), /* dwProtocols: supports T=0 and T=1 */
HIBYTE(USBD_CCID_PROTOCOL),
0x00,
0x00,
LOBYTE(USBD_CCID_DEFAULT_CLOCK_FREQ), /* dwDefaultClock: 3.6Mhz */
HIBYTE(USBD_CCID_DEFAULT_CLOCK_FREQ),
0x00,
0x00,
LOBYTE(USBD_CCID_MAX_CLOCK_FREQ), /* dwMaximumClock */
HIBYTE(USBD_CCID_MAX_CLOCK_FREQ),
0x00,
0x00,
0x00, /* bNumClockSupported */
LOBYTE(USBD_CCID_DEFAULT_DATA_RATE), /* dwDataRate: 9677 bps */
HIBYTE(USBD_CCID_DEFAULT_DATA_RATE),
0x00,
0x00,
LOBYTE(USBD_CCID_MAX_DATA_RATE), /* dwMaxDataRate */
HIBYTE(USBD_CCID_MAX_DATA_RATE),
0x00,
0x00,
0x35, /* bNumDataRatesSupported */
LOBYTE(USBD_CCID_MAX_INF_FIELD_SIZE), /* dwMaxIFSD: maximum IFSD supported for T=1 */
HIBYTE(USBD_CCID_MAX_INF_FIELD_SIZE),
0x00,
0x00,
0x00, 0x00, 0x00, 0x00, /* dwSynchProtocols */
0x00, 0x00, 0x00, 0x00, /* dwMechanical: no special characteristics */
0xBA, 0x04, EXCHANGE_LEVEL_FEATURE, 0x00, /* dwFeatures */
LOBYTE(CCID_MAX_BLOCK_SIZE_HEADER), /* dwMaxCCIDMessageLength: Maximum block size + header*/
HIBYTE(CCID_MAX_BLOCK_SIZE_HEADER),
0x00,
0x00,
0x00, /* bClassGetResponse*/
0x00, /* bClassEnvelope */
0x00, 0x00, /* wLcdLayout : 0000h no LCD. */
0x03, /* bPINSupport : PIN verification and PIN modification */
0x01, /* bMaxCCIDBusySlots */
/******************** CCID Endpoints ********************/
CCID_ENDPOINT_DESC_SIZE, /* Endpoint descriptor length = 7 */
USB_DESC_TYPE_ENDPOINT, /* Endpoint descriptor type */
CCID_IN_EP, /* Endpoint address (IN, address 1) */
USBD_EP_TYPE_BULK, /* Bulk endpoint type */
LOBYTE(CCID_DATA_FS_MAX_PACKET_SIZE),
HIBYTE(CCID_DATA_FS_MAX_PACKET_SIZE),
0x00, /* Polling interval in milliseconds */
CCID_ENDPOINT_DESC_SIZE, /* Endpoint descriptor length = 7 */
USB_DESC_TYPE_ENDPOINT, /* Endpoint descriptor type */
CCID_OUT_EP, /* Endpoint address (OUT, address 1) */
USBD_EP_TYPE_BULK, /* Bulk endpoint type */
LOBYTE(CCID_DATA_FS_MAX_PACKET_SIZE),
HIBYTE(CCID_DATA_FS_MAX_PACKET_SIZE),
0x00, /* Polling interval in milliseconds */
CCID_ENDPOINT_DESC_SIZE, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType:*/
CCID_CMD_EP, /* bEndpointAddress: Endpoint Address (IN) */
USBD_EP_TYPE_INTR, /* bmAttributes: Interrupt endpoint */
LOBYTE(CCID_CMD_PACKET_SIZE),
HIBYTE(CCID_CMD_PACKET_SIZE),
CCID_CMD_FS_BINTERVAL /* Polling interval in milliseconds */
};
/* USB Standard Device Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CCID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
{
USB_LEN_DEV_QUALIFIER_DESC,
USB_DESC_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
0x00,
0x00,
0x00,
0x40,
0x01,
0x00,
};
#endif /* USE_USBD_COMPOSITE */
/**
* @}
*/
/** @defgroup USBD_CCID_Private_Functions
* @{
*/
/**
* @brief USBD_CCID_Init
* Initialize the CCID interface
* @param pdev: device instance
* @param cfgidx: Configuration index
* @retval status
*/
static uint8_t USBD_CCID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
USBD_CCID_HandleTypeDef *hccid;
UNUSED(cfgidx);
/* Allocate CCID structure */
hccid = (USBD_CCID_HandleTypeDef *)USBD_malloc(sizeof(USBD_CCID_HandleTypeDef));
if (hccid == NULL)
{
pdev->pClassDataCmsit[pdev->classId] = NULL;
return (uint8_t)USBD_EMEM;
}
pdev->pClassDataCmsit[pdev->classId] = (void *)hccid;
pdev->pClassData = pdev->pClassDataCmsit[pdev->classId];
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
CCIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
CCIDOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
CCIDCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
/* Init the CCID parameters into a state where it can receive a new command message */
hccid->USBD_CCID_Param.bAbortRequestFlag = 0U;
hccid->USBD_CCID_Param.bSeq = 0U;
hccid->USBD_CCID_Param.bSlot = 0U;
hccid->MaxPcktLen = (pdev->dev_speed == USBD_SPEED_HIGH) ? \
CCID_DATA_HS_MAX_PACKET_SIZE : CCID_DATA_FS_MAX_PACKET_SIZE;
/* Open EP IN */
(void)USBD_LL_OpenEP(pdev, CCIDInEpAdd, USBD_EP_TYPE_BULK, (uint16_t)hccid->MaxPcktLen);
pdev->ep_in[CCIDInEpAdd & 0xFU].is_used = 1U;
/* Open EP OUT */
(void)USBD_LL_OpenEP(pdev, CCIDOutEpAdd, USBD_EP_TYPE_BULK, (uint16_t)hccid->MaxPcktLen);
pdev->ep_out[CCIDOutEpAdd & 0xFU].is_used = 1U;
/* Open INTR EP IN */
(void)USBD_LL_OpenEP(pdev, CCIDCmdEpAdd,
USBD_EP_TYPE_INTR, CCID_CMD_PACKET_SIZE);
pdev->ep_in[CCIDCmdEpAdd & 0xFU].is_used = 1U;
/* Init physical Interface components */
((USBD_CCID_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init(pdev);
/* Prepare Out endpoint to receive next packet */
(void)USBD_LL_PrepareReceive(pdev, CCIDOutEpAdd,
hccid->data, hccid->MaxPcktLen);
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_CCID_DeInit
* DeInitialize the CCID layer
* @param pdev: device instance
* @param cfgidx: Configuration index
* @retval status
*/
static uint8_t USBD_CCID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
UNUSED(cfgidx);
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
CCIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
CCIDOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
CCIDCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
/* Close EP IN */
(void)USBD_LL_CloseEP(pdev, CCIDInEpAdd);
pdev->ep_in[CCIDInEpAdd & 0xFU].is_used = 0U;
/* Close EP OUT */
(void)USBD_LL_CloseEP(pdev, CCIDOutEpAdd);
pdev->ep_out[CCIDOutEpAdd & 0xFU].is_used = 0U;
/* Close EP Command */
(void)USBD_LL_CloseEP(pdev, CCIDCmdEpAdd);
pdev->ep_in[CCIDCmdEpAdd & 0xFU].is_used = 0U;
/* DeInit physical Interface components */
if (pdev->pClassDataCmsit[pdev->classId] != NULL)
{
((USBD_CCID_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit(pdev);
(void)USBD_free(pdev->pClassDataCmsit[pdev->classId]);
pdev->pClassDataCmsit[pdev->classId] = NULL;
pdev->pClassData = NULL;
}
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_CCID_Setup
* Handle the CCID specific requests
* @param pdev: instance
* @param req: usb requests
* @retval status
*/
static uint8_t USBD_CCID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
USBD_CCID_ItfTypeDef *hCCIDitf = (USBD_CCID_ItfTypeDef *)pdev->pUserData[pdev->classId];
USBD_StatusTypeDef ret = USBD_OK;
uint8_t ifalt = 0U;
uint16_t status_info = 0U;
uint16_t len;
switch (req->bmRequest & USB_REQ_TYPE_MASK)
{
/* Class request */
case USB_REQ_TYPE_CLASS :
if (req->wLength != 0U)
{
len = MIN(CCID_EP0_BUFF_SIZ, req->wLength);
if ((req->bmRequest & 0x80U) != 0U)
{
hCCIDitf->Control(req->bRequest, hccid->data, &len);
(void)USBD_CtlSendData(pdev, hccid->data, len);
}
else
{
(void)USBD_CtlPrepareRx(pdev, hccid->data, len);
}
}
else
{
len = 0U;
hCCIDitf->Control(req->bRequest, (uint8_t *)&req->wValue, &len);
}
break;
/* Interface & Endpoint request */
case USB_REQ_TYPE_STANDARD:
switch (req->bRequest)
{
case USB_REQ_GET_STATUS:
if (pdev->dev_state == USBD_STATE_CONFIGURED)
{
(void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
}
else
{
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
}
break;
case USB_REQ_GET_INTERFACE:
if (pdev->dev_state == USBD_STATE_CONFIGURED)
{
(void)USBD_CtlSendData(pdev, &ifalt, 1U);
}
else
{
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
}
break;
case USB_REQ_SET_INTERFACE:
if (pdev->dev_state != USBD_STATE_CONFIGURED)
{
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
}
break;
case USB_REQ_CLEAR_FEATURE:
break;
default:
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
break;
}
break;
default:
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
break;
}
return (uint8_t)ret;
}
/**
* @brief USBD_CCID_DataIn
* Data sent on non-control IN endpoint
* @param pdev: device instance
* @param epnum: endpoint number
* @retval status
*/
static uint8_t USBD_CCID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
CCIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
CCIDCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (epnum == (CCIDInEpAdd & 0x7FU))
{
/* Filter the epnum by masking with 0x7f (mask of IN Direction) */
/*************** Handle Bulk Transfer IN data completion *****************/
switch (hccid->blkt_state)
{
case CCID_STATE_SEND_RESP:
/* won't wait ack to avoid missing a command */
hccid->blkt_state = CCID_STATE_IDLE;
/* Prepare EP to Receive Cmd */
(void)USBD_LL_PrepareReceive(pdev, CCID_OUT_EP,
hccid->data, hccid->MaxPcktLen);
break;
default:
break;
}
}
else if (epnum == (CCIDCmdEpAdd & 0x7FU))
{
/* Filter the epnum by masking with 0x7f (mask of IN Direction) */
/*************** Handle Interrupt Transfer IN data completion *****************/
(void)USBD_CCID_IntMessage(pdev);
}
else
{
return (uint8_t)USBD_FAIL;
}
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_CCID_DataOut
* Data received on non-control Out endpoint
* @param pdev: device instance
* @param epnum: endpoint number
* @retval status
*/
static uint8_t USBD_CCID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint16_t CurrPcktLen;
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
CCIDOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (hccid == NULL)
{
return (uint8_t)USBD_EMEM;
}
if (epnum == CCIDOutEpAdd)
{
CurrPcktLen = (uint16_t)USBD_GetRxCount(pdev, epnum);
switch (hccid->blkt_state)
{
case CCID_STATE_IDLE:
if (CurrPcktLen >= (uint16_t)CCID_CMD_HEADER_SIZE)
{
hccid->UsbMessageLength = CurrPcktLen; /* Store for future use */
/* Fill CCID_BulkOut Data Buffer from USB Buffer */
(void)USBD_CCID_ReceiveCmdHeader(pdev, (uint8_t *)&hccid->UsbBlkOutData.bMessageType,
(uint16_t)CurrPcktLen);
/*
Refer : 6 CCID Messages
The response messages always contain the exact same slot number,
and sequence number fields from the header that was contained in
the Bulk-OUT command message.
*/
hccid->UsbBlkInData.bSlot = hccid->UsbBlkOutData.bSlot;
hccid->UsbBlkInData.bSeq = hccid->UsbBlkOutData.bSeq;
if (CurrPcktLen < hccid->MaxPcktLen)
{
/* Short message, less than the EP Out Size, execute the command,
if parameter like dwLength is too big, the appropriate command will
give an error */
(void)USBD_CCID_DispatchCommand(pdev);
}
else
{
/* Check if length of data to be sent by host is > buffer size */
if (hccid->UsbBlkOutData.dwLength > (uint32_t)ABDATA_SIZE)
{
/* Too long data received.... Error ! */
hccid->blkt_state = CCID_STATE_UNCORRECT_LENGTH;
}
else
{
/* Expect more data on OUT EP */
hccid->blkt_state = CCID_STATE_RECEIVE_DATA;
/* Prepare EP to Receive next Cmd */
(void)USBD_LL_PrepareReceive(pdev, CCID_OUT_EP,
hccid->data, hccid->MaxPcktLen);
} /* if (CurrPcktLen == CCID_DATA_MAX_PACKET_SIZE) ends */
} /* if (CurrPcktLen >= CCID_DATA_MAX_PACKET_SIZE) ends */
} /* if (CurrPcktLen >= CCID_CMD_HEADER_SIZE) ends */
else
{
if (CurrPcktLen == 0x00U) /* Zero Length Packet Received */
{
hccid->blkt_state = CCID_STATE_IDLE;
}
}
break;
case CCID_STATE_RECEIVE_DATA:
hccid->UsbMessageLength += CurrPcktLen;
if (CurrPcktLen < hccid->MaxPcktLen)
{
/* Short message, less than the EP Out Size, execute the command,
if parameter like dwLength is too big, the appropriate command will
give an error */
/* Full command is received, process the Command */
(void)USBD_CCID_ReceiveCmdHeader(pdev, (uint8_t *)&hccid->UsbBlkOutData.bMessageType,
(uint16_t)CurrPcktLen);
(void)USBD_CCID_DispatchCommand(pdev);
}
else if (CurrPcktLen == hccid->MaxPcktLen)
{
if (hccid->UsbMessageLength < (hccid->UsbBlkOutData.dwLength + (uint32_t)CCID_CMD_HEADER_SIZE))
{
(void)USBD_CCID_ReceiveCmdHeader(pdev, (uint8_t *)&hccid->UsbBlkOutData.bMessageType,
(uint16_t)CurrPcktLen); /* Copy data */
/* Prepare EP to Receive next Cmd */
(void)USBD_LL_PrepareReceive(pdev, CCID_OUT_EP,
hccid->data, hccid->MaxPcktLen);
}
else if (hccid->UsbMessageLength == (hccid->UsbBlkOutData.dwLength + (uint32_t)CCID_CMD_HEADER_SIZE))
{
/* Full command is received, process the Command */
(void)USBD_CCID_ReceiveCmdHeader(pdev, (uint8_t *)&hccid->UsbBlkOutData.bMessageType,
(uint16_t)CurrPcktLen);
(void)USBD_CCID_DispatchCommand(pdev);
}
else
{
/* Too long data received.... Error ! */
hccid->blkt_state = CCID_STATE_UNCORRECT_LENGTH;
}
}
else
{
/* Too long data received.... Error ! */
hccid->blkt_state = CCID_STATE_UNCORRECT_LENGTH;
}
break;
case CCID_STATE_UNCORRECT_LENGTH:
hccid->blkt_state = CCID_STATE_IDLE;
break;
default:
break;
}
}
else
{
return (uint8_t)USBD_FAIL;
}
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_CCID_DispatchCommand
* Parse the commands and Process command
* @param pdev: device instance
* @retval status value
*/
static uint8_t USBD_CCID_DispatchCommand(USBD_HandleTypeDef *pdev)
{
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint8_t errorCode;
switch (hccid->UsbBlkOutData.bMessageType)
{
case PC_TO_RDR_ICCPOWERON:
errorCode = PC_to_RDR_IccPowerOn(pdev);
RDR_to_PC_DataBlock(errorCode, pdev);
break;
case PC_TO_RDR_ICCPOWEROFF:
errorCode = PC_to_RDR_IccPowerOff(pdev);
RDR_to_PC_SlotStatus(errorCode, pdev);
break;
case PC_TO_RDR_GETSLOTSTATUS:
errorCode = PC_to_RDR_GetSlotStatus(pdev);
RDR_to_PC_SlotStatus(errorCode, pdev);
break;
case PC_TO_RDR_XFRBLOCK:
errorCode = PC_to_RDR_XfrBlock(pdev);
RDR_to_PC_DataBlock(errorCode, pdev);
break;
case PC_TO_RDR_GETPARAMETERS:
errorCode = PC_to_RDR_GetParameters(pdev);
RDR_to_PC_Parameters(errorCode, pdev);
break;
case PC_TO_RDR_RESETPARAMETERS:
errorCode = PC_to_RDR_ResetParameters(pdev);
RDR_to_PC_Parameters(errorCode, pdev);
break;
case PC_TO_RDR_SETPARAMETERS:
errorCode = PC_to_RDR_SetParameters(pdev);
RDR_to_PC_Parameters(errorCode, pdev);
break;
case PC_TO_RDR_ESCAPE:
errorCode = PC_to_RDR_Escape(pdev);
RDR_to_PC_Escape(errorCode, pdev);
break;
case PC_TO_RDR_ICCCLOCK:
errorCode = PC_to_RDR_IccClock(pdev);
RDR_to_PC_SlotStatus(errorCode, pdev);
break;
case PC_TO_RDR_ABORT:
errorCode = PC_to_RDR_Abort(pdev);
RDR_to_PC_SlotStatus(errorCode, pdev);
break;
case PC_TO_RDR_T0APDU:
errorCode = PC_TO_RDR_T0Apdu(pdev);
RDR_to_PC_SlotStatus(errorCode, pdev);
break;
case PC_TO_RDR_MECHANICAL:
errorCode = PC_TO_RDR_Mechanical(pdev);
RDR_to_PC_SlotStatus(errorCode, pdev);
break;
case PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY:
errorCode = PC_TO_RDR_SetDataRateAndClockFrequency(pdev);
RDR_to_PC_DataRateAndClockFrequency(errorCode, pdev);
break;
case PC_TO_RDR_SECURE:
errorCode = PC_TO_RDR_Secure(pdev);
RDR_to_PC_DataBlock(errorCode, pdev);
break;
default:
RDR_to_PC_SlotStatus(SLOTERROR_CMD_NOT_SUPPORTED, pdev);
break;
}
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_CCID_Transfer_Data_Request
* Prepare the request response to be sent to the host
* @param pdev: device instance
* @param dataPointer: Pointer to the data buffer to send
* @param dataLen : number of bytes to send
* @retval status value
*/
uint8_t USBD_CCID_Transfer_Data_Request(USBD_HandleTypeDef *pdev,
uint8_t *dataPointer, uint16_t dataLen)
{
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
USBD_CCID_ItfTypeDef *hCCIDitf = (USBD_CCID_ItfTypeDef *)pdev->pUserData[pdev->classId];
UNUSED(dataPointer);
hccid->blkt_state = CCID_STATE_SEND_RESP;
hccid->UsbMessageLength = (uint32_t)dataLen; /* Store for future use */
/* use the header declared size packet must be well formed */
hCCIDitf->Response_SendData(pdev, (uint8_t *)&hccid->UsbBlkInData,
(uint16_t)MIN(CCID_DATA_FS_MAX_PACKET_SIZE, hccid->UsbMessageLength));
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_CCID_ReceiveCmdHeader
* Receive the Data from USB BulkOut Buffer to Pointer
* @param pdev: device instance
* @param pDst: destination address to copy the buffer
* @param u8length: length of data to copy
* @retval status
*/
static uint8_t USBD_CCID_ReceiveCmdHeader(USBD_HandleTypeDef *pdev,
uint8_t *pDst, uint16_t u8length)
{
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint8_t *pdst = pDst;
uint32_t Counter;
for (Counter = 0U; Counter < u8length; Counter++)
{
*pdst = hccid->data[Counter];
pdst++;
}
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_CCID_IntMessage
* Send the Interrupt-IN data to the host
* @param pdev: device instance
* @retval None
*/
uint8_t USBD_CCID_IntMessage(USBD_HandleTypeDef *pdev)
{
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
CCIDCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
/* Check if there is change in Smartcard Slot status */
if (CCID_IsSlotStatusChange(pdev) != 0U)
{
/* Check Slot Status is changed. Card is Removed/Fitted */
RDR_to_PC_NotifySlotChange(pdev);
/* Set the Slot status */
((USBD_CCID_ItfTypeDef *)pdev->pUserData[pdev->classId])->SetSlotStatus(pdev);
(void)USBD_LL_Transmit(pdev, CCIDCmdEpAdd, hccid->UsbIntData, 2U);
}
else
{
/* Set the Slot status */
((USBD_CCID_ItfTypeDef *)pdev->pUserData[pdev->classId])->SetSlotStatus(pdev);
}
return (uint8_t)USBD_OK;
}
#ifndef USE_USBD_COMPOSITE
/**
* @brief USBD_CCID_GetHSCfgDesc
* Return configuration descriptor
* @param length pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_CCID_GetHSCfgDesc(uint16_t *length)
{
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_IN_EP);
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_OUT_EP);
USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_CMD_EP);
if (pEpInDesc != NULL)
{
pEpInDesc->wMaxPacketSize = CCID_DATA_HS_MAX_PACKET_SIZE;
}
if (pEpOutDesc != NULL)
{
pEpOutDesc->wMaxPacketSize = CCID_DATA_HS_MAX_PACKET_SIZE;
}
if (pEpCmdDesc != NULL)
{
pEpCmdDesc->bInterval = CCID_CMD_HS_BINTERVAL;
}
*length = (uint16_t)sizeof(USBD_CCID_CfgDesc);
return USBD_CCID_CfgDesc;
}
/**
* @brief USBD_CCID_GetFSCfgDesc
* Return configuration descriptor
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_CCID_GetFSCfgDesc(uint16_t *length)
{
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_IN_EP);
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_OUT_EP);
USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_CMD_EP);
if (pEpInDesc != NULL)
{
pEpInDesc->wMaxPacketSize = CCID_DATA_FS_MAX_PACKET_SIZE;
}
if (pEpOutDesc != NULL)
{
pEpOutDesc->wMaxPacketSize = CCID_DATA_FS_MAX_PACKET_SIZE;
}
if (pEpCmdDesc != NULL)
{
pEpCmdDesc->bInterval = CCID_CMD_FS_BINTERVAL;
}
*length = (uint16_t)sizeof(USBD_CCID_CfgDesc);
return USBD_CCID_CfgDesc;
}
/**
* @brief USBD_CCID_GetOtherSpeedCfgDesc
* Return configuration descriptor
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_CCID_GetOtherSpeedCfgDesc(uint16_t *length)
{
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_IN_EP);
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_OUT_EP);
USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_CMD_EP);
if (pEpInDesc != NULL)
{
pEpInDesc->wMaxPacketSize = CCID_DATA_FS_MAX_PACKET_SIZE;
}
if (pEpOutDesc != NULL)
{
pEpOutDesc->wMaxPacketSize = CCID_DATA_FS_MAX_PACKET_SIZE;
}
if (pEpCmdDesc != NULL)
{
pEpCmdDesc->bInterval = CCID_CMD_FS_BINTERVAL;
}
*length = (uint16_t)sizeof(USBD_CCID_CfgDesc);
return USBD_CCID_CfgDesc;
}
/**
* @brief USBD_CCID_GetDeviceQualifierDescriptor
* return Device Qualifier descriptor
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_CCID_GetDeviceQualifierDescriptor(uint16_t *length)
{
*length = (uint16_t)(sizeof(USBD_CCID_DeviceQualifierDesc));
return USBD_CCID_DeviceQualifierDesc;
}
#endif /* USE_USBD_COMPOSITE */
/**
* @brief USBD_CCID_RegisterInterface
* @param pdev: device instance
* @param fops: CD Interface callback
* @retval status
*/
uint8_t USBD_CCID_RegisterInterface(USBD_HandleTypeDef *pdev,
USBD_CCID_ItfTypeDef *fops)
{
if (fops == NULL)
{
return (uint8_t)USBD_FAIL;
}
pdev->pUserData[pdev->classId] = fops;
return (uint8_t)USBD_OK;
}
/**
* @}
*/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,270 @@
/**
******************************************************************************
* @file usbd_ccid_if_template.c
* @author MCD Application Team
* @brief This file provides all the functions for USB Interface for CCID
******************************************************************************
* @attention
*
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_ccid.h"
#include "usbd_ccid_if_template.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static REP_Command_t REP_command;
/* Private function prototypes -----------------------------------------------*/
static uint8_t CCID_Init(USBD_HandleTypeDef *pdev);
static uint8_t CCID_DeInit(USBD_HandleTypeDef *pdev);
static uint8_t CCID_ControlReq(uint8_t req, uint8_t *pbuf, uint16_t *length);
static uint8_t CCID_Response_SendData(USBD_HandleTypeDef *pdev, uint8_t *buf, uint16_t len);
static uint8_t CCID_Send_Process(uint8_t *Command, uint8_t *Data);
static uint8_t CCID_Response_Process(void);
static uint8_t CCID_SetSlotStatus(USBD_HandleTypeDef *pdev);
/* Private functions ---------------------------------------------------------*/
/**
* @}
*/
USBD_CCID_ItfTypeDef USBD_CCID_If_fops =
{
CCID_Init,
CCID_DeInit,
CCID_ControlReq,
CCID_Response_SendData,
CCID_Send_Process,
CCID_SetSlotStatus,
};
/**
* @brief CCID_Init
* Initialize the CCID USB Layer
* @param pdev: device instance
* @retval status value
*/
uint8_t CCID_Init(USBD_HandleTypeDef *pdev)
{
#ifdef USE_USBD_COMPOSITE
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
#else
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData;
#endif /* USE_USBD_COMPOSITE */
/* CCID Related Initialization */
hccid->blkt_state = CCID_STATE_IDLE;
return (uint8_t)USBD_OK;
}
/**
* @brief CCID_DeInit
* Uninitialize the CCID Machine
* @param pdev: device instance
* @retval status value
*/
uint8_t CCID_DeInit(USBD_HandleTypeDef *pdev)
{
#ifdef USE_USBD_COMPOSITE
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
#else
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData;
#endif /* USE_USBD_COMPOSITE */
hccid->blkt_state = CCID_STATE_IDLE;
return (uint8_t)USBD_OK;
}
/**
* @brief CCID_ControlReq
* Manage the CCID class requests
* @param Cmd: Command code
* @param Buf: Buffer containing command data (request parameters)
* @param Len: Number of data to be sent (in bytes)
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
static uint8_t CCID_ControlReq(uint8_t req, uint8_t *pbuf, uint16_t *length)
{
#ifdef USE_USBD_COMPOSITE
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)USBD_Device.pClassDataCmsit[USBD_Device.classId];
#else
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)USBD_Device.pClassData;
#endif /* USE_USBD_COMPOSITE */
UNUSED(length);
switch (req)
{
case REQUEST_ABORT:
/* The wValue field contains the slot number (bSlot) in the low byte
and the sequence number (bSeq) in the high byte.*/
hccid->slot_nb = ((uint16_t) * pbuf & 0x0fU);
hccid->seq_nb = (((uint16_t) * pbuf & 0xf0U) >> 8);
if (CCID_CmdAbort(&USBD_Device, (uint8_t)hccid->slot_nb, (uint8_t)hccid->seq_nb) != 0U)
{
/* If error is returned by lower layer :
Generally Slot# may not have matched */
return (int8_t)USBD_FAIL;
}
break;
case REQUEST_GET_CLOCK_FREQUENCIES:
/* User have to fill the pbuf with the GetClockFrequency data buffer */
break;
case REQUEST_GET_DATA_RATES:
/* User have to fill the pbuf with the GetDataRates data buffer */
break;
default:
break;
}
UNUSED(pbuf);
return ((int8_t)USBD_OK);
}
/**
* @brief CCID_Response_SendData
* Send the data on bulk-in EP
* @param pdev: device instance
* @param buf: pointer to data buffer
* @param len: Data Length
* @retval status value
*/
uint8_t CCID_Response_SendData(USBD_HandleTypeDef *pdev, uint8_t *buf, uint16_t len)
{
(void)USBD_LL_Transmit(pdev, CCID_IN_EP, buf, len);
return (uint8_t)USBD_OK;
}
/**
* @brief CCID_SEND_Process
* @param Command: pointer to a buffer containing command header
* @param Data: pointer to a buffer containing data sent from Host
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
static uint8_t CCID_Send_Process(uint8_t *Command, uint8_t *Data)
{
Command_State_t Command_State = Command_NOT_OK;
/* Initialize ICC APP header */
uint8_t SC_Command[5] = {0};
UNUSED(Data);
UNUSED(Command_State);
UNUSED(SC_Command);
/* Start SC Demo ---------------------------------------------------------*/
switch (Command[1]) /* type of instruction */
{
case SC_ENABLE:
/* Add your code here */
break;
case SC_VERIFY:
/* Add your code here */
break;
case SC_READ_BINARY :
/* Add your code here */
break;
case SC_CHANGE :
/* Add your code here */
break;
default:
break;
}
/* check if Command header is OK */
(void)CCID_Response_Process(); /* Get ICC response */
return ((uint8_t)USBD_OK);
}
/**
* @brief CCID_Response_Process
* @param None
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
static uint8_t CCID_Response_Process(void)
{
switch (REP_command)
{
case REP_OK:
/* Add your code here */
break;
case REP_NOT_OK :
/* Add your code here */
break;
case REP_NOT_SUPP :
/* Add your code here */
break;
case REP_ENABLED :
/* Add your code here */
break;
case REP_CHANGE :
/* Add your code here */
break;
default:
break;
}
return ((uint8_t)USBD_OK);
}
/**
* @brief CCID_SetSlotStatus
* Set Slot Status of the Interrupt Transfer
* @param pdev: device instance
* @retval status
*/
uint8_t CCID_SetSlotStatus(USBD_HandleTypeDef *pdev)
{
/* Get the CCID handler pointer */
#ifdef USE_USBD_COMPOSITE
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
#else
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData;
#endif /* USE_USBD_COMPOSITE */
if ((hccid->SlotStatus.SlotStatus) == 1U) /* Transfer Complete Status
of previous Interrupt transfer */
{
/* Add your code here */
}
else
{
/* Add your code here */
}
return (uint8_t)USBD_OK;
}

View File

@@ -0,0 +1,473 @@
/**
******************************************************************************
* @file usbd_ccid_sc_if_template.c
* @author MCD Application Team
* @brief SmartCard Interface file
******************************************************************************
* @attention
*
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_ccid_sc_if_template.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* State Machine for the SmartCard Interface */
static SC_State SCState = SC_POWER_OFF;
/* APDU Transport Structures */
SC_ADPU_CommandsTypeDef SC_ADPU;
SC_ADPU_ResponseTypeDef SC_Response;
SC_Param_t SC_Param;
Protocol_01_DataTypeDef ProtocolData;
/* Extern variables ----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
static void SC_SaveVoltage(uint8_t voltage);
static void SC_Itf_UpdateParams(void);
/* Private functions ---------------------------------------------------------*/
/**
* @brief SC_Itf_IccPowerOn Manages the Warm and Cold Reset
and get the Answer to Reset from ICC
* @param voltage: required by host
* @retval None
*/
void SC_Itf_IccPowerOn(uint8_t voltage)
{
SCState = SC_POWER_ON;
SC_ADPU.Header.CLA = 0x00U;
SC_ADPU.Header.INS = SC_GET_A2R;
SC_ADPU.Header.P1 = 0x00U;
SC_ADPU.Header.P2 = 0x00U;
SC_ADPU.Body.LC = 0x00U;
/* Power ON the card */
SC_PowerCmd(SC_ENABLED);
/* Configure the Voltage, Even if IO is still not configured */
SC_VoltageConfig(voltage);
while ((SCState != SC_ACTIVE_ON_T0) && (SCState != SC_ACTIVE_ON_T1)
&& (SCState != SC_NO_INIT))
{
/* If Either The Card has become Active or Become De-Active */
SC_Handler(&SCState, &SC_ADPU, &SC_Response);
}
if ((SCState == SC_ACTIVE_ON_T0) || (SCState == SC_ACTIVE_ON_T1))
{
SC_Itf_UpdateParams();
/* Apply the Procedure Type Selection (PTS) */
SC_PTSConfig();
/* Save Voltage for Future use */
SC_SaveVoltage(voltage);
}
return;
}
/**
* @brief SC_Itf_IccPowerOff Power OFF the card
* @param None
* @retval None
*/
void SC_Itf_IccPowerOff(void)
{
SC_PowerCmd(SC_DISABLED);
SC_SetState(SC_POWER_OFF);
return;
}
/**
* @brief Initialize the parameters structures to the default value
* @param None
* @retval None
*/
void SC_Itf_InitParams(void)
{
/*
FI, the reference to a clock rate conversion factor
over the bits b8 to b5
- DI, the reference to a baud rate adjustment factor
over the bits b4 to bl
*/
SC_Param.SC_A2R_FiDi = DEFAULT_FIDI;
SC_Param.SC_hostFiDi = DEFAULT_FIDI;
ProtocolData.bmFindexDindex = DEFAULT_FIDI;
/* Placeholder, Ignored */
/* 0 = Direct, first byte of the ICC ATR data. */
ProtocolData.bmTCCKST0 = DEFAULT_T01CONVCHECKSUM;
/* Extra GuardTime = 0 etu */
ProtocolData.bGuardTimeT0 = DEFAULT_EXTRA_GUARDTIME;
ProtocolData.bWaitingIntegerT0 = DEFAULT_WAITINGINTEGER;
ProtocolData.bClockStop = 0U; /* Stopping the Clock is not allowed */
/*T=1 protocol */
ProtocolData.bIfsc = DEFAULT_IFSC;
ProtocolData.bNad = DEFAULT_NAD;
return;
}
/**
* @brief Save the A2R Parameters for further usage
* @param None
* @retval None
*/
static void SC_Itf_UpdateParams(void)
{
/*
FI, the reference to a clock rate conversion factor
over the bits b8 to b5
DI, the reference to a baud rate adjustment factor
over the bits b4 to bl
*/
SC_Param.SC_A2R_FiDi = SC_A2R.T[0].InterfaceByte[0].Value;
SC_Param.SC_hostFiDi = SC_A2R.T[0].InterfaceByte[0].Value;
ProtocolData.bmFindexDindex = SC_A2R.T[0].InterfaceByte[0].Value;
return;
}
/**
* @brief SC_Itf_SetParams
* Set the parameters for CCID/USART interface
* @param pPtr: pointer to buffer containing the
* parameters to be set in USART
* @param T_01: type of protocol, T=1 or T=0
* @retval status value
*/
uint8_t SC_Itf_SetParams(Protocol_01_DataTypeDef *pPtr, uint8_t T_01)
{
/* uint16_t guardTime; */ /* Keep it 16b for handling 8b additions */
uint32_t fi_new;
uint32_t di_new;
Protocol_01_DataTypeDef New_DataStructure;
fi_new = pPtr->bmFindexDindex;
di_new = pPtr->bmFindexDindex;
New_DataStructure.bmTCCKST0 = pPtr->bmTCCKST0;
New_DataStructure.bGuardTimeT0 = pPtr->bGuardTimeT0;
New_DataStructure.bWaitingIntegerT0 = pPtr->bWaitingIntegerT0;
New_DataStructure.bClockStop = pPtr->bClockStop;
if (T_01 == 0x01U)
{
New_DataStructure.bIfsc = pPtr->bIfsc;
New_DataStructure.bNad = pPtr->bNad;
}
else
{
New_DataStructure.bIfsc = 0x00U;
New_DataStructure.bNad = 0x00U;
}
/* Check for the FIDI Value set by Host */
di_new &= (uint8_t)0x0F;
if (SC_GetDTableValue(di_new) == 0U)
{
return SLOTERROR_BAD_FIDI;
}
fi_new >>= 4U;
fi_new &= 0x0FU;
if (SC_GetDTableValue(fi_new) == 0U)
{
return SLOTERROR_BAD_FIDI;
}
if ((T_01 == 0x00U)
&& (New_DataStructure.bmTCCKST0 != 0x00U)
&& (New_DataStructure.bmTCCKST0 != 0x02U))
{
return SLOTERROR_BAD_T01CONVCHECKSUM;
}
if ((T_01 == 0x01U)
&& (New_DataStructure.bmTCCKST0 != 0x10U)
&& (New_DataStructure.bmTCCKST0 != 0x11U)
&& (New_DataStructure.bmTCCKST0 != 0x12U)
&& (New_DataStructure.bmTCCKST0 != 0x13U))
{
return SLOTERROR_BAD_T01CONVCHECKSUM;
}
if ((New_DataStructure.bWaitingIntegerT0 >= 0xA0U)
&& ((New_DataStructure.bmTCCKST0 & 0x10U) == 0x10U))
{
return SLOTERROR_BAD_WAITINGINTEGER;
}
if ((New_DataStructure.bClockStop != 0x00U)
&& (New_DataStructure.bClockStop != 0x03U))
{
return SLOTERROR_BAD_CLOCKSTOP;
}
if (New_DataStructure.bNad != 0x00U)
{
return SLOTERROR_BAD_NAD;
}
/* Put Total GuardTime in USART Settings */
/* USART_SetGuardTime(SC_USART, (uint8_t)(guardTime + DEFAULT_EXTRA_GUARDTIME)); */
/* Save Extra GuardTime Value */
ProtocolData.bGuardTimeT0 = New_DataStructure.bGuardTimeT0;
ProtocolData.bmTCCKST0 = New_DataStructure.bmTCCKST0;
ProtocolData.bWaitingIntegerT0 = New_DataStructure.bWaitingIntegerT0;
ProtocolData.bClockStop = New_DataStructure.bClockStop;
ProtocolData.bIfsc = New_DataStructure.bIfsc;
ProtocolData.bNad = New_DataStructure.bNad;
/* Save New bmFindexDindex */
SC_Param.SC_hostFiDi = pPtr->bmFindexDindex;
SC_PTSConfig();
ProtocolData.bmFindexDindex = pPtr->bmFindexDindex;
return SLOT_NO_ERROR;
}
/**
* @brief SC_Itf_Escape function from the host
* This is user implementable
* @param ptrEscape: pointer to buffer containing the Escape data
* @param escapeLen: length of escaped data
* @param responseBuff: pointer containing escape buffer response
* @param responseLen: length of escape response buffer
* @retval status value
*/
uint8_t SC_Itf_Escape(uint8_t *ptrEscape, uint32_t escapeLen,
uint8_t *responseBuff, uint32_t *responseLen)
{
UNUSED(ptrEscape);
UNUSED(escapeLen);
UNUSED(responseBuff);
UNUSED(responseLen);
/* Manufacturer specific implementation ... */
/*
uint32_t idx;
uint8_t *pResBuff = responseBuff;
uint8_t *pEscape = ptrEscape;
for(idx = 0; idx < escapeLen; idx++)
{
*pResBuff = *pEscape;
pResBuff++;
pEscape++;
}
*responseLen = escapeLen;
*/
return SLOT_NO_ERROR;
}
/**
* @brief SC_Itf_SetClock function to define Clock Status request from the host.
* This is user implementable
* @param bClockCommand: Clock status from the host
* @retval status value
*/
uint8_t SC_Itf_SetClock(uint8_t bClockCommand)
{
/* bClockCommand
00h restarts Clock
01h Stops Clock in the state shown in the bClockStop
field of the PC_to_RDR_SetParameters command
and RDR_to_PC_Parameters message.*/
if (bClockCommand == 0U)
{
/* 00h restarts Clock : Since Clock is always running, PASS this command */
return SLOT_NO_ERROR;
}
else
{
if (bClockCommand == 1U)
{
return SLOTERROR_BAD_CLOCKCOMMAND;
}
}
return SLOTERROR_CMD_NOT_SUPPORTED;
}
/**
* @brief SC_Itf_XferBlock function from the host.
* This is user implementable
* @param ptrBlock : Pointer containing the data from host
* @param blockLen : length of block data for the data transfer
* @param expectedLen: expected length of data transfer
* @param CCID_BulkIn_Data: Pointer containing the CCID Bulk In Data Structure
* @retval status value
*/
uint8_t SC_Itf_XferBlock(uint8_t *ptrBlock, uint32_t blockLen, uint16_t expectedLen,
USBD_CCID_BulkIn_DataTypeDef *CCID_BulkIn_Data)
{
uint8_t ErrorCode = SLOT_NO_ERROR;
UNUSED(CCID_BulkIn_Data);
UNUSED(expectedLen);
UNUSED(blockLen);
UNUSED(ptrBlock);
if (ProtocolNUM_OUT == 0x00U)
{
/* Add your code here */
}
if (ProtocolNUM_OUT == 0x01U)
{
/* Add your code here */
}
if (ErrorCode != SLOT_NO_ERROR)
{
return ErrorCode;
}
return ErrorCode;
}
/**
* @brief SC_Itf_T0Apdu
Class Specific Request from the host to provide supported data rates
* This is Optional function & user implementable
* @param bmChanges : value specifying which parameter is valid in
* command among next bClassGetResponse, bClassEnvelope
* @param bClassGetResponse : Value to force the class byte of the
* header in a Get Response command.
* @param bClassEnvelope : Value to force the class byte of the header
* in a Envelope command.
* @retval status value
*/
uint8_t SC_Itf_T0Apdu(uint8_t bmChanges, uint8_t bClassGetResponse,
uint8_t bClassEnvelope)
{
UNUSED(bClassEnvelope);
UNUSED(bClassGetResponse);
/* User have to fill the pbuf with the GetDataRates data buffer */
if (bmChanges == 0U)
{
/* Bit cleared indicates that the associated field is not significant and
that default behaviour defined in CCID class descriptor is selected */
return SLOT_NO_ERROR;
}
return SLOTERROR_CMD_NOT_SUPPORTED;
}
/**
* @brief SC_Itf_Mechanical
Mechanical Function being requested by Host
* This is Optional function & user implementable
* @param bFunction : value corresponds to the mechanical function
* being requested by host
* @retval status value
*/
uint8_t SC_Itf_Mechanical(uint8_t bFunction)
{
UNUSED(bFunction);
return SLOTERROR_CMD_NOT_SUPPORTED;
}
/**
* @brief SC_Itf_SetDataRateAndClockFrequency
* Set the Clock and data Rate of the Interface
* This is Optional function & user implementable
* @param dwClockFrequency : value of clock in kHz requested by host
* @param dwDataRate : value of data rate requested by host
* @retval status value
*/
uint8_t SC_Itf_SetDataRateAndClockFrequency(uint32_t dwClockFrequency,
uint32_t dwDataRate)
{
/* User have to fill the pbuf with the GetDataRates data buffer */
if ((dwDataRate == USBD_CCID_DEFAULT_DATA_RATE) &&
(dwClockFrequency == USBD_CCID_DEFAULT_CLOCK_FREQ))
{
return SLOT_NO_ERROR;
}
return SLOTERROR_CMD_NOT_SUPPORTED;
}
/**
* @brief SC_Itf_Secure
* Process the Secure command
* This is Optional function & user implementable
* @param dwLength : length of data from the host
* @param bBWI : Block Waiting Timeout sent by host
* @param wLevelParameter : Parameters sent by host
* @param pbuf : buffer containing the data
* @param returnLen : Length of data expected to return
* @retval status value
*/
uint8_t SC_Itf_Secure(uint32_t dwLength, uint8_t bBWI, uint16_t wLevelParameter,
uint8_t *pbuf, uint32_t *returnLen)
{
UNUSED(pbuf);
UNUSED(wLevelParameter);
UNUSED(bBWI);
UNUSED(dwLength);
*returnLen = 0U;
return SLOTERROR_CMD_NOT_SUPPORTED;
}
/**
* @brief SC_SaveVoltage
Saves the voltage value to be saved for further usage
* @param voltage: voltage value to be saved for further usage
* @retval None
*/
static void SC_SaveVoltage(uint8_t voltage)
{
SC_Param.voltage = voltage;
return;
}
/**
* @brief Provides the value of SCState variable
* @param None
* @retval uint8_t SCState
*/
uint8_t SC_GetState(void)
{
return (uint8_t)SCState;
}
/**
* @brief Set the value of SCState variable to Off
* @param scState: value of SCState to be updated
* @retval None
*/
void SC_SetState(SC_State scState)
{
SCState = scState;
return;
}

View File

@@ -0,0 +1,486 @@
/**
******************************************************************************
* @file usbd_ccid_smartcard_template.c
* @author MCD Application Team
* @brief This file provides all the Smartcard firmware functions.
******************************************************************************
* @attention
*
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/** @addtogroup usbd_ccid_Smartcard
* @{
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_ccid_smartcard_template.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Directories & Files ID */
/*The following Directories & Files ID can take any of following Values and can
be used in the smartcard application */
/*
const uint8_t MasterRoot[2] = {0x3F, 0x00};
const uint8_t GSMDir[2] = {0x7F, 0x20};
const uint8_t ICCID[2] = {0x2F, 0xE2};
const uint8_t IMSI[2] = {0x6F, 0x07};
__IO uint8_t ICCID_Content[10] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint32_t CHV1Status = 0U;
uint8_t CHV1[8] = {'0', '0', '0', '0', '0', '0', '0', '0'};
__IO uint8_t IMSI_Content[9] = {0x01, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
*/
/* F Table: Clock Rate Conversion Table from ISO/IEC 7816-3 */
/* static uint32_t F_Table[16] = {372, 372, 558, 744, 1116, 1488, 1860, 0, 0, 512, 768,
1024, 1536, 2048, 0, 0
}; */
/* D Table: Baud Rate Adjustment Factor Table from ISO/IEC 7816-3 */
static uint32_t D_Table[16] = {0, 1, 2, 4, 8, 16, 32, 64, 12, 20, 0, 0, 0, 0, 0, 0};
/* Global variables definition and initialization ----------------------------*/
SC_ATRTypeDef SC_A2R;
uint8_t SC_ATR_Table[40];
uint8_t ProtocolNUM_OUT;
/* Private function prototypes -----------------------------------------------*/
static void SC_Init(void);
static void SC_DeInit(void);
static void SC_AnswerReq(SC_State *SC_state, uint8_t *card, uint8_t length); /* Ask ATR */
static uint8_t SC_decode_Answer2reset(uint8_t *card); /* Decode ATR */
static void SC_SendData(SC_ADPU_CommandsTypeDef *SCADPU, SC_ADPU_ResponseTypeDef *SC_ResponseStatus);
/* static void SC_Reset(GPIO_PinState ResetState); */
/* Private functions ---------------------------------------------------------*/
/**
* @brief Handles all Smartcard states and serves to send and receive all
* communication data between Smartcard and reader.
* @param SCState: pointer to an SC_State enumeration that will contain the
* Smartcard state.
* @param SC_ADPU: pointer to an SC_ADPU_Commands structure that will be initialized.
* @param SC_Response: pointer to a SC_ADPU_Response structure which will be initialized.
* @retval None
*/
void SC_Handler(SC_State *SCState, SC_ADPU_CommandsTypeDef *SC_ADPU, SC_ADPU_ResponseTypeDef *SC_Response)
{
uint32_t i;
uint32_t j;
switch (*SCState)
{
case SC_POWER_ON:
if (SC_ADPU->Header.INS == SC_GET_A2R)
{
/* Smartcard initialization */
SC_Init();
/* Reset Data from SC buffer */
for (i = 0U; i < 40U; i++)
{
SC_ATR_Table[i] = 0;
}
/* Reset SC_A2R Structure */
SC_A2R.TS = 0U;
SC_A2R.T0 = 0U;
for (i = 0U; i < MAX_PROTOCOLLEVEL; i++)
{
for (j = 0U; j < MAX_INTERFACEBYTE; j++)
{
SC_A2R.T[i].InterfaceByte[j].Status = 0U;
SC_A2R.T[i].InterfaceByte[j].Value = 0U;
}
}
for (i = 0U; i < HIST_LENGTH; i++)
{
SC_A2R.Historical[i] = 0U;
}
SC_A2R.Tlength = 0U;
SC_A2R.Hlength = 0U;
/* Next State */
*SCState = SC_RESET_LOW;
}
break;
case SC_RESET_LOW:
if (SC_ADPU->Header.INS == SC_GET_A2R)
{
/* If card is detected then Power ON, Card Reset and wait for an answer) */
if (SC_Detect() != 0U)
{
while (((*SCState) != SC_POWER_OFF) && ((*SCState) != SC_ACTIVE))
{
SC_AnswerReq(SCState, &SC_ATR_Table[0], 40U); /* Check for answer to reset */
}
}
else
{
(*SCState) = SC_POWER_OFF;
}
}
break;
case SC_ACTIVE:
if (SC_ADPU->Header.INS == SC_GET_A2R)
{
uint8_t protocol = SC_decode_Answer2reset(&SC_ATR_Table[0]);
if (protocol == T0_PROTOCOL)
{
(*SCState) = SC_ACTIVE_ON_T0;
ProtocolNUM_OUT = T0_PROTOCOL;
}
else if (protocol == T1_PROTOCOL)
{
(*SCState) = SC_ACTIVE_ON_T1;
ProtocolNUM_OUT = T1_PROTOCOL;
}
else
{
(*SCState) = SC_POWER_OFF;
}
}
break;
case SC_ACTIVE_ON_T0:
/* process commands other than ATR */
SC_SendData(SC_ADPU, SC_Response);
break;
case SC_ACTIVE_ON_T1:
/* process commands other than ATR */
SC_SendData(SC_ADPU, SC_Response);
break;
case SC_POWER_OFF:
SC_DeInit(); /* Disable Smartcard interface */
break;
default:
(*SCState) = SC_POWER_OFF;
break;
}
}
/**
* @brief Enables or disables the power to the Smartcard.
* @param NewState: new state of the Smartcard power supply.
* This parameter can be: SC_ENABLED or SC_DISABLED.
* @retval None
*/
void SC_PowerCmd(SCPowerState NewState)
{
UNUSED(NewState);
/* enable or disable smartcard pin */
return;
}
/**
* @brief Sets or clears the Smartcard reset pin.
* @param ResetState: this parameter specifies the state of the Smartcard
* reset pin. BitVal must be one of the BitAction enum values:
* @arg Bit_RESET: to clear the port pin.
* @arg Bit_SET: to set the port pin.
* @retval None
*/
/* static void SC_Reset(GPIO_PinState ResetState)
{
UNUSED(ResetState);
return;
}
*/
/**
* @brief Resends the byte that failed to be received (by the Smartcard) correctly.
* @param None
* @retval None
*/
void SC_ParityErrorHandler(void)
{
/* Add your code here */
return;
}
/**
* @brief Configures the IO speed (BaudRate) communication.
* @param None
* @retval None
*/
void SC_PTSConfig(void)
{
/* Add your code here */
return;
}
/**
* @brief Manages the Smartcard transport layer: send APDU commands and receives
* the APDU response.
* @param SC_ADPU: pointer to a SC_ADPU_Commands structure which will be initialized.
* @param SC_Response: pointer to a SC_ADPU_Response structure which will be initialized.
* @retval None
*/
static void SC_SendData(SC_ADPU_CommandsTypeDef *SCADPU, SC_ADPU_ResponseTypeDef *SC_ResponseStatus)
{
uint8_t i;
uint8_t SC_Command[5];
uint8_t SC_DATA[LC_MAX];
UNUSED(SCADPU);
/* Reset response buffer */
for (i = 0U; i < LC_MAX; i++)
{
SC_ResponseStatus->Data[i] = 0U;
SC_DATA[i] = 0U;
}
/* User to add code here */
/* send command to ICC and get response status */
USBD_CCID_If_fops.Send_Process((uint8_t *)&SC_Command, (uint8_t *)&SC_DATA);
}
/**
* @brief SC_AnswerReq
Requests the reset answer from card.
* @param SC_state: pointer to an SC_State enumeration that will contain the Smartcard state.
* @param atr_buffer: pointer to a buffer which will contain the card ATR.
* @param length: maximum ATR length
* @retval None
*/
static void SC_AnswerReq(SC_State *SC_state, uint8_t *atr_buffer, uint8_t length)
{
UNUSED(length);
UNUSED(atr_buffer);
/* to be implemented by USER */
switch (*SC_state)
{
case SC_RESET_LOW:
/* Check response with reset low */
(*SC_state) = SC_ACTIVE;
break;
case SC_ACTIVE:
break;
case SC_RESET_HIGH:
/* Check response with reset high */
break;
case SC_POWER_OFF:
/* Close Connection if no answer received */
break;
default:
(*SC_state) = SC_RESET_LOW;
break;
}
return;
}
/**
* @brief SC_decode_Answer2reset
Decodes the Answer to reset received from card.
* @param card: pointer to the buffer containing the card ATR.
* @retval None
*/
static uint8_t SC_decode_Answer2reset(uint8_t *card)
{
uint32_t i = 0U;
uint32_t flag = 0U;
uint32_t protocol;
uint8_t index = 0U;
uint8_t level = 0U;
/******************************TS/T0 Decode************************************/
index++;
SC_A2R.TS = card[index]; /* Initial character */
index++;
SC_A2R.T0 = card[index]; /* Format character */
/*************************Historical Table Length Decode***********************/
SC_A2R.Hlength = SC_A2R.T0 & 0x0FU;
/******************************Protocol Level(1) Decode************************/
/* Check TD(1) if present */
if ((SC_A2R.T0 & 0x80U) == 0x80U)
{
flag = 1U;
}
/* Each bits in the T0 high nibble(b8 to b5) equal to 1 indicates the presence
of a further interface byte */
for (i = 0U; i < 4U; i++)
{
if ((((SC_A2R.T0 & 0xF0U) >> (4U + i)) & 0x1U) != 0U)
{
SC_A2R.T[level].InterfaceByte[i].Status = 1U;
index++;
SC_A2R.T[level].InterfaceByte[i].Value = card[index];
SC_A2R.Tlength++;
}
}
/*****************************T Decode*****************************************/
if (SC_A2R.T[level].InterfaceByte[3].Status == 1U)
{
/* Only the protocol(parameter T) present in TD(1) is detected
if two or more values of parameter T are present in TD(1), TD(2)..., so the
firmware should be updated to support them */
protocol = (uint8_t)(SC_A2R.T[level].InterfaceByte[SC_INTERFACEBYTE_TD].Value & 0x0FU);
}
else
{
protocol = 0U;
}
/* Protocol Level Increment */
/******************************Protocol Level(n>1) Decode**********************/
while (flag != 0U)
{
if ((SC_A2R.T[level].InterfaceByte[SC_INTERFACEBYTE_TD].Value & 0x80U) == 0x80U)
{
flag = 1U;
}
else
{
flag = 0U;
}
/* Each bits in the high nibble(b8 to b5) for the TD(i) equal to 1 indicates
the presence of a further interface byte */
for (i = 0U; i < 4U; i++)
{
if ((((SC_A2R.T[level].InterfaceByte[SC_INTERFACEBYTE_TD].Value & 0xF0U) >> (4U + i)) & 0x1U) != 0U)
{
SC_A2R.T[level + 1U].InterfaceByte[i].Status = 1U;
index++;
SC_A2R.T[level + 1U].InterfaceByte[i].Value = card[index];
SC_A2R.Tlength++;
}
}
level++;
}
for (i = 0U; i < SC_A2R.Hlength; i++)
{
SC_A2R.Historical[i] = card[i + 2U + SC_A2R.Tlength];
}
/*************************************TCK Decode*******************************/
SC_A2R.TCK = card[SC_A2R.Hlength + 2U + SC_A2R.Tlength];
return (uint8_t)protocol;
}
/**
* @brief Initializes all peripheral used for Smartcard interface.
* @param None
* @retval None
*/
static void SC_Init(void)
{
/*
Add your initialization code here
*/
return;
}
/**
* @brief Deinitializes all resources used by the Smartcard interface.
* @param None
* @retval None
*/
static void SC_DeInit(void)
{
/*
Add your deinitialization code here
*/
return;
}
/**
* @brief Configures the card power voltage.
* @param SC_Voltage: specifies the card power voltage.
* This parameter can be one of the following values:
* @arg SC_VOLTAGE_5V: 5V cards.
* @arg SC_VOLTAGE_3V: 3V cards.
* @retval None
*/
void SC_VoltageConfig(uint32_t SC_Voltage)
{
UNUSED(SC_Voltage);
/* Add your code here */
return;
}
/**
* @brief Configures GPIO hardware resources used for Samrtcard.
* @param None
* @retval None
*/
void SC_IOConfig(void)
{
/* Add your code here */
return;
}
/**
* @brief Detects whether the Smartcard is present or not.
* @param None.
* @retval 1 - Smartcard inserted
* 0 - Smartcard not inserted
*/
uint8_t SC_Detect(void)
{
uint8_t PIN_State = 0U;
/* Add your code here */
return PIN_State;
}
/**
* @brief Get the Right Value from the D_Table Index
* @param idx : Index to Read from the Table
* @retval Value read from the Table
*/
uint32_t SC_GetDTableValue(uint32_t idx)
{
return D_Table[idx];
}

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -41,9 +40,15 @@ extern "C" {
/** @defgroup usbd_cdc_Exported_Defines
* @{
*/
#ifndef CDC_IN_EP
#define CDC_IN_EP 0x81U /* EP1 for data IN */
#endif /* CDC_IN_EP */
#ifndef CDC_OUT_EP
#define CDC_OUT_EP 0x01U /* EP1 for data OUT */
#endif /* CDC_OUT_EP */
#ifndef CDC_CMD_EP
#define CDC_CMD_EP 0x82U /* EP2 for CDC commands */
#endif /* CDC_CMD_EP */
#ifndef CDC_HS_BINTERVAL
#define CDC_HS_BINTERVAL 0x10U
@@ -149,12 +154,17 @@ extern USBD_ClassTypeDef USBD_CDC;
uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev,
USBD_CDC_ItfTypeDef *fops);
#ifdef USE_USBD_COMPOSITE
uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff,
uint32_t length, uint8_t ClassId);
uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t ClassId);
#else
uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff,
uint32_t length);
uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev);
#endif /* USE_USBD_COMPOSITE */
uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff);
uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev);
uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev);
/**
* @}
*/
@@ -172,4 +182,3 @@ uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev);
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -42,4 +41,3 @@ extern USBD_CDC_ItfTypeDef USBD_CDC_Template_fops;
#endif /* __USBD_CDC_IF_TEMPLATE_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -10,6 +10,17 @@
* - Command IN transfer (class requests management)
* - Error management
*
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
* @verbatim
*
* ===================================================================
@@ -37,17 +48,6 @@
* @endverbatim
*
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* BSPDependencies
@@ -105,13 +105,14 @@ static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *re
static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev);
#ifndef USE_USBD_COMPOSITE
static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length);
static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length);
static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length);
static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length);
uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length);
#endif /* USE_USBD_COMPOSITE */
#ifndef USE_USBD_COMPOSITE
/* USB Standard Device Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
{
@@ -126,7 +127,7 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_
0x01,
0x00,
};
#endif /* USE_USBD_COMPOSITE */
/**
* @}
*/
@@ -149,113 +150,22 @@ USBD_ClassTypeDef USBD_CDC =
NULL,
NULL,
NULL,
#ifdef USE_USBD_COMPOSITE
NULL,
NULL,
NULL,
NULL,
#else
USBD_CDC_GetHSCfgDesc,
USBD_CDC_GetFSCfgDesc,
USBD_CDC_GetOtherSpeedCfgDesc,
USBD_CDC_GetDeviceQualifierDescriptor,
#endif /* USE_USBD_COMPOSITE */
};
#ifndef USE_USBD_COMPOSITE
/* USB CDC device Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
{
/* Configuration Descriptor */
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */
0x00,
0x02, /* bNumInterfaces: 2 interfaces */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
#if (USBD_SELF_POWERED == 1U)
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
USBD_MAX_POWER, /* MaxPower (mA) */
/*---------------------------------------------------------------------------*/
/* Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints: One endpoints used */
0x02, /* bInterfaceClass: Communication Interface Class */
0x02, /* bInterfaceSubClass: Abstract Control Model */
0x01, /* bInterfaceProtocol: Common AT commands */
0x00, /* iInterface */
/* Header Functional Descriptor */
0x05, /* bLength: Endpoint Descriptor size */
0x24, /* bDescriptorType: CS_INTERFACE */
0x00, /* bDescriptorSubtype: Header Func Desc */
0x10, /* bcdCDC: spec release number */
0x01,
/* Call Management Functional Descriptor */
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x01, /* bDescriptorSubtype: Call Management Func Desc */
0x00, /* bmCapabilities: D0+D1 */
0x01, /* bDataInterface: 1 */
/* ACM Functional Descriptor */
0x04, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
0x02, /* bmCapabilities */
/* Union Functional Descriptor */
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x06, /* bDescriptorSubtype: Union func desc */
0x00, /* bMasterInterface: Communication class interface */
0x01, /* bSlaveInterface0: Data Class Interface */
/* Endpoint 2 Descriptor */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_CMD_EP, /* bEndpointAddress */
0x03, /* bmAttributes: Interrupt */
LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize */
HIBYTE(CDC_CMD_PACKET_SIZE),
CDC_HS_BINTERVAL, /* bInterval */
/*---------------------------------------------------------------------------*/
/* Data class interface descriptor */
0x09, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
0x01, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints: Two endpoints used */
0x0A, /* bInterfaceClass: CDC */
0x00, /* bInterfaceSubClass */
0x00, /* bInterfaceProtocol */
0x00, /* iInterface */
/* Endpoint OUT Descriptor */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_OUT_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize */
HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
0x00, /* bInterval */
/* Endpoint IN Descriptor */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_IN_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize */
HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
0x00 /* bInterval */
};
/* USB CDC device Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
__ALIGN_BEGIN static uint8_t USBD_CDC_CfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
{
/* Configuration Descriptor */
0x09, /* bLength: Configuration Descriptor size */
@@ -264,12 +174,13 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN
0x00,
0x02, /* bNumInterfaces: 2 interfaces */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
0x00, /* iConfiguration: Index of string descriptor
describing the configuration */
#if (USBD_SELF_POWERED == 1U)
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
#endif /* USBD_SELF_POWERED */
USBD_MAX_POWER, /* MaxPower (mA) */
/*---------------------------------------------------------------------------*/
@@ -352,102 +263,11 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN
HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
0x00 /* bInterval */
};
#endif /* USE_USBD_COMPOSITE */
__ALIGN_BEGIN static uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
{
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,
USB_CDC_CONFIG_DESC_SIZ,
0x00,
0x02, /* bNumInterfaces: 2 interfaces */
0x01, /* bConfigurationValue */
0x04, /* iConfiguration */
#if (USBD_SELF_POWERED == 1U)
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
USBD_MAX_POWER, /* MaxPower (mA) */
/* Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
/* Interface descriptor type */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints: One endpoints used */
0x02, /* bInterfaceClass: Communication Interface Class */
0x02, /* bInterfaceSubClass: Abstract Control Model */
0x01, /* bInterfaceProtocol: Common AT commands */
0x00, /* iInterface */
/* Header Functional Descriptor */
0x05, /* bLength: Endpoint Descriptor size */
0x24, /* bDescriptorType: CS_INTERFACE */
0x00, /* bDescriptorSubtype: Header Func Desc */
0x10, /* bcdCDC: spec release number */
0x01,
/* Call Management Functional Descriptor */
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x01, /* bDescriptorSubtype: Call Management Func Desc */
0x00, /* bmCapabilities */
0x01, /* bDataInterface */
/* ACM Functional Descriptor */
0x04, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
0x02, /* bmCapabilities */
/* Union Functional Descriptor */
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x06, /* bDescriptorSubtype: Union func desc */
0x00, /* bMasterInterface: Communication class interface */
0x01, /* bSlaveInterface0: Data Class Interface */
/* Endpoint 2 Descriptor */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_CMD_EP, /* bEndpointAddress */
0x03, /* bmAttributes: Interrupt */
LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize */
HIBYTE(CDC_CMD_PACKET_SIZE),
CDC_FS_BINTERVAL, /* bInterval */
/*---------------------------------------------------------------------------*/
/*Data class interface descriptor*/
0x09, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
0x01, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints: Two endpoints used */
0x0A, /* bInterfaceClass: CDC */
0x00, /* bInterfaceSubClass */
0x00, /* bInterfaceProtocol */
0x00, /* iInterface */
/*Endpoint OUT Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_OUT_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
0x40, /* wMaxPacketSize */
0x00,
0x00, /* bInterval */
/*Endpoint IN Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_IN_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
0x40, /* wMaxPacketSize */
0x00,
0x00 /* bInterval */
};
static uint8_t CDCInEpAdd = CDC_IN_EP;
static uint8_t CDCOutEpAdd = CDC_OUT_EP;
static uint8_t CDCCmdEpAdd = CDC_CMD_EP;
/**
* @}
@@ -473,68 +293,85 @@ static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
if (hcdc == NULL)
{
pdev->pClassData = NULL;
pdev->pClassDataCmsit[pdev->classId] = NULL;
return (uint8_t)USBD_EMEM;
}
pdev->pClassData = (void *)hcdc;
(void)USBD_memset(hcdc, 0, sizeof(USBD_CDC_HandleTypeDef));
pdev->pClassDataCmsit[pdev->classId] = (void *)hcdc;
pdev->pClassData = pdev->pClassDataCmsit[pdev->classId];
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
CDCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
CDCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
CDCCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (pdev->dev_speed == USBD_SPEED_HIGH)
{
/* Open EP IN */
(void)USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK,
(void)USBD_LL_OpenEP(pdev, CDCInEpAdd, USBD_EP_TYPE_BULK,
CDC_DATA_HS_IN_PACKET_SIZE);
pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U;
pdev->ep_in[CDCInEpAdd & 0xFU].is_used = 1U;
/* Open EP OUT */
(void)USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK,
(void)USBD_LL_OpenEP(pdev, CDCOutEpAdd, USBD_EP_TYPE_BULK,
CDC_DATA_HS_OUT_PACKET_SIZE);
pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U;
pdev->ep_out[CDCOutEpAdd & 0xFU].is_used = 1U;
/* Set bInterval for CDC CMD Endpoint */
pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = CDC_HS_BINTERVAL;
pdev->ep_in[CDCCmdEpAdd & 0xFU].bInterval = CDC_HS_BINTERVAL;
}
else
{
/* Open EP IN */
(void)USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK,
(void)USBD_LL_OpenEP(pdev, CDCInEpAdd, USBD_EP_TYPE_BULK,
CDC_DATA_FS_IN_PACKET_SIZE);
pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U;
pdev->ep_in[CDCInEpAdd & 0xFU].is_used = 1U;
/* Open EP OUT */
(void)USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK,
(void)USBD_LL_OpenEP(pdev, CDCOutEpAdd, USBD_EP_TYPE_BULK,
CDC_DATA_FS_OUT_PACKET_SIZE);
pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U;
pdev->ep_out[CDCOutEpAdd & 0xFU].is_used = 1U;
/* Set bInterval for CMD Endpoint */
pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = CDC_FS_BINTERVAL;
pdev->ep_in[CDCCmdEpAdd & 0xFU].bInterval = CDC_FS_BINTERVAL;
}
/* Open Command IN EP */
(void)USBD_LL_OpenEP(pdev, CDC_CMD_EP, USBD_EP_TYPE_INTR, CDC_CMD_PACKET_SIZE);
pdev->ep_in[CDC_CMD_EP & 0xFU].is_used = 1U;
(void)USBD_LL_OpenEP(pdev, CDCCmdEpAdd, USBD_EP_TYPE_INTR, CDC_CMD_PACKET_SIZE);
pdev->ep_in[CDCCmdEpAdd & 0xFU].is_used = 1U;
hcdc->RxBuffer = NULL;
/* Init physical Interface components */
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init();
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init();
/* Init Xfer states */
hcdc->TxState = 0U;
hcdc->RxState = 0U;
if (hcdc->RxBuffer == NULL)
{
return (uint8_t)USBD_EMEM;
}
if (pdev->dev_speed == USBD_SPEED_HIGH)
{
/* Prepare Out endpoint to receive next packet */
(void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
(void)USBD_LL_PrepareReceive(pdev, CDCOutEpAdd, hcdc->RxBuffer,
CDC_DATA_HS_OUT_PACKET_SIZE);
}
else
{
/* Prepare Out endpoint to receive next packet */
(void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
(void)USBD_LL_PrepareReceive(pdev, CDCOutEpAdd, hcdc->RxBuffer,
CDC_DATA_FS_OUT_PACKET_SIZE);
}
@@ -552,24 +389,33 @@ static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
UNUSED(cfgidx);
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this CDC class instance */
CDCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
CDCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
CDCCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
/* Close EP IN */
(void)USBD_LL_CloseEP(pdev, CDC_IN_EP);
pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 0U;
(void)USBD_LL_CloseEP(pdev, CDCInEpAdd);
pdev->ep_in[CDCInEpAdd & 0xFU].is_used = 0U;
/* Close EP OUT */
(void)USBD_LL_CloseEP(pdev, CDC_OUT_EP);
pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 0U;
(void)USBD_LL_CloseEP(pdev, CDCOutEpAdd);
pdev->ep_out[CDCOutEpAdd & 0xFU].is_used = 0U;
/* Close Command IN EP */
(void)USBD_LL_CloseEP(pdev, CDC_CMD_EP);
pdev->ep_in[CDC_CMD_EP & 0xFU].is_used = 0U;
pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = 0U;
(void)USBD_LL_CloseEP(pdev, CDCCmdEpAdd);
pdev->ep_in[CDCCmdEpAdd & 0xFU].is_used = 0U;
pdev->ep_in[CDCCmdEpAdd & 0xFU].bInterval = 0U;
/* DeInit physical Interface components */
if (pdev->pClassData != NULL)
if (pdev->pClassDataCmsit[pdev->classId] != NULL)
{
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->DeInit();
(void)USBD_free(pdev->pClassData);
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit();
(void)USBD_free(pdev->pClassDataCmsit[pdev->classId]);
pdev->pClassDataCmsit[pdev->classId] = NULL;
pdev->pClassData = NULL;
}
@@ -586,7 +432,7 @@ static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
USBD_SetupReqTypedef *req)
{
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint16_t len;
uint8_t ifalt = 0U;
uint16_t status_info = 0U;
@@ -604,7 +450,7 @@ static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
{
if ((req->bmRequest & 0x80U) != 0U)
{
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Control(req->bRequest,
(uint8_t *)hcdc->data,
req->wLength);
@@ -621,7 +467,7 @@ static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
}
else
{
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Control(req->bRequest,
(uint8_t *)req, 0U);
}
break;
@@ -690,20 +536,20 @@ static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
USBD_CDC_HandleTypeDef *hcdc;
PCD_HandleTypeDef *hpcd = pdev->pData;
PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef *)pdev->pData;
if (pdev->pClassData == NULL)
if (pdev->pClassDataCmsit[pdev->classId] == NULL)
{
return (uint8_t)USBD_FAIL;
}
hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if ((pdev->ep_in[epnum].total_length > 0U) &&
((pdev->ep_in[epnum].total_length % hpcd->IN_ep[epnum].maxpacket) == 0U))
if ((pdev->ep_in[epnum & 0xFU].total_length > 0U) &&
((pdev->ep_in[epnum & 0xFU].total_length % hpcd->IN_ep[epnum & 0xFU].maxpacket) == 0U))
{
/* Update the packet total length */
pdev->ep_in[epnum].total_length = 0U;
pdev->ep_in[epnum & 0xFU].total_length = 0U;
/* Send ZLP */
(void)USBD_LL_Transmit(pdev, epnum, NULL, 0U);
@@ -712,9 +558,9 @@ static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
hcdc->TxState = 0U;
if (((USBD_CDC_ItfTypeDef *)pdev->pUserData)->TransmitCplt != NULL)
if (((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->TransmitCplt != NULL)
{
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum);
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum);
}
}
@@ -730,9 +576,9 @@ static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
*/
static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (pdev->pClassData == NULL)
if (pdev->pClassDataCmsit[pdev->classId] == NULL)
{
return (uint8_t)USBD_FAIL;
}
@@ -743,7 +589,7 @@ static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
/* USB data will be immediately processed, this allow next USB traffic being
NAKed till the end of the application Xfer */
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength);
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Receive(hcdc->RxBuffer, &hcdc->RxLength);
return (uint8_t)USBD_OK;
}
@@ -756,16 +602,16 @@ static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
*/
static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev)
{
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hcdc == NULL)
{
return (uint8_t)USBD_FAIL;
}
if ((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFFU))
if ((pdev->pUserData[pdev->classId] != NULL) && (hcdc->CmdOpCode != 0xFFU))
{
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode,
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Control(hcdc->CmdOpCode,
(uint8_t *)hcdc->data,
(uint16_t)hcdc->CmdLength);
hcdc->CmdOpCode = 0xFFU;
@@ -773,47 +619,98 @@ static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev)
return (uint8_t)USBD_OK;
}
#ifndef USE_USBD_COMPOSITE
/**
* @brief USBD_CDC_GetFSCfgDesc
* Return configuration descriptor
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length)
{
*length = (uint16_t)sizeof(USBD_CDC_CfgFSDesc);
USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_CMD_EP);
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_OUT_EP);
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_IN_EP);
return USBD_CDC_CfgFSDesc;
if (pEpCmdDesc != NULL)
{
pEpCmdDesc->bInterval = CDC_FS_BINTERVAL;
}
if (pEpOutDesc != NULL)
{
pEpOutDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE;
}
if (pEpInDesc != NULL)
{
pEpInDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE;
}
*length = (uint16_t)sizeof(USBD_CDC_CfgDesc);
return USBD_CDC_CfgDesc;
}
/**
* @brief USBD_CDC_GetHSCfgDesc
* Return configuration descriptor
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length)
{
*length = (uint16_t)sizeof(USBD_CDC_CfgHSDesc);
USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_CMD_EP);
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_OUT_EP);
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_IN_EP);
return USBD_CDC_CfgHSDesc;
if (pEpCmdDesc != NULL)
{
pEpCmdDesc->bInterval = CDC_HS_BINTERVAL;
}
if (pEpOutDesc != NULL)
{
pEpOutDesc->wMaxPacketSize = CDC_DATA_HS_MAX_PACKET_SIZE;
}
if (pEpInDesc != NULL)
{
pEpInDesc->wMaxPacketSize = CDC_DATA_HS_MAX_PACKET_SIZE;
}
*length = (uint16_t)sizeof(USBD_CDC_CfgDesc);
return USBD_CDC_CfgDesc;
}
/**
* @brief USBD_CDC_GetOtherSpeedCfgDesc
* Return configuration descriptor
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length)
{
*length = (uint16_t)sizeof(USBD_CDC_OtherSpeedCfgDesc);
USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_CMD_EP);
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_OUT_EP);
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_IN_EP);
return USBD_CDC_OtherSpeedCfgDesc;
if (pEpCmdDesc != NULL)
{
pEpCmdDesc->bInterval = CDC_FS_BINTERVAL;
}
if (pEpOutDesc != NULL)
{
pEpOutDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE;
}
if (pEpInDesc != NULL)
{
pEpInDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE;
}
*length = (uint16_t)sizeof(USBD_CDC_CfgDesc);
return USBD_CDC_CfgDesc;
}
/**
@@ -828,7 +725,7 @@ uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length)
return USBD_CDC_DeviceQualifierDesc;
}
#endif /* USE_USBD_COMPOSITE */
/**
* @brief USBD_CDC_RegisterInterface
* @param pdev: device instance
@@ -843,21 +740,31 @@ uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev,
return (uint8_t)USBD_FAIL;
}
pdev->pUserData = fops;
pdev->pUserData[pdev->classId] = fops;
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_CDC_SetTxBuffer
* @param pdev: device instance
* @param pbuff: Tx Buffer
* @param length: length of data to be sent
* @param ClassId: The Class ID
* @retval status
*/
#ifdef USE_USBD_COMPOSITE
uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev,
uint8_t *pbuff, uint32_t length, uint8_t ClassId)
{
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[ClassId];
#else
uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev,
uint8_t *pbuff, uint32_t length)
{
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
#endif /* USE_USBD_COMPOSITE */
if (hcdc == NULL)
{
@@ -878,7 +785,7 @@ uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev,
*/
uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff)
{
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hcdc == NULL)
{
@@ -890,18 +797,32 @@ uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff)
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_CDC_TransmitPacket
* Transmit packet on IN endpoint
* @param pdev: device instance
* @param ClassId: The Class ID
* @retval status
*/
#ifdef USE_USBD_COMPOSITE
uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t ClassId)
{
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[ClassId];
#else
uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
{
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
#endif /* USE_USBD_COMPOSITE */
USBD_StatusTypeDef ret = USBD_BUSY;
if (pdev->pClassData == NULL)
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
CDCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, ClassId);
#endif /* USE_USBD_COMPOSITE */
if (hcdc == NULL)
{
return (uint8_t)USBD_FAIL;
}
@@ -912,10 +833,10 @@ uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
hcdc->TxState = 1U;
/* Update the packet total length */
pdev->ep_in[CDC_IN_EP & 0xFU].total_length = hcdc->TxLength;
pdev->ep_in[CDCInEpAdd & 0xFU].total_length = hcdc->TxLength;
/* Transmit next packet */
(void)USBD_LL_Transmit(pdev, CDC_IN_EP, hcdc->TxBuffer, hcdc->TxLength);
(void)USBD_LL_Transmit(pdev, CDCInEpAdd, hcdc->TxBuffer, hcdc->TxLength);
ret = USBD_OK;
}
@@ -931,9 +852,14 @@ uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
*/
uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev)
{
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (pdev->pClassData == NULL)
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
CDCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (pdev->pClassDataCmsit[pdev->classId] == NULL)
{
return (uint8_t)USBD_FAIL;
}
@@ -941,13 +867,13 @@ uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev)
if (pdev->dev_speed == USBD_SPEED_HIGH)
{
/* Prepare Out endpoint to receive next packet */
(void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
(void)USBD_LL_PrepareReceive(pdev, CDCOutEpAdd, hcdc->RxBuffer,
CDC_DATA_HS_OUT_PACKET_SIZE);
}
else
{
/* Prepare Out endpoint to receive next packet */
(void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
(void)USBD_LL_PrepareReceive(pdev, CDCOutEpAdd, hcdc->RxBuffer,
CDC_DATA_FS_OUT_PACKET_SIZE);
}
@@ -965,4 +891,3 @@ uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev)
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -128,6 +127,8 @@ static int8_t TEMPLATE_DeInit(void)
*/
static int8_t TEMPLATE_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length)
{
UNUSED(length);
switch (cmd)
{
case CDC_SEND_ENCAPSULATED_COMMAND:
@@ -244,5 +245,3 @@ static int8_t TEMPLATE_TransmitCplt(uint8_t *Buf, uint32_t *Len, uint8_t epnum)
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2019 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -43,10 +42,15 @@ extern "C" {
*/
/* Comment this define in order to disable the CDC ECM Notification pipe */
#ifndef CDC_ECM_IN_EP
#define CDC_ECM_IN_EP 0x81U /* EP1 for data IN */
#endif /* CDC_ECM_IN_EP */
#ifndef CDC_ECM_OUT_EP
#define CDC_ECM_OUT_EP 0x01U /* EP1 for data OUT */
#endif /* CDC_ECM_OUT_EP */
#ifndef CDC_ECM_CMD_EP
#define CDC_ECM_CMD_EP 0x82U /* EP2 for CDC ECM commands */
#endif /* CDC_ECM_CMD_EP */
#ifndef CDC_ECM_CMD_ITF_NBR
#define CDC_ECM_CMD_ITF_NBR 0x00U /* Command Interface Number 0 */
@@ -173,6 +177,26 @@ typedef struct
uint8_t data[8];
} USBD_CDC_ECM_NotifTypeDef;
/*
* ECM Class specification revision 1.2
* Table 3: Ethernet Networking Functional Descriptor
*/
typedef struct
{
uint8_t bFunctionLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubType;
uint8_t iMacAddress;
uint8_t bEthernetStatistics3;
uint8_t bEthernetStatistics2;
uint8_t bEthernetStatistics1;
uint8_t bEthernetStatistics0;
uint16_t wMaxSegmentSize;
uint16_t bNumberMCFiltes;
uint8_t bNumberPowerFiltes;
} __PACKED USBD_ECMFuncDescTypeDef;
typedef struct
{
uint32_t data[CDC_ECM_DATA_BUFFER_SIZE / 4U]; /* Force 32-bit alignment */
@@ -194,12 +218,6 @@ typedef struct
USBD_CDC_ECM_NotifTypeDef Req;
} USBD_CDC_ECM_HandleTypeDef;
typedef enum
{
NETWORK_CONNECTION = 0x00,
RESPONSE_AVAILABLE = 0x01,
CONNECTION_SPEED_CHANGE = 0x2A
} USBD_CDC_ECM_NotifCodeTypeDef;
/** @defgroup USBD_CORE_Exported_Macros
* @{
@@ -225,17 +243,21 @@ extern USBD_ClassTypeDef USBD_CDC_ECM;
uint8_t USBD_CDC_ECM_RegisterInterface(USBD_HandleTypeDef *pdev,
USBD_CDC_ECM_ItfTypeDef *fops);
uint8_t USBD_CDC_ECM_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff,
uint32_t length);
uint8_t USBD_CDC_ECM_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff);
uint8_t USBD_CDC_ECM_ReceivePacket(USBD_HandleTypeDef *pdev);
#ifdef USE_USBD_COMPOSITE
uint8_t USBD_CDC_ECM_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t ClassId);
uint8_t USBD_CDC_ECM_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff,
uint32_t length, uint8_t ClassId);
#else
uint8_t USBD_CDC_ECM_TransmitPacket(USBD_HandleTypeDef *pdev);
uint8_t USBD_CDC_ECM_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff,
uint32_t length);
#endif /* USE_USBD_COMPOSITE */
uint8_t USBD_CDC_ECM_SendNotification(USBD_HandleTypeDef *pdev,
USBD_CDC_ECM_NotifCodeTypeDef Notif,
USBD_CDC_NotifCodeTypeDef Notif,
uint16_t bVal, uint8_t *pData);
/**
* @}
@@ -254,4 +276,3 @@ uint8_t USBD_CDC_ECM_SendNotification(USBD_HandleTypeDef *pdev,
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2019 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -79,4 +78,3 @@ extern USBD_CDC_ECM_ItfTypeDef USBD_CDC_ECM_fops;
/* Exported functions ------------------------------------------------------- */
#endif /* __USBD_CDC_ECM_IF_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -13,13 +13,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2019 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -35,7 +34,7 @@ EndBSPDependencies */
#ifndef __USBD_CDC_ECM_IF_H
#include "usbd_cdc_ecm_if_template.h"
#endif
#endif /* __USBD_CDC_ECM_IF_H */
/** @addtogroup STM32_USB_DEVICE_LIBRARY
@@ -84,19 +83,20 @@ static uint8_t USBD_CDC_ECM_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
static uint8_t USBD_CDC_ECM_EP0_RxReady(USBD_HandleTypeDef *pdev);
static uint8_t USBD_CDC_ECM_Setup(USBD_HandleTypeDef *pdev,
USBD_SetupReqTypedef *req);
#ifndef USE_USBD_COMPOSITE
static uint8_t *USBD_CDC_ECM_GetFSCfgDesc(uint16_t *length);
static uint8_t *USBD_CDC_ECM_GetHSCfgDesc(uint16_t *length);
static uint8_t *USBD_CDC_ECM_GetOtherSpeedCfgDesc(uint16_t *length);
static uint8_t *USBD_CDC_ECM_GetOtherSpeedCfgDesc(uint16_t *length);
#endif /* USE_USBD_COMPOSITE */
#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
static uint8_t *USBD_CDC_ECM_USRStringDescriptor(USBD_HandleTypeDef *pdev,
uint8_t index, uint16_t *length);
#endif
#endif /* USBD_SUPPORT_USER_STRING_DESC */
#ifndef USE_USBD_COMPOSITE
uint8_t *USBD_CDC_ECM_GetDeviceQualifierDescriptor(uint16_t *length);
#endif /* USE_USBD_COMPOSITE */
#ifndef USE_USBD_COMPOSITE
/* USB Standard Device Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CDC_ECM_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
{
@@ -111,7 +111,7 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_ECM_DeviceQualifierDesc[USB_LEN_DEV_QUALIF
0x01,
0x00,
};
#endif /* USE_USBD_COMPOSITE */
static uint32_t ConnSpeedTab[2] = {CDC_ECM_CONNECT_SPEED_UPSTREAM,
CDC_ECM_CONNECT_SPEED_DOWNSTREAM
};
@@ -138,129 +138,25 @@ USBD_ClassTypeDef USBD_CDC_ECM =
NULL,
NULL,
NULL,
#ifdef USE_USBD_COMPOSITE
NULL,
NULL,
NULL,
NULL,
#else
USBD_CDC_ECM_GetHSCfgDesc,
USBD_CDC_ECM_GetFSCfgDesc,
USBD_CDC_ECM_GetOtherSpeedCfgDesc,
USBD_CDC_ECM_GetDeviceQualifierDescriptor,
#endif /* USE_USBD_COMPOSITE */
#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
USBD_CDC_ECM_USRStringDescriptor,
#endif
#endif /* USBD_SUPPORT_USER_STRING_DESC */
};
#ifndef USE_USBD_COMPOSITE
/* USB CDC_ECM device Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CDC_ECM_CfgHSDesc[] __ALIGN_END =
{
/* Configuration Descriptor */
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
LOBYTE(CDC_ECM_CONFIG_DESC_SIZ), /* wTotalLength:no of returned bytes */
HIBYTE(CDC_ECM_CONFIG_DESC_SIZ),
0x02, /* bNumInterfaces: 2 interfaces */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
#if (USBD_SELF_POWERED == 1U)
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
USBD_MAX_POWER, /* MaxPower (mA) */
/*---------------------------------------------------------------------------*/
/* IAD descriptor */
0x08, /* bLength */
0x0B, /* bDescriptorType */
0x00, /* bFirstInterface */
0x02, /* bInterfaceCount */
0x02, /* bFunctionClass (Wireless Controller) */
0x06, /* bFunctionSubClass */
0x00, /* bFunctionProtocol */
0x00, /* iFunction */
/* Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
CDC_ECM_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints: One endpoint used */
0x02, /* bInterfaceClass: Communication Interface Class */
0x06, /* bInterfaceSubClass: Ethernet Control Model */
0x00, /* bInterfaceProtocol: No specific protocol required */
0x00, /* iInterface */
/* Header Functional Descriptor */
0x05, /* bLength: Endpoint Descriptor size */
0x24, /* bDescriptorType: CS_INTERFACE */
0x00, /* bDescriptorSubtype: Header functional descriptor */
0x10, /* bcd CDC_ECM: spec release number: 1.10 */
0x01,
/* CDC_ECM Functional Descriptor */
0x0D, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x0F, /* Ethernet Networking functional descriptor subtype */
CDC_ECM_MAC_STRING_INDEX, /* Device's MAC string index */
CDC_ECM_ETH_STATS_BYTE3, /* Ethernet statistics byte 3 (bitmap) */
CDC_ECM_ETH_STATS_BYTE2, /* Ethernet statistics byte 2 (bitmap) */
CDC_ECM_ETH_STATS_BYTE1, /* Ethernet statistics byte 1 (bitmap) */
CDC_ECM_ETH_STATS_BYTE0, /* Ethernet statistics byte 0 (bitmap) */
LOBYTE(CDC_ECM_ETH_MAX_SEGSZE),
HIBYTE(CDC_ECM_ETH_MAX_SEGSZE), /* wMaxSegmentSize: Ethernet Maximum Segment size, typically 1514 bytes */
LOBYTE(CDC_ECM_ETH_NBR_MACFILTERS),
HIBYTE(CDC_ECM_ETH_NBR_MACFILTERS), /* wNumberMCFilters: the number of multicast filters */
CDC_ECM_ETH_NBR_PWRFILTERS, /* bNumberPowerFilters: the number of wakeup power filters */
/* Union Functional Descriptor */
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x06, /* bDescriptorSubtype: Union functional descriptor */
0x00, /* bMasterInterface: Communication class interface */
0x01, /* bSlaveInterface0: Data Class Interface */
/* Communication Endpoint Descriptor */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_ECM_CMD_EP, /* bEndpointAddress */
0x03, /* bmAttributes: Interrupt */
LOBYTE(CDC_ECM_CMD_PACKET_SIZE), /* wMaxPacketSize */
HIBYTE(CDC_ECM_CMD_PACKET_SIZE),
CDC_ECM_HS_BINTERVAL, /* bInterval */
/*----------------------*/
/* Data class interface descriptor */
0x09, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
CDC_ECM_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints: Two endpoints used */
0x0A, /* bInterfaceClass: CDC */
0x00, /* bInterfaceSubClass */
0x00, /* bInterfaceProtocol */
0x00, /* iInterface */
/* Endpoint OUT Descriptor */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_ECM_OUT_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
LOBYTE(CDC_ECM_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize */
HIBYTE(CDC_ECM_DATA_HS_MAX_PACKET_SIZE),
0x00, /* bInterval */
/* Endpoint IN Descriptor */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_ECM_IN_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
LOBYTE(CDC_ECM_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize */
HIBYTE(CDC_ECM_DATA_HS_MAX_PACKET_SIZE),
0x00 /* bInterval */
};
/* USB CDC_ECM device Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CDC_ECM_CfgFSDesc[] __ALIGN_END =
__ALIGN_BEGIN static uint8_t USBD_CDC_ECM_CfgDesc[] __ALIGN_END =
{
/* Configuration Descriptor */
0x09, /* bLength: Configuration Descriptor size */
@@ -269,12 +165,13 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_ECM_CfgFSDesc[] __ALIGN_END =
HIBYTE(CDC_ECM_CONFIG_DESC_SIZ),
0x02, /* bNumInterfaces: 2 interfaces */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
0x00, /* iConfiguration: Index of string descriptor
describing the configuration */
#if (USBD_SELF_POWERED == 1U)
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
#endif /* USBD_SELF_POWERED */
USBD_MAX_POWER, /* MaxPower (mA) */
/*---------------------------------------------------------------------------*/
@@ -369,115 +266,11 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_ECM_CfgFSDesc[] __ALIGN_END =
HIBYTE(CDC_ECM_DATA_FS_MAX_PACKET_SIZE),
0x00 /* bInterval */
} ;
#endif /* USE_USBD_COMPOSITE */
__ALIGN_BEGIN static uint8_t USBD_CDC_ECM_OtherSpeedCfgDesc[] __ALIGN_END =
{
/* Configuration Descriptor */
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
LOBYTE(CDC_ECM_CONFIG_DESC_SIZ), /* wTotalLength */
HIBYTE(CDC_ECM_CONFIG_DESC_SIZ),
0x02, /* bNumInterfaces: 2 interfaces */
0x01, /* bConfigurationValue: Configuration value */
0x04, /* iConfiguration: Index of string descriptor describing the configuration */
#if (USBD_SELF_POWERED == 1U)
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
USBD_MAX_POWER, /* MaxPower (mA) */
/*--------------------------------------- ------------------------------------*/
/* IAD descriptor */
0x08, /* bLength */
0x0B, /* bDescriptorType */
0x00, /* bFirstInterface */
0x02, /* bInterfaceCount */
0x02, /* bFunctionClass (Wireless Controller) */
0x06, /* bFunctionSubClass */
0x00, /* bFunctionProtocol */
0x00, /* iFunction */
/* Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints: One endpoint used */
0x02, /* bInterfaceClass: Communication Interface Class */
0x06, /* bInterfaceSubClass: Ethernet Control Model */
0x00, /* bInterfaceProtocol: No specific protocol required */
0x00, /* iInterface: */
/* Header Functional Descriptor */
0x05, /* bLength: Endpoint Descriptor size */
0x24, /* bDescriptorType: CS_INTERFACE */
0x00, /* bDescriptorSubtype: Header functional descriptor */
0x10, /* bcd CDC_ECM : spec release number: 1.20 */
0x01,
/* CDC_ECM Functional Descriptor */
0x0D, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x0F, /* Ethernet Networking functional descriptor subtype */
CDC_ECM_MAC_STRING_INDEX, /* Device's MAC string index */
CDC_ECM_ETH_STATS_BYTE3, /* Ethernet statistics byte 3 (bitmap) */
CDC_ECM_ETH_STATS_BYTE2, /* Ethernet statistics byte 2 (bitmap) */
CDC_ECM_ETH_STATS_BYTE1, /* Ethernet statistics byte 1 (bitmap) */
CDC_ECM_ETH_STATS_BYTE0, /* Ethernet statistics byte 0 (bitmap) */
LOBYTE(CDC_ECM_ETH_MAX_SEGSZE),
HIBYTE(CDC_ECM_ETH_MAX_SEGSZE), /* wMaxSegmentSize: Ethernet Maximum Segment size, typically 1514 bytes */
LOBYTE(CDC_ECM_ETH_NBR_MACFILTERS),
HIBYTE(CDC_ECM_ETH_NBR_MACFILTERS), /* wNumberMCFilters: the number of multicast filters */
CDC_ECM_ETH_NBR_PWRFILTERS, /* bNumberPowerFilters: the number of wakeup power filters */
/* Union Functional Descriptor */
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x06, /* bDescriptorSubtype: Union functional descriptor */
0x00, /* bMasterInterface: Communication class interface */
0x01, /* bSlaveInterface0: Data Class Interface */
/* Communication Endpoint Descriptor */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_ECM_CMD_EP, /* bEndpointAddress */
0x03, /* bmAttributes: Interrupt */
LOBYTE(CDC_ECM_CMD_PACKET_SIZE), /* wMaxPacketSize */
HIBYTE(CDC_ECM_CMD_PACKET_SIZE),
CDC_ECM_FS_BINTERVAL, /* bInterval */
/*----------------------*/
/* Data class interface descriptor */
0x09, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: interface */
0x01, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints: Two endpoints used */
0x0A, /* bInterfaceClass: CDC */
0x00, /* bInterfaceSubClass */
0x00, /* bInterfaceProtocol */
0x00, /* iInterface: */
/* Endpoint OUT Descriptor */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_ECM_OUT_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
0x40, /* wMaxPacketSize */
0x00,
0x00, /* bInterval */
/* Endpoint IN Descriptor */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_ECM_IN_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
0x40, /* wMaxPacketSize */
0x00,
0x00 /* bInterval */
};
static uint8_t ECMInEpAdd = CDC_ECM_IN_EP;
static uint8_t ECMOutEpAdd = CDC_ECM_OUT_EP;
static uint8_t ECMCmdEpAdd = CDC_ECM_CMD_EP;
/**
* @}
@@ -500,57 +293,69 @@ static uint8_t USBD_CDC_ECM_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
USBD_CDC_ECM_HandleTypeDef *hcdc;
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
ECMInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
ECMOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
ECMCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
hcdc = (USBD_CDC_ECM_HandleTypeDef *)USBD_malloc(sizeof(USBD_CDC_ECM_HandleTypeDef));
if (hcdc == NULL)
{
pdev->pClassData = NULL;
pdev->pClassDataCmsit[pdev->classId] = NULL;
return (uint8_t)USBD_EMEM;
}
pdev->pClassData = (void *)hcdc;
(void)USBD_memset(hcdc, 0, sizeof(USBD_CDC_ECM_HandleTypeDef));
pdev->pClassDataCmsit[pdev->classId] = (void *)hcdc;
pdev->pClassData = pdev->pClassDataCmsit[pdev->classId];
if (pdev->dev_speed == USBD_SPEED_HIGH)
{
/* Open EP IN */
(void)USBD_LL_OpenEP(pdev, CDC_ECM_IN_EP, USBD_EP_TYPE_BULK,
(void)USBD_LL_OpenEP(pdev, ECMInEpAdd, USBD_EP_TYPE_BULK,
CDC_ECM_DATA_HS_IN_PACKET_SIZE);
pdev->ep_in[CDC_ECM_IN_EP & 0xFU].is_used = 1U;
pdev->ep_in[ECMInEpAdd & 0xFU].is_used = 1U;
/* Open EP OUT */
(void)USBD_LL_OpenEP(pdev, CDC_ECM_OUT_EP, USBD_EP_TYPE_BULK,
(void)USBD_LL_OpenEP(pdev, ECMOutEpAdd, USBD_EP_TYPE_BULK,
CDC_ECM_DATA_HS_OUT_PACKET_SIZE);
pdev->ep_out[CDC_ECM_OUT_EP & 0xFU].is_used = 1U;
pdev->ep_out[ECMOutEpAdd & 0xFU].is_used = 1U;
/* Set bInterval for CDC ECM CMD Endpoint */
pdev->ep_in[CDC_ECM_CMD_EP & 0xFU].bInterval = CDC_ECM_HS_BINTERVAL;
pdev->ep_in[ECMCmdEpAdd & 0xFU].bInterval = CDC_ECM_HS_BINTERVAL;
}
else
{
/* Open EP IN */
(void)USBD_LL_OpenEP(pdev, CDC_ECM_IN_EP, USBD_EP_TYPE_BULK,
(void)USBD_LL_OpenEP(pdev, ECMInEpAdd, USBD_EP_TYPE_BULK,
CDC_ECM_DATA_FS_IN_PACKET_SIZE);
pdev->ep_in[CDC_ECM_IN_EP & 0xFU].is_used = 1U;
pdev->ep_in[ECMInEpAdd & 0xFU].is_used = 1U;
/* Open EP OUT */
(void)USBD_LL_OpenEP(pdev, CDC_ECM_OUT_EP, USBD_EP_TYPE_BULK,
(void)USBD_LL_OpenEP(pdev, ECMOutEpAdd, USBD_EP_TYPE_BULK,
CDC_ECM_DATA_FS_OUT_PACKET_SIZE);
pdev->ep_out[CDC_ECM_OUT_EP & 0xFU].is_used = 1U;
pdev->ep_out[ECMOutEpAdd & 0xFU].is_used = 1U;
/* Set bInterval for CDC ECM CMD Endpoint */
pdev->ep_in[CDC_ECM_CMD_EP & 0xFU].bInterval = CDC_ECM_FS_BINTERVAL;
pdev->ep_in[ECMCmdEpAdd & 0xFU].bInterval = CDC_ECM_FS_BINTERVAL;
}
/* Open Command IN EP */
(void)USBD_LL_OpenEP(pdev, CDC_ECM_CMD_EP, USBD_EP_TYPE_INTR, CDC_ECM_CMD_PACKET_SIZE);
pdev->ep_in[CDC_ECM_CMD_EP & 0xFU].is_used = 1U;
(void)USBD_LL_OpenEP(pdev, ECMCmdEpAdd, USBD_EP_TYPE_INTR, CDC_ECM_CMD_PACKET_SIZE);
pdev->ep_in[ECMCmdEpAdd & 0xFU].is_used = 1U;
hcdc->RxBuffer = NULL;
/* Init physical Interface components */
((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData)->Init();
((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init();
/* Init Xfer states */
hcdc->TxState = 0U;
@@ -559,10 +364,16 @@ static uint8_t USBD_CDC_ECM_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
hcdc->TxLength = 0U;
hcdc->LinkStatus = 0U;
hcdc->NotificationStatus = 0U;
hcdc->MaxPcktLen = (pdev->dev_speed == USBD_SPEED_HIGH) ? CDC_ECM_DATA_HS_MAX_PACKET_SIZE : CDC_ECM_DATA_FS_MAX_PACKET_SIZE;
hcdc->MaxPcktLen = (pdev->dev_speed == USBD_SPEED_HIGH) ? CDC_ECM_DATA_HS_MAX_PACKET_SIZE : \
CDC_ECM_DATA_FS_MAX_PACKET_SIZE;
if (hcdc->RxBuffer == NULL)
{
return (uint8_t)USBD_EMEM;
}
/* Prepare Out endpoint to receive next packet */
(void)USBD_LL_PrepareReceive(pdev, CDC_ECM_OUT_EP, hcdc->RxBuffer, hcdc->MaxPcktLen);
(void)USBD_LL_PrepareReceive(pdev, ECMOutEpAdd, hcdc->RxBuffer, hcdc->MaxPcktLen);
return (uint8_t)USBD_OK;
}
@@ -578,24 +389,32 @@ static uint8_t USBD_CDC_ECM_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
UNUSED(cfgidx);
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
ECMInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
ECMOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
ECMCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
/* Close EP IN */
(void)USBD_LL_CloseEP(pdev, CDC_ECM_IN_EP);
pdev->ep_in[CDC_ECM_IN_EP & 0xFU].is_used = 0U;
(void)USBD_LL_CloseEP(pdev, ECMInEpAdd);
pdev->ep_in[ECMInEpAdd & 0xFU].is_used = 0U;
/* Close EP OUT */
(void)USBD_LL_CloseEP(pdev, CDC_ECM_OUT_EP);
pdev->ep_out[CDC_ECM_OUT_EP & 0xFU].is_used = 0U;
(void)USBD_LL_CloseEP(pdev, ECMOutEpAdd);
pdev->ep_out[ECMOutEpAdd & 0xFU].is_used = 0U;
/* Close Command IN EP */
(void)USBD_LL_CloseEP(pdev, CDC_ECM_CMD_EP);
pdev->ep_in[CDC_ECM_CMD_EP & 0xFU].is_used = 0U;
pdev->ep_in[CDC_ECM_CMD_EP & 0xFU].bInterval = 0U;
(void)USBD_LL_CloseEP(pdev, ECMCmdEpAdd);
pdev->ep_in[ECMCmdEpAdd & 0xFU].is_used = 0U;
pdev->ep_in[ECMCmdEpAdd & 0xFU].bInterval = 0U;
/* DeInit physical Interface components */
if (pdev->pClassData != NULL)
if (pdev->pClassDataCmsit[pdev->classId] != NULL)
{
((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData)->DeInit();
USBD_free(pdev->pClassData);
((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit();
USBD_free(pdev->pClassDataCmsit[pdev->classId]);
pdev->pClassDataCmsit[pdev->classId] = NULL;
pdev->pClassData = NULL;
}
@@ -609,11 +428,10 @@ static uint8_t USBD_CDC_ECM_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
* @param req: usb requests
* @retval status
*/
static uint8_t USBD_CDC_ECM_Setup(USBD_HandleTypeDef *pdev,
USBD_SetupReqTypedef *req)
static uint8_t USBD_CDC_ECM_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *) pdev->pClassData;
USBD_CDC_ECM_ItfTypeDef *EcmInterface = (USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData;
USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *) pdev->pClassDataCmsit[pdev->classId];
USBD_CDC_ECM_ItfTypeDef *EcmInterface = (USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData[pdev->classId];
USBD_StatusTypeDef ret = USBD_OK;
uint16_t len;
uint16_t status_info = 0U;
@@ -631,8 +449,7 @@ static uint8_t USBD_CDC_ECM_Setup(USBD_HandleTypeDef *pdev,
{
if ((req->bmRequest & 0x80U) != 0U)
{
EcmInterface->Control(req->bRequest,
(uint8_t *)hcdc->data, req->wLength);
EcmInterface->Control(req->bRequest, (uint8_t *)hcdc->data, req->wLength);
len = MIN(CDC_ECM_DATA_BUFFER_SIZE, req->wLength);
(void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data, len);
@@ -714,21 +531,26 @@ static uint8_t USBD_CDC_ECM_Setup(USBD_HandleTypeDef *pdev,
*/
static uint8_t USBD_CDC_ECM_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData;
PCD_HandleTypeDef *hpcd = pdev->pData;
USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef *)pdev->pData;
if (pdev->pClassData == NULL)
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
ECMInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (pdev->pClassDataCmsit[pdev->classId] == NULL)
{
return (uint8_t)USBD_FAIL;
}
if (epnum == (CDC_ECM_IN_EP & 0x7FU))
if (epnum == (ECMInEpAdd & 0x7FU))
{
if ((pdev->ep_in[epnum].total_length > 0U) &&
((pdev->ep_in[epnum].total_length % hpcd->IN_ep[epnum].maxpacket) == 0U))
if ((pdev->ep_in[epnum & 0xFU].total_length > 0U) &&
((pdev->ep_in[epnum & 0xFU].total_length % hpcd->IN_ep[epnum & 0xFU].maxpacket) == 0U))
{
/* Update the packet total length */
pdev->ep_in[epnum].total_length = 0U;
pdev->ep_in[epnum & 0xFU].total_length = 0U;
/* Send ZLP */
(void)USBD_LL_Transmit(pdev, epnum, NULL, 0U);
@@ -736,18 +558,18 @@ static uint8_t USBD_CDC_ECM_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
else
{
hcdc->TxState = 0U;
if (((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData)->TransmitCplt != NULL)
if (((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData[pdev->classId])->TransmitCplt != NULL)
{
((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData)->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum);
((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData[pdev->classId])->TransmitCplt(hcdc->TxBuffer,
&hcdc->TxLength, epnum);
}
}
}
else if (epnum == (CDC_ECM_CMD_EP & 0x7FU))
else if (epnum == (ECMCmdEpAdd & 0x7FU))
{
if (hcdc->NotificationStatus != 0U)
{
(void)USBD_CDC_ECM_SendNotification(pdev, CONNECTION_SPEED_CHANGE,
0U, (uint8_t *)ConnSpeedTab);
(void)USBD_CDC_ECM_SendNotification(pdev, CONNECTION_SPEED_CHANGE, 0U, (uint8_t *)ConnSpeedTab);
hcdc->NotificationStatus = 0U;
}
@@ -769,15 +591,20 @@ static uint8_t USBD_CDC_ECM_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
*/
static uint8_t USBD_CDC_ECM_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData;
USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint32_t CurrPcktLen;
if (pdev->pClassData == NULL)
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
ECMOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (pdev->pClassDataCmsit[pdev->classId] == NULL)
{
return (uint8_t)USBD_FAIL;
}
if (epnum == CDC_ECM_OUT_EP)
if (epnum == ECMOutEpAdd)
{
/* Get the received data length */
CurrPcktLen = USBD_LL_GetRxDataSize(pdev, epnum);
@@ -793,12 +620,12 @@ static uint8_t USBD_CDC_ECM_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
/* Process data by application (ie. copy to app buffer or notify user)
hcdc->RxLength must be reset to zero at the end of the call of this function */
((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength);
((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData[pdev->classId])->Receive(hcdc->RxBuffer, &hcdc->RxLength);
}
else
{
/* Prepare Out endpoint to receive next packet in current/new frame */
(void)USBD_LL_PrepareReceive(pdev, CDC_ECM_OUT_EP,
(void)USBD_LL_PrepareReceive(pdev, ECMOutEpAdd,
(uint8_t *)(hcdc->RxBuffer + hcdc->RxLength),
hcdc->MaxPcktLen);
}
@@ -819,16 +646,16 @@ static uint8_t USBD_CDC_ECM_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
*/
static uint8_t USBD_CDC_ECM_EP0_RxReady(USBD_HandleTypeDef *pdev)
{
USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData;
USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hcdc == NULL)
{
return (uint8_t)USBD_FAIL;
}
if ((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFFU))
if ((pdev->pUserData[pdev->classId] != NULL) && (hcdc->CmdOpCode != 0xFFU))
{
((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode,
((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData[pdev->classId])->Control(hcdc->CmdOpCode,
(uint8_t *)hcdc->data,
(uint16_t)hcdc->CmdLength);
hcdc->CmdOpCode = 0xFFU;
@@ -836,47 +663,98 @@ static uint8_t USBD_CDC_ECM_EP0_RxReady(USBD_HandleTypeDef *pdev)
}
return (uint8_t)USBD_OK;
}
#ifndef USE_USBD_COMPOSITE
/**
* @brief USBD_CDC_ECM_GetFSCfgDesc
* Return configuration descriptor
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_CDC_ECM_GetFSCfgDesc(uint16_t *length)
{
*length = (uint16_t)sizeof(USBD_CDC_ECM_CfgFSDesc);
USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_ECM_CfgDesc, CDC_ECM_CMD_EP);
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_ECM_CfgDesc, CDC_ECM_OUT_EP);
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_ECM_CfgDesc, CDC_ECM_IN_EP);
return USBD_CDC_ECM_CfgFSDesc;
if (pEpCmdDesc != NULL)
{
pEpCmdDesc->bInterval = CDC_ECM_FS_BINTERVAL;
}
if (pEpOutDesc != NULL)
{
pEpOutDesc->wMaxPacketSize = CDC_ECM_DATA_FS_MAX_PACKET_SIZE;
}
if (pEpInDesc != NULL)
{
pEpInDesc->wMaxPacketSize = CDC_ECM_DATA_FS_MAX_PACKET_SIZE;
}
*length = (uint16_t) sizeof(USBD_CDC_ECM_CfgDesc);
return USBD_CDC_ECM_CfgDesc;
}
/**
* @brief USBD_CDC_ECM_GetHSCfgDesc
* Return configuration descriptor
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_CDC_ECM_GetHSCfgDesc(uint16_t *length)
{
*length = (uint16_t) sizeof(USBD_CDC_ECM_CfgHSDesc);
USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_ECM_CfgDesc, CDC_ECM_CMD_EP);
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_ECM_CfgDesc, CDC_ECM_OUT_EP);
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_ECM_CfgDesc, CDC_ECM_IN_EP);
return USBD_CDC_ECM_CfgHSDesc;
if (pEpCmdDesc != NULL)
{
pEpCmdDesc->bInterval = CDC_ECM_HS_BINTERVAL;
}
if (pEpOutDesc != NULL)
{
pEpOutDesc->wMaxPacketSize = CDC_ECM_DATA_HS_MAX_PACKET_SIZE;
}
if (pEpInDesc != NULL)
{
pEpInDesc->wMaxPacketSize = CDC_ECM_DATA_HS_MAX_PACKET_SIZE;
}
*length = (uint16_t) sizeof(USBD_CDC_ECM_CfgDesc);
return USBD_CDC_ECM_CfgDesc;
}
/**
* @brief USBD_CDC_ECM_GetCfgDesc
* Return configuration descriptor
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_CDC_ECM_GetOtherSpeedCfgDesc(uint16_t *length)
{
*length = (uint16_t)sizeof(USBD_CDC_ECM_OtherSpeedCfgDesc);
USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_ECM_CfgDesc, CDC_ECM_CMD_EP);
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_ECM_CfgDesc, CDC_ECM_OUT_EP);
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_ECM_CfgDesc, CDC_ECM_IN_EP);
return USBD_CDC_ECM_OtherSpeedCfgDesc;
if (pEpCmdDesc != NULL)
{
pEpCmdDesc->bInterval = CDC_ECM_FS_BINTERVAL;
}
if (pEpOutDesc != NULL)
{
pEpOutDesc->wMaxPacketSize = CDC_ECM_DATA_FS_MAX_PACKET_SIZE;
}
if (pEpInDesc != NULL)
{
pEpInDesc->wMaxPacketSize = CDC_ECM_DATA_FS_MAX_PACKET_SIZE;
}
*length = (uint16_t) sizeof(USBD_CDC_ECM_CfgDesc);
return USBD_CDC_ECM_CfgDesc;
}
/**
@@ -891,7 +769,7 @@ uint8_t *USBD_CDC_ECM_GetDeviceQualifierDescriptor(uint16_t *length)
return USBD_CDC_ECM_DeviceQualifierDesc;
}
#endif /* USE_USBD_COMPOSITE */
/**
* @brief USBD_CDC_ECM_RegisterInterface
* @param pdev: device instance
@@ -906,7 +784,7 @@ uint8_t USBD_CDC_ECM_RegisterInterface(USBD_HandleTypeDef *pdev,
return (uint8_t)USBD_FAIL;
}
pdev->pUserData = fops;
pdev->pUserData[pdev->classId] = fops;
return (uint8_t)USBD_OK;
}
@@ -915,7 +793,7 @@ uint8_t USBD_CDC_ECM_RegisterInterface(USBD_HandleTypeDef *pdev,
/**
* @brief USBD_CDC_ECM_USRStringDescriptor
* Manages the transfer of user string descriptors.
* @param speed : current device speed
* @param pdev: device instance
* @param index: descriptor index
* @param length : pointer data length
* @retval pointer to the descriptor table or NULL if the descriptor is not supported.
@@ -928,7 +806,10 @@ static uint8_t *USBD_CDC_ECM_USRStringDescriptor(USBD_HandleTypeDef *pdev, uint8
/* Check if the requested string interface is supported */
if (index == CDC_ECM_MAC_STRING_INDEX)
{
USBD_GetString((uint8_t *)((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData)->pStrDesc, USBD_StrDesc, length);
USBD_GetString((uint8_t *)((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData[pdev->classId])->pStrDesc,
USBD_StrDesc,
length);
return USBD_StrDesc;
}
/* Not supported Interface Descriptor index */
@@ -937,17 +818,25 @@ static uint8_t *USBD_CDC_ECM_USRStringDescriptor(USBD_HandleTypeDef *pdev, uint8
return NULL;
}
}
#endif
#endif /* USBD_SUPPORT_USER_STRING_DESC */
/**
* @brief USBD_CDC_ECM_SetTxBuffer
* @param pdev: device instance
* @param pbuff: Tx Buffer
* @param length: Tx Buffer length
* @param ClassId: The Class ID
* @retval status
*/
#ifdef USE_USBD_COMPOSITE
uint8_t USBD_CDC_ECM_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uint32_t length, uint8_t ClassId)
{
USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassDataCmsit[ClassId];
#else
uint8_t USBD_CDC_ECM_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uint32_t length)
{
USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData;
USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
#endif /* USE_USBD_COMPOSITE */
if (hcdc == NULL)
{
@@ -969,7 +858,7 @@ uint8_t USBD_CDC_ECM_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uint3
*/
uint8_t USBD_CDC_ECM_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff)
{
USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData;
USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hcdc == NULL)
{
@@ -981,18 +870,32 @@ uint8_t USBD_CDC_ECM_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff)
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_CDC_ECM_TransmitPacket
* Transmit packet on IN endpoint
* @param pdev: device instance
* @param ClassId: The Class ID
* @retval status
*/
#ifdef USE_USBD_COMPOSITE
uint8_t USBD_CDC_ECM_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t ClassId)
{
USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassDataCmsit[ClassId];
#else
uint8_t USBD_CDC_ECM_TransmitPacket(USBD_HandleTypeDef *pdev)
{
USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData;
USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
#endif /* USE_USBD_COMPOSITE */
USBD_StatusTypeDef ret = USBD_BUSY;
if (pdev->pClassData == NULL)
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
ECMInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, ClassId);
#endif /* USE_USBD_COMPOSITE */
if (hcdc == NULL)
{
return (uint8_t)USBD_FAIL;
}
@@ -1003,10 +906,10 @@ uint8_t USBD_CDC_ECM_TransmitPacket(USBD_HandleTypeDef *pdev)
hcdc->TxState = 1U;
/* Update the packet total length */
pdev->ep_in[CDC_ECM_IN_EP & 0xFU].total_length = hcdc->TxLength;
pdev->ep_in[ECMInEpAdd & 0xFU].total_length = hcdc->TxLength;
/* Transmit next packet */
(void)USBD_LL_Transmit(pdev, CDC_ECM_IN_EP, hcdc->TxBuffer, hcdc->TxLength);
(void)USBD_LL_Transmit(pdev, ECMInEpAdd, hcdc->TxBuffer, hcdc->TxLength);
ret = USBD_OK;
}
@@ -1023,15 +926,20 @@ uint8_t USBD_CDC_ECM_TransmitPacket(USBD_HandleTypeDef *pdev)
*/
uint8_t USBD_CDC_ECM_ReceivePacket(USBD_HandleTypeDef *pdev)
{
USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData;
USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (pdev->pClassData == NULL)
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
ECMOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (pdev->pClassDataCmsit[pdev->classId] == NULL)
{
return (uint8_t)USBD_FAIL;
}
/* Prepare Out endpoint to receive next packet */
(void)USBD_LL_PrepareReceive(pdev, CDC_ECM_OUT_EP, hcdc->RxBuffer, hcdc->MaxPcktLen);
(void)USBD_LL_PrepareReceive(pdev, ECMOutEpAdd, hcdc->RxBuffer, hcdc->MaxPcktLen);
return (uint8_t)USBD_OK;
}
@@ -1046,12 +954,12 @@ uint8_t USBD_CDC_ECM_ReceivePacket(USBD_HandleTypeDef *pdev)
* @retval status
*/
uint8_t USBD_CDC_ECM_SendNotification(USBD_HandleTypeDef *pdev,
USBD_CDC_ECM_NotifCodeTypeDef Notif,
USBD_CDC_NotifCodeTypeDef Notif,
uint16_t bVal, uint8_t *pData)
{
uint32_t Idx;
uint32_t ReqSize = 0U;
USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData;
USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
USBD_StatusTypeDef ret = USBD_OK;
if (hcdc == NULL)
@@ -1059,6 +967,11 @@ uint8_t USBD_CDC_ECM_SendNotification(USBD_HandleTypeDef *pdev,
return (uint8_t)USBD_FAIL;
}
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
ECMCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
/* Initialize the request fields */
(hcdc->Req).bmRequest = CDC_ECM_BMREQUEST_TYPE_ECM;
(hcdc->Req).bRequest = (uint8_t)Notif;
@@ -1112,7 +1025,7 @@ uint8_t USBD_CDC_ECM_SendNotification(USBD_HandleTypeDef *pdev,
/* Transmit notification packet */
if (ReqSize != 0U)
{
(void)USBD_LL_Transmit(pdev, CDC_ECM_CMD_EP, (uint8_t *) &(hcdc->Req), ReqSize);
(void)USBD_LL_Transmit(pdev, ECMCmdEpAdd, (uint8_t *)&hcdc->Req, ReqSize);
}
return (uint8_t)ret;
@@ -1131,4 +1044,3 @@ uint8_t USBD_CDC_ECM_SendNotification(USBD_HandleTypeDef *pdev,
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,20 +6,19 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2019 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usbd_cdc_ecm_if_template.h"
/*
Include here LwIP files if used
@@ -30,16 +29,17 @@
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Received Data over USB are stored in this buffer */
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
__ALIGN_BEGIN static uint8_t UserRxBuffer[CDC_ECM_ETH_MAX_SEGSZE + 100]__ALIGN_END; /* Received Data over USB are stored in this buffer */
#endif /* ( __ICCARM__ ) */
__ALIGN_BEGIN static uint8_t UserRxBuffer[CDC_ECM_ETH_MAX_SEGSZE + 100]__ALIGN_END;
/* Transmitted Data over CDC_ECM (CDC_ECM interface) are stored in this buffer */
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
__ALIGN_BEGIN static uint8_t UserTxBuffer[CDC_ECM_ETH_MAX_SEGSZE + 100]__ALIGN_END; /* Received Data over CDC_ECM (CDC_ECM interface) are stored in this buffer */
#endif /* ( __ICCARM__ ) */
__ALIGN_BEGIN static uint8_t UserTxBuffer[CDC_ECM_ETH_MAX_SEGSZE + 100]__ALIGN_END;
static uint8_t CDC_ECMInitialized = 0U;
@@ -85,7 +85,11 @@ static int8_t CDC_ECM_Itf_Init(void)
}
/* Set Application Buffers */
#ifdef USE_USBD_COMPOSITE
(void)USBD_CDC_ECM_SetTxBuffer(&USBD_Device, UserTxBuffer, 0U, 0U);
#else
(void)USBD_CDC_ECM_SetTxBuffer(&USBD_Device, UserTxBuffer, 0U);
#endif /* USE_USBD_COMPOSITE */
(void)USBD_CDC_ECM_SetRxBuffer(&USBD_Device, UserRxBuffer);
return (0);
@@ -99,7 +103,12 @@ static int8_t CDC_ECM_Itf_Init(void)
*/
static int8_t CDC_ECM_Itf_DeInit(void)
{
#ifdef USE_USBD_COMPOSITE
USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *) \
(USBD_Device.pClassDataCmsit[USBD_Device.classId]);
#else
USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *)(USBD_Device.pClassData);
#endif /* USE_USBD_COMPOSITE */
/* Notify application layer that link is down */
hcdc_cdc_ecm->LinkStatus = 0U;
@@ -117,7 +126,12 @@ static int8_t CDC_ECM_Itf_DeInit(void)
*/
static int8_t CDC_ECM_Itf_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length)
{
#ifdef USE_USBD_COMPOSITE
USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *) \
(USBD_Device.pClassDataCmsit[USBD_Device.classId]);
#else
USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *)(USBD_Device.pClassData);
#endif /* USE_USBD_COMPOSITE */
switch (cmd)
{
@@ -188,7 +202,12 @@ static int8_t CDC_ECM_Itf_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length)
static int8_t CDC_ECM_Itf_Receive(uint8_t *Buf, uint32_t *Len)
{
/* Get the CDC_ECM handler pointer */
#ifdef USE_USBD_COMPOSITE
USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *) \
(USBD_Device.pClassDataCmsit[USBD_Device.classId]);
#else
USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *)(USBD_Device.pClassData);
#endif /* USE_USBD_COMPOSITE */
/* Call Eth buffer processing */
hcdc_cdc_ecm->RxState = 1U;
@@ -230,9 +249,18 @@ static int8_t CDC_ECM_Itf_TransmitCplt(uint8_t *Buf, uint32_t *Len, uint8_t epnu
static int8_t CDC_ECM_Itf_Process(USBD_HandleTypeDef *pdev)
{
/* Get the CDC_ECM handler pointer */
#ifdef USE_USBD_COMPOSITE
USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *)(pdev->pClassDataCmsit[pdev->classId]);
#else
USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *)(pdev->pClassData);
#endif /* USE_USBD_COMPOSITE */
if ((hcdc_cdc_ecm != NULL) && (hcdc_cdc_ecm->LinkStatus != 0U))
if (hcdc_cdc_ecm == NULL)
{
return (-1);
}
if (hcdc_cdc_ecm->LinkStatus != 0U)
{
/*
Read a received packet from the Ethernet buffers and send it
@@ -244,4 +272,3 @@ static int8_t CDC_ECM_Itf_Process(USBD_HandleTypeDef *pdev)
return (0);
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2019 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -41,10 +40,15 @@ extern "C" {
/** @defgroup usbd_cdc_rndis_Exported_Defines
* @{
*/
#ifndef CDC_RNDIS_IN_EP
#define CDC_RNDIS_IN_EP 0x81U /* EP1 for data IN */
#endif /* CDC_RNDIS_IN_EP */
#ifndef CDC_RNDIS_OUT_EP
#define CDC_RNDIS_OUT_EP 0x01U /* EP1 for data OUT */
#endif /* CDC_RNDIS_OUT_EP */
#ifndef CDC_RNDIS_CMD_EP
#define CDC_RNDIS_CMD_EP 0x82U /* EP2 for CDC_RNDIS commands */
#endif /* CDC_RNDIS_CMD_EP */
#ifndef CDC_RNDIS_CMD_ITF_NBR
#define CDC_RNDIS_CMD_ITF_NBR 0x00U /* Command Interface Number 0 */
@@ -265,15 +269,6 @@ typedef struct
__IO uint32_t PacketFilter;
} USBD_CDC_RNDIS_HandleTypeDef;
typedef enum
{
NETWORK_CONNECTION = 0x00,
RESPONSE_AVAILABLE = 0x01,
CONNECTION_SPEED_CHANGE = 0x2A
} USBD_CDC_RNDIS_NotifCodeTypeDef;
/* Messages Sent by the Host ---------------------*/
/* Type define for a CDC_RNDIS Initialize command message */
@@ -498,16 +493,20 @@ extern USBD_ClassTypeDef USBD_CDC_RNDIS;
*/
uint8_t USBD_CDC_RNDIS_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff);
uint8_t USBD_CDC_RNDIS_ReceivePacket(USBD_HandleTypeDef *pdev);
uint8_t USBD_CDC_RNDIS_TransmitPacket(USBD_HandleTypeDef *pdev);
uint8_t USBD_CDC_RNDIS_RegisterInterface(USBD_HandleTypeDef *pdev,
USBD_CDC_RNDIS_ItfTypeDef *fops);
#ifdef USE_USBD_COMPOSITE
uint8_t USBD_CDC_RNDIS_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t ClassId);
uint8_t USBD_CDC_RNDIS_SetTxBuffer(USBD_HandleTypeDef *pdev,
uint8_t *pbuff, uint32_t length, uint8_t ClassId);
#else
uint8_t USBD_CDC_RNDIS_TransmitPacket(USBD_HandleTypeDef *pdev);
uint8_t USBD_CDC_RNDIS_SetTxBuffer(USBD_HandleTypeDef *pdev,
uint8_t *pbuff, uint32_t length);
#endif /* USE_USBD_COMPOSITE */
uint8_t USBD_CDC_RNDIS_SendNotification(USBD_HandleTypeDef *pdev,
USBD_CDC_RNDIS_NotifCodeTypeDef Notif,
USBD_CDC_NotifCodeTypeDef Notif,
uint16_t bVal, uint8_t *pData);
/**
* @}
@@ -526,4 +525,3 @@ uint8_t USBD_CDC_RNDIS_SendNotification(USBD_HandleTypeDef *pdev,
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2019 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -57,4 +56,3 @@ extern USBD_CDC_RNDIS_ItfTypeDef USBD_CDC_RNDIS_fops;
#endif /* __USBD_CDC_RNDIS_IF_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -10,6 +10,17 @@
* - Command IN transfer (class requests management)
* - Error management
*
******************************************************************************
* @attention
*
* Copyright (c) 2019 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
* @verbatim
*
* ===================================================================
@@ -37,17 +48,6 @@
* @endverbatim
*
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
@@ -56,7 +56,7 @@
#ifndef __USBD_CDC_RNDIS_IF_H
#include "usbd_cdc_rndis_if_template.h"
#endif
#endif /* __USBD_CDC_RNDIS_IF_H */
/** @addtogroup STM32_USB_DEVICE_LIBRARY
* @{
*/
@@ -105,17 +105,18 @@ static uint8_t USBD_CDC_RNDIS_Setup(USBD_HandleTypeDef *pdev,
static uint8_t USBD_CDC_RNDIS_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
static uint8_t USBD_CDC_RNDIS_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
static uint8_t USBD_CDC_RNDIS_EP0_RxReady(USBD_HandleTypeDef *pdev);
#ifndef USE_USBD_COMPOSITE
static uint8_t *USBD_CDC_RNDIS_GetFSCfgDesc(uint16_t *length);
static uint8_t *USBD_CDC_RNDIS_GetHSCfgDesc(uint16_t *length);
static uint8_t *USBD_CDC_RNDIS_GetOtherSpeedCfgDesc(uint16_t *length);
static uint8_t *USBD_CDC_RNDIS_GetOtherSpeedCfgDesc(uint16_t *length);
#endif /* USE_USBD_COMPOSITE */
#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
static uint8_t *USBD_CDC_RNDIS_USRStringDescriptor(USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length);
#endif
#endif /* USBD_SUPPORT_USER_STRING_DESC */
#ifndef USE_USBD_COMPOSITE
uint8_t *USBD_CDC_RNDIS_GetDeviceQualifierDescriptor(uint16_t *length);
#endif /* USE_USBD_COMPOSITE */
/* CDC_RNDIS Internal messages parsing and construction functions */
static uint8_t USBD_CDC_RNDIS_MsgParsing(USBD_HandleTypeDef *pdev, uint8_t *RxBuff);
@@ -129,6 +130,7 @@ static uint8_t USBD_CDC_RNDIS_ProcessPacketMsg(USBD_HandleTypeDef *pdev, USBD_CD
static uint8_t USBD_CDC_RNDIS_ProcessUnsupportedMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_CtrlMsgTypeDef *Msg);
/* USB Standard Device Descriptor */
#ifndef USE_USBD_COMPOSITE
__ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
{
USB_LEN_DEV_QUALIFIER_DESC,
@@ -142,7 +144,7 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_DeviceQualifierDesc[USB_LEN_DEV_QUAL
0x01,
0x00,
};
#endif /* USE_USBD_COMPOSITE */
static uint8_t MAC_StrDesc[6] = {CDC_RNDIS_MAC_ADDR0, CDC_RNDIS_MAC_ADDR1, CDC_RNDIS_MAC_ADDR2,
CDC_RNDIS_MAC_ADDR3, CDC_RNDIS_MAC_ADDR4, CDC_RNDIS_MAC_ADDR5
};
@@ -175,126 +177,25 @@ USBD_ClassTypeDef USBD_CDC_RNDIS =
NULL,
NULL,
NULL,
#ifdef USE_USBD_COMPOSITE
NULL,
NULL,
NULL,
NULL,
#else
USBD_CDC_RNDIS_GetHSCfgDesc,
USBD_CDC_RNDIS_GetFSCfgDesc,
USBD_CDC_RNDIS_GetOtherSpeedCfgDesc,
USBD_CDC_RNDIS_GetDeviceQualifierDescriptor,
#endif /* USE_USBD_COMPOSITE */
#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
USBD_CDC_RNDIS_USRStringDescriptor,
#endif
#endif /* USBD_SUPPORT_USER_STRING_DESC */
};
/* USB CDC_RNDIS device Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_CfgHSDesc[] __ALIGN_END =
{
/* Configuration Descriptor */
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
LOBYTE(CDC_RNDIS_CONFIG_DESC_SIZ), /* wTotalLength: Total size of the Config descriptor */
HIBYTE(CDC_RNDIS_CONFIG_DESC_SIZ),
0x02, /* bNumInterfaces: 2 interfaces */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
#if (USBD_SELF_POWERED == 1U)
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
USBD_MAX_POWER, /* MaxPower (mA) */
/*---------------------------------------------------------------------------*/
/* IAD descriptor */
0x08, /* bLength */
0x0B, /* bDescriptorType */
0x00, /* bFirstInterface */
0x02, /* bInterfaceCount */
0xE0, /* bFunctionClass (Wireless Controller) */
0x01, /* bFunctionSubClass */
0x03, /* bFunctionProtocol */
0x00, /* iFunction */
/*---------------------------------------------------------------------------*/
/* Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
CDC_RNDIS_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints: One endpoint used */
0x02, /* bInterfaceClass: Communication Interface Class */
0x02, /* bInterfaceSubClass:Abstract Control Model */
0xFF, /* bInterfaceProtocol: Common AT commands */
0x00, /* iInterface */
/* Header Functional Descriptor */
0x05, /* bLength: Endpoint Descriptor size */
0x24, /* bDescriptorType: CS_INTERFACE */
0x00, /* bDescriptorSubtype: Header functional descriptor */
0x10, /* bcdCDC: spec release number: 1.20 */
0x01,
/* Call Management Functional Descriptor */
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x01, /* bDescriptorSubtype: Call Management Func Desc */
0x00, /* bmCapabilities: D0+D1 */
CDC_RNDIS_COM_ITF_NBR, /* bDataInterface: 1 */
/* ACM Functional Descriptor */
0x04, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
0x00, /* bmCapabilities */
/* Union Functional Descriptor */
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x06, /* bDescriptorSubtype: Union functional descriptor */
CDC_RNDIS_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */
CDC_RNDIS_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */
/* Notification Endpoint Descriptor */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_RNDIS_CMD_EP, /* bEndpointAddress */
0x03, /* bmAttributes: Interrupt */
LOBYTE(CDC_RNDIS_CMD_PACKET_SIZE), /* wMaxPacketSize */
HIBYTE(CDC_RNDIS_CMD_PACKET_SIZE),
CDC_RNDIS_HS_BINTERVAL, /* bInterval */
/*---------------------------------------------------------------------------*/
/* Data class interface descriptor */
0x09, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
CDC_RNDIS_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints: Two endpoints used */
0x0A, /* bInterfaceClass: CDC */
0x00, /* bInterfaceSubClass */
0x00, /* bInterfaceProtocol */
0x00, /* iInterface */
/* Endpoint OUT Descriptor */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_RNDIS_OUT_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
LOBYTE(CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize */
HIBYTE(CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE),
0x00, /* bInterval */
/* Endpoint IN Descriptor */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_RNDIS_IN_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
LOBYTE(CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
HIBYTE(CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE),
0x00 /* bInterval */
};
#ifndef USE_USBD_COMPOSITE
/* USB CDC device Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_CfgFSDesc[] __ALIGN_END =
__ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_CfgDesc[] __ALIGN_END =
{
/* Configuration Descriptor */
0x09, /* bLength: Configuration Descriptor size */
@@ -303,12 +204,13 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_CfgFSDesc[] __ALIGN_END =
HIBYTE(CDC_RNDIS_CONFIG_DESC_SIZ),
0x02, /* bNumInterfaces: 2 interfaces */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
0x00, /* iConfiguration: Index of string descriptor
describing the configuration */
#if (USBD_SELF_POWERED == 1U)
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
#endif /* USBD_SELF_POWERED */
USBD_MAX_POWER, /* MaxPower (mA) */
/*---------------------------------------------------------------------------*/
@@ -400,114 +302,11 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_CfgFSDesc[] __ALIGN_END =
HIBYTE(CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE),
0x00 /* bInterval */
} ;
#endif /* USE_USBD_COMPOSITE */
__ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_OtherSpeedCfgDesc[] __ALIGN_END =
{
/* Configuration Descriptor */
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
LOBYTE(CDC_RNDIS_CONFIG_DESC_SIZ), /* wTotalLength:no of returned bytes */
HIBYTE(CDC_RNDIS_CONFIG_DESC_SIZ),
0x02, /* bNumInterfaces: 2 interfaces */
0x01, /* bConfigurationValue: Configuration value */
0x04, /* iConfiguration: Index of string descriptor describing the configuration */
#if (USBD_SELF_POWERED == 1U)
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
USBD_MAX_POWER, /* MaxPower (mA) */
/*---------------------------------------------------------------------------*/
/* IAD descriptor */
0x08, /* bLength */
0x0B, /* bDescriptorType */
0x00, /* bFirstInterface */
0x02, /* bInterfaceCount */
0xE0, /* bFunctionClass (Wireless Controller) */
0x01, /* bFunctionSubClass */
0x03, /* bFunctionProtocol */
0x00, /* iFunction */
/*---------------------------------------------------------------------------*/
/* Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
CDC_RNDIS_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints: One endpoint used */
0x02, /* bInterfaceClass: Communication Interface Class */
0x02, /* bInterfaceSubClass:Abstract Control Model */
0xFF, /* bInterfaceProtocol: Common AT commands */
0x00, /* iInterface */
/* Header Functional Descriptor */
0x05, /* bLength: Endpoint Descriptor size */
0x24, /* bDescriptorType: CS_INTERFACE */
0x00, /* bDescriptorSubtype: Header functional descriptor */
0x10, /* bcdCDC: spec release number: 1.20 */
0x01,
/* Call Management Functional Descriptor */
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x01, /* bDescriptorSubtype: Call Management Func Desc */
0x00, /* bmCapabilities: D0+D1 */
CDC_RNDIS_COM_ITF_NBR, /* bDataInterface: 1 */
/* ACM Functional Descriptor */
0x04, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
0x00, /* bmCapabilities */
/* Union Functional Descriptor */
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x06, /* bDescriptorSubtype: Union functional descriptor */
CDC_RNDIS_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */
CDC_RNDIS_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */
/* Communication Endpoint Descriptor */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_RNDIS_CMD_EP, /* bEndpointAddress */
0x03, /* bmAttributes: Interrupt */
LOBYTE(CDC_RNDIS_CMD_PACKET_SIZE), /* wMaxPacketSize */
HIBYTE(CDC_RNDIS_CMD_PACKET_SIZE),
CDC_RNDIS_FS_BINTERVAL, /* bInterval */
/*---------------------------------------------------------------------------*/
/* Data class interface descriptor */
0x09, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
CDC_RNDIS_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints: Two endpoints used */
0x0A, /* bInterfaceClass: CDC */
0x00, /* bInterfaceSubClass */
0x00, /* bInterfaceProtocol */
0x00, /* iInterface */
/* Endpoint OUT Descriptor */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_RNDIS_OUT_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
0x40, /* wMaxPacketSize */
0x00,
0x00, /* bInterval */
/* Endpoint IN Descriptor */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_RNDIS_IN_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
0x40, /* wMaxPacketSize */
0x00,
0x00 /* bInterval */
};
static uint8_t RNDISInEpAdd = CDC_RNDIS_IN_EP;
static uint8_t RNDISOutEpAdd = CDC_RNDIS_OUT_EP;
static uint8_t RNDISCmdEpAdd = CDC_RNDIS_CMD_EP;
static const uint32_t CDC_RNDIS_SupportedOIDs[] =
{
@@ -556,55 +355,67 @@ static uint8_t USBD_CDC_RNDIS_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)USBD_malloc(sizeof(USBD_CDC_RNDIS_HandleTypeDef));
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
RNDISInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
RNDISOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
RNDISCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (hcdc == NULL)
{
pdev->pClassData = NULL;
pdev->pClassDataCmsit[pdev->classId] = NULL;
return (uint8_t)USBD_EMEM;
}
pdev->pClassData = (void *)hcdc;
(void)USBD_memset(hcdc, 0, sizeof(USBD_CDC_RNDIS_HandleTypeDef));
pdev->pClassDataCmsit[pdev->classId] = (void *)hcdc;
pdev->pClassData = pdev->pClassDataCmsit[pdev->classId];
if (pdev->dev_speed == USBD_SPEED_HIGH)
{
/* Open EP IN */
(void)USBD_LL_OpenEP(pdev, CDC_RNDIS_IN_EP, USBD_EP_TYPE_BULK,
(void)USBD_LL_OpenEP(pdev, RNDISInEpAdd, USBD_EP_TYPE_BULK,
CDC_RNDIS_DATA_HS_IN_PACKET_SIZE);
pdev->ep_in[CDC_RNDIS_IN_EP & 0xFU].is_used = 1U;
pdev->ep_in[RNDISInEpAdd & 0xFU].is_used = 1U;
/* Open EP OUT */
(void)USBD_LL_OpenEP(pdev, CDC_RNDIS_OUT_EP, USBD_EP_TYPE_BULK,
(void)USBD_LL_OpenEP(pdev, RNDISOutEpAdd, USBD_EP_TYPE_BULK,
CDC_RNDIS_DATA_HS_OUT_PACKET_SIZE);
pdev->ep_out[CDC_RNDIS_OUT_EP & 0xFU].is_used = 1U;
pdev->ep_out[RNDISOutEpAdd & 0xFU].is_used = 1U;
/* Set bInterval for CDC RNDIS CMD Endpoint */
pdev->ep_in[CDC_RNDIS_CMD_EP & 0xFU].bInterval = CDC_RNDIS_HS_BINTERVAL;
pdev->ep_in[RNDISCmdEpAdd & 0xFU].bInterval = CDC_RNDIS_HS_BINTERVAL;
}
else
{
/* Open EP IN */
(void)USBD_LL_OpenEP(pdev, CDC_RNDIS_IN_EP, USBD_EP_TYPE_BULK,
(void)USBD_LL_OpenEP(pdev, RNDISInEpAdd, USBD_EP_TYPE_BULK,
CDC_RNDIS_DATA_FS_IN_PACKET_SIZE);
pdev->ep_in[CDC_RNDIS_IN_EP & 0xFU].is_used = 1U;
pdev->ep_in[RNDISInEpAdd & 0xFU].is_used = 1U;
/* Open EP OUT */
(void)USBD_LL_OpenEP(pdev, CDC_RNDIS_OUT_EP, USBD_EP_TYPE_BULK,
(void)USBD_LL_OpenEP(pdev, RNDISOutEpAdd, USBD_EP_TYPE_BULK,
CDC_RNDIS_DATA_FS_OUT_PACKET_SIZE);
pdev->ep_out[CDC_RNDIS_OUT_EP & 0xFU].is_used = 1U;
pdev->ep_out[RNDISOutEpAdd & 0xFU].is_used = 1U;
/* Set bInterval for CDC RNDIS CMD Endpoint */
pdev->ep_in[CDC_RNDIS_CMD_EP & 0xFU].bInterval = CDC_RNDIS_FS_BINTERVAL;
pdev->ep_in[RNDISCmdEpAdd & 0xFU].bInterval = CDC_RNDIS_FS_BINTERVAL;
}
/* Open Command IN EP */
(void)USBD_LL_OpenEP(pdev, CDC_RNDIS_CMD_EP, USBD_EP_TYPE_INTR, CDC_RNDIS_CMD_PACKET_SIZE);
pdev->ep_in[CDC_RNDIS_CMD_EP & 0xFU].is_used = 1U;
(void)USBD_LL_OpenEP(pdev, RNDISCmdEpAdd, USBD_EP_TYPE_INTR, CDC_RNDIS_CMD_PACKET_SIZE);
pdev->ep_in[RNDISCmdEpAdd & 0xFU].is_used = 1U;
hcdc->RxBuffer = NULL;
/* Init physical Interface components */
((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->Init();
((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init();
/* Init the CDC_RNDIS state */
hcdc->State = CDC_RNDIS_STATE_BUS_INITIALIZED;
@@ -616,10 +427,16 @@ static uint8_t USBD_CDC_RNDIS_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
hcdc->TxLength = 0U;
hcdc->LinkStatus = 0U;
hcdc->NotificationStatus = 0U;
hcdc->MaxPcktLen = (pdev->dev_speed == USBD_SPEED_HIGH) ? CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE : CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE;
hcdc->MaxPcktLen = (pdev->dev_speed == USBD_SPEED_HIGH) ? CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE : \
CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE;
if (hcdc->RxBuffer == NULL)
{
return (uint8_t)USBD_EMEM;
}
/* Prepare Out endpoint to receive next packet */
(void)USBD_LL_PrepareReceive(pdev, CDC_RNDIS_OUT_EP,
(void)USBD_LL_PrepareReceive(pdev, RNDISOutEpAdd,
hcdc->RxBuffer, hcdc->MaxPcktLen);
return (uint8_t)USBD_OK;
@@ -636,24 +453,32 @@ static uint8_t USBD_CDC_RNDIS_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
UNUSED(cfgidx);
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
RNDISInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
RNDISOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
RNDISCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
/* Close EP IN */
(void)USBD_LL_CloseEP(pdev, CDC_RNDIS_IN_EP);
pdev->ep_in[CDC_RNDIS_IN_EP & 0xFU].is_used = 0U;
(void)USBD_LL_CloseEP(pdev, RNDISInEpAdd);
pdev->ep_in[RNDISInEpAdd & 0xFU].is_used = 0U;
/* Close EP OUT */
(void)USBD_LL_CloseEP(pdev, CDC_RNDIS_OUT_EP);
pdev->ep_out[CDC_RNDIS_OUT_EP & 0xFU].is_used = 0U;
(void)USBD_LL_CloseEP(pdev, RNDISOutEpAdd);
pdev->ep_out[RNDISOutEpAdd & 0xFU].is_used = 0U;
/* Close Command IN EP */
(void)USBD_LL_CloseEP(pdev, CDC_RNDIS_CMD_EP);
pdev->ep_in[CDC_RNDIS_CMD_EP & 0xFU].is_used = 0U;
pdev->ep_in[CDC_RNDIS_CMD_EP & 0xFU].bInterval = 0U;
(void)USBD_LL_CloseEP(pdev, RNDISCmdEpAdd);
pdev->ep_in[RNDISCmdEpAdd & 0xFU].is_used = 0U;
pdev->ep_in[RNDISCmdEpAdd & 0xFU].bInterval = 0U;
/* DeInit physical Interface components */
if (pdev->pClassData != NULL)
if (pdev->pClassDataCmsit[pdev->classId] != NULL)
{
((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->DeInit();
USBD_free(pdev->pClassData);
((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit();
USBD_free(pdev->pClassDataCmsit[pdev->classId]);
pdev->pClassDataCmsit[pdev->classId] = NULL;
pdev->pClassData = NULL;
}
@@ -670,8 +495,8 @@ static uint8_t USBD_CDC_RNDIS_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
static uint8_t USBD_CDC_RNDIS_Setup(USBD_HandleTypeDef *pdev,
USBD_SetupReqTypedef *req)
{
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData;
USBD_CDC_RNDIS_CtrlMsgTypeDef *Msg = (USBD_CDC_RNDIS_CtrlMsgTypeDef *)(void *)hcdc->data;
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
USBD_CDC_RNDIS_CtrlMsgTypeDef *Msg;
uint8_t ifalt = 0U;
uint16_t status_info = 0U;
USBD_StatusTypeDef ret = USBD_OK;
@@ -681,6 +506,8 @@ static uint8_t USBD_CDC_RNDIS_Setup(USBD_HandleTypeDef *pdev,
return (uint8_t)USBD_FAIL;
}
Msg = (USBD_CDC_RNDIS_CtrlMsgTypeDef *)(void *)hcdc->data;
switch (req->bmRequest & USB_REQ_TYPE_MASK)
{
case USB_REQ_TYPE_CLASS :
@@ -703,7 +530,7 @@ static uint8_t USBD_CDC_RNDIS_Setup(USBD_HandleTypeDef *pdev,
}
/* Allow application layer to pre-process data or add own processing before sending response */
((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData[pdev->classId])->Control(req->bRequest,
(uint8_t *)hcdc->data,
req->wLength);
/* Check if Response is ready */
@@ -729,7 +556,7 @@ static uint8_t USBD_CDC_RNDIS_Setup(USBD_HandleTypeDef *pdev,
else
{
hcdc->CmdOpCode = req->bRequest;
hcdc->CmdLength = (uint8_t)MIN(CDC_RNDIS_CMD_PACKET_SIZE, req->wLength);
hcdc->CmdLength = (uint8_t)MIN(CDC_RNDIS_MAX_INFO_BUFF_SZ, req->wLength);
(void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data, hcdc->CmdLength);
}
@@ -738,7 +565,7 @@ static uint8_t USBD_CDC_RNDIS_Setup(USBD_HandleTypeDef *pdev,
so let application layer manage this case */
else
{
((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData[pdev->classId])->Control(req->bRequest,
(uint8_t *)req, 0U);
}
break;
@@ -807,16 +634,21 @@ static uint8_t USBD_CDC_RNDIS_Setup(USBD_HandleTypeDef *pdev,
static uint8_t USBD_CDC_RNDIS_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
USBD_CDC_RNDIS_HandleTypeDef *hcdc;
PCD_HandleTypeDef *hpcd = pdev->pData;
PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef *)pdev->pData;
if (pdev->pClassData == NULL)
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
RNDISInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (pdev->pClassDataCmsit[pdev->classId] == NULL)
{
return (uint8_t)USBD_FAIL;
}
hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData;
hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (epnum == (CDC_RNDIS_IN_EP & 0x7FU))
if (epnum == (RNDISInEpAdd & 0x7FU))
{
if ((pdev->ep_in[epnum & 0xFU].total_length > 0U) &&
((pdev->ep_in[epnum & 0xFU].total_length % hpcd->IN_ep[epnum & 0xFU].maxpacket) == 0U))
@@ -831,13 +663,14 @@ static uint8_t USBD_CDC_RNDIS_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
hcdc->TxState = 0U;
if (((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->TransmitCplt != NULL)
if (((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData[pdev->classId])->TransmitCplt != NULL)
{
((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum);
((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData[pdev->classId])->TransmitCplt(hcdc->TxBuffer, \
&hcdc->TxLength, epnum);
}
}
}
else if (epnum == (CDC_RNDIS_CMD_EP & 0x7FU))
else if (epnum == (RNDISCmdEpAdd & 0x7FU))
{
if (hcdc->NotificationStatus != 0U)
{
@@ -867,14 +700,18 @@ static uint8_t USBD_CDC_RNDIS_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
USBD_CDC_RNDIS_HandleTypeDef *hcdc;
uint32_t CurrPcktLen;
if (pdev->pClassData == NULL)
#ifdef USE_USBD_COMPOSITE /* Get the Endpoints addresses allocated for this class instance */
RNDISOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (pdev->pClassDataCmsit[pdev->classId] == NULL)
{
return (uint8_t)USBD_FAIL;
}
hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData;
hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (epnum == CDC_RNDIS_OUT_EP)
if (epnum == RNDISOutEpAdd)
{
/* Get the received data length */
CurrPcktLen = USBD_LL_GetRxDataSize(pdev, epnum);
@@ -895,7 +732,7 @@ static uint8_t USBD_CDC_RNDIS_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
else
{
/* Prepare Out endpoint to receive next packet in current/new frame */
(void)USBD_LL_PrepareReceive(pdev, CDC_RNDIS_OUT_EP,
(void)USBD_LL_PrepareReceive(pdev, RNDISOutEpAdd,
(uint8_t *)(hcdc->RxBuffer + hcdc->RxLength),
hcdc->MaxPcktLen);
}
@@ -916,14 +753,14 @@ static uint8_t USBD_CDC_RNDIS_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
*/
static uint8_t USBD_CDC_RNDIS_EP0_RxReady(USBD_HandleTypeDef *pdev)
{
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData;
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hcdc == NULL)
{
return (uint8_t)USBD_FAIL;
}
if ((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFFU))
if ((pdev->pUserData[pdev->classId] != NULL) && (hcdc->CmdOpCode != 0xFFU))
{
/* Check if the received command is SendEncapsulated command */
if (hcdc->CmdOpCode == CDC_RNDIS_SEND_ENCAPSULATED_COMMAND)
@@ -946,47 +783,98 @@ static uint8_t USBD_CDC_RNDIS_EP0_RxReady(USBD_HandleTypeDef *pdev)
return (uint8_t)USBD_OK;
}
#ifndef USE_USBD_COMPOSITE
/**
* @brief USBD_CDC_RNDIS_GetFSCfgDesc
* Return configuration descriptor
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_CDC_RNDIS_GetFSCfgDesc(uint16_t *length)
{
*length = (uint16_t)(sizeof(USBD_CDC_RNDIS_CfgFSDesc));
USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_RNDIS_CfgDesc, CDC_RNDIS_CMD_EP);
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_RNDIS_CfgDesc, CDC_RNDIS_OUT_EP);
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_RNDIS_CfgDesc, CDC_RNDIS_IN_EP);
return USBD_CDC_RNDIS_CfgFSDesc;
if (pEpCmdDesc != NULL)
{
pEpCmdDesc->bInterval = CDC_RNDIS_FS_BINTERVAL;
}
if (pEpOutDesc != NULL)
{
pEpOutDesc->wMaxPacketSize = CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE;
}
if (pEpInDesc != NULL)
{
pEpInDesc->wMaxPacketSize = CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE;
}
*length = (uint16_t)(sizeof(USBD_CDC_RNDIS_CfgDesc));
return USBD_CDC_RNDIS_CfgDesc;
}
/**
* @brief USBD_CDC_RNDIS_GetHSCfgDesc
* Return configuration descriptor
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_CDC_RNDIS_GetHSCfgDesc(uint16_t *length)
{
*length = (uint16_t)(sizeof(USBD_CDC_RNDIS_CfgHSDesc));
USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_RNDIS_CfgDesc, CDC_RNDIS_CMD_EP);
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_RNDIS_CfgDesc, CDC_RNDIS_OUT_EP);
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_RNDIS_CfgDesc, CDC_RNDIS_IN_EP);
return USBD_CDC_RNDIS_CfgHSDesc;
if (pEpCmdDesc != NULL)
{
pEpCmdDesc->bInterval = CDC_RNDIS_HS_BINTERVAL;
}
if (pEpOutDesc != NULL)
{
pEpOutDesc->wMaxPacketSize = CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE;
}
if (pEpInDesc != NULL)
{
pEpInDesc->wMaxPacketSize = CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE;
}
*length = (uint16_t)(sizeof(USBD_CDC_RNDIS_CfgDesc));
return USBD_CDC_RNDIS_CfgDesc;
}
/**
* @brief USBD_CDC_RNDIS_GetOtherSpeedCfgDesc
* Return configuration descriptor
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_CDC_RNDIS_GetOtherSpeedCfgDesc(uint16_t *length)
{
*length = (uint16_t)(sizeof(USBD_CDC_RNDIS_OtherSpeedCfgDesc));
USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_RNDIS_CfgDesc, CDC_RNDIS_CMD_EP);
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_RNDIS_CfgDesc, CDC_RNDIS_OUT_EP);
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_RNDIS_CfgDesc, CDC_RNDIS_IN_EP);
return USBD_CDC_RNDIS_OtherSpeedCfgDesc;
if (pEpCmdDesc != NULL)
{
pEpCmdDesc->bInterval = CDC_RNDIS_FS_BINTERVAL;
}
if (pEpOutDesc != NULL)
{
pEpOutDesc->wMaxPacketSize = CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE;
}
if (pEpInDesc != NULL)
{
pEpInDesc->wMaxPacketSize = CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE;
}
*length = (uint16_t)(sizeof(USBD_CDC_RNDIS_CfgDesc));
return USBD_CDC_RNDIS_CfgDesc;
}
/**
@@ -1001,7 +889,7 @@ uint8_t *USBD_CDC_RNDIS_GetDeviceQualifierDescriptor(uint16_t *length)
return USBD_CDC_RNDIS_DeviceQualifierDesc;
}
#endif /* USE_USBD_COMPOSITE */
/**
* @brief USBD_CDC_RNDIS_RegisterInterface
* @param pdev: device instance
@@ -1016,7 +904,7 @@ uint8_t USBD_CDC_RNDIS_RegisterInterface(USBD_HandleTypeDef *pdev,
return (uint8_t)USBD_FAIL;
}
pdev->pUserData = fops;
pdev->pUserData[pdev->classId] = fops;
return (uint8_t)USBD_OK;
}
@@ -1025,7 +913,7 @@ uint8_t USBD_CDC_RNDIS_RegisterInterface(USBD_HandleTypeDef *pdev,
/**
* @brief USBD_CDC_RNDIS_USRStringDescriptor
* Manages the transfer of user string descriptors.
* @param speed : current device speed
* @param pdev: device instance
* @param index: descriptor index
* @param length : pointer data length
* @retval pointer to the descriptor table or NULL if the descriptor is not supported.
@@ -1038,7 +926,8 @@ static uint8_t *USBD_CDC_RNDIS_USRStringDescriptor(USBD_HandleTypeDef *pdev, uin
/* Check if the requested string interface is supported */
if (index == CDC_RNDIS_MAC_STRING_INDEX)
{
USBD_GetString((uint8_t *)((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->pStrDesc, USBD_StrDesc, length);
USBD_GetString((uint8_t *)((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData[pdev->classId])->pStrDesc, USBD_StrDesc,
length);
return USBD_StrDesc;
}
/* Not supported Interface Descriptor index */
@@ -1049,15 +938,25 @@ static uint8_t *USBD_CDC_RNDIS_USRStringDescriptor(USBD_HandleTypeDef *pdev, uin
}
#endif /* USBD_SUPPORT_USER_STRING_DESC */
/**
* @brief USBD_CDC_RNDIS_SetTxBuffer
* @param pdev: device instance
* @param pbuff: Tx Buffer
* @param length: Tx Buffer length
* @param ClassId: The Class ID
* @retval status
*/
#ifdef USE_USBD_COMPOSITE
uint8_t USBD_CDC_RNDIS_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uint32_t length, uint8_t ClassId)
{
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[ClassId];
#else
uint8_t USBD_CDC_RNDIS_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uint32_t length)
{
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData;
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
#endif /* USE_USBD_COMPOSITE */
if (hcdc == NULL)
{
@@ -1079,7 +978,7 @@ uint8_t USBD_CDC_RNDIS_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uin
*/
uint8_t USBD_CDC_RNDIS_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff)
{
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData;
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hcdc == NULL)
{
@@ -1096,20 +995,32 @@ uint8_t USBD_CDC_RNDIS_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff)
* @brief USBD_CDC_RNDIS_TransmitPacket
* Transmit packet on IN endpoint
* @param pdev: device instance
* @param ClassId: The Class ID
* @retval status
*/
#ifdef USE_USBD_COMPOSITE
uint8_t USBD_CDC_RNDIS_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t ClassId)
{
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[ClassId];
#else
uint8_t USBD_CDC_RNDIS_TransmitPacket(USBD_HandleTypeDef *pdev)
{
USBD_CDC_RNDIS_HandleTypeDef *hcdc;
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
#endif /* USE_USBD_COMPOSITE */
USBD_CDC_RNDIS_PacketMsgTypeDef *PacketMsg;
USBD_StatusTypeDef ret = USBD_BUSY;
if (pdev->pClassData == NULL)
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
RNDISInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, ClassId);
#endif /* USE_USBD_COMPOSITE */
if (hcdc == NULL)
{
return (uint8_t)USBD_FAIL;
}
hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData;
PacketMsg = (USBD_CDC_RNDIS_PacketMsgTypeDef *)(void *)hcdc->TxBuffer;
if (hcdc->TxState == 0U)
@@ -1131,10 +1042,10 @@ uint8_t USBD_CDC_RNDIS_TransmitPacket(USBD_HandleTypeDef *pdev)
PacketMsg->Reserved = 0U;
/* Update the packet total length */
pdev->ep_in[CDC_RNDIS_IN_EP & 0xFU].total_length = hcdc->TxLength;
pdev->ep_in[RNDISInEpAdd & 0xFU].total_length = hcdc->TxLength;
/* Transmit next packet */
(void)USBD_LL_Transmit(pdev, CDC_RNDIS_IN_EP, hcdc->TxBuffer, hcdc->TxLength);
(void)USBD_LL_Transmit(pdev, RNDISInEpAdd, hcdc->TxBuffer, hcdc->TxLength);
ret = USBD_OK;
}
@@ -1153,15 +1064,20 @@ uint8_t USBD_CDC_RNDIS_ReceivePacket(USBD_HandleTypeDef *pdev)
{
USBD_CDC_RNDIS_HandleTypeDef *hcdc;
if (pdev->pClassData == NULL)
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
RNDISOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (pdev->pClassDataCmsit[pdev->classId] == NULL)
{
return (uint8_t)USBD_FAIL;
}
hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData;
hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
/* Prepare Out endpoint to receive next packet */
(void)USBD_LL_PrepareReceive(pdev, CDC_RNDIS_OUT_EP,
(void)USBD_LL_PrepareReceive(pdev, RNDISOutEpAdd,
hcdc->RxBuffer, hcdc->MaxPcktLen);
return (uint8_t)USBD_OK;
@@ -1178,12 +1094,12 @@ uint8_t USBD_CDC_RNDIS_ReceivePacket(USBD_HandleTypeDef *pdev)
* @retval status
*/
uint8_t USBD_CDC_RNDIS_SendNotification(USBD_HandleTypeDef *pdev,
USBD_CDC_RNDIS_NotifCodeTypeDef Notif,
USBD_CDC_NotifCodeTypeDef Notif,
uint16_t bVal, uint8_t *pData)
{
uint32_t Idx;
uint16_t ReqSize = 0U;
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData;
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
USBD_StatusTypeDef ret = USBD_OK;
UNUSED(bVal);
@@ -1194,6 +1110,11 @@ uint8_t USBD_CDC_RNDIS_SendNotification(USBD_HandleTypeDef *pdev,
return (uint8_t)USBD_FAIL;
}
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
RNDISCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
/* Initialize the request fields */
(hcdc->Req).bmRequest = CDC_RNDIS_BMREQUEST_TYPE_RNDIS;
(hcdc->Req).bRequest = (uint8_t)Notif;
@@ -1221,7 +1142,7 @@ uint8_t USBD_CDC_RNDIS_SendNotification(USBD_HandleTypeDef *pdev,
/* Transmit notification packet */
if (ReqSize != 0U)
{
(void)USBD_LL_Transmit(pdev, CDC_RNDIS_CMD_EP, (uint8_t *) &(hcdc->Req), ReqSize);
(void)USBD_LL_Transmit(pdev, RNDISCmdEpAdd, (uint8_t *)&hcdc->Req, ReqSize);
}
return (uint8_t)ret;
@@ -1295,7 +1216,7 @@ static uint8_t USBD_CDC_RNDIS_ProcessInitMsg(USBD_HandleTypeDef *pdev,
USBD_CDC_RNDIS_InitMsgTypeDef *Msg)
{
/* Get the CDC_RNDIS handle pointer */
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData;
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
/* Get and format the Msg input */
USBD_CDC_RNDIS_InitMsgTypeDef *InitMessage = (USBD_CDC_RNDIS_InitMsgTypeDef *)Msg;
@@ -1360,7 +1281,7 @@ static uint8_t USBD_CDC_RNDIS_ProcessHaltMsg(USBD_HandleTypeDef *pdev,
USBD_CDC_RNDIS_HaltMsgTypeDef *Msg)
{
/* Get the CDC_RNDIS handle pointer */
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData;
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hcdc == NULL)
{
@@ -1389,7 +1310,7 @@ static uint8_t USBD_CDC_RNDIS_ProcessKeepAliveMsg(USBD_HandleTypeDef *pdev,
USBD_CDC_RNDIS_KpAliveMsgTypeDef *Msg)
{
/* Get the CDC_RNDIS handle pointer */
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData;
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
/* Use same Msg input buffer as response buffer */
USBD_CDC_RNDIS_KpAliveCpltMsgTypeDef *InitResponse = (USBD_CDC_RNDIS_KpAliveCpltMsgTypeDef *)(void *)Msg;
@@ -1439,7 +1360,7 @@ static uint8_t USBD_CDC_RNDIS_ProcessQueryMsg(USBD_HandleTypeDef *pdev,
USBD_CDC_RNDIS_QueryMsgTypeDef *Msg)
{
/* Get the CDC_RNDIS handle pointer */
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData;
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
/* Use same Msg input buffer as response buffer */
USBD_CDC_RNDIS_QueryCpltMsgTypeDef *QueryResponse = (USBD_CDC_RNDIS_QueryCpltMsgTypeDef *)(void *)Msg;
@@ -1584,7 +1505,7 @@ static uint8_t USBD_CDC_RNDIS_ProcessSetMsg(USBD_HandleTypeDef *pdev,
USBD_CDC_RNDIS_SetMsgTypeDef *Msg)
{
/* Get the CDC_RNDIS handle pointer */
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData;
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
/* Get and format the Msg input */
USBD_CDC_RNDIS_SetMsgTypeDef *SetMessage = (USBD_CDC_RNDIS_SetMsgTypeDef *)Msg;
@@ -1647,7 +1568,7 @@ static uint8_t USBD_CDC_RNDIS_ProcessResetMsg(USBD_HandleTypeDef *pdev,
/* Get and format the Msg input */
USBD_CDC_RNDIS_ResetMsgTypeDef *ResetMessage = (USBD_CDC_RNDIS_ResetMsgTypeDef *)Msg;
/* Get the CDC_RNDIS handle pointer */
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData;
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
/* Use same Msg input buffer as response buffer */
USBD_CDC_RNDIS_ResetCpltMsgTypeDef *ResetResponse = (USBD_CDC_RNDIS_ResetCpltMsgTypeDef *)(void *)Msg;
@@ -1695,10 +1616,11 @@ static uint8_t USBD_CDC_RNDIS_ProcessResetMsg(USBD_HandleTypeDef *pdev,
static uint8_t USBD_CDC_RNDIS_ProcessPacketMsg(USBD_HandleTypeDef *pdev,
USBD_CDC_RNDIS_PacketMsgTypeDef *Msg)
{
uint32_t tmp1, tmp2;
uint32_t tmp1;
uint32_t tmp2;
/* Get the CDC_RNDIS handle pointer */
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData;
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
/* Get and format the Msg input */
USBD_CDC_RNDIS_PacketMsgTypeDef *PacketMsg = (USBD_CDC_RNDIS_PacketMsgTypeDef *)Msg;
@@ -1723,7 +1645,7 @@ static uint8_t USBD_CDC_RNDIS_ProcessPacketMsg(USBD_HandleTypeDef *pdev,
hcdc->RxLength = PacketMsg->DataLength;
/* Process data by application */
((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength);
((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData[pdev->classId])->Receive(hcdc->RxBuffer, &hcdc->RxLength);
return (uint8_t)USBD_OK;
}
@@ -1740,7 +1662,7 @@ static uint8_t USBD_CDC_RNDIS_ProcessUnsupportedMsg(USBD_HandleTypeDef *pdev,
USBD_CDC_RNDIS_CtrlMsgTypeDef *Msg)
{
/* Get the CDC_RNDIS handle pointer */
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData;
USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
/* Use same Msg input buffer as response buffer */
USBD_CDC_RNDIS_StsChangeMsgTypeDef *Response = (USBD_CDC_RNDIS_StsChangeMsgTypeDef *)(void *)Msg;
@@ -1780,5 +1702,3 @@ static uint8_t USBD_CDC_RNDIS_ProcessUnsupportedMsg(USBD_HandleTypeDef *pdev,
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2019 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -31,21 +30,23 @@
#include "ethernetif.h"
*/
#include "main.h"
#include "usbd_cdc_rndis_if_template.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Received Data over USB are stored in this buffer */
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
__ALIGN_BEGIN uint8_t UserRxBuffer[CDC_RNDIS_ETH_MAX_SEGSZE + 100] __ALIGN_END; /* Received Data over USB are stored in this buffer */
#endif /* __ICCARM__ */
__ALIGN_BEGIN uint8_t UserRxBuffer[CDC_RNDIS_ETH_MAX_SEGSZE + 100] __ALIGN_END;
/* Transmitted Data over CDC_RNDIS (CDC_RNDIS interface) are stored in this buffer */
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
__ALIGN_BEGIN static uint8_t UserTxBuffer[CDC_RNDIS_ETH_MAX_SEGSZE + 100] __ALIGN_END; /* Received Data over CDC_RNDIS (CDC_RNDIS interface) are stored in this buffer */
#endif /* __ICCARM__ */
__ALIGN_BEGIN static uint8_t UserTxBuffer[CDC_RNDIS_ETH_MAX_SEGSZE + 100] __ALIGN_END;
static uint8_t CDC_RNDISInitialized = 0U;
@@ -94,7 +95,11 @@ static int8_t CDC_RNDIS_Itf_Init(void)
}
/* Set Application Buffers */
#ifdef USE_USBD_COMPOSITE
(void)USBD_CDC_RNDIS_SetTxBuffer(&USBD_Device, UserTxBuffer, 0U, 0U);
#else
(void)USBD_CDC_RNDIS_SetTxBuffer(&USBD_Device, UserTxBuffer, 0U);
#endif /* USE_USBD_COMPOSITE */
(void)USBD_CDC_RNDIS_SetRxBuffer(&USBD_Device, UserRxBuffer);
return (0);
@@ -108,7 +113,12 @@ static int8_t CDC_RNDIS_Itf_Init(void)
*/
static int8_t CDC_RNDIS_Itf_DeInit(void)
{
#ifdef USE_USBD_COMPOSITE
USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *) \
(USBD_Device.pClassDataCmsit[USBD_Device.classId]);
#else
USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *)(USBD_Device.pClassData);
#endif /* USE_USBD_COMPOSITE */
/*
Add your code here
@@ -130,7 +140,12 @@ static int8_t CDC_RNDIS_Itf_DeInit(void)
*/
static int8_t CDC_RNDIS_Itf_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length)
{
#ifdef USE_USBD_COMPOSITE
USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *) \
(USBD_Device.pClassDataCmsit[USBD_Device.classId]);
#else
USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *)(USBD_Device.pClassData);
#endif /* USE_USBD_COMPOSITE */
switch (cmd)
{
@@ -173,7 +188,12 @@ static int8_t CDC_RNDIS_Itf_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length)
static int8_t CDC_RNDIS_Itf_Receive(uint8_t *Buf, uint32_t *Len)
{
/* Get the CDC_RNDIS handler pointer */
#ifdef USE_USBD_COMPOSITE
USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *) \
(USBD_Device.pClassDataCmsit[USBD_Device.classId]);
#else
USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *)(USBD_Device.pClassData);
#endif /* USE_USBD_COMPOSITE */
/* Call Eth buffer processing */
hcdc_cdc_rndis->RxState = 1U;
@@ -216,9 +236,18 @@ static int8_t CDC_RNDIS_Itf_TransmitCplt(uint8_t *Buf, uint32_t *Len, uint8_t ep
static int8_t CDC_RNDIS_Itf_Process(USBD_HandleTypeDef *pdev)
{
/* Get the CDC_RNDIS handler pointer */
#ifdef USE_USBD_COMPOSITE
USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *)(pdev->pClassDataCmsit[pdev->classId]);
#else
USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *)(pdev->pClassData);
#endif /* USE_USBD_COMPOSITE */
if ((hcdc_cdc_rndis != NULL) && (hcdc_cdc_rndis->LinkStatus != 0U))
if (hcdc_cdc_rndis == NULL)
{
return (-1);
}
if (hcdc_cdc_rndis->LinkStatus != 0U)
{
/*
Add your code here
@@ -230,4 +259,3 @@ static int8_t CDC_RNDIS_Itf_Process(USBD_HandleTypeDef *pdev)
return (0);
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,289 @@
/**
******************************************************************************
* @file usbd_composite_builder.h
* @author MCD Application Team
* @brief Header for the usbd_composite_builder.c file
******************************************************************************
* @attention
*
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_COMPOSITE_BUILDER_H__
#define __USBD_COMPOSITE_BUILDER_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbd_ioreq.h"
#if USBD_CMPSIT_ACTIVATE_HID == 1U
#include "usbd_hid.h"
#endif /* USBD_CMPSIT_ACTIVATE_HID */
#if USBD_CMPSIT_ACTIVATE_MSC == 1U
#include "usbd_msc.h"
#endif /* USBD_CMPSIT_ACTIVATE_MSC */
#if USBD_CMPSIT_ACTIVATE_CDC == 1U
#include "usbd_cdc.h"
#endif /* USBD_CMPSIT_ACTIVATE_CDC */
#if USBD_CMPSIT_ACTIVATE_DFU == 1U
#include "usbd_dfu.h"
#endif /* USBD_CMPSIT_ACTIVATE_DFU */
#if USBD_CMPSIT_ACTIVATE_RNDIS == 1U
#include "usbd_cdc_rndis.h"
#endif /* USBD_CMPSIT_ACTIVATE_RNDIS */
#if USBD_CMPSIT_ACTIVATE_CDC_ECM == 1U
#include "usbd_cdc_ecm.h"
#ifndef __USBD_CDC_ECM_IF_H
#include "usbd_cdc_ecm_if_template.h"
#endif /* __USBD_CDC_ECM_IF_H */
#endif /* USBD_CMPSIT_ACTIVATE_CDC_ECM */
#if USBD_CMPSIT_ACTIVATE_AUDIO == 1
#include "usbd_audio.h"
#endif /* USBD_CMPSIT_ACTIVATE_AUDIO */
#if USBD_CMPSIT_ACTIVATE_CUSTOMHID == 1
#include "usbd_customhid.h"
#endif /* USBD_CMPSIT_ACTIVATE_CUSTOMHID */
#if USBD_CMPSIT_ACTIVATE_VIDEO == 1
#include "usbd_video.h"
#endif /* USBD_CMPSIT_ACTIVATE_VIDEO */
#if USBD_CMPSIT_ACTIVATE_PRINTER == 1
#include "usbd_printer.h"
#endif /* USBD_CMPSIT_ACTIVATE_PRINTER */
#if USBD_CMPSIT_ACTIVATE_CCID == 1U
#include "usbd_ccid.h"
#endif /* USBD_CMPSIT_ACTIVATE_CCID */
#if USBD_CMPSIT_ACTIVATE_MTP == 1U
#include "usbd_mtp.h"
#endif /* USBD_CMPSIT_ACTIVATE_MTP */
/* Private defines -----------------------------------------------------------*/
/* By default all classes are deactivated, in order to activate a class
define its value to zero */
#ifndef USBD_CMPSIT_ACTIVATE_HID
#define USBD_CMPSIT_ACTIVATE_HID 0U
#endif /* USBD_CMPSIT_ACTIVATE_HID */
#ifndef USBD_CMPSIT_ACTIVATE_MSC
#define USBD_CMPSIT_ACTIVATE_MSC 0U
#endif /* USBD_CMPSIT_ACTIVATE_MSC */
#ifndef USBD_CMPSIT_ACTIVATE_DFU
#define USBD_CMPSIT_ACTIVATE_DFU 0U
#endif /* USBD_CMPSIT_ACTIVATE_DFU */
#ifndef USBD_CMPSIT_ACTIVATE_CDC
#define USBD_CMPSIT_ACTIVATE_CDC 0U
#endif /* USBD_CMPSIT_ACTIVATE_CDC */
#ifndef USBD_CMPSIT_ACTIVATE_CDC_ECM
#define USBD_CMPSIT_ACTIVATE_CDC_ECM 0U
#endif /* USBD_CMPSIT_ACTIVATE_CDC_ECM */
#ifndef USBD_CMPSIT_ACTIVATE_RNDIS
#define USBD_CMPSIT_ACTIVATE_RNDIS 0U
#endif /* USBD_CMPSIT_ACTIVATE_RNDIS */
#ifndef USBD_CMPSIT_ACTIVATE_AUDIO
#define USBD_CMPSIT_ACTIVATE_AUDIO 0U
#endif /* USBD_CMPSIT_ACTIVATE_AUDIO */
#ifndef USBD_CMPSIT_ACTIVATE_CUSTOMHID
#define USBD_CMPSIT_ACTIVATE_CUSTOMHID 0U
#endif /* USBD_CMPSIT_ACTIVATE_CUSTOMHID */
#ifndef USBD_CMPSIT_ACTIVATE_VIDEO
#define USBD_CMPSIT_ACTIVATE_VIDEO 0U
#endif /* USBD_CMPSIT_ACTIVATE_VIDEO */
#ifndef USBD_CMPSIT_ACTIVATE_PRINTER
#define USBD_CMPSIT_ACTIVATE_PRINTER 0U
#endif /* USBD_CMPSIT_ACTIVATE_PRINTER */
#ifndef USBD_CMPSIT_ACTIVATE_CCID
#define USBD_CMPSIT_ACTIVATE_CCID 0U
#endif /* USBD_CMPSIT_ACTIVATE_CCID */
#ifndef USBD_CMPSIT_ACTIVATE_MTP
#define USBD_CMPSIT_ACTIVATE_MTP 0U
#endif /* USBD_CMPSIT_ACTIVATE_MTP */
/* This is the maximum supported configuration descriptor size
User may define this value in usbd_conf.h in order to optimize footprint */
#ifndef USBD_CMPST_MAX_CONFDESC_SZ
#define USBD_CMPST_MAX_CONFDESC_SZ 300U
#endif /* USBD_CMPST_MAX_CONFDESC_SZ */
#ifndef USBD_CONFIG_STR_DESC_IDX
#define USBD_CONFIG_STR_DESC_IDX 4U
#endif /* USBD_CONFIG_STR_DESC_IDX */
/* Exported types ------------------------------------------------------------*/
/* USB Iad descriptors structure */
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bFirstInterface;
uint8_t bInterfaceCount;
uint8_t bFunctionClass;
uint8_t bFunctionSubClass;
uint8_t bFunctionProtocol;
uint8_t iFunction;
} USBD_IadDescTypeDef;
/* USB interface descriptors structure */
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bInterfaceNumber;
uint8_t bAlternateSetting;
uint8_t bNumEndpoints;
uint8_t bInterfaceClass;
uint8_t bInterfaceSubClass;
uint8_t bInterfaceProtocol;
uint8_t iInterface;
} USBD_IfDescTypeDef;
#if (USBD_CMPSIT_ACTIVATE_CDC == 1) || (USBD_CMPSIT_ACTIVATE_RNDIS == 1) || (USBD_CMPSIT_ACTIVATE_CDC_ECM == 1)
typedef struct
{
/*
* CDC Class specification revision 1.2
* Table 15: Class-Specific Descriptor Header Format
*/
/* Header Functional Descriptor */
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint16_t bcdCDC;
} __PACKED USBD_CDCHeaderFuncDescTypeDef;
typedef struct
{
/* Call Management Functional Descriptor */
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bmCapabilities;
uint8_t bDataInterface;
} USBD_CDCCallMgmFuncDescTypeDef;
typedef struct
{
/* ACM Functional Descriptor */
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bmCapabilities;
} USBD_CDCACMFuncDescTypeDef;
typedef struct
{
/*
* CDC Class specification revision 1.2
* Table 16: Union Interface Functional Descriptor
*/
/* Union Functional Descriptor */
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bMasterInterface;
uint8_t bSlaveInterface;
} USBD_CDCUnionFuncDescTypeDef;
#endif /* (USBD_CMPSIT_ACTIVATE_CDC == 1) || (USBD_CMPSIT_ACTIVATE_RNDIS == 1) || (USBD_CMPSIT_ACTIVATE_CDC_ECM == 1)*/
extern USBD_ClassTypeDef USBD_CMPSIT;
/* Exported functions prototypes ---------------------------------------------*/
uint8_t USBD_CMPSIT_AddToConfDesc(USBD_HandleTypeDef *pdev);
#ifdef USE_USBD_COMPOSITE
uint8_t USBD_CMPSIT_AddClass(USBD_HandleTypeDef *pdev,
USBD_ClassTypeDef *pclass,
USBD_CompositeClassTypeDef class,
uint8_t cfgidx);
uint32_t USBD_CMPSIT_SetClassID(USBD_HandleTypeDef *pdev,
USBD_CompositeClassTypeDef Class,
uint32_t Instance);
uint32_t USBD_CMPSIT_GetClassID(USBD_HandleTypeDef *pdev,
USBD_CompositeClassTypeDef Class,
uint32_t Instance);
#endif /* USE_USBD_COMPOSITE */
uint8_t USBD_CMPST_ClearConfDesc(USBD_HandleTypeDef *pdev);
/* Private macro -----------------------------------------------------------*/
#define __USBD_CMPSIT_SET_EP(epadd, eptype, epsize, HSinterval, FSinterval) \
do { \
/* Append Endpoint descriptor to Configuration descriptor */ \
pEpDesc = ((USBD_EpDescTypeDef*)((uint32_t)pConf + *Sze)); \
pEpDesc->bLength = (uint8_t)sizeof(USBD_EpDescTypeDef); \
pEpDesc->bDescriptorType = USB_DESC_TYPE_ENDPOINT; \
pEpDesc->bEndpointAddress = (epadd); \
pEpDesc->bmAttributes = (eptype); \
pEpDesc->wMaxPacketSize = (uint16_t)(epsize); \
if(speed == (uint8_t)USBD_SPEED_HIGH) \
{ \
pEpDesc->bInterval = HSinterval; \
} \
else \
{ \
pEpDesc->bInterval = FSinterval; \
} \
*Sze += (uint32_t)sizeof(USBD_EpDescTypeDef); \
} while(0)
#define __USBD_CMPSIT_SET_IF(ifnum, alt, eps, class, subclass, protocol, istring) \
do { \
/* Interface Descriptor */ \
pIfDesc = ((USBD_IfDescTypeDef*)((uint32_t)pConf + *Sze)); \
pIfDesc->bLength = (uint8_t)sizeof(USBD_IfDescTypeDef); \
pIfDesc->bDescriptorType = USB_DESC_TYPE_INTERFACE; \
pIfDesc->bInterfaceNumber = ifnum; \
pIfDesc->bAlternateSetting = alt; \
pIfDesc->bNumEndpoints = eps; \
pIfDesc->bInterfaceClass = class; \
pIfDesc->bInterfaceSubClass = subclass; \
pIfDesc->bInterfaceProtocol = protocol; \
pIfDesc->iInterface = istring; \
*Sze += (uint32_t)sizeof(USBD_IfDescTypeDef); \
} while(0)
#ifdef __cplusplus
}
#endif
#endif /* __USBD_COMPOSITE_BUILDER_H__ */
/**
* @}
*/

File diff suppressed because it is too large Load Diff

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -41,17 +40,21 @@ extern "C" {
/** @defgroup USBD_CUSTOM_HID_Exported_Defines
* @{
*/
#ifndef CUSTOM_HID_EPIN_ADDR
#define CUSTOM_HID_EPIN_ADDR 0x81U
#endif /* CUSTOM_HID_EPIN_ADDR */
#ifndef CUSTOM_HID_EPIN_SIZE
#define CUSTOM_HID_EPIN_SIZE 0x02U
#endif
#endif /* CUSTOM_HID_EPIN_SIZE */
#ifndef CUSTOM_HID_EPOUT_ADDR
#define CUSTOM_HID_EPOUT_ADDR 0x01U
#endif /* CUSTOM_HID_EPOUT_ADDR */
#ifndef CUSTOM_HID_EPOUT_SIZE
#define CUSTOM_HID_EPOUT_SIZE 0x02U
#endif
#endif /* CUSTOM_HID_EPOUT_SIZE*/
#define USB_CUSTOM_HID_CONFIG_DESC_SIZ 41U
#define USB_CUSTOM_HID_DESC_SIZ 9U
@@ -103,7 +106,12 @@ typedef struct _USBD_CUSTOM_HID_Itf
int8_t (* Init)(void);
int8_t (* DeInit)(void);
int8_t (* OutEvent)(uint8_t event_idx, uint8_t state);
#ifdef USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED
int8_t (* CtrlReqComplete)(uint8_t request, uint16_t wLength);
#endif /* USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */
#ifdef USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED
uint8_t *(* GetReport)(uint16_t *ReportLength);
#endif /* USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED */
} USBD_CUSTOM_HID_ItfTypeDef;
typedef struct
@@ -115,6 +123,23 @@ typedef struct
uint32_t IsReportAvailable;
CUSTOM_HID_StateTypeDef state;
} USBD_CUSTOM_HID_HandleTypeDef;
/*
* HID Class specification version 1.1
* 6.2.1 HID Descriptor
*/
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorTypeCHID;
uint16_t bcdCUSTOM_HID;
uint8_t bCountryCode;
uint8_t bNumDescriptors;
uint8_t bDescriptorType;
uint16_t wItemLength;
} __PACKED USBD_DescTypeDef;
/**
* @}
*/
@@ -142,9 +167,13 @@ extern USBD_ClassTypeDef USBD_CUSTOM_HID;
/** @defgroup USB_CORE_Exported_Functions
* @{
*/
#ifdef USE_USBD_COMPOSITE
uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev,
uint8_t *report, uint16_t len, uint8_t ClassId);
#else
uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev,
uint8_t *report, uint16_t len);
#endif /* USE_USBD_COMPOSITE */
uint8_t USBD_CUSTOM_HID_ReceivePacket(USBD_HandleTypeDef *pdev);
uint8_t USBD_CUSTOM_HID_RegisterInterface(USBD_HandleTypeDef *pdev,
@@ -167,4 +196,3 @@ uint8_t USBD_CUSTOM_HID_RegisterInterface(USBD_HandleTypeDef *pdev,
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -40,4 +39,3 @@ extern USBD_CUSTOM_HID_ItfTypeDef USBD_CustomHID_template_fops;
#endif /* __USBD_CUSTOMHID_IF_TEMPLATE_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -4,6 +4,17 @@
* @author MCD Application Team
* @brief This file provides the CUSTOM_HID core functions.
*
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
* @verbatim
*
* ===================================================================
@@ -24,17 +35,6 @@
* @endverbatim
*
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* BSPDependencies
@@ -91,12 +91,12 @@ static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqType
static uint8_t USBD_CUSTOM_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
static uint8_t USBD_CUSTOM_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
static uint8_t USBD_CUSTOM_HID_EP0_RxReady(USBD_HandleTypeDef *pdev);
#ifndef USE_USBD_COMPOSITE
static uint8_t *USBD_CUSTOM_HID_GetFSCfgDesc(uint16_t *length);
static uint8_t *USBD_CUSTOM_HID_GetHSCfgDesc(uint16_t *length);
static uint8_t *USBD_CUSTOM_HID_GetOtherSpeedCfgDesc(uint16_t *length);
static uint8_t *USBD_CUSTOM_HID_GetDeviceQualifierDesc(uint16_t *length);
#endif /* USE_USBD_COMPOSITE */
/**
* @}
*/
@@ -117,27 +117,36 @@ USBD_ClassTypeDef USBD_CUSTOM_HID =
NULL, /*SOF */
NULL,
NULL,
#ifdef USE_USBD_COMPOSITE
NULL,
NULL,
NULL,
NULL,
#else
USBD_CUSTOM_HID_GetHSCfgDesc,
USBD_CUSTOM_HID_GetFSCfgDesc,
USBD_CUSTOM_HID_GetOtherSpeedCfgDesc,
USBD_CUSTOM_HID_GetDeviceQualifierDesc,
#endif /* USE_USBD_COMPOSITE */
};
#ifndef USE_USBD_COMPOSITE
/* USB CUSTOM_HID device FS Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgFSDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END =
__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END =
{
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
USB_CUSTOM_HID_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */
0x00,
LOBYTE(USB_CUSTOM_HID_CONFIG_DESC_SIZ), /* wTotalLength: Bytes returned */
HIBYTE(USB_CUSTOM_HID_CONFIG_DESC_SIZ),
0x01, /* bNumInterfaces: 1 interface */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
0x00, /* iConfiguration: Index of string descriptor
describing the configuration */
#if (USBD_SELF_POWERED == 1U)
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
#endif /* USBD_SELF_POWERED */
USBD_MAX_POWER, /* MaxPower (mA) */
/************** Descriptor of CUSTOM HID interface ****************/
@@ -158,10 +167,11 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgFSDesc[USB_CUSTOM_HID_CONFIG_DES
0x11, /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */
0x01,
0x00, /* bCountryCode: Hardware target country */
0x01, /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */
0x01, /* bNumDescriptors: Number of CUSTOM_HID class descriptors
to follow */
0x22, /* bDescriptorType */
USBD_CUSTOM_HID_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
0x00,
LOBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE), /* wItemLength: Total length of Report descriptor */
HIBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE),
/******************** Descriptor of Custom HID endpoints ********************/
/* 27 */
0x07, /* bLength: Endpoint Descriptor size */
@@ -169,8 +179,8 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgFSDesc[USB_CUSTOM_HID_CONFIG_DES
CUSTOM_HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */
0x03, /* bmAttributes: Interrupt endpoint */
CUSTOM_HID_EPIN_SIZE, /* wMaxPacketSize: 2 Bytes max */
0x00,
LOBYTE(CUSTOM_HID_EPIN_SIZE), /* wMaxPacketSize: 2 Bytes max */
HIBYTE(CUSTOM_HID_EPIN_SIZE),
CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval */
/* 34 */
@@ -178,133 +188,12 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgFSDesc[USB_CUSTOM_HID_CONFIG_DES
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */
CUSTOM_HID_EPOUT_ADDR, /* bEndpointAddress: Endpoint Address (OUT) */
0x03, /* bmAttributes: Interrupt endpoint */
CUSTOM_HID_EPOUT_SIZE, /* wMaxPacketSize: 2 Bytes max */
0x00,
CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval */
/* 41 */
};
/* USB CUSTOM_HID device HS Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgHSDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END =
{
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
USB_CUSTOM_HID_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */
0x00,
0x01, /* bNumInterfaces: 1 interface */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
#if (USBD_SELF_POWERED == 1U)
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
USBD_MAX_POWER, /* MaxPower (mA) */
/************** Descriptor of CUSTOM HID interface ****************/
/* 09 */
0x09, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints */
0x03, /* bInterfaceClass: CUSTOM_HID */
0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
0, /* iInterface: Index of string descriptor */
/******************** Descriptor of CUSTOM_HID *************************/
/* 18 */
0x09, /* bLength: CUSTOM_HID Descriptor size */
CUSTOM_HID_DESCRIPTOR_TYPE, /* bDescriptorType: CUSTOM_HID */
0x11, /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */
0x01,
0x00, /* bCountryCode: Hardware target country */
0x01, /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */
0x22, /* bDescriptorType */
USBD_CUSTOM_HID_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
0x00,
/******************** Descriptor of Custom HID endpoints ********************/
/* 27 */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType */
CUSTOM_HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */
0x03, /* bmAttributes: Interrupt endpoint */
CUSTOM_HID_EPIN_SIZE, /* wMaxPacketSize: 2 Bytes max */
0x00,
CUSTOM_HID_HS_BINTERVAL, /* bInterval: Polling Interval */
/* 34 */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */
CUSTOM_HID_EPOUT_ADDR, /* bEndpointAddress: Endpoint Address (OUT) */
0x03, /* bmAttributes: Interrupt endpoint */
CUSTOM_HID_EPOUT_SIZE, /* wMaxPacketSize: 2 Bytes max */
0x00,
CUSTOM_HID_HS_BINTERVAL, /* bInterval: Polling Interval */
/* 41 */
};
/* USB CUSTOM_HID device Other Speed Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_OtherSpeedCfgDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END =
{
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
USB_CUSTOM_HID_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */
0x00,
0x01, /* bNumInterfaces: 1 interface */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
#if (USBD_SELF_POWERED == 1U)
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
USBD_MAX_POWER, /* MaxPower (mA) */
/************** Descriptor of CUSTOM HID interface ****************/
/* 09 */
0x09, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints */
0x03, /* bInterfaceClass: CUSTOM_HID */
0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
0, /* iInterface: Index of string descriptor */
/******************** Descriptor of CUSTOM_HID *************************/
/* 18 */
0x09, /* bLength: CUSTOM_HID Descriptor size */
CUSTOM_HID_DESCRIPTOR_TYPE, /* bDescriptorType: CUSTOM_HID */
0x11, /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */
0x01,
0x00, /* bCountryCode: Hardware target country */
0x01, /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */
0x22, /* bDescriptorType */
USBD_CUSTOM_HID_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
0x00,
/******************** Descriptor of Custom HID endpoints ********************/
/* 27 */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */
CUSTOM_HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */
0x03, /* bmAttributes: Interrupt endpoint */
CUSTOM_HID_EPIN_SIZE, /* wMaxPacketSize: 2 Bytes max */
0x00,
CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval */
/* 34 */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */
CUSTOM_HID_EPOUT_ADDR, /* bEndpointAddress: Endpoint Address (OUT) */
0x03, /* bmAttributes: Interrupt endpoint */
CUSTOM_HID_EPOUT_SIZE, /* wMaxPacketSize: 2 Bytes max */
0x00,
LOBYTE(CUSTOM_HID_EPOUT_SIZE), /* wMaxPacketSize: 2 Bytes max */
HIBYTE(CUSTOM_HID_EPOUT_SIZE),
CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval */
/* 41 */
};
#endif /* USE_USBD_COMPOSITE */
/* USB CUSTOM_HID device Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_Desc[USB_CUSTOM_HID_DESC_SIZ] __ALIGN_END =
@@ -315,12 +204,14 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_Desc[USB_CUSTOM_HID_DESC_SIZ] __ALI
0x11, /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */
0x01,
0x00, /* bCountryCode: Hardware target country */
0x01, /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */
0x01, /* bNumDescriptors: Number of CUSTOM_HID class descriptors
to follow */
0x22, /* bDescriptorType */
USBD_CUSTOM_HID_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
0x00,
LOBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE), /* wItemLength: Total length of Report descriptor */
HIBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE),
};
#ifndef USE_USBD_COMPOSITE
/* USB Standard Device Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
{
@@ -335,7 +226,10 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_DeviceQualifierDesc[USB_LEN_DEV_QUA
0x01,
0x00,
};
#endif /* USE_USBD_COMPOSITE */
static uint8_t CUSTOMHIDInEpAdd = CUSTOM_HID_EPIN_ADDR;
static uint8_t CUSTOMHIDOutEpAdd = CUSTOM_HID_EPOUT_ADDR;
/**
* @}
*/
@@ -360,42 +254,51 @@ static uint8_t USBD_CUSTOM_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
if (hhid == NULL)
{
pdev->pClassData = NULL;
pdev->pClassDataCmsit[pdev->classId] = NULL;
return (uint8_t)USBD_EMEM;
}
pdev->pClassData = (void *)hhid;
pdev->pClassDataCmsit[pdev->classId] = (void *)hhid;
pdev->pClassData = pdev->pClassDataCmsit[pdev->classId];
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
CUSTOMHIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
CUSTOMHIDOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (pdev->dev_speed == USBD_SPEED_HIGH)
{
pdev->ep_in[CUSTOM_HID_EPIN_ADDR & 0xFU].bInterval = CUSTOM_HID_HS_BINTERVAL;
pdev->ep_out[CUSTOM_HID_EPOUT_ADDR & 0xFU].bInterval = CUSTOM_HID_HS_BINTERVAL;
pdev->ep_in[CUSTOMHIDInEpAdd & 0xFU].bInterval = CUSTOM_HID_HS_BINTERVAL;
pdev->ep_out[CUSTOMHIDOutEpAdd & 0xFU].bInterval = CUSTOM_HID_HS_BINTERVAL;
}
else /* LOW and FULL-speed endpoints */
{
pdev->ep_in[CUSTOM_HID_EPIN_ADDR & 0xFU].bInterval = CUSTOM_HID_FS_BINTERVAL;
pdev->ep_out[CUSTOM_HID_EPOUT_ADDR & 0xFU].bInterval = CUSTOM_HID_FS_BINTERVAL;
pdev->ep_in[CUSTOMHIDInEpAdd & 0xFU].bInterval = CUSTOM_HID_FS_BINTERVAL;
pdev->ep_out[CUSTOMHIDOutEpAdd & 0xFU].bInterval = CUSTOM_HID_FS_BINTERVAL;
}
/* Open EP IN */
(void)USBD_LL_OpenEP(pdev, CUSTOM_HID_EPIN_ADDR, USBD_EP_TYPE_INTR,
(void)USBD_LL_OpenEP(pdev, CUSTOMHIDInEpAdd, USBD_EP_TYPE_INTR,
CUSTOM_HID_EPIN_SIZE);
pdev->ep_in[CUSTOM_HID_EPIN_ADDR & 0xFU].is_used = 1U;
pdev->ep_in[CUSTOMHIDInEpAdd & 0xFU].is_used = 1U;
/* Open EP OUT */
(void)USBD_LL_OpenEP(pdev, CUSTOM_HID_EPOUT_ADDR, USBD_EP_TYPE_INTR,
(void)USBD_LL_OpenEP(pdev, CUSTOMHIDOutEpAdd, USBD_EP_TYPE_INTR,
CUSTOM_HID_EPOUT_SIZE);
pdev->ep_out[CUSTOM_HID_EPOUT_ADDR & 0xFU].is_used = 1U;
pdev->ep_out[CUSTOMHIDOutEpAdd & 0xFU].is_used = 1U;
hhid->state = CUSTOM_HID_IDLE;
((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->Init();
((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init();
#ifndef USBD_CUSTOMHID_OUT_PREPARE_RECEIVE_DISABLED
/* Prepare Out endpoint to receive 1st packet */
(void)USBD_LL_PrepareReceive(pdev, CUSTOM_HID_EPOUT_ADDR, hhid->Report_buf,
(void)USBD_LL_PrepareReceive(pdev, CUSTOMHIDOutEpAdd, hhid->Report_buf,
USBD_CUSTOMHID_OUTREPORT_BUF_SIZE);
#endif /* USBD_CUSTOMHID_OUT_PREPARE_RECEIVE_DISABLED */
return (uint8_t)USBD_OK;
}
@@ -411,21 +314,28 @@ static uint8_t USBD_CUSTOM_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
UNUSED(cfgidx);
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
CUSTOMHIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
CUSTOMHIDOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
/* Close CUSTOM_HID EP IN */
(void)USBD_LL_CloseEP(pdev, CUSTOM_HID_EPIN_ADDR);
pdev->ep_in[CUSTOM_HID_EPIN_ADDR & 0xFU].is_used = 0U;
pdev->ep_in[CUSTOM_HID_EPIN_ADDR & 0xFU].bInterval = 0U;
(void)USBD_LL_CloseEP(pdev, CUSTOMHIDInEpAdd);
pdev->ep_in[CUSTOMHIDInEpAdd & 0xFU].is_used = 0U;
pdev->ep_in[CUSTOMHIDInEpAdd & 0xFU].bInterval = 0U;
/* Close CUSTOM_HID EP OUT */
(void)USBD_LL_CloseEP(pdev, CUSTOM_HID_EPOUT_ADDR);
pdev->ep_out[CUSTOM_HID_EPOUT_ADDR & 0xFU].is_used = 0U;
pdev->ep_out[CUSTOM_HID_EPOUT_ADDR & 0xFU].bInterval = 0U;
(void)USBD_LL_CloseEP(pdev, CUSTOMHIDOutEpAdd);
pdev->ep_out[CUSTOMHIDOutEpAdd & 0xFU].is_used = 0U;
pdev->ep_out[CUSTOMHIDOutEpAdd & 0xFU].bInterval = 0U;
/* Free allocated memory */
if (pdev->pClassData != NULL)
if (pdev->pClassDataCmsit[pdev->classId] != NULL)
{
((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->DeInit();
USBD_free(pdev->pClassData);
((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit();
USBD_free(pdev->pClassDataCmsit[pdev->classId]);
pdev->pClassDataCmsit[pdev->classId] = NULL;
pdev->pClassData = NULL;
}
@@ -442,8 +352,11 @@ static uint8_t USBD_CUSTOM_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev,
USBD_SetupReqTypedef *req)
{
USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData;
USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint16_t len = 0U;
#ifdef USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED
uint16_t ReportLength = 0U;
#endif /* USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED */
uint8_t *pbuf = NULL;
uint16_t status_info = 0U;
USBD_StatusTypeDef ret = USBD_OK;
@@ -475,10 +388,59 @@ static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev,
break;
case CUSTOM_HID_REQ_SET_REPORT:
#ifdef USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED
if (((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->CtrlReqComplete != NULL)
{
/* Let the application decide when to enable EP0 to receive the next report */
((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->CtrlReqComplete(req->bRequest,
req->wLength);
}
#endif /* USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */
#ifndef USBD_CUSTOMHID_EP0_OUT_PREPARE_RECEIVE_DISABLED
hhid->IsReportAvailable = 1U;
(void)USBD_CtlPrepareRx(pdev, hhid->Report_buf,
MIN(req->wLength, USBD_CUSTOMHID_OUTREPORT_BUF_SIZE));
#endif /* USBD_CUSTOMHID_EP0_OUT_PREPARE_RECEIVE_DISABLED */
break;
#ifdef USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED
case CUSTOM_HID_REQ_GET_REPORT:
if (((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->GetReport != NULL)
{
ReportLength = req->wLength;
/* Get report data buffer */
pbuf = ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->GetReport(&ReportLength);
}
if ((pbuf != NULL) && (ReportLength != 0U))
{
len = MIN(ReportLength, req->wLength);
/* Send the report data over EP0 */
(void)USBD_CtlSendData(pdev, pbuf, len);
}
else
{
#ifdef USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED
if (((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->CtrlReqComplete != NULL)
{
/* Let the application decide what to do, keep EP0 data phase in NAK state and
use USBD_CtlSendData() when data become available or stall the EP0 data phase */
((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->CtrlReqComplete(req->bRequest,
req->wLength);
}
else
{
/* Stall EP0 if no data available */
USBD_CtlError(pdev, req);
}
#else
/* Stall EP0 if no data available */
USBD_CtlError(pdev, req);
#endif /* USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */
}
break;
#endif /* USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED */
default:
USBD_CtlError(pdev, req);
@@ -506,7 +468,7 @@ static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev,
if ((req->wValue >> 8) == CUSTOM_HID_REPORT_DESC)
{
len = MIN(USBD_CUSTOM_HID_REPORT_DESC_SIZE, req->wLength);
pbuf = ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->pReport;
pbuf = ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->pReport;
}
else
{
@@ -567,26 +529,37 @@ static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev,
* Send CUSTOM_HID Report
* @param pdev: device instance
* @param buff: pointer to report
* @param ClassId: The Class ID
* @retval status
*/
#ifdef USE_USBD_COMPOSITE
uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev,
uint8_t *report, uint16_t len, uint8_t ClassId)
{
USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassDataCmsit[ClassId];
#else
uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev,
uint8_t *report, uint16_t len)
{
USBD_CUSTOM_HID_HandleTypeDef *hhid;
USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
#endif /* USE_USBD_COMPOSITE */
if (pdev->pClassData == NULL)
if (hhid == NULL)
{
return (uint8_t)USBD_FAIL;
}
hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData;
#ifdef USE_USBD_COMPOSITE
/* Get Endpoint IN address allocated for this class instance */
CUSTOMHIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, ClassId);
#endif /* USE_USBD_COMPOSITE */
if (pdev->dev_state == USBD_STATE_CONFIGURED)
{
if (hhid->state == CUSTOM_HID_IDLE)
{
hhid->state = CUSTOM_HID_BUSY;
(void)USBD_LL_Transmit(pdev, CUSTOM_HID_EPIN_ADDR, report, len);
(void)USBD_LL_Transmit(pdev, CUSTOMHIDInEpAdd, report, len);
}
else
{
@@ -595,7 +568,7 @@ uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev,
}
return (uint8_t)USBD_OK;
}
#ifndef USE_USBD_COMPOSITE
/**
* @brief USBD_CUSTOM_HID_GetFSCfgDesc
* return FS configuration descriptor
@@ -605,9 +578,23 @@ uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev,
*/
static uint8_t *USBD_CUSTOM_HID_GetFSCfgDesc(uint16_t *length)
{
*length = (uint16_t)sizeof(USBD_CUSTOM_HID_CfgFSDesc);
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CUSTOM_HID_CfgDesc, CUSTOM_HID_EPIN_ADDR);
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CUSTOM_HID_CfgDesc, CUSTOM_HID_EPOUT_ADDR);
return USBD_CUSTOM_HID_CfgFSDesc;
if (pEpInDesc != NULL)
{
pEpInDesc->wMaxPacketSize = CUSTOM_HID_EPIN_SIZE;
pEpInDesc->bInterval = CUSTOM_HID_FS_BINTERVAL;
}
if (pEpOutDesc != NULL)
{
pEpOutDesc->wMaxPacketSize = CUSTOM_HID_EPOUT_SIZE;
pEpOutDesc->bInterval = CUSTOM_HID_FS_BINTERVAL;
}
*length = (uint16_t)sizeof(USBD_CUSTOM_HID_CfgDesc);
return USBD_CUSTOM_HID_CfgDesc;
}
/**
@@ -619,9 +606,23 @@ static uint8_t *USBD_CUSTOM_HID_GetFSCfgDesc(uint16_t *length)
*/
static uint8_t *USBD_CUSTOM_HID_GetHSCfgDesc(uint16_t *length)
{
*length = (uint16_t)sizeof(USBD_CUSTOM_HID_CfgHSDesc);
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CUSTOM_HID_CfgDesc, CUSTOM_HID_EPIN_ADDR);
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CUSTOM_HID_CfgDesc, CUSTOM_HID_EPOUT_ADDR);
return USBD_CUSTOM_HID_CfgHSDesc;
if (pEpInDesc != NULL)
{
pEpInDesc->wMaxPacketSize = CUSTOM_HID_EPIN_SIZE;
pEpInDesc->bInterval = CUSTOM_HID_HS_BINTERVAL;
}
if (pEpOutDesc != NULL)
{
pEpOutDesc->wMaxPacketSize = CUSTOM_HID_EPOUT_SIZE;
pEpOutDesc->bInterval = CUSTOM_HID_HS_BINTERVAL;
}
*length = (uint16_t)sizeof(USBD_CUSTOM_HID_CfgDesc);
return USBD_CUSTOM_HID_CfgDesc;
}
/**
@@ -633,10 +634,25 @@ static uint8_t *USBD_CUSTOM_HID_GetHSCfgDesc(uint16_t *length)
*/
static uint8_t *USBD_CUSTOM_HID_GetOtherSpeedCfgDesc(uint16_t *length)
{
*length = (uint16_t)sizeof(USBD_CUSTOM_HID_OtherSpeedCfgDesc);
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CUSTOM_HID_CfgDesc, CUSTOM_HID_EPIN_ADDR);
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CUSTOM_HID_CfgDesc, CUSTOM_HID_EPOUT_ADDR);
return USBD_CUSTOM_HID_OtherSpeedCfgDesc;
if (pEpInDesc != NULL)
{
pEpInDesc->wMaxPacketSize = CUSTOM_HID_EPIN_SIZE;
pEpInDesc->bInterval = CUSTOM_HID_FS_BINTERVAL;
}
if (pEpOutDesc != NULL)
{
pEpOutDesc->wMaxPacketSize = CUSTOM_HID_EPOUT_SIZE;
pEpOutDesc->bInterval = CUSTOM_HID_FS_BINTERVAL;
}
*length = (uint16_t)sizeof(USBD_CUSTOM_HID_CfgDesc);
return USBD_CUSTOM_HID_CfgDesc;
}
#endif /* USE_USBD_COMPOSITE */
/**
* @brief USBD_CUSTOM_HID_DataIn
@@ -651,7 +667,7 @@ static uint8_t USBD_CUSTOM_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
/* Ensure that the FIFO is empty before a new transfer, this condition could
be caused by a new transfer before the end of the previous transfer */
((USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData)->state = CUSTOM_HID_IDLE;
((USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId])->state = CUSTOM_HID_IDLE;
return (uint8_t)USBD_OK;
}
@@ -668,16 +684,16 @@ static uint8_t USBD_CUSTOM_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
UNUSED(epnum);
USBD_CUSTOM_HID_HandleTypeDef *hhid;
if (pdev->pClassData == NULL)
if (pdev->pClassDataCmsit[pdev->classId] == NULL)
{
return (uint8_t)USBD_FAIL;
}
hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData;
hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
/* USB data will be immediately processed, this allow next USB traffic being
NAKed till the end of the application processing */
((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->OutEvent(hhid->Report_buf[0],
((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->OutEvent(hhid->Report_buf[0],
hhid->Report_buf[1]);
return (uint8_t)USBD_OK;
@@ -694,15 +710,20 @@ uint8_t USBD_CUSTOM_HID_ReceivePacket(USBD_HandleTypeDef *pdev)
{
USBD_CUSTOM_HID_HandleTypeDef *hhid;
if (pdev->pClassData == NULL)
if (pdev->pClassDataCmsit[pdev->classId] == NULL)
{
return (uint8_t)USBD_FAIL;
}
hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData;
#ifdef USE_USBD_COMPOSITE
/* Get OUT Endpoint address allocated for this class instance */
CUSTOMHIDOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
/* Resume USB Out process */
(void)USBD_LL_PrepareReceive(pdev, CUSTOM_HID_EPOUT_ADDR, hhid->Report_buf,
(void)USBD_LL_PrepareReceive(pdev, CUSTOMHIDOutEpAdd, hhid->Report_buf,
USBD_CUSTOMHID_OUTREPORT_BUF_SIZE);
return (uint8_t)USBD_OK;
@@ -717,7 +738,7 @@ uint8_t USBD_CUSTOM_HID_ReceivePacket(USBD_HandleTypeDef *pdev)
*/
static uint8_t USBD_CUSTOM_HID_EP0_RxReady(USBD_HandleTypeDef *pdev)
{
USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData;
USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hhid == NULL)
{
@@ -726,7 +747,7 @@ static uint8_t USBD_CUSTOM_HID_EP0_RxReady(USBD_HandleTypeDef *pdev)
if (hhid->IsReportAvailable == 1U)
{
((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->OutEvent(hhid->Report_buf[0],
((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->OutEvent(hhid->Report_buf[0],
hhid->Report_buf[1]);
hhid->IsReportAvailable = 0U;
}
@@ -734,6 +755,7 @@ static uint8_t USBD_CUSTOM_HID_EP0_RxReady(USBD_HandleTypeDef *pdev)
return (uint8_t)USBD_OK;
}
#ifndef USE_USBD_COMPOSITE
/**
* @brief DeviceQualifierDescriptor
* return Device Qualifier descriptor
@@ -746,7 +768,7 @@ static uint8_t *USBD_CUSTOM_HID_GetDeviceQualifierDesc(uint16_t *length)
return USBD_CUSTOM_HID_DeviceQualifierDesc;
}
#endif /* USE_USBD_COMPOSITE */
/**
* @brief USBD_CUSTOM_HID_RegisterInterface
* @param pdev: device instance
@@ -761,7 +783,7 @@ uint8_t USBD_CUSTOM_HID_RegisterInterface(USBD_HandleTypeDef *pdev,
return (uint8_t)USBD_FAIL;
}
pdev->pUserData = fops;
pdev->pUserData[pdev->classId] = fops;
return (uint8_t)USBD_OK;
}
@@ -779,4 +801,3 @@ uint8_t USBD_CUSTOM_HID_RegisterInterface(USBD_HandleTypeDef *pdev,
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -8,13 +8,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -34,13 +33,31 @@ EndBSPDependencies */
static int8_t TEMPLATE_CUSTOM_HID_Init(void);
static int8_t TEMPLATE_CUSTOM_HID_DeInit(void);
static int8_t TEMPLATE_CUSTOM_HID_OutEvent(uint8_t event_idx, uint8_t state);
#ifdef USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED
static int8_t TEMPLATE_CUSTOM_HID_CtrlReqComplete(uint8_t request, uint16_t wLength);
#endif /* USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */
#ifdef USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED
static uint8_t *TEMPLATE_CUSTOM_HID_GetReport(uint16_t *ReportLength);
#endif /* USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED */
/* Private variables ---------------------------------------------------------*/
extern USBD_HandleTypeDef USBD_Device;
__ALIGN_BEGIN static uint8_t TEMPLATE_CUSTOM_HID_ReportDesc[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END = {0};
USBD_CUSTOM_HID_ItfTypeDef USBD_CustomHID_template_fops =
{
TEMPLATE_CUSTOM_HID_ReportDesc,
TEMPLATE_CUSTOM_HID_Init,
TEMPLATE_CUSTOM_HID_DeInit,
TEMPLATE_CUSTOM_HID_OutEvent,
#ifdef USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED
TEMPLATE_CUSTOM_HID_CtrlReqComplete,
#endif /* USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */
#ifdef USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED
TEMPLATE_CUSTOM_HID_GetReport,
#endif /* USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED */
};
/* Private functions ---------------------------------------------------------*/
@@ -84,8 +101,58 @@ static int8_t TEMPLATE_CUSTOM_HID_OutEvent(uint8_t event_idx, uint8_t state)
UNUSED(state);
/* Start next USB packet transfer once data processing is completed */
USBD_CUSTOM_HID_ReceivePacket(&USBD_Device);
if (USBD_CUSTOM_HID_ReceivePacket(&USBD_Device) != (uint8_t)USBD_OK)
{
return -1;
}
return (0);
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
#ifdef USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED
/**
* @brief TEMPLATE_CUSTOM_HID_CtrlReqComplete
* Manage the CUSTOM HID control request complete
* @param request: control request
* @param wLength: request wLength
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t TEMPLATE_CUSTOM_HID_CtrlReqComplete(uint8_t request, uint16_t wLength)
{
UNUSED(wLength);
switch (request)
{
case CUSTOM_HID_REQ_SET_REPORT:
break;
case CUSTOM_HID_REQ_GET_REPORT:
break;
default:
break;
}
return (0);
}
#endif /* USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */
#ifdef USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED
/**
* @brief TEMPLATE_CUSTOM_HID_GetReport
* Manage the CUSTOM HID control Get Report request
* @param event_idx: event index
* @param state: event state
* @retval return pointer to HID report
*/
static uint8_t *TEMPLATE_CUSTOM_HID_GetReport(uint16_t *ReportLength)
{
UNUSED(ReportLength);
uint8_t *pbuff;
return (pbuff);
}
#endif /* USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED */

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -53,6 +52,14 @@ extern "C" {
#define USBD_DFU_APP_DEFAULT_ADD 0x08008000U /* The first sector (32 KB) is reserved for DFU code */
#endif /* USBD_DFU_APP_DEFAULT_ADD */
#ifndef USBD_DFU_BM_ATTRIBUTES
#define USBD_DFU_BM_ATTRIBUTES 0x0BU
#endif /* USBD_DFU_BM_ATTRIBUTES */
#ifndef USBD_DFU_DETACH_TIMEOUT
#define USBD_DFU_DETACH_TIMEOUT 0xFFU
#endif /* USBD_DFU_DETACH_TIMEOUT */
#define USB_DFU_CONFIG_DESC_SIZ (18U + (9U * USBD_DFU_MAX_ITF_NUM))
#define USB_DFU_DESC_SIZ 9U
@@ -115,7 +122,8 @@ extern "C" {
/* Other defines */
/**************************************************/
/* Bit Detach capable = bit 3 in bmAttributes field */
#define DFU_DETACH_MASK (1U << 4)
#define DFU_DETACH_MASK (1U << 3)
#define DFU_MANIFEST_MASK (1U << 2)
#define DFU_STATUS_DEPTH 6U
typedef enum
@@ -133,7 +141,8 @@ typedef void (*pFunction)(void);
/********** Descriptor of DFU interface 0 Alternate setting n ****************/
#define USBD_DFU_IF_DESC(n) 0x09, /* bLength: Interface Descriptor size */ \
#define USBD_DFU_IF_DESC(n) \
0x09, /* bLength: Interface Descriptor size */ \
USB_DESC_TYPE_INTERFACE, /* bDescriptorType */ \
0x00, /* bInterfaceNumber: Number of Interface */ \
(n), /* bAlternateSetting: Alternate setting */ \
@@ -141,12 +150,11 @@ typedef void (*pFunction)(void);
0xFE, /* bInterfaceClass: Application Specific Class Code */ \
0x01, /* bInterfaceSubClass : Device Firmware Upgrade Code */ \
0x02, /* nInterfaceProtocol: DFU mode protocol */ \
USBD_IDX_INTERFACE_STR + (n) + 1U /* iInterface: Index of string descriptor */ \
USBD_IDX_INTERFACE_STR + (n) + 1U /* iInterface: Index of string descriptor */
#define TRANSFER_SIZE_BYTES(size) ((uint8_t)(size)), /* XFERSIZEB0 */\
((uint8_t)((size) >> 8)) /* XFERSIZEB1 */
#define TRANSFER_SIZE_BYTES(size) ((uint8_t)(size)), ((uint8_t)((size) >> 8))
#define IS_PROTECTED_AREA(add) (uint8_t)((((add) >= 0x08000000) && ((add) < (APP_DEFAULT_ADD)))? 1:0)
#define IS_PROTECTED_AREA(add) (uint8_t)((((add) >= 0x08000000) && ((add) < (APP_DEFAULT_ADD))) ? 1 : 0)
/**
* @}
@@ -186,6 +194,17 @@ typedef struct
uint8_t *(* Read)(uint8_t *src, uint8_t *dest, uint32_t Len);
uint16_t (* GetStatus)(uint32_t Add, uint8_t cmd, uint8_t *buff);
} USBD_DFU_MediaTypeDef;
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bmAttributes;
uint16_t wDetachTimeout;
uint16_t wTransferSze;
uint16_t bcdDFUVersion;
} __PACKED USBD_DFUFuncDescTypeDef;
/**
* @}
*/
@@ -231,5 +250,3 @@ uint8_t USBD_DFU_RegisterMedia(USBD_HandleTypeDef *pdev,
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -94,4 +93,3 @@ extern USBD_DFU_MediaTypeDef USBD_DFU_MEDIA_Template_fops;
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -4,6 +4,17 @@
* @author MCD Application Team
* @brief This file provides the DFU core functions.
*
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
* @verbatim
*
* ===================================================================
@@ -34,17 +45,6 @@
* @endverbatim
*
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* BSPDependencies
@@ -104,13 +104,15 @@ static uint8_t USBD_DFU_EP0_RxReady(USBD_HandleTypeDef *pdev);
static uint8_t USBD_DFU_EP0_TxReady(USBD_HandleTypeDef *pdev);
static uint8_t USBD_DFU_SOF(USBD_HandleTypeDef *pdev);
#ifndef USE_USBD_COMPOSITE
static uint8_t *USBD_DFU_GetCfgDesc(uint16_t *length);
static uint8_t *USBD_DFU_GetDeviceQualifierDesc(uint16_t *length);
#endif /* USE_USBD_COMPOSITE */
#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
static uint8_t *USBD_DFU_GetUsrStringDesc(USBD_HandleTypeDef *pdev,
uint8_t index, uint16_t *length);
#endif
#endif /* USBD_SUPPORT_USER_STRING_DESC */
static void DFU_Detach(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
static void DFU_Download(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
@@ -120,6 +122,7 @@ static void DFU_ClearStatus(USBD_HandleTypeDef *pdev);
static void DFU_GetState(USBD_HandleTypeDef *pdev);
static void DFU_Abort(USBD_HandleTypeDef *pdev);
static void DFU_Leave(USBD_HandleTypeDef *pdev);
static void *USBD_DFU_GetDfuFuncDesc(uint8_t *pConfDesc);
/**
* @}
@@ -141,15 +144,23 @@ USBD_ClassTypeDef USBD_DFU =
USBD_DFU_SOF,
NULL,
NULL,
#ifdef USE_USBD_COMPOSITE
NULL,
NULL,
NULL,
NULL,
#else
USBD_DFU_GetCfgDesc,
USBD_DFU_GetCfgDesc,
USBD_DFU_GetCfgDesc,
USBD_DFU_GetDeviceQualifierDesc,
#endif /* USE_USBD_COMPOSITE */
#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
USBD_DFU_GetUsrStringDesc
#endif
#endif /* USBD_SUPPORT_USER_STRING_DESC */
};
#ifndef USE_USBD_COMPOSITE
/* USB DFU device Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_DFU_CfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END =
{
@@ -159,12 +170,13 @@ __ALIGN_BEGIN static uint8_t USBD_DFU_CfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_E
0x00,
0x01, /* bNumInterfaces: 1 interface */
0x01, /* bConfigurationValue: Configuration value */
0x02, /* iConfiguration: Index of string descriptor describing the configuration */
0x02, /* iConfiguration: Index of string descriptor
describing the configuration */
#if (USBD_SELF_POWERED == 1U)
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
#endif /* USBD_SELF_POWERED */
USBD_MAX_POWER, /* MaxPower (mA) */
/* 09 */
@@ -235,6 +247,7 @@ __ALIGN_BEGIN static uint8_t USBD_DFU_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_
0x01,
0x00,
};
#endif /* USE_USBD_COMPOSITE */
/**
* @}
@@ -262,11 +275,12 @@ static uint8_t USBD_DFU_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
if (hdfu == NULL)
{
pdev->pClassData = NULL;
pdev->pClassDataCmsit[pdev->classId] = NULL;
return (uint8_t)USBD_EMEM;
}
pdev->pClassData = (void *)hdfu;
pdev->pClassDataCmsit[pdev->classId] = (void *)hdfu;
pdev->pClassData = pdev->pClassDataCmsit[pdev->classId];
hdfu->alt_setting = 0U;
hdfu->data_ptr = USBD_DFU_APP_DEFAULT_ADD;
@@ -284,7 +298,7 @@ static uint8_t USBD_DFU_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
hdfu->dev_status[5] = 0U;
/* Initialize Hardware layer */
if (((USBD_DFU_MediaTypeDef *)pdev->pUserData)->Init() != USBD_OK)
if (((USBD_DFU_MediaTypeDef *)pdev->pUserData[pdev->classId])->Init() != USBD_OK)
{
return (uint8_t)USBD_FAIL;
}
@@ -293,7 +307,7 @@ static uint8_t USBD_DFU_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
}
/**
* @brief USBD_DFU_Init
* @brief USBD_DFU_DeInit
* De-Initialize the DFU layer
* @param pdev: device instance
* @param cfgidx: Configuration index
@@ -304,12 +318,12 @@ static uint8_t USBD_DFU_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
UNUSED(cfgidx);
USBD_DFU_HandleTypeDef *hdfu;
if (pdev->pClassData == NULL)
if (pdev->pClassDataCmsit[pdev->classId] == NULL)
{
return (uint8_t)USBD_EMEM;
}
hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData;
hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
hdfu->wblock_num = 0U;
hdfu->wlength = 0U;
@@ -318,8 +332,9 @@ static uint8_t USBD_DFU_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
hdfu->dev_status[4] = DFU_STATE_IDLE;
/* DeInit physical Interface components and Hardware Layer */
((USBD_DFU_MediaTypeDef *)pdev->pUserData)->DeInit();
USBD_free(pdev->pClassData);
((USBD_DFU_MediaTypeDef *)pdev->pUserData[pdev->classId])->DeInit();
USBD_free(pdev->pClassDataCmsit[pdev->classId]);
pdev->pClassDataCmsit[pdev->classId] = NULL;
pdev->pClassData = NULL;
return (uint8_t)USBD_OK;
@@ -334,10 +349,10 @@ static uint8_t USBD_DFU_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
*/
static uint8_t USBD_DFU_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData;
USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
USBD_StatusTypeDef ret = USBD_OK;
uint8_t *pbuf = NULL;
uint16_t len = 0U;
uint8_t *pbuf;
uint16_t len;
uint16_t status_info = 0U;
if (hdfu == NULL)
@@ -403,11 +418,19 @@ static uint8_t USBD_DFU_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *re
case USB_REQ_GET_DESCRIPTOR:
if ((req->wValue >> 8) == DFU_DESCRIPTOR_TYPE)
{
pbuf = USBD_DFU_CfgDesc + (9U * (USBD_DFU_MAX_ITF_NUM + 1U));
len = MIN(USB_DFU_DESC_SIZ, req->wLength);
}
pbuf = (uint8_t *)USBD_DFU_GetDfuFuncDesc(pdev->pConfDesc);
if (pbuf != NULL)
{
len = MIN(USB_DFU_DESC_SIZ, req->wLength);
(void)USBD_CtlSendData(pdev, pbuf, len);
}
else
{
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
}
}
break;
case USB_REQ_GET_INTERFACE:
@@ -462,11 +485,10 @@ static uint8_t USBD_DFU_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *re
return (uint8_t)ret;
}
#ifndef USE_USBD_COMPOSITE
/**
* @brief USBD_DFU_GetCfgDesc
* return configuration descriptor
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
@@ -476,7 +498,7 @@ static uint8_t *USBD_DFU_GetCfgDesc(uint16_t *length)
return USBD_DFU_CfgDesc;
}
#endif /* USE_USBD_COMPOSITE */
/**
* @brief USBD_DFU_EP0_RxReady
@@ -500,8 +522,8 @@ static uint8_t USBD_DFU_EP0_TxReady(USBD_HandleTypeDef *pdev)
{
USBD_SetupReqTypedef req;
uint32_t addr;
USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData;
USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData;
USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData[pdev->classId];
if (hdfu == NULL)
{
@@ -610,7 +632,7 @@ static uint8_t USBD_DFU_SOF(USBD_HandleTypeDef *pdev)
return (uint8_t)USBD_OK;
}
#ifndef USE_USBD_COMPOSITE
/**
* @brief DeviceQualifierDescriptor
* return Device Qualifier descriptor
@@ -623,11 +645,12 @@ static uint8_t *USBD_DFU_GetDeviceQualifierDesc(uint16_t *length)
return USBD_DFU_DeviceQualifierDesc;
}
#endif /* USE_USBD_COMPOSITE */
/**
* @brief USBD_DFU_GetUsrStringDesc
* Manages the transfer of memory interfaces string descriptors.
* @param speed : current device speed
* @param pdev: device instance
* @param index: descriptor index
* @param length : pointer data length
* @retval pointer to the descriptor table or NULL if the descriptor is not supported.
@@ -636,7 +659,7 @@ static uint8_t *USBD_DFU_GetDeviceQualifierDesc(uint16_t *length)
static uint8_t *USBD_DFU_GetUsrStringDesc(USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length)
{
static uint8_t USBD_StrDesc[255];
USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData;
USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData[pdev->classId];
/* Check if the requested string interface is supported */
if (index <= (USBD_IDX_INTERFACE_STR + USBD_DFU_MAX_ITF_NUM))
@@ -647,13 +670,15 @@ static uint8_t *USBD_DFU_GetUsrStringDesc(USBD_HandleTypeDef *pdev, uint8_t inde
else
{
/* Not supported Interface Descriptor index */
length = 0U;
return NULL;
}
}
#endif
#endif /* USBD_SUPPORT_USER_STRING_DESC */
/**
* @brief USBD_MSC_RegisterStorage
* @param pdev: device instance
* @param fops: storage callback
* @retval status
*/
@@ -665,7 +690,7 @@ uint8_t USBD_DFU_RegisterMedia(USBD_HandleTypeDef *pdev,
return (uint8_t)USBD_FAIL;
}
pdev->pUserData = fops;
pdev->pUserData[pdev->classId] = fops;
return (uint8_t)USBD_OK;
}
@@ -682,9 +707,10 @@ uint8_t USBD_DFU_RegisterMedia(USBD_HandleTypeDef *pdev,
*/
static void DFU_Detach(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData;
USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
USBD_DFUFuncDescTypeDef *pDfuFunc = (USBD_DFUFuncDescTypeDef *)USBD_DFU_GetDfuFuncDesc(pdev->pConfDesc);
if (hdfu == NULL)
if ((hdfu == NULL) || (pDfuFunc == NULL))
{
return;
}
@@ -708,7 +734,7 @@ static void DFU_Detach(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
}
/* Check the detach capability in the DFU functional descriptor */
if (((USBD_DFU_CfgDesc[12U + (9U * USBD_DFU_MAX_ITF_NUM)]) & DFU_DETACH_MASK) != 0U)
if ((pDfuFunc->bmAttributes & DFU_DETACH_MASK) != 0U)
{
/* Perform an Attach-Detach operation on USB bus */
(void)USBD_Stop(pdev);
@@ -730,7 +756,7 @@ static void DFU_Detach(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
*/
static void DFU_Download(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData;
USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hdfu == NULL)
{
@@ -790,8 +816,8 @@ static void DFU_Download(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
*/
static void DFU_Upload(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData;
USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData;
USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData[pdev->classId];
uint8_t *phaddr;
uint32_t addr;
@@ -888,10 +914,11 @@ static void DFU_Upload(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
*/
static void DFU_GetStatus(USBD_HandleTypeDef *pdev)
{
USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData;
USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData;
USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData[pdev->classId];
USBD_DFUFuncDescTypeDef *pDfuFunc = (USBD_DFUFuncDescTypeDef *)USBD_DFU_GetDfuFuncDesc(pdev->pConfDesc);
if (hdfu == NULL)
if ((hdfu == NULL) || (DfuInterface == NULL) || (pDfuFunc == NULL))
{
return;
}
@@ -941,7 +968,7 @@ static void DFU_GetStatus(USBD_HandleTypeDef *pdev)
else
{
if ((hdfu->manif_state == DFU_MANIFEST_COMPLETE) &&
(((USBD_DFU_CfgDesc[(11U + (9U * USBD_DFU_MAX_ITF_NUM))]) & 0x04U) != 0U))
((pDfuFunc->bmAttributes & DFU_MANIFEST_MASK) != 0U))
{
hdfu->dev_state = DFU_STATE_IDLE;
@@ -969,7 +996,7 @@ static void DFU_GetStatus(USBD_HandleTypeDef *pdev)
*/
static void DFU_ClearStatus(USBD_HandleTypeDef *pdev)
{
USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData;
USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hdfu == NULL)
{
@@ -1007,7 +1034,7 @@ static void DFU_ClearStatus(USBD_HandleTypeDef *pdev)
*/
static void DFU_GetState(USBD_HandleTypeDef *pdev)
{
USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData;
USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hdfu == NULL)
{
@@ -1026,7 +1053,7 @@ static void DFU_GetState(USBD_HandleTypeDef *pdev)
*/
static void DFU_Abort(USBD_HandleTypeDef *pdev)
{
USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData;
USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hdfu == NULL)
{
@@ -1060,16 +1087,17 @@ static void DFU_Abort(USBD_HandleTypeDef *pdev)
*/
static void DFU_Leave(USBD_HandleTypeDef *pdev)
{
USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData;
USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
USBD_DFUFuncDescTypeDef *pDfuFunc = (USBD_DFUFuncDescTypeDef *)USBD_DFU_GetDfuFuncDesc(pdev->pConfDesc);
if (hdfu == NULL)
if ((hdfu == NULL) || (pDfuFunc == NULL))
{
return;
}
hdfu->manif_state = DFU_MANIFEST_COMPLETE;
if (((USBD_DFU_CfgDesc[(11U + (9U * USBD_DFU_MAX_ITF_NUM))]) & 0x04U) != 0U)
if ((pDfuFunc->bmAttributes & DFU_MANIFEST_MASK) != 0U)
{
hdfu->dev_state = DFU_STATE_MANIFEST_SYNC;
@@ -1098,6 +1126,38 @@ static void DFU_Leave(USBD_HandleTypeDef *pdev)
}
}
/**
* @brief USBD_DFU_GetDfuFuncDesc
* This function return the DFU descriptor
* @param pdev: device instance
* @param pConfDesc: pointer to Bos descriptor
* @retval pointer to the DFU descriptor
*/
static void *USBD_DFU_GetDfuFuncDesc(uint8_t *pConfDesc)
{
USBD_ConfigDescTypeDef *desc = (USBD_ConfigDescTypeDef *)(void *)pConfDesc;
USBD_DescHeaderTypeDef *pdesc = (USBD_DescHeaderTypeDef *)(void *)pConfDesc;
uint8_t *pDfuDesc = NULL;
uint16_t ptr;
if (desc->wTotalLength > desc->bLength)
{
ptr = desc->bLength;
while (ptr < desc->wTotalLength)
{
pdesc = USBD_GetNextDesc((uint8_t *)pdesc, &ptr);
if (pdesc->bDescriptorType == DFU_DESCRIPTOR_TYPE)
{
pDfuDesc = (uint8_t *)pdesc;
break;
}
}
}
return pDfuDesc;
}
/**
* @}
*/
@@ -1112,4 +1172,3 @@ static void DFU_Leave(USBD_HandleTypeDef *pdev)
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -81,6 +80,8 @@ uint16_t MEM_If_DeInit(void)
*/
uint16_t MEM_If_Erase(uint32_t Add)
{
UNUSED(Add);
return 0;
}
@@ -93,6 +94,10 @@ uint16_t MEM_If_Erase(uint32_t Add)
*/
uint16_t MEM_If_Write(uint8_t *src, uint8_t *dest, uint32_t Len)
{
UNUSED(src);
UNUSED(dest);
UNUSED(Len);
return 0;
}
@@ -105,6 +110,10 @@ uint16_t MEM_If_Write(uint8_t *src, uint8_t *dest, uint32_t Len)
*/
uint8_t *MEM_If_Read(uint8_t *src, uint8_t *dest, uint32_t Len)
{
UNUSED(src);
UNUSED(dest);
UNUSED(Len);
/* Return a valid address to avoid HardFault */
return (uint8_t *)(0);
}
@@ -118,6 +127,9 @@ uint8_t *MEM_If_Read(uint8_t *src, uint8_t *dest, uint32_t Len)
*/
uint16_t MEM_If_GetStatus(uint32_t Add, uint8_t Cmd, uint8_t *buffer)
{
UNUSED(Add);
UNUSED(buffer);
switch (Cmd)
{
case DFU_MEDIA_PROGRAM:
@@ -131,5 +143,4 @@ uint16_t MEM_If_GetStatus(uint32_t Add, uint8_t Cmd, uint8_t *buffer)
}
return (0);
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -41,7 +40,9 @@ extern "C" {
/** @defgroup USBD_HID_Exported_Defines
* @{
*/
#ifndef HID_EPIN_ADDR
#define HID_EPIN_ADDR 0x81U
#endif /* HID_EPIN_ADDR */
#define HID_EPIN_SIZE 0x04U
#define USB_HID_CONFIG_DESC_SIZ 34U
@@ -59,14 +60,14 @@ extern "C" {
#define HID_FS_BINTERVAL 0x0AU
#endif /* HID_FS_BINTERVAL */
#define HID_REQ_SET_PROTOCOL 0x0BU
#define HID_REQ_GET_PROTOCOL 0x03U
#define USBD_HID_REQ_SET_PROTOCOL 0x0BU
#define USBD_HID_REQ_GET_PROTOCOL 0x03U
#define HID_REQ_SET_IDLE 0x0AU
#define HID_REQ_GET_IDLE 0x02U
#define USBD_HID_REQ_SET_IDLE 0x0AU
#define USBD_HID_REQ_GET_IDLE 0x02U
#define HID_REQ_SET_REPORT 0x09U
#define HID_REQ_GET_REPORT 0x01U
#define USBD_HID_REQ_SET_REPORT 0x09U
#define USBD_HID_REQ_GET_REPORT 0x01U
/**
* @}
*/
@@ -77,9 +78,9 @@ extern "C" {
*/
typedef enum
{
HID_IDLE = 0,
HID_BUSY,
} HID_StateTypeDef;
USBD_HID_IDLE = 0,
USBD_HID_BUSY,
} USBD_HID_StateTypeDef;
typedef struct
@@ -87,8 +88,25 @@ typedef struct
uint32_t Protocol;
uint32_t IdleState;
uint32_t AltSetting;
HID_StateTypeDef state;
USBD_HID_StateTypeDef state;
} USBD_HID_HandleTypeDef;
/*
* HID Class specification version 1.1
* 6.2.1 HID Descriptor
*/
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdHID;
uint8_t bCountryCode;
uint8_t bNumDescriptors;
uint8_t bHIDDescriptorType;
uint16_t wItemLength;
} __PACKED USBD_HIDDescTypeDef;
/**
* @}
*/
@@ -116,7 +134,11 @@ extern USBD_ClassTypeDef USBD_HID;
/** @defgroup USB_CORE_Exported_Functions
* @{
*/
#ifdef USE_USBD_COMPOSITE
uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len, uint8_t ClassId);
#else
uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len);
#endif /* USE_USBD_COMPOSITE */
uint32_t USBD_HID_GetPollingInterval(USBD_HandleTypeDef *pdev);
/**
@@ -136,4 +158,3 @@ uint32_t USBD_HID_GetPollingInterval(USBD_HandleTypeDef *pdev);
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -4,6 +4,17 @@
* @author MCD Application Team
* @brief This file provides the HID core functions.
*
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
* @verbatim
*
* ===================================================================
@@ -25,17 +36,6 @@
* @endverbatim
*
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* BSPDependencies
@@ -91,12 +91,12 @@ static uint8_t USBD_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
static uint8_t USBD_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
static uint8_t USBD_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
static uint8_t USBD_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
#ifndef USE_USBD_COMPOSITE
static uint8_t *USBD_HID_GetFSCfgDesc(uint16_t *length);
static uint8_t *USBD_HID_GetHSCfgDesc(uint16_t *length);
static uint8_t *USBD_HID_GetOtherSpeedCfgDesc(uint16_t *length);
static uint8_t *USBD_HID_GetDeviceQualifierDesc(uint16_t *length);
#endif /* USE_USBD_COMPOSITE */
/**
* @}
*/
@@ -117,14 +117,22 @@ USBD_ClassTypeDef USBD_HID =
NULL, /* SOF */
NULL,
NULL,
#ifdef USE_USBD_COMPOSITE
NULL,
NULL,
NULL,
NULL,
#else
USBD_HID_GetHSCfgDesc,
USBD_HID_GetFSCfgDesc,
USBD_HID_GetOtherSpeedCfgDesc,
USBD_HID_GetDeviceQualifierDesc,
#endif /* USE_USBD_COMPOSITE */
};
#ifndef USE_USBD_COMPOSITE
/* USB HID device FS Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_HID_CfgFSDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END =
__ALIGN_BEGIN static uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END =
{
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
@@ -132,12 +140,13 @@ __ALIGN_BEGIN static uint8_t USBD_HID_CfgFSDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN
0x00,
0x01, /* bNumInterfaces: 1 interface */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
0x00, /* iConfiguration: Index of string descriptor
describing the configuration */
#if (USBD_SELF_POWERED == 1U)
0xE0, /* bmAttributes: Bus Powered according to user configuration */
#else
0xA0, /* bmAttributes: Bus Powered according to user configuration */
#endif
#endif /* USBD_SELF_POWERED */
USBD_MAX_POWER, /* MaxPower (mA) */
/************** Descriptor of Joystick Mouse interface ****************/
@@ -174,111 +183,7 @@ __ALIGN_BEGIN static uint8_t USBD_HID_CfgFSDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN
HID_FS_BINTERVAL, /* bInterval: Polling Interval */
/* 34 */
};
/* USB HID device HS Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_HID_CfgHSDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END =
{
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
USB_HID_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */
0x00,
0x01, /* bNumInterfaces: 1 interface */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
#if (USBD_SELF_POWERED == 1U)
0xE0, /* bmAttributes: Bus Powered according to user configuration */
#else
0xA0, /* bmAttributes: Bus Powered according to user configuration */
#endif
USBD_MAX_POWER, /* MaxPower (mA) */
/************** Descriptor of Joystick Mouse interface ****************/
/* 09 */
0x09, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints */
0x03, /* bInterfaceClass: HID */
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
0, /* iInterface: Index of string descriptor */
/******************** Descriptor of Joystick Mouse HID ********************/
/* 18 */
0x09, /* bLength: HID Descriptor size */
HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */
0x11, /* bcdHID: HID Class Spec release number */
0x01,
0x00, /* bCountryCode: Hardware target country */
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
0x22, /* bDescriptorType */
HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
0x00,
/******************** Descriptor of Mouse endpoint ********************/
/* 27 */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */
HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */
0x03, /* bmAttributes: Interrupt endpoint */
HID_EPIN_SIZE, /* wMaxPacketSize: 4 Bytes max */
0x00,
HID_HS_BINTERVAL, /* bInterval: Polling Interval */
/* 34 */
};
/* USB HID device Other Speed Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_HID_OtherSpeedCfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END =
{
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
USB_HID_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */
0x00,
0x01, /* bNumInterfaces: 1 interface */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
#if (USBD_SELF_POWERED == 1U)
0xE0, /* bmAttributes: Bus Powered according to user configuration */
#else
0xA0, /* bmAttributes: Bus Powered according to user configuration */
#endif
USBD_MAX_POWER, /* MaxPower (mA) */
/************** Descriptor of Joystick Mouse interface ****************/
/* 09 */
0x09, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints */
0x03, /* bInterfaceClass: HID */
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
0, /* iInterface: Index of string descriptor */
/******************** Descriptor of Joystick Mouse HID ********************/
/* 18 */
0x09, /* bLength: HID Descriptor size */
HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */
0x11, /* bcdHID: HID Class Spec release number */
0x01,
0x00, /* bCountryCode: Hardware target country */
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
0x22, /* bDescriptorType */
HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
0x00,
/******************** Descriptor of Mouse endpoint ********************/
/* 27 */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */
HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */
0x03, /* bmAttributes: Interrupt endpoint */
HID_EPIN_SIZE, /* wMaxPacketSize: 4 Bytes max */
0x00,
HID_FS_BINTERVAL, /* bInterval: Polling Interval */
/* 34 */
};
#endif /* USE_USBD_COMPOSITE */
/* USB HID device Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_HID_Desc[USB_HID_DESC_SIZ] __ALIGN_END =
@@ -295,6 +200,7 @@ __ALIGN_BEGIN static uint8_t USBD_HID_Desc[USB_HID_DESC_SIZ] __ALIGN_END =
0x00,
};
#ifndef USE_USBD_COMPOSITE
/* USB Standard Device Descriptor */
__ALIGN_BEGIN static uint8_t USBD_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
{
@@ -309,6 +215,7 @@ __ALIGN_BEGIN static uint8_t USBD_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_
0x01,
0x00,
};
#endif /* USE_USBD_COMPOSITE */
__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END =
{
@@ -352,6 +259,8 @@ __ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __
0xC0 /* End Collection */
};
static uint8_t HIDInEpAdd = HID_EPIN_ADDR;
/**
* @}
*/
@@ -377,26 +286,32 @@ static uint8_t USBD_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
if (hhid == NULL)
{
pdev->pClassData = NULL;
pdev->pClassDataCmsit[pdev->classId] = NULL;
return (uint8_t)USBD_EMEM;
}
pdev->pClassData = (void *)hhid;
pdev->pClassDataCmsit[pdev->classId] = (void *)hhid;
pdev->pClassData = pdev->pClassDataCmsit[pdev->classId];
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
HIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (pdev->dev_speed == USBD_SPEED_HIGH)
{
pdev->ep_in[HID_EPIN_ADDR & 0xFU].bInterval = HID_HS_BINTERVAL;
pdev->ep_in[HIDInEpAdd & 0xFU].bInterval = HID_HS_BINTERVAL;
}
else /* LOW and FULL-speed endpoints */
{
pdev->ep_in[HID_EPIN_ADDR & 0xFU].bInterval = HID_FS_BINTERVAL;
pdev->ep_in[HIDInEpAdd & 0xFU].bInterval = HID_FS_BINTERVAL;
}
/* Open EP IN */
(void)USBD_LL_OpenEP(pdev, HID_EPIN_ADDR, USBD_EP_TYPE_INTR, HID_EPIN_SIZE);
pdev->ep_in[HID_EPIN_ADDR & 0xFU].is_used = 1U;
(void)USBD_LL_OpenEP(pdev, HIDInEpAdd, USBD_EP_TYPE_INTR, HID_EPIN_SIZE);
pdev->ep_in[HIDInEpAdd & 0xFU].is_used = 1U;
hhid->state = HID_IDLE;
hhid->state = USBD_HID_IDLE;
return (uint8_t)USBD_OK;
}
@@ -412,16 +327,21 @@ static uint8_t USBD_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
UNUSED(cfgidx);
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
HIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
/* Close HID EPs */
(void)USBD_LL_CloseEP(pdev, HID_EPIN_ADDR);
pdev->ep_in[HID_EPIN_ADDR & 0xFU].is_used = 0U;
pdev->ep_in[HID_EPIN_ADDR & 0xFU].bInterval = 0U;
(void)USBD_LL_CloseEP(pdev, HIDInEpAdd);
pdev->ep_in[HIDInEpAdd & 0xFU].is_used = 0U;
pdev->ep_in[HIDInEpAdd & 0xFU].bInterval = 0U;
/* Free allocated memory */
if (pdev->pClassData != NULL)
if (pdev->pClassDataCmsit[pdev->classId] != NULL)
{
(void)USBD_free(pdev->pClassData);
pdev->pClassData = NULL;
(void)USBD_free(pdev->pClassDataCmsit[pdev->classId]);
pdev->pClassDataCmsit[pdev->classId] = NULL;
}
return (uint8_t)USBD_OK;
@@ -436,7 +356,7 @@ static uint8_t USBD_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
*/
static uint8_t USBD_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)pdev->pClassData;
USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
USBD_StatusTypeDef ret = USBD_OK;
uint16_t len;
uint8_t *pbuf;
@@ -452,19 +372,19 @@ static uint8_t USBD_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *re
case USB_REQ_TYPE_CLASS :
switch (req->bRequest)
{
case HID_REQ_SET_PROTOCOL:
case USBD_HID_REQ_SET_PROTOCOL:
hhid->Protocol = (uint8_t)(req->wValue);
break;
case HID_REQ_GET_PROTOCOL:
case USBD_HID_REQ_GET_PROTOCOL:
(void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->Protocol, 1U);
break;
case HID_REQ_SET_IDLE:
case USBD_HID_REQ_SET_IDLE:
hhid->IdleState = (uint8_t)(req->wValue >> 8);
break;
case HID_REQ_GET_IDLE:
case USBD_HID_REQ_GET_IDLE:
(void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->IdleState, 1U);
break;
@@ -552,28 +472,41 @@ static uint8_t USBD_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *re
return (uint8_t)ret;
}
/**
* @brief USBD_HID_SendReport
* Send HID Report
* @param pdev: device instance
* @param buff: pointer to report
* @param ClassId: The Class ID
* @retval status
*/
#ifdef USE_USBD_COMPOSITE
uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len, uint8_t ClassId)
{
USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)pdev->pClassDataCmsit[ClassId];
#else
uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len)
{
USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)pdev->pClassData;
USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
#endif /* USE_USBD_COMPOSITE */
if (hhid == NULL)
{
return (uint8_t)USBD_FAIL;
}
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
HIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, ClassId);
#endif /* USE_USBD_COMPOSITE */
if (pdev->dev_state == USBD_STATE_CONFIGURED)
{
if (hhid->state == HID_IDLE)
if (hhid->state == USBD_HID_IDLE)
{
hhid->state = HID_BUSY;
(void)USBD_LL_Transmit(pdev, HID_EPIN_ADDR, report, len);
hhid->state = USBD_HID_BUSY;
(void)USBD_LL_Transmit(pdev, HIDInEpAdd, report, len);
}
}
@@ -608,6 +541,7 @@ uint32_t USBD_HID_GetPollingInterval(USBD_HandleTypeDef *pdev)
return ((uint32_t)(polling_interval));
}
#ifndef USE_USBD_COMPOSITE
/**
* @brief USBD_HID_GetCfgFSDesc
* return FS configuration descriptor
@@ -617,9 +551,15 @@ uint32_t USBD_HID_GetPollingInterval(USBD_HandleTypeDef *pdev)
*/
static uint8_t *USBD_HID_GetFSCfgDesc(uint16_t *length)
{
*length = (uint16_t)sizeof(USBD_HID_CfgFSDesc);
USBD_EpDescTypeDef *pEpDesc = USBD_GetEpDesc(USBD_HID_CfgDesc, HID_EPIN_ADDR);
return USBD_HID_CfgFSDesc;
if (pEpDesc != NULL)
{
pEpDesc->bInterval = HID_FS_BINTERVAL;
}
*length = (uint16_t)sizeof(USBD_HID_CfgDesc);
return USBD_HID_CfgDesc;
}
/**
@@ -631,9 +571,15 @@ static uint8_t *USBD_HID_GetFSCfgDesc(uint16_t *length)
*/
static uint8_t *USBD_HID_GetHSCfgDesc(uint16_t *length)
{
*length = (uint16_t)sizeof(USBD_HID_CfgHSDesc);
USBD_EpDescTypeDef *pEpDesc = USBD_GetEpDesc(USBD_HID_CfgDesc, HID_EPIN_ADDR);
return USBD_HID_CfgHSDesc;
if (pEpDesc != NULL)
{
pEpDesc->bInterval = HID_HS_BINTERVAL;
}
*length = (uint16_t)sizeof(USBD_HID_CfgDesc);
return USBD_HID_CfgDesc;
}
/**
@@ -645,10 +591,17 @@ static uint8_t *USBD_HID_GetHSCfgDesc(uint16_t *length)
*/
static uint8_t *USBD_HID_GetOtherSpeedCfgDesc(uint16_t *length)
{
*length = (uint16_t)sizeof(USBD_HID_OtherSpeedCfgDesc);
USBD_EpDescTypeDef *pEpDesc = USBD_GetEpDesc(USBD_HID_CfgDesc, HID_EPIN_ADDR);
return USBD_HID_OtherSpeedCfgDesc;
if (pEpDesc != NULL)
{
pEpDesc->bInterval = HID_FS_BINTERVAL;
}
*length = (uint16_t)sizeof(USBD_HID_CfgDesc);
return USBD_HID_CfgDesc;
}
#endif /* USE_USBD_COMPOSITE */
/**
* @brief USBD_HID_DataIn
@@ -662,12 +615,12 @@ static uint8_t USBD_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
UNUSED(epnum);
/* Ensure that the FIFO is empty before a new transfer, this condition could
be caused by a new transfer before the end of the previous transfer */
((USBD_HID_HandleTypeDef *)pdev->pClassData)->state = HID_IDLE;
((USBD_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId])->state = USBD_HID_IDLE;
return (uint8_t)USBD_OK;
}
#ifndef USE_USBD_COMPOSITE
/**
* @brief DeviceQualifierDescriptor
* return Device Qualifier descriptor
@@ -680,7 +633,7 @@ static uint8_t *USBD_HID_GetDeviceQualifierDesc(uint16_t *length)
return USBD_HID_DeviceQualifierDesc;
}
#endif /* USE_USBD_COMPOSITE */
/**
* @}
*/
@@ -695,4 +648,3 @@ static uint8_t *USBD_HID_GetDeviceQualifierDesc(uint16_t *length)
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -55,9 +54,13 @@ extern "C" {
#define BOT_RESET 0xFF
#define USB_MSC_CONFIG_DESC_SIZ 32
#ifndef MSC_EPIN_ADDR
#define MSC_EPIN_ADDR 0x81U
#endif /* MSC_EPIN_ADDR */
#ifndef MSC_EPOUT_ADDR
#define MSC_EPOUT_ADDR 0x01U
#endif /* MSC_EPOUT_ADDR */
/**
* @}
@@ -101,8 +104,7 @@ typedef struct
uint32_t scsi_blk_addr;
uint32_t scsi_blk_len;
}
USBD_MSC_BOT_HandleTypeDef;
} USBD_MSC_BOT_HandleTypeDef;
/* Structure for MSC process */
extern USBD_ClassTypeDef USBD_MSC;
@@ -126,5 +128,3 @@ uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev,
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -87,8 +86,7 @@ typedef struct
uint8_t bCBLength;
uint8_t CB[16];
uint8_t ReservedForAlign;
}
USBD_MSC_BOT_CBWTypeDef;
} USBD_MSC_BOT_CBWTypeDef;
typedef struct
@@ -98,8 +96,7 @@ typedef struct
uint32_t dDataResidue;
uint8_t bStatus;
uint8_t ReservedForAlign[3];
}
USBD_MSC_BOT_CSWTypeDef;
} USBD_MSC_BOT_CSWTypeDef;
/**
* @}
@@ -146,5 +143,4 @@ void MSC_BOT_CplClrFeature(USBD_HandleTypeDef *pdev,
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -101,5 +100,3 @@ extern uint8_t MSC_Mode_Sense10_data[MODE_SENSE10_LEN];
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -83,7 +82,7 @@ extern "C" {
#define UNIT_ATTENTION 6U
#define DATA_PROTECT 7U
#define BLANK_CHECK 8U
#define VENDOR_SPECIFIC 9U
#define MSC_VENDOR_SPECIFIC 9U
#define COPY_ABORTED 10U
#define ABORTED_COMMAND 11U
#define VOLUME_OVERFLOW 13U
@@ -181,5 +180,3 @@ void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey,
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -94,4 +93,4 @@ extern USBD_StorageTypeDef USBD_MSC_Template_fops;
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -4,6 +4,17 @@
* @author MCD Application Team
* @brief This file provides all the MSC core functions.
*
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
* @verbatim
*
* ===================================================================
@@ -19,17 +30,6 @@
* @endverbatim
*
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* BSPDependencies
@@ -86,11 +86,12 @@ uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
uint8_t USBD_MSC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
uint8_t USBD_MSC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
#ifndef USE_USBD_COMPOSITE
uint8_t *USBD_MSC_GetHSCfgDesc(uint16_t *length);
uint8_t *USBD_MSC_GetFSCfgDesc(uint16_t *length);
uint8_t *USBD_MSC_GetOtherSpeedCfgDesc(uint16_t *length);
uint8_t *USBD_MSC_GetDeviceQualifierDescriptor(uint16_t *length);
#endif /* USE_USBD_COMPOSITE */
/**
* @}
*/
@@ -113,15 +114,24 @@ USBD_ClassTypeDef USBD_MSC =
NULL, /*SOF */
NULL,
NULL,
#ifdef USE_USBD_COMPOSITE
NULL,
NULL,
NULL,
NULL,
#else
USBD_MSC_GetHSCfgDesc,
USBD_MSC_GetFSCfgDesc,
USBD_MSC_GetOtherSpeedCfgDesc,
USBD_MSC_GetDeviceQualifierDescriptor,
#endif /* USE_USBD_COMPOSITE */
};
/* USB Mass storage device Configuration Descriptor */
#ifndef USE_USBD_COMPOSITE
/* USB Mass storage device Configuration Descriptor */
/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
__ALIGN_BEGIN static uint8_t USBD_MSC_CfgHSDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END =
__ALIGN_BEGIN static uint8_t USBD_MSC_CfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END =
{
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
@@ -135,54 +145,7 @@ __ALIGN_BEGIN static uint8_t USBD_MSC_CfgHSDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIG
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
USBD_MAX_POWER, /* MaxPower (mA) */
/******************** Mass Storage interface ********************/
0x09, /* bLength: Interface Descriptor size */
0x04, /* bDescriptorType: */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints */
0x08, /* bInterfaceClass: MSC Class */
0x06, /* bInterfaceSubClass : SCSI transparent */
0x50, /* nInterfaceProtocol */
0x05, /* iInterface */
/******************** Mass Storage Endpoints ********************/
0x07, /* Endpoint descriptor length = 7 */
0x05, /* Endpoint descriptor type */
MSC_EPIN_ADDR, /* Endpoint address (IN, address 1) */
0x02, /* Bulk endpoint type */
LOBYTE(MSC_MAX_HS_PACKET),
HIBYTE(MSC_MAX_HS_PACKET),
0x00, /* Polling interval in milliseconds */
0x07, /* Endpoint descriptor length = 7 */
0x05, /* Endpoint descriptor type */
MSC_EPOUT_ADDR, /* Endpoint address (OUT, address 1) */
0x02, /* Bulk endpoint type */
LOBYTE(MSC_MAX_HS_PACKET),
HIBYTE(MSC_MAX_HS_PACKET),
0x00 /* Polling interval in milliseconds */
};
/* USB Mass storage device Configuration Descriptor */
/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
__ALIGN_BEGIN static uint8_t USBD_MSC_CfgFSDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END =
{
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
USB_MSC_CONFIG_DESC_SIZ,
0x00,
0x01, /* bNumInterfaces: 1 interface */
0x01, /* bConfigurationValue */
0x04, /* iConfiguration */
#if (USBD_SELF_POWERED == 1U)
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
#endif /* USBD_SELF_POWERED */
USBD_MAX_POWER, /* MaxPower (mA) */
/******************** Mass Storage interface ********************/
@@ -213,51 +176,6 @@ __ALIGN_BEGIN static uint8_t USBD_MSC_CfgFSDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIG
0x00 /* Polling interval in milliseconds */
};
__ALIGN_BEGIN static uint8_t USBD_MSC_OtherSpeedCfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END =
{
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,
USB_MSC_CONFIG_DESC_SIZ,
0x00,
0x01, /* bNumInterfaces: 1 interface */
0x01, /* bConfigurationValue */
0x04, /* iConfiguration */
#if (USBD_SELF_POWERED == 1U)
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
USBD_MAX_POWER, /* MaxPower (mA) */
/******************** Mass Storage interface ********************/
0x09, /* bLength: Interface Descriptor size */
0x04, /* bDescriptorType */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints */
0x08, /* bInterfaceClass: MSC Class */
0x06, /* bInterfaceSubClass : SCSI transparent command set */
0x50, /* nInterfaceProtocol */
0x05, /* iInterface */
/******************** Mass Storage Endpoints ********************/
0x07, /* Endpoint descriptor length = 7 */
0x05, /* Endpoint descriptor type */
MSC_EPIN_ADDR, /* Endpoint address (IN, address 1) */
0x02, /* Bulk endpoint type */
0x40,
0x00,
0x00, /* Polling interval in milliseconds */
0x07, /* Endpoint descriptor length = 7 */
0x05, /* Endpoint descriptor type */
MSC_EPOUT_ADDR, /* Endpoint address (OUT, address 1) */
0x02, /* Bulk endpoint type */
0x40,
0x00,
0x00 /* Polling interval in milliseconds */
};
/* USB Standard Device Descriptor */
__ALIGN_BEGIN static uint8_t USBD_MSC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
{
@@ -272,6 +190,11 @@ __ALIGN_BEGIN static uint8_t USBD_MSC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_
0x01,
0x00,
};
#endif /* USE_USBD_COMPOSITE */
uint8_t MSCInEpAdd = MSC_EPIN_ADDR;
uint8_t MSCOutEpAdd = MSC_EPOUT_ADDR;
/**
* @}
*/
@@ -297,31 +220,38 @@ uint8_t USBD_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
if (hmsc == NULL)
{
pdev->pClassData = NULL;
pdev->pClassDataCmsit[pdev->classId] = NULL;
return (uint8_t)USBD_EMEM;
}
pdev->pClassData = (void *)hmsc;
pdev->pClassDataCmsit[pdev->classId] = (void *)hmsc;
pdev->pClassData = pdev->pClassDataCmsit[pdev->classId];
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
MSCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (pdev->dev_speed == USBD_SPEED_HIGH)
{
/* Open EP OUT */
(void)USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET);
pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 1U;
(void)USBD_LL_OpenEP(pdev, MSCOutEpAdd, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET);
pdev->ep_out[MSCOutEpAdd & 0xFU].is_used = 1U;
/* Open EP IN */
(void)USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET);
pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 1U;
(void)USBD_LL_OpenEP(pdev, MSCInEpAdd, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET);
pdev->ep_in[MSCInEpAdd & 0xFU].is_used = 1U;
}
else
{
/* Open EP OUT */
(void)USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET);
pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 1U;
(void)USBD_LL_OpenEP(pdev, MSCOutEpAdd, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET);
pdev->ep_out[MSCOutEpAdd & 0xFU].is_used = 1U;
/* Open EP IN */
(void)USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET);
pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 1U;
(void)USBD_LL_OpenEP(pdev, MSCInEpAdd, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET);
pdev->ep_in[MSCInEpAdd & 0xFU].is_used = 1U;
}
/* Init the BOT layer */
@@ -341,21 +271,28 @@ uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
UNUSED(cfgidx);
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
MSCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
/* Close MSC EPs */
(void)USBD_LL_CloseEP(pdev, MSC_EPOUT_ADDR);
pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 0U;
(void)USBD_LL_CloseEP(pdev, MSCOutEpAdd);
pdev->ep_out[MSCOutEpAdd & 0xFU].is_used = 0U;
/* Close EP IN */
(void)USBD_LL_CloseEP(pdev, MSC_EPIN_ADDR);
pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 0U;
(void)USBD_LL_CloseEP(pdev, MSCInEpAdd);
pdev->ep_in[MSCInEpAdd & 0xFU].is_used = 0U;
/* Free MSC Class Resources */
if (pdev->pClassData != NULL)
if (pdev->pClassDataCmsit[pdev->classId] != NULL)
{
/* De-Init the BOT layer */
MSC_BOT_DeInit(pdev);
(void)USBD_free(pdev->pClassData);
(void)USBD_free(pdev->pClassDataCmsit[pdev->classId]);
pdev->pClassDataCmsit[pdev->classId] = NULL;
pdev->pClassData = NULL;
}
@@ -370,10 +307,16 @@ uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
*/
uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
USBD_StatusTypeDef ret = USBD_OK;
uint16_t status_info = 0U;
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
MSCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (hmsc == NULL)
{
return (uint8_t)USBD_FAIL;
@@ -389,7 +332,7 @@ uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
if ((req->wValue == 0U) && (req->wLength == 1U) &&
((req->bmRequest & 0x80U) == 0x80U))
{
hmsc->max_lun = (uint32_t)((USBD_StorageTypeDef *)pdev->pUserData)->GetMaxLun();
hmsc->max_lun = (uint32_t)((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetMaxLun();
(void)USBD_CtlSendData(pdev, (uint8_t *)&hmsc->max_lun, 1U);
}
else
@@ -515,7 +458,7 @@ uint8_t USBD_MSC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
return (uint8_t)USBD_OK;
}
#ifndef USE_USBD_COMPOSITE
/**
* @brief USBD_MSC_GetHSCfgDesc
* return configuration descriptor
@@ -524,9 +467,21 @@ uint8_t USBD_MSC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
*/
uint8_t *USBD_MSC_GetHSCfgDesc(uint16_t *length)
{
*length = (uint16_t)sizeof(USBD_MSC_CfgHSDesc);
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_MSC_CfgDesc, MSC_EPIN_ADDR);
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_MSC_CfgDesc, MSC_EPOUT_ADDR);
return USBD_MSC_CfgHSDesc;
if (pEpInDesc != NULL)
{
pEpInDesc->wMaxPacketSize = MSC_MAX_HS_PACKET;
}
if (pEpOutDesc != NULL)
{
pEpOutDesc->wMaxPacketSize = MSC_MAX_HS_PACKET;
}
*length = (uint16_t)sizeof(USBD_MSC_CfgDesc);
return USBD_MSC_CfgDesc;
}
/**
@@ -537,9 +492,21 @@ uint8_t *USBD_MSC_GetHSCfgDesc(uint16_t *length)
*/
uint8_t *USBD_MSC_GetFSCfgDesc(uint16_t *length)
{
*length = (uint16_t)sizeof(USBD_MSC_CfgFSDesc);
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_MSC_CfgDesc, MSC_EPIN_ADDR);
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_MSC_CfgDesc, MSC_EPOUT_ADDR);
return USBD_MSC_CfgFSDesc;
if (pEpInDesc != NULL)
{
pEpInDesc->wMaxPacketSize = MSC_MAX_FS_PACKET;
}
if (pEpOutDesc != NULL)
{
pEpOutDesc->wMaxPacketSize = MSC_MAX_FS_PACKET;
}
*length = (uint16_t)sizeof(USBD_MSC_CfgDesc);
return USBD_MSC_CfgDesc;
}
/**
@@ -550,9 +517,21 @@ uint8_t *USBD_MSC_GetFSCfgDesc(uint16_t *length)
*/
uint8_t *USBD_MSC_GetOtherSpeedCfgDesc(uint16_t *length)
{
*length = (uint16_t)sizeof(USBD_MSC_OtherSpeedCfgDesc);
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_MSC_CfgDesc, MSC_EPIN_ADDR);
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_MSC_CfgDesc, MSC_EPOUT_ADDR);
return USBD_MSC_OtherSpeedCfgDesc;
if (pEpInDesc != NULL)
{
pEpInDesc->wMaxPacketSize = MSC_MAX_FS_PACKET;
}
if (pEpOutDesc != NULL)
{
pEpOutDesc->wMaxPacketSize = MSC_MAX_FS_PACKET;
}
*length = (uint16_t)sizeof(USBD_MSC_CfgDesc);
return USBD_MSC_CfgDesc;
}
/**
* @brief DeviceQualifierDescriptor
@@ -566,7 +545,7 @@ uint8_t *USBD_MSC_GetDeviceQualifierDescriptor(uint16_t *length)
return USBD_MSC_DeviceQualifierDesc;
}
#endif /* USE_USBD_COMPOSITE */
/**
* @brief USBD_MSC_RegisterStorage
* @param fops: storage callback
@@ -579,7 +558,7 @@ uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev, USBD_StorageTypeDef *
return (uint8_t)USBD_FAIL;
}
pdev->pUserData = fops;
pdev->pUserData[pdev->classId] = fops;
return (uint8_t)USBD_OK;
}
@@ -598,4 +577,3 @@ uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev, USBD_StorageTypeDef *
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -67,7 +66,8 @@ EndBSPDependencies */
/** @defgroup MSC_BOT_Private_Variables
* @{
*/
extern uint8_t MSCInEpAdd;
extern uint8_t MSCOutEpAdd;
/**
* @}
*/
@@ -97,7 +97,13 @@ static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev);
*/
void MSC_BOT_Init(USBD_HandleTypeDef *pdev)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
MSCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (hmsc == NULL)
{
@@ -111,13 +117,13 @@ void MSC_BOT_Init(USBD_HandleTypeDef *pdev)
hmsc->scsi_sense_head = 0U;
hmsc->scsi_medium_state = SCSI_MEDIUM_UNLOCKED;
((USBD_StorageTypeDef *)pdev->pUserData)->Init(0U);
((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->Init(0U);
(void)USBD_LL_FlushEP(pdev, MSC_EPOUT_ADDR);
(void)USBD_LL_FlushEP(pdev, MSC_EPIN_ADDR);
(void)USBD_LL_FlushEP(pdev, MSCOutEpAdd);
(void)USBD_LL_FlushEP(pdev, MSCInEpAdd);
/* Prepare EP to Receive First BOT Cmd */
(void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)&hmsc->cbw,
(void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, (uint8_t *)&hmsc->cbw,
USBD_BOT_CBW_LENGTH);
}
@@ -129,7 +135,13 @@ void MSC_BOT_Init(USBD_HandleTypeDef *pdev)
*/
void MSC_BOT_Reset(USBD_HandleTypeDef *pdev)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
MSCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (hmsc == NULL)
{
@@ -139,11 +151,11 @@ void MSC_BOT_Reset(USBD_HandleTypeDef *pdev)
hmsc->bot_state = USBD_BOT_IDLE;
hmsc->bot_status = USBD_BOT_STATUS_RECOVERY;
(void)USBD_LL_ClearStallEP(pdev, MSC_EPIN_ADDR);
(void)USBD_LL_ClearStallEP(pdev, MSC_EPOUT_ADDR);
(void)USBD_LL_ClearStallEP(pdev, MSCInEpAdd);
(void)USBD_LL_ClearStallEP(pdev, MSCOutEpAdd);
/* Prepare EP to Receive First BOT Cmd */
(void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)&hmsc->cbw,
(void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, (uint8_t *)&hmsc->cbw,
USBD_BOT_CBW_LENGTH);
}
@@ -155,7 +167,7 @@ void MSC_BOT_Reset(USBD_HandleTypeDef *pdev)
*/
void MSC_BOT_DeInit(USBD_HandleTypeDef *pdev)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hmsc != NULL)
{
@@ -174,7 +186,7 @@ void MSC_BOT_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
UNUSED(epnum);
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hmsc == NULL)
{
@@ -210,7 +222,7 @@ void MSC_BOT_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
UNUSED(epnum);
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hmsc == NULL)
{
@@ -243,7 +255,13 @@ void MSC_BOT_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
*/
static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef *pdev)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
MSCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (hmsc == NULL)
{
@@ -253,7 +271,7 @@ static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef *pdev)
hmsc->csw.dTag = hmsc->cbw.dTag;
hmsc->csw.dDataResidue = hmsc->cbw.dDataLength;
if ((USBD_LL_GetRxDataSize(pdev, MSC_EPOUT_ADDR) != USBD_BOT_CBW_LENGTH) ||
if ((USBD_LL_GetRxDataSize(pdev, MSCOutEpAdd) != USBD_BOT_CBW_LENGTH) ||
(hmsc->cbw.dSignature != USBD_BOT_CBW_SIGNATURE) ||
(hmsc->cbw.bLUN > 1U) || (hmsc->cbw.bCBLength < 1U) ||
(hmsc->cbw.bCBLength > 16U))
@@ -311,20 +329,28 @@ static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef *pdev)
*/
static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t len)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint32_t length = MIN(hmsc->cbw.dDataLength, len);
uint32_t length;
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
MSCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (hmsc == NULL)
{
return;
}
length = MIN(hmsc->cbw.dDataLength, len);
hmsc->csw.dDataResidue -= len;
hmsc->csw.bStatus = USBD_CSW_CMD_PASSED;
hmsc->bot_state = USBD_BOT_SEND_DATA;
(void)USBD_LL_Transmit(pdev, MSC_EPIN_ADDR, pbuf, length);
(void)USBD_LL_Transmit(pdev, MSCInEpAdd, pbuf, length);
}
/**
@@ -336,7 +362,13 @@ static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t
*/
void MSC_BOT_SendCSW(USBD_HandleTypeDef *pdev, uint8_t CSW_Status)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
MSCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (hmsc == NULL)
{
@@ -347,11 +379,11 @@ void MSC_BOT_SendCSW(USBD_HandleTypeDef *pdev, uint8_t CSW_Status)
hmsc->csw.bStatus = CSW_Status;
hmsc->bot_state = USBD_BOT_IDLE;
(void)USBD_LL_Transmit(pdev, MSC_EPIN_ADDR, (uint8_t *)&hmsc->csw,
(void)USBD_LL_Transmit(pdev, MSCInEpAdd, (uint8_t *)&hmsc->csw,
USBD_BOT_CSW_LENGTH);
/* Prepare EP to Receive next Cmd */
(void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)&hmsc->cbw,
(void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, (uint8_t *)&hmsc->cbw,
USBD_BOT_CBW_LENGTH);
}
@@ -364,7 +396,13 @@ void MSC_BOT_SendCSW(USBD_HandleTypeDef *pdev, uint8_t CSW_Status)
static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
MSCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (hmsc == NULL)
{
@@ -375,15 +413,15 @@ static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev)
(hmsc->cbw.dDataLength != 0U) &&
(hmsc->bot_status == USBD_BOT_STATUS_NORMAL))
{
(void)USBD_LL_StallEP(pdev, MSC_EPOUT_ADDR);
(void)USBD_LL_StallEP(pdev, MSCOutEpAdd);
}
(void)USBD_LL_StallEP(pdev, MSC_EPIN_ADDR);
(void)USBD_LL_StallEP(pdev, MSCInEpAdd);
if (hmsc->bot_status == USBD_BOT_STATUS_ERROR)
{
(void)USBD_LL_StallEP(pdev, MSC_EPIN_ADDR);
(void)USBD_LL_StallEP(pdev, MSC_EPOUT_ADDR);
(void)USBD_LL_StallEP(pdev, MSCInEpAdd);
(void)USBD_LL_StallEP(pdev, MSCOutEpAdd);
}
}
@@ -397,7 +435,13 @@ static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev)
void MSC_BOT_CplClrFeature(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
MSCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (hmsc == NULL)
{
@@ -406,8 +450,8 @@ void MSC_BOT_CplClrFeature(USBD_HandleTypeDef *pdev, uint8_t epnum)
if (hmsc->bot_status == USBD_BOT_STATUS_ERROR) /* Bad CBW Signature */
{
(void)USBD_LL_StallEP(pdev, MSC_EPIN_ADDR);
(void)USBD_LL_StallEP(pdev, MSC_EPOUT_ADDR);
(void)USBD_LL_StallEP(pdev, MSCInEpAdd);
(void)USBD_LL_StallEP(pdev, MSCOutEpAdd);
}
else if (((epnum & 0x80U) == 0x80U) && (hmsc->bot_status != USBD_BOT_STATUS_RECOVERY))
{
@@ -432,4 +476,3 @@ void MSC_BOT_CplClrFeature(USBD_HandleTypeDef *pdev, uint8_t epnum)
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -180,4 +179,3 @@ uint8_t MSC_Mode_Sense10_data[MODE_SENSE10_LEN] =
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -68,7 +67,8 @@ EndBSPDependencies */
/** @defgroup MSC_SCSI_Private_Variables
* @{
*/
extern uint8_t MSCInEpAdd;
extern uint8_t MSCOutEpAdd;
/**
* @}
*/
@@ -121,7 +121,7 @@ static int8_t SCSI_UpdateBotData(USBD_MSC_BOT_HandleTypeDef *hmsc,
int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd)
{
int8_t ret;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hmsc == NULL)
{
@@ -211,7 +211,7 @@ int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd)
static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
UNUSED(params);
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hmsc == NULL)
{
@@ -233,7 +233,7 @@ static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
return -1;
}
if (((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) != 0)
if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsReady(lun) != 0)
{
SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
hmsc->bot_state = USBD_BOT_NO_DATA;
@@ -257,7 +257,7 @@ static int8_t SCSI_Inquiry(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param
{
uint8_t *pPage;
uint16_t len;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hmsc == NULL)
{
@@ -290,7 +290,9 @@ static int8_t SCSI_Inquiry(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param
}
else
{
pPage = (uint8_t *) &((USBD_StorageTypeDef *)pdev->pUserData)->pInquiry[lun * STANDARD_INQUIRY_DATA_LEN];
pPage = (uint8_t *) & ((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId]) \
->pInquiry[lun * STANDARD_INQUIRY_DATA_LEN];
len = (uint16_t)pPage[4] + 5U;
if (params[4] <= len)
@@ -316,14 +318,15 @@ static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
{
UNUSED(params);
int8_t ret;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hmsc == NULL)
{
return -1;
}
ret = ((USBD_StorageTypeDef *)pdev->pUserData)->GetCapacity(lun, &hmsc->scsi_blk_nbr, &hmsc->scsi_blk_size);
ret = ((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetCapacity(lun, &hmsc->scsi_blk_nbr,
&hmsc->scsi_blk_size);
if ((ret != 0) || (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED))
{
@@ -358,16 +361,17 @@ static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
UNUSED(params);
uint8_t idx;
uint32_t idx;
int8_t ret;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hmsc == NULL)
{
return -1;
}
ret = ((USBD_StorageTypeDef *)pdev->pUserData)->GetCapacity(lun, &hmsc->scsi_blk_nbr, &hmsc->scsi_blk_size);
ret = ((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetCapacity(lun, &hmsc->scsi_blk_nbr,
&hmsc->scsi_blk_size);
if ((ret != 0) || (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED))
{
@@ -418,14 +422,14 @@ static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uin
uint32_t blk_nbr;
uint16_t i;
int8_t ret;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hmsc == NULL)
{
return -1;
}
ret = ((USBD_StorageTypeDef *)pdev->pUserData)->GetCapacity(lun, &blk_nbr, &blk_size);
ret = ((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetCapacity(lun, &blk_nbr, &blk_size);
if ((ret != 0) || (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED))
{
@@ -465,7 +469,7 @@ static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uin
static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
UNUSED(lun);
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint16_t len = MODE_SENSE6_LEN;
if (hmsc == NULL)
@@ -494,7 +498,7 @@ static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *pa
static int8_t SCSI_ModeSense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
UNUSED(lun);
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint16_t len = MODE_SENSE10_LEN;
if (hmsc == NULL)
@@ -524,7 +528,7 @@ static int8_t SCSI_RequestSense(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *
{
UNUSED(lun);
uint8_t i;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hmsc == NULL)
{
@@ -581,7 +585,7 @@ static int8_t SCSI_RequestSense(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *
void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey, uint8_t ASC)
{
UNUSED(lun);
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hmsc == NULL)
{
@@ -610,7 +614,7 @@ void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey, uint8_t
static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
UNUSED(lun);
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hmsc == NULL)
{
@@ -656,7 +660,7 @@ static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
static int8_t SCSI_AllowPreventRemovable(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
UNUSED(lun);
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hmsc == NULL)
{
@@ -687,7 +691,7 @@ static int8_t SCSI_AllowPreventRemovable(USBD_HandleTypeDef *pdev, uint8_t lun,
*/
static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hmsc == NULL)
{
@@ -710,7 +714,7 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params
return -1;
}
if (((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) != 0)
if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsReady(lun) != 0)
{
SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
return -1;
@@ -753,7 +757,7 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params
*/
static int8_t SCSI_Read12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hmsc == NULL)
{
@@ -775,7 +779,7 @@ static int8_t SCSI_Read12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params
return -1;
}
if (((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) != 0)
if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsReady(lun) != 0)
{
SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
return -1;
@@ -821,7 +825,7 @@ static int8_t SCSI_Read12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params
*/
static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint32_t len;
if (hmsc == NULL)
@@ -829,6 +833,11 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param
return -1;
}
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */
{
if (hmsc->cbw.dDataLength == 0U)
@@ -845,14 +854,14 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param
}
/* Check whether Media is ready */
if (((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) != 0)
if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsReady(lun) != 0)
{
SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
return -1;
}
/* Check If media is write-protected */
if (((USBD_StorageTypeDef *)pdev->pUserData)->IsWriteProtected(lun) != 0)
if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsWriteProtected(lun) != 0)
{
SCSI_SenseCode(pdev, lun, NOT_READY, WRITE_PROTECTED);
return -1;
@@ -886,7 +895,7 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param
/* Prepare EP to receive first data packet */
hmsc->bot_state = USBD_BOT_DATA_OUT;
(void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, hmsc->bot_data, len);
(void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, hmsc->bot_data, len);
}
else /* Write Process ongoing */
{
@@ -906,13 +915,17 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param
*/
static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint32_t len;
if (hmsc == NULL)
{
return -1;
}
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */
{
@@ -930,7 +943,7 @@ static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param
}
/* Check whether Media is ready */
if (((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) != 0)
if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsReady(lun) != 0)
{
SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
hmsc->bot_state = USBD_BOT_NO_DATA;
@@ -938,7 +951,7 @@ static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param
}
/* Check If media is write-protected */
if (((USBD_StorageTypeDef *)pdev->pUserData)->IsWriteProtected(lun) != 0)
if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsWriteProtected(lun) != 0)
{
SCSI_SenseCode(pdev, lun, NOT_READY, WRITE_PROTECTED);
hmsc->bot_state = USBD_BOT_NO_DATA;
@@ -975,7 +988,7 @@ static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param
/* Prepare EP to receive first data packet */
hmsc->bot_state = USBD_BOT_DATA_OUT;
(void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, hmsc->bot_data, len);
(void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, hmsc->bot_data, len);
}
else /* Write Process ongoing */
{
@@ -995,7 +1008,7 @@ static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param
*/
static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hmsc == NULL)
{
@@ -1029,7 +1042,7 @@ static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *para
static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun,
uint32_t blk_offset, uint32_t blk_nbr)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hmsc == NULL)
{
@@ -1053,17 +1066,24 @@ static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun,
*/
static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
uint32_t len = hmsc->scsi_blk_len * hmsc->scsi_blk_size;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint32_t len;
if (hmsc == NULL)
{
return -1;
}
len = hmsc->scsi_blk_len * hmsc->scsi_blk_size;
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
MSCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
len = MIN(len, MSC_MEDIA_PACKET);
if (((USBD_StorageTypeDef *)pdev->pUserData)->Read(lun, hmsc->bot_data,
if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->Read(lun, hmsc->bot_data,
hmsc->scsi_blk_addr,
(len / hmsc->scsi_blk_size)) < 0)
{
@@ -1071,7 +1091,7 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun)
return -1;
}
(void)USBD_LL_Transmit(pdev, MSC_EPIN_ADDR, hmsc->bot_data, len);
(void)USBD_LL_Transmit(pdev, MSCInEpAdd, hmsc->bot_data, len);
hmsc->scsi_blk_addr += (len / hmsc->scsi_blk_size);
hmsc->scsi_blk_len -= (len / hmsc->scsi_blk_size);
@@ -1095,17 +1115,24 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun)
*/
static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;
uint32_t len = hmsc->scsi_blk_len * hmsc->scsi_blk_size;
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint32_t len;
if (hmsc == NULL)
{
return -1;
}
len = hmsc->scsi_blk_len * hmsc->scsi_blk_size;
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
len = MIN(len, MSC_MEDIA_PACKET);
if (((USBD_StorageTypeDef *)pdev->pUserData)->Write(lun, hmsc->bot_data,
if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->Write(lun, hmsc->bot_data,
hmsc->scsi_blk_addr,
(len / hmsc->scsi_blk_size)) < 0)
{
@@ -1128,7 +1155,7 @@ static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun)
len = MIN((hmsc->scsi_blk_len * hmsc->scsi_blk_size), MSC_MEDIA_PACKET);
/* Prepare EP to Receive next packet */
(void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, hmsc->bot_data, len);
(void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, hmsc->bot_data, len);
}
return 0;
@@ -1177,4 +1204,3 @@ static int8_t SCSI_UpdateBotData(USBD_MSC_BOT_HandleTypeDef *hmsc,
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -87,91 +86,106 @@ USBD_StorageTypeDef USBD_MSC_Template_fops =
STORAGE_Inquirydata,
};
/*******************************************************************************
* Function Name : Read_Memory
* Description : Handle the Read operation from the microSD card.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
/**
* @brief Initializes the storage unit (medium)
* @param lun: Logical unit number
* @retval Status (0 : OK / -1 : Error)
*/
int8_t STORAGE_Init(uint8_t lun)
{
UNUSED(lun);
return (0);
}
/*******************************************************************************
* Function Name : Read_Memory
* Description : Handle the Read operation from the STORAGE card.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
/**
* @brief Returns the medium capacity.
* @param lun: Logical unit number
* @param block_num: Number of total block number
* @param block_size: Block size
* @retval Status (0: OK / -1: Error)
*/
int8_t STORAGE_GetCapacity(uint8_t lun, uint32_t *block_num, uint16_t *block_size)
{
UNUSED(lun);
*block_num = STORAGE_BLK_NBR;
*block_size = STORAGE_BLK_SIZ;
return (0);
}
/*******************************************************************************
* Function Name : Read_Memory
* Description : Handle the Read operation from the STORAGE card.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
/**
* @brief Checks whether the medium is ready.
* @param lun: Logical unit number
* @retval Status (0: OK / -1: Error)
*/
int8_t STORAGE_IsReady(uint8_t lun)
{
UNUSED(lun);
return (0);
}
/*******************************************************************************
* Function Name : Read_Memory
* Description : Handle the Read operation from the STORAGE card.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
/**
* @brief Checks whether the medium is write protected.
* @param lun: Logical unit number
* @retval Status (0: write enabled / -1: otherwise)
*/
int8_t STORAGE_IsWriteProtected(uint8_t lun)
{
UNUSED(lun);
return 0;
}
/*******************************************************************************
* Function Name : Read_Memory
* Description : Handle the Read operation from the STORAGE card.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
/**
* @brief Reads data from the medium.
* @param lun: Logical unit number
* @param buf: data buffer
* @param blk_addr: Logical block address
* @param blk_len: Blocks number
* @retval Status (0: OK / -1: Error)
*/
int8_t STORAGE_Read(uint8_t lun, uint8_t *buf,
uint32_t blk_addr, uint16_t blk_len)
{
UNUSED(lun);
UNUSED(buf);
UNUSED(blk_addr);
UNUSED(blk_len);
return 0;
}
/*******************************************************************************
* Function Name : Write_Memory
* Description : Handle the Write operation to the STORAGE card.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
/**
* @brief Writes data into the medium.
* @param lun: Logical unit number
* @param buf: data buffer
* @param blk_addr: Logical block address
* @param blk_len: Blocks number
* @retval Status (0 : OK / -1 : Error)
*/
int8_t STORAGE_Write(uint8_t lun, uint8_t *buf,
uint32_t blk_addr, uint16_t blk_len)
{
UNUSED(lun);
UNUSED(buf);
UNUSED(blk_addr);
UNUSED(blk_len);
return (0);
}
/*******************************************************************************
* Function Name : Write_Memory
* Description : Handle the Write operation to the STORAGE card.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
/**
* @brief Returns the Max Supported LUNs.
* @param None
* @retval Lun(s) number
*/
int8_t STORAGE_GetMaxLun(void)
{
return (STORAGE_LUN_NBR - 1);
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

358
Class/MTP/Inc/usbd_mtp.h Normal file
View File

@@ -0,0 +1,358 @@
/**
******************************************************************************
* @file usbd_mtp.h
* @author MCD Application Team
* @brief header file for the usbd_mtp.c file.
******************************************************************************
* @attention
*
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_MTP_H
#define __USB_MTP_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbd_ioreq.h"
#include "usbd_ctlreq.h"
/** @addtogroup STM32_USB_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_MTP
* @brief This file is the header file for usbd_mtp.c
* @{
*/
/** @defgroup USBD_MTP_Exported_Defines
* @{
*/
#ifndef MTP_IN_EP
#define MTP_IN_EP 0x81U /* EP1 for data IN */
#endif /* MTP_IN_EP */
#ifndef MTP_OUT_EP
#define MTP_OUT_EP 0x01U /* EP1 for data OUT */
#endif /* MTP_OUT_EP */
#ifndef MTP_CMD_EP
#define MTP_CMD_EP 0x82U /* EP2 for MTP commands */
#endif /* MTP_CMD_EP */
#ifndef MTP_CMD_ITF_NBR
#define MTP_CMD_ITF_NBR 0x00U /* Command Interface Number 0 */
#endif /* MTP_CMD_ITF_NBR */
#ifndef MTP_COM_ITF_NBR
#define MTP_COM_ITF_NBR 0x01U /* Communication Interface Number 0 */
#endif /* MTP_CMD_ITF_NBR */
#ifndef MTP_HS_BINTERVAL
#define MTP_HS_BINTERVAL 0x10U
#endif /* MTP_HS_BINTERVAL */
#ifndef MTP_FS_BINTERVAL
#define MTP_FS_BINTERVAL 0x10U
#endif /* MTP_FS_BINTERVAL */
#define MTP_DATA_MAX_HS_PACKET_SIZE 512U
#define MTP_DATA_MAX_FS_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */
#define MTP_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */
#define MTP_MEDIA_PACKET 512U
#define MTP_CONT_HEADER_SIZE 12U
#define MTP_CONFIG_DESC_SIZ 39U
#define MTP_INTERFACE_DESC_SIZE 0x09U
#define USB_MTP_INTRERFACE_CLASS 0x06U
#define USB_MTP_INTRERFACE_SUB_CLASS 0x01U
#define USB_MTP_INTRERFACE_PROTOCOL 0x01U
#define MTP_ENDPOINT_DESC_SIZE 0x07U
/*---------------------------------------------------------------------*/
/* MTP definitions */
/*---------------------------------------------------------------------*/
/* MTP class requests */
#define MTP_REQ_CANCEL 0x64U
#define MTP_REQ_GET_EXT_EVENT_DATA 0x65U
#define MTP_REQ_RESET 0x66U
#define MTP_REQ_GET_DEVICE_STATUS 0x67U
/* Max info items size */
#define MTP_SUPPORTED_OPERATIONS_NBR 100U
#define MTP_SUPPORTED_EVENTS_NBR 100U
#define MTP_SUPPORTED_PROPRIETIES_NBR 100U
#define MTP_CAPTURE_FORMATS_NBR 100U
#define MTP_IMAGE_FORMATS_NBR 100U
#define MTP_MAX_STR_SIZE 255U
/* MTP response code */
#define MTP_RESPONSE_OK 0x2001U
#define MTP_RESPONSE_GENERAL_ERROR 0x2002U
#define MTP_RESPONSE_PARAMETER_NOT_SUPPORTED 0x2006U
#define MTP_RESPONSE_INCOMPLETE_TRANSFER 0x2007U
#define MTP_RESPONSE_INVALID_STORAGE_ID 0x2008U
#define MTP_RESPONSE_INVALID_OBJECT_HANDLE 0x2009U
#define MTP_RESPONSE_DEVICEPROP_NOT_SUPPORTED 0x200AU
#define MTP_RESPONSE_STORE_FULL 0x200CU
#define MTP_RESPONSE_ACCESS_DENIED 0x200FU
#define MTP_RESPONSE_STORE_NOT_AVAILABLE 0x2013U
#define MTP_RESPONSE_SPECIFICATION_BY_FORMAT_NOT_SUPPORTED 0x2014U
#define MTP_RESPONSE_NO_VALID_OBJECT_INFO 0x2015U
#define MTP_RESPONSE_DEVICE_BUSY 0x2019U
#define MTP_RESPONSE_INVALID_PARENT_OBJECT 0x201AU
#define MTP_RESPONSE_INVALID_PARAMETER 0x201DU
#define MTP_RESPONSE_SESSION_ALREADY_OPEN 0x201EU
#define MTP_RESPONSE_TRANSACTION_CANCELLED 0x201FU
#define MTP_RESPONSE_INVALID_OBJECT_PROP_CODE 0xA801U
#define MTP_RESPONSE_SPECIFICATION_BY_GROUP_UNSUPPORTED 0xA807U
#define MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED 0xA80AU
/*
* MTP Class specification Revision 1.1
* Appendix A. Object Formats
*/
/* MTP Object format codes */
#define MTP_OBJ_FORMAT_UNDEFINED 0x3000U
#define MTP_OBJ_FORMAT_ASSOCIATION 0x3001U
#define MTP_OBJ_FORMAT_SCRIPT 0x3002U
#define MTP_OBJ_FORMAT_EXECUTABLE 0x3003U
#define MTP_OBJ_FORMAT_TEXT 0x3004U
#define MTP_OBJ_FORMAT_HTML 0x3005U
#define MTP_OBJ_FORMAT_DPOF 0x3006U
#define MTP_OBJ_FORMAT_AIFF 0x3007U
#define MTP_OBJ_FORMAT_WAV 0x3008U
#define MTP_OBJ_FORMAT_MP3 0x3009U
#define MTP_OBJ_FORMAT_AVI 0x300AU
#define MTP_OBJ_FORMAT_MPEG 0x300BU
#define MTP_OBJ_FORMAT_ASF 0x300CU
#define MTP_OBJ_FORMAT_DEFINED 0x3800U
#define MTP_OBJ_FORMAT_EXIF_JPEG 0x3801U
#define MTP_OBJ_FORMAT_TIFF_EP 0x3802U
#define MTP_OBJ_FORMAT_FLASHPIX 0x3803U
#define MTP_OBJ_FORMAT_BMP 0x3804U
#define MTP_OBJ_FORMAT_CIFF 0x3805U
#define MTP_OBJ_FORMAT_UNDEFINED_RESERVED0 0x3806U
#define MTP_OBJ_FORMAT_GIF 0x3807U
#define MTP_OBJ_FORMAT_JFIF 0x3808U
#define MTP_OBJ_FORMAT_CD 0x3809U
#define MTP_OBJ_FORMAT_PICT 0x380AU
#define MTP_OBJ_FORMAT_PNG 0x380BU
#define MTP_OBJ_FORMAT_UNDEFINED_RESERVED1 0x380CU
#define MTP_OBJ_FORMAT_TIFF 0x380DU
#define MTP_OBJ_FORMAT_TIFF_IT 0x380EU
#define MTP_OBJ_FORMAT_JP2 0x380FU
#define MTP_OBJ_FORMAT_JPX 0x3810U
#define MTP_OBJ_FORMAT_UNDEFINED_FIRMWARE 0xB802U
#define MTP_OBJ_FORMAT_WINDOWS_IMAGE_FORMAT 0xB881U
#define MTP_OBJ_FORMAT_UNDEFINED_AUDIO 0xB900U
#define MTP_OBJ_FORMAT_WMA 0xB901U
#define MTP_OBJ_FORMAT_OGG 0xB902U
#define MTP_OBJ_FORMAT_AAC 0xB903U
#define MTP_OBJ_FORMAT_AUDIBLE 0xB904U
#define MTP_OBJ_FORMAT_FLAC 0xB906U
#define MTP_OBJ_FORMAT_UNDEFINED_VIDEO 0xB980U
#define MTP_OBJ_FORMAT_WMV 0xB981U
#define MTP_OBJ_FORMAT_MP4_CONTAINER 0xB982U
#define MTP_OBJ_FORMAT_MP2 0xB983U
#define MTP_OBJ_FORMAT_3GP_CONTAINER 0xB984U
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_TypesDefinitions
* @{
*/
/**
* @}
*/
/* MTP Session state */
typedef enum
{
MTP_SESSION_NOT_OPENED = 0x00,
MTP_SESSION_OPENED = 0x01,
} MTP_SessionStateTypeDef;
/* MTP response phases */
typedef enum
{
MTP_PHASE_IDLE = 0x00,
MTP_RESPONSE_PHASE = 0x01,
MTP_READ_DATA = 0x02,
MTP_RECEIVE_DATA = 0x03,
} MTP_ResponsePhaseTypeDef;
typedef struct
{
uint32_t temp_length;
uint32_t prv_len;
uint32_t totallen;
uint32_t rx_length;
uint32_t readbytes; /* File write/read counts */
} MTP_DataLengthTypeDef;
typedef enum
{
RECEIVE_IDLE_STATE = 0x00U,
RECEIVE_COMMAND_DATA = 0x01U,
RECEIVE_FIRST_DATA = 0x02U,
RECEIVE_REST_OF_DATA = 0x03U,
SEND_RESPONSE = 0x04U,
} MTP_RECEIVE_DATA_STATUS;
typedef struct
{
uint32_t length;
uint16_t type;
uint16_t code;
uint32_t trans_id;
uint32_t Param1;
uint32_t Param2;
uint32_t Param3;
uint32_t Param4;
uint32_t Param5;
} MTP_OperationsTypeDef;
typedef struct
{
uint32_t length;
uint16_t type;
uint16_t code;
uint32_t trans_id;
uint8_t data[MTP_MEDIA_PACKET];
} MTP_GenericContainerTypeDef;
#if defined ( __GNUC__ )
typedef __PACKED_STRUCT
#else
__packed typedef struct
#endif /* __GNUC__ */
{
uint32_t Storage_id;
uint16_t ObjectFormat;
uint16_t ProtectionStatus;
uint32_t ObjectCompressedSize;
uint16_t ThumbFormat;
uint32_t ThumbCompressedSize;
uint32_t ThumbPixWidth;
uint32_t ThumbPixHeight;
uint32_t ImagePixWidth;
uint32_t ImagePixHeight;
uint32_t ImageBitDepth;
uint32_t ParentObject;
uint16_t AssociationType;
uint32_t AssociationDesc;
uint32_t SequenceNumber;
uint8_t Filename_len;
uint16_t Filename[255];
uint32_t CaptureDate;
uint32_t ModificationDate;
uint8_t Keywords;
} MTP_ObjectInfoTypeDef;
typedef struct
{
uint32_t alt_setting;
uint32_t dev_status;
uint32_t ResponseLength;
uint32_t ResponseCode;
__IO uint16_t MaxPcktLen;
uint32_t rx_buff[MTP_MEDIA_PACKET / 4U]; /* Force 32-bit alignment */
MTP_ResponsePhaseTypeDef MTP_ResponsePhase;
MTP_SessionStateTypeDef MTP_SessionState;
MTP_RECEIVE_DATA_STATUS RECEIVE_DATA_STATUS;
MTP_OperationsTypeDef OperationsContainer;
MTP_GenericContainerTypeDef GenericContainer;
} USBD_MTP_HandleTypeDef;
/** @defgroup USBD_CORE_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_Variables
* @{
*/
extern USBD_ClassTypeDef USBD_MTP;
#define USBD_MTP_CLASS &USBD_MTP
/**
* @}
*/
/** @defgroup USB_CORE_Exported_Functions
* @{
*/
typedef struct _USBD_MTP_ItfTypeDef
{
uint8_t (*Init)(void);
uint8_t (*DeInit)(void);
uint32_t (*ReadData)(uint32_t Param1, uint8_t *buff, MTP_DataLengthTypeDef *data_length);
uint16_t (*Create_NewObject)(MTP_ObjectInfoTypeDef ObjectInfo, uint32_t objhandle);
uint32_t (*GetIdx)(uint32_t Param3, uint32_t *obj_handle);
uint32_t (*GetParentObject)(uint32_t Param);
uint16_t (*GetObjectFormat)(uint32_t Param);
uint8_t (*GetObjectName_len)(uint32_t Param);
void (*GetObjectName)(uint32_t Param, uint8_t obj_len, uint16_t *buf);
uint32_t (*GetObjectSize)(uint32_t Param);
uint64_t (*GetMaxCapability)(void);
uint64_t (*GetFreeSpaceInBytes)(void);
uint32_t (*GetNewIndex)(uint16_t objformat);
void (*WriteData)(uint16_t len, uint8_t buff[]);
uint32_t (*GetContainerLength)(uint32_t Param1);
uint16_t (*DeleteObject)(uint32_t Param1);
void (*Cancel)(uint32_t Phase);
uint32_t *ScratchBuff;
uint32_t ScratchBuffSze;
} USBD_MTP_ItfTypeDef;
/**
* @}
*/
/** @defgroup USB_CORE_Exported_Functions
* @{
*/
uint8_t USBD_MTP_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_MTP_ItfTypeDef *fops);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USB_MTP_H */
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,96 @@
/**
******************************************************************************
* @file usbd_mtp_if_template.h
* @author MCD Application Team
* @brief Header file for the usbd_mtp_if_template.c file.
******************************************************************************
* @attention
*
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_MTP_IF_TEMPLATE_H
#define __USBD_MTP_IF_TEMPLATE_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbd_mtp.h"
/* Exported Define -----------------------------------------------------------*/
#define USBD_MTP_DEVICE_PROP_SUPPORTED 1U
#define USBD_MTP_CAPTURE_FORMAT_SUPPORTED 1U
#define USBD_MTP_VEND_EXT_DESC_SUPPORTED 1U
#define USBD_MTP_EVENTS_SUPPORTED 1U
#if USBD_MTP_EVENTS_SUPPORTED == 1
#define SUPP_EVENTS_LEN (uint8_t)((uint8_t)sizeof(SuppEvents) / 2U)
#else
#define SUPP_EVENTS_LEN 0U
#endif /* USBD_MTP_EVENTS_SUPPORTED */
#if USBD_MTP_VEND_EXT_DESC_SUPPORTED == 1
#define VEND_EXT_DESC_LEN (sizeof(VendExtDesc) / 2U)
#else
#define VEND_EXT_DESC_LEN 0U
#endif /* USBD_MTP_VEND_EXT_DESC_SUPPORTED */
#if USBD_MTP_CAPTURE_FORMAT_SUPPORTED == 1
#define SUPP_CAPT_FORMAT_LEN (uint8_t)((uint8_t)sizeof(SuppCaptFormat) / 2U)
#else
#define SUPP_CAPT_FORMAT_LEN 0U
#endif /* USBD_MTP_CAPTURE_FORMAT_SUPPORTED */
#if USBD_MTP_DEVICE_PROP_SUPPORTED == 1
#define SUPP_DEVICE_PROP_LEN (uint8_t)((uint8_t)sizeof(DevicePropSupp) / 2U)
#else
#define SUPP_DEVICE_PROP_LEN 0U
#endif /* USBD_MTP_DEVICE_PROP_SUPPORTED */
#define MTP_IF_SCRATCH_BUFF_SZE 1024U
/* Exported types ------------------------------------------------------------*/
extern USBD_MTP_ItfTypeDef USBD_MTP_fops;
/* Exported macros -----------------------------------------------------------*/
/* Exported variables --------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
static const uint16_t Manuf[] = {'S', 'T', 'M', 0}; /* last 2 bytes must be 0*/
static const uint16_t Model[] = {'S', 'T', 'M', '3', '2', 0}; /* last 2 bytes must be 0*/
static const uint16_t VendExtDesc[] = {'m', 'i', 'c', 'r', 'o', 's', 'o', 'f', 't', '.',
'c', 'o', 'm', ':', ' ', '1', '.', '0', ';', ' ', 0
}; /* last 2 bytes must be 0*/
/*SerialNbr shall be 32 character hexadecimal string for legacy compatibility reasons */
static const uint16_t SerialNbr[] = {'0', '0', '0', '0', '1', '0', '0', '0', '0', '1', '0', '0', '0', '0',
'1', '0', '0', '0', '0', '1', '0', '0', '0', '0', '1', '0', '0', '0',
'0', '1', '0', '0', 0
}; /* last 2 bytes must be 0*/
static const uint16_t DeviceVers[] = {'V', '1', '.', '0', '0', 0}; /* last 2 bytes must be 0*/
static const uint16_t DefaultFileName[] = {'N', 'e', 'w', ' ', 'F', 'o', 'l', 'd', 'e', 'r', 0};
static const uint16_t DevicePropDefVal[] = {'S', 'T', 'M', '3', '2', 0}; /* last 2 bytes must be 0*/
static const uint16_t DevicePropCurDefVal[] = {'S', 'T', 'M', '3', '2', ' ', 'V', '1', '.', '0', 0};
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_MTP_IF_TEMPLATE_H */

View File

@@ -0,0 +1,681 @@
/**
******************************************************************************
* @file usbd_mtp_opt.h
* @author MCD Application Team
* @brief header file for the usbd_mtp_opt.c file.
******************************************************************************
* @attention
*
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_MTP_OPT_H__
#define __USBD_MTP_OPT_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#ifndef __USBD_MTP_IF_H
#include "usbd_mtp_if_template.h"
#endif /* __USBD_MTP_IF_H */
#include "usbd_mtp.h"
/** @addtogroup STM32_USB_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_MTP_OPT
* @brief This file is the header file for usbd_mtp_opt.c
* @{
*/
/** @defgroup USBD_MTP_OPT_Exported_Defines
* @{
*/
/*
* MTP Class specification Revision 1.1
* Appendix B. Object Properties
*/
/* MTP OBJECT PROPERTIES supported*/
#define MTP_OB_PROP_STORAGE_ID 0xDC01U
#define MTP_OB_PROP_OBJECT_FORMAT 0xDC02U
#define MTP_OB_PROP_PROTECTION_STATUS 0xDC03U
#define MTP_OB_PROP_OBJECT_SIZE 0xDC04U
#define MTP_OB_PROP_ASSOC_TYPE 0xDC05U
#define MTP_OB_PROP_ASSOC_DESC 0xDC06U
#define MTP_OB_PROP_OBJ_FILE_NAME 0xDC07U
#define MTP_OB_PROP_DATE_CREATED 0xDC08U
#define MTP_OB_PROP_DATE_MODIFIED 0xDC09U
#define MTP_OB_PROP_KEYWORDS 0xDC0AU
#define MTP_OB_PROP_PARENT_OBJECT 0xDC0BU
#define MTP_OB_PROP_ALLOWED_FOLD_CONTENTS 0xDC0CU
#define MTP_OB_PROP_HIDDEN 0xDC0DU
#define MTP_OB_PROP_SYSTEM_OBJECT 0xDC0EU
#define MTP_OB_PROP_PERS_UNIQ_OBJ_IDEN 0xDC41U
#define MTP_OB_PROP_SYNCID 0xDC42U
#define MTP_OB_PROP_PROPERTY_BAG 0xDC43U
#define MTP_OB_PROP_NAME 0xDC44U
#define MTP_OB_PROP_CREATED_BY 0xDC45U
#define MTP_OB_PROP_ARTIST 0xDC46U
#define MTP_OB_PROP_DATE_AUTHORED 0xDC47U
#define MTP_OB_PROP_DESCRIPTION 0xDC48U
#define MTP_OB_PROP_URL_REFERENCE 0xDC49U
#define MTP_OB_PROP_LANGUAGELOCALE 0xDC4AU
#define MTP_OB_PROP_COPYRIGHT_INFORMATION 0xDC4BU
#define MTP_OB_PROP_SOURCE 0xDC4CU
#define MTP_OB_PROP_ORIGIN_LOCATION 0xDC4DU
#define MTP_OB_PROP_DATE_ADDED 0xDC4EU
#define MTP_OB_PROP_NON_CONSUMABLE 0xDC4FU
#define MTP_OB_PROP_CORRUPTUNPLAYABLE 0xDC50U
#define MTP_OB_PROP_PRODUCERSERIALNUMBER 0xDC51U
#define MTP_OB_PROP_REPRESENTATIVE_SAMPLE_FORMAT 0xDC81U
#define MTP_OB_PROP_REPRESENTATIVE_SAMPLE_SIZE 0xDC82U
#define MTP_OB_PROP_REPRESENTATIVE_SAMPLE_HEIGHT 0xDC83U
#define MTP_OB_PROP_REPRESENTATIVE_SAMPLE_WIDTH 0xDC84U
#define MTP_OB_PROP_REPRESENTATIVE_SAMPLE_DURATION 0xDC85U
#define MTP_OB_PROP_REPRESENTATIVE_SAMPLE_DATA 0xDC86U
#define MTP_OB_PROP_WIDTH 0xDC87U
#define MTP_OB_PROP_HEIGHT 0xDC88U
#define MTP_OB_PROP_DURATION 0xDC89U
#define MTP_OB_PROP_RATING 0xDC8AU
#define MTP_OB_PROP_TRACK 0xDC8BU
#define MTP_OB_PROP_GENRE 0xDC8CU
#define MTP_OB_PROP_CREDITS 0xDC8DU
#define MTP_OB_PROP_LYRICS 0xDC8EU
#define MTP_OB_PROP_SUBSCRIPTION_CONTENT_ID 0xDC8FU
#define MTP_OB_PROP_PRODUCED_BY 0xDC90U
#define MTP_OB_PROP_USE_COUNT 0xDC91U
#define MTP_OB_PROP_SKIP_COUNT 0xDC92U
#define MTP_OB_PROP_LAST_ACCESSED 0xDC93U
#define MTP_OB_PROP_PARENTAL_RATING 0xDC94U
#define MTP_OB_PROP_META_GENRE 0xDC95U
#define MTP_OB_PROP_COMPOSER 0xDC96U
#define MTP_OB_PROP_EFFECTIVE_RATING 0xDC97U
#define MTP_OB_PROP_SUBTITLE 0xDC98U
#define MTP_OB_PROP_ORIGINAL_RELEASE_DATE 0xDC99U
#define MTP_OB_PROP_ALBUM_NAME 0xDC9AU
#define MTP_OB_PROP_ALBUM_ARTIST 0xDC9BU
#define MTP_OB_PROP_MOOD 0xDC9CU
#define MTP_OB_PROP_DRM_STATUS 0xDC9DU
#define MTP_OB_PROP_SUB_DESCRIPTION 0xDC9EU
#define MTP_OB_PROP_IS_CROPPED 0xDCD1U
#define MTP_OB_PROP_IS_COLOUR_CORRECTED 0xDCD2U
#define MTP_OB_PROP_IMAGE_BIT_DEPTH 0xDCD3U
#define MTP_OB_PROP_FNUMBER 0xDCD4U
#define MTP_OB_PROP_EXPOSURE_TIME 0xDCD5U
#define MTP_OB_PROP_EXPOSURE_INDEX 0xDCD6U
#define MTP_OB_PROP_TOTAL_BITRATE 0xDE91U
#define MTP_OB_PROP_BITRATE_TYPE 0xDE92U
#define MTP_OB_PROP_SAMPLE_RATE 0xDE93U
#define MTP_OB_PROP_NUMBER_OF_CHANNELS 0xDE94U
#define MTP_OB_PROP_AUDIO_BITDEPTH 0xDE95U
#define MTP_OB_PROP_SCAN_TYPE 0xDE97U
#define MTP_OB_PROP_AUDIO_WAVE_CODEC 0xDE99U
#define MTP_OB_PROP_AUDIO_BITRATE 0xDE9AU
#define MTP_OB_PROP_VIDEO_FOURCC_CODEC 0xDE9BU
#define MTP_OB_PROP_VIDEO_BITRATE 0xDE9CU
#define MTP_OB_PROP_FRAMES_PER_THOUSAND_SECONDS 0xDE9DU
#define MTP_OB_PROP_KEYFRAME_DISTANCE 0xDE9EU
#define MTP_OB_PROP_BUFFER_SIZE 0xDE9FU
#define MTP_OB_PROP_ENCODING_QUALITY 0xDEA0U
#define MTP_OB_PROP_ENCODING_PROFILE 0xDEA1U
#define MTP_OB_PROP_DISPLAY_NAME 0xDCE0U
#define MTP_OB_PROP_BODY_TEXT 0xDCE1U
#define MTP_OB_PROP_SUBJECT 0xDCE2U
#define MTP_OB_PROP_PRIORITY 0xDCE3U
#define MTP_OB_PROP_GIVEN_NAME 0xDD00U
#define MTP_OB_PROP_MIDDLE_NAMES 0xDD01U
#define MTP_OB_PROP_FAMILY_NAME 0xDD02U
#define MTP_OB_PROP_PREFIX 0xDD03U
#define MTP_OB_PROP_SUFFIX 0xDD04U
#define MTP_OB_PROP_PHONETIC_GIVEN_NAME 0xDD05U
#define MTP_OB_PROP_PHONETIC_FAMILY_NAME 0xDD06U
#define MTP_OB_PROP_EMAIL_PRIMARY 0xDD07U
#define MTP_OB_PROP_EMAIL_PERSONAL_1 0xDD08U
#define MTP_OB_PROP_EMAIL_PERSONAL_2 0xDD09U
#define MTP_OB_PROP_EMAIL_BUSINESS_1 0xDD0AU
#define MTP_OB_PROP_EMAIL_BUSINESS_2 0xDD0BU
#define MTP_OB_PROP_EMAIL_OTHERS 0xDD0CU
#define MTP_OB_PROP_PHONE_NUMBER_PRIMARY 0xDD0DU
#define MTP_OB_PROP_PHONE_NUMBER_PERSONAL 0xDD0EU
#define MTP_OB_PROP_PHONE_NUMBER_PERSONAL_2 0xDD0FU
#define MTP_OB_PROP_PHONE_NUMBER_BUSINESS 0xDD10U
#define MTP_OB_PROP_PHONE_NUMBER_BUSINESS_2 0xDD11U
#define MTP_OB_PROP_PHONE_NUMBER_MOBILE 0xDD12U
#define MTP_OB_PROP_PHONE_NUMBER_MOBILE_2 0xDD13U
#define MTP_OB_PROP_FAX_NUMBER_PRIMARY 0xDD14U
#define MTP_OB_PROP_FAX_NUMBER_PERSONAL 0xDD15U
#define MTP_OB_PROP_FAX_NUMBER_BUSINESS 0xDD16U
#define MTP_OB_PROP_PAGER_NUMBER 0xDD17U
#define MTP_OB_PROP_PHONE_NUMBER_OTHERS 0xDD18U
#define MTP_OB_PROP_PRIMARY_WEB_ADDRESS 0xDD19U
#define MTP_OB_PROP_PERSONAL_WEB_ADDRESS 0xDD1AU
#define MTP_OB_PROP_BUSINESS_WEB_ADDRESS 0xDD1BU
#define MTP_OB_PROP_INSTANT_MESSENGER_ADDRESS 0xDD1CU
#define MTP_OB_PROP_INSTANT_MESSENGER_ADDRESS_2 0xDD1DU
#define MTP_OB_PROP_INSTANT_MESSENGER_ADDRESS_3 0xDD1EU
#define MTP_OB_PROP_POSTAL_ADDRESS_PERSONAL_FULL 0xDD1FU
#define MTP_OB_PROP_POSTAL_ADDRESS_PERSONAL_LINE_1 0xDD20U
#define MTP_OB_PROP_POSTAL_ADDRESS_PERSONAL_LINE_2 0xDD21U
#define MTP_OB_PROP_POSTAL_ADDRESS_PERSONAL_CITY 0xDD22U
#define MTP_OB_PROP_POSTAL_ADDRESS_PERSONAL_REGION 0xDD23U
#define MTP_OB_PROP_POSTAL_ADDRESS_PERSONAL_POSTAL_CODE 0xDD24U
#define MTP_OB_PROP_POSTAL_ADDRESS_PERSONAL_COUNTRY 0xDD25U
#define MTP_OB_PROP_POSTAL_ADDRESS_BUSINESS_FULL 0xDD26U
#define MTP_OB_PROP_POSTAL_ADDRESS_BUSINESS_LINE_1 0xDD27U
#define MTP_OB_PROP_POSTAL_ADDRESS_BUSINESS_LINE_2 0xDD28U
#define MTP_OB_PROP_POSTAL_ADDRESS_BUSINESS_CITY 0xDD29U
#define MTP_OB_PROP_POSTAL_ADDRESS_BUSINESS_REGION 0xDD2AU
#define MTP_OB_PROP_POSTAL_ADDRESS_BUSINESS_POSTAL_CODE 0xDD2BU
#define MTP_OB_PROP_POSTAL_ADDRESS_BUSINESS_COUNTRY 0xDD2CU
#define MTP_OB_PROP_POSTAL_ADDRESS_OTHER_FULL 0xDD2DU
#define MTP_OB_PROP_POSTAL_ADDRESS_OTHER_LINE_1 0xDD2EU
#define MTP_OB_PROP_POSTAL_ADDRESS_OTHER_LINE_2 0xDD2FU
#define MTP_OB_PROP_POSTAL_ADDRESS_OTHER_CITY 0xDD30U
#define MTP_OB_PROP_POSTAL_ADDRESS_OTHER_REGION 0xDD31U
#define MTP_OB_PROP_POSTAL_ADDRESS_OTHER_POSTAL_CODE 0xDD32U
#define MTP_OB_PROP_POSTAL_ADDRESS_OTHER_COUNTRY 0xDD33U
#define MTP_OB_PROP_ORGANIZATION_NAME 0xDD34U
#define MTP_OB_PROP_PHONETIC_ORGANIZATION_NAME 0xDD35U
#define MTP_OB_PROP_ROLE 0xDD36U
#define MTP_OB_PROP_BIRTHDATE 0xDD37U
#define MTP_OB_PROP_MESSAGE_TO 0xDD40U
#define MTP_OB_PROP_MESSAGE_CC 0xDD41U
#define MTP_OB_PROP_MESSAGE_BCC 0xDD42U
#define MTP_OB_PROP_MESSAGE_READ 0xDD43U
#define MTP_OB_PROP_MESSAGE_RECEIVED_TIME 0xDD44U
#define MTP_OB_PROP_MESSAGE_SENDER 0xDD45U
#define MTP_OB_PROP_ACT_BEGIN_TIME 0xDD50U
#define MTP_OB_PROP_ACT_END_TIME 0xDD51U
#define MTP_OB_PROP_ACT_LOCATION 0xDD52U
#define MTP_OB_PROP_ACT_REQUIRED_ATTENDEES 0xDD54U
#define MTP_OB_PROP_ACT_OPTIONAL_ATTENDEES 0xDD55U
#define MTP_OB_PROP_ACT_RESOURCES 0xDD56U
#define MTP_OB_PROP_ACT_ACCEPTED 0xDD57U
#define MTP_OB_PROP_OWNER 0xDD5DU
#define MTP_OB_PROP_EDITOR 0xDD5EU
#define MTP_OB_PROP_WEBMASTER 0xDD5FU
#define MTP_OB_PROP_URL_SOURCE 0xDD60U
#define MTP_OB_PROP_URL_DESTINATION 0xDD61U
#define MTP_OB_PROP_TIME_BOOKMARK 0xDD62U
#define MTP_OB_PROP_OBJECT_BOOKMARK 0xDD63U
#define MTP_OB_PROP_BYTE_BOOKMARK 0xDD64U
#define MTP_OB_PROP_LAST_BUILD_DATE 0xDD70U
#define MTP_OB_PROP_TIME_TO_LIVE 0xDD71U
#define MTP_OB_PROP_MEDIA_GUID 0xDD72U
/* MTP event codes*/
#define MTP_EVENT_UNDEFINED 0x4000U
#define MTP_EVENT_CANCELTRANSACTION 0x4001U
#define MTP_EVENT_OBJECTADDED 0x4002U
#define MTP_EVENT_OBJECTREMOVED 0x4003U
#define MTP_EVENT_STOREADDED 0x4004U
#define MTP_EVENT_STOREREMOVED 0x4005U
#define MTP_EVENT_DEVICEPROPCHANGED 0x4006U
#define MTP_EVENT_OBJECTINFOCHANGED 0x4007U
#define MTP_EVENT_DEVICEINFOCHANGED 0x4008U
#define MTP_EVENT_REQUESTOBJECTTRANSFER 0x4009U
#define MTP_EVENT_STOREFULL 0x400AU
#define MTP_EVENT_DEVICERESET 0x400BU
#define MTP_EVENT_STORAGEINFOCHANGED 0x400CU
#define MTP_EVENT_CAPTURECOMPLETE 0x400DU
#define MTP_EVENT_UNREPORTEDSTATUS 0x400EU
#define MTP_EVENT_OBJECTPROPCHANGED 0xC801U
#define MTP_EVENT_OBJECTPROPDESCCHANGED 0xC802U
#define MTP_EVENT_OBJECTREFERENCESCHANGED 0xC803U
/*
* MTP Class specification Revision 1.1
* Appendix D. Operations
*/
/* Operations code */
#define MTP_OP_GET_DEVICE_INFO 0x1001U
#define MTP_OP_OPEN_SESSION 0x1002U
#define MTP_OP_CLOSE_SESSION 0x1003U
#define MTP_OP_GET_STORAGE_IDS 0x1004U
#define MTP_OP_GET_STORAGE_INFO 0x1005U
#define MTP_OP_GET_NUM_OBJECTS 0x1006U
#define MTP_OP_GET_OBJECT_HANDLES 0x1007U
#define MTP_OP_GET_OBJECT_INFO 0x1008U
#define MTP_OP_GET_OBJECT 0x1009U
#define MTP_OP_GET_THUMB 0x100AU
#define MTP_OP_DELETE_OBJECT 0x100BU
#define MTP_OP_SEND_OBJECT_INFO 0x100CU
#define MTP_OP_SEND_OBJECT 0x100DU
#define MTP_OP_FORMAT_STORE 0x100FU
#define MTP_OP_RESET_DEVICE 0x1010U
#define MTP_OP_GET_DEVICE_PROP_DESC 0x1014U
#define MTP_OP_GET_DEVICE_PROP_VALUE 0x1015U
#define MTP_OP_SET_DEVICE_PROP_VALUE 0x1016U
#define MTP_OP_RESET_DEVICE_PROP_VALUE 0x1017U
#define MTP_OP_TERMINATE_OPEN_CAPTURE 0x1018U
#define MTP_OP_MOVE_OBJECT 0x1019U
#define MTP_OP_COPY_OBJECT 0x101AU
#define MTP_OP_GET_PARTIAL_OBJECT 0x101BU
#define MTP_OP_INITIATE_OPEN_CAPTURE 0x101CU
#define MTP_OP_GET_OBJECT_PROPS_SUPPORTED 0x9801U
#define MTP_OP_GET_OBJECT_PROP_DESC 0x9802U
#define MTP_OP_GET_OBJECT_PROP_VALUE 0x9803U
#define MTP_OP_SET_OBJECT_PROP_VALUE 0x9804U
#define MTP_OP_GET_OBJECT_PROPLIST 0x9805U
#define MTP_OP_GET_OBJECT_PROP_REFERENCES 0x9810U
#define MTP_OP_GETSERVICEIDS 0x9301U
#define MTP_OP_GETSERVICEINFO 0x9302U
#define MTP_OP_GETSERVICECAPABILITIES 0x9303U
#define MTP_OP_GETSERVICEPROPDESC 0x9304U
/*
* MTP Class specification Revision 1.1
* Appendix C. Device Properties
*/
/* MTP device properties code*/
#define MTP_DEV_PROP_UNDEFINED 0x5000U
#define MTP_DEV_PROP_BATTERY_LEVEL 0x5001U
#define MTP_DEV_PROP_FUNCTIONAL_MODE 0x5002U
#define MTP_DEV_PROP_IMAGE_SIZE 0x5003U
#define MTP_DEV_PROP_COMPRESSION_SETTING 0x5004U
#define MTP_DEV_PROP_WHITE_BALANCE 0x5005U
#define MTP_DEV_PROP_RGB_GAIN 0x5006U
#define MTP_DEV_PROP_F_NUMBER 0x5007U
#define MTP_DEV_PROP_FOCAL_LENGTH 0x5008U
#define MTP_DEV_PROP_FOCUS_DISTANCE 0x5009U
#define MTP_DEV_PROP_FOCUS_MODE 0x500AU
#define MTP_DEV_PROP_EXPOSURE_METERING_MODE 0x500BU
#define MTP_DEV_PROP_FLASH_MODE 0x500CU
#define MTP_DEV_PROP_EXPOSURE_TIME 0x500DU
#define MTP_DEV_PROP_EXPOSURE_PROGRAM_MODE 0x500EU
#define MTP_DEV_PROP_EXPOSURE_INDEX 0x500FU
#define MTP_DEV_PROP_EXPOSURE_BIAS_COMPENSATION 0x5010U
#define MTP_DEV_PROP_DATETIME 0x5011U
#define MTP_DEV_PROP_CAPTURE_DELAY 0x5012U
#define MTP_DEV_PROP_STILL_CAPTURE_MODE 0x5013U
#define MTP_DEV_PROP_CONTRAST 0x5014U
#define MTP_DEV_PROP_SHARPNESS 0x5015U
#define MTP_DEV_PROP_DIGITAL_ZOOM 0x5016U
#define MTP_DEV_PROP_EFFECT_MODE 0x5017U
#define MTP_DEV_PROP_BURST_NUMBER 0x5018U
#define MTP_DEV_PROP_BURST_INTERVAL 0x5019U
#define MTP_DEV_PROP_TIMELAPSE_NUMBER 0x501AU
#define MTP_DEV_PROP_TIMELAPSE_INTERVAL 0x501BU
#define MTP_DEV_PROP_FOCUS_METERING_MODE 0x501CU
#define MTP_DEV_PROP_UPLOAD_URL 0x501DU
#define MTP_DEV_PROP_ARTIST 0x501EU
#define MTP_DEV_PROP_COPYRIGHT_INFO 0x501FU
#define MTP_DEV_PROP_SYNCHRONIZATION_PARTNER 0xD401U
#define MTP_DEV_PROP_DEVICE_FRIENDLY_NAME 0xD402U
#define MTP_DEV_PROP_VOLUME 0xD403U
#define MTP_DEV_PROP_SUPPORTEDFORMATSORDERED 0xD404U
#define MTP_DEV_PROP_DEVICEICON 0xD405U
#define MTP_DEV_PROP_PLAYBACK_RATE 0xD410U
#define MTP_DEV_PROP_PLAYBACK_OBJECT 0xD411U
#define MTP_DEV_PROP_PLAYBACK_CONTAINER 0xD412U
#define MTP_DEV_PROP_SESSION_INITIATOR_VERSION_INFO 0xD406U
#define MTP_DEV_PROP_PERCEIVED_DEVICE_TYPE 0xD407U
/* Container Types */
#define MTP_CONT_TYPE_UNDEFINED 0U
#define MTP_CONT_TYPE_COMMAND 1U
#define MTP_CONT_TYPE_DATA 2U
#define MTP_CONT_TYPE_RESPONSE 3U
#define MTP_CONT_TYPE_EVENT 4U
#ifndef MTP_STORAGE_ID
#define MTP_STORAGE_ID 0x00010001U /* SD card is inserted*/
#endif /* MTP_STORAGE_ID */
#define MTP_NBR_STORAGE_ID 1U
#define FREE_SPACE_IN_OBJ_NOT_USED 0xFFFFFFFFU
/* MTP storage type */
#define MTP_STORAGE_UNDEFINED 0U
#define MTP_STORAGE_FIXED_ROM 0x0001U
#define MTP_STORAGE_REMOVABLE_ROM 0x0002U
#define MTP_STORAGE_FIXED_RAM 0x0003U
#define MTP_STORAGE_REMOVABLE_RAM 0x0004U
/* MTP file system type */
#define MTP_FILESYSTEM_UNDEFINED 0U
#define MTP_FILESYSTEM_GENERIC_FLAT 0x0001U
#define MTP_FILESYSTEM_GENERIC_HIERARCH 0x0002U
#define MTP_FILESYSTEM_DCF 0x0003U
/* MTP access capability */
#define MTP_ACCESS_CAP_RW 0U /* read write */
#define MTP_ACCESS_CAP_RO_WITHOUT_DEL 0x0001U
#define MTP_ACCESS_CAP_RO_WITH_DEL 0x0002U
/* MTP standard data types supported */
#define MTP_DATATYPE_INT8 0x0001U
#define MTP_DATATYPE_UINT8 0x0002U
#define MTP_DATATYPE_INT16 0x0003U
#define MTP_DATATYPE_UINT16 0x0004U
#define MTP_DATATYPE_INT32 0x0005U
#define MTP_DATATYPE_UINT32 0x0006U
#define MTP_DATATYPE_INT64 0x0007U
#define MTP_DATATYPE_UINT64 0x0008U
#define MTP_DATATYPE_UINT128 0x000AU
#define MTP_DATATYPE_STR 0xFFFFU
/* MTP reading only or reading/writing */
#define MTP_PROP_GET 0x00U
#define MTP_PROP_GET_SET 0x01U
/* MTP functional mode */
#define STANDARD_MODE 0U
#define SLEEP_STATE 1U
#define FUNCTIONAL_MODE STANDARD_MODE
/* MTP device info */
#define STANDARD_VERSION 100U
#define VEND_EXT_ID 0x06U
#define VEND_EXT_VERSION 100U
#define MANUF_LEN (sizeof(Manuf) / 2U)
#define MODEL_LEN (sizeof(Model) / 2U)
#define SUPP_OP_LEN (sizeof(SuppOP) / 2U)
#define SERIAL_NBR_LEN (sizeof(SerialNbr) / 2U)
#define DEVICE_VERSION_LEN (sizeof(DeviceVers) / 2U)
#define SUPP_IMG_FORMAT_LEN (sizeof(SuppImgFormat) / 2U)
#define SUPP_OBJ_PROP_LEN (sizeof(ObjectPropSupp) / 2U)
#ifndef MAX_FILE_NAME
#define MAX_FILE_NAME 255U
#endif /* MAX_FILE_NAME */
#ifndef MAX_OBJECT_HANDLE_LEN
#define MAX_OBJECT_HANDLE_LEN 100U
#endif /* MAX_OBJECT_HANDLE_LEN */
#ifndef DEVICE_PROP_DESC_DEF_LEN
#define DEVICE_PROP_DESC_DEF_LEN (uint8_t)(sizeof(DevicePropDefVal) / 2U)
#endif /* DEVICE_PROP_DESC_DEF_LEN */
#ifndef DEVICE_PROP_DESC_CUR_LEN
#define DEVICE_PROP_DESC_CUR_LEN (uint8_t)(sizeof(DevicePropCurDefVal) / 2U)
#endif /* DEVICE_PROP_DESC_CUR_LEN */
#ifndef DEFAULT_FILE_NAME_LEN
#define DEFAULT_FILE_NAME_LEN (uint8_t)(sizeof(DefaultFileName) / 2U)
#endif /* DEFAULT_FILE_NAME_LEN */
/**
* @}
*/
/** @defgroup USBD_MTP_OPT_Exported_TypesDefinitions
* @{
*/
/**
* @}
*/
static const uint16_t SuppOP[] = { MTP_OP_GET_DEVICE_INFO, MTP_OP_OPEN_SESSION, MTP_OP_CLOSE_SESSION,
MTP_OP_GET_STORAGE_IDS, MTP_OP_GET_STORAGE_INFO, MTP_OP_GET_NUM_OBJECTS,
MTP_OP_GET_OBJECT_HANDLES, MTP_OP_GET_OBJECT_INFO, MTP_OP_GET_OBJECT,
MTP_OP_DELETE_OBJECT, MTP_OP_SEND_OBJECT_INFO, MTP_OP_SEND_OBJECT,
MTP_OP_GET_DEVICE_PROP_DESC, MTP_OP_GET_DEVICE_PROP_VALUE,
MTP_OP_SET_OBJECT_PROP_VALUE, MTP_OP_GET_OBJECT_PROP_VALUE,
MTP_OP_GET_OBJECT_PROPS_SUPPORTED, MTP_OP_GET_OBJECT_PROPLIST,
MTP_OP_GET_OBJECT_PROP_DESC, MTP_OP_GET_OBJECT_PROP_REFERENCES
};
static const uint16_t SuppEvents[] = {MTP_EVENT_OBJECTADDED};
static const uint16_t SuppImgFormat[] = {MTP_OBJ_FORMAT_UNDEFINED, MTP_OBJ_FORMAT_TEXT, MTP_OBJ_FORMAT_ASSOCIATION,
MTP_OBJ_FORMAT_EXECUTABLE, MTP_OBJ_FORMAT_WAV, MTP_OBJ_FORMAT_MP3,
MTP_OBJ_FORMAT_EXIF_JPEG, MTP_OBJ_FORMAT_MPEG, MTP_OBJ_FORMAT_MP4_CONTAINER,
MTP_OBJ_FORMAT_WINDOWS_IMAGE_FORMAT, MTP_OBJ_FORMAT_PNG, MTP_OBJ_FORMAT_WMA,
MTP_OBJ_FORMAT_WMV
};
static const uint16_t SuppCaptFormat[] = {MTP_OBJ_FORMAT_UNDEFINED, MTP_OBJ_FORMAT_ASSOCIATION, MTP_OBJ_FORMAT_TEXT};
/* required for all object format : storageID, objectFormat, ObjectCompressedSize,
persistent unique object identifier, name*/
static const uint16_t ObjectPropSupp[] = {MTP_OB_PROP_STORAGE_ID, MTP_OB_PROP_OBJECT_FORMAT, MTP_OB_PROP_OBJECT_SIZE,
MTP_OB_PROP_OBJ_FILE_NAME, MTP_OB_PROP_PARENT_OBJECT, MTP_OB_PROP_NAME,
MTP_OB_PROP_PERS_UNIQ_OBJ_IDEN, MTP_OB_PROP_PROTECTION_STATUS
};
static const uint16_t DevicePropSupp[] = {MTP_DEV_PROP_DEVICE_FRIENDLY_NAME, MTP_DEV_PROP_BATTERY_LEVEL};
/* for all mtp struct */
typedef struct
{
uint32_t StorageIDS_len;
uint32_t StorageIDS[MTP_NBR_STORAGE_ID];
} MTP_StorageIDSTypeDef;
#if defined ( __GNUC__ )
typedef __PACKED_STRUCT
#else
__packed typedef struct
#endif /* __GNUC__ */
{
uint8_t FileName_len;
uint16_t FileName[MAX_FILE_NAME];
} MTP_FileNameTypeDef;
typedef struct
{
uint32_t ObjectHandle_len;
uint32_t ObjectHandle[MAX_OBJECT_HANDLE_LEN];
} MTP_ObjectHandleTypeDef;
#if defined ( __GNUC__ )
typedef __PACKED_STRUCT
#else
__packed typedef struct
#endif /* __GNUC__ */
{
uint32_t ObjectPropSupp_len;
uint16_t ObjectPropSupp[SUPP_OBJ_PROP_LEN];
} MTP_ObjectPropSuppTypeDef;
#if defined ( __GNUC__ )
typedef __PACKED_STRUCT
#else
__packed typedef struct
#endif /* __GNUC__ */
{
uint16_t StorageType;
uint16_t FilesystemType;
uint16_t AccessCapability;
uint64_t MaxCapability;
uint64_t FreeSpaceInBytes;
uint32_t FreeSpaceInObjects;
uint8_t StorageDescription;
uint8_t VolumeLabel;
} MTP_StorageInfoTypedef;
typedef union
{
uint16_t str[100];
uint8_t u8;
int8_t i8;
uint16_t u16;
int16_t i16;
uint32_t u32;
int32_t i32;
uint64_t u64;
int64_t i64;
} MTP_PropertyValueTypedef;
#if defined ( __GNUC__ )
typedef __PACKED_STRUCT
#else
__packed typedef struct
#endif /* __GNUC__ */
{
uint16_t ObjectPropertyCode;
uint16_t DataType;
uint8_t GetSet;
uint8_t *DefValue;
uint32_t GroupCode;
uint8_t FormFlag;
} MTP_ObjectPropDescTypeDef;
#if defined ( __GNUC__ )
typedef __PACKED_STRUCT
#else
__packed typedef struct
#endif /* __GNUC__ */
{
uint32_t ObjectHandle;
uint16_t PropertyCode;
uint16_t Datatype;
uint8_t *propval;
} MTP_PropertiesTypedef;
#if defined ( __GNUC__ )
typedef __PACKED_STRUCT
#else
__packed typedef struct
#endif /* __GNUC__ */
{
uint32_t MTP_Properties_len;
MTP_PropertiesTypedef MTP_Properties[SUPP_OBJ_PROP_LEN];
} MTP_PropertiesListTypedef;
#if defined ( __GNUC__ )
typedef __PACKED_STRUCT
#else
__packed typedef struct
#endif /* __GNUC__ */
{
uint32_t ref_len;
uint32_t ref[1];
} MTP_RefTypeDef;
#if defined ( __GNUC__ )
typedef __PACKED_STRUCT
#else
__packed typedef struct
#endif /* __GNUC__ */
{
uint16_t DevicePropertyCode;
uint16_t DataType;
uint8_t GetSet;
uint8_t DefValue_len;
uint16_t DefValue[DEVICE_PROP_DESC_DEF_LEN];
uint8_t curDefValue_len;
uint16_t curDefValue[DEVICE_PROP_DESC_CUR_LEN];
uint8_t FormFlag;
} MTP_DevicePropDescTypeDef;
/* MTP device info structure */
#if defined ( __GNUC__ )
typedef __PACKED_STRUCT
#else
__packed typedef struct
#endif /* __GNUC__ */
{
uint16_t StandardVersion;
uint32_t VendorExtensionID;
uint16_t VendorExtensionVersion;
uint8_t VendorExtensionDesc_len;
#if USBD_MTP_VEND_EXT_DESC_SUPPORTED == 1
uint16_t VendorExtensionDesc[VEND_EXT_DESC_LEN];
#endif /* USBD_MTP_VEND_EXT_DESC_SUPPORTED */
uint16_t FunctionalMode;
uint32_t OperationsSupported_len;
uint16_t OperationsSupported[SUPP_OP_LEN];
uint32_t EventsSupported_len;
#if USBD_MTP_EVENTS_SUPPORTED == 1
uint16_t EventsSupported[SUPP_EVENTS_LEN];
#endif /* USBD_MTP_EVENTS_SUPPORTED */
uint32_t DevicePropertiesSupported_len;
#if USBD_MTP_DEVICE_PROP_SUPPORTED == 1
uint16_t DevicePropertiesSupported[SUPP_DEVICE_PROP_LEN];
#endif /* USBD_MTP_DEVICE_PROP_SUPPORTED */
uint32_t CaptureFormats_len;
#if USBD_MTP_CAPTURE_FORMAT_SUPPORTED == 1
uint16_t CaptureFormats[SUPP_CAPT_FORMAT_LEN];
#endif /* USBD_MTP_CAPTURE_FORMAT_SUPPORTED */
uint32_t ImageFormats_len;
uint16_t ImageFormats[SUPP_IMG_FORMAT_LEN];
uint8_t Manufacturer_len;
uint16_t Manufacturer[MANUF_LEN];
uint8_t Model_len;
uint16_t Model[MODEL_LEN];
uint8_t DeviceVersion_len;
uint16_t DeviceVersion[DEVICE_VERSION_LEN];
uint8_t SerialNumber_len;
uint16_t SerialNumber[SERIAL_NBR_LEN];
} MTP_DeviceInfoTypedef;
/** @defgroup USBD_MTP_OPT_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_MTP_OPT_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBD_MTP_OPT_Exported_Functions
* @{
*/
void USBD_MTP_OPT_CreateObjectHandle(USBD_HandleTypeDef *pdev);
void USBD_MTP_OPT_GetDeviceInfo(USBD_HandleTypeDef *pdev);
void USBD_MTP_OPT_GetStorageIDS(USBD_HandleTypeDef *pdev);
void USBD_MTP_OPT_GetStorageInfo(USBD_HandleTypeDef *pdev);
void USBD_MTP_OPT_GetObjectHandle(USBD_HandleTypeDef *pdev);
void USBD_MTP_OPT_GetObjectInfo(USBD_HandleTypeDef *pdev);
void USBD_MTP_OPT_GetObjectReferences(USBD_HandleTypeDef *pdev);
void USBD_MTP_OPT_GetObjectPropSupp(USBD_HandleTypeDef *pdev);
void USBD_MTP_OPT_GetObjectPropDesc(USBD_HandleTypeDef *pdev);
void USBD_MTP_OPT_GetObjectPropValue(USBD_HandleTypeDef *pdev);
void USBD_MTP_OPT_GetObjectPropList(USBD_HandleTypeDef *pdev);
void USBD_MTP_OPT_GetDevicePropDesc(USBD_HandleTypeDef *pdev);
void USBD_MTP_OPT_SendObjectInfo(USBD_HandleTypeDef *pdev, uint8_t *buff, uint32_t len);
void USBD_MTP_OPT_SendObject(USBD_HandleTypeDef *pdev, uint8_t *buff, uint32_t len);
void USBD_MTP_OPT_GetObject(USBD_HandleTypeDef *pdev);
void USBD_MTP_OPT_DeleteObject(USBD_HandleTypeDef *pdev);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_MTP_OPT_H__ */
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,118 @@
/**
******************************************************************************
* @file usbd_mtp_storage.h
* @author MCD Application Team
* @brief header file for the usbd_mtp_storage.c file.
******************************************************************************
* @attention
*
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_MTP_STORAGE_H__
#define __USBD_MTP_STORAGE_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbd_ctlreq.h"
#include "usbd_mtp_opt.h"
/** @addtogroup STM32_USB_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_MTP_STORAGE
* @brief This file is the header file for usbd_template_core.c
* @{
*/
/** @defgroup USBD_MTP_STORAGE_Exported_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBD_MTP_STORAGE_Exported_TypesDefinitions
* @{
*/
typedef enum
{
DATA_TYPE = 0x00,
REP_TYPE = 0x01,
} MTP_CONTAINER_TYPE;
typedef enum
{
READ_FIRST_DATA = 0x00,
READ_REST_OF_DATA = 0x01,
} MTP_READ_DATA_STATUS;
/**
* @}
*/
/** @defgroup USBD_MTP_STORAGE_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_MTP_STORAGE_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBD_MTP_STORAGE_Exported_Functions
* @{
*/
uint8_t USBD_MTP_STORAGE_Init(USBD_HandleTypeDef *pdev);
uint8_t USBD_MTP_STORAGE_DeInit(USBD_HandleTypeDef *pdev);
void USBD_MTP_STORAGE_Cancel(USBD_HandleTypeDef *pdev, MTP_ResponsePhaseTypeDef MTP_ResponsePhase);
uint8_t USBD_MTP_STORAGE_ReadData(USBD_HandleTypeDef *pdev);
uint8_t USBD_MTP_STORAGE_SendContainer(USBD_HandleTypeDef *pdev, MTP_CONTAINER_TYPE CONT_TYPE);
uint8_t USBD_MTP_STORAGE_ReceiveOpt(USBD_HandleTypeDef *pdev);
uint8_t USBD_MTP_STORAGE_ReceiveData(USBD_HandleTypeDef *pdev);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_MTP_STORAGE_H */
/**
* @}
*/
/**
* @}
*/

701
Class/MTP/Src/usbd_mtp.c Normal file
View File

@@ -0,0 +1,701 @@
/**
******************************************************************************
* @file usbd_mtp.c
* @author MCD Application Team
* @brief This file provides the high layer firmware functions to manage the
* following functionalities of the USB MTP Class:
* - Initialization and Configuration of high and low layer
* - Enumeration as MTP Device (and enumeration for each implemented memory interface)
* - OUT/IN data transfer
* - Command IN transfer (class requests management)
* - Error management
*
******************************************************************************
* @attention
*
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
* @verbatim
*
* ===================================================================
* MTP Class Driver Description
* ===================================================================
* This driver manages the "Universal Serial Bus Class Definitions for Media Transfer Protocol
* Revision 1.1 April 6, 2011"
* This driver implements the following aspects of the specification:
* - Device descriptor management
* - Configuration descriptor management
* - Enumeration as MTP device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN)
* - Requests management
*
*
* @endverbatim
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_mtp.h"
#include "usbd_mtp_storage.h"
/** @addtogroup STM32_USB_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_MTP
* @brief usbd core module
* @{
*/
/** @defgroup USBD_MTP_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBD_MTP_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBD_MTP_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_MTP_Private_FunctionPrototypes
* @{
*/
static uint8_t USBD_MTP_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
static uint8_t USBD_MTP_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
static uint8_t USBD_MTP_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
static uint8_t USBD_MTP_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
static uint8_t USBD_MTP_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
#ifndef USE_USBD_COMPOSITE
static uint8_t *USBD_MTP_GetHSCfgDesc(uint16_t *length);
static uint8_t *USBD_MTP_GetFSCfgDesc(uint16_t *length);
static uint8_t *USBD_MTP_GetOtherSpeedCfgDesc(uint16_t *length);
static uint8_t *USBD_MTP_GetDeviceQualifierDescriptor(uint16_t *length);
#endif /* USE_USBD_COMPOSITE */
/**
* @}
*/
/** @defgroup USBD_MTP_Private_Variables
* @{
*/
/* MTP interface class callbacks structure */
USBD_ClassTypeDef USBD_MTP =
{
USBD_MTP_Init,
USBD_MTP_DeInit,
USBD_MTP_Setup,
NULL, /*EP0_TxSent*/
NULL, /*EP0_RxReady*/
USBD_MTP_DataIn,
USBD_MTP_DataOut,
NULL, /*SOF */
NULL, /*ISOIn*/
NULL, /*ISOOut*/
#ifdef USE_USBD_COMPOSITE
NULL,
NULL,
NULL,
NULL,
#else
USBD_MTP_GetHSCfgDesc,
USBD_MTP_GetFSCfgDesc,
USBD_MTP_GetOtherSpeedCfgDesc,
USBD_MTP_GetDeviceQualifierDescriptor,
#endif /* USE_USBD_COMPOSITE */
};
#ifndef USE_USBD_COMPOSITE
/* USB MTP device Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_MTP_CfgDesc[MTP_CONFIG_DESC_SIZ] __ALIGN_END =
{
/* Configuration Descriptor */
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
LOBYTE(MTP_CONFIG_DESC_SIZ), /* wTotalLength: Total size of the Config descriptor */
HIBYTE(MTP_CONFIG_DESC_SIZ),
0x01, /* bNumInterfaces: 1 interface */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor
describing the configuration */
#if (USBD_SELF_POWERED == 1U)
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif /* USBD_SELF_POWERED */
USBD_MAX_POWER, /* MaxPower (mA) */
/******************** MTP **** interface ********************/
MTP_INTERFACE_DESC_SIZE, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
MTP_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x03, /* bNumEndpoints: */
USB_MTP_INTRERFACE_CLASS, /* bInterfaceClass: bInterfaceClass: user's interface for MTP */
USB_MTP_INTRERFACE_SUB_CLASS, /* bInterfaceSubClass:Abstract Control Model */
USB_MTP_INTRERFACE_PROTOCOL, /* bInterfaceProtocol: Common AT commands */
0x00, /* iInterface: */
/******************** MTP Endpoints ********************/
MTP_ENDPOINT_DESC_SIZE, /* Endpoint descriptor length = 7 */
USB_DESC_TYPE_ENDPOINT, /* Endpoint descriptor type */
MTP_IN_EP, /* Endpoint address (IN, address 1) */
USBD_EP_TYPE_BULK, /* Bulk endpoint type */
LOBYTE(MTP_DATA_MAX_FS_PACKET_SIZE),
HIBYTE(MTP_DATA_MAX_FS_PACKET_SIZE),
0x00, /* Polling interval in milliseconds */
MTP_ENDPOINT_DESC_SIZE, /* Endpoint descriptor length = 7 */
USB_DESC_TYPE_ENDPOINT, /* Endpoint descriptor type */
MTP_OUT_EP, /* Endpoint address (OUT, address 1) */
USBD_EP_TYPE_BULK, /* Bulk endpoint type */
LOBYTE(MTP_DATA_MAX_FS_PACKET_SIZE),
HIBYTE(MTP_DATA_MAX_FS_PACKET_SIZE),
0x00, /* Polling interval in milliseconds */
MTP_ENDPOINT_DESC_SIZE, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType:*/
MTP_CMD_EP, /* bEndpointAddress: Endpoint Address (IN) */
USBD_EP_TYPE_INTR, /* bmAttributes: Interrupt endpoint */
LOBYTE(MTP_CMD_PACKET_SIZE),
HIBYTE(MTP_CMD_PACKET_SIZE),
MTP_FS_BINTERVAL /* Polling interval in milliseconds */
};
/* USB Standard Device Descriptor */
__ALIGN_BEGIN static uint8_t USBD_MTP_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
{
USB_LEN_DEV_QUALIFIER_DESC,
USB_DESC_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
0x00,
0x00,
0x00,
0x40,
0x01,
0x00,
};
#endif /* USE_USBD_COMPOSITE */
uint8_t MTPInEpAdd = MTP_IN_EP;
uint8_t MTPOutEpAdd = MTP_OUT_EP;
uint8_t MTPCmdEpAdd = MTP_CMD_EP;
/**
* @}
*/
/** @defgroup USBD_MTP_Private_Functions
* @{
*/
/**
* @brief USBD_MTP_Init
* Initialize the MTP interface
* @param pdev: device instance
* @param cfgidx: Configuration index
* @retval status
*/
static uint8_t USBD_MTP_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
UNUSED(cfgidx);
USBD_MTP_HandleTypeDef *hmtp;
hmtp = (USBD_MTP_HandleTypeDef *)USBD_malloc(sizeof(USBD_MTP_HandleTypeDef));
if (hmtp == NULL)
{
pdev->pClassDataCmsit[pdev->classId] = NULL;
return (uint8_t)USBD_EMEM;
}
/* Setup the pClassData pointer */
pdev->pClassDataCmsit[pdev->classId] = (void *)hmtp;
pdev->pClassData = pdev->pClassDataCmsit[pdev->classId];
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
MTPInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
MTPOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
MTPCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
/* Initialize all variables */
(void)USBD_memset(hmtp, 0, sizeof(USBD_MTP_HandleTypeDef));
/* Setup the max packet size according to selected speed */
if (pdev->dev_speed == USBD_SPEED_HIGH)
{
hmtp->MaxPcktLen = MTP_DATA_MAX_HS_PACKET_SIZE;
}
else
{
hmtp->MaxPcktLen = MTP_DATA_MAX_FS_PACKET_SIZE;
}
/* Open EP IN */
(void)USBD_LL_OpenEP(pdev, MTPInEpAdd, USBD_EP_TYPE_BULK, hmtp->MaxPcktLen);
pdev->ep_in[MTPInEpAdd & 0xFU].is_used = 1U;
/* Open EP OUT */
(void)USBD_LL_OpenEP(pdev, MTPOutEpAdd, USBD_EP_TYPE_BULK, hmtp->MaxPcktLen);
pdev->ep_out[MTPOutEpAdd & 0xFU].is_used = 1U;
/* Open INTR EP IN */
(void)USBD_LL_OpenEP(pdev, MTPCmdEpAdd, USBD_EP_TYPE_INTR, MTP_CMD_PACKET_SIZE);
pdev->ep_in[MTPCmdEpAdd & 0xFU].is_used = 1U;
/* Init the MTP layer */
(void)USBD_MTP_STORAGE_Init(pdev);
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_MTP_DeInit
* DeInitialize the MTP layer
* @param pdev: device instance
* @param cfgidx: Configuration index
* @retval status
*/
static uint8_t USBD_MTP_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
UNUSED(cfgidx);
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this MTP class instance */
MTPInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
MTPOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
MTPCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
/* Close EP IN */
(void)USBD_LL_CloseEP(pdev, MTPInEpAdd);
pdev->ep_in[MTPInEpAdd & 0xFU].is_used = 0U;
/* Close EP OUT */
(void)USBD_LL_CloseEP(pdev, MTPOutEpAdd);
pdev->ep_out[MTPOutEpAdd & 0xFU].is_used = 0U;
/* Close EP Command */
(void)USBD_LL_CloseEP(pdev, MTPCmdEpAdd);
pdev->ep_in[MTPCmdEpAdd & 0xFU].is_used = 0U;
/* Free MTP Class Resources */
if (pdev->pClassDataCmsit[pdev->classId] != NULL)
{
/* De-Init the MTP layer */
(void)USBD_MTP_STORAGE_DeInit(pdev);
(void)USBD_free(pdev->pClassDataCmsit[pdev->classId]);
pdev->pClassDataCmsit[pdev->classId] = NULL;
pdev->pClassData = NULL;
}
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_MTP_Setup
* Handle the MTP specific requests
* @param pdev: instance
* @param req: usb requests
* @retval status
*/
static uint8_t USBD_MTP_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
USBD_StatusTypeDef ret = USBD_OK;
uint16_t len = 0U;
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this MTP class instance */
MTPOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (hmtp == NULL)
{
return (uint8_t)USBD_FAIL;
}
switch (req->bmRequest & USB_REQ_TYPE_MASK)
{
/* Class request */
case USB_REQ_TYPE_CLASS :
switch (req->bRequest)
{
case MTP_REQ_CANCEL:
len = MIN(hmtp->MaxPcktLen, req->wLength);
(void)USBD_CtlPrepareRx(pdev, (uint8_t *)(hmtp->rx_buff), len);
break;
case MTP_REQ_GET_EXT_EVENT_DATA:
break;
case MTP_REQ_RESET:
/* Stop low layer file system operations if any */
USBD_MTP_STORAGE_Cancel(pdev, MTP_PHASE_IDLE);
(void)USBD_LL_PrepareReceive(pdev, MTPOutEpAdd, (uint8_t *)&hmtp->rx_buff, hmtp->MaxPcktLen);
break;
case MTP_REQ_GET_DEVICE_STATUS:
switch (hmtp->MTP_ResponsePhase)
{
case MTP_READ_DATA :
len = 4U;
hmtp->dev_status = ((uint32_t)MTP_RESPONSE_DEVICE_BUSY << 16) | len;
break;
case MTP_RECEIVE_DATA :
len = 4U;
hmtp->dev_status = ((uint32_t)MTP_RESPONSE_TRANSACTION_CANCELLED << 16) | len;
break;
case MTP_PHASE_IDLE :
len = 4U;
hmtp->dev_status = ((uint32_t)MTP_RESPONSE_OK << 16) | len;
break;
default:
break;
}
(void)USBD_CtlSendData(pdev, (uint8_t *)&hmtp->dev_status, len);
break;
default:
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
break;
}
break;
/* Interface & Endpoint request */
case USB_REQ_TYPE_STANDARD:
switch (req->bRequest)
{
case USB_REQ_GET_INTERFACE :
if (pdev->dev_state == USBD_STATE_CONFIGURED)
{
hmtp->alt_setting = 0U;
(void)USBD_CtlSendData(pdev, (uint8_t *)&hmtp->alt_setting, 1U);
}
break;
case USB_REQ_SET_INTERFACE :
if (pdev->dev_state != USBD_STATE_CONFIGURED)
{
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
}
break;
case USB_REQ_CLEAR_FEATURE:
/* Re-activate the EP */
(void)USBD_LL_CloseEP(pdev, (uint8_t)req->wIndex);
if ((((uint8_t)req->wIndex) & 0x80U) == 0x80U)
{
(void)USBD_LL_OpenEP(pdev, ((uint8_t)req->wIndex), USBD_EP_TYPE_BULK, hmtp->MaxPcktLen);
}
else
{
(void)USBD_LL_OpenEP(pdev, ((uint8_t)req->wIndex), USBD_EP_TYPE_BULK, hmtp->MaxPcktLen);
}
break;
default:
break;
}
break;
default:
break;
}
return (uint8_t)ret;
}
/**
* @brief USBD_MTP_DataIn
* Data sent on non-control IN endpoint
* @param pdev: device instance
* @param epnum: endpoint number
* @retval status
*/
static uint8_t USBD_MTP_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
UNUSED(epnum);
USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint16_t len;
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this MTP class instance */
MTPInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
MTPOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (epnum == (MTPInEpAdd & 0x7FU))
{
switch (hmtp->MTP_ResponsePhase)
{
case MTP_RESPONSE_PHASE :
(void)USBD_MTP_STORAGE_SendContainer(pdev, REP_TYPE);
/* prepare to receive next operation */
len = MIN(hmtp->MaxPcktLen, pdev->request.wLength);
(void)USBD_LL_PrepareReceive(pdev, MTPOutEpAdd, (uint8_t *)&hmtp->rx_buff, len);
hmtp->MTP_ResponsePhase = MTP_PHASE_IDLE;
break;
case MTP_READ_DATA :
(void)USBD_MTP_STORAGE_ReadData(pdev);
/* prepare to receive next operation */
len = MIN(hmtp->MaxPcktLen, pdev->request.wLength);
(void)USBD_LL_PrepareReceive(pdev, MTPInEpAdd, (uint8_t *)&hmtp->rx_buff, len);
break;
case MTP_PHASE_IDLE :
/* prepare to receive next operation */
len = MIN(hmtp->MaxPcktLen, pdev->request.wLength);
(void)USBD_LL_PrepareReceive(pdev, MTPOutEpAdd, (uint8_t *)&hmtp->rx_buff, len);
break;
default:
break;
}
}
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_MTP_DataOut
* Data received on non-control Out endpoint
* @param pdev: device instance
* @param epnum: endpoint number
* @retval status
*/
static uint8_t USBD_MTP_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
UNUSED(epnum);
USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint16_t len;
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this MTP class instance */
MTPOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
(void)USBD_MTP_STORAGE_ReceiveOpt(pdev);
switch (hmtp->MTP_ResponsePhase)
{
case MTP_RESPONSE_PHASE :
if (hmtp->ResponseLength == MTP_CONT_HEADER_SIZE)
{
(void)USBD_MTP_STORAGE_SendContainer(pdev, REP_TYPE);
hmtp->MTP_ResponsePhase = MTP_PHASE_IDLE;
}
else
{
(void)USBD_MTP_STORAGE_SendContainer(pdev, DATA_TYPE);
}
break;
case MTP_READ_DATA :
(void)USBD_MTP_STORAGE_ReadData(pdev);
break;
case MTP_RECEIVE_DATA :
(void)USBD_MTP_STORAGE_ReceiveData(pdev);
/* prepare endpoint to receive operations */
len = MIN(hmtp->MaxPcktLen, pdev->request.wLength);
(void)USBD_LL_PrepareReceive(pdev, MTPOutEpAdd, (uint8_t *)&hmtp->rx_buff, len);
break;
case MTP_PHASE_IDLE :
/* prepare to receive next operation */
len = MIN(hmtp->MaxPcktLen, pdev->request.wLength);
(void)USBD_LL_PrepareReceive(pdev, MTPOutEpAdd, (uint8_t *)&hmtp->rx_buff, len);
break;
default:
break;
}
return (uint8_t)USBD_OK;
}
#ifndef USE_USBD_COMPOSITE
/**
* @brief USBD_MTP_GetHSCfgDesc
* Return configuration descriptor
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_MTP_GetHSCfgDesc(uint16_t *length)
{
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_MTP_CfgDesc, MTP_IN_EP);
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_MTP_CfgDesc, MTP_OUT_EP);
USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_MTP_CfgDesc, MTP_CMD_EP);
if (pEpInDesc != NULL)
{
pEpInDesc->wMaxPacketSize = MTP_DATA_MAX_HS_PACKET_SIZE;
}
if (pEpOutDesc != NULL)
{
pEpOutDesc->wMaxPacketSize = MTP_DATA_MAX_HS_PACKET_SIZE;
}
if (pEpCmdDesc != NULL)
{
pEpCmdDesc->bInterval = MTP_HS_BINTERVAL;
}
*length = (uint16_t)sizeof(USBD_MTP_CfgDesc);
return USBD_MTP_CfgDesc;
}
/**
* @brief USBD_MTP_GetFSCfgDesc
* Return configuration descriptor
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_MTP_GetFSCfgDesc(uint16_t *length)
{
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_MTP_CfgDesc, MTP_IN_EP);
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_MTP_CfgDesc, MTP_OUT_EP);
USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_MTP_CfgDesc, MTP_CMD_EP);
if (pEpInDesc != NULL)
{
pEpInDesc->wMaxPacketSize = MTP_DATA_MAX_FS_PACKET_SIZE;
}
if (pEpOutDesc != NULL)
{
pEpOutDesc->wMaxPacketSize = MTP_DATA_MAX_FS_PACKET_SIZE;
}
if (pEpCmdDesc != NULL)
{
pEpCmdDesc->bInterval = MTP_FS_BINTERVAL;
}
*length = (uint16_t)sizeof(USBD_MTP_CfgDesc);
return USBD_MTP_CfgDesc;
}
/**
* @brief USBD_MTP_GetOtherSpeedCfgDesc
* Return configuration descriptor
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_MTP_GetOtherSpeedCfgDesc(uint16_t *length)
{
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_MTP_CfgDesc, MTP_IN_EP);
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_MTP_CfgDesc, MTP_OUT_EP);
USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_MTP_CfgDesc, MTP_CMD_EP);
if (pEpInDesc != NULL)
{
pEpInDesc->wMaxPacketSize = MTP_DATA_MAX_FS_PACKET_SIZE;
}
if (pEpOutDesc != NULL)
{
pEpOutDesc->wMaxPacketSize = MTP_DATA_MAX_FS_PACKET_SIZE;
}
if (pEpCmdDesc != NULL)
{
pEpCmdDesc->bInterval = MTP_FS_BINTERVAL;
}
*length = (uint16_t)sizeof(USBD_MTP_CfgDesc);
return USBD_MTP_CfgDesc;
}
/**
* @brief USBD_MTP_GetDeviceQualifierDescriptor
* return Device Qualifier descriptor
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_MTP_GetDeviceQualifierDescriptor(uint16_t *length)
{
*length = (uint16_t)(sizeof(USBD_MTP_DeviceQualifierDesc));
return USBD_MTP_DeviceQualifierDesc;
}
#endif /* USE_USBD_COMPOSITE */
/**
* @brief USBD_MTP_RegisterInterface
* @param pdev: device instance
* @param fops: CD Interface callback
* @retval status
*/
uint8_t USBD_MTP_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_MTP_ItfTypeDef *fops)
{
if (fops == NULL)
{
return (uint8_t)USBD_FAIL;
}
pdev->pUserData[pdev->classId] = fops;
return (uint8_t)USBD_OK;
}
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,347 @@
/**
******************************************************************************
* @file usbd_mtp_if.c
* @author MCD Application Team
* @brief Source file for USBD MTP file list_files.
******************************************************************************
* @attention
*
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_mtp_if_template.h"
/* Private typedef -----------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/*
static FILE MyFile;
static FATFS SDFatFs;
static char SDPath[4];
static FolderLevel Fold_Lvl;
static FOLD_INFTypeDef FoldStruct;
static FILE_INFTypeDef FileStruct;
static SD_Object_TypeDef sd_object;
*/
extern USBD_HandleTypeDef USBD_Device;
uint32_t idx[200];
uint32_t parent;
/* static char path[255]; */
uint32_t sc_buff[MTP_IF_SCRATCH_BUFF_SZE / 4U];
uint32_t sc_len = 0U;
uint32_t pckt_cnt = 1U;
uint32_t foldsize;
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
static uint8_t USBD_MTP_Itf_Init(void);
static uint8_t USBD_MTP_Itf_DeInit(void);
static uint32_t USBD_MTP_Itf_ReadData(uint32_t Param1, uint8_t *buff, MTP_DataLengthTypeDef *data_length);
static uint16_t USBD_MTP_Itf_Create_NewObject(MTP_ObjectInfoTypeDef ObjectInfo, uint32_t objhandle);
static uint32_t USBD_MTP_Itf_GetIdx(uint32_t Param3, uint32_t *obj_handle);
static uint32_t USBD_MTP_Itf_GetParentObject(uint32_t Param);
static uint16_t USBD_MTP_Itf_GetObjectFormat(uint32_t Param);
static uint8_t USBD_MTP_Itf_GetObjectName_len(uint32_t Param);
static void USBD_MTP_Itf_GetObjectName(uint32_t Param, uint8_t obj_len, uint16_t *buf);
static uint32_t USBD_MTP_Itf_GetObjectSize(uint32_t Param);
static uint64_t USBD_MTP_Itf_GetMaxCapability(void);
static uint64_t USBD_MTP_Itf_GetFreeSpaceInBytes(void);
static uint32_t USBD_MTP_Itf_GetNewIndex(uint16_t objformat);
static void USBD_MTP_Itf_WriteData(uint16_t len, uint8_t *buff);
static uint32_t USBD_MTP_Itf_GetContainerLength(uint32_t Param1);
static uint16_t USBD_MTP_Itf_DeleteObject(uint32_t Param1);
static void USBD_MTP_Itf_Cancel(uint32_t Phase);
/* static uint32_t USBD_MTP_Get_idx_to_delete(uint32_t Param, uint8_t *tab); */
USBD_MTP_ItfTypeDef USBD_MTP_fops =
{
USBD_MTP_Itf_Init,
USBD_MTP_Itf_DeInit,
USBD_MTP_Itf_ReadData,
USBD_MTP_Itf_Create_NewObject,
USBD_MTP_Itf_GetIdx,
USBD_MTP_Itf_GetParentObject,
USBD_MTP_Itf_GetObjectFormat,
USBD_MTP_Itf_GetObjectName_len,
USBD_MTP_Itf_GetObjectName,
USBD_MTP_Itf_GetObjectSize,
USBD_MTP_Itf_GetMaxCapability,
USBD_MTP_Itf_GetFreeSpaceInBytes,
USBD_MTP_Itf_GetNewIndex,
USBD_MTP_Itf_WriteData,
USBD_MTP_Itf_GetContainerLength,
USBD_MTP_Itf_DeleteObject,
USBD_MTP_Itf_Cancel,
sc_buff,
MTP_IF_SCRATCH_BUFF_SZE,
};
/* Private functions ---------------------------------------------------------*/
/**
* @brief USBD_MTP_Itf_Init
* Initialize the file system Layer
* @param None
* @retval status value
*/
static uint8_t USBD_MTP_Itf_Init(void)
{
return 0;
}
/**
* @brief USBD_MTP_Itf_DeInit
* Uninitialize the file system Layer
* @param None
* @retval status value
*/
static uint8_t USBD_MTP_Itf_DeInit(void)
{
return 0;
}
/**
* @brief USBD_MTP_Itf_GetIdx
* Get all object handle
* @param Param3: current object handle
* @param obj_handle: all objects handle (subfolders/files) in current object
* @retval number of object handle in current object
*/
static uint32_t USBD_MTP_Itf_GetIdx(uint32_t Param3, uint32_t *obj_handle)
{
uint32_t count = 0U;
UNUSED(Param3);
UNUSED(obj_handle);
return count;
}
/**
* @brief USBD_MTP_Itf_GetParentObject
* Get parent object
* @param Param: object handle (object index)
* @retval parent object
*/
static uint32_t USBD_MTP_Itf_GetParentObject(uint32_t Param)
{
uint32_t parentobj = 0U;
UNUSED(Param);
return parentobj;
}
/**
* @brief USBD_MTP_Itf_GetObjectFormat
* Get object format
* @param Param: object handle (object index)
* @retval object format
*/
static uint16_t USBD_MTP_Itf_GetObjectFormat(uint32_t Param)
{
uint16_t objformat = 0U;
UNUSED(Param);
return objformat;
}
/**
* @brief USBD_MTP_Itf_GetObjectName_len
* Get object name length
* @param Param: object handle (object index)
* @retval object name length
*/
static uint8_t USBD_MTP_Itf_GetObjectName_len(uint32_t Param)
{
uint8_t obj_len = 0U;
UNUSED(Param);
return obj_len;
}
/**
* @brief USBD_MTP_Itf_GetObjectName
* Get object name
* @param Param: object handle (object index)
* @param obj_len: length of object name
* @param buf: pointer to object name
* @retval object size in SD card
*/
static void USBD_MTP_Itf_GetObjectName(uint32_t Param, uint8_t obj_len, uint16_t *buf)
{
UNUSED(Param);
UNUSED(obj_len);
UNUSED(buf);
return;
}
/**
* @brief USBD_MTP_Itf_GetObjectSize
* Get size of current object
* @param Param: object handle (object index)
* @retval object size in SD card
*/
static uint32_t USBD_MTP_Itf_GetObjectSize(uint32_t Param)
{
uint32_t ObjCompSize = 0U;
UNUSED(Param);
return ObjCompSize;
}
/**
* @brief USBD_MTP_Itf_Create_NewObject
* Create new object in SD card and store necessary information for future use
* @param ObjectInfo: object information to use
* @param objhandle: object handle (object index)
* @retval None
*/
static uint16_t USBD_MTP_Itf_Create_NewObject(MTP_ObjectInfoTypeDef ObjectInfo, uint32_t objhandle)
{
uint16_t rep_code = 0U;
UNUSED(ObjectInfo);
UNUSED(objhandle);
return rep_code;
}
/**
* @brief USBD_MTP_Itf_GetMaxCapability
* Get max capability in SD card
* @param None
* @retval max capability
*/
static uint64_t USBD_MTP_Itf_GetMaxCapability(void)
{
uint64_t max_cap = 0U;
return max_cap;
}
/**
* @brief USBD_MTP_Itf_GetFreeSpaceInBytes
* Get free space in bytes in SD card
* @param None
* @retval free space in bytes
*/
static uint64_t USBD_MTP_Itf_GetFreeSpaceInBytes(void)
{
uint64_t f_space_inbytes = 0U;
return f_space_inbytes;
}
/**
* @brief USBD_MTP_Itf_GetNewIndex
* Create new object handle
* @param objformat: object format
* @retval object handle
*/
static uint32_t USBD_MTP_Itf_GetNewIndex(uint16_t objformat)
{
uint32_t n_index = 0U;
UNUSED(objformat);
return n_index;
}
/**
* @brief USBD_MTP_Itf_WriteData
* Write file data to SD card
* @param len: size of data to write
* @param buff: data to write in SD card
* @retval None
*/
static void USBD_MTP_Itf_WriteData(uint16_t len, uint8_t *buff)
{
UNUSED(len);
UNUSED(buff);
return;
}
/**
* @brief USBD_MTP_Itf_GetContainerLength
* Get length of generic container
* @param Param1: object handle
* @retval length of generic container
*/
static uint32_t USBD_MTP_Itf_GetContainerLength(uint32_t Param1)
{
uint32_t length = 0U;
UNUSED(Param1);
return length;
}
/**
* @brief USBD_MTP_Itf_DeleteObject
* delete object from SD card
* @param Param1: object handle (file/folder index)
* @retval response code
*/
static uint16_t USBD_MTP_Itf_DeleteObject(uint32_t Param1)
{
uint16_t rep_code = 0U;
UNUSED(Param1);
return rep_code;
}
/**
* @brief USBD_MTP_Get_idx_to_delete
* Get all files/foldres index to delete with descending order ( max depth)
* @param Param: object handle (file/folder index)
* @param tab: pointer to list of files/folders to delete
* @retval Number of files/folders to delete
*/
/* static uint32_t USBD_MTP_Get_idx_to_delete(uint32_t Param, uint8_t *tab)
{
uint32_t cnt = 0U;
return cnt;
}
*/
/**
* @brief USBD_MTP_Itf_ReadData
* Read data from SD card
* @param Param1: object handle
* @param buff: pointer to data to be read
* @param temp_length: current data size read
* @retval necessary information for next read/finish reading
*/
static uint32_t USBD_MTP_Itf_ReadData(uint32_t Param1, uint8_t *buff, MTP_DataLengthTypeDef *data_length)
{
UNUSED(Param1);
UNUSED(buff);
UNUSED(data_length);
return 0U;
}
/**
* @brief USBD_MTP_Itf_Cancel
* Close opened folder/file while cancelling transaction
* @param MTP_ResponsePhase: MTP current state
* @retval None
*/
static void USBD_MTP_Itf_Cancel(uint32_t Phase)
{
UNUSED(Phase);
/* Make sure to close open file while canceling transaction */
return;
}

1267
Class/MTP/Src/usbd_mtp_opt.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,472 @@
/**
******************************************************************************
* @file usbd_mtp_storage.c
* @author MCD Application Team
* @brief This file provides all the transfer command functions for MTP
******************************************************************************
* @attention
*
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_mtp_storage.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
extern uint8_t MTPInEpAdd;
extern uint8_t MTPOutEpAdd;
/* Private variables ---------------------------------------------------------*/
static MTP_DataLengthTypeDef MTP_DataLength;
static MTP_READ_DATA_STATUS ReadDataStatus;
/* Private function prototypes -----------------------------------------------*/
static uint8_t USBD_MTP_STORAGE_DecodeOperations(USBD_HandleTypeDef *pdev);
static uint8_t USBD_MTP_STORAGE_ReceiveContainer(USBD_HandleTypeDef *pdev, uint32_t *pDst, uint32_t len);
static uint8_t USBD_MTP_STORAGE_SendData(USBD_HandleTypeDef *pdev, uint8_t *buf, uint32_t len);
/* Private functions ---------------------------------------------------------*/
/**
* @}
*/
/**
* @brief USBD_MTP_STORAGE_Init
* Initialize the MTP USB Layer
* @param pdev: device instance
* @retval status value
*/
uint8_t USBD_MTP_STORAGE_Init(USBD_HandleTypeDef *pdev)
{
USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
MTPOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
/* Initialize the HW layyer of the file system */
(void)((USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init();
/* Prepare EP to Receive First Operation */
(void)USBD_LL_PrepareReceive(pdev, MTPOutEpAdd, (uint8_t *)&hmtp->rx_buff,
hmtp->MaxPcktLen);
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_MTP_STORAGE_DeInit
* Uninitialize the MTP Machine
* @param pdev: device instance
* @retval status value
*/
uint8_t USBD_MTP_STORAGE_DeInit(USBD_HandleTypeDef *pdev)
{
USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
/* DeInit physical Interface components */
hmtp->MTP_SessionState = MTP_SESSION_NOT_OPENED;
/* Stop low layer file system operations if any */
USBD_MTP_STORAGE_Cancel(pdev, MTP_PHASE_IDLE);
/* Free low layer file system resources */
(void)((USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit();
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_MTP_STORAGE_ReadData
* Read data from device objects and send it to the host
* @param pdev: device instance
* @retval status value
*/
uint8_t USBD_MTP_STORAGE_ReadData(USBD_HandleTypeDef *pdev)
{
USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint32_t *data_buff;
/* Get the data buffer pointer from the low layer interface */
data_buff = ((USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId])->ScratchBuff;
switch (ReadDataStatus)
{
case READ_FIRST_DATA:
/* Reset the data length */
MTP_DataLength.temp_length = 0U;
/* Perform the low layer read operation on the scratch buffer */
(void)((USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId])->ReadData(hmtp->OperationsContainer.Param1,
(uint8_t *)data_buff, &MTP_DataLength);
/* Add the container header to the data buffer */
(void)USBD_memcpy((uint8_t *)data_buff, (uint8_t *)&hmtp->GenericContainer, MTP_CONT_HEADER_SIZE);
/* Start USB data transmission to the host */
(void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)data_buff,
MTP_DataLength.readbytes + MTP_CONT_HEADER_SIZE);
/* Check if this will be the last packet to send ? */
if (MTP_DataLength.readbytes < ((uint32_t)hmtp->MaxPcktLen - MTP_CONT_HEADER_SIZE))
{
/* Move to response phase */
hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE;
}
else
{
/* Continue to the next packets sending */
ReadDataStatus = READ_REST_OF_DATA;
}
break;
case READ_REST_OF_DATA:
/* Perform the low layer read operation on the scratch buffer */
(void)((USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId])->ReadData(hmtp->OperationsContainer.Param1,
(uint8_t *)data_buff, &MTP_DataLength);
/* Check if more data need to be sent */
if (MTP_DataLength.temp_length == MTP_DataLength.totallen)
{
/* Start USB data transmission to the host */
(void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)data_buff, MTP_DataLength.readbytes);
/* Move to response phase */
hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE;
/* Reset the stat machine */
ReadDataStatus = READ_FIRST_DATA;
}
else
{
/* Start USB data transmission to the host */
(void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)data_buff, MTP_DataLength.readbytes);
/* Keep the state machine into sending next packet of data */
ReadDataStatus = READ_REST_OF_DATA;
}
break;
default:
break;
}
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_MTP_STORAGE_SendContainer
* Send generic container to the host
* @param pdev: device instance
* @retval status value
*/
uint8_t USBD_MTP_STORAGE_SendContainer(USBD_HandleTypeDef *pdev, MTP_CONTAINER_TYPE CONT_TYPE)
{
USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
switch (CONT_TYPE)
{
case DATA_TYPE:
/* send header + data : hmtp->ResponseLength = header size + data size */
(void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)&hmtp->GenericContainer, hmtp->ResponseLength);
break;
case REP_TYPE:
/* send header without data */
hmtp->GenericContainer.code = (uint16_t)hmtp->ResponseCode;
hmtp->ResponseLength = MTP_CONT_HEADER_SIZE;
hmtp->GenericContainer.length = hmtp->ResponseLength;
hmtp->GenericContainer.type = MTP_CONT_TYPE_RESPONSE;
(void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)&hmtp->GenericContainer, hmtp->ResponseLength);
break;
default:
break;
}
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_MTP_STORAGE_ReceiveOpt
* Data length Packet Received from host
* @param pdev: device instance
* @retval status value
*/
uint8_t USBD_MTP_STORAGE_ReceiveOpt(USBD_HandleTypeDef *pdev)
{
USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint32_t *pMsgBuffer;
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
MTPOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
MTP_DataLength.rx_length = USBD_GetRxCount(pdev, MTPOutEpAdd);
switch (hmtp->RECEIVE_DATA_STATUS)
{
case RECEIVE_REST_OF_DATA:
/* we don't need to do anything here because we receive only data without operation header*/
break;
case RECEIVE_FIRST_DATA:
/* Expected Data Length Packet Received */
pMsgBuffer = (uint32_t *) &hmtp->OperationsContainer;
/* Fill hmtp->OperationsContainer Data Buffer from USB Buffer */
(void)USBD_MTP_STORAGE_ReceiveContainer(pdev, pMsgBuffer, MTP_DataLength.rx_length);
break;
default:
/* Expected Data Length Packet Received */
pMsgBuffer = (uint32_t *) &hmtp->OperationsContainer;
/* Fill hmtp->OperationsContainer Data Buffer from USB Buffer */
(void)USBD_MTP_STORAGE_ReceiveContainer(pdev, pMsgBuffer, MTP_DataLength.rx_length);
(void)USBD_MTP_STORAGE_DecodeOperations(pdev);
break;
}
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_MTP_STORAGE_ReceiveData
* Receive objects or object info from host
* @param pdev: device instance
* @retval status value
*/
uint8_t USBD_MTP_STORAGE_ReceiveData(USBD_HandleTypeDef *pdev)
{
USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
switch (hmtp->RECEIVE_DATA_STATUS)
{
case RECEIVE_COMMAND_DATA :
if (hmtp->OperationsContainer.type == MTP_CONT_TYPE_COMMAND)
{
MTP_DataLength.temp_length = 0;
MTP_DataLength.prv_len = 0;
(void)USBD_MTP_STORAGE_DecodeOperations(pdev);
}
break;
case RECEIVE_FIRST_DATA :
if (hmtp->OperationsContainer.type == MTP_CONT_TYPE_DATA)
{
MTP_DataLength.totallen = hmtp->OperationsContainer.length;
MTP_DataLength.temp_length = MTP_DataLength.rx_length;
MTP_DataLength.rx_length = MTP_DataLength.temp_length - MTP_CONT_HEADER_SIZE;
(void)USBD_MTP_STORAGE_DecodeOperations(pdev);
if (MTP_DataLength.temp_length < hmtp->MaxPcktLen) /* we received all data, we don't need to go to next state */
{
hmtp->RECEIVE_DATA_STATUS = SEND_RESPONSE;
(void)USBD_MTP_STORAGE_DecodeOperations(pdev);
/* send response header after receiving all data successfully */
(void)USBD_MTP_STORAGE_SendContainer(pdev, DATA_TYPE);
}
}
break;
case RECEIVE_REST_OF_DATA :
MTP_DataLength.prv_len = MTP_DataLength.temp_length - MTP_CONT_HEADER_SIZE;
(void)USBD_MTP_STORAGE_DecodeOperations(pdev);
MTP_DataLength.temp_length = MTP_DataLength.temp_length + MTP_DataLength.rx_length;
if (MTP_DataLength.temp_length == MTP_DataLength.totallen) /* we received all data*/
{
hmtp->RECEIVE_DATA_STATUS = SEND_RESPONSE;
(void)USBD_MTP_STORAGE_DecodeOperations(pdev);
/* send response header after receiving all data successfully */
(void)USBD_MTP_STORAGE_SendContainer(pdev, DATA_TYPE);
}
break;
default :
break;
}
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_MTP_STORAGE_DecodeOperations
* Parse the operations and Process operations
* @param pdev: device instance
* @retval status value
*/
static uint8_t USBD_MTP_STORAGE_DecodeOperations(USBD_HandleTypeDef *pdev)
{
USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
switch (hmtp->OperationsContainer.code)
{
case MTP_OP_GET_DEVICE_INFO:
USBD_MTP_OPT_GetDeviceInfo(pdev);
hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE;
break;
case MTP_OP_OPEN_SESSION:
USBD_MTP_OPT_CreateObjectHandle(pdev);
hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE;
break;
case MTP_OP_GET_STORAGE_IDS:
USBD_MTP_OPT_GetStorageIDS(pdev);
hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE;
break;
case MTP_OP_GET_STORAGE_INFO:
USBD_MTP_OPT_GetStorageInfo(pdev);
hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE;
break;
case MTP_OP_GET_OBJECT_HANDLES:
USBD_MTP_OPT_GetObjectHandle(pdev);
hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE;
break;
case MTP_OP_GET_OBJECT_INFO:
USBD_MTP_OPT_GetObjectInfo(pdev);
hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE;
break;
case MTP_OP_GET_OBJECT_PROP_REFERENCES:
USBD_MTP_OPT_GetObjectReferences(pdev);
hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE;
break;
case MTP_OP_GET_OBJECT_PROPS_SUPPORTED:
USBD_MTP_OPT_GetObjectPropSupp(pdev);
hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE;
break;
case MTP_OP_GET_OBJECT_PROP_DESC:
USBD_MTP_OPT_GetObjectPropDesc(pdev);
hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE;
break;
case MTP_OP_GET_OBJECT_PROPLIST:
USBD_MTP_OPT_GetObjectPropList(pdev);
hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE;
break;
case MTP_OP_GET_OBJECT_PROP_VALUE:
USBD_MTP_OPT_GetObjectPropValue(pdev);
hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE;
break;
case MTP_OP_GET_DEVICE_PROP_DESC:
USBD_MTP_OPT_GetDevicePropDesc(pdev);
hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE;
break;
case MTP_OP_GET_OBJECT:
USBD_MTP_OPT_GetObject(pdev);
hmtp->MTP_ResponsePhase = MTP_READ_DATA;
break;
case MTP_OP_SEND_OBJECT_INFO:
USBD_MTP_OPT_SendObjectInfo(pdev, (uint8_t *)(hmtp->rx_buff), MTP_DataLength.prv_len);
hmtp->MTP_ResponsePhase = MTP_RECEIVE_DATA;
break;
case MTP_OP_SEND_OBJECT:
USBD_MTP_OPT_SendObject(pdev, (uint8_t *)(hmtp->rx_buff), MTP_DataLength.rx_length);
hmtp->MTP_ResponsePhase = MTP_RECEIVE_DATA;
break;
case MTP_OP_DELETE_OBJECT:
USBD_MTP_OPT_DeleteObject(pdev);
hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE;
break;
default:
break;
}
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_MTP_STORAGE_ReceiveContainer
* Receive the Data from USB BulkOut Buffer to Pointer
* @param pdev: device instance
* @param pDst: destination address to copy the buffer
* @param len: length of data to copy
* @retval status value
*/
static uint8_t USBD_MTP_STORAGE_ReceiveContainer(USBD_HandleTypeDef *pdev,
uint32_t *pDst, uint32_t len)
{
USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint32_t Counter;
uint32_t *pdst = pDst;
for (Counter = 0; Counter < len; Counter++)
{
*pdst = (hmtp->rx_buff[Counter]);
pdst++;
}
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_MTP_STORAGE_Cancel
* Reinitialize all states and cancel transfer through Bulk transfer
* @param pdev: device instance
* @param MTP_ResponsePhase: MTP current state
* @retval None
*/
void USBD_MTP_STORAGE_Cancel(USBD_HandleTypeDef *pdev,
MTP_ResponsePhaseTypeDef MTP_ResponsePhase)
{
USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
hmtp->MTP_ResponsePhase = MTP_PHASE_IDLE;
ReadDataStatus = READ_FIRST_DATA;
hmtp->RECEIVE_DATA_STATUS = RECEIVE_IDLE_STATE;
if (MTP_ResponsePhase == MTP_RECEIVE_DATA)
{
((USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId])->Cancel(1U);
}
else
{
((USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId])->Cancel(0U);
}
}
/**
* @brief USBD_MTP_STORAGE_SendData
* Send the data on bulk-in EP
* @param pdev: device instance
* @param buf: pointer to data buffer
* @param len: Data Length
* @retval status value
*/
static uint8_t USBD_MTP_STORAGE_SendData(USBD_HandleTypeDef *pdev, uint8_t *buf,
uint32_t len)
{
USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint32_t length = MIN(hmtp->GenericContainer.length, len);
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
MTPInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
(void)USBD_LL_Transmit(pdev, MTPInEpAdd, buf, length);
return (uint8_t)USBD_OK;
}

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -114,8 +113,7 @@ typedef struct
__IO uint32_t TxState;
__IO uint32_t RxState;
}
USBD_PRNT_HandleTypeDef;
} USBD_PRNT_HandleTypeDef;
@@ -161,4 +159,3 @@ uint8_t USBD_PRNT_ReceivePacket(USBD_HandleTypeDef *pdev);
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* http://www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -42,4 +41,3 @@ extern USBD_PRNT_ItfTypeDef USBD_PRNT_Template_fops;
#endif /* __USBD_PRNT_IF_TEMPLATE_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -10,6 +10,17 @@
* - Command OUT transfer (class requests management)
* - Error management
*
******************************************************************************
* @attention
*
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
* @verbatim
*
* ===================================================================
@@ -37,17 +48,6 @@
* @endverbatim
*
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* BSPDependencies
@@ -102,27 +102,13 @@ static uint8_t USBD_PRNT_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *r
static uint8_t USBD_PRNT_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
static uint8_t USBD_PRNT_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
#ifndef USE_USBD_COMPOSITE
static uint8_t *USBD_PRNT_GetFSCfgDesc(uint16_t *length);
static uint8_t *USBD_PRNT_GetHSCfgDesc(uint16_t *length);
static uint8_t *USBD_PRNT_GetOtherSpeedCfgDesc(uint16_t *length);
static uint8_t *USBD_PRNT_GetOtherSpeedCfgDesc(uint16_t *length);
uint8_t *USBD_PRNT_GetDeviceQualifierDescriptor(uint16_t *length);
/* USB Standard Device Descriptor */
__ALIGN_BEGIN static uint8_t USBD_PRNT_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
{
USB_LEN_DEV_QUALIFIER_DESC,
USB_DESC_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
0x00,
0x00,
0x00,
0x40,
0x01,
0x00,
};
#endif /* USE_USBD_COMPOSITE */
/**
* @}
*/
@@ -144,14 +130,22 @@ USBD_ClassTypeDef USBD_PRNT =
NULL,
NULL,
NULL,
#ifdef USE_USBD_COMPOSITE
NULL,
NULL,
NULL,
NULL,
#else
USBD_PRNT_GetHSCfgDesc,
USBD_PRNT_GetFSCfgDesc,
USBD_PRNT_GetOtherSpeedCfgDesc,
USBD_PRNT_GetDeviceQualifierDescriptor,
#endif /* USE_USBD_COMPOSITE */
};
#ifndef USE_USBD_COMPOSITE
/* USB PRNT device Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_PRNT_CfgHSDesc[] __ALIGN_END =
__ALIGN_BEGIN static uint8_t USBD_PRNT_CfgDesc[] __ALIGN_END =
{
/*Configuration Descriptor*/
0x09, /* bLength: Configuration Descriptor size */
@@ -165,56 +159,7 @@ __ALIGN_BEGIN static uint8_t USBD_PRNT_CfgHSDesc[] __ALIGN_END =
0xC0, /* bmAttributes: Self Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
USBD_MAX_POWER, /* MaxPower in mA */
/* Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints: 2 endpoints used */
0x07, /* bInterfaceClass: Communication Interface Class */
0x01, /* bInterfaceSubClass: Abstract Control Model */
USB_PRNT_BIDIRECTIONAL, /* bDeviceProtocol */
0x00, /* iInterface */
/* Endpoint IN Descriptor */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
PRNT_IN_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
LOBYTE(PRNT_DATA_HS_IN_PACKET_SIZE), /* wMaxPacketSize */
HIBYTE(PRNT_DATA_HS_IN_PACKET_SIZE),
0x00, /* bInterval */
/* Endpoint OUT Descriptor */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
PRNT_OUT_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
LOBYTE(PRNT_DATA_HS_OUT_PACKET_SIZE),/* wMaxPacketSize */
HIBYTE(PRNT_DATA_HS_OUT_PACKET_SIZE),
0x00 /* bInterval */
};
/* USB PRNT device Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_PRNT_CfgFSDesc[] __ALIGN_END =
{
/*Configuration Descriptor*/
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
USB_PRNT_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */
0x00,
0x01, /* bNumInterfaces: 1 interface */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
#if (USBD_SELF_POWERED == 1U)
0xC0, /* bmAttributes: Self Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
#endif /* USBD_SELF_POWERED */
USBD_MAX_POWER, /* MaxPower in mA */
/*Interface Descriptor */
@@ -247,52 +192,24 @@ __ALIGN_BEGIN static uint8_t USBD_PRNT_CfgFSDesc[] __ALIGN_END =
0x00 /* bInterval */
};
__ALIGN_BEGIN static uint8_t USBD_PRNT_OtherSpeedCfgDesc[] __ALIGN_END =
/* USB Standard Device Descriptor */
__ALIGN_BEGIN static uint8_t USBD_PRNT_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
{
/*Configuration Descriptor*/
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
USB_PRNT_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */
USB_LEN_DEV_QUALIFIER_DESC,
USB_DESC_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
0x00,
0x00,
0x00,
0x40,
0x01,
0x00,
0x01, /* bNumInterfaces: 1 interface */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
#if (USBD_SELF_POWERED == 1U)
0xC0, /* bmAttributes: Self Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
USBD_MAX_POWER, /* MaxPower in mA */
/*Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints: 2 endpoints used */
0x07, /* bInterfaceClass: Communication Interface Class */
0x01, /* bInterfaceSubClass: Abstract Control Model */
USB_PRNT_BIDIRECTIONAL, /* bDeviceProtocol */
0x00, /* iInterface */
/*Endpoint IN Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
PRNT_IN_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
LOBYTE(PRNT_DATA_FS_IN_PACKET_SIZE), /* wMaxPacketSize */
HIBYTE(PRNT_DATA_FS_IN_PACKET_SIZE),
0x00, /* bInterval */
/*Endpoint OUT Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
PRNT_OUT_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
LOBYTE(PRNT_DATA_FS_OUT_PACKET_SIZE),/* wMaxPacketSize */
HIBYTE(PRNT_DATA_FS_OUT_PACKET_SIZE),
0x00 /* bInterval */
};
#endif /* USE_USBD_COMPOSITE */
static uint8_t PRNTInEpAdd = PRNT_IN_EP;
static uint8_t PRNTOutEpAdd = PRNT_OUT_EP;
/**
* @}
@@ -315,16 +232,26 @@ static uint8_t USBD_PRNT_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
USBD_PRNT_HandleTypeDef *hPRNT;
uint16_t mps;
hPRNT = (USBD_PRNT_HandleTypeDef *)USBD_malloc(sizeof(USBD_PRNT_HandleTypeDef));
if (hPRNT == NULL)
{
pdev->pClassData = NULL;
pdev->pClassDataCmsit[pdev->classId] = NULL;
return (uint8_t)USBD_EMEM;
}
(void)USBD_memset(hPRNT, 0, sizeof(USBD_PRNT_HandleTypeDef));
/* Setup the pClassData pointer */
pdev->pClassData = (void *)hPRNT;
pdev->pClassDataCmsit[pdev->classId] = (void *)hPRNT;
pdev->pClassData = pdev->pClassDataCmsit[pdev->classId];
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
PRNTInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
PRNTOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
/* Setup the max packet size according to selected speed */
if (pdev->dev_speed == USBD_SPEED_HIGH)
@@ -337,22 +264,29 @@ static uint8_t USBD_PRNT_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
}
/* Open EP IN */
(void)USBD_LL_OpenEP(pdev, PRNT_IN_EP, USBD_EP_TYPE_BULK, mps);
(void)USBD_LL_OpenEP(pdev, PRNTInEpAdd, USBD_EP_TYPE_BULK, mps);
/* Set endpoint as used */
pdev->ep_in[PRNT_IN_EP & 0xFU].is_used = 1U;
pdev->ep_in[PRNTInEpAdd & 0xFU].is_used = 1U;
/* Open EP OUT */
(void)USBD_LL_OpenEP(pdev, PRNT_OUT_EP, USBD_EP_TYPE_BULK, mps);
(void)USBD_LL_OpenEP(pdev, PRNTOutEpAdd, USBD_EP_TYPE_BULK, mps);
/* Set endpoint as used */
pdev->ep_out[PRNT_OUT_EP & 0xFU].is_used = 1U;
pdev->ep_out[PRNTOutEpAdd & 0xFU].is_used = 1U;
hPRNT->RxBuffer = NULL;
/* Init physical Interface components */
((USBD_PRNT_ItfTypeDef *)pdev->pUserData)->Init();
((USBD_PRNT_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init();
if (hPRNT->RxBuffer == NULL)
{
return (uint8_t)USBD_EMEM;
}
/* Prepare Out endpoint to receive next packet */
(void)USBD_LL_PrepareReceive(pdev, PRNT_OUT_EP, hPRNT->RxBuffer, mps);
(void)USBD_LL_PrepareReceive(pdev, PRNTOutEpAdd, hPRNT->RxBuffer, mps);
/* End of initialization phase */
return (uint8_t)USBD_OK;
@@ -369,19 +303,26 @@ static uint8_t USBD_PRNT_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
UNUSED(cfgidx);
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
PRNTInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
PRNTOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
/* Close EP IN */
(void)USBD_LL_CloseEP(pdev, PRNT_IN_EP);
pdev->ep_in[PRNT_IN_EP & 0xFU].is_used = 0U;
(void)USBD_LL_CloseEP(pdev, PRNTInEpAdd);
pdev->ep_in[PRNTInEpAdd & 0xFU].is_used = 0U;
/* Close EP OUT */
(void)USBD_LL_CloseEP(pdev, PRNT_OUT_EP);
pdev->ep_out[PRNT_OUT_EP & 0xFU].is_used = 0U;
(void)USBD_LL_CloseEP(pdev, PRNTOutEpAdd);
pdev->ep_out[PRNTOutEpAdd & 0xFU].is_used = 0U;
/* DeInit physical Interface components */
if (pdev->pClassData != NULL)
if (pdev->pClassDataCmsit[pdev->classId] != NULL)
{
((USBD_PRNT_ItfTypeDef *)pdev->pUserData)->DeInit();
(void)USBD_free(pdev->pClassData);
((USBD_PRNT_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit();
(void)USBD_free(pdev->pClassDataCmsit[pdev->classId]);
pdev->pClassDataCmsit[pdev->classId] = NULL;
pdev->pClassData = NULL;
}
@@ -397,8 +338,8 @@ static uint8_t USBD_PRNT_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
*/
static uint8_t USBD_PRNT_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *)pdev->pClassData;
USBD_PRNT_ItfTypeDef *hPRNTitf = (USBD_PRNT_ItfTypeDef *)pdev->pUserData;
USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
USBD_PRNT_ItfTypeDef *hPRNTitf = (USBD_PRNT_ItfTypeDef *)pdev->pUserData[pdev->classId];
USBD_StatusTypeDef ret = USBD_OK;
uint16_t status_info = 0U;
@@ -495,7 +436,7 @@ static uint8_t USBD_PRNT_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *r
*/
static uint8_t USBD_PRNT_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *)pdev->pClassData;
USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
PCD_HandleTypeDef *hpcd = pdev->pData;
if (hPRNT == NULL)
@@ -503,11 +444,11 @@ static uint8_t USBD_PRNT_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
return (uint8_t)USBD_FAIL;
}
if ((pdev->ep_in[epnum].total_length > 0U) &&
((pdev->ep_in[epnum].total_length % hpcd->IN_ep[epnum].maxpacket) == 0U))
if ((pdev->ep_in[epnum & 0xFU].total_length > 0U) &&
((pdev->ep_in[epnum & 0xFU].total_length % hpcd->IN_ep[epnum & 0xFU].maxpacket) == 0U))
{
/* Update the packet total length */
pdev->ep_in[epnum].total_length = 0U;
pdev->ep_in[epnum & 0xFU].total_length = 0U;
/* Send ZLP */
(void) USBD_LL_Transmit(pdev, epnum, NULL, 0U);
@@ -528,7 +469,7 @@ static uint8_t USBD_PRNT_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
*/
static uint8_t USBD_PRNT_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *)pdev->pClassData;
USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hPRNT == NULL)
{
@@ -540,11 +481,12 @@ static uint8_t USBD_PRNT_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
/* USB data will be immediately processed, this allow next USB traffic being
NAKed till the end of the application Xfer */
((USBD_PRNT_ItfTypeDef *)pdev->pUserData)->Receive(hPRNT->RxBuffer, &hPRNT->RxLength);
((USBD_PRNT_ItfTypeDef *)pdev->pUserData[pdev->classId])->Receive(hPRNT->RxBuffer, &hPRNT->RxLength);
return (uint8_t)USBD_OK;
}
#ifndef USE_USBD_COMPOSITE
/**
* @brief USBD_PRNT_GetFSCfgDesc
* Return configuration descriptor
@@ -553,8 +495,21 @@ static uint8_t USBD_PRNT_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
*/
static uint8_t *USBD_PRNT_GetFSCfgDesc(uint16_t *length)
{
*length = (uint16_t) sizeof(USBD_PRNT_CfgFSDesc);
return USBD_PRNT_CfgFSDesc;
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_PRNT_CfgDesc, PRNT_IN_EP);
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_PRNT_CfgDesc, PRNT_OUT_EP);
if (pEpInDesc != NULL)
{
pEpInDesc->wMaxPacketSize = PRNT_DATA_FS_IN_PACKET_SIZE;
}
if (pEpOutDesc != NULL)
{
pEpOutDesc->wMaxPacketSize = PRNT_DATA_FS_OUT_PACKET_SIZE;
}
*length = (uint16_t) sizeof(USBD_PRNT_CfgDesc);
return USBD_PRNT_CfgDesc;
}
/**
@@ -565,8 +520,21 @@ static uint8_t *USBD_PRNT_GetFSCfgDesc(uint16_t *length)
*/
static uint8_t *USBD_PRNT_GetHSCfgDesc(uint16_t *length)
{
*length = (uint16_t) sizeof(USBD_PRNT_CfgHSDesc);
return USBD_PRNT_CfgHSDesc;
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_PRNT_CfgDesc, PRNT_IN_EP);
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_PRNT_CfgDesc, PRNT_OUT_EP);
if (pEpInDesc != NULL)
{
pEpInDesc->wMaxPacketSize = PRNT_DATA_HS_IN_PACKET_SIZE;
}
if (pEpOutDesc != NULL)
{
pEpOutDesc->wMaxPacketSize = PRNT_DATA_HS_OUT_PACKET_SIZE;
}
*length = (uint16_t) sizeof(USBD_PRNT_CfgDesc);
return USBD_PRNT_CfgDesc;
}
/**
@@ -577,8 +545,21 @@ static uint8_t *USBD_PRNT_GetHSCfgDesc(uint16_t *length)
*/
static uint8_t *USBD_PRNT_GetOtherSpeedCfgDesc(uint16_t *length)
{
*length = (uint16_t) sizeof(USBD_PRNT_OtherSpeedCfgDesc);
return USBD_PRNT_OtherSpeedCfgDesc;
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_PRNT_CfgDesc, PRNT_IN_EP);
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_PRNT_CfgDesc, PRNT_OUT_EP);
if (pEpInDesc != NULL)
{
pEpInDesc->wMaxPacketSize = PRNT_DATA_FS_IN_PACKET_SIZE;
}
if (pEpOutDesc != NULL)
{
pEpOutDesc->wMaxPacketSize = PRNT_DATA_FS_OUT_PACKET_SIZE;
}
*length = (uint16_t) sizeof(USBD_PRNT_CfgDesc);
return USBD_PRNT_CfgDesc;
}
/**
@@ -592,6 +573,7 @@ uint8_t *USBD_PRNT_GetDeviceQualifierDescriptor(uint16_t *length)
*length = (uint16_t)sizeof(USBD_PRNT_DeviceQualifierDesc);
return USBD_PRNT_DeviceQualifierDesc;
}
#endif /* USE_USBD_COMPOSITE */
/**
* @brief USBD_PRNT_RegisterInterface
@@ -608,7 +590,7 @@ uint8_t USBD_PRNT_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_PRNT_ItfTypeD
}
/* Setup the fops pointer */
pdev->pUserData = fops;
pdev->pUserData[pdev->classId] = fops;
return (uint8_t)USBD_OK;
}
@@ -621,7 +603,7 @@ uint8_t USBD_PRNT_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_PRNT_ItfTypeD
*/
uint8_t USBD_PRNT_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff)
{
USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *) pdev->pClassData;
USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *) pdev->pClassDataCmsit[pdev->classId];
hPRNT->RxBuffer = pbuff;
@@ -636,7 +618,13 @@ uint8_t USBD_PRNT_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff)
*/
uint8_t USBD_PRNT_ReceivePacket(USBD_HandleTypeDef *pdev)
{
USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *)pdev->pClassData;
USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
PRNTInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
PRNTOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (hPRNT == NULL)
{
@@ -646,18 +634,19 @@ uint8_t USBD_PRNT_ReceivePacket(USBD_HandleTypeDef *pdev)
if (pdev->dev_speed == USBD_SPEED_HIGH)
{
/* Prepare Out endpoint to receive next packet */
(void)USBD_LL_PrepareReceive(pdev, PRNT_OUT_EP, hPRNT->RxBuffer,
(void)USBD_LL_PrepareReceive(pdev, PRNTOutEpAdd, hPRNT->RxBuffer,
PRNT_DATA_HS_OUT_PACKET_SIZE);
}
else
{
/* Prepare Out endpoint to receive next packet */
(void)USBD_LL_PrepareReceive(pdev, PRNT_OUT_EP, hPRNT->RxBuffer,
(void)USBD_LL_PrepareReceive(pdev, PRNTOutEpAdd, hPRNT->RxBuffer,
PRNT_DATA_FS_OUT_PACKET_SIZE);
}
return (uint8_t)USBD_OK;
}
/**
* @}
*/
@@ -669,5 +658,3 @@ uint8_t USBD_PRNT_ReceivePacket(USBD_HandleTypeDef *pdev)
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

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

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -97,5 +96,3 @@ extern USBD_ClassTypeDef USBD_TEMPLATE_ClassDriver;
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -4,6 +4,17 @@
* @author MCD Application Team
* @brief This file provides the HID core functions.
*
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
* @verbatim
*
* ===================================================================
@@ -22,17 +33,6 @@
* @endverbatim
*
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
@@ -124,7 +124,7 @@ USBD_ClassTypeDef USBD_TEMPLATE_ClassDriver =
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* __ICCARM__ */
/* USB TEMPLATE device Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_TEMPLATE_CfgDesc[USB_TEMPLATE_CONFIG_DESC_SIZ] __ALIGN_END =
{
@@ -146,7 +146,7 @@ __ALIGN_BEGIN static uint8_t USBD_TEMPLATE_CfgDesc[USB_TEMPLATE_CONFIG_DESC_SIZ]
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* __ICCARM__ */
/* USB Standard Device Descriptor */
__ALIGN_BEGIN static uint8_t USBD_TEMPLATE_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
{
@@ -252,12 +252,12 @@ static uint8_t *USBD_TEMPLATE_GetCfgDesc(uint16_t *length)
}
/**
* @brief DeviceQualifierDescriptor
* @brief USBD_TEMPLATE_GetDeviceQualifierDesc
* return Device Qualifier descriptor
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
uint8_t *USBD_TEMPLATE_DeviceQualifierDescriptor(uint16_t *length)
uint8_t *USBD_TEMPLATE_GetDeviceQualifierDesc(uint16_t *length)
{
*length = (uint16_t)sizeof(USBD_TEMPLATE_DeviceQualifierDesc);
return USBD_TEMPLATE_DeviceQualifierDesc;
@@ -350,19 +350,6 @@ static uint8_t USBD_TEMPLATE_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
return (uint8_t)USBD_OK;
}
/**
* @brief DeviceQualifierDescriptor
* return Device Qualifier descriptor
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
uint8_t *USBD_TEMPLATE_GetDeviceQualifierDesc(uint16_t *length)
{
*length = (uint16_t)sizeof(USBD_TEMPLATE_DeviceQualifierDesc);
return USBD_TEMPLATE_DeviceQualifierDesc;
}
/**
* @}
*/
@@ -376,5 +363,3 @@ uint8_t *USBD_TEMPLATE_GetDeviceQualifierDesc(uint16_t *length)
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2020 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -47,12 +46,12 @@ extern "C" {
#define UVC_VERSION 0x0100U /* UVC 1.0 */
#else
#define UVC_VERSION 0x0110U /* UVC 1.1 */
#endif
#endif /* UVC_1_0 */
/* bEndpointAddress in Endpoint Descriptor */
#ifndef UVC_IN_EP
#define UVC_IN_EP 0x81U
#endif /* VIDEO_IN_EP */
#endif /* UVC_IN_EP */
/* These defines shall be updated in the usbd_conf.h file */
#ifndef UVC_WIDTH
@@ -111,15 +110,15 @@ extern "C" {
#ifndef UVC_ISO_FS_MPS
#define UVC_ISO_FS_MPS 256U
#endif
#endif /* UVC_ISO_FS_MPS */
#ifndef UVC_ISO_HS_MPS
#define UVC_ISO_HS_MPS 512U
#endif
#endif /* UVC_ISO_HS_MPS */
#ifndef UVC_HEADER_PACKET_CNT
#define UVC_HEADER_PACKET_CNT 0x01U
#endif
#endif /* UVC_HEADER_PACKET_CNT */
#define UVC_REQ_READ_MASK 0x80U
@@ -131,7 +130,9 @@ extern "C" {
#define UVC_CONFIG_DESC_SIZ (0x88U + 0x16U)
#else
#define UVC_CONFIG_DESC_SIZ 0x88U
#endif
#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */
#define USBD_VC_GIUD_FORMAT_SIZE 16U
#define UVC_TOTAL_BUF_SIZE 0x04U
@@ -148,10 +149,10 @@ extern "C" {
#ifndef WBVAL
#define WBVAL(x) ((x) & 0xFFU),(((x) >> 8) & 0xFFU)
#endif
#endif /* WBVAL */
#ifndef DBVAL
#define DBVAL(x) ((x)& 0xFFU),(((x) >> 8) & 0xFFU),(((x)>> 16) & 0xFFU),(((x) >> 24) & 0xFFU)
#endif
#endif /* DBVAL */
/* Video Interface Protocol Codes */
#define PC_PROTOCOL_UNDEFINED 0x00U
@@ -183,7 +184,7 @@ extern "C" {
#define VC_HEADER_SIZE (VIDEO_VS_IF_IN_HEADER_DESC_SIZE + \
VS_FORMAT_DESC_SIZE + \
VS_FRAME_DESC_SIZE)
#endif
#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */
/*
* Video Class specification release 1.1
@@ -364,32 +365,6 @@ typedef enum
VIDEO_OFFSET_UNKNOWN,
} VIDEO_OffsetTypeDef;
typedef struct _VIDEO_DescHeader
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubType;
} USBD_VIDEO_DescHeader_t;
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubType;
uint8_t bFrameIndex;
uint8_t bmCapabilities;
uint16_t wWidth;
uint16_t wHeight;
uint32_t dwMinBitRate;
uint32_t dwMaxBitRate;
uint32_t dwMaxVideoFrameBufSize;
uint32_t dwDefaultFrameInterval;
uint8_t bFrameIntervalType;
uint32_t dwMinFrameInterval;
uint32_t dwMaxFrameInterval;
uint32_t dwFrameIntervalStep;
} __PACKED USBD_VIDEO_VSFrameDescTypeDef;
typedef struct
{
uint8_t cmd;
@@ -413,7 +388,6 @@ typedef struct
int8_t (* DeInit)(void);
int8_t (* Control)(uint8_t, uint8_t *, uint16_t);
int8_t (* Data)(uint8_t **, uint16_t *, uint16_t *);
uint8_t *pStrDesc;
} USBD_VIDEO_ItfTypeDef;
/* UVC uses only 26 first bytes */
@@ -437,6 +411,130 @@ typedef struct
uint8_t bMaxVersion;
} __PACKED USBD_VideoControlTypeDef;
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bInterfaceNumber;
uint8_t bAlternateSetting;
uint8_t bNumEndpoints;
uint8_t bInterfaceClass;
uint8_t bInterfaceSubClass;
uint8_t bInterfaceProtocol;
uint8_t iFunction;
} __PACKED USBD_StandardVCIfDescTypeDef;
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint16_t bcdUVC;
uint16_t wTotalLength;
uint32_t dwClockFrequency;
uint8_t baInterfaceNr;
uint8_t iTerminal;
} __PACKED USBD_specificVCInDescTypeDef;
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bTerminalID;
uint16_t wTerminalType;
uint8_t bAssocTerminal;
uint8_t iTerminal;
} __PACKED USBD_InputTerminalDescTypeDef;
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bTerminalID;
uint16_t wTerminalType;
uint8_t bAssocTerminal;
uint8_t bSourceID;
uint8_t iTerminal;
} __PACKED USBD_OutputTerminalDescTypeDef;
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint16_t bNumFormats;
uint8_t bVideoControlSize;
uint8_t bEndPointAddress;
uint8_t bmInfo;
uint8_t bTerminalLink;
uint8_t bStillCaptureMethod;
uint8_t bTriggerSupport;
uint8_t bTriggerUsage;
uint8_t bControlSize;
uint8_t bmaControls;
} __PACKED USBD_ClassSpecificVsHeaderDescTypeDef;
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubType;
uint8_t bFormatIndex;
uint8_t bNumFrameDescriptor;
#ifdef USBD_UVC_FORMAT_UNCOMPRESSED
uint8_t pGiudFormat[USBD_VC_GIUD_FORMAT_SIZE];
uint8_t bBitsPerPixel;
#else
uint8_t bmFlags;
#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */
uint8_t bDefaultFrameIndex;
uint8_t bAspectRatioX;
uint8_t bAspectRatioY;
uint8_t bInterlaceFlags;
uint8_t bCopyProtect;
} __PACKED USBD_PayloadFormatDescTypeDef;
#ifdef USBD_UVC_FORMAT_UNCOMPRESSED
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubType;
uint8_t bColorPrimarie;
uint8_t bTransferCharacteristics;
uint8_t bMatrixCoefficients;
} __PACKED USBD_ColorMatchingDescTypeDef;
#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint16_t wMaxPacketSize;
uint8_t bInterval;
} __PACKED USBD_StandardVCDataEPDescTypeDef;
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubType;
uint8_t bFrameIndex;
uint8_t bmCapabilities;
uint16_t wWidth;
uint16_t wHeight;
uint32_t dwMinBitRate;
uint32_t dwMaxBitRate;
uint32_t dwMaxVideoFrameBufSize;
uint32_t dwDefaultFrameInterval;
uint8_t bFrameIntervalType;
uint32_t dwMinFrameInterval;
} __PACKED USBD_VIDEO_VSFrameDescTypeDef;
extern USBD_ClassTypeDef USBD_VIDEO;
#define USBD_VIDEO_CLASS &USBD_VIDEO
/**

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2020 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -114,6 +113,25 @@ void TransferComplete_CallBack_FS(void);
*/
void HalfTransfer_CallBack_FS(void);
#define IMG_NBR 1U
#define IMAGE_SIZE 0x1U
const uint8_t image[] = {0x00};
const uint8_t *tImagesList[] = {image};
uint16_t tImagesSizes[] = {IMAGE_SIZE};
/* Time laps between video frames in ms.
Please adjust this value depending on required speed.
Please note that this define uses the system HAL_Delay() which uses the systick.
In case of changes on HAL_Delay, please ensure the values in ms correspond. */
#ifdef USE_USB_HS
#define USBD_VIDEO_IMAGE_LAPS 160U
#else
#define USBD_VIDEO_IMAGE_LAPS 80U
#endif /* USE_USB_HS */
/* USER CODE BEGIN EXPORTED_FUNCTIONS */
/* USER CODE END EXPORTED_FUNCTIONS */
@@ -136,7 +154,3 @@ void HalfTransfer_CallBack_FS(void);
#endif /* USBD_VIDEO_IF_H_ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -4,6 +4,17 @@
* @author MCD Application Team
* @brief This file provides the Video core functions.
*
******************************************************************************
* @attention
*
* Copyright (c) 2020 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
* @verbatim
*
* ===================================================================
@@ -35,17 +46,6 @@
* @endverbatim
*
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
@@ -87,10 +87,14 @@
static uint8_t USBD_VIDEO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
static uint8_t USBD_VIDEO_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
static uint8_t USBD_VIDEO_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
#ifndef USE_USBD_COMPOSITE
static uint8_t *USBD_VIDEO_GetFSCfgDesc(uint16_t *length);
static uint8_t *USBD_VIDEO_GetHSCfgDesc(uint16_t *length);
static uint8_t *USBD_VIDEO_GetOtherSpeedCfgDesc(uint16_t *length);
static uint8_t *USBD_VIDEO_GetDeviceQualifierDesc(uint16_t *length);
#endif /* USE_USBD_COMPOSITE */
static uint8_t USBD_VIDEO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
static uint8_t USBD_VIDEO_SOF(USBD_HandleTypeDef *pdev);
static uint8_t USBD_VIDEO_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum);
@@ -99,10 +103,11 @@ static uint8_t USBD_VIDEO_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnu
static void VIDEO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
static void VIDEO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
static USBD_VIDEO_DescHeader_t *USBD_VIDEO_GetNextDesc(uint8_t *pbuf, uint16_t *ptr);
static void *USBD_VIDEO_GetEpDesc(uint8_t *pConfDesc, uint8_t EpAddr);
#ifndef USE_USBD_COMPOSITE
static void *USBD_VIDEO_GetVSFrameDesc(uint8_t *pConfDesc);
#endif /* USE_USBD_COMPOSITE */
static void *USBD_VIDEO_GetVideoHeaderDesc(uint8_t *pConfDesc);
/**
* @}
@@ -124,10 +129,17 @@ USBD_ClassTypeDef USBD_VIDEO =
USBD_VIDEO_SOF,
USBD_VIDEO_IsoINIncomplete,
NULL,
#ifdef USE_USBD_COMPOSITE
NULL,
NULL,
NULL,
NULL,
#else
USBD_VIDEO_GetHSCfgDesc,
USBD_VIDEO_GetFSCfgDesc,
USBD_VIDEO_GetOtherSpeedCfgDesc,
USBD_VIDEO_GetDeviceQualifierDesc,
#endif /* USE_USBD_COMPOSITE */
};
/* USB VIDEO device Configuration Descriptor (same for all speeds thanks to user defines) */
@@ -140,12 +152,13 @@ __ALIGN_BEGIN static uint8_t USBD_VIDEO_CfgDesc[] __ALIGN_END =
HIBYTE(UVC_CONFIG_DESC_SIZ),
0x02, /* bNumInterfaces: 2 interfaces */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
0x00, /* iConfiguration: Index of string descriptor
describing the configuration */
#if (USBD_SELF_POWERED == 1U)
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
#endif /* USBD_SELF_POWERED */
USBD_MAX_POWER, /* bMaxPower in mA according to user configuration */
/* Interface Association Descriptor */
@@ -182,8 +195,8 @@ __ALIGN_BEGIN static uint8_t USBD_VIDEO_CfgDesc[] __ALIGN_END =
0xDC,
0x02,
0x01, /* bInCollection: number of streaming interfaces */
0x01, /* baInterfaceNr(1): VideoStreaming interface 1 is part of VC interface */
0x01, /* baInterfaceNr(1): VideoStreaming interface 1 is part
of VC interface */
/* Input Terminal Descriptor */
VIDEO_IN_TERMINAL_DESC_SIZE, /* bLength: Input terminal descriptor size */
CS_INTERFACE, /* bDescriptorType: INTERFACE */
@@ -248,8 +261,9 @@ __ALIGN_BEGIN static uint8_t USBD_VIDEO_CfgDesc[] __ALIGN_END =
UVC_BITS_PER_PIXEL, /* bBitsPerPixel : Number of bits per pixel */
#else
0x01, /* bmFlags: FixedSizeSamples */
#endif
0x01, /* bDefaultFrameIndex: default frame used is frame 1 (only one frame used) */
#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */
0x01, /* bDefaultFrameIndex: default frame used is frame 1
(only one frame used) */
0x00, /* bAspectRatioX: not required by specification */
0x00, /* bAspectRatioY: not required by specification */
0x00, /* bInterlaceFlags: non interlaced stream */
@@ -264,7 +278,7 @@ __ALIGN_BEGIN static uint8_t USBD_VIDEO_CfgDesc[] __ALIGN_END =
0x00, /* bmCapabilities: no till image capture */
#else
0x02, /* bmCapabilities: fixed frame rate supported */
#endif
#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */
WBVAL(UVC_WIDTH), /* wWidth: Image Frame Width */
WBVAL(UVC_HEIGHT), /* wHeight: Image Frame Height */
DBVAL(UVC_MIN_BIT_RATE(UVC_CAM_FPS_FS)), /* dwMinBitRate: Minimum supported bit rate in bits/s */
@@ -282,7 +296,7 @@ __ALIGN_BEGIN static uint8_t USBD_VIDEO_CfgDesc[] __ALIGN_END =
UVC_COLOR_PRIMARIE, /* bColorPrimarie: 1: BT.709, sRGB (default) */
UVC_TFR_CHARACTERISTICS, /* bTransferCharacteristics: 1: BT.709 (default) */
UVC_MATRIX_COEFFICIENTS, /* bMatrixCoefficients: 4: BT.601, (default) */
#endif
#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */
/* Standard VS Interface Descriptor = interface 1, alternate setting 1 = data transfer mode */
USB_IF_DESC_SIZE, /* bLength */
@@ -305,6 +319,7 @@ __ALIGN_BEGIN static uint8_t USBD_VIDEO_CfgDesc[] __ALIGN_END =
0x01, /* bInterval: 1 frame interval */
};
#ifndef USE_USBD_COMPOSITE
/* USB Standard Device Descriptor */
__ALIGN_BEGIN static uint8_t USBD_VIDEO_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
{
@@ -319,6 +334,9 @@ __ALIGN_BEGIN static uint8_t USBD_VIDEO_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIE
0x01,
0x00,
};
#endif /* USE_USBD_COMPOSITE */
static uint8_t VIDEOinEpAdd = UVC_IN_EP;
/* Video Commit data structure */
static USBD_VideoControlTypeDef video_Commit_Control =
@@ -391,26 +409,32 @@ static uint8_t USBD_VIDEO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
}
/* Assign the pClassData pointer to the allocated structure */
pdev->pClassData = (void *)hVIDEO;
pdev->pClassDataCmsit[pdev->classId] = (void *)hVIDEO;
pdev->pClassData = pdev->pClassDataCmsit[pdev->classId];
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
VIDEOinEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_ISOC, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
/* Open EP IN */
if (pdev->dev_speed == USBD_SPEED_HIGH)
{
(void)USBD_LL_OpenEP(pdev, UVC_IN_EP, USBD_EP_TYPE_ISOC, UVC_ISO_HS_MPS);
(void)USBD_LL_OpenEP(pdev, VIDEOinEpAdd, USBD_EP_TYPE_ISOC, UVC_ISO_HS_MPS);
pdev->ep_in[UVC_IN_EP & 0xFU].is_used = 1U;
pdev->ep_in[UVC_IN_EP & 0xFU].maxpacket = UVC_ISO_HS_MPS;
pdev->ep_in[VIDEOinEpAdd & 0xFU].is_used = 1U;
pdev->ep_in[VIDEOinEpAdd & 0xFU].maxpacket = UVC_ISO_HS_MPS;
}
else
{
(void)USBD_LL_OpenEP(pdev, UVC_IN_EP, USBD_EP_TYPE_ISOC, UVC_ISO_FS_MPS);
(void)USBD_LL_OpenEP(pdev, VIDEOinEpAdd, USBD_EP_TYPE_ISOC, UVC_ISO_FS_MPS);
pdev->ep_in[UVC_IN_EP & 0xFU].is_used = 1U;
pdev->ep_in[UVC_IN_EP & 0xFU].maxpacket = UVC_ISO_FS_MPS;
pdev->ep_in[VIDEOinEpAdd & 0xFU].is_used = 1U;
pdev->ep_in[VIDEOinEpAdd & 0xFU].maxpacket = UVC_ISO_FS_MPS;
}
/* Init physical Interface components */
((USBD_VIDEO_ItfTypeDef *)pdev->pUserData)->Init();
((USBD_VIDEO_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init();
/* Init Xfer states */
hVIDEO->interface = 0U;
@@ -435,18 +459,24 @@ static uint8_t USBD_VIDEO_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
UNUSED(cfgidx);
/* Check if the video structure pointer is valid */
if (pdev->pClassData == NULL)
if (pdev->pClassDataCmsit[pdev->classId] == NULL)
{
return (uint8_t)USBD_FAIL;
}
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
VIDEOinEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_ISOC, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
/* Close EP IN */
(void)USBD_LL_CloseEP(pdev, UVC_IN_EP);
pdev->ep_in[UVC_IN_EP & 0xFU].is_used = 0U;
(void)USBD_LL_CloseEP(pdev, VIDEOinEpAdd);
pdev->ep_in[VIDEOinEpAdd & 0xFU].is_used = 0U;
/* DeInit physical Interface components */
((USBD_VIDEO_ItfTypeDef *)pdev->pUserData)->DeInit();
USBD_free(pdev->pClassData);
((USBD_VIDEO_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit();
USBD_free(pdev->pClassDataCmsit[pdev->classId]);
pdev->pClassDataCmsit[pdev->classId] = NULL;
pdev->pClassData = NULL;
/* Exit with no error code */
@@ -462,11 +492,11 @@ static uint8_t USBD_VIDEO_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
*/
static uint8_t USBD_VIDEO_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *) pdev->pClassData;
USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *) pdev->pClassDataCmsit[pdev->classId];
uint8_t ret = (uint8_t)USBD_OK;
uint16_t len = 0U;
uint8_t *pbuf = NULL;
uint16_t status_info = 0U;
uint16_t len;
uint8_t *pbuf;
switch (req->bmRequest & USB_REQ_TYPE_MASK)
{
@@ -480,13 +510,16 @@ static uint8_t USBD_VIDEO_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef
case UVC_GET_MAX:
VIDEO_REQ_GetCurrent(pdev, req);
break;
case UVC_GET_RES:
case UVC_GET_LEN:
case UVC_GET_INFO:
break;
case UVC_SET_CUR:
VIDEO_REQ_SetCurrent(pdev, req);
break;
default:
(void) USBD_CtlError(pdev, req);
ret = (uint8_t)USBD_FAIL;
@@ -513,10 +546,18 @@ static uint8_t USBD_VIDEO_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef
case USB_REQ_GET_DESCRIPTOR:
if ((req->wValue >> 8) == CS_DEVICE)
{
pbuf = USBD_VIDEO_CfgDesc + 18;
pbuf = (uint8_t *)USBD_VIDEO_GetVideoHeaderDesc(pdev->pConfDesc);
if (pbuf != NULL)
{
len = MIN((uint16_t)USB_CONF_DESC_SIZE, (uint16_t)req->wLength);
}
(void)USBD_CtlSendData(pdev, pbuf, len);
}
else
{
USBD_CtlError(pdev, req);
ret = (uint8_t)USBD_FAIL;
}
}
break;
case USB_REQ_GET_INTERFACE :
@@ -540,14 +581,14 @@ static uint8_t USBD_VIDEO_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef
if (hVIDEO->interface == 1U)
{
/* Start Streaming (First endpoint writing will be done on next SOF) */
(void)USBD_LL_FlushEP(pdev, UVC_IN_EP);
(void)USBD_LL_FlushEP(pdev, VIDEOinEpAdd);
hVIDEO->uvc_state = UVC_PLAY_STATUS_READY;
}
else
{
/* Stop Streaming */
hVIDEO->uvc_state = UVC_PLAY_STATUS_STOP;
(void)USBD_LL_FlushEP(pdev, UVC_IN_EP);
(void)USBD_LL_FlushEP(pdev, VIDEOinEpAdd);
}
}
else
@@ -592,20 +633,21 @@ static uint8_t USBD_VIDEO_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef
*/
static uint8_t USBD_VIDEO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *) pdev->pClassData;
USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *) pdev->pClassDataCmsit[pdev->classId];
static uint8_t packet[UVC_PACKET_SIZE + (UVC_HEADER_PACKET_CNT * 2U)] = {0x00U};
static uint8_t *Pcktdata = packet;
static uint16_t PcktIdx = 0U;
static uint16_t PcktSze = UVC_PACKET_SIZE;
static uint8_t payload_header[2] = {0x02U, 0x00U};
uint8_t i = 0U;
uint32_t RemainData, DataOffset = 0U;
uint32_t RemainData = 0U;
uint32_t DataOffset = 0U;
/* Check if the Streaming has already been started */
if (hVIDEO->uvc_state == UVC_PLAY_STATUS_STREAMING)
{
/* Get the current packet buffer, index and size from the application layer */
((USBD_VIDEO_ItfTypeDef *)pdev->pUserData)->Data(&Pcktdata, &PcktSze, &PcktIdx);
((USBD_VIDEO_ItfTypeDef *)pdev->pUserData[pdev->classId])->Data(&Pcktdata, &PcktSze, &PcktIdx);
/* Check if end of current image has been reached */
if (PcktSze > 2U)
@@ -624,9 +666,10 @@ static uint8_t USBD_VIDEO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
packet[((DataOffset + 0U) * i)] = payload_header[0];
packet[((DataOffset + 0U) * i) + 1U] = payload_header[1];
if (RemainData > pdev->ep_in[UVC_IN_EP & 0xFU].maxpacket)
if (RemainData > pdev->ep_in[VIDEOinEpAdd & 0xFU].maxpacket)
{
DataOffset = pdev->ep_in[UVC_IN_EP & 0xFU].maxpacket;
DataOffset = pdev->ep_in[VIDEOinEpAdd & 0xFU].maxpacket;
(void)USBD_memcpy((packet + ((DataOffset + 0U) * i) + 2U),
Pcktdata + ((DataOffset - 2U) * i), (DataOffset - 2U));
@@ -666,14 +709,14 @@ static uint8_t USBD_VIDEO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
*/
static uint8_t USBD_VIDEO_SOF(USBD_HandleTypeDef *pdev)
{
USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *) pdev->pClassData;
USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *) pdev->pClassDataCmsit[pdev->classId];
uint8_t payload[2] = {0x02U, 0x00U};
/* Check if the Streaming has already been started by SetInterface AltSetting 1 */
if (hVIDEO->uvc_state == UVC_PLAY_STATUS_READY)
{
/* Transmit the first packet indicating that Streaming is starting */
(void)USBD_LL_Transmit(pdev, UVC_IN_EP, (uint8_t *)payload, 2U);
(void)USBD_LL_Transmit(pdev, VIDEOinEpAdd, (uint8_t *)payload, 2U);
/* Enable Streaming state */
hVIDEO->uvc_state = UVC_PLAY_STATUS_STREAMING;
@@ -708,7 +751,7 @@ static uint8_t USBD_VIDEO_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnu
static void VIDEO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
USBD_VIDEO_HandleTypeDef *hVIDEO;
hVIDEO = (USBD_VIDEO_HandleTypeDef *)(pdev->pClassData);
hVIDEO = (USBD_VIDEO_HandleTypeDef *)(pdev->pClassDataCmsit[pdev->classId]);
static __IO uint8_t EntityStatus[8] = {0};
/* Reset buffer to zeros */
@@ -794,19 +837,18 @@ static void VIDEO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef
*/
static void VIDEO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *)(pdev->pClassData);
/* Check that the request has control data */
if (req->wLength > 0U)
{
/* Prepare the reception of the buffer over EP0 */
if (LOBYTE(req->wValue) == (uint8_t)VS_PROBE_CONTROL)
if (req->wValue == (uint16_t)VS_PROBE_CONTROL)
{
/* Probe Request */
(void) USBD_CtlPrepareRx(pdev, (uint8_t *)&video_Probe_Control,
MIN(req->wLength, sizeof(USBD_VideoControlTypeDef)));
}
else if (LOBYTE(req->wValue) == (uint8_t)VS_COMMIT_CONTROL)
else if (req->wValue == (uint16_t)VS_COMMIT_CONTROL)
{
/* Commit Request */
(void) USBD_CtlPrepareRx(pdev, (uint8_t *)&video_Commit_Control,
@@ -814,13 +856,12 @@ static void VIDEO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef
}
else
{
/* Prepare the reception of the buffer over EP0 */
(void) USBD_CtlPrepareRx(pdev, hVIDEO->control.data,
MIN(req->wLength, USB_MAX_EP0_SIZE));
(void)USBD_LL_StallEP(pdev, 0x80U);
}
}
}
#ifndef USE_USBD_COMPOSITE
/**
* @brief USBD_VIDEO_GetFSCfgDesc
* return configuration descriptor
@@ -829,7 +870,7 @@ static void VIDEO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef
*/
static uint8_t *USBD_VIDEO_GetFSCfgDesc(uint16_t *length)
{
USBD_EpDescTypedef *pEpDesc = USBD_VIDEO_GetEpDesc(USBD_VIDEO_CfgDesc, UVC_IN_EP);
USBD_EpDescTypeDef *pEpDesc = USBD_GetEpDesc(USBD_VIDEO_CfgDesc, VIDEOinEpAdd);
USBD_VIDEO_VSFrameDescTypeDef *pVSFrameDesc = USBD_VIDEO_GetVSFrameDesc(USBD_VIDEO_CfgDesc);
if (pEpDesc != NULL)
@@ -857,7 +898,7 @@ static uint8_t *USBD_VIDEO_GetFSCfgDesc(uint16_t *length)
*/
static uint8_t *USBD_VIDEO_GetHSCfgDesc(uint16_t *length)
{
USBD_EpDescTypedef *pEpDesc = USBD_VIDEO_GetEpDesc(USBD_VIDEO_CfgDesc, UVC_IN_EP);
USBD_EpDescTypeDef *pEpDesc = USBD_GetEpDesc(USBD_VIDEO_CfgDesc, VIDEOinEpAdd);
USBD_VIDEO_VSFrameDescTypeDef *pVSFrameDesc = USBD_VIDEO_GetVSFrameDesc(USBD_VIDEO_CfgDesc);
if (pEpDesc != NULL)
@@ -885,7 +926,7 @@ static uint8_t *USBD_VIDEO_GetHSCfgDesc(uint16_t *length)
*/
static uint8_t *USBD_VIDEO_GetOtherSpeedCfgDesc(uint16_t *length)
{
USBD_EpDescTypedef *pEpDesc = USBD_VIDEO_GetEpDesc(USBD_VIDEO_CfgDesc, UVC_IN_EP);
USBD_EpDescTypeDef *pEpDesc = USBD_GetEpDesc(USBD_VIDEO_CfgDesc, VIDEOinEpAdd);
USBD_VIDEO_VSFrameDescTypeDef *pVSFrameDesc = USBD_VIDEO_GetVSFrameDesc(USBD_VIDEO_CfgDesc);
if (pEpDesc != NULL)
@@ -917,23 +958,6 @@ static uint8_t *USBD_VIDEO_GetDeviceQualifierDesc(uint16_t *length)
return USBD_VIDEO_DeviceQualifierDesc;
}
/**
* @brief USBD_VIDEO_GetNextDesc
* This function return the next descriptor header
* @param buf: Buffer where the descriptor is available
* @param ptr: data pointer inside the descriptor
* @retval next header
*/
static USBD_VIDEO_DescHeader_t *USBD_VIDEO_GetNextDesc(uint8_t *pbuf, uint16_t *ptr)
{
USBD_VIDEO_DescHeader_t *pnext = (USBD_VIDEO_DescHeader_t *)(void *)pbuf;
*ptr += pnext->bLength;
pnext = (USBD_VIDEO_DescHeader_t *)(void *)(pbuf + pnext->bLength);
return (pnext);
}
/**
* @brief USBD_VIDEO_GetVSFrameDesc
* This function return the Video Endpoint descriptor
@@ -943,8 +967,8 @@ static USBD_VIDEO_DescHeader_t *USBD_VIDEO_GetNextDesc(uint8_t *pbuf, uint16_t *
*/
static void *USBD_VIDEO_GetVSFrameDesc(uint8_t *pConfDesc)
{
USBD_VIDEO_DescHeader_t *pdesc = (USBD_VIDEO_DescHeader_t *)(void *)pConfDesc;
USBD_ConfigDescTypedef *desc = (USBD_ConfigDescTypedef *)(void *)pConfDesc;
USBD_DescHeaderTypeDef *pdesc = (USBD_DescHeaderTypeDef *)(void *)pConfDesc;
USBD_ConfigDescTypeDef *desc = (USBD_ConfigDescTypeDef *)(void *)pConfDesc;
USBD_VIDEO_VSFrameDescTypeDef *pVSFrameDesc = NULL;
uint16_t ptr;
@@ -954,7 +978,7 @@ static void *USBD_VIDEO_GetVSFrameDesc(uint8_t *pConfDesc)
while (ptr < desc->wTotalLength)
{
pdesc = USBD_VIDEO_GetNextDesc((uint8_t *)pdesc, &ptr);
pdesc = USBD_GetNextDesc((uint8_t *)pdesc, &ptr);
if (((pdesc->bDescriptorSubType == VS_FRAME_MJPEG) ||
(pdesc->bDescriptorSubType == VS_FRAME_UNCOMPRESSED)) &&
@@ -968,20 +992,20 @@ static void *USBD_VIDEO_GetVSFrameDesc(uint8_t *pConfDesc)
return (void *)pVSFrameDesc;
}
#endif /* USE_USBD_COMPOSITE */
/**
* @brief USBD_VIDEO_GetEpDesc
* This function return the Video Endpoint descriptor
* @brief USBD_VIDEO_GetVideoHeaderDesc
* This function return the Video Header descriptor
* @param pdev: device instance
* @param pConfDesc: pointer to Bos descriptor
* @param EpAddr: endpoint address
* @retval pointer to video endpoint descriptor
* @retval pointer to the Video Header descriptor
*/
static void *USBD_VIDEO_GetEpDesc(uint8_t *pConfDesc, uint8_t EpAddr)
static void *USBD_VIDEO_GetVideoHeaderDesc(uint8_t *pConfDesc)
{
USBD_VIDEO_DescHeader_t *pdesc = (USBD_VIDEO_DescHeader_t *)(void *)pConfDesc;
USBD_ConfigDescTypedef *desc = (USBD_ConfigDescTypedef *)(void *)pConfDesc;
USBD_EpDescTypedef *pEpDesc = NULL;
USBD_ConfigDescTypeDef *desc = (USBD_ConfigDescTypeDef *)(void *)pConfDesc;
USBD_DescHeaderTypeDef *pdesc = (USBD_DescHeaderTypeDef *)(void *)pConfDesc;
uint8_t *pVideoDesc = NULL;
uint16_t ptr;
if (desc->wTotalLength > desc->bLength)
@@ -990,25 +1014,16 @@ static void *USBD_VIDEO_GetEpDesc(uint8_t *pConfDesc, uint8_t EpAddr)
while (ptr < desc->wTotalLength)
{
pdesc = USBD_VIDEO_GetNextDesc((uint8_t *)pdesc, &ptr);
if (pdesc->bDescriptorType == USB_DESC_TYPE_ENDPOINT)
{
pEpDesc = (USBD_EpDescTypedef *)(void *)pdesc;
if (pEpDesc->bEndpointAddress == EpAddr)
pdesc = USBD_GetNextDesc((uint8_t *)pdesc, &ptr);
if ((pdesc->bDescriptorType == CS_INTERFACE) &&
(pdesc->bDescriptorSubType == VC_HEADER))
{
pVideoDesc = (uint8_t *)pdesc;
break;
}
else
{
pEpDesc = NULL;
}
}
}
}
return (void *)pEpDesc;
return pVideoDesc;
}
/**
@@ -1026,7 +1041,7 @@ uint8_t USBD_VIDEO_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_VIDEO_ItfT
}
/* Assign the FOPS pointer */
pdev->pUserData = fops;
pdev->pUserData[pdev->classId] = fops;
/* Exit with no error code */
return (uint8_t)USBD_OK;
@@ -1045,7 +1060,3 @@ uint8_t USBD_VIDEO_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_VIDEO_ItfT
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

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

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -77,6 +76,11 @@ extern "C" {
#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE 0x02U
#define USBD_CUSTOM_HID_REPORT_DESC_SIZE 163U
/* #define USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED */
/* #define USBD_CUSTOMHID_OUT_PREPARE_RECEIVE_DISABLED */
/* #define USBD_CUSTOMHID_EP0_OUT_PREPARE_RECEIVE_DISABLED */
/* #define USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */
/* VIDEO Class Config */
#define UVC_1_1 /* #define UVC_1_0 */
@@ -91,7 +95,7 @@ extern "C" {
#define UVC_COLOR_PRIMARIE 0x01U
#define UVC_TFR_CHARACTERISTICS 0x01U
#define UVC_MATRIX_COEFFICIENTS 0x04U
#endif
#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */
/* Video Stream frame width and height */
#define UVC_WIDTH 176U
@@ -141,7 +145,7 @@ extern "C" {
} while (0)
#else
#define USBD_UsrLog(...) do {} while (0)
#endif
#endif /* (USBD_DEBUG_LEVEL > 0U) */
#if (USBD_DEBUG_LEVEL > 1U)
@@ -152,7 +156,7 @@ extern "C" {
} while (0)
#else
#define USBD_ErrLog(...) do {} while (0)
#endif
#endif /* (USBD_DEBUG_LEVEL > 1U) */
#if (USBD_DEBUG_LEVEL > 2U)
#define USBD_DbgLog(...) do { \
@@ -162,7 +166,7 @@ extern "C" {
} while (0)
#else
#define USBD_DbgLog(...) do {} while (0)
#endif
#endif /* (USBD_DEBUG_LEVEL > 2U) */
/**
* @}
@@ -221,4 +225,3 @@ void USBD_static_free(void *p);
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -88,6 +87,17 @@ USBD_StatusTypeDef USBD_Start(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass);
#ifdef USE_USBD_COMPOSITE
USBD_StatusTypeDef USBD_RegisterClassComposite(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass,
USBD_CompositeClassTypeDef classtype, uint8_t *EpAddr);
USBD_StatusTypeDef USBD_UnRegisterClassComposite(USBD_HandleTypeDef *pdev);
uint8_t USBD_CoreGetEPAdd(USBD_HandleTypeDef *pdev, uint8_t ep_dir, uint8_t ep_type, uint8_t ClassId);
#endif /* USE_USBD_COMPOSITE */
uint8_t USBD_CoreFindIF(USBD_HandleTypeDef *pdev, uint8_t index);
uint8_t USBD_CoreFindEP(USBD_HandleTypeDef *pdev, uint8_t index);
USBD_StatusTypeDef USBD_RunTestMode(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
@@ -129,11 +139,18 @@ USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr,
USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, uint8_t ep_addr,
uint8_t *pbuf, uint32_t size);
#ifdef USBD_HS_TESTMODE_ENABLE
USBD_StatusTypeDef USBD_LL_SetTestMode(USBD_HandleTypeDef *pdev, uint8_t testmode);
#endif /* USBD_HS_TESTMODE_ENABLE */
uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr);
uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr);
void USBD_LL_Delay(uint32_t Delay);
void *USBD_GetEpDesc(uint8_t *pConfDesc, uint8_t EpAddr);
USBD_DescHeaderTypeDef *USBD_GetNextDesc(uint8_t *pbuf, uint16_t *ptr);
/**
* @}
*/
@@ -152,7 +169,4 @@ void USBD_LL_Delay(uint32_t Delay);
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -100,4 +99,3 @@ void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len);
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -53,6 +52,24 @@ extern "C" {
#define USBD_MAX_NUM_CONFIGURATION 1U
#endif /* USBD_MAX_NUM_CONFIGURATION */
#ifdef USE_USBD_COMPOSITE
#ifndef USBD_MAX_SUPPORTED_CLASS
#define USBD_MAX_SUPPORTED_CLASS 4U
#endif /* USBD_MAX_SUPPORTED_CLASS */
#else
#ifndef USBD_MAX_SUPPORTED_CLASS
#define USBD_MAX_SUPPORTED_CLASS 1U
#endif /* USBD_MAX_SUPPORTED_CLASS */
#endif /* USE_USBD_COMPOSITE */
#ifndef USBD_MAX_CLASS_ENDPOINTS
#define USBD_MAX_CLASS_ENDPOINTS 5U
#endif /* USBD_MAX_CLASS_ENDPOINTS */
#ifndef USBD_MAX_CLASS_INTERFACES
#define USBD_MAX_CLASS_INTERFACES 5U
#endif /* USBD_MAX_CLASS_INTERFACES */
#ifndef USBD_LPM_ENABLED
#define USBD_LPM_ENABLED 0U
#endif /* USBD_LPM_ENABLED */
@@ -160,6 +177,14 @@ extern "C" {
#define USBD_EP_TYPE_BULK 0x02U
#define USBD_EP_TYPE_INTR 0x03U
#ifdef USE_USBD_COMPOSITE
#define USBD_EP_IN 0x80U
#define USBD_EP_OUT 0x00U
#define USBD_FUNC_DESCRIPTOR_TYPE 0x24U
#define USBD_DESC_SUBTYPE_ACM 0x0FU
#define USBD_DESC_ECM_BCD_LOW 0x00U
#define USBD_DESC_ECM_BCD_HIGH 0x10U
#endif /* USE_USBD_COMPOSITE */
/**
* @}
*/
@@ -188,7 +213,7 @@ typedef struct
uint8_t iConfiguration;
uint8_t bmAttributes;
uint8_t bMaxPower;
} USBD_ConfigDescTypedef;
} __PACKED USBD_ConfigDescTypeDef;
typedef struct
{
@@ -196,7 +221,7 @@ typedef struct
uint8_t bDescriptorType;
uint16_t wTotalLength;
uint8_t bNumDeviceCaps;
} USBD_BosDescTypedef;
} USBD_BosDescTypeDef;
typedef struct
{
@@ -206,7 +231,14 @@ typedef struct
uint8_t bmAttributes;
uint16_t wMaxPacketSize;
uint8_t bInterval;
} USBD_EpDescTypedef;
} __PACKED USBD_EpDescTypeDef;
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubType;
} USBD_DescHeaderTypeDef;
struct _USBD_HandleTypeDef;
@@ -231,7 +263,7 @@ typedef struct _Device_cb
uint8_t *(*GetDeviceQualifierDescriptor)(uint16_t *length);
#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
uint8_t *(*GetUsrStrDescriptor)(struct _USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length);
#endif
#endif /* USBD_SUPPORT_USER_STRING_DESC */
} USBD_ClassTypeDef;
@@ -264,10 +296,10 @@ typedef struct
uint8_t *(*GetInterfaceStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
#if (USBD_CLASS_USER_STRING_DESC == 1)
uint8_t *(*GetUserStrDescriptor)(USBD_SpeedTypeDef speed, uint8_t idx, uint16_t *length);
#endif
#endif /* USBD_CLASS_USER_STRING_DESC */
#if ((USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1))
uint8_t *(*GetBOSDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
#endif
#endif /* (USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1) */
} USBD_DescriptorsTypeDef;
/* USB Device handle structure */
@@ -281,6 +313,49 @@ typedef struct
uint16_t bInterval;
} USBD_EndpointTypeDef;
#ifdef USE_USBD_COMPOSITE
typedef enum
{
CLASS_TYPE_NONE = 0,
CLASS_TYPE_HID = 1,
CLASS_TYPE_CDC = 2,
CLASS_TYPE_MSC = 3,
CLASS_TYPE_DFU = 4,
CLASS_TYPE_CHID = 5,
CLASS_TYPE_AUDIO = 6,
CLASS_TYPE_ECM = 7,
CLASS_TYPE_RNDIS = 8,
CLASS_TYPE_MTP = 9,
CLASS_TYPE_VIDEO = 10,
CLASS_TYPE_PRINTER = 11,
CLASS_TYPE_CCID = 12,
} USBD_CompositeClassTypeDef;
/* USB Device handle structure */
typedef struct
{
uint8_t add;
uint8_t type;
uint8_t size;
uint8_t is_used;
} USBD_EPTypeDef;
/* USB Device handle structure */
typedef struct
{
USBD_CompositeClassTypeDef ClassType;
uint32_t ClassId;
uint32_t Active;
uint32_t NumEps;
USBD_EPTypeDef Eps[USBD_MAX_CLASS_ENDPOINTS];
uint8_t *EpAdd;
uint32_t NumIf;
uint8_t Ifs[USBD_MAX_CLASS_INTERFACES];
uint32_t CurrPcktSze;
} USBD_CompositeElementTypeDef;
#endif /* USE_USBD_COMPOSITE */
/* USB Device handle structure */
typedef struct _USBD_HandleTypeDef
{
@@ -303,14 +378,33 @@ typedef struct _USBD_HandleTypeDef
USBD_SetupReqTypedef request;
USBD_DescriptorsTypeDef *pDesc;
USBD_ClassTypeDef *pClass;
USBD_ClassTypeDef *pClass[USBD_MAX_SUPPORTED_CLASS];
void *pClassData;
void *pUserData;
void *pClassDataCmsit[USBD_MAX_SUPPORTED_CLASS];
void *pUserData[USBD_MAX_SUPPORTED_CLASS];
void *pData;
void *pBosDesc;
void *pConfDesc;
uint32_t classId;
uint32_t NumClasses;
#ifdef USE_USBD_COMPOSITE
USBD_CompositeElementTypeDef tclasslist[USBD_MAX_SUPPORTED_CLASS];
#endif /* USE_USBD_COMPOSITE */
} USBD_HandleTypeDef;
/* USB Device endpoint direction */
typedef enum
{
OUT = 0x00,
IN = 0x80,
} USBD_EPDirectionTypeDef;
typedef enum
{
NETWORK_CONNECTION = 0x00,
RESPONSE_AVAILABLE = 0x01,
CONNECTION_SPEED_CHANGE = 0x2A
} USBD_CDC_NotifCodeTypeDef;
/**
* @}
*/
@@ -322,7 +416,9 @@ typedef struct _USBD_HandleTypeDef
*/
__STATIC_INLINE uint16_t SWAPBYTE(uint8_t *addr)
{
uint16_t _SwapVal, _Byte1, _Byte2;
uint16_t _SwapVal;
uint16_t _Byte1;
uint16_t _Byte2;
uint8_t *_pbuff = addr;
_Byte1 = *(uint8_t *)_pbuff;
@@ -336,19 +432,19 @@ __STATIC_INLINE uint16_t SWAPBYTE(uint8_t *addr)
#ifndef LOBYTE
#define LOBYTE(x) ((uint8_t)((x) & 0x00FFU))
#endif
#endif /* LOBYTE */
#ifndef HIBYTE
#define HIBYTE(x) ((uint8_t)(((x) & 0xFF00U) >> 8U))
#endif
#endif /* HIBYTE */
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#endif /* MIN */
#ifndef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
#endif /* MAX */
#if defined ( __GNUC__ )
#ifndef __weak
@@ -417,4 +513,4 @@ __STATIC_INLINE uint16_t SWAPBYTE(uint8_t *addr)
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -44,7 +43,7 @@
#define USBD_BB_URL_STR_DESC (uint8_t *)"www.st.com"
#define USBD_BB_ALTMODE0_STR_DESC (uint8_t *)"STM32 Alternate0 Mode"
#define USBD_BB_ALTMODE1_STR_DESC (uint8_t *)"STM32 Alternate1 Mode"
#endif
#endif /* USBD_CLASS_USER_STRING_DESC */
#define USB_SIZ_STRING_SERIAL 0x1AU
@@ -52,7 +51,7 @@
#define USB_SIZ_BOS_DESC 0x0CU
#elif (USBD_CLASS_BOS_ENABLED == 1)
#define USB_SIZ_BOS_DESC 0x5DU
#endif
#endif /* USBD_LPM_ENABLED */
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
@@ -60,4 +59,3 @@ extern USBD_DescriptorsTypeDef XXX_Desc; /* Replace 'XXX_Desc' with your active
#endif /* __USBD_DESC_TEMPLATE_H*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -111,4 +110,4 @@ uint32_t USBD_GetRxCount(USBD_HandleTypeDef *pdev, uint8_t ep_addr);
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -8,13 +8,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -234,6 +233,22 @@ uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
return 0U;
}
#ifdef USBD_HS_TESTMODE_ENABLE
/**
* @brief Set High speed Test mode.
* @param pdev: Device handle
* @param testmode: test mode
* @retval USBD Status
*/
USBD_StatusTypeDef USBD_LL_SetTestMode(USBD_HandleTypeDef *pdev, uint8_t testmode)
{
UNUSED(pdev);
UNUSED(testmode);
return USBD_OK;
}
#endif /* USBD_HS_TESTMODE_ENABLE */
/**
* @brief Static single allocation.
* @param size: Size of allocated memory
@@ -241,6 +256,7 @@ uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
*/
void *USBD_static_malloc(uint32_t size)
{
UNUSED(size);
static uint32_t mem[(sizeof(USBD_HID_HandleTypeDef) / 4) + 1]; /* On 32-bit boundary */
return mem;
}
@@ -252,7 +268,7 @@ void *USBD_static_malloc(uint32_t size)
*/
void USBD_static_free(void *p)
{
UNUSED(p);
}
/**
@@ -264,5 +280,4 @@ void USBD_LL_Delay(uint32_t Delay)
{
UNUSED(Delay);
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -20,6 +19,10 @@
/* Includes ------------------------------------------------------------------*/
#include "usbd_core.h"
#ifdef USE_USBD_COMPOSITE
#include "usbd_composite_builder.h"
#endif /* USE_USBD_COMPOSITE */
/** @addtogroup STM32_USBD_DEVICE_LIBRARY
* @{
*/
@@ -96,13 +99,29 @@ USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev,
{
#if (USBD_DEBUG_LEVEL > 1U)
USBD_ErrLog("Invalid Device handle");
#endif
#endif /* (USBD_DEBUG_LEVEL > 1U) */
return USBD_FAIL;
}
/* Unlink previous class resources */
pdev->pClass = NULL;
pdev->pUserData = NULL;
#ifdef USE_USBD_COMPOSITE
/* Parse the table of classes in use */
for (uint32_t i = 0; i < USBD_MAX_SUPPORTED_CLASS; i++)
{
/* Unlink previous class*/
pdev->pClass[i] = NULL;
pdev->pUserData[i] = NULL;
/* Set class as inactive */
pdev->tclasslist[i].Active = 0;
pdev->NumClasses = 0;
pdev->classId = 0;
}
#else
/* Unlink previous class*/
pdev->pClass[0] = NULL;
pdev->pUserData[0] = NULL;
#endif /* USE_USBD_COMPOSITE */
pdev->pConfDesc = NULL;
/* Assign USBD Descriptors */
@@ -137,13 +156,31 @@ USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev)
/* Set Default State */
pdev->dev_state = USBD_STATE_DEFAULT;
/* Free Class Resources */
if (pdev->pClass != NULL)
#ifdef USE_USBD_COMPOSITE
/* Parse the table of classes in use */
for (uint32_t i = 0; i < USBD_MAX_SUPPORTED_CLASS; i++)
{
pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
pdev->pClass = NULL;
pdev->pUserData = NULL;
/* Check if current class is in use */
if ((pdev->tclasslist[i].Active) == 1U)
{
if (pdev->pClass[i] != NULL)
{
pdev->classId = i;
/* Free Class Resources */
pdev->pClass[i]->DeInit(pdev, (uint8_t)pdev->dev_config);
}
}
}
#else
/* Free Class Resources */
if (pdev->pClass[0] != NULL)
{
pdev->pClass[0]->DeInit(pdev, (uint8_t)pdev->dev_config);
}
pdev->pUserData[0] = NULL;
#endif /* USE_USBD_COMPOSITE */
/* Free Device descriptors resources */
pdev->pDesc = NULL;
@@ -170,29 +207,161 @@ USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDe
{
#if (USBD_DEBUG_LEVEL > 1U)
USBD_ErrLog("Invalid Class handle");
#endif
#endif /* (USBD_DEBUG_LEVEL > 1U) */
return USBD_FAIL;
}
/* link the class to the USB Device handle */
pdev->pClass = pclass;
pdev->pClass[0] = pclass;
/* Get Device Configuration Descriptor */
#ifdef USE_USB_HS
if (pdev->pClass->GetHSConfigDescriptor != NULL)
if (pdev->pClass[pdev->classId]->GetHSConfigDescriptor != NULL)
{
pdev->pConfDesc = (void *)pdev->pClass->GetHSConfigDescriptor(&len);
pdev->pConfDesc = (void *)pdev->pClass[pdev->classId]->GetHSConfigDescriptor(&len);
}
#else /* Default USE_USB_FS */
if (pdev->pClass->GetFSConfigDescriptor != NULL)
if (pdev->pClass[pdev->classId]->GetFSConfigDescriptor != NULL)
{
pdev->pConfDesc = (void *)pdev->pClass->GetFSConfigDescriptor(&len);
pdev->pConfDesc = (void *)pdev->pClass[pdev->classId]->GetFSConfigDescriptor(&len);
}
#endif /* USE_USB_FS */
/* Increment the NumClasses */
pdev->NumClasses ++;
return USBD_OK;
}
#ifdef USE_USBD_COMPOSITE
/**
* @brief USBD_RegisterClassComposite
* Link class driver to Device Core.
* @param pdev : Device Handle
* @param pclass: Class handle
* @param classtype: Class type
* @param EpAddr: Endpoint Address handle
* @retval USBD Status
*/
USBD_StatusTypeDef USBD_RegisterClassComposite(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass,
USBD_CompositeClassTypeDef classtype, uint8_t *EpAddr)
{
USBD_StatusTypeDef ret = USBD_OK;
uint16_t len = 0U;
if ((pdev->classId < USBD_MAX_SUPPORTED_CLASS) && (pdev->NumClasses < USBD_MAX_SUPPORTED_CLASS))
{
if ((uint32_t)pclass != 0U)
{
/* Link the class to the USB Device handle */
pdev->pClass[pdev->classId] = pclass;
ret = USBD_OK;
pdev->tclasslist[pdev->classId].EpAdd = EpAddr;
/* Call the composite class builder */
(void)USBD_CMPSIT_AddClass(pdev, pclass, classtype, 0);
/* Increment the ClassId for the next occurrence */
pdev->classId ++;
pdev->NumClasses ++;
}
else
{
#if (USBD_DEBUG_LEVEL > 1U)
USBD_ErrLog("Invalid Class handle");
#endif /* (USBD_DEBUG_LEVEL > 1U) */
ret = USBD_FAIL;
}
}
if (ret == USBD_OK)
{
/* Get Device Configuration Descriptor */
#ifdef USE_USB_HS
pdev->pConfDesc = USBD_CMPSIT.GetHSConfigDescriptor(&len);
#else /* Default USE_USB_FS */
pdev->pConfDesc = USBD_CMPSIT.GetFSConfigDescriptor(&len);
#endif /* USE_USB_FS */
}
return ret;
}
/**
* @brief USBD_UnRegisterClassComposite
* UnLink all composite class drivers from Device Core.
* @param pDevice : Device Handle
* @retval USBD Status
*/
USBD_StatusTypeDef USBD_UnRegisterClassComposite(USBD_HandleTypeDef *pdev)
{
USBD_StatusTypeDef ret = USBD_FAIL;
uint8_t idx1;
uint8_t idx2;
/* Unroll all activated classes */
for (idx1 = 0; idx1 < pdev->NumClasses; idx1++)
{
/* Check if the class correspond to the requested type and if it is active */
if (pdev->tclasslist[idx1].Active == 1U)
{
/* Set the new class ID */
pdev->classId = idx1;
/* Free resources used by the selected class */
if (pdev->pClass[pdev->classId] != NULL)
{
/* Free Class Resources */
if (pdev->pClass[pdev->classId]->DeInit(pdev, (uint8_t)pdev->dev_config) != 0U)
{
#if (USBD_DEBUG_LEVEL > 1U)
USBD_ErrLog("Class DeInit didn't succeed!, can't unregister selected class");
#endif /* (USBD_DEBUG_LEVEL > 1U) */
ret = USBD_FAIL;
}
}
/* Free the class pointer */
pdev->pClass[pdev->classId] = NULL;
/* Free the class location in classes table and reset its parameters to zero */
pdev->tclasslist[pdev->classId].ClassType = CLASS_TYPE_NONE;
pdev->tclasslist[pdev->classId].ClassId = 0U;
pdev->tclasslist[pdev->classId].Active = 0U;
pdev->tclasslist[pdev->classId].NumEps = 0U;
pdev->tclasslist[pdev->classId].NumIf = 0U;
pdev->tclasslist[pdev->classId].CurrPcktSze = 0U;
for (idx2 = 0U; idx2 < USBD_MAX_CLASS_ENDPOINTS; idx2++)
{
pdev->tclasslist[pdev->classId].Eps[idx2].add = 0U;
pdev->tclasslist[pdev->classId].Eps[idx2].type = 0U;
pdev->tclasslist[pdev->classId].Eps[idx2].size = 0U;
pdev->tclasslist[pdev->classId].Eps[idx2].is_used = 0U;
}
for (idx2 = 0U; idx2 < USBD_MAX_CLASS_INTERFACES; idx2++)
{
pdev->tclasslist[pdev->classId].Ifs[idx2] = 0U;
}
}
}
/* Reset the configuration descriptor */
(void)USBD_CMPST_ClearConfDesc(pdev);
/* Reset the class ID and number of classes */
pdev->classId = 0U;
pdev->NumClasses = 0U;
return ret;
}
#endif /* USE_USBD_COMPOSITE */
/**
* @brief USBD_Start
* Start the USB Device Core.
@@ -201,6 +370,10 @@ USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDe
*/
USBD_StatusTypeDef USBD_Start(USBD_HandleTypeDef *pdev)
{
#ifdef USE_USBD_COMPOSITE
pdev->classId = 0U;
#endif /* USE_USBD_COMPOSITE */
/* Start the low level driver */
return USBD_LL_Start(pdev);
}
@@ -217,10 +390,30 @@ USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev)
(void)USBD_LL_Stop(pdev);
/* Free Class Resources */
if (pdev->pClass != NULL)
#ifdef USE_USBD_COMPOSITE
/* Parse the table of classes in use */
for (uint32_t i = 0U; i < USBD_MAX_SUPPORTED_CLASS; i++)
{
(void)pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
/* Check if current class is in use */
if ((pdev->tclasslist[i].Active) == 1U)
{
if (pdev->pClass[i] != NULL)
{
pdev->classId = i;
/* Free Class Resources */
(void)pdev->pClass[i]->DeInit(pdev, (uint8_t)pdev->dev_config);
}
}
}
/* Reset the class ID */
pdev->classId = 0U;
#else
if (pdev->pClass[0] != NULL)
{
(void)pdev->pClass[0]->DeInit(pdev, (uint8_t)pdev->dev_config);
}
#endif /* USE_USBD_COMPOSITE */
return USBD_OK;
}
@@ -233,10 +426,19 @@ USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev)
*/
USBD_StatusTypeDef USBD_RunTestMode(USBD_HandleTypeDef *pdev)
{
#ifdef USBD_HS_TESTMODE_ENABLE
USBD_StatusTypeDef ret;
/* Run USB HS test mode */
ret = USBD_LL_SetTestMode(pdev, pdev->dev_test_mode);
return ret;
#else
/* Prevent unused argument compilation warning */
UNUSED(pdev);
return USBD_OK;
#endif /* USBD_HS_TESTMODE_ENABLE */
}
/**
@@ -249,13 +451,33 @@ USBD_StatusTypeDef USBD_RunTestMode(USBD_HandleTypeDef *pdev)
USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
USBD_StatusTypeDef ret = USBD_FAIL;
USBD_StatusTypeDef ret = USBD_OK;
if (pdev->pClass != NULL)
#ifdef USE_USBD_COMPOSITE
/* Parse the table of classes in use */
for (uint32_t i = 0U; i < USBD_MAX_SUPPORTED_CLASS; i++)
{
/* Check if current class is in use */
if ((pdev->tclasslist[i].Active) == 1U)
{
if (pdev->pClass[i] != NULL)
{
pdev->classId = i;
/* Set configuration and Start the Class*/
if (pdev->pClass[i]->Init(pdev, cfgidx) != 0U)
{
ret = USBD_FAIL;
}
}
}
}
#else
if (pdev->pClass[0] != NULL)
{
/* Set configuration and Start the Class */
ret = (USBD_StatusTypeDef)pdev->pClass->Init(pdev, cfgidx);
ret = (USBD_StatusTypeDef)pdev->pClass[0]->Init(pdev, cfgidx);
}
#endif /* USE_USBD_COMPOSITE */
return ret;
}
@@ -269,13 +491,35 @@ USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
*/
USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
/* Clear configuration and De-initialize the Class process */
if (pdev->pClass != NULL)
{
pdev->pClass->DeInit(pdev, cfgidx);
}
USBD_StatusTypeDef ret = USBD_OK;
return USBD_OK;
#ifdef USE_USBD_COMPOSITE
/* Parse the table of classes in use */
for (uint32_t i = 0U; i < USBD_MAX_SUPPORTED_CLASS; i++)
{
/* Check if current class is in use */
if ((pdev->tclasslist[i].Active) == 1U)
{
if (pdev->pClass[i] != NULL)
{
pdev->classId = i;
/* Clear configuration and De-initialize the Class process */
if (pdev->pClass[i]->DeInit(pdev, cfgidx) != 0U)
{
ret = USBD_FAIL;
}
}
}
}
#else
/* Clear configuration and De-initialize the Class process */
if (pdev->pClass[0]->DeInit(pdev, cfgidx) != 0U)
{
ret = USBD_FAIL;
}
#endif /* USE_USBD_COMPOSITE */
return ret;
}
@@ -329,7 +573,8 @@ USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev,
uint8_t epnum, uint8_t *pdata)
{
USBD_EndpointTypeDef *pep;
USBD_StatusTypeDef ret;
USBD_StatusTypeDef ret = USBD_OK;
uint8_t idx;
if (epnum == 0U)
{
@@ -345,46 +590,68 @@ USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev,
}
else
{
/* Find the class ID relative to the current request */
switch (pdev->request.bmRequest & 0x1FU)
{
case USB_REQ_RECIPIENT_DEVICE:
/* Device requests must be managed by the first instantiated class
(or duplicated by all classes for simplicity) */
idx = 0U;
break;
case USB_REQ_RECIPIENT_INTERFACE:
idx = USBD_CoreFindIF(pdev, LOBYTE(pdev->request.wIndex));
break;
case USB_REQ_RECIPIENT_ENDPOINT:
idx = USBD_CoreFindEP(pdev, LOBYTE(pdev->request.wIndex));
break;
default:
/* Back to the first class in case of doubt */
idx = 0U;
break;
}
if (idx < USBD_MAX_SUPPORTED_CLASS)
{
/* Setup the class ID and route the request to the relative class function */
if (pdev->dev_state == USBD_STATE_CONFIGURED)
{
if (pdev->pClass->EP0_RxReady != NULL)
if (pdev->pClass[idx]->EP0_RxReady != NULL)
{
pdev->pClass->EP0_RxReady(pdev);
pdev->classId = idx;
pdev->pClass[idx]->EP0_RxReady(pdev);
}
}
}
(void)USBD_CtlSendStatus(pdev);
}
}
else
{
#if 0
if (pdev->ep0_state == USBD_EP0_STATUS_OUT)
{
/*
* STATUS PHASE completed, update ep0_state to idle
*/
pdev->ep0_state = USBD_EP0_IDLE;
(void)USBD_LL_StallEP(pdev, 0U);
}
#endif
}
}
else
{
/* Get the class index relative to this interface */
idx = USBD_CoreFindEP(pdev, (epnum & 0x7FU));
if (((uint16_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS))
{
/* Call the class data out function to manage the request */
if (pdev->dev_state == USBD_STATE_CONFIGURED)
{
if (pdev->pClass->DataOut != NULL)
if (pdev->pClass[idx]->DataOut != NULL)
{
ret = (USBD_StatusTypeDef)pdev->pClass->DataOut(pdev, epnum);
pdev->classId = idx;
ret = (USBD_StatusTypeDef)pdev->pClass[idx]->DataOut(pdev, epnum);
}
}
if (ret != USBD_OK)
{
return ret;
}
}
}
}
return USBD_OK;
}
@@ -401,6 +668,7 @@ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev,
{
USBD_EndpointTypeDef *pep;
USBD_StatusTypeDef ret;
uint8_t idx;
if (epnum == 0U)
{
@@ -434,9 +702,10 @@ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev,
{
if (pdev->dev_state == USBD_STATE_CONFIGURED)
{
if (pdev->pClass->EP0_TxSent != NULL)
if (pdev->pClass[0]->EP0_TxSent != NULL)
{
pdev->pClass->EP0_TxSent(pdev);
pdev->classId = 0U;
pdev->pClass[0]->EP0_TxSent(pdev);
}
}
(void)USBD_LL_StallEP(pdev, 0x80U);
@@ -444,18 +713,8 @@ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev,
}
}
}
else
{
#if 0
if ((pdev->ep0_state == USBD_EP0_STATUS_IN) ||
(pdev->ep0_state == USBD_EP0_IDLE))
{
(void)USBD_LL_StallEP(pdev, 0x80U);
}
#endif
}
if (pdev->dev_test_mode == 1U)
if (pdev->dev_test_mode != 0U)
{
(void)USBD_RunTestMode(pdev);
pdev->dev_test_mode = 0U;
@@ -463,11 +722,18 @@ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev,
}
else
{
/* Get the class index relative to this interface */
idx = USBD_CoreFindEP(pdev, ((uint8_t)epnum | 0x80U));
if (((uint16_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS))
{
/* Call the class data out function to manage the request */
if (pdev->dev_state == USBD_STATE_CONFIGURED)
{
if (pdev->pClass->DataIn != NULL)
if (pdev->pClass[idx]->DataIn != NULL)
{
ret = (USBD_StatusTypeDef)pdev->pClass->DataIn(pdev, epnum);
pdev->classId = idx;
ret = (USBD_StatusTypeDef)pdev->pClass[idx]->DataIn(pdev, epnum);
if (ret != USBD_OK)
{
@@ -476,6 +742,7 @@ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev,
}
}
}
}
return USBD_OK;
}
@@ -489,24 +756,50 @@ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev,
USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev)
{
USBD_StatusTypeDef ret = USBD_OK;
/* Upon Reset call user call back */
pdev->dev_state = USBD_STATE_DEFAULT;
pdev->ep0_state = USBD_EP0_IDLE;
pdev->dev_config = 0U;
pdev->dev_remote_wakeup = 0U;
pdev->dev_test_mode = 0U;
if (pdev->pClass == NULL)
#ifdef USE_USBD_COMPOSITE
/* Parse the table of classes in use */
for (uint32_t i = 0U; i < USBD_MAX_SUPPORTED_CLASS; i++)
{
return USBD_FAIL;
}
/* Check if current class is in use */
if ((pdev->tclasslist[i].Active) == 1U)
{
if (pdev->pClass[i] != NULL)
{
pdev->classId = i;
/* Clear configuration and De-initialize the Class process*/
if (pdev->pClassData != NULL)
if (pdev->pClass[i]->DeInit != NULL)
{
if (pdev->pClass->DeInit != NULL)
if (pdev->pClass[i]->DeInit(pdev, (uint8_t)pdev->dev_config) != USBD_OK)
{
(void)pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
ret = USBD_FAIL;
}
}
}
}
}
#else
if (pdev->pClass[0] != NULL)
{
if (pdev->pClass[0]->DeInit != NULL)
{
if (pdev->pClass[0]->DeInit(pdev, (uint8_t)pdev->dev_config) != USBD_OK)
{
ret = USBD_FAIL;
}
}
}
#endif /* USE_USBD_COMPOSITE */
/* Open EP0 OUT */
(void)USBD_LL_OpenEP(pdev, 0x00U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE);
@@ -520,7 +813,7 @@ USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev)
pdev->ep_in[0].maxpacket = USB_MAX_EP0_SIZE;
return USBD_OK;
return ret;
}
/**
@@ -546,7 +839,11 @@ USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev,
USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev)
{
if (pdev->dev_state != USBD_STATE_SUSPENDED)
{
pdev->dev_old_state = pdev->dev_state;
}
pdev->dev_state = USBD_STATE_SUSPENDED;
return USBD_OK;
@@ -578,18 +875,36 @@ USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev)
USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev)
{
if (pdev->pClass == NULL)
{
return USBD_FAIL;
}
/* The SOF event can be distributed for all classes that support it */
if (pdev->dev_state == USBD_STATE_CONFIGURED)
{
if (pdev->pClass->SOF != NULL)
#ifdef USE_USBD_COMPOSITE
/* Parse the table of classes in use */
for (uint32_t i = 0; i < USBD_MAX_SUPPORTED_CLASS; i++)
{
(void)pdev->pClass->SOF(pdev);
/* Check if current class is in use */
if ((pdev->tclasslist[i].Active) == 1U)
{
if (pdev->pClass[i] != NULL)
{
if (pdev->pClass[i]->SOF != NULL)
{
pdev->classId = i;
(void)pdev->pClass[i]->SOF(pdev);
}
}
}
}
#else
if (pdev->pClass[0] != NULL)
{
if (pdev->pClass[0]->SOF != NULL)
{
(void)pdev->pClass[0]->SOF(pdev);
}
}
#endif /* USE_USBD_COMPOSITE */
}
return USBD_OK;
}
@@ -603,16 +918,16 @@ USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev)
USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev,
uint8_t epnum)
{
if (pdev->pClass == NULL)
if (pdev->pClass[pdev->classId] == NULL)
{
return USBD_FAIL;
}
if (pdev->dev_state == USBD_STATE_CONFIGURED)
{
if (pdev->pClass->IsoINIncomplete != NULL)
if (pdev->pClass[pdev->classId]->IsoINIncomplete != NULL)
{
(void)pdev->pClass->IsoINIncomplete(pdev, epnum);
(void)pdev->pClass[pdev->classId]->IsoINIncomplete(pdev, epnum);
}
}
@@ -628,16 +943,16 @@ USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev,
USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev,
uint8_t epnum)
{
if (pdev->pClass == NULL)
if (pdev->pClass[pdev->classId] == NULL)
{
return USBD_FAIL;
}
if (pdev->dev_state == USBD_STATE_CONFIGURED)
{
if (pdev->pClass->IsoOUTIncomplete != NULL)
if (pdev->pClass[pdev->classId]->IsoOUTIncomplete != NULL)
{
(void)pdev->pClass->IsoOUTIncomplete(pdev, epnum);
(void)pdev->pClass[pdev->classId]->IsoOUTIncomplete(pdev, epnum);
}
}
@@ -666,16 +981,211 @@ USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev)
*/
USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev)
{
USBD_StatusTypeDef ret = USBD_OK;
/* Free Class Resources */
pdev->dev_state = USBD_STATE_DEFAULT;
if (pdev->pClass != NULL)
#ifdef USE_USBD_COMPOSITE
/* Parse the table of classes in use */
for (uint32_t i = 0; i < USBD_MAX_SUPPORTED_CLASS; i++)
{
(void)pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
/* Check if current class is in use */
if ((pdev->tclasslist[i].Active) == 1U)
{
if (pdev->pClass[i] != NULL)
{
pdev->classId = i;
/* Clear configuration and De-initialize the Class process*/
if (pdev->pClass[i]->DeInit(pdev, (uint8_t)pdev->dev_config) != 0U)
{
ret = USBD_FAIL;
}
}
}
}
#else
if (pdev->pClass[0] != NULL)
{
if (pdev->pClass[0]->DeInit(pdev, (uint8_t)pdev->dev_config) != 0U)
{
ret = USBD_FAIL;
}
}
#endif /* USE_USBD_COMPOSITE */
return ret;
}
/**
* @brief USBD_CoreFindIF
* return the class index relative to the selected interface
* @param pdev: device instance
* @param index : selected interface number
* @retval index of the class using the selected interface number. OxFF if no class found.
*/
uint8_t USBD_CoreFindIF(USBD_HandleTypeDef *pdev, uint8_t index)
{
#ifdef USE_USBD_COMPOSITE
/* Parse the table of classes in use */
for (uint32_t i = 0U; i < USBD_MAX_SUPPORTED_CLASS; i++)
{
/* Check if current class is in use */
if ((pdev->tclasslist[i].Active) == 1U)
{
/* Parse all interfaces listed in the current class */
for (uint32_t j = 0U; j < pdev->tclasslist[i].NumIf; j++)
{
/* Check if requested Interface matches the current class interface */
if (pdev->tclasslist[i].Ifs[j] == index)
{
if (pdev->pClass[i]->Setup != NULL)
{
return (uint8_t)i;
}
}
}
}
}
return USBD_OK;
return 0xFFU;
#else
UNUSED(pdev);
UNUSED(index);
return 0x00U;
#endif /* USE_USBD_COMPOSITE */
}
/**
* @brief USBD_CoreFindEP
* return the class index relative to the selected endpoint
* @param pdev: device instance
* @param index : selected endpoint number
* @retval index of the class using the selected endpoint number. 0xFF if no class found.
*/
uint8_t USBD_CoreFindEP(USBD_HandleTypeDef *pdev, uint8_t index)
{
#ifdef USE_USBD_COMPOSITE
/* Parse the table of classes in use */
for (uint32_t i = 0U; i < USBD_MAX_SUPPORTED_CLASS; i++)
{
/* Check if current class is in use */
if ((pdev->tclasslist[i].Active) == 1U)
{
/* Parse all endpoints listed in the current class */
for (uint32_t j = 0U; j < pdev->tclasslist[i].NumEps; j++)
{
/* Check if requested endpoint matches the current class endpoint */
if (pdev->tclasslist[i].Eps[j].add == index)
{
if (pdev->pClass[i]->Setup != NULL)
{
return (uint8_t)i;
}
}
}
}
}
return 0xFFU;
#else
UNUSED(pdev);
UNUSED(index);
return 0x00U;
#endif /* USE_USBD_COMPOSITE */
}
#ifdef USE_USBD_COMPOSITE
/**
* @brief USBD_CoreGetEPAdd
* Get the endpoint address relative to a selected class
* @param pdev: device instance
* @param ep_dir: USBD_EP_IN or USBD_EP_OUT
* @param ep_type: USBD_EP_TYPE_CTRL, USBD_EP_TYPE_ISOC, USBD_EP_TYPE_BULK or USBD_EP_TYPE_INTR
* @param ClassId: The Class ID
* @retval Address of the selected endpoint or 0xFFU if no endpoint found.
*/
uint8_t USBD_CoreGetEPAdd(USBD_HandleTypeDef *pdev, uint8_t ep_dir, uint8_t ep_type, uint8_t ClassId)
{
uint8_t idx;
/* Find the EP address in the selected class table */
for (idx = 0; idx < pdev->tclasslist[ClassId].NumEps; idx++)
{
if (((pdev->tclasslist[ClassId].Eps[idx].add & USBD_EP_IN) == ep_dir) && \
(pdev->tclasslist[ClassId].Eps[idx].type == ep_type) && \
(pdev->tclasslist[ClassId].Eps[idx].is_used != 0U))
{
return (pdev->tclasslist[ClassId].Eps[idx].add);
}
}
/* If reaching this point, then no endpoint was found */
return 0xFFU;
}
#endif /* USE_USBD_COMPOSITE */
/**
* @brief USBD_GetEpDesc
* This function return the Endpoint descriptor
* @param pdev: device instance
* @param pConfDesc: pointer to Bos descriptor
* @param EpAddr: endpoint address
* @retval pointer to video endpoint descriptor
*/
void *USBD_GetEpDesc(uint8_t *pConfDesc, uint8_t EpAddr)
{
USBD_DescHeaderTypeDef *pdesc = (USBD_DescHeaderTypeDef *)(void *)pConfDesc;
USBD_ConfigDescTypeDef *desc = (USBD_ConfigDescTypeDef *)(void *)pConfDesc;
USBD_EpDescTypeDef *pEpDesc = NULL;
uint16_t ptr;
if (desc->wTotalLength > desc->bLength)
{
ptr = desc->bLength;
while (ptr < desc->wTotalLength)
{
pdesc = USBD_GetNextDesc((uint8_t *)pdesc, &ptr);
if (pdesc->bDescriptorType == USB_DESC_TYPE_ENDPOINT)
{
pEpDesc = (USBD_EpDescTypeDef *)(void *)pdesc;
if (pEpDesc->bEndpointAddress == EpAddr)
{
break;
}
else
{
pEpDesc = NULL;
}
}
}
}
return (void *)pEpDesc;
}
/**
* @brief USBD_GetNextDesc
* This function return the next descriptor header
* @param buf: Buffer where the descriptor is available
* @param ptr: data pointer inside the descriptor
* @retval next header
*/
USBD_DescHeaderTypeDef *USBD_GetNextDesc(uint8_t *pbuf, uint16_t *ptr)
{
USBD_DescHeaderTypeDef *pnext = (USBD_DescHeaderTypeDef *)(void *)pbuf;
*ptr += pnext->bLength;
pnext = (USBD_DescHeaderTypeDef *)(void *)(pbuf + pnext->bLength);
return (pnext);
}
/**
* @}
*/
@@ -690,5 +1200,3 @@ USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev)
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -21,6 +20,9 @@
#include "usbd_ctlreq.h"
#include "usbd_ioreq.h"
#ifdef USE_USBD_COMPOSITE
#include "usbd_composite_builder.h"
#endif /* USE_USBD_COMPOSITE */
/** @addtogroup STM32_USBD_STATE_DEVICE_LIBRARY
* @{
@@ -105,7 +107,7 @@ USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef
{
case USB_REQ_TYPE_CLASS:
case USB_REQ_TYPE_VENDOR:
ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req);
ret = (USBD_StatusTypeDef)pdev->pClass[pdev->classId]->Setup(pdev, req);
break;
case USB_REQ_TYPE_STANDARD:
@@ -163,6 +165,7 @@ USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef
USBD_StatusTypeDef USBD_StdItfReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
USBD_StatusTypeDef ret = USBD_OK;
uint8_t idx;
switch (req->bmRequest & USB_REQ_TYPE_MASK)
{
@@ -177,7 +180,27 @@ USBD_StatusTypeDef USBD_StdItfReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef
if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES)
{
ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req);
/* Get the class index relative to this interface */
idx = USBD_CoreFindIF(pdev, LOBYTE(req->wIndex));
if (((uint8_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS))
{
/* Call the class data out function to manage the request */
if (pdev->pClass[idx]->Setup != NULL)
{
pdev->classId = idx;
ret = (USBD_StatusTypeDef)(pdev->pClass[idx]->Setup(pdev, req));
}
else
{
/* should never reach this condition */
ret = USBD_FAIL;
}
}
else
{
/* No relative interface found */
ret = USBD_FAIL;
}
if ((req->wLength == 0U) && (ret == USBD_OK))
{
@@ -215,14 +238,26 @@ USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef
{
USBD_EndpointTypeDef *pep;
uint8_t ep_addr;
uint8_t idx;
USBD_StatusTypeDef ret = USBD_OK;
ep_addr = LOBYTE(req->wIndex);
switch (req->bmRequest & USB_REQ_TYPE_MASK)
{
case USB_REQ_TYPE_CLASS:
case USB_REQ_TYPE_VENDOR:
ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req);
/* Get the class index relative to this endpoint */
idx = USBD_CoreFindEP(pdev, ep_addr);
if (((uint8_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS))
{
pdev->classId = idx;
/* Call the class data out function to manage the request */
if (pdev->pClass[idx]->Setup != NULL)
{
ret = (USBD_StatusTypeDef)pdev->pClass[idx]->Setup(pdev, req);
}
}
break;
case USB_REQ_TYPE_STANDARD:
@@ -285,7 +320,18 @@ USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef
(void)USBD_LL_ClearStallEP(pdev, ep_addr);
}
(void)USBD_CtlSendStatus(pdev);
ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req);
/* Get the class index relative to this interface */
idx = USBD_CoreFindEP(pdev, ep_addr);
if (((uint8_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS))
{
pdev->classId = idx;
/* Call the class data out function to manage the request */
if (pdev->pClass[idx]->Setup != NULL)
{
ret = (USBD_StatusTypeDef)(pdev->pClass[idx]->Setup(pdev, req));
}
}
}
break;
@@ -397,7 +443,7 @@ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *r
err++;
}
break;
#endif
#endif /* (USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1U) */
case USB_DESC_TYPE_DEVICE:
pbuf = pdev->pDesc->GetDeviceDescriptor(pdev->dev_speed, &len);
break;
@@ -405,12 +451,30 @@ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *r
case USB_DESC_TYPE_CONFIGURATION:
if (pdev->dev_speed == USBD_SPEED_HIGH)
{
pbuf = pdev->pClass->GetHSConfigDescriptor(&len);
#ifdef USE_USBD_COMPOSITE
if ((uint8_t)(pdev->NumClasses) > 0U)
{
pbuf = (uint8_t *)USBD_CMPSIT.GetHSConfigDescriptor(&len);
}
else
#endif /* USE_USBD_COMPOSITE */
{
pbuf = (uint8_t *)pdev->pClass[0]->GetHSConfigDescriptor(&len);
}
pbuf[1] = USB_DESC_TYPE_CONFIGURATION;
}
else
{
pbuf = pdev->pClass->GetFSConfigDescriptor(&len);
#ifdef USE_USBD_COMPOSITE
if ((uint8_t)(pdev->NumClasses) > 0U)
{
pbuf = (uint8_t *)USBD_CMPSIT.GetFSConfigDescriptor(&len);
}
else
#endif /* USE_USBD_COMPOSITE */
{
pbuf = (uint8_t *)pdev->pClass[0]->GetFSConfigDescriptor(&len);
}
pbuf[1] = USB_DESC_TYPE_CONFIGURATION;
}
break;
@@ -492,16 +556,28 @@ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *r
default:
#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
if (pdev->pClass->GetUsrStrDescriptor != NULL)
pbuf = NULL;
for (uint32_t idx = 0U; (idx < pdev->NumClasses); idx++)
{
pbuf = pdev->pClass->GetUsrStrDescriptor(pdev, (req->wValue), &len);
if (pdev->pClass[idx]->GetUsrStrDescriptor != NULL)
{
pdev->classId = idx;
pbuf = pdev->pClass[idx]->GetUsrStrDescriptor(pdev, LOBYTE(req->wValue), &len);
if (pbuf == NULL) /* This means that no class recognized the string index */
{
continue;
}
else
{
USBD_CtlError(pdev, req);
err++;
break;
}
#endif
}
}
#endif /* USBD_SUPPORT_USER_STRING_DESC */
#if (USBD_CLASS_USER_STRING_DESC == 1U)
if (pdev->pDesc->GetUserStrDescriptor != NULL)
@@ -513,12 +589,12 @@ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *r
USBD_CtlError(pdev, req);
err++;
}
#endif
#endif /* USBD_SUPPORT_USER_STRING_DESC */
#if ((USBD_CLASS_USER_STRING_DESC == 0U) && (USBD_SUPPORT_USER_STRING_DESC == 0U))
USBD_CtlError(pdev, req);
err++;
#endif
#endif /* (USBD_CLASS_USER_STRING_DESC == 0U) && (USBD_SUPPORT_USER_STRING_DESC == 0U) */
break;
}
break;
@@ -526,7 +602,16 @@ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *r
case USB_DESC_TYPE_DEVICE_QUALIFIER:
if (pdev->dev_speed == USBD_SPEED_HIGH)
{
pbuf = pdev->pClass->GetDeviceQualifierDescriptor(&len);
#ifdef USE_USBD_COMPOSITE
if ((uint8_t)(pdev->NumClasses) > 0U)
{
pbuf = (uint8_t *)USBD_CMPSIT.GetDeviceQualifierDescriptor(&len);
}
else
#endif /* USE_USBD_COMPOSITE */
{
pbuf = (uint8_t *)pdev->pClass[0]->GetDeviceQualifierDescriptor(&len);
}
}
else
{
@@ -538,7 +623,16 @@ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *r
case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION:
if (pdev->dev_speed == USBD_SPEED_HIGH)
{
pbuf = pdev->pClass->GetOtherSpeedConfigDescriptor(&len);
#ifdef USE_USBD_COMPOSITE
if ((uint8_t)(pdev->NumClasses) > 0U)
{
pbuf = (uint8_t *)USBD_CMPSIT.GetOtherSpeedConfigDescriptor(&len);
}
else
#endif /* USE_USBD_COMPOSITE */
{
pbuf = (uint8_t *)pdev->pClass[0]->GetOtherSpeedConfigDescriptor(&len);
}
pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION;
}
else
@@ -651,6 +745,7 @@ static USBD_StatusTypeDef USBD_SetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReq
if (ret != USBD_OK)
{
USBD_CtlError(pdev, req);
pdev->dev_state = USBD_STATE_ADDRESSED;
}
else
{
@@ -767,7 +862,7 @@ static void USBD_GetStatus(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
pdev->dev_config_status = USB_CONFIG_SELF_POWERED;
#else
pdev->dev_config_status = 0U;
#endif
#endif /* USBD_SELF_POWERED */
if (pdev->dev_remote_wakeup != 0U)
{
@@ -798,6 +893,15 @@ static void USBD_SetFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
pdev->dev_remote_wakeup = 1U;
(void)USBD_CtlSendStatus(pdev);
}
else if (req->wValue == USB_FEATURE_TEST_MODE)
{
pdev->dev_test_mode = (uint8_t)(req->wIndex >> 8);
(void)USBD_CtlSendStatus(pdev);
}
else
{
USBD_CtlError(pdev, req);
}
}
@@ -945,4 +1049,3 @@ static uint8_t USBD_GetLen(uint8_t *buf)
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -8,13 +8,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -53,7 +52,7 @@ uint8_t *USBD_Class_UserStrDescriptor(USBD_SpeedTypeDef speed, uint8_t idx, uint
#if ((USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1))
uint8_t *USBD_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
#endif
#endif /* (USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1) */
/* Private variables ---------------------------------------------------------*/
USBD_DescriptorsTypeDef Class_Desc =
@@ -67,17 +66,17 @@ USBD_DescriptorsTypeDef Class_Desc =
USBD_Class_InterfaceStrDescriptor,
#if (USBD_CLASS_USER_STRING_DESC == 1)
USBD_CLASS_UserStrDescriptor,
#endif
#endif /* USB_CLASS_USER_STRING_DESC */
#if ((USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1))
USBD_USR_BOSDescriptor,
#endif
#endif /* (USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1) */
};
/* USB Standard Device Descriptor */
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* __ICCARM__ */
__ALIGN_BEGIN uint8_t USBD_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END =
{
0x12, /* bLength */
@@ -87,7 +86,7 @@ __ALIGN_BEGIN uint8_t USBD_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END =
in order to support BOS Desc */
#else
0x00, /* bcdUSB */
#endif
#endif /* (USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1) */
0x02,
0x00, /* bDeviceClass */
0x00, /* bDeviceSubClass */
@@ -110,7 +109,7 @@ __ALIGN_BEGIN uint8_t USBD_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END =
#if (USBD_LPM_ENABLED == 1)
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* __ICCARM__ */
__ALIGN_BEGIN uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END =
{
0x5,
@@ -127,13 +126,13 @@ __ALIGN_BEGIN uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END =
0x0,
0x0
};
#endif
#endif /* USBD_LPM_ENABLED */
/* USB Device Billboard BOS descriptor Template */
#if (USBD_CLASS_BOS_ENABLED == 1)
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* __ICCARM__ */
__ALIGN_BEGIN uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END =
{
0x05, /* bLength */
@@ -156,14 +155,16 @@ __ALIGN_BEGIN uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END =
0x34, /* bLength */
0x10, /* bDescriptorType: DEVICE CAPABILITY Type */
0x0D, /* bDevCapabilityType: BILLBOARD_CAPABILITY */
USBD_BB_URL_STRING_INDEX, /* iAddtionalInfoURL: Index of string descriptor providing a URL where the user can go to get more
detailed information about the product and the various Alternate Modes it supports */
USBD_BB_URL_STRING_INDEX, /* iAddtionalInfoURL: Index of string descriptor providing a URL where the user
can go to get more detailed information about the product and the various
Alternate Modes it supports */
0x02, /* bNumberOfAlternateModes: Number of Alternate modes supported. The
maximum value that this field can be set to is MAX_NUM_ALT_MODE. */
0x00, /* bPreferredAlternateMode: Index of the preferred Alternate Mode. System
software may use this information to provide the user with a better user experience. */
software may use this information to provide the user with a better
user experience. */
0x00, 0x00, /* VCONN Power needed by the adapter for full functionality 000b = 1W */
@@ -184,8 +185,8 @@ __ALIGN_BEGIN uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END =
0x00, /* bAlternateMode[0] Index of the Alternate Mode within the SVID as
returned in response to a Discover Modes command. Example:
0 <EFBFBD> first Mode entry
1 <EFBFBD> second mode entry */
0 first Mode entry
1 second mode entry */
USBD_BB_ALTMODE0_STRING_INDEX, /* iAlternateModeString[0]: Index of string descriptor describing protocol.
It is optional to support this string. */
@@ -195,8 +196,8 @@ __ALIGN_BEGIN uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END =
0x01, /* bAlternateMode[1] Index of the Alternate Mode within the SVID as
returned in response to a Discover Modes command. Example:
0 <EFBFBD> first Mode entry
1 <EFBFBD> second Mode entry */
0 first Mode entry
1 second Mode entry */
USBD_BB_ALTMODE1_STRING_INDEX, /* iAlternateModeString[1]: Index of string descriptor describing protocol.
It is optional to support this string. */
@@ -206,21 +207,23 @@ __ALIGN_BEGIN uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END =
0x10, /* bDescriptorType: Device Descriptor Type */
0x0F, /* bDevCapabilityType: BILLBOARD ALTERNATE MODE CAPABILITY */
0x00, /* bIndex: Index of Alternate Mode described in the Billboard Capability Desc */
0x10, 0x00, 0x00, 0x00, /* dwAlternateModeVdo: contents of the Mode VDO for the alternate mode identified by bIndex */
0x10, 0x00, 0x00, 0x00, /* dwAlternateModeVdo: contents of the Mode VDO for the alternate mode
identified by bIndex */
0x08, /* bLength */
0x10, /* bDescriptorType: Device Descriptor Type */
0x0F, /* bDevCapabilityType: BILLBOARD ALTERNATE MODE CAPABILITY */
0x01, /* bIndex: Index of Alternate Mode described in the Billboard Capability Desc */
0x20, 0x00, 0x00, 0x00, /* dwAlternateModeVdo: contents of the Mode VDO for the alternate mode identified by bIndex */
0x20, 0x00, 0x00, 0x00, /* dwAlternateModeVdo: contents of the Mode VDO for the alternate mode
identified by bIndex */
};
#endif
#endif /* USBD_CLASS_BOS_ENABLED */
/* USB Standard Device Descriptor */
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* __ICCARM__ */
__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END =
{
USB_LEN_LANGID_STR_DESC,
@@ -231,7 +234,7 @@ __ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END =
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* __ICCARM__ */
__ALIGN_BEGIN uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] =
{
USB_SIZ_STRING_SERIAL,
@@ -240,7 +243,7 @@ __ALIGN_BEGIN uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] =
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* __ICCARM__ */
__ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
/* Private functions ---------------------------------------------------------*/
@@ -371,7 +374,9 @@ uint8_t *USBD_Class_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *le
*/
static void Get_SerialNum(void)
{
uint32_t deviceserial0, deviceserial1, deviceserial2;
uint32_t deviceserial0;
uint32_t deviceserial1;
uint32_t deviceserial2;
deviceserial0 = *(uint32_t *)DEVICE_ID1;
deviceserial1 = *(uint32_t *)DEVICE_ID2;
@@ -400,7 +405,7 @@ uint8_t *USBD_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
*length = sizeof(USBD_BOSDesc);
return (uint8_t *)USBD_BOSDesc;
}
#endif
#endif /* (USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1) */
#if (USBD_CLASS_USER_STRING_DESC == 1)
@@ -417,7 +422,7 @@ uint8_t *USBD_Class_UserStrDescriptor(USBD_SpeedTypeDef speed, uint8_t idx, uint
return USBD_StrDesc;
}
#endif
#endif /* USBD_CLASS_USER_STRING_DESC */
/**
@@ -447,5 +452,3 @@ static void IntToUnicode(uint32_t value, uint8_t *pbuf, uint8_t len)
pbuf[2U * idx + 1] = 0U;
}
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -6,13 +6,12 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
@@ -95,7 +94,7 @@ USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev,
pdev->ep_in[0].rem_length = 0U;
#else
pdev->ep_in[0].rem_length = len;
#endif
#endif /* USBD_AVOID_PACKET_SPLIT_MPS */
/* Start the transfer */
(void)USBD_LL_Transmit(pdev, 0x00U, pbuf, len);
@@ -139,7 +138,7 @@ USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev,
pdev->ep_out[0].rem_length = 0U;
#else
pdev->ep_out[0].rem_length = len;
#endif
#endif /* USBD_AVOID_PACKET_SPLIT_MPS */
/* Start the transfer */
(void)USBD_LL_PrepareReceive(pdev, 0U, pbuf, len);
@@ -223,4 +222,3 @@ uint32_t USBD_GetRxCount(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

86
LICENSE.txt Normal file
View File

@@ -0,0 +1,86 @@
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 Rev5/February 2018
Software license agreement
ULTIMATE LIBERTY SOFTWARE LICENSE AGREEMENT
BY INSTALLING, COPYING, DOWNLOADING, ACCESSING OR OTHERWISE USING THIS SOFTWARE
OR ANY PART THEREOF (AND THE RELATED DOCUMENTATION) FROM STMICROELECTRONICS
INTERNATIONAL N.V, SWISS BRANCH AND/OR ITS AFFILIATED COMPANIES
(STMICROELECTRONICS), THE RECIPIENT, ON BEHALF OF HIMSELF OR HERSELF, OR ON
BEHALF OF ANY ENTITY BY WHICH SUCH RECIPIENT IS EMPLOYED AND/OR ENGAGED AGREES
TO BE BOUND BY THIS SOFTWARE LICENSE AGREEMENT.
Under STMicroelectronics intellectual property rights, the redistribution,
reproduction and use in source and binary forms of the software or any part
thereof, with or without modification, are permitted provided that the following
conditions are met:
1. Redistribution of source code (modified or not) must retain any copyright
notice, this list of conditions and the disclaimer set forth below as items 10
and 11.
2. Redistributions in binary form, except as embedded into microcontroller or
microprocessor device manufactured by or for STMicroelectronics or a software
update for such device, must reproduce any copyright notice provided with the
binary code, this list of conditions, and the disclaimer set forth below as
items 10 and 11, in documentation and/or other materials provided with the
distribution.
3. Neither the name of STMicroelectronics nor the names of other contributors to
this software may be used to endorse or promote products derived from this
software or part thereof without specific written permission.
4. This software or any part thereof, including modifications and/or derivative
works of this software, must be used and execute solely and exclusively on or in
combination with a microcontroller or microprocessor device manufactured by or
for STMicroelectronics.
5. No use, reproduction or redistribution of this software partially or totally
may be done in any manner that would subject this software to any Open Source
Terms. “Open Source Terms” shall mean any open source license which requires as
part of distribution of software that the source code of such software is
distributed therewith or otherwise made available, or open source license that
substantially complies with the Open Source definition specified at
www.opensource.org and any other comparable open source license such as for
example GNU General Public License (GPL), Eclipse Public License (EPL), Apache
Software License, BSD license or MIT license.
6. STMicroelectronics has no obligation to provide any maintenance, support or
updates for the software.
7. The software is and will remain the exclusive property of STMicroelectronics
and its licensors. The recipient will not take any action that jeopardizes
STMicroelectronics and its licensors' proprietary rights or acquire any rights
in the software, except the limited rights specified hereunder.
8. The recipient shall comply with all applicable laws and regulations affecting
the use of the software or any part thereof including any applicable export
control law or regulation.
9. Redistribution and use of this software or any part thereof other than as
permitted under this license is void and will automatically terminate your
rights under this license.
10. THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY RIGHTS, WHICH ARE
DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT SHALL
STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11. EXCEPT AS EXPRESSLY PERMITTED HEREUNDER, NO LICENSE OR OTHER RIGHTS, WHETHER
EXPRESS OR IMPLIED, ARE GRANTED UNDER ANY PATENT OR OTHER INTELLECTUAL PROPERTY
RIGHTS OF STMICROELECTRONICS OR ANY THIRD PARTY.

View File

@@ -1,3 +1,80 @@
# Copyright (c) 2015 STMicroelectronics.
SLA0044 Rev5/February 2018
This software component is licensed by ST under Ultimate Liberty license SLA0044, the "License". You may not use this file except in compliance with this license. You may obtain a copy of the license [here](https://www.st.com/SLA0044).
## Software license agreement
### __ULTIMATE LIBERTY SOFTWARE LICENSE AGREEMENT__
BY INSTALLING, COPYING, DOWNLOADING, ACCESSING OR OTHERWISE USING THIS SOFTWARE
OR ANY PART THEREOF (AND THE RELATED DOCUMENTATION) FROM STMICROELECTRONICS
INTERNATIONAL N.V, SWISS BRANCH AND/OR ITS AFFILIATED COMPANIES
(STMICROELECTRONICS), THE RECIPIENT, ON BEHALF OF HIMSELF OR HERSELF, OR ON
BEHALF OF ANY ENTITY BY WHICH SUCH RECIPIENT IS EMPLOYED AND/OR ENGAGED AGREES
TO BE BOUND BY THIS SOFTWARE LICENSE AGREEMENT.
Under STMicroelectronics intellectual property rights, the redistribution,
reproduction and use in source and binary forms of the software or any part
thereof, with or without modification, are permitted provided that the following
conditions are met:
1. Redistribution of source code (modified or not) must retain any copyright
notice, this list of conditions and the disclaimer set forth below as items 10
and 11.
2. Redistributions in binary form, except as embedded into microcontroller or
microprocessor device manufactured by or for STMicroelectronics or a software
update for such device, must reproduce any copyright notice provided with the
binary code, this list of conditions, and the disclaimer set forth below as
items 10 and 11, in documentation and/or other materials provided with the
distribution.
3. Neither the name of STMicroelectronics nor the names of other contributors to
this software may be used to endorse or promote products derived from this
software or part thereof without specific written permission.
4. This software or any part thereof, including modifications and/or derivative
works of this software, must be used and execute solely and exclusively on or in
combination with a microcontroller or microprocessor device manufactured by or
for STMicroelectronics.
5. No use, reproduction or redistribution of this software partially or totally
may be done in any manner that would subject this software to any Open Source
Terms. “Open Source Terms” shall mean any open source license which requires as
part of distribution of software that the source code of such software is
distributed therewith or otherwise made available, or open source license that
substantially complies with the Open Source definition specified at
www.opensource.org and any other comparable open source license such as for
example GNU General Public License (GPL), Eclipse Public License (EPL), Apache
Software License, BSD license or MIT license.
6. STMicroelectronics has no obligation to provide any maintenance, support or
updates for the software.
7. The software is and will remain the exclusive property of STMicroelectronics
and its licensors. The recipient will not take any action that jeopardizes
STMicroelectronics and its licensors' proprietary rights or acquire any rights
in the software, except the limited rights specified hereunder.
8. The recipient shall comply with all applicable laws and regulations affecting
the use of the software or any part thereof including any applicable export
control law or regulation.
9. Redistribution and use of this software or any part thereof other than as
permitted under this license is void and will automatically terminate your
rights under this license.
10. THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY RIGHTS, WHICH ARE
DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT SHALL
STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11. EXCEPT AS EXPRESSLY PERMITTED HEREUNDER, NO LICENSE OR OTHER RIGHTS, WHETHER
EXPRESS OR IMPLIED, ARE GRANTED UNDER ANY PATENT OR OTHER INTELLECTUAL PROPERTY
RIGHTS OF STMICROELECTRONICS OR ANY THIRD PARTY.

View File

@@ -1,29 +1,31 @@
# Middleware USB Device MCU Component
![latest tag](https://img.shields.io/github/v/tag/STMicroelectronics/stm32_mw_usb_device.svg?color=brightgreen)
## Overview
**STM32Cube** is an STMicroelectronics original initiative to ease the developers life by reducing efforts, time and cost.
**STM32Cube** is an STMicroelectronics original initiative to ease developers' life by reducing efforts, time and cost.
**STM32Cube** covers the overall STM32 products portfolio. It includes a comprehensive embedded software platform, delivered for each STM32 series.
**STM32Cube** covers the overall STM32 products portfolio. It includes a comprehensive embedded software platform delivered for each STM32 series.
* The CMSIS modules (core and device) corresponding to the ARM(tm) core implemented in this STM32 product.
* The STM32 HAL-LL drivers : an abstraction drivers layer, the API ensuring maximized portability across the STM32 portfolio.
* The BSP Drivers of each evaluation or demonstration board provided by this STM32 series.
* A consistent set of middlewares components such as RTOS, USB, FatFS, Graphics, STM32_TouchSensing_Library...
* A full set of software projects (basic examples, applications or demonstrations) for each board provided by this STM32 series.
* The STM32 HAL-LL drivers, an abstraction layer offering a set of APIs ensuring maximized portability across the STM32 portfolio.
* The BSP drivers of each evaluation, demonstration or nucleo board provided for this STM32 series.
* A consistent set of middleware libraries such as RTOS, USB, FatFS, graphics, touch sensing library...
* A full set of software projects (basic examples, applications, and demonstrations) for each board provided for this STM32 series.
Two models of publication are proposed for the STM32Cube embedded software:
* The monolithic **MCU Package** : all STM32Cube software modules of one STM32 series are present (Drivers, Middlewares, Projects, Utilities) in the repo (usual name **STM32Cubexx**, xx corresponding to the STM32 series).
* The **MCU component** : progressively from November 2019, each STM32Cube software module being part of the STM32Cube MCU Package, will be delivered as an individual repo, allowing the user to select and get only the required software functions.
* The monolithic **MCU Package**: all STM32Cube software modules of one STM32 series are present (Drivers, Middleware, Projects, Utilities) in the repository (usual name **STM32Cubexx**, xx corresponding to the STM32 series).
* The **MCU component**: each STM32Cube software module being part of the STM32Cube MCU Package, is delivered as an individual repository, allowing the user to select and get only the required software functions.
## Description
This **stm32_mw_usb_device** MCU component repository is one element **common to all** STM32Cube MCU embedded software packages, providing the **USB Device MCU Middleware** part.
## License
Copyright (c) 2015 STMicroelectronics.
This software component is licensed by ST under Ultimate Liberty license SLA0044, the "License". You may not use this file except in compliance with this license. You may obtain a copy of the license [here](https://www.st.com/SLA0044).
It represents ST offer to ensure the support of USB Devices on STM32 MCUs.
It includes two main modules:
* **Core** module for the USB device standard peripheral control APIs. It includes the files ensuring USB 2.0 standard code implementation for an USB device.
These files APIs will be called within every USB device application regardless of the desired functionality.
* **Class** module for the commonly supported classes APIs. it includes the files including different USB device classes. All STM32 USB classes are implemented according to the USB 2.0 and every classs specifications. These files APIs will be called within USB device applications according to the desired functionality.
## Release note
@@ -31,6 +33,4 @@ Details about the content of this release are available in the release note [her
## Troubleshooting
If you have any issue with the **software content** of this repository, you can file an issue [here](https://github.com/STMicroelectronics/stm32_mw_usb_device/issues/new/choose).
For any other question related to the product, the tools, the environment, you can submit a topic to the [ST Community](https://community.st.com/s/).
Please refer to the [CONTRIBUTING.md](CONTRIBUTING.md) guide.

File diff suppressed because it is too large Load Diff

520
Release_Notes.md Normal file
View File

@@ -0,0 +1,520 @@
---
pagetitle: Release Notes for STM32Cube USB Device Library
lang: en
header-includes: <link rel="icon" type="image/x-icon" href="_htmresc/favicon.png" />
---
::: {.row}
::: {.col-sm-12 .col-lg-4}
<center>
# Release Notes for <mark>STM32Cube USB Device Library</mark>
Copyright &copy; 2015 STMicroelectronics\
[![ST logo](_htmresc/st_logo_2020.png)](https://www.st.com){.logo}
</center>
# Purpose
The USB device library comes on top of the STM32Cube™ USB device HAL driver and
offers all the APIs required to develop an USB device application.
The main USB device library features are:
- Support of multi packet transfer features allowing sending big amount of data without
splitting it into max packet size transfers.
- Support of most common USB Class drivers (HID, MSC, DFU, CDC-ACM, CDC-ECM, RNDIS, MTP, AUDIO1.0, Printer, Video, Composite)
- Configuration files to interface with Cube HAL and change the library configuration without changing
the library code (Read Only).
- 32-bits aligned data structures to handle DMA based transfer in High speed modes.
Here is the list of references to user documents:
- [UM1734](https://www.st.com/resource/en/user_manual/DM00108129.pdf) : STM32Cube USB device library User Manual
- [Wiki Page](https://wiki.st.com/stm32mcu/wiki/USB_overview) : STM32Cube USB Wiki Page
:::
::: {.col-sm-12 .col-lg-8}
# Update History
::: {.collapse}
<input type="checkbox" id="collapse-section23" checked aria-hidden="true">
<label for="collapse-section23" aria-hidden="true">V2.11.1 / 27-September-2022</label>
<div>
## Main Changes
Headline
---------
Improvement of the memory management
**USB Core:**
Fix some compilation warnings related to unused parameters
Improve some code parts style
Add check on the USB Device status in USBD_LL_Suspend before suspending it
**USB CDC-ACM Class:**
Remove redundant prototype declaration of USBD_CDC_GetOtherSpeedCfgDesc()
**USB CompositeBuilder, CCID, CDC_ECM, CDC_RNDIS, CustomHID, MSC & Video Classes:**
Improve some code parts style
</div>
:::
::: {.col-sm-12 .col-lg-8}
# Update History
::: {.collapse}
<input type="checkbox" id="collapse-section22" checked aria-hidden="true">
<label for="collapse-section22" aria-hidden="true">V2.11.0 / 25-March-2022</label>
<div>
## Main Changes
Headline
---------
**USB VIDEO Class:**
Correction of the support of VS_PROBE_CONTROL & VS_COMMIT_CONTROL requets
**USB AUDIO Class:**
Correction of the check on AUDIO_TOTAL_BUF_SIZE to avoid vulnerabilities
**USB HID Class:**
Modification of some constants names to avoid duplication versus USB host library
**USB CustomHID Class:**
Add support of Get Report control request
Allow disabling EP OUT prepare receive using a dedicated macros that can be defined in usbd_conf.h application file
Add support of Report Descriptor with length greater than 255 bytes
**USB CCID Class:**
Fix minor Code Spelling warning
**USB All Classes:**
Update all classes to support composite multi-instance using the class id parameter
Fix code spelling and improve code style
fix misraC 2012 rule 10.3
</div>
:::
::: {.collapse}
<input type="checkbox" id="collapse-section21" checked aria-hidden="true">
<label for="collapse-section21" aria-hidden="true">V2.10.0 / 03-Sept-2021</label>
<div>
## Main Changes
Headline
---------
**Integration of new USB device Class driver:**
Adding support of Composite devices with an auto generation of composite device configuration descriptors
**USB All Classes:**
Fix Code Spelling and improve Code Style
Update device class drivers to support Composite devices
Improve declaration of USB configuration descriptor table which is allocated if the composite builder is not selected
</div>
:::
::: {.collapse}
<input type="checkbox" id="collapse-section20" checked aria-hidden="true">
<label for="collapse-section20" aria-hidden="true">V2.9.0 / 06-July-2021</label>
<div>
## Main Changes
Headline
---------
**Integration of new USB device Class driver:**
USB CCID Class driver based on Universal Serial Bus Device Class Definition for Integrated Circuit(s) Cards Interface Devices Revision 1.1
USB MTP Class driver based on Universal Serial Bus Device Class Media Transfer Protocol Revision 1.1
**USB All Classes:**
Fix Code Spelling and improve Code Style
Update the way to declare licenses
**USB CDC/RNDIS/ECM Classes:**
Fix compilation warning with C++ due to missing casting during class handler allocation
</div>
:::
::: {.collapse}
<input type="checkbox" id="collapse-section19" checked aria-hidden="true">
<label for="collapse-section19" aria-hidden="true">V2.8.0 / 10-Mars-2021</label>
<div>
## Main Changes
Headline
---------
**Integration of new USB device Class driver:**
USB Printer Class driver based on Universal Serial Bus Device Class Definition for Printing Devices Version 1.1
**USB All Classes:**
Fix USB buffer overflow vulnerability for CDC, CDC-ECM, CDC-RNDIS, DFU, AUDIO, CustomHID, and Video Classes
Fix compilation warning with C++ due to missing casting during class handler allocation
Enhance comments of USB configuration descriptors fields
**USB Video Class:**
Fix missing closing bracket for extern "C" in usbd_video.h
Fix USBCV test with Uncompressed video format support
</div>
:::
::: {.collapse}
<input type="checkbox" id="collapse-section17" checked aria-hidden="true">
<label for="collapse-section17" aria-hidden="true">V2.7.1 / 18-August-2020</label>
<div>
## Main Changes
Headline
---------
USB All Class: Add NULL pointer access check to Class handler
</div>
:::
::: {.collapse}
<input type="checkbox" id="collapse-section16" checked aria-hidden="true">
<label for="collapse-section16" aria-hidden="true">V2.7.0 / 12-August-2020</label>
<div>
## Main Changes
Headline
---------
**Integration of new USB device Class driver:**
USB video Class driver based on USB-IF video class definition version 1.1
**USB Core:**
Enhance NULL pointer check in Core APIs
Allow supporting both USER and USER Class string desc
Add support of USB controller which handles packet-size splitting by hardware
Avoid compilation warning due macro redefinition
change added to USBD_HandleTypeDef structure: dev_state, old_dev_state and ep0_state declaration become volatile to disable compiler optimization
Word spelling correction and file indentation improved
usbd_conf.h/c Template file updated to suggest using by default a static memory allocation for Class handler
**USB All Classes:**
Word spelling correction and file indentation improved
Allow updating device config descriptor Max power from user code usbd_conf.h using USBD_MAX_POWER define
Fix device config descriptor bmAttributes value which depends on user code define USBD_SELF_POWERED
**USB CDC Class:**
Class specific request, add protection to limit the maximum data length to be sent by the CDC device
**USB CustomHID Class:**
Allow changing CustomHID data EP size from user code
</div>
:::
::: {.collapse}
<input type="checkbox" id="collapse-section15" checked aria-hidden="true">
<label for="collapse-section15" aria-hidden="true">V2.6.1 / 05-June-2020</label>
<div>
## Main Changes
Headline
---------
Fix minor misra-c 2012 violations
**USB Core:**
minor rework on USBD_Init() USBD_DeInit()
Fix warning issue with Keil due to missing return value of setup API
**USB CDC Class:**
Fix file indentation
Avoid accessing to NULL pointer in case TransmitCplt() user fops is not defined to allow application compatibility with device library version below v2.6.0
</div>
:::
::: {.collapse}
<input type="checkbox" id="collapse-section14" checked aria-hidden="true">
<label for="collapse-section14" aria-hidden="true">V2.6.0 / 27-December-2019</label>
<div>
## Main Changes
Headline
---------
Integration of three new USB device Class drivers:CDC ECM , CDC RNDIS Microsoft, USB Billboard
Fix mandatory misra-c 2012 violations
update user core and class template files
**USB Core:**
Fix unexpected EP0 stall during enumeration phase
Improve APIs error management and prevent accessing NULL pointers
**USB MSC Class:**
Fix USBCV specific class tests
Fix multiple error with SCSI commands handling
Protect medium access when host ask for medium ejection
**USB CDC Class:**
Add new function to inform user that current IN transfer is completed
update transmit and receive APIs to transfer up to 64KB
**USB AUDIO Class:**
Fix audio sync start buffer size
update user callback periodicTC args by adding pointer to user buffer and size
**USB CustomHID Class:**
Rework the OUT transfer complete and prevent automatically re-enabling the OUT EP
Add new user API to restart the OUT transfer: USBD_CUSTOM_HID_ReceivePacket()
</div>
:::
::: {.collapse}
<input type="checkbox" id="collapse-section13" checked aria-hidden="true">
<label for="collapse-section13" aria-hidden="true">V2.5.3 / 30-April-2019</label>
<div>
## Main Changes
Headline
---------
Fix misra-c 2012 high severity violations
**Core driver:**
protect shared macros __ALIGN_BEGIN, __ALIGN_END with C directive #ifndef
update Core driver and DFU Class driver to use USBD_SUPPORT_USER_STRING_DESC instead of USBD_SUPPORT_USER_STRING
prevent accessing to NULL pointer if the get descriptor functions are not defined
Update on USBD_LL_Resume(), restore the device state only if the current state is USBD_STATE_SUSPENDED
</div>
:::
::: {.collapse}
<input type="checkbox" id="collapse-section12" checked aria-hidden="true">
<label for="collapse-section12" aria-hidden="true">V2.5.2 / 27-Mars-2019</label>
<div>
## Main Changes
Headline
---------
DFU Class: fix compilation warning due to unreachable instruction code introduced with CMSIS V5.4.0 NVIC_SystemReset() prototype change
</div>
:::
::: {.collapse}
<input type="checkbox" id="collapse-section11" checked aria-hidden="true">
<label for="collapse-section11" aria-hidden="true">V2.5.1 / 03-August-2018</label>
<div>
## Main Changes
Headline
---------
Update license section by adding path to get copy of ST Ultimate Liberty license
Core: Fix unexpected stall during status OUT phase
DFU Class: rework hdfu struct to prevent unaligned addresses
MSC Class: fix lba address overflow during large file transfers greater than 4Go
Template Class: add missing Switch case Break on USBD_Template_Setup API
</div>
:::
::: {.collapse}
<input type="checkbox" id="collapse-section10" checked aria-hidden="true">
<label for="collapse-section10" aria-hidden="true">V2.5.0 / 15-December-2017</label>
<div>
## Main Changes
Headline
---------
Update license section
Update some functions to be MISRAC 2004 compliant
Add HS and OtherSpeed configuration descriptor for HID and CustomHID classes
Correct error handling in all class setup function
Add usbd_desc_template.c/ usbd_desc_template.h templates files
Add support of class and vendor request
CDC Class: fix zero-length packet issue in bulk IN transfer
Fix compilation warning with unused arguments for some functions
Improve USB Core enumeration state machine
</div>
:::
::: {.collapse}
<input type="checkbox" id="collapse-section9" checked aria-hidden="true">
<label for="collapse-section9" aria-hidden="true">V2.4.2 / 11-December-2015</label>
<div>
## Main Changes
Headline
---------
**CDC Class**
usbd_cdc.c: change #include "USBD_CDC.h" by #include "usbd_cdc.h"
</div>
:::
::: {.collapse}
<input type="checkbox" id="collapse-section8" checked aria-hidden="true">
<label for="collapse-section8" aria-hidden="true">V2.4.1 / 19-June-2015</label>
<div>
## Main Changes
Headline
---------
**CDC Class**
usbd_cdc.c: comments update
**MSC Class**
usbd_msc_bot.h: update to be C++ compliant
**AUDIO Class**
usbd_audio.c: fix issue when Host sends GetInterface command it gets a wrong value
usbd_audio.c: remove useless management of DMA half transfer
</div>
:::
::: {.collapse}
<input type="checkbox" id="collapse-section7" checked aria-hidden="true">
<label for="collapse-section7" aria-hidden="true">V2.4.0 / 28-February-2015</label>
<div>
## Main Changes
Headline
---------
**Core Driver**
Add support of Link Power Management (LPM): add new API GetBOSDescriptor(), that is used only if USBD_LPM_ENABLED switch is enabled in usbd_conf.h file
usbd_core.c: Fix bug of unsupported premature Host Out stage during data In stage (ie. when endpoint 0 maximum data size is 8 and Host requests GetDeviceDescriptor for the first time)
usbd_ctlreq.c: Fix bug of unsupported Endpoint Class requests (ie. Audio SetCurrent request for endpoint sampling rate setting)
**HID Class**
Updating Polling time API USBD_HID_GetPollingInterval() to query this period for HS and FS
usbd_hid.c: Fix USBD_LL_CloseEP() function call in USBD_HID_DeInit() replacing endpoint size by endpoint address.
**CDC Class**
usbd_cdc.c: Add missing GetInterface request management in USBD_CDC_Setup() function
usbd_cdc.c: Update USBD_CDC_Setup() function to allow correct user implementation of CDC_SET_CONTROL_LINE_STATE and similar no-data setup requests.
</div>
:::
::: {.collapse}
<input type="checkbox" id="collapse-section6" checked aria-hidden="true">
<label for="collapse-section6" aria-hidden="true">V2.3.0 / 04-November-2014</label>
<div>
## Main Changes
Headline
---------
Update all drivers to be C++ compliant
**CDC Class**
usbd_cdc.c: fix clear flag issue in USBD_CDC_TransmitPacket() function
usbd_cdc_if_template.c: update TEMPLATE_Receive() function header comment
Miscellaneous source code comments update
</div>
:::
::: {.collapse}
<input type="checkbox" id="collapse-section5" checked aria-hidden="true">
<label for="collapse-section5" aria-hidden="true">V2.2.0 / 13-June-2014</label>
<div>
## Main Changes
Headline
---------
Source code comments review and update
**HID class**
Remove unused API USBD_HID_DeviceQualifierDescriptor()
Add a new API in the HID class to query the poll time USBD_HID_GetPollingInterval()
**CDC class**
Bug fix: missing handling ZeroLength Setup request
**All classes**
Add alias for the class definition, it's defined as macro with capital letter
ex. for the HID, the USBD_HID_CLASS macro is defined this way #define USBD_HID_CLASS &USBD_HID
and the application code can use the previous definition: &USBD_HID ex. USBD_RegisterClass(&USBD_Device, &USBD_HID) or the new USBD_HID_CLASS ex. USBD_RegisterClass(&USBD_Device, USBD_HID_CLASS)
</div>
:::
::: {.collapse}
<input type="checkbox" id="collapse-section4" checked aria-hidden="true">
<label for="collapse-section4" aria-hidden="true">V2.1.0 / 22-April-2014</label>
<div>
## Main Changes
Headline
---------
usbd_conf_template.c: update file with the right content (it was using MSC memory management layer)
usbd_conf_template.h: change include of stm32f4xx.h by stm32xxx.h and add comment to inform user to adapt it to the device used
Several enhancements in CustomHID class
Update the Custom HID class driver to simplify the link with user processes
Optimize the Custom HID class driver and reduce footprint
Add USBD_CUSTOM_HID_RegisterInterface() API to link user process to custom HID class
Add Custom HID interface template file usbd_customhid_if_template.c/h
Miscellaneous comments update
</div>
:::
::: {.collapse}
<input type="checkbox" id="collapse-section3" checked aria-hidden="true">
<label for="collapse-section3" aria-hidden="true">V2.0.0 / 18-February-2014</label>
<div>
## Main Changes
Major update based on STM32Cube specification.
Headline
---------
Library Core, Classes architecture and APIs modified vs. V1.1.0, and thus the 2 versions are not compatible.
**This version has to be used only with STM32Cube based development**
</div>
:::
::: {.collapse}
<input type="checkbox" id="collapse-section2" checked aria-hidden="true">
<label for="collapse-section2" aria-hidden="true">V1.1.0 / 19-March-2012</label>
<div>
## Main Changes
Headline
---------
Official support of STM32F4xx devices
All source files: license disclaimer text update and add link to the License file on ST Internet.
Handle test mode in the set feature request
Handle dynamically the USB SELF POWERED feature
Handle correctly the USBD_CtlError process to take into account error during Control OUT stage
Miscellaneous bug fix
</div>
:::
::: {.collapse}
<input type="checkbox" id="collapse-section1" checked aria-hidden="true">
<label for="collapse-section1" aria-hidden="true">V1.0.0 / 22-July-2011</label>
<div>
## Main Changes
First official version for STM32F105/7xx and STM32F2xx devices
</div>
:::
:::
:::
<footer class="sticky">
::: {.columns}
::: {.column width="95%"}
:::
::: {.column width="5%"}
<abbr title="Based on template cx566953 version 2.1">Info</abbr>
:::
:::
</footer>

BIN
_htmresc/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

1711
_htmresc/mini-st.css Normal file

File diff suppressed because it is too large Load Diff

BIN
_htmresc/st_logo_2020.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB