diff options
Diffstat (limited to 'components/drivers/usb/usbdevice')
18 files changed, 0 insertions, 10545 deletions
diff --git a/components/drivers/usb/usbdevice/SConscript b/components/drivers/usb/usbdevice/SConscript deleted file mode 100644 index 3cc5bf6d43..0000000000 --- a/components/drivers/usb/usbdevice/SConscript +++ /dev/null @@ -1,38 +0,0 @@ -Import('RTT_ROOT') -from building import * - -cwd = GetCurrentDir() -src = Split(""" -core/usbdevice_core.c -core/usbdevice.c -""") - -if GetDepend('RT_USB_DEVICE_CDC'): - src += Glob('class/cdc_vcom.c') - -if GetDepend('RT_USB_DEVICE_HID'): - src += Glob('class/hid.c') - -if GetDepend('RT_USB_DEVICE_MSTORAGE'): - src += Glob('class/mstorage.c') - -if GetDepend('RT_USB_DEVICE_ECM'): - src += Glob('class/ecm.c') - -if GetDepend('RT_USB_DEVICE_RNDIS'): - src += Glob('class/rndis.c') - -if GetDepend('RT_USB_DEVICE_WINUSB'): - src += Glob('class/winusb.c') - -if GetDepend('RT_USB_DEVICE_AUDIO_MIC'): - src += Glob('class/audio_mic.c') - -if GetDepend('RT_USB_DEVICE_AUDIO_SPEAKER'): - src += Glob('class/audio_speaker.c') - -CPPPATH = [cwd] - -group = DefineGroup('rt_usbd', src, depend = ['RT_USING_USB_DEVICE'], CPPPATH = CPPPATH) - -Return('group') diff --git a/components/drivers/usb/usbdevice/class/audio_mic.c b/components/drivers/usb/usbdevice/class/audio_mic.c deleted file mode 100644 index 9612e6b93f..0000000000 --- a/components/drivers/usb/usbdevice/class/audio_mic.c +++ /dev/null @@ -1,581 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2019-09-07 flybreak the first version - */ - -#include <rthw.h> -#include <rtdevice.h> -#include "drivers/usb_device.h" - -#include "uaudioreg.h" - -#define DBG_TAG "usbd.audio.mic" -#define DBG_LVL DBG_INFO -#include <rtdbg.h> - -#define RECORD_SAMPLERATE 16000 -#define RECORD_CHANNEL 1 -#define RESOLUTION_BITS 16 - -#define RESOLUTION_BYTE (RESOLUTION_BITS / 8) -#define RECORD_PER_MS_SZ ((RECORD_SAMPLERATE * RECORD_CHANNEL * RESOLUTION_BYTE) / 1000) -#define RECORD_BUFFER_SZ (RECORD_PER_MS_SZ * 20) /* 20ms */ - -#if defined(RT_USBD_MIC_DEVICE_NAME) - #define MIC_DEVICE_NAME RT_USBD_MIC_DEVICE_NAME -#else - #define MIC_DEVICE_NAME "mic0" -#endif - -#define EVENT_RECORD_START (1 << 0) -#define EVENT_RECORD_STOP (1 << 1) -#define EVENT_RECORD_DATA (1 << 2) - -#define MIC_INTF_STR_INDEX 8 -/* - * uac mic descriptor define - */ - -#define UAC_CS_INTERFACE 0x24 -#define UAC_CS_ENDPOINT 0x25 - -#define UAC_MAX_PACKET_SIZE 64 -#define UAC_EP_MAX_PACKET_SIZE 32 -#define UAC_CHANNEL_NUM RECORD_CHANNEL - -struct uac_ac_descriptor -{ -#ifdef RT_USB_DEVICE_COMPOSITE - struct uiad_descriptor iad_desc; -#endif - struct uinterface_descriptor intf_desc; - struct usb_audio_control_descriptor hdr_desc; - struct usb_audio_input_terminal it_desc; - struct usb_audio_output_terminal ot_desc; -#if UAC_USE_FEATURE_UNIT - struct usb_audio_feature_unit feature_unit_desc; -#endif -}; - -struct uac_as_descriptor -{ - struct uinterface_descriptor intf_desc; - struct usb_audio_streaming_interface_descriptor hdr_desc; - struct usb_audio_streaming_type1_descriptor format_type_desc; - struct uendpoint_descriptor ep_desc; - struct usb_audio_streaming_endpoint_descriptor as_ep_desc; -}; - -/* - * uac mic device type - */ - -struct uac_audio_mic -{ - rt_device_t dev; - rt_event_t event; - rt_uint8_t open_count; - - rt_uint8_t *buffer; - rt_uint32_t buffer_index; - - uep_t ep; -}; -static struct uac_audio_mic mic; - -rt_align(4) -static struct udevice_descriptor dev_desc = -{ - USB_DESC_LENGTH_DEVICE, //bLength; - USB_DESC_TYPE_DEVICE, //type; - USB_BCD_VERSION, //bcdUSB; - USB_CLASS_DEVICE, //bDeviceClass; - 0x00, //bDeviceSubClass; - 0x00, //bDeviceProtocol; - UAC_MAX_PACKET_SIZE, //bMaxPacketSize0; - _VENDOR_ID, //idVendor; - _PRODUCT_ID, //idProduct; - USB_BCD_DEVICE, //bcdDevice; - USB_STRING_MANU_INDEX, //iManufacturer; - USB_STRING_PRODUCT_INDEX, //iProduct; - USB_STRING_SERIAL_INDEX, //iSerialNumber;Unused. - USB_DYNAMIC, //bNumConfigurations; -}; - -//FS and HS needed -rt_align(4) -static struct usb_qualifier_descriptor dev_qualifier = -{ - sizeof(dev_qualifier), //bLength - USB_DESC_TYPE_DEVICEQUALIFIER, //bDescriptorType - 0x0200, //bcdUSB - USB_CLASS_AUDIO, //bDeviceClass - 0x00, //bDeviceSubClass - 0x00, //bDeviceProtocol - 64, //bMaxPacketSize0 - 0x01, //bNumConfigurations - 0, -}; - -rt_align(4) -const static char *_ustring[] = -{ - "Language", - "RT-Thread Team.", - "RT-Thread Audio Microphone", - "32021919830108", - "Configuration", - "Interface", -}; - -rt_align(4) -static struct uac_ac_descriptor ac_desc = -{ -#ifdef RT_USB_DEVICE_COMPOSITE - /* Interface Association Descriptor */ - { - USB_DESC_LENGTH_IAD, - USB_DESC_TYPE_IAD, - USB_DYNAMIC, - 0x02, - USB_CLASS_AUDIO, - USB_SUBCLASS_AUDIOSTREAMING, - 0x00, - 0x00, - }, -#endif - /* Interface Descriptor */ - { - USB_DESC_LENGTH_INTERFACE, - USB_DESC_TYPE_INTERFACE, - USB_DYNAMIC, - 0x00, - 0x00, - USB_CLASS_AUDIO, - USB_SUBCLASS_AUDIOCONTROL, - 0x00, -#ifdef RT_USB_DEVICE_COMPOSITE - MIC_INTF_STR_INDEX, -#else - 0x00, -#endif - }, - /* Header Descriptor */ - { - sizeof(struct usb_audio_control_descriptor), - UAC_CS_INTERFACE, - UDESCSUB_AC_HEADER, - 0x0100, /* Version: 1.00 */ - 0x001E, /* Total length: 30 */ - 0x01, /* Total number of interfaces: 1 */ - {0x01}, /* Interface number: 1 */ - }, - /* Input Terminal Descriptor */ - { - sizeof(struct usb_audio_input_terminal), - UAC_CS_INTERFACE, - UDESCSUB_AC_INPUT, - 0x01, /* Terminal ID: 1 */ - 0x0201, /* Terminal Type: Microphone (0x0201) */ - 0x00, /* Assoc Terminal: 0 */ - 0x01, /* Number Channels: 1 */ - 0x0000, /* Channel Config: 0x0000 */ - 0x00, /* Channel Names: 0 */ - 0x00, /* Terminal: 0 */ - }, - /* Output Terminal Descriptor */ - { - sizeof(struct usb_audio_output_terminal), - UAC_CS_INTERFACE, - UDESCSUB_AC_OUTPUT, - 0x02, /* Terminal ID: 2 */ - 0x0101, /* Terminal Type: USB Streaming (0x0101) */ - 0x00, /* Assoc Terminal: 0 */ - 0x01, /* Source ID: 1 */ - 0x00, /* Terminal: 0 */ - }, -#if UAC_USE_FEATURE_UNIT - /* Feature unit Descriptor */ - { - sizeof(struct usb_audio_feature_unit), - UAC_CS_INTERFACE, - UDESCSUB_AC_FEATURE, - 0x02, - 0x01, - 0x01, - 0x00, - 0x01, - }, -#endif -}; - -rt_align(4) -static struct uinterface_descriptor as_desc0 = -{ - USB_DESC_LENGTH_INTERFACE, - USB_DESC_TYPE_INTERFACE, - USB_DYNAMIC, - 0x00, - 0x00, - USB_CLASS_AUDIO, - USB_SUBCLASS_AUDIOSTREAMING, - 0x00, - 0x00, -}; - -rt_align(4) -static struct uac_as_descriptor as_desc = -{ - /* Interface Descriptor */ - { - USB_DESC_LENGTH_INTERFACE, - USB_DESC_TYPE_INTERFACE, - USB_DYNAMIC, - 0x01, - 0x01, - USB_CLASS_AUDIO, - USB_SUBCLASS_AUDIOSTREAMING, - 0x00, - 0x00, - }, - /* General AS Descriptor */ - { - sizeof(struct usb_audio_streaming_interface_descriptor), - UAC_CS_INTERFACE, - AS_GENERAL, - 0x02, /* Terminal ID: 2 */ - 0x01, /* Interface delay in frames: 1 */ - UA_FMT_PCM, - }, - /* Format type i Descriptor */ - { - sizeof(struct usb_audio_streaming_type1_descriptor), - UAC_CS_INTERFACE, - FORMAT_TYPE, - FORMAT_TYPE_I, - UAC_CHANNEL_NUM, - 2, /* Subframe Size: 2 */ - RESOLUTION_BITS, - 0x01, /* Samples Frequence Type: 1 */ - {0}, /* Samples Frequence */ - }, - /* Endpoint Descriptor */ - { - USB_DESC_LENGTH_ENDPOINT, - USB_DESC_TYPE_ENDPOINT, - USB_DYNAMIC | USB_DIR_IN, - USB_EP_ATTR_ISOC, - UAC_EP_MAX_PACKET_SIZE, - 0x01, - }, - /* AS Endpoint Descriptor */ - { - sizeof(struct usb_audio_streaming_endpoint_descriptor), - UAC_CS_ENDPOINT, - AS_GENERAL, - }, -}; - -void mic_entry(void *parameter) -{ - struct rt_audio_caps caps = {0}; - rt_uint32_t e, index; - - mic.buffer = rt_malloc(RECORD_BUFFER_SZ); - if (mic.buffer == RT_NULL) - { - LOG_E("malloc failed"); - goto __exit; - } - - mic.dev = rt_device_find(MIC_DEVICE_NAME); - if (mic.dev == RT_NULL) - { - LOG_E("can't find device:%s", MIC_DEVICE_NAME); - goto __exit; - } - - while (1) - { - if (rt_event_recv(mic.event, EVENT_RECORD_START | EVENT_RECORD_STOP, - RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, - 1000, &e) != RT_EOK) - { - continue; - } - if (mic.open_count == 0) - { - continue; - } - LOG_D("record start"); - - rt_device_open(mic.dev, RT_DEVICE_OFLAG_RDONLY); - - caps.main_type = AUDIO_TYPE_INPUT; - caps.sub_type = AUDIO_DSP_PARAM; - caps.udata.config.samplerate = RECORD_SAMPLERATE; - caps.udata.config.channels = RECORD_CHANNEL; - caps.udata.config.samplebits = RESOLUTION_BITS; - rt_device_control(mic.dev, AUDIO_CTL_CONFIGURE, &caps); - - while (1) - { - if (rt_event_recv(mic.event, EVENT_RECORD_DATA | EVENT_RECORD_STOP, - RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, - 1000, &e) != RT_EOK) - { - if (mic.open_count > 0) - continue; - else - break; - } - if (e & EVENT_RECORD_DATA) - { - index = (mic.buffer_index >= RECORD_BUFFER_SZ / 2) ? 0 : (RECORD_BUFFER_SZ / 2); - rt_device_read(mic.dev, 0, mic.buffer + index, RECORD_BUFFER_SZ / 2); - } - else if (e & EVENT_RECORD_STOP) - { - break; - } - } - LOG_D("record stop"); - rt_device_close(mic.dev); - } - -__exit: - if (mic.buffer) - rt_free(mic.buffer); -} - -static rt_err_t _record_start(ufunction_t func) -{ - mic.ep->request.buffer = RT_NULL; - mic.ep->request.size = UAC_EP_MAX_PACKET_SIZE; - mic.ep->request.req_type = UIO_REQUEST_WRITE; - rt_usbd_io_request(func->device, mic.ep, &mic.ep->request); - - mic.open_count ++; - rt_event_send(mic.event, EVENT_RECORD_START); - return 0; -} - -static rt_err_t _record_stop(ufunction_t func) -{ - mic.open_count --; - rt_event_send(mic.event, EVENT_RECORD_STOP); - return 0; -} - -static rt_err_t _ep_data_in_handler(ufunction_t func, rt_size_t size) -{ - RT_ASSERT(func != RT_NULL); - LOG_D("_ep_data_in_handler"); - - mic.ep->request.buffer = mic.buffer + mic.buffer_index; - mic.ep->request.size = UAC_EP_MAX_PACKET_SIZE; - mic.ep->request.req_type = UIO_REQUEST_WRITE; - rt_usbd_io_request(func->device, mic.ep, &mic.ep->request); - - mic.buffer_index += UAC_EP_MAX_PACKET_SIZE; - if (mic.buffer_index >= RECORD_BUFFER_SZ) - { - mic.buffer_index = 0; - rt_event_send(mic.event, EVENT_RECORD_DATA); - } - else if (mic.buffer_index == RECORD_BUFFER_SZ / 2) - { - rt_event_send(mic.event, EVENT_RECORD_DATA); - } - - return RT_EOK; -} - -static rt_err_t _interface_as_handler(ufunction_t func, ureq_t setup) -{ - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->device != RT_NULL); - RT_ASSERT(setup != RT_NULL); - - LOG_D("_interface_as_handler"); - - if ((setup->request_type & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_STANDARD) - { - switch (setup->bRequest) - { - case USB_REQ_GET_INTERFACE: - break; - case USB_REQ_SET_INTERFACE: - LOG_D("set interface handler"); - if (setup->wValue == 1) - { - _record_start(func); - } - else if (setup->wValue == 0) - { - _record_stop(func); - } - break; - default: - LOG_D("unknown uac request 0x%x", setup->bRequest); - return -RT_ERROR; - } - } - - return RT_EOK; -} - -static rt_err_t _function_enable(ufunction_t func) -{ - RT_ASSERT(func != RT_NULL); - - LOG_D("uac function enable"); - - return RT_EOK; -} - -static rt_err_t _function_disable(ufunction_t func) -{ - RT_ASSERT(func != RT_NULL); - - LOG_D("uac function disable"); - _record_stop(func); - return RT_EOK; -} - -static struct ufunction_ops ops = -{ - _function_enable, - _function_disable, - RT_NULL, -}; -/** - * This function will configure uac descriptor. - * - * @param comm the communication interface number. - * @param data the data interface number. - * - * @return RT_EOK on successful. - */ -static rt_err_t _uac_descriptor_config(struct uac_ac_descriptor *ac, - rt_uint8_t cintf_nr, struct uac_as_descriptor *as, rt_uint8_t sintf_nr) -{ - ac->hdr_desc.baInterfaceNr[0] = sintf_nr; -#ifdef RT_USB_DEVICE_COMPOSITE - ac->iad_desc.bFirstInterface = cintf_nr; -#endif - - return RT_EOK; -} - -static rt_err_t _uac_samplerate_config(struct uac_as_descriptor *as, rt_uint32_t samplerate) -{ - as->format_type_desc.tSamFreq[0 * 3 + 2] = samplerate >> 16 & 0xff; - as->format_type_desc.tSamFreq[0 * 3 + 1] = samplerate >> 8 & 0xff; - as->format_type_desc.tSamFreq[0 * 3 + 0] = samplerate & 0xff; - return RT_EOK; -} - -/** - * This function will create a uac function instance. - * - * @param device the usb device object. - * - * @return RT_EOK on successful. - */ -ufunction_t rt_usbd_function_uac_mic_create(udevice_t device) -{ - ufunction_t func; - uintf_t intf_ac, intf_as; - ualtsetting_t setting_as0; - ualtsetting_t setting_ac, setting_as; - struct uac_as_descriptor *as_desc_t; - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - -#ifdef RT_USB_DEVICE_COMPOSITE - rt_usbd_device_set_interface_string(device, MIC_INTF_STR_INDEX, _ustring[2]); -#else - /* set usb device string description */ - rt_usbd_device_set_string(device, _ustring); -#endif - /* create a uac function */ - func = rt_usbd_function_new(device, &dev_desc, &ops); - //not support HS - //rt_usbd_device_set_qualifier(device, &dev_qualifier); - - /* create interface */ - intf_ac = rt_usbd_interface_new(device, RT_NULL); - intf_as = rt_usbd_interface_new(device, _interface_as_handler); - - /* create alternate setting */ - setting_ac = rt_usbd_altsetting_new(sizeof(struct uac_ac_descriptor)); - setting_as0 = rt_usbd_altsetting_new(sizeof(struct uinterface_descriptor)); - setting_as = rt_usbd_altsetting_new(sizeof(struct uac_as_descriptor)); - /* config desc in alternate setting */ - rt_usbd_altsetting_config_descriptor(setting_ac, &ac_desc, - (rt_off_t) & ((struct uac_ac_descriptor *)0)->intf_desc); - rt_usbd_altsetting_config_descriptor(setting_as0, &as_desc0, 0); - rt_usbd_altsetting_config_descriptor(setting_as, &as_desc, - (rt_off_t) & ((struct uac_as_descriptor *)0)->intf_desc); - /* configure the uac interface descriptor */ - _uac_descriptor_config(setting_ac->desc, intf_ac->intf_num, setting_as->desc, intf_as->intf_num); - _uac_samplerate_config(setting_as->desc, RECORD_SAMPLERATE); - - /* create endpoint */ - as_desc_t = (struct uac_as_descriptor *)setting_as->desc; - mic.ep = rt_usbd_endpoint_new(&as_desc_t->ep_desc, _ep_data_in_handler); - - /* add the endpoint to the alternate setting */ - rt_usbd_altsetting_add_endpoint(setting_as, mic.ep); - - /* add the alternate setting to the interface, then set default setting of the interface */ - rt_usbd_interface_add_altsetting(intf_ac, setting_ac); - rt_usbd_set_altsetting(intf_ac, 0); - rt_usbd_interface_add_altsetting(intf_as, setting_as0); - rt_usbd_interface_add_altsetting(intf_as, setting_as); - rt_usbd_set_altsetting(intf_as, 0); - - /* add the interface to the uac function */ - rt_usbd_function_add_interface(func, intf_ac); - rt_usbd_function_add_interface(func, intf_as); - - return func; -} - -int audio_mic_init(void) -{ - rt_thread_t mic_tid; - mic.event = rt_event_create("mic_event", RT_IPC_FLAG_FIFO); - - mic_tid = rt_thread_create("mic_thread", - mic_entry, RT_NULL, - 1024, - 5, 10); - - if (mic_tid != RT_NULL) - rt_thread_startup(mic_tid); - return RT_EOK; -} -INIT_COMPONENT_EXPORT(audio_mic_init); - -/* - * register uac class - */ -struct udclass uac_class = -{ - .rt_usbd_function_create = rt_usbd_function_uac_mic_create -}; - -int rt_usbd_uac_mic_class_register(void) -{ - rt_usbd_class_register(&uac_class); - return 0; -} -INIT_PREV_EXPORT(rt_usbd_uac_mic_class_register); diff --git a/components/drivers/usb/usbdevice/class/audio_speaker.c b/components/drivers/usb/usbdevice/class/audio_speaker.c deleted file mode 100644 index 6560990c8e..0000000000 --- a/components/drivers/usb/usbdevice/class/audio_speaker.c +++ /dev/null @@ -1,582 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2019-09-19 flybreak the first version - */ - -#include <rthw.h> -#include <rtdevice.h> -#include "drivers/usb_device.h" - -#define AUFMT_MAX_FREQUENCIES 1 -#include "uaudioreg.h" - -#define DBG_TAG "usbd.audio.speaker" -#define DBG_LVL DBG_INFO -#include <rtdbg.h> - -#define AUDIO_SAMPLERATE 16000 -#define AUDIO_CHANNEL 1 -#define RESOLUTION_BITS 16 - -#define RESOLUTION_BYTE (RESOLUTION_BITS / 8) -#define AUDIO_PER_MS_SZ ((AUDIO_SAMPLERATE * AUDIO_CHANNEL * RESOLUTION_BYTE) / 1000) -#define AUDIO_BUFFER_SZ (AUDIO_PER_MS_SZ * 20) /* 20ms */ - -#if defined(RT_USBD_SPEAKER_DEVICE_NAME) - #define SPEAKER_DEVICE_NAME RT_USBD_SPEAKER_DEVICE_NAME -#else - #define SPEAKER_DEVICE_NAME "sound0" -#endif - -#define EVENT_AUDIO_START (1 << 0) -#define EVENT_AUDIO_STOP (1 << 1) -#define EVENT_AUDIO_DATA (1 << 2) - -#define SPK_INTF_STR_INDEX 9 -/* - * uac speaker descriptor define - */ - -#define UAC_CS_INTERFACE 0x24 -#define UAC_CS_ENDPOINT 0x25 - -#define UAC_MAX_PACKET_SIZE 64 -#define UAC_EP_MAX_PACKET_SIZE 32 -#define UAC_CHANNEL_NUM AUDIO_CHANNEL - -struct uac_ac_descriptor -{ -#ifdef RT_USB_DEVICE_COMPOSITE - struct uiad_descriptor iad_desc; -#endif - struct uinterface_descriptor intf_desc; - struct usb_audio_control_descriptor hdr_desc; - struct usb_audio_input_terminal it_desc; - struct usb_audio_output_terminal ot_desc; -#if UAC_USE_FEATURE_UNIT - struct usb_audio_feature_unit feature_unit_desc; -#endif -}; - -struct uac_as_descriptor -{ - struct uinterface_descriptor intf_desc; - struct usb_audio_streaming_interface_descriptor hdr_desc; - struct usb_audio_streaming_type1_descriptor format_type_desc; - struct uendpoint_descriptor ep_desc; - struct usb_audio_streaming_endpoint_descriptor as_ep_desc; -}; - -/* - * uac speaker device type - */ - -struct uac_audio_speaker -{ - rt_device_t dev; - rt_event_t event; - rt_uint8_t open_count; - - rt_uint8_t *buffer; - rt_uint32_t buffer_index; - - uep_t ep; -}; -static struct uac_audio_speaker speaker; - -rt_align(4) -static struct udevice_descriptor dev_desc = -{ - USB_DESC_LENGTH_DEVICE, //bLength; - USB_DESC_TYPE_DEVICE, //type; - USB_BCD_VERSION, //bcdUSB; - USB_CLASS_DEVICE, //bDeviceClass; - 0x00, //bDeviceSubClass; - 0x00, //bDeviceProtocol; - UAC_MAX_PACKET_SIZE, //bMaxPacketSize0; - _VENDOR_ID, //idVendor; - _PRODUCT_ID, //idProduct; - USB_BCD_DEVICE, //bcdDevice; - USB_STRING_MANU_INDEX, //iManufacturer; - USB_STRING_PRODUCT_INDEX, //iProduct; - USB_STRING_SERIAL_INDEX, //iSerialNumber;Unused. - USB_DYNAMIC, //bNumConfigurations; -}; - -//FS and HS needed -rt_align(4) -static struct usb_qualifier_descriptor dev_qualifier = -{ - sizeof(dev_qualifier), //bLength - USB_DESC_TYPE_DEVICEQUALIFIER, //bDescriptorType - 0x0200, //bcdUSB - USB_CLASS_AUDIO, //bDeviceClass - 0x00, //bDeviceSubClass - 0x00, //bDeviceProtocol - 64, //bMaxPacketSize0 - 0x01, //bNumConfigurations - 0, -}; - -rt_align(4) -const static char *_ustring[] = -{ - "Language", - "RT-Thread Team.", - "RT-Thread Audio Speaker", - "32021919830108", - "Configuration", - "Interface", -}; - -rt_align(4) -static struct uac_ac_descriptor ac_desc = -{ -#ifdef RT_USB_DEVICE_COMPOSITE - /* Interface Association Descriptor */ - { - USB_DESC_LENGTH_IAD, - USB_DESC_TYPE_IAD, - USB_DYNAMIC, - 0x02, - USB_CLASS_AUDIO, - USB_SUBCLASS_AUDIOSTREAMING, - 0x00, - 0x00, - }, -#endif - /* Interface Descriptor */ - { - USB_DESC_LENGTH_INTERFACE, - USB_DESC_TYPE_INTERFACE, - USB_DYNAMIC, - 0x00, - 0x00, - USB_CLASS_AUDIO, - USB_SUBCLASS_AUDIOCONTROL, - 0x00, -#ifdef RT_USB_DEVICE_COMPOSITE - SPK_INTF_STR_INDEX, -#else - 0x00, -#endif - }, - /* Header Descriptor */ - { - sizeof(struct usb_audio_control_descriptor), - UAC_CS_INTERFACE, - UDESCSUB_AC_HEADER, - 0x0100, /* Version: 1.00 */ - 0x0027, /* Total length: 39 */ - 0x01, /* Total number of interfaces: 1 */ - {0x01}, /* Interface number: 1 */ - }, - /* Input Terminal Descriptor */ - { - sizeof(struct usb_audio_input_terminal), - UAC_CS_INTERFACE, - UDESCSUB_AC_INPUT, - 0x01, /* Terminal ID: 1 */ - 0x0101, /* Terminal Type: USB Streaming (0x0101) */ - 0x00, /* Assoc Terminal: 0 */ - 0x01, /* Number Channels: 1 */ - 0x0000, /* Channel Config: 0x0000 */ - 0x00, /* Channel Names: 0 */ - 0x00, /* Terminal: 0 */ - }, - /* Output Terminal Descriptor */ - { - sizeof(struct usb_audio_output_terminal), - UAC_CS_INTERFACE, - UDESCSUB_AC_OUTPUT, - 0x02, /* Terminal ID: 2 */ - 0x0302, /* Terminal Type: Headphones (0x0302) */ - 0x00, /* Assoc Terminal: 0 */ - 0x01, /* Source ID: 1 */ - 0x00, /* Terminal: 0 */ - }, -#if UAC_USE_FEATURE_UNIT - /* Feature unit Descriptor */ - { - UAC_DT_FEATURE_UNIT_SIZE(UAC_CH_NUM), - UAC_CS_INTERFACE, - UAC_FEATURE_UNIT, - 0x02, - 0x0101, - 0x00, - 0x01, - }, -#endif -}; - -rt_align(4) -static struct uinterface_descriptor as_desc0 = -{ - USB_DESC_LENGTH_INTERFACE, - USB_DESC_TYPE_INTERFACE, - USB_DYNAMIC, - 0x00, - 0x00, - USB_CLASS_AUDIO, - USB_SUBCLASS_AUDIOSTREAMING, - 0x00, - 0x00, -}; - -rt_align(4) -static struct uac_as_descriptor as_desc = -{ - /* Interface Descriptor */ - { - USB_DESC_LENGTH_INTERFACE, - USB_DESC_TYPE_INTERFACE, - USB_DYNAMIC, - 0x01, - 0x01, - USB_CLASS_AUDIO, - USB_SUBCLASS_AUDIOSTREAMING, - 0x00, - 0x00, - }, - /* General AS Descriptor */ - { - sizeof(struct usb_audio_streaming_interface_descriptor), - UAC_CS_INTERFACE, - AS_GENERAL, - 0x01, /* Terminal ID: 1 */ - 0x01, /* Interface delay in frames: 1 */ - UA_FMT_PCM, - }, - /* Format type i Descriptor */ - { - sizeof(struct usb_audio_streaming_type1_descriptor), - UAC_CS_INTERFACE, - FORMAT_TYPE, - FORMAT_TYPE_I, - UAC_CHANNEL_NUM, - 2, /* Subframe Size: 2 */ - RESOLUTION_BITS, - 0x01, /* Samples Frequence Type: 1 */ - {0}, /* Samples Frequence */ - }, - /* Endpoint Descriptor */ - { - USB_DESC_LENGTH_ENDPOINT, - USB_DESC_TYPE_ENDPOINT, - USB_DYNAMIC | USB_DIR_OUT, - USB_EP_ATTR_ISOC, - UAC_EP_MAX_PACKET_SIZE, - 0x01, - }, - /* AS Endpoint Descriptor */ - { - sizeof(struct usb_audio_streaming_endpoint_descriptor), - UAC_CS_ENDPOINT, - AS_GENERAL, - }, -}; - -void speaker_entry(void *parameter) -{ - struct rt_audio_caps caps = {0}; - rt_uint32_t e, index; - - speaker.buffer = rt_malloc(AUDIO_BUFFER_SZ); - if (speaker.buffer == RT_NULL) - { - LOG_E("malloc failed"); - goto __exit; - } - - speaker.dev = rt_device_find(SPEAKER_DEVICE_NAME); - if (speaker.dev == RT_NULL) - { - LOG_E("can't find device:%s", SPEAKER_DEVICE_NAME); - goto __exit; - } - - while (1) - { - if (rt_event_recv(speaker.event, EVENT_AUDIO_START | EVENT_AUDIO_STOP, - RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, - 1000, &e) != RT_EOK) - { - continue; - } - if (speaker.open_count == 0) - { - continue; - } - LOG_D("play start"); - - rt_device_open(speaker.dev, RT_DEVICE_OFLAG_WRONLY); - - caps.main_type = AUDIO_TYPE_OUTPUT; - caps.sub_type = AUDIO_DSP_PARAM; - caps.udata.config.samplerate = AUDIO_SAMPLERATE; - caps.udata.config.channels = AUDIO_CHANNEL; - caps.udata.config.samplebits = RESOLUTION_BITS; - rt_device_control(speaker.dev, AUDIO_CTL_CONFIGURE, &caps); - - while (1) - { - if (rt_event_recv(speaker.event, EVENT_AUDIO_DATA | EVENT_AUDIO_STOP, - RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, - 1000, &e) != RT_EOK) - { - if (speaker.open_count > 0) - continue; - else - break; - } - if (e & EVENT_AUDIO_DATA) - { - index = (speaker.buffer_index >= AUDIO_BUFFER_SZ / 2) ? 0 : (AUDIO_BUFFER_SZ / 2); - rt_device_write(speaker.dev, 0, speaker.buffer + index, AUDIO_BUFFER_SZ / 2); - } - else if (e & EVENT_AUDIO_STOP) - { - break; - } - } - LOG_D("play stop"); - rt_device_close(speaker.dev); - } - -__exit: - if (speaker.buffer) - rt_free(speaker.buffer); -} - -static rt_err_t _audio_start(ufunction_t func) -{ - speaker.ep->request.buffer = speaker.buffer; - speaker.ep->request.size = UAC_EP_MAX_PACKET_SIZE; - speaker.ep->request.req_type = UIO_REQUEST_READ_FULL; - rt_usbd_io_request(func->device, speaker.ep, &speaker.ep->request); - - speaker.open_count ++; - rt_event_send(speaker.event, EVENT_AUDIO_START); - - return 0; -} - -static rt_err_t _audio_stop(ufunction_t func) -{ - speaker.open_count --; - rt_event_send(speaker.event, EVENT_AUDIO_STOP); - return 0; -} - -static rt_err_t _ep_data_handler(ufunction_t func, rt_size_t size) -{ - RT_ASSERT(func != RT_NULL); - LOG_D("_ep_data_handler"); - - speaker.ep->request.buffer = speaker.buffer + speaker.buffer_index; - speaker.ep->request.size = UAC_EP_MAX_PACKET_SIZE; - speaker.ep->request.req_type = UIO_REQUEST_READ_FULL; - rt_usbd_io_request(func->device, speaker.ep, &speaker.ep->request); - - speaker.buffer_index += UAC_EP_MAX_PACKET_SIZE; - if (speaker.buffer_index >= AUDIO_BUFFER_SZ) - { - speaker.buffer_index = 0; - rt_event_send(speaker.event, EVENT_AUDIO_DATA); - } - else if (speaker.buffer_index == AUDIO_BUFFER_SZ / 2) - { - rt_event_send(speaker.event, EVENT_AUDIO_DATA); - } - - return RT_EOK; -} - -static rt_err_t _interface_as_handler(ufunction_t func, ureq_t setup) -{ - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->device != RT_NULL); - RT_ASSERT(setup != RT_NULL); - - LOG_D("_interface_as_handler"); - - if ((setup->request_type & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_STANDARD) - { - switch (setup->bRequest) - { - case USB_REQ_GET_INTERFACE: - break; - case USB_REQ_SET_INTERFACE: - LOG_D("set interface handler"); - if (setup->wValue == 1) - { - _audio_start(func); - } - else if (setup->wValue == 0) - { - _audio_stop(func); - } - break; - default: - LOG_D("unknown uac request 0x%x", setup->bRequest); - return -RT_ERROR; - } - } - - return RT_EOK; -} - -static rt_err_t _function_enable(ufunction_t func) -{ - RT_ASSERT(func != RT_NULL); - - LOG_D("uac function enable"); - - return RT_EOK; -} - -static rt_err_t _function_disable(ufunction_t func) -{ - RT_ASSERT(func != RT_NULL); - - LOG_D("uac function disable"); - _audio_stop(func); - return RT_EOK; -} - -static struct ufunction_ops ops = -{ - _function_enable, - _function_disable, - RT_NULL, -}; -/** - * This function will configure uac descriptor. - * - * @param comm the communication interface number. - * @param data the data interface number. - * - * @return RT_EOK on successful. - */ -static rt_err_t _uac_descriptor_config(struct uac_ac_descriptor *ac, - rt_uint8_t cintf_nr, struct uac_as_descriptor *as, rt_uint8_t sintf_nr) -{ - ac->hdr_desc.baInterfaceNr[0] = sintf_nr; -#ifdef RT_USB_DEVICE_COMPOSITE - ac->iad_desc.bFirstInterface = cintf_nr; -#endif - - return RT_EOK; -} - -static rt_err_t _uac_samplerate_config(struct uac_as_descriptor *as, rt_uint32_t samplerate) -{ - as->format_type_desc.tSamFreq[0 * 3 + 2] = samplerate >> 16 & 0xff; - as->format_type_desc.tSamFreq[0 * 3 + 1] = samplerate >> 8 & 0xff; - as->format_type_desc.tSamFreq[0 * 3 + 0] = samplerate & 0xff; - return RT_EOK; -} - -/** - * This function will create a uac function instance. - * - * @param device the usb device object. - * - * @return RT_EOK on successful. - */ -ufunction_t rt_usbd_function_uac_speaker_create(udevice_t device) -{ - ufunction_t func; - uintf_t intf_ac, intf_as; - ualtsetting_t setting_as0; - ualtsetting_t setting_ac, setting_as; - struct uac_as_descriptor *as_desc_t; - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - -#ifdef RT_USB_DEVICE_COMPOSITE - rt_usbd_device_set_interface_string(device, SPK_INTF_STR_INDEX, _ustring[2]); -#else - /* set usb device string description */ - rt_usbd_device_set_string(device, _ustring); -#endif - /* create a uac function */ - func = rt_usbd_function_new(device, &dev_desc, &ops); - //not support HS - //rt_usbd_device_set_qualifier(device, &dev_qualifier); - - /* create interface */ - intf_ac = rt_usbd_interface_new(device, RT_NULL); - intf_as = rt_usbd_interface_new(device, _interface_as_handler); - - /* create alternate setting */ - setting_ac = rt_usbd_altsetting_new(sizeof(struct uac_ac_descriptor)); - setting_as0 = rt_usbd_altsetting_new(sizeof(struct uinterface_descriptor)); - setting_as = rt_usbd_altsetting_new(sizeof(struct uac_as_descriptor)); - /* config desc in alternate setting */ - rt_usbd_altsetting_config_descriptor(setting_ac, &ac_desc, - (rt_off_t) & ((struct uac_ac_descriptor *)0)->intf_desc); - rt_usbd_altsetting_config_descriptor(setting_as0, &as_desc0, 0); - rt_usbd_altsetting_config_descriptor(setting_as, &as_desc, - (rt_off_t) & ((struct uac_as_descriptor *)0)->intf_desc); - /* configure the uac interface descriptor */ - _uac_descriptor_config(setting_ac->desc, intf_ac->intf_num, setting_as->desc, intf_as->intf_num); - _uac_samplerate_config(setting_as->desc, AUDIO_SAMPLERATE); - - /* create endpoint */ - as_desc_t = (struct uac_as_descriptor *)setting_as->desc; - speaker.ep = rt_usbd_endpoint_new(&as_desc_t->ep_desc, _ep_data_handler); - - /* add the endpoint to the alternate setting */ - rt_usbd_altsetting_add_endpoint(setting_as, speaker.ep); - - /* add the alternate setting to the interface, then set default setting of the interface */ - rt_usbd_interface_add_altsetting(intf_ac, setting_ac); - rt_usbd_set_altsetting(intf_ac, 0); - rt_usbd_interface_add_altsetting(intf_as, setting_as0); - rt_usbd_interface_add_altsetting(intf_as, setting_as); - rt_usbd_set_altsetting(intf_as, 0); - - /* add the interface to the uac function */ - rt_usbd_function_add_interface(func, intf_ac); - rt_usbd_function_add_interface(func, intf_as); - - return func; -} - -int audio_speaker_init(void) -{ - rt_thread_t speaker_tid; - speaker.event = rt_event_create("speaker_event", RT_IPC_FLAG_FIFO); - - speaker_tid = rt_thread_create("speaker_thread", - speaker_entry, RT_NULL, - 1024, - 5, 10); - - if (speaker_tid != RT_NULL) - rt_thread_startup(speaker_tid); - return RT_EOK; -} -INIT_COMPONENT_EXPORT(audio_speaker_init); - -/* - * register uac class - */ -static struct udclass uac_speaker_class = -{ - .rt_usbd_function_create = rt_usbd_function_uac_speaker_create -}; - -int rt_usbd_uac_speaker_class_register(void) -{ - rt_usbd_class_register(&uac_speaker_class); - return 0; -} -INIT_PREV_EXPORT(rt_usbd_uac_speaker_class_register); diff --git a/components/drivers/usb/usbdevice/class/cdc.h b/components/drivers/usb/usbdevice/class/cdc.h deleted file mode 100644 index 6b79876734..0000000000 --- a/components/drivers/usb/usbdevice/class/cdc.h +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-10-03 Yi Qiu first version - * 2012-12-12 heyuanjie87 add CDC endpoints collection - */ - -#ifndef __CDC_H__ -#define __CDC_H__ - -#define USB_CDC_BUFSIZE 0x40 - -#define USB_CDC_CLASS_COMM 0x02 -#define USB_CDC_CLASS_DATA 0x0A - -#define USB_CDC_SUBCLASS_NONE 0x00 -#define USB_CDC_SUBCLASS_DLCM 0x01 -#define USB_CDC_SUBCLASS_ACM 0x02 -#define USB_CDC_SUBCLASS_TCM 0x03 -#define USB_CDC_SUBCLASS_MCCM 0x04 -#define USB_CDC_SUBCLASS_CCM 0x05 -#define USB_CDC_SUBCLASS_ETH 0x06 -#define USB_CDC_SUBCLASS_ATM 0x07 -#define USB_CDC_SUBCLASS_EEM 0x0C - -#define USB_CDC_PROTOCOL_NONE 0x00 -#define USB_CDC_PROTOCOL_V25TER 0x01 -#define USB_CDC_PROTOCOL_I430 0x30 -#define USB_CDC_PROTOCOL_HDLC 0x31 -#define USB_CDC_PROTOCOL_TRANS 0x32 -#define USB_CDC_PROTOCOL_Q921M 0x50 -#define USB_CDC_PROTOCOL_Q921 0x51 -#define USB_CDC_PROTOCOL_Q921TM 0x52 -#define USB_CDC_PROTOCOL_V42BIS 0x90 -#define USB_CDC_PROTOCOL_Q931 0x91 -#define USB_CDC_PROTOCOL_V120 0x92 -#define USB_CDC_PROTOCOL_CAPI20 0x93 -#define USB_CDC_PROTOCOL_HOST 0xFD -#define USB_CDC_PROTOCOL_PUFD 0xFE -#define USB_CDC_PROTOCOL_VENDOR 0xFF -#define USB_CDC_PROTOCOL_EEM 0x07 - -#define USB_CDC_CS_INTERFACE 0x24 -#define USB_CDC_CS_ENDPOINT 0x25 - -#define USB_CDC_SCS_HEADER 0x00 -#define USB_CDC_SCS_CALL_MGMT 0x01 -#define USB_CDC_SCS_ACM 0x02 -#define USB_CDC_SCS_UNION 0x06 -#define USB_CDC_SCS_ETH 0x0F - -#define CDC_SEND_ENCAPSULATED_COMMAND 0x00 -#define CDC_GET_ENCAPSULATED_RESPONSE 0x01 -#define CDC_SET_COMM_FEATURE 0x02 -#define CDC_GET_COMM_FEATURE 0x03 -#define CDC_CLEAR_COMM_FEATURE 0x04 -#define CDC_SET_AUX_LINE_STATE 0x10 -#define CDC_SET_HOOK_STATE 0x11 -#define CDC_PULSE_SETUP 0x12 -#define CDC_SEND_PULSE 0x13 -#define CDC_SET_PULSE_TIME 0x14 -#define CDC_RING_AUX_JACK 0x15 -#define CDC_SET_LINE_CODING 0x20 -#define CDC_GET_LINE_CODING 0x21 -#define CDC_SET_CONTROL_LINE_STATE 0x22 -#define CDC_SEND_BREAK 0x23 -#define CDC_SET_RINGER_PARMS 0x30 -#define CDC_GET_RINGER_PARMS 0x31 -#define CDC_SET_OPERATION_PARMS 0x32 -#define CDC_GET_OPERATION_PARMS 0x33 -#define CDC_SET_LINE_PARMS 0x34 -#define CDC_GET_LINE_PARMS 0x35 -#define CDC_DIAL_DIGITS 0x36 -#define CDC_SET_UNIT_PARAMETER 0x37 -#define CDC_GET_UNIT_PARAMETER 0x38 -#define CDC_CLEAR_UNIT_PARAMETER 0x39 -#define CDC_GET_PROFILE 0x3A -#define CDC_SET_ETH_MULTICAST_FILTERS 0x40 -#define CDC_SET_ETH_POWER_MGMT_FILT 0x41 -#define CDC_GET_ETH_POWER_MGMT_FILT 0x42 -#define CDC_SET_ETH_PACKET_FILTER 0x43 -#define CDC_GET_ETH_STATISTIC 0x44 -#define CDC_SET_ATM_DATA_FORMAT 0x50 -#define CDC_GET_ATM_DEVICE_STATISTICS 0x51 -#define CDC_SET_ATM_DEFAULT_VC 0x52 -#define CDC_GET_ATM_VC_STATISTICS 0x53 - -#pragma pack(1) - -struct ucdc_header_descriptor -{ - rt_uint8_t length; - rt_uint8_t type; - rt_uint8_t subtype; - rt_uint16_t bcd; -}; -typedef struct ucdc_header_descriptor* ucdc_hdr_desc_t; - -struct ucdc_acm_descriptor -{ - rt_uint8_t length; - rt_uint8_t type; - rt_uint8_t subtype; - rt_uint8_t capabilties; -}; -typedef struct ucdc_acm_descriptor* ucdc_acm_desc_t; - -struct ucdc_call_mgmt_descriptor -{ - rt_uint8_t length; - rt_uint8_t type; - rt_uint8_t subtype; - rt_uint8_t capabilties; - rt_uint8_t data_interface; -}; -typedef struct ucdc_call_mgmt_descriptor* ucdc_call_mgmt_desc_t; - -struct ucdc_union_descriptor -{ - rt_uint8_t length; - rt_uint8_t type; - rt_uint8_t subtype; - rt_uint8_t master_interface; - rt_uint8_t slave_interface0; -}; -typedef struct ucdc_union_descriptor* ucdc_union_desc_t; - -struct ucdc_comm_descriptor -{ -#ifdef RT_USB_DEVICE_COMPOSITE - struct uiad_descriptor iad_desc; -#endif - struct uinterface_descriptor intf_desc; - struct ucdc_header_descriptor hdr_desc; - struct ucdc_call_mgmt_descriptor call_mgmt_desc; - struct ucdc_acm_descriptor acm_desc; - struct ucdc_union_descriptor union_desc; - struct uendpoint_descriptor ep_desc; -}; -typedef struct ucdc_comm_descriptor* ucdc_comm_desc_t; - -struct ucdc_enet_descriptor -{ - rt_uint8_t bFunctionLength; - rt_uint8_t bDescriptorType; - rt_uint8_t bDescriptorSubtype; - rt_uint8_t iMACAddress; - rt_uint8_t bmEthernetStatistics[4]; - rt_uint16_t wMaxSegmentSize; - rt_uint16_t wMCFilters; - rt_uint8_t bNumberPowerFilters; -}; -struct ucdc_eth_descriptor -{ -#ifdef RT_USB_DEVICE_COMPOSITE - struct uiad_descriptor iad_desc; -#endif - struct uinterface_descriptor intf_desc; - struct ucdc_header_descriptor hdr_desc; - struct ucdc_union_descriptor union_desc; - struct ucdc_enet_descriptor enet_desc; - struct uendpoint_descriptor ep_desc; -}; -typedef struct ucdc_eth_descriptor* ucdc_eth_desc_t; - -struct ucdc_data_descriptor -{ - struct uinterface_descriptor intf_desc; - struct uendpoint_descriptor ep_out_desc; - struct uendpoint_descriptor ep_in_desc; -}; -typedef struct ucdc_data_descriptor* ucdc_data_desc_t; - -struct ucdc_line_coding -{ - rt_uint32_t dwDTERate; - rt_uint8_t bCharFormat; - rt_uint8_t bParityType; - rt_uint8_t bDataBits; -}; -typedef struct ucdc_line_coding* ucdc_line_coding_t; - -struct cdc_eps -{ - uep_t ep_out; - uep_t ep_in; - uep_t ep_cmd; -}; -typedef struct cdc_eps* cdc_eps_t; - - - -struct ucdc_management_element_notifications -{ - rt_uint8_t bmRequestType; - rt_uint8_t bNotificatinCode; - rt_uint16_t wValue; - rt_uint16_t wIndex; - rt_uint16_t wLength; -}; -typedef struct ucdc_management_element_notifications * ucdc_mg_notifications_t; - -struct ucdc_connection_speed_change_data -{ - rt_uint32_t down_bit_rate; - rt_uint32_t up_bit_rate; -}; -typedef struct connection_speed_change_data * connect_speed_data_t; - -enum ucdc_notification_code -{ - UCDC_NOTIFI_NETWORK_CONNECTION = 0x00, - UCDC_NOTIFI_RESPONSE_AVAILABLE = 0x01, - UCDC_NOTIFI_AUX_JACK_HOOK_STATE = 0x08, - UCDC_NOTIFI_RING_DETECT = 0x09, - UCDC_NOTIFI_SERIAL_STATE = 0x20, - UCDC_NOTIFI_CALL_STATE_CHANGE = 0x28, - UCDC_NOTIFI_LINE_STATE_CHANGE = 0x29, - UCDC_NOTIFI_CONNECTION_SPEED_CHANGE = 0x2A, -}; -typedef enum ucdc_notification_code ucdc_notification_code_t; - -#pragma pack() - -#endif diff --git a/components/drivers/usb/usbdevice/class/cdc_vcom.c b/components/drivers/usb/usbdevice/class/cdc_vcom.c deleted file mode 100644 index dec102b135..0000000000 --- a/components/drivers/usb/usbdevice/class/cdc_vcom.c +++ /dev/null @@ -1,1008 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-10-02 Yi Qiu first version - * 2012-12-12 heyuanjie87 change endpoints and function handler - * 2013-06-25 heyuanjie87 remove SOF mechinism - * 2013-07-20 Yi Qiu do more test - * 2016-02-01 Urey Fix some error - * 2021-10-14 mazhiyuan Fix some error - */ - -#include <rthw.h> -#include <rtdevice.h> -#include "drivers/usb_device.h" -#include "cdc.h" - -#ifdef RT_USB_DEVICE_CDC - -#define DBG_TAG "usbdevice_cdc" -#define DBG_LVL DBG_INFO -#include <rtdbg.h> - -#define VCOM_INTF_STR_INDEX 5 -#ifdef RT_VCOM_TX_TIMEOUT -#define VCOM_TX_TIMEOUT RT_VCOM_TX_TIMEOUT -#else /*!RT_VCOM_TX_TIMEOUT*/ -#define VCOM_TX_TIMEOUT 1000 -#endif /*RT_VCOM_TX_TIMEOUT*/ - -#ifdef RT_CDC_RX_BUFSIZE -#define CDC_RX_BUFSIZE RT_CDC_RX_BUFSIZE -#else -#define CDC_RX_BUFSIZE 128 -#endif -#define CDC_MAX_PACKET_SIZE 64 -#define VCOM_DEVICE "vcom" - -#ifdef RT_VCOM_TASK_STK_SIZE -#define VCOM_TASK_STK_SIZE RT_VCOM_TASK_STK_SIZE -#else /*!RT_VCOM_TASK_STK_SIZE*/ -#define VCOM_TASK_STK_SIZE 512 -#endif /*RT_VCOM_TASK_STK_SIZE*/ - -#ifdef RT_VCOM_TX_USE_DMA -#define VCOM_TX_USE_DMA -#endif /*RT_VCOM_TX_USE_DMA*/ - -#ifdef RT_VCOM_SERNO -#define _SER_NO RT_VCOM_SERNO -#else /*!RT_VCOM_SERNO*/ -#define _SER_NO "32021919830108" -#endif /*RT_VCOM_SERNO*/ - -#ifdef RT_VCOM_SER_LEN -#define _SER_NO_LEN RT_VCOM_SER_LEN -#else /*!RT_VCOM_SER_LEN*/ -#define _SER_NO_LEN 14 /*rt_strlen("32021919830108")*/ -#endif /*RT_VCOM_SER_LEN*/ - -rt_align(RT_ALIGN_SIZE) -static rt_uint8_t vcom_thread_stack[VCOM_TASK_STK_SIZE]; -static struct rt_thread vcom_thread; -static struct ucdc_line_coding line_coding; - -#define CDC_TX_BUFSIZE 1024 -#define CDC_BULKIN_MAXSIZE (CDC_TX_BUFSIZE / 8) - -#define CDC_TX_HAS_DATE 0x01 -#define CDC_TX_HAS_SPACE 0x02 - -struct vcom -{ - struct rt_serial_device serial; - uep_t ep_out; - uep_t ep_in; - uep_t ep_cmd; - rt_bool_t connected; - rt_bool_t in_sending; - struct rt_completion wait; - rt_uint8_t rx_rbp[CDC_RX_BUFSIZE]; - struct rt_ringbuffer rx_ringbuffer; - rt_uint8_t tx_rbp[CDC_TX_BUFSIZE]; - struct rt_ringbuffer tx_ringbuffer; - struct rt_event tx_event; -}; - -struct vcom_tx_msg -{ - struct rt_serial_device * serial; - const char *buf; - rt_size_t size; -}; - -rt_align(4) -static struct udevice_descriptor dev_desc = -{ - USB_DESC_LENGTH_DEVICE, //bLength; - USB_DESC_TYPE_DEVICE, //type; - USB_BCD_VERSION, //bcdUSB; - USB_CLASS_CDC, //bDeviceClass; - 0x02, //bDeviceSubClass; - 0x00, //bDeviceProtocol; - CDC_MAX_PACKET_SIZE, //bMaxPacketSize0; - _VENDOR_ID, //idVendor; - _PRODUCT_ID, //idProduct; - USB_BCD_DEVICE, //bcdDevice; - USB_STRING_MANU_INDEX, //iManufacturer; - USB_STRING_PRODUCT_INDEX, //iProduct; - USB_STRING_SERIAL_INDEX, //iSerialNumber; - USB_DYNAMIC, //bNumConfigurations; -}; - -//FS and HS needed -rt_align(4) -static struct usb_qualifier_descriptor dev_qualifier = -{ - sizeof(dev_qualifier), //bLength - USB_DESC_TYPE_DEVICEQUALIFIER, //bDescriptorType - 0x0200, //bcdUSB - USB_CLASS_CDC, //bDeviceClass - 0x02, //bDeviceSubClass - 0x00, //bDeviceProtocol - 64, //bMaxPacketSize0 - 0x01, //bNumConfigurations - 0, -}; - -/* communcation interface descriptor */ -rt_align(4) -const static struct ucdc_comm_descriptor _comm_desc = -{ -#ifdef RT_USB_DEVICE_COMPOSITE - /* Interface Association Descriptor */ - { - USB_DESC_LENGTH_IAD, - USB_DESC_TYPE_IAD, - USB_DYNAMIC, - 0x02, - USB_CDC_CLASS_COMM, - USB_CDC_SUBCLASS_ACM, - USB_CDC_PROTOCOL_V25TER, - 0x00, - }, -#endif - /* Interface Descriptor */ - { - USB_DESC_LENGTH_INTERFACE, - USB_DESC_TYPE_INTERFACE, - USB_DYNAMIC, - 0x00, - 0x01, - USB_CDC_CLASS_COMM, - USB_CDC_SUBCLASS_ACM, - USB_CDC_PROTOCOL_V25TER, -#ifdef RT_USB_DEVICE_COMPOSITE - VCOM_INTF_STR_INDEX, -#else - 0, -#endif - }, - /* Header Functional Descriptor */ - { - 0x05, - USB_CDC_CS_INTERFACE, - USB_CDC_SCS_HEADER, - 0x0110, - }, - /* Call Management Functional Descriptor */ - { - 0x05, - USB_CDC_CS_INTERFACE, - USB_CDC_SCS_CALL_MGMT, - 0x00, - USB_DYNAMIC, - }, - /* Abstract Control Management Functional Descriptor */ - { - 0x04, - USB_CDC_CS_INTERFACE, - USB_CDC_SCS_ACM, - 0x02, - }, - /* Union Functional Descriptor */ - { - 0x05, - USB_CDC_CS_INTERFACE, - USB_CDC_SCS_UNION, - USB_DYNAMIC, - USB_DYNAMIC, - }, - /* Endpoint Descriptor */ - { - USB_DESC_LENGTH_ENDPOINT, - USB_DESC_TYPE_ENDPOINT, - USB_DYNAMIC | USB_DIR_IN, - USB_EP_ATTR_INT, - 0x08, - 0xFF, - }, -}; - -/* data interface descriptor */ -rt_align(4) -const static struct ucdc_data_descriptor _data_desc = -{ - /* interface descriptor */ - { - USB_DESC_LENGTH_INTERFACE, - USB_DESC_TYPE_INTERFACE, - USB_DYNAMIC, - 0x00, - 0x02, - USB_CDC_CLASS_DATA, - 0x00, - 0x00, - 0x00, - }, - /* endpoint, bulk out */ - { - USB_DESC_LENGTH_ENDPOINT, - USB_DESC_TYPE_ENDPOINT, - USB_DYNAMIC | USB_DIR_OUT, - USB_EP_ATTR_BULK, - USB_CDC_BUFSIZE, - 0x00, - }, - /* endpoint, bulk in */ - { - USB_DESC_LENGTH_ENDPOINT, - USB_DESC_TYPE_ENDPOINT, - USB_DYNAMIC | USB_DIR_IN, - USB_EP_ATTR_BULK, - USB_CDC_BUFSIZE, - 0x00, - }, -}; -rt_align(4) -static char serno[_SER_NO_LEN + 1] = {'\0'}; -rt_weak rt_err_t vcom_get_stored_serno(char *serno, int size); - -rt_err_t vcom_get_stored_serno(char *serno, int size) -{ - return -RT_ERROR; -} -rt_align(4) -const static char* _ustring[] = -{ - "Language", - "RT-Thread Team.", - "RTT Virtual Serial", - serno, - "Configuration", - "Interface", -}; -static void rt_usb_vcom_init(struct ufunction *func); - -static void _vcom_reset_state(ufunction_t func) -{ - struct vcom* data; - rt_base_t level; - - RT_ASSERT(func != RT_NULL) - - data = (struct vcom*)func->user_data; - - level = rt_hw_interrupt_disable(); - data->connected = RT_FALSE; - data->in_sending = RT_FALSE; - /*rt_kprintf("reset USB serial\n", cnt);*/ - rt_hw_interrupt_enable(level); -} - -/** - * This function will handle cdc bulk in endpoint request. - * - * @param func the usb function object. - * @param size request size. - * - * @return RT_EOK. - */ -static rt_err_t _ep_in_handler(ufunction_t func, rt_size_t size) -{ - struct vcom *data; - rt_size_t request_size; - - RT_ASSERT(func != RT_NULL); - - data = (struct vcom*)func->user_data; - request_size = data->ep_in->request.size; - LOG_D("_ep_in_handler %d", request_size); - if ((request_size != 0) && ((request_size % EP_MAXPACKET(data->ep_in)) == 0)) - { - /* don't have data right now. Send a zero-length-packet to - * terminate the transaction. - * - * FIXME: actually, this might not be the right place to send zlp. - * Only the rt_device_write could know how much data is sending. */ - data->in_sending = RT_TRUE; - - data->ep_in->request.buffer = RT_NULL; - data->ep_in->request.size = 0; - data->ep_in->request.req_type = UIO_REQUEST_WRITE; - rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); - - return RT_EOK; - } - - rt_completion_done(&data->wait); - - return RT_EOK; -} - -/** - * This function will handle cdc bulk out endpoint request. - * - * @param func the usb function object. - * @param size request size. - * - * @return RT_EOK. - */ -static rt_err_t _ep_out_handler(ufunction_t func, rt_size_t size) -{ - rt_base_t level; - struct vcom *data; - - RT_ASSERT(func != RT_NULL); - - LOG_D("_ep_out_handler %d", size); - - data = (struct vcom*)func->user_data; - /* ensure serial is active */ - if((data->serial.parent.flag & RT_DEVICE_FLAG_ACTIVATED) - && (data->serial.parent.open_flag & RT_DEVICE_OFLAG_OPEN)) - { - /* receive data from USB VCOM */ - level = rt_hw_interrupt_disable(); - - rt_ringbuffer_put(&data->rx_ringbuffer, data->ep_out->buffer, size); - rt_hw_interrupt_enable(level); - - /* notify receive data */ - rt_hw_serial_isr(&data->serial,RT_SERIAL_EVENT_RX_IND); - } - - data->ep_out->request.buffer = data->ep_out->buffer; - data->ep_out->request.size = EP_MAXPACKET(data->ep_out); - data->ep_out->request.req_type = UIO_REQUEST_READ_BEST; - rt_usbd_io_request(func->device, data->ep_out, &data->ep_out->request); - - return RT_EOK; -} - -/** - * This function will handle cdc interrupt in endpoint request. - * - * @param device the usb device object. - * @param size request size. - * - * @return RT_EOK. - */ -static rt_err_t _ep_cmd_handler(ufunction_t func, rt_size_t size) -{ - RT_ASSERT(func != RT_NULL); - - LOG_D("_ep_cmd_handler"); - - return RT_EOK; -} - -/** - * This function will handle cdc_get_line_coding request. - * - * @param device the usb device object. - * @param setup the setup request. - * - * @return RT_EOK on successful. - */ -static rt_err_t _cdc_get_line_coding(udevice_t device, ureq_t setup) -{ - struct ucdc_line_coding data; - rt_uint16_t size; - - RT_ASSERT(device != RT_NULL); - RT_ASSERT(setup != RT_NULL); - - LOG_D("_cdc_get_line_coding"); - - data.dwDTERate = 115200; - data.bCharFormat = 0; - data.bDataBits = 8; - data.bParityType = 0; - size = setup->wLength > 7 ? 7 : setup->wLength; - - rt_usbd_ep0_write(device, (void*)&data, size); - - return RT_EOK; -} - -static rt_err_t _cdc_set_line_coding_callback(udevice_t device, rt_size_t size) -{ - LOG_D("_cdc_set_line_coding_callback"); - - dcd_ep0_send_status(device->dcd); - - return RT_EOK; -} - -/** - * This function will handle cdc_set_line_coding request. - * - * @param device the usb device object. - * @param setup the setup request. - * - * @return RT_EOK on successful. - */ -static rt_err_t _cdc_set_line_coding(udevice_t device, ureq_t setup) -{ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(setup != RT_NULL); - - LOG_D("_cdc_set_line_coding"); - - rt_usbd_ep0_read(device, (void*)&line_coding, sizeof(struct ucdc_line_coding), - _cdc_set_line_coding_callback); - - return RT_EOK; -} - -/** - * This function will handle cdc interface request. - * - * @param device the usb device object. - * @param setup the setup request. - * - * @return RT_EOK on successful. - */ -static rt_err_t _interface_handler(ufunction_t func, ureq_t setup) -{ - struct vcom *data; - - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->device != RT_NULL); - RT_ASSERT(setup != RT_NULL); - - data = (struct vcom*)func->user_data; - - switch(setup->bRequest) - { - case CDC_SEND_ENCAPSULATED_COMMAND: - break; - case CDC_GET_ENCAPSULATED_RESPONSE: - break; - case CDC_SET_COMM_FEATURE: - break; - case CDC_GET_COMM_FEATURE: - break; - case CDC_CLEAR_COMM_FEATURE: - break; - case CDC_SET_LINE_CODING: - _cdc_set_line_coding(func->device, setup); - break; - case CDC_GET_LINE_CODING: - _cdc_get_line_coding(func->device, setup); - break; - case CDC_SET_CONTROL_LINE_STATE: - data->connected = (setup->wValue & 0x01) > 0?RT_TRUE:RT_FALSE; - LOG_D("vcom state:%d ", data->connected); - dcd_ep0_send_status(func->device->dcd); - break; - case CDC_SEND_BREAK: - break; - default: - rt_kprintf("unknown cdc request\n",setup->request_type); - return -RT_ERROR; - } - - return RT_EOK; -} - -/** - * This function will run cdc function, it will be called on handle set configuration request. - * - * @param func the usb function object. - * - * @return RT_EOK on successful. - */ -static rt_err_t _function_enable(ufunction_t func) -{ - struct vcom *data; - - RT_ASSERT(func != RT_NULL); - - LOG_D("cdc function enable"); - - _vcom_reset_state(func); - - data = (struct vcom*)func->user_data; - data->ep_out->buffer = rt_malloc(CDC_RX_BUFSIZE); - RT_ASSERT(data->ep_out->buffer != RT_NULL); - -#ifdef RT_USING_SERIAL_V2 - data->serial.serial_rx = &data->rx_ringbuffer; -#endif - - data->ep_out->request.buffer = data->ep_out->buffer; - data->ep_out->request.size = EP_MAXPACKET(data->ep_out); - - data->ep_out->request.req_type = UIO_REQUEST_READ_BEST; - rt_usbd_io_request(func->device, data->ep_out, &data->ep_out->request); - - return RT_EOK; -} - -/** - * This function will stop cdc function, it will be called on handle set configuration request. - * - * @param func the usb function object. - * - * @return RT_EOK on successful. - */ -static rt_err_t _function_disable(ufunction_t func) -{ - struct vcom *data; - - RT_ASSERT(func != RT_NULL); - - LOG_D("cdc function disable"); - - _vcom_reset_state(func); - - data = (struct vcom*)func->user_data; - if(data->ep_out->buffer != RT_NULL) - { - rt_free(data->ep_out->buffer); - data->ep_out->buffer = RT_NULL; - } - - return RT_EOK; -} - -static struct ufunction_ops ops = -{ - _function_enable, - _function_disable, - RT_NULL, -}; - -/** - * This function will configure cdc descriptor. - * - * @param comm the communication interface number. - * @param data the data interface number. - * - * @return RT_EOK on successful. - */ -static rt_err_t _cdc_descriptor_config(ucdc_comm_desc_t comm, - rt_uint8_t cintf_nr, ucdc_data_desc_t data, rt_uint8_t dintf_nr) -{ - comm->call_mgmt_desc.data_interface = dintf_nr; - comm->union_desc.master_interface = cintf_nr; - comm->union_desc.slave_interface0 = dintf_nr; -#ifdef RT_USB_DEVICE_COMPOSITE - comm->iad_desc.bFirstInterface = cintf_nr; -#endif - - return RT_EOK; -} - -/** - * This function will create a cdc function instance. - * - * @param device the usb device object. - * - * @return RT_EOK on successful. - */ -ufunction_t rt_usbd_function_cdc_create(udevice_t device) -{ - ufunction_t func; - struct vcom* data; - uintf_t intf_comm, intf_data; - ualtsetting_t comm_setting, data_setting; - ucdc_data_desc_t data_desc; - ucdc_comm_desc_t comm_desc; - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - - rt_memset(serno, 0, _SER_NO_LEN + 1); - if(vcom_get_stored_serno(serno, _SER_NO_LEN) != RT_EOK) - { - rt_memset(serno, 0, _SER_NO_LEN + 1); - rt_memcpy(serno, _SER_NO, rt_strlen(_SER_NO)); - } -#ifdef RT_USB_DEVICE_COMPOSITE - rt_usbd_device_set_interface_string(device, VCOM_INTF_STR_INDEX, _ustring[2]); -#else - /* set usb device string description */ - rt_usbd_device_set_string(device, _ustring); -#endif - /* create a cdc function */ - func = rt_usbd_function_new(device, &dev_desc, &ops); - - /* support HS */ - rt_usbd_device_set_qualifier(device, &dev_qualifier); - - /* allocate memory for cdc vcom data */ - data = (struct vcom*)rt_malloc(sizeof(struct vcom)); - RT_ASSERT(data != RT_NULL); - rt_memset(data, 0, sizeof(struct vcom)); - func->user_data = (void*)data; - - /* initilize vcom */ - rt_usb_vcom_init(func); - - /* create a cdc communication interface and a cdc data interface */ - intf_comm = rt_usbd_interface_new(device, _interface_handler); - intf_data = rt_usbd_interface_new(device, _interface_handler); - - /* create a communication alternate setting and a data alternate setting */ - comm_setting = rt_usbd_altsetting_new(sizeof(struct ucdc_comm_descriptor)); - data_setting = rt_usbd_altsetting_new(sizeof(struct ucdc_data_descriptor)); - - /* config desc in alternate setting */ - rt_usbd_altsetting_config_descriptor(comm_setting, &_comm_desc, - (rt_off_t)&((ucdc_comm_desc_t)0)->intf_desc); - rt_usbd_altsetting_config_descriptor(data_setting, &_data_desc, 0); - /* configure the cdc interface descriptor */ - _cdc_descriptor_config(comm_setting->desc, intf_comm->intf_num, data_setting->desc, intf_data->intf_num); - - /* create a command endpoint */ - comm_desc = (ucdc_comm_desc_t)comm_setting->desc; - data->ep_cmd = rt_usbd_endpoint_new(&comm_desc->ep_desc, _ep_cmd_handler); - - /* add the command endpoint to the cdc communication interface */ - rt_usbd_altsetting_add_endpoint(comm_setting, data->ep_cmd); - - /* add the communication alternate setting to the communication interface, - then set default setting of the interface */ - rt_usbd_interface_add_altsetting(intf_comm, comm_setting); - rt_usbd_set_altsetting(intf_comm, 0); - - /* add the communication interface to the cdc function */ - rt_usbd_function_add_interface(func, intf_comm); - - /* create a bulk in and a bulk endpoint */ - data_desc = (ucdc_data_desc_t)data_setting->desc; - data->ep_out = rt_usbd_endpoint_new(&data_desc->ep_out_desc, _ep_out_handler); - data->ep_in = rt_usbd_endpoint_new(&data_desc->ep_in_desc, _ep_in_handler); - - /* add the bulk out and bulk in endpoints to the data alternate setting */ - rt_usbd_altsetting_add_endpoint(data_setting, data->ep_in); - rt_usbd_altsetting_add_endpoint(data_setting, data->ep_out); - - /* add the data alternate setting to the data interface - then set default setting of the interface */ - rt_usbd_interface_add_altsetting(intf_data, data_setting); - rt_usbd_set_altsetting(intf_data, 0); - - /* add the cdc data interface to cdc function */ - rt_usbd_function_add_interface(func, intf_data); - - return func; -} - -/** -* UART device in RT-Thread -*/ -static rt_err_t _vcom_configure(struct rt_serial_device *serial, - struct serial_configure *cfg) -{ - return RT_EOK; -} - -static rt_err_t _vcom_control(struct rt_serial_device *serial, - int cmd, void *arg) -{ - struct ufunction *func; - struct vcom *data; - - func = (struct ufunction*)serial->parent.user_data; - data = (struct vcom*)func->user_data; - - switch (cmd) - { - case RT_DEVICE_CTRL_CLR_INT: - /* disable rx irq */ - break; - case RT_DEVICE_CTRL_SET_INT: - /* enable rx irq */ - break; - case RT_USBD_CLASS_CTRL_CONNECTED: - (*(rt_bool_t*)arg) = data->connected; - break; - } - - return RT_EOK; -} - -static int _vcom_getc(struct rt_serial_device *serial) -{ - int result; - rt_uint8_t ch; - rt_base_t level; - struct ufunction *func; - struct vcom *data; - - func = (struct ufunction*)serial->parent.user_data; - data = (struct vcom*)func->user_data; - - result = -1; - - level = rt_hw_interrupt_disable(); - - if(rt_ringbuffer_getchar(&data->rx_ringbuffer, &ch) != 0) - { - result = ch; - } - - rt_hw_interrupt_enable(level); - - return result; -} - -static rt_ssize_t _vcom_rb_block_put(struct vcom *data, const rt_uint8_t *buf, rt_size_t size) -{ - rt_base_t level; - rt_size_t put_len = 0; - rt_size_t w_ptr = 0; - rt_uint32_t res; - rt_size_t remain_size = size; - - while (remain_size) - { - level = rt_hw_interrupt_disable(); - put_len = rt_ringbuffer_put(&data->tx_ringbuffer, (const rt_uint8_t *)&buf[w_ptr], remain_size); - rt_hw_interrupt_enable(level); - w_ptr += put_len; - remain_size -= put_len; - if (put_len == 0) - { - rt_event_recv(&data->tx_event, CDC_TX_HAS_SPACE, - RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, - VCOM_TX_TIMEOUT, &res); - } - else - { - rt_event_send(&data->tx_event, CDC_TX_HAS_DATE); - } - } - - return size; -} - -#ifdef RT_USING_SERIAL_V1 -static rt_ssize_t _vcom_tx(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction) -#else -static rt_ssize_t _vcom_tx(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, rt_uint32_t tx_flag) -#endif -{ - struct ufunction *func; - struct vcom *data; - rt_uint32_t send_size = 0; - rt_size_t ptr = 0; - rt_uint8_t crlf[2] = {'\r', '\n',}; - - func = (struct ufunction*)serial->parent.user_data; - data = (struct vcom*)func->user_data; - - RT_ASSERT(serial != RT_NULL); - RT_ASSERT(buf != RT_NULL); - - LOG_D("%s",__func__); - - if (data->connected) - { - if((serial->parent.open_flag & RT_DEVICE_FLAG_STREAM)) - { - while(send_size < size) - { - while(ptr < size && buf[ptr] != '\n') - { - ptr++; - } - if(ptr < size) - { - send_size += _vcom_rb_block_put(data, (const rt_uint8_t *)&buf[send_size], ptr - send_size); - _vcom_rb_block_put(data, crlf, 2); - send_size++; - ptr++; - } - else if (ptr == size) - { - send_size += _vcom_rb_block_put(data, (const rt_uint8_t *)&buf[send_size], ptr - send_size); - } - else - { - break; - } - } - } - else - { - while (send_size < size) - { - send_size += _vcom_rb_block_put(data, (rt_uint8_t *)&buf[send_size], size - send_size); - } - } - } - else - { - /* recover dataqueue resources */ - rt_hw_serial_isr(&data->serial,RT_SERIAL_EVENT_TX_DMADONE); - } - - return size; -} -static int _vcom_putc(struct rt_serial_device *serial, char c) -{ - rt_base_t level; - struct ufunction *func; - struct vcom *data; - - func = (struct ufunction*)serial->parent.user_data; - data = (struct vcom*)func->user_data; - - RT_ASSERT(serial != RT_NULL); - - if (data->connected) - { - if(c == '\n' && (serial->parent.open_flag & RT_DEVICE_FLAG_STREAM)) - { - level = rt_hw_interrupt_disable(); - rt_ringbuffer_putchar_force(&data->tx_ringbuffer, '\r'); - rt_hw_interrupt_enable(level); - rt_event_send(&data->tx_event, CDC_TX_HAS_DATE); - } - level = rt_hw_interrupt_disable(); - rt_ringbuffer_putchar_force(&data->tx_ringbuffer, c); - rt_hw_interrupt_enable(level); - rt_event_send(&data->tx_event, CDC_TX_HAS_DATE); - } - - return 1; -} - -static const struct rt_uart_ops usb_vcom_ops = -{ - _vcom_configure, - _vcom_control, - _vcom_putc, - _vcom_getc, - _vcom_tx -}; - -/* Vcom Tx Thread */ -static void vcom_tx_thread_entry(void* parameter) -{ - rt_base_t level; - rt_uint32_t res; - struct ufunction *func = (struct ufunction *)parameter; - struct vcom *data = (struct vcom*)func->user_data; - rt_uint8_t ch[CDC_BULKIN_MAXSIZE]; - - while (1) - { - if - ( - (rt_event_recv(&data->tx_event, CDC_TX_HAS_DATE, - RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, - RT_WAITING_FOREVER, &res) != RT_EOK) || - (!(res & CDC_TX_HAS_DATE)) - ) - { - continue; - } - if(!(res & CDC_TX_HAS_DATE)) - { - continue; - } - while(rt_ringbuffer_data_len(&data->tx_ringbuffer)) - { - level = rt_hw_interrupt_disable(); - res = rt_ringbuffer_get(&data->tx_ringbuffer, ch, CDC_BULKIN_MAXSIZE); - rt_hw_interrupt_enable(level); - - if(!res) - { - continue; - } - if (!data->connected) - { -#ifdef RT_USING_SERIAL_V1 -#ifndef VCOM_TX_USE_DMA - if(data->serial.parent.open_flag & RT_DEVICE_FLAG_INT_TX) -#else - if(data->serial.parent.open_flag & RT_DEVICE_FLAG_DMA_TX) -#endif -#endif -#ifdef RT_USING_SERIAL_V2 - if(data->serial.parent.open_flag & RT_DEVICE_FLAG_TX_BLOCKING) -#endif - { - /* drop msg */ -#ifndef VCOM_TX_USE_DMA - rt_hw_serial_isr(&data->serial,RT_SERIAL_EVENT_TX_DONE); -#else - rt_hw_serial_isr(&data->serial,RT_SERIAL_EVENT_TX_DMADONE); -#endif - } - continue; - } - rt_completion_init(&data->wait); - data->ep_in->request.buffer = ch; - data->ep_in->request.size = res; - - data->ep_in->request.req_type = UIO_REQUEST_WRITE; - - rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); - - if (rt_completion_wait(&data->wait, VCOM_TX_TIMEOUT) != RT_EOK) - { - LOG_D("vcom tx timeout"); - } -#ifdef RT_USING_SERIAL_V1 -#ifndef VCOM_TX_USE_DMA - if(data->serial.parent.open_flag & RT_DEVICE_FLAG_INT_TX) -#else - if(data->serial.parent.open_flag & RT_DEVICE_FLAG_DMA_TX) -#endif -#endif -#ifdef RT_USING_SERIAL_V2 - if(data->serial.parent.open_flag & RT_DEVICE_FLAG_TX_BLOCKING) -#endif - { -#ifndef VCOM_TX_USE_DMA - rt_hw_serial_isr(&data->serial,RT_SERIAL_EVENT_TX_DONE); -#else - rt_hw_serial_isr(&data->serial,RT_SERIAL_EVENT_TX_DMADONE); -#endif - rt_event_send(&data->tx_event, CDC_TX_HAS_SPACE); - } - } - - } -} - -static void rt_usb_vcom_init(struct ufunction *func) -{ - rt_err_t result = RT_EOK; - struct serial_configure config; - struct vcom *data = (struct vcom*)func->user_data; - - /* initialize ring buffer */ - rt_ringbuffer_init(&data->rx_ringbuffer, data->rx_rbp, CDC_RX_BUFSIZE); - rt_ringbuffer_init(&data->tx_ringbuffer, data->tx_rbp, CDC_TX_BUFSIZE); - - rt_event_init(&data->tx_event, "vcom", RT_IPC_FLAG_FIFO); - - config.baud_rate = BAUD_RATE_115200; - config.data_bits = DATA_BITS_8; - config.stop_bits = STOP_BITS_1; - config.parity = PARITY_NONE; - config.bit_order = BIT_ORDER_LSB; - config.invert = NRZ_NORMAL; -#if defined(RT_USING_SERIAL_V1) - config.bufsz = CDC_RX_BUFSIZE; -#elif defined(RT_USING_SERIAL_V2) - config.rx_bufsz = CDC_RX_BUFSIZE; - config.tx_bufsz = CDC_TX_BUFSIZE; -#endif - data->serial.ops = &usb_vcom_ops; - data->serial.serial_rx = RT_NULL; - data->serial.config = config; - - /* register vcom device */ - rt_hw_serial_register(&data->serial, VCOM_DEVICE, -#ifndef VCOM_TX_USE_DMA - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX, -#else - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_DMA_TX, -#endif - func); - - /* init usb device thread */ - rt_thread_init(&vcom_thread, "vcom", - vcom_tx_thread_entry, func, - vcom_thread_stack, VCOM_TASK_STK_SIZE, - 16, 20); - result = rt_thread_startup(&vcom_thread); - RT_ASSERT(result == RT_EOK); -} -struct udclass vcom_class = -{ - .rt_usbd_function_create = rt_usbd_function_cdc_create -}; - -int rt_usbd_vcom_class_register(void) -{ - rt_usbd_class_register(&vcom_class); - return 0; -} -INIT_PREV_EXPORT(rt_usbd_vcom_class_register); - -#endif diff --git a/components/drivers/usb/usbdevice/class/ecm.c b/components/drivers/usb/usbdevice/class/ecm.c deleted file mode 100644 index d856a1e332..0000000000 --- a/components/drivers/usb/usbdevice/class/ecm.c +++ /dev/null @@ -1,682 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2017-11-19 ZYH first version - * 2019-06-10 ZYH fix hotplug - */ - -#include <rtdevice.h> -#ifdef RT_USB_DEVICE_ECM -#include "cdc.h" - -#define DBG_LEVEL DBG_WARNING -#define DBG_SECTION_NAME "ECM" -#include <rtdbg.h> - -/* RT-Thread LWIP ethernet interface */ -#include <netif/ethernetif.h> - -#ifndef USB_ETH_MTU -#define USB_ETH_MTU 1514 -#endif -#define MAX_ADDR_LEN 6 -#define ECM_INTF_STR_INDEX 10 - -struct rt_ecm_eth -{ - /* inherit from ethernet device */ - struct eth_device parent; - struct ufunction * func; - struct cdc_eps eps; - /* interface address info */ - rt_uint8_t host_addr[MAX_ADDR_LEN]; - rt_uint8_t dev_addr[MAX_ADDR_LEN]; - - rt_align(4) - rt_uint8_t rx_pool[512]; - rt_align(4) - rt_size_t rx_size; - rt_align(4) - rt_size_t rx_offset; - rt_align(4) - char rx_buffer[USB_ETH_MTU]; - char tx_buffer[USB_ETH_MTU]; - - struct rt_semaphore tx_buffer_free; - -}; -typedef struct rt_ecm_eth * rt_ecm_eth_t; - -rt_align(4) -static struct udevice_descriptor _dev_desc = -{ - USB_DESC_LENGTH_DEVICE, /* bLength */ - USB_DESC_TYPE_DEVICE, /* type */ - USB_BCD_VERSION, /* bcdUSB */ - USB_CLASS_CDC, /* bDeviceClass */ - USB_CDC_SUBCLASS_ETH, /* bDeviceSubClass */ - USB_CDC_PROTOCOL_NONE, /* bDeviceProtocol */ - 0x40, /* bMaxPacketSize0 */ - _VENDOR_ID, /* idVendor */ - _PRODUCT_ID, /* idProduct */ - USB_BCD_DEVICE, /* bcdDevice */ - USB_STRING_MANU_INDEX, /* iManufacturer */ - USB_STRING_PRODUCT_INDEX, /* iProduct */ - USB_STRING_SERIAL_INDEX, /* iSerialNumber */ - USB_DYNAMIC /* bNumConfigurations */ -}; - -/* communcation interface descriptor */ -rt_align(4) -const static struct ucdc_eth_descriptor _comm_desc = -{ -#ifdef RT_USB_DEVICE_COMPOSITE - /* Interface Association Descriptor */ - { - USB_DESC_LENGTH_IAD, - USB_DESC_TYPE_IAD, - USB_DYNAMIC, - 0x02, - USB_CDC_CLASS_COMM, - USB_CDC_SUBCLASS_ETH, - USB_CDC_PROTOCOL_NONE, - 0x00, - }, -#endif - /* Interface Descriptor */ - { - USB_DESC_LENGTH_INTERFACE, - USB_DESC_TYPE_INTERFACE, - USB_DYNAMIC, - 0x00, - 0x01, - USB_CDC_CLASS_COMM, - USB_CDC_SUBCLASS_ETH, - USB_CDC_PROTOCOL_NONE, -#ifdef RT_USB_DEVICE_COMPOSITE - ECM_INTF_STR_INDEX, -#else - 0x00, -#endif - }, - /* Header Functional Descriptor */ - { - sizeof(struct ucdc_header_descriptor), - USB_CDC_CS_INTERFACE, - USB_CDC_SCS_HEADER, - 0x0110, - }, - /* Union Functional Descriptor */ - { - sizeof(struct ucdc_union_descriptor), - USB_CDC_CS_INTERFACE, - USB_CDC_SCS_UNION, - USB_DYNAMIC, - USB_DYNAMIC, - }, - /* Abstract Control Management Functional Descriptor */ - { - sizeof(struct ucdc_enet_descriptor), - USB_CDC_CS_INTERFACE, - USB_CDC_SCS_ETH, - USB_STRING_SERIAL_INDEX, - {0,0,0,0}, - USB_ETH_MTU, - 0x00, - 0x00, - }, - /* Endpoint Descriptor */ - { - USB_DESC_LENGTH_ENDPOINT, - USB_DESC_TYPE_ENDPOINT, - USB_DIR_IN | USB_DYNAMIC, - USB_EP_ATTR_INT, - 0x08, - 0xFF, - }, -}; - -/* data interface descriptor */ -rt_align(4) -const static struct ucdc_data_descriptor _data_desc = -{ - /* interface descriptor */ - { - USB_DESC_LENGTH_INTERFACE, - USB_DESC_TYPE_INTERFACE, - USB_DYNAMIC, - 0x00, - 0x02, - USB_CDC_CLASS_DATA, - USB_CDC_SUBCLASS_ETH, - 0x00, - 0x00, - }, - /* endpoint, bulk out */ - { - USB_DESC_LENGTH_ENDPOINT, - USB_DESC_TYPE_ENDPOINT, - USB_DIR_OUT | USB_DYNAMIC, - USB_EP_ATTR_BULK, - USB_DYNAMIC, - 0x00, - }, - /* endpoint, bulk in */ - { - USB_DESC_LENGTH_ENDPOINT, - USB_DESC_TYPE_ENDPOINT, - USB_DYNAMIC | USB_DIR_IN, - USB_EP_ATTR_BULK, - USB_DYNAMIC, - 0x00, - }, -}; - -rt_align(4) -const static char* _ustring[] = -{ - "Language", /* LANGID */ - "RT-Thread Team.", /* MANU */ - "RT-Thread ECM device", /* PRODUCT */ - "3497F694ECAB", /* SERIAL (MAC)*/ - "Configuration", /* CONFIG */ - "Interface", /* INTERFACE */ -}; - -rt_align(4) -//FS and HS needed -static struct usb_qualifier_descriptor dev_qualifier = -{ - sizeof(dev_qualifier), //bLength - USB_DESC_TYPE_DEVICEQUALIFIER, //bDescriptorType - 0x0200, //bcdUSB - USB_CLASS_CDC, //bDeviceClass - USB_CDC_SUBCLASS_ETH, //bDeviceSubClass - USB_CDC_PROTOCOL_NONE, //bDeviceProtocol - 64, //bMaxPacketSize0 - 0x01, //bNumConfigurations - 0, -}; - -static rt_err_t _cdc_send_notifi(ufunction_t func,ucdc_notification_code_t notifi,rt_uint16_t wValue,rt_uint16_t wLength) -{ - static struct ucdc_management_element_notifications _notifi; - cdc_eps_t eps; - RT_ASSERT(func!=RT_NULL) - eps = &((rt_ecm_eth_t)func->user_data)->eps; - _notifi.bmRequestType = 0xA1; - _notifi.bNotificatinCode = notifi; - _notifi.wValue = wValue; - _notifi.wLength = wLength; - - eps->ep_cmd->request.buffer = (void *)&_notifi; - eps->ep_cmd->request.size = 8; - eps->ep_cmd->request.req_type = UIO_REQUEST_WRITE; - rt_usbd_io_request(func->device, eps->ep_cmd, &eps->ep_cmd->request); - return RT_EOK; -} - - -static rt_err_t _ecm_set_eth_packet_filter(ufunction_t func, ureq_t setup) -{ - rt_ecm_eth_t _ecm_eth = (rt_ecm_eth_t)func->user_data; - dcd_ep0_send_status(func->device->dcd); - - /* send link up. */ - eth_device_linkchange(&_ecm_eth->parent, RT_TRUE); - _cdc_send_notifi(func, UCDC_NOTIFI_NETWORK_CONNECTION, 1, 0); - -#ifdef LWIP_USING_DHCPD - extern void dhcpd_start(const char *netif_name); - dhcpd_start("u0"); -#endif - - return RT_EOK; -} -/** - * This function will handle rndis interface request. - * - * @param device the usb device object. - * @param setup the setup request. - * - * @return RT_EOK on successful. - */ -static rt_err_t _interface_handler(ufunction_t func, ureq_t setup) -{ - RT_ASSERT(func != RT_NULL); - RT_ASSERT(setup != RT_NULL); - - switch(setup->bRequest) - { - case CDC_SET_ETH_PACKET_FILTER: - LOG_D("CDC_SET_ETH_PACKET_FILTER"); - _ecm_set_eth_packet_filter(func, setup); - break; - default: - LOG_E("Unknow setup->bRequest: 0x%02X", setup->bRequest); - break; - } - return RT_EOK; -} - -/** - * This function will handle rndis bulk in endpoint request. - * - * @param device the usb device object. - * @param size request size. - * - * @return RT_EOK. - */ - -static rt_err_t _ep_in_handler(ufunction_t func, rt_size_t size) -{ - rt_ecm_eth_t ecm_device = (rt_ecm_eth_t)func->user_data; - rt_sem_release(&ecm_device->tx_buffer_free); - return RT_EOK; -} - -/** - * This function will handle RNDIS bulk out endpoint request. - * - * @param device the usb device object. - * @param size request size. - * - * @return RT_EOK. - */ -static rt_err_t _ep_out_handler(ufunction_t func, rt_size_t size) -{ - rt_ecm_eth_t ecm_device = (rt_ecm_eth_t)func->user_data; - rt_memcpy((void *)(ecm_device->rx_buffer + ecm_device->rx_offset),ecm_device->rx_pool,size); - ecm_device->rx_offset += size; - if(size < EP_MAXPACKET(ecm_device->eps.ep_out)) - { - ecm_device->rx_size = ecm_device->rx_offset; - ecm_device->rx_offset = 0; - eth_device_ready(&ecm_device->parent); - - }else - { - ecm_device->eps.ep_out->request.buffer = ecm_device->eps.ep_out->buffer; - ecm_device->eps.ep_out->request.size = EP_MAXPACKET(ecm_device->eps.ep_out); - ecm_device->eps.ep_out->request.req_type = UIO_REQUEST_READ_BEST; - rt_usbd_io_request(ecm_device->func->device, ecm_device->eps.ep_out, &ecm_device->eps.ep_out->request); - } - - - return RT_EOK; -} -static rt_err_t rt_ecm_eth_init(rt_device_t dev) -{ - return RT_EOK; -} - -static rt_err_t rt_ecm_eth_open(rt_device_t dev, rt_uint16_t oflag) -{ - return RT_EOK; -} - -static rt_err_t rt_ecm_eth_close(rt_device_t dev) -{ - return RT_EOK; -} - -static rt_ssize_t rt_ecm_eth_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) -{ - rt_set_errno(-RT_ENOSYS); - return 0; -} - -static rt_ssize_t rt_ecm_eth_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) -{ - rt_set_errno(-RT_ENOSYS); - return 0; -} -static rt_err_t rt_ecm_eth_control(rt_device_t dev, int cmd, void *args) -{ - rt_ecm_eth_t ecm_eth_dev = (rt_ecm_eth_t)dev; - switch(cmd) - { - case NIOCTL_GADDR: - /* get mac address */ - if(args) rt_memcpy(args, ecm_eth_dev->dev_addr, MAX_ADDR_LEN); - else return -RT_ERROR; - break; - - default : - break; - } - - return RT_EOK; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops ecm_device_ops = -{ - rt_ecm_eth_init, - rt_ecm_eth_open, - rt_ecm_eth_close, - rt_ecm_eth_read, - rt_ecm_eth_write, - rt_ecm_eth_control -}; -#endif - -struct pbuf *rt_ecm_eth_rx(rt_device_t dev) -{ - struct pbuf* p = RT_NULL; - rt_uint32_t offset = 0; - rt_ecm_eth_t ecm_eth_dev = (rt_ecm_eth_t)dev; - if(ecm_eth_dev->rx_size != 0) - { - /* allocate buffer */ - p = pbuf_alloc(PBUF_RAW, ecm_eth_dev->rx_size, PBUF_RAM); - if (p != RT_NULL) - { - struct pbuf* q; - - for (q = p; q != RT_NULL; q= q->next) - { - /* Copy the received frame into buffer from memory pointed by the current ETHERNET DMA Rx descriptor */ - rt_memcpy(q->payload, - (rt_uint8_t *)((ecm_eth_dev->rx_buffer) + offset), - q->len); - offset += q->len; - } - } - } - - { - if(ecm_eth_dev->func->device->state == USB_STATE_CONFIGURED) - { - ecm_eth_dev->rx_size = 0; - ecm_eth_dev->rx_offset = 0; - ecm_eth_dev->eps.ep_out->request.buffer = ecm_eth_dev->eps.ep_out->buffer; - ecm_eth_dev->eps.ep_out->request.size = EP_MAXPACKET(ecm_eth_dev->eps.ep_out); - ecm_eth_dev->eps.ep_out->request.req_type = UIO_REQUEST_READ_BEST; - rt_usbd_io_request(ecm_eth_dev->func->device, ecm_eth_dev->eps.ep_out, &ecm_eth_dev->eps.ep_out->request); - } - } - - return p; -} - -rt_err_t rt_ecm_eth_tx(rt_device_t dev, struct pbuf* p) -{ - struct pbuf* q; - char * pbuffer; - rt_err_t result = RT_EOK; - rt_ecm_eth_t ecm_eth_dev = (rt_ecm_eth_t)dev; - - if(!ecm_eth_dev->parent.link_status) - { - LOG_D("linkdown, drop pkg"); - return RT_EOK; - } - - if(p->tot_len > USB_ETH_MTU) - { - LOG_W("ECM MTU is:%d, but the send packet size is %d", - USB_ETH_MTU, p->tot_len); - p->tot_len = USB_ETH_MTU; - } - - result = rt_sem_take(&ecm_eth_dev->tx_buffer_free, rt_tick_from_millisecond(1000)); - if(result != RT_EOK) - { - LOG_W("wait for buffer free timeout"); - /* if cost 1s to wait send done it said that connection is close . drop it */ - rt_sem_release(&ecm_eth_dev->tx_buffer_free); - return result; - } - - pbuffer = (char *)&ecm_eth_dev->tx_buffer; - for (q = p; q != NULL; q = q->next) - { - rt_memcpy(pbuffer, q->payload, q->len); - pbuffer += q->len; - } - - { - if(ecm_eth_dev->func->device->state == USB_STATE_CONFIGURED) - { - ecm_eth_dev->eps.ep_in->request.buffer = (void *)&ecm_eth_dev->tx_buffer; - ecm_eth_dev->eps.ep_in->request.size = p->tot_len; - ecm_eth_dev->eps.ep_in->request.req_type = UIO_REQUEST_WRITE; - rt_usbd_io_request(ecm_eth_dev->func->device, ecm_eth_dev->eps.ep_in, &ecm_eth_dev->eps.ep_in->request); - } - } - - return result; -} -/** - * This function will handle RNDIS interrupt in endpoint request. - * - * @param device the usb device object. - * @param size request size. - * - * @return RT_EOK. - */ -static rt_err_t _ep_cmd_handler(ufunction_t func, rt_size_t size) -{ - return RT_EOK; -} - -/** - * This function will run cdc class, it will be called on handle set configuration request. - * - * @param device the usb device object. - * - * @return RT_EOK on successful. - */ -static rt_err_t _function_enable(ufunction_t func) -{ - cdc_eps_t eps; - rt_ecm_eth_t ecm_device = (rt_ecm_eth_t)func->user_data; - - LOG_D("plugged in"); - - eps = (cdc_eps_t)&ecm_device->eps; - eps->ep_out->buffer = ecm_device->rx_pool; - - /* reset eth rx tx */ - ecm_device->rx_size = 0; - ecm_device->rx_offset = 0; - - eps->ep_out->request.buffer = (void *)eps->ep_out->buffer; - eps->ep_out->request.size = EP_MAXPACKET(eps->ep_out); - eps->ep_out->request.req_type = UIO_REQUEST_READ_BEST; - rt_usbd_io_request(func->device, eps->ep_out, &eps->ep_out->request); - return RT_EOK; -} - -/** - * This function will stop cdc class, it will be called on handle set configuration request. - * - * @param device the usb device object. - * - * @return RT_EOK on successful. - */ -static rt_err_t _function_disable(ufunction_t func) -{ - LOG_D("plugged out"); - - eth_device_linkchange(&((rt_ecm_eth_t)func->user_data)->parent, RT_FALSE); - - /* reset eth rx tx */ - ((rt_ecm_eth_t)func->user_data)->rx_size = 0; - ((rt_ecm_eth_t)func->user_data)->rx_offset = 0; - - return RT_EOK; -} - - -static struct ufunction_ops ops = -{ - _function_enable, - _function_disable, - RT_NULL, -}; - -/** - * This function will configure cdc descriptor. - * - * @param comm the communication interface number. - * @param data the data interface number. - * - * @return RT_EOK on successful. - */ -static rt_err_t _cdc_descriptor_config(ucdc_comm_desc_t comm, rt_uint8_t cintf_nr, ucdc_data_desc_t data, rt_uint8_t dintf_nr, rt_uint8_t device_is_hs) -{ - comm->call_mgmt_desc.data_interface = dintf_nr; - comm->union_desc.master_interface = cintf_nr; - comm->union_desc.slave_interface0 = dintf_nr; -#ifdef RT_USB_DEVICE_COMPOSITE - comm->iad_desc.bFirstInterface = cintf_nr; -#endif - data->ep_out_desc.wMaxPacketSize = device_is_hs ? 512 : 64; - data->ep_in_desc.wMaxPacketSize = device_is_hs ? 512 : 64; - return RT_EOK; -} - - - -/** - * This function will create a cdc ecm class instance. - * - * @param device the usb device object. - * - * @return RT_EOK on successful. - */ -ufunction_t rt_usbd_function_ecm_create(udevice_t device) -{ - ufunction_t cdc; - rt_ecm_eth_t _ecm_eth; - cdc_eps_t eps; - uintf_t intf_comm, intf_data; - ualtsetting_t comm_setting, data_setting; - ucdc_data_desc_t data_desc; - ucdc_eth_desc_t comm_desc; - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - - /* set usb device string description */ -#ifdef RT_USB_DEVICE_COMPOSITE - rt_usbd_device_set_interface_string(device, ECM_INTF_STR_INDEX, _ustring[2]); -#else - rt_usbd_device_set_string(device, _ustring); -#endif - /* create a cdc class */ - cdc = rt_usbd_function_new(device, &_dev_desc, &ops); - rt_usbd_device_set_qualifier(device, &dev_qualifier); - _ecm_eth= rt_malloc(sizeof(struct rt_ecm_eth)); - RT_ASSERT(_ecm_eth != RT_NULL); - rt_memset(_ecm_eth, 0, sizeof(struct rt_ecm_eth)); - cdc->user_data = _ecm_eth; - - _ecm_eth->func = cdc; - /* create a cdc class endpoints collection */ - eps = &_ecm_eth->eps; - /* create a cdc communication interface and a cdc data interface */ - intf_comm = rt_usbd_interface_new(device, _interface_handler); - intf_data = rt_usbd_interface_new(device, _interface_handler); - - /* create a communication alternate setting and a data alternate setting */ - comm_setting = rt_usbd_altsetting_new(sizeof(struct ucdc_eth_descriptor)); - data_setting = rt_usbd_altsetting_new(sizeof(struct ucdc_data_descriptor)); - - /* config desc in alternate setting */ - rt_usbd_altsetting_config_descriptor(comm_setting, &_comm_desc, - (rt_off_t)&((ucdc_eth_desc_t)0)->intf_desc); - rt_usbd_altsetting_config_descriptor(data_setting, &_data_desc, 0); - /* configure the cdc interface descriptor */ - _cdc_descriptor_config(comm_setting->desc, intf_comm->intf_num, data_setting->desc, intf_data->intf_num, device->dcd->device_is_hs); - - /* create a command endpoint */ - comm_desc = (ucdc_eth_desc_t)comm_setting->desc; - eps->ep_cmd = rt_usbd_endpoint_new(&comm_desc->ep_desc, _ep_cmd_handler); - /* add the command endpoint to the cdc communication interface */ - rt_usbd_altsetting_add_endpoint(comm_setting, eps->ep_cmd); - - /* add the communication alternate setting to the communication interface, - then set default setting of the interface */ - rt_usbd_interface_add_altsetting(intf_comm, comm_setting); - rt_usbd_set_altsetting(intf_comm, 0); - /* add the communication interface to the cdc class */ - rt_usbd_function_add_interface(cdc, intf_comm); - - /* create a bulk in and a bulk out endpoint */ - data_desc = (ucdc_data_desc_t)data_setting->desc; - eps->ep_out = rt_usbd_endpoint_new(&data_desc->ep_out_desc, _ep_out_handler); - eps->ep_in = rt_usbd_endpoint_new(&data_desc->ep_in_desc, _ep_in_handler); - - /* add the bulk out and bulk in endpoints to the data alternate setting */ - rt_usbd_altsetting_add_endpoint(data_setting, eps->ep_in); - rt_usbd_altsetting_add_endpoint(data_setting, eps->ep_out); - - /* add the data alternate setting to the data interface - then set default setting of the interface */ - rt_usbd_interface_add_altsetting(intf_data, data_setting); - rt_usbd_set_altsetting(intf_data, 0); - - /* add the cdc data interface to cdc class */ - rt_usbd_function_add_interface(cdc, intf_data); - - rt_sem_init(&_ecm_eth->tx_buffer_free, "ue_tx", 1, RT_IPC_FLAG_FIFO); - /* OUI 00-00-00, only for test. */ - _ecm_eth->dev_addr[0] = 0x34; - _ecm_eth->dev_addr[1] = 0x97; - _ecm_eth->dev_addr[2] = 0xF6; - /* generate random MAC. */ - _ecm_eth->dev_addr[3] = 0x94;//*(const rt_uint8_t *)(0x1fff7a10); - _ecm_eth->dev_addr[4] = 0xEC;//*(const rt_uint8_t *)(0x1fff7a14); - _ecm_eth->dev_addr[5] = 0xAC;//(const rt_uint8_t *)(0x1fff7a18); - /* OUI 00-00-00, only for test. */ - _ecm_eth->host_addr[0] = 0x34; - _ecm_eth->host_addr[1] = 0x97; - _ecm_eth->host_addr[2] = 0xF6; - /* generate random MAC. */ - _ecm_eth->host_addr[3] = 0x94;//*(const rt_uint8_t *)(0x1fff7a10); - _ecm_eth->host_addr[4] = 0xEC;//*(const rt_uint8_t *)(0x1fff7a14); - _ecm_eth->host_addr[5] = 0xAB;//*(const rt_uint8_t *)(0x1fff7a18); - -#ifdef RT_USING_DEVICE_OPS - _ecm_eth->parent.parent.ops = &ecm_device_ops; -#else - _ecm_eth->parent.parent.init = rt_ecm_eth_init; - _ecm_eth->parent.parent.open = rt_ecm_eth_open; - _ecm_eth->parent.parent.close = rt_ecm_eth_close; - _ecm_eth->parent.parent.read = rt_ecm_eth_read; - _ecm_eth->parent.parent.write = rt_ecm_eth_write; - _ecm_eth->parent.parent.control = rt_ecm_eth_control; -#endif - _ecm_eth->parent.parent.user_data = device; - - _ecm_eth->parent.eth_rx = rt_ecm_eth_rx; - _ecm_eth->parent.eth_tx = rt_ecm_eth_tx; - /* register eth device */ - eth_device_init(&_ecm_eth->parent, "u0"); - - /* send link up. */ - eth_device_linkchange(&_ecm_eth->parent, RT_FALSE); - - return cdc; -} - -struct udclass ecm_class = -{ - .rt_usbd_function_create = rt_usbd_function_ecm_create -}; - -int rt_usbd_ecm_class_register(void) -{ - rt_usbd_class_register(&ecm_class); - return 0; -} -INIT_PREV_EXPORT(rt_usbd_ecm_class_register); - -#endif /* RT_USB_DEVICE_ECM */ diff --git a/components/drivers/usb/usbdevice/class/hid.c b/components/drivers/usb/usbdevice/class/hid.c deleted file mode 100644 index b0c7e63e00..0000000000 --- a/components/drivers/usb/usbdevice/class/hid.c +++ /dev/null @@ -1,756 +0,0 @@ -/* - * File : hid.c - * COPYRIGHT (C) 2006 - 2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2017-03-13 Urey the first version - * 2017-11-16 ZYH Update to common hid - */ - -#include <rthw.h> -#include <rtdevice.h> -#include "drivers/usb_common.h" -#include "drivers/usb_device.h" -#include "hid.h" - -#ifdef RT_USB_DEVICE_HID - -#define DBG_TAG "usbdevice.hid" -#define DBG_LVL DBG_INFO -#include <rtdbg.h> - -#define HID_INTF_STR_INDEX 7 -struct hid_s -{ - struct rt_device parent; - struct ufunction *func; - uep_t ep_in; - uep_t ep_out; - int status; - rt_uint8_t protocol; - rt_uint8_t report_buf[MAX_REPORT_SIZE]; - struct rt_messagequeue hid_mq; -}; - -/* CustomHID_ConfigDescriptor */ -rt_align(4) -const rt_uint8_t _report_desc[]= -{ -#ifdef RT_USB_DEVICE_HID_KEYBOARD - USAGE_PAGE(1), 0x01, - USAGE(1), 0x06, - COLLECTION(1), 0x01, - REPORT_ID(1), HID_REPORT_ID_KEYBOARD1, - - USAGE_PAGE(1), 0x07, - USAGE_MINIMUM(1), 0xE0, - USAGE_MAXIMUM(1), 0xE7, - LOGICAL_MINIMUM(1), 0x00, - LOGICAL_MAXIMUM(1), 0x01, - REPORT_SIZE(1), 0x01, - REPORT_COUNT(1), 0x08, - INPUT(1), 0x02, - REPORT_COUNT(1), 0x01, - REPORT_SIZE(1), 0x08, - INPUT(1), 0x01, - - - REPORT_COUNT(1), 0x05, - REPORT_SIZE(1), 0x01, - USAGE_PAGE(1), 0x08, - USAGE_MINIMUM(1), 0x01, - USAGE_MAXIMUM(1), 0x05, - OUTPUT(1), 0x02, - REPORT_COUNT(1), 0x01, - REPORT_SIZE(1), 0x03, - OUTPUT(1), 0x01, - - - REPORT_COUNT(1), 0x06, - REPORT_SIZE(1), 0x08, - LOGICAL_MINIMUM(1), 0x00, - LOGICAL_MAXIMUM(1), 0x65, - USAGE_PAGE(1), 0x07, - USAGE_MINIMUM(1), 0x00, - USAGE_MAXIMUM(1), 0x65, - INPUT(1), 0x00, - END_COLLECTION(0), -#if RT_USB_DEVICE_HID_KEYBOARD_NUMBER>1 - /****keyboard2*****/ - USAGE_PAGE(1), 0x01, - USAGE(1), 0x06, - COLLECTION(1), 0x01, - REPORT_ID(1), HID_REPORT_ID_KEYBOARD2, - - USAGE_PAGE(1), 0x07, - USAGE_MINIMUM(1), 0xE0, - USAGE_MAXIMUM(1), 0xE7, - LOGICAL_MINIMUM(1), 0x00, - LOGICAL_MAXIMUM(1), 0x01, - REPORT_SIZE(1), 0x01, - REPORT_COUNT(1), 0x08, - INPUT(1), 0x02, - REPORT_COUNT(1), 0x01, - REPORT_SIZE(1), 0x08, - INPUT(1), 0x01, - - REPORT_COUNT(1), 0x06, - REPORT_SIZE(1), 0x08, - LOGICAL_MINIMUM(1), 0x00, - LOGICAL_MAXIMUM(1), 0x65, - USAGE_PAGE(1), 0x07, - USAGE_MINIMUM(1), 0x00, - USAGE_MAXIMUM(1), 0x65, - INPUT(1), 0x00, - END_COLLECTION(0), -#if RT_USB_DEVICE_HID_KEYBOARD_NUMBER>2 - USAGE_PAGE(1), 0x01, - USAGE(1), 0x06, - COLLECTION(1), 0x01, - REPORT_ID(1), HID_REPORT_ID_KEYBOARD3, - - USAGE_PAGE(1), 0x07, - USAGE_MINIMUM(1), 0xE0, - USAGE_MAXIMUM(1), 0xE7, - LOGICAL_MINIMUM(1), 0x00, - LOGICAL_MAXIMUM(1), 0x01, - REPORT_SIZE(1), 0x01, - REPORT_COUNT(1), 0x08, - INPUT(1), 0x02, - REPORT_COUNT(1), 0x01, - REPORT_SIZE(1), 0x08, - INPUT(1), 0x01, - - REPORT_COUNT(1), 0x06, - REPORT_SIZE(1), 0x08, - LOGICAL_MINIMUM(1), 0x00, - LOGICAL_MAXIMUM(1), 0x65, - USAGE_PAGE(1), 0x07, - USAGE_MINIMUM(1), 0x00, - USAGE_MAXIMUM(1), 0x65, - INPUT(1), 0x00, - END_COLLECTION(0), -#if RT_USB_DEVICE_HID_KEYBOARD_NUMBER>3 - USAGE_PAGE(1), 0x01, - USAGE(1), 0x06, - COLLECTION(1), 0x01, - REPORT_ID(1), HID_REPORT_ID_KEYBOARD4, - - USAGE_PAGE(1), 0x07, - USAGE_MINIMUM(1), 0xE0, - USAGE_MAXIMUM(1), 0xE7, - LOGICAL_MINIMUM(1), 0x00, - LOGICAL_MAXIMUM(1), 0x01, - REPORT_SIZE(1), 0x01, - REPORT_COUNT(1), 0x08, - INPUT(1), 0x02, - REPORT_COUNT(1), 0x01, - REPORT_SIZE(1), 0x08, - INPUT(1), 0x01, - - REPORT_COUNT(1), 0x06, - REPORT_SIZE(1), 0x08, - LOGICAL_MINIMUM(1), 0x00, - LOGICAL_MAXIMUM(1), 0x65, - USAGE_PAGE(1), 0x07, - USAGE_MINIMUM(1), 0x00, - USAGE_MAXIMUM(1), 0x65, - INPUT(1), 0x00, - END_COLLECTION(0), -#endif -#endif -#endif -#endif - // Media Control -#ifdef RT_USB_DEVICE_HID_MEDIA - USAGE_PAGE(1), 0x0C, - USAGE(1), 0x01, - COLLECTION(1), 0x01, - REPORT_ID(1), HID_REPORT_ID_MEDIA, - USAGE_PAGE(1), 0x0C, - LOGICAL_MINIMUM(1), 0x00, - LOGICAL_MAXIMUM(1), 0x01, - REPORT_SIZE(1), 0x01, - REPORT_COUNT(1), 0x07, - USAGE(1), 0xB5, // Next Track - USAGE(1), 0xB6, // Previous Track - USAGE(1), 0xB7, // Stop - USAGE(1), 0xCD, // Play / Pause - USAGE(1), 0xE2, // Mute - USAGE(1), 0xE9, // Volume Up - USAGE(1), 0xEA, // Volume Down - INPUT(1), 0x02, // Input (Data, Variable, Absolute) - REPORT_COUNT(1), 0x01, - INPUT(1), 0x01, - END_COLLECTION(0), -#endif - -#ifdef RT_USB_DEVICE_HID_GENERAL - USAGE_PAGE(1), 0x8c, - USAGE(1), 0x01, - COLLECTION(1), 0x01, - REPORT_ID(1), HID_REPORT_ID_GENERAL, - - REPORT_COUNT(1), RT_USB_DEVICE_HID_GENERAL_IN_REPORT_LENGTH, - USAGE(1), 0x03, - REPORT_SIZE(1), 0x08, - LOGICAL_MINIMUM(1), 0x00, - LOGICAL_MAXIMUM(1), 0xFF, - INPUT(1), 0x02, - - REPORT_COUNT(1), RT_USB_DEVICE_HID_GENERAL_OUT_REPORT_LENGTH, - USAGE(1), 0x04, - REPORT_SIZE(1), 0x08, - LOGICAL_MINIMUM(1), 0x00, - LOGICAL_MAXIMUM(1), 0xFF, - OUTPUT(1), 0x02, - END_COLLECTION(0), -#endif -#ifdef RT_USB_DEVICE_HID_MOUSE - USAGE_PAGE(1), 0x01, // Generic Desktop - USAGE(1), 0x02, // Mouse - COLLECTION(1), 0x01, // Application - USAGE(1), 0x01, // Pointer - COLLECTION(1), 0x00, // Physical - REPORT_ID(1), HID_REPORT_ID_MOUSE, - REPORT_COUNT(1), 0x03, - REPORT_SIZE(1), 0x01, - USAGE_PAGE(1), 0x09, // Buttons - USAGE_MINIMUM(1), 0x1, - USAGE_MAXIMUM(1), 0x3, - LOGICAL_MINIMUM(1), 0x00, - LOGICAL_MAXIMUM(1), 0x01, - INPUT(1), 0x02, - REPORT_COUNT(1), 0x01, - REPORT_SIZE(1), 0x05, - INPUT(1), 0x01, - REPORT_COUNT(1), 0x03, - REPORT_SIZE(1), 0x08, - USAGE_PAGE(1), 0x01, - USAGE(1), 0x30, // X - USAGE(1), 0x31, // Y - USAGE(1), 0x38, // scroll - LOGICAL_MINIMUM(1), 0x81, - LOGICAL_MAXIMUM(1), 0x7f, - INPUT(1), 0x06, - END_COLLECTION(0), - END_COLLECTION(0), -#endif -}; /* CustomHID_ReportDescriptor */ - -rt_align(4) -static struct udevice_descriptor _dev_desc = -{ - USB_DESC_LENGTH_DEVICE, //bLength; - USB_DESC_TYPE_DEVICE, //type; - USB_BCD_VERSION, //bcdUSB; - 0x0, //bDeviceClass; - 0x00, //bDeviceSubClass; - 0x00, //bDeviceProtocol; - 64, //bMaxPacketSize0; - _VENDOR_ID, //idVendor; - _PRODUCT_ID, //idProduct; - USB_BCD_DEVICE, //bcdDevice; - USB_STRING_MANU_INDEX, //iManufacturer; - USB_STRING_PRODUCT_INDEX, //iProduct; - USB_STRING_SERIAL_INDEX, //iSerialNumber; - USB_DYNAMIC, //bNumConfigurations; -}; - -//FS and HS needed -rt_align(4) -static struct usb_qualifier_descriptor dev_qualifier = -{ - sizeof(dev_qualifier), //bLength - USB_DESC_TYPE_DEVICEQUALIFIER, //bDescriptorType - 0x0200, //bcdUSB - 0x0, //bDeviceClass - 0x0, //bDeviceSubClass - 0x50, //bDeviceProtocol - 64, //bMaxPacketSize0 - 0x01, //bNumConfigurations - 0, -}; - - -/* hid interface descriptor */ -rt_align(4) -const static struct uhid_comm_descriptor _hid_comm_desc = -{ -#ifdef RT_USB_DEVICE_COMPOSITE - /* Interface Association Descriptor */ - { - USB_DESC_LENGTH_IAD, - USB_DESC_TYPE_IAD, - USB_DYNAMIC, - 0x01, - 0x03, /* bInterfaceClass: HID */ -#if defined(RT_USB_DEVICE_HID_KEYBOARD)||defined(RT_USB_DEVICE_HID_MOUSE) - USB_HID_SUBCLASS_BOOT, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ -#else - USB_HID_SUBCLASS_NOBOOT, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ -#endif -#if !defined(RT_USB_DEVICE_HID_KEYBOARD)||!defined(RT_USB_DEVICE_HID_MOUSE)||!defined(RT_USB_DEVICE_HID_MEDIA) - USB_HID_PROTOCOL_NONE, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ -#elif !defined(RT_USB_DEVICE_HID_MOUSE) - USB_HID_PROTOCOL_KEYBOARD, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ -#else - USB_HID_PROTOCOL_MOUSE, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ -#endif - 0x00, - }, -#endif - /* Interface Descriptor */ - { - USB_DESC_LENGTH_INTERFACE, - USB_DESC_TYPE_INTERFACE, - USB_DYNAMIC, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ -#if defined(RT_USB_DEVICE_HID_KEYBOARD)||defined(RT_USB_DEVICE_HID_MOUSE) - USB_HID_SUBCLASS_BOOT, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ -#else - USB_HID_SUBCLASS_NOBOOT, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ -#endif -#if !defined(RT_USB_DEVICE_HID_KEYBOARD)||!defined(RT_USB_DEVICE_HID_MOUSE)||!defined(RT_USB_DEVICE_HID_MEDIA) - USB_HID_PROTOCOL_NONE, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ -#elif !defined(RT_USB_DEVICE_HID_MOUSE) - USB_HID_PROTOCOL_KEYBOARD, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ -#else - USB_HID_PROTOCOL_MOUSE, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ -#endif -#ifdef RT_USB_DEVICE_COMPOSITE - HID_INTF_STR_INDEX, /* iInterface: Index of string descriptor */ -#else - 0, -#endif - }, - - /* HID Descriptor */ - { - HID_DESCRIPTOR_SIZE, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */ - 0x0110, /* bcdHID: HID Class Spec release number */ - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - { - { - 0x22, /* bDescriptorType */ - sizeof(_report_desc), /* wItemLength: Total length of Report descriptor */ - }, - }, - }, - - /* Endpoint Descriptor IN */ - { - USB_DESC_LENGTH_ENDPOINT, - USB_DESC_TYPE_ENDPOINT, - USB_DYNAMIC | USB_DIR_IN, - USB_EP_ATTR_INT, - 0x40, - 0x0A, - }, - - /* Endpoint Descriptor OUT */ - { - USB_DESC_LENGTH_ENDPOINT, - USB_DESC_TYPE_ENDPOINT, - USB_DYNAMIC | USB_DIR_OUT, - USB_EP_ATTR_INT, - 0x40, - 0x01, - }, -}; - -rt_align(4) -const static char* _ustring[] = -{ - "Language", - "RT-Thread Team.", - "RTT HID-Device", - "32021919830108", - "Configuration", - "Interface", -}; - -static void dump_data(rt_uint8_t *data, rt_size_t size) -{ - rt_size_t i; - for (i = 0; i < size; i++) - { - rt_kprintf("%02x ", *data++); - if ((i + 1) % 8 == 0) - { - rt_kprintf("\n"); - }else if ((i + 1) % 4 == 0){ - rt_kprintf(" "); - } - } -} -static void dump_report(struct hid_report * report) -{ - rt_kprintf("\nHID Recived:"); - rt_kprintf("\nReport ID %02x \n", report->report_id); - dump_data(report->report,report->size); -} - -static rt_err_t _ep_out_handler(ufunction_t func, rt_size_t size) -{ - struct hid_s *data; - struct hid_report report; - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->device != RT_NULL); - data = (struct hid_s *) func->user_data; - - if(size != 0) - { - rt_memcpy((void *)&report,(void*)data->ep_out->buffer,size); - report.size = size-1; - rt_mq_send(&data->hid_mq,(void *)&report,sizeof(report)); - } - - data->ep_out->request.buffer = data->ep_out->buffer; - data->ep_out->request.size = EP_MAXPACKET(data->ep_out); - data->ep_out->request.req_type = UIO_REQUEST_READ_BEST; - rt_usbd_io_request(func->device, data->ep_out, &data->ep_out->request); - return RT_EOK; -} - -static rt_err_t _ep_in_handler(ufunction_t func, rt_size_t size) -{ - struct hid_s *data; - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->device != RT_NULL); - - data = (struct hid_s *) func->user_data; - if(data->parent.tx_complete != RT_NULL) - { - data->parent.tx_complete(&data->parent,RT_NULL); - } - return RT_EOK; -} - -static rt_err_t _hid_set_report_callback(udevice_t device, rt_size_t size) -{ - LOG_D("_hid_set_report_callback"); - - if(size != 0) - { - } - - dcd_ep0_send_status(device->dcd); - - return RT_EOK; -} - -/** - * This function will handle hid interface bRequest. - * - * @param device the usb device object. - * @param setup the setup bRequest. - * - * @return RT_EOK on successful. - */ -static rt_err_t _interface_handler(ufunction_t func, ureq_t setup) -{ - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->device != RT_NULL); - RT_ASSERT(setup != RT_NULL); - - struct hid_s *data = (struct hid_s *) func->user_data; - - - switch (setup->bRequest) - { - case USB_REQ_GET_DESCRIPTOR: - if((setup->wValue >> 8) == USB_DESC_TYPE_REPORT) - { - rt_usbd_ep0_write(func->device, (void *)(&_report_desc[0]), sizeof(_report_desc)); - } - else if((setup->wValue >> 8) == USB_DESC_TYPE_HID) - { - - rt_usbd_ep0_write(func->device, (void *)(&_hid_comm_desc.hid_desc), sizeof(struct uhid_descriptor)); - } - break; - case USB_HID_REQ_GET_REPORT: - if(setup->wLength == 0) - { - rt_usbd_ep0_set_stall(func->device); - break; - } - if((setup->wLength == 0) || (setup->wLength > MAX_REPORT_SIZE)) - setup->wLength = MAX_REPORT_SIZE; - rt_usbd_ep0_write(func->device, data->report_buf,setup->wLength); - break; - case USB_HID_REQ_GET_IDLE: - - dcd_ep0_send_status(func->device->dcd); - break; - case USB_HID_REQ_GET_PROTOCOL: - rt_usbd_ep0_write(func->device, &data->protocol,1); - break; - case USB_HID_REQ_SET_REPORT: - - if((setup->wLength == 0) || (setup->wLength > MAX_REPORT_SIZE)) - rt_usbd_ep0_set_stall(func->device); - - rt_usbd_ep0_read(func->device, data->report_buf, setup->wLength, _hid_set_report_callback); - break; - case USB_HID_REQ_SET_IDLE: - dcd_ep0_send_status(func->device->dcd); - break; - case USB_HID_REQ_SET_PROTOCOL: - data->protocol = setup->wValue; - - dcd_ep0_send_status(func->device->dcd); - break; - } - - return RT_EOK; -} - - -/** - * This function will run cdc function, it will be called on handle set configuration bRequest. - * - * @param func the usb function object. - * - * @return RT_EOK on successful. - */ -static rt_err_t _function_enable(ufunction_t func) -{ - struct hid_s *data; - - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->device != RT_NULL); - data = (struct hid_s *) func->user_data; - - LOG_D("hid function enable"); -// -// _vcom_reset_state(func); -// - if(data->ep_out->buffer == RT_NULL) - { - data->ep_out->buffer = rt_malloc(HID_RX_BUFSIZE); - } - data->ep_out->request.buffer = data->ep_out->buffer; - data->ep_out->request.size = EP_MAXPACKET(data->ep_out); - data->ep_out->request.req_type = UIO_REQUEST_READ_BEST; - - rt_usbd_io_request(func->device, data->ep_out, &data->ep_out->request); - - return RT_EOK; -} - -/** - * This function will stop cdc function, it will be called on handle set configuration bRequest. - * - * @param func the usb function object. - * - * @return RT_EOK on successful. - */ -static rt_err_t _function_disable(ufunction_t func) -{ - struct hid_s *data; - - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->device != RT_NULL); - data = (struct hid_s *) func->user_data; - - LOG_D("hid function disable"); - - if(data->ep_out->buffer != RT_NULL) - { - rt_free(data->ep_out->buffer); - data->ep_out->buffer = RT_NULL; - } - - return RT_EOK; -} - -static struct ufunction_ops ops = -{ - _function_enable, - _function_disable, - RT_NULL, -}; - - - - -/** - * This function will configure hid descriptor. - * - * @param comm the communication interface number. - * @param data the data interface number. - * - * @return RT_EOK on successful. - */ -static rt_err_t _hid_descriptor_config(uhid_comm_desc_t hid, rt_uint8_t cintf_nr) -{ -#ifdef RT_USB_DEVICE_COMPOSITE - hid->iad_desc.bFirstInterface = cintf_nr; -#endif - - return RT_EOK; -} -static rt_ssize_t _hid_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) -{ - struct hid_s *hiddev = (struct hid_s *)dev; - struct hid_report report; - if (hiddev->func->device->state == USB_STATE_CONFIGURED) - { - report.report_id = pos; - rt_memcpy((void *)report.report,(void *)buffer,size); - report.size = size; - hiddev->ep_in->request.buffer = (void *)&report; - hiddev->ep_in->request.size = (size+1) > 64 ? 64 : size+1; - hiddev->ep_in->request.req_type = UIO_REQUEST_WRITE; - rt_usbd_io_request(hiddev->func->device, hiddev->ep_in, &hiddev->ep_in->request); - return size; - } - - return 0; -} -rt_weak void HID_Report_Received(hid_report_t report) -{ - dump_report(report); -} -rt_align(RT_ALIGN_SIZE) -static rt_uint8_t hid_thread_stack[512]; -static struct rt_thread hid_thread; - -static void hid_thread_entry(void* parameter) -{ - struct hid_report report; - struct hid_s *hiddev; - hiddev = (struct hid_s *)parameter; - while(1) - { - if(rt_mq_recv(&hiddev->hid_mq, &report, sizeof(report),RT_WAITING_FOREVER) < 0) - continue; - HID_Report_Received(&report); - } -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops hid_device_ops = -{ - RT_NULL, - RT_NULL, - RT_NULL, - RT_NULL, - _hid_write, - RT_NULL, -}; -#endif - -static rt_uint8_t hid_mq_pool[(sizeof(struct hid_report)+sizeof(void*))*8]; -static void rt_usb_hid_init(struct ufunction *func) -{ - struct hid_s *hiddev; - hiddev = (struct hid_s *)func->user_data; - rt_memset(&hiddev->parent, 0, sizeof(hiddev->parent)); - -#ifdef RT_USING_DEVICE_OPS - hiddev->parent.ops = &hid_device_ops; -#else - hiddev->parent.write = _hid_write; -#endif - hiddev->func = func; - - rt_device_register(&hiddev->parent, "hidd", RT_DEVICE_FLAG_RDWR); - rt_mq_init(&hiddev->hid_mq, "hiddmq", hid_mq_pool, sizeof(struct hid_report), - sizeof(hid_mq_pool), RT_IPC_FLAG_FIFO); - - rt_thread_init(&hid_thread, "hidd", hid_thread_entry, hiddev, - hid_thread_stack, sizeof(hid_thread_stack), RT_USBD_THREAD_PRIO, 20); - rt_thread_startup(&hid_thread); -} - - -/** - * This function will create a hid function instance. - * - * @param device the usb device object. - * - * @return RT_EOK on successful. - */ -ufunction_t rt_usbd_function_hid_create(udevice_t device) -{ - ufunction_t func; - struct hid_s *data; - - uintf_t hid_intf; - ualtsetting_t hid_setting; - uhid_comm_desc_t hid_desc; - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - - /* set usb device string description */ -#ifdef RT_USB_DEVICE_COMPOSITE - rt_usbd_device_set_interface_string(device, HID_INTF_STR_INDEX, _ustring[2]); -#else - rt_usbd_device_set_string(device, _ustring); -#endif - /* create a cdc function */ - func = rt_usbd_function_new(device, &_dev_desc, &ops); - - /* For high speed mode supporting */ - rt_usbd_device_set_qualifier(device, &dev_qualifier); - - /* allocate memory for cdc vcom data */ - data = (struct hid_s*)rt_malloc(sizeof(struct hid_s)); - rt_memset(data, 0, sizeof(struct hid_s)); - func->user_data = (void*)data; - - /* create an interface object */ - hid_intf = rt_usbd_interface_new(device, _interface_handler); - - /* create an alternate setting object */ - hid_setting = rt_usbd_altsetting_new(sizeof(struct uhid_comm_descriptor)); - - /* config desc in alternate setting */ - rt_usbd_altsetting_config_descriptor(hid_setting, &_hid_comm_desc, (rt_off_t)&((uhid_comm_desc_t)0)->intf_desc); - - /* configure the hid interface descriptor */ - _hid_descriptor_config(hid_setting->desc, hid_intf->intf_num); - - /* create endpoint */ - hid_desc = (uhid_comm_desc_t)hid_setting->desc; - data->ep_out = rt_usbd_endpoint_new(&hid_desc->ep_out_desc, _ep_out_handler); - data->ep_in = rt_usbd_endpoint_new(&hid_desc->ep_in_desc, _ep_in_handler); - - /* add the int out and int in endpoint to the alternate setting */ - rt_usbd_altsetting_add_endpoint(hid_setting, data->ep_out); - rt_usbd_altsetting_add_endpoint(hid_setting, data->ep_in); - - /* add the alternate setting to the interface, then set default setting */ - rt_usbd_interface_add_altsetting(hid_intf, hid_setting); - rt_usbd_set_altsetting(hid_intf, 0); - - /* add the interface to the mass storage function */ - rt_usbd_function_add_interface(func, hid_intf); - - /* initilize hid */ - rt_usb_hid_init(func); - return func; -} -struct udclass hid_class = -{ - .rt_usbd_function_create = rt_usbd_function_hid_create -}; - -int rt_usbd_hid_class_register(void) -{ - rt_usbd_class_register(&hid_class); - return 0; -} -INIT_PREV_EXPORT(rt_usbd_hid_class_register); -#endif /* RT_USB_DEVICE_HID */ diff --git a/components/drivers/usb/usbdevice/class/hid.h b/components/drivers/usb/usbdevice/class/hid.h deleted file mode 100644 index 99da810ce8..0000000000 --- a/components/drivers/usb/usbdevice/class/hid.h +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2017-03-13 Urey the first version - * 2017-11-16 ZYH Update to common hid - */ -#ifndef _USBDEVICE_CLASS_HID_H_ -#define _USBDEVICE_CLASS_HID_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#define HID_DESCRIPTOR_TYPE 0x21 -#define HID_DESCRIPTOR_SIZE 0x09 -#define HID_OFF_HID_DESC 0x12 - -#define USB_HID_SUBCLASS_BOOT 0x01 -#define USB_HID_SUBCLASS_NOBOOT 0x00 - -#define USB_HID_PROTOCOL_NONE 0x00 -#define USB_HID_PROTOCOL_KEYBOARD 0x01 -#define USB_HID_PROTOCOL_MOUSE 0x02 - - -#define USB_HID_REQ_GET_REPORT 0x01 -#define USB_HID_REQ_GET_IDLE 0x02 -#define USB_HID_REQ_GET_PROTOCOL 0x03 -#define USB_HID_REQ_SET_REPORT 0x09 -#define USB_HID_REQ_SET_IDLE 0x0a -#define USB_HID_REQ_SET_PROTOCOL 0x0b - -#define MAX_REPORT_SIZE 64 -#define HID_RX_BUFSIZE 64 - -/* HID Report Types */ -#define HID_REPORT_INPUT 0x01 -#define HID_REPORT_OUTPUT 0x02 -#define HID_REPORT_FEATURE 0x03 - -/* Usage Pages */ -#define USAGEPAGE_UNDEFINED 0x00 -#define USAGEPAGE_GENERIC 0x01 -#define USAGEPAGE_SIMULATION 0x02 -#define USAGEPAGE_VR 0x03 -#define USAGEPAGE_SPORT 0x04 -#define USAGEPAGE_GAME 0x05 -#define USAGEPAGE_DEV_CONTROLS 0x06 -#define USAGEPAGE_KEYBOARD 0x07 -#define USAGEPAGE_LED 0x08 -#define USAGEPAGE_BUTTON 0x09 -#define USAGEPAGE_ORDINAL 0x0A -#define USAGEPAGE_TELEPHONY 0x0B -#define USAGEPAGE_CONSUMER 0x0C -#define USAGEPAGE_DIGITIZER 0x0D -#define USAGEPAGE_PIDPAGE 0x0F -#define USAGEPAGE_UNICODE 0x10 -#define USAGEPAGE_ALPHANUMERIC 0x14 -#define USAGEPAGE_BARCODESCANNER 0x8C - -/* Generic Desktop Page (0x01) */ -#define USAGE_GENERIC_POINTER 0x01 -#define USAGE_GENERIC_MOUSE 0x02 -#define USAGE_GENERIC_JOYSTICK 0x04 -#define USAGE_GENERIC_GAMEPAD 0x05 -#define USAGE_GENERIC_KEYBOARD 0x06 -#define USAGE_GENERIC_KEYPAD 0x07 -#define USAGE_GENERIC_X 0x30 -#define USAGE_GENERIC_Y 0x31 -#define USAGE_GENERIC_Z 0x32 -#define USAGE_GENERIC_RX 0x33 -#define USAGE_GENERIC_RY 0x34 -#define USAGE_GENERIC_RZ 0x35 -#define USAGE_GENERIC_SLIDER 0x36 -#define USAGE_GENERIC_DIAL 0x37 -#define USAGE_GENERIC_WHEEL 0x38 -#define USAGE_GENERIC_HATSWITCH 0x39 -#define USAGE_GENERIC_COUNTED_BUFFER 0x3A -#define USAGE_GENERIC_BYTE_COUNT 0x3B -#define USAGE_GENERIC_MOTION_WAKEUP 0x3C -#define USAGE_GENERIC_VX 0x40 -#define USAGE_GENERIC_VY 0x41 -#define USAGE_GENERIC_VZ 0x42 -#define USAGE_GENERIC_VBRX 0x43 -#define USAGE_GENERIC_VBRY 0x44 -#define USAGE_GENERIC_VBRZ 0x45 -#define USAGE_GENERIC_VNO 0x46 -#define USAGE_GENERIC_SYSTEM_CTL 0x80 -#define USAGE_GENERIC_SYSCTL_POWER 0x81 -#define USAGE_GENERIC_SYSCTL_SLEEP 0x82 -#define USAGE_GENERIC_SYSCTL_WAKE 0x83 -#define USAGE_GENERIC_SYSCTL_CONTEXT_MENU 0x84 -#define USAGE_GENERIC_SYSCTL_MAIN_MENU 0x85 -#define USAGE_GENERIC_SYSCTL_APP_MENU 0x86 -#define USAGE_GENERIC_SYSCTL_HELP_MENU 0x87 -#define USAGE_GENERIC_SYSCTL_MENU_EXIT 0x88 -#define USAGE_GENERIC_SYSCTL_MENU_SELECT 0x89 -#define USAGE_GENERIC_SYSCTL_MENU_RIGHT 0x8A -#define USAGE_GENERIC_SYSCTL_MENU_LEFT 0x8B -#define USAGE_GENERIC_SYSCTL_MENU_UP 0x8C -#define USAGE_GENERIC_SYSCTL_MENU_DOWN 0x8D - -/* Simulation Controls Page(0x02) */ -#define USAGE_SIMCTRL_THROTTLE 0xBB - -/* HID Report Items */ - -/* Main Items */ -#define HID_Input(x) 0x81,x -#define HID_Output(x) 0x91,x -#define HID_Feature(x) 0xB1,x -#define HID_Collection(x) 0xA1,x -#define HID_EndCollection() 0xC0 - -/* Local Items */ -#define HID_Usage(x) 0x09,x -#define HID_UsageMin(x) 0x19,x -#define HID_UsageMax(x) 0x29,x - -/* Global Items */ -#define HID_UsagePage(x) 0x05,x -#define HID_UsagePageVendor(x) 0x06,x,0xFF -#define HID_LogicalMin(x) 0x15,x -#define HID_LogicalMinS(x) 0x16,(x&0xFF),((x>>8)&0xFF) -#define HID_LogicalMinL(x) 0x17,(x&0xFF),((x>>8)&0xFF),((x>>16)&0xFF),((x>>24)&0xFF) -#define HID_LogicalMax(x) 0x25,x -#define HID_LogicalMaxS(x) 0x26,(x&0xFF),((x>>8)&0xFF) -#define HID_LogicalMaxL(x) 0x27,(x&0xFF),((x>>8)&0xFF),((x>>16)&0xFF),((x>>24)&0xFF) -#define HID_PhysicalMin(x) 0x35,x -#define HID_PhysicalMinS(x) 0x36,(x&0xFF),((x>>8)&0xFF) -#define HID_PhysicalMinL(x) 0x37,(x&0xFF),((x>>8)&0xFF),((x>>16)&0xFF),((x>>24)&0xFF) -#define HID_PhysicalMax(x) 0x45,x -#define HID_PhysicalMaxS(x) 0x46,(x&0xFF),((x>>8)&0xFF) -#define HID_PhysicalMaxL(x) 0x47,(x&0xFF),((x>>8)&0xFF),((x>>16)&0xFF),((x>>24)&0xFF) -#define HID_UnitExponent(x) 0x55,x -#define HID_Unit(x) 0x65,x -#define HID_UnitS(x) 0x66,(x&0xFF),((x>>8)&0xFF) -#define HID_UnitL(x) 0x67,(x&0xFF),((x>>8)&0xFF),((x>>16)&0xFF),((x>>24)&0xFF) -#define HID_ReportSize(x) 0x75,x -#define HID_ReportSizeS(x) 0x76,(x&0xFF),((x>>8)&0xFF)) -#define HID_ReportSizeL(x) 0x77,(x&0xFF),((x>>8)&0xFF),((x>>16)&0xFF),((x>>24)&0xFF) -#define HID_ReportID(x) 0x85,x -#define HID_ReportCount(x) 0x95,x -#define HID_ReportCountS(x) 0x96,(x&0xFF),((x>>8)&0xFF) -#define HID_ReportCountL(x) 0x97,(x&0xFF),((x>>8)&0xFF),((x>>16)&0xFF),((x>>24)&0xFF) -#define HID_Push() 0xA4 -#define HID_Pop() 0xB4 - -/* Input, Output, Feature Data */ -#define HID_DATA (0<<0) -#define HID_CONST (1<<0) -#define HID_ARRAY (0<<1) -#define HID_VAR (1<<1) -#define HID_ABS (0<<2) -#define HID_REL (1<<2) -#define HID_NOWRAP (0<<3) -#define HID_WRAP (1<<3) -#define HID_LINEAR (0<<4) -#define HID_NONLINEAR (1<<4) -#define HID_PREFERREDSTATE (0<<5) -#define HID_NOPREFERRED (1<<5) -#define HID_NONULLPOSITION (0<<6) -#define HID_NULLSTATE (1<<6) -#define HID_NONVOLATILE (0<<7) -#define HID_VOLATILE (1<<7) - -/* Collection Data */ -#define HID_PHYSICAL 0x00 -#define HID_APPLICATION 0x01 -#define HID_LOGICAL 0x02 -#define HID_REPORT 0x03 -#define HID_NAMEDARRAY 0x04 -#define HID_USAGESWITCH 0x05 -#define HID_USAGEMODIFIER 0x06 - -//HID_MBED_DEFINE -#define HID_VERSION_1_11 (0x0111) - -/* HID Class */ -#define HID_CLASS (3) -#define HID_SUBCLASS_NONE (0) -#define HID_SUBCLASS_BOOT (1) -#define HID_PROTOCOL_NONE (0) -#define HID_PROTOCOL_KEYBOARD (1) -#define HID_PROTOCOL_MOUSE (2) - -/* Descriptors */ -#define HID_DESCRIPTOR (33) -#define HID_DESCRIPTOR_LENGTH (0x09) -#define REPORT_DESCRIPTOR (34) - -/* Class requests */ -#define GET_REPORT (0x1) -#define GET_IDLE (0x2) -#define SET_REPORT (0x9) -#define SET_IDLE (0xa) - -/* HID Class Report Descriptor */ -/* Short items: size is 0, 1, 2 or 3 specifying 0, 1, 2 or 4 (four) bytes */ -/* of data as per HID Class standard */ - -/* Main items */ -#define INPUT(size) (0x80 | size) -#define OUTPUT(size) (0x90 | size) -#define FEATURE(size) (0xb0 | size) -#define COLLECTION(size) (0xa0 | size) -#define END_COLLECTION(size) (0xc0 | size) - -/* Global items */ -#define USAGE_PAGE(size) (0x04 | size) -#define LOGICAL_MINIMUM(size) (0x14 | size) -#define LOGICAL_MAXIMUM(size) (0x24 | size) -#define PHYSICAL_MINIMUM(size) (0x34 | size) -#define PHYSICAL_MAXIMUM(size) (0x44 | size) -#define UNIT_EXPONENT(size) (0x54 | size) -#define UNIT(size) (0x64 | size) -#define REPORT_SIZE(size) (0x74 | size) -#define REPORT_ID(size) (0x84 | size) -#define REPORT_COUNT(size) (0x94 | size) -#define PUSH(size) (0xa4 | size) -#define POP(size) (0xb4 | size) - -/* Local items */ -#define USAGE(size) (0x08 | size) -#define USAGE_MINIMUM(size) (0x18 | size) -#define USAGE_MAXIMUM(size) (0x28 | size) -#define DESIGNATOR_INDEX(size) (0x38 | size) -#define DESIGNATOR_MINIMUM(size) (0x48 | size) -#define DESIGNATOR_MAXIMUM(size) (0x58 | size) -#define STRING_INDEX(size) (0x78 | size) -#define STRING_MINIMUM(size) (0x88 | size) -#define STRING_MAXIMUM(size) (0x98 | size) -#define DELIMITER(size) (0xa8 | size) - -#define LSB(n) ((n)&0xff) -#define MSB(n) (((n)&0xff00)>>8) -struct uhid_comm_descriptor -{ -#ifdef RT_USB_DEVICE_COMPOSITE - struct uiad_descriptor iad_desc; -#endif - struct uinterface_descriptor intf_desc; - struct uhid_descriptor hid_desc; - struct uendpoint_descriptor ep_in_desc; - struct uendpoint_descriptor ep_out_desc; -}; -typedef struct uhid_comm_descriptor* uhid_comm_desc_t; - - -#ifdef __cplusplus -} -#endif - -#endif /* _USBDEVICE_CLASS_HID_H_ */ diff --git a/components/drivers/usb/usbdevice/class/mstorage.c b/components/drivers/usb/usbdevice/class/mstorage.c deleted file mode 100644 index a077988102..0000000000 --- a/components/drivers/usb/usbdevice/class/mstorage.c +++ /dev/null @@ -1,1167 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-10-01 Yi Qiu first version - * 2012-11-25 Heyuanjie87 reduce the memory consumption - * 2012-12-09 Heyuanjie87 change function and endpoint handler - * 2013-07-25 Yi Qiu update for USB CV test - */ - -#include <rtthread.h> -#include <rtdevice.h> - -#include "drivers/usb_device.h" -#include "mstorage.h" - -#ifdef RT_USING_DFS_MNTTABLE -#include "dfs_fs.h" -#endif -#ifdef RT_USB_DEVICE_MSTORAGE -#define MSTRORAGE_INTF_STR_INDEX 11 - -#define DBG_TAG "usbdevice.mstorage" -#define DBG_LVL DBG_INFO -#include <rtdbg.h> - -enum STAT -{ - STAT_CBW, - STAT_CMD, - STAT_CSW, - STAT_RECEIVE, - STAT_SEND, -}; - -typedef enum -{ - FIXED, - COUNT, - BLOCK_COUNT, -}CB_SIZE_TYPE; - -typedef enum -{ - DIR_IN, - DIR_OUT, - DIR_NONE, -}CB_DIR; - -typedef rt_ssize_t (*cbw_handler)(ufunction_t func, ustorage_cbw_t cbw); - -struct scsi_cmd -{ - rt_uint16_t cmd; - cbw_handler handler; - rt_size_t cmd_len; - CB_SIZE_TYPE type; - rt_size_t data_size; - CB_DIR dir; -}; - -struct mstorage -{ - struct ustorage_csw csw_response; - uep_t ep_in; - uep_t ep_out; - int status; - rt_uint32_t cb_data_size; - rt_device_t disk; - rt_uint32_t block; - rt_int32_t count; - rt_int32_t size; - struct scsi_cmd* processing; - struct rt_device_blk_geometry geometry; -}; - -rt_align(4) -static struct udevice_descriptor dev_desc = -{ - USB_DESC_LENGTH_DEVICE, //bLength; - USB_DESC_TYPE_DEVICE, //type; - USB_BCD_VERSION, //bcdUSB; - USB_CLASS_MASS_STORAGE, //bDeviceClass; - 0x06, //bDeviceSubClass; - 0x50, //bDeviceProtocol; - 0x40, //bMaxPacketSize0; - _VENDOR_ID, //idVendor; - _PRODUCT_ID, //idProduct; - USB_BCD_DEVICE, //bcdDevice; - USB_STRING_MANU_INDEX, //iManufacturer; - USB_STRING_PRODUCT_INDEX, //iProduct; - USB_STRING_SERIAL_INDEX, //iSerialNumber; - USB_DYNAMIC, //bNumConfigurations; -}; - -//FS and HS needed -rt_align(4) -static struct usb_qualifier_descriptor dev_qualifier = -{ - sizeof(dev_qualifier), //bLength - USB_DESC_TYPE_DEVICEQUALIFIER, //bDescriptorType - 0x0200, //bcdUSB - USB_CLASS_MASS_STORAGE, //bDeviceClass - 0x06, //bDeviceSubClass - 0x50, //bDeviceProtocol - 64, //bMaxPacketSize0 - 0x01, //bNumConfigurations - 0, -}; - - -rt_align(4) -const static struct umass_descriptor _mass_desc = -{ -#ifdef RT_USB_DEVICE_COMPOSITE - /* Interface Association Descriptor */ - { - USB_DESC_LENGTH_IAD, - USB_DESC_TYPE_IAD, - USB_DYNAMIC, - 0x01, - USB_CLASS_MASS_STORAGE, - 0x06, - 0x50, - 0x00, - }, -#endif - { - USB_DESC_LENGTH_INTERFACE, //bLength; - USB_DESC_TYPE_INTERFACE, //type; - USB_DYNAMIC, //bInterfaceNumber; - 0x00, //bAlternateSetting; - 0x02, //bNumEndpoints - USB_CLASS_MASS_STORAGE, //bInterfaceClass; - 0x06, //bInterfaceSubClass; - 0x50, //bInterfaceProtocol; -#ifdef RT_USB_DEVICE_COMPOSITE - MSTRORAGE_INTF_STR_INDEX, -#else - 0x00, //iInterface; -#endif - }, - - { - USB_DESC_LENGTH_ENDPOINT, //bLength; - USB_DESC_TYPE_ENDPOINT, //type; - USB_DYNAMIC | USB_DIR_OUT, //bEndpointAddress; - USB_EP_ATTR_BULK, //bmAttributes; - USB_DYNAMIC, //wMaxPacketSize; - 0x00, //bInterval; - }, - - { - USB_DESC_LENGTH_ENDPOINT, //bLength; - USB_DESC_TYPE_ENDPOINT, //type; - USB_DYNAMIC | USB_DIR_IN, //bEndpointAddress; - USB_EP_ATTR_BULK, //bmAttributes; - USB_DYNAMIC, //wMaxPacketSize; - 0x00, //bInterval; - }, -}; - -rt_align(4) -const static char* _ustring[] = -{ - "Language", - "RT-Thread Team.", - "RTT Mass Storage", - "320219198301", - "Configuration", - "Interface", -}; - -static rt_ssize_t _test_unit_ready(ufunction_t func, ustorage_cbw_t cbw); -static rt_ssize_t _request_sense(ufunction_t func, ustorage_cbw_t cbw); -static rt_ssize_t _inquiry_cmd(ufunction_t func, ustorage_cbw_t cbw); -static rt_ssize_t _allow_removal(ufunction_t func, ustorage_cbw_t cbw); -static rt_ssize_t _start_stop(ufunction_t func, ustorage_cbw_t cbw); -static rt_ssize_t _mode_sense_6(ufunction_t func, ustorage_cbw_t cbw); -static rt_ssize_t _read_capacities(ufunction_t func, ustorage_cbw_t cbw); -static rt_ssize_t _read_capacity(ufunction_t func, ustorage_cbw_t cbw); -static rt_ssize_t _read_10(ufunction_t func, ustorage_cbw_t cbw); -static rt_ssize_t _write_10(ufunction_t func, ustorage_cbw_t cbw); -static rt_ssize_t _verify_10(ufunction_t func, ustorage_cbw_t cbw); - -rt_align(4) -static struct scsi_cmd cmd_data[] = -{ - {SCSI_TEST_UNIT_READY, _test_unit_ready, 6, FIXED, 0, DIR_NONE}, - {SCSI_REQUEST_SENSE, _request_sense, 6, COUNT, 0, DIR_IN}, - {SCSI_INQUIRY_CMD, _inquiry_cmd, 6, COUNT, 0, DIR_IN}, - {SCSI_ALLOW_REMOVAL, _allow_removal, 6, FIXED, 0, DIR_NONE}, - {SCSI_MODE_SENSE_6, _mode_sense_6, 6, COUNT, 0, DIR_IN}, - {SCSI_START_STOP, _start_stop, 6, FIXED, 0, DIR_NONE}, - {SCSI_READ_CAPACITIES, _read_capacities, 10, COUNT, 0, DIR_NONE}, - {SCSI_READ_CAPACITY, _read_capacity, 10, FIXED, 8, DIR_IN}, - {SCSI_READ_10, _read_10, 10, BLOCK_COUNT, 0, DIR_IN}, - {SCSI_WRITE_10, _write_10, 10, BLOCK_COUNT, 0, DIR_OUT}, - {SCSI_VERIFY_10, _verify_10, 10, FIXED, 0, DIR_NONE}, -}; - -static void _send_status(ufunction_t func) -{ - struct mstorage *data; - - RT_ASSERT(func != RT_NULL); - - LOG_D("_send_status"); - - data = (struct mstorage*)func->user_data; - data->ep_in->request.buffer = (rt_uint8_t*)&data->csw_response; - data->ep_in->request.size = SIZEOF_CSW; - data->ep_in->request.req_type = UIO_REQUEST_WRITE; - rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); - data->status = STAT_CSW; -} - -static rt_ssize_t _test_unit_ready(ufunction_t func, ustorage_cbw_t cbw) -{ - struct mstorage *data; - - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->device != RT_NULL); - - LOG_D("_test_unit_ready"); - - data = (struct mstorage*)func->user_data; - data->csw_response.status = 0; - - return 0; -} - -static rt_ssize_t _allow_removal(ufunction_t func, ustorage_cbw_t cbw) -{ - struct mstorage *data; - - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->device != RT_NULL); - - LOG_D("_allow_removal"); - - data = (struct mstorage*)func->user_data; - data->csw_response.status = 0; - - return 0; -} - -/** - * This function will handle inquiry command request. - * - * @param func the usb function object. - * @param cbw the command block wrapper. - * - * @return RT_EOK on successful. - */ - -static rt_ssize_t _inquiry_cmd(ufunction_t func, ustorage_cbw_t cbw) -{ - struct mstorage *data; - rt_uint8_t *buf; - - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->device != RT_NULL); - RT_ASSERT(cbw != RT_NULL); - - LOG_D("_inquiry_cmd"); - - data = (struct mstorage*)func->user_data; - buf = data->ep_in->buffer; - - *(rt_uint32_t*)&buf[0] = 0x0 | (0x80 << 8); - *(rt_uint32_t*)&buf[4] = 31; - - rt_memset(&buf[8], 0x20, 28); - rt_memcpy(&buf[8], "RTT", 3); - rt_memcpy(&buf[16], "USB Disk", 8); - - data->cb_data_size = MIN(data->cb_data_size, SIZEOF_INQUIRY_CMD); - data->ep_in->request.buffer = buf; - data->ep_in->request.size = data->cb_data_size; - data->ep_in->request.req_type = UIO_REQUEST_WRITE; - rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); - data->status = STAT_CMD; - - return data->cb_data_size; -} - -/** - * This function will handle sense request. - * - * @param func the usb function object. - * @param cbw the command block wrapper. - * - * @return RT_EOK on successful. - */ -static rt_ssize_t _request_sense(ufunction_t func, ustorage_cbw_t cbw) -{ - struct mstorage *data; - struct request_sense_data *buf; - - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->device != RT_NULL); - RT_ASSERT(cbw != RT_NULL); - - LOG_D("_request_sense"); - - data = (struct mstorage*)func->user_data; - buf = (struct request_sense_data *)data->ep_in->buffer; - - buf->ErrorCode = 0x70; - buf->Valid = 0; - buf->SenseKey = 2; - buf->Information[0] = 0; - buf->Information[1] = 0; - buf->Information[2] = 0; - buf->Information[3] = 0; - buf->AdditionalSenseLength = 0x0a; - buf->AdditionalSenseCode = 0x3a; - buf->AdditionalSenseCodeQualifier = 0; - - data->cb_data_size = MIN(data->cb_data_size, SIZEOF_REQUEST_SENSE); - data->ep_in->request.buffer = (rt_uint8_t*)data->ep_in->buffer; - data->ep_in->request.size = data->cb_data_size; - data->ep_in->request.req_type = UIO_REQUEST_WRITE; - rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); - data->status = STAT_CMD; - - return data->cb_data_size; -} - -/** - * This function will handle mode_sense_6 request. - * - * @param func the usb function object. - * @param cbw the command block wrapper. - * - * @return RT_EOK on successful. - */ -static rt_ssize_t _mode_sense_6(ufunction_t func, ustorage_cbw_t cbw) -{ - struct mstorage *data; - rt_uint8_t *buf; - - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->device != RT_NULL); - RT_ASSERT(cbw != RT_NULL); - - LOG_D("_mode_sense_6"); - - data = (struct mstorage*)func->user_data; - buf = data->ep_in->buffer; - buf[0] = 3; - buf[1] = 0; - buf[2] = 0; - buf[3] = 0; - - data->cb_data_size = MIN(data->cb_data_size, SIZEOF_MODE_SENSE_6); - data->ep_in->request.buffer = buf; - data->ep_in->request.size = data->cb_data_size; - data->ep_in->request.req_type = UIO_REQUEST_WRITE; - rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); - data->status = STAT_CMD; - - return data->cb_data_size; -} - -/** - * This function will handle read_capacities request. - * - * @param func the usb function object. - * @param cbw the command block wrapper. - * - * @return RT_EOK on successful. - */ -static rt_ssize_t _read_capacities(ufunction_t func, ustorage_cbw_t cbw) -{ - struct mstorage *data; - rt_uint8_t *buf; - rt_uint32_t sector_count, sector_size; - - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->device != RT_NULL); - RT_ASSERT(cbw != RT_NULL); - - LOG_D("_read_capacities"); - - data = (struct mstorage*)func->user_data; - buf = data->ep_in->buffer; - sector_count = data->geometry.sector_count; - sector_size = data->geometry.bytes_per_sector; - - *(rt_uint32_t*)&buf[0] = 0x08000000; - buf[4] = sector_count >> 24; - buf[5] = 0xff & (sector_count >> 16); - buf[6] = 0xff & (sector_count >> 8); - buf[7] = 0xff & (sector_count); - buf[8] = 0x02; - buf[9] = 0xff & (sector_size >> 16); - buf[10] = 0xff & (sector_size >> 8); - buf[11] = 0xff & sector_size; - - data->cb_data_size = MIN(data->cb_data_size, SIZEOF_READ_CAPACITIES); - data->ep_in->request.buffer = buf; - data->ep_in->request.size = data->cb_data_size; - data->ep_in->request.req_type = UIO_REQUEST_WRITE; - rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); - data->status = STAT_CMD; - - return data->cb_data_size; -} - -/** - * This function will handle read_capacity request. - * - * @param func the usb function object. - * @param cbw the command block wapper. - * - * @return RT_EOK on successful. - */ -static rt_ssize_t _read_capacity(ufunction_t func, ustorage_cbw_t cbw) -{ - struct mstorage *data; - - rt_uint8_t *buf; - rt_uint32_t sector_count, sector_size; - - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->device != RT_NULL); - RT_ASSERT(cbw != RT_NULL); - - LOG_D("_read_capacity"); - - data = (struct mstorage*)func->user_data; - buf = data->ep_in->buffer; - sector_count = data->geometry.sector_count - 1; /* Last Logical Block Address */ - sector_size = data->geometry.bytes_per_sector; - - buf[0] = sector_count >> 24; - buf[1] = 0xff & (sector_count >> 16); - buf[2] = 0xff & (sector_count >> 8); - buf[3] = 0xff & (sector_count); - buf[4] = 0x0; - buf[5] = 0xff & (sector_size >> 16); - buf[6] = 0xff & (sector_size >> 8); - buf[7] = 0xff & sector_size; - - data->cb_data_size = MIN(data->cb_data_size, SIZEOF_READ_CAPACITY); - data->ep_in->request.buffer = buf; - data->ep_in->request.size = data->cb_data_size; - data->ep_in->request.req_type = UIO_REQUEST_WRITE; - rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); - data->status = STAT_CMD; - - return data->cb_data_size; -} - -/** - * This function will handle read_10 request. - * - * @param func the usb function object. - * @param cbw the command block wrapper. - * - * @return RT_EOK on successful. - */ -static rt_ssize_t _read_10(ufunction_t func, ustorage_cbw_t cbw) -{ - struct mstorage *data; - rt_size_t size; - - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->device != RT_NULL); - RT_ASSERT(cbw != RT_NULL); - - data = (struct mstorage*)func->user_data; - data->block = cbw->cb[2]<<24 | cbw->cb[3]<<16 | cbw->cb[4]<<8 | - cbw->cb[5]<<0; - data->count = cbw->cb[7]<<8 | cbw->cb[8]<<0; - - RT_ASSERT(data->count < data->geometry.sector_count); - - data->csw_response.data_reside = data->cb_data_size; - size = rt_device_read(data->disk, data->block, data->ep_in->buffer, 1); - if(size == 0) - { - rt_kprintf("read data error\n"); - } - - data->ep_in->request.buffer = data->ep_in->buffer; - data->ep_in->request.size = data->geometry.bytes_per_sector; - data->ep_in->request.req_type = UIO_REQUEST_WRITE; - rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); - data->status = STAT_SEND; - - return data->geometry.bytes_per_sector; -} - -/** - * This function will handle write_10 request. - * - * @param func the usb function object. - * @param cbw the command block wrapper. - * - * @return RT_EOK on successful. - */ -static rt_ssize_t _write_10(ufunction_t func, ustorage_cbw_t cbw) -{ - struct mstorage *data; - - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->device != RT_NULL); - RT_ASSERT(cbw != RT_NULL); - - data = (struct mstorage*)func->user_data; - - data->block = cbw->cb[2]<<24 | cbw->cb[3]<<16 | cbw->cb[4]<<8 | - cbw->cb[5]<<0; - data->count = cbw->cb[7]<<8 | cbw->cb[8]; - data->csw_response.data_reside = cbw->xfer_len; - data->size = data->count * data->geometry.bytes_per_sector; - - LOG_D("_write_10 count 0x%x block 0x%x 0x%x", - data->count, data->block, data->geometry.sector_count); - - data->csw_response.data_reside = data->cb_data_size; - - data->ep_out->request.buffer = data->ep_out->buffer; - data->ep_out->request.size = data->geometry.bytes_per_sector; - data->ep_out->request.req_type = UIO_REQUEST_READ_FULL; - rt_usbd_io_request(func->device, data->ep_out, &data->ep_out->request); - data->status = STAT_RECEIVE; - - return data->geometry.bytes_per_sector; -} - -/** - * This function will handle verify_10 request. - * - * @param func the usb function object. - * - * @return RT_EOK on successful. - */ -static rt_ssize_t _verify_10(ufunction_t func, ustorage_cbw_t cbw) -{ - struct mstorage *data; - - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->device != RT_NULL); - - LOG_D("_verify_10"); - - data = (struct mstorage*)func->user_data; - data->csw_response.status = 0; - - return 0; -} - -static rt_ssize_t _start_stop(ufunction_t func, - ustorage_cbw_t cbw) -{ - struct mstorage *data; - - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->device != RT_NULL); - - LOG_D("_start_stop"); - - data = (struct mstorage*)func->user_data; - data->csw_response.status = 0; - - return 0; -} - -static rt_err_t _ep_in_handler(ufunction_t func, rt_size_t size) -{ - struct mstorage *data; - - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->device != RT_NULL); - - LOG_D("_ep_in_handler"); - - data = (struct mstorage*)func->user_data; - - switch(data->status) - { - case STAT_CSW: - if(data->ep_in->request.size != SIZEOF_CSW) - { - rt_kprintf("Size of csw command error\n"); - rt_usbd_ep_set_stall(func->device, data->ep_in); - } - else - { - LOG_D("return to cbw status"); - data->ep_out->request.buffer = data->ep_out->buffer; - data->ep_out->request.size = SIZEOF_CBW; - data->ep_out->request.req_type = UIO_REQUEST_READ_FULL; - rt_usbd_io_request(func->device, data->ep_out, &data->ep_out->request); - data->status = STAT_CBW; - } - break; - case STAT_CMD: - if(data->csw_response.data_reside == 0xFF) - { - data->csw_response.data_reside = 0; - } - else - { - data->csw_response.data_reside -= data->ep_in->request.size; - if(data->csw_response.data_reside != 0) - { - LOG_D("data_reside %d, request %d", - data->csw_response.data_reside, data->ep_in->request.size); - if(data->processing->dir == DIR_OUT) - { - rt_usbd_ep_set_stall(func->device, data->ep_out); - } - else - { - //rt_kprintf("warning:in stall path but not stall\n"); - - /* FIXME: Disable the operation or the disk cannot work. */ - //rt_usbd_ep_set_stall(func->device, data->ep_in); - } - data->csw_response.data_reside = 0; - } - } - _send_status(func); - break; - case STAT_SEND: - data->csw_response.data_reside -= data->ep_in->request.size; - data->count--; - data->block++; - if(data->count > 0 && data->csw_response.data_reside > 0) - { - if(rt_device_read(data->disk, data->block, data->ep_in->buffer, 1) == 0) - { - rt_kprintf("disk read error\n"); - rt_usbd_ep_set_stall(func->device, data->ep_in); - return -RT_ERROR; - } - - data->ep_in->request.buffer = data->ep_in->buffer; - data->ep_in->request.size = data->geometry.bytes_per_sector; - data->ep_in->request.req_type = UIO_REQUEST_WRITE; - rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); - } - else - { - _send_status(func); - } - break; - } - - return RT_EOK; -} - -#ifdef MASS_CBW_DUMP -static void cbw_dump(struct ustorage_cbw* cbw) -{ - RT_ASSERT(cbw != RT_NULL); - - LOG_D("signature 0x%x", cbw->signature); - LOG_D("tag 0x%x", cbw->tag); - LOG_D("xfer_len 0x%x", cbw->xfer_len); - LOG_D("dflags 0x%x", cbw->dflags); - LOG_D("lun 0x%x", cbw->lun); - LOG_D("cb_len 0x%x", cbw->cb_len); - LOG_D("cb[0] 0x%x", cbw->cb[0]); -} -#endif - -static struct scsi_cmd* _find_cbw_command(rt_uint16_t cmd) -{ - int i; - - for(i=0; i<sizeof(cmd_data)/sizeof(struct scsi_cmd); i++) - { - if(cmd_data[i].cmd == cmd) - return &cmd_data[i]; - } - - return RT_NULL; -} - -static void _cb_len_calc(ufunction_t func, struct scsi_cmd* cmd, - ustorage_cbw_t cbw) -{ - struct mstorage *data; - - RT_ASSERT(func != RT_NULL); - RT_ASSERT(cmd != RT_NULL); - RT_ASSERT(cbw != RT_NULL); - - data = (struct mstorage*)func->user_data; - if(cmd->cmd_len == 6) - { - switch(cmd->type) - { - case COUNT: - data->cb_data_size = cbw->cb[4]; - break; - case BLOCK_COUNT: - data->cb_data_size = cbw->cb[4] * data->geometry.bytes_per_sector; - break; - case FIXED: - data->cb_data_size = cmd->data_size; - break; - default: - break; - } - } - else if(cmd->cmd_len == 10) - { - switch(cmd->type) - { - case COUNT: - data->cb_data_size = cbw->cb[7]<<8 | cbw->cb[8]; - break; - case BLOCK_COUNT: - data->cb_data_size = (cbw->cb[7]<<8 | cbw->cb[8]) * - data->geometry.bytes_per_sector; - break; - case FIXED: - data->cb_data_size = cmd->data_size; - break; - default: - break; - } - } - - //workaround: for stability in full-speed mode - else if(cmd->cmd_len == 12) - { - switch(cmd->type) - { - case COUNT: - data->cb_data_size = cbw->cb[4]; - break; - default: - break; - } - } - else - { - rt_kprintf("cmd_len error %d\n", cmd->cmd_len); - } -} - -static rt_bool_t _cbw_verify(ufunction_t func, struct scsi_cmd* cmd, - ustorage_cbw_t cbw) -{ - struct mstorage *data; - - RT_ASSERT(cmd != RT_NULL); - RT_ASSERT(cbw != RT_NULL); - RT_ASSERT(func != RT_NULL); - - data = (struct mstorage*)func->user_data; - if(cmd->cmd_len != cbw->cb_len) - { - rt_kprintf("cb_len error\n"); - cmd->cmd_len = cbw->cb_len; - } - - if(cbw->xfer_len > 0 && data->cb_data_size == 0) - { - rt_kprintf("xfer_len > 0 && data_size == 0\n"); - return RT_FALSE; - } - - if(cbw->xfer_len == 0 && data->cb_data_size > 0) - { - rt_kprintf("xfer_len == 0 && data_size > 0"); - return RT_FALSE; - } - - if(((cbw->dflags & USB_DIR_IN) && (cmd->dir == DIR_OUT)) || - (!(cbw->dflags & USB_DIR_IN) && (cmd->dir == DIR_IN))) - { - rt_kprintf("dir error\n"); - return RT_FALSE; - } - - if(cbw->xfer_len > data->cb_data_size) - { - rt_kprintf("xfer_len > data_size\n"); - return RT_FALSE; - } - - if(cbw->xfer_len < data->cb_data_size) - { - rt_kprintf("xfer_len < data_size\n"); - data->cb_data_size = cbw->xfer_len; - data->csw_response.status = 1; - } - - return RT_TRUE; -} - -static rt_ssize_t _cbw_handler(ufunction_t func, struct scsi_cmd* cmd, - ustorage_cbw_t cbw) -{ - struct mstorage *data; - - RT_ASSERT(func != RT_NULL); - RT_ASSERT(cbw != RT_NULL); - RT_ASSERT(cmd->handler != RT_NULL); - - data = (struct mstorage*)func->user_data; - data->processing = cmd; - return cmd->handler(func, cbw); -} - -/** - * This function will handle mass storage bulk out endpoint request. - * - * @param func the usb function object. - * @param size request size. - * - * @return RT_EOK. - */ -static rt_err_t _ep_out_handler(ufunction_t func, rt_size_t size) -{ - struct mstorage *data; - struct scsi_cmd* cmd; - rt_size_t len; - struct ustorage_cbw* cbw; - - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->device != RT_NULL); - - LOG_D("_ep_out_handler %d", size); - - data = (struct mstorage*)func->user_data; - cbw = (struct ustorage_cbw*)data->ep_out->buffer; - if(data->status == STAT_CBW) - { - /* dump cbw information */ - if(cbw->signature != CBW_SIGNATURE || size != SIZEOF_CBW) - { - goto exit; - } - - data->csw_response.signature = CSW_SIGNATURE; - data->csw_response.tag = cbw->tag; - data->csw_response.data_reside = cbw->xfer_len; - data->csw_response.status = 0; - - LOG_D("ep_out reside %d", data->csw_response.data_reside); - - cmd = _find_cbw_command(cbw->cb[0]); - if(cmd == RT_NULL) - { - rt_kprintf("can't find cbw command\n"); - goto exit; - } - - _cb_len_calc(func, cmd, cbw); - if(!_cbw_verify(func, cmd, cbw)) - { - goto exit; - } - - len = _cbw_handler(func, cmd, cbw); - if(len == 0) - { - _send_status(func); - } - - return RT_EOK; - } - else if(data->status == STAT_RECEIVE) - { - LOG_D("write size %d block 0x%x oount 0x%x", - size, data->block, data->size); - - data->size -= size; - data->csw_response.data_reside -= size; - - rt_device_write(data->disk, data->block, data->ep_out->buffer, 1); - - if(data->csw_response.data_reside != 0) - { - data->ep_out->request.buffer = data->ep_out->buffer; - data->ep_out->request.size = data->geometry.bytes_per_sector; - data->ep_out->request.req_type = UIO_REQUEST_READ_FULL; - rt_usbd_io_request(func->device, data->ep_out, &data->ep_out->request); - data->block ++; - } - else - { - _send_status(func); - } - - return RT_EOK; - } - -exit: - if(data->csw_response.data_reside) - { - if(cbw->dflags & USB_DIR_IN) - { - rt_usbd_ep_set_stall(func->device, data->ep_in); - } - else - { - rt_usbd_ep_set_stall(func->device, data->ep_in); - rt_usbd_ep_set_stall(func->device, data->ep_out); - } - } - data->csw_response.status = 1; - _send_status(func); - - return -RT_ERROR; -} - -/** - * This function will handle mass storage interface request. - * - * @param func the usb function object. - * @param setup the setup request. - * - * @return RT_EOK on successful. - */ -static rt_err_t _interface_handler(ufunction_t func, ureq_t setup) -{ - rt_uint8_t lun = 0; - - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->device != RT_NULL); - RT_ASSERT(setup != RT_NULL); - - LOG_D("mstorage_interface_handler"); - - switch(setup->bRequest) - { - case USBREQ_GET_MAX_LUN: - - LOG_D("USBREQ_GET_MAX_LUN"); - - if(setup->wValue || setup->wLength != 1) - { - rt_usbd_ep0_set_stall(func->device); - } - else - { - rt_usbd_ep0_write(func->device, &lun, setup->wLength); - } - break; - case USBREQ_MASS_STORAGE_RESET: - - LOG_D("USBREQ_MASS_STORAGE_RESET"); - - if(setup->wValue || setup->wLength != 0) - { - rt_usbd_ep0_set_stall(func->device); - } - else - { - dcd_ep0_send_status(func->device->dcd); - } - break; - default: - rt_kprintf("unknown interface request\n"); - break; - } - - return RT_EOK; -} - -/** - * This function will run mass storage function, it will be called on handle set configuration request. - * - * @param func the usb function object. - * - * @return RT_EOK on successful. - */ -static rt_err_t _function_enable(ufunction_t func) -{ - struct mstorage *data; - RT_ASSERT(func != RT_NULL); - LOG_D("Mass storage function enabled"); - data = (struct mstorage*)func->user_data; - - data->disk = rt_device_find(RT_USB_MSTORAGE_DISK_NAME); - if(data->disk == RT_NULL) - { - rt_kprintf("no data->disk named %s\n", RT_USB_MSTORAGE_DISK_NAME); - return -RT_ERROR; - } - -#ifdef RT_USING_DFS_MNTTABLE - dfs_unmount_device(data->disk); -#endif - - if(rt_device_open(data->disk, RT_DEVICE_OFLAG_RDWR) != RT_EOK) - { - rt_kprintf("disk open error\n"); - return -RT_ERROR; - } - - if(rt_device_control(data->disk, RT_DEVICE_CTRL_BLK_GETGEOME, - (void*)&data->geometry) != RT_EOK) - { - rt_kprintf("get disk info error\n"); - return -RT_ERROR; - } - - data->ep_in->buffer = (rt_uint8_t*)rt_malloc(data->geometry.bytes_per_sector); - if(data->ep_in->buffer == RT_NULL) - { - rt_kprintf("no memory\n"); - return -RT_ENOMEM; - } - data->ep_out->buffer = (rt_uint8_t*)rt_malloc(data->geometry.bytes_per_sector); - if(data->ep_out->buffer == RT_NULL) - { - rt_free(data->ep_in->buffer); - rt_kprintf("no memory\n"); - return -RT_ENOMEM; - } - - /* prepare to read CBW request */ - data->ep_out->request.buffer = data->ep_out->buffer; - data->ep_out->request.size = SIZEOF_CBW; - data->ep_out->request.req_type = UIO_REQUEST_READ_FULL; - rt_usbd_io_request(func->device, data->ep_out, &data->ep_out->request); - - return RT_EOK; -} - -/** - * This function will stop mass storage function, it will be called on handle set configuration request. - * - * @param device the usb device object. - * - * @return RT_EOK on successful. - */ -static rt_err_t _function_disable(ufunction_t func) -{ - struct mstorage *data; - RT_ASSERT(func != RT_NULL); - - LOG_D("Mass storage function disabled"); - - data = (struct mstorage*)func->user_data; - if(data->ep_in->buffer != RT_NULL) - { - rt_free(data->ep_in->buffer); - data->ep_in->buffer = RT_NULL; - } - - if(data->ep_out->buffer != RT_NULL) - { - rt_free(data->ep_out->buffer); - data->ep_out->buffer = RT_NULL; - } - if(data->disk != RT_NULL) - { - rt_device_close(data->disk); -#ifdef RT_USING_DFS_MNTTABLE - dfs_mount_device(data->disk); -#endif - data->disk = RT_NULL; - } - - data->status = STAT_CBW; - - return RT_EOK; -} - -static struct ufunction_ops ops = -{ - _function_enable, - _function_disable, - RT_NULL, -}; -static rt_err_t _mstorage_descriptor_config(umass_desc_t desc, rt_uint8_t cintf_nr, rt_uint8_t device_is_hs) -{ -#ifdef RT_USB_DEVICE_COMPOSITE - desc->iad_desc.bFirstInterface = cintf_nr; -#endif - desc->ep_out_desc.wMaxPacketSize = device_is_hs ? 512 : 64; - desc->ep_in_desc.wMaxPacketSize = device_is_hs ? 512 : 64; - return RT_EOK; -} -/** - * This function will create a mass storage function instance. - * - * @param device the usb device object. - * - * @return RT_EOK on successful. - */ -ufunction_t rt_usbd_function_mstorage_create(udevice_t device) -{ - uintf_t intf; - struct mstorage *data; - ufunction_t func; - ualtsetting_t setting; - umass_desc_t mass_desc; - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - - /* set usb device string description */ -#ifdef RT_USB_DEVICE_COMPOSITE - rt_usbd_device_set_interface_string(device, MSTRORAGE_INTF_STR_INDEX, _ustring[2]); -#else - rt_usbd_device_set_string(device, _ustring); -#endif - - /* create a mass storage function */ - func = rt_usbd_function_new(device, &dev_desc, &ops); - device->dev_qualifier = &dev_qualifier; - - /* allocate memory for mass storage function data */ - data = (struct mstorage*)rt_malloc(sizeof(struct mstorage)); - rt_memset(data, 0, sizeof(struct mstorage)); - func->user_data = (void*)data; - - /* create an interface object */ - intf = rt_usbd_interface_new(device, _interface_handler); - - /* create an alternate setting object */ - setting = rt_usbd_altsetting_new(sizeof(struct umass_descriptor)); - - /* config desc in alternate setting */ - rt_usbd_altsetting_config_descriptor(setting, &_mass_desc, (rt_off_t)&((umass_desc_t)0)->intf_desc); - - /* configure the msc interface descriptor */ - _mstorage_descriptor_config(setting->desc, intf->intf_num, device->dcd->device_is_hs); - - /* create a bulk out and a bulk in endpoint */ - mass_desc = (umass_desc_t)setting->desc; - data->ep_in = rt_usbd_endpoint_new(&mass_desc->ep_in_desc, _ep_in_handler); - data->ep_out = rt_usbd_endpoint_new(&mass_desc->ep_out_desc, _ep_out_handler); - - /* add the bulk out and bulk in endpoint to the alternate setting */ - rt_usbd_altsetting_add_endpoint(setting, data->ep_out); - rt_usbd_altsetting_add_endpoint(setting, data->ep_in); - - /* add the alternate setting to the interface, then set default setting */ - rt_usbd_interface_add_altsetting(intf, setting); - rt_usbd_set_altsetting(intf, 0); - - /* add the interface to the mass storage function */ - rt_usbd_function_add_interface(func, intf); - - return func; -} -struct udclass msc_class = -{ - .rt_usbd_function_create = rt_usbd_function_mstorage_create -}; - -int rt_usbd_msc_class_register(void) -{ - rt_usbd_class_register(&msc_class); - return 0; -} -INIT_PREV_EXPORT(rt_usbd_msc_class_register); - -#endif diff --git a/components/drivers/usb/usbdevice/class/mstorage.h b/components/drivers/usb/usbdevice/class/mstorage.h deleted file mode 100644 index 812be4c190..0000000000 --- a/components/drivers/usb/usbdevice/class/mstorage.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-10-01 Yi Qiu first version - * 2012-12-12 heyuanjie87 add MASS endpoints collection - */ - -#ifndef __MSTORAGE_H__ -#define __MSTORAGE_H__ - -#include <rtthread.h> - -#pragma pack(1) - -struct umass_descriptor -{ -#ifdef RT_USB_DEVICE_COMPOSITE - struct uiad_descriptor iad_desc; -#endif - struct uinterface_descriptor intf_desc; - struct uendpoint_descriptor ep_out_desc; - struct uendpoint_descriptor ep_in_desc; -}; -typedef struct umass_descriptor* umass_desc_t; - -struct capacity_data -{ - rt_uint8_t LastLogicalBlockAddress[4]; - rt_uint8_t BlockLengthInBytes[4]; -}; - -struct request_sense_data -{ - rt_uint8_t ErrorCode:7; - rt_uint8_t Valid:1; - rt_uint8_t Reserved1; - rt_uint8_t SenseKey:4; - rt_uint8_t Reserved2:4; - rt_uint8_t Information[4]; - rt_uint8_t AdditionalSenseLength; - rt_uint8_t Reserved3[4]; - rt_uint8_t AdditionalSenseCode; - rt_uint8_t AdditionalSenseCodeQualifier; - rt_uint8_t Reserved4[4]; -}request_sense_data_t; - -#pragma pack() - -#endif diff --git a/components/drivers/usb/usbdevice/class/ndis.h b/components/drivers/usb/usbdevice/class/ndis.h deleted file mode 100644 index 40a1ffb64e..0000000000 --- a/components/drivers/usb/usbdevice/class/ndis.h +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ -/* - * ndis.h - * - * Modified by Colin O'Flynn <[email protected]> - * ntddndis.h modified by Benedikt Spranger <[email protected]> - * - * Thanks to the cygwin development team, - * espacially to Casper S. Hornstrup <[email protected]> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - */ - -#ifndef __NDIS_H__ -#define __NDIS_H__ - -#define NDIS_STATUS_MULTICAST_FULL 0xC0010009 -#define NDIS_STATUS_MULTICAST_EXISTS 0xC001000A -#define NDIS_STATUS_MULTICAST_NOT_FOUND 0xC001000B - -/* from drivers/net/sk98lin/h/skgepnmi.h */ -#define OID_PNP_CAPABILITIES 0xFD010100 -#define OID_PNP_SET_POWER 0xFD010101 -#define OID_PNP_QUERY_POWER 0xFD010102 -#define OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103 -#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104 -#define OID_PNP_ENABLE_WAKE_UP 0xFD010106 - -enum NDIS_DEVICE_POWER_STATE -{ - NdisDeviceStateUnspecified = 0, - NdisDeviceStateD0, - NdisDeviceStateD1, - NdisDeviceStateD2, - NdisDeviceStateD3, - NdisDeviceStateMaximum -}; - -struct NDIS_PM_WAKE_UP_CAPABILITIES -{ - enum NDIS_DEVICE_POWER_STATE MinMagicPacketWakeUp; - enum NDIS_DEVICE_POWER_STATE MinPatternWakeUp; - enum NDIS_DEVICE_POWER_STATE MinLinkChangeWakeUp; -}; - -/* NDIS_PNP_CAPABILITIES.Flags constants */ -#define NDIS_DEVICE_WAKE_UP_ENABLE 0x00000001 -#define NDIS_DEVICE_WAKE_ON_PATTERN_MATCH_ENABLE 0x00000002 -#define NDIS_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE 0x00000004 - -/* Required Object IDs (OIDs) */ -#define OID_GEN_SUPPORTED_LIST 0x00010101 -#define OID_GEN_HARDWARE_STATUS 0x00010102 -#define OID_GEN_MEDIA_SUPPORTED 0x00010103 -#define OID_GEN_MEDIA_IN_USE 0x00010104 -#define OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105 -#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106 -#define OID_GEN_LINK_SPEED 0x00010107 -#define OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108 -#define OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109 -#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A -#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B -#define OID_GEN_VENDOR_ID 0x0001010C -#define OID_GEN_VENDOR_DESCRIPTION 0x0001010D -#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010E -#define OID_GEN_CURRENT_LOOKAHEAD 0x0001010F -#define OID_GEN_DRIVER_VERSION 0x00010110 -#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111 -#define OID_GEN_PROTOCOL_OPTIONS 0x00010112 -#define OID_GEN_MAC_OPTIONS 0x00010113 -#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114 -#define OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115 -#define OID_GEN_VENDOR_DRIVER_VERSION 0x00010116 -#define OID_GEN_SUPPORTED_GUIDS 0x00010117 -#define OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118 -#define OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119 -#define OID_GEN_MACHINE_NAME 0x0001021A -#define OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B -#define OID_GEN_VLAN_ID 0x0001021C - -/* Optional OIDs */ -#define OID_GEN_MEDIA_CAPABILITIES 0x00010201 -#define OID_GEN_PHYSICAL_MEDIUM 0x00010202 - -/* Required statistics OIDs */ -#define OID_GEN_XMIT_OK 0x00020101 -#define OID_GEN_RCV_OK 0x00020102 -#define OID_GEN_XMIT_ERROR 0x00020103 -#define OID_GEN_RCV_ERROR 0x00020104 -#define OID_GEN_RCV_NO_BUFFER 0x00020105 - -/* Optional statistics OIDs */ -#define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 -#define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202 -#define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 -#define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204 -#define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 -#define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206 -#define OID_GEN_DIRECTED_BYTES_RCV 0x00020207 -#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208 -#define OID_GEN_MULTICAST_BYTES_RCV 0x00020209 -#define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A -#define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B -#define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C -#define OID_GEN_RCV_CRC_ERROR 0x0002020D -#define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E -#define OID_GEN_GET_TIME_CAPS 0x0002020F -#define OID_GEN_GET_NETCARD_TIME 0x00020210 -#define OID_GEN_NETCARD_LOAD 0x00020211 -#define OID_GEN_DEVICE_PROFILE 0x00020212 -#define OID_GEN_INIT_TIME_MS 0x00020213 -#define OID_GEN_RESET_COUNTS 0x00020214 -#define OID_GEN_MEDIA_SENSE_COUNTS 0x00020215 -#define OID_GEN_FRIENDLY_NAME 0x00020216 -#define OID_GEN_MINIPORT_INFO 0x00020217 -#define OID_GEN_RESET_VERIFY_PARAMETERS 0x00020218 - -/* IEEE 802.3 (Ethernet) OIDs */ -#define NDIS_802_3_MAC_OPTION_PRIORITY 0x00000001 - -#define OID_802_3_PERMANENT_ADDRESS 0x01010101 -#define OID_802_3_CURRENT_ADDRESS 0x01010102 -#define OID_802_3_MULTICAST_LIST 0x01010103 -#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 -#define OID_802_3_MAC_OPTIONS 0x01010105 -#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101 -#define OID_802_3_XMIT_ONE_COLLISION 0x01020102 -#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103 -#define OID_802_3_XMIT_DEFERRED 0x01020201 -#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202 -#define OID_802_3_RCV_OVERRUN 0x01020203 -#define OID_802_3_XMIT_UNDERRUN 0x01020204 -#define OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205 -#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206 -#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 - -/* Wireless LAN OIDs */ -#define OID_802_11_BSSID 0x0D010101 /* Q S */ -#define OID_802_11_SSID 0x0D010102 /* Q S */ -#define OID_802_11_NETWORK_TYPE_IN_USE 0x0D010204 /* Q S */ -#define OID_802_11_RSSI 0x0D010206 /* Q I */ -#define OID_802_11_BSSID_LIST 0x0D010217 /* Q */ -#define OID_802_11_BSSID_LIST_SCAN 0x0D01011A /* S */ -#define OID_802_11_INFRASTRUCTURE_MODE 0x0D010108 /* Q S */ -#define OID_802_11_SUPPORTED_RATES 0x0D01020E /* Q */ -#define OID_802_11_CONFIGURATION 0x0D010211 /* Q S */ -#define OID_802_11_ADD_WEP 0x0D010113 /* S */ -#define OID_802_11_WEP_STATUS 0x0D01011B /* Q S */ -#define OID_802_11_REMOVE_WEP 0x0D010114 /* S */ -#define OID_802_11_DISASSOCIATE 0x0D010115 /* S */ -#define OID_802_11_AUTHENTICATION_MODE 0x0D010118 /* Q S */ -#define OID_802_11_RELOAD_DEFAULTS 0x0D01011C /* S */ - -/* OID_GEN_MINIPORT_INFO constants */ -#define NDIS_MINIPORT_BUS_MASTER 0x00000001 -#define NDIS_MINIPORT_WDM_DRIVER 0x00000002 -#define NDIS_MINIPORT_SG_LIST 0x00000004 -#define NDIS_MINIPORT_SUPPORTS_MEDIA_QUERY 0x00000008 -#define NDIS_MINIPORT_INDICATES_PACKETS 0x00000010 -#define NDIS_MINIPORT_IGNORE_PACKET_QUEUE 0x00000020 -#define NDIS_MINIPORT_IGNORE_REQUEST_QUEUE 0x00000040 -#define NDIS_MINIPORT_IGNORE_TOKEN_RING_ERRORS 0x00000080 -#define NDIS_MINIPORT_INTERMEDIATE_DRIVER 0x00000100 -#define NDIS_MINIPORT_IS_NDIS_5 0x00000200 -#define NDIS_MINIPORT_IS_CO 0x00000400 -#define NDIS_MINIPORT_DESERIALIZE 0x00000800 -#define NDIS_MINIPORT_REQUIRES_MEDIA_POLLING 0x00001000 -#define NDIS_MINIPORT_SUPPORTS_MEDIA_SENSE 0x00002000 -#define NDIS_MINIPORT_NETBOOT_CARD 0x00004000 -#define NDIS_MINIPORT_PM_SUPPORTED 0x00008000 -#define NDIS_MINIPORT_SUPPORTS_MAC_ADDRESS_OVERWRITE 0x00010000 -#define NDIS_MINIPORT_USES_SAFE_BUFFER_APIS 0x00020000 -#define NDIS_MINIPORT_HIDDEN 0x00040000 -#define NDIS_MINIPORT_SWENUM 0x00080000 -#define NDIS_MINIPORT_SURPRISE_REMOVE_OK 0x00100000 -#define NDIS_MINIPORT_NO_HALT_ON_SUSPEND 0x00200000 -#define NDIS_MINIPORT_HARDWARE_DEVICE 0x00400000 -#define NDIS_MINIPORT_SUPPORTS_CANCEL_SEND_PACKETS 0x00800000 -#define NDIS_MINIPORT_64BITS_DMA 0x01000000 - -#define NDIS_MEDIUM_802_3 0x00000000 -#define NDIS_MEDIUM_802_5 0x00000001 -#define NDIS_MEDIUM_FDDI 0x00000002 -#define NDIS_MEDIUM_WAN 0x00000003 -#define NDIS_MEDIUM_LOCAL_TALK 0x00000004 -#define NDIS_MEDIUM_DIX 0x00000005 -#define NDIS_MEDIUM_ARCENT_RAW 0x00000006 -#define NDIS_MEDIUM_ARCENT_878_2 0x00000007 -#define NDIS_MEDIUM_ATM 0x00000008 -#define NDIS_MEDIUM_WIRELESS_LAN 0x00000009 -#define NDIS_MEDIUM_IRDA 0x0000000A -#define NDIS_MEDIUM_BPC 0x0000000B -#define NDIS_MEDIUM_CO_WAN 0x0000000C -#define NDIS_MEDIUM_1394 0x0000000D - -#define NDIS_PACKET_TYPE_DIRECTED 0x00000001 -#define NDIS_PACKET_TYPE_MULTICAST 0x00000002 -#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004 -#define NDIS_PACKET_TYPE_BROADCAST 0x00000008 -#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010 -#define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020 -#define NDIS_PACKET_TYPE_SMT 0x00000040 -#define NDIS_PACKET_TYPE_ALL_LOCAL 0x00000080 -#define NDIS_PACKET_TYPE_GROUP 0x00000100 -#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00000200 -#define NDIS_PACKET_TYPE_FUNCTIONAL 0x00000400 -#define NDIS_PACKET_TYPE_MAC_FRAME 0x00000800 - -#define NDIS_MEDIA_STATE_CONNECTED 0x00000000 -#define NDIS_MEDIA_STATE_DISCONNECTED 0x00000001 - -#define NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA 0x00000001 -#define NDIS_MAC_OPTION_RECEIVE_SERIALIZED 0x00000002 -#define NDIS_MAC_OPTION_TRANSFERS_NOT_PEND 0x00000004 -#define NDIS_MAC_OPTION_NO_LOOPBACK 0x00000008 -#define NDIS_MAC_OPTION_FULL_DUPLEX 0x00000010 -#define NDIS_MAC_OPTION_EOTX_INDICATION 0x00000020 -#define NDIS_MAC_OPTION_8021P_PRIORITY 0x00000040 -#define NDIS_MAC_OPTION_RESERVED 0x80000000 - -#endif /* __NDIS_H__ */ diff --git a/components/drivers/usb/usbdevice/class/rndis.c b/components/drivers/usb/usbdevice/class/rndis.c deleted file mode 100644 index d3ea89ee0a..0000000000 --- a/components/drivers/usb/usbdevice/class/rndis.c +++ /dev/null @@ -1,1476 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-12-24 heyuanjie87 first version - * 2013-04-13 aozima update ethernet driver. - * 2013-04-26 aozima align the desc to 4byte. - * 2013-05-08 aozima pad a dummy when send MAX_PKT_SIZE. - * 2013-05-09 aozima add delay linkup feature. - * 2013-07-09 aozima support respone chain list. - * 2013-07-18 aozima re-initial respone chain list when RNDIS restart. - * 2017-11-25 ZYH fix it and add OS descriptor - * 2019-06-10 ZYH fix hot plug and delay linkup - */ - -#include <rtdevice.h> -#ifdef RT_USB_DEVICE_RNDIS -#include "cdc.h" -#include "rndis.h" -#include "ndis.h" - -/* define RNDIS_DELAY_LINK_UP by menuconfig for delay linkup */ - -#define DBG_LEVEL DBG_WARNING -#define DBG_SECTION_NAME "RNDIS" -#include <rtdbg.h> - -#define RNDIS_INTF_STR_INDEX 12 -/* RT-Thread LWIP ethernet interface */ -#include <netif/ethernetif.h> - - -struct rt_rndis_response -{ - struct rt_list_node list; - const void * buffer; -}; - -#define MAX_ADDR_LEN 6 -struct rt_rndis_eth -{ - /* inherit from ethernet device */ - struct eth_device parent; - struct ufunction *func; - /* interface address info */ - rt_uint8_t host_addr[MAX_ADDR_LEN]; - rt_uint8_t dev_addr[MAX_ADDR_LEN]; - -#ifdef RNDIS_DELAY_LINK_UP - struct rt_timer timer; -#endif /* RNDIS_DELAY_LINK_UP */ - - rt_align(4) - rt_uint8_t rx_pool[512]; - rt_align(4) - rt_uint8_t tx_pool[512]; - - rt_uint32_t cmd_pool[2]; - rt_align(4) - char rx_buffer[sizeof(struct rndis_packet_msg) + USB_ETH_MTU + 14]; - rt_size_t rx_offset; - rt_size_t rx_length; - rt_bool_t rx_flag; - rt_bool_t rx_frist; - - rt_align(4) - char tx_buffer[sizeof(struct rndis_packet_msg) + USB_ETH_MTU + 14]; - struct rt_semaphore tx_buffer_free; - - struct rt_list_node response_list; - rt_bool_t need_notify; - struct cdc_eps eps; -}; -typedef struct rt_rndis_eth * rt_rndis_eth_t; -static rt_uint32_t oid_packet_filter = 0x0000000; - -rt_align(4) -static struct udevice_descriptor _dev_desc = -{ - USB_DESC_LENGTH_DEVICE, /* bLength */ - USB_DESC_TYPE_DEVICE, /* type */ - USB_BCD_VERSION, /* bcdUSB */ - 0xEF, /* bDeviceClass */ - 0x04, /* bDeviceSubClass */ - 0x01, /* bDeviceProtocol */ - USB_CDC_BUFSIZE, /* bMaxPacketSize0 */ - _VENDOR_ID, /* idVendor */ - _PRODUCT_ID, /* idProduct */ - USB_BCD_DEVICE, /* bcdDevice */ - USB_STRING_MANU_INDEX, /* iManufacturer */ - USB_STRING_PRODUCT_INDEX, /* iProduct */ - USB_STRING_SERIAL_INDEX, /* iSerialNumber */ - USB_DYNAMIC /* bNumConfigurations */ -}; - -/* communcation interface descriptor */ -rt_align(4) -const static struct ucdc_comm_descriptor _comm_desc = -{ -#ifdef RT_USB_DEVICE_COMPOSITE - /* Interface Association Descriptor */ - { - USB_DESC_LENGTH_IAD, - USB_DESC_TYPE_IAD, - USB_DYNAMIC, - 0x02, - USB_CDC_CLASS_COMM, - USB_CDC_SUBCLASS_ACM, - USB_CDC_PROTOCOL_VENDOR, - 0x00, - }, -#endif - /* Interface Descriptor */ - { - USB_DESC_LENGTH_INTERFACE, - USB_DESC_TYPE_INTERFACE, - USB_DYNAMIC, - 0x00, - 0x01, - USB_CDC_CLASS_COMM, - USB_CDC_SUBCLASS_ACM, - USB_CDC_PROTOCOL_VENDOR, -#ifdef RT_USB_DEVICE_COMPOSITE - RNDIS_INTF_STR_INDEX, -#else - 0x00, -#endif - }, - /* Header Functional Descriptor */ - { - 0x05, - USB_CDC_CS_INTERFACE, - USB_CDC_SCS_HEADER, - 0x0110, - }, - /* Call Management Functional Descriptor */ - { - 0x05, - USB_CDC_CS_INTERFACE, - USB_CDC_SCS_CALL_MGMT, - 0x00, - USB_DYNAMIC, - }, - /* Abstract Control Management Functional Descriptor */ - { - 0x04, - USB_CDC_CS_INTERFACE, - USB_CDC_SCS_ACM, - 0x02, - }, - /* Union Functional Descriptor */ - { - 0x05, - USB_CDC_CS_INTERFACE, - USB_CDC_SCS_UNION, - USB_DYNAMIC, - USB_DYNAMIC, - }, - /* Endpoint Descriptor */ - { - USB_DESC_LENGTH_ENDPOINT, - USB_DESC_TYPE_ENDPOINT, - USB_DIR_IN | USB_DYNAMIC, - USB_EP_ATTR_INT, - 0x08, - 0x0A, - }, -}; - -/* data interface descriptor */ -rt_align(4) -const static struct ucdc_data_descriptor _data_desc = -{ - /* interface descriptor */ - { - USB_DESC_LENGTH_INTERFACE, - USB_DESC_TYPE_INTERFACE, - USB_DYNAMIC, - 0x00, - 0x02, - USB_CDC_CLASS_DATA, - 0x00, - 0x00, - 0x00, - }, - /* endpoint, bulk out */ - { - USB_DESC_LENGTH_ENDPOINT, - USB_DESC_TYPE_ENDPOINT, - USB_DIR_OUT | USB_DYNAMIC, - USB_EP_ATTR_BULK, - USB_DYNAMIC, - 0x00, - }, - /* endpoint, bulk in */ - { - USB_DESC_LENGTH_ENDPOINT, - USB_DESC_TYPE_ENDPOINT, - USB_DYNAMIC | USB_DIR_IN, - USB_EP_ATTR_BULK, - USB_DYNAMIC, - 0x00, - }, -}; - -rt_align(4) -const static char* _ustring[] = -{ - "Language", /* LANGID */ - "RT-Thread Team.", /* MANU */ - "RT-Thread RNDIS device", /* PRODUCT */ - "1.1.0", /* SERIAL */ - "Configuration", /* CONFIG */ - "Interface", /* INTERFACE */ - USB_STRING_OS -}; - -rt_align(4) -struct usb_os_function_comp_id_descriptor rndis_func_comp_id_desc = -{ - .bFirstInterfaceNumber = USB_DYNAMIC, - .reserved1 = 0x01, - .compatibleID = {'R', 'N', 'D', 'I', 'S', 0x00, 0x00, 0x00}, - .subCompatibleID = {'5', '1', '6', '2', '0', '0', '1', 0x00}, - .reserved2 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} -}; - -//FS and HS needed -rt_align(4) -static struct usb_qualifier_descriptor dev_qualifier = -{ - sizeof(dev_qualifier), //bLength - USB_DESC_TYPE_DEVICEQUALIFIER, //bDescriptorType - 0x0200, //bcdUSB - USB_CLASS_CDC, //bDeviceClass - USB_CDC_SUBCLASS_ACM, //bDeviceSubClass - USB_CDC_PROTOCOL_VENDOR, //bDeviceProtocol - 64, //bMaxPacketSize0 - 0x01, //bNumConfigurations - 0, -}; - -/* supported OIDs */ -rt_align(4) -const static rt_uint32_t oid_supported_list[] = -{ - /* General OIDs */ - OID_GEN_SUPPORTED_LIST, - OID_GEN_HARDWARE_STATUS, - OID_GEN_MEDIA_SUPPORTED, - OID_GEN_MEDIA_IN_USE, - OID_GEN_MAXIMUM_FRAME_SIZE, - OID_GEN_LINK_SPEED, - OID_GEN_TRANSMIT_BLOCK_SIZE, - OID_GEN_RECEIVE_BLOCK_SIZE, - OID_GEN_VENDOR_ID, - OID_GEN_VENDOR_DESCRIPTION, - OID_GEN_VENDOR_DRIVER_VERSION, - OID_GEN_CURRENT_PACKET_FILTER, - OID_GEN_MAXIMUM_TOTAL_SIZE, - OID_GEN_MEDIA_CONNECT_STATUS, - - OID_GEN_PHYSICAL_MEDIUM, - - /* General Statistic OIDs */ - OID_GEN_XMIT_OK, - OID_GEN_RCV_OK, - OID_GEN_XMIT_ERROR, - OID_GEN_RCV_ERROR, - OID_GEN_RCV_NO_BUFFER, - - /* Please configure us */ - OID_GEN_RNDIS_CONFIG_PARAMETER, - - /* 802.3 OIDs */ - OID_802_3_PERMANENT_ADDRESS, - OID_802_3_CURRENT_ADDRESS, - OID_802_3_MULTICAST_LIST, - OID_802_3_MAXIMUM_LIST_SIZE, - - /* 802.3 Statistic OIDs */ - OID_802_3_RCV_ERROR_ALIGNMENT, - OID_802_3_XMIT_ONE_COLLISION, - OID_802_3_XMIT_MORE_COLLISIONS, - - OID_802_3_MAC_OPTIONS, -}; - -static rt_uint8_t rndis_message_buffer[RNDIS_MESSAGE_BUFFER_SIZE]; - -static void _rndis_response_available(ufunction_t func) -{ - rt_rndis_eth_t device = (rt_rndis_eth_t)func->user_data; - rt_uint32_t * data; - if(device->need_notify == RT_TRUE) - { - device->need_notify = RT_FALSE; - data = (rt_uint32_t *)device->eps.ep_cmd->buffer; - data[0] = RESPONSE_AVAILABLE; - data[1] = 0; - device->eps.ep_cmd->request.buffer = device->eps.ep_cmd->buffer; - device->eps.ep_cmd->request.size = 8; - device->eps.ep_cmd->request.req_type = UIO_REQUEST_WRITE; - rt_usbd_io_request(func->device, device->eps.ep_cmd, &device->eps.ep_cmd->request); - } -} - -static rt_err_t _rndis_init_response(ufunction_t func, rndis_init_msg_t msg) -{ - rndis_init_cmplt_t resp; - struct rt_rndis_response * response; - - response = rt_malloc(sizeof(struct rt_rndis_response)); - resp = rt_malloc(sizeof(struct rndis_init_cmplt)); - - if( (response == RT_NULL) || (resp == RT_NULL) ) - { - LOG_E("%s,%d: no memory!", __func__, __LINE__); - - if(response != RT_NULL) - rt_free(response); - - if(resp != RT_NULL) - rt_free(resp); - - return -RT_ENOMEM; - } - - resp->RequestId = msg->RequestId; - resp->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT; - resp->MessageLength = sizeof(struct rndis_init_cmplt); - resp->MajorVersion = RNDIS_MAJOR_VERSION; - resp->MinorVersion = RNDIS_MAJOR_VERSION; - resp->Status = RNDIS_STATUS_SUCCESS; - resp->DeviceFlags = RNDIS_DF_CONNECTIONLESS; - resp->Medium = RNDIS_MEDIUM_802_3; - resp->MaxPacketsPerTransfer = 1; - resp->MaxTransferSize = USB_ETH_MTU + 58; /* Space for 1280 IP buffer, Ethernet Header, - RNDIS messages */ - resp->PacketAlignmentFactor = 3; - resp->AfListOffset = 0; - resp->AfListSize = 0; - - response->buffer = resp; - - { - rt_base_t level = rt_hw_interrupt_disable(); - rt_list_insert_before(&((rt_rndis_eth_t)func->user_data)->response_list, &response->list); - rt_hw_interrupt_enable(level); - } - - - return RT_EOK; -} - -static rndis_query_cmplt_t _create_resp(rt_size_t size) -{ - rndis_query_cmplt_t resp; - - resp = rt_malloc(sizeof(struct rndis_query_cmplt) + size); - - if(resp == RT_NULL) - { - LOG_E("%s,%d: no memory!", __func__, __LINE__); - return RT_NULL; - } - - resp->InformationBufferLength = size; - - return resp; -} - -static void _copy_resp(rndis_query_cmplt_t resp, const void * buffer) -{ - char * resp_buffer = (char *)resp + sizeof(struct rndis_query_cmplt); - rt_memcpy(resp_buffer, buffer, resp->InformationBufferLength); -} - -static void _set_resp(rndis_query_cmplt_t resp, rt_uint32_t value) -{ - rt_uint32_t * response = (rt_uint32_t *)((char *)resp + sizeof(struct rndis_query_cmplt)); - *response = value; -} - -static rt_err_t _rndis_query_response(ufunction_t func,rndis_query_msg_t msg) -{ - rndis_query_cmplt_t resp = RT_NULL; - struct rt_rndis_response * response; - rt_err_t ret = RT_EOK; - - switch (msg->Oid) - { - /* - * general OIDs - */ - case OID_GEN_SUPPORTED_LIST: - resp = _create_resp(sizeof(oid_supported_list)); - if(resp == RT_NULL) break; - _copy_resp(resp, oid_supported_list); - break; - - case OID_GEN_PHYSICAL_MEDIUM: - resp = _create_resp(4); - if(resp == RT_NULL) break; - _set_resp(resp, NDIS_MEDIUM_802_3); - break; - - case OID_GEN_MAXIMUM_FRAME_SIZE: - case OID_GEN_TRANSMIT_BLOCK_SIZE: - case OID_GEN_RECEIVE_BLOCK_SIZE: - resp = _create_resp(4); - if(resp == RT_NULL) break; - _set_resp(resp, USB_ETH_MTU); - break; - - case OID_GEN_MAXIMUM_TOTAL_SIZE: - resp = _create_resp(4); - if(resp == RT_NULL) break; - _set_resp(resp, USB_ETH_MTU + RNDIS_MESSAGE_BUFFER_SIZE); - break; - - case OID_GEN_LINK_SPEED: - resp = _create_resp(4); - if(resp == RT_NULL) break; - _set_resp(resp, (func->device->dcd->device_is_hs ? (480UL * 1000 *1000) : (12UL * 1000 * 1000)) / 100); - break; - - case OID_GEN_MEDIA_CONNECT_STATUS: - /* link_status */ - resp = _create_resp(4); - if(resp == RT_NULL) break; - -#ifdef RNDIS_DELAY_LINK_UP - if(((rt_rndis_eth_t)func->user_data)->parent.link_status) - { - _set_resp(resp, NDIS_MEDIA_STATE_CONNECTED); - } - else - { - _set_resp(resp, NDIS_MEDIA_STATE_DISCONNECTED); - } -#else - _set_resp(resp, NDIS_MEDIA_STATE_CONNECTED); -#endif /* RNDIS_DELAY_LINK_UP */ - break; - - case OID_GEN_VENDOR_ID: - resp = _create_resp(4); - if(resp == RT_NULL) break; - _set_resp(resp, 0x12345678); /* only for test */ - break; - - case OID_GEN_VENDOR_DESCRIPTION: - { - const char vendor_desc[] = "RT-Thread RNDIS"; - - resp = _create_resp(sizeof(vendor_desc)); - if(resp == RT_NULL) break; - _copy_resp(resp, vendor_desc); - } - break; - - case OID_GEN_VENDOR_DRIVER_VERSION: - resp = _create_resp(4); - if(resp == RT_NULL) break; - _set_resp(resp, 0x0000200); - break; - - /* statistics OIDs */ - case OID_GEN_XMIT_OK: - case OID_GEN_RCV_OK: - resp = _create_resp(4); - if(resp == RT_NULL) break; - _set_resp(resp, 1); - break; - - case OID_GEN_XMIT_ERROR: - case OID_GEN_RCV_ERROR: - case OID_GEN_RCV_NO_BUFFER: - resp = _create_resp(4); - if(resp == RT_NULL) break; - _set_resp(resp, 0); - break; - - /* - * ieee802.3 OIDs - */ - case OID_802_3_MAXIMUM_LIST_SIZE: - resp = _create_resp(4); - if(resp == RT_NULL) break; - _set_resp(resp, 1); - break; - - case OID_802_3_PERMANENT_ADDRESS: - case OID_802_3_CURRENT_ADDRESS: - resp = _create_resp(sizeof(((rt_rndis_eth_t)func->user_data)->host_addr)); - if(resp == RT_NULL) break; - _copy_resp(resp, ((rt_rndis_eth_t)func->user_data)->host_addr); - break; - - case OID_802_3_MULTICAST_LIST: - resp = _create_resp(4); - if(resp == RT_NULL) break; - _set_resp(resp, 0xE000000); - break; - - case OID_802_3_MAC_OPTIONS: - resp = _create_resp(4); - if(resp == RT_NULL) break; - _set_resp(resp, 0); - break; - - default: - LOG_W("Not support OID %X", msg->Oid); - ret = -RT_ERROR; - break; - } - - response = rt_malloc(sizeof(struct rt_rndis_response)); - if( (response == RT_NULL) || (resp == RT_NULL) ) - { - LOG_E("%s,%d: no memory!", __func__, __LINE__); - - if(response != RT_NULL) - rt_free(response); - - if(resp != RT_NULL) - rt_free(resp); - - return -RT_ENOMEM; - } - - resp->RequestId = msg->RequestId; - resp->MessageType = REMOTE_NDIS_QUERY_CMPLT; - resp->InformationBufferOffset = 16; - - resp->Status = RNDIS_STATUS_SUCCESS; - resp->MessageLength = sizeof(struct rndis_query_cmplt) + resp->InformationBufferLength; - - response->buffer = resp; - - { - rt_base_t level = rt_hw_interrupt_disable(); - rt_list_insert_before(&((rt_rndis_eth_t)func->user_data)->response_list, &response->list); - rt_hw_interrupt_enable(level); - } - - return ret; -} - -static rt_err_t _rndis_set_response(ufunction_t func,rndis_set_msg_t msg) -{ - rndis_set_cmplt_t resp; - struct rt_rndis_response * response; - - response = rt_malloc(sizeof(struct rt_rndis_response)); - resp = rt_malloc(sizeof(struct rndis_set_cmplt)); - - if( (response == RT_NULL) || (resp == RT_NULL) ) - { - LOG_E("%s,%d: no memory!", __func__, __LINE__); - - if(response != RT_NULL) - rt_free(response); - - if(resp != RT_NULL) - rt_free(resp); - - return -RT_ENOMEM; - } - - resp->RequestId = msg->RequestId; - resp->MessageType = REMOTE_NDIS_SET_CMPLT; - resp->MessageLength = sizeof(struct rndis_set_cmplt); - - switch (msg->Oid) - { - case OID_GEN_CURRENT_PACKET_FILTER: - oid_packet_filter = *((rt_uint32_t *)((rt_uint8_t *)&(msg->RequestId) + \ - msg->InformationBufferOffset)); - /* TODO: make complier happy */ - oid_packet_filter = oid_packet_filter; - - LOG_D("OID_GEN_CURRENT_PACKET_FILTER"); - -#ifdef RNDIS_DELAY_LINK_UP - /* link up. */ - rt_timer_start(&((rt_rndis_eth_t)func->user_data)->timer); -#else - eth_device_linkchange(&((rt_rndis_eth_t)func->user_data)->parent, RT_TRUE); -#endif /* RNDIS_DELAY_LINK_UP */ - break; - - case OID_802_3_MULTICAST_LIST: - break; - - default: - LOG_W("Unknow rndis set 0x%02X", msg->Oid); - resp->Status = RNDIS_STATUS_FAILURE; - return RT_EOK; - } - - resp->Status = RNDIS_STATUS_SUCCESS; - - response->buffer = resp; - - { - rt_base_t level = rt_hw_interrupt_disable(); - rt_list_insert_before(&((rt_rndis_eth_t)func->user_data)->response_list, &response->list); - rt_hw_interrupt_enable(level); - } - - return RT_EOK; -} - -static rt_err_t _rndis_reset_response(ufunction_t func,rndis_set_msg_t msg) -{ - struct rndis_reset_cmplt * resp; - struct rt_rndis_response * response; - - response = rt_malloc(sizeof(struct rt_rndis_response)); - resp = rt_malloc(sizeof(struct rndis_reset_cmplt)); - - if( (response == RT_NULL) || (resp == RT_NULL) ) - { - LOG_E("%s,%d: no memory!", __func__, __LINE__); - - if(response != RT_NULL) - rt_free(response); - - if(resp != RT_NULL) - rt_free(resp); - - return -RT_ENOMEM; - } - - /* reset packet filter */ - - oid_packet_filter = 0x0000000; - - /* link down eth */ - - eth_device_linkchange(&((rt_rndis_eth_t)func->user_data)->parent, RT_FALSE); - - /* reset eth rx tx */ - ((rt_rndis_eth_t)func->user_data)->rx_frist = RT_TRUE; - ((rt_rndis_eth_t)func->user_data)->rx_flag = RT_FALSE; - - - resp->MessageType = REMOTE_NDIS_RESET_CMPLT; - resp->MessageLength = sizeof(struct rndis_reset_cmplt); - resp->Status = RNDIS_STATUS_SUCCESS; - resp->AddressingReset = 1; - - response->buffer = resp; - - { - rt_base_t level = rt_hw_interrupt_disable(); - rt_list_insert_before(&((rt_rndis_eth_t)func->user_data)->response_list, &response->list); - rt_hw_interrupt_enable(level); - } - - return RT_EOK; -} - -static rt_err_t _rndis_keepalive_response(ufunction_t func,rndis_keepalive_msg_t msg) -{ - rndis_keepalive_cmplt_t resp; - struct rt_rndis_response * response; - - response = rt_malloc(sizeof(struct rt_rndis_response)); - resp = rt_malloc(sizeof(struct rndis_keepalive_cmplt)); - - if( (response == RT_NULL) || (resp == RT_NULL) ) - { - LOG_E("%s,%d: no memory!", __func__, __LINE__); - - if(response != RT_NULL) - rt_free(response); - - if(resp != RT_NULL) - rt_free(resp); - - return -RT_ENOMEM; - } - - resp->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT; - resp->MessageLength = sizeof(struct rndis_keepalive_cmplt); - resp->Status = RNDIS_STATUS_SUCCESS; - - response->buffer = resp; - - { - rt_base_t level = rt_hw_interrupt_disable(); - rt_list_insert_before(&((rt_rndis_eth_t)func->user_data)->response_list, &response->list); - rt_hw_interrupt_enable(level); - } - - return RT_EOK; -} - -static rt_err_t _rndis_msg_parser(ufunction_t func, rt_uint8_t *msg) -{ - rt_err_t ret = -RT_ERROR; - - switch (((rndis_gen_msg_t) msg)->MessageType) - { - case REMOTE_NDIS_INITIALIZE_MSG: - LOG_D("REMOTE_NDIS_INITIALIZE_MSG"); - ret = _rndis_init_response(func, (rndis_init_msg_t) msg); - break; - - case REMOTE_NDIS_HALT_MSG: - LOG_D("REMOTE_NDIS_HALT_MSG"); - /* link down. */ - eth_device_linkchange(&((rt_rndis_eth_t)func->user_data)->parent, RT_FALSE); - - /* reset eth rx tx */ - ((rt_rndis_eth_t)func->user_data)->rx_frist = RT_TRUE; - ((rt_rndis_eth_t)func->user_data)->rx_flag = RT_FALSE; - break; - - case REMOTE_NDIS_QUERY_MSG: - LOG_D("REMOTE_NDIS_QUERY_MSG"); - ret = _rndis_query_response(func,(rndis_query_msg_t) msg); - break; - - case REMOTE_NDIS_SET_MSG: - LOG_D("REMOTE_NDIS_SET_MSG"); - ret = _rndis_set_response(func,(rndis_set_msg_t) msg); - break; - - case REMOTE_NDIS_RESET_MSG: - LOG_D("REMOTE_NDIS_RESET_MSG"); - ret = _rndis_reset_response(func,(rndis_set_msg_t) msg); - break; - - case REMOTE_NDIS_KEEPALIVE_MSG: - LOG_D("REMOTE_NDIS_KEEPALIVE_MSG"); - ret = _rndis_keepalive_response(func,(rndis_keepalive_msg_t) msg); - break; - - default: - LOG_W("not support RNDIS msg %X", ((rndis_gen_msg_t) msg)->MessageType); - ret = -RT_ERROR; - break; - } - - if (ret == RT_EOK) - _rndis_response_available(func); - - return ret; -} - -static ufunction_t function = RT_NULL; -static rt_err_t send_encapsulated_command_done(udevice_t device, rt_size_t size) -{ - if(function != RT_NULL) - { - dcd_ep0_send_status(device->dcd); - _rndis_msg_parser(function, rndis_message_buffer); - function = RT_NULL; - } - return RT_EOK; -} -//#error here have bug ep 0x82 send failed -static rt_err_t _rndis_send_encapsulated_command(ufunction_t func, ureq_t setup) -{ - RT_ASSERT(setup->wLength <= sizeof(rndis_message_buffer)); - function = func; - rt_usbd_ep0_read(func->device,rndis_message_buffer,setup->wLength,send_encapsulated_command_done); - - return RT_EOK; -} - -static rt_err_t _rndis_get_encapsulated_response(ufunction_t func, ureq_t setup) -{ - rndis_gen_msg_t msg; - struct rt_rndis_response * response; - - if(rt_list_isempty(&((rt_rndis_eth_t)func->user_data)->response_list)) - { - LOG_D("response_list is empty!"); - ((rt_rndis_eth_t)func->user_data)->need_notify = RT_TRUE; - return RT_EOK; - } - - response = (struct rt_rndis_response *)((rt_rndis_eth_t)func->user_data)->response_list.next; - - msg = (rndis_gen_msg_t)response->buffer; - rt_usbd_ep0_write(func->device, (void*)msg, msg->MessageLength); - - { - rt_base_t level = rt_hw_interrupt_disable(); - rt_list_remove(&response->list); - rt_hw_interrupt_enable(level); - } - - rt_free((void *)response->buffer); - rt_free(response); - - if(!rt_list_isempty(&((rt_rndis_eth_t)func->user_data)->response_list)) - { - rt_uint32_t * data; - - LOG_I("auto append next response!"); - data = (rt_uint32_t *)((rt_rndis_eth_t)func->user_data)->eps.ep_cmd->buffer; - data[0] = RESPONSE_AVAILABLE; - data[1] = 0; - ((rt_rndis_eth_t)func->user_data)->eps.ep_cmd->request.buffer = ((rt_rndis_eth_t)func->user_data)->eps.ep_cmd->buffer; - ((rt_rndis_eth_t)func->user_data)->eps.ep_cmd->request.size = 8; - ((rt_rndis_eth_t)func->user_data)->eps.ep_cmd->request.req_type = UIO_REQUEST_WRITE; - rt_usbd_io_request(func->device, ((rt_rndis_eth_t)func->user_data)->eps.ep_cmd, &((rt_rndis_eth_t)func->user_data)->eps.ep_cmd->request); - } - else - { - ((rt_rndis_eth_t)func->user_data)->need_notify = RT_TRUE; - } - - return RT_EOK; -} - -/** - * This function will handle rndis interface request. - * - * @param device the usb device object. - * @param setup the setup request. - * - * @return RT_EOK on successful. - */ -static rt_err_t _interface_handler(ufunction_t func, ureq_t setup) -{ - RT_ASSERT(func != RT_NULL); - RT_ASSERT(setup != RT_NULL); - - switch(setup->bRequest) - { - case CDC_SEND_ENCAPSULATED_COMMAND: - _rndis_send_encapsulated_command(func, setup); - break; - - case CDC_GET_ENCAPSULATED_RESPONSE: - _rndis_get_encapsulated_response(func, setup); - break; - - default: - LOG_W("unkown setup->request 0x%02X !", setup->bRequest); - break; - } - - return RT_EOK; -} - -/** - * This function will handle rndis bulk in endpoint request. - * - * @param device the usb device object. - * @param size request size. - * - * @return RT_EOK. - */ - -static rt_err_t _ep_in_handler(ufunction_t func, rt_size_t size) -{ - rt_sem_release(&((rt_rndis_eth_t)func->user_data)->tx_buffer_free); - return RT_EOK; -} - -/** - * This function will handle RNDIS bulk out endpoint request. - * - * @param device the usb device object. - * @param size request size. - * - * @return RT_EOK. - */ -static rt_err_t _ep_out_handler(ufunction_t func, rt_size_t size) -{ - cdc_eps_t eps; - char* data = RT_NULL; - - eps = (cdc_eps_t)&((rt_rndis_eth_t)func->user_data)->eps; - data = (char*)eps->ep_out->buffer; - - if(((rt_rndis_eth_t)func->user_data)->rx_frist == RT_TRUE) - { - rndis_packet_msg_t msg = (rndis_packet_msg_t)data; - - ((rt_rndis_eth_t)func->user_data)->rx_length = msg->DataLength; - ((rt_rndis_eth_t)func->user_data)->rx_offset = 0; - - if (size >= 44) - { - data += sizeof(struct rndis_packet_msg); - size -= sizeof(struct rndis_packet_msg); - ((rt_rndis_eth_t)func->user_data)->rx_frist = RT_FALSE; - rt_memcpy(&((rt_rndis_eth_t)func->user_data)->rx_buffer[((rt_rndis_eth_t)func->user_data)->rx_offset], data, size); - ((rt_rndis_eth_t)func->user_data)->rx_offset += size; - } - } - else - { - rt_memcpy(&((rt_rndis_eth_t)func->user_data)->rx_buffer[((rt_rndis_eth_t)func->user_data)->rx_offset], data, size); - ((rt_rndis_eth_t)func->user_data)->rx_offset += size; - } - - if(((rt_rndis_eth_t)func->user_data)->rx_offset >= ((rt_rndis_eth_t)func->user_data)->rx_length) - { - ((rt_rndis_eth_t)func->user_data)->rx_frist = RT_TRUE; - ((rt_rndis_eth_t)func->user_data)->rx_flag = RT_TRUE; - eth_device_ready(&(((rt_rndis_eth_t)func->user_data)->parent)); - } - else - { - eps->ep_out->request.buffer = eps->ep_out->buffer; - eps->ep_out->request.size = EP_MAXPACKET(eps->ep_out); - eps->ep_out->request.req_type = UIO_REQUEST_READ_BEST; - rt_usbd_io_request(func->device, eps->ep_out, &eps->ep_out->request); - } - - return RT_EOK; -} - -/** - * This function will handle RNDIS interrupt in endpoint request. - * - * @param device the usb device object. - * @param size request size. - * - * @return RT_EOK. - */ -static rt_err_t _ep_cmd_handler(ufunction_t func, rt_size_t size) -{ -// _rndis_response_available(func); - return RT_EOK; -} - -/** - * This function will run cdc class, it will be called on handle set configuration request. - * - * @param device the usb device object. - * - * @return RT_EOK on successful. - */ -static rt_err_t _function_enable(ufunction_t func) -{ - cdc_eps_t eps; - - LOG_I("plugged in"); - - eps = (cdc_eps_t)&((rt_rndis_eth_t)func->user_data)->eps; - eps->ep_in->buffer = ((rt_rndis_eth_t)func->user_data)->tx_pool; - eps->ep_out->buffer = ((rt_rndis_eth_t)func->user_data)->rx_pool; - eps->ep_cmd->buffer = (rt_uint8_t*)((rt_rndis_eth_t)func->user_data)->cmd_pool; - - eps->ep_out->request.buffer = eps->ep_out->buffer; - eps->ep_out->request.size = EP_MAXPACKET(eps->ep_out); - eps->ep_out->request.req_type = UIO_REQUEST_READ_BEST; - rt_usbd_io_request(func->device, eps->ep_out, &eps->ep_out->request); - - ((rt_rndis_eth_t)func->user_data)->rx_flag = RT_FALSE; - ((rt_rndis_eth_t)func->user_data)->rx_frist = RT_TRUE; - // eth_device_ready(&(((rt_rndis_eth_t)func->user_data)->parent)); - -#ifdef RNDIS_DELAY_LINK_UP - /* stop link up timer. */ - rt_timer_stop(&((rt_rndis_eth_t)func->user_data)->timer); -#endif /* RNDIS_DELAY_LINK_UP */ - - /* clean resp chain list. */ - { - struct rt_rndis_response * response; - rt_base_t level = rt_hw_interrupt_disable(); - - while(!rt_list_isempty(&((rt_rndis_eth_t)func->user_data)->response_list)) - { - response = (struct rt_rndis_response *)((rt_rndis_eth_t)func->user_data)->response_list.next; - - rt_list_remove(&response->list); - rt_free((void *)response->buffer); - rt_free(response); - } - - ((rt_rndis_eth_t)func->user_data)->need_notify = RT_TRUE; - rt_hw_interrupt_enable(level); - } - - return RT_EOK; -} - -/** - * This function will stop cdc class, it will be called on handle set configuration request. - * - * @param device the usb device object. - * - * @return RT_EOK on successful. - */ -static rt_err_t _function_disable(ufunction_t func) -{ - LOG_I("plugged out"); - -#ifdef RNDIS_DELAY_LINK_UP - /* stop link up timer. */ - rt_timer_stop(&((rt_rndis_eth_t)func->user_data)->timer); -#endif /* RNDIS_DELAY_LINK_UP */ - - /* clean resp chain list. */ - { - struct rt_rndis_response * response; - rt_base_t level = rt_hw_interrupt_disable(); - - while(!rt_list_isempty(&((rt_rndis_eth_t)func->user_data)->response_list)) - { - response = (struct rt_rndis_response *)((rt_rndis_eth_t)func->user_data)->response_list.next; - LOG_D("remove resp chain list!"); - - rt_list_remove(&response->list); - rt_free((void *)response->buffer); - rt_free(response); - } - - ((rt_rndis_eth_t)func->user_data)->need_notify = RT_TRUE; - rt_hw_interrupt_enable(level); - } - - - /* link down. */ - eth_device_linkchange(&((rt_rndis_eth_t)func->user_data)->parent, RT_FALSE); - - /* reset eth rx tx */ - ((rt_rndis_eth_t)func->user_data)->rx_frist = RT_TRUE; - ((rt_rndis_eth_t)func->user_data)->rx_flag = RT_FALSE; - - return RT_EOK; -} - - -static struct ufunction_ops ops = -{ - _function_enable, - _function_disable, - RT_NULL, -}; - -/** - * This function will configure cdc descriptor. - * - * @param comm the communication interface number. - * @param data the data interface number. - * - * @return RT_EOK on successful. - */ -static rt_err_t _cdc_descriptor_config(ucdc_comm_desc_t comm, rt_uint8_t cintf_nr, ucdc_data_desc_t data, rt_uint8_t dintf_nr, rt_uint8_t device_is_hs) -{ - comm->call_mgmt_desc.data_interface = dintf_nr; - comm->union_desc.master_interface = cintf_nr; - comm->union_desc.slave_interface0 = dintf_nr; -#ifdef RT_USB_DEVICE_COMPOSITE - comm->iad_desc.bFirstInterface = cintf_nr; -#endif - data->ep_out_desc.wMaxPacketSize = device_is_hs ? 512 : 64; - data->ep_in_desc.wMaxPacketSize = device_is_hs ? 512 : 64; - return RT_EOK; -} - -#ifdef RT_USING_LWIP -/* initialize the interface */ -static rt_err_t rt_rndis_eth_init(rt_device_t dev) -{ - return RT_EOK; -} - -static rt_err_t rt_rndis_eth_open(rt_device_t dev, rt_uint16_t oflag) -{ - return RT_EOK; -} - -static rt_err_t rt_rndis_eth_close(rt_device_t dev) -{ - return RT_EOK; -} - -static rt_ssize_t rt_rndis_eth_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) -{ - rt_set_errno(-RT_ENOSYS); - return 0; -} - -static rt_ssize_t rt_rndis_eth_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) -{ - rt_set_errno(-RT_ENOSYS); - return 0; -} -static rt_err_t rt_rndis_eth_control(rt_device_t dev, int cmd, void *args) -{ - rt_rndis_eth_t rndis_eth_dev = (rt_rndis_eth_t)dev; - switch(cmd) - { - case NIOCTL_GADDR: - /* get mac address */ - if(args) rt_memcpy(args, rndis_eth_dev->dev_addr, MAX_ADDR_LEN); - else return -RT_ERROR; - break; - - default : - break; - } - - return RT_EOK; -} - -/* ethernet device interface */ - - -/* reception packet. */ -struct pbuf *rt_rndis_eth_rx(rt_device_t dev) -{ - struct pbuf* p = RT_NULL; - rt_uint32_t offset = 0; - rt_rndis_eth_t device = (rt_rndis_eth_t)dev; - if(device->rx_flag == RT_FALSE) - { - return p; - } - - if(device->rx_length != 0) - { - /* allocate buffer */ - p = pbuf_alloc(PBUF_LINK, device->rx_length, PBUF_RAM); - if (p != RT_NULL) - { - struct pbuf* q; - - for (q = p; q != RT_NULL; q= q->next) - { - /* Copy the received frame into buffer from memory pointed by the current ETHERNET DMA Rx descriptor */ - rt_memcpy(q->payload, - (rt_uint8_t *)((device->rx_buffer) + offset), - q->len); - offset += q->len; - } - } - } - - { - device->rx_flag = RT_FALSE; - device->eps.ep_out->request.buffer = device->eps.ep_out->buffer; - device->eps.ep_out->request.size = EP_MAXPACKET(device->eps.ep_out); - device->eps.ep_out->request.req_type = UIO_REQUEST_READ_BEST; - rt_usbd_io_request(device->func->device, device->eps.ep_out, &device->eps.ep_out->request); - } - - return p; -} - -/* transmit packet. */ -rt_err_t rt_rndis_eth_tx(rt_device_t dev, struct pbuf* p) -{ - struct pbuf* q; - char * buffer; - rt_err_t result = RT_EOK; - rt_rndis_eth_t device = (rt_rndis_eth_t)dev; - - if(!device->parent.link_status) - { - LOG_I("linkdown, drop pkg"); - return RT_EOK; - } - - //RT_ASSERT(p->tot_len < sizeof(device->tx_buffer)); - if(p->tot_len > sizeof(device->tx_buffer)) - { - LOG_W("RNDIS MTU is:%d, but the send packet size is %d", - sizeof(device->tx_buffer), p->tot_len); - p->tot_len = sizeof(device->tx_buffer); - } - - /* wait for buffer free. */ - result = rt_sem_take(&device->tx_buffer_free, rt_tick_from_millisecond(1000)); - if(result != RT_EOK) - { - LOG_W("wait for buffer free timeout"); - /* if cost 1s to wait send done it said that connection is close . drop it */ - rt_sem_release(&device->tx_buffer_free); - return result; - } - - buffer = (char *)&device->tx_buffer + sizeof(struct rndis_packet_msg); - for (q = p; q != NULL; q = q->next) - { - rt_memcpy(buffer, q->payload, q->len); - buffer += q->len; - } - - /* send */ - { - rndis_packet_msg_t msg; - - msg = (rndis_packet_msg_t)&device->tx_buffer; - - msg->MessageType = REMOTE_NDIS_PACKET_MSG; - msg->DataOffset = sizeof(struct rndis_packet_msg) - 8; - msg->DataLength = p->tot_len; - msg->OOBDataLength = 0; - msg->OOBDataOffset = 0; - msg->NumOOBDataElements = 0; - msg->PerPacketInfoOffset = 0; - msg->PerPacketInfoLength = 0; - msg->VcHandle = 0; - msg->Reserved = 0; - msg->MessageLength = sizeof(struct rndis_packet_msg) + p->tot_len; - - if((msg->MessageLength & 0x3F) == 0) - { - /* pad a dummy. */ - msg->MessageLength += 1; - } - - device->eps.ep_in->request.buffer = (void *)&device->tx_buffer; - device->eps.ep_in->request.size = msg->MessageLength; - device->eps.ep_in->request.req_type = UIO_REQUEST_WRITE; - rt_usbd_io_request(device->func->device, device->eps.ep_in, &device->eps.ep_in->request); - } - - return result; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops rndis_device_ops = -{ - rt_rndis_eth_init, - rt_rndis_eth_open, - rt_rndis_eth_close, - rt_rndis_eth_read, - rt_rndis_eth_write, - rt_rndis_eth_control -}; -#endif - -#endif /* RT_USING_LWIP */ - -#ifdef RNDIS_DELAY_LINK_UP - -/** - * This function will set rndis connect status. - * - * @param device the usb device object. - * @param status the connect status. - * - * @return RT_EOK on successful. - */ -static rt_err_t _rndis_indicate_status_msg(ufunction_t func, rt_uint32_t status) -{ - rndis_indicate_status_msg_t resp; - struct rt_rndis_response * response; - - response = rt_malloc(sizeof(struct rt_rndis_response)); - resp = rt_malloc(sizeof(struct rndis_indicate_status_msg)); - - if( (response == RT_NULL) || (resp == RT_NULL) ) - { - LOG_E("%s,%d: no memory!", __func__, __LINE__); - - if(response != RT_NULL) - rt_free(response); - - if(resp != RT_NULL) - rt_free(resp); - - return -RT_ENOMEM; - } - - resp->MessageType = REMOTE_NDIS_INDICATE_STATUS_MSG; - resp->MessageLength = 20; /* sizeof(struct rndis_indicate_status_msg) */ - resp->Status = status; - resp->StatusBufferLength = 0; - resp->StatusBufferOffset = 0; - - response->buffer = resp; - { - rt_base_t level = rt_hw_interrupt_disable(); - rt_list_insert_before(&((rt_rndis_eth_t)func->user_data)->response_list, &response->list); - rt_hw_interrupt_enable(level); - } - - _rndis_response_available(func); - - return RT_EOK; -} - -/* the delay linkup timer handler. */ -static void timer_timeout(void* parameter) -{ - LOG_I("delay link up!"); - _rndis_indicate_status_msg(((rt_rndis_eth_t)parameter)->func, - RNDIS_STATUS_MEDIA_CONNECT); - eth_device_linkchange(&((rt_rndis_eth_t)parameter)->parent, RT_TRUE); -} -#endif /* RNDIS_DELAY_LINK_UP */ - -/** - * This function will create a cdc rndis class instance. - * - * @param device the usb device object. - * - * @return RT_EOK on successful. - */ -ufunction_t rt_usbd_function_rndis_create(udevice_t device) -{ - ufunction_t cdc; - rt_rndis_eth_t _rndis; - cdc_eps_t eps; - uintf_t intf_comm, intf_data; - ualtsetting_t comm_setting, data_setting; - ucdc_data_desc_t data_desc; - ucdc_comm_desc_t comm_desc; - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - - /* set usb device string description */ -#ifdef RT_USB_DEVICE_COMPOSITE - rt_usbd_device_set_interface_string(device, RNDIS_INTF_STR_INDEX, _ustring[2]); -#else - rt_usbd_device_set_string(device, _ustring); -#endif - /* create a cdc class */ - cdc = rt_usbd_function_new(device, &_dev_desc, &ops); - rt_usbd_device_set_qualifier(device, &dev_qualifier); - _rndis= rt_malloc(sizeof(struct rt_rndis_eth)); - - if(_rndis == RT_NULL) - { - LOG_E("%s,%d: no memory!", __func__, __LINE__); - return RT_NULL; - } - - rt_memset(_rndis, 0, sizeof(struct rt_rndis_eth)); - cdc->user_data = _rndis; - - _rndis->func = cdc; - /* create a cdc class endpoints collection */ - eps = &_rndis->eps; - /* create a cdc communication interface and a cdc data interface */ - intf_comm = rt_usbd_interface_new(device, _interface_handler); - intf_data = rt_usbd_interface_new(device, _interface_handler); - - if((intf_comm == RT_NULL) || (intf_data == RT_NULL)) - { - LOG_E("%s,%d: no memory!", __func__, __LINE__); - - if(intf_comm != RT_NULL) - rt_free(intf_comm); - - if(intf_data != RT_NULL) - rt_free(intf_data); - - return RT_NULL; - } - - /* create a communication alternate setting and a data alternate setting */ - comm_setting = rt_usbd_altsetting_new(sizeof(struct ucdc_comm_descriptor)); - data_setting = rt_usbd_altsetting_new(sizeof(struct ucdc_data_descriptor)); - - /* config desc in alternate setting */ - rt_usbd_altsetting_config_descriptor(comm_setting, &_comm_desc, - (rt_off_t)&((ucdc_comm_desc_t)0)->intf_desc); - rt_usbd_altsetting_config_descriptor(data_setting, &_data_desc, 0); - /* configure the cdc interface descriptor */ - _cdc_descriptor_config(comm_setting->desc, intf_comm->intf_num, data_setting->desc, intf_data->intf_num, device->dcd->device_is_hs); - - /* create a command endpoint */ - comm_desc = (ucdc_comm_desc_t)comm_setting->desc; - eps->ep_cmd = rt_usbd_endpoint_new(&comm_desc->ep_desc, _ep_cmd_handler); - /* add the command endpoint to the cdc communication interface */ - rt_usbd_altsetting_add_endpoint(comm_setting, eps->ep_cmd); - - /* add the communication alternate setting to the communication interface, - then set default setting of the interface */ - rt_usbd_interface_add_altsetting(intf_comm, comm_setting); - rt_usbd_set_altsetting(intf_comm, 0); - /* add the communication interface to the cdc class */ - rt_usbd_function_add_interface(cdc, intf_comm); - - /* create a bulk in and a bulk out endpoint */ - data_desc = (ucdc_data_desc_t)data_setting->desc; - eps->ep_out = rt_usbd_endpoint_new(&data_desc->ep_out_desc, _ep_out_handler); - eps->ep_in = rt_usbd_endpoint_new(&data_desc->ep_in_desc, _ep_in_handler); - - /* add the bulk out and bulk in endpoints to the data alternate setting */ - rt_usbd_altsetting_add_endpoint(data_setting, eps->ep_in); - rt_usbd_altsetting_add_endpoint(data_setting, eps->ep_out); - - /* add the data alternate setting to the data interface - then set default setting of the interface */ - rt_usbd_interface_add_altsetting(intf_data, data_setting); - rt_usbd_set_altsetting(intf_data, 0); - - /* add the cdc data interface to cdc class */ - rt_usbd_function_add_interface(cdc, intf_data); - - rt_usbd_os_comp_id_desc_add_os_func_comp_id_desc(device->os_comp_id_desc, &rndis_func_comp_id_desc); - - -#ifdef RT_USING_LWIP - - rt_list_init(&_rndis->response_list); - _rndis->need_notify = RT_TRUE; - - rt_sem_init(&_rndis->tx_buffer_free, "ue_tx", 1, RT_IPC_FLAG_FIFO); - -#ifdef RNDIS_DELAY_LINK_UP - rt_timer_init(&_rndis->timer, - "RNDIS", - timer_timeout, - _rndis, - RT_TICK_PER_SECOND * 2, - RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER); -#endif /* RNDIS_DELAY_LINK_UP */ - - /* OUI 00-00-00, only for test. */ - _rndis->dev_addr[0] = 0x34; - _rndis->dev_addr[1] = 0x97; - _rndis->dev_addr[2] = 0xF6; - /* generate random MAC. */ - _rndis->dev_addr[3] = 0x94;//*(const rt_uint8_t *)(0x1fff7a10); - _rndis->dev_addr[4] = 0xEA;//*(const rt_uint8_t *)(0x1fff7a14); - _rndis->dev_addr[5] = 0x12;//(const rt_uint8_t *)(0x1fff7a18); - /* OUI 00-00-00, only for test. */ - _rndis->host_addr[0] = 0x34; - _rndis->host_addr[1] = 0x97; - _rndis->host_addr[2] = 0xF6; - /* generate random MAC. */ - _rndis->host_addr[3] = 0x94;//*(const rt_uint8_t *)(0x0FE081F0); - _rndis->host_addr[4] = 0xEA;//*(const rt_uint8_t *)(0x0FE081F1); - _rndis->host_addr[5] = 0x13;//*(const rt_uint8_t *)(0x0FE081F2); - -#ifdef RT_USING_DEVICE_OPS - _rndis->parent.parent.ops = &rndis_device_ops; -#else - _rndis->parent.parent.init = rt_rndis_eth_init; - _rndis->parent.parent.open = rt_rndis_eth_open; - _rndis->parent.parent.close = rt_rndis_eth_close; - _rndis->parent.parent.read = rt_rndis_eth_read; - _rndis->parent.parent.write = rt_rndis_eth_write; - _rndis->parent.parent.control = rt_rndis_eth_control; -#endif - _rndis->parent.parent.user_data = device; - - _rndis->parent.eth_rx = rt_rndis_eth_rx; - _rndis->parent.eth_tx = rt_rndis_eth_tx; - - /* register eth device */ - eth_device_init(&((rt_rndis_eth_t)cdc->user_data)->parent, "u0"); - -#endif /* RT_USING_LWIP */ - - return cdc; -} - -struct udclass rndis_class = -{ - .rt_usbd_function_create = rt_usbd_function_rndis_create -}; - -int rt_usbd_rndis_class_register(void) -{ - rt_usbd_class_register(&rndis_class); - return 0; -} -INIT_PREV_EXPORT(rt_usbd_rndis_class_register); - -#endif /* RT_USB_DEVICE_RNDIS */ diff --git a/components/drivers/usb/usbdevice/class/rndis.h b/components/drivers/usb/usbdevice/class/rndis.h deleted file mode 100644 index c862b82c01..0000000000 --- a/components/drivers/usb/usbdevice/class/rndis.h +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-12-24 heyuanjie87 first version - */ - -#ifndef __RNDIS_H__ -#define __RNDIS_H__ - -#include <rtthread.h> - -#define USB_ETH_MTU 1500+14 -#define RNDIS_MESSAGE_BUFFER_SIZE 128 - -#define RESPONSE_AVAILABLE 0x00000001 - -/* Remote NDIS version numbers */ -#define RNDIS_MAJOR_VERSION 1 -#define RNDIS_MINOR_VERSION 0 - -/* common status values */ -#define RNDIS_STATUS_SUCCESS 0X00000000 -#define RNDIS_STATUS_FAILURE 0XC0000001 -#define RNDIS_STATUS_INVALID_DATA 0XC0010015 -#define RNDIS_STATUS_NOT_SUPPORTED 0XC00000BB -#define RNDIS_STATUS_MEDIA_CONNECT 0X4001000B -#define RNDIS_STATUS_MEDIA_DISCONNECT 0X4001000C - -/* Remote NDIS message types */ -#define REMOTE_NDIS_PACKET_MSG 0x00000001 -#define REMOTE_NDIS_INITIALIZE_MSG 0X00000002 -#define REMOTE_NDIS_HALT_MSG 0X00000003 -#define REMOTE_NDIS_QUERY_MSG 0X00000004 -#define REMOTE_NDIS_SET_MSG 0X00000005 -#define REMOTE_NDIS_RESET_MSG 0X00000006 -#define REMOTE_NDIS_INDICATE_STATUS_MSG 0X00000007 -#define REMOTE_NDIS_KEEPALIVE_MSG 0X00000008 -#define REMOTE_NDIS_INITIALIZE_CMPLT 0X80000002 -#define REMOTE_NDIS_QUERY_CMPLT 0X80000004 -#define REMOTE_NDIS_SET_CMPLT 0X80000005 -#define REMOTE_NDIS_RESET_CMPLT 0X80000006 -#define REMOTE_NDIS_KEEPALIVE_CMPLT 0X80000008 - -/* device flags */ -#define RNDIS_DF_CONNECTIONLESS 0x00000001 -#define RNDIS_DF_CONNECTION_ORIENTED 0x00000002 -/* mediums */ -#define RNDIS_MEDIUM_802_3 0x00000000 - -struct ucls_rndis -{ - uep_t notify; - rt_uint32_t filter; - rt_bool_t header; - rt_uint8_t rndis_state; - rt_uint8_t media_state; - rt_uint8_t ethaddr[6]; -}; - -/* Remote NDIS generic message type */ -struct rndis_gen_msg -{ - rt_uint32_t MessageType; - rt_uint32_t MessageLength; -}; -typedef struct rndis_gen_msg* rndis_gen_msg_t; - -struct rndis_packet_msg -{ - rt_uint32_t MessageType; - rt_uint32_t MessageLength; - rt_uint32_t DataOffset; - rt_uint32_t DataLength; - rt_uint32_t OOBDataOffset; - rt_uint32_t OOBDataLength; - rt_uint32_t NumOOBDataElements; - rt_uint32_t PerPacketInfoOffset; - rt_uint32_t PerPacketInfoLength; - rt_uint32_t VcHandle; - rt_uint32_t Reserved; -}; -typedef struct rndis_packet_msg* rndis_packet_msg_t; - -/* Remote NDIS Initialize Message */ -struct rndis_init_msg -{ - rt_uint32_t MessageType; - rt_uint32_t MessageLength; - rt_uint32_t RequestId; - rt_uint32_t MajorVersion; - rt_uint32_t MinorVersion; - rt_uint32_t MaxTransferSize; -}; -typedef struct rndis_init_msg* rndis_init_msg_t; - -/* Response */ -struct rndis_init_cmplt -{ - rt_uint32_t MessageType; - rt_uint32_t MessageLength; - rt_uint32_t RequestId; - rt_uint32_t Status; - rt_uint32_t MajorVersion; - rt_uint32_t MinorVersion; - rt_uint32_t DeviceFlags; - rt_uint32_t Medium; - rt_uint32_t MaxPacketsPerTransfer; - rt_uint32_t MaxTransferSize; - rt_uint32_t PacketAlignmentFactor; - rt_uint32_t AfListOffset; - rt_uint32_t AfListSize; -}; -typedef struct rndis_init_cmplt* rndis_init_cmplt_t; - -/* Remote NDIS Halt Message */ -struct rndis_halt_msg -{ - rt_uint32_t MessageType; - rt_uint32_t MessageLength; - rt_uint32_t RequestId; -}; - -/* Remote NDIS Query Message */ -struct rndis_query_msg -{ - rt_uint32_t MessageType; - rt_uint32_t MessageLength; - rt_uint32_t RequestId; - rt_uint32_t Oid; - rt_uint32_t InformationBufferLength; - rt_uint32_t InformationBufferOffset; - rt_uint32_t DeviceVcHandle; -}; -typedef struct rndis_query_msg* rndis_query_msg_t; - -/* Response */ -struct rndis_query_cmplt -{ - rt_uint32_t MessageType; - rt_uint32_t MessageLength; - rt_uint32_t RequestId; - rt_uint32_t Status; - rt_uint32_t InformationBufferLength; - rt_uint32_t InformationBufferOffset; -}; -typedef struct rndis_query_cmplt* rndis_query_cmplt_t; - -/* Remote NDIS Set Message */ -struct rndis_set_msg -{ - rt_uint32_t MessageType; - rt_uint32_t MessageLength; - rt_uint32_t RequestId; - rt_uint32_t Oid; - rt_uint32_t InformationBufferLength; - rt_uint32_t InformationBufferOffset; - rt_uint32_t DeviceVcHandle; -}; -typedef struct rndis_set_msg* rndis_set_msg_t; - -/* Response */ -struct rndis_set_cmplt -{ - rt_uint32_t MessageType; - rt_uint32_t MessageLength; - rt_uint32_t RequestId; - rt_uint32_t Status; -}; -typedef struct rndis_set_cmplt* rndis_set_cmplt_t; - -/* Remote NDIS Soft Reset Message */ -struct rndis_reset_msg -{ - rt_uint32_t MessageType; - rt_uint32_t MessageLength; - rt_uint32_t Reserved; -}; - -/* Remote NDIS Soft Reset Response */ -struct rndis_reset_cmplt -{ - rt_uint32_t MessageType; - rt_uint32_t MessageLength; - rt_uint32_t Status; - rt_uint32_t AddressingReset; -}; - -/* Remote NDIS Indicate Status Message */ -struct rndis_indicate_status_msg -{ - rt_uint32_t MessageType; - rt_uint32_t MessageLength; - rt_uint32_t Status; - rt_uint32_t StatusBufferLength; - rt_uint32_t StatusBufferOffset; -}; -typedef struct rndis_indicate_status_msg* rndis_indicate_status_msg_t; - -struct rndis_keepalive_msg -{ - rt_uint32_t MessageType; - rt_uint32_t MessageLength; - rt_uint32_t RequestID; -}; -typedef struct rndis_keepalive_msg* rndis_keepalive_msg_t; - -/* Response: */ -struct rndis_keepalive_cmplt -{ - rt_uint32_t MessageType; - rt_uint32_t MessageLength; - rt_uint32_t RequestId; - rt_uint32_t Status; -}; -typedef struct rndis_keepalive_cmplt* rndis_keepalive_cmplt_t; - - - - - - - -#endif diff --git a/components/drivers/usb/usbdevice/class/uaudioreg.h b/components/drivers/usb/usbdevice/class/uaudioreg.h deleted file mode 100644 index eea3c2f053..0000000000 --- a/components/drivers/usb/usbdevice/class/uaudioreg.h +++ /dev/null @@ -1,419 +0,0 @@ -/* $NetBSD: uaudioreg.h,v 1.15.38.1 2012/06/02 11:09:29 mrg Exp $ */ - -/* - * Copyright (c) 1999 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson ([email protected]) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <rtdef.h> -#include <stdint.h> - -typedef uint8_t uByte; -typedef uint16_t uWord; - -#define UPACKED __attribute__ ((packed)) - -#define UAUDIO_VERSION 0x100 - -#define USB_SUBCLASS_AUDIOCONTROL 1 -#define USB_SUBCLASS_AUDIOSTREAMING 2 -#define USB_SUBCLASS_AUDIOMIDISTREAM 3 - -#define UDESC_CS_CONFIG 0x22 -#define UDESC_CS_STRING 0x23 -#define UDESC_CS_INTERFACE 0x24 -#define UDESC_CS_ENDPOINT 0x25 - -#define UDESCSUB_AC_HEADER 1 -#define UDESCSUB_AC_INPUT 2 -#define UDESCSUB_AC_OUTPUT 3 -#define UDESCSUB_AC_MIXER 4 -#define UDESCSUB_AC_SELECTOR 5 -#define UDESCSUB_AC_FEATURE 6 -#define UDESCSUB_AC_PROCESSING 7 -#define UDESCSUB_AC_EXTENSION 8 - -#ifndef AUFMT_MAX_FREQUENCIES -#define AUFMT_MAX_FREQUENCIES 1 -#endif - -/* The first fields are identical to usb_endpoint_descriptor_t */ -typedef struct { - uByte bLength; - uByte bDescriptorType; - uByte bEndpointAddress; - uByte bmAttributes; - uWord wMaxPacketSize; - uByte bInterval; - /* - * The following two entries are only used by the Audio Class. - * And according to the specs the Audio Class is the only one - * allowed to extend the endpoint descriptor. - * Who knows what goes on in the minds of the people in the USB - * standardization? :-( - */ - uByte bRefresh; - uByte bSynchAddress; -} UPACKED usb_endpoint_descriptor_audio_t; - -/* generic, for iteration */ -typedef struct { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; -} UPACKED uaudio_cs_descriptor_t; - -struct usb_audio_control_descriptor { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; - uWord bcdADC; - uWord wTotalLength; - uByte bInCollection; - uByte baInterfaceNr[1]; -} UPACKED; - -struct usb_audio_streaming_interface_descriptor { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; - uByte bTerminalLink; - uByte bDelay; - uWord wFormatTag; -} UPACKED; - -struct usb_audio_streaming_endpoint_descriptor { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; - uByte bmAttributes; -#define UA_SED_FREQ_CONTROL 0x01 -#define UA_SED_PITCH_CONTROL 0x02 -#define UA_SED_MAXPACKETSONLY 0x80 - uByte bLockDelayUnits; - uWord wLockDelay; -} UPACKED; - -struct usb_audio_streaming_type1_descriptor { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; - uByte bFormatType; - uByte bNrChannels; - uByte bSubFrameSize; - uByte bBitResolution; - uByte bSamFreqType; -#define UA_SAMP_CONTNUOUS 0 - uByte tSamFreq[3*AUFMT_MAX_FREQUENCIES]; -#define UA_GETSAMP(p, n) ((p)->tSamFreq[(n)*3+0] | ((p)->tSamFreq[(n)*3+1] << 8) | ((p)->tSamFreq[(n)*3+2] << 16)) -#define UA_SAMP_LO(p) UA_GETSAMP(p, 0) -#define UA_SAMP_HI(p) UA_GETSAMP(p, 1) -} UPACKED; - -struct usb_audio_cluster { - uByte bNrChannels; - uWord wChannelConfig; -#define UA_CHANNEL_LEFT 0x0001 -#define UA_CHANNEL_RIGHT 0x0002 -#define UA_CHANNEL_CENTER 0x0004 -#define UA_CHANNEL_LFE 0x0008 -#define UA_CHANNEL_L_SURROUND 0x0010 -#define UA_CHANNEL_R_SURROUND 0x0020 -#define UA_CHANNEL_L_CENTER 0x0040 -#define UA_CHANNEL_R_CENTER 0x0080 -#define UA_CHANNEL_SURROUND 0x0100 -#define UA_CHANNEL_L_SIDE 0x0200 -#define UA_CHANNEL_R_SIDE 0x0400 -#define UA_CHANNEL_TOP 0x0800 - uByte iChannelNames; -} UPACKED; - -/* Shared by all units and terminals */ -struct usb_audio_unit { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; - uByte bUnitId; -}; - -/* UDESCSUB_AC_INPUT */ -struct usb_audio_input_terminal { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; - uByte bTerminalId; - uWord wTerminalType; - uByte bAssocTerminal; - uByte bNrChannels; - uWord wChannelConfig; - uByte iChannelNames; - uByte iTerminal; -} UPACKED; - -/* UDESCSUB_AC_OUTPUT */ -struct usb_audio_output_terminal { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; - uByte bTerminalId; - uWord wTerminalType; - uByte bAssocTerminal; - uByte bSourceId; - uByte iTerminal; -} UPACKED; - -/* UDESCSUB_AC_MIXER */ -struct usb_audio_mixer_unit { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; - uByte bUnitId; - uByte bNrInPins; - uByte baSourceId[255]; /* [bNrInPins] */ - /* struct usb_audio_mixer_unit_1 */ -} UPACKED; -struct usb_audio_mixer_unit_1 { - uByte bNrChannels; - uWord wChannelConfig; - uByte iChannelNames; - uByte bmControls[255]; /* [bNrChannels] */ - /*uByte iMixer;*/ -} UPACKED; - -/* UDESCSUB_AC_SELECTOR */ -struct usb_audio_selector_unit { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; - uByte bUnitId; - uByte bNrInPins; - uByte baSourceId[255]; /* [bNrInPins] */ - /* uByte iSelector; */ -} UPACKED; - -/* UDESCSUB_AC_FEATURE */ -struct usb_audio_feature_unit { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; - uByte bUnitId; - uByte bSourceId; - uByte bControlSize; - uByte bmaControls[2]; /* size for more than enough */ - /* uByte iFeature; */ -} UPACKED; - -/* UDESCSUB_AC_PROCESSING */ -struct usb_audio_processing_unit { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; - uByte bUnitId; - uWord wProcessType; - uByte bNrInPins; - uByte baSourceId[255]; /* [bNrInPins] */ - /* struct usb_audio_processing_unit_1 */ -} UPACKED; -struct usb_audio_processing_unit_1{ - uByte bNrChannels; - uWord wChannelConfig; - uByte iChannelNames; - uByte bControlSize; - uByte bmControls[255]; /* [bControlSize] */ -#define UA_PROC_ENABLE_MASK 1 -} UPACKED; - -struct usb_audio_processing_unit_updown { - uByte iProcessing; - uByte bNrModes; - uWord waModes[255]; /* [bNrModes] */ -} UPACKED; - -/* UDESCSUB_AC_EXTENSION */ -struct usb_audio_extension_unit { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; - uByte bUnitId; - uWord wExtensionCode; - uByte bNrInPins; - uByte baSourceId[255]; /* [bNrInPins] */ - /* struct usb_audio_extension_unit_1 */ -} UPACKED; -struct usb_audio_extension_unit_1 { - uByte bNrChannels; - uWord wChannelConfig; - uByte iChannelNames; - uByte bControlSize; - uByte bmControls[255]; /* [bControlSize] */ -#define UA_EXT_ENABLE_MASK 1 -#define UA_EXT_ENABLE 1 - /*uByte iExtension;*/ -} UPACKED; - -/* USB terminal types */ -#define UAT_UNDEFINED 0x0100 -#define UAT_STREAM 0x0101 -#define UAT_VENDOR 0x01ff -/* input terminal types */ -#define UATI_UNDEFINED 0x0200 -#define UATI_MICROPHONE 0x0201 -#define UATI_DESKMICROPHONE 0x0202 -#define UATI_PERSONALMICROPHONE 0x0203 -#define UATI_OMNIMICROPHONE 0x0204 -#define UATI_MICROPHONEARRAY 0x0205 -#define UATI_PROCMICROPHONEARR 0x0206 -/* output terminal types */ -#define UATO_UNDEFINED 0x0300 -#define UATO_SPEAKER 0x0301 -#define UATO_HEADPHONES 0x0302 -#define UATO_DISPLAYAUDIO 0x0303 -#define UATO_DESKTOPSPEAKER 0x0304 -#define UATO_ROOMSPEAKER 0x0305 -#define UATO_COMMSPEAKER 0x0306 -#define UATO_SUBWOOFER 0x0307 -/* bidir terminal types */ -#define UATB_UNDEFINED 0x0400 -#define UATB_HANDSET 0x0401 -#define UATB_HEADSET 0x0402 -#define UATB_SPEAKERPHONE 0x0403 -#define UATB_SPEAKERPHONEESUP 0x0404 -#define UATB_SPEAKERPHONEECANC 0x0405 -/* telephony terminal types */ -#define UATT_UNDEFINED 0x0500 -#define UATT_PHONELINE 0x0501 -#define UATT_TELEPHONE 0x0502 -#define UATT_DOWNLINEPHONE 0x0503 -/* external terminal types */ -#define UATE_UNDEFINED 0x0600 -#define UATE_ANALOGCONN 0x0601 -#define UATE_DIGITALAUIFC 0x0602 -#define UATE_LINECONN 0x0603 -#define UATE_LEGACYCONN 0x0604 -#define UATE_SPDIF 0x0605 -#define UATE_1394DA 0x0606 -#define UATE_1394DV 0x0607 -/* embedded function terminal types */ -#define UATF_UNDEFINED 0x0700 -#define UATF_CALIBNOISE 0x0701 -#define UATF_EQUNOISE 0x0702 -#define UATF_CDPLAYER 0x0703 -#define UATF_DAT 0x0704 -#define UATF_DCC 0x0705 -#define UATF_MINIDISK 0x0706 -#define UATF_ANALOGTAPE 0x0707 -#define UATF_PHONOGRAPH 0x0708 -#define UATF_VCRAUDIO 0x0709 -#define UATF_VIDEODISCAUDIO 0x070a -#define UATF_DVDAUDIO 0x070b -#define UATF_TVTUNERAUDIO 0x070c -#define UATF_SATELLITE 0x070d -#define UATF_CABLETUNER 0x070e -#define UATF_DSS 0x070f -#define UATF_RADIORECV 0x0710 -#define UATF_RADIOXMIT 0x0711 -#define UATF_MULTITRACK 0x0712 -#define UATF_SYNTHESIZER 0x0713 - - -#define SET_CUR 0x01 -#define GET_CUR 0x81 -#define SET_MIN 0x02 -#define GET_MIN 0x82 -#define SET_MAX 0x03 -#define GET_MAX 0x83 -#define SET_RES 0x04 -#define GET_RES 0x84 -#define SET_MEM 0x05 -#define GET_MEM 0x85 -#define GET_STAT 0xff - -#define MUTE_CONTROL 0x01 -#define VOLUME_CONTROL 0x02 -#define BASS_CONTROL 0x03 -#define MID_CONTROL 0x04 -#define TREBLE_CONTROL 0x05 -#define GRAPHIC_EQUALIZER_CONTROL 0x06 -#define AGC_CONTROL 0x07 -#define DELAY_CONTROL 0x08 -#define BASS_BOOST_CONTROL 0x09 -#define LOUDNESS_CONTROL 0x0a - -#define FU_MASK(u) (1 << ((u)-1)) - -#define MASTER_CHAN 0 - -#define AS_GENERAL 1 -#define FORMAT_TYPE 2 -#define FORMAT_SPECIFIC 3 - -#define UA_FMT_PCM 1 -#define UA_FMT_PCM8 2 -#define UA_FMT_IEEE_FLOAT 3 -#define UA_FMT_ALAW 4 -#define UA_FMT_MULAW 5 -#define UA_FMT_MPEG 0x1001 -#define UA_FMT_AC3 0x1002 - -#define SAMPLING_FREQ_CONTROL 0x01 -#define PITCH_CONTROL 0x02 - -#define FORMAT_TYPE_UNDEFINED 0 -#define FORMAT_TYPE_I 1 -#define FORMAT_TYPE_II 2 -#define FORMAT_TYPE_III 3 - -#define UA_PROC_MASK(n) (1<< ((n)-1)) -#define PROCESS_UNDEFINED 0 -#define XX_ENABLE_CONTROL 1 -#define UPDOWNMIX_PROCESS 1 -#define UD_ENABLE_CONTROL 1 -#define UD_MODE_SELECT_CONTROL 2 -#define DOLBY_PROLOGIC_PROCESS 2 -#define DP_ENABLE_CONTROL 1 -#define DP_MODE_SELECT_CONTROL 2 -#define P3D_STEREO_EXTENDER_PROCESS 3 -#define P3D_ENABLE_CONTROL 1 -#define P3D_SPACIOUSNESS_CONTROL 2 -#define REVERBATION_PROCESS 4 -#define RV_ENABLE_CONTROL 1 -#define RV_LEVEL_CONTROL 2 -#define RV_TIME_CONTROL 3 -#define RV_FEEDBACK_CONTROL 4 -#define CHORUS_PROCESS 5 -#define CH_ENABLE_CONTROL 1 -#define CH_LEVEL_CONTROL 2 -#define CH_RATE_CONTROL 3 -#define CH_DEPTH_CONTROL 4 -#define DYN_RANGE_COMP_PROCESS 6 -#define DR_ENABLE_CONTROL 1 -#define DR_COMPRESSION_RATE_CONTROL 2 -#define DR_MAXAMPL_CONTROL 3 -#define DR_THRESHOLD_CONTROL 4 -#define DR_ATTACK_TIME_CONTROL 5 -#define DR_RELEASE_TIME_CONTROL 6 diff --git a/components/drivers/usb/usbdevice/class/winusb.c b/components/drivers/usb/usbdevice/class/winusb.c deleted file mode 100644 index f39dab9f06..0000000000 --- a/components/drivers/usb/usbdevice/class/winusb.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2017-11-16 ZYH first version - */ -#include <rthw.h> -#include <rtdevice.h> -#include <drivers/usb_device.h> -#include "winusb.h" -struct winusb_device -{ - struct rt_device parent; - void (*cmd_handler)(rt_uint8_t *buffer,rt_size_t size); - rt_uint8_t cmd_buff[256]; - uep_t ep_out; - uep_t ep_in; -}; -#define WINUSB_INTF_STR_INDEX 13 -typedef struct winusb_device * winusb_device_t; - -rt_align(4) -static struct udevice_descriptor dev_desc = -{ - USB_DESC_LENGTH_DEVICE, //bLength; - USB_DESC_TYPE_DEVICE, //type; - USB_BCD_VERSION, //bcdUSB; - 0x00, //bDeviceClass; - 0x00, //bDeviceSubClass; - 0x00, //bDeviceProtocol; - 0x40, //bMaxPacketSize0; - _VENDOR_ID, //idVendor; - _PRODUCT_ID, //idProduct; - USB_BCD_DEVICE, //bcdDevice; - USB_STRING_MANU_INDEX, //iManufacturer; - USB_STRING_PRODUCT_INDEX, //iProduct; - USB_STRING_SERIAL_INDEX, //iSerialNumber; - USB_DYNAMIC, //bNumConfigurations; -}; - -//FS and HS needed -rt_align(4) -static struct usb_qualifier_descriptor dev_qualifier = -{ - sizeof(dev_qualifier), //bLength - USB_DESC_TYPE_DEVICEQUALIFIER, //bDescriptorType - 0x0200, //bcdUSB - 0xFF, //bDeviceClass - 0x00, //bDeviceSubClass - 0x00, //bDeviceProtocol - 64, //bMaxPacketSize0 - 0x01, //bNumConfigurations - 0, -}; - -rt_align(4) -struct winusb_descriptor _winusb_desc = -{ -#ifdef RT_USB_DEVICE_COMPOSITE - /* Interface Association Descriptor */ - { - USB_DESC_LENGTH_IAD, - USB_DESC_TYPE_IAD, - USB_DYNAMIC, - 0x01, - 0xFF, - 0x00, - 0x00, - 0x00, - }, -#endif - /*interface descriptor*/ - { - USB_DESC_LENGTH_INTERFACE, //bLength; - USB_DESC_TYPE_INTERFACE, //type; - USB_DYNAMIC, //bInterfaceNumber; - 0x00, //bAlternateSetting; - 0x02, //bNumEndpoints - 0xFF, //bInterfaceClass; - 0x00, //bInterfaceSubClass; - 0x00, //bInterfaceProtocol; -#ifdef RT_USB_DEVICE_COMPOSITE - WINUSB_INTF_STR_INDEX, -#else - 0x00, //iInterface; -#endif - }, - /*endpoint descriptor*/ - { - USB_DESC_LENGTH_ENDPOINT, - USB_DESC_TYPE_ENDPOINT, - USB_DYNAMIC | USB_DIR_OUT, - USB_EP_ATTR_BULK, - USB_DYNAMIC, - 0x00, - }, - /*endpoint descriptor*/ - { - USB_DESC_LENGTH_ENDPOINT, - USB_DESC_TYPE_ENDPOINT, - USB_DYNAMIC | USB_DIR_IN, - USB_EP_ATTR_BULK, - USB_DYNAMIC, - 0x00, - }, -}; - -rt_align(4) -const static char* _ustring[] = -{ - "Language", - "RT-Thread Team.", - "RTT Win USB", - "32021919830108", - "Configuration", - "Interface", - USB_STRING_OS//must be -}; - -rt_align(4) -struct usb_os_proerty winusb_proerty[] = -{ - USB_OS_PROPERTY_DESC(USB_OS_PROPERTY_TYPE_REG_SZ,"DeviceInterfaceGUID",RT_WINUSB_GUID), -}; - -rt_align(4) -struct usb_os_function_comp_id_descriptor winusb_func_comp_id_desc = -{ - .bFirstInterfaceNumber = USB_DYNAMIC, - .reserved1 = 0x01, - .compatibleID = {'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00}, - .subCompatibleID = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - .reserved2 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} -}; - -static rt_err_t _ep_out_handler(ufunction_t func, rt_size_t size) -{ - winusb_device_t winusb_device = (winusb_device_t)func->user_data; - if(winusb_device->parent.rx_indicate != RT_NULL) - { - winusb_device->parent.rx_indicate(&winusb_device->parent, size); - } - return RT_EOK; -} - -static rt_err_t _ep_in_handler(ufunction_t func, rt_size_t size) -{ - winusb_device_t winusb_device = (winusb_device_t)func->user_data; - if(winusb_device->parent.tx_complete != RT_NULL) - { - winusb_device->parent.tx_complete(&winusb_device->parent, winusb_device->ep_in->buffer); - } - return RT_EOK; -} -static ufunction_t cmd_func = RT_NULL; -static rt_err_t _ep0_cmd_handler(udevice_t device, rt_size_t size) -{ - winusb_device_t winusb_device; - - if(cmd_func != RT_NULL) - { - winusb_device = (winusb_device_t)cmd_func->user_data; - cmd_func = RT_NULL; - if(winusb_device->cmd_handler != RT_NULL) - { - winusb_device->cmd_handler(winusb_device->cmd_buff,size); - } - } - dcd_ep0_send_status(device->dcd); - return RT_EOK; -} -static rt_err_t _ep0_cmd_read(ufunction_t func, ureq_t setup) -{ - winusb_device_t winusb_device = (winusb_device_t)func->user_data; - cmd_func = func; - rt_usbd_ep0_read(func->device,winusb_device->cmd_buff,setup->wLength,_ep0_cmd_handler); - return RT_EOK; -} -static rt_err_t _interface_handler(ufunction_t func, ureq_t setup) -{ - switch(setup->bRequest) - { - case 'A': - switch(setup->wIndex) - { - case 0x05: - usbd_os_proerty_descriptor_send(func,setup,winusb_proerty,sizeof(winusb_proerty)/sizeof(winusb_proerty[0])); - break; - } - break; - case 0x0A://customer - _ep0_cmd_read(func, setup); - break; - } - - return RT_EOK; -} -static rt_err_t _function_enable(ufunction_t func) -{ - RT_ASSERT(func != RT_NULL); - return RT_EOK; -} -static rt_err_t _function_disable(ufunction_t func) -{ - RT_ASSERT(func != RT_NULL); - return RT_EOK; -} - -static struct ufunction_ops ops = -{ - _function_enable, - _function_disable, - RT_NULL, -}; - -static rt_err_t _winusb_descriptor_config(winusb_desc_t winusb, rt_uint8_t cintf_nr, rt_uint8_t device_is_hs) -{ -#ifdef RT_USB_DEVICE_COMPOSITE - winusb->iad_desc.bFirstInterface = cintf_nr; -#endif - winusb->ep_out_desc.wMaxPacketSize = device_is_hs ? 512 : 64; - winusb->ep_in_desc.wMaxPacketSize = device_is_hs ? 512 : 64; - winusb_func_comp_id_desc.bFirstInterfaceNumber = cintf_nr; - return RT_EOK; -} - -static rt_ssize_t win_usb_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) -{ - if(((ufunction_t)dev->user_data)->device->state != USB_STATE_CONFIGURED) - { - return 0; - } - winusb_device_t winusb_device = (winusb_device_t)dev; - winusb_device->ep_out->buffer = buffer; - winusb_device->ep_out->request.buffer = buffer; - winusb_device->ep_out->request.size = size; - winusb_device->ep_out->request.req_type = UIO_REQUEST_READ_FULL; - rt_usbd_io_request(((ufunction_t)dev->user_data)->device,winusb_device->ep_out,&winusb_device->ep_out->request); - return size; -} -static rt_ssize_t win_usb_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) -{ - if(((ufunction_t)dev->user_data)->device->state != USB_STATE_CONFIGURED) - { - return 0; - } - winusb_device_t winusb_device = (winusb_device_t)dev; - winusb_device->ep_in->buffer = (void *)buffer; - winusb_device->ep_in->request.buffer = winusb_device->ep_in->buffer; - winusb_device->ep_in->request.size = size; - winusb_device->ep_in->request.req_type = UIO_REQUEST_WRITE; - rt_usbd_io_request(((ufunction_t)dev->user_data)->device,winusb_device->ep_in,&winusb_device->ep_in->request); - return size; -} -static rt_err_t win_usb_control(rt_device_t dev, int cmd, void *args) -{ - winusb_device_t winusb_device = (winusb_device_t)dev; - if(RT_DEVICE_CTRL_CONFIG == cmd) - { - winusb_device->cmd_handler = (void(*)(rt_uint8_t*,rt_size_t))args; - } - return RT_EOK; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops winusb_device_ops = -{ - RT_NULL, - RT_NULL, - RT_NULL, - win_usb_read, - win_usb_write, - win_usb_control, -}; -#endif - -static rt_err_t rt_usb_winusb_init(ufunction_t func) -{ - winusb_device_t winusb_device = (winusb_device_t)func->user_data; - winusb_device->parent.type = RT_Device_Class_Miscellaneous; - -#ifdef RT_USING_DEVICE_OPS - winusb_device->parent.ops = &winusb_device_ops; -#else - winusb_device->parent.init = RT_NULL; - winusb_device->parent.open = RT_NULL; - winusb_device->parent.close = RT_NULL; - winusb_device->parent.read = win_usb_read; - winusb_device->parent.write = win_usb_write; - winusb_device->parent.control = win_usb_control; -#endif - - winusb_device->parent.user_data = func; - - - return rt_device_register(&winusb_device->parent, "winusb", RT_DEVICE_FLAG_RDWR); -} - -ufunction_t rt_usbd_function_winusb_create(udevice_t device) -{ - ufunction_t func; - winusb_device_t winusb_device; - - uintf_t winusb_intf; - ualtsetting_t winusb_setting; - winusb_desc_t winusb_desc; - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - - /* set usb device string description */ -#ifdef RT_USB_DEVICE_COMPOSITE - rt_usbd_device_set_interface_string(device, WINUSB_INTF_STR_INDEX, _ustring[2]); -#else - rt_usbd_device_set_string(device, _ustring); -#endif - - /* create a cdc function */ - func = rt_usbd_function_new(device, &dev_desc, &ops); - rt_usbd_device_set_qualifier(device, &dev_qualifier); - - /* allocate memory for cdc vcom data */ - winusb_device = (winusb_device_t)rt_malloc(sizeof(struct winusb_device)); - if (winusb_device == NULL) - return RT_NULL; - rt_memset((void *)winusb_device, 0, sizeof(struct winusb_device)); - func->user_data = (void*)winusb_device; - /* create an interface object */ - winusb_intf = rt_usbd_interface_new(device, _interface_handler); - - /* create an alternate setting object */ - winusb_setting = rt_usbd_altsetting_new(sizeof(struct winusb_descriptor)); - - /* config desc in alternate setting */ - rt_usbd_altsetting_config_descriptor(winusb_setting, &_winusb_desc, (rt_off_t)&((winusb_desc_t)0)->intf_desc); - - /* configure the hid interface descriptor */ - _winusb_descriptor_config(winusb_setting->desc, winusb_intf->intf_num, device->dcd->device_is_hs); - - /* create endpoint */ - winusb_desc = (winusb_desc_t)winusb_setting->desc; - winusb_device->ep_out = rt_usbd_endpoint_new(&winusb_desc->ep_out_desc, _ep_out_handler); - winusb_device->ep_in = rt_usbd_endpoint_new(&winusb_desc->ep_in_desc, _ep_in_handler); - - /* add the int out and int in endpoint to the alternate setting */ - rt_usbd_altsetting_add_endpoint(winusb_setting, winusb_device->ep_out); - rt_usbd_altsetting_add_endpoint(winusb_setting, winusb_device->ep_in); - - /* add the alternate setting to the interface, then set default setting */ - rt_usbd_interface_add_altsetting(winusb_intf, winusb_setting); - rt_usbd_set_altsetting(winusb_intf, 0); - - /* add the interface to the mass storage function */ - rt_usbd_function_add_interface(func, winusb_intf); - - rt_usbd_os_comp_id_desc_add_os_func_comp_id_desc(device->os_comp_id_desc, &winusb_func_comp_id_desc); - /* initilize winusb */ - rt_usb_winusb_init(func); - return func; -} - -struct udclass winusb_class = -{ - .rt_usbd_function_create = rt_usbd_function_winusb_create -}; - -int rt_usbd_winusb_class_register(void) -{ - rt_usbd_class_register(&winusb_class); - return 0; -} -INIT_PREV_EXPORT(rt_usbd_winusb_class_register); diff --git a/components/drivers/usb/usbdevice/class/winusb.h b/components/drivers/usb/usbdevice/class/winusb.h deleted file mode 100644 index 06325a0b03..0000000000 --- a/components/drivers/usb/usbdevice/class/winusb.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2017-11-16 ZYH first version - */ -#ifndef __WINUSB_H__ -#define __WINUSB_H__ -#include <rtthread.h> -struct winusb_descriptor -{ -#ifdef RT_USB_DEVICE_COMPOSITE - struct uiad_descriptor iad_desc; -#endif - struct uinterface_descriptor intf_desc; - struct uendpoint_descriptor ep_out_desc; - struct uendpoint_descriptor ep_in_desc; -}; -typedef struct winusb_descriptor* winusb_desc_t; - -#endif diff --git a/components/drivers/usb/usbdevice/core/usbdevice.c b/components/drivers/usb/usbdevice/core/usbdevice.c deleted file mode 100644 index eaa80217c8..0000000000 --- a/components/drivers/usb/usbdevice/core/usbdevice.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * File : hid.c - * COPYRIGHT (C) 2006 - 2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-10-02 Yi Qiu first version - */ - -#include <rtthread.h> -#include <rtdevice.h> -#include <rtservice.h> - -#ifdef RT_USING_USB_DEVICE - -#define USB_DEVICE_CONTROLLER_NAME "usbd" - -#ifdef RT_USB_DEVICE_COMPOSITE -const static char* ustring[] = -{ - "Language", - "RT-Thread Team.", - "RTT Composite Device", - "320219198301", - "Configuration", - "Interface", - USB_STRING_OS -}; - -static struct udevice_descriptor compsit_desc = -{ - USB_DESC_LENGTH_DEVICE, //bLength; - USB_DESC_TYPE_DEVICE, //type; - USB_BCD_VERSION, //bcdUSB; - USB_CLASS_MISC, //bDeviceClass; - 0x02, //bDeviceSubClass; - 0x01, //bDeviceProtocol; - 0x40, //bMaxPacketSize0; - _VENDOR_ID, //idVendor; - _PRODUCT_ID, //idProduct; - USB_BCD_DEVICE, //bcdDevice; - USB_STRING_MANU_INDEX, //iManufacturer; - USB_STRING_PRODUCT_INDEX, //iProduct; - USB_STRING_SERIAL_INDEX, //iSerialNumber; - USB_DYNAMIC, //bNumConfigurations; -}; - -//FS and HS needed -static struct usb_qualifier_descriptor dev_qualifier = -{ - sizeof(dev_qualifier), //bLength - USB_DESC_TYPE_DEVICEQUALIFIER, //bDescriptorType - 0x0200, //bcdUSB - USB_CLASS_MISC, //bDeviceClass - 0x02, //bDeviceSubClass - 0x01, //bDeviceProtocol - 64, //bMaxPacketSize0 - 0x01, //bNumConfigurations - 0, -}; -#endif - -struct usb_os_comp_id_descriptor usb_comp_id_desc = -{ - //head section - { - USB_DYNAMIC, - 0x0100, - 0x04, - USB_DYNAMIC, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - }, -}; -static rt_list_t class_list; -int rt_usbd_class_list_init(void) -{ - rt_list_init(&class_list); - return 0; -} -INIT_BOARD_EXPORT(rt_usbd_class_list_init); - -rt_err_t rt_usbd_class_register(udclass_t udclass) -{ -#ifndef RT_USB_DEVICE_COMPOSITE - if(!rt_list_isempty(&class_list)) - { - rt_kprintf("[D/USBD] If you want to use usb composite device please define RT_USB_DEVICE_COMPOSITE\n"); - return -RT_ERROR; - } -#endif - rt_list_insert_before(&class_list,&udclass->list); - return RT_EOK; -} - -rt_err_t rt_usb_device_init(void) -{ - rt_device_t udc; - udevice_t udevice; - uconfig_t cfg; - ufunction_t func; - rt_list_t *i; - udclass_t udclass; - - if(rt_list_isempty(&class_list)) - { - rt_kprintf("[D/USBD] No class register on usb device\n"); - return -RT_ERROR; - } - /* create and startup usb device thread */ - rt_usbd_core_init(); - - /* create a device object */ - udevice = rt_usbd_device_new(); - - udc = rt_device_find(USB_DEVICE_CONTROLLER_NAME); - if(udc == RT_NULL) - { - rt_kprintf("can't find usb device controller %s\n", USB_DEVICE_CONTROLLER_NAME); - return -RT_ERROR; - } - - /* set usb controller driver to the device */ - rt_usbd_device_set_controller(udevice, (udcd_t)udc); - - /* create a configuration object */ - cfg = rt_usbd_config_new(); - - rt_usbd_device_set_os_comp_id_desc(udevice, &usb_comp_id_desc); - - for(i = class_list.next; i!= &class_list; i = i->next) - { - /* get a class creater */ - udclass = rt_list_entry(i, struct udclass, list); - /* create a function object */ - func = udclass->rt_usbd_function_create(udevice); - /* add the function to the configuration */ - rt_usbd_config_add_function(cfg, func); - } - /* set device descriptor to the device */ -#ifdef RT_USB_DEVICE_COMPOSITE - rt_usbd_device_set_descriptor(udevice, &compsit_desc); - rt_usbd_device_set_string(udevice, ustring); - if(udevice->dcd->device_is_hs) - { - rt_usbd_device_set_qualifier(udevice, &dev_qualifier); - } -#else - rt_usbd_device_set_descriptor(udevice, func->dev_desc); -#endif - - /* add the configuration to the device */ - rt_usbd_device_add_config(udevice, cfg); - - /* initialize usb device controller */ - rt_device_init(udc); - - /* set default configuration to 1 */ - rt_usbd_set_config(udevice, 1); - - return RT_EOK; -} -#endif diff --git a/components/drivers/usb/usbdevice/core/usbdevice_core.c b/components/drivers/usb/usbdevice/core/usbdevice_core.c deleted file mode 100644 index 015473ffde..0000000000 --- a/components/drivers/usb/usbdevice/core/usbdevice_core.c +++ /dev/null @@ -1,2269 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-10-01 Yi Qiu first version - * 2012-12-12 heyuanjie87 change endpoint and function handler - * 2012-12-30 heyuanjie87 change inferface handler - * 2013-04-26 aozima add DEVICEQUALIFIER support. - * 2013-07-25 Yi Qiu update for USB CV test - * 2017-11-15 ZYH fix ep0 transform error - */ - -#include <rtthread.h> -#include "drivers/usb_common.h" -#include "drivers/usb_device.h" - -#define DBG_TAG "usbdevice.core" -#define DBG_LVL DBG_INFO -#include <rtdbg.h> - -static rt_list_t device_list; - -static rt_ssize_t rt_usbd_ep_write(udevice_t device, uep_t ep, void *buffer, rt_size_t size); -static rt_ssize_t rt_usbd_ep_read_prepare(udevice_t device, uep_t ep, void *buffer, rt_size_t size); -static rt_err_t rt_usbd_ep_assign(udevice_t device, uep_t ep); -rt_err_t rt_usbd_ep_unassign(udevice_t device, uep_t ep); - -/** - * This function will handle get_device_descriptor bRequest. - * - * @param device the usb device object. - * @param setup the setup bRequest. - * - * @return RT_EOK on successful. - */ -static rt_err_t _get_device_descriptor(struct udevice* device, ureq_t setup) -{ - rt_size_t size; - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(setup != RT_NULL); - - LOG_D("_get_device_descriptor"); - - /* device descriptor wLength should less than USB_DESC_LENGTH_DEVICE*/ - size = (setup->wLength > USB_DESC_LENGTH_DEVICE) ? - USB_DESC_LENGTH_DEVICE : setup->wLength; - - /* send device descriptor to endpoint 0 */ - rt_usbd_ep0_write(device, (rt_uint8_t*) &device->dev_desc, size); - - return RT_EOK; -} - -/** - * This function will handle get_config_descriptor bRequest. - * - * @param device the usb device object. - * @param setup the setup bRequest. - * - * @return RT_EOK on successful. - */ -static rt_err_t _get_config_descriptor(struct udevice* device, ureq_t setup) -{ - rt_size_t size; - ucfg_desc_t cfg_desc; - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(setup != RT_NULL); - - LOG_D("_get_config_descriptor"); - - cfg_desc = &device->curr_cfg->cfg_desc; - size = (setup->wLength > cfg_desc->wTotalLength) ? - cfg_desc->wTotalLength : setup->wLength; - - /* send configuration descriptor to endpoint 0 */ - rt_usbd_ep0_write(device, (rt_uint8_t*)cfg_desc, size); - - return RT_EOK; -} - -/** - * This function will handle get_string_descriptor bRequest. - * - * @param device the usb device object. - * @param setup the setup bRequest. - * - * @return RT_EOK on successful, -RT_ERROR on invalid bRequest. - */ -static rt_err_t _get_string_descriptor(struct udevice* device, ureq_t setup) -{ - struct ustring_descriptor str_desc; - rt_uint8_t index, i; - rt_uint32_t len; - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(setup != RT_NULL); - - LOG_D("_get_string_descriptor"); - - str_desc.type = USB_DESC_TYPE_STRING; - index = setup->wValue & 0xFF; - - if(index == 0xEE) - { - index = USB_STRING_OS_INDEX; - } - - if(index > USB_STRING_MAX) - { - rt_kprintf("unknown string index\n"); - rt_usbd_ep0_set_stall(device); - return -RT_ERROR; - } - else if(index == USB_STRING_LANGID_INDEX) - { - str_desc.bLength = 4; - str_desc.String[0] = 0x09; - str_desc.String[1] = 0x04; - } - else - { - if(index < 5) - len = rt_strlen(device->str[index]); - else - len = rt_strlen(device->str_intf[index]); - str_desc.bLength = len*2 + 2; - - for(i=0; i<len; i++) - { - if(index < 5) - str_desc.String[i*2] = device->str[index][i]; - else - str_desc.String[i*2] = device->str_intf[index][i]; - str_desc.String[i*2 + 1] = 0; - } - } - - if (setup->wLength > str_desc.bLength) - len = str_desc.bLength; - else - len = setup->wLength; - - /* send string descriptor to endpoint 0 */ - rt_usbd_ep0_write(device, (rt_uint8_t*)&str_desc, len); - - return RT_EOK; -} - -static rt_err_t _get_qualifier_descriptor(struct udevice* device, ureq_t setup) -{ - LOG_D("_get_qualifier_descriptor"); - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(setup != RT_NULL); - - if(device->dev_qualifier && device->dcd->device_is_hs) - { - /* send device qualifier descriptor to endpoint 0 */ - rt_usbd_ep0_write(device, (rt_uint8_t*)device->dev_qualifier, - sizeof(struct usb_qualifier_descriptor)); - } - else - { - rt_usbd_ep0_set_stall(device); - } - - return RT_EOK; -} - -/** - * This function will handle get_descriptor bRequest. - * - * @param device the usb device object. - * @param setup the setup bRequest. - * - * @return RT_EOK on successful. - */ -static rt_err_t _get_descriptor(struct udevice* device, ureq_t setup) -{ - /* parameter check */ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(setup != RT_NULL); - - if(setup->request_type == USB_REQ_TYPE_DIR_IN) - { - switch(setup->wValue >> 8) - { - case USB_DESC_TYPE_DEVICE: - _get_device_descriptor(device, setup); - break; - case USB_DESC_TYPE_CONFIGURATION: - _get_config_descriptor(device, setup); - break; - case USB_DESC_TYPE_STRING: - _get_string_descriptor(device, setup); - break; - case USB_DESC_TYPE_DEVICEQUALIFIER: - /* If a full-speed only device (with a device descriptor version number equal to 0200H) receives a - GetDescriptor() request for a device_qualifier, it must respond with a request error. The host must not make - a request for an other_speed_configuration descriptor unless it first successfully retrieves the - device_qualifier descriptor. */ - if(device->dcd->device_is_hs) - { - _get_qualifier_descriptor(device, setup); - } - else - { - rt_usbd_ep0_set_stall(device); - } - break; - case USB_DESC_TYPE_OTHERSPEED: - _get_config_descriptor(device, setup); - break; - default: - rt_kprintf("unsupported descriptor request\n"); - rt_usbd_ep0_set_stall(device); - break; - } - } - else - { - rt_kprintf("request direction error\n"); - rt_usbd_ep0_set_stall(device); - } - - return RT_EOK; -} - -/** - * This function will handle get_interface bRequest. - * - * @param device the usb device object. - * @param setup the setup bRequest. - * - * @return RT_EOK on successful. - */ -static rt_err_t _get_interface(struct udevice* device, ureq_t setup) -{ - rt_uint8_t value; - uintf_t intf; - ufunction_t func; - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(setup != RT_NULL); - - LOG_D("_get_interface"); - - if (device->state != USB_STATE_CONFIGURED) - { - rt_usbd_ep0_set_stall(device); - return -RT_ERROR; - } - - /* find the specified interface and its alternate setting */ - intf = rt_usbd_find_interface(device, setup->wIndex & 0xFF, &func); - value = intf->curr_setting->intf_desc->bAlternateSetting; - - /* send the interface alternate setting to endpoint 0*/ - rt_usbd_ep0_write(device, &value, 1); - - if (intf->handler) - { - intf->handler(func, setup); - } - - return RT_EOK; -} - -/** - * This function will handle set_interface bRequest. - * - * @param device the usb device object. - * @param setup the setup bRequest. - * - * @return RT_EOK on successful. - */ -static rt_err_t _set_interface(struct udevice* device, ureq_t setup) -{ - ufunction_t func; - uintf_t intf; - uep_t ep; - struct rt_list_node* i; - ualtsetting_t setting; - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(setup != RT_NULL); - - LOG_D("_set_interface"); - - if (device->state != USB_STATE_CONFIGURED) - { - rt_usbd_ep0_set_stall(device); - return -RT_ERROR; - } - - /* find the specified interface */ - intf = rt_usbd_find_interface(device, setup->wIndex & 0xFF, &func); - - /* set alternate setting to the interface */ - rt_usbd_set_altsetting(intf, setup->wValue & 0xFF); - setting = intf->curr_setting; - - /* start all endpoints of the interface alternate setting */ - for(i=setting->ep_list.next; i != &setting->ep_list; i=i->next) - { - ep = (uep_t)rt_list_entry(i, struct uendpoint, list); - dcd_ep_disable(device->dcd, ep); - dcd_ep_enable(device->dcd, ep); - } - dcd_ep0_send_status(device->dcd); - - if (intf->handler) - { - intf->handler(func, setup); - } - - return RT_EOK; -} - -/** - * This function will handle get_config bRequest. - * - * @param device the usb device object. - * @param setup the setup bRequest. - * - * @return RT_EOK on successful. - */ -static rt_err_t _get_config(struct udevice* device, ureq_t setup) -{ - rt_uint8_t value; - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(setup != RT_NULL); - RT_ASSERT(device->curr_cfg != RT_NULL); - - LOG_D("_get_config"); - - if (device->state == USB_STATE_CONFIGURED) - { - /* get current configuration */ - value = device->curr_cfg->cfg_desc.bConfigurationValue; - } - else - { - value = 0; - } - /* write the current configuration to endpoint 0 */ - rt_usbd_ep0_write(device, &value, 1); - - return RT_EOK; -} - -/** - * This function will handle set_config bRequest. - * - * @param device the usb device object. - * @param setup the setup bRequest. - * - * @return RT_EOK on successful. - */ -static rt_err_t _set_config(struct udevice* device, ureq_t setup) -{ - struct rt_list_node *i, *j, *k; - uconfig_t cfg; - uintf_t intf; - ualtsetting_t setting; - uep_t ep; - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(setup != RT_NULL); - - LOG_D("_set_config"); - - if (setup->wValue > device->dev_desc.bNumConfigurations) - { - rt_usbd_ep0_set_stall(device); - return -RT_ERROR; - } - - if (setup->wValue == 0) - { - LOG_D("address state"); - device->state = USB_STATE_ADDRESS; - - goto _exit; - } - - /* set current configuration */ - rt_usbd_set_config(device, setup->wValue); - cfg = device->curr_cfg; - - for (i=cfg->func_list.next; i!=&cfg->func_list; i=i->next) - { - /* run all functiones and their endpoints in the configuration */ - ufunction_t func = (ufunction_t)rt_list_entry(i, struct ufunction, list); - for(j=func->intf_list.next; j!=&func->intf_list; j=j->next) - { - intf = (uintf_t)rt_list_entry(j, struct uinterface, list); - setting = intf->curr_setting; - for(k=setting->ep_list.next; k != &setting->ep_list; k=k->next) - { - ep = (uep_t)rt_list_entry(k, struct uendpoint, list); - - /* first disable then enable an endpoint */ - dcd_ep_disable(device->dcd, ep); - dcd_ep_enable(device->dcd, ep); - } - } - /* after enabled endpoints, then enable function */ - FUNC_ENABLE(func); - } - - device->state = USB_STATE_CONFIGURED; - -_exit: - /* issue status stage */ - dcd_ep0_send_status(device->dcd); - - return RT_EOK; -} - -/** - * This function will handle set_address bRequest. - * - * @param device the usb device object. - * @param setup the setup bRequest. - * - * @return RT_EOK on successful. - */ -static rt_err_t _set_address(struct udevice* device, ureq_t setup) -{ - /* parameter check */ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(setup != RT_NULL); - - /* set address in device control driver */ - dcd_set_address(device->dcd, setup->wValue); - - /* issue status stage */ - dcd_ep0_send_status(device->dcd); - - LOG_D("_set_address"); - - device->state = USB_STATE_ADDRESS; - - return RT_EOK; -} - -/** - * This function will handle standard bRequest to - * interface that defined in function-specifics - * - * @param device the usb device object. - * @param setup the setup bRequest. - * - * @return RT_EOK on successful. - */ -static rt_err_t _request_interface(struct udevice* device, ureq_t setup) -{ - uintf_t intf; - ufunction_t func; - rt_err_t ret; - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(setup != RT_NULL); - - LOG_D("_request_interface"); - - intf = rt_usbd_find_interface(device, setup->wIndex & 0xFF, &func); - if (intf != RT_NULL) - { - ret = intf->handler(func, setup); - } - else - { - ret = -RT_ERROR; - } - - return ret; -} - -/** - * This function will handle standard bRequest. - * - * @param device the usb device object. - * @param setup the setup bRequest. - * - * @return RT_EOK on successful. - */ -static rt_err_t _standard_request(struct udevice* device, ureq_t setup) -{ - udcd_t dcd; - rt_uint16_t value = 0; - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(setup != RT_NULL); - - dcd = device->dcd; - - switch(setup->request_type & USB_REQ_TYPE_RECIPIENT_MASK) - { - case USB_REQ_TYPE_DEVICE: - switch(setup->bRequest) - { - case USB_REQ_GET_STATUS: - rt_usbd_ep0_write(device, &value, 2); - break; - case USB_REQ_CLEAR_FEATURE: - rt_usbd_clear_feature(device, setup->wValue, setup->wIndex); - dcd_ep0_send_status(dcd); - break; - case USB_REQ_SET_FEATURE: - rt_usbd_set_feature(device, setup->wValue, setup->wIndex); - break; - case USB_REQ_SET_ADDRESS: - _set_address(device, setup); - break; - case USB_REQ_GET_DESCRIPTOR: - _get_descriptor(device, setup); - break; - case USB_REQ_SET_DESCRIPTOR: - rt_usbd_ep0_set_stall(device); - break; - case USB_REQ_GET_CONFIGURATION: - _get_config(device, setup); - break; - case USB_REQ_SET_CONFIGURATION: - _set_config(device, setup); - break; - default: - rt_kprintf("unknown device request\n"); - rt_usbd_ep0_set_stall(device); - break; - } - break; - case USB_REQ_TYPE_INTERFACE: - switch(setup->bRequest) - { - case USB_REQ_GET_INTERFACE: - _get_interface(device, setup); - break; - case USB_REQ_SET_INTERFACE: - _set_interface(device, setup); - break; - default: - if (_request_interface(device, setup) != RT_EOK) - { - rt_kprintf("unknown interface request\n"); - rt_usbd_ep0_set_stall(device); - return -RT_ERROR; - } - else - break; - } - break; - case USB_REQ_TYPE_ENDPOINT: - switch(setup->bRequest) - { - case USB_REQ_GET_STATUS: - { - uep_t ep; - - ep = rt_usbd_find_endpoint(device, RT_NULL, setup->wIndex); - value = ep->stalled; - rt_usbd_ep0_write(device, &value, 2); - } - break; - case USB_REQ_CLEAR_FEATURE: - { - uep_t ep; - uio_request_t req; - struct rt_list_node *node; - - ep = rt_usbd_find_endpoint(device, RT_NULL, setup->wIndex); - if(USB_EP_HALT == setup->wValue && ep->stalled == RT_TRUE) - { - rt_usbd_clear_feature(device, setup->wValue, setup->wIndex); - dcd_ep0_send_status(dcd); - ep->stalled = RT_FALSE; - - for (node = ep->request_list.next; node != &ep->request_list; node = node->next) - { - req = (uio_request_t)rt_list_entry(node, struct uio_request, list); - rt_usbd_io_request(device, ep, req); - LOG_D("fired a request"); - } - - rt_list_init(&ep->request_list); - } - } - break; - case USB_REQ_SET_FEATURE: - { - uep_t ep; - - if(USB_EP_HALT == setup->wValue) - { - ep = rt_usbd_find_endpoint(device, RT_NULL, setup->wIndex); - ep->stalled = RT_TRUE; - rt_usbd_set_feature(device, setup->wValue, setup->wIndex); - dcd_ep0_send_status(dcd); - } - } - break; - case USB_REQ_SYNCH_FRAME: - break; - default: - rt_kprintf("unknown endpoint request\n"); - rt_usbd_ep0_set_stall(device); - break; - } - break; - case USB_REQ_TYPE_OTHER: - rt_kprintf("unknown other type request\n"); - rt_usbd_ep0_set_stall(device); - break; - default: - rt_kprintf("unknown type request\n"); - rt_usbd_ep0_set_stall(device); - break; - } - - return RT_EOK; -} - -/** - * This function will handle function bRequest. - * - * @param device the usb device object. - * @param setup the setup bRequest. - * - * @return RT_EOK on successful, -RT_ERROR on invalid bRequest. - */ -static rt_err_t _function_request(udevice_t device, ureq_t setup) -{ - uintf_t intf; - ufunction_t func; - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(setup != RT_NULL); - - /* verify bRequest wValue */ - if(setup->wIndex > device->curr_cfg->cfg_desc.bNumInterfaces) - { - rt_usbd_ep0_set_stall(device); - return -RT_ERROR; - } - - switch(setup->request_type & USB_REQ_TYPE_RECIPIENT_MASK) - { - case USB_REQ_TYPE_INTERFACE: - intf = rt_usbd_find_interface(device, setup->wIndex & 0xFF, &func); - if(intf == RT_NULL) - { - rt_kprintf("unkwown interface request\n"); - rt_usbd_ep0_set_stall(device); - } - else - { - intf->handler(func, setup); - } - break; - case USB_REQ_TYPE_ENDPOINT: - break; - default: - rt_kprintf("unknown function request type\n"); - rt_usbd_ep0_set_stall(device); - break; - } - - return RT_EOK; -} -static rt_err_t _vendor_request(udevice_t device, ureq_t setup) -{ - static rt_uint8_t * usb_comp_id_desc = RT_NULL; - static rt_uint32_t usb_comp_id_desc_size = 0; - usb_os_func_comp_id_desc_t func_comp_id_desc; - uintf_t intf; - ufunction_t func; - switch(setup->bRequest) - { - case 'A': - switch(setup->wIndex) - { - case 0x04: - if(rt_list_len(&device->os_comp_id_desc->func_desc) == 0) - { - rt_usbd_ep0_set_stall(device); - return RT_EOK; - } - if(usb_comp_id_desc == RT_NULL) - { - rt_uint8_t * pusb_comp_id_desc; - rt_list_t *p; - usb_comp_id_desc_size = sizeof(struct usb_os_header_comp_id_descriptor) + - (sizeof(struct usb_os_function_comp_id_descriptor)-sizeof(rt_list_t))*rt_list_len(&device->os_comp_id_desc->func_desc); - - usb_comp_id_desc = (rt_uint8_t *)rt_malloc(usb_comp_id_desc_size); - RT_ASSERT(usb_comp_id_desc != RT_NULL); - device->os_comp_id_desc->head_desc.dwLength = usb_comp_id_desc_size; - pusb_comp_id_desc = usb_comp_id_desc; - rt_memcpy((void *)pusb_comp_id_desc,(void *)&device->os_comp_id_desc->head_desc,sizeof(struct usb_os_header_comp_id_descriptor)); - pusb_comp_id_desc += sizeof(struct usb_os_header_comp_id_descriptor); - - for (p = device->os_comp_id_desc->func_desc.next; p != &device->os_comp_id_desc->func_desc; p = p->next) - { - func_comp_id_desc = rt_list_entry(p,struct usb_os_function_comp_id_descriptor,list); - rt_memcpy(pusb_comp_id_desc,(void *)&func_comp_id_desc->bFirstInterfaceNumber, - sizeof(struct usb_os_function_comp_id_descriptor)-sizeof(rt_list_t)); - pusb_comp_id_desc += sizeof(struct usb_os_function_comp_id_descriptor)-sizeof(rt_list_t); - } - } - rt_usbd_ep0_write(device, (void*)usb_comp_id_desc, setup->wLength); - break; - case 0x05: - intf = rt_usbd_find_interface(device, setup->wValue & 0xFF, &func); - if(intf != RT_NULL) - { - intf->handler(func, setup); - } - break; - } - - break; - } - return RT_EOK; -} -static rt_err_t _dump_setup_packet(ureq_t setup) -{ - LOG_D("["); - LOG_D(" setup_request : 0x%x", - setup->request_type); - LOG_D(" value : 0x%x", setup->wValue); - LOG_D(" length : 0x%x", setup->wLength); - LOG_D(" index : 0x%x", setup->wIndex); - LOG_D(" request : 0x%x", setup->bRequest); - LOG_D("]"); - - return RT_EOK; -} - -/** - * This function will handle setup bRequest. - * - * @param device the usb device object. - * @param setup the setup bRequest. - * - * @return RT_EOK on successful, -RT_ERROR on invalid bRequest. - */ -static rt_err_t _setup_request(udevice_t device, ureq_t setup) -{ - /* parameter check */ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(setup != RT_NULL); - - _dump_setup_packet(setup); - - switch((setup->request_type & USB_REQ_TYPE_MASK)) - { - case USB_REQ_TYPE_STANDARD: - _standard_request(device, setup); - break; - case USB_REQ_TYPE_CLASS: - _function_request(device, setup); - break; - case USB_REQ_TYPE_VENDOR: - _vendor_request(device, setup); - break; - default: - rt_kprintf("unknown setup request type\n"); - rt_usbd_ep0_set_stall(device); - return -RT_ERROR; - } - - return RT_EOK; -} - -/** - * This function will hanle data notify event. - * - * @param device the usb device object. - * @param ep_msg the endpoint message. - * - * @return RT_EOK. - */ -static rt_err_t _data_notify(udevice_t device, struct ep_msg* ep_msg) -{ - uep_t ep; - ufunction_t func; - rt_size_t size = 0; - - RT_ASSERT(device != RT_NULL); - RT_ASSERT(ep_msg != RT_NULL); - - if (device->state != USB_STATE_CONFIGURED) - { - return -RT_ERROR; - } - - ep = rt_usbd_find_endpoint(device, &func, ep_msg->ep_addr); - if(ep == RT_NULL) - { - rt_kprintf("invalid endpoint\n"); - return -RT_ERROR; - } - - if(EP_ADDRESS(ep) & USB_DIR_IN) - { - size = ep_msg->size; - if(ep->request.remain_size >= EP_MAXPACKET(ep)) - { - dcd_ep_write(device->dcd, EP_ADDRESS(ep), ep->request.buffer, EP_MAXPACKET(ep)); - ep->request.remain_size -= EP_MAXPACKET(ep); - ep->request.buffer += EP_MAXPACKET(ep); - } - else if(ep->request.remain_size > 0) - { - dcd_ep_write(device->dcd, EP_ADDRESS(ep), ep->request.buffer, ep->request.remain_size); - ep->request.remain_size = 0; - } - else - { - EP_HANDLER(ep, func, size); - } - } - else - { - size = ep_msg->size; - if(ep->request.remain_size == 0) - { - return RT_EOK; - } - - if(size == 0) - { - size = dcd_ep_read(device->dcd, EP_ADDRESS(ep), ep->request.buffer); - } - ep->request.remain_size -= size; - ep->request.buffer += size; - - if(ep->request.req_type == UIO_REQUEST_READ_BEST) - { - EP_HANDLER(ep, func, size); - } - else if(ep->request.remain_size == 0) - { - EP_HANDLER(ep, func, ep->request.size); - } - else - { - dcd_ep_read_prepare(device->dcd, EP_ADDRESS(ep), ep->request.buffer, ep->request.remain_size > EP_MAXPACKET(ep) ? EP_MAXPACKET(ep) : ep->request.remain_size); - } - } - - return RT_EOK; -} - -static rt_err_t _ep0_out_notify(udevice_t device, struct ep_msg* ep_msg) -{ - uep_t ep0; - rt_size_t size; - - RT_ASSERT(device != RT_NULL); - RT_ASSERT(ep_msg != RT_NULL); - RT_ASSERT(device->dcd != RT_NULL); - - ep0 = &device->dcd->ep0; - size = ep_msg->size; - - if(ep0->request.remain_size == 0) - { - return RT_EOK; - } - if(size == 0) - { - size = dcd_ep_read(device->dcd, EP0_OUT_ADDR, ep0->request.buffer); - if(size == 0) - { - return RT_EOK; - } - } - - ep0->request.remain_size -= size; - ep0->request.buffer += size; - if(ep0->request.remain_size == 0) - { - /* invoke callback */ - if(ep0->rx_indicate != RT_NULL) - { - ep0->rx_indicate(device, size); - } - } - else - { - rt_usbd_ep0_read(device, ep0->request.buffer, ep0->request.remain_size,ep0->rx_indicate); - } - - return RT_EOK; -} - -/** - * This function will notity sof event to all of function. - * - * @param device the usb device object. - * - * @return RT_EOK. - */ -static rt_err_t _sof_notify(udevice_t device) -{ - struct rt_list_node *i; - ufunction_t func; - - RT_ASSERT(device != RT_NULL); - - /* to notity every function that sof event comes */ - for (i=device->curr_cfg->func_list.next; - i!=&device->curr_cfg->func_list; i=i->next) - { - func = (ufunction_t)rt_list_entry(i, struct ufunction, list); - if(func->ops->sof_handler != RT_NULL) - func->ops->sof_handler(func); - } - - return RT_EOK; -} - -/** - * This function will disable all USB functions. - * - * @param device the usb device object. - * - * @return RT_EOK. - */ -static rt_err_t _stop_notify(udevice_t device) -{ - struct rt_list_node *i; - ufunction_t func; - - RT_ASSERT(device != RT_NULL); - - /* to notity every function */ - for (i = device->curr_cfg->func_list.next; - i != &device->curr_cfg->func_list; - i = i->next) - { - func = (ufunction_t)rt_list_entry(i, struct ufunction, list); - FUNC_DISABLE(func); - } - - return RT_EOK; -} - -static rt_ssize_t rt_usbd_ep_write(udevice_t device, uep_t ep, void *buffer, rt_size_t size) -{ - rt_uint16_t maxpacket; - - RT_ASSERT(device != RT_NULL); - RT_ASSERT(device->dcd != RT_NULL); - RT_ASSERT(ep != RT_NULL); - - rt_enter_critical(); - maxpacket = EP_MAXPACKET(ep); - if(ep->request.remain_size >= maxpacket) - { - dcd_ep_write(device->dcd, EP_ADDRESS(ep), ep->request.buffer, maxpacket); - ep->request.remain_size -= maxpacket; - ep->request.buffer += maxpacket; - } - else - { - dcd_ep_write(device->dcd, EP_ADDRESS(ep), ep->request.buffer, - ep->request.remain_size); - ep->request.remain_size = 0; - } - rt_exit_critical(); - return size; -} - -static rt_ssize_t rt_usbd_ep_read_prepare(udevice_t device, uep_t ep, void *buffer, rt_size_t size) -{ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(device->dcd != RT_NULL); - RT_ASSERT(ep != RT_NULL); - RT_ASSERT(buffer != RT_NULL); - RT_ASSERT(ep->ep_desc != RT_NULL); - - return dcd_ep_read_prepare(device->dcd, EP_ADDRESS(ep), buffer, size > EP_MAXPACKET(ep) ? EP_MAXPACKET(ep) : size); -} - -/** - * This function will create an usb device object. - * - * @param ustring the usb string array to contain string descriptor. - * - * @return an usb device object on success, RT_NULL on fail. - */ -udevice_t rt_usbd_device_new(void) -{ - udevice_t udevice; - - LOG_D("rt_usbd_device_new"); - - /* allocate memory for the object */ - udevice = (udevice_t)rt_malloc(sizeof(struct udevice)); - if(udevice == RT_NULL) - { - rt_kprintf("alloc memory failed\n"); - return RT_NULL; - } - rt_memset(udevice, 0, sizeof(struct udevice)); - - /* to initialize configuration list */ - rt_list_init(&udevice->cfg_list); - - /* insert the device object to device list */ - rt_list_insert_before(&device_list, &udevice->list); - - return udevice; -} - -/** - * This function will set usb device string description. - * - * @param device the usb device object. - * @param ustring pointer to string pointer array. - * - * @return RT_EOK. - */ -rt_err_t rt_usbd_device_set_string(udevice_t device, const char** ustring) -{ - /* parameter check */ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(ustring != RT_NULL); - - /* set string descriptor array to the device object */ - device->str = ustring; - - return RT_EOK; -} - -/** - * This function will set usb device interface string description. - * - * @param device the usb device object. - * @param index of interface string - * @param string pointer to interface string description. - * - * @return RT_EOK. - */ -rt_err_t rt_usbd_device_set_interface_string(udevice_t device, int index, const char* string) -{ - /* parameter check */ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(string != RT_NULL); - RT_ASSERT(index < MAX_INTF_STR); - - /* set string descriptor array to the device object */ - device->str_intf[index] = string; - - return RT_EOK; -} - -rt_err_t rt_usbd_device_set_os_comp_id_desc(udevice_t device, usb_os_comp_id_desc_t os_comp_id_desc) -{ - /* parameter check */ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(os_comp_id_desc != RT_NULL); - - /* set string descriptor array to the device object */ - device->os_comp_id_desc = os_comp_id_desc; - rt_list_init(&device->os_comp_id_desc->func_desc); - return RT_EOK; -} - -rt_err_t rt_usbd_device_set_qualifier(udevice_t device, struct usb_qualifier_descriptor* qualifier) -{ - /* parameter check */ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(qualifier != RT_NULL); - - device->dev_qualifier = qualifier; - - return RT_EOK; -} - -/** - * This function will set an usb controller driver to a device. - * - * @param device the usb device object. - * @param dcd the usb device controller driver. - * - * @return RT_EOK on successful. - */ -rt_err_t rt_usbd_device_set_controller(udevice_t device, udcd_t dcd) -{ - /* parameter check */ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(dcd != RT_NULL); - - /* set usb device controller driver to the device */ - device->dcd = dcd; - - return RT_EOK; -} - -/** - * This function will set an usb device descriptor to a device. - * - * @param device the usb device object. - * @param dev_desc the usb device descriptor. - * - * @return RT_EOK on successful. - */ -rt_err_t rt_usbd_device_set_descriptor(udevice_t device, udev_desc_t dev_desc) -{ - /* parameter check */ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(dev_desc != RT_NULL); - - /* copy the usb device descriptor to the device */ - rt_memcpy((void *)&device->dev_desc, (void *)dev_desc, USB_DESC_LENGTH_DEVICE); - - return RT_EOK; -} - -/** - * This function will create an usb configuration object. - * - * @param none. - * - * @return an usb configuration object. - */ -uconfig_t rt_usbd_config_new(void) -{ - uconfig_t cfg; - - LOG_D("rt_usbd_config_new"); - - /* allocate memory for the object */ - cfg = (uconfig_t)rt_malloc(sizeof(struct uconfig)); - if(cfg == RT_NULL) - { - rt_kprintf("alloc memory failed\n"); - return RT_NULL; - } - rt_memset(cfg, 0, sizeof(struct uconfig)); - - /* set default wValue */ - cfg->cfg_desc.bLength = USB_DESC_LENGTH_CONFIG; - cfg->cfg_desc.type = USB_DESC_TYPE_CONFIGURATION; - cfg->cfg_desc.wTotalLength = USB_DESC_LENGTH_CONFIG; - cfg->cfg_desc.bmAttributes = 0xC0; - cfg->cfg_desc.MaxPower = 0x32; - - /* to initialize function object list */ - rt_list_init(&cfg->func_list); - - return cfg; -} - -/** - * This function will create an usb interface object. - * - * @param device the usb device object. - * @handler the callback handler of object - * - * @return an usb interface object on success, RT_NULL on fail. - */ -uintf_t rt_usbd_interface_new(udevice_t device, uintf_handler_t handler) -{ - uintf_t intf; - - LOG_D("rt_usbd_interface_new"); - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - - /* allocate memory for the object */ - intf = (uintf_t)rt_malloc(sizeof(struct uinterface)); - if(intf == RT_NULL) - { - rt_kprintf("alloc memory failed\n"); - return RT_NULL; - } - intf->intf_num = device->nr_intf; - device->nr_intf++; - intf->handler = handler; - intf->curr_setting = RT_NULL; - - /* to initialize the alternate setting object list */ - rt_list_init(&intf->setting_list); - - return intf; -} - -/** - * This function will create an usb alternate setting object. - * - * @param intf_desc the interface descriptor. - * @desc_size the size of the interface descriptor. - * - * @return an usb alternate setting object on success, RT_NULL on fail. - */ -ualtsetting_t rt_usbd_altsetting_new(rt_size_t desc_size) -{ - ualtsetting_t setting; - - LOG_D("rt_usbd_altsetting_new"); - - /* parameter check */ - RT_ASSERT(desc_size > 0); - - /* allocate memory for the object */ - setting = (ualtsetting_t)rt_malloc(sizeof(struct ualtsetting)); - if(setting == RT_NULL) - { - rt_kprintf("alloc memory failed\n"); - return RT_NULL; - } - /* allocate memory for the desc */ - setting->desc = rt_malloc(desc_size); - if (setting->desc == RT_NULL) - { - rt_kprintf("alloc desc memory failed\n"); - rt_free(setting); - return RT_NULL; - } - - setting->desc_size = desc_size; - setting->intf_desc = RT_NULL; - - /* to initialize endpoint list */ - rt_list_init(&setting->ep_list); - - return setting; -} - -/** - * This function will config an desc in alternate setting object. - * - * @param setting the altsetting to be config. - * @param desc use it to init desc in setting. - * @param intf_pos the offset of interface descriptor in desc. - * - * @return RT_EOK. - */ -rt_err_t rt_usbd_altsetting_config_descriptor(ualtsetting_t setting, const void* desc, rt_off_t intf_pos) -{ - RT_ASSERT(setting != RT_NULL); - RT_ASSERT(setting->desc !=RT_NULL); - - rt_memcpy(setting->desc, desc, setting->desc_size); - setting->intf_desc = (uintf_desc_t)((char*)setting->desc + intf_pos); - - return RT_EOK; -} - -/** - * This function will create an usb function object. - * - * @param device the usb device object. - * @param dev_desc the device descriptor. - * @param ops the operation set. - * - * @return an usb function object on success, RT_NULL on fail. - */ -ufunction_t rt_usbd_function_new(udevice_t device, udev_desc_t dev_desc, - ufunction_ops_t ops) -{ - ufunction_t func; - - LOG_D("rt_usbd_function_new"); - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(dev_desc != RT_NULL); - - /* allocate memory for the object */ - func = (ufunction_t)rt_malloc(sizeof(struct ufunction)); - if(func == RT_NULL) - { - rt_kprintf("alloc memory failed\n"); - return RT_NULL; - } - func->dev_desc = dev_desc; - func->ops = ops; - func->device = device; - func->enabled = RT_FALSE; - - /* to initialize interface list */ - rt_list_init(&func->intf_list); - - return func; -} - -/** - * This function will create an usb endpoint object. - * - * @param ep_desc the endpoint descriptor. - * @handler the callback handler of object - * - * @return an usb endpoint object on success, RT_NULL on fail. - */ -uep_t rt_usbd_endpoint_new(uep_desc_t ep_desc, udep_handler_t handler) -{ - uep_t ep; - - LOG_D("rt_usbd_endpoint_new"); - - /* parameter check */ - RT_ASSERT(ep_desc != RT_NULL); - - /* allocate memory for the object */ - ep = (uep_t)rt_malloc(sizeof(struct uendpoint)); - if(ep == RT_NULL) - { - rt_kprintf("alloc memory failed\n"); - return RT_NULL; - } - ep->ep_desc = ep_desc; - ep->handler = handler; - ep->buffer = RT_NULL; - ep->stalled = RT_FALSE; - rt_list_init(&ep->request_list); - - return ep; -} - -/** - * This function will find an usb device object. - * - * @dcd usd device controller driver. - * - * @return an usb device object on found or RT_NULL on not found. - */ -udevice_t rt_usbd_find_device(udcd_t dcd) -{ - struct rt_list_node* node; - udevice_t device; - - /* parameter check */ - RT_ASSERT(dcd != RT_NULL); - - /* search a device in the the device list */ - for (node = device_list.next; node != &device_list; node = node->next) - { - device = (udevice_t)rt_list_entry(node, struct udevice, list); - if(device->dcd == dcd) return device; - } - - rt_kprintf("can't find device\n"); - return RT_NULL; -} - -/** - * This function will find an usb configuration object. - * - * @param device the usb device object. - * @param wValue the configuration number. - * - * @return an usb configuration object on found or RT_NULL on not found. - */ -uconfig_t rt_usbd_find_config(udevice_t device, rt_uint8_t value) -{ - struct rt_list_node* node; - uconfig_t cfg = RT_NULL; - - LOG_D("rt_usbd_find_config"); - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(value <= device->dev_desc.bNumConfigurations); - - /* search a configration in the the device */ - for (node = device->cfg_list.next; node != &device->cfg_list; node = node->next) - { - cfg = (uconfig_t)rt_list_entry(node, struct udevice, list); - if(cfg->cfg_desc.bConfigurationValue == value) - { - return cfg; - } - } - - rt_kprintf("can't find configuration %d\n", value); - return RT_NULL; -} - -/** - * This function will find an usb interface object. - * - * @param device the usb device object. - * @param wValue the interface number. - * - * @return an usb configuration object on found or RT_NULL on not found. - */ -uintf_t rt_usbd_find_interface(udevice_t device, rt_uint8_t value, ufunction_t *pfunc) -{ - struct rt_list_node *i, *j; - ufunction_t func; - uintf_t intf; - - LOG_D("rt_usbd_find_interface"); - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(value < device->nr_intf); - - /* search an interface in the current configuration */ - for (i=device->curr_cfg->func_list.next; - i!=&device->curr_cfg->func_list; i=i->next) - { - func = (ufunction_t)rt_list_entry(i, struct ufunction, list); - for(j=func->intf_list.next; j!=&func->intf_list; j=j->next) - { - intf = (uintf_t)rt_list_entry(j, struct uinterface, list); - if(intf->intf_num == value) - { - if (pfunc != RT_NULL) - *pfunc = func; - return intf; - } - } - } - - rt_kprintf("can't find interface %d\n", value); - return RT_NULL; -} - -/** - * This function will find an usb interface alternate setting object. - * - * @param device the usb device object. - * @param wValue the alternate setting number. - * - * @return an usb interface alternate setting object on found or RT_NULL on not found. - */ -ualtsetting_t rt_usbd_find_altsetting(uintf_t intf, rt_uint8_t value) -{ - struct rt_list_node *i; - ualtsetting_t setting; - - LOG_D("rt_usbd_find_altsetting"); - - /* parameter check */ - RT_ASSERT(intf != RT_NULL); - - if(intf->curr_setting != RT_NULL) - { - /* if the wValue equal to the current alternate setting, then do not search */ - if(intf->curr_setting->intf_desc->bAlternateSetting == value) - return intf->curr_setting; - } - - /* search a setting in the alternate setting list */ - for(i=intf->setting_list.next; i!=&intf->setting_list; i=i->next) - { - setting =(ualtsetting_t)rt_list_entry(i, struct ualtsetting, list); - if(setting->intf_desc->bAlternateSetting == value) - return setting; - } - - rt_kprintf("can't find alternate setting %d\n", value); - return RT_NULL; -} - -/** - * This function will find an usb endpoint object. - * - * @param device the usb device object. - * @param ep_addr endpoint address. - * - * @return an usb endpoint object on found or RT_NULL on not found. - */ -uep_t rt_usbd_find_endpoint(udevice_t device, ufunction_t* pfunc, rt_uint8_t ep_addr) -{ - uep_t ep; - struct rt_list_node *i, *j, *k; - ufunction_t func; - uintf_t intf; - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - - /* search a endpoint in the current configuration */ - for (i=device->curr_cfg->func_list.next; i!=&device->curr_cfg->func_list; i=i->next) - { - func = (ufunction_t)rt_list_entry(i, struct ufunction, list); - for(j=func->intf_list.next; j!=&func->intf_list; j=j->next) - { - intf = (uintf_t)rt_list_entry(j, struct uinterface, list); - for(k=intf->curr_setting->ep_list.next; - k!=&intf->curr_setting->ep_list; k=k->next) - { - ep = (uep_t)rt_list_entry(k, struct uendpoint, list); - if(EP_ADDRESS(ep) == ep_addr) - { - if (pfunc != RT_NULL) - *pfunc = func; - return ep; - } - } - } - } - - rt_kprintf("can't find endpoint 0x%x\n", ep_addr); - return RT_NULL; -} - -/** - * This function will add a configuration to an usb device. - * - * @param device the usb device object. - * @param cfg the configuration object. - * - * @return RT_EOK. - */ -rt_err_t rt_usbd_device_add_config(udevice_t device, uconfig_t cfg) -{ - struct rt_list_node *i, *j, *k, *m; - ufunction_t func; - uintf_t intf; - ualtsetting_t altsetting; - uep_t ep; - - LOG_D("rt_usbd_device_add_config"); - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(cfg != RT_NULL); - - /* set configuration number to the configuration descriptor */ - cfg->cfg_desc.bConfigurationValue = device->dev_desc.bNumConfigurations + 1; - device->dev_desc.bNumConfigurations++; - - for (i=cfg->func_list.next; i!=&cfg->func_list; i=i->next) - { - func = (ufunction_t)rt_list_entry(i, struct ufunction, list); - - for(j=func->intf_list.next; j!=&func->intf_list; j=j->next) - { - intf = (uintf_t)rt_list_entry(j, struct uinterface, list); - cfg->cfg_desc.bNumInterfaces++; - - for(k=intf->setting_list.next; k!=&intf->setting_list;k=k->next) - { - altsetting = (ualtsetting_t)rt_list_entry(k, struct ualtsetting, list); - - /* allocate address for every endpoint in the interface alternate setting */ - for(m=altsetting->ep_list.next; m!=&altsetting->ep_list; m=m->next) - { - ep = (uep_t)rt_list_entry(m, struct uendpoint, list); - if(rt_usbd_ep_assign(device, ep) != RT_EOK) - { - rt_kprintf("endpoint assign error\n"); - } - } - - /* construct complete configuration descriptor */ - rt_memcpy((void*)&cfg->cfg_desc.data[cfg->cfg_desc.wTotalLength - USB_DESC_LENGTH_CONFIG], - (void*)altsetting->desc, - altsetting->desc_size); - cfg->cfg_desc.wTotalLength += altsetting->desc_size; - } - } - } - - /* insert the configuration to the list */ - rt_list_insert_before(&device->cfg_list, &cfg->list); - - return RT_EOK; -} - -/** - * This function will add a function to a configuration. - * - * @param cfg the configuration object. - * @param func the function object. - * - * @return RT_EOK. - */ -rt_err_t rt_usbd_config_add_function(uconfig_t cfg, ufunction_t func) -{ - LOG_D("rt_usbd_config_add_function"); - - /* parameter check */ - RT_ASSERT(cfg != RT_NULL); - RT_ASSERT(func != RT_NULL); - - /* insert the function to the list */ - rt_list_insert_before(&cfg->func_list, &func->list); - - return RT_EOK; -} - -/** - * This function will add an interface to a function. - * - * @param func the function object. - * @param intf the interface object. - * - * @return RT_EOK. - */ -rt_err_t rt_usbd_function_add_interface(ufunction_t func, uintf_t intf) -{ - - LOG_D("rt_usbd_function_add_interface"); - - /* parameter check */ - RT_ASSERT(func != RT_NULL); - RT_ASSERT(intf != RT_NULL); - - /* insert the interface to the list */ - rt_list_insert_before(&func->intf_list, &intf->list); - - return RT_EOK; -} - -/** - * This function will add an alternate setting to an interface. - * - * @param intf the interface object. - * @param setting the alternate setting object. - * - * @return RT_EOK. - */ -rt_err_t rt_usbd_interface_add_altsetting(uintf_t intf, ualtsetting_t setting) -{ - LOG_D("rt_usbd_interface_add_altsetting"); - - /* parameter check */ - RT_ASSERT(intf != RT_NULL); - RT_ASSERT(setting != RT_NULL); - - setting->intf_desc->bInterfaceNumber = intf->intf_num; - - /* insert the alternate setting to the list */ - rt_list_insert_before(&intf->setting_list, &setting->list); - - return RT_EOK; -} - -/** - * This function will add an endpoint to an alternate setting. - * - * @param setting the alternate setting object. - * @param ep the endpoint object. - * - * @return RT_EOK. - */ -rt_err_t rt_usbd_altsetting_add_endpoint(ualtsetting_t setting, uep_t ep) -{ - LOG_D("rt_usbd_altsetting_add_endpoint"); - - /* parameter check */ - RT_ASSERT(setting != RT_NULL); - RT_ASSERT(ep != RT_NULL); - - /* insert the endpoint to the list */ - rt_list_insert_before(&setting->ep_list, &ep->list); - - return RT_EOK; -} - -rt_err_t rt_usbd_os_comp_id_desc_add_os_func_comp_id_desc(usb_os_comp_id_desc_t os_comp_id_desc, usb_os_func_comp_id_desc_t os_func_comp_id_desc) -{ - RT_ASSERT(os_comp_id_desc != RT_NULL); - RT_ASSERT(os_func_comp_id_desc != RT_NULL); - rt_list_insert_before(&os_comp_id_desc->func_desc, &os_func_comp_id_desc->list); - os_comp_id_desc->head_desc.bCount++; - return RT_EOK; -} - -/** - * This function will set an alternate setting for an interface. - * - * @param intf_desc the interface descriptor. - * @param wValue the alternate setting number. - * - * @return RT_EOK. - */ -rt_err_t rt_usbd_set_altsetting(uintf_t intf, rt_uint8_t value) -{ - ualtsetting_t setting; - - LOG_D("rt_usbd_set_altsetting"); - - /* parameter check */ - RT_ASSERT(intf != RT_NULL); - - /* find an alternate setting */ - setting = rt_usbd_find_altsetting(intf, value); - - /* set as current alternate setting */ - intf->curr_setting = setting; - - return RT_EOK; -} - -/** - * This function will set a configuration for an usb device. - * - * @param device the usb device object. - * @param wValue the configuration number. - * - * @return RT_EOK. - */ -rt_err_t rt_usbd_set_config(udevice_t device, rt_uint8_t value) -{ - uconfig_t cfg; - - LOG_D("rt_usbd_set_config"); - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(value <= device->dev_desc.bNumConfigurations); - - /* find a configuration */ - cfg = rt_usbd_find_config(device, value); - - /* set as current configuration */ - device->curr_cfg = cfg; - - dcd_set_config(device->dcd, value); - - return RT_TRUE; -} - -/** - * This function will bRequest an IO transaction. - * - * @param device the usb device object. - * @param ep the endpoint object. - * @param req IO bRequest. - * - * @return RT_EOK. - */ -rt_size_t rt_usbd_io_request(udevice_t device, uep_t ep, uio_request_t req) -{ - rt_size_t size = 0; - - RT_ASSERT(device != RT_NULL); - RT_ASSERT(req != RT_NULL); - - if(ep->stalled == RT_FALSE) - { - switch(req->req_type) - { - case UIO_REQUEST_READ_BEST: - case UIO_REQUEST_READ_FULL: - ep->request.remain_size = ep->request.size; - size = rt_usbd_ep_read_prepare(device, ep, req->buffer, req->size); - break; - case UIO_REQUEST_WRITE: - ep->request.remain_size = ep->request.size; - size = rt_usbd_ep_write(device, ep, req->buffer, req->size); - break; - default: - rt_kprintf("unknown request type\n"); - break; - } - } - else - { - rt_list_insert_before(&ep->request_list, &req->list); - LOG_D("suspend a request"); - } - - return size; -} - -/** - * This function will set feature for an usb device. - * - * @param device the usb device object. - * @param wValue the configuration number. - * - * @return RT_EOK. - */ -rt_err_t rt_usbd_set_feature(udevice_t device, rt_uint16_t value, rt_uint16_t index) -{ - RT_ASSERT(device != RT_NULL); - - if (value == USB_FEATURE_DEV_REMOTE_WAKEUP) - { - LOG_D("set feature remote wakeup"); - } - else if (value == USB_FEATURE_ENDPOINT_HALT) - { - LOG_D("set feature stall"); - dcd_ep_set_stall(device->dcd, (rt_uint32_t)(index & 0xFF)); - } - - return RT_EOK; -} - -/** - * This function will clear feature for an usb device. - * - * @param device the usb device object. - * @param wValue the configuration number. - * - * @return RT_EOK. - */ -rt_err_t rt_usbd_clear_feature(udevice_t device, rt_uint16_t value, rt_uint16_t index) -{ - RT_ASSERT(device != RT_NULL); - - if (value == USB_FEATURE_DEV_REMOTE_WAKEUP) - { - LOG_D("clear feature remote wakeup"); - } - else if (value == USB_FEATURE_ENDPOINT_HALT) - { - LOG_D("clear feature stall"); - dcd_ep_clear_stall(device->dcd, (rt_uint32_t)(index & 0xFF)); - } - - return RT_EOK; -} - -rt_err_t rt_usbd_ep0_set_stall(udevice_t device) -{ - RT_ASSERT(device != RT_NULL); - - return dcd_ep_set_stall(device->dcd, 0x80); -} - -rt_err_t rt_usbd_ep0_clear_stall(udevice_t device) -{ - RT_ASSERT(device != RT_NULL); - - return dcd_ep_clear_stall(device->dcd, 0x80); -} - -rt_err_t rt_usbd_ep_set_stall(udevice_t device, uep_t ep) -{ - rt_err_t ret; - - RT_ASSERT(device != RT_NULL); - RT_ASSERT(ep != RT_NULL); - RT_ASSERT(ep->ep_desc != RT_NULL); - - ret = dcd_ep_set_stall(device->dcd, EP_ADDRESS(ep)); - if(ret == RT_EOK) - { - ep->stalled = RT_TRUE; - } - - return ret; -} - -rt_err_t rt_usbd_ep_clear_stall(udevice_t device, uep_t ep) -{ - rt_err_t ret; - - RT_ASSERT(device != RT_NULL); - RT_ASSERT(ep != RT_NULL); - RT_ASSERT(ep->ep_desc != RT_NULL); - - ret = dcd_ep_clear_stall(device->dcd, EP_ADDRESS(ep)); - if(ret == RT_EOK) - { - ep->stalled = RT_FALSE; - } - - return ret; -} - -static rt_err_t rt_usbd_ep_assign(udevice_t device, uep_t ep) -{ - int i = 0; - - RT_ASSERT(device != RT_NULL); - RT_ASSERT(device->dcd != RT_NULL); - RT_ASSERT(device->dcd->ep_pool != RT_NULL); - RT_ASSERT(ep != RT_NULL); - RT_ASSERT(ep->ep_desc != RT_NULL); - - while(device->dcd->ep_pool[i].addr != 0xFF) - { - if(device->dcd->ep_pool[i].status == ID_UNASSIGNED && - ep->ep_desc->bmAttributes == device->dcd->ep_pool[i].type && (EP_ADDRESS(ep) & 0x80) == device->dcd->ep_pool[i].dir) - { - EP_ADDRESS(ep) |= device->dcd->ep_pool[i].addr; - ep->id = &device->dcd->ep_pool[i]; - device->dcd->ep_pool[i].status = ID_ASSIGNED; - - LOG_D("assigned %d", device->dcd->ep_pool[i].addr); - return RT_EOK; - } - - i++; - } - - return -RT_ERROR; -} - -rt_err_t rt_usbd_ep_unassign(udevice_t device, uep_t ep) -{ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(device->dcd != RT_NULL); - RT_ASSERT(device->dcd->ep_pool != RT_NULL); - RT_ASSERT(ep != RT_NULL); - RT_ASSERT(ep->ep_desc != RT_NULL); - - ep->id->status = ID_UNASSIGNED; - - return RT_EOK; -} - -rt_err_t rt_usbd_ep0_setup_handler(udcd_t dcd, struct urequest* setup) -{ - struct udev_msg msg; - rt_size_t size; - - RT_ASSERT(dcd != RT_NULL); - - if(setup == RT_NULL) - { - size = dcd_ep_read(dcd, EP0_OUT_ADDR, (void*)&msg.content.setup); - if(size != sizeof(struct urequest)) - { - rt_kprintf("read setup packet error\n"); - return -RT_ERROR; - } - } - else - { - rt_memcpy((void*)&msg.content.setup, (void*)setup, sizeof(struct urequest)); - } - - msg.type = USB_MSG_SETUP_NOTIFY; - msg.dcd = dcd; - rt_usbd_event_signal(&msg); - - return RT_EOK; -} - -rt_err_t rt_usbd_ep0_in_handler(udcd_t dcd) -{ - rt_int32_t remain, mps; - - RT_ASSERT(dcd != RT_NULL); - - if (dcd->stage != STAGE_DIN) - return RT_EOK; - - mps = dcd->ep0.id->maxpacket; - dcd->ep0.request.remain_size -= mps; - remain = dcd->ep0.request.remain_size; - - if (remain > 0) - { - if (remain >= mps) - { - remain = mps; - } - - dcd->ep0.request.buffer += mps; - dcd_ep_write(dcd, EP0_IN_ADDR, dcd->ep0.request.buffer, remain); - } - else - { - /* last packet is MPS multiple, so send ZLP packet */ - if ((remain == 0) && (dcd->ep0.request.size > 0)) - { - dcd->ep0.request.size = 0; - dcd_ep_write(dcd, EP0_IN_ADDR, RT_NULL, 0); - } - else - { - /* receive status */ - dcd->stage = STAGE_STATUS_OUT; - dcd_ep_read_prepare(dcd, EP0_OUT_ADDR, RT_NULL, 0); - } - } - - return RT_EOK; -} - -rt_err_t rt_usbd_ep0_out_handler(udcd_t dcd, rt_size_t size) -{ - struct udev_msg msg; - - RT_ASSERT(dcd != RT_NULL); - - msg.type = USB_MSG_EP0_OUT; - msg.dcd = dcd; - msg.content.ep_msg.size = size; - rt_usbd_event_signal(&msg); - - return RT_EOK; -} - -rt_err_t rt_usbd_ep_in_handler(udcd_t dcd, rt_uint8_t address, rt_size_t size) -{ - struct udev_msg msg; - - RT_ASSERT(dcd != RT_NULL); - - msg.type = USB_MSG_DATA_NOTIFY; - msg.dcd = dcd; - msg.content.ep_msg.ep_addr = address; - msg.content.ep_msg.size = size; - rt_usbd_event_signal(&msg); - - return RT_EOK; -} - -rt_err_t rt_usbd_ep_out_handler(udcd_t dcd, rt_uint8_t address, rt_size_t size) -{ - struct udev_msg msg; - - RT_ASSERT(dcd != RT_NULL); - - msg.type = USB_MSG_DATA_NOTIFY; - msg.dcd = dcd; - msg.content.ep_msg.ep_addr = address; - msg.content.ep_msg.size = size; - rt_usbd_event_signal(&msg); - - return RT_EOK; -} - -rt_err_t rt_usbd_reset_handler(udcd_t dcd) -{ - struct udev_msg msg; - - RT_ASSERT(dcd != RT_NULL); - - msg.type = USB_MSG_RESET; - msg.dcd = dcd; - rt_usbd_event_signal(&msg); - - return RT_EOK; -} - -rt_err_t rt_usbd_connect_handler(udcd_t dcd) -{ - struct udev_msg msg; - - RT_ASSERT(dcd != RT_NULL); - - msg.type = USB_MSG_PLUG_IN; - msg.dcd = dcd; - rt_usbd_event_signal(&msg); - - return RT_EOK; -} - -rt_err_t rt_usbd_disconnect_handler(udcd_t dcd) -{ - struct udev_msg msg; - - RT_ASSERT(dcd != RT_NULL); - - msg.type = USB_MSG_PLUG_OUT; - msg.dcd = dcd; - rt_usbd_event_signal(&msg); - - return RT_EOK; -} - -rt_err_t rt_usbd_sof_handler(udcd_t dcd) -{ - struct udev_msg msg; - - RT_ASSERT(dcd != RT_NULL); - - msg.type = USB_MSG_SOF; - msg.dcd = dcd; - rt_usbd_event_signal(&msg); - - return RT_EOK; -} - -rt_size_t rt_usbd_ep0_write(udevice_t device, void *buffer, rt_size_t size) -{ - uep_t ep0; - rt_size_t sent_size = 0; - - RT_ASSERT(device != RT_NULL); - RT_ASSERT(device->dcd != RT_NULL); - RT_ASSERT(buffer != RT_NULL); - RT_ASSERT(size > 0); - - ep0 = &device->dcd->ep0; - ep0->request.size = size; - ep0->request.buffer = (rt_uint8_t *)buffer; - ep0->request.remain_size = size; - if(size >= ep0->id->maxpacket) - { - sent_size = ep0->id->maxpacket; - } - else - { - sent_size = size; - } - device->dcd->stage = STAGE_DIN; - - return dcd_ep_write(device->dcd, EP0_IN_ADDR, ep0->request.buffer, sent_size); -} - -rt_size_t rt_usbd_ep0_read(udevice_t device, void *buffer, rt_size_t size, - rt_err_t (*rx_ind)(udevice_t device, rt_size_t size)) -{ - uep_t ep0; - rt_size_t read_size = 0; - - RT_ASSERT(device != RT_NULL); - RT_ASSERT(device->dcd != RT_NULL); - RT_ASSERT(buffer != RT_NULL); - - ep0 = &device->dcd->ep0; - ep0->request.buffer = (rt_uint8_t *)buffer; - ep0->request.remain_size = size; - ep0->rx_indicate = rx_ind; - if(size >= ep0->id->maxpacket) - { - read_size = ep0->id->maxpacket; - } - else - { - read_size = size; - } - device->dcd->stage = STAGE_DOUT; - dcd_ep_read_prepare(device->dcd, EP0_OUT_ADDR, buffer, read_size); - - return size; -} - -static struct rt_messagequeue usb_mq; - -/** - * This function is the main entry of usb device thread, it is in charge of - * processing all messages received from the usb message buffer. - * - * @param parameter the parameter of the usb device thread. - * - * @return none. - */ -static void rt_usbd_thread_entry(void* parameter) -{ - while(1) - { - struct udev_msg msg; - udevice_t device; - - /* receive message */ - if(rt_mq_recv(&usb_mq, &msg, sizeof(struct udev_msg), - RT_WAITING_FOREVER) < 0) - continue; - - device = rt_usbd_find_device(msg.dcd); - if(device == RT_NULL) - { - rt_kprintf("invalid usb device\n"); - continue; - } - - LOG_D("message type %d", msg.type); - - switch (msg.type) - { - case USB_MSG_SOF: - _sof_notify(device); - break; - case USB_MSG_DATA_NOTIFY: - /* some buggy drivers will have USB_MSG_DATA_NOTIFY before the core - * got configured. */ - _data_notify(device, &msg.content.ep_msg); - break; - case USB_MSG_SETUP_NOTIFY: - _setup_request(device, &msg.content.setup); - break; - case USB_MSG_EP0_OUT: - _ep0_out_notify(device, &msg.content.ep_msg); - break; - case USB_MSG_RESET: - LOG_D("reset %d", device->state); - if (device->state == USB_STATE_ADDRESS || device->state == USB_STATE_CONFIGURED) - _stop_notify(device); - device->state = USB_STATE_NOTATTACHED; - break; - case USB_MSG_PLUG_IN: - device->state = USB_STATE_ATTACHED; - break; - case USB_MSG_PLUG_OUT: - device->state = USB_STATE_NOTATTACHED; - _stop_notify(device); - break; - default: - rt_kprintf("unknown msg type %d\n", msg.type); - break; - } - } -} - -/** - * This function will post an message to usb message queue, - * - * @param msg the message to be posted - * @param size the size of the message . - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbd_event_signal(struct udev_msg* msg) -{ - RT_ASSERT(msg != RT_NULL); - - /* send message to usb message queue */ - return rt_mq_send(&usb_mq, (void*)msg, sizeof(struct udev_msg)); -} - - -rt_align(RT_ALIGN_SIZE) -static rt_uint8_t usb_thread_stack[RT_USBD_THREAD_STACK_SZ]; -static struct rt_thread usb_thread; -#define USBD_MQ_MSG_SZ 32 -#define USBD_MQ_MAX_MSG 16 -/* internal of the message queue: every message is associated with a pointer, - * so in order to recveive USBD_MQ_MAX_MSG messages, we have to allocate more - * than USBD_MQ_MSG_SZ*USBD_MQ_MAX_MSG memory. */ -static rt_uint8_t usb_mq_pool[(USBD_MQ_MSG_SZ+sizeof(void*))*USBD_MQ_MAX_MSG]; - -/** - * This function will initialize usb device thread. - * - * @return none. - * - */ -rt_err_t rt_usbd_core_init(void) -{ - rt_list_init(&device_list); - - /* create an usb message queue */ - rt_mq_init(&usb_mq, - "usbd", - usb_mq_pool, USBD_MQ_MSG_SZ, - sizeof(usb_mq_pool), - RT_IPC_FLAG_FIFO); - - /* init usb device thread */ - rt_thread_init(&usb_thread, - "usbd", - rt_usbd_thread_entry, RT_NULL, - usb_thread_stack, RT_USBD_THREAD_STACK_SZ, - RT_USBD_THREAD_PRIO, 20); - /* rt_thread_init should always be OK, so start the thread without further - * checking. */ - return rt_thread_startup(&usb_thread); -} - |
