Skip navigation
Home > All Places > USB > USB Superspeed Peripherals > Blog > 2019 > August > 02

     在本篇 blog 中,我们学习如何在固件中已有的分辨率基础上,添加新的分辨率。本篇 blog ,我们在上一篇 blog 的固件的基础上进行修改,所以用的硬件还是CX3      Denebola RDK。原固件中只定义了 1080P@30fps,此处我们增加 720P@60fps。

 

  1. 首先我们需要在描述符文件中添加相应的 frame descriptor。
    /* Class specific Uncompressed VS frame descriptor 2 - 720p@ 60fps*/
    0x1E,                               /* Descriptor size */
    CX3_CS_INTRFC_DESCR,                /* Descriptor type*/
    0x05,                               /* Subtype: Uncompressed frame interface*/
    0x02,                               /* Frame Descriptor Index: 2 */
    0x00,                               /* No Still image capture supported */
    0x00, 0x05,                         /* Width in pixel: 1280 */
    0xD0, 0x02,                         /* Height in pixel: 720 */
    0x00, 0x00, 0x57, 0x30,             /* Min bit rate @55fps (bits/s): 720 x 1280 x 2 x 55 x 8 = 811008000 */
    0x00, 0x00, 0xBC, 0x34,             /* Max bit rate @60fps (bits/s). 720 x 1280 x 2 x 60 x 8 = 884736000 */
    0x00, 0x20, 0x1C, 0x00,             /* Maximum video frame size in bytes(Deprecated): 1280 x 720 x 2   */
    0x0A, 0x8B, 0x02, 0x00,             /* Default frame interval (in 100ns units): (1/60)x10^7 */
    0x01,                               /* Frame interval type : No of discrete intervals */
    0x0A, 0x8B, 0x02, 0x00,             /* Frame interval 3: Same as Default frame interval */

  

可以看到,此处定义720P@60fps 的frame index 为2.

 

2. 修改 VS format descriptor  中的 frame descriptor 的个数。

    0x02,                               /* Number of Frame Descriptors that follow this descriptor: 2 */

 

3. 修改 Class-specific Video Streaming Input Header Descriptor  中的 Total size of Class specific VS descr.

    /* Class-specific Video Streaming Input Header Descriptor */
    0x0E,                               /* Descriptor size */
    CX3_CS_INTRFC_DESCR,                /* Class-specific VS I/f Type */
    0x01,                               /* Descriptor Subtype: Input Header */
    0x01,                               /* 1 format desciptor follows */
#ifdef Two_frame_rate
//    0x56,0x00,                          /* Total size of Class specific VS descr */
    0x74,0x00, /* Total size of Class specific VS descr */
#else
    0x52,0x00,                          /* Total size of Class specific VS descr */
#endif
    CX3_EP_BULK_VIDEO,                  /* EP address for BULK video data: EP 3 IN */
    0x00,                               /* No dynamic format change supported */
    0x04,                               /* Output terminal ID : 4 */
    0x02,                               /* > Still image capture method supported */
    0x00,                               /* Hardware trigger NOT supported */
    0x00,                               /* Hardware to initiate still image capture not supported */
    0x01,                               /* Size of controls field : 1 byte */
    0x00,                               /* D2 : Compression quality supported - No compression*/

 

4. 修改 configuration descriptor 的总长度

   /* Configuration Descriptor*/
    0x09,                               /* Descriptor Size */
    CY_U3P_USB_CONFIG_DESCR,            /* Configuration Descriptor Type */
#ifdef Two_frame_rate
//    0xe9,0x00,                         /* Length of this descriptor and all sub descriptors */
    0x07,0x01, /* Length of this descriptor and all sub descriptors */
#else
    0xe5,0x00,                         /* Length of this descriptor and all sub descriptors */
#endif
    0x02,                               /* Number of interfaces */
    0x01,                               /* Configuration number */
    0x03,                               /* Configuration string index */
    0xC0,                               /* Config characteristics - Self Powered */
    0x0C,                               /* Max power consumption of device (in 8mA unit) : 96mA */

 

5. 添加 Probe structure

