打印

怎样才能在FX DVK板子上实现双usb video设备??

[复制链接]
3228|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
nosilence_2007|  楼主 | 2013-9-14 00:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  从SDK sample中的uvc例子修改而来, 在 描述符中增加2个interface(1 control 1VS stream ), 一个EP0的address是和例子一样的0rex81,而我自己新增加EP1的address为0x83。
  但是我实现知识,GraphEdit 是可以打开我的FX3 capture 设备,而且也是有2个pin。 linux下面也是可以enum出2个video设备,但是运行的时候,第一个EP可以渲染的,但是第二个是不能渲染!
  我的方案是这样:
    我只开了一个DMA Channel, 2个EP都只用这个channel, 但是用了2个标志变量来分别判断EP0和EP1是否打开的。在有一个EP打开的时候,DMA 就Create了这个channel,但是只有当EP0和EP1都关闭的时候,才将这个DMA channel destroy掉。 也就是说只要有EP一个工作 ,这个dmachannel就一直工作,就一直有数据向这个DMA Channel 输送数据!  但是如果有一个EP关闭的话,那么我还是将这个EP  flush一下的。 但是这样却不知道为什么会不对呢?? EP1 根本就不能渲染????? 不知道是什么缘故?? 求问!


   下面是部分的代码片段:
   static void
CyFxUVCApplnUSBEventCB (
    CyU3PUsbEventType_t evtype, /* Event type */
    uint16_t            evdata  /* Event data */
    )
{
    uint8_t interface = 0, altSetting = 0;
    if (evtype == CY_U3P_USB_EVENT_SETINTF )
            CyU3PDebugPrint(4,"CyFxUVCApplnUSBEventCB evtype = %d \n  ",evtype);
    switch (evtype)
    {
        case CY_U3P_USB_EVENT_SETINTF:
             /* Start the video streamer application if the
              * interface requested was 1. If not, stop the
              * streamer. */
            interface = CY_U3P_GET_MSB(evdata);
            altSetting = CY_U3P_GET_LSB(evdata);

            if ((altSetting == CY_FX_UVC_STREAM_INTERFACE) &&
                    ((interface == 1)||(interface == 3)))
            {
                /* Stop the application before re-starting. */
                if (glIsApplnActive||glIsApplnActive2)
                {
                    CyFxUVCApplnStop (interface);
                }  //else         //added 0913
                CyFxUVCApplnStart (interface);
                break;
            }
            /* Fall-through. */

        case CY_U3P_USB_EVENT_SETCONF:
        case CY_U3P_USB_EVENT_RESET:
        case CY_U3P_USB_EVENT_DISCONNECT:
            /* Stop the video streamer application. */
            if (glIsApplnActive||glIsApplnActive2)
            {
                CyFxUVCApplnStop (interface);
            }
            break;

        default:
            break;
    }
//                CyU3PDebugPrint(4,"CyFxUVCApplnUSBEventCB is ok \n");
}
CyU3PReturnStatus_t
CyFxUVCApplnStart (uint8_t interface)
{
    CyU3PEpConfig_t epCfg;
    CyU3PDmaChannelConfig_t dmaCfg;
    CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS;
    CyU3PDebugPrint(4, "+++++CyFxUVCApplnStart++++\n");

    /*changed by jijun.yu  0913*/       
    uint8_t epAddr = -1;       
    if (!glIsApplnActive  && (interface == 1))        
                epAddr = CY_FX_EP_ISO_VIDEO;   
    else  if (!glIsApplnActive2 && (interface == 3))
                epAddr = CY_FX_EP_ISO_VIDEO_2;  
   else       
                return CY_U3P_SUCCESS;
   
       CyU3PDebugPrint(4, "+++++CyFxUVCApplnStart epAddr = %d++++\n",epAddr);

    /* Video streaming endpoint configuration */
    epCfg.enable = CyTrue;
    epCfg.epType = CY_U3P_USB_EP_ISO;
    epCfg.pcktSize = CY_FX_EP_ISO_VIDEO_PKT_SIZE;
    epCfg.isoPkts = 1;
    epCfg.burstLen = 1;
    epCfg.streams = 0;
//changed by jijun.yu  0913
    apiRetStatus = CyU3PSetEpConfig(epAddr, &epCfg);  //CY_FX_EP_ISO_VIDEO
    if (apiRetStatus != CY_U3P_SUCCESS)
    {
        CyU3PDebugPrint (4, "CyU3PSetEpConfig failed, Error Code = %d\n", apiRetStatus);
        return apiRetStatus;
    }

    /* Create a DMA Manual OUT channel for streaming data */
    /* Video streaming Channel is not active till a stream request is received */
    dmaCfg.size = CY_FX_UVC_STREAM_BUF_SIZE;
    dmaCfg.count = CY_FX_UVC_STREAM_BUF_COUNT;
    dmaCfg.prodSckId = CY_U3P_CPU_SOCKET_PROD;
    dmaCfg.consSckId = CY_FX_EP_VIDEO_CONS_SOCKET;
    dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
    dmaCfg.cb = NULL;
    dmaCfg.prodHeader = 0;
    dmaCfg.prodFooter = 0;
    dmaCfg.consHeader = 0;
    dmaCfg.prodAvailCount = 0;
/*changed jijun 0913*/       
   if ((!glIsApplnActive) && (!glIsApplnActive2))        {
            apiRetStatus = CyU3PDmaChannelCreate (&glChHandleUVCStream, CY_U3P_DMA_TYPE_MANUAL_OUT, &dmaCfg);
            if (apiRetStatus != CY_U3P_SUCCESS)
            {
                CyU3PDebugPrint (4, "CyU3PDmaChannelCreate failed, error code = %d\n",apiRetStatus);
                return apiRetStatus;
            }
           }
#ifdef stream2
    apiRetStatus = CyU3PDmaChannelCreate (&glChHandleUVCStream2, CY_U3P_DMA_TYPE_MANUAL_OUT, &dmaCfg);
    if (apiRetStatus != CY_U3P_SUCCESS)
    {
        CyU3PDebugPrint (4, "CyU3PDmaChannelCreate failed, error code = %d\n",apiRetStatus);
        return apiRetStatus;
    }
#endif
    /* Flush the endpoint memory */
    CyU3PUsbFlushEp(epAddr);


   /////////////??????
   if (!glIsApplnActive && !glIsApplnActive2) {
    apiRetStatus = CyU3PDmaChannelSetXfer (&glChHandleUVCStream, 0);
    if (apiRetStatus != CY_U3P_SUCCESS)
    {
        CyU3PDebugPrint (4, "CyU3PDmaChannelSetXfer failed, error code = %d\n", apiRetStatus);
        return apiRetStatus;
    }
   }
#ifdef stream2
    apiRetStatus = CyU3PDmaChannelSetXfer (&glChHandleUVCStream2, 0);
    if (apiRetStatus != CY_U3P_SUCCESS)
    {
        CyU3PDebugPrint (4, "CyU3PDmaChannelSetXfer failed, error code = %d\n", apiRetStatus);
        return apiRetStatus;
    }
#endif       
    /* Update the flag so that the application thread is notified of this. */
   if (interface == 1)
       glIsApplnActive = CyTrue;
   if (interface == 3)
            glIsApplnActive2 = CyTrue;


    return CY_U3P_SUCCESS;
}

