#ifndef __USB_H__ #define __USB_H__ #include "../types.h" #include "../utils.h" #include "proto.h" #define USBCTRL_DPSRAM_SIZE (1024*4) // See p122 #define USBCTRL_BUFFER_SIZE 64 // See p385 #define USB_ENDPOINT_COUNT 3 // Number of endpoints for the device driver #define USB_INTERFACE_COUNT 2 // Number of interfaces for the device driver #define BCD_USB 0x0110 #define USB_BUFFER_OFFSET(ADDR) (ADDR ^ USBCTRL_DPSRAM_BASE) // See here https://github.com/raspberrypi/pico-examples/blob/master/usb/device/dev_lowlevel/dev_lowlevel.c#L141 typedef struct EndPoint { void *buffer0; void *buffer1; void *rbc; // EP control register volatile u32 *rbc_in; // EP buffer control in register volatile u32 *rbc_out; // EP buffer control out register int next_pid; int is_in; } EndPoint; typedef struct EndPointConfiguration{ USB_ENDPOINT_DESCRIPTOR endpoint_descriptor; volatile u32* buffer0; volatile u32* buffer1; volatile u32* buffer_control; volatile u32* endpoint_control; u32 next_pid; // Next usb pkt pid (DATA0/DATA1) void (*handler)(u8*,int); } EndPointConfiguration; typedef struct FunctionalDescriptors { int size; void* descriptors; } FunctionalDescriptors; typedef struct DeviceConfiguration { u8 devaddr; // Current device address u8 setdevaddr; // Set to one when devaddr is available u8 configured; // Set to true when host triggered SET_CONFIGURATION USB_DEVICE_DESCRIPTOR device_descriptor; USB_CONFIGURATION_DESCRIPTOR configuration_descriptor; USB_INTERFACE_DESCRIPTOR interface_descriptors[USB_INTERFACE_COUNT]; EndPointConfiguration endpoints[2+USB_ENDPOINT_COUNT]; // Endpoint 0 in and out always required so +2 USB_STRING_DESCRIPTOR_ZERO supported_languages; FunctionalDescriptors functional_descriptors; void *full_configuration_descriptor; void (*setup_handler)(UD_SETUP *pkt); // Notify the driver in case of unhandled setup packet void (*setup_ack_handler)(void); // Notify the driver void (*eoi)(void); // Notify the driver for End Of Interrupt char *descriptor_strings[]; // All string like vendor and product id } DeviceConfiguration; void cusb_init(DeviceConfiguration *dc); void cusb_init_device_configuration(); void cusb_ep0_in_handler(u8 *buffer, int len); void cusb_ep0_out_handler(u8 *buffer, int len); void cusb_handle_setup(void); void cusb_handle_bus_reset(void); void cusb_handle_buffer_status(void); int cusb_check_interrupt(int int_bit); void usb_start_xfer(void* data, u32 size, int ep); void cusb_start_xfer(void *data, u32 size, EndPointConfiguration *ep); void cusb_status_xfer(u32 dir); void cusb_eoi(); // Trigger at end of each USB interrupt void cusb_isr_trigger(); // Manually trigger an usb interrupt #endif