1 /*
2 * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016,2019 - 2020 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8 #include "usb_host_config.h"
9 #if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI > 0U))
10 #include "usb_host.h"
11 #include "usb_host_hci.h"
12 #include "usb_host_devices.h"
13 #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
14 #include "usb_host_framework.h"
15 #endif
16 #include "fsl_device_registers.h"
17 #include "usb_host_ehci.h"
18 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT))
19 #include "usb_phy.h"
20 #endif
21 #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
22 #include "usb_host.h"
23 #endif
24 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
25 #include "fsl_memory.h"
26 #endif
27
28 /*******************************************************************************
29 * Definitions
30 ******************************************************************************/
31
32 #if defined(USB_STACK_USE_DEDICATED_RAM) && (USB_STACK_USE_DEDICATED_RAM > 0U)
33
34 #error The SOC does not suppoort dedicated RAM case.
35
36 #endif
37
38 #define USB_HOST_EHCI_BANDWIDTH_DELAY (3500U)
39 #define USB_HOST_EHCI_BANDWIDTH_HUB_LS_SETUP (333U)
40 #define USB_HOST_EHCI_BANDWIDTH_FRAME_TOTOAL_TIME (900U)
41
42 #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
43 #define USB_HOST_EHCI_TEST_DESCRIPTOR_LENGTH (18U)
44 #define USB_HOST_EHCI_PORTSC_PTC_J_STATE (0x01U)
45 #define USB_HOST_EHCI_PORTSC_PTC_K_STATE (0x02U)
46 #define USB_HOST_EHCI_PORTSC_PTC_SE0_NAK (0x03U)
47 #define USB_HOST_EHCI_PORTSC_PTC_PACKET (0x04U)
48 #define USB_HOST_EHCI_PORTSC_PTC_FORCE_ENABLE_HS (0x05U)
49 #define USB_HOST_EHCI_PORTSC_PTC_FORCE_ENABLE_FS (0x06U)
50 #define USB_HOST_EHCI_PORTSC_PTC_FORCE_ENABLE_LS (0x07U)
51 #endif
52
53 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
54 #define USB_HOST_MEMORY_CPU_2_DMA(x) MEMORY_ConvertMemoryMapAddress((uint32_t)(x), kMEMORY_Local2DMA)
55 #define USB_HOST_MEMORY_DMA_2_CPU(x) MEMORY_ConvertMemoryMapAddress((uint32_t)(x), kMEMORY_DMA2Local)
56 #endif
57
58 /*******************************************************************************
59 * Prototypes
60 ******************************************************************************/
61 /*!
62 * @brief compute data bandwidth time.
63 *
64 * @param speed data speed.
65 * @param pipeType data type.
66 * @param direction data direction.
67 * @param dataLength data length.
68 *
69 *@return time value.
70 */
71 static uint32_t USB_HostBandwidthComputeTime(uint8_t speed, uint8_t pipeType, uint8_t direction, uint32_t dataLength);
72
73 /*!
74 * @brief compute current allocated bandwidth when ehci work as full-speed or low-speed host.
75 *
76 * @param ehciInstance ehci instance pointer.
77 * @param frameIndex frame index.
78 * @param frameBandwidths return frame bandwidth data.
79 */
80 static void USB_HostBandwidthFslsHostComputeCurrent(usb_host_ehci_instance_t *ehciInstance,
81 uint16_t frameIndex,
82 uint16_t *frameBandwidth);
83
84 /*!
85 * @brief compute current hub's allocated FS/LS bandwidth when ehci work as hi-speed host.
86 *
87 * @param ehciInstance ehci instance pointer.
88 * @param hubNumber hub address.
89 * @param frameIndex frame index.
90 * @param frameBandwidths return frame bandwidth data.
91 */
92 static void USB_HostBandwidthHsHostComputeCurrentFsls(usb_host_ehci_instance_t *ehciInstance,
93 uint32_t hubNumber,
94 uint16_t frameIndex,
95 uint16_t frameBandwidths[8]);
96
97 /*!
98 * @brief compute current allocated HS bandwidth when ehci work as hi-speed host.
99 *
100 * @param ehciInstance ehci instance pointer.
101 * @param frameIndex frame index.
102 * @param frameBandwidths return frame bandwidth data.
103 */
104 static void USB_HostBandwidthHsHostComputeCurrentHsAll(usb_host_ehci_instance_t *ehciInstance,
105 uint16_t frameIndex,
106 uint16_t frameBandwidths[8]);
107
108 /*!
109 * @brief allocate HS bandwidth when host work as high-speed host.
110 *
111 * @param ehciInstance ehci instance pointer.
112 * @param uframeInterval micro-frame interval.
113 * @param timeData time for allocating.
114 * @param uframe_index_out return start uframe index.
115 *
116 * @return kStatus_USB_Success or error codes.
117 */
118 static usb_status_t USB_HostBandwidthHsHostAllocateHsCommon(usb_host_ehci_instance_t *ehciInstance,
119 uint16_t uframeInterval,
120 uint16_t timeData,
121 uint16_t *uframeIndexOut);
122
123 /*!
124 * @brief allocate HS interrupt bandwidth when host work as high-speed host.
125 *
126 * @param ehciInstance ehci instance pointer.
127 * @param ehciPipePointer ehci pipe pointer.
128 *
129 * @return kStatus_USB_Success or error codes.
130 */
131 static usb_status_t USB_HostBandwidthHsHostAllocateInterrupt(usb_host_ehci_instance_t *ehciInstance,
132 usb_host_ehci_pipe_t *ehciPipePointer);
133
134 /*!
135 * @brief allocate bandwidth when host work as full-speed or low-speed host.
136 *
137 * @param ehciInstance ehci instance pointer.
138 * @param ehciPipePointer ehci pipe pointer.
139 *
140 * @return kStatus_USB_Success or error codes.
141 */
142 static usb_status_t USB_HostBandwidthFslsHostAllocate(usb_host_ehci_instance_t *ehciInstance,
143 usb_host_ehci_pipe_t *ehciPipePointer);
144
145 /*!
146 * @brief get the 2 power value of uint8_t.
147 *
148 * @param value input uint8_t value.
149 */
150 static uint8_t USB_HostEhciGet2PowerValue(uint8_t value);
151
152 /*!
153 * @brief memory zero.
154 *
155 * @param buffer buffer pointer.
156 * @param length buffer length.
157 */
158 static void USB_HostEhciZeroMem(uint32_t *buffer, uint32_t length);
159
160 /*!
161 * @brief host ehci delay.
162 *
163 * @param ehciIpBase ehci ip base address.
164 * @param ms millisecond.
165 */
166 static void USB_HostEhciDelay(USBHS_Type *ehciIpBase, uint32_t ms);
167
168 /*!
169 * @brief host ehci start async schedule.
170 *
171 * @param ehciInstance ehci instance pointer.
172 */
173 static void USB_HostEhciStartAsync(usb_host_ehci_instance_t *ehciInstance);
174
175 /*!
176 * @brief host ehci stop async schedule.
177 *
178 * @param ehciInstance ehci instance pointer.
179 */
180 static void USB_HostEhciStopAsync(usb_host_ehci_instance_t *ehciInstance);
181
182 /*!
183 * @brief host ehci start periodic schedule.
184 *
185 * @param ehciInstance ehci instance pointer.
186 */
187 static void USB_HostEhciStartPeriodic(usb_host_ehci_instance_t *ehciInstance);
188
189 /*!
190 * @brief host ehci stop periodic schedule.
191 *
192 * @param ehciInstance ehci instance pointer.
193 */
194 static void USB_HostEhciStopPeriodic(usb_host_ehci_instance_t *ehciInstance);
195
196 /*!
197 * @brief initialize the qtd for one transfer.
198 *
199 * @param ehciInstance ehci instance pointer.
200 * @param ehciPipePointer ehci pipe pointer.
201 * @param transfer transfer information.
202 *
203 *@return kStatus_USB_Success or error codes.
204 */
205 static usb_status_t USB_HostEhciQhQtdListInit(usb_host_ehci_instance_t *ehciInstance,
206 usb_host_ehci_pipe_t *ehciPipePointer,
207 usb_host_transfer_t *transfer);
208
209 /*!
210 * @brief release the qtd list.
211 *
212 * @param ehciInstance ehci instance pointer.
213 * @param ehciQtdStart qtd list start pointer.
214 * @param ehciQtdEnd qtd list end pointer.
215 *
216 *@return the transfer's length.
217 */
218 static uint32_t USB_HostEhciQtdListRelease(usb_host_ehci_instance_t *ehciInstance,
219 usb_host_ehci_qtd_t *ehciQtdStart,
220 usb_host_ehci_qtd_t *ehciQtdEnd);
221
222 /*!
223 * @brief de-initialize qh's linking qtd list.
224 * 1. remove qtd from qh; 2. remove transfer from qh; 3. release qtd; 4. transfer callback.
225 *
226 * @param ehciInstance ehci instance pointer.
227 * @param ehciPipePointer ehci pipe.
228 *
229 *@return kStatus_USB_Success or error codes.
230 */
231 static usb_status_t USB_HostEhciQhQtdListDeinit(usb_host_ehci_instance_t *ehciInstance,
232 usb_host_ehci_pipe_t *ehciPipePointer);
233
234 /*!
235 * @brief de-initialize transfer's linking qtd list.
236 * 1. stop this qh schedule; 2. remove qtd from qh; 3. remove transfer from qh; 4. release qtd; 5. transfer callback; 6.
237 *start this qh schedule.
238 *
239 * @param ehciInstance ehci instance pointer.
240 * @param ehciPipePointer ehci pipe pointer.
241 * @param transfer transfer information.
242 *
243 *@return kStatus_USB_Success or error codes.
244 */
245 static usb_status_t USB_HostEhciTransferQtdListDeinit(usb_host_ehci_instance_t *ehciInstance,
246 usb_host_ehci_pipe_t *ehciPipePointer,
247 usb_host_transfer_t *transfer);
248
249 /*!
250 * @brief initialize QH when opening one control, bulk or interrupt pipe.
251 *
252 * @param ehciInstance ehci instance pointer.
253 * @param ehciPipePointer ehci pipe pointer.
254 *
255 * @return kStatus_USB_Success or error codes.
256 */
257 static usb_status_t USB_HostEhciQhInit(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer);
258
259 /*!
260 * @brief de-initialize QH when closing one control, bulk or interrupt pipe.
261 *
262 * @param ehciInstance ehci instance pointer.
263 * @param ehciPipePointer ehci pipe pointer.
264 *
265 * @return kStatus_USB_Success or error codes.
266 */
267 static usb_status_t USB_HostEhciQhDeinit(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer);
268
269 /*!
270 * @brief add qh to one frame entry.
271 *
272 * @param ehciInstance ehci instance pointer.
273 * @param entryPointerValue entry pointer value.
274 * @param framePos frame index.
275 * @param uframeInterval micro-frame interval.
276 */
277 static void USB_HostEhciAddQhToFrame(usb_host_ehci_instance_t *ehciInstance,
278 uint32_t entryPointerValue,
279 uint16_t framePos,
280 uint16_t uframeInterval);
281
282 /*!
283 * @brief remove entry from frame list.
284 *
285 * @param ehciInstance ehci instance pointer.
286 * @param entryPointerValue entry pointer value.
287 * @param framePos frame index.
288 */
289 static void USB_HostEhciRemoveFromFrame(usb_host_ehci_instance_t *ehciInstance,
290 uint32_t entryPointerValue,
291 uint16_t framePos);
292
293 #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
294 /*!
295 * @brief add sitd array to the frame list.
296 *
297 * @param ehciInstance ehci instance pointer.
298 * @param entryPointerValue entry pointer value.
299 * @param startEntryPointer sitd entry pointer.
300 */
301 static void USB_HostEhciLinkSitd(usb_host_ehci_instance_t *ehciInstance,
302 usb_host_ehci_pipe_t *ehciPipePointer,
303 void *startEntryPointer);
304
305 /*!
306 * @brief initialize sitd array for one transfer.
307 *
308 * @param ehciInstance ehci instance pointer.
309 * @param ehciPipePointer ehci pipe pointer.
310 * @param transfer transfer information.
311 */
312 static usb_status_t USB_HostEhciSitdArrayInit(usb_host_ehci_instance_t *ehciInstance,
313 usb_host_ehci_pipe_t *ehciPipePointer,
314 usb_host_transfer_t *transfer);
315
316 /*!
317 * @brief release sitd list.
318 *
319 * @param ehciInstance ehci instance pointer.
320 * @param startSitdPointer start sitd pointer.
321 * @param endSitdPointer end sitd pointer.
322 *
323 * @return transfer's result length.
324 */
325 static uint32_t USB_HostEhciSitdArrayRelease(usb_host_ehci_instance_t *ehciInstance,
326 usb_host_ehci_sitd_t *startSitdPointer,
327 usb_host_ehci_sitd_t *endSitdPointer);
328
329 /*!
330 * @brief de-initialize sitd list.
331 * 1. remove transfer; 2. remove sitd from frame list and release sitd; 3. transfer callback
332 *
333 * @param ehciInstance ehci instance pointer.
334 * @param ehciPipePointer ehci pipe pointer.
335 *
336 * @return kStatus_USB_Success or error codes.
337 */
338 static usb_status_t USB_HostEhciSitdArrayDeinit(usb_host_ehci_instance_t *ehciInstance,
339 usb_host_ehci_pipe_t *ehciPipePointer);
340 #endif /* USB_HOST_CONFIG_EHCI_MAX_SITD */
341
342 #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
343 /*!
344 * @brief compute the frame index when inserting itd.
345 *
346 * @param ehciInstance ehci instance pointer.
347 * @param lastLinkUframe last inserted micro-frame.
348 * @param startUframe start micro-frame.
349 * @param uframeInterval micro-frame interval.
350 *
351 * @return frame index
352 */
353 static uint32_t USB_HostEhciGetItdLinkFrame(usb_host_ehci_instance_t *ehciInstance,
354 uint32_t lastLinkUframe,
355 uint16_t startUframe,
356 uint16_t uframeInterval);
357
358 /*!
359 * @brief initialize itd list for one transfer.
360 * 1. initialize itd list; 2. insert itd to frame list.
361 *
362 * @param ehciInstance ehci instance pointer.
363 * @param ehciPipePointer ehci pipe pointer.
364 * @param transfer transfer information.
365 *
366 * @return kStatus_USB_Success or error codes.
367 */
368 static usb_status_t USB_HostEhciItdArrayInit(usb_host_ehci_instance_t *ehciInstance,
369 usb_host_ehci_pipe_t *ehciPipePointer,
370 usb_host_transfer_t *transfer);
371
372 /*!
373 * @brief release itd list.
374 *
375 * @param ehciInstance ehci instance pointer.
376 * @param startItdPointer start itd pointer.
377 * @param endItdPointer end itd pointer.
378 *
379 * @return transfer's result length.
380 */
381 static uint32_t USB_HostEhciItdArrayRelease(usb_host_ehci_instance_t *ehciInstance,
382 usb_host_ehci_itd_t *startItdPointer,
383 usb_host_ehci_itd_t *endItdPointer);
384
385 /*!
386 * @brief de-initialize itd list.
387 * 1. remove transfer; 2. remove itd from frame list and release itd; 3. transfer callback
388 *
389 * @param ehciInstance ehci instance pointer.
390 * @param ehciPipePointer ehci pipe pointer.
391 *
392 * @return kStatus_USB_Success or error codes.
393 */
394 static usb_status_t USB_HostEhciItdArrayDeinit(usb_host_ehci_instance_t *ehciInstance,
395 usb_host_ehci_pipe_t *ehciPipePointer);
396 #endif /* USB_HOST_CONFIG_EHCI_MAX_ITD */
397
398 /*!
399 * @brief open control or bulk pipe.
400 *
401 * @param ehciInstance ehci instance pointer.
402 * @param ehciPipePointer ehci pipe pointer.
403 *
404 * @return kStatus_USB_Success or error codes.
405 */
406 static usb_status_t USB_HostEhciOpenControlBulk(usb_host_ehci_instance_t *ehciInstance,
407 usb_host_ehci_pipe_t *ehciPipePointer);
408
409 /*!
410 * @brief close control or bulk pipe.
411 *
412 * @param ehciInstance ehci instance pointer.
413 * @param ehciPipePointer ehci pipe pointer.
414 *
415 * @return kStatus_USB_Success or error codes.
416 */
417 static usb_status_t USB_HostEhciCloseControlBulk(usb_host_ehci_instance_t *ehciInstance,
418 usb_host_ehci_pipe_t *ehciPipePointer);
419
420 /*!
421 * @brief open interrupt pipe.
422 *
423 * @param ehciInstance ehci instance pointer.
424 * @param ehciPipePointer ehci pipe pointer.
425 *
426 * @return kStatus_USB_Success or error codes.
427 */
428 static usb_status_t USB_HostEhciOpenInterrupt(usb_host_ehci_instance_t *ehciInstance,
429 usb_host_ehci_pipe_t *ehciPipePointer);
430
431 /*!
432 * @brief close interrupt pipe.
433 *
434 * @param ehciInstance ehci instance pointer.
435 * @param ehciPipePointer ehci pipe pointer.
436 *
437 * @return kStatus_USB_Success or error codes.
438 */
439 static usb_status_t USB_HostEhciCloseInterrupt(usb_host_ehci_instance_t *ehciInstance,
440 usb_host_ehci_pipe_t *ehciPipePointer);
441
442 #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
443 ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
444 /*!
445 * @brief open iso pipe.
446 *
447 * @param ehciInstance ehci instance pointer.
448 * @param ehciPipePointer ehci pipe pointer.
449 *
450 * @return kStatus_USB_Success or error codes.
451 */
452 static usb_status_t USB_HostEhciOpenIso(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer);
453
454 /*!
455 * @brief close iso pipe.
456 *
457 * @param ehciInstance ehci instance pointer.
458 * @param ehciPipePointer ehci pipe pointer.
459 *
460 * @return kStatus_USB_Success or error codes.
461 */
462 static usb_status_t USB_HostEhciCloseIso(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer);
463
464 /*!
465 * @brief allocate HS iso bandwidth when host work as high-speed host.
466 *
467 * @param ehciInstance ehci instance pointer.
468 * @param ehciPipePointer ehci pipe pointer.
469 *
470 * @return kStatus_USB_Success or error codes.
471 */
472 static usb_status_t USB_HostBandwidthHsHostAllocateIso(usb_host_ehci_instance_t *ehciInstance,
473 usb_host_ehci_pipe_t *ehciPipePointer);
474
475 #endif
476
477 /*!
478 * @brief reset ehci ip.
479 *
480 * @param ehciInstance ehci instance pointer.
481 *
482 * @return kStatus_USB_Success or error codes.
483 */
484 static usb_status_t USB_HostEhciResetIP(usb_host_ehci_instance_t *ehciInstance);
485
486 /*!
487 * @brief start ehci ip.
488 *
489 * @param ehciInstance ehci instance pointer.
490 *
491 * @return kStatus_USB_Success or error codes.
492 */
493 static usb_status_t USB_HostEhciStartIP(usb_host_ehci_instance_t *ehciInstance);
494
495 /*!
496 * @brief cancel pipe's transfers.
497 *
498 * @param ehciInstance ehci instance pointer.
499 * @param ehciPipePointer ehci pipe pointer.
500 * @param transfer the canceling transfer.
501 *
502 * @return kStatus_USB_Success or error codes.
503 */
504 static usb_status_t USB_HostEhciCancelPipe(usb_host_ehci_instance_t *ehciInstance,
505 usb_host_ehci_pipe_t *ehciPipePointer,
506 usb_host_transfer_t *transfer);
507
508 /*!
509 * @brief control ehci bus.
510 *
511 * @param ehciInstance ehci instance pointer.
512 * @param bus_control control code.
513 *
514 * @return kStatus_USB_Success or error codes.
515 */
516 static usb_status_t USB_HostEhciControlBus(usb_host_ehci_instance_t *ehciInstance, uint8_t busControl);
517
518 /*!
519 * @brief ehci transaction done process function.
520 *
521 * @param ehciInstance ehci instance pointer.
522 */
523 void USB_HostEhciTransactionDone(usb_host_ehci_instance_t *ehciInstance);
524
525 /*!
526 * @brief ehci port change interrupt process function.
527 *
528 * @param ehciInstance ehci instance pointer.
529 */
530 static void USB_HostEhciPortChange(usb_host_ehci_instance_t *ehciInstance);
531
532 /*!
533 * @brief ehci timer0 interrupt process function.
534 * cancel control/bulk transfer that time out.
535 *
536 * @param ehciInstance ehci instance pointer.
537 */
538 static void USB_HostEhciTimer0(usb_host_ehci_instance_t *ehciInstance);
539
540 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
541 /*!
542 * @brief ehci timer1 interrupt process function.
543 * cancel control/bulk transfer that time out.
544 *
545 * @param ehciInstance ehci instance pointer.
546 */
547 static void USB_HostEhciTimer1(usb_host_ehci_instance_t *ehciInstance);
548 #endif
549
550 #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
551 /*!
552 * @brief suspend bus.
553 *
554 * @param ehciInstance ehci instance pointer.
555 */
556 static void USB_HostEhciSuspendBus(usb_host_ehci_instance_t *ehciInstance);
557
558 /*!
559 * @brief resume bus.
560 *
561 * @param ehciInstance ehci instance pointer.
562 */
563 static void USB_HostEhciResumeBus(usb_host_ehci_instance_t *ehciInstance);
564
565 extern usb_status_t USB_HostStandardSetGetDescriptor(usb_host_device_instance_t *deviceInstance,
566 usb_host_transfer_t *transfer,
567 void *param);
568 #endif /* USB_HOST_CONFIG_COMPLIANCE_TEST */
569
570 /*******************************************************************************
571 * Variables
572 ******************************************************************************/
573
574 /* EHCI controller driver instances. */
575 #if (USB_HOST_CONFIG_EHCI == 1U)
576 USB_RAM_ADDRESS_ALIGNMENT(4096)
577 USB_CONTROLLER_DATA static uint8_t s_UsbHostEhciFrameList1[USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 4];
578
579 static uint8_t usbHostEhciFramListStatus[1] = {0};
580
581 USB_RAM_ADDRESS_ALIGNMENT(64) USB_CONTROLLER_DATA static usb_host_ehci_data_t s_UsbHostEhciData1;
582 #elif (USB_HOST_CONFIG_EHCI == 2U)
583 USB_RAM_ADDRESS_ALIGNMENT(4096)
584 USB_CONTROLLER_DATA static uint8_t s_UsbHostEhciFrameList1[USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 4];
585 USB_RAM_ADDRESS_ALIGNMENT(4096)
586 USB_CONTROLLER_DATA static uint8_t s_UsbHostEhciFrameList2[USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 4];
587 static uint8_t usbHostEhciFramListStatus[2] = {0, 0};
588
589 USB_RAM_ADDRESS_ALIGNMENT(64) USB_CONTROLLER_DATA static usb_host_ehci_data_t s_UsbHostEhciData1;
590 USB_RAM_ADDRESS_ALIGNMENT(64) USB_CONTROLLER_DATA static usb_host_ehci_data_t s_UsbHostEhciData2;
591 #else
592 #error "Please increase the instance count."
593 #endif
594 #define USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE (1024U)
595 #define USB_HOST_EHCI_MAX_MICRFRAME_VALUE ((USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE << 3U) - 1U)
596
597 static uint8_t s_SlotMaxBandwidth[8] = {125, 125, 125, 125, 125, 125, 50, 0};
598 static uint8_t s_SlotMaxBandwidthHs[8] = {100, 100, 100, 100, 100, 100, 100, 100};
599
600 /*******************************************************************************
601 * Code
602 ******************************************************************************/
603 /*!
604 * @brief EHCI NC get USB NC bass address.
605 *
606 * This function is used to get USB NC bass address.
607 *
608 * @param[in] controllerId EHCI controller ID; See the #usb_controller_index_t.
609 *
610 * @retval USB NC bass address.
611 */
612 #if (defined(USB_HOST_CONFIG_LOW_POWER_MODE) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
613 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
USB_EhciNCGetBase(uint8_t controllerId)614 static void *USB_EhciNCGetBase(uint8_t controllerId)
615 {
616 void *usbNCBase = NULL;
617 #if ((defined FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
618 uint32_t instance_count;
619 #if defined(USBNC_STACK_BASE_ADDRS)
620 uint32_t usbnc_base[] = USBNC_STACK_BASE_ADDRS;
621 #else
622 uint32_t usbnc_base[] = USBNC_BASE_ADDRS;
623 #endif
624
625 if (controllerId < (uint8_t)kUSB_ControllerEhci0)
626 {
627 return NULL;
628 }
629
630 controllerId = controllerId - (uint8_t)kUSB_ControllerEhci0;
631
632 instance_count = sizeof(usbnc_base) / sizeof(usbnc_base[0]);
633 if (controllerId >= instance_count)
634 {
635 return NULL;
636 }
637
638 usbNCBase = (void *)(uint8_t *)usbnc_base[controllerId];
639 #endif
640 return usbNCBase;
641 }
642 #endif
643 #endif
644
645 #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
646
USB_HostEhciTestSetMode(usb_host_ehci_instance_t * ehciInstance,uint32_t testMode)647 usb_status_t USB_HostEhciTestSetMode(usb_host_ehci_instance_t *ehciInstance, uint32_t testMode)
648 {
649 uint32_t ehciPortSC;
650
651 ehciPortSC = ehciInstance->ehciIpBase->PORTSC1;
652 ehciPortSC &= ~((uint32_t)USBHS_PORTSC1_PTC_MASK); /* clear test mode bits */
653 ehciPortSC |= (testMode << USBHS_PORTSC1_PTC_SHIFT); /* set test mode bits */
654 ehciInstance->ehciIpBase->PORTSC1 = ehciPortSC;
655 return kStatus_USB_Success;
656 }
657
USB_HostEhciTestSuspendResume(usb_host_ehci_instance_t * ehciInstance)658 static void USB_HostEhciTestSuspendResume(usb_host_ehci_instance_t *ehciInstance)
659 {
660 uint8_t timeCount;
661 timeCount = 15; /* 15s */
662 while (timeCount--)
663 {
664 USB_HostEhciDelay(ehciInstance->ehciIpBase, 1000U);
665 }
666 USB_HostEhciSuspendBus(ehciInstance);
667 timeCount = 15; /* 15s */
668 while (timeCount--)
669 {
670 USB_HostEhciDelay(ehciInstance->ehciIpBase, 1000U);
671 }
672
673 USB_HostEhciResumeBus(ehciInstance);
674 }
675
USB_HostEhciTestCallback(void * param,usb_host_transfer_t * transfer,usb_status_t status)676 static void USB_HostEhciTestCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
677 {
678 USB_HostFreeTransfer(param, transfer);
679 }
680
USB_HostEhciTestSingleStepGetDeviceDesc(usb_host_ehci_instance_t * ehciInstance,usb_device_handle deviceHandle)681 static void USB_HostEhciTestSingleStepGetDeviceDesc(usb_host_ehci_instance_t *ehciInstance,
682 usb_device_handle deviceHandle)
683 {
684 usb_host_process_descriptor_param_t getDescriptorParam;
685 usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
686 usb_host_transfer_t *transfer;
687 uint8_t timeCount;
688 USB_HostEhciLock();
689 /* disable periodic shedule */
690 USB_HostEhciStopPeriodic(ehciInstance);
691 USB_HostEhciUnlock();
692
693 timeCount = 15; /* 15s */
694 while (timeCount--)
695 {
696 USB_HostEhciDelay(ehciInstance->ehciIpBase, 1000U);
697 }
698
699 /* malloc one transfer */
700 if (USB_HostMallocTransfer(ehciInstance->hostHandle, &transfer) != kStatus_USB_Success)
701 {
702 #ifdef HOST_ECHO
703 usb_echo("allocate transfer error\r\n");
704 #endif
705 return;
706 }
707
708 getDescriptorParam.descriptorLength = sizeof(usb_descriptor_device_t);
709 getDescriptorParam.descriptorLength = 18;
710 getDescriptorParam.descriptorBuffer = (uint8_t *)&deviceInstance->deviceDescriptor;
711 getDescriptorParam.descriptorType = USB_DESCRIPTOR_TYPE_DEVICE;
712 getDescriptorParam.descriptorIndex = 0;
713 getDescriptorParam.languageId = 0;
714 transfer->callbackFn = USB_HostEhciTestCallback;
715 transfer->callbackParam = ehciInstance->hostHandle;
716 transfer->setupPacket->bmRequestType = USB_REQUEST_TYPE_DIR_IN;
717 transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_GET_DESCRIPTOR;
718 transfer->setupPacket->wIndex = 0;
719 transfer->setupPacket->wLength = 0;
720 transfer->setupPacket->wValue = 0;
721 USB_HostStandardSetGetDescriptor(deviceInstance, transfer, &getDescriptorParam);
722 }
723
USB_HostEhciSingleStepQtdListInit(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer,usb_host_transfer_t * transfer,uint8_t setupPhase)724 static usb_status_t USB_HostEhciSingleStepQtdListInit(usb_host_ehci_instance_t *ehciInstance,
725 usb_host_ehci_pipe_t *ehciPipePointer,
726 usb_host_transfer_t *transfer,
727 uint8_t setupPhase)
728 {
729 volatile usb_host_ehci_qh_t *vltQhPointer;
730 usb_host_ehci_qtd_t *qtdPointer = NULL;
731 volatile uint32_t *entryPointer;
732 uint32_t qtdNumber;
733 uint32_t dataLength;
734 uint32_t dataAddress;
735 uint8_t index;
736
737 /* compute the qtd number */
738 qtdNumber = 1;
739
740 vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
741 /* get qtd list */
742 USB_HostEhciLock();
743 if (qtdNumber <= ehciInstance->ehciQtdNumber)
744 {
745 ehciInstance->ehciQtdNumber -= qtdNumber;
746 qtdPointer = NULL;
747 do
748 {
749 if (qtdPointer != NULL)
750 {
751 qtdPointer->nextQtdPointer = (uint32_t)ehciInstance->ehciQtdHead;
752 }
753 qtdPointer = ehciInstance->ehciQtdHead;
754 ehciInstance->ehciQtdHead = (usb_host_ehci_qtd_t *)qtdPointer->nextQtdPointer;
755 qtdPointer->nextQtdPointer = 0;
756 } while (--qtdNumber);
757 }
758 else
759 {
760 USB_HostEhciUnlock();
761 return kStatus_USB_Error;
762 }
763 USB_HostEhciUnlock();
764
765 /* int qTD */
766 if (setupPhase == 1) /* setup transaction qtd init */
767 {
768 qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
769 /* dt: need set; ioc: 0; C_Page: 0; PID Code: SETUP; Status: Active */
770 qtdPointer->transferResults[0] = qtdPointer->transferResults[1] = 0;
771 qtdPointer->transferResults[0] =
772 ((0x00000000 << EHCI_HOST_QTD_DT_SHIFT) | (8 << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
773 (EHCI_HOST_PID_SETUP << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
774 dataAddress = (uint32_t)(transfer->setupPacket);
775 qtdPointer->transferResults[1] = dataAddress; /* current offset is set too */
776 /* set buffer pointer no matter data length */
777 for (index = 0; index < 4; ++index)
778 {
779 qtdPointer->bufferPointers[index] = ((dataAddress + (index + 1) * 4 * 1024) & 0xFFFFF000);
780 }
781 }
782 else if (setupPhase == 2) /* data transaction qtd */
783 {
784 dataLength = transfer->transferLength;
785 if (dataLength != 0)
786 {
787 qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
788 /* dt: need set; ioc: 0; C_Page: 0; PID Code: IN/OUT; Status: Active */
789 qtdPointer->transferResults[0] = qtdPointer->transferResults[1] = 0;
790
791 qtdPointer->transferResults[0] =
792 ((0x00000001U << EHCI_HOST_QTD_DT_SHIFT) | (dataLength << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
793 (EHCI_HOST_PID_IN << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
794
795 dataAddress = (uint32_t)(transfer->transferBuffer);
796 qtdPointer->transferResults[1] = dataAddress; /* current offset is set too */
797 /* set buffer pointer no matter data length */
798 for (index = 0; index < 4; ++index)
799 {
800 qtdPointer->bufferPointers[index] = ((dataAddress + (index + 1) * 4 * 1024) & 0xFFFFF000);
801 }
802 }
803 }
804 else if (setupPhase == 3)
805 {
806 /* status transaction qtd */
807 qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
808 /* dt: dont care; ioc: 1; C_Page: 0; PID Code: IN/OUT; Status: Active */
809 qtdPointer->transferResults[0] = qtdPointer->transferResults[1] = 0;
810
811 qtdPointer->transferResults[0] =
812 ((0x00000001U << EHCI_HOST_QTD_DT_SHIFT) | (EHCI_HOST_PID_OUT << EHCI_HOST_QTD_PID_CODE_SHIFT) |
813 (EHCI_HOST_QTD_IOC_MASK) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
814
815 qtdPointer->nextQtdPointer |= EHCI_HOST_T_INVALID_VALUE;
816 }
817 qtdPointer->nextQtdPointer |= EHCI_HOST_T_INVALID_VALUE;
818 qtdPointer->transferResults[0] |= EHCI_HOST_QTD_IOC_MASK; /* set IOC */
819
820 /* save qtd to transfer */
821 transfer->union1.unitHead = (uint32_t)qtdPointer;
822 transfer->union2.unitTail = (uint32_t)qtdPointer;
823 /* link transfer to qh */
824 transfer->next = NULL;
825 if (vltQhPointer->ehciTransferHead == NULL)
826 {
827 transfer->next = NULL;
828 vltQhPointer->ehciTransferHead = vltQhPointer->ehciTransferTail = transfer;
829 }
830 else
831 {
832 transfer->next = NULL;
833 vltQhPointer->ehciTransferTail->next = transfer;
834 vltQhPointer->ehciTransferTail = transfer;
835 }
836
837 USB_HostEhciLock();
838 /* link qtd to qh (link to end) */
839 entryPointer = &(vltQhPointer->nextQtdPointer);
840 dataAddress = *entryPointer; /* dataAddress variable means entry value here */
841 while ((dataAddress) && (!(dataAddress & EHCI_HOST_T_INVALID_VALUE)))
842 {
843 entryPointer = (volatile uint32_t *)dataAddress;
844 dataAddress = *entryPointer;
845 }
846 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
847 *entryPointer = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(qtdPointer);
848 #else
849 *entryPointer = (uint32_t)qtdPointer;
850 #endif
851 USB_HostEhciStartAsync(ehciInstance);
852 USB_HostEhciUnlock();
853
854 return kStatus_USB_Success;
855 }
856
USB_HostEhciTestSingleStepGetDeviceDescData(usb_host_ehci_instance_t * ehciInstance,usb_device_handle deviceHandle)857 static void USB_HostEhciTestSingleStepGetDeviceDescData(usb_host_ehci_instance_t *ehciInstance,
858 usb_device_handle deviceHandle)
859 {
860 static uint8_t buffer[USB_HOST_EHCI_TEST_DESCRIPTOR_LENGTH];
861 usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
862 usb_host_transfer_t *transfer;
863 uint8_t timeCount;
864 USB_HostEhciLock();
865 USB_HostEhciStopPeriodic(ehciInstance);
866 USB_HostEhciUnlock();
867
868 if (USB_HostMallocTransfer(ehciInstance->hostHandle, &transfer) != kStatus_USB_Success)
869 {
870 return;
871 }
872 transfer->callbackFn = USB_HostEhciTestCallback;
873 transfer->callbackParam = ehciInstance->hostHandle;
874 transfer->setupPacket->bmRequestType = USB_REQUEST_TYPE_DIR_IN;
875 transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_GET_DESCRIPTOR;
876 transfer->setupPacket->wLength = USB_SHORT_TO_LITTLE_ENDIAN(USB_HOST_EHCI_TEST_DESCRIPTOR_LENGTH);
877 transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN((uint16_t)((uint16_t)USB_DESCRIPTOR_TYPE_DEVICE << 8));
878 transfer->setupPacket->wIndex = 0;
879 USB_HostEhciSingleStepQtdListInit(ehciInstance, (usb_host_ehci_pipe_t *)(deviceInstance->controlPipe), transfer, 1);
880
881 timeCount = 15; /* 15s */
882 while (timeCount--)
883 {
884 USB_HostEhciDelay(ehciInstance->ehciIpBase, 1000U);
885 }
886
887 if (USB_HostMallocTransfer(ehciInstance->hostHandle, &transfer) != kStatus_USB_Success)
888 {
889 return;
890 }
891 transfer->callbackFn = USB_HostEhciTestCallback;
892 transfer->callbackParam = ehciInstance->hostHandle;
893 transfer->transferBuffer = buffer;
894 transfer->transferLength = USB_HOST_EHCI_TEST_DESCRIPTOR_LENGTH;
895 USB_HostEhciSingleStepQtdListInit(ehciInstance, (usb_host_ehci_pipe_t *)(deviceInstance->controlPipe), transfer, 2);
896
897 if (USB_HostMallocTransfer(ehciInstance->hostHandle, &transfer) != kStatus_USB_Success)
898 {
899 return;
900 }
901 transfer->callbackFn = USB_HostEhciTestCallback;
902 transfer->callbackParam = ehciInstance->hostHandle;
903 transfer->transferBuffer = NULL;
904 transfer->transferLength = 0;
905 USB_HostEhciSingleStepQtdListInit(ehciInstance, (usb_host_ehci_pipe_t *)(deviceInstance->controlPipe), transfer, 3);
906
907 timeCount = 15; /* 15s */
908 while (timeCount--)
909 {
910 USB_HostEhciDelay(ehciInstance->ehciIpBase, 1000U);
911 }
912
913 usb_echo("test_single_step_get_dev_desc_data finished\r\n");
914
915 return;
916 }
917
USB_HostEhciTestModeInit(usb_device_handle deviceHandle)918 static void USB_HostEhciTestModeInit(usb_device_handle deviceHandle)
919 {
920 uint32_t productId;
921 usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
922 usb_host_ehci_instance_t *ehciInstance =
923 (usb_host_ehci_instance_t *)(((usb_host_instance_t *)(deviceInstance->hostHandle))->controllerHandle);
924
925 USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDevicePID, &productId);
926
927 usb_echo("usb host ehci test mode init product id:0x%x\r\n", productId);
928
929 switch (productId)
930 {
931 case 0x0101U:
932 USB_HostEhciTestSetMode(ehciInstance, USB_HOST_EHCI_PORTSC_PTC_SE0_NAK);
933 break;
934 case 0x0102U:
935 USB_HostEhciTestSetMode(ehciInstance, USB_HOST_EHCI_PORTSC_PTC_J_STATE);
936 break;
937 case 0x0103U:
938 USB_HostEhciTestSetMode(ehciInstance, USB_HOST_EHCI_PORTSC_PTC_K_STATE);
939 break;
940 case 0x0104U:
941 USB_HostEhciTestSetMode(ehciInstance, USB_HOST_EHCI_PORTSC_PTC_PACKET);
942 break;
943 case 0x0105U:
944 usb_echo("set test mode FORCE_ENALBE_HS\r\n");
945 USB_HostEhciTestSetMode(ehciInstance, USB_HOST_EHCI_PORTSC_PTC_FORCE_ENABLE_HS);
946 break;
947 case 0x0106U:
948 USB_HostEhciTestSuspendResume(ehciInstance);
949 break;
950 case 0x0107U:
951 usb_echo("start test SINGLE_STEP_GET_DEV_DESC\r\n");
952 USB_HostEhciTestSingleStepGetDeviceDesc(ehciInstance, deviceHandle);
953 break;
954 case 0x0108U:
955 usb_echo("start test SINGLE_STEP_GET_DEV_DESC_DATA\r\n");
956 USB_HostEhciTestSingleStepGetDeviceDescData(ehciInstance, deviceHandle);
957 break;
958 default:
959 /*no action */
960 break;
961 }
962
963 return;
964 }
965
USB_HostEhciSuspendBus(usb_host_ehci_instance_t * ehciInstance)966 static void USB_HostEhciSuspendBus(usb_host_ehci_instance_t *ehciInstance)
967 {
968 uint32_t ehciPortSC;
969
970 USB_HostEhciLock();
971 ehciPortSC = ehciInstance->ehciIpBase->PORTSC1;
972 if (ehciPortSC & USBHS_PORTSC1_PE_MASK)
973 {
974 ehciPortSC = ehciInstance->ehciIpBase->PORTSC1;
975 ehciPortSC &= (uint32_t)(~EHCI_PORTSC1_W1_BITS);
976 ehciInstance->ehciIpBase->PORTSC1 = (ehciPortSC | USBHS_PORTSC1_SUSP_MASK);
977 }
978 USB_HostEhciUnlock();
979 }
980
USB_HostEhciResumeBus(usb_host_ehci_instance_t * ehciInstance)981 static void USB_HostEhciResumeBus(usb_host_ehci_instance_t *ehciInstance)
982 {
983 uint32_t ehciPortSC;
984
985 USB_HostEhciLock();
986 /* Resume port */
987 ehciPortSC = ehciInstance->ehciIpBase->PORTSC1;
988 if (ehciPortSC & USBHS_PORTSC1_PE_MASK)
989 {
990 ehciPortSC &= (uint32_t)(~EHCI_PORTSC1_W1_BITS);
991 ehciInstance->ehciIpBase->PORTSC1 = (ehciPortSC | USBHS_PORTSC1_FPR_MASK);
992 }
993 USB_HostEhciUnlock();
994 }
995 #endif
996
USB_HostBandwidthComputeTime(uint8_t speed,uint8_t pipeType,uint8_t direction,uint32_t dataLength)997 static uint32_t USB_HostBandwidthComputeTime(uint8_t speed, uint8_t pipeType, uint8_t direction, uint32_t dataLength)
998 {
999 uint32_t result = (3167U + ((1000U * dataLength) * 7U * 8U / 6U)) / 1000U;
1000
1001 if (pipeType == USB_ENDPOINT_ISOCHRONOUS) /* iso */
1002 {
1003 if (speed == USB_SPEED_HIGH)
1004 {
1005 result = 38U * 8U * 2083U + 2083U * result + USB_HOST_EHCI_BANDWIDTH_DELAY;
1006 }
1007 else if (speed == USB_SPEED_FULL)
1008 {
1009 if (direction == USB_IN)
1010 {
1011 result = 7268000U + 83540U * result + USB_HOST_EHCI_BANDWIDTH_DELAY;
1012 }
1013 else
1014 {
1015 result = 6265000U + 83540U * result + USB_HOST_EHCI_BANDWIDTH_DELAY;
1016 }
1017 }
1018 else
1019 {
1020 /*no action*/
1021 }
1022 }
1023 else /* interrupt */
1024 {
1025 if (speed == USB_SPEED_HIGH)
1026 {
1027 result = 55U * 8U * 2083U + 2083U * result + USB_HOST_EHCI_BANDWIDTH_DELAY;
1028 }
1029 else if (speed == USB_SPEED_FULL)
1030 {
1031 result = 9107000U + 83540U * result + USB_HOST_EHCI_BANDWIDTH_DELAY;
1032 }
1033 else if (speed == USB_SPEED_LOW)
1034 {
1035 if (direction == USB_IN)
1036 {
1037 result = 64060000U + 2000U * USB_HOST_EHCI_BANDWIDTH_HUB_LS_SETUP + 676670U * result +
1038 USB_HOST_EHCI_BANDWIDTH_DELAY;
1039 }
1040 else
1041 {
1042 result = 6265000U + 83540U * result + USB_HOST_EHCI_BANDWIDTH_DELAY;
1043 }
1044 }
1045 else
1046 {
1047 /*no action*/
1048 }
1049 }
1050
1051 result /= 1000000U;
1052 if (result == 0U)
1053 {
1054 result = 1U;
1055 }
1056
1057 return result;
1058 }
1059
USB_HostBandwidthFslsHostComputeCurrent(usb_host_ehci_instance_t * ehciInstance,uint16_t frameIndex,uint16_t * frameBandwidth)1060 static void USB_HostBandwidthFslsHostComputeCurrent(usb_host_ehci_instance_t *ehciInstance,
1061 uint16_t frameIndex,
1062 uint16_t *frameBandwidth)
1063 {
1064 usb_host_ehci_pipe_t *ehciPipePointer;
1065 void *temp;
1066 /* clear the bandwidth */
1067 *frameBandwidth = 0;
1068
1069 ehciPipePointer = ehciInstance->ehciRunningPipeList;
1070 while (ehciPipePointer != NULL)
1071 {
1072 /* only compute iso and interrupt pipe */
1073 if ((ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_ISOCHRONOUS) ||
1074 (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT))
1075 {
1076 /* does pipe allocate bandwidth in frameIndex frame? note: interval is power of 2. */
1077 if ((frameIndex >= ehciPipePointer->startFrame) &&
1078 (0U == ((uint32_t)((uint32_t)frameIndex - ehciPipePointer->startFrame) &
1079 ((uint32_t)ehciPipePointer->pipeCommon.interval - 1U))))
1080 {
1081 *frameBandwidth += ehciPipePointer->dataTime;
1082 }
1083 }
1084 temp = (void *)ehciPipePointer->pipeCommon.next;
1085 ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
1086 }
1087 }
1088
USB_HostBandwidthHsHostComputeCurrentFsls(usb_host_ehci_instance_t * ehciInstance,uint32_t hubNumber,uint16_t frameIndex,uint16_t frameBandwidths[8])1089 static void USB_HostBandwidthHsHostComputeCurrentFsls(usb_host_ehci_instance_t *ehciInstance,
1090 uint32_t hubNumber,
1091 uint16_t frameIndex,
1092 uint16_t frameBandwidths[8])
1093 {
1094 usb_host_ehci_pipe_t *ehciPipePointer;
1095 uint8_t index;
1096 uint32_t deviceInfo = 0U;
1097 void *temp;
1098
1099 for (index = 0; index < 8U; ++index)
1100 {
1101 frameBandwidths[index] = 0;
1102 }
1103
1104 ehciPipePointer = ehciInstance->ehciRunningPipeList;
1105 while (ehciPipePointer != NULL)
1106 {
1107 /* only compute iso and interrupt pipe */
1108 if ((ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_ISOCHRONOUS) ||
1109 (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT))
1110 {
1111 /* compute FS/LS bandwidth that blong to same high-speed hub, because FS/LS bandwidth is allocated from
1112 * first parent high-speed hub */
1113 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
1114 (uint32_t)kUSB_HostGetDeviceHSHubNumber, &deviceInfo);
1115 if (deviceInfo != hubNumber)
1116 {
1117 temp = (void *)ehciPipePointer->pipeCommon.next;
1118 ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
1119 continue;
1120 }
1121 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
1122 (uint32_t)kUSB_HostGetDeviceSpeed, &deviceInfo);
1123 if (deviceInfo == USB_SPEED_HIGH)
1124 {
1125 temp = (void *)ehciPipePointer->pipeCommon.next;
1126 ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
1127 continue;
1128 }
1129
1130 /* does pipe allocate bandwidth in frameIndex frame? note: interval is power of 2. */
1131 if ((frameIndex >= ehciPipePointer->startFrame) &&
1132 (0U == ((uint32_t)((uint32_t)frameIndex - ehciPipePointer->startFrame) &
1133 ((uint32_t)ehciPipePointer->pipeCommon.interval - 1U))))
1134 {
1135 if (ehciPipePointer->pipeCommon.pipeType ==
1136 USB_ENDPOINT_ISOCHRONOUS) /* iso bandwidth is allocated once */
1137 {
1138 frameBandwidths[ehciPipePointer->startUframe + 1U] += ehciPipePointer->dataTime;
1139 }
1140 else /* iso bandwidth is allocated three times */
1141 {
1142 frameBandwidths[ehciPipePointer->startUframe + 1U] += ehciPipePointer->dataTime;
1143 frameBandwidths[ehciPipePointer->startUframe + 2U] += ehciPipePointer->dataTime;
1144 frameBandwidths[ehciPipePointer->startUframe + 3U] += ehciPipePointer->dataTime;
1145 }
1146 }
1147 }
1148 temp = (void *)ehciPipePointer->pipeCommon.next;
1149 ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
1150 }
1151
1152 for (index = 0; index < 7U; ++index) /* */
1153 {
1154 if (frameBandwidths[index] > s_SlotMaxBandwidth[index])
1155 {
1156 frameBandwidths[index + 1U] += (frameBandwidths[index] - s_SlotMaxBandwidth[index]);
1157 frameBandwidths[index] = s_SlotMaxBandwidth[index];
1158 }
1159 }
1160 }
1161
USB_HostBandwidthHsHostComputeCurrentHsAll(usb_host_ehci_instance_t * ehciInstance,uint16_t frameIndex,uint16_t frameBandwidths[8])1162 static void USB_HostBandwidthHsHostComputeCurrentHsAll(usb_host_ehci_instance_t *ehciInstance,
1163 uint16_t frameIndex,
1164 uint16_t frameBandwidths[8])
1165 {
1166 usb_host_ehci_pipe_t *ehciPipePointer;
1167 uint16_t index;
1168 uint32_t deviceInfo = 0U;
1169 uint16_t frameInterval;
1170 void *temp;
1171 for (index = 0; index < 8U; ++index)
1172 {
1173 frameBandwidths[index] = 0;
1174 }
1175
1176 ehciPipePointer = ehciInstance->ehciRunningPipeList;
1177 while (ehciPipePointer != NULL)
1178 {
1179 /* only compute iso and interrupt pipe */
1180 if ((ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_ISOCHRONOUS) ||
1181 (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT))
1182 {
1183 frameInterval = ehciPipePointer->pipeCommon.interval;
1184 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
1185 (uint32_t)kUSB_HostGetDeviceSpeed, &deviceInfo);
1186 if (deviceInfo == USB_SPEED_HIGH) /* high-speed data bandwidth */
1187 {
1188 /* frameInterval means micro-frame here */
1189 if (frameIndex >= ehciPipePointer->startFrame)
1190 {
1191 if ((frameInterval > 8U) &&
1192 (frameIndex * 8U - ehciPipePointer->startFrame * 8U >= ehciPipePointer->startUframe))
1193 {
1194 if (0U == ((((uint32_t)frameIndex) * 8U - ehciPipePointer->startFrame * 8U -
1195 ehciPipePointer->startUframe) &
1196 ((uint32_t)frameInterval - 1U)))
1197 {
1198 frameBandwidths[ehciPipePointer->startUframe] += ehciPipePointer->dataTime;
1199 }
1200 }
1201 else
1202 {
1203 for (index = ehciPipePointer->startUframe; index < 8U; index += frameInterval)
1204 {
1205 frameBandwidths[index] += ehciPipePointer->dataTime;
1206 }
1207 }
1208 }
1209 }
1210 else /* full-speed split bandwidth */
1211 {
1212 if ((frameIndex >= ehciPipePointer->startFrame) &&
1213 (0U == ((uint32_t)((uint32_t)frameIndex - ehciPipePointer->startFrame) &
1214 (uint32_t)((uint32_t)frameInterval - 1U))))
1215 {
1216 for (index = 0; index < 8U; ++index)
1217 {
1218 if (0U != ((uint32_t)(ehciPipePointer->uframeSmask) &
1219 (uint32_t)(0x01UL << index))) /* start-split micro-frames */
1220 {
1221 frameBandwidths[index] += ehciPipePointer->startSplitTime;
1222 }
1223 if (0U != ((uint32_t)(ehciPipePointer->uframeCmask) &
1224 (uint32_t)(0x01UL << index))) /* complete-split micro-frames */
1225 {
1226 frameBandwidths[index] += ehciPipePointer->completeSplitTime;
1227 }
1228 }
1229 }
1230 }
1231 }
1232 temp = (void *)ehciPipePointer->pipeCommon.next;
1233 ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
1234 }
1235
1236 #if 0
1237 for (index = 0; index < 7; ++index) /* */
1238 {
1239 if (frameBandwidths[index] > s_SlotMaxBandwidthHs[index])
1240 {
1241 frameBandwidths[index + 1] += (frameBandwidths[index] - s_SlotMaxBandwidthHs[index]);
1242 frameBandwidths[index] = s_SlotMaxBandwidthHs[index];
1243 }
1244 }
1245 #endif
1246 }
1247
1248 /*!
1249 * @brief allocate HS bandwidth when host work as high-speed host.
1250 *
1251 * @param ehciInstance ehci instance pointer.
1252 * @param uframeInterval micro-frame interval.
1253 * @param timeData time for allocating.
1254 * @param uframeIndexOut return start uframe index.
1255 *
1256 * @return kStatus_USB_Success or error codes.
1257 */
USB_HostBandwidthHsHostAllocateHsCommon(usb_host_ehci_instance_t * ehciInstance,uint16_t uframeInterval,uint16_t timeData,uint16_t * uframeIndexOut)1258 static usb_status_t USB_HostBandwidthHsHostAllocateHsCommon(usb_host_ehci_instance_t *ehciInstance,
1259 uint16_t uframeInterval,
1260 uint16_t timeData,
1261 uint16_t *uframeIndexOut)
1262 {
1263 uint16_t uframeIntervalIndex;
1264 uint16_t uframeIndex;
1265 uint16_t frameIndex;
1266 uint16_t frameTimes[8];
1267
1268 frameIndex = 0;
1269 for (uint8_t i = 0; i < 8U; ++i)
1270 {
1271 frameTimes[i] = 0U;
1272 }
1273 USB_HostBandwidthHsHostComputeCurrentHsAll(
1274 ehciInstance, frameIndex, frameTimes); /* compute the allocated bandwidths in the frameIndex frame */
1275 for (uframeIntervalIndex = 0; (uframeIntervalIndex < uframeInterval); ++uframeIntervalIndex) /* start micro-frame */
1276 {
1277 /* for all the micro-frame in interval uframeInterval */
1278 for (uframeIndex = uframeIntervalIndex; uframeIndex < (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 8U);
1279 uframeIndex += uframeInterval)
1280 {
1281 if (frameIndex != (uframeIndex >> 3))
1282 {
1283 frameIndex = (uframeIndex >> 3);
1284 USB_HostBandwidthHsHostComputeCurrentHsAll(
1285 ehciInstance, frameIndex,
1286 frameTimes); /* compute the allocated bandwidths in the new frameIndex frame */
1287 }
1288 if (frameTimes[uframeIndex & 0x0007U] + timeData >
1289 s_SlotMaxBandwidthHs[(uframeIndex & 0x0007U)]) /* micro-frame has enough idle bandwidth? */
1290 {
1291 break; /* fail */
1292 }
1293 }
1294 if (uframeIndex >= (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 8U)) /* success? */
1295 {
1296 break;
1297 }
1298 }
1299
1300 if (uframeIntervalIndex < uframeInterval)
1301 {
1302 *uframeIndexOut = (uframeIntervalIndex);
1303 return kStatus_USB_Success;
1304 }
1305 else
1306 {
1307 return kStatus_USB_Error;
1308 }
1309 }
1310
1311 #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
1312 ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
1313
USB_HostBandwidthHsHostAllocateIso(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)1314 static usb_status_t USB_HostBandwidthHsHostAllocateIso(usb_host_ehci_instance_t *ehciInstance,
1315 usb_host_ehci_pipe_t *ehciPipePointer)
1316 {
1317 usb_status_t status;
1318 uint32_t deviceInfo = 0;
1319 uint32_t hubNumber = 0;
1320 uint16_t uframeIntervalIndex = 0;
1321 uint16_t frameIntervalIndex = 0;
1322 uint16_t frameIndex;
1323 uint16_t timeCompleteSplit;
1324 uint16_t timeStartSplit;
1325 uint32_t timeData;
1326 uint8_t SsCsNumber = 0;
1327 uint16_t frameInterval;
1328 uint16_t frameTimes[8];
1329 uint8_t allocateOk = 1;
1330 uint16_t index;
1331
1332 for (uint8_t i = 0; i < 8U; ++i)
1333 {
1334 frameTimes[i] = 0U;
1335 }
1336 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
1337 (uint32_t)kUSB_HostGetDeviceSpeed, &deviceInfo);
1338
1339 timeData = USB_HostBandwidthComputeTime(
1340 (uint8_t)deviceInfo, USB_ENDPOINT_ISOCHRONOUS, ehciPipePointer->pipeCommon.direction,
1341 (((uint32_t)ehciPipePointer->pipeCommon.maxPacketSize) * ehciPipePointer->pipeCommon.numberPerUframe));
1342 /* pipe is high-speed */
1343 if (deviceInfo == USB_SPEED_HIGH)
1344 {
1345 uframeIntervalIndex = 0;
1346 status = USB_HostBandwidthHsHostAllocateHsCommon(ehciInstance, ehciPipePointer->uframeInterval,
1347 (uint16_t)timeData, &uframeIntervalIndex);
1348 if (status == kStatus_USB_Success)
1349 {
1350 ehciPipePointer->startFrame = (uframeIntervalIndex / 8U);
1351 ehciPipePointer->startUframe = (uint8_t)(uframeIntervalIndex & 0x0007U);
1352 ehciPipePointer->dataTime = (uint16_t)timeData;
1353
1354 return kStatus_USB_Success;
1355 }
1356 }
1357 else /* pipe is full-speed or low-speed */
1358 {
1359 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
1360 (uint32_t)kUSB_HostGetHubThinkTime,
1361 &deviceInfo); /* deviceInfo variable means hub think time */
1362 timeData += (deviceInfo * 7U / (6U * 12U));
1363 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
1364 (uint32_t)kUSB_HostGetDeviceHSHubNumber, &hubNumber);
1365 frameInterval = ehciPipePointer->pipeCommon.interval;
1366
1367 /* compute start-split and complete-split bandwidth */
1368 if (ehciPipePointer->pipeCommon.direction == USB_OUT)
1369 {
1370 timeStartSplit = (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_ISOCHRONOUS, USB_OUT,
1371 ehciPipePointer->pipeCommon.maxPacketSize);
1372 timeCompleteSplit = 0;
1373 }
1374 else
1375 {
1376 timeStartSplit =
1377 (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_ISOCHRONOUS, USB_IN, 1);
1378 timeCompleteSplit = (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_ISOCHRONOUS, USB_IN,
1379 ehciPipePointer->pipeCommon.maxPacketSize);
1380 }
1381 /* note: bandwidth must put in one frame */
1382 for (uframeIntervalIndex = 0U; uframeIntervalIndex <= 5U; ++uframeIntervalIndex) /* uframe interval */
1383 {
1384 for (frameIntervalIndex = 0U; frameIntervalIndex < frameInterval; ++frameIntervalIndex) /* frame interval */
1385 {
1386 allocateOk = 1;
1387 for (frameIndex = frameIntervalIndex; frameIndex < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE;
1388 frameIndex += frameInterval) /* check all the frames */
1389 {
1390 /* compute start-split and complete-split number */
1391 SsCsNumber = (uint8_t)((ehciPipePointer->pipeCommon.maxPacketSize + 187U) /
1392 188U); /* ss number for iso out; cs number for iso in */
1393 if (ehciPipePointer->pipeCommon.direction == USB_OUT) /* ISO OUT */
1394 {
1395 if (uframeIntervalIndex + SsCsNumber > 8U)
1396 {
1397 allocateOk = 0U;
1398 }
1399 }
1400 else
1401 {
1402 if (uframeIntervalIndex + 2U + SsCsNumber >
1403 8U) /* ISO IN: there are two micro-frame interval between start-split and complete-split */
1404 {
1405 allocateOk = 0U;
1406 }
1407 }
1408 if (0U != allocateOk)
1409 {
1410 /* allocate start-split and complete-split bandwidth */
1411 USB_HostBandwidthHsHostComputeCurrentHsAll(ehciInstance, frameIndex, frameTimes);
1412 if (ehciPipePointer->pipeCommon.direction == USB_OUT) /* ISO OUT */
1413 {
1414 index = uframeIntervalIndex;
1415 for (; index < (uframeIntervalIndex + SsCsNumber); ++index)
1416 {
1417 if (frameTimes[index] + timeStartSplit > s_SlotMaxBandwidthHs[index])
1418 {
1419 allocateOk = 0U;
1420 break;
1421 }
1422 }
1423 }
1424 else /* ISO IN */
1425 {
1426 index = uframeIntervalIndex;
1427 if (frameTimes[index] + timeStartSplit > s_SlotMaxBandwidthHs[index])
1428 {
1429 allocateOk = 0U;
1430 }
1431 if (0U != allocateOk)
1432 {
1433 index =
1434 uframeIntervalIndex +
1435 2U; /* there are two micro-frames interval between start-split and complete-split */
1436 for (; index < (uframeIntervalIndex + 2U + SsCsNumber); ++index)
1437 {
1438 if (frameTimes[index] + timeCompleteSplit > s_SlotMaxBandwidthHs[index])
1439 {
1440 allocateOk = 0U;
1441 break;
1442 }
1443 }
1444 }
1445 }
1446 }
1447
1448 /* allocate data bandwidth */
1449 if (0U != allocateOk)
1450 {
1451 USB_HostBandwidthHsHostComputeCurrentFsls(ehciInstance, hubNumber, frameIndex, frameTimes);
1452 index = uframeIntervalIndex + 1U; /* timeData bandwidth start position */
1453 /* iso must occupy all the uframe bandwidth */
1454 {
1455 deviceInfo = timeData; /* note: deviceInfo variable means bandwidth here */
1456 while ((index < 8U) && (deviceInfo > s_SlotMaxBandwidth[index]))
1457 {
1458 if (frameTimes[index] > 0U)
1459 {
1460 allocateOk = 0U;
1461 break;
1462 }
1463 else
1464 {
1465 deviceInfo -= s_SlotMaxBandwidth[index];
1466 }
1467 ++index;
1468 }
1469 }
1470 }
1471 if (0U != allocateOk)
1472 {
1473 /* data bandwidth can be put in the frame? */
1474 index = uframeIntervalIndex + 1U; /* timeData bandwidth start position */
1475 frameTimes[index] += (uint16_t)timeData;
1476 for (; index < 7U; ++index)
1477 {
1478 if (frameTimes[index] > s_SlotMaxBandwidth[index])
1479 {
1480 frameTimes[index + 1U] += (frameTimes[index] - s_SlotMaxBandwidth[index]);
1481 frameTimes[index] = s_SlotMaxBandwidth[index];
1482 }
1483 else
1484 {
1485 break;
1486 }
1487 }
1488 if (frameTimes[index] > s_SlotMaxBandwidth[index])
1489 {
1490 allocateOk = 0;
1491 }
1492 }
1493
1494 if (0U != allocateOk)
1495 {
1496 break;
1497 }
1498 }
1499 if (0U != allocateOk)
1500 {
1501 break;
1502 }
1503 }
1504 if (0U != allocateOk)
1505 {
1506 break;
1507 }
1508 }
1509
1510 if (0U != allocateOk)
1511 {
1512 ehciPipePointer->startFrame = frameIntervalIndex;
1513 ehciPipePointer->startUframe = (uint8_t)uframeIntervalIndex;
1514 ehciPipePointer->dataTime = (uint16_t)timeData;
1515 ehciPipePointer->startSplitTime = timeStartSplit;
1516 ehciPipePointer->completeSplitTime = timeCompleteSplit;
1517 if (ehciPipePointer->pipeCommon.direction == USB_OUT)
1518 {
1519 index = uframeIntervalIndex;
1520 for (; index < (uframeIntervalIndex + SsCsNumber); ++index)
1521 {
1522 ehciPipePointer->uframeSmask = ehciPipePointer->uframeSmask | (uint8_t)(0x01UL << index);
1523 }
1524 }
1525 else
1526 {
1527 index = uframeIntervalIndex;
1528 ehciPipePointer->uframeSmask = ehciPipePointer->uframeSmask | (uint8_t)(0x01UL << index);
1529 index = uframeIntervalIndex + 2U;
1530 for (; index < (uframeIntervalIndex + 2U + SsCsNumber); ++index)
1531 {
1532 ehciPipePointer->uframeCmask = ehciPipePointer->uframeCmask | (uint8_t)(0x01UL << index);
1533 }
1534 }
1535
1536 return kStatus_USB_Success;
1537 }
1538 }
1539
1540 return kStatus_USB_Error;
1541 }
1542
1543 #endif
1544
USB_HostBandwidthHsHostAllocateInterrupt(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)1545 static usb_status_t USB_HostBandwidthHsHostAllocateInterrupt(usb_host_ehci_instance_t *ehciInstance,
1546 usb_host_ehci_pipe_t *ehciPipePointer)
1547 {
1548 usb_status_t status;
1549 uint32_t deviceInfo = 0;
1550 uint32_t hubNumber = 0;
1551 uint16_t uframeIntervalIndex = 0;
1552 uint16_t frameIntervalIndex = 0;
1553 uint16_t frameIndex;
1554 uint16_t timeCompleteSplit;
1555 uint16_t timeStartSplit;
1556 uint32_t timeData;
1557 uint8_t SsCsNumber;
1558 uint16_t frameInterval;
1559 uint16_t frameTimes[8];
1560 uint8_t allocateOk = 1;
1561 uint8_t index;
1562
1563 for (uint8_t i = 0; i < 8U; ++i)
1564 {
1565 frameTimes[i] = 0U;
1566 }
1567 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
1568 (uint32_t)kUSB_HostGetDeviceSpeed, &deviceInfo);
1569
1570 timeData = USB_HostBandwidthComputeTime(
1571 (uint8_t)deviceInfo, USB_ENDPOINT_INTERRUPT, ehciPipePointer->pipeCommon.direction,
1572 (uint32_t)ehciPipePointer->pipeCommon.maxPacketSize * ehciPipePointer->pipeCommon.numberPerUframe);
1573 /* pipe is high-speed */
1574 if (deviceInfo == USB_SPEED_HIGH)
1575 {
1576 uframeIntervalIndex = 0;
1577 status = USB_HostBandwidthHsHostAllocateHsCommon(ehciInstance, ehciPipePointer->uframeInterval,
1578 (uint16_t)timeData, &uframeIntervalIndex);
1579 if (status == kStatus_USB_Success)
1580 {
1581 ehciPipePointer->startFrame = (uframeIntervalIndex / 8U);
1582 ehciPipePointer->startUframe = (uint8_t)(uframeIntervalIndex & 0x0007U);
1583 /* for HS interrupt start transaction position */
1584 if (ehciPipePointer->uframeInterval >= 8U)
1585 {
1586 ehciPipePointer->uframeSmask = (0x01U << ehciPipePointer->startUframe);
1587 }
1588 else
1589 {
1590 ehciPipePointer->uframeSmask = 0x00U;
1591 for (index = ehciPipePointer->startUframe; index < 8U;
1592 index += (uint8_t)ehciPipePointer->uframeInterval)
1593 {
1594 ehciPipePointer->uframeSmask |= (0x01U << index);
1595 }
1596 }
1597 ehciPipePointer->dataTime = (uint16_t)timeData;
1598
1599 return kStatus_USB_Success;
1600 }
1601 }
1602 else /* pipe is full-speed or low-speed */
1603 {
1604 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
1605 (uint32_t)kUSB_HostGetHubThinkTime, &deviceInfo);
1606 timeData += (deviceInfo * 7U / (6U * 12U));
1607 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
1608 (uint32_t)kUSB_HostGetDeviceHSHubNumber, &hubNumber);
1609 frameInterval = ehciPipePointer->pipeCommon.interval;
1610 SsCsNumber = 3U; /* complete split number */
1611
1612 /* compute start-split and complete-split bandwidth */
1613 if (ehciPipePointer->pipeCommon.direction == USB_OUT)
1614 {
1615 timeStartSplit = (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_OUT,
1616 ehciPipePointer->pipeCommon.maxPacketSize);
1617 timeStartSplit +=
1618 (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_OUT, 1U);
1619 timeCompleteSplit =
1620 (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_OUT, 0U);
1621 }
1622 else
1623 {
1624 timeStartSplit = (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_IN, 1U);
1625 timeCompleteSplit = (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_IN,
1626 ehciPipePointer->pipeCommon.maxPacketSize);
1627 timeCompleteSplit +=
1628 (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_IN, 0U);
1629 }
1630 /* note: bandwidth must put in one frame */
1631 for (uframeIntervalIndex = 0U; uframeIntervalIndex <= 4U; ++uframeIntervalIndex) /* uframe interval */
1632 {
1633 for (frameIntervalIndex = 0U; frameIntervalIndex < frameInterval; ++frameIntervalIndex) /* frame interval */
1634 {
1635 allocateOk = 1U;
1636 for (frameIndex = frameIntervalIndex; frameIndex < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE;
1637 frameIndex += frameInterval) /* check all the frames */
1638 {
1639 /* allocate data bandwidth */
1640 USB_HostBandwidthHsHostComputeCurrentFsls(ehciInstance, hubNumber, frameIndex, frameTimes);
1641 index = (uint8_t)(uframeIntervalIndex + 1U);
1642 for (; index <= (uframeIntervalIndex + 3U); ++index) /* data bandwidth number is 3.
1643 uframeIntervalIndex don't exceed 4, so
1644 index cannot exceed 7 */
1645 {
1646 if (frameTimes[index] + timeData > s_SlotMaxBandwidth[index])
1647 {
1648 allocateOk = 0;
1649 break;
1650 }
1651 }
1652
1653 if (0U != allocateOk)
1654 {
1655 USB_HostBandwidthHsHostComputeCurrentHsAll(ehciInstance, frameIndex, frameTimes);
1656 /* allocate start_split bandwidth */
1657 if (frameTimes[uframeIntervalIndex] + timeStartSplit >
1658 s_SlotMaxBandwidthHs[uframeIntervalIndex])
1659 {
1660 allocateOk = 0U;
1661 }
1662 if (0U != allocateOk)
1663 {
1664 /* allocate complete_split bandwidth */
1665 index = (uint8_t)uframeIntervalIndex + 2U;
1666 /* complete-split number is normal 3. When uframeIntervalIndex is 4, complete-split number
1667 * is 2. */
1668 for (; (index <= (uframeIntervalIndex + 1U + SsCsNumber)) && (index < 8U); ++index)
1669 {
1670 if (frameTimes[index] + timeCompleteSplit > s_SlotMaxBandwidthHs[index])
1671 {
1672 allocateOk = 0U;
1673 break;
1674 }
1675 }
1676 }
1677 }
1678
1679 if (0U == allocateOk)
1680 {
1681 break; /* allocate fail */
1682 }
1683 }
1684 if (0U != allocateOk)
1685 {
1686 break;
1687 }
1688 }
1689 if (0U != allocateOk)
1690 {
1691 break;
1692 }
1693 }
1694
1695 if (0U != allocateOk)
1696 {
1697 ehciPipePointer->startFrame = frameIntervalIndex;
1698 ehciPipePointer->startUframe = (uint8_t)uframeIntervalIndex;
1699 ehciPipePointer->uframeSmask = (0x01u << ehciPipePointer->startUframe);
1700 ehciPipePointer->uframeCmask = 0u;
1701 index = (uint8_t)uframeIntervalIndex + 2u;
1702 for (; (index <= (uframeIntervalIndex + 1u + SsCsNumber)) && (index < 8u); ++index)
1703 {
1704 ehciPipePointer->uframeCmask = ehciPipePointer->uframeCmask | (0x01U << index);
1705 }
1706 ehciPipePointer->dataTime = (uint16_t)timeData;
1707 ehciPipePointer->startSplitTime = timeStartSplit;
1708 ehciPipePointer->completeSplitTime = timeCompleteSplit;
1709
1710 return kStatus_USB_Success;
1711 }
1712 }
1713
1714 return kStatus_USB_BandwidthFail;
1715 }
1716
USB_HostBandwidthFslsHostAllocate(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)1717 static usb_status_t USB_HostBandwidthFslsHostAllocate(usb_host_ehci_instance_t *ehciInstance,
1718 usb_host_ehci_pipe_t *ehciPipePointer)
1719 {
1720 uint32_t FslsTime = 0;
1721 uint32_t speed = 0;
1722 uint16_t uframeIntervalIndex;
1723 uint16_t frameIndex;
1724 uint16_t frameInterval;
1725 uint16_t frameTime;
1726
1727 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
1728 (uint32_t)kUSB_HostGetHubThinkTime, &FslsTime);
1729 FslsTime += (FslsTime * 7U / (6U * 12U));
1730 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
1731 (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
1732 FslsTime = FslsTime + USB_HostBandwidthComputeTime((uint8_t)speed, ehciPipePointer->pipeCommon.pipeType,
1733 ehciPipePointer->pipeCommon.direction,
1734 ehciPipePointer->pipeCommon.maxPacketSize);
1735
1736 frameInterval = ehciPipePointer->pipeCommon.interval;
1737 for (uframeIntervalIndex = 0; uframeIntervalIndex < ehciPipePointer->uframeInterval;
1738 ++uframeIntervalIndex) /* uframeIntervalIndex can exceed 8 */
1739 {
1740 for (frameIndex = (uframeIntervalIndex >> 3); frameIndex < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE;
1741 frameIndex += frameInterval)
1742 {
1743 USB_HostBandwidthFslsHostComputeCurrent(ehciInstance, frameIndex, &frameTime);
1744 if (frameTime + FslsTime > USB_HOST_EHCI_BANDWIDTH_FRAME_TOTOAL_TIME)
1745 {
1746 break;
1747 }
1748 }
1749 if (frameIndex >= USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE)
1750 {
1751 break;
1752 }
1753 }
1754 if (uframeIntervalIndex < ehciPipePointer->uframeInterval)
1755 {
1756 ehciPipePointer->startFrame = (uframeIntervalIndex >> 3);
1757 ehciPipePointer->startUframe = (uint8_t)(uframeIntervalIndex & 0x0007U);
1758 ehciPipePointer->uframeSmask = 0; /* useless */
1759 ehciPipePointer->uframeCmask = 0;
1760 ehciPipePointer->dataTime = (uint16_t)FslsTime;
1761
1762 return kStatus_USB_Success;
1763 }
1764
1765 return kStatus_USB_BandwidthFail;
1766 }
1767
USB_HostEhciGet2PowerValue(uint8_t value)1768 static uint8_t USB_HostEhciGet2PowerValue(uint8_t value)
1769 {
1770 if ((value == 0U) || (value == 1U))
1771 {
1772 return value;
1773 }
1774 if (0U != (value & 0xf0U))
1775 {
1776 if (0U != (value & 0x80U))
1777 {
1778 return 128U;
1779 }
1780 else if (0U != (value & 0x40U))
1781 {
1782 return 64U;
1783 }
1784 else if (0U != (value & 0x20U))
1785 {
1786 return 32U;
1787 }
1788 else
1789 {
1790 return 16U;
1791 }
1792 }
1793 else
1794 {
1795 if (0U != (value & 0x08U))
1796 {
1797 return 8U;
1798 }
1799 else if (0U != (value & 0x04U))
1800 {
1801 return 4U;
1802 }
1803 else if (0U != (value & 0x02U))
1804 {
1805 return 2U;
1806 }
1807 else
1808 {
1809 return 1U;
1810 }
1811 }
1812 }
1813
USB_HostEhciZeroMem(uint32_t * buffer,uint32_t length)1814 static void USB_HostEhciZeroMem(uint32_t *buffer, uint32_t length)
1815 {
1816 /* note: the zero unit is uint32_t */
1817 while (0U != length)
1818 {
1819 length--;
1820 *buffer = 0;
1821 buffer++;
1822 }
1823 }
1824
USB_HostEhciDelay(USBHS_Type * ehciIpBase,uint32_t ms)1825 static void USB_HostEhciDelay(USBHS_Type *ehciIpBase, uint32_t ms)
1826 {
1827 /* note: the max delay time cannot exceed half of max value (0x4000) */
1828 uint32_t sofStart;
1829 uint32_t SofEnd;
1830 uint32_t distance;
1831
1832 sofStart = (ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE);
1833
1834 do
1835 {
1836 SofEnd = (ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE);
1837 distance = (SofEnd + EHCI_MAX_UFRAME_VALUE + 1U - sofStart);
1838 } while ((distance & EHCI_MAX_UFRAME_VALUE) < (ms * 8U)); /* compute the distance between sofStart and SofEnd */
1839 }
1840
USB_HostEhciStartAsync(usb_host_ehci_instance_t * ehciInstance)1841 static void USB_HostEhciStartAsync(usb_host_ehci_instance_t *ehciInstance)
1842 {
1843 uint32_t stateSync;
1844
1845 if (0U == (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK))
1846 {
1847 /* the status must be same when change USBCMD->ASE */
1848 do
1849 {
1850 stateSync = ((ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK) |
1851 (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_ASE_MASK));
1852 } while ((stateSync == USBHS_USBSTS_AS_MASK) || (stateSync == USBHS_USBCMD_ASE_MASK));
1853 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
1854 ehciInstance->ehciIpBase->ASYNCLISTADDR = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(ehciInstance->shedFirstQh);
1855 #else
1856 ehciInstance->ehciIpBase->ASYNCLISTADDR = (uint32_t)(ehciInstance->shedFirstQh);
1857 #endif
1858 ehciInstance->ehciIpBase->USBCMD |= USBHS_USBCMD_ASE_MASK;
1859 while (0U == (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK))
1860 {
1861 }
1862 }
1863 }
1864
USB_HostEhciStopAsync(usb_host_ehci_instance_t * ehciInstance)1865 static void USB_HostEhciStopAsync(usb_host_ehci_instance_t *ehciInstance)
1866 {
1867 uint32_t stateSync;
1868
1869 /* the status must be same when change USBCMD->ASE */
1870 do
1871 {
1872 stateSync = ((ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK) |
1873 (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_ASE_MASK));
1874 } while ((stateSync == USBHS_USBSTS_AS_MASK) || (stateSync == USBHS_USBCMD_ASE_MASK));
1875
1876 ehciInstance->ehciIpBase->USBCMD &= (uint32_t)(~(uint32_t)USBHS_USBCMD_ASE_MASK); /* disable async schedule */
1877 while (0U != (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK))
1878 {
1879 }
1880 }
1881
USB_HostEhciStartPeriodic(usb_host_ehci_instance_t * ehciInstance)1882 static void USB_HostEhciStartPeriodic(usb_host_ehci_instance_t *ehciInstance)
1883 {
1884 uint32_t stateSync;
1885
1886 if (0U == (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_PS_MASK))
1887 {
1888 /* the status must be same when change USBCMD->PSE */
1889 do
1890 {
1891 stateSync = ((ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_PS_MASK) |
1892 (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_PSE_MASK));
1893 } while ((stateSync == USBHS_USBSTS_PS_MASK) || (stateSync == USBHS_USBCMD_PSE_MASK));
1894 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
1895 ehciInstance->ehciIpBase->PERIODICLISTBASE = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(ehciInstance->ehciFrameList);
1896 #else
1897 ehciInstance->ehciIpBase->PERIODICLISTBASE = (uint32_t)(ehciInstance->ehciFrameList);
1898 #endif
1899 if (0U == (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_PSE_MASK))
1900 {
1901 ehciInstance->ehciIpBase->USBCMD |= USBHS_USBCMD_PSE_MASK; /* start periodic schedule */
1902 }
1903 while (0U == (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_PS_MASK))
1904 {
1905 }
1906 }
1907 return;
1908 }
1909
USB_HostEhciStopPeriodic(usb_host_ehci_instance_t * ehciInstance)1910 static void USB_HostEhciStopPeriodic(usb_host_ehci_instance_t *ehciInstance)
1911 {
1912 uint32_t stateSync;
1913
1914 /* the status must be same when change USBCMD->PSE */
1915 do
1916 {
1917 stateSync = ((ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_PS_MASK) |
1918 (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_PSE_MASK));
1919 } while ((stateSync == USBHS_USBSTS_PS_MASK) || (stateSync == USBHS_USBCMD_PSE_MASK));
1920
1921 ehciInstance->ehciIpBase->USBCMD &= (~USBHS_USBCMD_PSE_MASK); /* stop periodic schedule */
1922 while (0U != (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_PS_MASK))
1923 {
1924 }
1925 }
1926
USB_HostEhciQhQtdListInit(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer,usb_host_transfer_t * transfer)1927 static usb_status_t USB_HostEhciQhQtdListInit(usb_host_ehci_instance_t *ehciInstance,
1928 usb_host_ehci_pipe_t *ehciPipePointer,
1929 usb_host_transfer_t *transfer)
1930 {
1931 volatile usb_host_ehci_qh_t *vltQhPointer;
1932 usb_host_ehci_qtd_t *qtdPointer = NULL;
1933 usb_host_ehci_qtd_t *BaseQtdPointer = NULL;
1934 volatile uint32_t *entryPointer;
1935 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
1936 uint32_t convert_addr = 0U;
1937 #endif
1938 uint32_t qtdNumber;
1939 uint32_t dataLength;
1940 uint32_t dataAddress;
1941 uint32_t endAddress;
1942 uint8_t index;
1943
1944 /* compute the qtd number */
1945 if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_CONTROL)
1946 {
1947 /* assume setup data don't exceed one qtd data size, one qtd can transfer least 16k data */
1948 if (transfer->transferLength == 0U)
1949 {
1950 qtdNumber = 2U;
1951 }
1952 else
1953 {
1954 qtdNumber = 3U;
1955 }
1956 }
1957 else
1958 {
1959 qtdNumber = (((transfer->transferLength) & 0xFFFFC000U) >> 14U) +
1960 (0U != ((transfer->transferLength) & 0x00003FFFU) ? 1U : 0U);
1961 if (0U == qtdNumber)
1962 {
1963 qtdNumber = 1U;
1964 }
1965 }
1966
1967 vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
1968 /* get qtd list */
1969 USB_HostEhciLock();
1970 if (qtdNumber <= ehciInstance->ehciQtdNumber)
1971 {
1972 ehciInstance->ehciQtdNumber -= (uint8_t)qtdNumber;
1973 BaseQtdPointer = ehciInstance->ehciQtdHead;
1974 qtdPointer = NULL;
1975 do
1976 {
1977 if (qtdPointer != NULL)
1978 {
1979 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
1980 qtdPointer->nextQtdPointer = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(ehciInstance->ehciQtdHead);
1981 #else
1982 qtdPointer->nextQtdPointer = (uint32_t)ehciInstance->ehciQtdHead;
1983 #endif
1984 }
1985 qtdPointer = ehciInstance->ehciQtdHead;
1986 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
1987 ehciInstance->ehciQtdHead = (usb_host_ehci_qtd_t *)USB_HOST_MEMORY_DMA_2_CPU(qtdPointer->nextQtdPointer);
1988 #else
1989 ehciInstance->ehciQtdHead = (usb_host_ehci_qtd_t *)qtdPointer->nextQtdPointer;
1990 #endif
1991 qtdPointer->nextQtdPointer = 0;
1992 --qtdNumber;
1993 } while (0U != qtdNumber);
1994 if (ehciInstance->ehciQtdNumber == 0U)
1995 {
1996 ehciInstance->ehciQtdTail = NULL;
1997 }
1998 }
1999 else
2000 {
2001 USB_HostEhciUnlock();
2002 return kStatus_USB_Error;
2003 }
2004 USB_HostEhciUnlock();
2005
2006 /* int qTD list */
2007 if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_CONTROL)
2008 {
2009 /* setup transaction qtd */
2010 qtdPointer = BaseQtdPointer;
2011 qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
2012 /* dt: need set; ioc: 0; C_Page: 0; PID Code: SETUP; Status: Active */
2013 qtdPointer->transferResults[1] = 0U;
2014 qtdPointer->transferResults[0] =
2015 ((0x00000000UL << EHCI_HOST_QTD_DT_SHIFT) | (8UL << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
2016 (EHCI_HOST_PID_SETUP << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
2017 dataAddress = ((uint32_t)transfer->setupPacket);
2018 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2019 convert_addr = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(dataAddress);
2020 qtdPointer->transferResults[1] = convert_addr; /* current offset is set too */
2021 #else
2022 qtdPointer->transferResults[1] = dataAddress; /* current offset is set too */
2023 #endif
2024
2025 /* set buffer pointer no matter data length */
2026 for (index = 0; index < 4U; ++index)
2027 {
2028 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2029 qtdPointer->bufferPointers[index] = ((convert_addr + ((uint32_t)index + 1U) * 4U * 1024U) & 0xFFFFF000U);
2030 #else
2031 qtdPointer->bufferPointers[index] = ((dataAddress + ((uint32_t)index + 1U) * 4U * 1024U) & 0xFFFFF000U);
2032 #endif
2033 }
2034
2035 /* data transaction qtd */
2036 dataLength = transfer->transferLength;
2037 if (dataLength != 0U)
2038 {
2039 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2040 qtdPointer = (usb_host_ehci_qtd_t *)USB_HOST_MEMORY_DMA_2_CPU(qtdPointer->nextQtdPointer);
2041 #else
2042 qtdPointer = (usb_host_ehci_qtd_t *)(qtdPointer->nextQtdPointer);
2043 #endif
2044 qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
2045 /* dt: need set; ioc: 0; C_Page: 0; PID Code: IN/OUT; Status: Active */
2046 qtdPointer->transferResults[1] = 0U;
2047 if (transfer->direction == USB_OUT)
2048 {
2049 qtdPointer->transferResults[0] =
2050 ((0x00000001UL << EHCI_HOST_QTD_DT_SHIFT) | (dataLength << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
2051 (EHCI_HOST_PID_OUT << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
2052 }
2053 else
2054 {
2055 qtdPointer->transferResults[0] =
2056 ((0x00000001U << EHCI_HOST_QTD_DT_SHIFT) | (dataLength << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
2057 (EHCI_HOST_PID_IN << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
2058 }
2059
2060 dataAddress = (uint32_t)transfer->transferBuffer;
2061 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2062 convert_addr = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(dataAddress);
2063 qtdPointer->transferResults[1] = convert_addr; /* current offset is set too */
2064 #else
2065 qtdPointer->transferResults[1] = dataAddress; /* current offset is set too */
2066 #endif
2067 /* set buffer pointer no matter data length */
2068 for (index = 0; index < 4U; ++index)
2069 {
2070 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2071 qtdPointer->bufferPointers[index] =
2072 ((convert_addr + ((uint32_t)index + 1U) * 4U * 1024U) & 0xFFFFF000U);
2073 #else
2074 qtdPointer->bufferPointers[index] = ((dataAddress + ((uint32_t)index + 1U) * 4U * 1024U) & 0xFFFFF000U);
2075 #endif
2076 }
2077 }
2078 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2079 /* status transaction qtd */
2080 qtdPointer = (usb_host_ehci_qtd_t *)USB_HOST_MEMORY_DMA_2_CPU(qtdPointer->nextQtdPointer);
2081 #else
2082 /* status transaction qtd */
2083 qtdPointer = (usb_host_ehci_qtd_t *)(qtdPointer->nextQtdPointer);
2084 #endif
2085 qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
2086 /* dt: dont care; ioc: 1; C_Page: 0; PID Code: IN/OUT; Status: Active */
2087 qtdPointer->transferResults[1] = 0;
2088 if ((dataLength == 0U) || (transfer->direction == USB_OUT))
2089 {
2090 qtdPointer->transferResults[0] =
2091 ((0x00000001UL << EHCI_HOST_QTD_DT_SHIFT) | (EHCI_HOST_PID_IN << EHCI_HOST_QTD_PID_CODE_SHIFT) |
2092 (EHCI_HOST_QTD_IOC_MASK) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
2093 }
2094 else
2095 {
2096 qtdPointer->transferResults[0] =
2097 ((0x00000001U << EHCI_HOST_QTD_DT_SHIFT) | (EHCI_HOST_PID_OUT << EHCI_HOST_QTD_PID_CODE_SHIFT) |
2098 (EHCI_HOST_QTD_IOC_MASK) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
2099 }
2100 qtdPointer->nextQtdPointer |= EHCI_HOST_T_INVALID_VALUE;
2101 }
2102 else
2103 {
2104 dataAddress = (uint32_t)transfer->transferBuffer;
2105 qtdPointer = BaseQtdPointer;
2106 while (1U == 1U)
2107 {
2108 endAddress = dataAddress + (16U * 1024U);
2109 if (endAddress > (uint32_t)(transfer->transferBuffer + transfer->transferLength))
2110 {
2111 endAddress = (uint32_t)(transfer->transferBuffer + transfer->transferLength);
2112 }
2113
2114 qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
2115 /* dt: set; ioc: 0; C_Page: 0; PID Code: IN/OUT; Status: Active */
2116 qtdPointer->transferResults[1] = 0U;
2117 if (transfer->direction == USB_OUT)
2118 {
2119 qtdPointer->transferResults[0] =
2120 (((endAddress - dataAddress) << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
2121 ((uint32_t)ehciPipePointer->pipeCommon.nextdata01 << EHCI_HOST_QTD_DT_SHIFT) |
2122 (EHCI_HOST_QTD_CERR_MAX_VALUE << EHCI_HOST_QTD_CERR_SHIFT) |
2123 (EHCI_HOST_PID_OUT << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
2124 }
2125 else
2126 {
2127 qtdPointer->transferResults[0] =
2128 (((endAddress - dataAddress) << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
2129 ((uint32_t)ehciPipePointer->pipeCommon.nextdata01 << EHCI_HOST_QTD_DT_SHIFT) |
2130 (EHCI_HOST_QTD_CERR_MAX_VALUE << EHCI_HOST_QTD_CERR_SHIFT) |
2131 (EHCI_HOST_PID_IN << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
2132 }
2133 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2134 convert_addr = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(dataAddress);
2135 qtdPointer->transferResults[1] = convert_addr; /* current offset is set too */
2136 #else
2137 qtdPointer->transferResults[1] = dataAddress; /* current offset is set too */
2138 #endif
2139 /* set buffer pointer no matter data length */
2140 for (index = 0; index < 4U; ++index)
2141 {
2142 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2143 qtdPointer->bufferPointers[index] =
2144 ((convert_addr + ((uint32_t)index + 1U) * 4U * 1024U) & 0xFFFFF000U);
2145 #else
2146 qtdPointer->bufferPointers[index] = ((dataAddress + ((uint32_t)index + 1U) * 4U * 1024U) & 0xFFFFF000U);
2147 #endif
2148 }
2149 dataAddress = endAddress; /* for next qtd */
2150
2151 if (qtdPointer->nextQtdPointer == 0U)
2152 {
2153 break;
2154 }
2155 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2156 qtdPointer = (usb_host_ehci_qtd_t *)USB_HOST_MEMORY_DMA_2_CPU(qtdPointer->nextQtdPointer);
2157 #else
2158 qtdPointer = (usb_host_ehci_qtd_t *)(qtdPointer->nextQtdPointer);
2159 #endif
2160 }
2161
2162 qtdPointer->nextQtdPointer |= EHCI_HOST_T_INVALID_VALUE;
2163 qtdPointer->transferResults[0] |= EHCI_HOST_QTD_IOC_MASK; /* last one set IOC */
2164 }
2165
2166 /* save qtd to transfer */
2167 transfer->union1.unitHead = (uint32_t)BaseQtdPointer;
2168 transfer->union2.unitTail = (uint32_t)qtdPointer;
2169 /* link transfer to qh */
2170 transfer->next = NULL;
2171 if (vltQhPointer->ehciTransferHead == NULL)
2172 {
2173 transfer->next = NULL;
2174 vltQhPointer->ehciTransferTail = transfer;
2175 vltQhPointer->ehciTransferHead = transfer;
2176 }
2177 else
2178 {
2179 transfer->next = NULL;
2180 vltQhPointer->ehciTransferTail->next = transfer;
2181 vltQhPointer->ehciTransferTail = transfer;
2182 }
2183
2184 USB_HostEhciLock();
2185 /* link qtd to qh (link to end) */
2186 entryPointer = &(vltQhPointer->nextQtdPointer);
2187 dataAddress = *entryPointer; /* dataAddress variable means entry value here */
2188 while ((0U != dataAddress) && (0U == (dataAddress & EHCI_HOST_T_INVALID_VALUE)))
2189 {
2190 entryPointer = (volatile uint32_t *)dataAddress;
2191 dataAddress = *entryPointer;
2192 }
2193 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2194 *entryPointer = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(BaseQtdPointer);
2195 #else
2196 *entryPointer = (uint32_t)BaseQtdPointer;
2197 #endif
2198 USB_HostEhciStartAsync(ehciInstance);
2199 USB_HostEhciUnlock();
2200
2201 return kStatus_USB_Success;
2202 }
2203
USB_HostEhciQtdListRelease(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_qtd_t * ehciQtdStart,usb_host_ehci_qtd_t * ehciQtdEnd)2204 static uint32_t USB_HostEhciQtdListRelease(usb_host_ehci_instance_t *ehciInstance,
2205 usb_host_ehci_qtd_t *ehciQtdStart,
2206 usb_host_ehci_qtd_t *ehciQtdEnd)
2207 {
2208 uint32_t length = 0;
2209 usb_host_ehci_qtd_t *qtdPointer;
2210
2211 ehciQtdEnd->nextQtdPointer = 0U;
2212
2213 /* compute remaining length */
2214 qtdPointer = ehciQtdStart;
2215 while (qtdPointer != ehciQtdEnd)
2216 {
2217 length +=
2218 ((qtdPointer->transferResults[0] & EHCI_HOST_QTD_TOTAL_BYTES_MASK) >> EHCI_HOST_QTD_TOTAL_BYTES_SHIFT);
2219 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2220 qtdPointer = (usb_host_ehci_qtd_t *)USB_HOST_MEMORY_DMA_2_CPU(qtdPointer->nextQtdPointer);
2221 #else
2222 qtdPointer = (usb_host_ehci_qtd_t *)qtdPointer->nextQtdPointer;
2223 #endif
2224 }
2225 qtdPointer = ehciQtdEnd;
2226 length += ((qtdPointer->transferResults[0] & EHCI_HOST_QTD_TOTAL_BYTES_MASK) >> EHCI_HOST_QTD_TOTAL_BYTES_SHIFT);
2227
2228 /* put releasing qtd to idle qtd list */
2229 USB_HostEhciLock();
2230 if (ehciInstance->ehciQtdNumber == 0U)
2231 {
2232 ehciInstance->ehciQtdHead = ehciQtdStart;
2233 ehciInstance->ehciQtdTail = ehciQtdEnd;
2234 }
2235 else
2236 {
2237 ehciInstance->ehciQtdTail->nextQtdPointer = (uint32_t)ehciQtdStart;
2238 ehciInstance->ehciQtdTail = ehciQtdEnd;
2239 }
2240
2241 while (ehciQtdStart != ehciQtdEnd)
2242 {
2243 ehciInstance->ehciQtdNumber++;
2244 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2245 ehciQtdStart = (usb_host_ehci_qtd_t *)USB_HOST_MEMORY_DMA_2_CPU(ehciQtdStart->nextQtdPointer);
2246 #else
2247 ehciQtdStart = (usb_host_ehci_qtd_t *)ehciQtdStart->nextQtdPointer;
2248 #endif
2249 }
2250 ehciInstance->ehciQtdNumber++;
2251 USB_HostEhciUnlock();
2252
2253 return length;
2254 }
2255
USB_HostEhciQhQtdListDeinit(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)2256 static usb_status_t USB_HostEhciQhQtdListDeinit(usb_host_ehci_instance_t *ehciInstance,
2257 usb_host_ehci_pipe_t *ehciPipePointer)
2258 {
2259 volatile usb_host_ehci_qh_t *vltQhPointer;
2260 usb_host_transfer_t *transfer;
2261 usb_host_transfer_t *nextTransfer;
2262 uint32_t currentQtdPointer;
2263 uint8_t needStop = 0U;
2264 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2265 uint32_t convert_addr = 0U;
2266 #endif
2267
2268 vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
2269
2270 USB_HostEhciLock(); /* this API is called from APP, the host task may occupy to access the same resource */
2271 /* remove qtd from qh */
2272 /*for misra 13.5*/
2273 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2274 currentQtdPointer = (uint32_t)USB_HOST_MEMORY_DMA_2_CPU(vltQhPointer->currentQtdPointer);
2275 #else
2276 currentQtdPointer = vltQhPointer->currentQtdPointer;
2277 #endif
2278
2279 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2280 convert_addr = (uint32_t)USB_HOST_MEMORY_DMA_2_CPU(vltQhPointer->nextQtdPointer);
2281 if ((0U == ((uint32_t)convert_addr & EHCI_HOST_T_INVALID_VALUE)) ||
2282 #else
2283 if ((0U == ((uint32_t)vltQhPointer->nextQtdPointer & EHCI_HOST_T_INVALID_VALUE)) ||
2284 #endif
2285 (0U == ((uint32_t)currentQtdPointer & EHCI_HOST_T_INVALID_VALUE)))
2286 {
2287 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2288 convert_addr = (uint32_t)USB_HOST_MEMORY_DMA_2_CPU(vltQhPointer->horizontalLinkPointer);
2289 /* need stop async schedule */
2290 if ((0U == (convert_addr & EHCI_HOST_T_INVALID_VALUE)) &&
2291 #else
2292 /* need stop async schedule */
2293 if ((0U == (vltQhPointer->horizontalLinkPointer & EHCI_HOST_T_INVALID_VALUE)) &&
2294 #endif
2295 (ehciPipePointer->pipeCommon.pipeType != USB_ENDPOINT_INTERRUPT))
2296 {
2297 needStop = 1U;
2298 }
2299 if (0U != needStop)
2300 {
2301 USB_HostEhciStopAsync(ehciInstance);
2302 }
2303 vltQhPointer->currentQtdPointer = EHCI_HOST_T_INVALID_VALUE; /* invalid current qtd */
2304 vltQhPointer->nextQtdPointer = EHCI_HOST_T_INVALID_VALUE; /* invalid next qtd */
2305 vltQhPointer->transferOverlayResults[0] &= (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
2306 if (0U != needStop)
2307 {
2308 USB_HostEhciStartAsync(ehciInstance);
2309 }
2310 }
2311
2312 /* remove transfer from the QH transfer list */
2313 transfer = vltQhPointer->ehciTransferHead;
2314 vltQhPointer->ehciTransferTail = NULL;
2315 vltQhPointer->ehciTransferHead = NULL;
2316 USB_HostEhciUnlock();
2317
2318 /* release qtd and transfer callback*/
2319 while (transfer != NULL)
2320 {
2321 nextTransfer = transfer->next; /* the transfer is released when call back */
2322 transfer->transferSofar =
2323 USB_HostEhciQtdListRelease(ehciInstance, (usb_host_ehci_qtd_t *)(transfer->union1.unitHead),
2324 (usb_host_ehci_qtd_t *)(transfer->union2.unitTail));
2325 transfer->transferSofar = (transfer->transferLength < transfer->transferSofar) ?
2326 0U :
2327 (transfer->transferLength - transfer->transferSofar);
2328 /* callback function is different from the current condition */
2329 transfer->callbackFn(transfer->callbackParam, transfer, kStatus_USB_TransferCancel);
2330 transfer = nextTransfer;
2331 }
2332
2333 return kStatus_USB_Success;
2334 }
2335
USB_HostEhciTransferQtdListDeinit(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer,usb_host_transfer_t * transfer)2336 static usb_status_t USB_HostEhciTransferQtdListDeinit(usb_host_ehci_instance_t *ehciInstance,
2337 usb_host_ehci_pipe_t *ehciPipePointer,
2338 usb_host_transfer_t *transfer)
2339 {
2340 volatile usb_host_ehci_qh_t *vltQhPointer;
2341 usb_host_transfer_t *preSearchTransfer;
2342 uint32_t qhNextQtdValue;
2343 uint32_t qtdPointerEntry;
2344 uint32_t *searchQtdEntryPointer;
2345
2346 vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
2347
2348 USB_HostEhciLock(); /* this API is called from APP, the host task may occupy to access the same resource */
2349 /* remove qtd from qh */
2350 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2351 qhNextQtdValue = (uint32_t)USB_HOST_MEMORY_DMA_2_CPU(vltQhPointer->currentQtdPointer);
2352 #else
2353 qhNextQtdValue = (uint32_t)vltQhPointer->currentQtdPointer;
2354 #endif
2355
2356 qtdPointerEntry = *((uint32_t *)qhNextQtdValue + 2); /* note: qtdPointerEntry means qtd status */
2357 if ((0U != (qhNextQtdValue & EHCI_HOST_T_INVALID_VALUE)) ||
2358 (0U == (qtdPointerEntry & EHCI_HOST_QTD_STATUS_ACTIVE_MASK)))
2359 {
2360 qhNextQtdValue = (uint32_t)vltQhPointer->nextQtdPointer;
2361 }
2362 if (0U == (qhNextQtdValue & EHCI_HOST_T_INVALID_VALUE)) /* there is pending qtd in the qh */
2363 {
2364 /* this qh don't schedule temporarily */
2365 if (ehciPipePointer->pipeCommon.pipeType != USB_ENDPOINT_INTERRUPT)
2366 {
2367 USB_HostEhciStopAsync(ehciInstance);
2368 }
2369 vltQhPointer->currentQtdPointer |= EHCI_HOST_T_INVALID_VALUE; /* invalid current qtd */
2370 vltQhPointer->nextQtdPointer |= EHCI_HOST_T_INVALID_VALUE; /* invalid next qtd */
2371 if (ehciPipePointer->pipeCommon.pipeType != USB_ENDPOINT_INTERRUPT)
2372 {
2373 USB_HostEhciStartAsync(ehciInstance);
2374 }
2375
2376 /* remove qtd from qh one by one */
2377 qtdPointerEntry = transfer->union1.unitHead;
2378 while (1U == 1U)
2379 {
2380 /* search qh's qtd list for qtdPointerEntry */
2381 searchQtdEntryPointer = &qhNextQtdValue;
2382 while (0U == ((*searchQtdEntryPointer) & EHCI_HOST_T_INVALID_VALUE))
2383 {
2384 if ((*searchQtdEntryPointer) == qtdPointerEntry)
2385 {
2386 *searchQtdEntryPointer = *((uint32_t *)qtdPointerEntry); /* remove the qtd from qh */
2387 break;
2388 }
2389 else
2390 {
2391 searchQtdEntryPointer = (uint32_t *)(*searchQtdEntryPointer);
2392 }
2393 }
2394 if (qtdPointerEntry == transfer->union2.unitTail)
2395 {
2396 break;
2397 }
2398 qtdPointerEntry = *((uint32_t *)qtdPointerEntry);
2399 }
2400 }
2401
2402 /* remove transfer from the QH transfer list */
2403 preSearchTransfer = vltQhPointer->ehciTransferHead;
2404 if (preSearchTransfer == transfer)
2405 {
2406 vltQhPointer->ehciTransferHead = preSearchTransfer->next;
2407 }
2408 else
2409 {
2410 while (preSearchTransfer != NULL)
2411 {
2412 if (preSearchTransfer->next == transfer)
2413 {
2414 preSearchTransfer->next = transfer->next;
2415 break;
2416 }
2417 else
2418 {
2419 preSearchTransfer = preSearchTransfer->next;
2420 }
2421 }
2422 }
2423 USB_HostEhciUnlock();
2424
2425 /* release qtd and callback */
2426 transfer->transferSofar =
2427 USB_HostEhciQtdListRelease(ehciInstance, (usb_host_ehci_qtd_t *)(transfer->union1.unitHead),
2428 (usb_host_ehci_qtd_t *)(transfer->union2.unitTail));
2429 transfer->transferSofar = (transfer->transferLength < transfer->transferSofar) ?
2430 0U :
2431 (transfer->transferLength - transfer->transferSofar);
2432 /* callback function is different from the current condition */
2433 transfer->callbackFn(transfer->callbackParam, transfer, kStatus_USB_TransferCancel);
2434
2435 /* start this qh schedule */
2436 vltQhPointer->transferOverlayResults[0] &= (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
2437 if ((qhNextQtdValue != 0U) && (0U == (qhNextQtdValue & EHCI_HOST_T_INVALID_VALUE)))
2438 {
2439 vltQhPointer->nextQtdPointer = qhNextQtdValue;
2440 }
2441
2442 return kStatus_USB_Success;
2443 }
2444
USB_HostEhciQhInit(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)2445 static usb_status_t USB_HostEhciQhInit(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer)
2446 {
2447 usb_host_ehci_qh_t *qhPointer = NULL;
2448 uint32_t address = 0;
2449 uint32_t speed = 0;
2450 uint32_t portNumber = 0;
2451 uint32_t hubNumber = 0;
2452 ;
2453 uint32_t controlBits1 = 0U;
2454 uint32_t controlBits2 = 0U;
2455
2456 /* get qh */
2457 USB_HostEhciLock();
2458 if (ehciInstance->ehciQhList != NULL)
2459 {
2460 qhPointer = (usb_host_ehci_qh_t *)ehciInstance->ehciQhList;
2461 ehciInstance->ehciQhList =
2462 (usb_host_ehci_qh_t *)(ehciInstance->ehciQhList->horizontalLinkPointer & EHCI_HOST_POINTER_ADDRESS_MASK);
2463 }
2464 USB_HostEhciUnlock();
2465 if (qhPointer == NULL)
2466 {
2467 #ifdef HOST_EHCO
2468 usb_echo("get qh error\r\n");
2469 #endif
2470 return kStatus_USB_Error;
2471 }
2472 ehciPipePointer->ehciQh = (void *)qhPointer;
2473
2474 /* initialize qh */
2475 USB_HostEhciZeroMem((void *)qhPointer, sizeof(usb_host_ehci_qh_t) / 4U);
2476 qhPointer->horizontalLinkPointer = EHCI_HOST_T_INVALID_VALUE;
2477 qhPointer->currentQtdPointer = EHCI_HOST_T_INVALID_VALUE;
2478 qhPointer->nextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
2479 qhPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
2480 qhPointer->ehciPipePointer = ehciPipePointer;
2481 qhPointer->timeOutLabel = 0;
2482 qhPointer->timeOutValue = USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE;
2483 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
2484 (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
2485 /* initialize staticEndpointStates[0] */
2486 if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT)
2487 {
2488 /* Software should set the RL field to zero if the queue head is an interrupt endpoint. */
2489 controlBits1 |= ((0UL << EHCI_HOST_QH_RL_SHIFT) & EHCI_HOST_QH_RL_MASK);
2490 }
2491 else
2492 {
2493 if (ehciPipePointer->pipeCommon.nakCount >= 16U)
2494 {
2495 controlBits1 |= ((15UL << EHCI_HOST_QH_RL_SHIFT) & EHCI_HOST_QH_RL_MASK);
2496 }
2497 else
2498 {
2499 controlBits1 |=
2500 (((uint32_t)ehciPipePointer->pipeCommon.nakCount << EHCI_HOST_QH_RL_SHIFT) & EHCI_HOST_QH_RL_MASK);
2501 }
2502 }
2503 if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_CONTROL)
2504 {
2505 if (speed != USB_SPEED_HIGH)
2506 {
2507 controlBits1 |= (1UL << EHCI_HOST_QH_C_SHIFT);
2508 }
2509 controlBits1 |= (1UL << EHCI_HOST_QH_DTC_SHIFT);
2510 }
2511 controlBits1 |= ((uint32_t)ehciPipePointer->pipeCommon.maxPacketSize << EHCI_HOST_QH_MAX_PACKET_LENGTH_SHIFT);
2512 controlBits1 |= (speed << EHCI_HOST_QH_EPS_SHIFT);
2513 controlBits1 |= ((uint32_t)ehciPipePointer->pipeCommon.endpointAddress << EHCI_HOST_QH_ENDPT_SHIFT);
2514 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
2515 (uint32_t)kUSB_HostGetDeviceAddress, &address);
2516 controlBits1 |= (address << EHCI_HOST_QH_DEVICE_ADDRESS_SHIFT);
2517 qhPointer->staticEndpointStates[0] = controlBits1;
2518 if (speed == USB_SPEED_HIGH)
2519 {
2520 controlBits2 |= ((uint32_t)ehciPipePointer->pipeCommon.numberPerUframe << EHCI_HOST_QH_MULT_SHIFT);
2521 }
2522 else
2523 {
2524 controlBits2 |= (0x00000001UL << EHCI_HOST_QH_MULT_SHIFT);
2525 }
2526 /*initialize staticEndpointStates[1] */
2527 if (speed != USB_SPEED_HIGH)
2528 {
2529 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
2530 (uint32_t)kUSB_HostGetDeviceHSHubNumber, &hubNumber);
2531 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
2532 (uint32_t)kUSB_HostGetDeviceHSHubPort, &portNumber);
2533 }
2534 else
2535 {
2536 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
2537 (uint32_t)kUSB_HostGetDeviceHubNumber, &hubNumber);
2538 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
2539 (uint32_t)kUSB_HostGetDevicePortNumber, &portNumber);
2540 }
2541 controlBits2 |= (portNumber << EHCI_HOST_QH_PORT_NUMBER_SHIFT);
2542 controlBits2 |= (hubNumber << EHCI_HOST_QH_HUB_ADDR_SHIFT);
2543 controlBits2 |= ((uint32_t)ehciPipePointer->uframeCmask << EHCI_HOST_QH_UFRAME_CMASK_SHIFT);
2544 controlBits2 |= ((uint32_t)ehciPipePointer->uframeSmask << EHCI_HOST_QH_UFRAME_SMASK_SHIFT);
2545 qhPointer->staticEndpointStates[1] = controlBits2;
2546
2547 return kStatus_USB_Success;
2548 }
2549
USB_HostEhciQhDeinit(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)2550 static usb_status_t USB_HostEhciQhDeinit(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer)
2551 {
2552 usb_host_ehci_qh_t *qhPointer;
2553
2554 qhPointer = (usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
2555 /* de-initialize qtd from qh */
2556 (void)USB_HostEhciQhQtdListDeinit(ehciInstance, ehciPipePointer);
2557
2558 /* release QH */
2559 USB_HostEhciLock();
2560 qhPointer->horizontalLinkPointer = (uint32_t)ehciInstance->ehciQhList;
2561 ehciInstance->ehciQhList = qhPointer;
2562 USB_HostEhciUnlock();
2563
2564 return kStatus_USB_Success;
2565 }
2566
USB_HostEhciAddQhToFrame(usb_host_ehci_instance_t * ehciInstance,uint32_t entryPointerValue,uint16_t framePos,uint16_t uframeInterval)2567 static void USB_HostEhciAddQhToFrame(usb_host_ehci_instance_t *ehciInstance,
2568 uint32_t entryPointerValue,
2569 uint16_t framePos,
2570 uint16_t uframeInterval)
2571 {
2572 volatile uint32_t *frameEntryPointer;
2573 uint32_t frameEntryValue;
2574 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2575 uint32_t convert_addr = 0U;
2576 #endif
2577 void *temp;
2578
2579 /* search for the inserting point by interval */
2580 temp = (void *)ehciInstance->ehciFrameList;
2581 frameEntryPointer = (volatile uint32_t *)(&((uint32_t *)temp)[framePos]);
2582 while (NULL != frameEntryPointer)
2583 {
2584 frameEntryValue = *frameEntryPointer;
2585 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2586 frameEntryValue = (uint32_t)USB_HOST_MEMORY_DMA_2_CPU(frameEntryValue);
2587 #endif
2588 if (0U != (frameEntryValue & EHCI_HOST_T_INVALID_VALUE))
2589 {
2590 /* insert into the end */
2591 *((uint32_t *)entryPointerValue) = EHCI_HOST_T_INVALID_VALUE;
2592 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2593 convert_addr = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(entryPointerValue);
2594 *frameEntryPointer = (convert_addr | EHCI_HOST_POINTER_TYPE_QH);
2595 #else
2596 *frameEntryPointer = (entryPointerValue | EHCI_HOST_POINTER_TYPE_QH);
2597 #endif
2598 break;
2599 }
2600
2601 if ((frameEntryValue & EHCI_HOST_POINTER_ADDRESS_MASK) == entryPointerValue)
2602 {
2603 return; /* has inserted */
2604 }
2605 if (((frameEntryValue & EHCI_HOST_POINTER_TYPE_MASK) == EHCI_HOST_POINTER_TYPE_QH) &&
2606 (((usb_host_ehci_qh_t *)(frameEntryValue & EHCI_HOST_POINTER_ADDRESS_MASK))
2607 ->ehciPipePointer->uframeInterval <= uframeInterval))
2608 {
2609 /* insert into this point */
2610 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2611 frameEntryValue = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(frameEntryValue);
2612 #endif
2613 *((uint32_t *)entryPointerValue) = frameEntryValue;
2614 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2615 convert_addr = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(entryPointerValue);
2616 *frameEntryPointer = (convert_addr | EHCI_HOST_POINTER_TYPE_QH);
2617 #else
2618 *frameEntryPointer = (entryPointerValue | EHCI_HOST_POINTER_TYPE_QH);
2619 #endif
2620 return;
2621 }
2622 else
2623 {
2624 frameEntryPointer = (volatile uint32_t *)(frameEntryValue & EHCI_HOST_POINTER_ADDRESS_MASK);
2625 }
2626 }
2627 }
2628
USB_HostEhciRemoveFromFrame(usb_host_ehci_instance_t * ehciInstance,uint32_t entryPointerValue,uint16_t framePos)2629 static void USB_HostEhciRemoveFromFrame(usb_host_ehci_instance_t *ehciInstance,
2630 uint32_t entryPointerValue,
2631 uint16_t framePos)
2632 {
2633 volatile uint32_t *frameEntryPointer;
2634 uint32_t frameEntryValue;
2635 void *temp;
2636 /* search for the qh/itd/sitd entry */
2637 temp = (void *)ehciInstance->ehciFrameList;
2638 frameEntryPointer = (volatile uint32_t *)(&((uint32_t *)temp)[framePos]);
2639
2640 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2641 frameEntryPointer = (volatile uint32_t *)USB_HOST_MEMORY_DMA_2_CPU(frameEntryPointer);
2642 #endif
2643
2644 while (NULL != frameEntryPointer)
2645 {
2646 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2647 frameEntryValue = *((uint32_t *)frameEntryPointer);
2648 frameEntryValue = (uint32_t)USB_HOST_MEMORY_DMA_2_CPU(frameEntryValue);
2649 #else
2650 frameEntryValue = *frameEntryPointer;
2651 #endif
2652 if (0U != (frameEntryValue & EHCI_HOST_T_INVALID_VALUE))
2653 {
2654 return;
2655 }
2656
2657 if ((frameEntryValue & EHCI_HOST_POINTER_ADDRESS_MASK) == entryPointerValue)
2658 {
2659 /* remove the entry */
2660 *frameEntryPointer = *((uint32_t *)entryPointerValue);
2661 break;
2662 }
2663 else
2664 {
2665 frameEntryPointer = (volatile uint32_t *)(frameEntryValue & EHCI_HOST_POINTER_ADDRESS_MASK);
2666 }
2667 }
2668 }
2669
2670 #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
USB_HostEhciLinkSitd(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer,void * startEntryPointer)2671 static void USB_HostEhciLinkSitd(usb_host_ehci_instance_t *ehciInstance,
2672 usb_host_ehci_pipe_t *ehciPipePointer,
2673 void *startEntryPointer)
2674 {
2675 usb_host_ehci_iso_t *isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
2676 usb_host_ehci_sitd_t *sitdPointer;
2677 uint32_t distance;
2678 uint32_t frameInterval;
2679 uint32_t shouldLinkFrame;
2680 uint32_t currentFrame;
2681 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2682 uint32_t convert_addr = 0U;
2683 #endif
2684 void *temp;
2685
2686 frameInterval = ((uint32_t)ehciPipePointer->uframeInterval >> 3U);
2687
2688 if (isoPointer->lastLinkFrame == 0xFFFFU) /* first link */
2689 {
2690 currentFrame = ((ehciInstance->ehciIpBase->FRINDEX & USB_HOST_EHCI_MAX_MICRFRAME_VALUE) >> 3U);
2691 currentFrame = ((uint32_t)(currentFrame + USB_HOST_EHCI_ISO_BOUNCE_FRAME_NUMBER) &
2692 (USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3U)); /* add USB_HOST_EHCI_ISO_BOUNCE_FRAME_NUMBER */
2693 /* frame should align with interval */
2694 if (currentFrame <= ehciPipePointer->startFrame)
2695 {
2696 currentFrame = ehciPipePointer->startFrame;
2697 }
2698 else
2699 {
2700 currentFrame -= ehciPipePointer->startFrame;
2701 currentFrame = ((currentFrame + frameInterval - 1U) & (~(frameInterval - 1U)));
2702 currentFrame += ehciPipePointer->startFrame;
2703 }
2704 }
2705 else
2706 {
2707 shouldLinkFrame = isoPointer->lastLinkFrame + frameInterval; /* continuous next should link frame */
2708 if (shouldLinkFrame > USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3U)
2709 {
2710 shouldLinkFrame = shouldLinkFrame - ((USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3U) + 1U);
2711 }
2712 currentFrame = ((ehciInstance->ehciIpBase->FRINDEX & USB_HOST_EHCI_MAX_MICRFRAME_VALUE) >> 3U);
2713 distance =
2714 ((shouldLinkFrame + (USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3U) + 1U - currentFrame) &
2715 (USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3)); /* get the distance from shouldLinkFrame to currentFrame */
2716 /* shouldLinkFrame has add frameInterval, think about the align with interval, so here add (frameInterval *
2717 * 2) */
2718 if ((distance <=
2719 (USB_HOST_EHCI_ISO_BOUNCE_FRAME_NUMBER + frameInterval * USB_HOST_EHCI_ISO_MAX_CONTINUOUS_TRANSFER)) &&
2720 (distance > 0U))
2721 {
2722 currentFrame = shouldLinkFrame;
2723 }
2724 else /* re-link */
2725 {
2726 currentFrame =
2727 ((currentFrame + USB_HOST_EHCI_ISO_BOUNCE_FRAME_NUMBER) & (USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3));
2728
2729 /*if (currentFrame > (USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3))
2730 {
2731 currentFrame = currentFrame - ((USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3) + 1U);
2732 }*/
2733 /* frame should align with interval */
2734 if (currentFrame <= ehciPipePointer->startFrame)
2735 {
2736 currentFrame = ehciPipePointer->startFrame;
2737 }
2738 else
2739 {
2740 currentFrame -= ehciPipePointer->startFrame;
2741 currentFrame = ((currentFrame + frameInterval - 1U) & (~(frameInterval - 1U)));
2742 currentFrame += ehciPipePointer->startFrame;
2743 }
2744 }
2745 }
2746 if (currentFrame >= USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE) /* frame turn around */
2747 {
2748 shouldLinkFrame =
2749 (currentFrame - USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE); /* shouldLinkFrame means inserted frame position */
2750 }
2751 else
2752 {
2753 shouldLinkFrame = currentFrame; /* shouldLinkFrame means inserted frame position */
2754 }
2755
2756 sitdPointer = (usb_host_ehci_sitd_t *)startEntryPointer;
2757 while (NULL != sitdPointer)
2758 {
2759 sitdPointer->frameEntryIndex = (uint16_t)shouldLinkFrame;
2760 /* add to frame list head */
2761 temp = (void *)ehciInstance->ehciFrameList;
2762 sitdPointer->nextLinkPointer = ((uint32_t *)temp)[shouldLinkFrame];
2763 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2764 convert_addr = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(sitdPointer);
2765 ((uint32_t *)temp)[shouldLinkFrame] = ((uint32_t)convert_addr | EHCI_HOST_POINTER_TYPE_SITD);
2766 #else
2767 ((uint32_t *)temp)[shouldLinkFrame] = ((uint32_t)sitdPointer | EHCI_HOST_POINTER_TYPE_SITD);
2768 #endif
2769 if (sitdPointer->nextSitdIndex == 0xFFU) /* 0xFF is invalid value */
2770 {
2771 break;
2772 }
2773 sitdPointer = &(ehciInstance->ehciSitdIndexBase[sitdPointer->nextSitdIndex]); /* next sitd */
2774
2775 shouldLinkFrame += frameInterval;
2776 currentFrame += frameInterval;
2777 if (shouldLinkFrame >= USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE)
2778 {
2779 shouldLinkFrame = (shouldLinkFrame - USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE);
2780 }
2781 }
2782
2783 if (currentFrame > (USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3))
2784 {
2785 currentFrame = currentFrame - ((USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3) + 1U);
2786 }
2787 isoPointer->lastLinkFrame = (uint16_t)currentFrame; /* save the last link frame value */
2788 }
2789
USB_HostEhciSitdArrayInit(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer,usb_host_transfer_t * transfer)2790 static usb_status_t USB_HostEhciSitdArrayInit(usb_host_ehci_instance_t *ehciInstance,
2791 usb_host_ehci_pipe_t *ehciPipePointer,
2792 usb_host_transfer_t *transfer)
2793 {
2794 usb_host_ehci_iso_t *isoPointer;
2795 uint32_t sitdNumber = 0;
2796 usb_host_ehci_sitd_t *sitdPointer;
2797 uint32_t dataLength = 0;
2798 uint32_t sitdLength = 0;
2799 uint32_t dataBufferValue;
2800 uint32_t hubNumber = 0U;
2801 uint32_t portNumber = 0U;
2802 uint32_t address = 0U;
2803 uint32_t tmp;
2804 uint32_t *temp;
2805 uint32_t index;
2806 int32_t tempIndex;
2807 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
2808 (uint32_t)kUSB_HostGetDeviceAddress, &address);
2809
2810 sitdNumber = ((transfer->transferLength - 1U + (ehciPipePointer->pipeCommon.maxPacketSize)) /
2811 (ehciPipePointer->pipeCommon.maxPacketSize));
2812 /* get sitd array */
2813 /* USB_HostEhciLock(); */
2814 if (ehciInstance->ehciSitdNumber >= sitdNumber)
2815 {
2816 sitdPointer = ehciInstance->ehciSitdList;
2817 transfer->union1.unitHead = (uint32_t)sitdPointer;
2818 for (index = 1U; index < sitdNumber; ++index)
2819 {
2820 /*misra 10.8*/
2821 tempIndex = (((usb_host_ehci_sitd_t *)(sitdPointer->nextLinkPointer & 0xFFFFFFFEU)) -
2822 ehciInstance->ehciSitdIndexBase);
2823 sitdPointer->nextSitdIndex = (uint8_t)tempIndex;
2824 sitdPointer = (usb_host_ehci_sitd_t *)(sitdPointer->nextLinkPointer & 0xFFFFFFFEU);
2825 }
2826 sitdPointer->nextSitdIndex = 0xFF;
2827 ehciInstance->ehciSitdList = (usb_host_ehci_sitd_t *)(sitdPointer->nextLinkPointer & 0xFFFFFFFEU);
2828 ehciInstance->ehciSitdNumber -= (uint8_t)sitdNumber;
2829 }
2830 else
2831 {
2832 /* USB_HostEhciUnlock(); */
2833 return kStatus_USB_Error;
2834 }
2835 /* USB_HostEhciUnlock(); */
2836 transfer->union2.unitTail = (uint32_t)sitdPointer;
2837 /* initialize sitd array */
2838 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
2839 (uint32_t)kUSB_HostGetDeviceHubNumber, &hubNumber);
2840 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
2841 (uint32_t)kUSB_HostGetDevicePortNumber, &portNumber);
2842 sitdPointer = (usb_host_ehci_sitd_t *)transfer->union1.unitHead;
2843 dataLength = transfer->transferLength;
2844 while (0U != sitdNumber)
2845 {
2846 sitdNumber--;
2847 USB_HostEhciZeroMem((void *)sitdPointer, 7);
2848 sitdLength = dataLength;
2849 if (sitdLength > ehciPipePointer->pipeCommon.maxPacketSize)
2850 {
2851 sitdLength = ehciPipePointer->pipeCommon.maxPacketSize;
2852 }
2853 dataBufferValue = (uint32_t)(transfer->transferBuffer + (transfer->transferLength - dataLength));
2854 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2855 dataBufferValue = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(dataBufferValue);
2856 #endif
2857 dataLength -= sitdLength; /* update left data length */
2858 sitdPointer->transferResults[1] = dataBufferValue;
2859 sitdPointer->transferResults[2] = ((dataBufferValue + 4U * 1024U) & 0xFFFFF000U);
2860 sitdPointer->endpointStates[0] =
2861 (((uint32_t)ehciPipePointer->pipeCommon.direction << EHCI_HOST_SITD_DIRECTION_SHIFT) |
2862 (portNumber << EHCI_HOST_SITD_PORT_NUMBER_SHIFT) | (hubNumber << EHCI_HOST_SITD_HUB_ADDR_SHIFT) |
2863 ((uint32_t)ehciPipePointer->pipeCommon.endpointAddress << EHCI_HOST_SITD_ENDPT_SHIFT) |
2864 (address << EHCI_HOST_SITD_DEVICE_ADDRESS_SHIFT));
2865 sitdPointer->transferResults[0] =
2866 ((sitdLength << EHCI_HOST_SITD_TOTAL_BYTES_SHIFT) | (EHCI_HOST_SITD_STATUS_ACTIVE_MASK));
2867
2868 if (ehciInstance->firstDeviceSpeed == USB_SPEED_HIGH)
2869 {
2870 sitdPointer->endpointStates[1] = (((uint32_t)ehciPipePointer->uframeCmask << EHCI_HOST_SITD_CMASK_SHIFT) |
2871 ((uint32_t)ehciPipePointer->uframeSmask << EHCI_HOST_SITD_SMASK_SHIFT));
2872
2873 tmp = (sitdLength + 187U) / 188U;
2874 if (tmp > 1U)
2875 {
2876 sitdPointer->transferResults[2] |= (0x01U << EHCI_HOST_SITD_TP_SHIFT); /* for iso split */
2877 }
2878 else
2879 {
2880 sitdPointer->transferResults[2] |= (0x00U << EHCI_HOST_SITD_TP_SHIFT); /* for iso split */
2881 }
2882 sitdPointer->transferResults[2] |= (tmp << EHCI_HOST_SITD_TCOUNT_SHIFT); /* for iso split */
2883 }
2884
2885 sitdPointer->backPointer = EHCI_HOST_T_INVALID_VALUE;
2886
2887 sitdPointer = (ehciInstance->ehciSitdIndexBase + sitdPointer->nextSitdIndex);
2888 }
2889 sitdPointer = (usb_host_ehci_sitd_t *)transfer->union2.unitTail;
2890 sitdPointer->transferResults[0] |= (1UL << EHCI_HOST_SITD_IOC_SHIFT); /* last set IOC */
2891
2892 /* link transfer to usb_host_ehci_iso_t transfer list */
2893 isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
2894 USB_HostEhciLock();
2895 if (isoPointer->ehciTransferHead == NULL)
2896 {
2897 transfer->next = NULL;
2898 isoPointer->ehciTransferTail = transfer;
2899 isoPointer->ehciTransferHead = transfer;
2900 }
2901 else
2902 {
2903 transfer->next = NULL;
2904 isoPointer->ehciTransferTail->next = transfer;
2905 isoPointer->ehciTransferTail = transfer;
2906 }
2907 USB_HostEhciUnlock();
2908
2909 /* link itd to frame list (note: initialize frameEntryIndex)*/
2910 /*misra 11.6*/
2911 temp = (uint32_t *)(transfer->union1.unitHead);
2912 USB_HostEhciLinkSitd(ehciInstance, ehciPipePointer, (void *)temp);
2913
2914 return kStatus_USB_Success;
2915 }
2916
USB_HostEhciSitdArrayRelease(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_sitd_t * startSitdPointer,usb_host_ehci_sitd_t * endSitdPointer)2917 static uint32_t USB_HostEhciSitdArrayRelease(usb_host_ehci_instance_t *ehciInstance,
2918 usb_host_ehci_sitd_t *startSitdPointer,
2919 usb_host_ehci_sitd_t *endSitdPointer)
2920 {
2921 usb_host_ehci_sitd_t *sitdPointer = startSitdPointer;
2922 uint32_t leftLength = 0;
2923 /* remove itd from frame list */
2924 while (1U == 1U)
2925 {
2926 /* record the transfer's result length */
2927 leftLength +=
2928 ((sitdPointer->transferResults[0] & EHCI_HOST_SITD_TOTAL_BYTES_MASK) >> EHCI_HOST_SITD_TOTAL_BYTES_SHIFT);
2929 USB_HostEhciRemoveFromFrame(ehciInstance, (uint32_t)sitdPointer,
2930 sitdPointer->frameEntryIndex); /* remove from the inserted frame list */
2931
2932 /* release itd */
2933 /* USB_HostEhciLock(); */
2934 /*set next link pointer to invalid in case hardware access invalid sitd structure in special case*/
2935 sitdPointer->nextLinkPointer = (((uint32_t)ehciInstance->ehciSitdList) | EHCI_HOST_T_INVALID_VALUE);
2936 ehciInstance->ehciSitdList = sitdPointer;
2937 ehciInstance->ehciSitdNumber++;
2938 /* USB_HostEhciUnlock(); */
2939
2940 if (sitdPointer == endSitdPointer)
2941 {
2942 break;
2943 }
2944
2945 sitdPointer = &(ehciInstance->ehciSitdIndexBase[sitdPointer->nextSitdIndex]);
2946 }
2947
2948 return leftLength;
2949 }
2950
USB_HostEhciSitdArrayDeinit(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)2951 static usb_status_t USB_HostEhciSitdArrayDeinit(usb_host_ehci_instance_t *ehciInstance,
2952 usb_host_ehci_pipe_t *ehciPipePointer)
2953 {
2954 usb_host_ehci_iso_t *isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
2955 usb_host_transfer_t *transfer;
2956 usb_host_transfer_t *nextTransfer;
2957
2958 /* firstly remove the transfer (because host task may occupy to access the resource) */
2959 USB_HostEhciLock();
2960 transfer = isoPointer->ehciTransferHead;
2961 isoPointer->ehciTransferTail = NULL;
2962 isoPointer->ehciTransferHead = NULL;
2963 USB_HostEhciUnlock();
2964
2965 while (transfer != NULL)
2966 {
2967 nextTransfer = transfer->next;
2968 /* remove sitd from frame list and release itd */
2969 transfer->transferSofar =
2970 transfer->transferLength - USB_HostEhciSitdArrayRelease(ehciInstance,
2971 (usb_host_ehci_sitd_t *)transfer->union1.unitHead,
2972 (usb_host_ehci_sitd_t *)transfer->union2.unitTail);
2973 /* callback function is different from the current condition */
2974 transfer->callbackFn(transfer->callbackParam, transfer, kStatus_USB_TransferCancel);
2975 /* next transfer */
2976 transfer = nextTransfer;
2977 }
2978
2979 return kStatus_USB_Success;
2980 }
2981 #endif /* USB_HOST_CONFIG_EHCI_MAX_SITD */
2982
2983 #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
USB_HostEhciGetItdLinkFrame(usb_host_ehci_instance_t * ehciInstance,uint32_t lastLinkUframe,uint16_t startUframe,uint16_t uframeInterval)2984 static uint32_t USB_HostEhciGetItdLinkFrame(usb_host_ehci_instance_t *ehciInstance,
2985 uint32_t lastLinkUframe,
2986 uint16_t startUframe,
2987 uint16_t uframeInterval)
2988 {
2989 uint32_t shouldLinkUframe;
2990 uint32_t currentUframe;
2991 uint32_t distance;
2992
2993 if (lastLinkUframe != 0xFFFFU)
2994 {
2995 shouldLinkUframe = lastLinkUframe + uframeInterval;
2996 if (shouldLinkUframe > USB_HOST_EHCI_MAX_MICRFRAME_VALUE)
2997 {
2998 shouldLinkUframe = shouldLinkUframe - (USB_HOST_EHCI_MAX_MICRFRAME_VALUE + 1U);
2999 }
3000 currentUframe = (ehciInstance->ehciIpBase->FRINDEX & USB_HOST_EHCI_MAX_MICRFRAME_VALUE);
3001 distance = ((shouldLinkUframe + USB_HOST_EHCI_MAX_MICRFRAME_VALUE + 1U - currentUframe) &
3002 USB_HOST_EHCI_MAX_MICRFRAME_VALUE); /* get the distance */
3003 /* shouldLinkUframe has add uframeInterval, think about the align with interval, so here add (uframeInterval
3004 * * 2) */
3005 if ((distance <= ((uint32_t)USB_HOST_EHCI_ISO_BOUNCE_UFRAME_NUMBER +
3006 ((uint32_t)uframeInterval * USB_HOST_EHCI_ISO_MAX_CONTINUOUS_TRANSFER))) &&
3007 (distance > 2U))
3008 {
3009 currentUframe = shouldLinkUframe;
3010 }
3011 else /* re-link */
3012 {
3013 currentUframe =
3014 ((currentUframe + USB_HOST_EHCI_ISO_BOUNCE_UFRAME_NUMBER) & USB_HOST_EHCI_MAX_MICRFRAME_VALUE);
3015 /*if (currentUframe > USB_HOST_EHCI_MAX_MICRFRAME_VALUE)
3016 {
3017 currentUframe = currentUframe - (USB_HOST_EHCI_MAX_MICRFRAME_VALUE + 1U);
3018 }*/
3019 /* uframe should align with interval */
3020 if (currentUframe <= startUframe)
3021 {
3022 currentUframe = startUframe;
3023 }
3024 else
3025 {
3026 currentUframe -= startUframe;
3027 currentUframe = ((uint32_t)(currentUframe + uframeInterval) &
3028 (~((uint32_t)uframeInterval - 1U))); /* uframeInterval is power of 2 */
3029 currentUframe += startUframe;
3030 }
3031 }
3032 }
3033 else
3034 {
3035 currentUframe = (ehciInstance->ehciIpBase->FRINDEX & USB_HOST_EHCI_MAX_MICRFRAME_VALUE);
3036 currentUframe = ((currentUframe + USB_HOST_EHCI_ISO_BOUNCE_UFRAME_NUMBER) & USB_HOST_EHCI_MAX_MICRFRAME_VALUE);
3037 /* uframe should align with interval */
3038 if (currentUframe <= startUframe)
3039 {
3040 currentUframe = startUframe;
3041 }
3042 else
3043 {
3044 currentUframe -= startUframe;
3045 currentUframe =
3046 ((currentUframe + uframeInterval) & (~(uframeInterval - 1U))); /* uframeInterval is power of 2 */
3047 currentUframe += startUframe;
3048 }
3049 }
3050
3051 return currentUframe;
3052 }
3053
USB_HostEhciItdArrayInit(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer,usb_host_transfer_t * transfer)3054 static usb_status_t USB_HostEhciItdArrayInit(usb_host_ehci_instance_t *ehciInstance,
3055 usb_host_ehci_pipe_t *ehciPipePointer,
3056 usb_host_transfer_t *transfer)
3057 {
3058 usb_host_ehci_iso_t *isoPointer;
3059 usb_host_ehci_itd_t *itdPointer = NULL;
3060 usb_host_ehci_itd_t *itdHead = NULL;
3061 usb_host_ehci_itd_t *tmpItdPointer;
3062 uint32_t dataLength; /* the remaining data for sending */
3063 uint32_t transactionLength; /* the initializing transaction descriptor data length */
3064 uint32_t itdBufferValue;
3065 uint32_t itdBufferBaseValue; /* for calculating PG value */
3066 uint32_t address = 0U;
3067 uint32_t lastShouldLinkUframe;
3068 uint32_t linkUframe;
3069 uint32_t minDataPerItd =
3070 (uint32_t)ehciPipePointer->pipeCommon.numberPerUframe * ehciPipePointer->pipeCommon.maxPacketSize;
3071 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3072 uint32_t convert_addr = 0U;
3073 uint32_t convert_addr1 = 0U;
3074 #endif
3075 uint8_t maxItdNumber;
3076 uint16_t index = 0;
3077
3078 isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
3079 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
3080 (uint32_t)kUSB_HostGetDeviceAddress, &address);
3081
3082 /* max needed itd number, the actual needed number may be less because micro-frame interval may be less than 8 */
3083 maxItdNumber = (uint8_t)((transfer->transferLength - 1U + minDataPerItd) / minDataPerItd);
3084 if (ehciPipePointer->uframeInterval < 8U)
3085 {
3086 maxItdNumber = (uint8_t)((maxItdNumber * ehciPipePointer->uframeInterval + 7U) / 8U) + 1U;
3087 }
3088 if (maxItdNumber > ehciInstance->ehciItdNumber)
3089 {
3090 return kStatus_USB_Error;
3091 }
3092
3093 /* link transfer to usb_host_ehci_iso_t transfer list */
3094 transfer->next = NULL;
3095 /* USB_HostEhciLock(); */
3096 if (isoPointer->ehciTransferHead == NULL)
3097 {
3098 isoPointer->ehciTransferTail = transfer;
3099 isoPointer->ehciTransferHead = transfer;
3100 }
3101 else
3102 {
3103 isoPointer->ehciTransferTail->next = transfer;
3104 isoPointer->ehciTransferTail = transfer;
3105 }
3106 /* USB_HostEhciUnlock(); */
3107
3108 dataLength = transfer->transferLength;
3109 transfer->union1.unitHead = 0U;
3110 /* get the link micro-frame */
3111 lastShouldLinkUframe = USB_HostEhciGetItdLinkFrame(
3112 ehciInstance, isoPointer->lastLinkFrame,
3113 (uint16_t)((ehciPipePointer->startFrame << 3) + ehciPipePointer->startUframe), ehciPipePointer->uframeInterval);
3114 if (lastShouldLinkUframe > USB_HOST_EHCI_MAX_MICRFRAME_VALUE)
3115 {
3116 linkUframe = lastShouldLinkUframe - (USB_HOST_EHCI_MAX_MICRFRAME_VALUE + 1U);
3117 }
3118 else
3119 {
3120 linkUframe = lastShouldLinkUframe;
3121 }
3122 itdHead = ehciInstance->ehciItdList;
3123 while (0U != dataLength)
3124 {
3125 /* get one idle itd */
3126 tmpItdPointer = ehciInstance->ehciItdList;
3127 if (tmpItdPointer == NULL)
3128 {
3129 return kStatus_USB_Error; /* this should not reach */
3130 }
3131 ehciInstance->ehciItdList = (usb_host_ehci_itd_t *)tmpItdPointer->nextItdPointer;
3132 ehciInstance->ehciItdNumber -= 1U;
3133
3134 tmpItdPointer->nextItdPointer = NULL;
3135
3136 /* use the itd */
3137 if (transfer->union1.unitHead == 0U) /* first itd */
3138 {
3139 transfer->union1.unitHead = (uint32_t)tmpItdPointer;
3140 }
3141 else /* link itd list */
3142 {
3143 itdPointer->nextItdPointer = tmpItdPointer;
3144 }
3145 itdPointer = tmpItdPointer;
3146
3147 /* itd has been set to all zero when releasing */
3148 itdBufferValue = (uint32_t)(transfer->transferBuffer + (transfer->transferLength - dataLength));
3149 itdBufferBaseValue = itdBufferValue;
3150 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3151 convert_addr = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(itdBufferBaseValue);
3152 convert_addr1 = convert_addr;
3153 #endif
3154 for (index = 0; index < 7U; ++index)
3155 {
3156 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3157 itdPointer->bufferPointers[index] = ((convert_addr + ((uint32_t)index * 4U * 1024U)) & 0xFFFFF000U);
3158 #else
3159 itdPointer->bufferPointers[index] = ((itdBufferBaseValue + ((uint32_t)index * 4U * 1024U)) & 0xFFFFF000U);
3160 #endif
3161 }
3162 /* initialize iTD common fields */
3163 itdPointer->bufferPointers[0] |=
3164 (((uint32_t)ehciPipePointer->pipeCommon.endpointAddress << EHCI_HOST_ITD_ENDPT_SHIFT) |
3165 (address << EHCI_HOST_ITD_DEVICE_ADDRESS_SHIFT));
3166 itdPointer->bufferPointers[1] |=
3167 (((uint32_t)ehciPipePointer->pipeCommon.direction << EHCI_HOST_ITD_DIRECTION_SHIFT) |
3168 ((uint32_t)ehciPipePointer->pipeCommon.maxPacketSize << EHCI_HOST_ITD_MAX_PACKET_SIZE_SHIFT));
3169 itdPointer->bufferPointers[2] |= (ehciPipePointer->pipeCommon.numberPerUframe);
3170 /* initialize transaction descriptors */
3171 for (index = (uint8_t)(linkUframe & 0x0007U); index < 8U; index += ehciPipePointer->uframeInterval)
3172 {
3173 transactionLength = ((dataLength > minDataPerItd) ? minDataPerItd : dataLength);
3174 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3175 /* initialize the uframeIndex's transaction descriptor in itd */
3176 itdPointer->transactions[index] =
3177 ((EHCI_HOST_ITD_STATUS_ACTIVE_MASK) | (transactionLength << EHCI_HOST_ITD_TRANSACTION_LEN_SHIFT) |
3178 ((((convert_addr1 & 0xFFFFF000U) - (convert_addr & 0xFFFFF000U)) >> EHCI_HOST_ITD_BUFFER_POINTER_SHIFT)
3179 << EHCI_HOST_ITD_PG_SHIFT) |
3180 (convert_addr1 & EHCI_HOST_ITD_TRANSACTION_OFFSET_MASK));
3181 dataLength -= transactionLength;
3182 convert_addr1 += transactionLength;
3183 #else
3184 /* initialize the uframeIndex's transaction descriptor in itd */
3185 itdPointer->transactions[index] =
3186 ((EHCI_HOST_ITD_STATUS_ACTIVE_MASK) | (transactionLength << EHCI_HOST_ITD_TRANSACTION_LEN_SHIFT) |
3187 ((((itdBufferValue & 0xFFFFF000U) - (itdBufferBaseValue & 0xFFFFF000U)) >>
3188 EHCI_HOST_ITD_BUFFER_POINTER_SHIFT)
3189 << EHCI_HOST_ITD_PG_SHIFT) |
3190 (itdBufferValue & EHCI_HOST_ITD_TRANSACTION_OFFSET_MASK));
3191 dataLength -= transactionLength;
3192 itdBufferValue += transactionLength;
3193 #endif
3194 if (dataLength <= 0U)
3195 {
3196 break;
3197 }
3198 }
3199 }
3200
3201 transfer->union2.unitTail = (uint32_t)itdPointer;
3202 itdPointer->transactions[index] |= (1UL << EHCI_HOST_ITD_IOC_SHIFT); /* last set IOC */
3203
3204 itdPointer = itdHead;
3205 /* link itd to frame list (note: initialize frameEntryIndex)*/
3206 while (NULL != itdPointer)
3207 {
3208 void *temp = (void *)ehciInstance->ehciFrameList;
3209 uint32_t *linkPointer = &((uint32_t *)temp)[linkUframe >> 3];
3210 uint32_t linkValue = *linkPointer;
3211 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3212 linkValue = (uint32_t)USB_HOST_MEMORY_DMA_2_CPU(linkValue);
3213 #endif
3214 itdPointer->frameEntryIndex = linkUframe >> 3;
3215 while ((0U == (linkValue & EHCI_HOST_T_INVALID_VALUE)) &&
3216 ((linkValue & EHCI_HOST_POINTER_TYPE_MASK) == EHCI_HOST_POINTER_TYPE_ITD))
3217 {
3218 linkPointer = (uint32_t *)(linkValue & EHCI_HOST_POINTER_ADDRESS_MASK);
3219 linkValue = *linkPointer;
3220 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3221 linkValue = (uint32_t)USB_HOST_MEMORY_DMA_2_CPU(linkValue);
3222 #endif
3223 }
3224 itdPointer->nextLinkPointer = *linkPointer;
3225 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3226 convert_addr = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(itdPointer);
3227 *linkPointer = ((uint32_t)convert_addr | EHCI_HOST_POINTER_TYPE_ITD);
3228 #else
3229 *linkPointer = ((uint32_t)itdPointer | EHCI_HOST_POINTER_TYPE_ITD);
3230 #endif
3231 itdPointer = itdPointer->nextItdPointer;
3232 if (itdPointer == NULL)
3233 {
3234 break;
3235 }
3236
3237 linkUframe += ehciPipePointer->uframeInterval;
3238 lastShouldLinkUframe += ehciPipePointer->uframeInterval;
3239 if (linkUframe >= (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE << 3))
3240 {
3241 linkUframe = (linkUframe - (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE << 3));
3242 }
3243 }
3244
3245 if (lastShouldLinkUframe > USB_HOST_EHCI_MAX_MICRFRAME_VALUE)
3246 {
3247 lastShouldLinkUframe = lastShouldLinkUframe - (USB_HOST_EHCI_MAX_MICRFRAME_VALUE + 1U);
3248 }
3249 isoPointer->lastLinkFrame = (uint16_t)lastShouldLinkUframe;
3250
3251 return kStatus_USB_Success;
3252 }
3253
USB_HostEhciItdArrayRelease(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_itd_t * startItdPointer,usb_host_ehci_itd_t * endItdPointer)3254 static uint32_t USB_HostEhciItdArrayRelease(usb_host_ehci_instance_t *ehciInstance,
3255 usb_host_ehci_itd_t *startItdPointer,
3256 usb_host_ehci_itd_t *endItdPointer)
3257 {
3258 usb_host_ehci_itd_t *itdPointer = startItdPointer;
3259 uint8_t index;
3260 uint32_t doneLength = 0;
3261
3262 /* remove itd from frame list */
3263 while (1U == 1U)
3264 {
3265 /* record the transfer's result length */
3266 for (index = 0U; index < 8U; ++index)
3267 {
3268 doneLength += ((itdPointer->transactions[index] & EHCI_HOST_ITD_TRANSACTION_LEN_MASK) >>
3269 EHCI_HOST_ITD_TRANSACTION_LEN_SHIFT);
3270 }
3271
3272 USB_HostEhciRemoveFromFrame(ehciInstance, (uint32_t)itdPointer,
3273 (uint16_t)itdPointer->frameEntryIndex); /* remove from the inserted frame list */
3274
3275 /* release itd */
3276 /* USB_HostEhciLock(); */
3277 /*set next link pointer to invalid in case hardware access invalid itd structure in special case*/
3278 itdPointer->nextLinkPointer = EHCI_HOST_T_INVALID_VALUE;
3279 USB_HostEhciZeroMem((uint32_t *)(void *)itdPointer + 1, ((sizeof(usb_host_ehci_itd_t) >> 2) - 4U));
3280 itdPointer->nextItdPointer = (usb_host_ehci_itd_t *)ehciInstance->ehciItdList;
3281 ehciInstance->ehciItdList = itdPointer;
3282 ehciInstance->ehciItdNumber++;
3283 /* USB_HostEhciUnlock(); */
3284
3285 if (itdPointer == endItdPointer)
3286 {
3287 break;
3288 }
3289 itdPointer = itdPointer->nextItdPointer;
3290 }
3291
3292 return doneLength;
3293 }
3294
USB_HostEhciItdArrayDeinit(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)3295 static usb_status_t USB_HostEhciItdArrayDeinit(usb_host_ehci_instance_t *ehciInstance,
3296 usb_host_ehci_pipe_t *ehciPipePointer)
3297 {
3298 usb_host_ehci_iso_t *isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
3299 usb_host_transfer_t *transfer;
3300 usb_host_transfer_t *nextTransfer;
3301 uint32_t doneLength = 0;
3302
3303 /* firstly remove the transfer (because host task may occupy to access the resource) */
3304 USB_HostEhciLock();
3305 transfer = isoPointer->ehciTransferHead;
3306 isoPointer->ehciTransferTail = NULL;
3307 isoPointer->ehciTransferHead = NULL;
3308 USB_HostEhciUnlock();
3309
3310 while (transfer != NULL)
3311 {
3312 nextTransfer = transfer->next;
3313 doneLength = 0;
3314 /* remove itd from frame list and release itd */
3315 doneLength = USB_HostEhciItdArrayRelease(ehciInstance, (usb_host_ehci_itd_t *)transfer->union1.unitHead,
3316 (usb_host_ehci_itd_t *)transfer->union2.unitTail);
3317
3318 /* transfer callback */
3319 if (ehciPipePointer->pipeCommon.direction == USB_OUT)
3320 {
3321 doneLength = transfer->transferLength;
3322 }
3323 transfer->transferSofar = doneLength;
3324 /* callback function is different from the current condition */
3325 transfer->callbackFn(transfer->callbackParam, transfer, kStatus_USB_TransferCancel);
3326
3327 /* next transfer */
3328 transfer = nextTransfer;
3329 }
3330
3331 return kStatus_USB_Success;
3332 }
3333 #endif /* USB_HOST_CONFIG_EHCI_MAX_ITD */
3334
USB_HostEhciOpenControlBulk(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)3335 static usb_status_t USB_HostEhciOpenControlBulk(usb_host_ehci_instance_t *ehciInstance,
3336 usb_host_ehci_pipe_t *ehciPipePointer)
3337 {
3338 usb_host_ehci_qh_t *qhPointer;
3339 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3340 uint32_t convert_addr = 0U;
3341 #endif
3342
3343 if (USB_HostEhciQhInit(ehciInstance, ehciPipePointer) != kStatus_USB_Success) /* initialize control/bulk qh */
3344 {
3345 return kStatus_USB_Error;
3346 }
3347
3348 qhPointer = (usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
3349
3350 /* add qh to async */
3351 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3352 qhPointer->horizontalLinkPointer =
3353 (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(ehciInstance->shedFirstQh->horizontalLinkPointer);
3354 convert_addr = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(qhPointer);
3355 ehciInstance->shedFirstQh->horizontalLinkPointer = (convert_addr | EHCI_HOST_POINTER_TYPE_QH);
3356 #else
3357 qhPointer->horizontalLinkPointer = ehciInstance->shedFirstQh->horizontalLinkPointer;
3358 ehciInstance->shedFirstQh->horizontalLinkPointer = ((uint32_t)qhPointer | EHCI_HOST_POINTER_TYPE_QH);
3359 #endif
3360
3361 return kStatus_USB_Success;
3362 }
3363
USB_HostEhciCloseControlBulk(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)3364 static usb_status_t USB_HostEhciCloseControlBulk(usb_host_ehci_instance_t *ehciInstance,
3365 usb_host_ehci_pipe_t *ehciPipePointer)
3366 {
3367 volatile usb_host_ehci_qh_t *vltPrevQhPointer;
3368 uint32_t horizontalLinkValue;
3369 uint32_t *temp;
3370 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3371 uint32_t convert_addr = 0U;
3372 #endif
3373
3374 /* remove qh from async schedule */
3375 temp = (uint32_t *)ehciPipePointer->ehciQh;
3376 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3377 convert_addr = (uint32_t)USB_HOST_MEMORY_DMA_2_CPU(ehciInstance->shedFirstQh->horizontalLinkPointer);
3378 if ((convert_addr & EHCI_HOST_POINTER_ADDRESS_MASK) ==
3379 #else
3380 if ((ehciInstance->shedFirstQh->horizontalLinkPointer & EHCI_HOST_POINTER_ADDRESS_MASK) ==
3381 #endif
3382 (uint32_t)temp) /* the removing qh is the first qh in the async list */
3383 {
3384 USB_HostEhciLock();
3385 USB_HostEhciStopAsync(ehciInstance);
3386 ehciInstance->shedFirstQh->horizontalLinkPointer =
3387 ((usb_host_ehci_qh_t *)ehciPipePointer->ehciQh)->horizontalLinkPointer;
3388 USB_HostEhciStartAsync(ehciInstance);
3389 USB_HostEhciUnlock();
3390 }
3391 else
3392 {
3393 /* search for the removing qh from the async list */
3394 vltPrevQhPointer = ehciInstance->shedFirstQh;
3395 while (vltPrevQhPointer != NULL)
3396 {
3397 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3398 horizontalLinkValue = (uint32_t)USB_HOST_MEMORY_DMA_2_CPU(vltPrevQhPointer->horizontalLinkPointer);
3399 #else
3400 horizontalLinkValue = vltPrevQhPointer->horizontalLinkPointer;
3401 #endif
3402 if ((0U != (horizontalLinkValue & EHCI_HOST_T_INVALID_VALUE)) ||
3403 ((horizontalLinkValue & EHCI_HOST_POINTER_ADDRESS_MASK) == (uint32_t)temp) ||
3404 ((horizontalLinkValue & EHCI_HOST_POINTER_ADDRESS_MASK) == (uint32_t)ehciInstance->shedFirstQh))
3405 {
3406 break;
3407 }
3408
3409 vltPrevQhPointer = (volatile usb_host_ehci_qh_t *)(horizontalLinkValue & EHCI_HOST_POINTER_ADDRESS_MASK);
3410 }
3411
3412 /* remove the qh from async list */
3413 /*for misra 11.6*/
3414 temp = (uint32_t *)ehciPipePointer->ehciQh;
3415 if ((vltPrevQhPointer != NULL) && (0U == (horizontalLinkValue & EHCI_HOST_T_INVALID_VALUE)) &&
3416 ((horizontalLinkValue & EHCI_HOST_POINTER_ADDRESS_MASK) == (uint32_t)temp))
3417 {
3418 USB_HostEhciLock();
3419 USB_HostEhciStopAsync(ehciInstance);
3420 vltPrevQhPointer->horizontalLinkPointer =
3421 ((usb_host_ehci_qh_t *)ehciPipePointer->ehciQh)->horizontalLinkPointer;
3422 USB_HostEhciStartAsync(ehciInstance);
3423 USB_HostEhciUnlock();
3424 }
3425 }
3426 ((usb_host_ehci_qh_t *)ehciPipePointer->ehciQh)->horizontalLinkPointer =
3427 EHCI_HOST_T_INVALID_VALUE; /* invalid next qh link */
3428 return USB_HostEhciQhDeinit(ehciInstance, ehciPipePointer); /* de-initialize qh and release qh */
3429 }
3430
USB_HostEhciOpenInterrupt(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)3431 static usb_status_t USB_HostEhciOpenInterrupt(usb_host_ehci_instance_t *ehciInstance,
3432 usb_host_ehci_pipe_t *ehciPipePointer)
3433 {
3434 usb_status_t status = kStatus_USB_Success;
3435 uint32_t frameIndex;
3436 uint32_t *temp;
3437
3438 /* allocate bandwidth */
3439 if (ehciInstance->firstDeviceSpeed == USB_SPEED_HIGH)
3440 {
3441 status = USB_HostBandwidthHsHostAllocateInterrupt(ehciInstance, ehciPipePointer); /* host works as high-speed */
3442 }
3443 else
3444 {
3445 status = USB_HostBandwidthFslsHostAllocate(ehciInstance,
3446 ehciPipePointer); /* host works as full-speed or low-speed */
3447 }
3448
3449 if (status != kStatus_USB_Success)
3450 {
3451 return status;
3452 }
3453 if (USB_HostEhciQhInit(ehciInstance, ehciPipePointer) != kStatus_USB_Success)
3454 {
3455 return kStatus_USB_Error;
3456 }
3457
3458 /* insert QH to frame list */
3459 for (frameIndex = ehciPipePointer->startFrame; frameIndex < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE;
3460 frameIndex += (((uint32_t)ehciPipePointer->uframeInterval + 7U) / 8U))
3461 {
3462 temp = (uint32_t *)ehciPipePointer->ehciQh;
3463 USB_HostEhciAddQhToFrame(ehciInstance, (uint32_t)temp, (uint16_t)frameIndex, ehciPipePointer->uframeInterval);
3464 }
3465
3466 return kStatus_USB_Success;
3467 }
3468
USB_HostEhciCloseInterrupt(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)3469 static usb_status_t USB_HostEhciCloseInterrupt(usb_host_ehci_instance_t *ehciInstance,
3470 usb_host_ehci_pipe_t *ehciPipePointer)
3471 {
3472 uint32_t frameIndex;
3473 uint32_t *temp;
3474 /* remove from frame list */
3475 for (frameIndex = ehciPipePointer->startFrame; frameIndex < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE;
3476 frameIndex += (((uint32_t)ehciPipePointer->uframeInterval + 7U) / 8U))
3477 {
3478 temp = (uint32_t *)ehciPipePointer->ehciQh;
3479 USB_HostEhciRemoveFromFrame(ehciInstance, (uint32_t)temp, (uint16_t)frameIndex);
3480 }
3481 ((usb_host_ehci_qh_t *)ehciPipePointer->ehciQh)->horizontalLinkPointer |=
3482 EHCI_HOST_T_INVALID_VALUE; /* invalid next qh link */
3483
3484 return USB_HostEhciQhDeinit(ehciInstance, ehciPipePointer); /* de-initilaze qh and release qh */
3485 }
3486
3487 #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
3488 ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
3489
USB_HostEhciOpenIso(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)3490 static usb_status_t USB_HostEhciOpenIso(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer)
3491 {
3492 usb_host_ehci_iso_t *isoPointer;
3493 usb_status_t status = kStatus_USB_Success;
3494
3495 if (ehciInstance->firstDeviceSpeed == USB_SPEED_HIGH)
3496 {
3497 status = USB_HostBandwidthHsHostAllocateIso(
3498 ehciInstance, ehciPipePointer); /* allocate iso bandwidth when host works as high-speed */
3499 }
3500 else
3501 {
3502 status = USB_HostBandwidthFslsHostAllocate(
3503 ehciInstance, ehciPipePointer); /* allocate iso bandwidth when host works as full-speed or low-speed */
3504 }
3505
3506 if (status != kStatus_USB_Success)
3507 {
3508 return status;
3509 }
3510
3511 /* get usb_host_ehci_iso_t */
3512 if (ehciInstance->ehciIsoList == NULL)
3513 {
3514 return kStatus_USB_Error;
3515 }
3516 USB_HostEhciLock();
3517 isoPointer = ehciInstance->ehciIsoList;
3518 ehciInstance->ehciIsoList = ehciInstance->ehciIsoList->next;
3519 USB_HostEhciUnlock();
3520 isoPointer->lastLinkFrame = 0xFFFF;
3521 ehciPipePointer->ehciQh = isoPointer;
3522
3523 return status;
3524 }
3525
USB_HostEhciCloseIso(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)3526 static usb_status_t USB_HostEhciCloseIso(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer)
3527 {
3528 usb_host_ehci_iso_t *isoPointer;
3529 uint32_t speed = 0U;
3530
3531 isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
3532
3533 if (isoPointer->ehciTransferHead != NULL)
3534 {
3535 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
3536 (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
3537 if (speed == USB_SPEED_HIGH)
3538 {
3539 #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
3540 (void)USB_HostEhciItdArrayDeinit(ehciInstance, ehciPipePointer); /* de-initialize itd list and free them */
3541 #endif
3542 }
3543 else
3544 {
3545 #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
3546 (void)USB_HostEhciSitdArrayDeinit(ehciInstance,
3547 ehciPipePointer); /* de-initialize sitd list and free them */
3548 #endif
3549 }
3550 }
3551
3552 /* release usb_host_ehci_iso_t */
3553 USB_HostEhciLock();
3554 isoPointer->next = ehciInstance->ehciIsoList;
3555 ehciInstance->ehciIsoList = isoPointer;
3556 USB_HostEhciUnlock();
3557 return kStatus_USB_Success;
3558 }
3559
3560 #endif
3561
USB_HostEhciResetIP(usb_host_ehci_instance_t * ehciInstance)3562 static usb_status_t USB_HostEhciResetIP(usb_host_ehci_instance_t *ehciInstance)
3563 {
3564 /* reset controller */
3565 ehciInstance->ehciIpBase->USBCMD = USBHS_USBCMD_RST_MASK;
3566 while (0U != (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_RST_MASK))
3567 {
3568 }
3569 /* set host mode */
3570 #if (ENDIANNESS == USB_LITTLE_ENDIAN)
3571 ehciInstance->ehciIpBase->USBMODE |= 0x03U;
3572 #else
3573 ehciInstance->ehciIpBase->USBMODE |= (0x03U | (0x01U << USBHS_USBMODE_ES_SHIFT));
3574 #endif
3575 /* check frame list size */
3576 if (0U == (ehciInstance->ehciIpBase->HCCPARAMS & USBHS_HCCPARAMS_PFL_MASK))
3577 {
3578 #if ((USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE < 8) || (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE > 1024))
3579 return kStatus_USB_Error;
3580 #endif
3581 #if (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE & (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE - 1))
3582 return kStatus_USB_Error; /* frame size must be 1024/512/256/128/64/32/16/8 */
3583 #endif
3584 }
3585 return kStatus_USB_Success;
3586 }
3587
USB_HostEhciStartIP(usb_host_ehci_instance_t * ehciInstance)3588 static usb_status_t USB_HostEhciStartIP(usb_host_ehci_instance_t *ehciInstance)
3589 {
3590 uint32_t tmp = 0;
3591
3592 if (0U != (ehciInstance->ehciIpBase->HCSPARAMS & USBHS_HCSPARAMS_PPC_MASK)) /* Ports have power port switches */
3593 {
3594 /* only has one port */
3595 tmp = ehciInstance->ehciIpBase->PORTSC1;
3596 tmp &= (~EHCI_PORTSC1_W1_BITS);
3597 ehciInstance->ehciIpBase->PORTSC1 = (tmp | USBHS_PORTSC1_PP_MASK); /* turn on port power */
3598 }
3599
3600 /* set frame list size */
3601 if (0U != (ehciInstance->ehciIpBase->HCCPARAMS & USBHS_HCCPARAMS_PFL_MASK))
3602 {
3603 #if (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE <= 64)
3604 ehciInstance->ehciIpBase->USBCMD |= (USBHS_USBCMD_FS2_MASK);
3605 #if (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 64)
3606 ehciInstance->ehciIpBase->USBCMD |= (0x00U << USBHS_USBCMD_FS_SHIFT);
3607 #elif (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 32)
3608 ehciInstance->ehciIpBase->USBCMD |= (0x01U << USBHS_USBCMD_FS_SHIFT);
3609 #elif (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 16)
3610 ehciInstance->ehciIpBase->USBCMD |= (0x02U << USBHS_USBCMD_FS_SHIFT);
3611 #elif (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 8)
3612 ehciInstance->ehciIpBase->USBCMD |= (0x03U << USBHS_USBCMD_FS_SHIFT);
3613 #endif
3614 #else
3615 #if (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 1024)
3616 ehciInstance->ehciIpBase->USBCMD |= (0x00U << USBHS_USBCMD_FS_SHIFT);
3617 #elif (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 512)
3618 ehciInstance->ehciIpBase->USBCMD |= (0x01U << USBHS_USBCMD_FS_SHIFT);
3619 #elif (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 256)
3620 ehciInstance->ehciIpBase->USBCMD |= (0x02U << USBHS_USBCMD_FS_SHIFT);
3621 #elif (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 128)
3622 ehciInstance->ehciIpBase->USBCMD |= (0x03U << USBHS_USBCMD_FS_SHIFT);
3623 #endif
3624 #endif
3625 }
3626 /* no interrupt threshold */
3627 ehciInstance->ehciIpBase->USBCMD &= ~USBHS_USBCMD_ITC_MASK;
3628 /* start the controller */
3629 ehciInstance->ehciIpBase->USBCMD |= USBHS_USBCMD_RS_MASK;
3630 /* set timer0 */
3631 ehciInstance->ehciIpBase->GPTIMER0LD = (100U * 1000U - 1U); /* 100ms */
3632
3633 /* enable interrupt (USB interrupt enable + USB error interrupt enable + port change detect enable + system error
3634 * enable + interrupt on async advance enable) + general purpos Timer 0 Interrupt enable */
3635 ehciInstance->ehciIpBase->USBINTR |= (0x1000037U);
3636
3637 return kStatus_USB_Success;
3638 }
3639
USB_HostEhciCancelPipe(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer,usb_host_transfer_t * transfer)3640 static usb_status_t USB_HostEhciCancelPipe(usb_host_ehci_instance_t *ehciInstance,
3641 usb_host_ehci_pipe_t *ehciPipePointer,
3642 usb_host_transfer_t *transfer)
3643 {
3644 usb_host_ehci_qh_t *qhPointer;
3645 #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
3646 ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
3647 usb_host_ehci_iso_t *isoPointer;
3648 uint32_t speed = 0U;
3649 #endif
3650 uint8_t cancelPipe = 0;
3651
3652 switch (ehciPipePointer->pipeCommon.pipeType)
3653 {
3654 case USB_ENDPOINT_BULK:
3655 case USB_ENDPOINT_CONTROL:
3656 case USB_ENDPOINT_INTERRUPT:
3657 qhPointer = (usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
3658 if (qhPointer->ehciTransferHead == NULL) /* there is no transfer to cancel */
3659 {
3660 return kStatus_USB_Success;
3661 }
3662 if (transfer != NULL)
3663 {
3664 if ((qhPointer->ehciTransferHead == transfer) &&
3665 (qhPointer->ehciTransferHead == qhPointer->ehciTransferTail)) /* only has this one transfer */
3666 {
3667 cancelPipe = 1U;
3668 }
3669 else
3670 {
3671 cancelPipe = 0U;
3672 }
3673 }
3674 else
3675 {
3676 cancelPipe = 1U;
3677 }
3678 if (cancelPipe == 1U) /* cancel all pipe */
3679 {
3680 (void)USB_HostEhciQhQtdListDeinit(ehciInstance, ehciPipePointer); /* release all the qtd */
3681 }
3682 else /* cancel one transfer */
3683 {
3684 (void)USB_HostEhciTransferQtdListDeinit(ehciInstance, ehciPipePointer, transfer);
3685 }
3686 break;
3687
3688 #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
3689 ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
3690 case USB_ENDPOINT_ISOCHRONOUS:
3691 isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
3692 if (isoPointer->ehciTransferHead == NULL) /* there is no transfer to cancel */
3693 {
3694 return kStatus_USB_Success;
3695 }
3696 /* cancel all pipe, don't implement canceling transfer for iso */
3697 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
3698 (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
3699 if (speed == USB_SPEED_HIGH)
3700 {
3701 #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
3702 (void)USB_HostEhciItdArrayDeinit(ehciInstance, ehciPipePointer); /* de-initialize itd */
3703 #endif
3704 }
3705 else
3706 {
3707 #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
3708 (void)USB_HostEhciSitdArrayDeinit(ehciInstance, ehciPipePointer); /* de-initialize sitd */
3709 #endif
3710 }
3711 break;
3712 #endif
3713
3714 default:
3715 /*no action*/
3716 break;
3717 }
3718
3719 return kStatus_USB_Success;
3720 }
3721
USB_HostEhciControlBus(usb_host_ehci_instance_t * ehciInstance,uint8_t busControl)3722 static usb_status_t USB_HostEhciControlBus(usb_host_ehci_instance_t *ehciInstance, uint8_t busControl)
3723 {
3724 usb_status_t status = kStatus_USB_Success;
3725 uint32_t portScRegister;
3726 usb_host_bus_control_t controlCode = (usb_host_bus_control_t)busControl;
3727 switch (controlCode)
3728 {
3729 case kUSB_HostBusReset:
3730 /* reset port */
3731 portScRegister = ehciInstance->ehciIpBase->PORTSC1;
3732 portScRegister &= (~EHCI_PORTSC1_W1_BITS);
3733 ehciInstance->ehciIpBase->PORTSC1 = (portScRegister | USBHS_PORTSC1_PR_MASK);
3734 while (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_PR_MASK))
3735 {
3736 }
3737 break;
3738
3739 case kUSB_HostBusRestart:
3740 ehciInstance->deviceAttached = (uint8_t)kEHCIDeviceDetached;
3741 ehciInstance->ehciIpBase->USBINTR |= (USBHS_USBINTR_PCE_MASK); /* enable ehci port change interrupt */
3742 break;
3743
3744 case kUSB_HostBusEnableAttach: /* enable device attach */
3745 if (ehciInstance->deviceAttached == (uint8_t)kEHCIDeviceDetached)
3746 {
3747 ehciInstance->ehciIpBase->USBINTR |= (USBHS_USBINTR_PCE_MASK); /* enable ehci port change interrupt */
3748 }
3749 break;
3750
3751 case kUSB_HostBusDisableAttach: /* disable device attach */
3752 ehciInstance->ehciIpBase->USBINTR &= (~USBHS_USBINTR_PCE_MASK); /* disable ehci port change interrupt */
3753 break;
3754 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
3755 case kUSB_HostBusSuspend:
3756 if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
3757 {
3758 /* set timer1 */
3759 ehciInstance->ehciIpBase->GPTIMER1LD = (1 * 1000); /* 1ms */
3760 ehciInstance->ehciIpBase->GPTIMER1CTL |=
3761 (USBHS_GPTIMER0CTL_RUN_MASK | USBHS_GPTIMER0CTL_MODE_MASK | USBHS_GPTIMER0CTL_RST_MASK);
3762 USB_HostEhciLock();
3763 USB_HostEhciStopAsync(ehciInstance);
3764 USB_HostEhciStopPeriodic(ehciInstance);
3765 USB_HostEhciUnlock();
3766 while (0U != (ehciInstance->ehciIpBase->USBSTS & (USBHS_USBSTS_PS_MASK | USBHS_USBSTS_AS_MASK)))
3767 {
3768 __NOP();
3769 }
3770 ehciInstance->ehciIpBase->PORTSC1 &= ~USBHS_PORTSC1_WKCN_MASK;
3771 ehciInstance->ehciIpBase->PORTSC1 |= USBHS_PORTSC1_WKDS_MASK;
3772 ehciInstance->ehciIpBase->PORTSC1 |= (USBHS_PORTSC1_SUSP_MASK); /* Suspend the device */
3773 #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
3774 PMU->WAKEUP_PM2_MASK1 |= PMU_WAKEUP_PM2_MASK1_USB(1);
3775 #endif
3776 ehciInstance->matchTick = 0U;
3777 ehciInstance->ehciIpBase->USBINTR |= (USBHS_USBINTR_TIE1_MASK);
3778 ehciInstance->busSuspendStatus = kBus_EhciStartSuspend;
3779 }
3780 else
3781 {
3782 status = kStatus_USB_Error;
3783 }
3784 break;
3785 case kUSB_HostBusResume:
3786 ehciInstance->ehciIpBase->PORTSC1 &= ~(USBHS_PORTSC1_SUSP_MASK); /* Clear Suspend bit */
3787 ehciInstance->ehciIpBase->PORTSC1 &= ~USBHS_PORTSC1_PHCD_MASK;
3788 if (ehciInstance->deviceAttached != (uint8_t)kEHCIDeviceDetached)
3789 {
3790 ehciInstance->busSuspendStatus = kBus_EhciStartResume;
3791 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
3792 ehciInstance->registerNcBase->USB_OTGn_CTRL &= ~USBNC_USB_OTGn_CTRL_WIE_MASK;
3793 #else
3794 #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
3795 #else
3796 ehciInstance->ehciIpBase->USBGENCTRL &= ~USBHS_USBGENCTRL_WU_IE_MASK;
3797 #endif
3798 #endif
3799 ehciInstance->ehciIpBase->USBCMD |= (USBHS_USBCMD_RS_MASK);
3800 ehciInstance->ehciIpBase->PORTSC1 |= (USBHS_PORTSC1_FPR_MASK); /* Resume the device */
3801 }
3802 else
3803 {
3804 status = kStatus_USB_Error;
3805 }
3806 break;
3807 #endif
3808 default:
3809 status = kStatus_USB_Error;
3810 break;
3811 }
3812 return status;
3813 }
3814
USB_HostEhciTransactionDone(usb_host_ehci_instance_t * ehciInstance)3815 void USB_HostEhciTransactionDone(usb_host_ehci_instance_t *ehciInstance)
3816 {
3817 /* process async QH */
3818 usb_host_ehci_pipe_t *ehciPipePointer;
3819 usb_host_ehci_pipe_t *ehciClearPipePointer = NULL;
3820 volatile usb_host_ehci_qh_t *vltQhPointer;
3821 volatile usb_host_ehci_qtd_t *vltQtdPointer;
3822 usb_host_transfer_t *transfer;
3823 usb_host_transfer_t *nextTransfer;
3824 uint32_t qtdStatus = 0;
3825 #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
3826 volatile usb_host_ehci_itd_t *vltItdPointer;
3827 uint8_t index = 0;
3828 #endif
3829 #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
3830 volatile usb_host_ehci_sitd_t *vltSitdPointer;
3831 #endif
3832 #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
3833 ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
3834 usb_host_ehci_iso_t *isoPointer;
3835 uint32_t dataLength;
3836 uint32_t speed = 0U;
3837 #endif
3838 void *temp;
3839 uint32_t transferResults;
3840 uint32_t transferOverlayResults;
3841
3842 ehciPipePointer = ehciInstance->ehciRunningPipeList; /* check all the running pipes */
3843 while (ehciPipePointer != NULL)
3844 {
3845 switch (ehciPipePointer->pipeCommon.pipeType)
3846 {
3847 case USB_ENDPOINT_BULK:
3848 case USB_ENDPOINT_INTERRUPT:
3849 case USB_ENDPOINT_CONTROL:
3850 vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh; /* pipe's qh */
3851 transfer = vltQhPointer->ehciTransferHead; /* qh's transfer */
3852 while (transfer != NULL)
3853 {
3854 nextTransfer = transfer->next;
3855 /* normal case */
3856 vltQtdPointer = (volatile usb_host_ehci_qtd_t *)transfer->union2.unitTail;
3857 transferResults = vltQtdPointer->transferResults[0];
3858 transferOverlayResults = vltQhPointer->transferOverlayResults[0];
3859 if ((0U != (transferResults & (EHCI_HOST_QTD_IOC_MASK))) &&
3860 (0U == (transferResults & EHCI_HOST_QTD_STATUS_ACTIVE_MASK))) /* transfer is done */
3861 {
3862 qtdStatus = (transferResults & EHCI_HOST_QTD_STATUS_ERROR_MASK);
3863 transfer->transferSofar =
3864 USB_HostEhciQtdListRelease(ehciInstance, (usb_host_ehci_qtd_t *)(transfer->union1.unitHead),
3865 (usb_host_ehci_qtd_t *)(transfer->union2.unitTail));
3866 transfer->transferSofar = (transfer->transferLength < transfer->transferSofar) ?
3867 0U :
3868 (transfer->transferLength - transfer->transferSofar);
3869
3870 vltQhPointer->ehciTransferHead = transfer->next;
3871 vltQhPointer->timeOutLabel = 0U;
3872 vltQhPointer->timeOutValue = USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE;
3873 if (0U != qtdStatus) /* has errors */
3874 {
3875 if (0U == (transferOverlayResults & EHCI_HOST_QTD_STATUS_ACTIVE_MASK))
3876 {
3877 vltQhPointer->transferOverlayResults[0] &=
3878 (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
3879 }
3880 if (0U != (qtdStatus & EHCI_HOST_QH_STATUS_NOSTALL_ERROR_MASK))
3881 {
3882 /* callback function is different from the current condition */
3883 transfer->callbackFn(transfer->callbackParam, transfer,
3884 kStatus_USB_TransferFailed); /* transfer fail */
3885 }
3886 else
3887 {
3888 /* callback function is different from the current condition */
3889 transfer->callbackFn(transfer->callbackParam, transfer, kStatus_USB_TransferStall);
3890 }
3891 }
3892 else
3893 {
3894 if ((ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_CONTROL) &&
3895 (transfer->setupPacket->bRequest == USB_REQUEST_STANDARD_CLEAR_FEATURE) &&
3896 (transfer->setupPacket->bmRequestType == USB_REQUEST_TYPE_RECIPIENT_ENDPOINT) &&
3897 ((USB_SHORT_FROM_LITTLE_ENDIAN(transfer->setupPacket->wValue) & 0x00FFu) ==
3898 USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT))
3899 {
3900 ehciClearPipePointer = ehciInstance->ehciRunningPipeList;
3901 while (ehciClearPipePointer != NULL)
3902 {
3903 /* only compute bulk and interrupt pipe */
3904 if (((ehciClearPipePointer->pipeCommon.endpointAddress |
3905 (ehciClearPipePointer->pipeCommon.direction
3906 << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) ==
3907 (uint8_t)(USB_SHORT_FROM_LITTLE_ENDIAN(transfer->setupPacket->wIndex))) &&
3908 (ehciClearPipePointer->pipeCommon.deviceHandle ==
3909 ehciPipePointer->pipeCommon.deviceHandle))
3910 {
3911 break;
3912 }
3913 temp = (void *)ehciClearPipePointer->pipeCommon.next;
3914 ehciClearPipePointer = (usb_host_ehci_pipe_t *)temp;
3915 }
3916
3917 if ((ehciClearPipePointer != NULL) &&
3918 ((ehciClearPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT) ||
3919 (ehciClearPipePointer->pipeCommon.pipeType == USB_ENDPOINT_BULK)))
3920 {
3921 ((volatile usb_host_ehci_qh_t *)(ehciClearPipePointer->ehciQh))
3922 ->transferOverlayResults[0] &= (~EHCI_HOST_QTD_DT_MASK);
3923 }
3924 }
3925 /* callback function is different from the current condition */
3926 transfer->callbackFn(transfer->callbackParam, transfer,
3927 kStatus_USB_Success); /* transfer success */
3928 }
3929 }
3930 else if ((0U == (transferOverlayResults & EHCI_HOST_QTD_STATUS_ACTIVE_MASK)) &&
3931 (0U != (transferOverlayResults &
3932 EHCI_HOST_QH_STATUS_ERROR_MASK))) /* there is error and transfer is done */
3933 {
3934 qtdStatus = (vltQhPointer->transferOverlayResults[0] & EHCI_HOST_QH_STATUS_ERROR_MASK);
3935 vltQtdPointer = (volatile usb_host_ehci_qtd_t *)(vltQhPointer->currentQtdPointer);
3936 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3937 vltQtdPointer = (volatile usb_host_ehci_qtd_t *)USB_HOST_MEMORY_DMA_2_CPU(vltQtdPointer);
3938 #endif
3939 if ((0U != ((uint32_t)vltQtdPointer & EHCI_HOST_T_INVALID_VALUE)) ||
3940 (vltQtdPointer == NULL)) /* the error status is unreasonable */
3941 {
3942 vltQhPointer->transferOverlayResults[0] &=
3943 (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
3944 }
3945 else
3946 {
3947 /* remove qtd from qh */
3948 do
3949 {
3950 if (vltQtdPointer == NULL)
3951 {
3952 break;
3953 }
3954 else if (0U != (vltQtdPointer->transferResults[0] & EHCI_HOST_QTD_IOC_MASK))
3955 {
3956 break;
3957 }
3958 else
3959 {
3960 /* no action */
3961 }
3962 vltQtdPointer = (volatile usb_host_ehci_qtd_t *)vltQtdPointer->nextQtdPointer;
3963 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3964 vltQtdPointer =
3965 (volatile usb_host_ehci_qtd_t *)USB_HOST_MEMORY_DMA_2_CPU(vltQtdPointer);
3966 #endif
3967 } while (true);
3968
3969 vltQhPointer->nextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
3970 vltQhPointer->currentQtdPointer = EHCI_HOST_T_INVALID_VALUE;
3971 vltQhPointer->transferOverlayResults[0] &=
3972 (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
3973 if (vltQtdPointer != NULL)
3974 {
3975 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3976 vltQhPointer->nextQtdPointer =
3977 (uint32_t)USB_HOST_MEMORY_DMA_2_CPU(vltQtdPointer->nextQtdPointer);
3978 #else
3979 vltQhPointer->nextQtdPointer = vltQtdPointer->nextQtdPointer;
3980 #endif
3981 }
3982
3983 transfer->transferSofar = USB_HostEhciQtdListRelease(
3984 ehciInstance, (usb_host_ehci_qtd_t *)(transfer->union1.unitHead),
3985 (usb_host_ehci_qtd_t *)(transfer->union2.unitTail));
3986 transfer->transferSofar = (transfer->transferLength < transfer->transferSofar) ?
3987 0U :
3988 (transfer->transferLength - transfer->transferSofar);
3989 vltQhPointer->ehciTransferHead = transfer->next;
3990 vltQhPointer->timeOutLabel = 0U;
3991 vltQhPointer->timeOutValue = USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE;
3992 if (0U != (qtdStatus & EHCI_HOST_QH_STATUS_NOSTALL_ERROR_MASK))
3993 {
3994 /* callback function is different from the current condition */
3995 transfer->callbackFn(transfer->callbackParam, transfer,
3996 kStatus_USB_TransferFailed); /* transfer fail */
3997 }
3998 else
3999 {
4000 /* callback function is different from the current condition */
4001 transfer->callbackFn(transfer->callbackParam, transfer,
4002 kStatus_USB_TransferStall); /* transfer stall */
4003 }
4004 }
4005 }
4006 else
4007 {
4008 break;
4009 }
4010 transfer = nextTransfer;
4011 }
4012 break;
4013 #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
4014 ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
4015 case USB_ENDPOINT_ISOCHRONOUS:
4016 qtdStatus = 0; /* qtdStatus means break here, because there is only one break in while for misra */
4017 isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh; /* pipe's usb_host_ehci_iso_t */
4018 transfer = isoPointer->ehciTransferHead; /* usb_host_ehci_iso_t's transfer */
4019 while (transfer != NULL)
4020 {
4021 nextTransfer = transfer->next;
4022 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
4023 (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
4024 if (speed == USB_SPEED_HIGH)
4025 {
4026 #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
4027 vltItdPointer =
4028 (volatile usb_host_ehci_itd_t *)(transfer->union2.unitTail); /* transfer's last itd */
4029 for (index = 0; index < 8U; ++index)
4030 {
4031 if (0U != (vltItdPointer->transactions[index] & EHCI_HOST_ITD_STATUS_ACTIVE_MASK))
4032 {
4033 break;
4034 }
4035 }
4036 if (index == 8U) /* transfer is done */
4037 {
4038 /* remove itd from frame list and release itd */
4039 dataLength = USB_HostEhciItdArrayRelease(ehciInstance,
4040 (usb_host_ehci_itd_t *)transfer->union1.unitHead,
4041 (usb_host_ehci_itd_t *)transfer->union2.unitTail);
4042 transfer->transferSofar = dataLength;
4043 isoPointer->ehciTransferHead = transfer->next;
4044 /* callback function is different from the current condition */
4045 transfer->callbackFn(transfer->callbackParam, transfer,
4046 kStatus_USB_Success); /* transfer callback success */
4047 /* TODO: iso callback error */
4048 }
4049 else
4050 {
4051 qtdStatus = 1U; /* break */
4052 }
4053 #endif
4054 }
4055 else
4056 {
4057 #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
4058 vltSitdPointer =
4059 (volatile usb_host_ehci_sitd_t *)(transfer->union2.unitTail); /* transfer's last sitd */
4060 if (0U == (vltSitdPointer->transferResults[0] &
4061 EHCI_HOST_SITD_STATUS_ACTIVE_MASK)) /* transfer is done */
4062 {
4063 /* remove sitd from frame list and release itd */
4064 dataLength = USB_HostEhciSitdArrayRelease(
4065 ehciInstance, (usb_host_ehci_sitd_t *)transfer->union1.unitHead,
4066 (usb_host_ehci_sitd_t *)transfer->union2.unitTail);
4067 transfer->transferSofar = transfer->transferLength - dataLength;
4068 isoPointer->ehciTransferHead = transfer->next;
4069 /* callback function is different from the current condition */
4070 transfer->callbackFn(transfer->callbackParam, transfer,
4071 kStatus_USB_Success); /* transfer callback success */
4072 /* TODO: iso callback error */
4073 }
4074 else
4075 {
4076 qtdStatus = 1U; /* break */
4077 }
4078 #endif
4079 }
4080 if (qtdStatus == 1U)
4081 {
4082 break;
4083 }
4084 transfer = nextTransfer;
4085 }
4086 break;
4087 #endif
4088
4089 default:
4090 /*no action*/
4091 break;
4092 }
4093 temp = (void *)ehciPipePointer->pipeCommon.next;
4094 ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
4095 }
4096 }
4097
USB_HostEhciPortChange(usb_host_ehci_instance_t * ehciInstance)4098 static void USB_HostEhciPortChange(usb_host_ehci_instance_t *ehciInstance)
4099 {
4100 /* note: only has one port */
4101 uint32_t portScRegister = ehciInstance->ehciIpBase->PORTSC1;
4102 uint32_t sofStart = 0;
4103 uint32_t sofCount = 0;
4104 uint32_t index;
4105
4106 if (0U != (portScRegister & USBHS_PORTSC1_CSC_MASK)) /* connection status change */
4107 {
4108 sofStart = (ehciInstance->ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE);
4109
4110 /* process CSC bit */
4111 while (1U == 1U)
4112 {
4113 portScRegister = ehciInstance->ehciIpBase->PORTSC1;
4114 if (0U != (portScRegister & USBHS_PORTSC1_CSC_MASK))
4115 {
4116 /* clear csc bit */
4117 portScRegister = ehciInstance->ehciIpBase->PORTSC1;
4118 portScRegister &= (~EHCI_PORTSC1_W1_BITS);
4119 ehciInstance->ehciIpBase->PORTSC1 = (portScRegister | USBHS_PORTSC1_CSC_MASK);
4120 }
4121 sofCount = (ehciInstance->ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE);
4122 if (((sofCount + EHCI_MAX_UFRAME_VALUE + 1U - sofStart) & EHCI_MAX_UFRAME_VALUE) >
4123 (1U * 8U)) /* delay 1ms to clear CSC */
4124 {
4125 break;
4126 }
4127 }
4128 }
4129
4130 /* process CCS bit */
4131 portScRegister = ehciInstance->ehciIpBase->PORTSC1;
4132 if (0U != (portScRegister & USBHS_PORTSC1_CCS_MASK)) /* process attach */
4133 {
4134 if ((ehciInstance->deviceAttached == (uint8_t)kEHCIDevicePhyAttached) ||
4135 (ehciInstance->deviceAttached == (uint8_t)kEHCIDeviceAttached))
4136 {
4137 return;
4138 }
4139 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
4140 ehciInstance->busSuspendStatus = kBus_EhciIdle;
4141 ehciInstance->ehciIpBase->USBINTR &= ~(USBHS_USBINTR_TIE1_MASK);
4142 #endif
4143 for (index = 0; index < USB_HOST_EHCI_PORT_CONNECT_DEBOUNCE_DELAY; ++index)
4144 {
4145 USB_HostEhciDelay(ehciInstance->ehciIpBase, 1);
4146 if (0U == (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
4147 {
4148 break;
4149 }
4150 }
4151 if (index < USB_HOST_EHCI_PORT_CONNECT_DEBOUNCE_DELAY) /* CCS is cleared */
4152 {
4153 ehciInstance->deviceAttached = (uint8_t)kEHCIDeviceDetached;
4154 return;
4155 }
4156 /* reset port */
4157 portScRegister = ehciInstance->ehciIpBase->PORTSC1;
4158 portScRegister &= (~EHCI_PORTSC1_W1_BITS);
4159 ehciInstance->ehciIpBase->PORTSC1 = (portScRegister | USBHS_PORTSC1_PR_MASK);
4160 while (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_PR_MASK))
4161 {
4162 }
4163 ehciInstance->firstDeviceSpeed =
4164 (uint8_t)((ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_PSPD_MASK) >> USBHS_PORTSC1_PSPD_SHIFT);
4165 /* enable ehci phy disconnection */
4166 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
4167 if (ehciInstance->firstDeviceSpeed == USB_SPEED_HIGH)
4168 {
4169 USB_EhcihostPhyDisconnectDetectCmd(ehciInstance->controllerId, 1);
4170 }
4171 #endif
4172
4173 /* wait for reset */
4174 USB_HostEhciDelay(ehciInstance->ehciIpBase, USB_HOST_EHCI_PORT_RESET_DELAY);
4175 /* process attach */
4176 (void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_DEVICE_ATTACH);
4177 /* gpt timer start */
4178 ehciInstance->ehciIpBase->GPTIMER0CTL |=
4179 (USBHS_GPTIMER0CTL_RUN_MASK | USBHS_GPTIMER0CTL_MODE_MASK | USBHS_GPTIMER0CTL_RST_MASK);
4180 ehciInstance->deviceAttached = (uint8_t)kEHCIDevicePhyAttached;
4181 }
4182 else
4183 {
4184 if ((ehciInstance->deviceAttached == (uint8_t)kEHCIDevicePhyAttached) ||
4185 (ehciInstance->deviceAttached == (uint8_t)kEHCIDeviceAttached))
4186 {
4187 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
4188 ehciInstance->busSuspendStatus = kBus_EhciIdle;
4189 ehciInstance->ehciIpBase->USBINTR &= ~(USBHS_USBINTR_TIE1_MASK);
4190 #endif
4191 /* disable ehci phy disconnection */
4192 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
4193 USB_EhcihostPhyDisconnectDetectCmd(ehciInstance->controllerId, 0);
4194 #endif
4195 USB_HostEhciLock();
4196 /* disable async and periodic */
4197 USB_HostEhciStopAsync(ehciInstance);
4198 USB_HostEhciStopPeriodic(ehciInstance);
4199 USB_HostEhciUnlock();
4200 (void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_DEVICE_DETACH);
4201 }
4202 }
4203 }
4204
USB_HostEhciTimer0(usb_host_ehci_instance_t * ehciInstance)4205 static void USB_HostEhciTimer0(usb_host_ehci_instance_t *ehciInstance)
4206 {
4207 volatile usb_host_ehci_qh_t *vltQhPointer;
4208 usb_host_ehci_qtd_t *vltQtdPointer;
4209 usb_host_transfer_t *transfer;
4210 uint32_t backValue;
4211 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
4212 uint32_t convert_addr = 0U;
4213 #endif
4214 volatile uint32_t *totalBytesAddress = NULL;
4215 usb_host_ehci_pipe_t *ehciPipePointer = ehciInstance->ehciRunningPipeList;
4216 void *temp;
4217 uint8_t timeoutLabel;
4218
4219 while (ehciPipePointer != NULL)
4220 {
4221 switch (ehciPipePointer->pipeCommon.pipeType)
4222 {
4223 case USB_ENDPOINT_BULK:
4224 case USB_ENDPOINT_CONTROL:
4225 vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh; /* pipe's qh */
4226 transfer = vltQhPointer->ehciTransferHead; /* qh's transfer */
4227 if ((transfer != NULL)) /* there is transfering data */
4228 {
4229 timeoutLabel = 0U;
4230 if (ehciInstance->deviceAttached != (uint8_t)kEHCIDeviceAttached)
4231 {
4232 vltQtdPointer = (usb_host_ehci_qtd_t *)transfer->union2.unitTail;
4233
4234 vltQhPointer->nextQtdPointer = EHCI_HOST_T_INVALID_VALUE; /* invalid next qtd */
4235 vltQhPointer->transferOverlayResults[0] &=
4236 (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
4237 timeoutLabel = 1;
4238 }
4239 else
4240 {
4241 if (0U != (vltQhPointer->transferOverlayResults[0] & EHCI_HOST_QTD_STATUS_ACTIVE_MASK))
4242 {
4243 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
4244 vltQtdPointer =
4245 (usb_host_ehci_qtd_t *)USB_HOST_MEMORY_DMA_2_CPU(vltQhPointer->currentQtdPointer);
4246 #else
4247 vltQtdPointer = (usb_host_ehci_qtd_t *)vltQhPointer->currentQtdPointer;
4248 #endif
4249 totalBytesAddress = &(vltQhPointer->transferOverlayResults[0]);
4250 }
4251 else
4252 {
4253 vltQtdPointer = (usb_host_ehci_qtd_t *)transfer->union2.unitTail;
4254 totalBytesAddress = &(vltQtdPointer->transferResults[0]);
4255 }
4256
4257 backValue =
4258 (((*totalBytesAddress) & EHCI_HOST_QTD_TOTAL_BYTES_MASK) >>
4259 EHCI_HOST_QTD_TOTAL_BYTES_SHIFT); /* backValue is used for total bytes to transfer */
4260 if (vltQhPointer->timeOutLabel != backValue) /* use total bytes to reflect the time out */
4261 {
4262 vltQhPointer->timeOutValue = USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE;
4263 vltQhPointer->timeOutLabel = (uint16_t)backValue;
4264 }
4265 else
4266 {
4267 /* time out when the total bytes don't change for the duration
4268 * USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE
4269 */
4270 (vltQhPointer->timeOutValue)--;
4271 if (vltQhPointer->timeOutValue == 0U)
4272 {
4273 USB_HostEhciLock();
4274 /* stop the qh schedule */
4275 USB_HostEhciStopAsync(ehciInstance);
4276 if (backValue != (((*totalBytesAddress) & EHCI_HOST_QTD_TOTAL_BYTES_MASK) >>
4277 EHCI_HOST_QTD_TOTAL_BYTES_SHIFT))
4278 {
4279 USB_HostEhciStartAsync(ehciInstance);
4280 }
4281 else
4282 {
4283 vltQhPointer->nextQtdPointer = EHCI_HOST_T_INVALID_VALUE; /* invalid next qtd */
4284 vltQhPointer->transferOverlayResults[0] &=
4285 (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
4286 USB_HostEhciStartAsync(ehciInstance);
4287 timeoutLabel = 1U;
4288 }
4289 USB_HostEhciUnlock();
4290 }
4291 }
4292 }
4293
4294 if (timeoutLabel == 1U)
4295 {
4296 /* remove qtd from qh */
4297 temp = (void *)vltQhPointer->ehciTransferTail;
4298 while ((vltQtdPointer != NULL) &&
4299 (0U == (vltQtdPointer->transferResults[0] & EHCI_HOST_QTD_IOC_MASK)) &&
4300 (vltQtdPointer != (usb_host_ehci_qtd_t *)temp))
4301 {
4302 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
4303 vltQtdPointer =
4304 (usb_host_ehci_qtd_t *)USB_HOST_MEMORY_DMA_2_CPU(vltQtdPointer->nextQtdPointer);
4305 #else
4306 vltQtdPointer = (usb_host_ehci_qtd_t *)vltQtdPointer->nextQtdPointer;
4307 #endif
4308 }
4309 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
4310 convert_addr = (uint32_t)USB_HOST_MEMORY_DMA_2_CPU(vltQtdPointer->nextQtdPointer);
4311 if ((vltQtdPointer != NULL) && (0U == (convert_addr & EHCI_HOST_T_INVALID_VALUE)))
4312 {
4313 vltQhPointer->nextQtdPointer = convert_addr; /* start qh if there are other qtd that don't
4314 belong to the transfer */
4315 }
4316 #else
4317 if ((vltQtdPointer != NULL) &&
4318 (0U == (vltQtdPointer->nextQtdPointer & EHCI_HOST_T_INVALID_VALUE)))
4319 {
4320 vltQhPointer->nextQtdPointer =
4321 vltQtdPointer->nextQtdPointer; /* start qh if there are other qtd that don't belong to
4322 the transfer */
4323 }
4324 #endif
4325 transfer->transferSofar =
4326 USB_HostEhciQtdListRelease(ehciInstance, (usb_host_ehci_qtd_t *)(transfer->union1.unitHead),
4327 (usb_host_ehci_qtd_t *)(transfer->union2.unitTail));
4328 transfer->transferSofar = (transfer->transferLength < transfer->transferSofar) ?
4329 0U :
4330 (transfer->transferLength - transfer->transferSofar);
4331
4332 vltQhPointer->ehciTransferHead = transfer->next;
4333 vltQhPointer->timeOutValue = USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE;
4334 /* callback function is different from the current condition */
4335 transfer->callbackFn(transfer->callbackParam, transfer, kStatus_USB_TransferFailed);
4336 }
4337 }
4338 break;
4339 default:
4340 /*no action*/
4341 break;
4342 }
4343 temp = (void *)ehciPipePointer->pipeCommon.next;
4344 ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
4345 }
4346 }
4347
4348 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
USB_HostEhciTimer1(usb_host_ehci_instance_t * ehciInstance)4349 static void USB_HostEhciTimer1(usb_host_ehci_instance_t *ehciInstance)
4350 {
4351 if (ehciInstance->deviceAttached != (uint8_t)kEHCIDeviceDetached)
4352 {
4353 if (kBus_EhciStartSuspend == ehciInstance->busSuspendStatus)
4354 {
4355 usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
4356
4357 if (0U == ehciInstance->matchTick)
4358 {
4359 ehciInstance->matchTick = hostPointer->hwTick;
4360 }
4361 else
4362 {
4363 if ((hostPointer->hwTick - ehciInstance->matchTick) >= 5U)
4364 {
4365 ehciInstance->ehciIpBase->USBCMD &= ~USBHS_USBCMD_RS_MASK;
4366 ehciInstance->ehciIpBase->USBSTS |= USBHS_USBSTS_SRI_MASK;
4367 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
4368 #if 0
4369 ehciInstance->registerPhyBase->CTRL |= USBPHY_CTRL_ENVBUSCHG_WKUP_MASK
4370 | USBPHY_CTRL_ENIDCHG_WKUP_MASK
4371 | USBPHY_CTRL_ENDPDMCHG_WKUP_MASK
4372 | USBPHY_CTRL_ENIRQRESUMEDETECT_MASK
4373 ;
4374 #endif
4375 #endif
4376 #if (defined(FSL_FEATURE_USBPHY_28FDSOI) && (FSL_FEATURE_USBPHY_28FDSOI > 0U))
4377 ehciInstance->registerPhyBase->USB1_VBUS_DETECT_SET |=
4378 USBPHY_USB1_VBUS_DETECT_VBUSVALID_TO_SESSVALID_MASK;
4379 #endif
4380 ehciInstance->ehciIpBase->PORTSC1 |= USBHS_PORTSC1_PHCD_MASK;
4381 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
4382 ehciInstance->registerPhyBase->PWD = 0xFFFFFFFFU;
4383
4384 while (0U != (ehciInstance->registerPhyBase->CTRL & (USBPHY_CTRL_UTMI_SUSPENDM_MASK)))
4385 {
4386 __NOP();
4387 }
4388 #endif
4389 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
4390 ehciInstance->registerNcBase->USB_OTGn_CTRL |= USBNC_USB_OTGn_CTRL_WKUP_ID_EN_MASK |
4391 USBNC_USB_OTGn_CTRL_WKUP_VBUS_EN_MASK |
4392 USBNC_USB_OTGn_CTRL_WKUP_DPDM_EN_MASK;
4393 ehciInstance->registerNcBase->USB_OTGn_CTRL |= USBNC_USB_OTGn_CTRL_WIE_MASK;
4394 #else
4395 #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
4396 #else
4397 ehciInstance->ehciIpBase->USBGENCTRL = USBHS_USBGENCTRL_WU_IE_MASK;
4398 #endif
4399 #endif
4400 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
4401 ehciInstance->registerPhyBase->CTRL |= USBPHY_CTRL_CLKGATE_MASK;
4402 #endif
4403 (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
4404 kUSB_HostEventSuspended); /* call host callback function */
4405 ehciInstance->busSuspendStatus = kBus_EhciSuspended;
4406 }
4407 }
4408 }
4409 else if (kBus_EhciStartResume == ehciInstance->busSuspendStatus)
4410 {
4411 usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
4412 if (0U == (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_FPR_MASK))
4413 {
4414 ehciInstance->ehciIpBase->PORTSC1 &= ~USBHS_PORTSC1_WKDS_MASK;
4415 if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
4416 {
4417 USB_HostEhciLock();
4418 USB_HostEhciStartAsync(ehciInstance);
4419 USB_HostEhciStartPeriodic(ehciInstance);
4420 USB_HostEhciUnlock();
4421 }
4422 (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
4423 kUSB_HostEventResumed); /* call host callback function */
4424 hostPointer->suspendedDevice = NULL;
4425 ehciInstance->busSuspendStatus = kBus_EhciIdle;
4426 ehciInstance->ehciIpBase->USBINTR &= ~(USBHS_USBINTR_TIE1_MASK);
4427 }
4428 }
4429 else
4430 {
4431 }
4432 }
4433 else
4434 {
4435 ehciInstance->busSuspendStatus = kBus_EhciIdle;
4436 ehciInstance->ehciIpBase->USBINTR &= ~(USBHS_USBINTR_TIE1_MASK);
4437 }
4438 }
4439 #endif
4440
USB_HostEhciCreate(uint8_t controllerId,usb_host_handle upperLayerHandle,usb_host_controller_handle * controllerHandle)4441 usb_status_t USB_HostEhciCreate(uint8_t controllerId,
4442 usb_host_handle upperLayerHandle,
4443 usb_host_controller_handle *controllerHandle)
4444 {
4445 uint32_t index = 0;
4446 osa_status_t osaStatus;
4447 usb_host_ehci_instance_t *ehciInstance;
4448 #if defined(USBHS_STACK_BASE_ADDRS)
4449 uint32_t usbhsBaseAddrs[] = USBHS_STACK_BASE_ADDRS;
4450 #else
4451 uint32_t usbhsBaseAddrs[] = USBHS_BASE_ADDRS;
4452 #endif
4453 usb_host_ehci_data_t *usbHostEhciData[USB_HOST_CONFIG_EHCI];
4454 uint32_t *framePointer;
4455 void *temp;
4456 uint8_t instanceIndex = 0U;
4457
4458 if ((controllerId - (uint8_t)kUSB_ControllerEhci0) >= (sizeof(usbhsBaseAddrs) / sizeof(usbhsBaseAddrs[0])))
4459 {
4460 return kStatus_USB_ControllerNotFound;
4461 }
4462
4463 *controllerHandle = NULL;
4464 ehciInstance = (usb_host_ehci_instance_t *)OSA_MemoryAllocate(
4465 sizeof(usb_host_ehci_instance_t)); /* malloc host ehci instance */
4466 if (ehciInstance == NULL)
4467 {
4468 return kStatus_USB_AllocFail;
4469 }
4470 ehciInstance->controllerId = controllerId;
4471 ehciInstance->hostHandle = upperLayerHandle;
4472 ehciInstance->deviceAttached = (uint8_t)kEHCIDeviceDetached;
4473 ehciInstance->ehciIpBase = (USBHS_Type *)
4474 usbhsBaseAddrs[controllerId - (uint8_t)kUSB_ControllerEhci0]; /* operate ehci ip through the base address */
4475 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
4476 ehciInstance->busSuspendStatus = kBus_EhciIdle;
4477
4478 #if (defined(USB_HOST_CONFIG_LOW_POWER_MODE) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
4479 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
4480 ehciInstance->registerPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
4481 #endif
4482 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
4483 ehciInstance->registerNcBase = (USBNC_Type *)USB_EhciNCGetBase(controllerId);
4484 #endif
4485
4486 #endif
4487
4488 #endif
4489
4490 if ((USB_HostEhciResetIP(ehciInstance) != kStatus_USB_Success) ||
4491 ((ehciInstance->controllerId < (uint8_t)kUSB_ControllerEhci0))) /* reset ehci ip */
4492 {
4493 OSA_MemoryFree(ehciInstance);
4494 return kStatus_USB_Error;
4495 }
4496
4497 #if (USB_HOST_CONFIG_EHCI == 1U)
4498 if (0U == usbHostEhciFramListStatus[0])
4499 {
4500 usbHostEhciFramListStatus[0] = 1U;
4501 instanceIndex = 0U;
4502 ehciInstance->ehciFrameList = &s_UsbHostEhciFrameList1[0];
4503 }
4504 #elif (USB_HOST_CONFIG_EHCI == 2U)
4505 if (0U == usbHostEhciFramListStatus[0])
4506 {
4507 usbHostEhciFramListStatus[0] = 1U;
4508 instanceIndex = 0U;
4509 ehciInstance->ehciFrameList = &s_UsbHostEhciFrameList1[0];
4510 }
4511 else if (0U == usbHostEhciFramListStatus[1])
4512 {
4513 usbHostEhciFramListStatus[1] = 1U;
4514 instanceIndex = 1U;
4515 ehciInstance->ehciFrameList = &s_UsbHostEhciFrameList2[0];
4516 }
4517 else
4518 {
4519 /*no action*/
4520 }
4521 #endif
4522 if (ehciInstance->ehciFrameList == NULL)
4523 {
4524 OSA_MemoryFree(ehciInstance);
4525 return kStatus_USB_Error;
4526 }
4527
4528 #if (USB_HOST_CONFIG_EHCI == 1U)
4529 usbHostEhciData[0] = &s_UsbHostEhciData1;
4530 #elif (USB_HOST_CONFIG_EHCI == 2U)
4531 usbHostEhciData[0] = &s_UsbHostEhciData1;
4532 usbHostEhciData[1] = &s_UsbHostEhciData2;
4533 #else
4534 #error "Please increase the instance count."
4535 #endif
4536
4537 temp = (void *)usbHostEhciData[instanceIndex];
4538 ehciInstance->ehciUnitBase = (uint32_t *)(temp);
4539 /* initialize qh/qtd/itd/sitd/iso list */
4540 ehciInstance->ehciQhList = (usb_host_ehci_qh_t *)((uint32_t)(ehciInstance->ehciUnitBase));
4541 ehciInstance->ehciQtdHead = (usb_host_ehci_qtd_t *)((uint32_t)ehciInstance->ehciQhList +
4542 (sizeof(usb_host_ehci_qh_t) * USB_HOST_CONFIG_EHCI_MAX_QH));
4543 ehciInstance->ehciItdList = (usb_host_ehci_itd_t *)((uint32_t)ehciInstance->ehciQtdHead +
4544 (sizeof(usb_host_ehci_qtd_t) * USB_HOST_CONFIG_EHCI_MAX_QTD));
4545 #if ((defined(USB_HOST_CONFIG_EHCI_MAX_ITD)) && (USB_HOST_CONFIG_EHCI_MAX_ITD > 0U))
4546 /* If one ITD's first 32 bytes and next 32 bytes are in different 4K region,
4547 * the ITD need move 32 bytes because the ITD cannot cross over 4K boundary.
4548 */
4549 index = ((((((uint32_t)(ehciInstance->ehciItdList)) + 4095U) & 0xFFFFF000U) -
4550 ((uint32_t)(ehciInstance->ehciItdList))) >>
4551 5U);
4552 if (((index / 3U) < USB_HOST_CONFIG_EHCI_MAX_ITD) && ((index % 3U) == 1U))
4553 {
4554 ehciInstance->ehciItdList = (usb_host_ehci_itd_t *)(((uint32_t)(ehciInstance->ehciItdList)) + 32U);
4555 }
4556 #endif
4557 ehciInstance->ehciSitdIndexBase =
4558 (usb_host_ehci_sitd_t *)((uint32_t)ehciInstance->ehciItdList +
4559 (sizeof(usb_host_ehci_itd_t) * USB_HOST_CONFIG_EHCI_MAX_ITD));
4560 ehciInstance->ehciSitdList = ehciInstance->ehciSitdIndexBase;
4561 ehciInstance->ehciIsoList = (usb_host_ehci_iso_t *)((uint32_t)ehciInstance->ehciSitdList +
4562 (sizeof(usb_host_ehci_sitd_t) * USB_HOST_CONFIG_EHCI_MAX_SITD));
4563 ehciInstance->ehciPipeIndexBase =
4564 (usb_host_ehci_pipe_t *)((uint32_t)ehciInstance->ehciIsoList +
4565 (sizeof(usb_host_ehci_iso_t) * USB_HOST_EHCI_ISO_NUMBER));
4566 for (index = 1U; index < USB_HOST_CONFIG_EHCI_MAX_QH; ++index)
4567 {
4568 ehciInstance->ehciQhList[index - 1U].horizontalLinkPointer = (uint32_t)(&ehciInstance->ehciQhList[index]);
4569 }
4570 ehciInstance->ehciQhList[USB_HOST_CONFIG_EHCI_MAX_QH - 1U].horizontalLinkPointer = 0U;
4571 for (index = 1; index < USB_HOST_CONFIG_EHCI_MAX_QTD; ++index)
4572 {
4573 ehciInstance->ehciQtdHead[index - 1U].nextQtdPointer = (uint32_t)(&ehciInstance->ehciQtdHead[index]);
4574 }
4575 ehciInstance->ehciQtdNumber = USB_HOST_CONFIG_EHCI_MAX_QTD;
4576 ehciInstance->ehciQtdHead[USB_HOST_CONFIG_EHCI_MAX_QTD - 1U].nextQtdPointer = 0U;
4577 ehciInstance->ehciQtdTail = &ehciInstance->ehciQtdHead[USB_HOST_CONFIG_EHCI_MAX_QTD - 1U];
4578
4579 #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
4580 for (index = 1; index < USB_HOST_CONFIG_EHCI_MAX_ITD; ++index)
4581 {
4582 ehciInstance->ehciItdList[index - 1U].nextItdPointer =
4583 (usb_host_ehci_itd_t *)(&ehciInstance->ehciItdList[index]);
4584 }
4585 ehciInstance->ehciItdNumber = USB_HOST_CONFIG_EHCI_MAX_ITD;
4586 ehciInstance->ehciItdList[USB_HOST_CONFIG_EHCI_MAX_ITD - 1U].nextItdPointer = NULL;
4587 #endif /* USB_HOST_CONFIG_EHCI_MAX_ITD */
4588
4589 #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
4590 for (index = 1; index < USB_HOST_CONFIG_EHCI_MAX_SITD; ++index)
4591 {
4592 ehciInstance->ehciSitdList[index - 1U].nextLinkPointer = (uint32_t)(&ehciInstance->ehciSitdList[index]);
4593 }
4594 ehciInstance->ehciSitdNumber = USB_HOST_CONFIG_EHCI_MAX_SITD;
4595 ehciInstance->ehciSitdList[USB_HOST_CONFIG_EHCI_MAX_SITD - 1U].nextLinkPointer = 0U;
4596 #endif /* USB_HOST_CONFIG_EHCI_MAX_SITD */
4597
4598 #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
4599 for (index = 1; index < USB_HOST_EHCI_ISO_NUMBER; ++index)
4600 {
4601 ehciInstance->ehciIsoList[index - 1U].next = &ehciInstance->ehciIsoList[index];
4602 }
4603 ehciInstance->ehciIsoList[USB_HOST_EHCI_ISO_NUMBER - 1U].next = NULL;
4604 #endif
4605
4606 /* initialize pipes */
4607 ehciInstance->ehciPipeList = ehciInstance->ehciPipeIndexBase;
4608 for (index = 1; index < USB_HOST_CONFIG_MAX_PIPES; ++index)
4609 {
4610 temp = (void *)&ehciInstance->ehciPipeList[index];
4611 ehciInstance->ehciPipeList[index - 1U].pipeCommon.next = (usb_host_pipe_t *)temp;
4612 }
4613 /* initialize mutext */
4614 ehciInstance->ehciMutex = (osa_mutex_handle_t)(&ehciInstance->mutexBuffer[0]);
4615 osaStatus = OSA_MutexCreate(ehciInstance->ehciMutex);
4616 if (osaStatus != KOSA_StatusSuccess)
4617 {
4618 #ifdef HOST_ECHO
4619 usb_echo("ehci mutex init fail\r\n");
4620 #endif
4621 OSA_MemoryFree(ehciInstance);
4622 return kStatus_USB_Error;
4623 }
4624 /* initialize task event */
4625 ehciInstance->taskEventHandle = (osa_event_handle_t)&ehciInstance->taskEventHandleBuffer[0];
4626 osaStatus = OSA_EventCreate(ehciInstance->taskEventHandle, 1);
4627 if (osaStatus != KOSA_StatusSuccess)
4628 {
4629 #ifdef HOST_ECHO
4630 usb_echo("ehci event init fail\r\n");
4631 #endif
4632 (void)OSA_MutexDestroy(ehciInstance->ehciMutex);
4633 OSA_MemoryFree(ehciInstance);
4634 return kStatus_USB_Error;
4635 }
4636
4637 /* initialize first qh */
4638 ehciInstance->shedFirstQh = ehciInstance->ehciQhList;
4639 ehciInstance->ehciQhList =
4640 (usb_host_ehci_qh_t *)(ehciInstance->ehciQhList->horizontalLinkPointer & EHCI_HOST_POINTER_ADDRESS_MASK);
4641 ehciInstance->shedFirstQh->staticEndpointStates[0] |= (1UL << EHCI_HOST_QH_H_SHIFT); /* first qh */
4642 ehciInstance->shedFirstQh->horizontalLinkPointer = EHCI_HOST_T_INVALID_VALUE;
4643 ehciInstance->shedFirstQh->currentQtdPointer = EHCI_HOST_T_INVALID_VALUE;
4644 ehciInstance->shedFirstQh->nextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
4645 ehciInstance->shedFirstQh->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
4646 ehciInstance->shedFirstQh->horizontalLinkPointer =
4647 (uint32_t)((uint32_t)(ehciInstance->shedFirstQh) | EHCI_HOST_POINTER_TYPE_QH);
4648
4649 /* initialize periodic list */
4650 temp = (void *)ehciInstance->ehciFrameList;
4651 framePointer = (uint32_t *)temp;
4652 for (index = 0; index < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE; ++index)
4653 {
4654 framePointer[index] = EHCI_HOST_T_INVALID_VALUE;
4655 }
4656
4657 (void)USB_HostEhciStartIP(ehciInstance); /* start ehci ip */
4658
4659 *controllerHandle = ehciInstance;
4660
4661 return kStatus_USB_Success;
4662 }
4663
USB_HostEhciDestory(usb_host_controller_handle controllerHandle)4664 usb_status_t USB_HostEhciDestory(usb_host_controller_handle controllerHandle)
4665 {
4666 usb_host_ehci_instance_t *ehciInstance = (usb_host_ehci_instance_t *)controllerHandle;
4667
4668 /* disable all interrupts */
4669 ehciInstance->ehciIpBase->USBINTR = 0;
4670 /* stop the controller */
4671 ehciInstance->ehciIpBase->USBCMD = 0;
4672 /* free memory */
4673 #if (USB_HOST_CONFIG_EHCI == 1U)
4674 if (ehciInstance->ehciFrameList == &s_UsbHostEhciFrameList1[0])
4675 {
4676 usbHostEhciFramListStatus[0] = 0;
4677 }
4678 #elif (USB_HOST_CONFIG_EHCI == 2U)
4679 if (ehciInstance->ehciFrameList == &s_UsbHostEhciFrameList1[0])
4680 {
4681 usbHostEhciFramListStatus[0] = 0;
4682 }
4683 else if (ehciInstance->ehciFrameList == &s_UsbHostEhciFrameList2[0])
4684 {
4685 usbHostEhciFramListStatus[1] = 0;
4686 }
4687 else
4688 {
4689 /*no action*/
4690 }
4691 #endif
4692 (void)OSA_MutexDestroy(ehciInstance->ehciMutex);
4693 (void)OSA_EventDestroy(ehciInstance->taskEventHandle);
4694 OSA_MemoryFree(ehciInstance);
4695
4696 return kStatus_USB_Success;
4697 }
4698
USB_HostEhciOpenPipe(usb_host_controller_handle controllerHandle,usb_host_pipe_handle * pipeHandle,usb_host_pipe_init_t * pipeInit)4699 usb_status_t USB_HostEhciOpenPipe(usb_host_controller_handle controllerHandle,
4700 usb_host_pipe_handle *pipeHandle,
4701 usb_host_pipe_init_t *pipeInit)
4702 {
4703 usb_host_ehci_pipe_t *ehciPipePointer = NULL;
4704 usb_status_t status;
4705 uint32_t speed = 0;
4706 usb_host_ehci_instance_t *ehciInstance = (usb_host_ehci_instance_t *)controllerHandle;
4707 void *temp;
4708 /* get one pipe */
4709 USB_HostEhciLock();
4710 if (ehciInstance->ehciPipeList != NULL)
4711 {
4712 ehciPipePointer = ehciInstance->ehciPipeList;
4713 temp = (void *)ehciPipePointer->pipeCommon.next;
4714 ehciInstance->ehciPipeList = (usb_host_ehci_pipe_t *)temp;
4715 }
4716 USB_HostEhciUnlock();
4717 if (ehciPipePointer == NULL)
4718 {
4719 #ifdef HOST_ECHO
4720 usb_echo("ehci open pipe failed\r\n");
4721 #endif
4722 return kStatus_USB_Busy;
4723 }
4724
4725 /* initialize pipe informations */
4726 USB_HostEhciZeroMem((void *)ehciPipePointer, sizeof(usb_host_ehci_pipe_t) / 4U);
4727 ehciPipePointer->pipeCommon.deviceHandle = pipeInit->devInstance;
4728 ehciPipePointer->pipeCommon.endpointAddress = pipeInit->endpointAddress;
4729 ehciPipePointer->pipeCommon.direction = pipeInit->direction;
4730 ehciPipePointer->pipeCommon.interval = pipeInit->interval;
4731 ehciPipePointer->pipeCommon.maxPacketSize = pipeInit->maxPacketSize;
4732 ehciPipePointer->pipeCommon.pipeType = pipeInit->pipeType;
4733 ehciPipePointer->pipeCommon.numberPerUframe = pipeInit->numberPerUframe + 1U;
4734 if (ehciPipePointer->pipeCommon.numberPerUframe > 3U)
4735 {
4736 ehciPipePointer->pipeCommon.numberPerUframe = 3U;
4737 }
4738 ehciPipePointer->pipeCommon.nakCount = pipeInit->nakCount;
4739 ehciPipePointer->pipeCommon.nextdata01 = 0U;
4740 ehciPipePointer->ehciQh = NULL;
4741 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
4742 (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
4743 if ((ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_ISOCHRONOUS) ||
4744 (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT))
4745 {
4746 if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_ISOCHRONOUS)
4747 {
4748 ehciPipePointer->pipeCommon.interval =
4749 (uint16_t)(1UL << (ehciPipePointer->pipeCommon.interval - 1U)); /* iso interval is the power of 2 */
4750 }
4751 else
4752 {
4753 if (speed == USB_SPEED_HIGH)
4754 {
4755 ehciPipePointer->pipeCommon.interval = (uint16_t)(
4756 1UL << (ehciPipePointer->pipeCommon.interval - 1U)); /* HS interrupt interval is the power of 2 */
4757 }
4758 else
4759 {
4760 ehciPipePointer->pipeCommon.interval = USB_HostEhciGet2PowerValue(
4761 (uint8_t)ehciPipePointer->pipeCommon.interval); /* FS/LS interrupt interval should be the power of
4762 2, it is used for ehci bandwidth */
4763 }
4764 }
4765 }
4766
4767 /* save the micro-frame interval, it is convenient for the interval process */
4768 if (speed == USB_SPEED_HIGH)
4769 {
4770 ehciPipePointer->uframeInterval = ehciPipePointer->pipeCommon.interval;
4771 }
4772 else
4773 {
4774 ehciPipePointer->uframeInterval = 8U * ehciPipePointer->pipeCommon.interval;
4775 }
4776
4777 /* open pipe */
4778 switch (ehciPipePointer->pipeCommon.pipeType)
4779 {
4780 case USB_ENDPOINT_CONTROL:
4781 case USB_ENDPOINT_BULK:
4782 status = USB_HostEhciOpenControlBulk(ehciInstance, ehciPipePointer);
4783 break;
4784
4785 #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
4786 ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
4787 case USB_ENDPOINT_ISOCHRONOUS:
4788 status = USB_HostEhciOpenIso(ehciInstance, ehciPipePointer);
4789 break;
4790 #endif
4791
4792 case USB_ENDPOINT_INTERRUPT:
4793 status = USB_HostEhciOpenInterrupt(ehciInstance, ehciPipePointer);
4794 break;
4795
4796 default:
4797 status = kStatus_USB_Error;
4798 break;
4799 }
4800
4801 if (status != kStatus_USB_Success)
4802 {
4803 /* release pipe */
4804 USB_HostEhciLock();
4805 temp = (void *)ehciInstance->ehciPipeList;
4806 ehciPipePointer->pipeCommon.next = (usb_host_pipe_t *)temp;
4807 ehciInstance->ehciPipeList = ehciPipePointer;
4808 USB_HostEhciUnlock();
4809 return status;
4810 }
4811
4812 /* add pipe to run pipe list */
4813 USB_HostEhciLock();
4814 temp = (void *)ehciInstance->ehciRunningPipeList;
4815 ehciPipePointer->pipeCommon.next = (usb_host_pipe_t *)temp;
4816 ehciInstance->ehciRunningPipeList = ehciPipePointer;
4817 USB_HostEhciUnlock();
4818
4819 *pipeHandle = ehciPipePointer;
4820 return status;
4821 }
4822
USB_HostEhciClosePipe(usb_host_controller_handle controllerHandle,usb_host_pipe_handle pipeHandle)4823 usb_status_t USB_HostEhciClosePipe(usb_host_controller_handle controllerHandle, usb_host_pipe_handle pipeHandle)
4824 {
4825 usb_host_ehci_instance_t *ehciInstance = (usb_host_ehci_instance_t *)controllerHandle;
4826 usb_host_ehci_pipe_t *ehciPipePointer = (usb_host_ehci_pipe_t *)pipeHandle;
4827 usb_host_pipe_t *prevPointer = NULL;
4828 void *temp;
4829 void *tempCurrent;
4830
4831 switch (ehciPipePointer->pipeCommon.pipeType)
4832 {
4833 case USB_ENDPOINT_BULK:
4834 case USB_ENDPOINT_CONTROL:
4835 (void)USB_HostEhciCloseControlBulk(ehciInstance, ehciPipePointer);
4836 break;
4837
4838 case USB_ENDPOINT_INTERRUPT:
4839 (void)USB_HostEhciCloseInterrupt(ehciInstance, ehciPipePointer);
4840 break;
4841
4842 #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
4843 ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
4844 case USB_ENDPOINT_ISOCHRONOUS:
4845 (void)USB_HostEhciCloseIso(ehciInstance, ehciPipePointer);
4846 break;
4847 #endif
4848
4849 default:
4850 /*no action*/
4851 break;
4852 }
4853
4854 /* delete pipe from run pipe list */
4855 USB_HostEhciLock();
4856 temp = (void *)ehciInstance->ehciRunningPipeList;
4857 prevPointer = (usb_host_pipe_t *)temp;
4858 tempCurrent = (void *)ehciPipePointer;
4859 if (prevPointer == (usb_host_pipe_t *)tempCurrent)
4860 {
4861 temp = (void *)prevPointer->next;
4862 ehciInstance->ehciRunningPipeList = (usb_host_ehci_pipe_t *)(temp);
4863 }
4864 else
4865 {
4866 while (prevPointer != NULL)
4867 {
4868 temp = (void *)ehciPipePointer;
4869 if (prevPointer->next == (usb_host_pipe_t *)temp)
4870 {
4871 prevPointer->next = ehciPipePointer->pipeCommon.next;
4872 break;
4873 }
4874 else
4875 {
4876 prevPointer = prevPointer->next;
4877 }
4878 }
4879 }
4880 USB_HostEhciUnlock();
4881
4882 /* release pipe */
4883 USB_HostEhciLock();
4884 temp = (void *)ehciInstance->ehciPipeList;
4885 ehciPipePointer->pipeCommon.next = (usb_host_pipe_t *)temp;
4886 ehciInstance->ehciPipeList = ehciPipePointer;
4887 USB_HostEhciUnlock();
4888
4889 return kStatus_USB_Success;
4890 }
4891
USB_HostEhciWritePipe(usb_host_controller_handle controllerHandle,usb_host_pipe_handle pipeHandle,usb_host_transfer_t * transfer)4892 usb_status_t USB_HostEhciWritePipe(usb_host_controller_handle controllerHandle,
4893 usb_host_pipe_handle pipeHandle,
4894 usb_host_transfer_t *transfer)
4895 {
4896 usb_host_ehci_instance_t *ehciInstance = (usb_host_ehci_instance_t *)controllerHandle;
4897 usb_host_ehci_pipe_t *ehciPipePointer = (usb_host_ehci_pipe_t *)pipeHandle;
4898 usb_status_t status = kStatus_USB_Success;
4899 #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
4900 ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
4901 uint32_t speed = 0U;
4902 #endif
4903
4904 switch (ehciPipePointer->pipeCommon.pipeType)
4905 {
4906 case USB_ENDPOINT_BULK:
4907 case USB_ENDPOINT_CONTROL:
4908 case USB_ENDPOINT_INTERRUPT:
4909 status = USB_HostEhciQhQtdListInit(ehciInstance, ehciPipePointer,
4910 transfer); /* initialize qtd for control/bulk transfer */
4911 break;
4912
4913 #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
4914 ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
4915 case USB_ENDPOINT_ISOCHRONOUS:
4916 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
4917 (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
4918 if (speed == USB_SPEED_HIGH)
4919 {
4920 #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
4921 status = USB_HostEhciItdArrayInit(ehciInstance, ehciPipePointer,
4922 transfer); /* initialize itd for iso transfer */
4923 #endif
4924 }
4925 else
4926 {
4927 #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
4928 status = USB_HostEhciSitdArrayInit(ehciInstance, ehciPipePointer,
4929 transfer); /* initialize sitd for iso transfer */
4930 #endif
4931 }
4932 break;
4933 #endif
4934
4935 default:
4936 /*no action*/
4937 break;
4938 }
4939 return status;
4940 }
4941
USB_HostEhciReadpipe(usb_host_controller_handle controllerHandle,usb_host_pipe_handle pipeHandle,usb_host_transfer_t * transfer)4942 usb_status_t USB_HostEhciReadpipe(usb_host_controller_handle controllerHandle,
4943 usb_host_pipe_handle pipeHandle,
4944 usb_host_transfer_t *transfer)
4945 {
4946 return USB_HostEhciWritePipe(controllerHandle, pipeHandle, transfer); /* same as write */
4947 }
4948
USB_HostEhciIoctl(usb_host_controller_handle controllerHandle,uint32_t ioctlEvent,void * ioctlParam)4949 usb_status_t USB_HostEhciIoctl(usb_host_controller_handle controllerHandle, uint32_t ioctlEvent, void *ioctlParam)
4950 {
4951 usb_status_t status = kStatus_USB_Success;
4952 usb_host_ehci_instance_t *ehciInstance = (usb_host_ehci_instance_t *)controllerHandle;
4953 usb_host_cancel_param_t *param;
4954 usb_host_ehci_pipe_t *ehciPipePointer;
4955 volatile usb_host_ehci_qh_t *vltQhPointer;
4956 uint32_t deviceAddress = 0;
4957 usb_host_controller_control_t controlCode = (usb_host_controller_control_t)ioctlEvent;
4958 if (controllerHandle == NULL)
4959 {
4960 return kStatus_USB_InvalidHandle;
4961 }
4962
4963 switch (controlCode)
4964 {
4965 case kUSB_HostCancelTransfer: /* cancel pipe or one transfer */
4966 param = (usb_host_cancel_param_t *)ioctlParam;
4967 status = USB_HostEhciCancelPipe(ehciInstance, (usb_host_ehci_pipe_t *)param->pipeHandle, param->transfer);
4968 break;
4969
4970 case kUSB_HostBusControl: /* bus control */
4971 status = USB_HostEhciControlBus(ehciInstance, *((uint8_t *)ioctlParam));
4972 break;
4973
4974 case kUSB_HostGetFrameNumber: /* get frame number */
4975 *((uint32_t *)ioctlParam) = ((ehciInstance->ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE) >> 3);
4976 break;
4977
4978 case kUSB_HostUpdateControlEndpointAddress:
4979 ehciPipePointer = (usb_host_ehci_pipe_t *)ioctlParam;
4980 vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
4981 /* update address */
4982 (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
4983 (uint32_t)kUSB_HostGetDeviceAddress, &deviceAddress);
4984 vltQhPointer->staticEndpointStates[0] |= deviceAddress;
4985 USB_HostEhciDelay(ehciInstance->ehciIpBase, 2U);
4986 break;
4987
4988 case kUSB_HostUpdateControlPacketSize:
4989 ehciPipePointer = (usb_host_ehci_pipe_t *)ioctlParam;
4990 vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
4991 USB_HostEhciLock();
4992 if (0U != (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK))
4993 {
4994 USB_HostEhciStopAsync(ehciInstance);
4995 /* update max packet size */
4996 vltQhPointer->staticEndpointStates[0] =
4997 (((vltQhPointer->staticEndpointStates[0]) & (~EHCI_HOST_QH_MAX_PACKET_LENGTH_MASK)) |
4998 ((uint32_t)ehciPipePointer->pipeCommon.maxPacketSize << EHCI_HOST_QH_MAX_PACKET_LENGTH_SHIFT));
4999 USB_HostEhciStartAsync(ehciInstance);
5000 }
5001 else
5002 {
5003 /* update max packet size */
5004 vltQhPointer->staticEndpointStates[0] =
5005 (((vltQhPointer->staticEndpointStates[0]) & (~EHCI_HOST_QH_MAX_PACKET_LENGTH_MASK)) |
5006 ((uint32_t)ehciPipePointer->pipeCommon.maxPacketSize << EHCI_HOST_QH_MAX_PACKET_LENGTH_SHIFT));
5007 }
5008 USB_HostEhciUnlock();
5009 break;
5010 #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
5011 case kUSB_HostTestModeInit: /* test mode control */
5012 USB_HostEhciTestModeInit((usb_host_device_instance_t *)ioctlParam);
5013 break;
5014 #endif
5015 default:
5016 status = kStatus_USB_NotSupported;
5017 break;
5018 }
5019 return status;
5020 }
5021
USB_HostEhciTaskFunction(void * hostHandle)5022 void USB_HostEhciTaskFunction(void *hostHandle)
5023 {
5024 usb_host_ehci_instance_t *ehciInstance;
5025 uint32_t bitSet;
5026 usb_device_handle deviceHandle;
5027
5028 if (hostHandle == NULL)
5029 {
5030 return;
5031 }
5032 ehciInstance = (usb_host_ehci_instance_t *)((usb_host_instance_t *)hostHandle)->controllerHandle;
5033
5034 if (OSA_EventWait(ehciInstance->taskEventHandle, 0xFF, 0, USB_OSA_WAIT_TIMEOUT, &bitSet) ==
5035 KOSA_StatusSuccess) /* wait all event */
5036 {
5037 if (0U != (bitSet & EHCI_TASK_EVENT_PORT_CHANGE)) /* port change */
5038 {
5039 USB_HostEhciPortChange(ehciInstance);
5040 }
5041
5042 if (0U != (bitSet & EHCI_TASK_EVENT_TIMER0)) /* timer0 */
5043 {
5044 USB_HostEhciTimer0(ehciInstance);
5045 }
5046
5047 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
5048 if (0U != (bitSet & EHCI_TASK_EVENT_TIMER1)) /* timer1 */
5049 {
5050 USB_HostEhciTimer1(ehciInstance);
5051 }
5052 #endif
5053
5054 if ((ehciInstance->deviceAttached == (uint8_t)kEHCIDeviceAttached))
5055 {
5056 if (0U != (bitSet & EHCI_TASK_EVENT_TRANSACTION_DONE)) /* transaction done */
5057 {
5058 USB_HostEhciTransactionDone(ehciInstance);
5059 }
5060
5061 if (0U != (bitSet & EHCI_TASK_EVENT_DEVICE_DETACH)) /* device detach */
5062 {
5063 ehciInstance->ehciIpBase->USBINTR &=
5064 (~USBHS_USBINTR_PCE_MASK); /* disable attach, enable when the detach process is done */
5065 ehciInstance->deviceAttached = (uint8_t)kEHCIDeviceDetached;
5066 (void)USB_HostDetachDevice(ehciInstance->hostHandle, 0, 0);
5067 }
5068 }
5069 else if (ehciInstance->deviceAttached != (uint8_t)kEHCIDeviceAttached)
5070 {
5071 if (0U != (bitSet & EHCI_TASK_EVENT_DEVICE_ATTACH)) /* device is attached */
5072 {
5073 USB_HostEhciLock();
5074 USB_HostEhciStartAsync(ehciInstance);
5075 USB_HostEhciStartPeriodic(ehciInstance);
5076 USB_HostEhciUnlock();
5077
5078 if (USB_HostAttachDevice(ehciInstance->hostHandle, ehciInstance->firstDeviceSpeed, 0, 0, 1,
5079 &deviceHandle) == kStatus_USB_Success)
5080 {
5081 ehciInstance->deviceAttached = (uint8_t)kEHCIDeviceAttached;
5082 }
5083 }
5084 }
5085 else
5086 {
5087 /*no action*/
5088 }
5089 }
5090 }
5091
USB_HostEhciIsrFunction(void * hostHandle)5092 void USB_HostEhciIsrFunction(void *hostHandle)
5093 {
5094 usb_host_ehci_instance_t *ehciInstance;
5095 static uint32_t interruptStatus = 0;
5096
5097 if (hostHandle == NULL)
5098 {
5099 return;
5100 }
5101
5102 ehciInstance = (usb_host_ehci_instance_t *)((usb_host_instance_t *)hostHandle)->controllerHandle;
5103
5104 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
5105
5106 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
5107 if (0U != (ehciInstance->registerNcBase->USB_OTGn_CTRL & USBNC_USB_OTGn_CTRL_WIE_MASK))
5108 {
5109 usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
5110 ehciInstance->registerNcBase->USB_OTGn_CTRL &= ~USBNC_USB_OTGn_CTRL_WIE_MASK;
5111 (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
5112 kUSB_HostEventDetectResume); /* call host callback function */
5113 #if (defined(USBNC_USB_OTGn_PHY_CTRL_0_UTMI_CLK_VLD_MASK))
5114 while (0U == (ehciInstance->registerNcBase->USB_OTGn_PHY_CTRL_0 & USBNC_USB_OTGn_PHY_CTRL_0_UTMI_CLK_VLD_MASK))
5115 {
5116 }
5117 #endif
5118 if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
5119 {
5120 USB_HostEhciStartAsync(ehciInstance);
5121 USB_HostEhciStartPeriodic(ehciInstance);
5122 }
5123 ehciInstance->ehciIpBase->USBCMD |= (USBHS_USBCMD_RS_MASK);
5124 if ((kBus_EhciSuspended == ehciInstance->busSuspendStatus))
5125 {
5126 /* ehciInstance->ehciIpBase->PORTSC1 |= USBHS_PORTSC1_FPR_MASK; */
5127 ehciInstance->busSuspendStatus = kBus_EhciStartResume;
5128 }
5129 else
5130 {
5131 /*no action*/
5132 }
5133 }
5134 else
5135 {
5136 /*no action*/
5137 }
5138 #else
5139 #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
5140 #else
5141 if (0U != (ehciInstance->ehciIpBase->USBGENCTRL & USBHS_USBGENCTRL_WU_IE_MASK))
5142 {
5143 usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
5144
5145 (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
5146 kUSB_HostEventDetectResume); /* call host callback function */
5147
5148 while (0U == (USBPHY->PLL_SIC & USBPHY_PLL_SIC_PLL_LOCK_MASK))
5149 {
5150 }
5151 ehciInstance->ehciIpBase->USBGENCTRL |= USBHS_USBGENCTRL_WU_INT_CLR_MASK;
5152 ehciInstance->ehciIpBase->USBGENCTRL &= ~USBHS_USBGENCTRL_WU_IE_MASK;
5153 if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
5154 {
5155 USB_HostEhciStartAsync(ehciInstance);
5156 USB_HostEhciStartPeriodic(ehciInstance);
5157 }
5158 ehciInstance->ehciIpBase->USBCMD |= (USBHS_USBCMD_RS_MASK);
5159 if ((kBus_EhciSuspended == ehciInstance->busSuspendStatus))
5160 {
5161 ehciInstance->busSuspendStatus = kBus_EhciStartResume;
5162 /*ehciInstance->ehciIpBase->PORTSC1 |= USBHS_PORTSC1_FPR_MASK; */
5163 }
5164 else
5165 {
5166 /*no action*/
5167 }
5168 }
5169 else
5170 {
5171 /*no action*/
5172 }
5173 #endif /* FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT */
5174 #endif /* FSL_FEATURE_SOC_USBNC_COUNT */
5175 #endif /* USB_HOST_CONFIG_LOW_POWER_MODE */
5176
5177 interruptStatus = ehciInstance->ehciIpBase->USBSTS;
5178 interruptStatus &= ehciInstance->ehciIpBase->USBINTR;
5179 while (0U != interruptStatus) /* there are usb interrupts */
5180 {
5181 ehciInstance->ehciIpBase->USBSTS = interruptStatus; /* clear interrupt */
5182
5183 if (0U != (interruptStatus & USBHS_USBSTS_SRI_MASK)) /* SOF interrupt */
5184 {
5185 }
5186
5187 if (0U != (interruptStatus & USBHS_USBSTS_SEI_MASK)) /* system error interrupt */
5188 {
5189 }
5190
5191 if ((0U != (interruptStatus & USBHS_USBSTS_UI_MASK)) ||
5192 (0U != (interruptStatus & USBHS_USBSTS_UEI_MASK))) /* USB interrupt or USB error interrupt */
5193 {
5194 (void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_TRANSACTION_DONE);
5195 }
5196
5197 if (0U != (interruptStatus & USBHS_USBSTS_PCI_MASK)) /* port change detect interrupt */
5198 {
5199 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
5200 usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
5201 if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_FPR_MASK))
5202 {
5203 if (kBus_EhciStartSuspend == ehciInstance->busSuspendStatus)
5204 {
5205 if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
5206 {
5207 USB_HostEhciStartAsync(ehciInstance);
5208 USB_HostEhciStartPeriodic(ehciInstance);
5209 }
5210 (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
5211 kUSB_HostEventNotSuspended); /* call host callback function */
5212 hostPointer->suspendedDevice = NULL;
5213 ehciInstance->busSuspendStatus = kBus_EhciIdle;
5214 ehciInstance->ehciIpBase->USBINTR &= ~(USBHS_USBINTR_TIE1_MASK);
5215 }
5216 else
5217 {
5218 /*no action */
5219 }
5220 }
5221 #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
5222 if ((kBus_EhciSuspended == ehciInstance->busSuspendStatus))
5223 {
5224 usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
5225
5226 (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
5227 kUSB_HostEventDetectResume); /* call host callback function */
5228
5229 uint32_t delay = 100000;
5230 while (delay-- && !(USBOTG->PLL_CONTROL_0 & USBC_PLL_CONTROL_0_PLL_READY_MASK))
5231 {
5232 }
5233 if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
5234 {
5235 USB_HostEhciStartAsync(ehciInstance);
5236 USB_HostEhciStartPeriodic(ehciInstance);
5237 }
5238 ehciInstance->ehciIpBase->USBCMD |= (USBHS_USBCMD_RS_MASK);
5239 ehciInstance->busSuspendStatus = kBus_EhciStartResume;
5240 }
5241 #endif
5242 #endif
5243 (void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_PORT_CHANGE);
5244 }
5245
5246 if (0U != (interruptStatus & USBHS_USBSTS_TI0_MASK)) /* timer 0 interrupt */
5247 {
5248 (void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_TIMER0);
5249 }
5250
5251 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
5252 if (0U != (interruptStatus & USBHS_USBSTS_TI1_MASK)) /* timer 1 interrupt */
5253 {
5254 (void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_TIMER1);
5255 }
5256 #endif
5257
5258 interruptStatus = ehciInstance->ehciIpBase->USBSTS;
5259 interruptStatus &= ehciInstance->ehciIpBase->USBINTR;
5260 }
5261 }
5262
5263 #endif /* USB_HOST_CONFIG_EHCI */
5264