From 4115724dc70ed23b1c3fcef13a31d311635b6f33 Mon Sep 17 00:00:00 2001 From: jzlv Date: Fri, 4 Jun 2021 17:51:38 +0800 Subject: [PATCH] [feat] add usb audio and video driver --- components/usb_stack/CMakeLists.txt | 1 + components/usb_stack/class/audio/usbd_audio.c | 89 +++++++++ components/usb_stack/class/audio/usbd_audio.h | 173 +++++++++++------- components/usb_stack/class/cdc/usbd_cdc.c | 17 +- components/usb_stack/class/hid/usbd_hid.c | 122 +++++++++--- components/usb_stack/class/hid/usbd_hid.h | 11 +- components/usb_stack/class/video/usbd_video.c | 115 ++---------- components/usb_stack/class/video/usbd_video.h | 5 +- components/usb_stack/common/usb_util.h | 2 +- components/usb_stack/core/usbd_core.c | 34 ++-- components/usb_stack/core/usbd_core.h | 4 - 11 files changed, 352 insertions(+), 221 deletions(-) diff --git a/components/usb_stack/CMakeLists.txt b/components/usb_stack/CMakeLists.txt index be3acf73..6415ff46 100644 --- a/components/usb_stack/CMakeLists.txt +++ b/components/usb_stack/CMakeLists.txt @@ -6,6 +6,7 @@ list(APPEND ADD_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/class/hid" "${CMAKE_CURRENT_SOURCE_DIR}/class/msc" "${CMAKE_CURRENT_SOURCE_DIR}/class/video" +"${CMAKE_CURRENT_SOURCE_DIR}/class/audio" #"${CMAKE_CURRENT_SOURCE_DIR}/class/vendor" "${CMAKE_CURRENT_SOURCE_DIR}/class/winusb" ) diff --git a/components/usb_stack/class/audio/usbd_audio.c b/components/usb_stack/class/audio/usbd_audio.c index 8e2b8acf..2b7db616 100644 --- a/components/usb_stack/class/audio/usbd_audio.c +++ b/components/usb_stack/class/audio/usbd_audio.c @@ -1,7 +1,96 @@ #include "usbd_core.h" #include "usbd_audio.h" + +struct usbd_audio_control_info audio_control_info = {0xdb00,0x0000,0x0100,0xf600,0}; + int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len) { + USBD_LOG_DBG("Class request:" + "bRequest 0x%02x, bmRequestType 0x%02x len %d", + setup->bRequest, setup->bmRequestType, *len); + + switch (setup->bRequest) + { + case AUDIO_REQUEST_SET_CUR: + + if(setup->wValueL == 0x01) + { + if(setup->wValueH == AUDIO_FU_CONTROL_MUTE) + { + memcpy(&audio_control_info.mute,*data,*len); + } + else if(setup->wValueH == AUDIO_FU_CONTROL_VOLUME) + { + memcpy(&audio_control_info.vol_current,*data,*len); + USBD_LOG_DBG("vol:0x%x\r\n",audio_control_info.vol_current); + } + } + break; + case AUDIO_REQUEST_GET_CUR: + if(setup->wValueH == AUDIO_FU_CONTROL_MUTE) + { + *data = (uint8_t*)&audio_control_info.mute; + *len = 1; + } + else if(setup->wValueH == AUDIO_FU_CONTROL_VOLUME) + { + *data = (uint8_t*)&audio_control_info.vol_current; + *len = 2; + } + + break; + case AUDIO_REQUEST_SET_RES: + break; + case AUDIO_REQUEST_GET_MIN: + *data = (uint8_t*)&audio_control_info.vol_min; + *len = 2; + break; + case AUDIO_REQUEST_GET_MAX: + *data = (uint8_t*)&audio_control_info.vol_max; + *len = 2; + break; + case AUDIO_REQUEST_GET_RES: + *data = (uint8_t*)&audio_control_info.vol_res; + *len = 2; + break; + default: + USBD_LOG_ERR("Unhandled request 0x%02x", setup->bRequest); + break; + } return 0; } + +void audio_notify_handler(uint8_t event, void* arg) +{ + switch (event) + { + case USB_EVENT_RESET: + + break; + case USB_EVENT_SOF: + break; + case USB_EVENT_SET_INTERFACE: + usbd_audio_set_interface_callback(((uint8_t*)arg)[3]); + break; + default: + break; + } +} + +void usbd_audio_add_interface(usbd_class_t *class, usbd_interface_t *intf) +{ + static usbd_class_t *last_class = NULL; + + if(last_class != class) + { + last_class = class; + usbd_class_register(class); + } + + intf->class_handler = audio_class_request_handler; + intf->custom_handler = NULL; + intf->vendor_handler = NULL; + intf->notify_handler = audio_notify_handler; + usbd_class_add_interface(class,intf); +} \ No newline at end of file diff --git a/components/usb_stack/class/audio/usbd_audio.h b/components/usb_stack/class/audio/usbd_audio.h index 9c7ebc8f..614e7c83 100644 --- a/components/usb_stack/class/audio/usbd_audio.h +++ b/components/usb_stack/class/audio/usbd_audio.h @@ -20,72 +20,116 @@ extern "C" { /** Audio Interface Subclass Codes * Refer to Table A-2 from audio10.pdf */ -enum usb_audio_int_subclass_codes { - USB_AUDIO_SUBCLASS_UNDEFINED = 0x00, - USB_AUDIO_AUDIOCONTROL = 0x01, - USB_AUDIO_AUDIOSTREAMING = 0x02, - USB_AUDIO_MIDISTREAMING = 0x03 -}; +#define AUDIO_SUBCLASS_UNDEFINED 0x00 +#define AUDIO_SUBCLASS_AUDIOCONTROL 0x01 +#define AUDIO_SUBCLASS_AUDIOSTREAMING 0x02 +#define AUDIO_SUBCLASS_MIDISTREAMING 0x03 -/** Audio Class-Specific AC Interface Descriptor Subtypes +#define AUDIO_PROTOCOL_UNDEFINED 0x00U + +#define AUDIO_ENDPOINT_GENERAL 0x01U + +/** Audio Class-Specific Control Interface Descriptor Subtypes * Refer to Table A-5 from audio10.pdf */ -enum usb_audio_cs_ac_int_desc_subtypes { - USB_AUDIO_AC_DESCRIPTOR_UNDEFINED = 0x00, - USB_AUDIO_HEADER = 0x01, - USB_AUDIO_INPUT_TERMINAL = 0x02, - USB_AUDIO_OUTPUT_TERMINAL = 0x03, - USB_AUDIO_MIXER_UNIT = 0x04, - USB_AUDIO_SELECTOR_UNIT = 0x05, - USB_AUDIO_FEATURE_UNIT = 0x06, - USB_AUDIO_PROCESSING_UNIT = 0x07, - USB_AUDIO_EXTENSION_UNIT = 0x08 -}; +#define AUDIO_CONTROL_UNDEFINED 0x01U +#define AUDIO_CONTROL_HEADER 0x01U +#define AUDIO_CONTROL_INPUT_TERMINAL 0x02U +#define AUDIO_CONTROL_OUTPUT_TERMINAL 0x03U +#define AUDIO_CONTROL_MIXER_UNIT 0x04U +#define AUDIO_CONTROL_SELECTOR_UNIT 0x05U +#define AUDIO_CONTROL_FEATURE_UNIT 0x06U +#define AUDIO_CONTROL_PROCESSING_UNIT 0x07U +#define AUDIO_CONTROL_EXTENSION_UNIT 0x08U /** Audio Class-Specific AS Interface Descriptor Subtypes * Refer to Table A-6 from audio10.pdf */ -enum usb_audio_cs_as_int_desc_subtypes { - USB_AUDIO_AS_DESCRIPTOR_UNDEFINED = 0x00, - USB_AUDIO_AS_GENERAL = 0x01, - USB_AUDIO_FORMAT_TYPE = 0x02, - USB_AUDIO_FORMAT_SPECIFIC = 0x03 -}; +#define AUDIO_STREAMING_UNDEFINED 0x00U +#define AUDIO_STREAMING_GENERAL 0x01U +#define AUDIO_STREAMING_FORMAT_TYPE 0x02U +#define AUDIO_STREAMING_FORMAT_SPECIFIC 0x03U /** Audio Class-Specific Request Codes * Refer to Table A-9 from audio10.pdf */ -enum usb_audio_cs_req_codes { - USB_AUDIO_REQUEST_CODE_UNDEFINED = 0x00, - USB_AUDIO_SET_CUR = 0x01, - USB_AUDIO_GET_CUR = 0x81, - USB_AUDIO_SET_MIN = 0x02, - USB_AUDIO_GET_MIN = 0x82, - USB_AUDIO_SET_MAX = 0x03, - USB_AUDIO_GET_MAX = 0x83, - USB_AUDIO_SET_RES = 0x04, - USB_AUDIO_GET_RES = 0x84, - USB_AUDIO_SET_MEM = 0x05, - USB_AUDIO_GET_MEM = 0x85, - USB_AUDIO_GET_STAT = 0xFF -}; +#define AUDIO_REQUEST_UNDEFINED 0x00 +#define AUDIO_REQUEST_SET_CUR 0x01 +#define AUDIO_REQUEST_GET_CUR 0x81 +#define AUDIO_REQUEST_SET_MIN 0x02 +#define AUDIO_REQUEST_GET_MIN 0x82 +#define AUDIO_REQUEST_SET_MAX 0x03 +#define AUDIO_REQUEST_GET_MAX 0x83 +#define AUDIO_REQUEST_SET_RES 0x04 +#define AUDIO_REQUEST_GET_RES 0x84 +#define AUDIO_REQUEST_SET_MEM 0x05 +#define AUDIO_REQUEST_GET_MEM 0x85 +#define AUDIO_REQUEST_GET_STAT 0xFF + +/* Feature Unit Control Bits */ +#define AUDIO_CONTROL_MUTE 0x0001 +#define AUDIO_CONTROL_VOLUME 0x0002 +#define AUDIO_CONTROL_BASS 0x0004 +#define AUDIO_CONTROL_MID 0x0008 +#define AUDIO_CONTROL_TREBLE 0x0010 +#define AUDIO_CONTROL_GRAPHIC_EQUALIZER 0x0020 +#define AUDIO_CONTROL_AUTOMATIC_GAIN 0x0040 +#define AUDIO_CONTROL_DEALY 0x0080 +#define AUDIO_CONTROL_BASS_BOOST 0x0100 +#define AUDIO_CONTROL_LOUDNESS 0x0200 + /** Feature Unit Control Selectors * Refer to Table A-11 from audio10.pdf */ -enum usb_audio_fucs { - USB_AUDIO_FU_CONTROL_UNDEFINED = 0x00, - USB_AUDIO_FU_MUTE_CONTROL = 0x01, - USB_AUDIO_FU_VOLUME_CONTROL = 0x02, - USB_AUDIO_FU_BASS_CONTROL = 0x03, - USB_AUDIO_FU_MID_CONTROL = 0x04, - USB_AUDIO_FU_TREBLE_CONTROL = 0x05, - USB_AUDIO_FU_GRAPHIC_EQUALIZER_CONTROL = 0x06, - USB_AUDIO_FU_AUTOMATIC_GAIN_CONTROL = 0x07, - USB_AUDIO_FU_DELAY_CONTROL = 0x08, - USB_AUDIO_FU_BASS_BOOST_CONTROL = 0x09, - USB_AUDIO_FU_LOUDNESS_CONTROL = 0x0A -}; +#define AUDIO_FU_CONTROL_MUTE 0x01 +#define AUDIO_FU_CONTROL_VOLUME 0x02 +#define AUDIO_FU_CONTROL_BASS 0x03 +#define AUDIO_FU_CONTROL_MID 0x04 +#define AUDIO_FU_CONTROL_TREBLE 0x05 +#define AUDIO_FU_CONTROL_GRAPHIC_EQUALIZER 0x06 +#define AUDIO_FU_CONTROL_AUTOMATIC_GAIN 0x07 +#define AUDIO_FU_CONTROL_DELAY 0x08 +#define AUDIO_FU_CONTROL_BASS_BOOST 0x09 +#define AUDIO_FU_CONTROL_LOUDNESS 0x0A + + +/* Audio Descriptor Types */ +#define AUDIO_UNDEFINED_DESCRIPTOR_TYPE 0x20 +#define AUDIO_DEVICE_DESCRIPTOR_TYPE 0x21 +#define AUDIO_CONFIGURATION_DESCRIPTOR_TYPE 0x22 +#define AUDIO_STRING_DESCRIPTOR_TYPE 0x23 +#define AUDIO_INTERFACE_DESCRIPTOR_TYPE 0x24 +#define AUDIO_ENDPOINT_DESCRIPTOR_TYPE 0x25 + + +/* Audio Data Format Type I Codes */ +#define AUDIO_FORMAT_TYPE_I_UNDEFINED 0x0000 +#define AUDIO_FORMAT_PCM 0x0001 +#define AUDIO_FORMAT_PCM8 0x0002 +#define AUDIO_FORMAT_IEEE_FLOAT 0x0003 +#define AUDIO_FORMAT_ALAW 0x0004 +#define AUDIO_FORMAT_MULAW 0x0005 + +/* Predefined Audio Channel Configuration Bits */ +#define AUDIO_CHANNEL_M 0x0000 /* Mono */ +#define AUDIO_CHANNEL_L 0x0001 /* Left Front */ +#define AUDIO_CHANNEL_R 0x0002 /* Right Front */ +#define AUDIO_CHANNEL_C 0x0004 /* Center Front */ +#define AUDIO_CHANNEL_LFE 0x0008 /* Low Freq. Enhance. */ +#define AUDIO_CHANNEL_LS 0x0010 /* Left Surround */ +#define AUDIO_CHANNEL_RS 0x0020 /* Right Surround */ +#define AUDIO_CHANNEL_LC 0x0040 /* Left of Center */ +#define AUDIO_CHANNEL_RC 0x0080 /* Right of Center */ +#define AUDIO_CHANNEL_S 0x0100 /* Surround */ +#define AUDIO_CHANNEL_SL 0x0200 /* Side Left */ +#define AUDIO_CHANNEL_SR 0x0400 /* Side Right */ +#define AUDIO_CHANNEL_T 0x0800 /* Top */ + +#define AUDIO_FORMAT_TYPE_I 0x01 +#define AUDIO_FORMAT_TYPE_II 0x02 +#define AUDIO_FORMAT_TYPE_III 0x03 + /** USB Terminal Types * Refer to Table 2-1 - Table 2-4 from termt10.pdf @@ -124,21 +168,6 @@ enum usb_audio_terminal_types { USB_AUDIO_IO_SPEAKERPHONE_ECHO_CAN = 0x0405, }; -enum usb_audio_direction { - USB_AUDIO_IN = 0x00, - USB_AUDIO_OUT = 0x01 -}; - -/** - * Addressable logical object inside an audio function. - * Entity is one of: Terminal or Unit. - * Refer to 1.4 Terms and Abbreviations from audio10.pdf - */ -struct usb_audio_entity { - enum usb_audio_cs_ac_int_desc_subtypes subtype; - uint8_t id; -}; - /** * @warning Size of baInterface is 2 just to make it useable * for all kind of devices: headphones, microphone and headset. @@ -233,8 +262,20 @@ struct cs_as_ad_ep_descriptor { uint8_t bLockDelayUnits; uint16_t wLockDelay; } __packed; + +struct usbd_audio_control_info +{ + uint16_t vol_min; + uint16_t vol_max; + uint16_t vol_res; + uint16_t vol_current; + uint8_t mute; +}; + #ifdef __cplusplus } #endif +void usbd_audio_add_interface(usbd_class_t *class, usbd_interface_t *intf); +void usbd_audio_set_interface_callback(uint8_t value); #endif /* _USB_AUDIO_H_ */ diff --git a/components/usb_stack/class/cdc/usbd_cdc.c b/components/usb_stack/class/cdc/usbd_cdc.c index 195f4425..ca962acc 100644 --- a/components/usb_stack/class/cdc/usbd_cdc.c +++ b/components/usb_stack/class/cdc/usbd_cdc.c @@ -23,8 +23,8 @@ #include "usbd_core.h" #include "usbd_cdc.h" -static const char *stop_name[] = {"1", "1.5", "2"}; -static const char *parity_name[] = {"N","O","E","M","S"}; +const char *stop_name[] = {"1", "1.5", "2"}; +const char *parity_name[] = {"N","O","E","M","S"}; /* Device data structure */ struct cdc_acm_cfg_private { @@ -40,9 +40,11 @@ struct cdc_acm_cfg_private { bool configured; /* CDC ACM suspended flag */ bool suspended; + uint32_t uart_first_init_flag; } usbd_cdc_acm_cfg; + static void usbd_cdc_acm_reset(void) { usbd_cdc_acm_cfg.line_coding.dwDTERate = 2000000; @@ -50,6 +52,7 @@ static void usbd_cdc_acm_reset(void) usbd_cdc_acm_cfg.line_coding.bParityType = 0; usbd_cdc_acm_cfg.line_coding.bCharFormat = 0; usbd_cdc_acm_cfg.configured = false; + usbd_cdc_acm_cfg.uart_first_init_flag = 0; } /** @@ -83,8 +86,14 @@ static int cdc_acm_class_request_handler(struct usb_setup_packet *pSetup,uint8_t /* 4 - Space */ /* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */ /*******************************************************************************/ + if(usbd_cdc_acm_cfg.uart_first_init_flag == 0) + { + usbd_cdc_acm_cfg.uart_first_init_flag = 1; + return 0; + } + memcpy(&usbd_cdc_acm_cfg.line_coding,*data, sizeof(usbd_cdc_acm_cfg.line_coding)); - USBD_LOG("CDC_SET_LINE_CODING <%d %d %s %s>\r\n", + USBD_LOG_DBG("CDC_SET_LINE_CODING <%d %d %s %s>\r\n", usbd_cdc_acm_cfg.line_coding.dwDTERate, usbd_cdc_acm_cfg.line_coding.bDataBits, parity_name[usbd_cdc_acm_cfg.line_coding.bParityType], @@ -98,7 +107,7 @@ static int cdc_acm_class_request_handler(struct usb_setup_packet *pSetup,uint8_t usbd_cdc_acm_cfg.line_state = (uint8_t)pSetup->wValue; bool dtr = (pSetup->wValue & 0x01); bool rts = (pSetup->wValue & 0x02); - USBD_LOG("DTR 0x%x,RTS 0x%x\r\n", + USBD_LOG_DBG("DTR 0x%x,RTS 0x%x\r\n", dtr,rts); usbd_cdc_acm_set_dtr(dtr); usbd_cdc_acm_set_rts(rts); diff --git a/components/usb_stack/class/hid/usbd_hid.c b/components/usb_stack/class/hid/usbd_hid.c index 41172876..2bed252d 100644 --- a/components/usb_stack/class/hid/usbd_hid.c +++ b/components/usb_stack/class/hid/usbd_hid.c @@ -23,11 +23,31 @@ #include "usbd_core.h" #include "usbd_hid.h" +#define HID_STATE_IDLE 0 +#define HID_STATE_BUSY 1 + +struct usbd_hid_cfg_private +{ + const uint8_t* hid_descriptor; + const uint8_t* hid_report_descriptor; + uint32_t hid_report_descriptor_len; + uint32_t protocol; + uint32_t idle_state; + uint8_t hid_state; +} usbd_hid_cfg; + +static void usbd_hid_reset(void) +{ + usbd_hid_cfg.idle_state = 0; + usbd_hid_cfg.protocol = 2; + usbd_hid_cfg.hid_state = HID_STATE_IDLE; +} + int hid_custom_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len) { USBD_LOG_DBG("Standard request:" - "bRequest 0x%02x, bmRequestType 0x%02x, len %d", - setup->bRequest, setup->bmRequestType, *len); + "bmRequestType 0x%02x, bRequest 0x%02x, len %d\r\n", + setup->bmRequestType, setup->bRequest, *len); if (REQTYPE_GET_DIR(setup->bmRequestType) == USB_REQUEST_DEVICE_TO_HOST && setup->bRequest == USB_REQUEST_GET_DESCRIPTOR) @@ -37,17 +57,18 @@ int hid_custom_request_handler(struct usb_setup_packet *setup, uint8_t **data, u switch (value) { - case USB_DESCRIPTOR_TYPE_HID: - - USBD_LOG_DBG("Return HID Descriptor"); - + case HID_DESCRIPTOR_TYPE_HID: + USBD_LOG("get HID Descriptor\r\n"); + *data = (uint8_t*)usbd_hid_cfg.hid_descriptor; + *len = usbd_hid_cfg.hid_descriptor[0]; break; - case USB_DESCRIPTOR_TYPE_HID_REPORT: - USBD_LOG_DBG("Return Report Descriptor"); - + case HID_DESCRIPTOR_TYPE_HID_REPORT: + USBD_LOG("get Report Descriptor\r\n"); + *data = (uint8_t*)usbd_hid_cfg.hid_report_descriptor; + *len = usbd_hid_cfg.hid_report_descriptor_len; break; - case USB_DESCRIPTOR_TYPE_HID_PHYSICAL: - USBD_LOG_DBG("Return PHYSICAL Descriptor"); + case HID_DESCRIPTOR_TYPE_HID_PHYSICAL: + USBD_LOG_DBG("get PHYSICAL Descriptor\r\n"); break; default: @@ -59,36 +80,87 @@ int hid_custom_request_handler(struct usb_setup_packet *setup, uint8_t **data, u return -1; } + int hid_class_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len) { - USBD_LOG_DBG("Class request:" - "bRequest 0x%02x, bmRequestType 0x%02x len %d", - setup->bRequest, setup->bmRequestType, *len); + USBD_LOG("Class request:" + "bmRequestType 0x%02x bRequest 0x%02x, len %d\r\n", + setup->bmRequestType,setup->bRequest, *len); switch (setup->bRequest) { case HID_REQUEST_GET_IDLE: - - break; - case HID_REQUEST_GET_REPORT: - + *data = (uint8_t*)&usbd_hid_cfg.idle_state; + *len = 1; break; case HID_REQUEST_GET_PROTOCOL: - + *data = (uint8_t*)&usbd_hid_cfg.protocol; + *len = 1; break; case HID_REQUEST_SET_IDLE: - - break; - case HID_REQUEST_SET_REPORT: - + usbd_hid_cfg.idle_state = setup->wValueH; break; case HID_REQUEST_SET_PROTOCOL: - + usbd_hid_cfg.protocol = setup->wValueL; break; default: - USBD_LOG_ERR("Unhandled request 0x%02x", setup->bRequest); + USBD_LOG_ERR("Unhandled request 0x%02x\r\n", setup->bRequest); break; } return 0; } + +static void hid_notify_handler(uint8_t event, void* arg) +{ + switch (event) + { + case USB_EVENT_RESET: + usbd_hid_reset(); + break; + default: + break; + } +} + +void usbd_hid_reset_state(void) +{ + usbd_hid_cfg.hid_state = HID_STATE_IDLE; +} + +void usbd_hid_send_report(uint8_t ep, uint8_t* data, uint8_t len) +{ + if(usbd_hid_cfg.hid_state == HID_STATE_IDLE) + { + usbd_hid_cfg.hid_state = HID_STATE_BUSY; + usbd_ep_write(ep,data,len,NULL); + } +} + +void usbd_hid_descriptor_register(const uint8_t* desc) +{ + usbd_hid_cfg.hid_descriptor = desc; +} + +void usbd_hid_report_descriptor_register(const uint8_t* desc, uint32_t desc_len) +{ + usbd_hid_cfg.hid_report_descriptor = desc; + usbd_hid_cfg.hid_report_descriptor_len = desc_len; +} + +void usbd_hid_add_interface(usbd_class_t *class, usbd_interface_t *intf) +{ + static usbd_class_t *last_class = NULL; + + if(last_class != class) + { + last_class = class; + usbd_class_register(class); + } + + intf->class_handler = hid_class_request_handler; + intf->custom_handler = hid_custom_request_handler; + intf->vendor_handler = NULL; + intf->notify_handler = hid_notify_handler; + usbd_class_add_interface(class,intf); +} diff --git a/components/usb_stack/class/hid/usbd_hid.h b/components/usb_stack/class/hid/usbd_hid.h index 6d5b0065..96495ecd 100644 --- a/components/usb_stack/class/hid/usbd_hid.h +++ b/components/usb_stack/class/hid/usbd_hid.h @@ -13,9 +13,9 @@ extern "C" { #endif /* HID Class Descriptor Types */ -#define USB_DESCRIPTOR_TYPE_HID 0x21 -#define USB_DESCRIPTOR_TYPE_HID_REPORT 0x22 -#define USB_DESCRIPTOR_TYPE_HID_PHYSICAL 0x23 +#define HID_DESCRIPTOR_TYPE_HID 0x21 +#define HID_DESCRIPTOR_TYPE_HID_REPORT 0x22 +#define HID_DESCRIPTOR_TYPE_HID_PHYSICAL 0x23 /* HID Class Specific Requests */ #define HID_REQUEST_GET_REPORT 0x01 @@ -393,4 +393,9 @@ enum hid_kbd_led { } #endif +void usbd_hid_descriptor_register(const uint8_t* desc); +void usbd_hid_report_descriptor_register(const uint8_t* desc, uint32_t desc_len); +void usbd_hid_add_interface(usbd_class_t *class, usbd_interface_t *intf); +void usbd_hid_reset_state(void); +void usbd_hid_send_report(uint8_t ep, uint8_t* data, uint8_t len); #endif /* _USB_HID_H_ */ diff --git a/components/usb_stack/class/video/usbd_video.c b/components/usb_stack/class/video/usbd_video.c index 43202f8d..4f643923 100644 --- a/components/usb_stack/class/video/usbd_video.c +++ b/components/usb_stack/class/video/usbd_video.c @@ -22,56 +22,8 @@ #include "usbd_core.h" #include "usbd_video.h" -#define WIDTH (unsigned int)320 -#define HEIGHT (unsigned int)240 -#define VIDEO_PACKET_SIZE (unsigned int)(768+2) - -#define CAM_FPS 20 -#define INTERVAL (unsigned long)(10000000/CAM_FPS) -#define MIN_BIT_RATE (unsigned long)(WIDTH*HEIGHT*16*CAM_FPS)//16 bit -#define MAX_BIT_RATE (unsigned long)(WIDTH*HEIGHT*16*CAM_FPS) -#define MAX_FRAME_SIZE (unsigned long)(WIDTH * HEIGHT *2) - -struct video_probe_and_commit_controls probe = -{ - .hintUnion.bmHint = 0, - .hintUnion1.bmHint = 0, - .bFormatIndex = 1, - .bFrameIndex = 1, - .dwFrameInterval = INTERVAL, - .wKeyFrameRate = 0, - .wPFrameRate = 0, - .wCompQuality = 0, - .wCompWindowSize = 0, - .wDelay = 0, - .dwMaxVideoFrameSize = MAX_FRAME_SIZE, - .dwMaxPayloadTransferSize = 0, - .dwClockFrequency = 0, - .bmFramingInfo = 0, - .bPreferedVersion = 0, - .bMinVersion = 0, - .bMaxVersion = 0, -}; -struct video_probe_and_commit_controls commit = -{ - .hintUnion.bmHint = 0, - .hintUnion1.bmHint = 0, - .bFormatIndex = 1, - .bFrameIndex = 1, - .dwFrameInterval = INTERVAL, - .wKeyFrameRate = 0, - .wPFrameRate = 0, - .wCompQuality = 0, - .wCompWindowSize = 0, - .wDelay = 0, - .dwMaxVideoFrameSize = MAX_FRAME_SIZE, - .dwMaxPayloadTransferSize = 0, - .dwClockFrequency = 0, - .bmFramingInfo = 0, - .bPreferedVersion = 0, - .bMinVersion = 0, - .bMaxVersion = 0, -}; +extern struct video_probe_and_commit_controls probe; +extern struct video_probe_and_commit_controls commit; int video_class_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len) { @@ -126,65 +78,38 @@ int video_class_request_handler(struct usb_setup_packet *setup, uint8_t **data, } return 0; } -uint8_t play_status = 0; + void video_notify_handler(uint8_t event, void* arg) { switch (event) { case USB_EVENT_RESET: - //usbd_cdc_acm_reset(); + break; + case USB_EVENT_SOF: + usbd_video_sof_callback(); + break; case USB_EVENT_SET_INTERFACE: - if(((uint8_t*)arg)[3]) - { - play_status =1; - MSG("Y\r\n"); - } - else - { - play_status=0; - MSG("N\r\n"); - } + usbd_video_set_interface_callback(((uint8_t*)arg)[3]); break; default: break; } } -__weak void usbd_video_isoch_out(uint8_t ep) +void usbd_video_add_interface(usbd_class_t *class, usbd_interface_t *intf) { + static usbd_class_t *last_class = NULL; -} -__weak void usbd_video_isoch_in(uint8_t ep) -{ - -} - - - -static usbd_class_t video_class; - -usbd_interface_t video_stream_intf = -{ - .class_handler = video_class_request_handler, - .vendor_handler = NULL, - .notify_handler = video_notify_handler, -}; - -static usbd_endpoint_t video_in_ep = -{ - .ep_cb = usbd_video_isoch_in, - .ep_addr = 0x81 -}; - -void usbd_video_class_init(const char *name,uint8_t in_ep) -{ - video_class.name = name; - - usbd_class_register(&video_class); - usbd_class_add_interface(&video_class,&video_stream_intf); - video_stream_intf.intf_num = 1; - video_in_ep.ep_addr = in_ep; - usbd_interface_add_endpoint(&video_stream_intf,&video_in_ep); + if(last_class != class) + { + last_class = class; + usbd_class_register(class); + } + intf->class_handler = video_class_request_handler; + intf->custom_handler = NULL; + intf->vendor_handler = NULL; + intf->notify_handler = video_notify_handler; + usbd_class_add_interface(class,intf); } \ No newline at end of file diff --git a/components/usb_stack/class/video/usbd_video.h b/components/usb_stack/class/video/usbd_video.h index da0f298d..200870e5 100644 --- a/components/usb_stack/class/video/usbd_video.h +++ b/components/usb_stack/class/video/usbd_video.h @@ -816,8 +816,9 @@ struct video_still_probe_and_commit_controls receive in a single payload transfer.*/ } __packed; -void usbd_video_isoch_in(uint8_t ep); -void usbd_video_class_init(const char *name,uint8_t in_ep); +void usbd_video_sof_callback(void); +void usbd_video_set_interface_callback(uint8_t value); +void usbd_video_add_interface(usbd_class_t *class, usbd_interface_t *intf); #ifdef __cplusplus } #endif diff --git a/components/usb_stack/common/usb_util.h b/components/usb_stack/common/usb_util.h index 7d3d6b19..2d42584d 100644 --- a/components/usb_stack/common/usb_util.h +++ b/components/usb_stack/common/usb_util.h @@ -70,7 +70,7 @@ #define BCD(x) ((((x) / 10) << 4) | ((x) % 10)) -#define BIT(n) (1UL << (n)) +#define BIT(x) (1<<(x)) #define ARRAY_SIZE(array) \ ((int)((sizeof(array) / sizeof((array)[0])))) diff --git a/components/usb_stack/core/usbd_core.c b/components/usb_stack/core/usbd_core.c index c340b1c0..acee5393 100644 --- a/components/usb_stack/core/usbd_core.c +++ b/components/usb_stack/core/usbd_core.c @@ -78,7 +78,7 @@ static struct usbd_core_cfg_priv static usb_slist_t usbd_class_head= USB_SLIST_OBJECT_INIT(usbd_class_head); static struct usb_msosv1_descriptor *msosv1_desc; static struct usb_bos_descriptor *bos_desc; -static volatile uint32_t sof_tick = 0; + /** * @brief print the contents of a setup packet * @@ -962,7 +962,7 @@ static void usbd_send_to_host(uint16_t len) if ((!usbd_core_cfg.ep0_data_buf_residue) && !(usbd_core_cfg.ep0_data_buf_len % USB_CTRL_EP_MPS)) { /* Transfers a zero-length packet */ - // LOG_DBG("ZLP, requested %u , length %u ", + // USBD_LOG("ZLP, requested %u , length %u ", // len, usb_dev.ep0_data_buf_len); usbd_core_cfg.zlp_flag = true; } @@ -1010,7 +1010,7 @@ static void usbd_ep0_setup_handler(void) if (setup->wLength && setup->bmRequestType_b.Dir == USB_REQUEST_HOST_TO_DEVICE) { - USBD_LOG_DBG("D\r\n"); + USBD_LOG_DBG("prepare to out data\r\n"); /*set ep ack to recv next data*/ usbd_ep_read(USB_CONTROL_OUT_EP0,NULL,0,NULL); return; @@ -1036,23 +1036,23 @@ static void usbd_ep0_out_handler(void) uint32_t chunk = 0U; struct usb_setup_packet *setup = &usbd_core_cfg.setup; - /* OUT transfer, data or status packets */ - if (usbd_core_cfg.ep0_data_buf_residue <= 0) + /* OUT transfer, status packets */ + if (usbd_core_cfg.ep0_data_buf_residue == 0) { /* absorb zero-length status message */ - USBD_LOG_DBG("Z\r\n"); + USBD_LOG_DBG("recv status\r\n"); if (usbd_ep_read(USB_CONTROL_OUT_EP0, - usbd_core_cfg.ep0_data_buf, - 0, &chunk) < 0) + NULL, + 0, NULL) < 0) { USBD_LOG_ERR("Read DATA Packet failed\r\n"); usbd_ep_set_stall(USB_CONTROL_IN_EP0); - return; } + return; } - usbd_core_cfg.ep0_data_buf = usbd_core_cfg.req_data; - /* OUT transfer, data or status packets */ + + /* OUT transfer, data packets */ if (usbd_ep_read(USB_CONTROL_OUT_EP0, usbd_core_cfg.ep0_data_buf, usbd_core_cfg.ep0_data_buf_residue, &chunk) < 0) @@ -1064,7 +1064,7 @@ static void usbd_ep0_out_handler(void) usbd_core_cfg.ep0_data_buf += chunk; usbd_core_cfg.ep0_data_buf_residue -= chunk; - + if (usbd_core_cfg.ep0_data_buf_residue == 0) { /* Received all, send data to handler */ @@ -1166,16 +1166,13 @@ void usbd_event_notify_handler(uint8_t event, void* arg) { switch (event) { - case USB_EVENT_SOF: - sof_tick++; - USBD_LOG_DBG("tick: %d\r\n", sof_tick); - break; case USB_EVENT_RESET: usbd_set_address(0); #if USBD_EP_CALLBACK_SEARCH_METHOD == 1 usbd_ep_callback_register(); #endif case USB_EVENT_ERROR: + case USB_EVENT_SOF: case USB_EVENT_CONNECTED: case USB_EVENT_CONFIGURED: case USB_EVENT_SUSPEND: @@ -1243,8 +1240,3 @@ bool usb_device_is_configured(void) { return usbd_core_cfg.configured; } - -uint32_t usbd_get_sof_tick(void) -{ - return sof_tick; -} \ No newline at end of file diff --git a/components/usb_stack/core/usbd_core.h b/components/usb_stack/core/usbd_core.h index 295f1e6d..e008ea3d 100644 --- a/components/usb_stack/core/usbd_core.h +++ b/components/usb_stack/core/usbd_core.h @@ -131,10 +131,6 @@ void usbd_msosv1_desc_register(struct usb_msosv1_descriptor *desc); void usbd_class_add_interface(usbd_class_t *class,usbd_interface_t *intf); void usbd_interface_add_endpoint(usbd_interface_t *intf,usbd_endpoint_t *ep); bool usb_device_is_configured(void); -uint32_t usbd_get_sof_tick(void); -/** - * @} - */ #ifdef __cplusplus }