• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Bestechnic (Shanghai) Co., Ltd. All rights reserved.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef __USBHOST__
16 #define __USBHOST__
17 
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21 
22 #include "hal_usbhost.h"
23 
24 #define USING_MSGQ
25 // #define USB_SLEEP_TEST
26 // #define USB_WAKEUP_OPEN
27 
28 #define TOKEN_SETUP 0
29 #define TOKEN_IN  1
30 #define TOKEN_OUT 2
31 //  Status flags from hub
32 #define PORT_CONNECTION 0
33 #define PORT_ENABLE  1
34 #define PORT_SUSPEND  2
35 #define PORT_OVER_CURRENT 3
36 #define PORT_RESET 4
37 #define PORT_POWER 8
38 #define PORT_LOW_SPEED 9
39 
40 #define C_PORT_CONNECTION 16
41 #define C_PORT_ENABLE 17
42 #define C_PORT_SUSPEND 18
43 #define C_PORT_OVER_CURRENT 19
44 #define C_PORT_RESET 20
45 
46 //  Hardware defines
47 #define  TD_ROUNDING        (uint32_t)0x00040000
48 #define  TD_SETUP           (uint32_t)0x00000000
49 #define  TD_IN              (uint32_t)0x00100000
50 #define  TD_OUT             (uint32_t)0x00080000
51 #define  TD_DELAY_INT(x)    (uint32_t)((x) << 21)
52 #define  TD_TOGGLE_0        (uint32_t)0x02000000
53 #define  TD_TOGGLE_1        (uint32_t)0x03000000
54 #define  TD_CC              (uint32_t)0xF0000000
55 
56 //  HcControl
57 #define PERIODICLISTENABLE  0x00000004
58 #define ISOCHRONOUSENABLE   0x00000008
59 #define CONTROLLISTENABLE   0x00000010
60 #define BULKLISTENABLE      0x00000020
61 #define OPERATIONALMASK     0x00000080
62 #define HOSTCONTROLLERFUNCTIONALSTATE   0x000000C0
63 
64 //  HcCommandStatus
65 #define HOSTCONTROLLERRESET 0x00000001
66 #define CONTROLLISTFILLED   0x00000002
67 #define BULKLISTFILLED      0x00000004
68 
69 //  HcInterruptStatus Register
70 #define WRITEBACKDONEHEAD       0x00000002
71 #define STARTOFFRAME            0x00000004
72 #define RESUMEDETECTED          0x00000008
73 #define UNRECOVERABLEERROR      0x00000010
74 #define FRAMENUMBEROVERFLOW     0x00000020
75 #define ROOTHUB_STATUS_CHANGE   0x00000040
76 #define OWNERSHIPCHANGE         0x00000080
77 #define MASTERINTERRUPTENABLE   0x80000000
78 
79 //  HcRhStatus
80 #define SETGLOBALPOWER              0x00010000
81 #define DEVICEREMOTEWAKEUPENABLE    0x00008000
82 
83 //  HcRhPortStatus (hub 0, port 1)
84 #define CURRENTCONNECTSTATUS        0x00000001
85 #define PORTENABLESTATUS            0x00000002
86 #define PORTSUSPENDSTATUS           0x00000004
87 #define PORTOVERCURRENTINDICATOR    0x00000008
88 #define PORTRESETSTATUS             0x00000010
89 
90 #define PORTPOWERSTATUS         0x00000100
91 #define LOWSPEEDDEVICE          0x00000200
92 #define HIGHSPEEDDEVICE         0x00000400
93 
94 #define CONNECT_STATUS_CHANGE   (CURRENTCONNECTSTATUS << 16)
95 #define PORTRESETSTATUSCHANGE   (PORTRESETSTATUS << 16)
96 
97 #define SKIP_CLEANUP_HW_CHAN        (1 << 0)
98 #define SKIP_CLEANUP_CLOSE          (1 << 1)
99 #define SKIP_CLEANUP_FILE_SYSTEM    (1 << 2)
100 
101 #define REQUEST_TYPE_CLASS          0x20
102 #define USB_ENDPORT_DMA_BUFFER_LEN  4096
103 enum USB_ENDPORT_STATE_T
104 {
105     USB_ENDPORT_STATE_FREE,
106     USB_ENDPORT_STATE_NOTQUEUED,
107     USB_ENDPORT_STATE_IDLE,
108     USB_ENDPORT_STATE_SETUPQUEUED,
109     USB_ENDPORT_STATE_DATAQUEUED,
110     USB_ENDPORT_STATE_STATUSQUEUED,
111     USB_ENDPORT_STATE_CALLBACK_PENDING,
112     // USB_ENDPORT_STATE_WAIT_PROCESS_DONE,
113 };
114 
115 //HostController EndPoint Descriptor
116 typedef struct {
117     volatile uint32_t   control;
118     volatile uint32_t   tail_td;
119     volatile uint32_t   head_td;
120     volatile uint32_t   next;
121 } HCED_T;
122 
123 //HostController Transfer Descriptor
124 typedef struct {
125     volatile uint32_t   control;
126     volatile uint32_t   curr_buf_ptr;
127     volatile uint32_t   next;
128     volatile uint32_t   bufend;
129 } HCTD_T;
130 
131 // Host Controller Communication Area
132 typedef struct {
133     volatile uint32_t   InterruptTable[32];
134     volatile uint16_t   FrameNumber;
135     volatile uint16_t   FrameNumberPad;
136     volatile uint32_t   DoneHead;
137     volatile uint8_t Reserved[120];
138 } HCCA;
139 
140 enum USBHOST_CLASS_CODE_T
141 {
142     USB_CLASS_DEVICE = 0x0,
143     USB_CLASS_AUDIO = 0x01,
144     USB_CLASS_COMM = 0x02,
145     USB_CLASS_HID = 0x03,
146     USB_CLASS_PHYSICAL = 0x05,
147     USB_CLASS_IMAGING = 0x06,
148     USB_CLASS_PRINTER = 0x07,
149     USB_CLASS_MASS_STORAGE = 0x08,
150     USB_CLASS_HUB = 0x09,
151     USB_CLASS_DATA = 0x0a,
152     USB_CLASS_SMART_CARD = 0x0b,
153     USB_CLASS_CONTENT_SECURITY = 0x0d,
154     USB_CLASS_VIDEO = 0x0e,
155     USB_CALSS_PERSONAL_HEALTHCARE = 0x0f,
156     USB_CLASS_DIAGNOSTIC_DEVICE = 0xdc,
157     USB_CLASS_WIRELESS = 0xe0,
158     USB_CLASS_MISCELLANEOUS = 0xef,
159     USB_CLASS_APP_SPECIFIC = 0xfe,
160     USB_CLASS_VENDOR_SPECIFIC = 0xff
161 };
162 
163 enum USBHOST_DESCRIPTOR_TYPE
164 {
165     DESCRIPTOR_TYPE_DEVICE = 0x01,
166     DESCRIPTOR_TYPE_CONFIG = 0x02,
167     DESCRIPTOR_TYPE_STRING = 0x03,
168     DESCRIPTOR_TYPE_INTERFACE = 0x04,
169     DESCRIPTOR_TYPE_ENDPOINT = 0x05,
170     DESCRIPTOR_TYPE_BOS = 0x0f,
171     DESCRIPTOR_TYPE_DEVICE_CAPABILITY = 0x10,
172     DESCRIPTOR_TYPE_DEVICE_HID = 0x21,
173     DESCRIPTOR_TYPE_DEVICE_REPORT = 0x22,
174     DESCRIPTOR_TYPE_DEVICE_PHYSICAL = 0x23,
175     DESCRIPTOR_TYPE_DEVICE_HUB = 0x29,
176     DESCRIPTOR_TYPE_DEVICE_SUPERSPEED_HUB = 0x2a,
177     DESCRIPTOR_TYPE_DEVICE_ENDPOINT_COMPANION = 0x2a,
178 };
179 
180 enum USBHOST_ENDPOINT_DIRECTION_T
181 {
182     USB_ENDPOINT_DIRECTION_IN = 0x80,
183     USB_ENDPOINT_DIRECTION_OUT = 0x0,
184 };
185 
186 enum USBHOST_TRANSFER_TYPE_T
187 {
188     USB_TRANSFER_TYPE_CONTROL = 0,
189     USB_TRANSFER_TYPE_ISOCHRONOUS = 1,
190     USB_TRANSFER_TYPE_BULK = 2,
191     USB_TRANSFER_TYPE_INTERRUPT = 3,
192 };
193 
194 enum USBHOST_REQUEST_T
195 {
196     USB_REQUEST_GET_STATUS = 0x00,
197     USB_REQUEST_CLEAR_FEATURE = 0x01,
198     USB_REQUEST_SET_FEATURE = 0x03,
199     USB_REQUEST_SET_ADDRESS = 0x05,
200     USB_REQUEST_GET_DESCRIPTOR = 0x06,
201     USB_REQUEST_SET_DESCRIPTOR = 0x07,
202     USB_REQUEST_GET_CONFIGURATION = 0x08,
203     USB_REQUEST_SET_CONFIGURATION = 0x09,
204     USB_REQUEST_GET_INTERFACE = 0x0a,
205     USB_REQUEST_SET_INTERFACE = 0x0b,
206     USB_REQUEST_SYNCH_FRAME = 0x0c,
207     USB_REQUEST_SET_SEL = 0x30,
208     USB_REQUEST_SET_ISOCH_DELAY = 0x31,
209 };
210 
211 enum USBHOST_REQUEST_RECIPIENT_T
212 {
213     USB_REQUEST_RECIPIENT_DEVICE = 0x00,
214     USB_REQUEST_RECIPIENT_INTERFACE = 0x01,
215     USB_REQUEST_RECIPIENT_ENDPOINT = 0x02,
216     USB_REQUEST_RECIPIENT_OTHER = 0x03,
217 };
218 
219 #define AUTOEVT(_class,_subclass,_protocol) (((_class) << 16) | ((_subclass) << 8) | _protocol)
220 #define AUTO_KEYBOARD AUTOEVT(USB_CLASS_HID,1,1)
221 #define AUTO_MOUSE AUTOEVT(USB_CLASS_HID,1,2)
222 
223 #define MAX_DEVICES 8               // Max number of devices
224 #define MAX_ENDPOINTS_TOTAL 16      // Max number of endpoints total
225 #define MAX_ENDPOINTS_PER_DEVICE 8  // Max number of endpoints for any one device
226 #define MAX_CALLBACK_PENDING 16
227 
228 typedef struct {
229     uint8_t     bLength;
230     uint8_t     bDescriptorType;
231     uint16_t    bcdUSB;
232     uint8_t     bDeviceClass;
233     uint8_t     bDeviceSubClass;
234     uint8_t     bDeviceProtocol;
235     uint8_t     bMaxPacketSize;
236     uint16_t    idVendor;
237     uint16_t    idProduct;
238     uint16_t    bcdDevice; // version
239     uint8_t     iManufacturer;
240     uint8_t     iProduct;
241     uint8_t     iSerialNumber;
242     uint8_t     bNumConfigurations;
243 } USBHOST_DEVICE_DESCRIPTOR_T;  // 18 bytes
244 
245 typedef struct {
246     uint8_t     bLength;
247     uint8_t     bDescriptorType;
248     uint16_t    wTotalLength;
249     uint8_t     bNumInterfaces;
250     uint8_t     bConfigurationValue;    // Value to use as an argument to select this configuration
251     uint8_t     iConfiguration;         // Index of String Descriptor describing this configuration
252     uint8_t     bmAttributes;           // Bitmap D7 Reserved, set to 1. (USB 1.0 Bus Powered),D6 Self Powered,D5 Remote Wakeup,D4..0 = 0
253     uint8_t     bMaxPower;              // Maximum Power Consumption in 2mA units
254 } USBHOST_CONFIGURATION_DICRIPTOR_T;
255 
256 typedef struct {
257     uint8_t bLength;
258     uint8_t bDescriptorType;
259     uint8_t bInterfaceNumber;
260     uint8_t bAlternateSetting;
261     uint8_t bNumEndpoints;
262     uint8_t bInterfaceClass;
263     uint8_t bInterfaceSubClass;
264     uint8_t bInterfaceProtocol;
265     uint8_t iInterface;             // Index of String Descriptor Describing this interface
266 } USBHOST_INTERFACE_DESCRIPTOR_T;
267 
268 typedef struct {
269     uint8_t     bLength;
270     uint8_t     bDescriptorType;
271     uint8_t     bEndpointAddress;   // Bits 0:3 endpoint, Bits 7 Direction 0 = Out, 1 = In (Ignored for Control Endpoints)
272     uint8_t     bmAttributes;       // Bits 0:1 00 = Control, 01 = Isochronous, 10 = Bulk, 11 = Interrupt
273     uint16_t    wMaxPacketSize;
274     uint8_t     bInterval;          // Interval for polling endpoint data transfers.
275     /* NOTE:  these two are _only_ in audio endpoints. */
276     /* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
277     uint8_t     refresh;
278     uint8_t     synch_address;
279 } USBHOST_ENDPOINT_DESCRIPTOR_T;
280 
281 typedef struct {
282     uint8_t    bLength;
283     uint8_t    bDescriptorType;
284     uint16_t   bcdHID;
285     uint8_t    bCountryCode;
286     uint8_t    bNumDescriptors;
287     uint8_t    bDescriptorType2;
288     uint16_t   wDescriptorLength;
289 } USBHOST_HID_DESCRIPTOR_T;
290 
291 typedef struct {
292     uint8_t length;
293     uint8_t descriptor_type;
294     uint8_t string[1];
295 } USBHOST_STRING_DESCRIPTION_T;
296 
297 #define USB_MAXCHILDREN     (31)
298 
299 typedef struct {
300     uint8_t  bLength;
301     uint8_t  bDescriptorType;
302     uint8_t  bNbrPorts;
303     uint16_t wHubCharacteristics;
304     uint8_t  bPwrOn2PwrGood;
305     uint8_t  bHubContrCurrent;
306 
307     /* 2.0 and 3.0 hubs differ here */
308     union {
309         struct {
310             /* add 1 bit for hub status change; round to bytes */
311             uint8_t  DeviceRemovable[(USB_MAXCHILDREN + 1 + 7) / 8];
312             uint8_t  PortPwrCtrlMask[(USB_MAXCHILDREN + 1 + 7) / 8];
313         } __attribute__ ((packed)) hs;
314 
315         struct {
316             uint8_t     bHubHdrDecLat;
317             uint16_t    wHubDelay;
318             uint16_t    DeviceRemovable;
319         } __attribute__ ((packed)) ss;
320     } u;
321 } USBHOST_HUB_DESCRIPTOR_T;
322 
323 enum ENDPOINTSTATE {
324     EP_FREE,
325     EP_NOTQUEUED,
326     EP_IDLE,
327     EP_SETUPQUEUED,
328     EP_DATAQUEUED,
329     EP_STATUSQUEUED,
330     EP_CALLBACKPENDING
331 };
332 
333 typedef void (*USBHOSTCALLBACK)(int device, int endpoint, int status, uint8_t* data, int len, void* userData);
334 typedef  void (*INTERRUPT_HANDLE_CB) (void);
335 typedef  void (*PLUG_HANDLE_CB) (void);
336 
337 typedef struct UHEndpoint UHEndpoint;
338 typedef struct UHDevice UHDevice;
339 typedef struct UHController UHController;
340 
341 typedef struct {
342     void (*init)(UHEndpoint *);
343     void (*hook)(UHEndpoint *);
344 
345     uint8_t (*is_free)(UHEndpoint *);
346     int (*get_direct)(UHEndpoint *);
347     int (*status)(UHEndpoint *);
348     void (*set_current_state)(UHEndpoint *, int s);
349     UHController * (*get_controller)(UHEndpoint *);
350 
351     int (*wait_io_done)(UHEndpoint *);
352     int (*prepare)(UHEndpoint *, UHDevice * device, uint8_t device_id, int address, int ep_type, int mps, int index);
353     int (*before_transfer)(UHEndpoint *, uint8_t flags, uint8_t* data, int length, USBHOSTCALLBACK callback, void* userData);
354     int (*transfer)(UHEndpoint *, int token, uint8_t* data, int len, int state);
355     void (*release_chan)(UHEndpoint *, uint8_t *chan);
356     void (*release)(UHEndpoint *, uint8_t _skipCleanupBitmap);
357     void (*pending_process)(UHEndpoint *);
358 
359     void (*show)(UHEndpoint *);
360 } UHEndpoint_actions;
361 
362 struct UHEndpoint {
363     //location information under Device
364     UHDevice * device;
365     uint8_t device_id;
366     int index;  //the index of endpoints in UHDevice
367 
368     //self information
369     int address;
370     uint8_t ep_transfer_type;   //control/bulk/interrupt/...
371 
372     uint8_t chan;
373     uint8_t chan_ctrl_in;
374 
375     uint32_t dma_buf[4096 / 4];
376     bool first_xfer;
377     uint16_t mps;
378 
379     volatile uint8_t current_state;
380 
381     uint16_t     length;
382     uint8_t*     data;
383     USBHOSTCALLBACK callback;    // Must be a multiple of 16 bytes long
384     void*  user_data;
385 
386     UHEndpoint_actions * actions;
387     // HCED EndpointDescriptor;    // Pointer to EndpointDescriptor == Pointer to Endpoint
388     // HCTD TDHead;
389 };
390 
391 typedef struct {
392     //function list
393     void (*init)(UHDevice *);
394     void (*hook)(UHDevice *);
395 
396     UHEndpoint * (*get_endpoint)(UHDevice *, int address, int *index);
397     UHEndpoint * (*get_write_ep)(UHDevice *);
398     UHEndpoint * (*get_read_ep)(UHDevice *);
399 
400     int (*get_descriptor)(UHDevice *, int descType,int descIndex, uint8_t* data, int length);
401     int (*connect)(UHDevice *, UHController *, int hub, int port, int address, int isLowSpeed);
402     int (*set_config_and_interface)(UHDevice *);
403     int (*after_add_endpoint)(UHDevice *, USBHOST_INTERFACE_DESCRIPTOR_T* id, USBHOST_ENDPOINT_DESCRIPTOR_T * ed);
404     void (*load_device)(UHDevice * that, USBHOST_INTERFACE_DESCRIPTOR_T* interfaceDesc);
405     int (*disconnect)(UHDevice *, uint8_t _skipCleanupBitmap);
406     int (*unload)(UHDevice *);
407     int (*on_insert_disk)(UHDevice *);
408     int (*add_endpoint)(UHDevice *, int address, int attributes, int maxPacketSize, int interval);
409 
410     int (*get_string)(UHDevice *, int device, int index, char* dst, int length);
411     int (*set_address)(UHDevice *, int new_addr);
412     int (*set_config)(UHDevice *, int configNum);
413     int (*set_interface)(UHDevice *, int ifNum, int altNum);
414     //  HUB stuff
415     int (*set_port_feature)(UHDevice *, int feature, int index);
416     int (*clear_port_feature)(UHDevice *, int feature, int index);
417     int (*port_poweron)(UHDevice *, int port, int delayMs);
418     int (*port_reset)(UHDevice *, int port);
419     int (*get_port_status)(UHDevice *, int port, u32* status);
420     // Transfer
421     int (*control_transfer)(UHDevice *, int request_type, int request, int value, int index, uint8_t* data, int length, USBHOSTCALLBACK callback, void * userData);
422     int (*interrupt_transfer)(UHDevice *, int ep, uint8_t* data, int length, USBHOSTCALLBACK callback, void* userData);
423     int (*bulk_transfer)(UHDevice *, int ep, uint8_t* data, int length, USBHOSTCALLBACK callback, void* userData);
424     int (*transfer)(UHDevice *, int ep, uint8_t flags, uint8_t* data, int length, USBHOSTCALLBACK callback, void* userData);
425     int (*transfer_abort)(UHDevice *, int ep);
426     struct HAL_USBHOST_SETUP_PKT_T * (*get_setup)(UHDevice *);
427 
428     void (*add_auto_event)(UHDevice *, USBHOST_INTERFACE_DESCRIPTOR_T* id, USBHOST_ENDPOINT_DESCRIPTOR_T* ed);
429     int (*init_hub)(UHDevice *);
430     int (*get_hub_port_count)(UHDevice *);
431     int (*get_hub_interrupt_data)(UHDevice *);
432 
433     void (*show)(UHDevice *);
434 } UHDevice_actions;
435 
436 struct UHDevice {
437     //Location information Under controller
438     UHController * controller;
439     int index;      //the index of devices in UHController
440 
441     //self information
442     uint8_t hub;
443     uint8_t port;
444     uint8_t device_id;
445     uint8_t pad;
446     uint8_t  is_low_speed;
447 
448     uint8_t scsi_read_ep;
449     uint8_t scsi_write_ep;
450     uint8_t scsi_itf_num;
451 
452     USBHOST_DEVICE_DESCRIPTOR_T desc;
453 
454     //  Only if this device is a hub
455     uint8_t hub_port_count; // nonzero if this is a hub
456     uint8_t hub_interrupt_data;
457     uint8_t hub_map;
458     uint8_t hub_mask;
459 
460     struct HAL_USBHOST_SETUP_PKT_T setup_buffer;
461     UHEndpoint * zero;
462 
463     unsigned int usb_dma_in_buffer[64 * 4 /4];
464     unsigned int usb_dma_len;
465 
466     int endpoint_status[MAX_ENDPOINTS_PER_DEVICE];
467     UHEndpoint endpoints[MAX_ENDPOINTS_PER_DEVICE];
468 
469     UHDevice_actions * actions;
470 };
471 
472 typedef struct {
473     //function list
474     void (*init)(UHController *, INTERRUPT_HANDLE_CB interrupt_handler, PLUG_HANDLE_CB plug_handler);
475     void (*hook)(UHController *);
476     void (*hw_init)(UHController *);
477 
478     UHEndpoint * (*get_ep0)(UHController *);
479     struct HAL_USBHOST_SETUP_PKT_T * (*get_setup)(UHController *);
480 
481     void (*trig_event)(UHController *, int event_type, int evt);
482 
483     int (*connect)(UHController *, int hub, int port, bool isLowSpeed);
484     int (*disconnect)(UHController *, int hub, int port);
485     int (*disconnect_device)(UHController *, int device_index);
486 
487     void (*reset_port)(UHController *, int hub, int port);
488     int32_t (*resume_port)(UHController *, int hub, int port);
489     int32_t (*suspend_port)(UHController *, int hub, int port);
490     void (*reconnect_cleanup)(UHController *, int hub, int port);
491     UHDevice * (*get_device)(UHController *, int device_id);
492     int (*get_device_index)(UHController *, int hub, int port);
493     // Called from interrupt
494     void (*hub_status_change)(UHController *, int hub, int port, u32 status);
495     void (*countdown_process)(UHController *, uint8_t hub, uint8_t port, int connect);
496 #ifdef USB_SLEEP_TEST
497     void (*sleep_countdown_process)(UHController * that, int hub, int port);
498     void (*wakeup_countdown_process)(UHController * that, int hub, int port);
499     void (*fs_test_countdown_process)(UHController *that, int hub, int port);
500 #endif
501     void (*loop)(UHController *);
502 
503     //HubInterrupt - bitmap in dev->HubInterruptData
504     void (*hub_interrupt)(UHController *, int device);
505 
506     //Called from interrupt...
507     //Control endpoints use a state machine to progress through the transfers
508     void (*process_done_q)(UHController *, UHEndpoint* endpoint, int status);
509 
510     void (*show)(UHController *);
511     void (*deinit)(UHController *);
512 } UHController_actions;
513 
514 struct UHController {
515     uint8_t connect_hub;
516     uint8_t connect_port;
517     u32 connect_countdown;
518     u32 disconn_countdown;
519 #ifdef USB_SLEEP_TEST
520     u32 sleep_count_down;
521     u32 wakeup_count_down;
522     u32 fs_test_count_down;
523 #endif
524 
525     int device_hubport[MAX_DEVICES]; //hubport<-->device map
526     UHDevice devices[MAX_DEVICES];
527 
528     struct HAL_USBHOST_SETUP_PKT_T setup_buffer;
529     UHEndpoint zero;
530     volatile UHEndpoint * pending_endpoints[MAX_CALLBACK_PENDING];
531     int callbacks_pending; //how many pending callback functions
532     uint8_t connect_pending;
533 
534     INTERRUPT_HANDLE_CB interrupt_handler;
535     PLUG_HANDLE_CB plug_handler;
536 
537     uint8_t root_hub_status_change; //  Root hub status has changed, set from ISR
538     enum HAL_USBHOST_PORT_EVENT_T root_hub_event;
539 
540     uint8_t plug_status_change;
541     enum HAL_USBHOST_PLUG_STATUS_T plug_status;
542 
543     volatile int frame_number;
544 
545     UHController_actions * actions;
546 };
547 
548 int usbhost_control_transfer(int device, int request_type, int request, int value, int index, uint8_t* data, int length, USBHOSTCALLBACK callback, void * userData);
549 int usbhost_interrupt_transfer(int device, int ep, uint8_t* data, int length, USBHOSTCALLBACK callback, void* userData);
550 int usbhost_bulk_transfer(int device, int ep, uint8_t* data, int length, USBHOSTCALLBACK callback, void* userData);
551 void usbhost_plug_handler(enum HAL_USBHOST_PLUG_STATUS_T status);
552 
553 #define USB_PLUG_STATUS_MESSAGE_PLUG    0x0
554 #define USB_ROOT_HUB_STATUS_CHANGE      0x1
555 #define USB_TRANSFER_COMPLETED          0x2
556 #define USB_DEVICE_LOADED               0x3
557 #define DISCONN_COUNTDOWN_EVENT         0x4
558 #define CONN_COUNTDOWN_EVENT            0x5
559 #define DISK_INSERTED                   0x6
560 #define DISK_PLUGOUT                    0x7
561 #define WAKEUP_COUNTDOWN_EVENT          0x8
562 #define SLEEP_COUNTDOWN_EVENT           0x9
563 #define FS_TEST_COUNTDOWN_EVENT         0xA
564 
565 #ifdef USING_MSGQ
566 #define USBHOST_MAILBOX_MAX   20
567 #define MSG_CALLBACK_MAX 20
568 
569 typedef int (*USBHOST_MSG_CALLBACK)(void *msg, void *context);
570 typedef int (*USBHOST_NOMSGCALLBACK)(void *context);
571 
572 typedef struct {
573     int msg_id;
574     USBHOST_MSG_CALLBACK cb;
575 } ID_CB_MAP;
576 
577 typedef struct {
578     int msg_id;
579     USBHOST_NOMSGCALLBACK cb;
580 } ID_NOMSGCB_MAP;
581 
582 typedef struct {
583     int id;
584     uint32_t param0;
585 } USBHOST_MESSAGE;
586 
587 int usbhost_register_callback(int msg_id, USBHOST_MSG_CALLBACK cb);
588 #endif
589 
590 void usbhost_init(INTERRUPT_HANDLE_CB interrupt_handler, PLUG_HANDLE_CB plug_handler);
591 void usbhost_loop();
592 
593 #define IO_PENDING -100
594 #define ERR_ENDPOINT_NONE_LEFT      -101
595 #define ERR_ENDPOINT_NOT_FOUND      -102
596 #define ERR_DEVICE_NOT_FOUND        -103
597 #define ERR_DEVICE_NONE_LEFT        -104
598 #define ERR_HUB_INIT_FAILED         -105
599 #define ERR_INTERFACE_NOT_FOUND     -106
600 #define ERR_DATA_SIZE_IS_ZERO       -107
601 #define ERR_DATA_SIZE_TOO_LARGE     -108
602 #define ERR_DATA_SIZE_NOT_ALIGNMENT -109
603 
604 #ifdef __cplusplus
605 }
606 #endif
607 
608 #endif