社区导航

 

搜索
查看: 17552|回复: 28

[原创] UVC摄像头枚举过程分析——D881HD720P

[复制链接]

671

TA的帖子

3

TA的资源

版主

Rank: 6Rank: 6

发表于 2015-9-23 13:07 | 显示全部楼层 |阅读模式
计划在单片机(主要是Cortex-M系列)上驱动USB UVC摄像头,本帖是对Windows下枚举过程的分析。

摄像头插入后的枚举,一开始由usbh core来负责,此过程与其他类设备相同,不再赘述。
UVC类驱动主要负责获得摄像头状态,根据要求设置摄像头参数以及获得数据。

win7系统上,当应用有读取摄像头的请求是,类驱动便按照一定流程开始操作,我的目的便是按照这一流程在单片机上激活特定摄像头并获得数据。(UVC标准类驱动太过复杂,暂无搞通用驱动的必要)

传输类型总览:
图片1.png
其中bRequest意义参考此表:
图片2.png
整个流程中使用了GET_CUR,GET_MIN,GET_MAX以及SET_CUR四种请求。

Transfer分析:
在上图所有transferwIndex都是0x0001,即指定了entity0interface1
由配置描述符可知interface1为VideoStreaming,所以根据下表分析:
图片3.png
bRequest中缩写的意义:
Current setting attribute (GET_CUR)
Minimum setting attribute (GET_MIN)
Maximum setting attribute (GET_MAX)
Default setting attribute (GET_DEF)
Resolution attribute (GET_RES)
Data length attribute (GET_LEN)
Information attribute (GET_INFO)

wValue是选择控制器,除一个0x0200外,都是0x0100,意义如下
VS_CONTROL_UNDEFINED 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
wLength指定附件参数长度,都是26

这样分析后,就可以清楚的看到,系统对视频流接口的参数进行了probecommit两种操作,先通过probe进行参数协商,最后commit激活。
也可以看下协议中对这个过程的描述:
图片4.png


关于data中26字节数据的分析,请看下表,如果表格显示不完整,请看附件
捕获.PNG

在在协商完成后,设置interface altr setting,随后启动同步传输,开始搬运数据。
至此,针对D881HD720P摄像头的枚举分析完毕。

附上分析表及原始数据。
D881_协商数据分析.xls (17 KB, 下载次数: 166)

i.MX RT1010 真香


回复

使用道具 举报

1万

TA的帖子

14

TA的资源

版主

Rank: 6Rank: 6

测评达人

发表于 2015-9-23 14:06 | 显示全部楼层
预备怎么做?用那种单片机?

点评

新唐的505(OHCI)核心已经弄好了 所以先拿它做类驱动 后面支持STM32的IP核心(DWCOTG)  详情 回复 发表于 2015-9-23 14:09

回复

使用道具 举报

671

TA的帖子

3

TA的资源

版主

Rank: 6Rank: 6

 楼主| 发表于 2015-9-23 14:09 | 显示全部楼层
dcexpert 发表于 2015-9-23 14:06
预备怎么做?用那种单片机?

新唐的505(OHCI)核心已经弄好了
所以先拿它做类驱动
后面支持STM32的IP核心(DWCOTG)

i.MX RT1010 真香


回复

使用道具 举报

671

TA的帖子

3

TA的资源

版主

Rank: 6Rank: 6

 楼主| 发表于 2015-10-15 10:29 | 显示全部楼层
正好说一下,这个uvc已经能在stm32f7上面跑了
在1024 * 1 同步传输设置下,能稳定获得5.4Mb/s的图像流

速度上应该还有提升空间,估计能到15Mb的样子,但是这种大数据流stm32f7压根没法处理,最多转发下,咔咔

i.MX RT1010 真香


回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2015-10-16 10:04 | 显示全部楼层
Hi,le062,这两天一直根据您的帖子学习UVC枚举。我是在stm32F2系列芯片上实现UVC host驱动,接一个USB摄像头获取视频,由于技术底子薄,目前很不顺利,但是任务又很紧(要求两个星期内完成),不知道能否将您的代码发给我学习一下,gdcwj2003@163.com。多谢啦!

点评

