diff options
Diffstat (limited to 'common')
| -rw-r--r-- | common/usb_dc.h | 36 | ||||
| -rw-r--r-- | common/usb_def.h | 41 | ||||
| -rw-r--r-- | common/usb_hc.h | 17 | ||||
| -rw-r--r-- | common/usb_util.h | 20 | ||||
| -rw-r--r-- | common/usb_vfs.h | 150 |
5 files changed, 264 insertions, 0 deletions
diff --git a/common/usb_dc.h b/common/usb_dc.h index 42a332e7..cdb9f415 100644 --- a/common/usb_dc.h +++ b/common/usb_dc.h @@ -13,6 +13,33 @@ extern "C" { #endif /** + * @brief USB device controller driver ops. + * + * Structure containing the USB device controller driver ops. + */ +struct usbd_dc_driver { + const char *driver_name; + const char *driver_desc; + int (*init)(uint8_t busid); + int (*deinit)(uint8_t busid); + int (*set_address)(uint8_t busid, const uint8_t addr); + int (*set_remote_wakeup)(uint8_t busid); + uint8_t (*get_port_speed)(uint8_t busid); + int (*ep_open)(uint8_t busid, const struct usb_endpoint_descriptor *ep); + int (*ep_open_extra)(uint8_t busid, const struct usb_endpoint_descriptor *ep, const struct usb_endpoint_companion_descriptor *ep_comp); + int (*ep_close)(uint8_t busid, const uint8_t ep); + int (*ep_set_stall)(uint8_t busid, const uint8_t ep); + int (*ep_clear_stall)(uint8_t busid, const uint8_t ep); + int (*ep_is_stalled)(uint8_t busid, const uint8_t ep, uint8_t *stalled); + int (*ep_start_write)(uint8_t busid, const uint8_t ep, const uint8_t *data, uint32_t data_len); + int (*ep_start_read)(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len); + void (*irq_handler)(uint8_t busid); +#ifdef CONFIG_USBDEV_TEST_MODE + void (*execute_test_mode)(uint8_t busid, uint8_t test_mode); +#endif +}; + +/** * @brief init device controller registers. * @return On success will return 0, and others indicate fail. */ @@ -59,6 +86,15 @@ uint8_t usbd_get_port_speed(uint8_t busid); int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep); /** + * @brief configure endpoint extra for usb3.0. + * + * @param [in] ep_cfg Endpoint config. + * + * @return On success will return 0, and others indicate fail. + */ +int usbd_ep_open_extra(uint8_t busid, const struct usb_endpoint_descriptor *ep, const struct usb_endpoint_companion_descriptor *ep_comp); + +/** * @brief Disable the selected endpoint * * @param[in] ep Endpoint address diff --git a/common/usb_def.h b/common/usb_def.h index e3fdd240..73d2b800 100644 --- a/common/usb_def.h +++ b/common/usb_def.h @@ -104,6 +104,8 @@ #define USB_REQUEST_LOOPBACK_DATA_WRITE 0x15 #define USB_REQUEST_LOOPBACK_DATA_READ 0x16 #define USB_REQUEST_SET_INTERFACE_DS 0x17 +#define USB_REQUEST_SET_SEL 0x30 +#define USB_REQUEST_SET_ISOCH_DLY 0x31 /* USB Standard Feature selectors */ #define USB_FEATURE_ENDPOINT_HALT 0 @@ -116,11 +118,15 @@ #define USB_FEATURE_AHNPSUPPORT 4 #define USB_FEATURE_AALTHNPSUPPORT 5 #define USB_FEATURE_DEBUGMODE 6 +#define USB_FEATURE_U1_ENABLE 0x30 +#define USB_FEATURE_U2_ENABLE 0x31 /* USB GET_STATUS Bit Values */ #define USB_GETSTATUS_ENDPOINT_HALT 0x01 #define USB_GETSTATUS_SELF_POWERED 0x01 #define USB_GETSTATUS_REMOTE_WAKEUP 0x02 +#define USB_GETSTATUS_U1_ENABLE 0x04 +#define USB_GETSTATUS_U2_ENABLE 0x08 /* USB Descriptor Types */ #define USB_DESCRIPTOR_TYPE_DEVICE 0x01U @@ -137,6 +143,7 @@ #define USB_DESCRIPTOR_TYPE_BINARY_OBJECT_STORE 0x0FU #define USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY 0x10U #define USB_DESCRIPTOR_TYPE_WIRELESS_ENDPOINTCOMP 0x11U +#define USB_DESCRIPTOR_TYPE_ENDPOINT_COMPANION 0x30U /* Class Specific Descriptor */ #define USB_CS_DESCRIPTOR_TYPE_DEVICE 0x21U @@ -405,6 +412,17 @@ struct usb_endpoint_descriptor { #define USB_SIZEOF_ENDPOINT_DESC 7 +/** Standard Endpoint Companion Descriptor */ +struct usb_endpoint_companion_descriptor { + uint8_t bLength; /* Descriptor size in bytes = 6 */ + uint8_t bDescriptorType; /* ENDPOINT COMPANION descriptor type = 0x30 */ + uint8_t bMaxBurst; /* Maximum number of bursts */ + uint8_t bmAttributes; /* Companion attributes */ + uint16_t wBytesPerInterval; /* Bytes per interval */ +} __PACKED; + +#define USB_SIZEOF_ENDPOINT_COMPANION_DESC 6 + /** Unicode (UTF16LE) String Descriptor */ struct usb_string_descriptor { uint8_t bLength; @@ -638,6 +656,22 @@ struct usb_desc_header { USB_STRING_SERIAL_INDEX, /* iSerial */ \ bNumConfigurations /* bNumConfigurations */ +#define USB3_DEVICE_DESCRIPTOR_INIT(bcdUSB, bDeviceClass, bDeviceSubClass, bDeviceProtocol, idVendor, idProduct, bcdDevice, bNumConfigurations) \ + 0x12, /* bLength */ \ + USB_DESCRIPTOR_TYPE_DEVICE, /* bDescriptorType */ \ + WBVAL(USB_3_0), /* bcdUSB */ \ + bDeviceClass, /* bDeviceClass */ \ + bDeviceSubClass, /* bDeviceSubClass */ \ + bDeviceProtocol, /* bDeviceProtocol */ \ + 0x09, /* bMaxPacketSize */ \ + WBVAL(idVendor), /* idVendor */ \ + WBVAL(idProduct), /* idProduct */ \ + WBVAL(bcdDevice), /* bcdDevice */ \ + USB_STRING_MFC_INDEX, /* iManufacturer */ \ + USB_STRING_PRODUCT_INDEX, /* iProduct */ \ + USB_STRING_SERIAL_INDEX, /* iSerial */ \ + bNumConfigurations /* bNumConfigurations */ + #define USB_CONFIG_DESCRIPTOR_INIT(wTotalLength, bNumInterfaces, bConfigurationValue, bmAttributes, bMaxPower) \ 0x09, /* bLength */ \ USB_DESCRIPTOR_TYPE_CONFIGURATION, /* bDescriptorType */ \ @@ -689,6 +723,13 @@ struct usb_desc_header { WBVAL(wMaxPacketSize), /* wMaxPacketSize */ \ bInterval /* bInterval */ +#define USB_ENDPOINT_COMPANION_DESCRIPTOR_INIT(bMaxBurst, bmAttributes, wBytesPerInterval) \ + 0x06, /* bLength */ \ + USB_DESCRIPTOR_TYPE_ENDPOINT_COMPANION, /* bDescriptorType */ \ + bMaxBurst, /* bMaxBurst */ \ + bmAttributes, /* bmAttributes */ \ + WBVAL(wBytesPerInterval) /* wBytesPerInterval */ + #define USB_IAD_DESCRIPTOR_INIT(bFirstInterface, bInterfaceCount, bFunctionClass, bFunctionSubClass, bFunctionProtocol) \ 0x08, /* bLength */ \ USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, /* bDescriptorType */ \ diff --git a/common/usb_hc.h b/common/usb_hc.h index aa411eef..f24c337e 100644 --- a/common/usb_hc.h +++ b/common/usb_hc.h @@ -59,6 +59,23 @@ struct usbh_urb { }; /** + * @brief USB host controller driver. + * + * Structure containing the USB host controller driver. + */ +struct usbh_hc_driver { + const char *driver_name; + const char *driver_desc; + int (*init)(struct usbh_bus *bus); + int (*deinit)(struct usbh_bus *bus); + uint16_t (*get_frame_number)(struct usbh_bus *bus); + int (*roothub_control)(struct usbh_bus *bus, struct usb_setup_packet *setup, uint8_t *buf); + int (*submit_urb)(struct usbh_urb *urb); + int (*kill_urb)(struct usbh_urb *urb); + void (*irq_handler)(uint8_t busid); +}; + +/** * @brief usb host controller hardware init. * * @return On success will return 0, and others indicate fail. diff --git a/common/usb_util.h b/common/usb_util.h index 521bf27f..97e0917c 100644 --- a/common/usb_util.h +++ b/common/usb_util.h @@ -185,6 +185,26 @@ (field)[3] = (uint8_t)((value) >> 0); \ } while (0) +#define GET_LE16(field) \ + (((uint16_t)(field)[0] << 0) | ((uint16_t)(field)[1] << 8)) + +#define GET_LE32(field) \ + (((uint32_t)(field)[0] << 0) | ((uint32_t)(field)[1] << 8) | ((uint32_t)(field)[2] << 16) | ((uint32_t)(field)[3] << 24)) + +#define SET_LE16(field, value) \ + do { \ + (field)[0] = (uint8_t)((value) >> 0); \ + (field)[1] = (uint8_t)((value) >> 8); \ + } while (0) + +#define SET_LE32(field, value) \ + do { \ + (field)[0] = (uint8_t)((value) >> 0); \ + (field)[1] = (uint8_t)((value) >> 8); \ + (field)[2] = (uint8_t)((value) >> 16); \ + (field)[3] = (uint8_t)((value) >> 24); \ + } while (0) + #define WBVAL(x) ((x) & 0xFF), (((x) >> 8) & 0xFF) #define DBVAL(x) ((x) & 0xFF), (((x) >> 8) & 0xFF), (((x) >> 16) & 0xFF), (((x) >> 24) & 0xFF) diff --git a/common/usb_vfs.h b/common/usb_vfs.h new file mode 100644 index 00000000..0fd5a4ee --- /dev/null +++ b/common/usb_vfs.h @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2026, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + * + */ +#ifndef USB_VFS_H +#define USB_VFS_H + +#include <stdint.h> +#include <stddef.h> + +#define VFS_O_RDONLY 0 /* +1 == FREAD, existing file only */ +#define VFS_O_WRONLY 1 /* +1 == FWRITE, create / truncate */ +#define VFS_O_RDWR 2 /* +1 == FREAD|FWRITE, create, no truncate */ + +/* file mode bits, POSIX layout so they can go straight into the wire reply */ +#define VFS_S_IFMT 0170000 /* type of file */ +#define VFS_S_IFDIR 0040000 /* directory */ +#define VFS_S_IFCHR 0020000 /* character special */ +#define VFS_S_IFBLK 0060000 /* block special */ +#define VFS_S_IFREG 0100000 /* regular */ +#define VFS_S_IFLNK 0120000 /* symbolic link */ +#define VFS_S_IFSOCK 0140000 /* socket */ +#define VFS_S_IFIFO 0010000 /* fifo */ +#define VFS_S_IREAD 0000400 /* read permission, owner */ +#define VFS_S_IWRITE 0000200 /* write permission, owner */ +#define VFS_S_IEXEC 0000100 /* execute/search permission, owner */ +#define VFS_S_ENFMT 0002000 /* enforcement-mode locking */ + +#define VFS_S_IRWXU (VFS_S_IRUSR | VFS_S_IWUSR | VFS_S_IXUSR) +#define VFS_S_IRUSR 0000400 /* read permission, owner */ +#define VFS_S_IWUSR 0000200 /* write permission, owner */ +#define VFS_S_IXUSR 0000100 /* execute/search permission, owner */ +#define VFS_S_IRWXG (VFS_S_IRGRP | VFS_S_IWGRP | VFS_S_IXGRP) +#define VFS_S_IRGRP 0000040 /* read permission, group */ +#define VFS_S_IWGRP 0000020 /* write permission, group */ +#define VFS_S_IXGRP 0000010 /* execute/search permission, group */ +#define VFS_S_IRWXO (VFS_S_IROTH | VFS_S_IWOTH | VFS_S_IXOTH) +#define VFS_S_IROTH 0000004 /* read permission, other */ +#define VFS_S_IWOTH 0000002 /* write permission, other */ +#define VFS_S_IXOTH 0000001 /* execute/search permission, other */ + +#define VFS_ERR_GENERIC (-1) /* unspecified */ +#define VFS_ERR_NOENT (-2) /* no such file or directory */ +#define VFS_ERR_IO (-3) /* low level I/O error */ +#define VFS_ERR_NOTDIR (-4) /* a path component is not a directory */ +#define VFS_ERR_ISDIR (-5) /* it is a directory, not a file */ +#define VFS_ERR_EXIST (-6) /* already exists */ +#define VFS_ERR_NOSPC (-7) /* no space left on device */ +#define VFS_ERR_ROFS (-8) /* read-only file system */ +#define VFS_ERR_INVAL (-9) /* invalid argument or invalid name */ +#define VFS_ERR_NOMEM (-10) /* out of memory */ +#define VFS_ERR_AGAIN (-11) /* busy, try again */ +#define VFS_ERR_NODEV (-12) /* no file system mounted on that path */ + +#ifndef VFS_MAX_PATHNAME +#define VFS_MAX_PATHNAME 256 +#endif + +typedef void VFS_DIR; + +struct vfs_statfs { + size_t f_bsize; /* block size */ + size_t f_blocks; /* total data blocks in file system */ + size_t f_bfree; /* free blocks in file system */ +}; + +struct vfs_stat { + uint32_t st_dev; + uint32_t st_ino; + uint32_t st_mode; + uint32_t st_nlink; + uint32_t st_uid; + uint32_t st_gid; + size_t st_size; + size_t st_blksize; + size_t st_blocks; + uint32_t st_mtime; +}; + +struct vfs_dirent { + uint8_t d_type; /* The type of the file */ + uint8_t d_namlen; /* The length of the not including the terminating null file name */ + uint16_t d_reclen; /* length of this record */ + char d_name[VFS_MAX_PATHNAME]; /* The null-terminated file name */ +}; + +#ifdef __cplusplus +extern "C" { +#endif + +const char *vfs_get_fs_root_path(void); + +const char *vfs_get_fs_description(void); + +int vfs_mkdir(const char *path); +int vfs_rmdir(const char *path); + +VFS_DIR *vfs_opendir(const char *name); +int vfs_closedir(VFS_DIR *d); +struct vfs_dirent *vfs_readdir(VFS_DIR *d); + +int vfs_statfs(const char *path, struct vfs_statfs *buf); +int vfs_stat(const char *file, struct vfs_stat *buf); + +int vfs_open(const char *path, uint8_t mode); +int vfs_close(int fd); +int vfs_read(int fd, void *buf, size_t len); +int vfs_write(int fd, const void *buf, size_t len); + +int vfs_unlink(const char *path); + +static inline const char *vfs_strerror(int err) +{ + switch (err) { + case 0: + return "success"; + case VFS_ERR_NOENT: + return "no such file or directory"; + case VFS_ERR_IO: + return "input/output error"; + case VFS_ERR_NOTDIR: + return "not a directory"; + case VFS_ERR_ISDIR: + return "is a directory"; + case VFS_ERR_EXIST: + return "file exists"; + case VFS_ERR_NOSPC: + return "no space left on device"; + case VFS_ERR_ROFS: + return "read-only file system"; + case VFS_ERR_INVAL: + return "invalid argument"; + case VFS_ERR_NOMEM: + return "out of memory"; + case VFS_ERR_AGAIN: + return "resource temporarily unavailable"; + case VFS_ERR_NODEV: + return "no such device or address"; + default: + return "unspecified error"; + } +} + +#ifdef __cplusplus +} +#endif + +#endif /* USB_VFS_H */ |
