/ src / usb_definitions.h
usb_definitions.h
  1  
  2  #pragma once
  3  
  4  #include <stdint.h>
  5  
  6  #include "pio_usb_configuration.h"
  7  
  8  typedef enum {
  9    CONTROL_NONE,
 10    CONTROL_IN,
 11    CONTROL_OUT,
 12    CONTROL_COMPLETE,
 13    CONTROL_ERROR,
 14  } control_transfer_operation_t;
 15  
 16  typedef enum {
 17    EP_IN = 0x80,
 18    EP_OUT = 0x00,
 19  } ep_type_t;
 20  
 21  typedef enum {
 22    STAGE_SETUP,
 23    STAGE_DATA,
 24    STAGE_IN,
 25    STAGE_OUT,
 26    STAGE_STATUS,
 27    STAGE_COMPLETE,
 28    STAGE_ERROR
 29  } setup_transfer_stage_t;
 30  
 31  typedef enum {
 32    STAGE_IDLE,
 33    STAGE_DEVICE,
 34    STAGE_CONFIG,
 35    STAGE_CONFIG2,
 36    STAGE_INTERFACE,
 37    STAGE_ENDPOINT
 38  } usb_enumeration_stage_t;
 39  
 40  typedef struct {
 41    uint8_t *tx_address;
 42    uint8_t tx_length;
 43  } packet_info_t;
 44  
 45  typedef struct {
 46    volatile uint8_t data_in_num;
 47    volatile uint16_t buffer_idx;
 48    volatile uint8_t *rx_buffer;
 49    volatile packet_info_t setup_packet;
 50    volatile packet_info_t out_data_packet;
 51    volatile int16_t request_length;
 52    volatile control_transfer_operation_t operation;
 53    volatile setup_transfer_stage_t stage;
 54  } control_pipe_t;
 55  
 56  typedef struct {
 57    volatile uint8_t root_idx;
 58    volatile uint8_t dev_addr;
 59    bool need_pre;
 60    bool is_tx; // Host out or Device in
 61  
 62    volatile uint8_t ep_num;
 63    volatile bool new_data_flag;
 64    volatile uint16_t size;
 65  
 66    volatile uint8_t attr;
 67    volatile uint8_t interval;
 68    volatile uint8_t interval_counter;
 69    volatile uint8_t data_id; // data0 or data1
 70  
 71    volatile bool stalled;
 72    volatile bool has_transfer;
 73    volatile bool transfer_started;
 74    volatile bool transfer_aborted;
 75  
 76    uint8_t buffer[(64 + 4) * 2 * 7 / 6 + 2];
 77    uint8_t encoded_data_len;
 78    uint8_t *app_buf;
 79    uint16_t total_len;
 80    uint16_t actual_len;
 81  } endpoint_t;
 82  
 83  typedef enum {
 84    EVENT_NONE,
 85    EVENT_CONNECT,
 86    EVENT_DISCONNECT,
 87    EVENT_HUB_PORT_CHANGE,
 88  } usb_device_event_t;
 89  
 90  typedef struct struct_usb_device_t usb_device_t;
 91  typedef struct struct_root_port_t {
 92    volatile bool initialized;
 93    volatile bool addr0_exists;
 94    volatile uint8_t pin_dp;
 95    volatile uint8_t pin_dm;
 96    volatile usb_device_event_t event;
 97    usb_device_t *root_device;
 98    PIO_USB_PINOUT pinout;
 99  
100    volatile bool is_fullspeed;
101    volatile bool connected;
102    volatile bool suspended;
103    uint8_t mode;
104  
105    // register interface
106    volatile uint32_t ints; // interrupt status
107    volatile uint32_t ep_complete;
108    volatile uint32_t ep_error;
109    volatile uint32_t ep_stalled;
110    volatile uint32_t ep_continue;
111  
112    // device only
113    uint8_t dev_addr;
114    uint8_t *setup_packet;
115  } root_port_t;
116  
117  struct struct_usb_device_t {
118    volatile bool connected;
119    volatile bool enumerated;
120    volatile usb_device_event_t event;
121    volatile uint8_t address;
122    volatile uint16_t vid;
123    volatile uint16_t pid;
124    volatile uint8_t device_class;
125    volatile bool is_fullspeed;
126    volatile bool is_root;
127    control_pipe_t control_pipe;
128    uint8_t endpoint_id[PIO_USB_DEV_EP_CNT];
129    uint8_t child_devices[PIO_USB_HUB_PORT_CNT];
130    struct struct_usb_device_t *parent_device;
131    uint8_t parent_port;
132    root_port_t *root;
133  };
134  
135  enum {
136    USB_SYNC = 0x80,
137    USB_PID_OUT = 0xe1,
138    USB_PID_IN = 0x69,
139    USB_PID_SOF = 0xa5,
140    USB_PID_SETUP = 0x2d,
141    USB_PID_DATA0 = 0xc3,
142    USB_PID_DATA1 = 0x4b,
143    USB_PID_ACK = 0xd2,
144    USB_PID_NAK = 0x5a,
145    USB_PID_STALL = 0x1e,
146    USB_PID_PRE = 0x3c,
147    USB_CRC16_PLACE = 0,
148  };
149  
150  enum {
151    DESC_TYPE_DEVICE = 0x01,
152    DESC_TYPE_CONFIG = 0x02,
153    DESC_TYPE_STRING = 0x03,
154    DESC_TYPE_INTERFACE = 0x04,
155    DESC_TYPE_ENDPOINT = 0x05,
156    DESC_TYPE_HID = 0x21,
157    DESC_TYPE_HID_REPORT = 0x22,
158  };
159  
160  enum {
161    CLASS_HID = 0x03,
162    CLASS_HUB = 0x09,
163  };
164  
165  enum {
166    EP_ATTR_CONTROL = 0x00,
167    EP_ATTR_ISOCHRONOUS = 0x01,
168    EP_ATTR_BULK = 0x02,
169    EP_ATTR_INTERRUPT = 0x03,
170    EP_ATTR_ENUMERATING = 0x80
171  };
172  
173  typedef struct {
174    //  uint8_t sync;
175    //  uint8_t pid;
176    uint8_t request_type;
177    uint8_t request;
178    uint8_t value_lsb;
179    uint8_t value_msb;
180    uint8_t index_lsb;
181    uint8_t index_msb;
182    uint8_t length_lsb;
183    uint8_t length_msb;
184    //  uint8_t crc16[2];
185  } usb_setup_packet_t;
186  
187  typedef struct {
188    uint8_t length;
189    uint8_t type;
190    uint8_t bcd_usb[2];
191    uint8_t device_class;
192    uint8_t subclass;
193    uint8_t protocol;
194    uint8_t max_packet_size;
195    uint8_t vid[2];
196    uint8_t pid[2];
197    uint8_t bcd_device[2];
198    uint8_t manufacture;
199    uint8_t product;
200    uint8_t serial;
201    uint8_t num_configu;
202  } device_descriptor_t;
203  
204  typedef struct {
205    uint8_t length;
206    uint8_t type;
207    uint8_t string[62];
208  } __attribute__((aligned(2))) string_descriptor_t;
209  
210  typedef struct {
211    uint8_t length;
212    uint8_t type;
213    uint8_t inum;
214    uint8_t altsetting;
215    uint8_t numep;
216    uint8_t iclass;
217    uint8_t isubclass;
218    uint8_t iprotocol;
219    uint8_t iface;
220  } interface_descriptor_t;
221  
222  typedef struct {
223    uint8_t length;
224    uint8_t type;
225    uint8_t epaddr;
226    uint8_t attr;
227    uint8_t max_size[2];
228    uint8_t interval;
229  } endpoint_descriptor_t;
230  
231  typedef struct {
232    uint8_t length;
233    uint8_t type;
234    uint8_t bcd_hid[2];
235    uint8_t contry_code;
236    uint8_t num_desc;
237    uint8_t desc_type;
238    uint8_t desc_len[2];
239  } hid_descriptor_t;
240  
241  typedef struct configuration_descriptor_tag {
242    uint8_t length;
243    uint8_t type;
244    uint8_t total_length_lsb;
245    uint8_t total_length_msb;
246    uint8_t num_interfaces;
247    uint8_t configuration_value;
248    uint8_t configuration;
249    uint8_t attributes;
250    uint8_t max_power;
251  } configuration_descriptor_t;
252  
253  typedef struct {
254    uint8_t lenght;
255    uint8_t type;
256    uint8_t port_num;
257    uint8_t chara_lsb;
258    uint8_t chara_msb;
259    uint8_t pow_on_time;
260    uint8_t current;
261    uint8_t removable;
262  } hub_descriptor_t;
263  
264  typedef struct {
265    uint16_t port_status;
266    uint16_t port_change;
267  } hub_port_status_t;
268  
269  enum {
270    HUB_SET_PORT_RESET = 4,
271    HUB_SET_PORT_POWER = 8,
272    HUB_CLR_PORT_CONNECTION = 16,
273    HUB_CLR_PORT_ENABLE = 17,
274    HUB_CLR_PORT_SUSPEND = 18,
275    HUB_CLR_PORT_RESET = 20,
276  };
277  
278  enum {
279    HUB_STAT_PORT_CONNECTION = (1 << 0),
280    HUB_STAT_PORT_ENABLE = (1 << 1),
281    HUB_STAT_PORT_SUSPEND = (1 << 2),
282    HUB_STAT_PORT_OC = (1 << 3),
283    HUB_STAT_PORT_RESET = (1 << 4),
284    HUB_STAT_PORT_POWER = (1 << 8),
285    HUB_STAT_PORT_LOWSPEED = (1 << 9),
286  };
287  
288  enum {
289    HUB_CHANGE_PORT_CONNECTION = (1 << 0),
290    HUB_CHANGE_PORT_ENABLE = (1 << 1),
291    HUB_CHANGE_PORT_SUSPEND = (1 << 2),
292    HUB_CHANGE_PORT_OC = (1 << 3),
293    HUB_CHANGE_PORT_RESET = (1 << 4),
294  };
295  
296  enum {
297    USB_REQ_DIR_IN = 0x80,
298    USB_REQ_DIR_OUT = 0x00,
299    USB_REQ_TYP_STANDARD = 0x00,
300    USB_REQ_TYP_CLASS = 0x20,
301    USB_REQ_TYP_VENDOR = 0x40,
302    USB_REQ_REC_DEVICE = 0x00,
303    USB_REQ_REC_IFACE = 0x01,
304    USB_REQ_REC_EP = 0x02,
305    USB_REQ_REC_OTHER = 0x03,
306  };
307  
308  #define GET_DEVICE_DESCRIPTOR_REQ_DEFAULT                                      \
309    { USB_REQ_DIR_IN, 0x06, 0, 0x01, 0, 0, 0x12, 0 }
310  #define GET_CONFIGURATION_DESCRIPTOR_REQ_DEFAULT                               \
311    { USB_REQ_DIR_IN, 0x06, 0, 0x02, 0, 0, 0x09, 0 }
312  #define SET_CONFIGURATION_REQ_DEFAULT                                          \
313    { USB_REQ_DIR_OUT, 0x09, 0, 0, 0, 0, 0, 0 }
314  #define SET_ADDRESS_REQ_DEFAULT                                                \
315    { USB_REQ_DIR_OUT, 0x5, 0x02, 0, 0, 0, 0, 0 }
316  #define SET_HID_IDLE_REQ_DEFAULT                                               \
317    { USB_REQ_TYP_CLASS | USB_REQ_REC_IFACE, 0x0A, 0, 0, 0, 0, 0, 0 }
318  #define GET_HID_REPORT_DESCRIPTOR_DEFAULT                                      \
319    { USB_REQ_DIR_IN | USB_REQ_REC_IFACE, 0x06, 0, 0x22, 0, 0, 0xff, 0 }
320  #define GET_HUB_DESCRPTOR_REQUEST                                              \
321    {                                                                            \
322      USB_REQ_DIR_IN | USB_REQ_TYP_CLASS | USB_REQ_REC_DEVICE, 0x06, 0, 0x29, 0, \
323          0, 8, 0                                                                \
324    }
325  #define GET_HUB_PORT_STATUS_REQUEST                                            \
326    {                                                                            \
327      USB_REQ_DIR_IN | USB_REQ_TYP_CLASS | USB_REQ_REC_OTHER, 0, 0, 0, 0, 0, 4,  \
328          0                                                                      \
329    }
330  #define SET_HUB_FEATURE_REQUEST                                                \
331    {                                                                            \
332      USB_REQ_DIR_OUT | USB_REQ_TYP_CLASS | USB_REQ_REC_OTHER, 0x03, 0, 0, 0, 0, \
333          0, 0                                                                   \
334    }
335  #define CLEAR_HUB_FEATURE_REQUEST                                              \
336    {                                                                            \
337      USB_REQ_DIR_OUT | USB_REQ_TYP_CLASS | USB_REQ_REC_OTHER, 0x01, 0, 0, 0, 0, \
338          0, 0                                                                   \
339    }
340  
341  typedef struct {
342    const uint8_t *device;
343    const uint8_t *config;
344    const uint8_t **hid_report;
345    const string_descriptor_t *string;
346  } usb_descriptor_buffers_t;