Skip to content

Commit 7de7359

Browse files
jfischer-notmon-nordic
authored andcommitted
[nrf fromtree] usb: device_next: allow CDC ACM UART to be initialized and enabled at boot
There are some boards and samples in the tree that use the CDC ACM UART as the default serial backend, just like a real UART controller would. The new device stack requires more detailed configuration than the old one. In order to use the CDC ACM UART as the serial backend with the new device stack in the same way as with the legacy stack, we need to provide a solution to initialise and enable the CDC ACM UART at boot time. We cannot use snippets as they do not support Kconfig files or source code. Shields would be an option, but they cannot be used for virtual devices such as the CDC ACM UART. The remaining solution is to put the code and Kconfig file for it in the subsys directory. Allow CDC ACM UART instance and USB device stack to be initialized and enabled at boot time and to use it as serial backend for logging or shell. Signed-off-by: Johann Fischer <[email protected]> (cherry picked from commit 7ffa620) Signed-off-by: Tomasz Moń <[email protected]>
1 parent 56cfdce commit 7de7359

File tree

6 files changed

+196
-0
lines changed

6 files changed

+196
-0
lines changed

subsys/usb/device_next/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ zephyr_library_sources(
1717
usbd_msg.c
1818
)
1919

20+
add_subdirectory(app)
21+
2022
zephyr_library_sources_ifdef(
2123
CONFIG_USBD_SHELL
2224
usbd_shell.c

subsys/usb/device_next/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,6 @@ config USBD_MSG_WORK_DELAY
5656
yet ready to publish the message. The delay unit is milliseconds.
5757

5858
rsource "class/Kconfig"
59+
rsource "app/Kconfig.cdc_acm_serial"
5960

6061
endif # USB_DEVICE_STACK_NEXT
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Copyright (c) 2024 Nordic Semiconductor ASA
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
zephyr_sources_ifdef(CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT cdc_acm_serial.c)
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Copyright (c) 2024 Nordic Semiconductor ASA
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
# This file contains Kconfig options and defaults for configuring the USB
5+
# device stack and CDC ACM instance to be used as the default serial backend
6+
# for logging or shell.
7+
8+
9+
menuconfig CDC_ACM_SERIAL_INITIALIZE_AT_BOOT
10+
bool "Initialize USB device and CDC ACM UART at boot"
11+
depends on USBD_CDC_ACM_CLASS
12+
help
13+
This is intended for use with cdc-acm-snippet or as a default serial
14+
backend only in applications where no other USB features are
15+
required, configured, and enabled.
16+
17+
if CDC_ACM_SERIAL_INITIALIZE_AT_BOOT
18+
19+
config CDC_ACM_SERIAL_MANUFACTURER_STRING
20+
string "USB device manufacturer string descriptor"
21+
default "Zephyr Project"
22+
help
23+
USB device manufacturer string descriptor.
24+
25+
config CDC_ACM_SERIAL_PRODUCT_STRING
26+
string "USB device product string descriptor"
27+
default "CDC ACM serial backend"
28+
help
29+
USB device product string descriptor.
30+
31+
config CDC_ACM_SERIAL_VID
32+
hex "USB device Vendor ID"
33+
default 0x2fe3
34+
help
35+
You must use your own VID for samples and applications outside of
36+
Zephyr Project.
37+
38+
config CDC_ACM_SERIAL_PID
39+
hex "USB device Product ID"
40+
default 0x0004
41+
help
42+
You must use your own PID for samples and applications outside of
43+
Zephyr Project.
44+
45+
config CDC_ACM_SERIAL_SELF_POWERED
46+
bool "USB device Self-powered attribute"
47+
help
48+
Set the Self-powered attribute in the configuration.
49+
50+
config CDC_ACM_SERIAL_MAX_POWER
51+
int "USB device bMaxPower value"
52+
default 125
53+
range 0 250
54+
help
55+
bMaxPower value in the configuration in 2 mA units.
56+
57+
endif #CDC_ACM_SERIAL_INITIALIZE_AT_BOOT
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/*
2+
* Copyright (c) 2024 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <stdint.h>
8+
9+
#include <zephyr/init.h>
10+
#include <zephyr/kernel.h>
11+
#include <zephyr/device.h>
12+
#include <zephyr/usb/usbd.h>
13+
14+
#include <zephyr/logging/log.h>
15+
LOG_MODULE_REGISTER(cdc_acm_serial, LOG_LEVEL_DBG);
16+
17+
/*
18+
* This is intended for use with cdc-acm-snippet or as a default serial backend
19+
* only in applications where no other USB features are required, configured,
20+
* and enabled. This code only registers the first CDC-ACM instance.
21+
*/
22+
23+
USBD_DEVICE_DEFINE(cdc_acm_serial,
24+
DEVICE_DT_GET(DT_NODELABEL(zephyr_udc0)),
25+
CONFIG_CDC_ACM_SERIAL_VID, CONFIG_CDC_ACM_SERIAL_PID);
26+
27+
USBD_DESC_LANG_DEFINE(cdc_acm_serial_lang);
28+
USBD_DESC_MANUFACTURER_DEFINE(cdc_acm_serial_mfr, CONFIG_CDC_ACM_SERIAL_MANUFACTURER_STRING);
29+
USBD_DESC_PRODUCT_DEFINE(cdc_acm_serial_product, CONFIG_CDC_ACM_SERIAL_PRODUCT_STRING);
30+
USBD_DESC_SERIAL_NUMBER_DEFINE(cdc_acm_serial_sn);
31+
32+
USBD_DESC_CONFIG_DEFINE(fs_cfg_desc, "FS Configuration");
33+
USBD_DESC_CONFIG_DEFINE(hs_cfg_desc, "HS Configuration");
34+
35+
static const uint8_t attributes = IS_ENABLED(CONFIG_CDC_ACM_SERIAL_SELF_POWERED) ?
36+
USB_SCD_SELF_POWERED : 0;
37+
38+
USBD_CONFIGURATION_DEFINE(cdc_acm_serial_fs_config,
39+
attributes,
40+
CONFIG_CDC_ACM_SERIAL_MAX_POWER, &fs_cfg_desc);
41+
42+
USBD_CONFIGURATION_DEFINE(cdc_acm_serial_hs_config,
43+
attributes,
44+
CONFIG_CDC_ACM_SERIAL_MAX_POWER, &hs_cfg_desc);
45+
46+
47+
static int register_cdc_acm_0(struct usbd_context *const uds_ctx,
48+
const enum usbd_speed speed)
49+
{
50+
struct usbd_config_node *cfg_nd;
51+
int err;
52+
53+
if (speed == USBD_SPEED_HS) {
54+
cfg_nd = &cdc_acm_serial_hs_config;
55+
} else {
56+
cfg_nd = &cdc_acm_serial_fs_config;
57+
}
58+
59+
err = usbd_add_configuration(uds_ctx, speed, cfg_nd);
60+
if (err) {
61+
LOG_ERR("Failed to add configuration");
62+
return err;
63+
}
64+
65+
err = usbd_register_class(&cdc_acm_serial, "cdc_acm_0", speed, 1);
66+
if (err) {
67+
LOG_ERR("Failed to register classes");
68+
return err;
69+
}
70+
71+
return usbd_device_set_code_triple(uds_ctx, speed,
72+
USB_BCC_MISCELLANEOUS, 0x02, 0x01);
73+
}
74+
75+
76+
static int cdc_acm_serial_init_device(void)
77+
{
78+
int err;
79+
80+
err = usbd_add_descriptor(&cdc_acm_serial, &cdc_acm_serial_lang);
81+
if (err) {
82+
LOG_ERR("Failed to initialize language descriptor (%d)", err);
83+
return err;
84+
}
85+
86+
err = usbd_add_descriptor(&cdc_acm_serial, &cdc_acm_serial_mfr);
87+
if (err) {
88+
LOG_ERR("Failed to initialize manufacturer descriptor (%d)", err);
89+
return err;
90+
}
91+
92+
err = usbd_add_descriptor(&cdc_acm_serial, &cdc_acm_serial_product);
93+
if (err) {
94+
LOG_ERR("Failed to initialize product descriptor (%d)", err);
95+
return err;
96+
}
97+
98+
err = usbd_add_descriptor(&cdc_acm_serial, &cdc_acm_serial_sn);
99+
if (err) {
100+
LOG_ERR("Failed to initialize SN descriptor (%d)", err);
101+
return err;
102+
}
103+
104+
if (usbd_caps_speed(&cdc_acm_serial) == USBD_SPEED_HS) {
105+
err = register_cdc_acm_0(&cdc_acm_serial, USBD_SPEED_HS);
106+
if (err) {
107+
return err;
108+
}
109+
}
110+
111+
err = register_cdc_acm_0(&cdc_acm_serial, USBD_SPEED_FS);
112+
if (err) {
113+
return err;
114+
}
115+
116+
err = usbd_init(&cdc_acm_serial);
117+
if (err) {
118+
LOG_ERR("Failed to initialize device support");
119+
return err;
120+
}
121+
122+
err = usbd_enable(&cdc_acm_serial);
123+
if (err) {
124+
LOG_ERR("Failed to enable device support");
125+
return err;
126+
}
127+
128+
return 0;
129+
}
130+
131+
SYS_INIT(cdc_acm_serial_init_device, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);

subsys/usb/device_next/class/Kconfig.cdc_acm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ config USBD_CDC_ACM_CLASS
1010
select SERIAL_SUPPORT_INTERRUPT
1111
select RING_BUFFER
1212
select UART_INTERRUPT_DRIVEN
13+
default y
1314
help
1415
USB device CDC ACM class implementation.
1516

0 commit comments

Comments
 (0)