vsfusb中ohci部分是完全开源的,st的dwcotg暂时未开源 如果你们能换用新唐的芯片做uvc,这部分是现成的  详情 回复 发表于 2015-10-16 12:27
usb这上面的麻烦很大的 我建议你使用st的usb驱动程序 我可以把uvc部分的简单驱动逻辑发给你 在枚举之后,直接commit 协商结果,接着set interface 这样就能开始同步传输了  详情 回复 发表于 2015-10-16 12:25

回复

使用道具 举报

671

TA的帖子

3

TA的资源

版主

Rank: 6Rank: 6

 楼主| 发表于 2015-10-16 12:25 | 显示全部楼层
gdcwj2012 发表于 2015-10-16 10:04
Hi,le062,这两天一直根据您的帖子学习UVC枚举。我是在stm32F2系列芯片上实现UVC host驱动,接一个USB摄像 ...

usb这上面的麻烦很大的
我建议你使用st的usb驱动程序

我可以把uvc部分的简单驱动逻辑发给你
  1. #include "app_cfg.h"
  2. #include "app_type.h"

  3. #include "interfaces.h"
  4. #include "tool/buffer/buffer.h"

  5. #include "stack/usb/core/vsfusbh.h"
  6. #include "stack/usb/class/host/UVC/vsfusbh_UVC.h"

  7. #define UVC_PROBE_CRTL_DATA_SIZE 36

  8. enum uav_evt_t
  9. {
  10.         UAV_RESET_STREAM_PARAM = VSFSM_EVT_USER_LOCAL + 1,
  11.         UAV_ISO_ENABLE,
  12.         UAV_ISO_DISABLE,
  13. };

  14. enum uav_request_t
  15. {
  16.         RC_UNDEFINED = 0x00,
  17.         SET_CUR = 0x01,
  18.         GET_CUR = 0x81,
  19.         GET_MIN = 0x82,
  20.         GET_MAX = 0x83,
  21.         GET_RES = 0x84,
  22.         GET_LEN = 0x85,
  23.         GET_INFO = 0x86,
  24.         GET_DEF = 0x87,
  25. };

  26. struct vsfusbh_uvc_t
  27. {
  28.         struct vsfusbh_t *usbh;
  29.         struct vsfusbh_device_t *dev;

  30.         struct vsfsm_t init_sm;
  31.         struct vsfsm_pt_t init_pt;
  32.         struct vsfsm_t ctrl_sm;
  33.         struct vsfsm_pt_t ctrl_pt;
  34.         struct vsfsm_t video_sm;
  35.         //struct vsfsm_t audio_sm;

  36.         struct vsfusbh_urb_t ctrl_urb;
  37.         struct vsfusbh_urb_t video_urb;
  38.         //struct vsfusbh_urb_t audio_urb;

  39.         uint8_t *ctrl_urb_buf;
  40.         uint8_t *video_urb_buf;
  41.         //uint8_t *audio_urb_buf;

  42.         struct vsfusbh_uvc_payload_t video_payload;
  43.         //struct vsfusbh_uvc_payload_t audio_payload;

  44.         struct vsfusbh_uvc_param_t set_param;
  45.         struct vsfusbh_uvc_param_t cur_param;

  46.         uint16_t video_iso_packet_len;
  47.         //uint16_t audio_iso_packet_len;
  48.         uint8_t video_iso_ep;
  49.         //uint8_t audio_iso_ep;

  50. };

  51. void (*vsfusbh_uvc_report)(void *dev_data, struct vsfusbh_uvc_param_t *param,
  52.                 struct vsfusbh_uvc_payload_t *payload) = NULL;

  53. static vsf_err_t uvc_init_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt)
  54. {
  55.         vsf_err_t err;
  56.         struct vsfusbh_uvc_t *hdata = (struct vsfusbh_uvc_t *)pt->user_data;
  57.         struct vsfusbh_urb_t *vsfurb = &hdata->ctrl_urb;

  58.         vsfsm_pt_begin(pt);

  59.         // reset interfaces 1 (video)
  60.         vsfurb->transfer_buffer = NULL;
  61.         vsfurb->transfer_length = 0;
  62.         err = vsfusbh_set_interface(hdata->usbh, vsfurb, 1, 0);
  63.         if (err != VSFERR_NONE)
  64.                 return err;
  65.         vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE);
  66.         if (vsfurb->status != URB_OK)
  67.                 return VSFERR_FAIL;

  68.         vsfsm_pt_end(pt);

  69.         return VSFERR_NONE;
  70. }

  71. static struct vsfsm_state_t *uvc_evt_handler_init(struct vsfsm_t *sm,
  72.                 vsfsm_evt_t evt)
  73. {
  74.         vsf_err_t err;
  75.         struct vsfusbh_uvc_t *hdata = (struct vsfusbh_uvc_t *)sm->user_data;

  76.         switch (evt)
  77.         {
  78.         case VSFSM_EVT_INIT:
  79.         case VSFSM_EVT_URB_COMPLETE:
  80.         case VSFSM_EVT_DELAY_DONE:
  81.                 err = hdata->init_pt.thread(&hdata->init_pt, evt);
  82.                 if (err < 0)
  83.                 {
  84.                         // TODO
  85.                 }
  86.                 else if (err == 0)
  87.                 {
  88.                         hdata->ctrl_urb.sm = &hdata->ctrl_sm;

  89.                         if (vsfusbh_uvc_report)
  90.                                 vsfusbh_uvc_report(hdata, &hdata->cur_param, NULL);
  91.                 }
  92.                 break;
  93.         default:
  94.                 break;
  95.         }
  96.         return NULL;
  97. }

  98. const uint8_t negotiate_temp[26] =
  99. {
  100. 0x00, 0x00, 0x01, 0x03, 0x15, 0x16, 0x05, 0x00,
  101. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  102. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  103. 0x00, 0x00
  104. };

  105. static vsf_err_t uvc_ctrl_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt)
  106. {
  107.         vsf_err_t err;
  108.         struct vsfusbh_uvc_t *hdata = (struct vsfusbh_uvc_t *)pt->user_data;
  109.         struct vsfusbh_urb_t *vsfurb = &hdata->ctrl_urb;

  110.         vsfsm_pt_begin(pt);

  111.         if (hdata->set_param.video_enable)
  112.         {
  113.                 // negotiate
  114.                 hdata->video_iso_packet_len = 1024;
  115.                 hdata->video_iso_ep = 1;

  116.                 // commit param
  117.                 vsfurb->transfer_buffer = hdata->ctrl_urb_buf;
  118.                 memcpy(vsfurb->transfer_buffer, negotiate_temp, 26);
  119.                 vsfurb->transfer_length = 26;
  120.                 vsfurb->pipe = usb_sndctrlpipe(vsfurb->vsfdev, 0);
  121.                 err =  vsfusbh_control_msg(hdata->usbh, vsfurb,
  122.                                 USB_TYPE_CLASS |USB_RECIP_INTERFACE | USB_DIR_OUT, SET_CUR,
  123.                                 0x0200, 0x0001);
  124.                 if (err != VSFERR_NONE)
  125.                         return err;
  126.                 vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE);
  127.                 if (vsfurb->status != URB_OK)
  128.                         return VSFERR_FAIL;

  129.                 // set interfaces
  130.                 vsfurb->transfer_buffer = NULL;
  131.                 vsfurb->transfer_length = 0;
  132.                 err = vsfusbh_set_interface(hdata->usbh, vsfurb, 1, 4);
  133.                 if (err != VSFERR_NONE)
  134.                         return err;
  135.                 vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE);
  136.                 if (vsfurb->status != URB_OK)
  137.                         return VSFERR_FAIL;

  138.                 // enable video
  139.                 vsfsm_post_evt_pending(&hdata->video_sm, UAV_ISO_ENABLE);
  140.         }
  141.         else
  142.         {
  143.                 vsfurb->transfer_buffer = NULL;
  144.                 vsfurb->transfer_length = 0;
  145.                 err = vsfusbh_set_interface(hdata->usbh, vsfurb, 1, 0);
  146.                 if (err != VSFERR_NONE)
  147.                         return err;
  148.                 vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE);
  149.                 if (vsfurb->status != URB_OK)
  150.                         return VSFERR_FAIL;
  151.         }
  152.        
  153.         vsf_bufmgr_free(hdata->ctrl_urb_buf);
  154.         hdata->ctrl_urb_buf = NULL;
  155.        
  156.         memcpy(&hdata->cur_param, &hdata->set_param,
  157.                         sizeof(struct vsfusbh_uvc_param_t));
  158.         vsfusbh_uvc_report(hdata, &hdata->cur_param, NULL);

  159.         vsfsm_pt_end(pt);

  160.         return VSFERR_NONE;
  161. }

  162. static struct vsfsm_state_t *uvc_evt_handler_ctrl(struct vsfsm_t *sm,
  163.                 vsfsm_evt_t evt)
  164. {
  165.         vsf_err_t err;
  166.         struct vsfusbh_uvc_t *hdata = (struct vsfusbh_uvc_t *)sm->user_data;

  167.         switch (evt)
  168.         {
  169.         case VSFSM_EVT_INIT:
  170.                 break;
  171.         case UAV_RESET_STREAM_PARAM:
  172.                 hdata->ctrl_pt.state = 0;
  173.                 if (hdata->ctrl_urb_buf == NULL)
  174.                 {
  175.                         hdata->ctrl_urb_buf = vsf_bufmgr_malloc(UVC_PROBE_CRTL_DATA_SIZE);
  176.                         if (hdata->ctrl_urb_buf == NULL)
  177.                                 return NULL;
  178.                 }
  179.         case VSFSM_EVT_URB_COMPLETE:
  180.         case VSFSM_EVT_DELAY_DONE:
  181.                 err = hdata->ctrl_pt.thread(&hdata->ctrl_pt, evt);
  182.                 if (err < 0)
  183.                 {
  184.                         // TODO

  185.                         vsf_bufmgr_free(hdata->ctrl_urb_buf);
  186.                         hdata->ctrl_urb_buf = NULL;
  187.                 }
  188.                 else if (err == 0)
  189.                 {
  190.                         vsf_bufmgr_free(hdata->ctrl_urb_buf);
  191.                         hdata->ctrl_urb_buf = NULL;
  192.                 }
  193.                 break;
  194.         default:
  195.                 break;
  196.         }
  197.         return NULL;
  198. }

  199. static struct vsfsm_state_t *uvc_evt_handler_video(struct vsfsm_t *sm,
  200.                 vsfsm_evt_t evt)
  201. {
  202.         vsf_err_t err;
  203.         struct vsfusbh_uvc_t *hdata = (struct vsfusbh_uvc_t *)sm->user_data;
  204.         struct vsfusbh_t *usbh = hdata->usbh;
  205.         struct vsfusbh_urb_t *vsfurb = &hdata->video_urb;

  206.         switch (evt)
  207.         {
  208.         case VSFSM_EVT_INIT:
  209.                 break;
  210.         case UAV_ISO_ENABLE:
  211.                 if (hdata->video_urb_buf == NULL)
  212.                 {
  213.                         vsfurb->vsfdev->epmaxpacketin[hdata->video_iso_ep] = hdata->video_iso_packet_len;
  214.                         hdata->video_urb_buf = vsf_bufmgr_malloc(hdata->video_iso_packet_len);
  215.                         if (hdata->video_urb_buf == NULL)
  216.                                 return NULL;
  217.                         vsfurb->transfer_buffer = hdata->video_urb_buf;
  218.                         vsfurb->transfer_length = hdata->video_iso_packet_len;
  219.                         vsfurb->pipe = usb_rcvisocpipe(vsfurb->vsfdev, hdata->video_iso_ep);
  220.                         vsfurb->transfer_flags |= USB_ISO_ASAP;
  221.                         vsfurb->number_of_packets = 1;
  222.                         vsfurb->iso_frame_desc[0].offset = 0;
  223.                         vsfurb->iso_frame_desc[0].length = hdata->video_iso_packet_len;
  224.                         err = vsfusbh_submit_urb(usbh, vsfurb);
  225.                         if (err != VSFERR_NONE)
  226.                                 goto error;
  227.                 }
  228.                 break;
  229.         case UAV_ISO_DISABLE:
  230.                 // TODO
  231.                 break;
  232.         case VSFSM_EVT_URB_COMPLETE:
  233.                 if (vsfurb->status == URB_OK)
  234.                 {
  235.                         hdata->video_payload.len = vsfurb->actual_length;
  236.                         vsfusbh_uvc_report(hdata, &hdata->cur_param, &hdata->video_payload);
  237.                 }
  238.                 else
  239.                 {
  240.                         goto error;
  241.                 }
  242.                 err = vsfusbh_relink_urb(usbh, vsfurb);
  243.                 if (err != VSFERR_NONE)
  244.                         goto error;
  245.                 break;
  246.         default:
  247.                 break;
  248.         }
  249.         return NULL;

  250. error:
  251.         vsf_bufmgr_free(hdata->video_urb_buf);
  252.         hdata->video_urb_buf = NULL;
  253.         return NULL;
  254. }

  255. static void *vsfusbh_uvc_init(struct vsfusbh_t *usbh, struct vsfusbh_device_t *dev)
  256. {
  257.         struct vsfusbh_class_data_t *cdata;
  258.         struct vsfusbh_uvc_t *hdata;

  259.         cdata = vsf_bufmgr_malloc(sizeof(struct vsfusbh_class_data_t));
  260.         if (NULL == cdata)
  261.                 return NULL;

  262.         hdata = vsf_bufmgr_malloc(sizeof(struct vsfusbh_uvc_t));
  263.         if (NULL == hdata)
  264.         {
  265.                 vsf_bufmgr_free(cdata);
  266.                 return NULL;
  267.         }
  268.         memset(cdata, 0, sizeof(struct vsfusbh_class_data_t));
  269.         memset(hdata, 0, sizeof(struct vsfusbh_uvc_t));

  270.         cdata->dev = dev;
  271.         hdata->dev = dev;
  272.         hdata->usbh = usbh;
  273.         cdata->param = hdata;

  274.         hdata->video_payload.type = VSFUSBH_UVC_PAYLOAD_VIDEO;
  275.         hdata->video_payload.buf = hdata->video_urb_buf;

  276.         hdata->init_sm.init_state.evt_handler = uvc_evt_handler_init;
  277.         hdata->init_sm.user_data = (void*)hdata;
  278.         hdata->init_pt.thread = uvc_init_thread;
  279.         hdata->init_pt.user_data = hdata;
  280.         hdata->init_pt.sm = &hdata->init_sm;
  281.         hdata->init_pt.state = 0;
  282.        
  283.         hdata->ctrl_sm.init_state.evt_handler = uvc_evt_handler_ctrl;
  284.         hdata->ctrl_sm.user_data = (void*)hdata;
  285.         hdata->ctrl_pt.thread = uvc_ctrl_thread;
  286.         hdata->ctrl_pt.user_data = hdata;
  287.         hdata->ctrl_pt.sm = &hdata->ctrl_sm;
  288.         hdata->ctrl_pt.state = 0;
  289.        
  290.         hdata->ctrl_urb.vsfdev = dev;
  291.         hdata->ctrl_urb.timeout = 200;
  292.         hdata->ctrl_urb.sm = &hdata->init_sm;

  293.         hdata->video_sm.init_state.evt_handler = uvc_evt_handler_video;
  294.         hdata->video_sm.user_data = (void*)hdata;
  295.         hdata->video_urb.vsfdev = dev;
  296.         hdata->video_urb.timeout = 200;
  297.         hdata->video_urb.sm = &hdata->video_sm;

  298.         vsfsm_init(&hdata->init_sm);
  299.         vsfsm_init(&hdata->ctrl_sm);
  300.         vsfsm_init(&hdata->video_sm);

  301.         return cdata;
  302. }

  303. static vsf_err_t vsfusbh_uvc_match(struct vsfusbh_device_t *dev)
  304. {
  305.         if ((dev->descriptor.idVendor == 0x04f2) &&
  306.                 (dev->descriptor.idProduct == 0xb130))
  307.         {
  308.                 return VSFERR_NONE;
  309.         }

  310.         return VSFERR_FAIL;
  311. }

  312. static void vsfusbh_uvc_free(struct vsfusbh_device_t *dev)
  313. {
  314.         struct vsfusbh_class_data_t *cdata = (struct vsfusbh_class_data_t *)(dev->priv);
  315.         struct vsfusbh_uvc_t *hdata = (struct vsfusbh_uvc_t *)cdata->param;

  316.         // TODO
  317.         // free urb

  318.         vsf_bufmgr_free(hdata);
  319.         vsf_bufmgr_free(cdata);
  320. }

  321. const struct vsfusbh_class_drv_t vsfusbh_uvc_drv = {
  322.         vsfusbh_uvc_init,
  323.         vsfusbh_uvc_free,
  324.         vsfusbh_uvc_match,
  325. };

  326. vsf_err_t vsfusbh_uvc_set(void *dev_data, struct vsfusbh_uvc_param_t *param)
  327. {
  328.         struct vsfusbh_uvc_t *hdata = (struct vsfusbh_uvc_t *)dev_data;

  329.         hdata->set_param = *param;
  330.         vsfsm_post_evt_pending(&hdata->ctrl_sm, UAV_RESET_STREAM_PARAM);
  331.         return VSFERR_NONE;
  332. }
