diff options
| author | sakumisu <[email protected]> | 2024-10-20 00:23:21 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-10-19 12:23:21 -0400 |
| commit | 4c206caf8b472ebbbff536ccbe85e20fe213e5ea (patch) | |
| tree | d22f44ece37d81dcdb7747ffccbad2dc995b5d42 /components/drivers/usb/cherryusb/class | |
| parent | e47f478e1249f1fb938885dadcc1e4bab66f0c59 (diff) | |
update(cherryusb): update to v1.4.1
Diffstat (limited to 'components/drivers/usb/cherryusb/class')
23 files changed, 492 insertions, 292 deletions
diff --git a/components/drivers/usb/cherryusb/class/audio/usb_audio.h b/components/drivers/usb/cherryusb/class/audio/usb_audio.h index 2b3cdaffa8..1aced20ff4 100644 --- a/components/drivers/usb/cherryusb/class/audio/usb_audio.h +++ b/components/drivers/usb/cherryusb/class/audio/usb_audio.h @@ -132,11 +132,11 @@ #define AUDIO_FORMAT_ALAW 0x0004 #define AUDIO_FORMAT_MULAW 0x0005 -#define AUDIO_V2_FORMAT_PCM 0x00000001 -#define AUDIO_V2_FORMAT_PCM8 0x00000002 -#define AUDIO_V2_FORMAT_IEEE_FLOAT 0x00000004 -#define AUDIO_V2_FORMAT_ALAW 0x00000008 -#define AUDIO_V2_FORMAT_MULAW 0x00000010 +#define AUDIO_V2_FORMAT_PCM 0x00000001 +#define AUDIO_V2_FORMAT_PCM8 0x00000002 +#define AUDIO_V2_FORMAT_IEEE_FLOAT 0x00000004 +#define AUDIO_V2_FORMAT_ALAW 0x00000008 +#define AUDIO_V2_FORMAT_MULAW 0x00000010 /* bmChannelConfig: a bitmap field that indicates which spatial locations * are occupied by the channels present in the cluster. The bit allocations @@ -812,6 +812,60 @@ struct audio_cs_ep_ep_general_descriptor { #define AUDIO_AS_DESCRIPTOR_INIT_LEN(n) (0x09 + 0x09 + 0x07 + 0x08 + 3 * n + 0x09 + 0x07) +#define AUDIO_AS_ALTSETTING_DESCRIPTOR_INIT(bInterfaceNumber, bAlternateSetting, bTerminalLink, bNrChannels, bSubFrameSize, bBitResolution, bEndpointAddress, bmAttributes, wMaxPacketSize, bInterval, ...) \ + 0x09, /* bLength */ \ + USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ + bInterfaceNumber, /* bInterfaceNumber */ \ + bAlternateSetting, /* bAlternateSetting */ \ + 0x01, /* bNumEndpoints */ \ + USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ \ + AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ \ + AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ \ + 0x00, /* iInterface */ \ + 0x07, /* bLength */ \ + AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \ + AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */ \ + bTerminalLink, /* bTerminalLink : Unit ID of the Output Terminal*/ \ + 0x01, /* bDelay */ \ + WBVAL(AUDIO_FORMAT_PCM), /* wFormatTag : AUDIO_FORMAT_PCM */ \ + 0x08 + PP_NARG(__VA_ARGS__), /* bLength */ \ + AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \ + AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */ \ + AUDIO_FORMAT_TYPE_I, /* bFormatType */ \ + bNrChannels, /* bNrChannels */ \ + bSubFrameSize, /* bSubFrameSize : Bytes per audio subframe */ \ + bBitResolution, /* bBitResolution : bits per sample */ \ + (PP_NARG(__VA_ARGS__)/3), /* bSamFreqType : only one frequency supported */ \ + __VA_ARGS__, /* tSamFreq : Audio sampling frequency coded on 3 bytes */ \ + 0x09, /* bLength */ \ + USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \ + bEndpointAddress, /* bEndpointAddress : IN endpoint 1 */ \ + bmAttributes, /* bmAttributes */ \ + WBVAL(wMaxPacketSize), /* wMaxPacketSize */ \ + bInterval, /* bInterval : one packet per frame */ \ + 0x00, /* bRefresh */ \ + 0x00, /* bSynchAddress */ \ + 0x07, /* bLength */ \ + AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ \ + AUDIO_ENDPOINT_GENERAL, /* bDescriptor */ \ + AUDIO_EP_CONTROL_SAMPLING_FEQ, /* bmAttributes AUDIO_SAMPLING_FREQ_CONTROL */ \ + 0x00, /* bLockDelayUnits */ \ + 0x00, /* wLockDelay */ \ + 0x00 + +#define AUDIO_AS_ALTSETTING_DESCRIPTOR_INIT_LEN(n) (0x09 + 0x07 + 0x08 + 3 * n + 0x09 + 0x07) + +#define AUDIO_AS_ALTSETTING0_DESCRIPTOR_INIT(bInterfaceNumber) \ + 0x09, /* bLength */ \ + USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ + bInterfaceNumber, /* bInterfaceNumber */ \ + 0x00, /* bAlternateSetting */ \ + 0x01, /* bNumEndpoints */ \ + USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ \ + AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ \ + AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ \ + 0x00 /* iInterface */ + #define AUDIO_MS_STANDARD_DESCRIPTOR_INIT(bInterfaceNumber, bNumEndpoints) \ 0x09, /* bLength */ \ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ @@ -1096,6 +1150,58 @@ struct audio_v2_control_range3_param_block { 0x00, /* wLockDelay */ \ 0x00 +#define AUDIO_V2_AS_ALTSETTING_DESCRIPTOR_INIT(bInterfaceNumber, bAlternateSetting, bTerminalLink, bNrChannels, bmChannelConfig, bSubslotSize, bBitResolution, bEndpointAddress, bmAttributes, wMaxPacketSize, bInterval) \ + 0x09, /* bLength */ \ + USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ + bInterfaceNumber, /* bInterfaceNumber */ \ + bAlternateSetting, /* bAlternateSetting */ \ + 0x01, /* bNumEndpoints */ \ + USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ \ + AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ \ + AUDIO_PROTOCOLv20, /* bInterfaceProtocol */ \ + 0x00, /* iInterface */ \ + 0x10, /* bLength */ \ + AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \ + AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */ \ + bTerminalLink, /* bTerminalLink : Unit ID of the Output or Input Terminal*/ \ + 0x00, /* bmControls */ \ + AUDIO_FORMAT_TYPE_I, /* bFormatType : AUDIO_FORMAT_TYPE_I */ \ + DBVAL(AUDIO_V2_FORMAT_PCM), /* bmFormats PCM */ \ + bNrChannels, /* bNrChannels */ \ + DBVAL(bmChannelConfig), /* bmChannelConfig */ \ + 0x00, /* iChannelNames */ \ + 0x06, /* bLength */ \ + AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \ + AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */ \ + AUDIO_FORMAT_TYPE_I, /* bFormatType */ \ + bSubslotSize, /* bSubslotSize */ \ + bBitResolution, /* bBitResolution */ \ + 0x07, /* bLength */ \ + USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \ + bEndpointAddress, /* bEndpointAddress 3 out endpoint for Audio */ \ + bmAttributes, /* bmAttributes */ \ + WBVAL(wMaxPacketSize), /* XXXX wMaxPacketSize in Bytes (SampleRate * SlotByteSize * NumChannels) */ \ + bInterval, /* bInterval */ \ + 0x08, /* bLength */ \ + AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ \ + AUDIO_ENDPOINT_GENERAL, /* bDescriptor */ \ + 0x00, /* bmAttributes */ \ + 0x00, /* bmControls */ \ + 0x00, /* bLockDelayUnits */ \ + 0x00, /* wLockDelay */ \ + 0x00 + +#define AUDIO_V2_AS_ALTSETTING0_DESCRIPTOR_INIT(bInterfaceNumber) \ + 0x09, /* bLength */ \ + USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ + bInterfaceNumber, /* bInterfaceNumber */ \ + 0x00, /* bAlternateSetting */ \ + 0x01, /* bNumEndpoints */ \ + USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ \ + AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ \ + AUDIO_PROTOCOLv20, /* bInterfaceProtocol */ \ + 0x00 /* iInterface */ + #define AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT(bInterfaceNumber, bTerminalLink, bNrChannels, bmChannelConfig, bSubslotSize, bBitResolution, bEndpointAddress, wMaxPacketSize, bInterval, bFeedbackEndpointAddress) \ 0x09, /* bLength */ \ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ @@ -1150,12 +1256,13 @@ struct audio_v2_control_range3_param_block { bFeedbackEndpointAddress, /* bFeedbackEndpointAddress Revise Dir to bEndpointAddress */ \ 0x11, /* bmAttributes: TransferType=Isochronous SyncType=None EndpointType=Feedback */ \ WBVAL(4), /* XXXX wMaxPacketSize in Bytes */ \ - bInterval /* bInterval */ \ + bInterval /* bInterval */ // clang-format on -#define AUDIO_V2_AS_DESCRIPTOR_INIT_LEN (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08) -#define AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT_LEN (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08 + 0x07) +#define AUDIO_V2_AS_DESCRIPTOR_INIT_LEN (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08) +#define AUDIO_V2_AS_ALTSETTING_DESCRIPTOR_INIT_LEN (0x09 + 0x10 + 0x06 + 0x07 + 0x08) +#define AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT_LEN (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08 + 0x07) #define AUDIO_SAMPLE_FREQ_NUM(num) (uint8_t)(num), (uint8_t)((num >> 8)) #define AUDIO_SAMPLE_FREQ_3B(frq) (uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16)) diff --git a/components/drivers/usb/cherryusb/class/audio/usbh_audio.c b/components/drivers/usb/cherryusb/class/audio/usbh_audio.c index 2f06782682..9e838bbae0 100644 --- a/components/drivers/usb/cherryusb/class/audio/usbh_audio.c +++ b/components/drivers/usb/cherryusb/class/audio/usbh_audio.c @@ -21,10 +21,6 @@ #define INTF_DESC_bInterfaceNumber 2 /** Interface number offset */ #define INTF_DESC_bAlternateSetting 3 /** Alternate setting offset */ -#ifndef CONFIG_USBHOST_MAX_AUDIO_CLASS -#define CONFIG_USBHOST_MAX_AUDIO_CLASS 4 -#endif - USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_audio_buf[128]; static struct usbh_audio g_audio_class[CONFIG_USBHOST_MAX_AUDIO_CLASS]; @@ -32,11 +28,11 @@ static uint32_t g_devinuse = 0; static struct usbh_audio *usbh_audio_class_alloc(void) { - int devno; + uint8_t devno; for (devno = 0; devno < CONFIG_USBHOST_MAX_AUDIO_CLASS; devno++) { - if ((g_devinuse & (1 << devno)) == 0) { - g_devinuse |= (1 << devno); + if ((g_devinuse & (1U << devno)) == 0) { + g_devinuse |= (1U << devno); memset(&g_audio_class[devno], 0, sizeof(struct usbh_audio)); g_audio_class[devno].minor = devno; return &g_audio_class[devno]; @@ -47,15 +43,15 @@ static struct usbh_audio *usbh_audio_class_alloc(void) static void usbh_audio_class_free(struct usbh_audio *audio_class) { - int devno = audio_class->minor; + uint8_t devno = audio_class->minor; - if (devno >= 0 && devno < 32) { - g_devinuse &= ~(1 << devno); + if (devno < 32) { + g_devinuse &= ~(1U << devno); } memset(audio_class, 0, sizeof(struct usbh_audio)); } -int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t samp_freq) +int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t samp_freq, uint8_t bitresolution) { struct usb_setup_packet *setup; struct usb_endpoint_descriptor *ep_desc; @@ -74,20 +70,24 @@ int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t s return 0; } - for (uint8_t i = 0; i < audio_class->module_num; i++) { - if (strcmp(name, audio_class->module[i].name) == 0) { - for (uint8_t j = 0; j < audio_class->num_of_intf_altsettings; j++) { - for (uint8_t k = 0; k < audio_class->module[i].altsetting[j].sampfreq_num; k++) { - if (audio_class->module[i].altsetting[j].sampfreq[k] == samp_freq) { - intf = audio_class->module[i].data_intf; - altsetting = j; - goto freq_found; + for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) { + if (strcmp(name, audio_class->as_msg_table[i].stream_name) == 0) { + intf = audio_class->as_msg_table[i].stream_intf; + for (uint8_t j = 1; j < audio_class->as_msg_table[i].num_of_altsetting; j++) { + if (audio_class->as_msg_table[i].as_format[j].bBitResolution == bitresolution) { + for (uint8_t k = 0; k < audio_class->as_msg_table[i].as_format[j].bSamFreqType; k++) { + uint32_t freq = 0; + + memcpy(&freq, &audio_class->as_msg_table[i].as_format[j].tSamFreq[3 * k], 3); + if (freq == samp_freq) { + altsetting = j; + goto freq_found; + } } } } } } - return -USB_ERR_NODEV; freq_found: @@ -105,16 +105,18 @@ freq_found: ep_desc = &audio_class->hport->config.intf[intf].altsetting[altsetting].ep[0].ep_desc; - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_ENDPOINT; - setup->bRequest = AUDIO_REQUEST_SET_CUR; - setup->wValue = (AUDIO_EP_CONTROL_SAMPLING_FEQ << 8) | 0x00; - setup->wIndex = ep_desc->bEndpointAddress; - setup->wLength = 3; + if (audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].ep_attr & AUDIO_EP_CONTROL_SAMPLING_FEQ) { + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_ENDPOINT; + setup->bRequest = AUDIO_REQUEST_SET_CUR; + setup->wValue = (AUDIO_EP_CONTROL_SAMPLING_FEQ << 8) | 0x00; + setup->wIndex = ep_desc->bEndpointAddress; + setup->wLength = 3; - memcpy(g_audio_buf, &samp_freq, 3); - ret = usbh_control_transfer(audio_class->hport, setup, g_audio_buf); - if (ret < 0) { - return ret; + memcpy(g_audio_buf, &samp_freq, 3); + ret = usbh_control_transfer(audio_class->hport, setup, g_audio_buf); + if (ret < 0) { + return ret; + } } mult = (ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_MASK) >> USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT; @@ -127,7 +129,7 @@ freq_found: USBH_EP_INIT(audio_class->isoout, ep_desc); } - USB_LOG_INFO("Open audio module :%s, altsetting: %u\r\n", name, altsetting); + USB_LOG_INFO("Open audio stream :%s, altsetting: %u\r\n", name, altsetting); audio_class->is_opened = true; return ret; } @@ -145,9 +147,9 @@ int usbh_audio_close(struct usbh_audio *audio_class, const char *name) } setup = audio_class->hport->setup; - for (size_t i = 0; i < audio_class->module_num; i++) { - if (strcmp(name, audio_class->module[i].name) == 0) { - intf = audio_class->module[i].data_intf; + for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) { + if (strcmp(name, audio_class->as_msg_table[i].stream_name) == 0) { + intf = audio_class->as_msg_table[i].stream_intf; } } @@ -155,7 +157,17 @@ int usbh_audio_close(struct usbh_audio *audio_class, const char *name) return -USB_ERR_NODEV; } - USB_LOG_INFO("Close audio module :%s\r\n", name); + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE; + setup->bRequest = USB_REQUEST_SET_INTERFACE; + setup->wValue = 0; + setup->wIndex = intf; + setup->wLength = 0; + + ret = usbh_control_transfer(audio_class->hport, setup, NULL); + if (ret < 0) { + return ret; + } + USB_LOG_INFO("Close audio stream :%s\r\n", name); audio_class->is_opened = false; ep_desc = &audio_class->hport->config.intf[intf].altsetting[altsetting].ep[0].ep_desc; @@ -169,14 +181,6 @@ int usbh_audio_close(struct usbh_audio *audio_class, const char *name) } } - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE; - setup->bRequest = USB_REQUEST_SET_INTERFACE; - setup->wValue = 0; - setup->wIndex = intf; - setup->wLength = 0; - - ret = usbh_control_transfer(audio_class->hport, setup, NULL); - return ret; } @@ -184,30 +188,29 @@ int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint { struct usb_setup_packet *setup; int ret; - uint8_t intf = 0xff; uint8_t feature_id = 0xff; uint16_t volume_hex; if (!audio_class || !audio_class->hport) { return -USB_ERR_INVAL; } - setup = audio_class->hport->setup; - for (size_t i = 0; i < audio_class->module_num; i++) { - if (strcmp(name, audio_class->module[i].name) == 0) { - intf = audio_class->ctrl_intf; - feature_id = audio_class->module[i].feature_unit_id; - } + if (volume > 100) { + return -USB_ERR_INVAL; } - if (intf == 0xff) { - return -USB_ERR_NODEV; + setup = audio_class->hport->setup; + + for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) { + if (strcmp(name, audio_class->as_msg_table[i].stream_name) == 0) { + feature_id = audio_class->as_msg_table[i].feature_terminal_id; + } } setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; setup->bRequest = AUDIO_REQUEST_SET_CUR; setup->wValue = (AUDIO_FU_CONTROL_VOLUME << 8) | ch; - setup->wIndex = (feature_id << 8) | intf; + setup->wIndex = (feature_id << 8) | audio_class->ctrl_intf; setup->wLength = 2; volume_hex = -0xDB00 / 100 * volume + 0xdb00; @@ -222,7 +225,6 @@ int usbh_audio_set_mute(struct usbh_audio *audio_class, const char *name, uint8_ { struct usb_setup_packet *setup; int ret; - uint8_t intf = 0xff; uint8_t feature_id = 0xff; if (!audio_class || !audio_class->hport) { @@ -230,21 +232,16 @@ int usbh_audio_set_mute(struct usbh_audio *audio_class, const char *name, uint8_ } setup = audio_class->hport->setup; - for (size_t i = 0; i < audio_class->module_num; i++) { - if (strcmp(name, audio_class->module[i].name) == 0) { - intf = audio_class->ctrl_intf; - feature_id = audio_class->module[i].feature_unit_id; + for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) { + if (strcmp(name, audio_class->as_msg_table[i].stream_name) == 0) { + feature_id = audio_class->as_msg_table[i].feature_terminal_id; } } - if (intf == 0xff) { - return -USB_ERR_NODEV; - } - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; setup->bRequest = AUDIO_REQUEST_SET_CUR; setup->wValue = (AUDIO_FU_CONTROL_MUTE << 8) | ch; - setup->wIndex = (feature_id << 8) | intf; + setup->wIndex = (feature_id << 8) | audio_class->ctrl_intf; setup->wLength = 1; memcpy(g_audio_buf, &mute, 1); @@ -257,26 +254,28 @@ void usbh_audio_list_module(struct usbh_audio *audio_class) { USB_LOG_INFO("============= Audio module information ===================\r\n"); USB_LOG_RAW("bcdADC :%04x\r\n", audio_class->bcdADC); - USB_LOG_RAW("Num of modules :%u\r\n", audio_class->module_num); - USB_LOG_RAW("Num of altsettings:%u\r\n", audio_class->num_of_intf_altsettings); + USB_LOG_RAW("Num of audio stream :%u\r\n", audio_class->stream_intf_num); - for (uint8_t i = 0; i < audio_class->module_num; i++) { - USB_LOG_RAW(" module name :%s\r\n", audio_class->module[i].name); - USB_LOG_RAW(" module feature unit id :%d\r\n", audio_class->module[i].feature_unit_id); + for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) { + USB_LOG_RAW("\tstream name :%s\r\n", audio_class->as_msg_table[i].stream_name); + USB_LOG_RAW("\tstream intf :%u\r\n", audio_class->as_msg_table[i].stream_intf); + USB_LOG_RAW("\tNum of altsetting :%u\r\n", audio_class->as_msg_table[i].num_of_altsetting); - for (uint8_t j = 0; j < audio_class->num_of_intf_altsettings; j++) { + for (uint8_t j = 0; j < audio_class->as_msg_table[i].num_of_altsetting; j++) { if (j == 0) { - USB_LOG_RAW(" Ingore altsetting 0\r\n"); + USB_LOG_RAW("\t\tIngore altsetting 0\r\n"); continue; } - USB_LOG_RAW(" Altsetting %u\r\n", j); - USB_LOG_RAW(" module channels :%u\r\n", audio_class->module[i].altsetting[j].channels); - //USB_LOG_RAW(" module format_type :%u\r\n",audio_class->module[i].altsetting[j].format_type); - USB_LOG_RAW(" module bitresolution :%u\r\n", audio_class->module[i].altsetting[j].bitresolution); - USB_LOG_RAW(" module sampfreq num :%u\r\n", audio_class->module[i].altsetting[j].sampfreq_num); + USB_LOG_RAW("\t\tAltsetting :%u\r\n", j); + USB_LOG_RAW("\t\t\tbNrChannels :%u\r\n", audio_class->as_msg_table[i].as_format[j].bNrChannels); + USB_LOG_RAW("\t\t\tbBitResolution :%u\r\n", audio_class->as_msg_table[i].as_format[j].bBitResolution); + USB_LOG_RAW("\t\t\tbSamFreqType :%u\r\n", audio_class->as_msg_table[i].as_format[j].bSamFreqType); - for (uint8_t k = 0; k < audio_class->module[i].altsetting[j].sampfreq_num; k++) { - USB_LOG_RAW(" module sampfreq :%d hz\r\n", audio_class->module[i].altsetting[j].sampfreq[k]); + for (uint8_t k = 0; k < audio_class->as_msg_table[i].as_format[j].bSamFreqType; k++) { + uint32_t freq = 0; + + memcpy(&freq, &audio_class->as_msg_table[i].as_format[j].tSamFreq[3 * k], 3); + USB_LOG_RAW("\t\t\t\tSampleFreq :%u\r\n", freq); } } } @@ -293,7 +292,6 @@ static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) uint8_t input_offset = 0; uint8_t output_offset = 0; uint8_t feature_unit_offset = 0; - uint8_t format_offset = 0; uint8_t *p; struct usbh_audio *audio_class = usbh_audio_class_alloc(); @@ -304,8 +302,6 @@ static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) audio_class->hport = hport; audio_class->ctrl_intf = intf; - audio_class->num_of_intf_altsettings = hport->config.intf[intf + 1].altsetting_num; - hport->config.intf[intf].priv = audio_class; p = hport->raw_config_desc; @@ -331,39 +327,19 @@ static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) case AUDIO_CONTROL_INPUT_TERMINAL: { struct audio_cs_if_ac_input_terminal_descriptor *desc = (struct audio_cs_if_ac_input_terminal_descriptor *)p; - audio_class->module[input_offset].input_terminal_id = desc->bTerminalID; - audio_class->module[input_offset].input_terminal_type = desc->wTerminalType; - audio_class->module[input_offset].input_channel_config = desc->wChannelConfig; - - if (desc->wTerminalType == AUDIO_TERMINAL_STREAMING) { - audio_class->module[input_offset].terminal_link_id = desc->bTerminalID; - } - if (desc->wTerminalType == AUDIO_INTERM_MIC) { - audio_class->module[input_offset].name = "mic"; - } + memcpy(&audio_class->ac_msg_table[input_offset].ac_input, desc, sizeof(struct audio_cs_if_ac_input_terminal_descriptor)); input_offset++; } break; - break; case AUDIO_CONTROL_OUTPUT_TERMINAL: { struct audio_cs_if_ac_output_terminal_descriptor *desc = (struct audio_cs_if_ac_output_terminal_descriptor *)p; - audio_class->module[output_offset].output_terminal_id = desc->bTerminalID; - audio_class->module[output_offset].output_terminal_type = desc->wTerminalType; - if (desc->wTerminalType == AUDIO_TERMINAL_STREAMING) { - audio_class->module[output_offset].terminal_link_id = desc->bTerminalID; - } - if (desc->wTerminalType == AUDIO_OUTTERM_SPEAKER) { - audio_class->module[output_offset].name = "speaker"; - } + + memcpy(&audio_class->ac_msg_table[output_offset].ac_output, desc, sizeof(struct audio_cs_if_ac_output_terminal_descriptor)); output_offset++; } break; case AUDIO_CONTROL_FEATURE_UNIT: { struct audio_cs_if_ac_feature_unit_descriptor *desc = (struct audio_cs_if_ac_feature_unit_descriptor *)p; - audio_class->module[feature_unit_offset].feature_unit_id = desc->bUnitID; - audio_class->module[feature_unit_offset].feature_unit_controlsize = desc->bControlSize; - for (uint8_t j = 0; j < desc->bControlSize; j++) { - audio_class->module[feature_unit_offset].feature_unit_controls[j] = p[6 + j]; - } + memcpy(&audio_class->ac_msg_table[feature_unit_offset].ac_feature_unit, desc, desc->bLength); feature_unit_offset++; } break; case AUDIO_CONTROL_PROCESSING_UNIT: @@ -372,34 +348,33 @@ static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) default: break; } - } else if ((cur_iface < (audio_class->ctrl_intf + cur_iface_count)) && (cur_iface > audio_class->ctrl_intf)) { + } else if ((cur_iface > audio_class->ctrl_intf) && (cur_iface < (audio_class->ctrl_intf + cur_iface_count))) { switch (p[DESC_bDescriptorSubType]) { - case AUDIO_STREAMING_GENERAL: + case AUDIO_STREAMING_GENERAL: { + struct audio_cs_if_as_general_descriptor *desc = (struct audio_cs_if_as_general_descriptor *)p; - break; + /* all altsetting have the same general */ + audio_class->as_msg_table[cur_iface - audio_class->ctrl_intf - 1].stream_intf = cur_iface; + memcpy(&audio_class->as_msg_table[cur_iface - audio_class->ctrl_intf - 1].as_general, desc, sizeof(struct audio_cs_if_as_general_descriptor)); + } break; case AUDIO_STREAMING_FORMAT_TYPE: { struct audio_cs_if_as_format_type_descriptor *desc = (struct audio_cs_if_as_format_type_descriptor *)p; - - audio_class->module[format_offset].data_intf = cur_iface; - audio_class->module[format_offset].altsetting[cur_alt_setting].channels = desc->bNrChannels; - audio_class->module[format_offset].altsetting[cur_alt_setting].format_type = desc->bFormatType; - audio_class->module[format_offset].altsetting[cur_alt_setting].bitresolution = desc->bBitResolution; - audio_class->module[format_offset].altsetting[cur_alt_setting].sampfreq_num = desc->bSamFreqType; - - for (uint8_t j = 0; j < desc->bSamFreqType; j++) { - audio_class->module[format_offset].altsetting[cur_alt_setting].sampfreq[j] = (uint32_t)(p[10 + j * 3] << 16) | - (uint32_t)(p[9 + j * 3] << 8) | - (uint32_t)(p[8 + j * 3] << 0); - } - if (cur_alt_setting == (hport->config.intf[intf + 1].altsetting_num - 1)) { - format_offset++; - } + audio_class->as_msg_table[cur_iface - audio_class->ctrl_intf - 1].num_of_altsetting = (cur_alt_setting + 1); + memcpy(&audio_class->as_msg_table[cur_iface - audio_class->ctrl_intf - 1].as_format[cur_alt_setting], desc, desc->bLength); } break; default: break; } } break; + case AUDIO_ENDPOINT_DESCRIPTOR_TYPE: + if ((cur_iface > audio_class->ctrl_intf) && (cur_iface < (audio_class->ctrl_intf + cur_iface_count))) { + if (p[DESC_bDescriptorSubType] == AUDIO_ENDPOINT_GENERAL) { + struct audio_cs_ep_ep_general_descriptor *desc = (struct audio_cs_ep_ep_general_descriptor *)p; + audio_class->as_msg_table[cur_iface - audio_class->ctrl_intf - 1].ep_attr = desc->bmAttributes; + } + } + break; default: break; } @@ -407,16 +382,86 @@ static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) p += p[DESC_bLength]; } - if ((input_offset != output_offset) && (input_offset != feature_unit_offset) && (input_offset != format_offset)) { + if ((input_offset != output_offset) && (input_offset != feature_unit_offset)) { + USB_LOG_ERR("Audio descriptor is invalid\r\n"); return -USB_ERR_INVAL; } - audio_class->module_num = input_offset; + audio_class->stream_intf_num = input_offset; + + for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) { + /* Search 0x0101 in input or output desc */ + for (uint8_t streamidx = 0; streamidx < audio_class->stream_intf_num; streamidx++) { + if (audio_class->as_msg_table[i].as_general.bTerminalLink == audio_class->ac_msg_table[streamidx].ac_input.bTerminalID) { + /* INPUT --> FEATURE UNIT --> OUTPUT */ + audio_class->as_msg_table[i].input_terminal_id = audio_class->ac_msg_table[streamidx].ac_input.bTerminalID; + + /* Search input terminal id in feature desc */ + for (uint8_t featureidx = 0; featureidx < audio_class->stream_intf_num; featureidx++) { + if (audio_class->ac_msg_table[streamidx].ac_input.bTerminalID == audio_class->ac_msg_table[featureidx].ac_feature_unit.bSourceID) { + audio_class->as_msg_table[i].feature_terminal_id = audio_class->ac_msg_table[featureidx].ac_feature_unit.bUnitID; + + /* Search feature unit id in output desc */ + for (uint8_t outputid = 0; outputid < audio_class->stream_intf_num; outputid++) { + if (audio_class->ac_msg_table[featureidx].ac_feature_unit.bUnitID == audio_class->ac_msg_table[outputid].ac_output.bSourceID) { + audio_class->as_msg_table[i].output_terminal_id = audio_class->ac_msg_table[outputid].ac_output.bTerminalID; + + switch (audio_class->ac_msg_table[outputid].ac_output.wTerminalType) { + case AUDIO_OUTTERM_SPEAKER: + audio_class->as_msg_table[i].stream_name = "speaker"; + break; + case AUDIO_OUTTERM_HEADPHONES: + audio_class->as_msg_table[i].stream_name = "headphoens"; + break; + case AUDIO_OUTTERM_HEADDISPLAY: + audio_class->as_msg_table[i].stream_name = "headdisplay"; + break; + default: + audio_class->as_msg_table[i].stream_name = "unknown"; + break; + } + break; + } + } + break; + } + } + } else if (audio_class->as_msg_table[i].as_general.bTerminalLink == audio_class->ac_msg_table[streamidx].ac_output.bTerminalID) { + /* OUTPUT --> FEATURE UNIT --> INPUT */ + audio_class->as_msg_table[i].output_terminal_id = audio_class->ac_msg_table[streamidx].ac_output.bTerminalID; + + /* Search output terminal id in feature desc */ + for (uint8_t featureidx = 0; featureidx < audio_class->stream_intf_num; featureidx++) { + if (audio_class->ac_msg_table[streamidx].ac_output.bSourceID == audio_class->ac_msg_table[featureidx].ac_feature_unit.bUnitID) { + audio_class->as_msg_table[i].feature_terminal_id = audio_class->ac_msg_table[featureidx].ac_feature_unit.bUnitID; + + /* Search feature unit id in input desc */ + for (uint8_t inputid = 0; inputid < audio_class->stream_intf_num; inputid++) { + if (audio_class->ac_msg_table[featureidx].ac_feature_unit.bSourceID == audio_class->ac_msg_table[inputid].ac_input.bTerminalID) { + audio_class->as_msg_table[i].input_terminal_id = audio_class->ac_msg_table[inputid].ac_input.bTerminalID; + + switch (audio_class->ac_msg_table[inputid].ac_input.wTerminalType) { + case AUDIO_INTERM_MIC: + audio_class->as_msg_table[i].stream_name = "mic"; + break; + default: + audio_class->as_msg_table[i].stream_name = "unknown"; + break; + } + break; + } + } + break; + } + } + } + } + } - for (size_t i = 0; i < audio_class->module_num; i++) { - ret = usbh_audio_close(audio_class, audio_class->module[i].name); + for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) { + ret = usbh_audio_close(audio_class, audio_class->as_msg_table[i].stream_name); if (ret < 0) { - USB_LOG_ERR("Fail to close audio module :%s\r\n", audio_class->module[i].name); + USB_LOG_ERR("Fail to close audio stream :%s\r\n", audio_class->as_msg_table[i].stream_name); return ret; } } diff --git a/components/drivers/usb/cherryusb/class/audio/usbh_audio.h b/components/drivers/usb/cherryusb/class/audio/usbh_audio.h index 038a8f7e93..d6eeeffb02 100644 --- a/components/drivers/usb/cherryusb/class/audio/usbh_audio.h +++ b/components/drivers/usb/cherryusb/class/audio/usbh_audio.h @@ -8,34 +8,26 @@ #include "usb_audio.h" -struct usbh_audio_format_type { - uint8_t channels; - uint8_t format_type; - uint8_t bitresolution; - uint8_t sampfreq_num; - uint32_t sampfreq[3]; +#ifndef CONFIG_USBHOST_AUDIO_MAX_STREAMS +#define CONFIG_USBHOST_AUDIO_MAX_STREAMS 3 +#endif + +struct usbh_audio_ac_msg { + struct audio_cs_if_ac_input_terminal_descriptor ac_input; + struct audio_cs_if_ac_feature_unit_descriptor ac_feature_unit; + struct audio_cs_if_ac_output_terminal_descriptor ac_output; }; -/** - * bSourceID in feature_unit = input_terminal_id - * bSourceID in output_terminal = feature_unit_id - * terminal_link_id = input_terminal_id or output_terminal_id (if input_terminal_type or output_terminal_type is 0x0101) - * - * -*/ -struct usbh_audio_module { - const char *name; - uint8_t data_intf; +struct usbh_audio_as_msg { + const char *stream_name; + uint8_t stream_intf; uint8_t input_terminal_id; - uint16_t input_terminal_type; - uint16_t input_channel_config; + uint8_t feature_terminal_id; uint8_t output_terminal_id; - uint16_t output_terminal_type; - uint8_t feature_unit_id; - uint8_t feature_unit_controlsize; - uint8_t feature_unit_controls[8]; - uint8_t terminal_link_id; - struct usbh_audio_format_type altsetting[CONFIG_USBHOST_MAX_INTF_ALTSETTINGS]; + uint8_t ep_attr; + uint8_t num_of_altsetting; + struct audio_cs_if_as_general_descriptor as_general; + struct audio_cs_if_as_format_type_descriptor as_format[CONFIG_USBHOST_MAX_INTF_ALTSETTINGS]; }; struct usbh_audio { @@ -50,9 +42,9 @@ struct usbh_audio { bool is_opened; uint16_t bcdADC; uint8_t bInCollection; - uint8_t num_of_intf_altsettings; - struct usbh_audio_module module[2]; - uint8_t module_num; + uint8_t stream_intf_num; + struct usbh_audio_ac_msg ac_msg_table[CONFIG_USBHOST_AUDIO_MAX_STREAMS]; + struct usbh_audio_as_msg as_msg_table[CONFIG_USBHOST_AUDIO_MAX_STREAMS]; void *user_data; }; @@ -61,7 +53,7 @@ struct usbh_audio { extern "C" { #endif -int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t samp_freq); +int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t samp_freq, uint8_t bitresolution); int usbh_audio_close(struct usbh_audio *audio_class, const char *name); int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint8_t ch, uint8_t volume); int usbh_audio_set_mute(struct usbh_audio *audio_class, const char *name, uint8_t ch, bool mute); diff --git a/components/drivers/usb/cherryusb/class/cdc/usb_cdc.h b/components/drivers/usb/cherryusb/class/cdc/usb_cdc.h index 2bf0a17a51..eb2b286269 100644 --- a/components/drivers/usb/cherryusb/class/cdc/usb_cdc.h +++ b/components/drivers/usb/cherryusb/class/cdc/usb_cdc.h @@ -421,7 +421,7 @@ struct cdc_ncm_ndp16 { 0x02, /* bInterfaceCount */ \ USB_DEVICE_CLASS_CDC, /* bFunctionClass */ \ CDC_ABSTRACT_CONTROL_MODEL, /* bFunctionSubClass */ \ - CDC_COMMON_PROTOCOL_AT_COMMANDS, /* bFunctionProtocol */ \ + CDC_COMMON_PROTOCOL_NONE, /* bFunctionProtocol */ \ 0x00, /* iFunction */ \ 0x09, /* bLength */ \ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ @@ -430,7 +430,7 @@ struct cdc_ncm_ndp16 { 0x01, /* bNumEndpoints */ \ USB_DEVICE_CLASS_CDC, /* bInterfaceClass */ \ CDC_ABSTRACT_CONTROL_MODEL, /* bInterfaceSubClass */ \ - CDC_COMMON_PROTOCOL_AT_COMMANDS, /* bInterfaceProtocol */ \ + CDC_COMMON_PROTOCOL_NONE, /* bInterfaceProtocol */ \ str_idx, /* iInterface */ \ 0x05, /* bLength */ \ CDC_CS_INTERFACE, /* bDescriptorType */ \ @@ -489,8 +489,8 @@ struct cdc_ncm_ndp16 { bFirstInterface, /* bFirstInterface */ \ 0x02, /* bInterfaceCount */ \ USB_DEVICE_CLASS_WIRELESS, /* bFunctionClass */ \ - CDC_DIRECT_LINE_CONTROL_MODEL, /* bFunctionSubClass */ \ - CDC_COMMON_PROTOCOL_AT_COMMANDS_PCCA_101_AND_ANNEXO, /* bFunctionProtocol */ \ + 0x01, /* bFunctionSubClass */ \ + 0x03, /* bFunctionProtocol */ \ 0x00, /* iFunction */ \ 0x09, /* bLength */ \ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ @@ -498,8 +498,8 @@ struct cdc_ncm_ndp16 { 0x00, /* bAlternateSetting */ \ 0x01, /* bNumEndpoints */ \ USB_DEVICE_CLASS_WIRELESS, /* bInterfaceClass */ \ - CDC_DIRECT_LINE_CONTROL_MODEL, /* bInterfaceSubClass */ \ - CDC_COMMON_PROTOCOL_AT_COMMANDS_PCCA_101_AND_ANNEXO, /* bInterfaceProtocol */ \ + 0x01, /* bInterfaceSubClass */ \ + 0x03, /* bInterfaceProtocol */ \ str_idx, /* iInterface */ \ 0x05, /* bLength */ \ CDC_CS_INTERFACE, /* bDescriptorType */ \ diff --git a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.c b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.c index 957c6b2e1a..ceb5ad0c2d 100644 --- a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.c +++ b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.c @@ -19,11 +19,11 @@ static uint32_t g_devinuse = 0; static struct usbh_cdc_acm *usbh_cdc_acm_class_alloc(void) { - int devno; + uint8_t devno; for (devno = 0; devno < CONFIG_USBHOST_MAX_CDC_ACM_CLASS; devno++) { - if ((g_devinuse & (1 << devno)) == 0) { - g_devinuse |= (1 << devno); + if ((g_devinuse & (1U << devno)) == 0) { + g_devinuse |= (1U << devno); memset(&g_cdc_acm_class[devno], 0, sizeof(struct usbh_cdc_acm)); g_cdc_acm_class[devno].minor = devno; return &g_cdc_acm_class[devno]; @@ -34,10 +34,10 @@ static struct usbh_cdc_acm *usbh_cdc_acm_class_alloc(void) static void usbh_cdc_acm_class_free(struct usbh_cdc_acm *cdc_acm_class) { - int devno = cdc_acm_class->minor; + uint8_t devno = cdc_acm_class->minor; - if (devno >= 0 && devno < 32) { - g_devinuse &= ~(1 << devno); + if (devno < 32) { + g_devinuse &= ~(1U << devno); } memset(cdc_acm_class, 0, sizeof(struct usbh_cdc_acm)); } @@ -266,10 +266,10 @@ const struct usbh_class_driver cdc_data_class_driver = { }; CLASS_INFO_DEFINE const struct usbh_class_info cdc_acm_class_info = { - .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL, + .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS, .class = USB_DEVICE_CLASS_CDC, .subclass = CDC_ABSTRACT_CONTROL_MODEL, - .protocol = CDC_COMMON_PROTOCOL_AT_COMMANDS, + .protocol = 0x00, .id_table = NULL, .class_driver = &cdc_acm_class_driver }; diff --git a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.c b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.c index 2456fba54a..094241aab5 100644 --- a/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.c +++ b/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.c @@ -48,7 +48,7 @@ static int usbh_cdc_ncm_get_ntb_parameters(struct usbh_cdc_ncm *cdc_ncm_class, s setup->wLength = 28; ret = usbh_control_transfer(cdc_ncm_class->hport, setup, g_cdc_ncm_buf); - if (ret < 0) { + if (ret < 8) { return ret; } diff --git a/components/drivers/usb/cherryusb/class/hid/usbh_hid.c b/components/drivers/usb/cherryusb/class/hid/usbh_hid.c index d2a25b3059..de1ddc0748 100644 --- a/components/drivers/usb/cherryusb/class/hid/usbh_hid.c +++ b/components/drivers/usb/cherryusb/class/hid/usbh_hid.c @@ -20,18 +20,18 @@ #define INTF_DESC_bInterfaceNumber 2 /** Interface number offset */ #define INTF_DESC_bAlternateSetting 3 /** Alternate setting offset */ -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hid_buf[CONFIG_USBHOST_MAX_HID_CLASS][USB_ALIGN_UP(256, CONFIG_USB_ALIGN_SIZE)]; +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hid_buf[CONFIG_USBHOST_MAX_HID_CLASS][USB_ALIGN_UP(64, CONFIG_USB_ALIGN_SIZE)]; static struct usbh_hid g_hid_class[CONFIG_USBHOST_MAX_HID_CLASS]; static uint32_t g_devinuse = 0; static struct usbh_hid *usbh_hid_class_alloc(void) { - int devno; + uint8_t devno; for (devno = 0; devno < CONFIG_USBHOST_MAX_HID_CLASS; devno++) { - if ((g_devinuse & (1 << devno)) == 0) { - g_devinuse |= (1 << devno); + if ((g_devinuse & (1U << devno)) == 0) { + g_devinuse |= (1U << devno); memset(&g_hid_class[devno], 0, sizeof(struct usbh_hid)); g_hid_class[devno].minor = devno; return &g_hid_class[devno]; @@ -42,18 +42,17 @@ static struct usbh_hid *usbh_hid_class_alloc(void) static void usbh_hid_class_free(struct usbh_hid *hid_class) { - int devno = hid_class->minor; + uint8_t devno = hid_class->minor; - if (devno >= 0 && devno < 32) { - g_devinuse &= ~(1 << devno); + if (devno < 32) { + g_devinuse &= ~(1U << devno); } memset(hid_class, 0, sizeof(struct usbh_hid)); } -static int usbh_hid_get_report_descriptor(struct usbh_hid *hid_class, uint8_t *buffer) +int usbh_hid_get_report_descriptor(struct usbh_hid *hid_class, uint8_t *buffer, uint32_t buflen) { struct usb_setup_packet *setup; - int ret; if (!hid_class || !hid_class->hport) { return -USB_ERR_INVAL; @@ -64,14 +63,9 @@ static int usbh_hid_get_report_descriptor(struct usbh_hid *hid_class, uint8_t *b setup->bRequest = USB_REQUEST_GET_DESCRIPTOR; setup->wValue = HID_DESCRIPTOR_TYPE_HID_REPORT << 8; setup->wIndex = hid_class->intf; - setup->wLength = hid_class->report_size; + setup->wLength = buflen; - ret = usbh_control_transfer(hid_class->hport, setup, g_hid_buf[hid_class->minor]); - if (ret < 0) { - return ret; - } - memcpy(buffer, g_hid_buf[hid_class->minor], ret - 8); - return ret; + return usbh_control_transfer(hid_class->hport, setup, buffer); } int usbh_hid_set_idle(struct usbh_hid *hid_class, uint8_t report_id, uint8_t duration) @@ -109,7 +103,7 @@ int usbh_hid_get_idle(struct usbh_hid *hid_class, uint8_t *buffer) setup->wLength = 1; ret = usbh_control_transfer(hid_class->hport, setup, g_hid_buf[hid_class->minor]); - if (ret < 0) { + if (ret < 8) { return ret; } memcpy(buffer, g_hid_buf[hid_class->minor], ret - 8); @@ -169,7 +163,7 @@ int usbh_hid_get_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t setup->wLength = buflen; ret = usbh_control_transfer(hid_class->hport, setup, g_hid_buf[hid_class->minor]); - if (ret < 0) { + if (ret < 8) { return ret; } memcpy(buffer, g_hid_buf[hid_class->minor], ret - 8); @@ -215,11 +209,6 @@ int usbh_hid_connect(struct usbh_hubport *hport, uint8_t intf) } hid_class->report_size = desc->subdesc[0].wDescriptorLength; - - if (hid_class->report_size > sizeof(g_hid_buf[hid_class->minor])) { - USB_LOG_ERR("HID report descriptor too large\r\n"); - return -USB_ERR_INVAL; - } found = true; goto found; } @@ -247,7 +236,8 @@ found: USB_LOG_WRN("Do not support set idle\r\n"); } - ret = usbh_hid_get_report_descriptor(hid_class, hid_class->report_desc); + /* We read report desc but do nothing (because of too much memory usage for parsing report desc, parsed by users) */ + ret = usbh_hid_get_report_descriptor(hid_class, g_hid_buf[hid_class->minor], MIN(sizeof(g_hid_buf[hid_class->minor]), hid_class->report_size)); if (ret < 0) { return ret; } diff --git a/components/drivers/usb/cherryusb/class/hid/usbh_hid.h b/components/drivers/usb/cherryusb/class/hid/usbh_hid.h index 6a6cef1645..5e8fce61f7 100644 --- a/components/drivers/usb/cherryusb/class/hid/usbh_hid.h +++ b/components/drivers/usb/cherryusb/class/hid/usbh_hid.h @@ -15,7 +15,6 @@ struct usbh_hid { struct usbh_urb intin_urb; /* INTR IN urb */ struct usbh_urb intout_urb; /* INTR OUT urb */ - uint8_t report_desc[256]; uint16_t report_size; uint8_t protocol; @@ -29,6 +28,7 @@ struct usbh_hid { extern "C" { #endif +int usbh_hid_get_report_descriptor(struct usbh_hid *hid_class, uint8_t *buffer, uint32_t buflen); int usbh_hid_set_idle(struct usbh_hid *hid_class, uint8_t report_id, uint8_t duration); int usbh_hid_get_idle(struct usbh_hid *hid_class, uint8_t *buffer); int usbh_hid_set_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t report_id, uint8_t *buffer, uint32_t buflen); diff --git a/components/drivers/usb/cherryusb/class/hub/usbh_hub.c b/components/drivers/usb/cherryusb/class/hub/usbh_hub.c index a39a8d15c7..2bcf4ddb48 100644 --- a/components/drivers/usb/cherryusb/class/hub/usbh_hub.c +++ b/components/drivers/usb/cherryusb/class/hub/usbh_hub.c @@ -33,11 +33,11 @@ static uint32_t g_devinuse = 0; static struct usbh_hub *usbh_hub_class_alloc(void) { - int devno; + uint8_t devno; for (devno = 0; devno < CONFIG_USBHOST_MAX_EXTHUBS; devno++) { - if ((g_devinuse & (1 << devno)) == 0) { - g_devinuse |= (1 << devno); + if ((g_devinuse & (1U << devno)) == 0) { + g_devinuse |= (1U << devno); memset(&g_hub_class[devno], 0, sizeof(struct usbh_hub)); g_hub_class[devno].index = EXTHUB_FIRST_INDEX + devno; return &g_hub_class[devno]; @@ -48,10 +48,10 @@ static struct usbh_hub *usbh_hub_class_alloc(void) static void usbh_hub_class_free(struct usbh_hub *hub_class) { - int devno = hub_class->index - EXTHUB_FIRST_INDEX; + uint8_t devno = hub_class->index - EXTHUB_FIRST_INDEX; - if (devno >= 0 && devno < 32) { - g_devinuse &= ~(1 << devno); + if (devno < 32) { + g_devinuse &= ~(1U << devno); } memset(hub_class, 0, sizeof(struct usbh_hub)); } diff --git a/components/drivers/usb/cherryusb/class/msc/usbd_msc.c b/components/drivers/usb/cherryusb/class/msc/usbd_msc.c index c791fd0c7e..1f84d02c9b 100644 --- a/components/drivers/usb/cherryusb/class/msc/usbd_msc.c +++ b/components/drivers/usb/cherryusb/class/msc/usbd_msc.c @@ -109,7 +109,7 @@ void msc_storage_notify_handler(uint8_t busid, uint8_t event, void *arg) if (g_usbd_msc[busid].usbd_msc_mq == NULL) { USB_LOG_ERR("No memory to alloc for g_usbd_msc[busid].usbd_msc_mq\r\n"); } - g_usbd_msc[busid].usbd_msc_thread = usb_osal_thread_create("usbd_msc", CONFIG_USBDEV_MSC_STACKSIZE, CONFIG_USBDEV_MSC_PRIO, usbdev_msc_thread, (void *)busid); + g_usbd_msc[busid].usbd_msc_thread = usb_osal_thread_create("usbd_msc", CONFIG_USBDEV_MSC_STACKSIZE, CONFIG_USBDEV_MSC_PRIO, usbdev_msc_thread, (void *)(uint32_t)busid); if (g_usbd_msc[busid].usbd_msc_thread == NULL) { USB_LOG_ERR("No memory to alloc for g_usbd_msc[busid].usbd_msc_thread\r\n"); } @@ -915,7 +915,7 @@ static void usbdev_msc_thread(void *argument) { uintptr_t event; int ret; - uint8_t busid = (uint8_t)argument; + uint8_t busid = (uint8_t)(uint32_t)argument; while (1) { ret = usb_osal_mq_recv(g_usbd_msc[busid].usbd_msc_mq, (uintptr_t *)&event, USB_OSAL_WAITING_FOREVER); @@ -977,9 +977,9 @@ struct usbd_interface *usbd_msc_init_intf(uint8_t busid, struct usbd_interface * for (uint8_t i = 0u; i <= g_usbd_msc[busid].max_lun; i++) { usbd_msc_get_cap(busid, i, &g_usbd_msc[busid].scsi_blk_nbr[i], &g_usbd_msc[busid].scsi_blk_size[i]); - if (g_usbd_msc[busid].scsi_blk_size[i] > CONFIG_USBDEV_MSC_MAX_BUFSIZE) { - USB_LOG_ERR("msc block buffer overflow\r\n"); - return NULL; + if (CONFIG_USBDEV_MSC_MAX_BUFSIZE % g_usbd_msc[busid].scsi_blk_size[i]) { + USB_LOG_ERR("CONFIG_USBDEV_MSC_MAX_BUFSIZE must be a multiple of block size\r\n"); + while(1){} } } diff --git a/components/drivers/usb/cherryusb/class/msc/usbh_msc.c b/components/drivers/usb/cherryusb/class/msc/usbh_msc.c index 773b0defb0..1327175fce 100644 --- a/components/drivers/usb/cherryusb/class/msc/usbh_msc.c +++ b/components/drivers/usb/cherryusb/class/msc/usbh_msc.c @@ -23,11 +23,11 @@ static struct usbh_msc_modeswitch_config *g_msc_modeswitch_config = NULL; static struct usbh_msc *usbh_msc_class_alloc(void) { - int devno; + uint8_t devno; for (devno = 0; devno < CONFIG_USBHOST_MAX_MSC_CLASS; devno++) { - if ((g_devinuse & (1 << devno)) == 0) { - g_devinuse |= (1 << devno); + if ((g_devinuse & (1U << devno)) == 0) { + g_devinuse |= (1U << devno); memset(&g_msc_class[devno], 0, sizeof(struct usbh_msc)); g_msc_class[devno].sdchar = 'a' + devno; return &g_msc_class[devno]; @@ -38,10 +38,10 @@ static struct usbh_msc *usbh_msc_class_alloc(void) static void usbh_msc_class_free(struct usbh_msc *msc_class) { - int devno = msc_class->sdchar - 'a'; + uint8_t devno = msc_class->sdchar - 'a'; - if (devno >= 0 && devno < 32) { - g_devinuse &= ~(1 << devno); + if (devno < 32) { + g_devinuse &= ~(1U << devno); } memset(msc_class, 0, sizeof(struct usbh_msc)); } @@ -278,7 +278,12 @@ static int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf) ret = usbh_msc_get_maxlun(msc_class, g_msc_buf[msc_class->sdchar - 'a']); if (ret < 0) { - return ret; + if (ret == -USB_ERR_STALL) { + USB_LOG_WRN("Device does not support multiple LUNs\r\n"); + g_msc_buf[msc_class->sdchar - 'a'][0] = 0; + } else { + return ret; + } } USB_LOG_INFO("Get max LUN:%u\r\n", g_msc_buf[msc_class->sdchar - 'a'][0] + 1); @@ -372,7 +377,6 @@ static int usbh_msc_disconnect(struct usbh_hubport *hport, uint8_t intf) return ret; } - int usbh_msc_scsi_write10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors) { struct CBW *cbw; diff --git a/components/drivers/usb/cherryusb/class/template/usbh_xxx.c b/components/drivers/usb/cherryusb/class/template/usbh_xxx.c index 22b3636d62..78d531fc3c 100644 --- a/components/drivers/usb/cherryusb/class/template/usbh_xxx.c +++ b/components/drivers/usb/cherryusb/class/template/usbh_xxx.c @@ -9,11 +9,11 @@ static uint32_t g_devinuse = 0; static struct usbh_xxx *usbh_xxx_class_alloc(void) { - int devno; + uint8_t devno; for (devno = 0; devno < CONFIG_USBHOST_MAX_CUSTOM_CLASS; devno++) { - if ((g_devinuse & (1 << devno)) == 0) { - g_devinuse |= (1 << devno); + if ((g_devinuse & (1U << devno)) == 0) { + g_devinuse |= (1U << devno); memset(&g_xxx_class[devno], 0, sizeof(struct usbh_xxx)); g_xxx_class[devno].minor = devno; return &g_xxx_class[devno]; @@ -24,10 +24,10 @@ static struct usbh_xxx *usbh_xxx_class_alloc(void) static void usbh_xxx_class_free(struct usbh_xxx *xxx_class) { - int devno = xxx_class->minor; + uint8_t devno = xxx_class->minor; - if (devno >= 0 && devno < 32) { - g_devinuse &= ~(1 << devno); + if (devno < 32) { + g_devinuse &= ~(1U << devno); } memset(xxx_class, 0, sizeof(struct usbh_xxx)); } diff --git a/components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.c b/components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.c index cbc3c5d6c3..e8c7eb1537 100644 --- a/components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.c +++ b/components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.c @@ -70,7 +70,7 @@ static int usbh_asix_read_cmd(struct usbh_asix *asix_class, setup->wLength = size; ret = usbh_control_transfer(asix_class->hport, setup, g_asix_buf); - if (ret < 0) { + if (ret < 8) { return ret; } memcpy(data, g_asix_buf, ret - 8); @@ -98,9 +98,12 @@ static int usbh_asix_write_cmd(struct usbh_asix *asix_class, setup->wIndex = index; setup->wLength = size; - memcpy(g_asix_buf, data, size); - - return usbh_control_transfer(asix_class->hport, setup, g_asix_buf); + if (data && size) { + memcpy(g_asix_buf, data, size); + return usbh_control_transfer(asix_class->hport, setup, g_asix_buf); + } else { + return usbh_control_transfer(asix_class->hport, setup, NULL); + } } static int usbh_asix_mdio_write(struct usbh_asix *asix_class, int phy_id, int loc, int val) diff --git a/components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.c b/components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.c index cbf7ea4f4d..778ab26479 100644 --- a/components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.c +++ b/components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.c @@ -961,7 +961,7 @@ static int usbh_rtl8152_read_regs(struct usbh_rtl8152 *rtl8152_class, setup->wLength = size; ret = usbh_control_transfer(rtl8152_class->hport, setup, g_rtl8152_buf); - if (ret < 0) { + if (ret < 8) { return ret; } memcpy(data, g_rtl8152_buf, ret - 8); @@ -997,9 +997,10 @@ static int generic_ocp_read(struct usbh_rtl8152 *tp, uint16_t index, uint16_t si { uint16_t limit = 64; int ret = 0; + uint8_t *buf = data; /* both size and indix must be 4 bytes align */ - if ((size & 3) || !size || (index & 3) || !data) + if ((size & 3) || !size || (index & 3) || !buf) return -USB_ERR_INVAL; if ((uint32_t)index + (uint32_t)size > 0xffff) @@ -1007,20 +1008,20 @@ static int generic_ocp_read(struct usbh_rtl8152 *tp, uint16_t index, uint16_t si while (size) { if (size > limit) { - ret = usbh_rtl8152_read_regs(tp, index, type, limit, data); + ret = usbh_rtl8152_read_regs(tp, index, type, limit, buf); if (ret < 0) break; index += limit; - data += limit; + buf += limit; size -= limit; } else { - ret = usbh_rtl8152_read_regs(tp, index, type, size, data); + ret = usbh_rtl8152_read_regs(tp, index, type, size, buf); if (ret < 0) break; index += size; - data += size; + buf += size; size = 0; break; } @@ -1035,9 +1036,10 @@ static int generic_ocp_write(struct usbh_rtl8152 *tp, uint16_t index, uint16_t b int ret; uint16_t byteen_start, byteen_end, byen; uint16_t limit = 512; + uint8_t *buf = data; /* both size and indix must be 4 bytes align */ - if ((size & 3) || !size || (index & 3) || !data) + if ((size & 3) || !size || (index & 3) || !buf) return -USB_ERR_INVAL; if ((uint32_t)index + (uint32_t)size > 0xffff) @@ -1050,12 +1052,12 @@ static int generic_ocp_write(struct usbh_rtl8152 *tp, uint16_t index, uint16_t b /* Split the first DWORD if the byte_en is not 0xff */ if (byen != BYTE_EN_DWORD) { - ret = usbh_rtl8152_write_regs(tp, index, type | byen, 4, data); + ret = usbh_rtl8152_write_regs(tp, index, type | byen, 4, buf); if (ret < 0) goto error1; index += 4; - data += 4; + buf += 4; size -= 4; } @@ -1070,22 +1072,22 @@ static int generic_ocp_write(struct usbh_rtl8152 *tp, uint16_t index, uint16_t b if (size > limit) { ret = usbh_rtl8152_write_regs(tp, index, type | BYTE_EN_DWORD, - limit, data); + limit, buf); if (ret < 0) goto error1; index += limit; - data += limit; + buf += limit; size -= limit; } else { ret = usbh_rtl8152_write_regs(tp, index, type | BYTE_EN_DWORD, - size, data); + size, buf); if (ret < 0) goto error1; index += size; - data += size; + buf += size; size = 0; break; } @@ -1093,7 +1095,7 @@ static int generic_ocp_write(struct usbh_rtl8152 *tp, uint16_t index, uint16_t b /* Set the last DWORD */ if (byen != BYTE_EN_DWORD) - ret = usbh_rtl8152_write_regs(tp, index, type | byen, 4, data); + ret = usbh_rtl8152_write_regs(tp, index, type | byen, 4, buf); } error1: diff --git a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.c b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.c index 92cafde3d0..d0de5b4cf2 100644 --- a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.c +++ b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.c @@ -17,11 +17,11 @@ static uint32_t g_devinuse = 0; static struct usbh_ch34x *usbh_ch34x_class_alloc(void) { - int devno; + uint8_t devno; for (devno = 0; devno < CONFIG_USBHOST_MAX_CP210X_CLASS; devno++) { - if ((g_devinuse & (1 << devno)) == 0) { - g_devinuse |= (1 << devno); + if ((g_devinuse & (1U << devno)) == 0) { + g_devinuse |= (1U << devno); memset(&g_ch34x_class[devno], 0, sizeof(struct usbh_ch34x)); g_ch34x_class[devno].minor = devno; return &g_ch34x_class[devno]; @@ -32,10 +32,10 @@ static struct usbh_ch34x *usbh_ch34x_class_alloc(void) static void usbh_ch34x_class_free(struct usbh_ch34x *ch34x_class) { - int devno = ch34x_class->minor; + uint8_t devno = ch34x_class->minor; - if (devno >= 0 && devno < 32) { - g_devinuse &= ~(1 << devno); + if (devno < 32) { + g_devinuse &= ~(1U << devno); } memset(ch34x_class, 0, sizeof(struct usbh_ch34x)); } diff --git a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.c b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.c index a82ee0f728..4cd06b95be 100644 --- a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.c +++ b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.c @@ -17,11 +17,11 @@ static uint32_t g_devinuse = 0; static struct usbh_cp210x *usbh_cp210x_class_alloc(void) { - int devno; + uint8_t devno; for (devno = 0; devno < CONFIG_USBHOST_MAX_CP210X_CLASS; devno++) { - if ((g_devinuse & (1 << devno)) == 0) { - g_devinuse |= (1 << devno); + if ((g_devinuse & (1U << devno)) == 0) { + g_devinuse |= (1U << devno); memset(&g_cp210x_class[devno], 0, sizeof(struct usbh_cp210x)); g_cp210x_class[devno].minor = devno; return &g_cp210x_class[devno]; @@ -32,10 +32,10 @@ static struct usbh_cp210x *usbh_cp210x_class_alloc(void) static void usbh_cp210x_class_free(struct usbh_cp210x *cp210x_class) { - int devno = cp210x_class->minor; + uint8_t devno = cp210x_class->minor; - if (devno >= 0 && devno < 32) { - g_devinuse &= ~(1 << devno); + if (devno < 32) { + g_devinuse &= ~(1U << devno); } memset(cp210x_class, 0, sizeof(struct usbh_cp210x)); } diff --git a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.c b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.c index 8b58138b30..4ed698390c 100644 --- a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.c +++ b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.c @@ -17,11 +17,11 @@ static uint32_t g_devinuse = 0; static struct usbh_ftdi *usbh_ftdi_class_alloc(void) { - int devno; + uint8_t devno; for (devno = 0; devno < CONFIG_USBHOST_MAX_FTDI_CLASS; devno++) { - if ((g_devinuse & (1 << devno)) == 0) { - g_devinuse |= (1 << devno); + if ((g_devinuse & (1U << devno)) == 0) { + g_devinuse |= (1U << devno); memset(&g_ftdi_class[devno], 0, sizeof(struct usbh_ftdi)); g_ftdi_class[devno].minor = devno; return &g_ftdi_class[devno]; @@ -32,10 +32,10 @@ static struct usbh_ftdi *usbh_ftdi_class_alloc(void) static void usbh_ftdi_class_free(struct usbh_ftdi *ftdi_class) { - int devno = ftdi_class->minor; + uint8_t devno = ftdi_class->minor; - if (devno >= 0 && devno < 32) { - g_devinuse &= ~(1 << devno); + if (devno < 32) { + g_devinuse &= ~(1U << devno); } memset(ftdi_class, 0, sizeof(struct usbh_ftdi)); } diff --git a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.c b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.c index 5000b4d8a7..42c963db4e 100644 --- a/components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.c +++ b/components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.c @@ -25,11 +25,11 @@ static uint32_t g_devinuse = 0; static struct usbh_pl2303 *usbh_pl2303_class_alloc(void) { - int devno; + uint8_t devno; for (devno = 0; devno < CONFIG_USBHOST_MAX_PL2303_CLASS; devno++) { - if ((g_devinuse & (1 << devno)) == 0) { - g_devinuse |= (1 << devno); + if ((g_devinuse & (1U << devno)) == 0) { + g_devinuse |= (1U << devno); memset(&g_pl2303_class[devno], 0, sizeof(struct usbh_pl2303)); g_pl2303_class[devno].minor = devno; return &g_pl2303_class[devno]; @@ -40,10 +40,10 @@ static struct usbh_pl2303 *usbh_pl2303_class_alloc(void) static void usbh_pl2303_class_free(struct usbh_pl2303 *pl2303_class) { - int devno = pl2303_class->minor; + uint8_t devno = pl2303_class->minor; - if (devno >= 0 && devno < 32) { - g_devinuse &= ~(1 << devno); + if (devno < 32) { + g_devinuse &= ~(1U << devno); } memset(pl2303_class, 0, sizeof(struct usbh_pl2303)); } diff --git a/components/drivers/usb/cherryusb/class/vendor/xbox/usbh_xbox.c b/components/drivers/usb/cherryusb/class/vendor/xbox/usbh_xbox.c index 519d1d36cf..ecfb465190 100644 --- a/components/drivers/usb/cherryusb/class/vendor/xbox/usbh_xbox.c +++ b/components/drivers/usb/cherryusb/class/vendor/xbox/usbh_xbox.c @@ -15,11 +15,11 @@ static uint32_t g_devinuse = 0; static struct usbh_xbox *usbh_xbox_class_alloc(void) { - int devno; + uint8_t devno; for (devno = 0; devno < CONFIG_USBHOST_MAX_XBOX_CLASS; devno++) { - if ((g_devinuse & (1 << devno)) == 0) { - g_devinuse |= (1 << devno); + if ((g_devinuse & (1U << devno)) == 0) { + g_devinuse |= (1U << devno); memset(&g_xbox_class[devno], 0, sizeof(struct usbh_xbox)); g_xbox_class[devno].minor = devno; return &g_xbox_class[devno]; @@ -30,10 +30,10 @@ static struct usbh_xbox *usbh_xbox_class_alloc(void) static void usbh_xbox_class_free(struct usbh_xbox *xbox_class) { - int devno = xbox_class->minor; + uint8_t devno = xbox_class->minor; - if (devno >= 0 && devno < 32) { - g_devinuse &= ~(1 << devno); + if (devno < 32) { + g_devinuse &= ~(1U << devno); } memset(xbox_class, 0, sizeof(struct usbh_xbox)); } diff --git a/components/drivers/usb/cherryusb/class/video/usbd_video.c b/components/drivers/usb/cherryusb/class/video/usbd_video.c index ee8ca5ee30..a1a42cdcf1 100644 --- a/components/drivers/usb/cherryusb/class/video/usbd_video.c +++ b/components/drivers/usb/cherryusb/class/video/usbd_video.c @@ -18,6 +18,10 @@ struct usbd_video_priv { uint8_t power_mode; uint8_t error_code; struct video_entity_info info[3]; + uint8_t *ep_buffer; + uint8_t *stream_buf; + uint32_t stream_len; + uint32_t stream_offset; } g_usbd_video[CONFIG_USBDEV_MAX_BUS]; static int usbd_video_control_request_handler(uint8_t busid, struct usb_setup_packet *setup, uint8_t **data, uint32_t *len) @@ -671,7 +675,7 @@ static int video_class_interface_request_handler(uint8_t busid, struct usb_setup } else { return usbd_video_control_unit_terminal_request_handler(busid, setup, data, len); /* Unit and Terminal Requests */ } - } else if (intf_num == 1) { /* Video Stream Inteface */ + } else if (intf_num == 1) { /* Video Stream Inteface */ return usbd_video_stream_request_handler(busid, setup, data, len); /* Interface Stream Requests */ } return -1; @@ -700,7 +704,7 @@ static void video_notify_handler(uint8_t busid, uint8_t event, void *arg) } } -void usbd_video_probe_and_commit_controls_init(uint8_t busid, uint32_t dwFrameInterval, uint32_t dwMaxVideoFrameSize, uint32_t dwMaxPayloadTransferSize) +static void usbd_video_probe_and_commit_controls_init(uint8_t busid, uint32_t dwFrameInterval, uint32_t dwMaxVideoFrameSize, uint32_t dwMaxPayloadTransferSize) { g_usbd_video[busid].probe.hintUnion.bmHint = 0x01; g_usbd_video[busid].probe.hintUnion1.bmHint = 0; @@ -739,7 +743,8 @@ void usbd_video_probe_and_commit_controls_init(uint8_t busid, uint32_t dwFrameIn g_usbd_video[busid].commit.bMaxVersion = 0; } -struct usbd_interface *usbd_video_init_intf(uint8_t busid, struct usbd_interface *intf, +struct usbd_interface *usbd_video_init_intf(uint8_t busid, + struct usbd_interface *intf, uint32_t dwFrameInterval, uint32_t dwMaxVideoFrameSize, uint32_t dwMaxPayloadTransferSize) @@ -763,6 +768,54 @@ struct usbd_interface *usbd_video_init_intf(uint8_t busid, struct usbd_interface return intf; } +bool usbd_video_stream_split_transfer(uint8_t busid, uint8_t ep) +{ + struct video_payload_header *header = (struct video_payload_header *)g_usbd_video[busid].ep_buffer; + uint32_t remain; + uint32_t len; + bool last_packet = false; + + header->bHeaderLength = 2; + header->headerInfoUnion.headerInfoBits.endOfHeader = 1; + + remain = g_usbd_video[busid].stream_len - g_usbd_video[busid].stream_offset; + + len = MIN(remain, g_usbd_video[busid].probe.dwMaxPayloadTransferSize - header->bHeaderLength); + memcpy(&g_usbd_video[busid].ep_buffer[header->bHeaderLength], + &g_usbd_video[busid].stream_buf[g_usbd_video[busid].stream_offset], + len); + + g_usbd_video[busid].stream_offset += len; + + if (g_usbd_video[busid].stream_offset == g_usbd_video[busid].stream_len) { + last_packet = true; + header->headerInfoUnion.headerInfoBits.endOfFrame = 1; + } + + usbd_ep_start_write(busid, ep, g_usbd_video[busid].ep_buffer, len + header->bHeaderLength); + return last_packet; +} + +int usbd_video_stream_start_write(uint8_t busid, uint8_t ep, uint8_t *ep_buffer, uint8_t *buf, uint32_t len) +{ + if (usb_device_is_configured(busid) == 0) { + return -1; + } + + g_usbd_video[busid].ep_buffer = ep_buffer; + g_usbd_video[busid].stream_buf = buf; + g_usbd_video[busid].stream_len = len; + g_usbd_video[busid].stream_offset = 0; + + struct video_payload_header *header = (struct video_payload_header *)g_usbd_video[busid].ep_buffer; + + header->headerInfoUnion.headerInfoBits.frameIdentifier ^= 1; + header->headerInfoUnion.headerInfoBits.endOfFrame = 0; + + usbd_video_stream_split_transfer(busid, ep); + return 0; +} + uint32_t usbd_video_payload_fill(uint8_t busid, uint8_t *input, uint32_t input_len, uint8_t *output, uint32_t *out_len) { uint32_t packets; @@ -770,7 +823,7 @@ uint32_t usbd_video_payload_fill(uint8_t busid, uint8_t *input, uint32_t input_l uint32_t picture_pos = 0; static uint8_t uvc_header[2] = { 0x02, 0x80 }; - packets = (input_len + (g_usbd_video[busid].probe.dwMaxPayloadTransferSize - 2) ) / (g_usbd_video[busid].probe.dwMaxPayloadTransferSize - 2); + packets = (input_len + (g_usbd_video[busid].probe.dwMaxPayloadTransferSize - 2)) / (g_usbd_video[busid].probe.dwMaxPayloadTransferSize - 2); last_packet_size = input_len - ((packets - 1) * (g_usbd_video[busid].probe.dwMaxPayloadTransferSize - 2)); for (size_t i = 0; i < packets; i++) { diff --git a/components/drivers/usb/cherryusb/class/video/usbd_video.h b/components/drivers/usb/cherryusb/class/video/usbd_video.h index 14636fbc4b..24855c897d 100644 --- a/components/drivers/usb/cherryusb/class/video/usbd_video.h +++ b/components/drivers/usb/cherryusb/class/video/usbd_video.h @@ -20,6 +20,10 @@ struct usbd_interface *usbd_video_init_intf(uint8_t busid, struct usbd_interface void usbd_video_open(uint8_t busid, uint8_t intf); void usbd_video_close(uint8_t busid, uint8_t intf); + +bool usbd_video_stream_split_transfer(uint8_t busid, uint8_t ep); +int usbd_video_stream_start_write(uint8_t busid, uint8_t ep, uint8_t *ep_buffer, uint8_t *buf, uint32_t len); + uint32_t usbd_video_payload_fill(uint8_t busid, uint8_t *input, uint32_t input_len, uint8_t *output, uint32_t *out_len); #ifdef __cplusplus diff --git a/components/drivers/usb/cherryusb/class/video/usbh_video.c b/components/drivers/usb/cherryusb/class/video/usbh_video.c index c5458a403d..043eb1d6bd 100644 --- a/components/drivers/usb/cherryusb/class/video/usbh_video.c +++ b/components/drivers/usb/cherryusb/class/video/usbh_video.c @@ -34,11 +34,11 @@ static uint32_t g_devinuse = 0; static struct usbh_video *usbh_video_class_alloc(void) { - int devno; + uint8_t devno; for (devno = 0; devno < CONFIG_USBHOST_MAX_VIDEO_CLASS; devno++) { - if ((g_devinuse & (1 << devno)) == 0) { - g_devinuse |= (1 << devno); + if ((g_devinuse & (1U << devno)) == 0) { + g_devinuse |= (1U << devno); memset(&g_video_class[devno], 0, sizeof(struct usbh_video)); g_video_class[devno].minor = devno; return &g_video_class[devno]; @@ -49,10 +49,10 @@ static struct usbh_video *usbh_video_class_alloc(void) static void usbh_video_class_free(struct usbh_video *video_class) { - int devno = video_class->minor; + uint8_t devno = video_class->minor; - if (devno >= 0 && devno < 32) { - g_devinuse &= ~(1 << devno); + if (devno < 32) { + g_devinuse &= ~(1U << devno); } memset(video_class, 0, sizeof(struct usbh_video)); } diff --git a/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.c b/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.c index 2b45fb1a07..fa53f8400b 100644 --- a/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.c +++ b/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.c @@ -13,7 +13,7 @@ #define DEV_FORMAT "/dev/rndis" -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_buf[4096]; +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_buf[512]; #define CONFIG_USBHOST_RNDIS_ETH_MAX_FRAME_SIZE 1514 #define CONFIG_USBHOST_RNDIS_ETH_MSG_SIZE (CONFIG_USBHOST_RNDIS_ETH_MAX_FRAME_SIZE + 44) @@ -80,7 +80,7 @@ static int usbh_rndis_init_msg_transfer(struct usbh_rndis *rndis_class) setup->bRequest = CDC_REQUEST_GET_ENCAPSULATED_RESPONSE; setup->wValue = 0; setup->wIndex = 0; - setup->wLength = 4096; + setup->wLength = sizeof(g_rndis_buf); ret = usbh_control_transfer(rndis_class->hport, setup, (uint8_t *)resp); if (ret < 0) { @@ -138,7 +138,7 @@ int usbh_rndis_query_msg_transfer(struct usbh_rndis *rndis_class, uint32_t oid, setup->bRequest = CDC_REQUEST_GET_ENCAPSULATED_RESPONSE; setup->wValue = 0; setup->wIndex = 0; - setup->wLength = 4096; + setup->wLength = sizeof(g_rndis_buf); ret = usbh_control_transfer(rndis_class->hport, setup, (uint8_t *)resp); if (ret < 0) { @@ -195,7 +195,7 @@ static int usbh_rndis_set_msg_transfer(struct usbh_rndis *rndis_class, uint32_t setup->bRequest = CDC_REQUEST_GET_ENCAPSULATED_RESPONSE; setup->wValue = 0; setup->wIndex = 0; - setup->wLength = 4096; + setup->wLength = sizeof(g_rndis_buf); ret = usbh_control_transfer(rndis_class->hport, setup, (uint8_t *)resp); if (ret < 0) { @@ -262,7 +262,7 @@ int usbh_rndis_keepalive(struct usbh_rndis *rndis_class) setup->bRequest = CDC_REQUEST_GET_ENCAPSULATED_RESPONSE; setup->wValue = 0; setup->wIndex = 0; - setup->wLength = 4096; + setup->wLength = sizeof(g_rndis_buf); ret = usbh_control_transfer(rndis_class->hport, setup, (uint8_t *)resp); if (ret < 0) { @@ -387,14 +387,14 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf) } uint32_t packet_filter = 0x0f; - usbh_rndis_set_msg_transfer(rndis_class, OID_GEN_CURRENT_PACKET_FILTER, (uint8_t *)&packet_filter, 4); + ret = usbh_rndis_set_msg_transfer(rndis_class, OID_GEN_CURRENT_PACKET_FILTER, (uint8_t *)&packet_filter, 4); if (ret < 0) { return ret; } USB_LOG_INFO("rndis set OID_GEN_CURRENT_PACKET_FILTER success\r\n"); uint8_t multicast_list[6] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0x01 }; - usbh_rndis_set_msg_transfer(rndis_class, OID_802_3_MULTICAST_LIST, multicast_list, 6); + ret = usbh_rndis_set_msg_transfer(rndis_class, OID_802_3_MULTICAST_LIST, multicast_list, 6); if (ret < 0) { return ret; } |
