tinyusb
ehci.h
Go to the documentation of this file.
1 /**************************************************************************/
37 /**************************************************************************/
38 
46 #ifndef _TUSB_EHCI_H_
47 #define _TUSB_EHCI_H_
48 
49 #include "common/common.h"
50 
51 /* Abbreviation
52  * HC: Host Controller
53  * HCD: Host Controller Driver
54  * QHD: Queue Head for non-ISO transfer
55  * QTD: Queue Transfer Descriptor for non-ISO transfer
56  * ITD: Iso Transfer Descriptor for highspeed
57  * SITD: Split ISO Transfer Descriptor for full-speed
58  * SMASK: Start Split mask for Slipt Transaction
59  * CMASK: Complete Split mask for Slipt Transaction
60  * RO: Read Only
61  * R/WC: Read, Write to Clear
62 */
63 
64 #ifdef __cplusplus
65  extern "C" {
66 #endif
67 
68 //--------------------------------------------------------------------+
69 // EHCI CONFIGURATION & CONSTANTS
70 //--------------------------------------------------------------------+
71 #define HOST_HCD_XFER_INTERRUPT // TODO interrupt is used widely, should always be enalbed
72 #define EHCI_PERIODIC_LIST (defined HOST_HCD_XFER_INTERRUPT || defined HOST_HCD_XFER_ISOCHRONOUS)
73 
74 // TODO merge OHCI with EHCI
75 #define EHCI_MAX_QHD 8
76 #define EHCI_MAX_QTD 20
77 #define EHCI_MAX_ITD 4
78 #define EHCI_MAX_SITD 16
79 
80 #define EHCI_CFG_FRAMELIST_SIZE_BITS 7
81 #define EHCI_FRAMELIST_SIZE (1024 >> EHCI_CFG_FRAMELIST_SIZE_BITS)
82 
83 //------------- Validation -------------//
84 #if EHCI_CFG_FRAMELIST_SIZE_BITS > 7
85  #error EHCI_CFG_FRAMELIST_SIZE_BITS must be from 0-7
86 #endif
87 
88 //--------------------------------------------------------------------+
89 // EHCI Data Structure
90 //--------------------------------------------------------------------+
96 };
97 
99 enum tusb_pid_{
100  EHCI_PID_OUT = 0 ,
101  EHCI_PID_IN ,
102  EHCI_PID_SETUP
103 };
104 
106 typedef union {
107  uint32_t address;
108  struct {
109  uint32_t terminate : 1;
110  uint32_t type : 2;
111  };
112 }ehci_link_t;
113 
115 typedef struct {
116 
119 
121  union{
122  ehci_link_t alternate;
123  struct {
124  uint32_t : 5;
125  uint32_t used : 1;
126  uint32_t : 10;
127  uint32_t expected_bytes : 16;
128  };
129  };
130 
132  volatile uint32_t pingstate_err : 1 ;
133  volatile uint32_t non_hs_split_state : 1 ;
134  volatile uint32_t non_hs_period_missed_uframe : 1 ;
135  volatile uint32_t xact_err : 1 ;
136  volatile uint32_t babble_err : 1 ;
137  volatile uint32_t buffer_err : 1 ;
138  volatile uint32_t halted : 1 ;
139  volatile uint32_t active : 1 ;
140 
141  uint32_t pid : 2 ;
142  volatile uint32_t cerr : 2 ;
143  volatile uint32_t current_page : 3 ;
144  uint32_t int_on_complete : 1 ;
145 
146  volatile uint32_t total_bytes : 15 ;
147  volatile uint32_t data_toggle : 1 ;
148  uint32_t : 0 ; // padding to the end of current storage unit
149  // End of Word 2
150 
152  uint32_t buffer[5];
153 } ehci_qtd_t; // XXX qtd is used to declare overlay in ehci_qhd_t -> cannot be declared with ATTR_ALIGNED(32)
154 
155 STATIC_ASSERT( sizeof(ehci_qtd_t) == 32, "size is not correct" );
156 
158 typedef struct {
161 
163  uint32_t device_address : 7 ;
164  uint32_t non_hs_period_inactive_next_xact : 1 ;
165  uint32_t endpoint_number : 4 ;
166  uint32_t endpoint_speed : 2 ;
167  uint32_t data_toggle_control : 1 ;
168  uint32_t head_list_flag : 1 ;
169  uint32_t max_package_size : 11 ;
170  uint32_t non_hs_control_endpoint : 1 ;
171  uint32_t nak_count_reload : 4 ;
172  uint32_t : 0 ; // padding to the end of current storage unit
173  // End of Word 1
174 
176  uint32_t interrupt_smask : 8 ;
177  uint32_t non_hs_interrupt_cmask : 8 ;
178  uint32_t hub_address : 7 ;
179  uint32_t hub_port : 7 ;
180  uint32_t mult : 2 ;
181  uint32_t : 0 ; // padding to the end of current storage unit
182  // End of Word 2
183 
185  volatile uint32_t qtd_addr;
186 
189 
190  //--------------------------------------------------------------------+
193  //--------------------------------------------------------------------+
194  uint8_t used;
195  uint8_t is_removing;
196  uint8_t pid_non_control;
197  uint8_t class_code;
198 
199  uint16_t total_xferred_bytes; // number of bytes xferred until a qtd with ioc bit set
200  uint8_t interval_ms; // polling interval in frames (or milisecond)
201  uint8_t reserved;
202 
203  ehci_qtd_t * volatile p_qtd_list_head; // head of the scheduled TD list
204  ehci_qtd_t * volatile p_qtd_list_tail; // tail of the scheduled TD list
205 } ehci_qhd_t;
206 
207 STATIC_ASSERT( sizeof(ehci_qhd_t) == 64, "size is not correct" );
208 
210 typedef struct ATTR_ALIGNED(32) {
213 
215  struct {
216  // iTD Control
217  volatile uint32_t offset : 12 ;
218  volatile uint32_t page_select : 3 ;
219  uint32_t int_on_complete : 1 ;
220  volatile uint32_t length : 12 ;
221  // iTD Status
223  volatile uint32_t error : 1 ;
224  volatile uint32_t babble_err : 1 ;
225  volatile uint32_t buffer_err : 1 ;
226  volatile uint32_t active : 1 ;
227  } xact[8];
228 
230  uint32_t BufferPointer[7];
231 
232 // // FIXME: Store meta data into buffer pointer reserved for saving memory
233 // /*---------- HCD Area ----------*/
234 // uint32_t used;
235 // uint32_t IhdIdx;
236 // uint32_t reserved[6];
237 } ehci_itd_t;
238 
239 STATIC_ASSERT( sizeof(ehci_itd_t) == 64, "size is not correct" );
240 
242 typedef struct ATTR_ALIGNED(32) {
245 
247  uint32_t device_address : 7;
248  uint32_t : 1;
249  uint32_t endpoint_number : 4;
250  uint32_t : 4;
251  uint32_t hub_address : 7;
252  uint32_t : 1;
253  uint32_t port_number : 7;
254  uint32_t direction : 1;
255  uint32_t : 0; // padding to the end of current storage unit
256  // End of Word 1
257 
259  uint8_t interrupt_smask ;
261  uint16_t reserved ;
262  // End of Word 2
263 
265  // Status [7:0] TODO indentical to qTD Token'status --> refractor later
266  volatile uint32_t : 1 ; // reserved
267  volatile uint32_t split_state : 1 ;
268  volatile uint32_t missed_uframe : 1 ;
269  volatile uint32_t xact_err : 1 ;
270  volatile uint32_t babble_err : 1 ;
271  volatile uint32_t buffer_err : 1 ;
272  volatile uint32_t error : 1 ;
273  volatile uint32_t active : 1 ;
274  // Micro-frame Schedule Control
275  volatile uint32_t cmask_progress : 8 ;
276  volatile uint32_t total_bytes : 10 ;
277  volatile uint32_t : 4 ;
278  volatile uint32_t page_select : 1 ;
279  uint32_t int_on_complete : 1 ;
280  uint32_t : 0 ; // padding to the end of current storage unit
281  // End of Word 3
282 
284  uint32_t buffer[2]; // buffer[1] TP: Transaction Position - T-Count: Transaction Count
285 
286 // union{
287 // uint32_t BufferPointer1;
288 // struct {
289 // volatile uint32_t TCount : 3;
290 // volatile uint32_t TPosition : 2;
291 // };
292 // };
293 
294  /*---------- Word 6 ----------*/
295  ehci_link_t back;
296 
298  uint8_t used;
299  uint8_t ihd_idx;
300  uint8_t reserved2[2];
301 } ehci_sitd_t;
302 
303 STATIC_ASSERT( sizeof(ehci_sitd_t) == 32, "size is not correct" );
304 
305 //--------------------------------------------------------------------+
306 // EHCI Operational Register
307 //--------------------------------------------------------------------+
308 enum ehci_interrupt_mask_{
309  EHCI_INT_MASK_USB = BIT_(0),
310  EHCI_INT_MASK_ERROR = BIT_(1),
311  EHCI_INT_MASK_PORT_CHANGE = BIT_(2),
312 
313  EHCI_INT_MASK_FRAMELIST_ROLLOVER = BIT_(3),
314  EHCI_INT_MASK_PCI_HOST_SYSTEM_ERROR = BIT_(4),
315  EHCI_INT_MASK_ASYNC_ADVANCE = BIT_(5),
316  EHCI_INT_MASK_NXP_SOF = BIT_(7),
317 
318  EHCI_INT_MASK_NXP_ASYNC = BIT_(18),
319  EHCI_INT_MASK_NXP_PERIODIC = BIT_(19),
320 
321  EHCI_INT_MASK_ALL =
322  EHCI_INT_MASK_USB | EHCI_INT_MASK_ERROR | EHCI_INT_MASK_PORT_CHANGE |
323  EHCI_INT_MASK_FRAMELIST_ROLLOVER | EHCI_INT_MASK_PCI_HOST_SYSTEM_ERROR |
324  EHCI_INT_MASK_ASYNC_ADVANCE | EHCI_INT_MASK_NXP_SOF |
325  EHCI_INT_MASK_NXP_ASYNC | EHCI_INT_MASK_NXP_PERIODIC
326 };
327 
328 enum ehci_usbcmd_pos_ {
329  EHCI_USBCMD_POS_RUN_STOP = 0,
330  EHCI_USBCMD_POS_FRAMELIST_SZIE = 2,
331  EHCI_USBCMD_POS_PERIOD_ENABLE = 4,
332  EHCI_USBCMD_POS_ASYNC_ENABLE = 5,
333  EHCI_USBCMD_POS_NXP_FRAMELIST_SIZE_MSB = 15,
334  EHCI_USBCMD_POS_INTERRUPT_THRESHOLD = 16
335 };
336 
337 enum ehci_portsc_change_mask_{
338  EHCI_PORTSC_MASK_CONNECT_STATUS_CHANGE = BIT_(1),
339  EHCI_PORTSC_MASK_PORT_ENABLE_CHAGNE = BIT_(3),
340  EHCI_PORTSC_MASK_OVER_CURRENT_CHANGE = BIT_(5),
341 
342  EHCI_PORTSC_MASK_ALL =
343  EHCI_PORTSC_MASK_CONNECT_STATUS_CHANGE |
344  EHCI_PORTSC_MASK_PORT_ENABLE_CHAGNE |
345  EHCI_PORTSC_MASK_OVER_CURRENT_CHANGE
346 };
347 
348 typedef volatile struct {
349  union {
350  uint32_t usb_cmd ;
351  struct {
352  uint32_t run_stop : 1 ;
353  uint32_t reset : 1 ;
354  uint32_t framelist_size : 2 ;
355  uint32_t periodic_enable : 1 ;
356  uint32_t async_enable : 1 ;
357  uint32_t advacne_async : 1 ;
358  uint32_t light_reset : 1 ;
359  uint32_t async_park : 2 ;
360  uint32_t : 1 ;
361  uint32_t async_park_enable : 1 ;
362  uint32_t : 3 ;
363  uint32_t nxp_framelist_size_msb : 1 ;
364  uint32_t int_threshold : 8 ;
365  uint32_t : 0 ; // padding to the boundary of storage unit
366  }usb_cmd_bit;
367  };
368 
369  union {
370  uint32_t usb_sts ;
371  struct {
372  uint32_t usb : 1 ;
373  uint32_t usb_error : 1 ;
374  uint32_t port_change_detect : 1 ;
375  uint32_t framelist_rollover : 1 ;
376  uint32_t pci_host_system_error : 1 ;
377  uint32_t async_advance : 1 ;
378  uint32_t : 1 ;
379  uint32_t nxp_int_sof : 1 ;
380  uint32_t : 4 ;
381  uint32_t hc_halted : 1 ;
382  uint32_t reclamation : 1 ;
383  uint32_t period_schedule_status : 1 ;
384  uint32_t async_schedule_status : 1 ;
385  uint32_t : 2 ;
386  uint32_t nxp_int_async : 1 ;
387  uint32_t nxp_int_period : 1 ;
388  uint32_t : 12 ;
389  uint32_t : 0 ; // padding to the boundary of storage unit
390  }usb_sts_bit;
391  };
392 
393  union{
394  uint32_t usb_int_enable ;
395  struct {
396  uint32_t usb : 1 ;
397  uint32_t usb_error : 1 ;
398  uint32_t port_change_detect : 1 ;
399  uint32_t framelist_rollover : 1 ;
400  uint32_t pci_host_system_error : 1 ;
401  uint32_t async_advance : 1 ;
402  uint32_t : 1 ;
403  uint32_t nxp_int_sof : 1 ;
404  uint32_t : 10 ;
405  uint32_t nxp_int_async : 1 ;
406  uint32_t nxp_int_period : 1 ;
407  uint32_t : 12 ;
408  uint32_t : 0 ; // padding to the boundary of storage unit
409  }usb_int_enable_bit;
410  };
411 
412  uint32_t frame_index ;
413  uint32_t ctrl_ds_seg ;
414  uint32_t periodic_list_base ;
415  uint32_t async_list_base ;
416  uint32_t tt_control ;
417  uint32_t reserved[8] ;
418  uint32_t config_flag ;
419 
420  union {
421  uint32_t portsc ;
422  struct {
423  uint32_t current_connect_status : 1;
424  uint32_t connect_status_change : 1;
425  uint32_t port_enable : 1;
426  uint32_t port_enable_change : 1;
427  uint32_t over_current_active : 1;
428  uint32_t over_current_change : 1;
429  uint32_t force_port_resume : 1;
430  uint32_t suspend : 1;
431  uint32_t port_reset : 1;
432  uint32_t nxp_highspeed_status : 1;
433  uint32_t line_status : 2;
434  uint32_t port_power : 1;
435  uint32_t port_owner : 1;
436  uint32_t port_indicator_control : 2;
437  uint32_t port_test_control : 4;
438  uint32_t wake_on_connect_enable : 1;
439  uint32_t wake_on_disconnect_enable : 1;
440  uint32_t wake_on_over_current_enable : 1;
441  uint32_t nxp_phy_clock_disable : 1;
442  uint32_t nxp_port_force_fullspeed : 1;
443  uint32_t : 1;
444  uint32_t nxp_port_speed : 2;
445  uint32_t : 0; // padding to the boundary of storage unit
446  }portsc_bit;
447  };
449 
450 //--------------------------------------------------------------------+
451 // EHCI Data Organization
452 //--------------------------------------------------------------------+
453 typedef struct {
454  //------------- Static Async/Period List Head, Each for one controller -------------//
455  ehci_qhd_t async_head[CONTROLLER_HOST_NUMBER];
456 
457 #if EHCI_PERIODIC_LIST
458  // for NXP ECHI, only implement 1 ms & 2 ms & 4 ms, 8 ms (framelist)
459  // [0] : 1ms, [1] : 2ms, [2] : 4ms, [3] : 8 ms
460  ehci_qhd_t period_head_arr[CONTROLLER_HOST_NUMBER][4];
461 #endif
462 
463  //------------- Data for Address 0 (use async head as its queue head) -------------//
464  ehci_qtd_t addr0_qtd[3];
465 
466  struct {
467  struct {
469  ehci_qtd_t qtd[3];
470  }control;
471 
472  ehci_qhd_t qhd[EHCI_MAX_QHD] ;
473  ehci_qtd_t qtd[EHCI_MAX_QTD] ATTR_ALIGNED(32) ;
474 // ehci_itd_t itd[EHCI_MAX_ITD] ; ///< Iso Transfer Pool
475 // ehci_sitd_t sitd[EHCI_MAX_SITD] ; ///< Split (FS) Isochronous Transfer Pool
476  }device[TUSB_CFG_HOST_DEVICE_MAX];
477 }ehci_data_t;
478 
479 #ifdef __cplusplus
480  }
481 #endif
482 
483 #endif /* _TUSB_EHCI_H_ */
484 
volatile ehci_qtd_t qtd_overlay
Word 4-11: Transfer Overlay.
Definition: ehci.h:188
1
Definition: ehci.h:93
#define BIT_(n)
n-th Bit
Definition: binary.h:54
uint32_t ctrl_ds_seg
(not used by NXP) This 32-bit register corresponds to the most significant address bits [63:32] for a...
Definition: ehci.h:413
uint16_t reserved
reserved
Definition: ehci.h:261
#define TUSB_CFG_HOST_DEVICE_MAX
Maximum number of device host stack can manage If hub class is not enabled, set this equal to numbe...
Definition: configuration.txt:35
uint32_t periodic_list_base
This 32-bit register contains the beginning address of the Periodic Frame List in the system memory...
Definition: ehci.h:414
tusb_pid_
EHCI PID.
Definition: ehci.h:99
volatile uint32_t qtd_addr
Word 3: Current qTD Pointer.
Definition: ehci.h:185
uint32_t config_flag
(not used by NXP) configured flag register
Definition: ehci.h:418
uint8_t used
thus there are 16 bytes padding free that we can make use of.
Definition: ehci.h:194
Definition: ehci.h:348
uint32_t frame_index
This register is used by the host controller to index into the periodic frame list. The register updates every 125 microseconds (once each micro-frame). Bits [N:3] are used to select a particular entry in the Periodic Frame List during periodic schedule execution. The number of bits used for the index depends on the size of the frame list as set by system software in the Frame List Sizefield in the USBCMD register.
Definition: ehci.h:412
ehci_queue_element_type_
Definition: ehci.h:91
ehci_link_t next
Word 0: Next Link Pointer.
Definition: ehci.h:244
2
Definition: ehci.h:94
0
Definition: ehci.h:92
Queue Head (section 3.6)
Definition: ehci.h:158
uint32_t portsc
port status and control
Definition: ehci.h:421
ehci_link_t next
Word 0: Next QTD Pointer.
Definition: ehci.h:118
uint32_t async_list_base
This 32-bit register contains the address of the next asynchronous queue head to be executed...
Definition: ehci.h:415
uint32_t usb_int_enable
This register enables and disables reporting of the corresponding interrupt to the software...
Definition: ehci.h:394
ehci_qhd_t qhd
Queue Head Pool.
Definition: ehci.h:468
ehci_link_t next
Word 0: Next Link Pointer.
Definition: ehci.h:212
uint8_t used
SITD is 32-byte aligned but occupies only 28 –> 4 bytes for storing extra data.
Definition: ehci.h:298
uint32_t usb_sts
This register indicates pending interrupts and various states of the Host Controller. The status resulting from a transaction on the serial bus is not indicated in this register. Software sets a bit to 0 in this register by writing a 1 to it. See Section 4.15 for additional information concerning USB interrupt conditions.
Definition: ehci.h:370
#define ATTR_ALIGNED(Bytes)
This attribute specifies a minimum alignment for the variable or structure field, measured in bytes...
Definition: compiler_gcc.h:72
3
Definition: ehci.h:95
Definition: ehci.h:453
ehci_link_t next
Word 0: Queue Head Horizontal Link Pointer.
Definition: ehci.h:160
uint32_t usb_cmd
The Command Register indicates the command to be executed by the serial bus host controller. Writing to the register causes a command to be executed.
Definition: ehci.h:350
Split (Full-Speed) Isochronous Transfer Descriptor.
Definition: ehci.h:242
Queue Element Transfer Descriptor (section 3.5)
Definition: ehci.h:115
uint8_t interrupt_smask
Word 2: Micro-frame Schedule Control.
Definition: ehci.h:259
uint8_t non_hs_interrupt_cmask
This field (along with the Activeand SplitX-statefields in the Statusbyte) are used to determine duri...
Definition: ehci.h:260
Highspeed Isochronous Transfer Descriptor (section 3.3)
Definition: ehci.h:210
uint32_t tt_control
nxp embedded transaction translator (reserved by EHCI specs)
Definition: ehci.h:416