Camera USB主机UVC摄像头FTDI Vinculum II未读取视频流

Camera USB主机UVC摄像头FTDI Vinculum II未读取视频流,camera,usb,host,ftdi,uvc,Camera,Usb,Host,Ftdi,Uvc,我已将最小程序提取到一个文件中,该文件是在较大程序的上下文之外演示问题所必需的。在最高级别的描述中,USB主机(FTDI Vinculum II)连接到UVC摄像头,正确枚举设备接口、端点等,设置传输,但最终当它执行vos_dev_read()(第511行)时,返回无错误,读取零字节。主机->UVC摄像头ioctl r/w工作正常,所有从UVC摄像头检索到的值(测试中使用了多个摄像头)都根据USB设备查看器的USB转储正确验证。因此,双向对话非常有效,只是没有视频数据。如果我将值更改为无效值或拔

我已将最小程序提取到一个文件中,该文件是在较大程序的上下文之外演示问题所必需的。在最高级别的描述中,USB主机(FTDI Vinculum II)连接到UVC摄像头,正确枚举设备接口、端点等,设置传输,但最终当它执行vos_dev_read()(第511行)时,返回无错误,读取零字节。主机->UVC摄像头ioctl r/w工作正常,所有从UVC摄像头检索到的值(测试中使用了多个摄像头)都根据USB设备查看器的USB转储正确验证。因此,双向对话非常有效,只是没有视频数据。如果我将值更改为无效值或拔下相机插头,我会得到预期的错误代码

明确地说,这个派生程序对读取的数据不做任何处理,除了它向UART终端(9600波特,无流量控制)写入读取的字节数。底线;为这个程序找到一个修复程序,同样的方法也适用于真正的程序

我知道找到一只独角兽的人有Vinculum II USB 2.0芯片的经验,但我相信问题是USB/UVC问题,而不是芯片的问题或它试图做什么。有一个比FTDI主机芯片稍大的UVC蜂巢。我试着去寻找魔法咒语;我试着对着芯片大喊四个字母的单词,甚至很友好地问:“请”也没用。该代码源于FTDI的网络摄像头演示程序,该程序编写得非常糟糕,包含大量未描述的硬编码数值常量

我查看了整个互联网上的每个USB/UVC驱动程序(主要是Linux和Windows)。请致电所有USB主机专家寻求帮助

谢谢大家!

...
#include "vos.h"
#include "USBHost.h"
#include "USB.h"
#include "UART.h"
#include "ioctl.h"
#include "stdio.h"

#define VOS_QUANTUM                 50
#define VOS_TICK_INTERVAL           1

#define NUMBER_OF_DEVICES           3
#define VOS_DEV_USBHOST             0
#define VOS_DEV_UVC                 1
#define VOS_DEV_UART                2

#define ISO_TRANSFER_SIZE   192
#define ISO_TRANSFER_COUNT  1
#define WEBCAM_HEADER_SIZE  12
#define WEBCAM_PAYLOAD_SIZE (ISO_TRANSFER_SIZE - WEBCAM_HEADER_SIZE)
#define BUF_SIZE            (ISO_TRANSFER_SIZE * ISO_TRANSFER_COUNT)

enum uvc_ret_e
{
    UVC_OK,
    UVC_INVALID_PARAMETER,
    UVC_NOT_FOUND,
    UVC_ERROR
};  

// configure request structure for VOS_IOCTL_UVC_CLASS_REQUEST
#define set_class_request(d, iface, ent, cs, code, len) \
    do \
    { \
        (d).bRequest = (code); \
        (d).wValue = ((cs) << 8); \
        (d).wIndex = (((ent) << 8) | (iface)); \
        (d).wLength = (len); \
    } \
    while (0)

// UVC ioctl parameter structure
typedef struct _uvc_ioctl_cb_t
{
    unsigned char ioctl_code;
    unsigned char *get;
    unsigned char *set;
} uvc_ioctl_cb_t;

typedef struct _uvc_context_t
{
    // host controller handle
    VOS_HANDLE                 hc;

    unsigned short             vid;
    unsigned short             pid;

    // endpoint handles
    usbhost_ep_handle_ex       epInt;
    usbhost_ep_handle_ex       epCtrl;
    usbhost_ep_handle_ex       epIsoIn;

    // endpoint info
    usbhost_ioctl_cb_ep_info_t epInfo;

    unsigned char              state;
} uvc_context_t;

