zephyr/samples/subsys/usb/common/sample_usbd_init.c
Johann Fischer b00a998cf1 samples: usb: add common USB device instantiation and initialization
There is common code for the new USB device support in the samples to
instantiate USB device, descriptors, configuration and initialize USB
device. Add common code that can be used for the simple usecase with a
single USB device and single configuration.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2023-12-13 17:52:00 +01:00

103 lines
2.7 KiB
C

/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <zephyr/device.h>
#include <zephyr/usb/usbd.h>
#include <zephyr/sys/iterable_sections.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(usbd_sample_config);
#define ZEPHYR_PROJECT_USB_VID 0x2fe3
USBD_DEVICE_DEFINE(sample_usbd,
DEVICE_DT_GET(DT_NODELABEL(zephyr_udc0)),
ZEPHYR_PROJECT_USB_VID, CONFIG_SAMPLE_USBD_PID);
USBD_DESC_LANG_DEFINE(sample_lang);
USBD_DESC_MANUFACTURER_DEFINE(sample_mfr, CONFIG_SAMPLE_USBD_MANUFACTURER);
USBD_DESC_PRODUCT_DEFINE(sample_product, CONFIG_SAMPLE_USBD_PRODUCT);
USBD_DESC_SERIAL_NUMBER_DEFINE(sample_sn, "0123456789ABCDEF");
static const uint8_t attributes = (IS_ENABLED(CONFIG_SAMPLE_USBD_SELF_POWERED) ?
USB_SCD_SELF_POWERED : 0) |
(IS_ENABLED(CONFIG_SAMPLE_USBD_REMOTE_WAKEUP) ?
USB_SCD_REMOTE_WAKEUP : 0);
USBD_CONFIGURATION_DEFINE(sample_config,
attributes,
CONFIG_SAMPLE_USBD_MAX_POWER);
struct usbd_contex *sample_usbd_init_device(void)
{
int err;
err = usbd_add_descriptor(&sample_usbd, &sample_lang);
if (err) {
LOG_ERR("Failed to initialize language descriptor (%d)", err);
return NULL;
}
err = usbd_add_descriptor(&sample_usbd, &sample_mfr);
if (err) {
LOG_ERR("Failed to initialize manufacturer descriptor (%d)", err);
return NULL;
}
err = usbd_add_descriptor(&sample_usbd, &sample_product);
if (err) {
LOG_ERR("Failed to initialize product descriptor (%d)", err);
return NULL;
}
err = usbd_add_descriptor(&sample_usbd, &sample_sn);
if (err) {
LOG_ERR("Failed to initialize SN descriptor (%d)", err);
return NULL;
}
err = usbd_add_configuration(&sample_usbd, &sample_config);
if (err) {
LOG_ERR("Failed to add configuration (%d)", err);
return NULL;
}
STRUCT_SECTION_FOREACH(usbd_class_node, node) {
/* Pull everything that is enabled in our configuration. */
err = usbd_register_class(&sample_usbd, node->name, 1);
if (err) {
LOG_ERR("Failed to register %s (%d)", node->name, err);
return NULL;
}
LOG_DBG("Register %s", node->name);
}
/* Always use class code information from Interface Descriptors */
if (IS_ENABLED(CONFIG_USBD_CDC_ACM_CLASS) ||
IS_ENABLED(CONFIG_USBD_CDC_ECM_CLASS)) {
/*
* Class with multiple interfaces have an Interface
* Association Descriptor available, use an appropriate triple
* to indicate it.
*/
usbd_device_set_code_triple(&sample_usbd,
USB_BCC_MISCELLANEOUS, 0x02, 0x01);
} else {
usbd_device_set_code_triple(&sample_usbd, 0, 0, 0);
}
err = usbd_init(&sample_usbd);
if (err) {
LOG_ERR("Failed to initialize device support");
return NULL;
}
return &sample_usbd;
}