/* UVC Probe Control Setting - 720p@60fps*/
uint8_t const gl720pProbeCtrl[CX3_APP_MAX_PROBE_SETTING] = {
    0x00, 0x00,                         /* bmHint : No fixed parameters */
    0x01,                               /* Use 1st Video format index */
    0x02,                               /* Use 2nd Video frame index */
    0x0A, 0x8B, 0x02, 0x00,             /* Desired frame interval in 100ns = (1/60)x10^7*/
    0x00, 0x00,                         /* Key frame rate in key frame/video frame units */
    0x00, 0x00,                         /* PFrame rate in PFrame / key frame units */
    0x00, 0x00,                         /* Compression quality control */
    0x00, 0x00,                         /* Window size for average bit rate */
    0x00, 0x00,                         /* Internal video streaming i/f latency in ms */
    0x00, 0x20, 0x1C, 0x00,             /* Max video frame size in bytes: 720 x 1280 x 2*/
#ifdef CX3_UVC_1_0_SUPPORT
    0x00, 0x90, 0x00, 0x00              /* No. of bytes device can rx in single payload: 36KB */
#else
    /* UVC 1.1 Probe Control has additional fields from UVC 1.0 */
    0x00, 0x90, 0x00, 0x00,             /* No. of bytes device can rx in single payload: 36KB */
    0x00, 0x60, 0xE3, 0x16,             /* Device Clock */
    0x00,                               /* Framing Information - Ignored for uncompressed format*/
    0x00,                               /* Preferred payload format version */
    0x00,                               /* Minimum payload format version */
    0x00                                /* Maximum payload format version */
#endif
};

 

6. 在添加 if 分支 以向主机返回相应的 Probe structure

/*Returns the pointer to the Probe Control structure for the corresponding frame index.*/
uint8_t *
CyCx3UvcAppGetProbeControlData (
        CyU3PUSBSpeed_t usbConType,
        uint8_t         frameIndex,
        uint32_t glCurrentFrameInterval
        )
{
uint32_t frame_fps = 10000000 / glCurrentFrameInterval;
    if (usbConType == CY_U3P_SUPER_SPEED)
    {
       if (frameIndex == 1)
        {
       if(frame_fps == 30)
       {
            /* 1920 x 1080 @30.0 fps */
       CyU3PDebugPrint(4,"\n Line:%d: Return 30 fps structure",__LINE__);
               return ((uint8_t *) gl1080pProbeCtrl_30fps);
       }
       else if(frame_fps == 60)
       {              /* 1920 x 1080 @60.0 fps */
       CyU3PDebugPrint(4,"\n Line:%d Return 60 fps structure",__LINE__);
                  return ((uint8_t *) gl1080pProbeCtrl_60fps);
       }


        }
       else if (frameIndex == 2)
       {
           return ((uint8_t *) gl720pProbeCtrl);


       }
    }
    else if (usbConType == CY_U3P_HIGH_SPEED)
    {
    }
    else
    {


    }
    return NULL;
}







 

7. 添加 720P 对应的 MIPI CSI 初始化参数 结构体,此处我们直接添加 SDK 目录下的 Cx3UVCOV5640 例子中的参数。用户在使用其他sensor以及添加其他分辨率的支持时,需要首先确认 sensor 的配置参数,将参数输入到 MIPI configuration tool 里面进行计算,从而找到一组合适 的 MIPI CSI的初始化参数。需要注意的是,同样一组sensor 的 配置参数,与之对应的MIPI CSI 初始化参数不止一组,找到一组可用值即可。用户在MIPI configuration tool里面也可以看到, 很多参数都是有一个允许的取值范围,而不是唯一值。

/* Configuration parameters for 720p @60FPS for the OV5640 sensor */
CyU3PMipicsiCfg_t cfgUvc720p60NoMclk =  { 
    CY_U3P_CSI_DF_YUV422_8_2,     /* dataFormat   */
    2,                          /* numDataLanes */
    1,                        /* pllPrd       */
    62,                         /* pllFbd       */
    CY_U3P_CSI_PLL_FRS_250_500M, /* pllFrs      */
    CY_U3P_CSI_PLL_CLK_DIV_4,   /* csiRxClkDiv  */
    CY_U3P_CSI_PLL_CLK_DIV_4,   /* parClkDiv    */
    0x00,                       /* mclkCtl      */
    CY_U3P_CSI_PLL_CLK_DIV_8,   /* mClkRefDiv   */
    1280,                       /* hResolution  */
    0x01                       /* fifoDelay    */
};

 