typedef enum _VS_InterfaceControlStatus_e
{
    VS_CONTROL_UNDEFINED = 0x00,       // 0x00
    VS_PROBE_CONTROL,                  // 0x01
    VS_COMMIT_CONTROL,                 // 0x02
    VS_STILL_PROBE_CONTROL,            // 0x03
    VS_STILL_COMMIT_CONTROL,           // 0x04
    VS_STILL_IMAGE_TRIGGER_CONTROL,    // 0x05
    VS_STREAM_ERROR_CODE_CONTROL,      // 0x06
    VS_GENERATE_KEY_FRAME_CONTROL,     // 0x07
    VS_UPDATE_FRAME_SEGMENT_CONTROL,   // 0x08
    VS_SYNCH_DELAY_CONTROL             // 0x09
} VS_InterfaceControlStatus_e;

typedef enum _VS_ControlRequest_e
{
    RC_UNDEFINED = 0x00,               // 0x00
    SET_CUR,                           // 0x01
    GET_CUR = 0x81,                    // 0x81
    GET_MIN,                           // 0x82
    GET_MAX,                           // 0x83
    GET_RES,                           // 0x84
    GET_LEN,                           // 0x85
    GET_INFO,                          // 0x86
    GET_DEF                            // 0x87
} VS_ControlRequest_e;

typedef struct _VideoProbeAndCommiteControl_t
{
    unsigned short bmHint;
    unsigned char  bFormatIndex;
    unsigned char  bFrameIndex;
    unsigned int   dwFrameInterval;
    unsigned short wKeyFrameRate;
    unsigned short wPFrameRate;
    unsigned short wCompQuality;
    unsigned short wCompWindowSize;
    unsigned short wDelay;
    unsigned int   dwMaxVideoFrameSize;
    unsigned int   dwMaxPayloadTransferSize;
    unsigned int   dwClockFrequency;
    unsigned char  bmFramingInfo;
    unsigned char  bPreferedVersion;
    unsigned char  bMinVersion;
    unsigned char  bMaxVersion;
} VideoProbeAndCommiteControl_t;

// IOCTLS
#define VOS_IOCTL_UVC_ATTACH        1
#define VOS_IOCTL_UVC_DETACH        2
#define VOS_IOCTL_UVC_CLASS_REQUEST 3

unsigned char uvc_init(unsigned char vos_dev_num);
unsigned char uvc_ioctl(uvc_ioctl_cb_t *cb, uvc_context_t *ctx);
void uvc_open(uvc_context_t *ctx);
void uvc_close(uvc_context_t *ctx);
unsigned char uvc_read(char *buffer, unsigned short num_to_read, unsigned short *num_read, uvc_context_t *ctx);
unsigned char uvc_write(char *buffer, unsigned short num_to_write, unsigned short *num_written, uvc_context_t *ctx);

void setupUART(void);
void firmware(void);
void open_drivers(void);
void attach_drivers(void);

vos_tcb_t *tcbFIRMWARE;
VOS_HANDLE hUsbHost;
VOS_HANDLE hUvc;
VOS_HANDLE hUART;      
unsigned char buffer1[BUF_SIZE];
VideoProbeAndCommiteControl_t VProbeAndCom;     

void firmware(void)
{
    unsigned short iRead;
    unsigned char iStatus;
    unsigned int iLoopCnt = 0;
    uvc_ioctl_cb_t uvc_iocb;
    usb_deviceRequest_t desc_dev;
    unsigned char USBState;
    hUsbHost = vos_dev_open(VOS_DEV_USBHOST);
    hUvc = vos_dev_open(VOS_DEV_UVC);
    hUART = vos_dev_open(VOS_DEV_UART);
    
    setupUART();
    stdioAttach(hUART);
    printf ("Start\n");
    
    do
    {
        uvc_iocb.ioctl_code = VOS_IOCTL_UVC_ATTACH;
        uvc_iocb.set = (void *) hUsbHost;
        if (vos_dev_ioctl(hUvc, &uvc_iocb) != UVC_OK)
        {
            asm {HALT};
        }

        // Get the CUR supported res
        set_class_request(desc_dev, 1, 0, VS_PROBE_CONTROL, GET_CUR, 26 /*sizeof (VProbeAndCom)*/);

        uvc_iocb.ioctl_code = VOS_IOCTL_UVC_CLASS_REQUEST;
        uvc_iocb.set = &desc_dev;
        uvc_iocb.get = &VProbeAndCom;
        iStatus = vos_dev_ioctl(hUvc, &uvc_iocb);
        if (iStatus != UVC_OK)
        {
            asm {HALT};
        }
    
        VProbeAndCom.dwMaxPayloadTransferSize = ISO_TRANSFER_SIZE;

        set_class_request(desc_dev, 1, 0, VS_COMMIT_CONTROL, SET_CUR, 26 /*sizeof (VProbeAndCom)*/);

        uvc_iocb.ioctl_code = VOS_IOCTL_UVC_CLASS_REQUEST;
        uvc_iocb.set = &desc_dev;
        uvc_iocb.get = &VProbeAndCom;
        iStatus = vos_dev_ioctl(hUvc, &uvc_iocb);
        if (iStatus != UVC_OK)
        {
            asm {HALT};
        }
        
        break;
    }
    while (1);
    
    vos_delay_msecs(300);

    do
    {
        iStatus = iRead = 0;
        iStatus = vos_dev_read(hUvc, buffer1, ISO_TRANSFER_SIZE * ISO_TRANSFER_COUNT, &iRead);  // read from the ISO endpoint
        printf("%d: status = %d, iRead = %d\n", iLoopCnt++, iStatus, iRead);
    }
    while (1);
}
    
