Skip to content

Commit 31ccd03

Browse files
committed
applications: nrf_desktop: Integrate USB next stack
Change integrates USB next stack to the application. Jira: NCSDK-27014 Signed-off-by: Marek Pieta <Marek.Pieta@nordicsemi.no>
1 parent 3bf639d commit 31ccd03

File tree

1 file changed

+240
-3
lines changed

1 file changed

+240
-3
lines changed

applications/nrf_desktop/src/modules/usb_state.c

Lines changed: 240 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,15 @@
66
#include <stdio.h>
77
#include <stdint.h>
88

9+
#include <zephyr/device.h>
10+
#include <zephyr/sys/iterable_sections.h>
911
#include <zephyr/types.h>
1012
#include <zephyr/sys/byteorder.h>
1113
#include <zephyr/sys/util.h>
1214

15+
#include <zephyr/usb/usbd.h>
16+
#include <zephyr/usb/usbd_msg.h>
17+
1318
#include <zephyr/usb/usb_device.h>
1419
#include <zephyr/usb/usb_ch9.h>
1520
#include <zephyr/usb/class/usb_hid.h>
@@ -77,6 +82,8 @@ BUILD_ASSERT(!IS_ENABLED(CONFIG_DESKTOP_HID_STATE_ENABLE) ||
7782
IS_ENABLED(CONFIG_DESKTOP_USB_SELECTIVE_REPORT_SUBSCRIPTION) ||
7883
(ARRAY_SIZE(usb_hid_device) <= 1));
7984

85+
static struct usbd_contex *usbd_ctx;
86+
8087
static struct config_channel_transport cfg_chan_transport;
8188

8289

