Skip to content

Commit e754e06

Browse files
author
Josuah Demangeon
committed
samples: usb: uvc_uvb: connecting USB device to host via UVB
Add a sample to experiment the USB Video Class host support by using the existing Zephyr USB Video Class device support. This allows running implementing the host side from the device side. Signed-off-by: Josuah Demangeon <[email protected]>
1 parent 05ffa1c commit e754e06

File tree

9 files changed

+267
-0
lines changed

9 files changed

+267
-0
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.20.0)
4+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
5+
project(uvc_uvb)
6+
7+
# This sample cannot use the common USB sample infrastructure as we do not want
8+
# to initialize the board default `zephyr_udc0` but instead an unrelated `virtual_udc0`.
9+
#include(${ZEPHYR_BASE}/samples/subsys/usb/common/common.cmake)
10+
11+
FILE(GLOB app_sources src/*.c)
12+
target_sources(app PRIVATE ${app_sources})
13+
zephyr_include_directories(${ZEPHYR_BASE}/subsys/usb/host)

samples/subsys/usb/uvc_uvb/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Copyright The Zephyr Project Contributors
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
# Source common USB sample options used to initialize new experimental USB
5+
# device stack. The scope of these options is limited to USB samples in project
6+
# tree, you cannot use them in your own application.
7+
source "samples/subsys/usb/common/Kconfig.sample_usbd"
8+
9+
source "Kconfig.zephyr"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Zephyr UVC Host Testbench
2+
3+
This repo is there to experiment with UVC Host support in Zephyr.
4+
5+
Uses the USB Virtual Bus to connect the virtual USB host to the virtual USB device together.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/ {
8+
virtual_uhc0: uhc-virtual {
9+
compatible = "zephyr,uhc-virtual";
10+
maximum-speed = "full-speed";
11+
12+
virtual_udc0: udc-virtual {
13+
compatible = "zephyr,udc-virtual";
14+
num-bidir-endpoints = <4>;
15+
maximum-speed = "full-speed";
16+
17+
uvc_device: uvc-device {
18+
compatible = "zephyr,uvc-device";
19+
};
20+
};
21+
};
22+
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
CONFIG_LOG=y
2+
CONFIG_UDC_DRIVER_LOG_LEVEL_INF=y
3+
CONFIG_UHC_DRIVER_LOG_LEVEL_INF=y
4+
CONFIG_USBD_VIDEO_CLASS=y
5+
CONFIG_USBD_VIDEO_LOG_LEVEL_INF=y
6+
CONFIG_USBH_LOG_LEVEL_INF=y
7+
CONFIG_USB_DEVICE_STACK_NEXT=y
8+
CONFIG_USB_HOST_STACK=y
9+
CONFIG_UVB_LOG_LEVEL_INF=y
10+
CONFIG_VIDEO=y
11+
CONFIG_VIDEO_LOG_LEVEL_INF=y
12+
CONFIG_UDC_BUF_POOL_SIZE=2048
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef NORDIC_USBH_TESTS_APP_H
8+
#define NORDIC_USBH_TESTS_APP_H
9+
10+
#include <stdint.h>
11+
#include <zephyr/usb/usbd.h>
12+
#include <zephyr/usb/usbh.h>
13+
14+
struct usbh_contex *app_usbh_init_controller(void);
15+
16+
#endif /* NORDIC_USBH_TESTS_APP_H */
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/device.h>
8+
#include <zephyr/logging/log.h>
9+
#include <zephyr/usb/usbd.h>
10+
#include <zephyr/usb/usbh.h>
11+
#include <zephyr/usb/class/usbd_uvc.h>
12+
13+
#include "usbh_device.h"
14+
#include "usbh_ch9.h"
15+
#include "usbh_class.h"
16+
17+
LOG_MODULE_REGISTER(app_main, LOG_LEVEL_INF);
18+
19+
#include "app.h"
20+
21+
#define APP_USBH_CLASS_DESC_MAX_SIZE 512
22+
23+
/*
24+
* This is expected to be located in the USB host subsystem, but in the meantime
25+
* that this becomes implemented, it is implemented locally here in the sample
26+
* to allow pursuing the implementation of the UVC host class.
27+
*/
28+
int usbh_class_init(struct usb_device *udev)
29+
{
30+
const size_t len = APP_USBH_CLASS_DESC_MAX_SIZE;
31+
struct net_buf *buf;
32+
int ret;
33+
34+
buf = usbh_xfer_buf_alloc(udev, len);
35+
if (buf == NULL) {
36+
LOG_ERR("Failed to allocate a host transfer buffer");
37+
return -ENOMEM;
38+
}
39+
40+
ret = usbh_req_desc(udev, USB_DESC_DEVICE, 0, 0, len, buf);
41+
if (ret != 0) {
42+
LOG_ERR("Failed to request descriptor");
43+
return ret;
44+
}
45+
46+
LOG_HEXDUMP_INF(buf->data, buf->len, "buf");
47+
48+
return 0;
49+
}
50+
51+
const struct device *const uvc_dev = DEVICE_DT_GET(DT_NODELABEL(uvc_device));
52+
const struct device *const video_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_camera));
53+
54+
int main(void)
55+
{
56+
struct usbd_context *app_usbd;
57+
struct usbh_contex *app_usbh;
58+
int ret;
59+
60+
uvc_set_video_dev(uvc_dev, video_dev);
61+
62+
/* Enable the virtual USB device and virtual USB host so they can
63+
* communicate together via UVB.
64+
*/
65+
66+
app_usbd = app_usbd_init_device();
67+
if (app_usbd == NULL) {
68+
LOG_ERR("Failed to initialize USB Device contexts");
69+
return 0;
70+
}
71+
72+
app_usbh = app_usbh_init_controller();
73+
if (app_usbh == NULL) {
74+
LOG_ERR("Failed to initialize USB Host controller");
75+
return 0;
76+
}
77+
78+
ret = usbh_enable(app_usbh);
79+
if (ret != 0) {
80+
LOG_ERR("Failed to enable USB Host");
81+
return 0;
82+
}
83+
84+
ret = usbd_enable(app_usbd);
85+
if (ret != 0) {
86+
LOG_ERR("Failed to enable USB Device");
87+
return 0;
88+
}
89+
90+
return 0;
91+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <stdint.h>
8+
9+
#include <zephyr/device.h>
10+
#include <zephyr/usb/usbd.h>
11+
#include <zephyr/logging/log.h>
12+
13+
LOG_MODULE_REGISTER(usbd_app_config, CONFIG_LOG_DEFAULT_LEVEL);
14+
15+
USBD_DEVICE_DEFINE(app_usbd, DEVICE_DT_GET(DT_NODELABEL(virtual_udc0)), 0x2fe3, 0x9999);
16+
USBD_DESC_LANG_DEFINE(app_lang);
17+
USBD_DESC_MANUFACTURER_DEFINE(app_mfr, "Nordic");
18+
USBD_DESC_PRODUCT_DEFINE(app_product, "Virtual UVC device");
19+
USBD_DESC_CONFIG_DEFINE(fs_cfg_desc, "FS Configuration");
20+
USBD_CONFIGURATION_DEFINE(app_fs_config, 0, 200, &fs_cfg_desc);
21+
22+
/* This is a minimal as possible configuration for the purpose of providing
23+
* a temporary test bench, and does not support all the configurations of the
24+
* sample USB config. Notably, only FullSpeed support
25+
*/
26+
27+
struct usbd_context *app_usbd_init_device(void)
28+
{
29+
int ret;
30+
31+
ret = usbd_add_descriptor(&app_usbd, &app_lang);
32+
if (ret != 0) {
33+
LOG_ERR("Failed to initialize language descriptor (%d)", ret);
34+
return NULL;
35+
}
36+
37+
ret = usbd_add_descriptor(&app_usbd, &app_mfr);
38+
if (ret != 0) {
39+
LOG_ERR("Failed to initialize manufacturer descriptor (%d)", ret);
40+
return NULL;
41+
}
42+
43+
ret = usbd_add_descriptor(&app_usbd, &app_product);
44+
if (ret != 0) {
45+
LOG_ERR("Failed to initialize product descriptor (%d)", ret);
46+
return NULL;
47+
}
48+
49+
ret = usbd_add_configuration(&app_usbd, USBD_SPEED_FS, &app_fs_config);
50+
if (ret != 0) {
51+
LOG_ERR("Failed to add Full-Speed configuration");
52+
return NULL;
53+
}
54+
55+
ret = usbd_register_all_classes(&app_usbd, USBD_SPEED_FS, 1, NULL);
56+
if (ret != 0) {
57+
LOG_ERR("Failed to add register classes");
58+
return NULL;
59+
}
60+
61+
usbd_device_set_code_triple(&app_usbd, USBD_SPEED_FS, USB_BCC_MISCELLANEOUS, 0x02, 0x01);
62+
63+
usbd_self_powered(&app_usbd, USB_SCD_SELF_POWERED);
64+
65+
ret = usbd_init(&app_usbd);
66+
if (ret != 0) {
67+
LOG_ERR("Failed to initialize device support");
68+
return NULL;
69+
}
70+
71+
return &app_usbd;
72+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/device.h>
8+
#include <zephyr/usb/usbh.h>
9+
10+
#include <zephyr/logging/log.h>
11+
LOG_MODULE_REGISTER(usbh_app_config);
12+
13+
USBH_CONTROLLER_DEFINE(app_usbh,
14+
DEVICE_DT_GET(DT_NODELABEL(virtual_uhc0)));
15+
16+
struct usbh_contex *app_usbh_init_controller(void)
17+
{
18+
int err;
19+
20+
err = usbh_init(&app_usbh);
21+
if (err) {
22+
LOG_ERR("Failed to initialize host support");
23+
return NULL;
24+
}
25+
26+
return &app_usbh;
27+
}

0 commit comments

Comments
 (0)