void main(void)
{
    uart_context_t uartContext;
    usbhost_context_t usbhostContext;
    
    vos_set_clock_frequency(VOS_48MHZ_CLOCK_FREQUENCY);
    vos_init(VOS_QUANTUM, VOS_TICK_INTERVAL, NUMBER_OF_DEVICES);

    // configure USB Host port 1 only
    // use a max of 4 USB devices
    usbhostContext.if_count = 16;
    usbhostContext.ep_count = 10;
    usbhostContext.xfer_count = 2;
    usbhostContext.iso_xfer_count = 36;
    
    uartContext.buffer_size = VOS_BUFFER_SIZE_128_BYTES;

    usbhost_init(VOS_DEV_USBHOST, -1, &usbhostContext);
    uvc_init(VOS_DEV_UVC);
    uart_init(VOS_DEV_UART, &uartContext);

    tcbFIRMWARE = vos_create_thread_ex(20, 4096, firmware, "Application", 0);   
    vos_start_scheduler();

main_loop:
    goto main_loop;
}

static vos_driver_t uvc_cb;

unsigned char uvc_init(unsigned char vos_dev_num)
{
    uvc_context_t *ctx;

    // allocate  context
    ctx = vos_malloc(sizeof(uvc_context_t));
    if (ctx == 0)
    {
        return UVC_ERROR;
    }

    // Set up function pointers to the driver
    uvc_cb.flags = 0;
    uvc_cb.read = uvc_read;
    uvc_cb.write = uvc_write;
    uvc_cb.ioctl = uvc_ioctl;
    uvc_cb.interrupt = (PF_INT) 0;
    uvc_cb.open = uvc_open;
    uvc_cb.close = uvc_close;

    // OK - register with device manager
    vos_dev_init(vos_dev_num, &uvc_cb, ctx);

    return UVC_OK;
}

void uvc_open(uvc_context_t *ctx)
{
    vos_memset(ctx, 0, sizeof(uvc_context_t));
}

void uvc_close(uvc_context_t *ctx)
{
    vos_memset(ctx, 0, sizeof(uvc_context_t));
}

unsigned char uvc_detach(uvc_context_t *ctx)
{
    vos_memset(ctx, 0, sizeof(uvc_context_t));
    return UVC_OK;
}

