1 /*
2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016 - 2017,2019 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "usb_otg_config.h"
10
11 #if ((defined USB_OTG_CONFIG_KHCI) && (USB_OTG_CONFIG_KHCI))
12
13 #include "fsl_device_registers.h"
14 #include "usb_otg.h"
15 #include "usb_otg_oci.h"
16 #include "usb_otg_khci.h"
17 #if ((defined USB_OTG_KHCI_PERIPHERAL_ENABLE) && (USB_OTG_KHCI_PERIPHERAL_ENABLE))
18 #include "usb_otg_peripheral.h"
19 #endif
20
21 /*******************************************************************************
22 * Definitions
23 ******************************************************************************/
24
25 /*******************************************************************************
26 * Prototypes
27 ******************************************************************************/
28
29 static void _USB_OtgKhciRequestState(usb_otg_khci_instance_t *otgKhciInstance,
30 uint32_t requestState,
31 uint32_t stateMachine);
32 static usb_status_t _USB_OtgKhciCheckSrp(usb_otg_khci_instance_t *otgKhciInstance);
33 /*misra 17.2 function can't call themselves*/
34 static usb_status_t USB_OtgKhciControlPullUp(usb_otg_controller_handle controllerHandle,
35 uint32_t controlValue1,
36 uint32_t controlValue2);
37 /*******************************************************************************
38 * Variables
39 ******************************************************************************/
40
41 /*******************************************************************************
42 * Code
43 ******************************************************************************/
44
_USB_OtgKhciCheckSrp(usb_otg_khci_instance_t * otgKhciInstance)45 static usb_status_t _USB_OtgKhciCheckSrp(usb_otg_khci_instance_t *otgKhciInstance)
46 {
47 otgKhciInstance->checkTime++;
48
49 if (otgKhciInstance->checkTime >= USB_OTG_TIME_SRP_TIME_OUT)
50 {
51 otgKhciInstance->checkTime = 0U;
52 otgKhciInstance->checkSrpState = 0U;
53 }
54
55 if (otgKhciInstance->checkSrpState == 0U) /* check SE0 */
56 {
57 if (0U != otgKhciInstance->se0State) /* se0 */
58 {
59 otgKhciInstance->checkSrpState = 1U;
60 }
61 }
62 else if (otgKhciInstance->checkSrpState == 1U) /* check J */
63 {
64 if (0U != otgKhciInstance->jState) /* J */
65 {
66 otgKhciInstance->checkSrpState = 2;
67 otgKhciInstance->checkTime = 0;
68 }
69 else if ((0U == (otgKhciInstance->se0State)) &&
70 (0U != (otgKhciInstance->usbRegBase->OTGSTAT & USB_OTGSTAT_LINESTATESTABLE_MASK)))
71 {
72 otgKhciInstance->checkSrpState = 0U;
73 }
74 else
75 {
76 /*no action*/
77 }
78 }
79 else if (otgKhciInstance->checkSrpState == 2U) /* check SE0 */
80 {
81 if (0U != otgKhciInstance->se0State) /* se0 */
82 {
83 otgKhciInstance->checkSrpState = 0U; /* check next srp */
84 if ((otgKhciInstance->checkTime >= USB_OTG_TIME_B_DATA_PLS_MIN) &&
85 (otgKhciInstance->checkTime <= USB_OTG_TIME_B_DATA_PLS_MAX))
86 {
87 otgKhciInstance->checkTime = 0U;
88 (void)USB_OtgNotifyChange(otgKhciInstance->otgHandle, (uint32_t)kOtg_StatusSrpDet, 1U);
89 return kStatus_USB_Success;
90 }
91 }
92 else if ((0U == (otgKhciInstance->jState)) &&
93 (0U != (otgKhciInstance->usbRegBase->OTGSTAT & USB_OTGSTAT_LINESTATESTABLE_MASK)))
94 {
95 otgKhciInstance->checkSrpState = 0U;
96 }
97 else
98 {
99 /*no action*/
100 }
101 }
102 else
103 {
104 /*no action*/
105 }
106
107 return kStatus_USB_Error;
108 }
109 /*add this for misra 17.2, function can't call themselves. the function is same as kOtg_ControlPullUp of
110 * USB_OtgKhciControl*/
USB_OtgKhciControlPullUp(usb_otg_controller_handle controllerHandle,uint32_t controlValue1,uint32_t controlValue2)111 static usb_status_t USB_OtgKhciControlPullUp(usb_otg_controller_handle controllerHandle,
112 uint32_t controlValue1,
113 uint32_t controlValue2)
114
115 {
116 usb_otg_khci_instance_t *otgKhciInstance = (usb_otg_khci_instance_t *)controllerHandle;
117 if (controllerHandle == NULL)
118 {
119 return kStatus_USB_Error;
120 }
121
122 if (0U != (controlValue1 & ((uint32_t)kOtg_PullDp)))
123 {
124 #if (FSL_FEATURE_USB_KHCI_OTG_ENABLED)
125 otgKhciInstance->usbRegBase->OTGCTL |= USB_OTGCTL_DPHIGH_MASK;
126 otgKhciInstance->usbRegBase->CONTROL |= USB_CONTROL_DPPULLUPNONOTG_MASK;
127 #else
128 otgKhciInstance->usbRegBase->CONTROL |= USB_CONTROL_DPPULLUPNONOTG_MASK;
129 #endif
130 }
131 else
132 {
133 #if (FSL_FEATURE_USB_KHCI_OTG_ENABLED)
134 otgKhciInstance->usbRegBase->OTGCTL &= (uint8_t)(~USB_OTGCTL_DPHIGH_MASK);
135 otgKhciInstance->usbRegBase->CONTROL &= (uint8_t)(~USB_CONTROL_DPPULLUPNONOTG_MASK);
136 #else
137 otgKhciInstance->usbRegBase->CONTROL &= (uint8_t)(~USB_CONTROL_DPPULLUPNONOTG_MASK);
138 #endif
139 }
140 return kStatus_USB_Success;
141 }
USB_OtgKhciParsePeripheralStatus(usb_otg_khci_instance_t * otgKhciInstance,uint32_t newStatus)142 static void USB_OtgKhciParsePeripheralStatus(usb_otg_khci_instance_t *otgKhciInstance, uint32_t newStatus)
143 {
144 uint32_t changes = 0;
145 uint32_t value = 0;
146
147 changes = otgKhciInstance->peripheralStatus ^ newStatus;
148 otgKhciInstance->peripheralStatus = newStatus;
149
150 if (otgKhciInstance->checkType == (uint8_t)kOtg_CheckBHNP)
151 {
152 if (0U != (newStatus & ((uint32_t)kPeripheral_StatusHNPdetected)))
153 {
154 if (otgKhciInstance->lastState == (uint32_t)kOtg_State_ASuspend)
155 {
156 /* keep the pull-up */
157 (void)USB_OtgKhciControlPullUp(otgKhciInstance, (uint32_t)kOtg_PullDp, 0U);
158 /* disable hnp check */
159 (void)USB_OtgPeripheralControl(otgKhciInstance, (uint32_t)kPeripheral_ControlHNPCheckEnable, 0U, 0U);
160 (void)USB_OtgNotifyChange(otgKhciInstance->otgHandle, (uint32_t)kOtg_StatusBConn,
161 0U); /* enter a_peripheral */
162 }
163 else if (otgKhciInstance->lastState == (uint32_t)kOtg_State_BWaitAcon)
164 {
165 (void)USB_OtgNotifyChange(otgKhciInstance->otgHandle, (uint32_t)kOtg_StatusAConn,
166 1U); /* enter b_host */
167 }
168 else
169 {
170 /*no action*/
171 }
172 }
173 }
174
175 if (0U != (changes & ((uint32_t)kPeripheral_StatusId)))
176 {
177 value = 0U;
178 if (0U != (newStatus & ((uint32_t)kPeripheral_StatusId)))
179 {
180 value = 1U;
181 }
182 (void)USB_OtgNotifyChange(otgKhciInstance->otgHandle, (uint32_t)kOtg_StatusId, value);
183 }
184
185 if (0U != (changes & ((uint32_t)kPeripheral_StatusSessVld)))
186 {
187 value = 0U;
188 if (0U != (newStatus & ((uint32_t)kPeripheral_StatusSessVld)))
189 {
190 value = 1U;
191 }
192 (void)USB_OtgNotifyChange(otgKhciInstance->otgHandle, (uint32_t)kOtg_StatusSessVld, value);
193 }
194
195 if (0U != (changes & ((uint8_t)kPeripheral_StatusVbusVld)))
196 {
197 value = 0U;
198 if (0U != (newStatus & ((uint8_t)kPeripheral_StatusVbusVld)))
199 {
200 value = 1U;
201 }
202 (void)USB_OtgNotifyChange(otgKhciInstance->otgHandle, (uint32_t)kOtg_StatusVbusVld, value);
203 }
204 }
205
_USB_OtgKhciRequestState(usb_otg_khci_instance_t * otgKhciInstance,uint32_t requestState,uint32_t stateMachine)206 static void _USB_OtgKhciRequestState(usb_otg_khci_instance_t *otgKhciInstance,
207 uint32_t requestState,
208 uint32_t stateMachine)
209 {
210 uint32_t value;
211 otgKhciInstance->checkType = (uint8_t)kOtg_CheckNone;
212
213 if ((stateMachine == ((uint32_t)kOtg_State_ASuspend)) || (stateMachine == ((uint32_t)kOtg_State_BWaitAcon)))
214 {
215 /* enable hnp check */
216 (void)USB_OtgPeripheralControl(otgKhciInstance, (uint32_t)kPeripheral_ControlHNPCheckEnable, 1U, 0U);
217 otgKhciInstance->checkTime = USB_OTG_TIME_CHECK_BHNP_PERIODIC;
218 otgKhciInstance->checkType = (uint8_t)kOtg_CheckBHNP;
219 }
220 else
221 {
222 /* disable hnp check */
223 (void)USB_OtgPeripheralControl(otgKhciInstance, (uint32_t)kPeripheral_ControlHNPCheckEnable, 0U, 0U);
224 }
225
226 /*
227 * Don't need process the follow requested state because they are notified by interrupt:
228 * kOtg_StatusId, kOtg_StatusVbusVld, kOtg_StatusVbusInvld, kOtg_StatusSessInvld, kOtg_StatusSessVld
229 */
230 if (0U != (requestState & ((uint32_t)kOtg_StatusAdpChange)))
231 {
232 /* todo: not yet */
233 }
234
235 if (0U != (requestState & ((uint32_t)kOtg_StatusSrpDet)))
236 {
237 otgKhciInstance->checkTime = 0;
238 otgKhciInstance->checkType = (uint8_t)kOtg_CheckSrp;
239 }
240
241 if (0U != (requestState & ((uint8_t)kOtg_StatusAConn)))
242 {
243 /* check max3353 BHNP periodic */
244 otgKhciInstance->checkTime = USB_OTG_TIME_CHECK_BHNP_PERIODIC;
245 otgKhciInstance->checkType = (uint8_t)kOtg_CheckBHNP;
246 }
247
248 if (0U != (requestState & ((uint32_t)kOtg_StatusBusResume)))
249 {
250 /* todo: check resume, not yet */
251 }
252
253 if (0U != (requestState & ((uint8_t)kOtg_StatusBusSuspend)))
254 {
255 otgKhciInstance->checkType = (uint8_t)kOtg_CheckSuspend;
256 }
257
258 if (0U != (requestState & ((uint32_t)kOtg_StatusSe0Srp)))
259 {
260 otgKhciInstance->checkTime = 0;
261 otgKhciInstance->checkType = (uint8_t)kOtg_CheckSsendSe0Srp; /* check session invalid */
262 }
263
264 if (0U != (requestState & ((uint32_t)kOtg_StatusSsendSrp)))
265 {
266 if (otgKhciInstance->bssendsrpCheck > USB_OTG_TIME_B_SSEND_SRP)
267 {
268 (void)USB_OtgNotifyChange(otgKhciInstance->otgHandle, (uint32_t)kOtg_StatusSsendSrp, 1);
269 }
270 }
271
272 if (0U != (requestState & ((uint32_t)kOtg_StatusBConn)))
273 {
274 if (otgKhciInstance->lastState == (uint32_t)kOtg_State_AWaitVrise)
275 {
276 otgKhciInstance->checkTime = USB_OTG_TIME_A_BCON_LDB;
277 }
278 else
279 {
280 otgKhciInstance->checkTime = USB_OTG_TIME_A_BCON_SDB;
281 }
282 otgKhciInstance->checkType = (uint8_t)kOtg_CheckConn;
283 }
284
285 if (0U != (requestState & ((uint32_t)kOtg_StatusBDisconn)))
286 {
287 if (stateMachine != ((uint32_t)kOtg_State_ASuspend))
288 {
289 otgKhciInstance->checkTime = USB_OTG_TIME_CHECK_DETACH;
290 otgKhciInstance->checkType = (uint8_t)kOtg_CheckNonConn;
291 }
292 }
293
294 if (0U != (requestState & ((uint32_t)kOtg_StatusADisconn)))
295 {
296 otgKhciInstance->checkTime = USB_OTG_TIME_CHECK_DETACH;
297 otgKhciInstance->checkType = (uint8_t)kOtg_CheckNonConn;
298 }
299
300 if (0U != (requestState & ((uint32_t)kOtg_StatusCheckIdleInAPeripheral)))
301 {
302 otgKhciInstance->checkType = (uint8_t)kOtg_CheckIdleTimeOut;
303 otgKhciInstance->lineStableTime = 0U;
304 }
305
306 #if ((defined USB_OTG_KHCI_PERIPHERAL_ENABLE) && (USB_OTG_KHCI_PERIPHERAL_ENABLE))
307 (void)USB_OtgPeripheralGetStatus((uint32_t)kPeripheral_StatusAll, &value);
308 (void)USB_OtgKhciParsePeripheralStatus(otgKhciInstance, value);
309
310 /* at start, don't know the id state, so need notify the id state no matter the id value */
311 if (0U != ((requestState & ((uint32_t)kOtg_StatusId))) && (stateMachine == ((uint32_t)kOtg_State_Start)))
312 {
313 (void)USB_OtgPeripheralGetStatus((uint32_t)kPeripheral_StatusAll, &value);
314 otgKhciInstance->peripheralStatus = value; /* initialized status */
315 if (0U != (value & ((uint32_t)kPeripheral_StatusId)))
316 {
317 value = 1U;
318 }
319 else
320 {
321 value = 0U;
322 }
323 (void)USB_OtgNotifyChange(otgKhciInstance->otgHandle, (uint32_t)kOtg_StatusId, value);
324 }
325 #endif
326
327 otgKhciInstance->lastState = stateMachine;
328 }
329
USB_OtgKhciInit(uint8_t controllerId,usb_otg_handle otgHandle,usb_otg_controller_handle * controllerHandle)330 usb_status_t USB_OtgKhciInit(uint8_t controllerId,
331 usb_otg_handle otgHandle,
332 usb_otg_controller_handle *controllerHandle)
333 {
334 usb_otg_khci_instance_t *otgKhciInstance;
335 uint32_t usbfsBaseAddrs[] = USB_BASE_ADDRS;
336 void *temp;
337 uint32_t *pointer;
338
339 if (((uint32_t)controllerId - (uint32_t)kUSB_ControllerKhci0) >=
340 (sizeof(usbfsBaseAddrs) / sizeof(usbfsBaseAddrs[0])))
341 {
342 return kStatus_USB_ControllerNotFound;
343 }
344 if (otgHandle == NULL)
345 {
346 return kStatus_USB_Error;
347 }
348
349 otgKhciInstance = (usb_otg_khci_instance_t *)OSA_MemoryAllocate(sizeof(usb_otg_khci_instance_t));
350 if (otgKhciInstance == NULL)
351 {
352 return kStatus_USB_AllocFail;
353 }
354 otgKhciInstance->otgHandle = otgHandle;
355 pointer = (uint32_t *)usbfsBaseAddrs[controllerId - (uint8_t)kUSB_ControllerKhci0];
356 temp = (void *)pointer;
357 otgKhciInstance->usbRegBase = (USB_Type *)temp;
358 otgKhciInstance->externalTimerEnable = 0U;
359
360 /* initialize controller */
361 otgKhciInstance->usbRegBase->ISTAT = 0xFFU; /* clear all interrupts */
362 otgKhciInstance->usbRegBase->OTGISTAT = 0xFFU;
363 otgKhciInstance->usbRegBase->OTGCTL |= USB_OTGCTL_OTGEN_MASK; /* enable otg */
364 otgKhciInstance->usbRegBase->OTGICR |=
365 (USB_OTGICR_LINESTATEEN_MASK | USB_OTGICR_ONEMSECEN_MASK); /* 1ms and LINE_STAT_CHG interrupts */
366
367 *controllerHandle = otgKhciInstance;
368 #if ((defined USB_OTG_KHCI_PERIPHERAL_ENABLE) && (USB_OTG_KHCI_PERIPHERAL_ENABLE))
369 return USB_OtgPeripheralEnable();
370 #else
371 return kStatus_USB_Success;
372 #endif
373 }
374
USB_OtgKhciDeinit(usb_otg_controller_handle controllerHandle)375 usb_status_t USB_OtgKhciDeinit(usb_otg_controller_handle controllerHandle)
376 {
377 usb_otg_khci_instance_t *otgKhciInstance = (usb_otg_khci_instance_t *)controllerHandle;
378
379 if (controllerHandle == NULL)
380 {
381 return kStatus_USB_Error;
382 }
383
384 /* clear all interrupts */
385 otgKhciInstance->usbRegBase->OTGCTL &= (uint8_t)(~USB_OTGCTL_OTGEN_MASK); /* disable otg */
386 otgKhciInstance->usbRegBase->ISTAT = 0xFFU;
387 otgKhciInstance->usbRegBase->OTGISTAT = 0xFFU;
388
389 OSA_MemoryFree(otgKhciInstance);
390
391 #if ((defined USB_OTG_KHCI_PERIPHERAL_ENABLE) && (USB_OTG_KHCI_PERIPHERAL_ENABLE))
392 return USB_OtgPeripheralDisable();
393 #else
394 return kStatus_USB_Success;
395 #endif
396 }
397
USB_OtgKhciControl(usb_otg_controller_handle controllerHandle,uint32_t controlType,uint32_t controlValue1,uint32_t controlValue2)398 usb_status_t USB_OtgKhciControl(usb_otg_controller_handle controllerHandle,
399 uint32_t controlType,
400 uint32_t controlValue1,
401 uint32_t controlValue2)
402 {
403 usb_otg_khci_instance_t *otgKhciInstance = (usb_otg_khci_instance_t *)controllerHandle;
404 uint32_t statusValue = 0U;
405 usb_otg_control_t controlCode = (usb_otg_control_t)controlType;
406 if (controllerHandle == NULL)
407 {
408 return kStatus_USB_Error;
409 }
410
411 switch (controlCode)
412 {
413 case kOtg_ControlPullUp:
414 if (0U != (controlValue1 & ((uint32_t)kOtg_PullDp)))
415 {
416 #if (FSL_FEATURE_USB_KHCI_OTG_ENABLED)
417 otgKhciInstance->usbRegBase->OTGCTL |= USB_OTGCTL_DPHIGH_MASK;
418 otgKhciInstance->usbRegBase->CONTROL |= USB_CONTROL_DPPULLUPNONOTG_MASK;
419 #else
420 otgKhciInstance->usbRegBase->CONTROL |= USB_CONTROL_DPPULLUPNONOTG_MASK;
421 #endif
422 }
423 else
424 {
425 #if (FSL_FEATURE_USB_KHCI_OTG_ENABLED)
426 otgKhciInstance->usbRegBase->OTGCTL &= (uint8_t)(~USB_OTGCTL_DPHIGH_MASK);
427 otgKhciInstance->usbRegBase->CONTROL &= (uint8_t)(~USB_CONTROL_DPPULLUPNONOTG_MASK);
428 #else
429 otgKhciInstance->usbRegBase->CONTROL &= (uint8_t)(~USB_CONTROL_DPPULLUPNONOTG_MASK);
430 #endif
431 }
432 break;
433 case kOtg_ControlPullDown:
434 if (0U != (controlValue1 & ((uint32_t)kOtg_PullDp)))
435 {
436 otgKhciInstance->usbRegBase->OTGCTL |= USB_OTGCTL_DPLOW_MASK;
437 }
438 else
439 {
440 otgKhciInstance->usbRegBase->OTGCTL &= (uint8_t)(~USB_OTGCTL_DPLOW_MASK);
441 }
442
443 if (0U != (controlValue1 & ((uint32_t)kOtg_PullDm)))
444 {
445 otgKhciInstance->usbRegBase->OTGCTL |= USB_OTGCTL_DMLOW_MASK;
446 }
447 else
448 {
449 otgKhciInstance->usbRegBase->OTGCTL &= (uint8_t)(~USB_OTGCTL_DMLOW_MASK);
450 }
451 break;
452
453 case kOtg_ControlResume:
454 if (0U != controlValue1)
455 {
456 otgKhciInstance->usbRegBase->CTL |= USB_CTL_RESUME_MASK;
457
458 otgKhciInstance->internalTimerValue = (uint16_t)controlValue1; /* ms */
459 while (otgKhciInstance->internalTimerValue > 0U)
460 {
461 }
462
463 otgKhciInstance->usbRegBase->CTL &= (uint8_t)(~USB_CTL_RESUME_MASK);
464 }
465 break;
466 #if ((defined USB_OTG_ADP_ENABLE) && (USB_OTG_ADP_ENABLE))
467 case kOtg_ControlAdpPrb:
468 break;
469 #endif
470
471 case kOtg_ControlDataPulse:
472 /* send srp */
473 (void)USB_OtgKhciControlPullUp(otgKhciInstance, (uint32_t)kOtg_PullDp, 0U);
474 otgKhciInstance->internalTimerValue = USB_OTG_TIME_B_DATA_PLS; /* ms */
475 while (otgKhciInstance->internalTimerValue > 0U)
476 {
477 }
478 (void)USB_OtgKhciControlPullUp(otgKhciInstance, 0U, 0U);
479 (void)USB_OtgNotifyChange(otgKhciInstance->otgHandle, (uint32_t)kOtg_StatusBSrpDone, 1U);
480 break;
481
482 case kOtg_ControlSetTimer:
483 otgKhciInstance->externalTimerEnable = 1U;
484 otgKhciInstance->externalTimerValue = (uint16_t)controlValue1;
485 break;
486
487 case kOtg_ControlCancelTimer:
488 otgKhciInstance->externalTimerEnable = 0U;
489 break;
490
491 case kOtg_ControlVbus:
492 #if ((defined USB_OTG_KHCI_PERIPHERAL_ENABLE) && (USB_OTG_KHCI_PERIPHERAL_ENABLE))
493 (void)USB_OtgPeripheralControl(otgKhciInstance, (uint32_t)kPeripheral_ControlVbus, controlValue1, 0U);
494 #endif
495 break;
496
497 case kOtg_ControlUpdateStatus:
498 #if ((defined USB_OTG_KHCI_PERIPHERAL_ENABLE) && (USB_OTG_KHCI_PERIPHERAL_ENABLE))
499 (void)USB_OtgPeripheralControl(otgKhciInstance, (uint32_t)kPeripheral_ControlUpdateStatus, controlValue1,
500 0U);
501 #endif
502 (void)USB_OtgPeripheralGetStatus((uint32_t)kPeripheral_StatusAll, &statusValue);
503 (void)USB_OtgKhciParsePeripheralStatus(otgKhciInstance, statusValue);
504 break;
505
506 case kOtg_ControlRequestStatus:
507 (void)_USB_OtgKhciRequestState(otgKhciInstance, controlValue1, controlValue2);
508 break;
509
510 default:
511 /*no action*/
512 break;
513 }
514
515 return kStatus_USB_Success;
516 }
517
USB_OtgKhciIsrFunction(usb_otg_handle otgHandle)518 void USB_OtgKhciIsrFunction(usb_otg_handle otgHandle)
519 {
520 usb_otg_khci_instance_t *otgKhciInstance;
521 uint8_t otgInterrupts;
522 uint32_t value;
523 usb_otg_check_type_t checkType;
524 if (otgHandle == NULL)
525 {
526 return;
527 }
528 otgKhciInstance = (usb_otg_khci_instance_t *)(((usb_otg_instance_t *)otgHandle)->controllerHandle);
529
530 otgInterrupts = (otgKhciInstance->usbRegBase->OTGISTAT & otgKhciInstance->usbRegBase->OTGICR);
531 otgKhciInstance->usbRegBase->OTGISTAT = otgInterrupts; /* clear interrupts */
532
533 if ((0U != (otgInterrupts & USB_OTGISTAT_LINE_STATE_CHG_MASK)) &&
534 (0U !=
535 (otgKhciInstance->usbRegBase->OTGSTAT & USB_OTGSTAT_LINESTATESTABLE_MASK))) /* line state change and stable */
536 {
537 otgKhciInstance->lineStableTime = 0U;
538 otgKhciInstance->se0State = otgKhciInstance->usbRegBase->CTL & USB_CTL_SE0_MASK;
539 if (0U != (otgKhciInstance->se0State))
540 {
541 otgKhciInstance->jState = 0U;
542 }
543 else
544 {
545 otgKhciInstance->jState = otgKhciInstance->usbRegBase->CTL & USB_CTL_JSTATE_MASK;
546 }
547 }
548
549 if (0U != (otgInterrupts & USB_OTGISTAT_ONEMSEC_MASK)) /* 1ms */
550 {
551 if (0U == (otgKhciInstance->usbRegBase->OTGSTAT & USB_OTGSTAT_LINESTATESTABLE_MASK))
552 {
553 otgKhciInstance->lineStableTime = 0U;
554 otgKhciInstance->se0State = otgKhciInstance->usbRegBase->CTL & USB_CTL_SE0_MASK;
555 otgKhciInstance->jState = 0U;
556 }
557 else
558 {
559 if (otgKhciInstance->lineStableTime != 0xFFFFU)
560 {
561 otgKhciInstance->lineStableTime++;
562 }
563 }
564
565 if ((0U != otgKhciInstance->externalTimerEnable) && (otgKhciInstance->externalTimerValue > 0U))
566 {
567 otgKhciInstance->externalTimerValue--;
568 if (otgKhciInstance->externalTimerValue == 0U)
569 {
570 otgKhciInstance->externalTimerEnable = 0U;
571 (void)USB_OtgNotifyChange(otgHandle, (uint32_t)kOtg_StatusTimeOut, 1U);
572 }
573 }
574
575 if (otgKhciInstance->internalTimerValue > 0U)
576 {
577 otgKhciInstance->internalTimerValue--;
578 }
579
580 checkType = (usb_otg_check_type_t)otgKhciInstance->checkType;
581 switch (checkType)
582 {
583 case kOtg_CheckNonConn:
584 if ((0U != otgKhciInstance->se0State) && (otgKhciInstance->lineStableTime > otgKhciInstance->checkTime))
585 {
586 otgKhciInstance->checkType = (uint8_t)kOtg_CheckNone;
587 if (otgKhciInstance->lastState == (uint32_t)kOtg_State_BHost)
588 {
589 (void)USB_OtgNotifyChange(otgHandle, (uint32_t)kOtg_StatusAConn, 0);
590 }
591 else if ((otgKhciInstance->lastState == (uint32_t)kOtg_State_AHost))
592 {
593 (void)USB_OtgNotifyChange(otgHandle, (uint32_t)kOtg_StatusBConn, 0);
594 }
595 else
596 {
597 /*no action*/
598 }
599 }
600 break;
601
602 case kOtg_CheckConn:
603 if ((0U == (otgKhciInstance->se0State)) && (0U != otgKhciInstance->jState) &&
604 (0U != (otgKhciInstance->usbRegBase->OTGSTAT & USB_OTGSTAT_LINESTATESTABLE_MASK)))
605 {
606 if (otgKhciInstance->lastState == (uint32_t)kOtg_State_AWaitBcon)
607 {
608 if (otgKhciInstance->lineStableTime >= otgKhciInstance->checkTime)
609 {
610 otgKhciInstance->checkType = (uint8_t)kOtg_CheckNone;
611 (void)USB_OtgNotifyChange(otgHandle, (uint32_t)kOtg_StatusBConn, 1U);
612 }
613 }
614 }
615 break;
616
617 case kOtg_CheckSsendSe0Srp: /* b_idle */
618 if ((0U != otgKhciInstance->se0State) &&
619 (otgKhciInstance->lineStableTime >= USB_OTG_TIME_B_SE0_SRP)) /* se0 */
620 {
621 otgKhciInstance->lineStableTime = 0U;
622 (void)USB_OtgNotifyChange(otgHandle, (uint32_t)kOtg_StatusSe0Srp, 1U);
623 }
624 break;
625
626 case kOtg_CheckIdleTimeOut: /* a_peripheral */
627 if ((otgKhciInstance->lineStableTime >= USB_OTG_TIME_A_BIDL_ADIS))
628 {
629 otgKhciInstance->checkType = (uint8_t)kOtg_CheckNone;
630 (void)USB_OtgNotifyChange(otgHandle, (uint32_t)kOtg_StatusTimeOut, 1U);
631 }
632 break;
633
634 case kOtg_CheckSrp:
635 (void)_USB_OtgKhciCheckSrp(otgKhciInstance);
636 break;
637
638 case kOtg_CheckBHNP:
639 otgKhciInstance->checkTime--;
640 if (otgKhciInstance->checkTime == 0U)
641 {
642 otgKhciInstance->checkTime = USB_OTG_TIME_CHECK_BHNP_PERIODIC;
643 /* poll for HNP because max3353 has no interrupt for it */
644 (void)USB_OtgNotifyChange(otgHandle, (uint32_t)kOtg_StatusChange, 1U);
645 }
646 break;
647
648 case kOtg_CheckSuspend:
649 if (otgKhciInstance->lineStableTime >= USB_OTG_TIME_B_AIDL_BDIS) /* suspend */
650 {
651 otgKhciInstance->lineStableTime = 0;
652 (void)USB_OtgNotifyChange(otgHandle, (uint32_t)kOtg_StatusBusSuspend, 1);
653 }
654 break;
655
656 default:
657 /*no action*/
658 break;
659 }
660
661 if (otgKhciInstance->bssendsrpCheck <= USB_OTG_TIME_B_SSEND_SRP)
662 {
663 (void)USB_OtgPeripheralGetStatus((uint32_t)kPeripheral_StatusSessVld, &value);
664 if (0U != value)
665 {
666 otgKhciInstance->peripheralStatus |= (uint32_t)kPeripheral_StatusSessVld;
667 }
668 else
669 {
670 otgKhciInstance->peripheralStatus &= (~((uint32_t)kPeripheral_StatusSessVld));
671 }
672 if (0U == value) /* invalid */
673 {
674 otgKhciInstance->bssendsrpCheck++;
675 if (otgKhciInstance->bssendsrpCheck > USB_OTG_TIME_B_SSEND_SRP)
676 {
677 (void)USB_OtgNotifyChange(otgHandle, (uint32_t)kOtg_StatusSsendSrp, 1);
678 }
679 }
680 #if 0
681 else /* valid */
682 {
683 otgKhciInstance->bssendsrpCheck = 0; /* stop check */
684 (void)USB_OtgNotifyChange(otgHandle, (uint32_t)kOtg_StatusSessVld, 1);
685 }
686 #endif
687 }
688 }
689 }
690
691 #endif
692