#include <stdint.h>
#ifndef USB_H
#define USB_H
typedef enum {
USB_SETUP_HOST_TO_DEVICE,
USB_SETUP_DEVICE_TO_HOST,
} usb_setup_command_direction_t;
typedef enum {
USB_SETUP_STANDARD,
USB_SETUP_CLASS,
USB_SETUP_VENDOR,
USB_SETUP_RESERVED,
} usb_setup_command_type_t;
typedef enum {
USB_SETUP_DEVICE,
USB_SETUP_INTERFACE,
USB_SETUP_ENDPOINT,
USB_SETUP_OTHER,
} usb_setup_command_recipient_t;
typedef struct {
uint8_t recipient : 5;
usb_setup_command_type_t type : 2;
usb_setup_command_direction_t direction : 1;
} usb_setup_command_request_type_t;
typedef enum {
USB_SETUP_GET_STATUS = 0,
USB_SETUP_CLEAR_FEATURE = 1,
RESERVED1 = 2,
USB_SETUP_SET_FEATURE = 3,
RESERVED2 = 4,
USB_SETUP_SET_ADDRESS = 5,
USB_SETUP_GET_DESCRIPTOR = 6,
USB_SETUP_SET_DESCRIPTOR = 7,
USB_SETUP_GET_CONFIGURATION = 8,
USB_SETUP_SET_CONFIGURATION = 9,
USB_SETUP_GET_INTERFACE = 10,
USB_SETUP_SET_INTERFACE = 11,
USB_SETUP_SYNCH_FRAME = 12,
} usb_setup_request_t;
typedef enum {
DESCRIPTOR_DEVICE = 1,
DESCRIPTOR_CONFIGURATION = 1,
DESCRIPTOR_STRING = 2,
DESCRIPTOR_INTERFACE = 3,
DESCRIPTOR_ENDPOINT = 4,
DESCRIPTOR_DEVICE_QUALIFIER = 5,
DESCRIPTOR_OTHER_SPEED_CONFIGURATION = 6,
DESCRIPTOR_INTERFACE_POWER = 7,
} usb_descriptor_type_t;
#pragma GCC diagnostic error "-Wpadded"
typedef struct __attribute__((packed)) {
usb_setup_command_request_type_t bmRequestType;
usb_setup_request_t bRequest;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
} usb_setup_command_t;
_Static_assert(sizeof(usb_setup_command_t) == 8, "Size check");
typedef struct __attribute__((packed)) {
uint8_t bLength;
uint8_t bDescriptorType;
} usb_descriptor_t;
typedef struct {
usb_descriptor_t header;
uint16_t bcdUSB;
uint8_t bDeviceClass;
uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol;
uint8_t bMaxPacketSize0;
uint16_t idVendor;
uint16_t idProduct;
uint16_t bcdDevice;
uint8_t iManufacturer;
uint8_t iProduct;
uint8_t iSerialNumber;
uint8_t bNumConfigurations;
} usb_device_descriptor_t;
_Static_assert(sizeof(usb_device_descriptor_t) == 18, "Size check");
typedef struct {
usb_descriptor_t header;
uint16_t bcdUSB;
uint8_t bDeviceClass;
uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol;
uint8_t bMaxPacketSize0;
uint8_t bNumConfigurations;
uint8_t bReserved;
} usb_device_qualifier_t;
_Static_assert(sizeof(usb_device_qualifier_t) == 10, "Size check");
typedef struct {
uint8_t reserved1 : 1;
uint8_t self_powered : 1;
uint8_t remote_wakeup : 1;
uint8_t reserved2: 5;
} usb_configuration_descriptor_attributes;
typedef struct __attribute__((packed)) {
usb_descriptor_t header;
uint16_t wTotalLength;
uint8_t bNumInterfaces;
uint8_t bConfigurationValue;
uint8_t iConfiguration;
usb_configuration_descriptor_attributes bmAttributes;
uint8_t bMaxPower;
} usb_configuration_descriptor_t;
_Static_assert(sizeof(usb_configuration_descriptor_t) == 9, "Size check");
typedef usb_configuration_descriptor_t usb_other_speed_configuration_t;
typedef struct __attribute__((packed)) {
usb_descriptor_t header;
uint8_t bInterfaceNumber;
uint8_t bAlternateSetting;
uint8_t bNumEndpoints;
uint8_t bInterfaceClass;
uint8_t bInterfaceSubClass;
uint8_t bInterfaceProtocol;
uint8_t iInterface;
} usb_interface_descriptor_t;
_Static_assert(sizeof(usb_interface_descriptor_t) == 9, "Size check");
typedef enum {
USB_ENDPOINT_OUT = 0,
USB_ENDPOINT_IN = 1,
} usb_endpoint_direction_t;
typedef struct {
uint8_t endpoint_number : 4;
uint8_t reserved : 3;
uint8_t direction : 1;
} usb_endpoint_address_t;
typedef enum {
USB_ENDPOINT_TYPE_CONTROL = 0,
USB_ENDPOINT_TYPE_ISOCHRONOUS = 1,
USB_ENDPOINT_TYPE_BULK = 2,
USB_ENDPOINT_TYPE_INTERRUPT = 3,
} usb_endpoint_transfer_type_t;
typedef enum {
USB_ENDPOINT_SYNC_NO_SYNC = 0,
USB_ENDPOINT_SYNC_ASYNCHRONOUS = 1,
USB_ENDPOINT_SYNC_ADAPTIVE = 2,
USB_ENDPOINT_SYNC_SYNCHRONOUS = 3,
} usb_endpoint_synchronization_type_t;
typedef enum {
USB_ENDPOINT_USAGE_DATA = 0,
USB_ENDPOINT_USAGE_FEEDBACK = 1,
USB_ENDPOINT_USAGE_IMPLICIT_FEEDBACK = 2,
USB_ENDPOINT_USAGE_RESERVED = 3,
} usb_endpoint_usage_type_t;
typedef struct __attribute__((packed)) {
usb_endpoint_transfer_type_t transfer_type : 2;
usb_endpoint_synchronization_type_t synchronization_type : 2;
usb_endpoint_usage_type_t usage_type : 2;
uint8_t reserved_zeros : 2;
} usb_endpoint_attributes_t;
typedef struct __attribute__((packed)) {
usb_descriptor_t header;
usb_endpoint_address_t bEndpointAddress;
usb_endpoint_attributes_t bmAttributes;
uint16_t wMaxPacketSize;
uint8_t bInterval;
} usb_endpoint_descriptor_t;
_Static_assert(sizeof(usb_endpoint_descriptor_t) == 7, "Size check");
#pragma GCC diagnostic ignored "-Wpadded"
typedef struct {
// uint8_t bLength; // lengto of wLANGID + 2
usb_descriptor_t header;
uint16_t *wLANGID; // should have length equal to bLength - 2
} usb_string_descriptor_zero_t;
typedef struct {
usb_descriptor_t header;
uint8_t *bString;
} usb_unicode_string_descriptor_t;
void usb_generic_send(uint8_t* data, uint16_t size, uint32_t *fifo_tx_target);
void usb_generic_read(uint8_t *data, uint16_t size, uint32_t *fifo_rx_source);
void usb_send_descriptor(usb_descriptor_t* descriptor, uint32_t *fifo_tx_target);
/* void usb_send_ack(uint32_t* fifo_tx_target); */
void usb_send_configuration_descriptor(usb_configuration_descriptor_t* descriptor, uint32_t *fifo_tx_target);
void usb_send_interface_descriptor(usb_interface_descriptor_t* descriptor, uint32_t *fifo_tx_target);
void usb_send_endpoint_descriptor(usb_endpoint_descriptor_t* descriptor, uint32_t *fifo_tx_target);
void usb_send_string_descriptor_zero(usb_string_descriptor_zero_t* string_descriptor, uint32_t *fifo_tx_target);
void usb_send_unicode_string_descriptor(usb_unicode_string_descriptor_t* string_descriptor, uint32_t *fifo_tx_target);
#endif // USB_H