复制代码


在枚举之后,直接commit 协商结果,接着set interface
这样就能开始同步传输了

i.MX RT1010 真香


回复

使用道具 举报

671

TA的帖子

3

TA的资源

版主

Rank: 6Rank: 6

 楼主| 发表于 2015-10-16 12:27 | 显示全部楼层
gdcwj2012 发表于 2015-10-16 10:04
Hi,le062,这两天一直根据您的帖子学习UVC枚举。我是在stm32F2系列芯片上实现UVC host驱动,接一个USB摄像 ...

vsfusb中ohci部分是完全开源的,st的dwcotg暂时未开源
如果你们能换用新唐的芯片做uvc,这部分是现成的

i.MX RT1010 真香


回复

使用道具 举报

4036

TA的帖子

233

TA的资源

管理员

Rank: 13Rank: 13Rank: 13Rank: 13

发表于 2015-10-26 10:08 | 显示全部楼层
路过围观

回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2015-11-16 17:08 | 显示全部楼层
你好,我想问下用stm32F4开发平台实现UVC HOST后接USB摄像头采集图像,然后做图像处理可行吗?

点评

接摄像头没问题,图像处理不清楚  详情 回复 发表于 2015-11-17 13:37

回复

使用道具 举报

671

TA的帖子

3

TA的资源