8. 在 SetVideoResolution 中添加720P对应分支。

static void
CyCx3UvcAppImageSensorSetVideoResolution(
        uint8_t resolution_index,
        uint32_t frame_Interval
        )
{
CyU3PReturnStatus_t status = CY_U3P_SUCCESS;
uint32_t frameRate= 10000000/frame_Interval;
switch (CyU3PUsbGetSpeed ())
{
case CY_U3P_SUPER_SPEED:
switch (resolution_index)
{
case 0x01:
{
if(frameRate == 30)
{
CyU3PDebugPrint(4,"\r\n Line:%d: Set 30 fps",__LINE__);
/* Write 1080pSettings */
#ifndef FX3_STREAMING
status = CyU3PMipicsiSetIntfParams (&OV5640_YUY2_1080p, CyFalse);
if (status != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "\n\rUSBStpCB:SetIntfParams SS1 Err = 0x%x", status);
}
#endif
CyCx3_ImageSensor_Set_1080p ();


}
else if (frameRate == 60)
{
CyU3PDebugPrint(4,"\r\n Line:%d: Set 60 fps",__LINE__);
/* Write 1080pSettings */
#ifndef FX3_STREAMING
status = CyU3PMipicsiSetIntfParams (&OV5640_YUY2_1080p, CyFalse);
if (status != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "\n\rUSBStpCB:SetIntfParams SS1 Err = 0x%x", status);
}
#endif
CyCx3_ImageSensor_Set_1080p ();


}


}
break;


case 0x02:
{
CyU3PDebugPrint(4,"\r\n Line:%d: Set 720P@60fps",__LINE__);
/* Write 720pSettings */
#ifndef FX3_STREAMING
status = CyU3PMipicsiSetIntfParams (&cfgUvc720p60NoMclk, CyFalse);
if (status != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "\n\rUSBStpCB:SetIntfParams SS1 Err = 0x%x", status);
}
#endif
CyCx3_ImageSensor_Set_720p ();


}
break;


}
break;


case CY_U3P_HIGH_SPEED:
switch (resolution_index)
{




}
break;
}
}













 

至此,固件修改完成。编译并下载到Demo 板中测试。可以看到,现在固件可以支持 720P@60fps 的视频传输。

Snipaste_2019-08-03_12-05-18.png

Snipaste_2019-08-03_12-05-02.png

 

同样,附件提供修改后的固件,供用户参考。

在本篇 blog 中,我们学习如何在同一个分辨率下支持多个帧率的视频传输。

 

  1. 首先,我们需要对 frame descriptor 进行修改。此处,我们配置分辨率为 1920 x 1080,帧率分别为 30 fps 和 60 fps。
    0x22,                               /* Descriptor size */
    CX3_CS_INTRFC_DESCR,                /* Descriptor type*/
    0x05,                               /* Subtype:  frame interface*/
    0x01,                               /* Frame Descriptor Index: 1 */
    0x00,                               /* No Still image capture method supported */
    0x80,0x07,                         /* Width in pixel:  1920 */
    0x38,0x04,                         /* Height in pixel: 1080 */
    0x00,0x00,0xa7,0x76,             /* Max bit rate (bits/s): 1920 x 1080 x 16 x 60 = 0x76a70000 */
    0x00,0x80,0x53,0x3b,             /* Min bit rate (bits/s): 1920 x 1080 x 16 x 30 = 995328000 */
    0x00,0x48,0x3f,0x00,             /* Maximum video or still frame size in bytes(Deprecated): 1920 x 1080 x 2 */
    0x15,0x16,0x05,0x00,             /* Default frame interval (in 100ns units): (1/30)x10^7 */
    0x02,                               /* Frame interval type : No of discrete intervals */
    0x0a,0x8b,0x02,0x00, /* 60 fps */
    0x15,0x16,0x05,0x00,             /* 30 fps */

 

2.随后修改 Class-specific Video Streaming Input Header Descriptor  中的长度值。

 

    0x56,0x00,                          /* Total size of Class specific VS descr */

 

和 CyCx3USBSSConfigDscr 中的总长度值。

 

    0xe9,0x00,                         /* Length of this descriptor and all sub descriptors */

 

 

