summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/usb_dc.h36
-rw-r--r--common/usb_def.h41
-rw-r--r--common/usb_hc.h17
-rw-r--r--common/usb_util.h20
-rw-r--r--common/usb_vfs.h150
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 */