mirror of
https://github.com/STMicroelectronics/stm32-mw-usb-device.git
synced 2026-02-08 12:08:06 -05:00
Release v2.10.0
This commit is contained in:
@@ -46,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
|
||||
@@ -110,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
|
||||
@@ -130,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
|
||||
|
||||
@@ -147,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
|
||||
@@ -182,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
|
||||
@@ -363,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;
|
||||
@@ -435,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
|
||||
/**
|
||||
|
||||
@@ -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 =
|
||||
@@ -377,7 +395,7 @@ static USBD_VideoControlTypeDef video_Probe_Control =
|
||||
* @param cfgidx: Configuration index
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_VIDEO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||
static uint8_t USBD_VIDEO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||
{
|
||||
USBD_VIDEO_HandleTypeDef *hVIDEO;
|
||||
|
||||
@@ -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);
|
||||
#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;
|
||||
@@ -430,23 +454,29 @@ static uint8_t USBD_VIDEO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||
* @param cfgidx: Configuration index
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_VIDEO_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||
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);
|
||||
#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 */
|
||||
@@ -460,13 +490,13 @@ static uint8_t USBD_VIDEO_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||
* @param req: usb requests
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_VIDEO_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
|
||||
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;
|
||||
len = MIN((uint16_t)USB_CONF_DESC_SIZE, (uint16_t)req->wLength);
|
||||
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;
|
||||
}
|
||||
}
|
||||
(void)USBD_CtlSendData(pdev, pbuf, len);
|
||||
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,7 +633,7 @@ 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;
|
||||
@@ -605,7 +646,7 @@ static uint8_t USBD_VIDEO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||
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 +665,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 +708,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 +750,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,7 +836,7 @@ 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);
|
||||
USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *)(pdev->pClassDataCmsit[pdev->classId]);
|
||||
|
||||
/* Check that the request has control data */
|
||||
if (req->wLength > 0U)
|
||||
@@ -821,6 +863,7 @@ static void VIDEO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef USE_USBD_COMPOSITE
|
||||
/**
|
||||
* @brief USBD_VIDEO_GetFSCfgDesc
|
||||
* return configuration descriptor
|
||||
@@ -829,7 +872,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 +900,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 +928,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 +960,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 +969,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 +980,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 +994,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 +1016,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)
|
||||
pdesc = USBD_GetNextDesc((uint8_t *)pdesc, &ptr);
|
||||
if ((pdesc->bDescriptorType == CS_INTERFACE) &&
|
||||
(pdesc->bDescriptorSubType == VC_HEADER))
|
||||
{
|
||||
pEpDesc = (USBD_EpDescTypedef *)(void *)pdesc;
|
||||
|
||||
if (pEpDesc->bEndpointAddress == EpAddr)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
pEpDesc = NULL;
|
||||
}
|
||||
pVideoDesc = (uint8_t *)pdesc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (void *)pEpDesc;
|
||||
return pVideoDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1026,7 +1043,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;
|
||||
|
||||
Reference in New Issue
Block a user