#include #include "usb.h" #ifndef USB_DEVICE_H #define USB_DEVICE_H typedef enum { // error states first so they are lowest CONTROL_ERROR = -4, UNKNOWN_CONTROL_COMMAND = -4, ERROR = -3, UNKNOWN_INTERRUPT = -2, OTG_ERROR = -1, // shouldn't happen, since otg is not used INIT = 0, RESET = 1, RESET_DONE = 2, SET_ADDRESS_RCVD = 3, ENUMERATED = 4, } usb_device_state_t; typedef struct { volatile uint32_t data[128]; } usb_fifo_t; struct usb_class_header_t; struct usb_device_t; typedef struct usb_device_t usb_device_t; typedef struct { struct usb_class_header_t *(*init)(usb_device_t *device, uint16_t id_vendor, uint16_t id_product, char *vendor_name, char *product_name, uint16_t serial_number, char* serial_name); void (*send_configuration)(usb_device_t* device, usb_setup_command_t* cmd); void (*setup_endpoints)(usb_device_t* device, uint8_t configuration); void (*reset_endpoints)(usb_device_t* device); void (*reset_callback)(usb_device_t* device); void (*setup_packet_callback)(usb_device_t* device, usb_setup_command_t* cmd); void (*enumeration_done_callback)(usb_device_t* device); void (*txfifo_empty_callback)(usb_device_t* device, uint8_t endpoint); void (*rxfifo_empty_callback)(usb_device_t* device, uint8_t endpoint); void (*transmit_done_callback)(usb_device_t* device, uint8_t endpoint); void (*nak_callback)(usb_device_t* device, uint8_t endpoint); void (*nyet_callback)(usb_device_t* device, uint8_t endpoint); } usb_class_vtable_t; typedef struct { usb_interface_descriptor_t interface_descriptor; uint8_t endpoint_descriptors_count; usb_endpoint_descriptor_t *endpoint_descriptors; } usb_interface_t; struct usb_class_header_t { usb_device_descriptor_t device_descriptor; usb_device_qualifier_t device_qualifier; usb_configuration_descriptor_t configuration_descriptor; uint8_t interfaces_count; usb_interface_t *interfaces; usb_string_descriptor_zero_t string_descriptor_zero; usb_unicode_string_descriptor_t *string_descriptors; }; typedef struct usb_class_header_t usb_class_header_t; typedef enum { SETUP_STAGE_NONE, SETUP_STAGE_RCVD_SETUP_PACKET, SETUP_STAGE_AWAITING_RESPONSE, SETUP_STAGE_SENDING_RESPONSE, SETUP_STAGE_SENDING_ACK, SETUP_STAGE_AWAITING_ACK, } usb_setup_command_stage_t; struct usb_device_t { USB_OTG_GlobalTypeDef *core; USB_OTG_DeviceTypeDef *device; USB_OTG_OUTEndpointTypeDef *out; USB_OTG_INEndpointTypeDef *in; usb_fifo_t *fifos; usb_class_vtable_t vt; usb_class_header_t* class; usb_device_state_t state; // TODO: is this count field required? uint8_t received_setup_commands_count; uint8_t received_setup_commands_index; usb_setup_command_stage_t setup_stage; uint8_t detected_setup_errors; usb_setup_command_t received_setup_commands[3]; }; // has configuration etc typedef enum { USB_OTG_HS1 = 0, USB_OTG_FS2 = 1, } usb_device_slot_t; extern usb_device_t usb_devices[2]; void *usb_device_init(usb_device_slot_t slot, usb_class_vtable_t *class, uint16_t id_vendor, uint16_t id_product, char *vendor_name, char *product_name, uint16_t serial_number, char* serial_name); void usb_device_setup(void* device); void usb_device_wait_for_handshake(void* device); #endif // USB_DEVICE_H