diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/class/hub/usb_hub.h b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/class/hub/usb_hub.h index de5074663..d66b40a25 100644 --- a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/class/hub/usb_hub.h +++ b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/class/hub/usb_hub.h @@ -1,6 +1,124 @@ +/* + * Copyright (c) 2022, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef USB_HUB_H_ #define USB_HUB_H_ +#include + +/* HUB Class Descriptor Types */ +#define HUB_DESCRIPTOR_TYPE_HUB 0x29 +#define HUB_DESCRIPTOR_TYPE_HUB3 0x2a + +/* Hub class requests */ +#define HUB_REQUEST_GET_STATUS USB_REQUEST_GET_STATUS +#define HUB_REQUEST_CLEAR_FEATURE USB_REQUEST_CLEAR_FEATURE +#define HUB_REQUEST_SET_FEATURE USB_REQUEST_SET_FEATURE +#define HUB_REQUEST_GET_DESCRIPTOR USB_REQUEST_GET_DESCRIPTOR +#define HUB_REQUEST_SET_DESCRIPTOR USB_REQUEST_SET_DESCRIPTOR +#define HUB_REQUEST_CLEAR_TT_BUFFER (0x08) +#define HUB_REQUEST_RESET_TT (0x09) +#define HUB_REQUEST_GET_TT_STATE (0x0a) +#define HUB_REQUEST_STOP_TT (0x0b) +#define HUB_REQUEST_SET_HUB_DEPTH (0x0C) + +/* Hub class features */ +#define HUB_FEATURE_HUB_C_LOCALPOWER (0x0) +#define HUB_FEATURE_HUB_C_OVERCURRENT (0x1) + +/* Port features */ +#define HUB_PORT_FEATURE_CONNECTION (0x00) +#define HUB_PORT_FEATURE_ENABLE (0x01) +#define HUB_PORT_FEATURE_SUSPEND (0x02) +#define HUB_PORT_FEATURE_OVERCURRENT (0x03) +#define HUB_PORT_FEATURE_RESET (0x04) +#define HUB_PORT_FEATURE_L1 (0x05) +#define HUB_PORT_FEATURE_POWER (0x08) +#define HUB_PORT_FEATURE_LOWSPEED (0x09) +#define HUB_PORT_FEATURE_HIGHSPEED (0x0a) +#define HUB_PORT_FEATURE_C_CONNECTION (0x10) +#define HUB_PORT_FEATURE_C_ENABLE (0x11) +#define HUB_PORT_FEATURE_C_SUSPEND (0x12) +#define HUB_PORT_FEATURE_C_OVER_CURREN (0x13) +#define HUB_PORT_FEATURE_C_RESET (0x14) +#define HUB_PORT_FEATURE_TEST (0x15) +#define HUB_PORT_FEATURE_INDICATOR (0x16) +#define HUB_PORT_FEATURE_C_PORTL1 (0x17) + +/* Hub status */ +#define HUB_STATUS_LOCALPOWER (1 << 0) +#define HUB_STATUS_OVERCURRENT (1 << 1) + +/* Hub status change */ +#define HUB_STATUS_C_LOCALPOWER (1 << 0) +#define HUB_STATUS_C_OVERCURRENT (1 << 1) + +/* Hub port status */ +#define HUB_PORT_STATUS_CONNECTION (1 << 0) +#define HUB_PORT_STATUS_ENABLE (1 << 1) +#define HUB_PORT_STATUS_SUSPEND (1 << 2) +#define HUB_PORT_STATUS_OVERCURRENT (1 << 3) +#define HUB_PORT_STATUS_RESET (1 << 4) +#define HUB_PORT_STATUS_L1 (1 << 5) +#define HUB_PORT_STATUS_POWER (1 << 8) +#define HUB_PORT_STATUS_LOW_SPEED (1 << 9) +#define HUB_PORT_STATUS_HIGH_SPEED (1 << 10) +#define HUB_PORT_STATUS_TEST (1 << 11) +#define HUB_PORT_STATUS_INDICATOR (1 << 12) + +/* Hub port status change */ +#define HUB_PORT_STATUS_C_CONNECTION (1 << 0) +#define HUB_PORT_STATUS_C_ENABLE (1 << 1) +#define HUB_PORT_STATUS_C_SUSPEND (1 << 2) +#define HUB_PORT_STATUS_C_OVERCURRENT (1 << 3) +#define HUB_PORT_STATUS_C_RESET (1 << 4) +#define HUB_PORT_STATUS_C_L1 (1 << 5) + +/* Hub characteristics */ +#define HUB_CHAR_LPSM_SHIFT (0) /* Bits 0-1: Logical Power Switching Mode */ +#define HUB_CHAR_LPSM_MASK (3 << HUB_CHAR_LPSM_SHIFT) +#define HUB_CHAR_LPSM_GANGED (0 << HUB_CHAR_LPSM_SHIFT) +#define HUB_CHAR_LPSM_INDIVIDUAL (1 << HUB_CHAR_LPSM_SHIFT) +#define HUB_CHAR_COMPOUND (1 << 2) /* Bit 2: Compound device */ +#define HUB_CHAR_OCPM_SHIFT (3) /* Bits 3-4: Over-current Protection Mode */ +#define HUB_CHAR_OCPM_MASK (3 << HUB_CHAR_OCPM_SHIFT) +#define HUB_CHAR_OCPM_GLOBAL (0 << HUB_CHAR_OCPM_SHIFT) +#define HUB_CHAR_OCPM_INDIVIDUAL (1 << HUB_CHAR_OCPM_SHIFT) +#define HUB_CHAR_TTTT_SHIFT (5) /* Bits 5-6: TT Think Time */ +#define HUB_CHAR_TTTT_MASK (3 << HUB_CHAR_TTTT_SHIFT) +#define HUB_CHAR_TTTT_8_BITS (0 << HUB_CHAR_TTTT_SHIFT) +#define HUB_CHAR_TTTT_16_BITS (1 << HUB_CHAR_TTTT_SHIFT) +#define HUB_CHAR_TTTT_24_BITS (2 << HUB_CHAR_TTTT_SHIFT) +#define HUB_CHAR_TTTT_32_BITS (3 << HUB_CHAR_TTTT_SHIFT) +#define HUB_CHAR_PORTIND (1 << 7) /* Bit 7: Port Indicators Supported */ + +/* Hub descriptor */ +struct usb_hub_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bNbrPorts; + uint16_t wHubCharacteristics; + uint8_t bPwrOn2PwrGood; + uint8_t bHubContrCurrent; + uint8_t DeviceRemovable; + uint8_t PortPwrCtrlMask; +} __PACKED; + +#define USB_SIZEOF_HUB_DESC 9 + +/* Hub status */ +struct hub_status { + uint16_t wPortStatus; + uint16_t wPortChange; +}; + +/* Hub port status */ +struct hub_port_status { + uint16_t wPortStatus; + uint16_t wPortChange; +}; diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/class/hub/usbh_hub.h b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/class/hub/usbh_hub.h index 1ea7bf19f..08dcfa7b7 100644 --- a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/class/hub/usbh_hub.h +++ b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/class/hub/usbh_hub.h @@ -1,9 +1,25 @@ +/* + * Copyright (c) 2022, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef USBH_HUB_H_ #define USBH_HUB_H_ +#include "usbh_core.h" #include "usb_hub.h" +#ifdef __cplusplus +extern "C" { +#endif +void usbh_roothub_thread_wakeup(uint32_t usb_id, uint8_t port); +int usbh_hub_initialize(struct usbh_bus *usb); +struct usbh_hubport *usbh_get_roothub_port (struct usbh_bus *bus, unsigned int port); + +#ifdef __cplusplus +} +#endif #endif diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/core/usbh_core.h b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/core/usbh_core.h index 1a2de80c4..ddc40012b 100644 --- a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/core/usbh_core.h +++ b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/core/usbh_core.h @@ -1,7 +1,291 @@ #ifndef USBH_CORE_H_ #define USBH_CORE_H_ +#include +#include +#include +#include +#include "usb_config.h" +#include "usb_util.h" +#include "usb_errno.h" +#include "usb_def.h" +#include "usb_list.h" +#include "usb_mem.h" +#include "usb_log.h" +#include "usb_hc.h" +#include "usb_osal.h" +#include "usb_hub.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define USB_CLASS_MATCH_VENDOR 0x0001 +#define USB_CLASS_MATCH_PRODUCT 0x0002 +#define USB_CLASS_MATCH_INTF_CLASS 0x0004 +#define USB_CLASS_MATCH_INTF_SUBCLASS 0x0008 +#define USB_CLASS_MATCH_INTF_PROTOCOL 0x0010 + +#define CLASS_CONNECT(hport, i) ((hport)->config.intf[i].class_driver->connect(hport, i)) +#define CLASS_DISCONNECT(hport, i) ((hport)->config.intf[i].class_driver->disconnect(hport, i)) + +#ifdef __ARMCC_VERSION /* ARM C Compiler */ +#define CLASS_INFO_DEFINE __attribute__((section("usbh_class_info"))) __USED __ALIGNED(1) +#elif defined(__GNUC__) +#define CLASS_INFO_DEFINE __attribute__((section(".usbh_class_info"))) __USED __ALIGNED(1) +#elif defined(__ICCARM__) || defined(__ICCRX__) +#pragma section = "usbh_class_info" +#define CLASS_INFO_DEFINE __attribute__((section("usbh_class_info"))) __USED __ALIGNED(1) +#endif + + +static inline void usbh_control_urb_fill(struct usbh_urb *urb, + usbh_pipe_t pipe, + struct usb_setup_packet *setup, + uint8_t *transfer_buffer, + uint32_t transfer_buffer_length, + uint32_t timeout, + usbh_complete_callback_t complete, + void *arg) +{ + urb->pipe = pipe; + urb->setup = setup; + urb->transfer_buffer = transfer_buffer; + urb->transfer_buffer_length = transfer_buffer_length; + urb->timeout = timeout; + urb->complete = complete; + urb->arg = arg; +} + + + +static inline void usbh_bulk_urb_fill(struct usbh_urb *urb, + usbh_pipe_t pipe, + uint8_t *transfer_buffer, + uint32_t transfer_buffer_length, + uint32_t timeout, + usbh_complete_callback_t complete, + void *arg) +{ + urb->pipe = pipe; + urb->setup = NULL; + urb->transfer_buffer = transfer_buffer; + urb->transfer_buffer_length = transfer_buffer_length; + urb->timeout = timeout; + urb->complete = complete; + urb->arg = arg; +} + + + +static inline void usbh_int_urb_fill(struct usbh_urb *urb, + usbh_pipe_t pipe, + uint8_t *transfer_buffer, + uint32_t transfer_buffer_length, + uint32_t timeout, + usbh_complete_callback_t complete, + void *arg) +{ + urb->pipe = pipe; + urb->setup = NULL; + urb->transfer_buffer = transfer_buffer; + urb->transfer_buffer_length = transfer_buffer_length; + urb->timeout = timeout; + urb->complete = complete; + urb->arg = arg; +} + + + +struct usbh_class_info { + uint8_t match_flags; /* Used for product specific matches; range is inclusive */ + uint8_t class; /* Base device class code */ + uint8_t subclass; /* Sub-class, depends on base class. Eg. */ + uint8_t protocol; /* Protocol, depends on base class. Eg. */ + uint16_t vid; /* Vendor ID (for vendor/product specific devices) */ + uint16_t pid; /* Product ID (for vendor/product specific devices) */ + const struct usbh_class_driver *class_driver; +}; + + +struct usbh_hubport; + +struct usbh_class_driver { + const char *driver_name; + int (*connect)(struct usbh_hubport *hport, uint8_t intf); + int (*disconnect)(struct usbh_hubport *hport, uint8_t intf); +}; + + + +struct usbh_endpoint { + struct usb_endpoint_descriptor ep_desc; +}; + +struct usbh_interface_altsetting { + struct usb_interface_descriptor intf_desc; + struct usbh_endpoint ep[CONFIG_USBHOST_MAX_ENDPOINTS]; +}; + +struct usbh_interface { + char devname[CONFIG_USBHOST_DEV_NAMELEN]; + struct usbh_class_driver *class_driver; + void *priv; + struct usbh_interface_altsetting altsetting[CONFIG_USBHOST_MAX_INTF_ALTSETTINGS]; + uint8_t altsetting_num; +}; + +struct usbh_configuration { + struct usb_configuration_descriptor config_desc; + struct usbh_interface intf[CONFIG_USBHOST_MAX_INTERFACES]; +}; + +struct usbh_hub; + + +struct usbh_hubport { + /** Name */ + char name[32]; + bool connected; /* True: device connected; false: disconnected */ + uint8_t port; /* Hub port index */ + uint8_t dev_addr; /* device address */ + uint8_t speed; /* device speed */ + usbh_pipe_t ep0; /* control ep pipe info */ + struct usb_device_descriptor device_desc; + struct usbh_configuration config; + const char *iManufacturer; + const char *iProduct; + const char *iSerialNumber; + uint8_t *raw_config_desc; + struct usb_setup_packet *setup; + struct usbh_hub *parent; +#ifdef CONFIG_USBHOST_XHCI + uint32_t protocol; /* port protocol, for xhci, some ports are USB2.0, others are USB3.0 */ +#endif +}; + + + +struct usbh_bus; + +struct usbh_hub { + usb_slist_t list; + bool connected; + bool is_roothub; + uint8_t index; + uint8_t hub_addr; + usbh_pipe_t intin; + uint8_t *int_buffer; + struct usbh_urb intin_urb; + struct usb_hub_descriptor hub_desc; + struct usbh_hubport child[CONFIG_USBHOST_MAX_EHPORTS]; + struct usbh_hubport *parent; + usb_slist_t hub_event_list; + struct usbh_bus *usb; + uint32_t ports; /* num of ports */ + USB_MEM_ALIGNX uint8_t g_hub_buf[32]; + USB_MEM_ALIGNX uint8_t g_hub_intbuf[CONFIG_USBHOST_MAX_EXTHUBS + 1][1]; +}; + + +int usbh_hport_activate_epx(usbh_pipe_t *pipe, struct usbh_hubport *hport, struct usb_endpoint_descriptor *ep_desc); + +/** + * @brief Submit an control transfer to an endpoint. + * This is a blocking method; this method will not return until the transfer has completed. + * Default timeout is 500ms. + * + * @param pipe The control endpoint to send/receive the control request. + * @param setup Setup packet to be sent. + * @param buffer buffer used for sending the request and for returning any responses. + * @return On success will return 0, and others indicate fail. + */ +int usbh_control_transfer(usbh_pipe_t pipe, struct usb_setup_packet *setup, uint8_t *buffer); + +struct usbh_devaddr_map { + /** + * alloctab[0]:addr from 0~31 + * alloctab[1]:addr from 32~63 + * alloctab[2]:addr from 64~95 + * alloctab[3]:addr from 96~127 + * + */ + uint8_t next; /* Next device address */ + uint32_t alloctab[4]; /* Bit allocation table */ +}; + +struct usbh_bus { + usb_slist_t list; + uint8_t id; + /** Largest transfer allowed on the bus */ + size_t mtu; + struct usbh_devaddr_map devgen; + struct usbh_hub roothub; +#if CONFIG_USBHOST_MAX_EXTHUBS > 0 + struct usbh_hub exthub[CONFIG_USBHOST_MAX_EXTHUBS]; +#endif + struct usbh_hubport roothub_parent_port; + usb_slist_t hub_event_head; + usb_slist_t hub_class_head; + usb_osal_sem_t hub_event_wait; + usb_osal_thread_t hub_thread; + usb_osal_mq_t hub_mq; + void *priv; /* private data, usb host */ + int (*hub_open)(struct usbh_hub *hub); + void (*hub_close)(struct usbh_hub *hub); + int (*root_open)(struct usbh_hub *hub); + USB_MEM_ALIGNX uint8_t ep0_request_buffer[CONFIG_USBHOST_REQUEST_BUFFER_LEN]; + USB_MEM_ALIGNX struct usb_setup_packet g_setup[CONFIG_USBHOST_MAX_EXTHUBS + 1][CONFIG_USBHOST_MAX_EHPORTS]; +}; + +/** + * Get USB transaction translator + * + * @v hport Hub port of USB device + * @ret port Transaction translator port, or NULL + */ +struct usbh_hubport *usbh_transaction_translator ( struct usbh_hubport *hport ); + +/** + * Get USB route string + * + * @v hport Hub Port of USB device + * @ret route USB route string + */ +unsigned int usbh_route_string ( struct usbh_hubport *hport ); + +static inline struct usbh_bus* usbh_get_bus_of_port(struct usbh_hubport *hport) +{ + USB_ASSERT(hport && hport->parent); + return hport->parent->usb; +} + +static inline struct usbh_hub *usbh_get_roothub_of_port(struct usbh_hubport *hport) +{ + return &(usbh_get_bus_of_port(hport)->roothub); +} + +struct usbh_bus* usbh_get_bus_of_index(uint8_t usb); + +/** + * Get USB root hub port + * + * @v hport Hub port of USB device + * @ret port Root hub port + */ +struct usbh_hubport * usbh_root_hub_port ( struct usbh_hubport *hport ); + +int usbh_initialize(uint32_t id, struct usbh_bus *usb); +struct usbh_hubport *usbh_find_hubport(uint32_t id, uint8_t dev_addr); +void *usbh_find_class_instance(const char *devname); +int lsusb(int argc, char **argv); + + +#ifdef __cplusplus +} +#endif diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/osal/usb_osal.c b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/osal/usb_osal.c index 46e58b361..2731ef6bb 100644 --- a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/osal/usb_osal.c +++ b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/osal/usb_osal.c @@ -1,6 +1,6 @@ #include "usb_osal.h" -int usb_wait_until(int msec){ - return 0; -} +usb_osal_thread_t usb_osal_thread_create(const char *name, uint32_t stack_size, uint32_t prio, usb_thread_entry_t entry, void *args){ + return NULL; +} \ No newline at end of file