版主

Rank: 6Rank: 6

 楼主| 发表于 2015-11-17 13:37 | 显示全部楼层
anzyelay 发表于 2015-11-16 17:08
你好,我想问下用stm32F4开发平台实现UVC HOST后接USB摄像头采集图像,然后做图像处理可行吗?

接摄像头没问题,图像处理不清楚

i.MX RT1010 真香


回复

使用道具 举报

21

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2015-12-23 09:55 | 显示全部楼层
楼主用746实现的UVC是用的FS模式还是HS模式?FS模式的话我这边从摄像头获取的端点描述符中最大端点大小是1020Bytes, 同步传输时1ms传输一个packet的话速率最高1020*1000B/s=996KB/s基本达到FS的总带宽了(12Mbit/s).
但是在用746的HS模式的时候746的OTG_HCCHAR寄存器的MPSIZ只有11位也就是一个packet最大2047字节。而从摄像头获取的Ep描述符来看最大的端点有5KB大小。如果用2047来算的话同步传输带宽最大也只有2047*8*1000≈16MB/s?看到OTG_HCCHAR有个MCNT可设置一帧传输3次,这样的话倒是基本能占满HS的带宽,但没实际测试过是否可行。以上不知道我的理解有没有问题。
另外HS模式默认是使用DMA传输数据,DMA传输时都是传输已知量的数据,而对于摄像头同步传输在采集视频流的时候我们无法确定一次能从摄像头接收多少数据,这个时候该怎么处理,请教一下楼主

