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