6
6
#include <stdio.h>
7
7
#include <stdint.h>
8
8
9
+ #include <zephyr/device.h>
10
+ #include <zephyr/sys/iterable_sections.h>
9
11
#include <zephyr/types.h>
10
12
#include <zephyr/sys/byteorder.h>
11
13
#include <zephyr/sys/util.h>
12
14
15
+ #include <zephyr/usb/usbd.h>
16
+ #include <zephyr/usb/usbd_msg.h>
17
+
13
18
#include <zephyr/usb/usb_device.h>
14
19
#include <zephyr/usb/usb_ch9.h>
15
20
#include <zephyr/usb/class/usb_hid.h>
@@ -77,6 +82,8 @@ BUILD_ASSERT(!IS_ENABLED(CONFIG_DESKTOP_HID_STATE_ENABLE) ||
77
82
IS_ENABLED (CONFIG_DESKTOP_USB_SELECTIVE_REPORT_SUBSCRIPTION ) ||
78
83
(ARRAY_SIZE (usb_hid_device ) <= 1 ));
79
84
85
+ static struct usbd_contex * usbd_ctx ;
86
+
80
87
static struct config_channel_transport cfg_chan_transport ;
81
88
82
89
@@ -480,8 +487,8 @@ static void usb_wakeup(void)
480
487
{
481
488
int err = 0 ;
482
489
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 );
485
492
} else {
486
493
__ASSERT_NO_MSG (IS_ENABLED (CONFIG_DESKTOP_USB_STACK_LEGACY ));
487
494
err = usb_wakeup_request ();
@@ -804,6 +811,236 @@ static int usb_init_legacy(void)
804
811
return 0 ;
805
812
}
806
813
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
+
807
1044
static int usb_init (void )
808
1045
{
809
1046
int err = 0 ;
@@ -815,7 +1052,7 @@ static int usb_init(void)
815
1052
}
816
1053
817
1054
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 ( );
819
1056
} else {
820
1057
__ASSERT_NO_MSG (IS_ENABLED (CONFIG_DESKTOP_USB_STACK_LEGACY ));
821
1058
err = usb_init_legacy ();
0 commit comments