sakimisu 2 лет назад
Родитель
Сommit
1a7259649b
2 измененных файлов с 77 добавлено и 24 удалено
  1. 73 19
      class/video/usbh_video.c
  2. 4 5
      class/video/usbh_video.h

+ 73 - 19
class/video/usbh_video.c

@@ -53,32 +53,45 @@ static void usbh_video_class_free(struct usbh_video *video_class)
     memset(video_class, 0, sizeof(struct usbh_video));
 }
 
-int usbh_video_get_cur(struct usbh_video *video_class, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len)
+int usbh_video_get(struct usbh_video *video_class, uint8_t request, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len)
 {
     struct usb_setup_packet *setup = video_class->hport->setup;
     int ret;
+    uint8_t retry;
 
     setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
-    setup->bRequest = VIDEO_REQUEST_GET_CUR;
+    setup->bRequest = request;
     setup->wValue = cs << 8;
     setup->wIndex = (entity_id << 8) | intf;
     setup->wLength = len;
 
-    ret = usbh_control_transfer(video_class->hport->ep0, setup, g_video_buf);
-    if (ret < 0) {
-        return ret;
+    retry = 0;
+    while (1) {
+        ret = usbh_control_transfer(video_class->hport->ep0, setup, g_video_buf);
+        if (ret > 0) {
+            break;
+        }
+        retry++;
+
+        if (retry == 3) {
+            return ret;
+        }
+    }
+
+    if (buf) {
+        memcpy(buf, g_video_buf, len);
     }
-    memcpy(buf, g_video_buf, len);
+
     return ret;
 }
 
-int usbh_video_set_cur(struct usbh_video *video_class, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len)
+int usbh_video_set(struct usbh_video *video_class, uint8_t request, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len)
 {
     struct usb_setup_packet *setup = video_class->hport->setup;
     int ret;
 
     setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
-    setup->bRequest = VIDEO_REQUEST_SET_CUR;
+    setup->bRequest = request;
     setup->wValue = cs << 8;
     setup->wIndex = (entity_id << 8) | intf;
     setup->wLength = len;
@@ -86,13 +99,13 @@ int usbh_video_set_cur(struct usbh_video *video_class, uint8_t intf, uint8_t ent
     memcpy(g_video_buf, buf, len);
 
     ret = usbh_control_transfer(video_class->hport->ep0, setup, g_video_buf);
-    usb_osal_msleep(5);
+    usb_osal_msleep(50);
     return ret;
 }
 
 int usbh_videostreaming_get_cur_probe(struct usbh_video *video_class)
 {
-    return usbh_video_get_cur(video_class, video_class->data_intf, 0x00, VIDEO_VS_PROBE_CONTROL, (uint8_t *)&video_class->probe, 26);
+    return usbh_video_get(video_class, VIDEO_REQUEST_GET_CUR, video_class->data_intf, 0x00, VIDEO_VS_PROBE_CONTROL, (uint8_t *)&video_class->probe, 26);
 }
 
 int usbh_videostreaming_set_cur_probe(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex)
@@ -100,7 +113,8 @@ int usbh_videostreaming_set_cur_probe(struct usbh_video *video_class, uint8_t fo
     video_class->probe.bFormatIndex = formatindex;
     video_class->probe.bFrameIndex = frameindex;
     video_class->probe.dwMaxPayloadTransferSize = 0;
-    return usbh_video_set_cur(video_class, video_class->data_intf, 0x00, VIDEO_VS_PROBE_CONTROL, (uint8_t *)&video_class->probe, 26);
+    video_class->probe.dwFrameInterval = 333333;
+    return usbh_video_set(video_class, VIDEO_REQUEST_SET_CUR, video_class->data_intf, 0x00, VIDEO_VS_PROBE_CONTROL, (uint8_t *)&video_class->probe, 26);
 }
 
 int usbh_videostreaming_set_cur_commit(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex)
@@ -108,7 +122,8 @@ int usbh_videostreaming_set_cur_commit(struct usbh_video *video_class, uint8_t f
     memcpy(&video_class->commit, &video_class->probe, sizeof(struct video_probe_and_commit_controls));
     video_class->commit.bFormatIndex = formatindex;
     video_class->commit.bFrameIndex = frameindex;
-    return usbh_video_set_cur(video_class, video_class->data_intf, 0x00, VIDEO_VS_COMMIT_CONTROL, (uint8_t *)&video_class->commit, 26);
+    video_class->commit.dwFrameInterval = 333333;
+    return usbh_video_set(video_class, VIDEO_REQUEST_SET_CUR, video_class->data_intf, 0x00, VIDEO_VS_COMMIT_CONTROL, (uint8_t *)&video_class->commit, 26);
 }
 
 int usbh_video_open(struct usbh_video *video_class,
@@ -125,6 +140,7 @@ int usbh_video_open(struct usbh_video *video_class,
     bool found = false;
     uint8_t formatidx = 0;
     uint8_t frameidx = 0;
+    uint8_t step;
 
     if (video_class->is_opened) {
         return -EMFILE;
@@ -152,31 +168,65 @@ int usbh_video_open(struct usbh_video *video_class,
         return -EINVAL;
     }
 
+    /* Open video step:
+     * Get CUR request (probe)
+     * Set CUR request (probe)
+     * Get CUR request (probe)
+     * Get MAX request (probe)
+     * Get MIN request (probe)
+     * Get CUR request (probe)
+     * Set CUR request (commit)
+     *    
+    */
+    step = 0;
     ret = usbh_videostreaming_get_cur_probe(video_class);
     if (ret < 0) {
-        return ret;
+        goto errout;
     }
+
+    step = 1;
     ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx);
     if (ret < 0) {
-        return ret;
+        goto errout;
     }
+
+    step = 2;
     ret = usbh_videostreaming_get_cur_probe(video_class);
     if (ret < 0) {
-        return ret;
+        goto errout;
     }
+
+    step = 3;
+    ret = usbh_video_get(video_class, VIDEO_REQUEST_GET_MAX, video_class->data_intf, 0x00, VIDEO_VS_PROBE_CONTROL, NULL, 26);
+    if (ret < 0) {
+        goto errout;
+    }
+
+    step = 4;
+    ret = usbh_video_get(video_class, VIDEO_REQUEST_GET_MIN, video_class->data_intf, 0x00, VIDEO_VS_PROBE_CONTROL, NULL, 26);
+    if (ret < 0) {
+        goto errout;
+    }
+
+    step = 5;
     ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx);
     if (ret < 0) {
-        return ret;
+        goto errout;
     }
+
+    step = 6;
     ret = usbh_videostreaming_get_cur_probe(video_class);
     if (ret < 0) {
-        return ret;
+        goto errout;
     }
+
+    step = 7;
     ret = usbh_videostreaming_set_cur_commit(video_class, formatidx, frameidx);
     if (ret < 0) {
-        return ret;
+        goto errout;
     }
 
+    step = 8;
     setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE;
     setup->bRequest = USB_REQUEST_SET_INTERFACE;
     setup->wValue = altsetting;
@@ -185,7 +235,7 @@ int usbh_video_open(struct usbh_video *video_class,
 
     ret = usbh_control_transfer(video_class->hport->ep0, setup, NULL);
     if (ret < 0) {
-        return ret;
+        goto errout;
     }
 
     ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[altsetting].ep[0].ep_desc;
@@ -203,6 +253,10 @@ int usbh_video_open(struct usbh_video *video_class,
     video_class->is_opened = true;
     video_class->current_format = format_type;
     return ret;
+
+errout:
+    USB_LOG_ERR("Fail to open video in step %u\r\n", step);
+    return ret;
 }
 
 int usbh_video_close(struct usbh_video *video_class)

+ 4 - 5
class/video/usbh_video.h

@@ -25,6 +25,8 @@ struct usbh_video_format {
 struct usbh_videostreaming {
     uint32_t bufoffset;
     uint32_t buflen;
+    uint16_t width;
+    uint16_t heigth;
     void (*video_one_frame_callback)(struct usbh_videostreaming *stream);
 };
 
@@ -52,11 +54,8 @@ struct usbh_video {
 extern "C" {
 #endif
 
-int usbh_video_get_cur(struct usbh_video *video_class, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len);
-int usbh_video_set_cur(struct usbh_video *video_class, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len);
-int usbh_videostreaming_get_cur_probe(struct usbh_video *video_class);
-int usbh_videostreaming_set_cur_probe(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex);
-int usbh_videostreaming_set_cur_commit(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex);
+int usbh_video_get_cur(struct usbh_video *video_class, uint8_t request, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len);
+int usbh_video_set_cur(struct usbh_video *video_class, uint8_t request, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len);
 
 int usbh_video_open(struct usbh_video *video_class,
                     uint8_t format_type,