3. 分别配置 30fps 和 60fps 对应的 probe 结构体

/* UVC Probe Control Setting - 1080p_60fps*/
uint8_t const gl1080pProbeCtrl_60fps[CX3_UVC_MAX_PROBE_SETTING] = {
    0x00, 0x00,                         /* bmHint : No fixed parameters */
    0x01,                               /* Use 1st Video format index */
    0x01,                               /* Use 1st Video frame index */
    0x0a,0x8b,0x02,0x00,             /* Desired frame interval in 100ns = (1/30)x10^7 */
    0x00, 0x00,                         /* Key frame rate in key frame/video frame units */
    0x00, 0x00,                         /* PFrame rate in PFrame / key frame units */
    0x00, 0x00,                         /* Compression quality control */
    0x00, 0x00,                         /* Window size for average bit rate */
    0x00, 0x00,                         /* Internal video streaming i/f latency in ms */
    0x00,0x48,0x3f,0x00,             /* Max video frame size in bytes = 1920 x 1080 x 2 */
#ifdef CX3_UVC_1_0_SUPPORT
    0x00, 0x90, 0x00, 0x00              /* No. of bytes device can rx in single payload: 36KB */
#else
    /* UVC 1.1 Probe Control has additional fields from UVC 1.0 */
    0x00, 0x90, 0x00, 0x00,             /* No. of bytes device can rx in single payload: 36KB */
    0x00, 0x60, 0xE3, 0x16,             /* Device Clock */
    0x00,                               /* Framing Information - Ignored for uncompressed format*/
    0x00,                               /* Preferred payload format version */
    0x00,                               /* Minimum payload format version */
    0x00                                /* Maximum payload format version */
#endif
};


 

/* UVC Probe Control Setting - 1080p_30fps*/
uint8_t const gl1080pProbeCtrl_30fps[CX3_UVC_MAX_PROBE_SETTING] = {
    0x00, 0x00,                         /* bmHint : No fixed parameters */
    0x01,                               /* Use 1st Video format index */
    0x01,                               /* Use 1st Video frame index */
    0x15,0x16,0x05,0x00,             /* Desired frame interval in 100ns = (1/30)x10^7 */
    0x00, 0x00,                         /* Key frame rate in key frame/video frame units */
    0x00, 0x00,                         /* PFrame rate in PFrame / key frame units */
    0x00, 0x00,                         /* Compression quality control */
    0x00, 0x00,                         /* Window size for average bit rate */
    0x00, 0x00,                         /* Internal video streaming i/f latency in ms */
    0x00,0x48,0x3f,0x00,             /* Max video frame size in bytes = 1920 x 1080 x 2 */ 
#ifdef CX3_UVC_1_0_SUPPORT 
    0x00, 0x90, 0x00, 0x00              /* No. of bytes device can rx in single payload: 36KB */
#else
    /* UVC 1.1 Probe Control has additional fields from UVC 1.0 */
    0x00, 0x90, 0x00, 0x00,             /* No. of bytes device can rx in single payload: 36KB */
    0x00, 0x60, 0xE3, 0x16,             /* Device Clock */
    0x00,                               /* Framing Information - Ignored for uncompressed format*/
    0x00,                               /* Preferred payload format version */
    0x00,                               /* Minimum payload format version */
    0x00                                /* Maximum payload format version */
#endif
};


 

 

4.修改 CyCx3UvcAppGetProbeControlData 以返回相应的 probe 结构体

/*Returns the pointer to the Probe Control structure for the corresponding frame index.*/
uint8_t *
CyCx3UvcAppGetProbeControlData (
        CyU3PUSBSpeed_t usbConType,
        uint8_t         frameIndex,
        uint32_t glCurrentFrameInterval
        )
{
uint32_t frame_fps = 10000000 / glCurrentFrameInterval;
    if (usbConType == CY_U3P_SUPER_SPEED)
    {
       if (frameIndex == 1)
        {
       if(frame_fps == 30)
       {
            /* 1920 x 1080 @30.0 fps */
       CyU3PDebugPrint(4,"\n Line:%d: Return 30 fps structure",__LINE__);
               return ((uint8_t *) gl1080pProbeCtrl_30fps);
       }
       else if(frame_fps == 60)
       {              /* 1920 x 1080 @60.0 fps */
       CyU3PDebugPrint(4,"\n Line:%d Return 60 fps structure",__LINE__);
                  return ((uint8_t *) gl1080pProbeCtrl_60fps);
       }


        }
    }
    else if (usbConType == CY_U3P_HIGH_SPEED)
    {
    }
    else
    {


    }
    return NULL;
}







 

 