unsigned char uvc_attach(uvc_context_t *ctx, void *params)
{
    usbhost_ioctl_cb_t hc_iocb;        // USBHost ioctl request block
    usbhost_ioctl_cb_class_t hc_class;
    usbhost_ioctl_cb_dev_info_t devInfo;
    usbhost_device_handle_ex ifDev;    // device handle
    int ifs, aset;
    unsigned char status;
    unsigned char ret;
    unsigned char num_dev;
    unsigned char i;

    status = ret = UVC_OK;

    ctx->hc = (VOS_HANDLE) params;

    do
    {
        vos_delay_msecs(1000);

        // poll for enumeration to complete
        hc_iocb.ioctl_code = VOS_IOCTL_USBHOST_GET_CONNECT_STATE;
        hc_iocb.get = &i;
        ret = vos_dev_ioctl(ctx->hc, &hc_iocb);
        if (ret != USBHOST_OK)
        {
            ret = UVC_ERROR;
            break;
        }

        if (i == PORT_STATE_ENUMERATED)
        {
            num_dev = 0;
            // user ioctl to find device count
            hc_iocb.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_GET_COUNT;
            hc_iocb.set = NULL;
            hc_iocb.get = &num_dev;

            if (vos_dev_ioctl(ctx->hc, &hc_iocb) != USBHOST_OK)
            {
                status = UVC_ERROR;
                break;
            }

            ifDev = NULL;

            for (i = 0; i < num_dev; )
            {
                // user ioctl to find first device
                hc_iocb.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_GET_NEXT_HANDLE;
                hc_iocb.handle.dif = ifDev;
                hc_iocb.get = &ifDev;

                if (vos_dev_ioctl(ctx->hc, &hc_iocb) != USBHOST_OK)
                {
                    ret = UVC_ERROR;
                    break;
                }

                if (ifDev)
                {
                    vos_memset(&hc_class, 0, sizeof(usbhost_ioctl_cb_class_t));
                    hc_iocb.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_GET_CLASS_INFO;
                    hc_iocb.get = &hc_class;
                    vos_dev_ioctl(ctx->hc, &hc_iocb);

                    hc_iocb.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_GET_DEV_INFO;
                    hc_iocb.handle.dif = ifDev;
                    hc_iocb.set = NULL;
                    hc_iocb.get = &devInfo;
                    ret = vos_dev_ioctl(ctx->hc, &hc_iocb);
                    if (ret != USBHOST_OK)
                    {
                        ret = UVC_ERROR;
                        break;
                    }

                    ifs = devInfo.interface_number;
                    aset = devInfo.alt;

                    if ((hc_class.dev_class == USB_CLASS_VIDEO) &&
                        (hc_class.dev_subclass == USB_SUBCLASS_VIDEO_VIDEOSTREAMING))
                    {
                        // find interface 1, alternate 1
                        // this is an interface with an isochromous endpoint
                        // it is 192 bytes max packet size
                        if ((ifs == 1 /*1*/) && (aset == 1 /*1*/ ))
                        {
                            // user ioctl to find iso out endpoint on this device
                            hc_iocb.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_GET_ISO_IN_ENDPOINT_HANDLE;
                            hc_iocb.handle.dif = ifDev;
                            hc_iocb.get = &ctx->epIsoIn;

                            if (vos_dev_ioctl(ctx->hc, &hc_iocb) == USBHOST_OK)
                            {
                                break;
                            }
                        }
                    }
                }

                i++;
            }

            if (ret == UVC_ERROR)
            {
                status = UVC_ERROR;
                break;
            }

            if (ifDev == NULL)
            {
                status = UVC_ERROR;
                break;
            }

            // user ioctl to find interrupt endpoint on this device
            hc_iocb.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_GET_CONTROL_ENDPOINT_HANDLE;
            hc_iocb.handle.dif = ifDev;
            hc_iocb.get = &ctx->epCtrl;
            if (vos_dev_ioctl(ctx->hc, &hc_iocb) != USBHOST_OK)
            {
                status = UVC_ERROR;
                break;
            }

            // set this interface to be enabled
            hc_iocb.ioctl_code = VOS_IOCTL_USBHOST_SET_INTERFACE;
            hc_iocb.handle.dif = ifDev;
            if (vos_dev_ioctl(ctx->hc, &hc_iocb) != USBHOST_OK)
            {
                status = UVC_ERROR;
                break;
            }

            // user ioctl to find interrupt endpoint on this device
            hc_iocb.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_GET_ENDPOINT_INFO;
            hc_iocb.handle.ep = ctx->epIsoIn;
            hc_iocb.get = &ctx->epInfo;
            if (vos_dev_ioctl(ctx->hc, &hc_iocb) != USBHOST_OK)
            {
                status = UVC_ERROR;
                break;
            }

            break;
        }
    }
    while (1);

    return status;
}

unsigned char host_device_setup_transfer(uvc_context_t *ctx, usb_deviceRequest_t *req_desc, void *out_data)
{
    // USBHost ioctl request block
    usbhost_ioctl_cb_t iocb;

    iocb.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_SETUP_TRANSFER;
    iocb.handle.ep = ctx->epCtrl;
    iocb.set = req_desc;
    iocb.get = out_data;

    if (vos_dev_ioctl(ctx->hc, &iocb) != USBHOST_OK)
        return UVC_ERROR;

    return UVC_OK;
}