@@ -480,8 +487,8 @@ static void usb_wakeup(void)
480487
{
481488
int err = 0;
482489

483-
if (IS_ENABLED(CONFIG_DESKTOP_USB_STACK_NEXT)) {
484-
LOG_WRN("usb_wakeup not integrated for USB next");
490+
if (IS_ENABLED(CONFIG_DESKTOP_USB_STACK_NEXT) && usbd_ctx) {
491+
err = usbd_wakeup_request(usbd_ctx);
485492
} else {
486493
__ASSERT_NO_MSG(IS_ENABLED(CONFIG_DESKTOP_USB_STACK_LEGACY));
487494
err = usb_wakeup_request();
@@ -804,6 +811,236 @@ static int usb_init_legacy(void)
804811
return 0;
805812
}
806813

814+
static void usb_init_next_status_cb(struct usbd_contex *const contex,
815+
const struct usbd_msg *const msg)
816+
{
817+
static enum usb_state before_suspend;
818+
enum usb_state new_state = state;
819+
820+
LOG_DBG("USBD msg: %s", usbd_msg_type_string(msg->type));
821+
822+
switch (msg->type) {
823+
case USBD_MSG_VBUS_READY:
824+
if (state != USB_STATE_DISCONNECTED) {
825+
LOG_WRN("USBD_MSG_VBUS_READY while USB is not disconnected");
826+
}
827+
new_state = USB_STATE_POWERED;
828+
break;
829+
830+
case USBD_MSG_VBUS_REMOVED:
831+
new_state = USB_STATE_DISCONNECTED;
832+
break;
833+
834+
case USBD_MSG_RESUME:
835+
if (state == USB_STATE_SUSPENDED) {
836+
new_state = before_suspend;
837+
}
838+
break;
839+
840+
case USBD_MSG_SUSPEND:
841+
before_suspend = state;
842+
new_state = USB_STATE_SUSPENDED;
843+
break;
844+
845+
case USBD_MSG_RESET:
846+
if (state != USB_STATE_DISCONNECTED) {
847+
new_state = USB_STATE_POWERED;
848+
} else {
849+
LOG_WRN("Reset while disconnected");
850+
}
851+
break;
852+
853+
case USBD_MSG_UDC_ERROR:
854+
LOG_ERR("Non-correctable UDC error message");
855+
module_set_state(MODULE_STATE_ERROR);
856+
break;
857+
858+
case USBD_MSG_STACK_ERROR:
859+
LOG_ERR("Unrecoverable USB device stack error");
860+
module_set_state(MODULE_STATE_ERROR);
861+
break;
862+
863+
case USBD_MSG_CDC_ACM_LINE_CODING:
864+
case USBD_MSG_CDC_ACM_CONTROL_LINE_STATE:
865+
/* Ignore */
866+
break;
867+
868+
default:
869+
LOG_ERR("Unexpected USB device message type: %d", msg->type);
870+
break;
871+
}
872+
873+
if (new_state != state) {
874+
broadcast_usb_state(new_state);
875+
state = new_state;
876+
}
877+
}
878+
879+
static int usb_init_next_register_fs_classes(struct usbd_contex *usbd)
880+
{
881+
int err = 0;
882+
883+
STRUCT_SECTION_FOREACH_ALTERNATE(usbd_class_fs, usbd_class_node, c_nd) {
884+
err = usbd_register_class(usbd, c_nd->c_data->name, USBD_SPEED_FS, 1);
885+
if (err) {
886+
LOG_ERR("usbd_register_class failed for %s (err: %d)",
887+
c_nd->c_data->name, err);
888+
return err;
889+
}
890+
}
891+
892+
return err;
893+
}
894+
895+
static int usb_init_next_register_hs_classes(struct usbd_contex *usbd)
896+
{
897+
int err = 0;
898+
899+
STRUCT_SECTION_FOREACH_ALTERNATE(usbd_class_hs, usbd_class_node, c_nd) {
900+
err = usbd_register_class(usbd, c_nd->c_data->name, USBD_SPEED_HS, 1);
901+
if (err) {
902+
LOG_ERR("usbd_register_class failed for %s (err: %d)",
903+
c_nd->c_data->name, err);
904+
return err;
905+
}
906+
}
907+
908+
return err;
909+
}
910+
911+
static int usb_init_next_add_configuration(struct usbd_contex *usbd,
912+
const enum usbd_speed speed,
913+
struct usbd_config_node *config)
914+
{
915+
int err;
916+
917+
err = usbd_add_configuration(usbd, speed, config);
918+
if (err) {
919+
LOG_ERR("usbd_add_configuration failed (err: %d)", err);
920+
return err;
921+
}
922+
923+
if (speed == USBD_SPEED_FS) {
924+
err = usb_init_next_register_fs_classes(usbd);
925+
} else if (speed == USBD_SPEED_HS) {
926+
err = usb_init_next_register_hs_classes(usbd);
927+
}
928+
929+
if (err) {
930+
return err;
931+
}
932+
933+
/* Always use class code information from Interface Descriptors */
934+
if (IS_ENABLED(CONFIG_USBD_CDC_ACM_CLASS)) {
935+
BUILD_ASSERT(!IS_ENABLED(CONFIG_USBD_CDC_ECM_CLASS));
936+
BUILD_ASSERT(!IS_ENABLED(CONFIG_USBD_AUDIO2_CLASS));
937+
/*
938+
* Class with multiple interfaces have an Interface
939+
* Association Descriptor available, use an appropriate triple
940+
* to indicate it.
941+
*/
942+
usbd_device_set_code_triple(usbd, speed, USB_BCC_MISCELLANEOUS, 0x02, 0x01);
943+
} else {
944+
usbd_device_set_code_triple(usbd, speed, 0, 0, 0);
945+
}
946+
947+
return 0;
948+
}
949+
950+
static struct usbd_contex *usb_init_next_usbd_init(void)
951+
{
952+
int err;
953+
954+
USBD_DEVICE_DEFINE(usbd, DEVICE_DT_GET(DT_NODELABEL(usbd)),
955+
CONFIG_DESKTOP_DEVICE_VID, CONFIG_DESKTOP_DEVICE_PID);
956+
957+
USBD_DESC_LANG_DEFINE(lang);
958+
USBD_DESC_MANUFACTURER_DEFINE(manufacturer, CONFIG_DESKTOP_DEVICE_MANUFACTURER);
959+
USBD_DESC_PRODUCT_DEFINE(product, CONFIG_DESKTOP_DEVICE_PRODUCT);
960+
USBD_DESC_SERIAL_NUMBER_DEFINE(serial_number);
961+
962+
/* Maximum power consumption of a device: 250 * 2 mA = 500 mA. */
963+
static const uint8_t max_power = 250;
964+
static const uint8_t attributes = IS_ENABLED(CONFIG_DESKTOP_USB_REMOTE_WAKEUP) ?
965+
(USB_SCD_REMOTE_WAKEUP) : (0);
966+
967+
USBD_CONFIGURATION_DEFINE(fs_config, attributes, max_power);
968+
USBD_CONFIGURATION_DEFINE(hs_config, attributes, max_power);
969+
970+
err = usbd_add_descriptor(&usbd, &lang);
971+
if (err) {
972+
LOG_ERR("usbd_add_descriptor(lang) failed (err: %d)", err);
973+
return NULL;
974+
}
975+
976+
err = usbd_add_descriptor(&usbd, &manufacturer);
977+
if (err) {
978+
LOG_ERR("usbd_add_descriptor(manufacturer) failed (err: %d)", err);
979+
return NULL;
980+
}
981+
982+
err = usbd_add_descriptor(&usbd, &product);
983+
if (err) {
984+
LOG_ERR("usbd_add_descriptor(product) failed (err: %d)", err);
985+
return NULL;
986+
}
987+
988+
err = usbd_add_descriptor(&usbd, &serial_number);
989+
if (err) {
990+
LOG_ERR("usbd_add_descriptor(serial_number) failed (err: %d)", err);
991+
return NULL;
992+
}
993+
994+
if (usbd_caps_speed(&usbd) == USBD_SPEED_HS) {
995+
err = usb_init_next_add_configuration(&usbd, USBD_SPEED_HS, &hs_config);
996+
if (err) {
997+
LOG_ERR("usb_init_next_add_configuration failed (err: %d)", err);
998+
return NULL;
999+
}
1000+
}
1001+
1002+
err = usb_init_next_add_configuration(&usbd, USBD_SPEED_FS, &fs_config);
1003+
if (err) {
1004+
LOG_ERR("usb_init_next_add_configuration failed (err: %d)", err);
1005+
return NULL;
1006+
}
1007+
1008+
err = usbd_init(&usbd);
1009+
if (err) {
1010+
LOG_ERR("usbd_init (err: %d)", err);
1011+
return NULL;
1012+
}
1013+
1014+
return &usbd;
1015+
}
1016+
1017+
static int usb_init_next(void)
1018+
{
1019+
struct usbd_contex *usbd = usb_init_next_usbd_init();
1020+
1021+
if (!usbd) {
1022+
LOG_ERR("usb_init_next_usbd_init failed");
1023+
return -ENXIO;
1024+
}
1025+
1026+
int err = usbd_msg_register_cb(usbd, usb_init_next_status_cb);
1027+
1028+
if (err) {
1029+
LOG_ERR("usbd_msg_register_cb failed (err: %d)", err);
1030+
return err;
1031+
}
1032+
1033+
err = usbd_enable(usbd);
1034+
if (err) {
1035+
LOG_ERR("usbd_enable failed (err: %d)", err);
1036+
return err;
1037+
}
1038+
1039+
usbd_ctx = usbd;
1040+
1041+
return 0;
1042+
}
1043+
8071044
static int usb_init(void)
8081045
{
8091046
int err = 0;
@@ -815,7 +1052,7 @@ static int usb_init(void)
8151052
}
8161053

8171054
if (IS_ENABLED(CONFIG_DESKTOP_USB_STACK_NEXT)) {
818-
LOG_WRN("USB next stack APIs are not yet in use");
1055+
err = usb_init_next();
8191056
} else {
8201057
__ASSERT_NO_MSG(IS_ENABLED(CONFIG_DESKTOP_USB_STACK_LEGACY));
8211058
err = usb_init_legacy();

0 commit comments

Comments
 (0)