5. 在 Callback 函数中修改 Set_cur 的代码

 

    /* Set Probe Control */
    if (wValue == CX3_UVC_VS_PROBE_CONTROL)
    {
        glCurrentFrameIndex = glCommitCtrl[3];
#ifdef Two_frame_rate
        glCurrentFrameInterval = ((uint32_t)glCommitCtrl[7] << 24) | ((uint32_t)glCommitCtrl[6] << 16) |
((uint32_t)glCommitCtrl[5] << 8) | ((uint32_t)glCommitCtrl[4] << 0);
        CyU3PDebugPrint(4,"\r\n Line:%d: glCurrentFrameInterval = 0x%x",__LINE__,glCurrentFrameInterval);
#endif
    }

 

6. 修改 SetVideoResolution 函数的实现

 

/* Set the video resolution through this function. This function lists all the
 *  supported resolutions in SuperSpeed and HighSpeed. The frame index of resolutions
 *  supported in Still Capture can be different from the frame index of resolutions supported
 *  in Video streaming.
 */
static void
CyCx3UvcAppImageSensorSetVideoResolution(
        uint8_t resolution_index,
        uint32_t frame_Interval
        )
{
CyU3PReturnStatus_t status = CY_U3P_SUCCESS;
uint32_t frameRate= 10000000/frame_Interval;
switch (CyU3PUsbGetSpeed ())
{
case CY_U3P_SUPER_SPEED:
switch (resolution_index)
{
case 0x01:
{
if(frameRate == 30)
{
CyU3PDebugPrint(4,"\r\n Line:%d: Set 30 fps",__LINE__);
/* Write 1080pSettings */
#ifndef FX3_STREAMING
status = CyU3PMipicsiSetIntfParams (&OV5640_YUY2_1080p, CyFalse);
if (status != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "\n\rUSBStpCB:SetIntfParams SS1 Err = 0x%x", status);
}
#endif
CyCx3_ImageSensor_Set_1080p ();


}
else if (frameRate == 60)
{
CyU3PDebugPrint(4,"\r\n Line:%d: Set 60 fps",__LINE__);
/* Write 1080pSettings */
#ifndef FX3_STREAMING
status = CyU3PMipicsiSetIntfParams (&OV5640_YUY2_1080p, CyFalse);
if (status != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "\n\rUSBStpCB:SetIntfParams SS1 Err = 0x%x", status);
}
#endif
CyCx3_ImageSensor_Set_1080p ();


}


}
break;


}
break;


case CY_U3P_HIGH_SPEED:
switch (resolution_index)
{




}
break;
}
}



 

 

按以上的步骤修改后,将固件下载至Demo 板,进行测试。

 

Snipaste_2019-08-02_17-12-35.png

 

 

Snipaste_2019-08-02_17-12-13.png

 

 

Snipaste_2019-08-02_17-11-58.png

 

可以看到,用户可以在主机端软件中对不同 fps 的配置进行正常切换。用户可以参考附件的工程获取更多细节信息。

 

注:

  • 出于演示的目的,本篇文档所附的固件中,只配置了USB3.0 的配置描述符(以及其他所有相关的 处理函数),没有 设置 USB2.0 及以下速度对应的配置描述符。如有需要,用户可以自行进行添加。
  • 同上,本篇 blog 所附的固件中,实际上当主机设置不同的 fps 时,固件采用相同的参数对 MIPI CSI 模块和 sensor进行配置(即执行相同的代码),只是采用 UART 打印的方式演示函数分支可以正常执行。实际使用中,用户当然需要做不同的配置。
  • 在主机软件的分辨率列表中,同一分辨率只会显示默认的帧率,不会同时列出所有帧率。
  • 在第一步中,需要先定义Max bits/s 后 Min bits/s,先 高帧率 后低帧率,否则烧录固件后不能正常工作。参考 CX3 multiple framerate support in same resolution