unsigned char uvc_class_request(uvc_context_t *ctx, void *in_data, void *out_data)
{
    usb_deviceRequest_t *req = (usb_deviceRequest_t *) in_data;

    if (req->bRequest == SET_CUR)
    {
        req->bmRequestType = USB_BMREQUESTTYPE_HOST_TO_DEV |
            USB_BMREQUESTTYPE_CLASS |
            USB_BMREQUESTTYPE_INTERFACE;
    }
    else
    {
        req->bmRequestType = USB_BMREQUESTTYPE_DEV_TO_HOST |
            USB_BMREQUESTTYPE_CLASS |
            USB_BMREQUESTTYPE_INTERFACE;
    }

    return host_device_setup_transfer(ctx, req, out_data);
}

// UVC read function
unsigned char uvc_read(char *buffer,
                       unsigned short num_to_read,
                       unsigned short *num_read,
                       uvc_context_t *ctx)
{
    usbhost_ioctl_cb_t hc_iocb;
    usbhost_xfer_iso_t xfer;
    vos_semaphore_t semDum;
    unsigned char status;
    unsigned short frame;
    unsigned char i = 0;
    unsigned short xfer_size = ISO_TRANSFER_SIZE; // LAZ, Was ctx->epInfo.max_size; Snake cam returns too big of size for example

    vos_init_semaphore(&semDum, 0);

    // form isochronous transfer descriptor
    xfer.cond_code = USBHOST_CC_NOTACCESSED;
    xfer.flags = 0;
    xfer.s = &semDum;
    xfer.ep = ctx->epIsoIn;
    xfer.buf = buffer;
    xfer.len = num_to_read;

    xfer.count = (unsigned char) (num_to_read / xfer_size);

    while (num_to_read)
    {
        xfer.len_psw[i].size = (num_to_read > xfer_size)?xfer_size:num_to_read;
        num_to_read -= xfer_size;
        i++;
    }
    
    // user ioctl to find frame number (as close as possible to use)
    hc_iocb.ioctl_code = VOS_IOCTL_USBHOST_HW_GET_FRAME_NUMBER;
    hc_iocb.get = &frame;
    if (vos_dev_ioctl(ctx->hc, &hc_iocb) != USBHOST_OK)
    {
        return UVC_ERROR;
    }

    xfer.frame = frame + 1;
    
    num_read = 0; // LAZ, Added
    
    // now start the read from the ISO endpoint (line 511)
    status = vos_dev_read(ctx->hc, (unsigned char *) &xfer, sizeof(usbhost_xfer_t), num_read);

    if (status != USBHOST_OK)
    {
        return UVC_ERROR;
    }

    if (xfer.cond_code != USBHOST_CC_NOERROR)
    {
        return UVC_ERROR;
    }

    return UVC_OK;
}

// UVC write function
unsigned char uvc_write(char *buffer,
                        unsigned short num_to_write,
                        unsigned short *num_written,
                        uvc_context_t *ctx)
{
    unsigned char status = UVC_OK;

    return status;
}

// UVC IOCTL function
unsigned char uvc_ioctl(uvc_ioctl_cb_t *cb, uvc_context_t *ctx)
{
    unsigned char status = UVC_INVALID_PARAMETER;

    switch (cb->ioctl_code)
    {
    case VOS_IOCTL_UVC_ATTACH:
        status = uvc_attach(ctx, cb->set);
        break;

    case VOS_IOCTL_UVC_DETACH:
        status = uvc_detach(ctx);
        break;

    case VOS_IOCTL_UVC_CLASS_REQUEST:
        status = uvc_class_request(ctx, cb->set, cb->get);
        break;

    default:
        break;
    }

    return status;
}


