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)
74 #define EHCI_CFG_FRAMELIST_SIZE_BITS 7
75 #define EHCI_FRAMELIST_SIZE (1024 >> EHCI_CFG_FRAMELIST_SIZE_BITS)
84 STATIC_ASSERT(EHCI_CFG_FRAMELIST_SIZE_BITS <= 7,
"incorrect value");
107 uint32_t terminate : 1;
125 uint32_t expected_bytes : 16;
130 volatile uint32_t pingstate_err : 1 ;
131 volatile uint32_t non_hs_split_state : 1 ;
132 volatile uint32_t non_hs_period_missed_uframe : 1 ;
133 volatile uint32_t xact_err : 1 ;
134 volatile uint32_t babble_err : 1 ;
135 volatile uint32_t buffer_err : 1 ;
136 volatile uint32_t halted : 1 ;
137 volatile uint32_t active : 1 ;
140 volatile uint32_t cerr : 2 ;
141 volatile uint32_t current_page : 3 ;
142 uint32_t int_on_complete : 1 ;
144 volatile uint32_t total_bytes : 15 ;
145 volatile uint32_t data_toggle : 1 ;
153 STATIC_ASSERT(
sizeof(
ehci_qtd_t) == 32,
"size is not correct" );
161 uint32_t device_address : 7 ;
162 uint32_t non_hs_period_inactive_next_xact : 1 ;
163 uint32_t endpoint_number : 4 ;
164 uint32_t endpoint_speed : 2 ;
165 uint32_t data_toggle_control : 1 ;
166 uint32_t head_list_flag : 1 ;
167 uint32_t max_package_size : 11 ;
168 uint32_t non_hs_control_endpoint : 1 ;
169 uint32_t nak_count_reload : 4 ;
174 uint32_t interrupt_smask : 8 ;
175 uint32_t non_hs_interrupt_cmask : 8 ;
176 uint32_t hub_address : 7 ;
177 uint32_t hub_port : 7 ;
194 uint8_t pid_non_control;
197 uint16_t total_xferred_bytes;
205 STATIC_ASSERT(
sizeof(
ehci_qhd_t) == 64,
"size is not correct" );
215 volatile uint32_t offset : 12 ;
216 volatile uint32_t page_select : 3 ;
217 uint32_t int_on_complete : 1 ;
218 volatile uint32_t length : 12 ;
221 volatile uint32_t error : 1 ;
222 volatile uint32_t babble_err : 1 ;
223 volatile uint32_t buffer_err : 1 ;
224 volatile uint32_t active : 1 ;
228 uint32_t BufferPointer[7];
237 STATIC_ASSERT(
sizeof(
ehci_itd_t) == 64,
"size is not correct" );
245 uint32_t device_address : 7;
247 uint32_t endpoint_number : 4;
249 uint32_t hub_address : 7;
251 uint32_t port_number : 7;
252 uint32_t direction : 1;
264 volatile uint32_t : 1 ;
265 volatile uint32_t split_state : 1 ;
266 volatile uint32_t missed_uframe : 1 ;
267 volatile uint32_t xact_err : 1 ;
268 volatile uint32_t babble_err : 1 ;
269 volatile uint32_t buffer_err : 1 ;
270 volatile uint32_t error : 1 ;
271 volatile uint32_t active : 1 ;
273 volatile uint32_t cmask_progress : 8 ;
274 volatile uint32_t total_bytes : 10 ;
275 volatile uint32_t : 4 ;
276 volatile uint32_t page_select : 1 ;
277 uint32_t int_on_complete : 1 ;
298 uint8_t reserved2[2];
301 STATIC_ASSERT(
sizeof(
ehci_sitd_t) == 32,
"size is not correct" );
306 enum ehci_interrupt_mask_{
307 EHCI_INT_MASK_USB =
BIT_(0),
308 EHCI_INT_MASK_ERROR =
BIT_(1),
309 EHCI_INT_MASK_PORT_CHANGE =
BIT_(2),
311 EHCI_INT_MASK_FRAMELIST_ROLLOVER =
BIT_(3),
312 EHCI_INT_MASK_PCI_HOST_SYSTEM_ERROR =
BIT_(4),
313 EHCI_INT_MASK_ASYNC_ADVANCE =
BIT_(5),
314 EHCI_INT_MASK_NXP_SOF =
BIT_(7),
316 EHCI_INT_MASK_NXP_ASYNC =
BIT_(18),
317 EHCI_INT_MASK_NXP_PERIODIC =
BIT_(19),
320 EHCI_INT_MASK_USB | EHCI_INT_MASK_ERROR | EHCI_INT_MASK_PORT_CHANGE |
321 EHCI_INT_MASK_FRAMELIST_ROLLOVER | EHCI_INT_MASK_PCI_HOST_SYSTEM_ERROR |
322 EHCI_INT_MASK_ASYNC_ADVANCE | EHCI_INT_MASK_NXP_SOF |
323 EHCI_INT_MASK_NXP_ASYNC | EHCI_INT_MASK_NXP_PERIODIC
326 enum ehci_usbcmd_pos_ {
327 EHCI_USBCMD_POS_RUN_STOP = 0,
328 EHCI_USBCMD_POS_FRAMELIST_SZIE = 2,
329 EHCI_USBCMD_POS_PERIOD_ENABLE = 4,
330 EHCI_USBCMD_POS_ASYNC_ENABLE = 5,
331 EHCI_USBCMD_POS_NXP_FRAMELIST_SIZE_MSB = 15,
332 EHCI_USBCMD_POS_INTERRUPT_THRESHOLD = 16
335 enum ehci_portsc_change_mask_{
336 EHCI_PORTSC_MASK_CONNECT_STATUS_CHANGE =
BIT_(1),
337 EHCI_PORTSC_MASK_PORT_ENABLE_CHAGNE =
BIT_(3),
338 EHCI_PORTSC_MASK_OVER_CURRENT_CHANGE =
BIT_(5),
340 EHCI_PORTSC_MASK_ALL =
341 EHCI_PORTSC_MASK_CONNECT_STATUS_CHANGE |
342 EHCI_PORTSC_MASK_PORT_ENABLE_CHAGNE |
343 EHCI_PORTSC_MASK_OVER_CURRENT_CHANGE
346 typedef volatile struct {
350 uint32_t run_stop : 1 ;
352 uint32_t framelist_size : 2 ;
353 uint32_t periodic_enable : 1 ;
354 uint32_t async_enable : 1 ;
355 uint32_t advacne_async : 1 ;
356 uint32_t light_reset : 1 ;
357 uint32_t async_park : 2 ;
359 uint32_t async_park_enable : 1 ;
361 uint32_t nxp_framelist_size_msb : 1 ;
362 uint32_t int_threshold : 8 ;
371 uint32_t usb_error : 1 ;
372 uint32_t port_change_detect : 1 ;
373 uint32_t framelist_rollover : 1 ;
374 uint32_t pci_host_system_error : 1 ;
375 uint32_t async_advance : 1 ;
377 uint32_t nxp_int_sof : 1 ;
379 uint32_t hc_halted : 1 ;
380 uint32_t reclamation : 1 ;
381 uint32_t period_schedule_status : 1 ;
382 uint32_t async_schedule_status : 1 ;
384 uint32_t nxp_int_async : 1 ;
385 uint32_t nxp_int_period : 1 ;
395 uint32_t usb_error : 1 ;
396 uint32_t port_change_detect : 1 ;
397 uint32_t framelist_rollover : 1 ;
398 uint32_t pci_host_system_error : 1 ;
399 uint32_t async_advance : 1 ;
401 uint32_t nxp_int_sof : 1 ;
403 uint32_t nxp_int_async : 1 ;
404 uint32_t nxp_int_period : 1 ;
415 uint32_t reserved[8] ;
421 uint32_t current_connect_status : 1;
422 uint32_t connect_status_change : 1;
423 uint32_t port_enable : 1;
424 uint32_t port_enable_change : 1;
425 uint32_t over_current_active : 1;
426 uint32_t over_current_change : 1;
427 uint32_t force_port_resume : 1;
428 uint32_t suspend : 1;
429 uint32_t port_reset : 1;
430 uint32_t nxp_highspeed_status : 1;
431 uint32_t line_status : 2;
432 uint32_t port_power : 1;
433 uint32_t port_owner : 1;
434 uint32_t port_indicator_control : 2;
435 uint32_t port_test_control : 4;
436 uint32_t wake_on_connect_enable : 1;
437 uint32_t wake_on_disconnect_enable : 1;
438 uint32_t wake_on_over_current_enable : 1;
439 uint32_t nxp_phy_clock_disable : 1;
440 uint32_t nxp_port_force_fullspeed : 1;
442 uint32_t nxp_port_speed : 2;
453 ehci_qhd_t async_head[CONTROLLER_HOST_NUMBER];
455 #if EHCI_PERIODIC_LIST
458 ehci_qhd_t period_head_arr[CONTROLLER_HOST_NUMBER][4];
volatile ehci_qtd_t qtd_overlay
Word 4-11: Transfer Overlay.
uint32_t ctrl_ds_seg
(not used by NXP) This 32-bit register corresponds to the most significant address bits [63:32] for a...
ehci_qhd_t qhd
Queue Head Pool.
uint16_t reserved
reserved
#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...
uint32_t periodic_list_base
This 32-bit register contains the beginning address of the Periodic Frame List in the system memory...
volatile uint32_t qtd_addr
Word 3: Current qTD Pointer.
uint32_t config_flag
(not used by NXP) configured flag register
uint8_t used
thus there are 16 bytes padding free that we can make use of.
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.
ehci_link_t next
Word 0: Next Link Pointer.
uint32_t portsc
port status and control
ehci_link_t next
Word 0: Next QTD Pointer.
uint32_t async_list_base
This 32-bit register contains the address of the next asynchronous queue head to be executed...
uint32_t usb_int_enable
This register enables and disables reporting of the corresponding interrupt to the software...
ehci_link_t next
Word 0: Next Link Pointer.
uint8_t used
SITD is 32-byte aligned but occupies only 28 –> 4 bytes for storing extra data.
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.
#define ATTR_ALIGNED(Bytes)
This attribute specifies a minimum alignment for the variable or structure field, measured in bytes...
ehci_link_t next
Word 0: Queue Head Horizontal Link Pointer.
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.
Split (Full-Speed) Isochronous Transfer Descriptor.
Queue Element Transfer Descriptor (section 3.5)
uint8_t interrupt_smask
Word 2: Micro-frame Schedule Control.
uint8_t non_hs_interrupt_cmask
This field (along with the Activeand SplitX-statefields in the Statusbyte) are used to determine duri...
Highspeed Isochronous Transfer Descriptor (section 3.3)
uint32_t tt_control
nxp embedded transaction translator (reserved by EHCI specs)