diff options
| author | sakumisu <[email protected]> | 2024-06-02 11:20:13 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-06-02 11:20:13 +0800 |
| commit | 62d321caa028dee04bf0b43fc0abb68b40e80ddd (patch) | |
| tree | 31fa88156af25b434a194398154dc8027d6b413d /components/drivers/usb/usbhost/core | |
| parent | 658813213e5ad1dc81739746f6001099c6cc9e41 (diff) | |
refactor(drivers/usb):replace rtt usb stack with cherryusb (#8799)
Diffstat (limited to 'components/drivers/usb/usbhost/core')
| -rw-r--r-- | components/drivers/usb/usbhost/core/driver.c | 147 | ||||
| -rw-r--r-- | components/drivers/usb/usbhost/core/hub.c | 727 | ||||
| -rw-r--r-- | components/drivers/usb/usbhost/core/usbhost.c | 76 | ||||
| -rw-r--r-- | components/drivers/usb/usbhost/core/usbhost_core.c | 586 |
4 files changed, 0 insertions, 1536 deletions
diff --git a/components/drivers/usb/usbhost/core/driver.c b/components/drivers/usb/usbhost/core/driver.c deleted file mode 100644 index 28a79dfa7f..0000000000 --- a/components/drivers/usb/usbhost/core/driver.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-03-12 Yi Qiu first version - * 2021-02-23 Leslie Lee provide possibility for multi usb host - */ - -#include <rtthread.h> -#include <rtservice.h> -#include <drivers/usb_host.h> - -static rt_list_t _driver_list; -static rt_bool_t _driver_list_created = RT_FALSE; - -/** - * This function will initilize the usb class driver related data structure, - * and it should be invoked in the usb system initialization. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_class_driver_init(void) -{ - if (_driver_list_created == RT_FALSE) - { - rt_list_init(&_driver_list); - _driver_list_created = RT_TRUE; - } - return RT_EOK; -} - -/** - * This function will register an usb class driver to the class driver manager. - * - * @param drv the pointer of the usb class driver. - * - * @return the error code, RT_EOK on successfully. - */ - -rt_err_t rt_usbh_class_driver_register(ucd_t drv) -{ - if (drv == RT_NULL) return -RT_ERROR; - - if (rt_usbh_class_driver_find(drv->class_code, drv->subclass_code) == RT_NULL) - { - /* insert class driver into driver list */ - rt_list_insert_after(&_driver_list, &(drv->list)); - } - - return RT_EOK; -} - -/** - * This function will removes a previously registed usb class driver. - * - * @param drv the pointer of the usb class driver structure. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_class_driver_unregister(ucd_t drv) -{ - RT_ASSERT(drv != RT_NULL); - - /* remove class driver from driver list */ - rt_list_remove(&(drv->list)); - - return RT_EOK; -} - -/** - * This function will run an usb class driver. - * - * @param drv the pointer of usb class driver. - * @param args the parameter of run function. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_class_driver_enable(ucd_t drv, void* args) -{ - RT_ASSERT(drv != RT_NULL); - - if(drv->enable != RT_NULL) - drv->enable(args); - - return RT_EOK; -} - -/** - * This function will stop a usb class driver. - * - * @param drv the pointer of usb class driver structure. - * @param args the argument of the stop function. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_class_driver_disable(ucd_t drv, void* args) -{ - RT_ASSERT(drv != RT_NULL); - - if(drv->disable != RT_NULL) - drv->disable(args); - - return RT_EOK; -} - - -/** - * This function finds a usb class driver by specified class code and subclass code. - * - * @param class_code the usb class driver's class code. - * @param subclass_code the usb class driver's sub class code. - * - * @return the registered usb class driver on successful, or RT_NULL on failure. - */ -ucd_t rt_usbh_class_driver_find(int class_code, int subclass_code) -{ - struct rt_list_node *node; - - /* enter critical */ - if (rt_thread_self() != RT_NULL) - rt_enter_critical(); - - /* try to find driver object */ - for (node = _driver_list.next; node != &_driver_list; node = node->next) - { - ucd_t drv = - (ucd_t)rt_list_entry(node, struct uclass_driver, list); - if (drv->class_code == class_code) - { - /* leave critical */ - if (rt_thread_self() != RT_NULL) - rt_exit_critical(); - - return drv; - } - } - - /* leave critical */ - if (rt_thread_self() != RT_NULL) - rt_exit_critical(); - - /* not found */ - return RT_NULL; -} diff --git a/components/drivers/usb/usbhost/core/hub.c b/components/drivers/usb/usbhost/core/hub.c deleted file mode 100644 index d8e6716099..0000000000 --- a/components/drivers/usb/usbhost/core/hub.c +++ /dev/null @@ -1,727 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-12-12 Yi Qiu first version - * 2021-02-23 Leslie Lee provide possibility for multi usb host - */ - -#include <rtthread.h> -#include <drivers/usb_host.h> - -#define USB_THREAD_STACK_SIZE 4096 - -#define DBG_TAG "usb.host.hub" -#define DBG_LVL DBG_INFO -#include <rtdbg.h> - - -// static struct rt_messagequeue *usb_mq; -static struct uclass_driver hub_driver; -// static struct uhub root_hub; - -static rt_err_t root_hub_ctrl(struct uhcd *hcd, rt_uint16_t port, rt_uint8_t cmd, void *args) -{ - switch(cmd) - { - case RH_GET_PORT_STATUS: - (*(rt_uint32_t *)args) = hcd->roothub->port_status[port-1]; - break; - case RH_SET_PORT_STATUS: - hcd->roothub->port_status[port-1] = (*(rt_uint32_t *)args); - break; - case RH_CLEAR_PORT_FEATURE: - switch(((rt_uint32_t)args)) - { - case PORT_FEAT_C_CONNECTION: - hcd->roothub->port_status[port-1] &= ~PORT_CCSC; - break; - case PORT_FEAT_C_ENABLE: - hcd->roothub->port_status[port-1] &= ~PORT_PESC; - break; - case PORT_FEAT_C_SUSPEND: - hcd->roothub->port_status[port-1] &= ~PORT_PSSC; - break; - case PORT_FEAT_C_OVER_CURRENT: - hcd->roothub->port_status[port-1] &= ~PORT_POCIC; - break; - case PORT_FEAT_C_RESET: - hcd->roothub->port_status[port-1] &= ~PORT_PRSC; - break; - } - break; - case RH_SET_PORT_FEATURE: - switch((rt_uint32_t)args) - { - case PORT_FEAT_CONNECTION: - hcd->roothub->port_status[port-1] |= PORT_CCSC; - break; - case PORT_FEAT_ENABLE: - hcd->roothub->port_status[port-1] |= PORT_PESC; - break; - case PORT_FEAT_SUSPEND: - hcd->roothub->port_status[port-1] |= PORT_PSSC; - break; - case PORT_FEAT_OVER_CURRENT: - hcd->roothub->port_status[port-1] |= PORT_POCIC; - break; - case PORT_FEAT_RESET: - hcd->ops->reset_port(port); - break; - case PORT_FEAT_POWER: - break; - case PORT_FEAT_LOWSPEED: - break; - case PORT_FEAT_HIGHSPEED: - break; - } - break; - default: - return -RT_ERROR; - } - return RT_EOK; -} -void rt_usbh_root_hub_connect_handler(struct uhcd *hcd, rt_uint8_t port, rt_bool_t isHS) -{ - struct uhost_msg msg; - msg.type = USB_MSG_CONNECT_CHANGE; - msg.content.hub = hcd->roothub; - hcd->roothub->port_status[port - 1] |= PORT_CCS | PORT_CCSC; - if(isHS) - { - hcd->roothub->port_status[port - 1] &= ~PORT_LSDA; - } - else - { - hcd->roothub->port_status[port - 1] |= PORT_LSDA; - } - rt_usbh_event_signal(hcd, &msg); -} - -void rt_usbh_root_hub_disconnect_handler(struct uhcd *hcd, rt_uint8_t port) -{ - struct uhost_msg msg; - msg.type = USB_MSG_CONNECT_CHANGE; - msg.content.hub = hcd->roothub; - hcd->roothub->port_status[port - 1] |= PORT_CCSC; - hcd->roothub->port_status[port - 1] &= ~PORT_CCS; - rt_usbh_event_signal(hcd, &msg); -} - -/** - * This function will do USB_REQ_GET_DESCRIPTOR bRequest for the device instance - * to get usb hub descriptor. - * - * @param intf the interface instance. - * @buffer the data buffer to save usb hub descriptor. - * @param nbytes the size of buffer - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_hub_get_descriptor(struct uinstance* device, rt_uint8_t *buffer, rt_size_t nbytes) -{ - struct urequest setup; - int timeout = USB_TIMEOUT_BASIC; - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - - setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_DEVICE; - setup.bRequest = USB_REQ_GET_DESCRIPTOR; - setup.wIndex = 0; - setup.wLength = nbytes; - setup.wValue = USB_DESC_TYPE_HUB << 8; - - if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) == 8) - { - if(rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, buffer, nbytes, timeout) == nbytes) - { - return RT_EOK; - } - } - return -RT_FALSE; -} - -/** - * This function will do USB_REQ_GET_STATUS bRequest for the device instance - * to get usb hub status. - * - * @param intf the interface instance. - * @buffer the data buffer to save usb hub status. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_hub_get_status(struct uinstance* device, rt_uint32_t* buffer) -{ - struct urequest setup; - int timeout = USB_TIMEOUT_BASIC; - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - - setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_DEVICE; - setup.bRequest = USB_REQ_GET_STATUS; - setup.wIndex = 0; - setup.wLength = 4; - setup.wValue = 0; - if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) == 8) - { - if(rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, buffer, 4, timeout) == 4) - { - return RT_EOK; - } - } - return -RT_FALSE; -} - -/** - * This function will do USB_REQ_GET_STATUS bRequest for the device instance - * to get hub port status. - * - * @param intf the interface instance. - * @port the hub port to get status. - * @buffer the data buffer to save usb hub status. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_hub_get_port_status(uhub_t hub, rt_uint16_t port, rt_uint32_t* buffer) -{ - struct urequest setup; - int timeout = USB_TIMEOUT_BASIC; - - /* parameter check */ - RT_ASSERT(hub != RT_NULL); - - /* get roothub port status */ - if(hub->is_roothub) - { - root_hub_ctrl(hub->hcd, port, RH_GET_PORT_STATUS, - (void*)buffer); - return RT_EOK; - } - - setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_OTHER; - setup.bRequest = USB_REQ_GET_STATUS; - setup.wIndex = port; - setup.wLength = 4; - setup.wValue = 0; - - if(rt_usb_hcd_setup_xfer(hub->hcd, hub->self->pipe_ep0_out, &setup, timeout) == 8) - { - if(rt_usb_hcd_pipe_xfer(hub->hcd, hub->self->pipe_ep0_in, buffer, 4, timeout) == 4) - { - return RT_EOK; - } - } - return -RT_FALSE; -} - -/** - * This function will do USB_REQ_CLEAR_FEATURE bRequest for the device instance - * to clear feature of the hub port. - * - * @param intf the interface instance. - * @port the hub port. - * @feature feature to be cleared. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_hub_clear_port_feature(uhub_t hub, rt_uint16_t port, rt_uint16_t feature) -{ - struct urequest setup; - int timeout = USB_TIMEOUT_BASIC; - - /* parameter check */ - RT_ASSERT(hub != RT_NULL); - - /* clear roothub feature */ - if(hub->is_roothub) - { - root_hub_ctrl(hub->hcd, port, RH_CLEAR_PORT_FEATURE, - (void*)(rt_uint32_t)feature); - return RT_EOK; - } - - setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_CLASS | - USB_REQ_TYPE_OTHER; - setup.bRequest = USB_REQ_CLEAR_FEATURE; - setup.wIndex = port; - setup.wLength = 0; - setup.wValue = feature; - - if(rt_usb_hcd_setup_xfer(hub->hcd, hub->self->pipe_ep0_out, &setup, timeout) == 8) - { - return RT_EOK; - } - return -RT_FALSE; -} - -/** - * This function will do USB_REQ_SET_FEATURE bRequest for the device instance - * to set feature of the hub port. - * - * @param intf the interface instance. - * @port the hub port. - * @feature feature to be set. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_hub_set_port_feature(uhub_t hub, rt_uint16_t port, - rt_uint16_t feature) -{ - struct urequest setup; - int timeout = USB_TIMEOUT_BASIC; - - /* parameter check */ - RT_ASSERT(hub != RT_NULL); - - /* clear roothub feature */ - if(hub->is_roothub) - { - root_hub_ctrl(hub->hcd, port, RH_SET_PORT_FEATURE, - (void*)(rt_uint32_t)feature); - return RT_EOK; - } - - setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_CLASS | - USB_REQ_TYPE_OTHER; - setup.bRequest = USB_REQ_SET_FEATURE; - setup.wIndex = port; - setup.wLength = 0; - setup.wValue = feature; - - if(rt_usb_hcd_setup_xfer(hub->hcd, hub->self->pipe_ep0_out, &setup, timeout) == 8) - { - return RT_EOK; - } - else return -RT_FALSE; -} - -/** - * This function will rest hub port, it is invoked when sub device attached to the hub port. - * - * @param intf the interface instance. - * @param port the hub port. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_hub_reset_port(uhub_t hub, rt_uint16_t port) -{ - rt_err_t ret; - rt_uint32_t pstatus; - - /* parameter check */ - RT_ASSERT(hub != RT_NULL); - - rt_thread_delay(50); - - /* reset hub port */ - ret = rt_usbh_hub_set_port_feature(hub, port, PORT_FEAT_RESET); - if(ret != RT_EOK) return ret; - - while(1) - { - ret = rt_usbh_hub_get_port_status(hub, port, &pstatus); - if(!(pstatus & PORT_PRS)) break; - } - - /* clear port reset feature */ - ret = rt_usbh_hub_clear_port_feature(hub, port, PORT_FEAT_C_RESET); - if(ret != RT_EOK) return ret; - - rt_thread_delay(50); - - return RT_EOK; -} - -/** - * This function will do debouce, it is invoked when sub device attached to the hub port. - * - * @param device the usb instance. - * @param port the hub port. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_hub_port_debounce(uhub_t hub, rt_uint16_t port) -{ - rt_err_t ret; - int i = 0, times = 20; - rt_uint32_t pstatus; - rt_bool_t connect = RT_TRUE; - int delayticks = USB_DEBOUNCE_TIME / times; - if (delayticks < 1) - delayticks = 1; - - /* parameter check */ - RT_ASSERT(hub != RT_NULL); - - for(i=0; i<times; i++) - { - ret = rt_usbh_hub_get_port_status(hub, port, &pstatus); - if(ret != RT_EOK) return ret; - - if(!(pstatus & PORT_CCS)) - { - connect = RT_FALSE; - break; - } - - rt_thread_delay(delayticks); - } - - if(connect) return RT_EOK; - else return -RT_ERROR; -} - -/** - * This function will poll all the hub ports to detect port status, especially connect and - * disconnect events. - * - * @param intf the interface instance. - * - * @return the error code, RT_EOK on successfully. - */ -static rt_err_t rt_usbh_hub_port_change(uhub_t hub) -{ - int i; - rt_bool_t reconnect; - - /* parameter check */ - RT_ASSERT(hub != RT_NULL); - - /* get usb device instance */ - for (i = 0; i < hub->num_ports; i++) - { - rt_err_t ret; - struct uinstance* device; - rt_uint32_t pstatus = 0; - - reconnect = RT_FALSE; - - /* get hub port status */ - ret = rt_usbh_hub_get_port_status(hub, i + 1, &pstatus); - if(ret != RT_EOK) continue; - - LOG_D("port %d status 0x%x", i + 1, pstatus); - - /* check port status change */ - if (pstatus & PORT_CCSC) - { - /* clear port status change feature */ - rt_usbh_hub_clear_port_feature(hub, i + 1, PORT_FEAT_C_CONNECTION); - reconnect = RT_TRUE; - } - - if(pstatus & PORT_PESC) - { - rt_usbh_hub_clear_port_feature(hub, i + 1, PORT_FEAT_C_ENABLE); - reconnect = RT_TRUE; - } - - if(reconnect) - { - if(hub->child[i] != RT_NULL && hub->child[i]->status != DEV_STATUS_IDLE) - { - rt_usbh_detach_instance(hub->child[i]); - - /* Child device have been detach. Set hub->child[i] to NULL. */ - hub->child[i] = RT_NULL; - } - - ret = rt_usbh_hub_port_debounce(hub, i + 1); - if(ret != RT_EOK) continue; - - /* allocate an usb instance for new connected device */ - device = rt_usbh_alloc_instance(hub->hcd); - if(device == RT_NULL) break; - - /* set usb device speed */ - device->speed = (pstatus & PORT_LSDA) ? 1 : 0; - device->parent_hub = hub; - device->hcd = hub->hcd; - device->port = i + 1; - hub->child[i] = device; - - /* reset usb roothub port */ - rt_usbh_hub_reset_port(hub, i + 1); - - /* attatch the usb instance to the hcd */ - rt_usbh_attatch_instance(device); - } - } - - return RT_EOK; -} - -/** - * This function is the callback function of hub's int endpoint, it is invoked when data comes. - * - * @param context the context of the callback function. - * - * @return none. - */ -static void rt_usbh_hub_irq(void* context) -{ - upipe_t pipe; - uhub_t hub; - int timeout = USB_TIMEOUT_BASIC; - - RT_ASSERT(context != RT_NULL); - - pipe = (upipe_t)context; - hub = (uhub_t)pipe->user_data; - - if(pipe->status != UPIPE_STATUS_OK) - { - LOG_D("hub irq error"); - return; - } - - rt_usbh_hub_port_change(hub); - - LOG_D("hub int xfer..."); - - /* parameter check */ - RT_ASSERT(pipe->inst->hcd != RT_NULL); - - rt_usb_hcd_pipe_xfer(hub->self->hcd, pipe, hub->buffer, pipe->ep.wMaxPacketSize, timeout); -} - -/** - * This function will run usb hub class driver when usb hub is detected and identified - * as a hub class device, it will continue to do the enumulate process. - * - * @param arg the argument. - * - * @return the error code, RT_EOK on successfully. - */ - -static rt_err_t rt_usbh_hub_enable(void *arg) -{ - int i = 0; - rt_err_t ret = RT_EOK; - uep_desc_t ep_desc = RT_NULL; - uhub_t hub; - struct uinstance* device; - struct uhintf* intf = (struct uhintf*)arg; - upipe_t pipe_in = RT_NULL; - int timeout = USB_TIMEOUT_LONG; - /* paremeter check */ - RT_ASSERT(intf != RT_NULL); - - /* get usb device instance */ - device = intf->device; - - /* create a hub instance */ - hub = rt_malloc(sizeof(struct uhub)); - RT_ASSERT(hub != RT_NULL); - rt_memset(hub, 0, sizeof(struct uhub)); - - /* make interface instance's user data point to hub instance */ - intf->user_data = (void*)hub; - - /* get hub descriptor head */ - ret = rt_usbh_hub_get_descriptor(device, (rt_uint8_t*)&hub->hub_desc, 8); - if(ret != RT_EOK) - { - rt_kprintf("get hub descriptor failed\n"); - return -RT_ERROR; - } - - /* get full hub descriptor */ - ret = rt_usbh_hub_get_descriptor(device, (rt_uint8_t*)&hub->hub_desc, - hub->hub_desc.length); - if(ret != RT_EOK) - { - rt_kprintf("get hub descriptor again failed\n"); - return -RT_ERROR; - } - - /* get hub ports number */ - /* If hub device supported ports over USB_HUB_PORT_NUM(Ex: 8 port hub). Set hub->num_ports to USB_HUB_PORT_NUM */ - if(hub->hub_desc.num_ports > USB_HUB_PORT_NUM) - hub->num_ports = USB_HUB_PORT_NUM; - else - hub->num_ports = hub->hub_desc.num_ports; - - hub->hcd = device->hcd; - hub->self = device; - - /* reset all hub ports */ - for (i = 0; i < hub->num_ports; i++) - { - rt_usbh_hub_set_port_feature(hub, i + 1, PORT_FEAT_POWER); - rt_thread_delay(hub->hub_desc.pwron_to_good - * 2 * RT_TICK_PER_SECOND / 1000 ); - } - - if(intf->intf_desc->bNumEndpoints != 1) - return -RT_ERROR; - - /* get endpoint descriptor from interface descriptor */ - rt_usbh_get_endpoint_descriptor(intf->intf_desc, 0, &ep_desc); - if(ep_desc == RT_NULL) - { - rt_kprintf("rt_usb_get_endpoint_descriptor error\n"); - return -RT_ERROR; - } - - /* the endpoint type of hub class should be interrupt */ - if( USB_EP_ATTR(ep_desc->bmAttributes) == USB_EP_ATTR_INT) - { - /* the endpoint direction of hub class should be in */ - if(ep_desc->bEndpointAddress & USB_DIR_IN) - { - /* allocate a pipe according to the endpoint type */ - pipe_in = rt_usb_instance_find_pipe(device,ep_desc->bEndpointAddress); - if(pipe_in == RT_NULL) - { - return -RT_ERROR; - } - rt_usb_pipe_add_callback(pipe_in,rt_usbh_hub_irq); - } - else return -RT_ERROR; - } - - /* parameter check */ - RT_ASSERT(device->hcd != RT_NULL); - pipe_in->user_data = hub; - rt_usb_hcd_pipe_xfer(hub->hcd, pipe_in, hub->buffer, - pipe_in->ep.wMaxPacketSize, timeout); - return RT_EOK; -} - -/** - * This function will be invoked when usb hub plug out is detected and it would clean - * and release all hub class related resources. - * - * @param arg the argument. - * - * @return the error code, RT_EOK on successfully. - */ -static rt_err_t rt_usbh_hub_disable(void* arg) -{ - int i; - uhub_t hub; - struct uhintf* intf = (struct uhintf*)arg; - - /* paremeter check */ - RT_ASSERT(intf != RT_NULL); - - LOG_D("rt_usbh_hub_stop"); - hub = (uhub_t)intf->user_data; - - for(i=0; i<hub->num_ports; i++) - { - if(hub->child[i] != RT_NULL) - rt_usbh_detach_instance(hub->child[i]); - } - - if(hub != RT_NULL) rt_free(hub); - - return RT_EOK; -} - -/** - * This function will register hub class driver to the usb class driver manager. - * and it should be invoked in the usb system initialization. - * - * @return the error code, RT_EOK on successfully. - */ -ucd_t rt_usbh_class_driver_hub(void) -{ - hub_driver.class_code = USB_CLASS_HUB; - - hub_driver.enable = rt_usbh_hub_enable; - hub_driver.disable = rt_usbh_hub_disable; - - return &hub_driver; -} - -/** - * This function is the main entry of usb hub thread, it is in charge of - * processing all messages received from the usb message buffer. - * - * @param parameter the parameter of the usb host thread. - * - * @return none. - */ -static void rt_usbh_hub_thread_entry(void* parameter) -{ - uhcd_t hcd = (uhcd_t)parameter; - while(1) - { - struct uhost_msg msg; - - /* receive message */ - if (rt_mq_recv(hcd->usb_mq, &msg, sizeof(struct uhost_msg), RT_WAITING_FOREVER) < 0) - continue; - - switch (msg.type) - { - case USB_MSG_CONNECT_CHANGE: - rt_usbh_hub_port_change(msg.content.hub); - break; - case USB_MSG_CALLBACK: - /* invoke callback */ - msg.content.cb.function(msg.content.cb.context); - break; - default: - break; - } - } -} - -/** - * This function will post an message to the usb message queue, - * - * @param msg the message to be posted - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_event_signal(uhcd_t hcd, struct uhost_msg* msg) -{ - RT_ASSERT(msg != RT_NULL); - - /* send message to usb message queue */ - rt_mq_send(hcd->usb_mq, (void*)msg, sizeof(struct uhost_msg)); - - return RT_EOK; -} - -/** - * This function will initialize usb hub thread. - * - * @return none. - * - */ -void rt_usbh_hub_init(uhcd_t hcd) -{ - rt_thread_t thread; - /* create root hub for hcd */ - hcd->roothub = rt_malloc(sizeof(struct uhub)); - if(hcd->roothub == RT_NULL) - { - LOG_E("hcd->roothub: allocate buffer failed."); - return; - } - rt_memset(hcd->roothub, 0, sizeof(struct uhub)); - hcd->roothub->is_roothub = RT_TRUE; - hcd->roothub->hcd = hcd; - hcd->roothub->num_ports = hcd->num_ports; - /* create usb message queue */ - - hcd->usb_mq = rt_mq_create(hcd->parent.parent.name, 32, 16, RT_IPC_FLAG_FIFO); - - /* create usb hub thread */ - thread = rt_thread_create(hcd->parent.parent.name, rt_usbh_hub_thread_entry, hcd, - USB_THREAD_STACK_SIZE, 8, 20); - if(thread != RT_NULL) - { - /* startup usb host thread */ - rt_thread_startup(thread); - } -} diff --git a/components/drivers/usb/usbhost/core/usbhost.c b/components/drivers/usb/usbhost/core/usbhost.c deleted file mode 100644 index a4cdc12e5e..0000000000 --- a/components/drivers/usb/usbhost/core/usbhost.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-12-12 Yi Qiu first version - * 2021-02-23 Leslie Lee provide possibility for multi usb host - */ -#include <rtthread.h> -#include <drivers/usb_host.h> - -#define USB_HOST_CONTROLLER_NAME "usbh" - -#if defined(RT_USBH_HID_KEYBOARD) || defined(RT_USBH_HID_MOUSE) -#include <hid.h> -#endif - -/** - * This function will initialize the usb host stack, all the usb class driver and - * host controller driver are also be initialized here. - * - * @return none. - */ -rt_err_t rt_usb_host_init(const char *name) -{ - ucd_t drv; - rt_device_t uhc; - - uhc = rt_device_find(name); - if(uhc == RT_NULL) - { - rt_kprintf("can't find usb host controller %s\n", name); - return -RT_ERROR; - } - - /* initialize usb hub */ - rt_usbh_hub_init((uhcd_t)uhc); - - /* initialize class driver */ - rt_usbh_class_driver_init(); - -#ifdef RT_USBH_MSTORAGE - /* register mass storage class driver */ - drv = rt_usbh_class_driver_storage(); - rt_usbh_class_driver_register(drv); -#endif -#ifdef RT_USBH_HID - extern ucd_t rt_usbh_class_driver_hid(void); - /* register mass storage class driver */ - drv = rt_usbh_class_driver_hid(); - rt_usbh_class_driver_register(drv); -#ifdef RT_USBH_HID_MOUSE - { - extern uprotocal_t rt_usbh_hid_protocal_mouse(void); - rt_usbh_hid_protocal_register(rt_usbh_hid_protocal_mouse()); - } -#endif -#ifdef RT_USBH_HID_KEYBOARD - { - extern uprotocal_t rt_usbh_hid_protocal_kbd(void); - rt_usbh_hid_protocal_register(rt_usbh_hid_protocal_kbd()); - } -#endif -#endif - - /* register hub class driver */ - drv = rt_usbh_class_driver_hub(); - rt_usbh_class_driver_register(drv); - - /* initialize usb host controller */ - rt_device_init(uhc); - - return RT_EOK; -} diff --git a/components/drivers/usb/usbhost/core/usbhost_core.c b/components/drivers/usb/usbhost/core/usbhost_core.c deleted file mode 100644 index fae5ba75fb..0000000000 --- a/components/drivers/usb/usbhost/core/usbhost_core.c +++ /dev/null @@ -1,586 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-12-12 Yi Qiu first version - */ - -#include <rtthread.h> -#include <drivers/usb_host.h> - -#define DBG_TAG "usbhost.core" -#define DBG_LVL DBG_INFO -#include <rtdbg.h> - -static struct uinstance dev[USB_MAX_DEVICE]; - -/** - * This function will allocate an usb device instance from system. - * - * @param parent the hub instance to which the new allocated device attached. - * @param port the hub port. - * - * @return the allocate instance on successful, or RT_NULL on failure. - */ -uinst_t rt_usbh_alloc_instance(uhcd_t uhcd) -{ - int i; - - /* lock scheduler */ - rt_enter_critical(); - - for(i=0; i<USB_MAX_DEVICE; i++) - { - /* to find an idle instance handle */ - if(dev[i].status != DEV_STATUS_IDLE) continue; - - /* initialize the usb device instance */ - rt_memset(&dev[i], 0, sizeof(struct uinstance)); - - dev[i].status = DEV_STATUS_BUSY; - dev[i].index = i + 1; - dev[i].address = 0; - dev[i].max_packet_size = 0x8; - rt_list_init(&dev[i].pipe); - dev[i].hcd = uhcd; - /* unlock scheduler */ - rt_exit_critical(); - return &dev[i]; - } - - /* unlock scheduler */ - rt_exit_critical(); - - return RT_NULL; -} - -/** - * This function will attatch an usb device instance to a host controller, - * and do device enumunation process. - * - * @param hcd the host controller driver. - * @param device the usb device instance. - * - * @return the error code, RT_EOK on successfully. - */ -static struct uendpoint_descriptor ep0_out_desc = -{ - /*endpoint descriptor*/ - USB_DESC_LENGTH_ENDPOINT, - USB_DESC_TYPE_ENDPOINT, - 0x00 | USB_DIR_OUT, - USB_EP_ATTR_CONTROL, - 0x00, - 0x00, -}; -static struct uendpoint_descriptor ep0_in_desc = -{ - /*endpoint descriptor*/ - USB_DESC_LENGTH_ENDPOINT, - USB_DESC_TYPE_ENDPOINT, - 0x00 | USB_DIR_IN, - USB_EP_ATTR_CONTROL, - 0x00, - 0x00, -}; -rt_err_t rt_usbh_attatch_instance(uinst_t device) -{ - int i = 0; - rt_err_t ret = RT_EOK; - struct uconfig_descriptor cfg_desc; - udev_desc_t dev_desc; - uintf_desc_t intf_desc; - uep_desc_t ep_desc; - rt_uint8_t ep_index; - upipe_t pipe; - ucd_t drv; - - RT_ASSERT(device != RT_NULL); - - rt_memset(&cfg_desc, 0, sizeof(struct uconfig_descriptor)); - dev_desc = &device->dev_desc; - - /* alloc address 0 ep0 pipe*/ - ep0_out_desc.wMaxPacketSize = 8; - ep0_in_desc.wMaxPacketSize = 8; - rt_usb_hcd_alloc_pipe(device->hcd, &device->pipe_ep0_out, device, &ep0_out_desc); - rt_usb_hcd_alloc_pipe(device->hcd, &device->pipe_ep0_in, device, &ep0_in_desc); - - LOG_D("start enumnation"); - - /* get device descriptor head */ - ret = rt_usbh_get_descriptor(device, USB_DESC_TYPE_DEVICE, (void*)dev_desc, 8); - if(ret != RT_EOK) - { - rt_kprintf("get device descriptor head failed\n"); - return ret; - } - - /* reset bus */ - rt_usbh_hub_reset_port(device->parent_hub, device->port); - rt_thread_delay(2); - rt_usbh_hub_clear_port_feature(device->parent_hub, i + 1, PORT_FEAT_C_CONNECTION); - /* set device address */ - ret = rt_usbh_set_address(device); - if(ret != RT_EOK) - { - rt_kprintf("set device address failed\n"); - return ret; - } - /* free address 0 ep0 pipe*/ - - rt_usb_hcd_free_pipe(device->hcd,device->pipe_ep0_out); - rt_usb_hcd_free_pipe(device->hcd,device->pipe_ep0_in); - - /* set device max packet size */ - ep0_out_desc.wMaxPacketSize = device->dev_desc.bMaxPacketSize0; - ep0_in_desc.wMaxPacketSize = device->dev_desc.bMaxPacketSize0; - - /* alloc true address ep0 pipe*/ - rt_usb_hcd_alloc_pipe(device->hcd, &device->pipe_ep0_out, device, &ep0_out_desc); - rt_usb_hcd_alloc_pipe(device->hcd, &device->pipe_ep0_in, device, &ep0_in_desc); - LOG_D("get device descriptor length %d", - dev_desc->bLength); - - /* get full device descriptor again */ - ret = rt_usbh_get_descriptor(device, USB_DESC_TYPE_DEVICE, (void*)dev_desc, dev_desc->bLength); - if(ret != RT_EOK) - { - rt_kprintf("get full device descriptor failed\n"); - return ret; - } - - LOG_D("Vendor ID 0x%x", dev_desc->idVendor); - LOG_D("Product ID 0x%x", dev_desc->idProduct); - - /* get configuration descriptor head */ - ret = rt_usbh_get_descriptor(device, USB_DESC_TYPE_CONFIGURATION, &cfg_desc, 18); - if(ret != RT_EOK) - { - rt_kprintf("get configuration descriptor head failed\n"); - return ret; - } - - /* alloc memory for configuration descriptor */ - device->cfg_desc = (ucfg_desc_t)rt_malloc(cfg_desc.wTotalLength); - if(device->cfg_desc == RT_NULL) - { - return -RT_ENOMEM; - } - rt_memset(device->cfg_desc, 0, cfg_desc.wTotalLength); - - /* get full configuration descriptor */ - ret = rt_usbh_get_descriptor(device, USB_DESC_TYPE_CONFIGURATION, - device->cfg_desc, cfg_desc.wTotalLength); - if(ret != RT_EOK) - { - rt_kprintf("get full configuration descriptor failed\n"); - return ret; - } - - /* set configuration */ - ret = rt_usbh_set_configure(device, 1); - if(ret != RT_EOK) - { - return ret; - } - for(i=0; i<device->cfg_desc->bNumInterfaces; i++) - { - /* get interface descriptor through configuration descriptor */ - ret = rt_usbh_get_interface_descriptor(device->cfg_desc, i, &intf_desc); - if(ret != RT_EOK) - { - rt_kprintf("rt_usb_get_interface_descriptor error\n"); - return -RT_ERROR; - } - - LOG_D("interface class 0x%x, subclass 0x%x", - intf_desc->bInterfaceClass, - intf_desc->bInterfaceSubClass); - /* alloc pipe*/ - for(ep_index = 0; ep_index < intf_desc->bNumEndpoints; ep_index++) - { - rt_usbh_get_endpoint_descriptor(intf_desc, ep_index, &ep_desc); - if(ep_desc != RT_NULL) - { - if(rt_usb_hcd_alloc_pipe(device->hcd, &pipe, device, ep_desc) != RT_EOK) - { - rt_kprintf("alloc pipe failed\n"); - return -RT_ERROR; - } - rt_usb_instance_add_pipe(device,pipe); - } - else - { - rt_kprintf("get endpoint desc failed\n"); - return -RT_ERROR; - } - } - /* find driver by class code found in interface descriptor */ - drv = rt_usbh_class_driver_find(intf_desc->bInterfaceClass, - intf_desc->bInterfaceSubClass); - - if(drv != RT_NULL) - { - /* allocate memory for interface device */ - device->intf[i] = (struct uhintf*)rt_malloc(sizeof(struct uhintf)); - if(device->intf[i] == RT_NULL) - { - return -RT_ENOMEM; - } - device->intf[i]->drv = drv; - device->intf[i]->device = device; - device->intf[i]->intf_desc = intf_desc; - device->intf[i]->user_data = RT_NULL; - - /* open usb class driver */ - ret = rt_usbh_class_driver_enable(drv, (void*)device->intf[i]); - if(ret != RT_EOK) - { - rt_kprintf("interface %d run class driver error\n", i); - } - } - else - { - rt_kprintf("find usb device driver failed\n"); - continue; - } - } - - return RT_EOK; -} - -/** - * This function will detach an usb device instance from its host controller, - * and release all resource. - * - * @param device the usb device instance. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_detach_instance(uinst_t device) -{ - int i = 0; - rt_list_t * l; - if(device == RT_NULL) - { - rt_kprintf("no usb instance to detach\n"); - return -RT_ERROR; - } - - /* free configration descriptor */ - if (device->cfg_desc) { - for (i = 0; i < device->cfg_desc->bNumInterfaces; i++) - { - if (device->intf[i] == RT_NULL) continue; - if (device->intf[i]->drv == RT_NULL) continue; - - RT_ASSERT(device->intf[i]->device == device); - - LOG_D("free interface instance %d", i); - rt_usbh_class_driver_disable(device->intf[i]->drv, (void*)device->intf[i]); - rt_free(device->intf[i]); - } - rt_free(device->cfg_desc); - } - - rt_usb_hcd_free_pipe(device->hcd,device->pipe_ep0_out); - rt_usb_hcd_free_pipe(device->hcd,device->pipe_ep0_in); - - while(device->pipe.next!= &device->pipe) - { - l = device->pipe.next; - rt_list_remove(l); - rt_usb_hcd_free_pipe(device->hcd,rt_list_entry(l,struct upipe,list)); - } - rt_memset(device, 0, sizeof(struct uinstance)); - - return RT_EOK; -} - -/** - * This function will do USB_REQ_GET_DESCRIPTO' bRequest for the usb device instance, - * - * @param device the usb device instance. - * @param type the type of descriptor bRequest. - * @param buffer the data buffer to save requested data - * @param nbytes the size of buffer - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_get_descriptor(uinst_t device, rt_uint8_t type, void* buffer, - int nbytes) -{ - struct urequest setup; - int timeout = USB_TIMEOUT_BASIC; - - RT_ASSERT(device != RT_NULL); - - setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_STANDARD | - USB_REQ_TYPE_DEVICE; - setup.bRequest = USB_REQ_GET_DESCRIPTOR; - setup.wIndex = 0; - setup.wLength = nbytes; - setup.wValue = type << 8; - - if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) == 8) - { - if(rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, buffer, nbytes, timeout) == nbytes) - { - if(rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_out, RT_NULL, 0, timeout) == 0) - { - return RT_EOK; - } - } - } - return -RT_ERROR; -} - -/** - * This function will set an address to the usb device. - * - * @param device the usb device instance. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_set_address(uinst_t device) -{ - struct urequest setup; - int timeout = USB_TIMEOUT_BASIC; - - RT_ASSERT(device != RT_NULL); - - LOG_D("rt_usb_set_address"); - - setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_STANDARD | - USB_REQ_TYPE_DEVICE; - setup.bRequest = USB_REQ_SET_ADDRESS; - setup.wIndex = 0; - setup.wLength = 0; - setup.wValue = device->index; - - if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) != 8) - { - return -RT_ERROR; - } - if(rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, RT_NULL, 0, timeout) == 0) - { - device->address = device->index; - } - - return RT_EOK; -} - -/** - * This function will set a configuration to the usb device. - * - * @param device the usb device instance. - * @param config the configuration number. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_set_configure(uinst_t device, int config) -{ - struct urequest setup; - int timeout = USB_TIMEOUT_BASIC; - - /* check parameter */ - RT_ASSERT(device != RT_NULL); - - setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_STANDARD | - USB_REQ_TYPE_DEVICE; - setup.bRequest = USB_REQ_SET_CONFIGURATION; - setup.wIndex = 0; - setup.wLength = 0; - setup.wValue = config; - - if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) != 8) - { - return -RT_ERROR; - } - if(rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, RT_NULL, 0, timeout) != 0) - { - return -RT_ERROR; - } - return RT_EOK; -} - -/** - * This function will set an interface to the usb device. - * - * @param device the usb device instance. - * @param intf the interface number. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_set_interface(uinst_t device, int intf) -{ - struct urequest setup; - int timeout = USB_TIMEOUT_BASIC; - - /* check parameter */ - RT_ASSERT(device != RT_NULL); - - setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_STANDARD | - USB_REQ_TYPE_INTERFACE; - setup.bRequest = USB_REQ_SET_INTERFACE; - setup.wIndex = 0; - setup.wLength = 0; - setup.wValue = intf; - - if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) != 8) - { - return -RT_ERROR; - } - - return RT_EOK; -} - -/** - * This function will clear feature for the endpoint of the usb device. - * - * @param device the usb device instance. - * @param endpoint the endpoint number of the usb device. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_clear_feature(uinst_t device, int endpoint, int feature) -{ - struct urequest setup; - int timeout = USB_TIMEOUT_BASIC; - - /* check parameter */ - RT_ASSERT(device != RT_NULL); - - setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_STANDARD | - USB_REQ_TYPE_ENDPOINT; - setup.bRequest = USB_REQ_CLEAR_FEATURE; - setup.wIndex = endpoint; - setup.wLength = 0; - setup.wValue = feature; - - if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) != 8) - { - return -RT_ERROR; - } - - return RT_EOK; -} - -/** - * This function will get an interface descriptor from the configuration descriptor. - * - * @param cfg_desc the point of configuration descriptor structure. - * @param num the number of interface descriptor. - * @intf_desc the point of interface descriptor point. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_get_interface_descriptor(ucfg_desc_t cfg_desc, int num, - uintf_desc_t* intf_desc) -{ - rt_uint32_t ptr, depth = 0; - udesc_t desc; - - /* check parameter */ - RT_ASSERT(cfg_desc != RT_NULL); - - ptr = (rt_uint32_t)cfg_desc + cfg_desc->bLength; - while(ptr < (rt_uint32_t)cfg_desc + cfg_desc->wTotalLength) - { - if(depth++ > 0x20) - { - *intf_desc = RT_NULL; - return -RT_EIO; - } - desc = (udesc_t)ptr; - if(desc->type == USB_DESC_TYPE_INTERFACE) - { - if(((uintf_desc_t)desc)->bInterfaceNumber == num) - { - *intf_desc = (uintf_desc_t)desc; - - LOG_D("rt_usb_get_interface_descriptor: %d", num); - return RT_EOK; - } - } - ptr = (rt_uint32_t)desc + desc->bLength; - } - - rt_kprintf("rt_usb_get_interface_descriptor %d failed\n", num); - return -RT_EIO; -} - -/** - * This function will get an endpoint descriptor from the interface descriptor. - * - * @param intf_desc the point of interface descriptor structure. - * @param num the number of endpoint descriptor. - * @param ep_desc the point of endpoint descriptor point. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_get_endpoint_descriptor(uintf_desc_t intf_desc, int num, - uep_desc_t* ep_desc) -{ - int count = 0, depth = 0; - rt_uint32_t ptr; - udesc_t desc; - - /* check parameter */ - RT_ASSERT(intf_desc != RT_NULL); - RT_ASSERT(num < intf_desc->bNumEndpoints); - *ep_desc = RT_NULL; - - ptr = (rt_uint32_t)intf_desc + intf_desc->bLength; - while(count < intf_desc->bNumEndpoints) - { - if(depth++ > 0x20) - { - *ep_desc = RT_NULL; - return -RT_EIO; - } - desc = (udesc_t)ptr; - if(desc->type == USB_DESC_TYPE_ENDPOINT) - { - if(num == count) - { - *ep_desc = (uep_desc_t)desc; - - LOG_D("rt_usb_get_endpoint_descriptor: %d", num); - return RT_EOK; - } - else count++; - } - ptr = (rt_uint32_t)desc + desc->bLength; - } - - rt_kprintf("rt_usb_get_endpoint_descriptor %d failed\n", num); - return -RT_EIO; -} - -int rt_usb_hcd_pipe_xfer(uhcd_t hcd, upipe_t pipe, void* buffer, int nbytes, int timeout) -{ - rt_size_t remain_size; - rt_size_t send_size; - remain_size = nbytes; - rt_uint8_t * pbuffer = (rt_uint8_t *)buffer; - do - { - LOG_D("pipe transform remain size,: %d", remain_size); - send_size = (remain_size > pipe->ep.wMaxPacketSize) ? pipe->ep.wMaxPacketSize : remain_size; - if(hcd->ops->pipe_xfer(pipe, USBH_PID_DATA, pbuffer, send_size, timeout) == send_size) - { - remain_size -= send_size; - pbuffer += send_size; - } - else - { - return 0; - } - }while(remain_size > 0); - return nbytes; -} |
