#include #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 { usb_setup_command_direction_t direction : 1; usb_setup_command_direction_t type : 2; usb_setup_command_direction_t recipient : 5; } 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 { 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 direction : 1; uint8_t reserved : 3; uint8_t endpoint_number : 4; } 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)) { uint8_t reserved_zeros : 2; usb_endpoint_usage_type_t usage_type : 2; usb_endpoint_synchronization_type_t synchronization_type : 2; usb_endpoint_transfer_type_t transfer_type : 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_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