1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
|
/**************************************************************************//**
* @file usb.h
* @version V1.00
* @brief USB Host library header file.
*
* SPDX-License-Identifier: Apache-2.0
*
* @copyright (C) 2017 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef _USBH_H_
#define _USBH_H_
#include "config.h"
#include "usbh_lib.h"
#include "ehci.h"
#include "ohci.h"
/// @cond HIDDEN_SYMBOLS
struct utr_t;
struct udev_t;
struct hub_dev_t;
struct iface_t;
struct ep_info_t;
/*----------------------------------------------------------------------------------*/
/* USB device request setup packet */
/*----------------------------------------------------------------------------------*/
#ifdef __ICCARM__
typedef struct
{
__packed uint8_t bmRequestType;
__packed uint8_t bRequest;
__packed uint16_t wValue;
__packed uint16_t wIndex;
__packed uint16_t wLength;
} DEV_REQ_T;
#else
typedef struct __attribute__((__packed__))
{
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
}
DEV_REQ_T;
#endif
/*
* bmRequestType[7] - Data transfer direction
*/
#define REQ_TYPE_OUT 0x00
#define REQ_TYPE_IN 0x80
/*
* bmRequestType[6:5] - Type
*/
#define REQ_TYPE_STD_DEV 0x00
#define REQ_TYPE_CLASS_DEV 0x20
#define REQ_TYPE_VENDOR_DEV 0x40
/*
* bmRequestType[4:0] - Recipient
*/
#define REQ_TYPE_TO_DEV 0x00
#define REQ_TYPE_TO_IFACE 0x01
#define REQ_TYPE_TO_EP 0x02
#define REQ_TYPE_TO_OTHER 0x03
/*
* Standard Requests
*/
#define USB_REQ_GET_STATUS 0x00
#define USB_REQ_CLEAR_FEATURE 0x01
#define USB_REQ_SET_FEATURE 0x03
#define USB_REQ_SET_ADDRESS 0x05
#define USB_REQ_GET_DESCRIPTOR 0x06
#define USB_REQ_SET_CONFIGURATION 0x09
#define USB_REQ_SET_INTERFACE 0x0B
/*
* Descriptor Types
*/
#define USB_DT_STANDARD 0x00
#define USB_DT_CLASS 0x20
#define USB_DT_VENDOR 0x40
#define USB_DT_DEVICE 0x01
#define USB_DT_CONFIGURATION 0x02
#define USB_DT_STRING 0x03
#define USB_DT_INTERFACE 0x04
#define USB_DT_ENDPOINT 0x05
#define USB_DT_DEVICE_QUALIFIER 0x06
#define USB_DT_OTHER_SPEED_CONF 0x07
#define USB_DT_IFACE_POWER 0x08
/*----------------------------------------------------------------------------------*/
/* USB standard descriptors */
/*----------------------------------------------------------------------------------*/
/* Descriptor header */
#ifdef __ICCARM__
typedef struct
{
__packed uint8_t bLength;
__packed uint8_t bDescriptorType;
} DESC_HDR_T;
#else
typedef struct __attribute__((__packed__))
{
uint8_t bLength;
uint8_t bDescriptorType;
}
DESC_HDR_T;
#endif
/*----------------------------------------------------------------------------------*/
/* USB device descriptor */
/*----------------------------------------------------------------------------------*/
#ifdef __ICCARM__
typedef struct /*!< device descriptor structure */
{
__packed uint8_t bLength; /*!< Length of device descriptor */
__packed uint8_t bDescriptorType; /*!< Device descriptor type */
__packed uint16_t bcdUSB; /*!< USB version number */
__packed uint8_t bDeviceClass; /*!< Device class code */
__packed uint8_t bDeviceSubClass; /*!< Device subclass code */
__packed uint8_t bDeviceProtocol; /*!< Device protocol code */
__packed uint8_t bMaxPacketSize0; /*!< Maximum packet size of control endpoint*/
__packed uint16_t idVendor; /*!< Vendor ID */
__packed uint16_t idProduct; /*!< Product ID */
__packed uint16_t bcdDevice; /*!< Device ID */
__packed uint8_t iManufacturer; /*!< Manufacture description string ID */
__packed uint8_t iProduct; /*!< Product description string ID */
__packed uint8_t iSerialNumber; /*!< Serial number description string ID */
__packed uint8_t bNumConfigurations; /*!< Total number of configurations */
} DESC_DEV_T; /*!< device descriptor structure */
#else
/*----------------------------------------------------------------------------------*/
/* USB device descriptor */
/*----------------------------------------------------------------------------------*/
typedef struct __attribute__((__packed__)) /*!< device descriptor structure */
{
uint8_t bLength; /*!< Length of device descriptor */
uint8_t bDescriptorType; /*!< Device descriptor type */
uint16_t bcdUSB; /*!< USB version number */
uint8_t bDeviceClass; /*!< Device class code */
uint8_t bDeviceSubClass; /*!< Device subclass code */
uint8_t bDeviceProtocol; /*!< Device protocol code */
uint8_t bMaxPacketSize0; /*!< Maximum packet size of control endpoint*/
uint16_t idVendor; /*!< Vendor ID */
uint16_t idProduct; /*!< Product ID */
uint16_t bcdDevice; /*!< Device ID */
uint8_t iManufacturer; /*!< Manufacture description string ID */
uint8_t iProduct; /*!< Product description string ID */
uint8_t iSerialNumber; /*!< Serial number description string ID */
uint8_t bNumConfigurations; /*!< Total number of configurations */
}
DESC_DEV_T; /*!< device descriptor structure */
#endif
/*
* Configuration Descriptor
*/
#ifdef __ICCARM__
typedef struct usb_config_descriptor /*!< Configuration descriptor structure */
{
__packed uint8_t bLength; /*!< Length of configuration descriptor */
__packed uint8_t bDescriptorType; /*!< Descriptor type */
__packed uint16_t wTotalLength; /*!< Total length of this configuration */
__packed uint8_t bNumInterfaces; /*!< Total number of interfaces */
__packed uint8_t bConfigurationValue; /*!< Configuration descriptor number */
__packed uint8_t iConfiguration; /*!< String descriptor ID */
__packed uint8_t bmAttributes; /*!< Configuration characteristics */
__packed uint8_t MaxPower; /*!< Maximum power consumption */
} DESC_CONF_T; /*!< Configuration descriptor structure */
#else
typedef struct __attribute__((__packed__)) usb_config_descriptor /*!< Configuration descriptor structure */
{
uint8_t bLength; /*!< Length of configuration descriptor */
uint8_t bDescriptorType; /*!< Descriptor type */
uint16_t wTotalLength; /*!< Total length of this configuration */
uint8_t bNumInterfaces; /*!< Total number of interfaces */
uint8_t bConfigurationValue; /*!< Configuration descriptor number */
uint8_t iConfiguration; /*!< String descriptor ID */
uint8_t bmAttributes; /*!< Configuration characteristics */
uint8_t MaxPower; /*!< Maximum power consumption */
} DESC_CONF_T; /*!< Configuration descriptor structure */
#endif
/*
* Interface Descriptor
*/
#ifdef __ICCARM__
typedef struct usb_interface_descriptor /*!< Interface descriptor structure */
{
__packed uint8_t bLength; /*!< Length of interface descriptor */
__packed uint8_t bDescriptorType; /*!< Descriptor type */
__packed uint8_t bInterfaceNumber; /*!< Interface number */
__packed uint8_t bAlternateSetting;/*!< Alternate setting number */
__packed uint8_t bNumEndpoints; /*!< Number of endpoints */
__packed uint8_t bInterfaceClass; /*!< Interface class code */
__packed uint8_t bInterfaceSubClass; /*!< Interface subclass code */
__packed uint8_t bInterfaceProtocol; /*!< Interface protocol code */
__packed uint8_t iInterface; /*!< Interface ID */
} DESC_IF_T; /*!< Interface descriptor structure */
#else
typedef struct __attribute__((__packed__)) usb_interface_descriptor /*!< Interface descriptor structure */
{
uint8_t bLength; /*!< Length of interface descriptor */
uint8_t bDescriptorType; /*!< Descriptor type */
uint8_t bInterfaceNumber; /*!< Interface number */
uint8_t bAlternateSetting; /*!< Alternate setting number */
uint8_t bNumEndpoints; /*!< Number of endpoints */
uint8_t bInterfaceClass; /*!< Interface class code */
uint8_t bInterfaceSubClass; /*!< Interface subclass code */
uint8_t bInterfaceProtocol; /*!< Interface protocol code */
uint8_t iInterface; /*!< Interface ID */
} DESC_IF_T; /*!< Interface descriptor structure */
#endif
/*
* Interface descriptor bInterfaceClass[7:0]
*/
#if 0
#define USB_CLASS_AUDIO 0x01
#define USB_CLASS_COMM 0x02
#define USB_CLASS_HID 0x03
#define USB_CLASS_PRINTER 0x07
#define USB_CLASS_MASS_STORAGE 0x08
#define USB_CLASS_HUB 0x09
#define USB_CLASS_DATA 0x0A
#define USB_CLASS_VIDEO 0x0E
#endif
/*
* Endpoint Descriptor
*/
#ifdef __ICCARM__
typedef struct usb_endpoint_descriptor /*!< Endpoint descriptor structure */
{
__packed uint8_t bLength; /*!< Length of endpoint descriptor */
__packed uint8_t bDescriptorType; /*!< Descriptor type */
__packed uint8_t bEndpointAddress; /*!< Endpoint address */
__packed uint8_t bmAttributes; /*!< Endpoint attribute */
__packed uint16_t wMaxPacketSize; /*!< Maximum packet size */
__packed uint8_t bInterval; /*!< Synchronous transfer interval */
__packed uint8_t bRefresh; /*!< Refresh */
__packed uint8_t bSynchAddress; /*!< Sync address */
} DESC_EP_T; /*!< Endpoint descriptor structure */
#else
typedef struct __attribute__((__packed__)) usb_endpoint_descriptor /*!< Endpoint descriptor structure */
{
uint8_t bLength; /*!< Length of endpoint descriptor */
uint8_t bDescriptorType; /*!< Descriptor type */
uint8_t bEndpointAddress; /*!< Endpoint address */
uint8_t bmAttributes; /*!< Endpoint attribute */
uint16_t wMaxPacketSize; /*!< Maximum packet size */
uint8_t bInterval; /*!< Synchronous transfer interval */
uint8_t bRefresh; /*!< Refresh */
uint8_t bSynchAddress; /*!< Sync address */
} DESC_EP_T; /*!< Endpoint descriptor structure */
#endif
/*
* Endpoint descriptor bEndpointAddress[7] - direction
*/
#define EP_ADDR_DIR_MASK 0x80
#define EP_ADDR_DIR_IN 0x80
#define EP_ADDR_DIR_OUT 0x00
/*
* Endpoint descriptor bmAttributes[1:0] - transfer type
*/
#define EP_ATTR_TT_MASK 0x03
#define EP_ATTR_TT_CTRL 0x00
#define EP_ATTR_TT_ISO 0x01
#define EP_ATTR_TT_BULK 0x02
#define EP_ATTR_TT_INT 0x03
/*----------------------------------------------------------------------------------*/
/* USB Host controller driver */
/*----------------------------------------------------------------------------------*/
typedef struct
{
int (*init)(void);
void (*shutdown)(void);
void (*suspend)(void);
void (*resume)(void);
int (*ctrl_xfer)(struct utr_t *utr);
int (*bulk_xfer)(struct utr_t *utr);
int (*int_xfer)(struct utr_t *utr);
int (*iso_xfer)(struct utr_t *utr);
int (*quit_xfer)(struct utr_t *utr, struct ep_info_t *ep);
/* root hub support */
int (*rthub_port_reset)(int port);
int (*rthub_polling)(void);
} HC_DRV_T;
/*----------------------------------------------------------------------------------*/
/* USB device driver */
/*----------------------------------------------------------------------------------*/
typedef struct
{
int (*probe)(struct iface_t *iface);
void (*disconnect)(struct iface_t *iface);
void (*suspend)(struct iface_t *iface);
void (*resume)(struct iface_t *iface);
} UDEV_DRV_T;
/*----------------------------------------------------------------------------------*/
/* USB device */
/*----------------------------------------------------------------------------------*/
typedef enum
{
SPEED_LOW,
SPEED_FULL,
SPEED_HIGH
} SPEED_E;
typedef struct ep_info_t
{
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint8_t bInterval;
uint8_t bToggle;
uint16_t wMaxPacketSize;
void *hw_pipe; /*!< point to the HC assocaied endpoint \hideinitializer */
} EP_INFO_T;
typedef struct udev_t
{
DESC_DEV_T descriptor; /*!< Device descriptor. \hideinitializer */
struct hub_dev_t *parent; /*!< parent hub device \hideinitializer */
uint8_t port_num; /*!< The hub port this device connected on \hideinitializer */
uint8_t dev_num; /*!< device number \hideinitializer */
int8_t cur_conf; /*!< Currentll selected configuration \hideinitializer */
SPEED_E speed; /*!< device speed (low/full/high) \hideinitializer */
/*
* The followings are lightweight USB stack internal used .
*/
uint8_t *cfd_buff; /*!< Configuration descriptor buffer. \hideinitializer */
EP_INFO_T ep0; /*!< Endpoint 0 \hideinitializer */
HC_DRV_T *hc_driver; /*!< host controller driver \hideinitializer */
struct iface_t *iface_list; /*!< Working interface list \hideinitializer */
struct udev_t *next; /*!< link for global usb device list \hideinitializer */
} UDEV_T;
typedef struct alt_iface_t
{
DESC_IF_T *ifd; /*!< point to the location of this alternative interface descriptor in UDEV_T->cfd_buff */
EP_INFO_T ep[MAX_EP_PER_IFACE]; /*!< endpoints of this alternative interface */
} ALT_IFACE_T;
typedef struct iface_t
{
UDEV_T *udev; /*!< USB device \hideinitializer */
uint8_t if_num; /*!< Interface number \hideinitializer */
uint8_t num_alt; /*!< Number of alternative interface \hideinitializer */
ALT_IFACE_T *aif; /*!< Point to the active alternative interface */
ALT_IFACE_T alt[MAX_ALT_PER_IFACE]; /*!< List of alternative interface \hideinitializer */
UDEV_DRV_T *driver; /*!< Interface associated driver \hideinitializer */
void *context; /*!< Reference to device context \hideinitializer */
struct iface_t *next; /*!< Point to next interface of the same device. Started from UDEV_T->iface_list \hideinitializer */
} IFACE_T;
/*----------------------------------------------------------------------------------*/
/* URB (USB Request Block) */
/*----------------------------------------------------------------------------------*/
#define IF_PER_UTR 8 /* number of frames per UTR isochronous transfer (DO NOT modify it!) */
typedef void (*FUNC_UTR_T)(struct utr_t *);
typedef struct utr_t
{
UDEV_T *udev; /*!< point to associated USB device \hideinitializer */
DEV_REQ_T setup; /*!< buffer for setup packet \hideinitializer */
EP_INFO_T *ep; /*!< associated endpoint \hideinitializer */
uint8_t *buff; /*!< transfer buffer \hideinitializer */
uint8_t bIsTransferDone; /*!< tansfer done? \hideinitializer */
uint32_t data_len; /*!< length of data to be transferred \hideinitializer */
uint32_t xfer_len; /*!< length of transferred data \hideinitializer */
uint8_t bIsoNewSched; /*!< New schedule isochronous transfer \hideinitializer */
uint16_t iso_sf; /*!< Isochronous start frame number \hideinitializer */
uint16_t iso_xlen[IF_PER_UTR]; /*!< transfer length of isochronous frames \hideinitializer */
uint8_t *iso_buff[IF_PER_UTR]; /*!< transfer buffer address of isochronous frames \hideinitializer */
int iso_status[IF_PER_UTR]; /*!< transfer status of isochronous frames \hideinitializer */
int td_cnt; /*!< number of transfer descriptors \hideinitializer */
int status; /*!< return status \hideinitializer */
int interval; /*!< interrupt/isochronous interval \hideinitializer */
void *context; /*!< point to deivce proprietary data area \hideinitializer */
FUNC_UTR_T func; /*!< tansfer done call-back function \hideinitializer */
struct utr_t *next; /* point to the next UTR of the same endpoint. \hideinitializer */
} UTR_T;
/*----------------------------------------------------------------------------------*/
/* Global variables */
/*----------------------------------------------------------------------------------*/
extern USBH_T *_ohci;
extern HSUSBH_T *_ehci;
extern HC_DRV_T ohci_driver;
extern HC_DRV_T ehci_driver;
extern UDEV_T *g_udev_list;
/*----------------------------------------------------------------------------------*/
/* USB stack exported functions */
/*----------------------------------------------------------------------------------*/
extern void usbh_delay_ms(int msec);
extern void dump_ohci_regs(void);
extern void dump_ohci_ports(void);
extern void dump_ohci_int_table(void);
extern void dump_ehci_regs(void);
extern void dump_ehci_qtd(qTD_T *qtd);
extern void dump_ehci_asynclist(void);
extern void dump_ehci_period_frame_list_simple(void);
extern void usbh_dump_buff_bytes(uint8_t *buff, int nSize);
extern void usbh_dump_interface_descriptor(DESC_IF_T *if_desc);
extern void usbh_dump_endpoint_descriptor(DESC_EP_T *ep_desc);
extern void usbh_dump_iface(IFACE_T *iface);
extern void usbh_dump_ep_info(EP_INFO_T *ep);
/*
* Memory management functions
*/
extern void usbh_memory_init(void);
extern uint32_t usbh_memory_used(void);
extern void *usbh_alloc_mem(int size);
extern void usbh_free_mem(void *p, int size);
extern int alloc_dev_address(void);
extern void free_dev_address(int dev_addr);
extern UDEV_T *alloc_device(void);
extern void free_device(UDEV_T *udev);
extern UTR_T *alloc_utr(UDEV_T *udev);
extern void free_utr(UTR_T *utr);
extern ED_T *alloc_ohci_ED(void);
extern void free_ohci_ED(ED_T *ed);
extern TD_T *alloc_ohci_TD(UTR_T *utr);
extern void free_ohci_TD(TD_T *td);
extern QH_T *alloc_ehci_QH(void);
extern void free_ehci_QH(QH_T *qh);
extern qTD_T *alloc_ehci_qTD(UTR_T *utr);
extern void free_ehci_qTD(qTD_T *qtd);
extern iTD_T *alloc_ehci_iTD(void);
extern void free_ehci_iTD(iTD_T *itd);
extern siTD_T *alloc_ehci_siTD(void);
extern void free_ehci_siTD(siTD_T *sitd);
extern void usbh_hub_init(void);
extern int usbh_connect_device(UDEV_T *);
extern void usbh_disconnect_device(UDEV_T *);
extern int usbh_register_driver(UDEV_DRV_T *driver);
extern EP_INFO_T *usbh_iface_find_ep(IFACE_T *iface, uint8_t ep_addr, uint8_t dir_type);
extern int usbh_reset_device(UDEV_T *);
extern int usbh_reset_port(UDEV_T *);
/*
* USB Standard Request functions
*/
extern int usbh_get_device_descriptor(UDEV_T *udev, DESC_DEV_T *desc_buff);
extern int usbh_get_config_descriptor(UDEV_T *udev, uint8_t *desc_buff, int buff_len);
extern int usbh_set_configuration(UDEV_T *udev, uint8_t conf_val);
extern int usbh_set_interface(IFACE_T *iface, uint16_t alt_setting);
extern int usbh_clear_halt(UDEV_T *udev, uint16_t ep_addr);
extern int usbh_ctrl_xfer(UDEV_T *udev, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength, uint8_t *buff, uint32_t *xfer_len, uint32_t timeout);
extern int usbh_bulk_xfer(UTR_T *utr);
extern int usbh_int_xfer(UTR_T *utr);
extern int usbh_iso_xfer(UTR_T *utr);
extern int usbh_quit_utr(UTR_T *utr);
extern int usbh_quit_xfer(UDEV_T *udev, EP_INFO_T *ep);
/// @endcond HIDDEN_SYMBOLS
#endif /* _USBH_H_ */
|