void setupUART(void)
{
    common_ioctl_cb_t uart_iocb;
    
    // setup the UART interface
    uart_iocb.ioctl_code = VOS_IOCTL_COMMON_ENABLE_DMA;
    vos_dev_ioctl(hUART, &uart_iocb);

    // set baud rate
    uart_iocb.ioctl_code = VOS_IOCTL_UART_SET_BAUD_RATE;
    uart_iocb.set.uart_baud_rate = UART_BAUD_9600;
    vos_dev_ioctl(hUART, &uart_iocb);

    // set flow control
    uart_iocb.ioctl_code = VOS_IOCTL_UART_SET_FLOW_CONTROL;
    uart_iocb.set.param = UART_FLOW_NONE; 
    vos_dev_ioctl(hUART, &uart_iocb);

    // set data bits
    uart_iocb.ioctl_code = VOS_IOCTL_UART_SET_DATA_BITS;
    uart_iocb.set.param = UART_DATA_BITS_8;
    vos_dev_ioctl(hUART, &uart_iocb);

    // set stop bits
    uart_iocb.ioctl_code = VOS_IOCTL_UART_SET_STOP_BITS;
    uart_iocb.set.param = UART_STOP_BITS_1;
    vos_dev_ioctl(hUART, &uart_iocb);

    // set parity
    uart_iocb.ioctl_code = VOS_IOCTL_UART_SET_PARITY;
    uart_iocb.set.param = UART_PARITY_NONE;
    vos_dev_ioctl(hUART, &uart_iocb);
}   

...
。。。
#包括“vos.h”
#包括“USBHost.h”
#包括“USB.h”
#包括“UART.h”
#包括“ioctl.h”
#包括“stdio.h”
#定义VOS_量子50
#定义VOS\u刻度\u间隔1
#定义\u设备的数量\u 3
#定义VOS_DEV_USBHOST 0
#定义VOS_DEV_UVC 1
#定义VOS_DEV_UART 2
#定义ISO_传输_大小192
#定义ISO_传输_计数1
#定义网络摄像头标题大小12
#定义网络摄像头有效负载大小(ISO传输大小-网络摄像头标题大小)
#定义基本单位大小(ISO_传输大小*ISO_传输计数)
枚举uvc_ret_e
{
好的,
UVC_参数无效,
未找到UVC_,
UVC_误差
};  
//为VOS_IOCTL_UVC_类_请求配置请求结构
#定义集合类请求(d、iface、ent、cs、代码、len)\
做\
{ \
(d) .bRequest=(代码)\
(d) .wValue=((cs)hc和hc_iocb);
如果(ret!=USBHOST_正常)
{
ret=UVC_误差;
打破
}
if(i==端口\状态\枚举)
{
num_dev=0;
//用户ioctl查找设备计数
hc_iocb.ioctl_code=VOS_ioctl_USBHOST_DEVICE_GET_COUNT;
hc_iocb.set=NULL;
hc_iocb.get=&num_dev;
如果(vos_dev_ioctl(ctx->hc和hc_iocb)!=USBHOST_OK)
{
状态=UVC\U错误;
打破
}
ifDev=NULL;
对于(i=0;ihc和hc_iocb)!=USBHOST_OK)
{
ret=UVC_误差;
打破
}
if(ifDev)
{
vos_成员集(&hc_类,0,sizeof(usbhost_ioctl_cb_类));
hc_iocb.ioctl_code=VOS_ioctl_USBHOST_DEVICE_GET_CLASS_INFO;
hc_iocb.get=&hc_类;
vos_dev_ioctl(ctx->hc和hc_iocb);
hc_iocb.ioctl_code=VOS_ioctl_USBHOST_DEVICE_GET_DEV_INFO;
hc_iocb.handle.dif=ifDev;
hc_iocb.set=NULL;
hc_iocb.get=&devInfo;
ret=vos_dev_ioctl(ctx->hc和hc_iocb);
如果(ret!=USBHOST_正常)
{
ret=UVC_误差;
打破
}
ifs=devInfo.interface\u编号;
aset=devInfo.alt;
如果((hc_class.dev_class==USB_class_视频)&&
(hc_class.dev_subclass==USB_subclass_VIDEO_VIDEOSTREAMING))
{
//查找接口1,备用1
//这是一个具有等色端点的界面
//最大数据包大小为192字节
如果((ifs==1/*1*/)&&(aset==1/*1*/)
{
//用户ioctl查找此设备上的iso out端点
hc_iocb.ioctl_code=VOS_ioctl_USBHOST_DEVICE_GET_ISO_IN_ENDPOINT_HANDLE;
hc_iocb.handle.dif=ifDev;
hc_iocb.get=&ctx->epoin;
如果(vos_dev_ioctl(ctx->hc,&hc_iocb)==USBHOST_OK)
{
打破
}
}
}
}
i++;
}
如果(ret==UVC\U错误)
{
状态=UVC\U错误;
打破
}
if(ifDev==NULL)
{
状态=UVC\U错误;
打破
}
//用户ioctl查找此设备上的中断终结点
hc_iocb.ioctl_code=VOS_ioctl_USBHOST_设备_GET_CONTROL_END