点评

HS模式 摄像头上面包大小是可以设置的,选个比f7小的就行。 在一个微帧里面,可以启动多次同步传输,这样可以速度更快,我的驱动里面没有这样做,毕竟这个驱动是做着玩的,并没有实际项目需要用这个。 DMA我不知  详情 回复 发表于 2015-12-23 11:39

回复

使用道具 举报

671

TA的帖子

3

TA的资源

版主

Rank: 6Rank: 6

 楼主| 发表于 2015-12-23 11:39 | 显示全部楼层
xijiele 发表于 2015-12-23 09:55
楼主用746实现的UVC是用的FS模式还是HS模式?FS模式的话我这边从摄像头获取的端点描述符中最大端点大小是10 ...

HS模式
摄像头上面包大小是可以设置的,选个比f7小的就行。
在一个微帧里面,可以启动多次同步传输,这样可以速度更快,我的驱动里面没有这样做,毕竟这个驱动是做着玩的,并没有实际项目需要用这个。
DMA我不知道,这个dwcotg自带DMA的把,好像高速模式必须启动内部dma的,不能手工搬运,至于数据长度,是有一个寄存器指定的,传输完成后,读一下寄存器就知道了

点评

重新看了下ST的HCD驱动里的HCD_HC_IN_IRQHandler,昨晚眼花了,确实可以通过寄存器读到实际DMA传输的数据量 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_XFRC) { if (hhcd->Init.dma_enable  详情 回复 发表于 2015-12-23 12:01

i.MX RT1010 真香


回复

使用道具 举报

21

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2015-12-23 12:01 | 显示全部楼层
le062 发表于 2015-12-23 11:39
HS模式
摄像头上面包大小是可以设置的,选个比f7小的就行。
在一个微帧里面,可以启动多次同步传输,这 ...

重新看了下ST的HCD驱动里的HCD_HC_IN_IRQHandler,昨晚眼花了,确实可以通过寄存器读到实际DMA传输的数据量
else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_XFRC)
  {
   
    if (hhcd->Init.dma_enable)
    {
      hhcd->hc[chnum].xfer_count = hhcd->hc[chnum].xfer_len - \
                               (USBx_HC(chnum)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ);
    }
    。。。。
}
今天再试试

回复

使用道具 举报

5

TA的帖子

1

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2016-1-7 10:31 | 显示全部楼层
gdcwj2012 发表于 2015-10-16 10:04
Hi,le062,这两天一直根据您的帖子学习UVC枚举。我是在stm32F2系列芯片上实现UVC host驱动,接一个USB摄像 ...

兄弟,我跟你的情况一样,现在也是要用F4系列的芯片上实现连接一个USB摄像头获取视频,现在是一头雾水,能不能把你的代码让我学习一下!万分感激。。。(wuxianghua1988@126.com

回复

使用道具 举报

3

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2016-7-13 11:33 | 显示全部楼层
和马克思握手 发表于 2016-1-7 10:31
兄弟,我跟你的情况一样,现在也是要用F4系列的芯片上实现连接一个USB摄像头获取视频,现在是一头雾水,能 ...

你好。相同的内容啊。STM32F407通过USB Host驱动一个USB摄像头然后将数据上传。哥们,搞到哪一步了

回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2016-8-2 10:05 | 显示全部楼层
qscdianzhi 发表于 2016-7-13 11:33
你好。相同的内容啊。STM32F407通过USB Host驱动一个USB摄像头然后将数据上传。哥们,搞到哪一步了

你好,你用407驱动uvc摄像头,做的怎么样了,能不能给点思路

回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2016-11-21 14:08 | 显示全部楼层
le062 发表于 2015-10-16 12:25
usb这上面的麻烦很大的
我建议你使用st的usb驱动程序

我可以把uvc部分的简单驱动逻辑发给你


在 ...

大神 我也想用F4的板子做一个UVC的主机  能否把资料也发我一份呢 谢谢 360101770@qq.com

点评

https://github.com/versaloon/vsf/tree/master/vsf/example/vsfusbh/proj/EWARM7.40_STM32F746G https://github.com/versaloon/vsf/tree/master/vsf/stack/usb/class/host/UVC 原来的工程没了,相关代码还在。  详情 回复 发表于 2016-11-22 19:23

回复

使用道具 举报

671

TA的帖子

3

TA的资源

版主

Rank: 6Rank: 6

 楼主| 发表于 2016-11-22 19:23 | 显示全部楼层
独自等待1 发表于 2016-11-21 14:08
大神 我也想用F4的板子做一个UVC的主机  能否把资料也发我一份呢 谢谢

https://github.com/versaloon/vsf ... WARM7.40_STM32F746G
https://github.com/versaloon/vsf ... /usb/class/host/UVC

原来的工程没了,相关代码还在。已全部开源

i.MX RT1010 真香


回复

使用道具 举报

6

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2016-12-2 16:52 | 显示全部楼层
还是下不来???

回复

使用道具 举报

3

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2018-5-18 14:15 | 显示全部楼层
楼主你好,
https://github.com/versaloon/vsf ... WARM7.40_STM32F746G
https://github.com/versaloon/vsf ... /usb/class/host/UVC
这个两个链接失效了。
d881_all.usb你的使用LeCroy USB trace版本的是多少。我使用Software Version 2.15, Build 358 。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

关闭

站长推荐上一条 1/4 下一条

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

Archiver|手机版|小黑屋|电子工程世界 ( 京ICP证 060456 )

GMT+8, 2020-6-4 15:18 , Processed in 0.644646 second(s), 42 queries , Gzip On, MemCache On.

快速回复 返回顶部 返回列表