/* This function stops the video streaming. It is called from the USB event
* handler, when there is a reset / disconnect or SET_INTERFACE for alternate
* interface 0. */
void
CyFxUVCApplnStop (uint8_t interface)
{
    CyU3PEpConfig_t epCfg;
    uint8_t epAddr = -1;
    CyU3PDebugPrint(4, "CyFxUVCApplnStop  interface = %d \n",interface);       
    /* Update the flag so that the application thread is notified of this. */
   if (interface ==1) {       
        epAddr = CY_FX_EP_ISO_VIDEO;
        glIsApplnActive = CyFalse;
    }
   if (interface == 3) {
           epAddr = CY_FX_EP_ISO_VIDEO_2;

           glIsApplnActive2 = CyFalse;
           }
    /* Abort and destroy the video streaming channel */
   if ((!glIsApplnActive) && (!glIsApplnActive2))         {
             CyU3PDebugPrint(4,"Destroy the dma channel \n");       
            CyU3PDmaChannelDestroy (&glChHandleUVCStream);
#ifdef stream2       
            CyU3PDmaChannelDestroy (&glChHandleUVCStream2);
#endif

           }
   
            /* Flush the endpoint memory */
            CyU3PUsbFlushEp(epAddr);

            /* Disable the video streaming endpoint. */
            CyU3PMemSet ((uint8_t *)&epCfg, 0, sizeof (epCfg));
            epCfg.enable = CyFalse;
            CyU3PSetEpConfig(epAddr, &epCfg);
}
沙发
kk5290122| | 2013-9-15 08:34 | 只看该作者
感觉lz好厉害…………

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

2

帖子

1

粉丝