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