Subversion Repositories LedShow

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 1
/**
2
  ******************************************************************************
3
  * @file    stm32f1xx_hal_hcd.c
4
  * @author  MCD Application Team
5
  * @brief   HCD HAL module driver.
6
  *          This file provides firmware functions to manage the following
7
  *          functionalities of the USB Peripheral Controller:
8
  *           + Initialization and de-initialization functions
9
  *           + IO operation functions
10
  *           + Peripheral Control functions
11
  *           + Peripheral State functions
12
  *
13
  @verbatim
14
  ==============================================================================
15
                    ##### How to use this driver #####
16
  ==============================================================================
17
  [..]
18
    (#)Declare a HCD_HandleTypeDef handle structure, for example:
19
       HCD_HandleTypeDef  hhcd;
20
 
21
    (#)Fill parameters of Init structure in HCD handle
22
 
23
    (#)Call HAL_HCD_Init() API to initialize the HCD peripheral (Core, Host core, ...)
24
 
25
    (#)Initialize the HCD low level resources through the HAL_HCD_MspInit() API:
26
        (##) Enable the HCD/USB Low Level interface clock using the following macro
27
             (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE()
28
 
29
        (##) Initialize the related GPIO clocks
30
        (##) Configure HCD pin-out
31
        (##) Configure HCD NVIC interrupt
32
 
33
    (#)Associate the Upper USB Host stack to the HAL HCD Driver:
34
        (##) hhcd.pData = phost;
35
 
36
    (#)Enable HCD transmission and reception:
37
        (##) HAL_HCD_Start();
38
 
39
  @endverbatim
40
  ******************************************************************************
41
  * @attention
42
  *
43
  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
44
  *
45
  * Redistribution and use in source and binary forms, with or without modification,
46
  * are permitted provided that the following conditions are met:
47
  *   1. Redistributions of source code must retain the above copyright notice,
48
  *      this list of conditions and the following disclaimer.
49
  *   2. Redistributions in binary form must reproduce the above copyright notice,
50
  *      this list of conditions and the following disclaimer in the documentation
51
  *      and/or other materials provided with the distribution.
52
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
53
  *      may be used to endorse or promote products derived from this software
54
  *      without specific prior written permission.
55
  *
56
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
57
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
59
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
60
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
61
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
62
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
63
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
64
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
65
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
66
  *
67
  ******************************************************************************
68
  */
69
 
70
/* Includes ------------------------------------------------------------------*/
71
#include "stm32f1xx_hal.h"
72
/** @addtogroup STM32F1xx_HAL_Driver
73
  * @{
74
  */
75
 
76
 
77
#ifdef HAL_HCD_MODULE_ENABLED
78
 
79
#if defined(STM32F105xC) || defined(STM32F107xC)
80
 
81
/** @defgroup HCD HCD
82
  * @brief HCD HAL module driver
83
  * @{
84
  */
85
 
86
/* Private types -------------------------------------------------------------*/
87
/* Private variables ---------------------------------------------------------*/
88
/* Private constants ---------------------------------------------------------*/
89
/* Private macros ------------------------------------------------------------*/
90
/* Private function ----------------------------------------------------------*/
91
/** @defgroup HCD_Private_Functions HCD Private Functions
92
  * @{
93
  */
94
static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
95
static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
96
static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd);
97
static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd);
98
/**
99
  * @}
100
  */
101
 
102
/* Exported functions --------------------------------------------------------*/
103
/** @defgroup HCD_Exported_Functions HCD Exported Functions
104
  * @{
105
  */
106
 
107
/** @defgroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions
108
 *  @brief    Initialization and Configuration functions
109
 *
110
@verbatim
111
 ===============================================================================
112
          ##### Initialization and de-initialization functions #####
113
 ===============================================================================
114
    [..]  This section provides functions allowing to:
115
 
116
@endverbatim
117
  * @{
118
  */
119
 
120
/**
121
  * @brief  Initialize the host driver
122
  * @param  hhcd: HCD handle
123
  * @retval HAL status
124
  */
125
HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd)
126
{
127
  /* Check the HCD handle allocation */
128
  if(hhcd == NULL)
129
  {
130
    return HAL_ERROR;
131
  }
132
 
133
  /* Check the parameters */
134
  assert_param(IS_HCD_ALL_INSTANCE(hhcd->Instance));
135
 
136
  if(hhcd->State == HAL_HCD_STATE_RESET)
137
  {  
138
    /* Allocate lock resource and initialize it */
139
    hhcd->Lock = HAL_UNLOCKED;
140
 
141
    /* Init the low level hardware : GPIO, CLOCK, NVIC... */
142
    HAL_HCD_MspInit(hhcd);
143
  }
144
 
145
  hhcd->State = HAL_HCD_STATE_BUSY;
146
 
147
  /* Disable the Interrupts */
148
  __HAL_HCD_DISABLE(hhcd);
149
 
150
  /* Init the Core (common init.) */
151
  USB_CoreInit(hhcd->Instance, hhcd->Init);
152
 
153
  /* Force Host Mode*/
154
  USB_SetCurrentMode(hhcd->Instance , USB_HOST_MODE);
155
 
156
  /* Init Host */
157
  USB_HostInit(hhcd->Instance, hhcd->Init);
158
 
159
  hhcd->State= HAL_HCD_STATE_READY;
160
 
161
  return HAL_OK;
162
}
163
 
164
/**
165
  * @brief  Initialize a host channel
166
  * @param  hhcd: HCD handle
167
  * @param  ch_num: Channel number.
168
  *         This parameter can be a value from 1 to 15
169
  * @param  epnum: Endpoint number.
170
  *          This parameter can be a value from 1 to 15
171
  * @param  dev_address : Current device address
172
  *          This parameter can be a value from 0 to 255
173
  * @param  speed: Current device speed.
174
  *          This parameter can be one of these values:
175
  *            HCD_SPEED_FULL: Full speed mode,
176
  *            HCD_SPEED_LOW: Low speed mode
177
  * @param  ep_type: Endpoint Type.
178
  *          This parameter can be one of these values:
179
  *            EP_TYPE_CTRL: Control type,
180
  *            EP_TYPE_ISOC: Isochronous type,
181
  *            EP_TYPE_BULK: Bulk type,
182
  *            EP_TYPE_INTR: Interrupt type
183
  * @param  mps: Max Packet Size.
184
  *          This parameter can be a value from 0 to32K
185
  * @retval HAL status
186
  */
187
HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd,
188
                                  uint8_t ch_num,
189
                                  uint8_t epnum,
190
                                  uint8_t dev_address,
191
                                  uint8_t speed,
192
                                  uint8_t ep_type,
193
                                  uint16_t mps)
194
{
195
  HAL_StatusTypeDef status = HAL_OK;
196
 
197
  __HAL_LOCK(hhcd);
198
 
199
  hhcd->hc[ch_num].dev_addr = dev_address;
200
  hhcd->hc[ch_num].max_packet = mps;
201
  hhcd->hc[ch_num].ch_num = ch_num;
202
  hhcd->hc[ch_num].ep_type = ep_type;
203
  hhcd->hc[ch_num].ep_num = epnum & 0x7FU;
204
  hhcd->hc[ch_num].ep_is_in = ((epnum & 0x80U) == 0x80U);
205
  hhcd->hc[ch_num].speed = speed;
206
 
207
  status =  USB_HC_Init(hhcd->Instance,
208
                        ch_num,
209
                        epnum,
210
                        dev_address,
211
                        speed,
212
                        ep_type,
213
                        mps);
214
  __HAL_UNLOCK(hhcd);
215
 
216
  return status;
217
}
218
 
219
/**
220
  * @brief  Halt a host channel
221
  * @param  hhcd: HCD handle
222
  * @param  ch_num: Channel number.
223
  *         This parameter can be a value from 1 to 15
224
  * @retval HAL status
225
  */
226
HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd,
227
                                  uint8_t ch_num)
228
{
229
  __HAL_LOCK(hhcd);
230
  USB_HC_Halt(hhcd->Instance, ch_num);
231
  __HAL_UNLOCK(hhcd);
232
 
233
  return HAL_OK;
234
}
235
 
236
/**
237
  * @brief  DeInitialize the host driver
238
  * @param  hhcd: HCD handle
239
  * @retval HAL status
240
  */
241
HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd)
242
{
243
  /* Check the HCD handle allocation */
244
  if(hhcd == NULL)
245
  {
246
    return HAL_ERROR;
247
  }
248
 
249
  hhcd->State = HAL_HCD_STATE_BUSY;
250
 
251
  /* DeInit the low level hardware */
252
  HAL_HCD_MspDeInit(hhcd);
253
 
254
  __HAL_HCD_DISABLE(hhcd);
255
 
256
  hhcd->State = HAL_HCD_STATE_RESET;
257
 
258
  return HAL_OK;
259
}
260
 
261
/**
262
  * @brief  Initializes the HCD MSP.
263
  * @param  hhcd: HCD handle
264
  * @retval None
265
  */
266
__weak void  HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd)
267
{
268
  /* Prevent unused argument(s) compilation warning */
269
  UNUSED(hhcd);
270
  /* NOTE : This function Should not be modified, when the callback is needed,
271
            the HAL_HCD_MspInit could be implemented in the user file
272
   */
273
}
274
 
275
/**
276
  * @brief  DeInitializes HCD MSP.
277
  * @param  hhcd: HCD handle
278
  * @retval None
279
  */
280
__weak void  HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd)
281
{
282
  /* Prevent unused argument(s) compilation warning */
283
  UNUSED(hhcd);
284
  /* NOTE : This function Should not be modified, when the callback is needed,
285
            the HAL_HCD_MspDeInit could be implemented in the user file
286
   */
287
}
288
 
289
/**
290
  * @}
291
  */
292
 
293
/** @defgroup HCD_Exported_Functions_Group2 IO operation functions
294
  *  @brief   HCD IO operation functions
295
  *
296
@verbatim
297
 ===============================================================================
298
                      ##### IO operation functions #####
299
 ===============================================================================
300
    This subsection provides a set of functions allowing to manage the USB Host Data
301
    Transfer
302
 
303
@endverbatim
304
  * @{
305
  */
306
 
307
/**                                
308
  * @brief  Submit a new URB for processing
309
  * @param  hhcd: HCD handle
310
  * @param  ch_num: Channel number.
311
  *         This parameter can be a value from 1 to 15
312
  * @param  direction: Channel number.
313
  *          This parameter can be one of these values:
314
  *           0 : Output / 1 : Input
315
  * @param  ep_type: Endpoint Type.
316
  *          This parameter can be one of these values:
317
  *            EP_TYPE_CTRL: Control type/
318
  *            EP_TYPE_ISOC: Isochronous type/
319
  *            EP_TYPE_BULK: Bulk type/
320
  *            EP_TYPE_INTR: Interrupt type/
321
  * @param  token: Endpoint Type.
322
  *          This parameter can be one of these values:
323
  *            0: HC_PID_SETUP / 1: HC_PID_DATA1
324
  * @param  pbuff: pointer to URB data
325
  * @param  length: Length of URB data
326
  * @param  do_ping: activate do ping protocol (for high speed only).
327
  *          This parameter can be one of these values:
328
  *           0 : do ping inactive / 1 : do ping active
329
  * @retval HAL status
330
  */
331
HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd,
332
                                           uint8_t ch_num,
333
                                           uint8_t direction,
334
                                           uint8_t ep_type,  
335
                                           uint8_t token,
336
                                           uint8_t* pbuff,
337
                                           uint16_t length,
338
                                           uint8_t do_ping)
339
{
340
  hhcd->hc[ch_num].ep_is_in = direction;
341
  hhcd->hc[ch_num].ep_type  = ep_type;
342
 
343
  if(token == 0U)
344
  {
345
    hhcd->hc[ch_num].data_pid = HC_PID_SETUP;
346
  }
347
  else
348
  {
349
    hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
350
  }
351
 
352
  /* Manage Data Toggle */
353
  switch(ep_type)
354
  {
355
  case EP_TYPE_CTRL:
356
    if((token == 1U) && (direction == 0U)) /*send data */
357
    {
358
      if (length == 0U)
359
      { /* For Status OUT stage, Length==0, Status Out PID = 1 */
360
        hhcd->hc[ch_num].toggle_out = 1U;
361
      }
362
 
363
      /* Set the Data Toggle bit as per the Flag */
364
      if ( hhcd->hc[ch_num].toggle_out == 0U)
365
      { /* Put the PID 0 */
366
        hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
367
      }
368
      else
369
      { /* Put the PID 1 */
370
        hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
371
      }
372
      if(hhcd->hc[ch_num].urb_state  != URB_NOTREADY)
373
      {
374
        hhcd->hc[ch_num].do_ping = do_ping;
375
      }
376
    }
377
    break;
378
 
379
  case EP_TYPE_BULK:
380
    if(direction == 0U)
381
    {
382
      /* Set the Data Toggle bit as per the Flag */
383
      if ( hhcd->hc[ch_num].toggle_out == 0U)
384
      { /* Put the PID 0 */
385
        hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
386
      }
387
      else
388
      { /* Put the PID 1 */
389
        hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
390
      }
391
      if(hhcd->hc[ch_num].urb_state  != URB_NOTREADY)
392
      {
393
        hhcd->hc[ch_num].do_ping = do_ping;
394
      }
395
    }
396
    else
397
    {
398
      if( hhcd->hc[ch_num].toggle_in == 0U)
399
      {
400
        hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
401
      }
402
      else
403
      {
404
        hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
405
      }
406
    }
407
    break;
408
 
409
  case EP_TYPE_INTR:
410
    if(direction == 0U)
411
    {
412
      /* Set the Data Toggle bit as per the Flag */
413
      if ( hhcd->hc[ch_num].toggle_out == 0U)
414
      { /* Put the PID 0 */
415
        hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
416
      }
417
      else
418
      { /* Put the PID 1 */
419
        hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
420
      }
421
    }
422
    else
423
    {
424
      if( hhcd->hc[ch_num].toggle_in == 0U)
425
      {
426
        hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
427
      }
428
      else
429
      {
430
        hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
431
      }
432
    }
433
    break;
434
 
435
  case EP_TYPE_ISOC:
436
    hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
437
    break;
438
  }
439
 
440
  hhcd->hc[ch_num].xfer_buff = pbuff;
441
  hhcd->hc[ch_num].xfer_len  = length;
442
  hhcd->hc[ch_num].urb_state = URB_IDLE;
443
  hhcd->hc[ch_num].xfer_count = 0U;
444
  hhcd->hc[ch_num].ch_num = ch_num;
445
  hhcd->hc[ch_num].state = HC_IDLE;
446
 
447
  return USB_HC_StartXfer(hhcd->Instance, &(hhcd->hc[ch_num]));
448
}
449
 
450
/**
451
  * @brief  handle HCD interrupt request.
452
  * @param  hhcd: HCD handle
453
  * @retval None
454
  */
455
void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd)
456
{
457
  USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
458
 
459
  uint32_t index = 0U, interrupt = 0U;
460
 
461
  /* ensure that we are in device mode */
462
  if (USB_GetMode(hhcd->Instance) == USB_OTG_MODE_HOST)
463
  {
464
    /* Avoid spurious interrupt */
465
    if(__HAL_HCD_IS_INVALID_INTERRUPT(hhcd))
466
    {
467
      return;
468
    }
469
 
470
    if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
471
    {
472
     /* Incorrect mode, acknowledge the interrupt */
473
      __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
474
    }
475
 
476
    if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR))
477
    {
478
     /* Incorrect mode, acknowledge the interrupt */
479
      __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR);
480
    }
481
 
482
    if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE))
483
    {
484
     /* Incorrect mode, acknowledge the interrupt */
485
      __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE);
486
    }
487
 
488
    if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_MMIS))
489
    {
490
     /* Incorrect mode, acknowledge the interrupt */
491
      __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_MMIS);
492
    }
493
 
494
    /* Handle Host Disconnect Interrupts */
495
    if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT))
496
    {
497
 
498
      /* Cleanup HPRT */
499
      USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
500
        USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
501
 
502
      /* Handle Host Port Interrupts */
503
      HAL_HCD_Disconnect_Callback(hhcd);
504
      USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ);
505
      __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT);
506
    }
507
 
508
    /* Handle Host Port Interrupts */
509
    if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HPRTINT))
510
    {
511
      HCD_Port_IRQHandler (hhcd);
512
    }
513
 
514
    /* Handle Host SOF Interrupts */
515
    if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF))
516
    {
517
      HAL_HCD_SOF_Callback(hhcd);
518
      __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_SOF);
519
    }
520
 
521
    /* Handle Host channel Interrupts */
522
    if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT))
523
    {
524
      interrupt = USB_HC_ReadInterrupt(hhcd->Instance);
525
      for (index = 0U; index < hhcd->Init.Host_channels ; index++)
526
      {
527
        if (interrupt & (1 << index))
528
        {
529
          if ((USBx_HC(index)->HCCHAR) &  USB_OTG_HCCHAR_EPDIR)
530
          {
531
            HCD_HC_IN_IRQHandler (hhcd, index);
532
          }
533
          else
534
          {
535
            HCD_HC_OUT_IRQHandler (hhcd, index);
536
          }
537
        }
538
      }
539
      __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_HCINT);
540
    }
541
 
542
    /* Handle Rx Queue Level Interrupts */
543
    if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_RXFLVL))
544
    {
545
      USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
546
 
547
      HCD_RXQLVL_IRQHandler (hhcd);
548
 
549
      USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
550
    }
551
  }
552
}
553
 
554
/**
555
  * @brief  SOF callback.
556
  * @param  hhcd: HCD handle
557
  * @retval None
558
  */
559
__weak void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
560
{
561
  /* Prevent unused argument(s) compilation warning */
562
  UNUSED(hhcd);
563
  /* NOTE : This function Should not be modified, when the callback is needed,
564
            the HAL_HCD_SOF_Callback could be implemented in the user file
565
   */
566
}
567
 
568
/**
569
  * @brief Connexion Event callback.
570
  * @param  hhcd: HCD handle
571
  * @retval None
572
  */
573
__weak void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
574
{
575
  /* Prevent unused argument(s) compilation warning */
576
  UNUSED(hhcd);
577
  /* NOTE : This function Should not be modified, when the callback is needed,
578
            the HAL_HCD_Connect_Callback could be implemented in the user file
579
   */
580
}
581
 
582
/**
583
  * @brief  Disonnection Event callback.
584
  * @param  hhcd: HCD handle
585
  * @retval None
586
  */
587
__weak void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
588
{
589
  /* Prevent unused argument(s) compilation warning */
590
  UNUSED(hhcd);
591
  /* NOTE : This function Should not be modified, when the callback is needed,
592
            the HAL_HCD_Disconnect_Callback could be implemented in the user file
593
   */
594
}
595
 
596
/**
597
  * @brief  Notify URB state change callback.
598
  * @param  hhcd: HCD handle
599
  * @param  chnum: Channel number.
600
  *         This parameter can be a value from 1 to 15
601
  * @param  urb_state:
602
  *          This parameter can be one of these values:
603
  *            URB_IDLE/
604
  *            URB_DONE/
605
  *            URB_NOTREADY/
606
  *            URB_NYET/
607
  *            URB_ERROR/  
608
  *            URB_STALL/
609
  * @retval None
610
  */
611
__weak void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
612
{
613
  /* Prevent unused argument(s) compilation warning */
614
  UNUSED(hhcd);
615
  UNUSED(chnum);
616
  UNUSED(urb_state);
617
  /* NOTE : This function Should not be modified, when the callback is needed,
618
            the HAL_HCD_HC_NotifyURBChange_Callback could be implemented in the user file
619
   */
620
}
621
 
622
/**
623
  * @}
624
  */
625
 
626
/** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions
627
 *  @brief   management functions
628
 *
629
@verbatim
630
 ===============================================================================
631
                      ##### Peripheral Control functions #####
632
 ===============================================================================
633
    [..]
634
    This subsection provides a set of functions allowing to control the HCD data
635
    transfers.
636
 
637
@endverbatim
638
  * @{
639
  */
640
 
641
/**
642
  * @brief  Start the host driver
643
  * @param  hhcd: HCD handle
644
  * @retval HAL status
645
  */
646
HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd)
647
{
648
  __HAL_LOCK(hhcd);
649
  __HAL_HCD_ENABLE(hhcd);
650
  USB_DriveVbus(hhcd->Instance, 1U);
651
  __HAL_UNLOCK(hhcd);
652
  return HAL_OK;
653
}
654
 
655
/**
656
  * @brief  Stop the host driver
657
  * @param  hhcd: HCD handle
658
  * @retval HAL status
659
  */
660
 
661
HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd)
662
{
663
  __HAL_LOCK(hhcd);
664
  USB_StopHost(hhcd->Instance);
665
  __HAL_UNLOCK(hhcd);
666
  return HAL_OK;
667
}
668
 
669
/**
670
  * @brief  Reset the host port
671
  * @param  hhcd: HCD handle
672
  * @retval HAL status
673
  */
674
HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd)
675
{
676
  return (USB_ResetPort(hhcd->Instance));
677
}
678
 
679
/**
680
  * @}
681
  */
682
 
683
/** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions
684
 *  @brief   Peripheral State functions
685
 *
686
@verbatim
687
 ===============================================================================
688
                      ##### Peripheral State functions #####
689
 ===============================================================================
690
    [..]
691
    This subsection permits to get in run-time the status of the peripheral
692
    and the data flow.
693
 
694
@endverbatim
695
  * @{
696
  */
697
 
698
/**
699
  * @brief  Return the HCD handle state
700
  * @param  hhcd: HCD handle
701
  * @retval HAL state
702
  */
703
HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef *hhcd)
704
{
705
  return hhcd->State;
706
}
707
 
708
/**
709
  * @brief  Return  URB state for a channel
710
  * @param  hhcd: HCD handle
711
  * @param  chnum: Channel number.
712
  *         This parameter can be a value from 1 to 15
713
  * @retval URB state.
714
  *          This parameter can be one of these values:
715
  *            URB_IDLE/
716
  *            URB_DONE/
717
  *            URB_NOTREADY/
718
  *            URB_NYET/
719
  *            URB_ERROR/
720
  *            URB_STALL/
721
  */
722
HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
723
{
724
  return hhcd->hc[chnum].urb_state;
725
}
726
 
727
 
728
/**
729
  * @brief  Return the last host transfer size
730
  * @param  hhcd: HCD handle
731
  * @param  chnum: Channel number.
732
  *         This parameter can be a value from 1 to 15
733
  * @retval last transfer size in byte
734
  */
735
uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef *hhcd, uint8_t chnum)
736
{
737
  return hhcd->hc[chnum].xfer_count;
738
}
739
 
740
/**
741
  * @brief  Return the Host Channel state
742
  * @param  hhcd: HCD handle
743
  * @param  chnum: Channel number.
744
  *         This parameter can be a value from 1 to 15
745
  * @retval Host channel state
746
  *          This parameter can be one of the these values:
747
  *            HC_IDLE/
748
  *            HC_XFRC/
749
  *            HC_HALTED/
750
  *            HC_NYET/
751
  *            HC_NAK/
752
  *            HC_STALL/
753
  *            HC_XACTERR/
754
  *            HC_BBLERR/
755
  *            HC_DATATGLERR/
756
  */
757
HCD_HCStateTypeDef  HAL_HCD_HC_GetState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
758
{
759
  return hhcd->hc[chnum].state;
760
}
761
 
762
/**
763
  * @brief  Return the current Host frame number
764
  * @param  hhcd: HCD handle
765
  * @retval Current Host frame number
766
  */
767
uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd)
768
{
769
  return (USB_GetCurrentFrame(hhcd->Instance));
770
}
771
 
772
/**
773
  * @brief  Return the Host enumeration speed
774
  * @param  hhcd: HCD handle
775
  * @retval Enumeration speed
776
  */
777
uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd)
778
{
779
  return (USB_GetHostSpeed(hhcd->Instance));
780
}
781
 
782
/**
783
  * @}
784
  */
785
/**
786
  * @}
787
  */
788
 
789
/** @addtogroup HCD_Private_Functions
790
  * @{
791
  */
792
/**
793
  * @brief  This function handles Host Channel IN interrupt requests.
794
  * @param  hhcd: HCD handle
795
  * @param  chnum: Channel number.
796
  *         This parameter can be a value from 1 to 15
797
  * @retval none
798
  */
799
static void HCD_HC_IN_IRQHandler (HCD_HandleTypeDef *hhcd, uint8_t chnum)
800
{
801
  USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
802
  uint32_t tmpreg = 0U;
803
 
804
  if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_AHBERR)
805
  {
806
    __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
807
    __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
808
  }  
809
  else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_ACK)
810
  {
811
    __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
812
  }
813
 
814
  else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_STALL)
815
  {
816
    __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
817
    hhcd->hc[chnum].state = HC_STALL;
818
    __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
819
    __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);
820
    USB_HC_Halt(hhcd->Instance, chnum);
821
  }
822
  else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_DTERR)
823
  {
824
    __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
825
    USB_HC_Halt(hhcd->Instance, chnum);
826
    __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
827
    hhcd->hc[chnum].state = HC_DATATGLERR;
828
    __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
829
  }
830
 
831
  if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_FRMOR)
832
  {
833
    __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
834
    USB_HC_Halt(hhcd->Instance, chnum);
835
    __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
836
  }
837
 
838
  else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_XFRC)
839
  {
840
    hhcd->hc[chnum].state = HC_XFRC;
841
    hhcd->hc[chnum].ErrCnt = 0U;
842
    __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
843
 
844
    if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)||
845
        (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
846
    {
847
      __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
848
      USB_HC_Halt(hhcd->Instance, chnum);
849
      __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
850
 
851
    }
852
    else if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
853
    {
854
      USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
855
      hhcd->hc[chnum].urb_state = URB_DONE;
856
      HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
857
    }
858
    hhcd->hc[chnum].toggle_in ^= 1U;
859
 
860
  }
861
  else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_CHH)
862
  {
863
    __HAL_HCD_MASK_HALT_HC_INT(chnum);
864
 
865
    if(hhcd->hc[chnum].state == HC_XFRC)
866
    {
867
      hhcd->hc[chnum].urb_state  = URB_DONE;
868
    }
869
    else if (hhcd->hc[chnum].state == HC_STALL)
870
    {
871
      hhcd->hc[chnum].urb_state  = URB_STALL;
872
    }
873
    else if((hhcd->hc[chnum].state == HC_XACTERR) ||
874
            (hhcd->hc[chnum].state == HC_DATATGLERR))
875
    {
876
      if(hhcd->hc[chnum].ErrCnt++ > 3U)
877
      {
878
        hhcd->hc[chnum].ErrCnt = 0U;
879
        hhcd->hc[chnum].urb_state = URB_ERROR;
880
      }
881
      else
882
      {
883
        hhcd->hc[chnum].urb_state = URB_NOTREADY;
884
      }
885
 
886
      /* re-activate the channel  */
887
      tmpreg = USBx_HC(chnum)->HCCHAR;
888
      tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
889
      tmpreg |= USB_OTG_HCCHAR_CHENA;
890
      USBx_HC(chnum)->HCCHAR = tmpreg;
891
    }
892
    __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
893
    HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
894
  }
895
 
896
  else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_TXERR)
897
  {
898
    __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
899
     hhcd->hc[chnum].ErrCnt++;
900
     hhcd->hc[chnum].state = HC_XACTERR;
901
     USB_HC_Halt(hhcd->Instance, chnum);
902
     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
903
  }
904
  else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_NAK)
905
  {
906
    if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
907
    {
908
      __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
909
      USB_HC_Halt(hhcd->Instance, chnum);
910
    }
911
    else if  ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)||
912
              (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
913
    {
914
      /* re-activate the channel  */
915
      tmpreg = USBx_HC(chnum)->HCCHAR;
916
      tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
917
      tmpreg |= USB_OTG_HCCHAR_CHENA;
918
      USBx_HC(chnum)->HCCHAR = tmpreg;
919
    }
920
    hhcd->hc[chnum].state = HC_NAK;
921
     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
922
  }
923
}
924
 
925
/**
926
  * @brief  This function handles Host Channel OUT interrupt requests.
927
  * @param  hhcd: HCD handle
928
  * @param  chnum: Channel number.
929
  *         This parameter can be a value from 1 to 15
930
  * @retval none
931
  */
932
static void HCD_HC_OUT_IRQHandler (HCD_HandleTypeDef *hhcd, uint8_t chnum)
933
{
934
  USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
935
  uint32_t tmpreg = 0U;
936
 
937
  if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_AHBERR)
938
  {
939
    __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
940
    __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
941
  }
942
  else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_ACK)
943
  {
944
    __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
945
 
946
    if( hhcd->hc[chnum].do_ping == 1U)
947
    {
948
      hhcd->hc[chnum].state = HC_NYET;
949
      __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
950
      USB_HC_Halt(hhcd->Instance, chnum);
951
      hhcd->hc[chnum].urb_state  = URB_NOTREADY;
952
    }
953
  }
954
 
955
  else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_NYET)
956
  {
957
    hhcd->hc[chnum].state = HC_NYET;
958
    hhcd->hc[chnum].ErrCnt= 0U;
959
    __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
960
    USB_HC_Halt(hhcd->Instance, chnum);
961
    __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NYET);
962
 
963
  }
964
 
965
  else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_FRMOR)
966
  {
967
    __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
968
    USB_HC_Halt(hhcd->Instance, chnum);
969
    __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
970
  }
971
 
972
  else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_XFRC)
973
  {
974
    hhcd->hc[chnum].ErrCnt = 0U;
975
    __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
976
    USB_HC_Halt(hhcd->Instance, chnum);
977
    __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
978
    hhcd->hc[chnum].state = HC_XFRC;
979
  }
980
  else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_STALL)
981
  {
982
    __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);
983
    __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
984
    USB_HC_Halt(hhcd->Instance, chnum);
985
    hhcd->hc[chnum].state = HC_STALL;
986
  }
987
  else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_NAK)
988
  {
989
    hhcd->hc[chnum].ErrCnt = 0U;
990
    __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
991
    USB_HC_Halt(hhcd->Instance, chnum);
992
    hhcd->hc[chnum].state = HC_NAK;
993
    __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
994
  }
995
  else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_TXERR)
996
  {
997
    __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
998
    USB_HC_Halt(hhcd->Instance, chnum);
999
    hhcd->hc[chnum].state = HC_XACTERR;
1000
     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
1001
  }
1002
  else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_DTERR)
1003
  {
1004
    __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
1005
    USB_HC_Halt(hhcd->Instance, chnum);
1006
    __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
1007
    __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
1008
    hhcd->hc[chnum].state = HC_DATATGLERR;
1009
  }
1010
  else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_CHH)
1011
  {
1012
    __HAL_HCD_MASK_HALT_HC_INT(chnum);
1013
 
1014
    if(hhcd->hc[chnum].state == HC_XFRC)
1015
    {
1016
      hhcd->hc[chnum].urb_state  = URB_DONE;
1017
      if (hhcd->hc[chnum].ep_type == EP_TYPE_BULK)
1018
      {
1019
        hhcd->hc[chnum].toggle_out ^= 1U;
1020
      }
1021
    }
1022
    else if (hhcd->hc[chnum].state == HC_NAK)
1023
    {
1024
      hhcd->hc[chnum].urb_state  = URB_NOTREADY;
1025
    }
1026
    else if (hhcd->hc[chnum].state == HC_NYET)
1027
    {
1028
      hhcd->hc[chnum].urb_state  = URB_NOTREADY;
1029
      hhcd->hc[chnum].do_ping = 0U;
1030
    }
1031
    else if (hhcd->hc[chnum].state == HC_STALL)
1032
    {
1033
      hhcd->hc[chnum].urb_state  = URB_STALL;
1034
    }
1035
    else if((hhcd->hc[chnum].state == HC_XACTERR) ||
1036
            (hhcd->hc[chnum].state == HC_DATATGLERR))
1037
    {
1038
      if(hhcd->hc[chnum].ErrCnt++ > 3U)
1039
      {
1040
        hhcd->hc[chnum].ErrCnt = 0U;
1041
        hhcd->hc[chnum].urb_state = URB_ERROR;
1042
      }
1043
      else
1044
      {
1045
        hhcd->hc[chnum].urb_state = URB_NOTREADY;
1046
      }
1047
 
1048
      /* re-activate the channel  */
1049
      tmpreg = USBx_HC(chnum)->HCCHAR;
1050
      tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1051
      tmpreg |= USB_OTG_HCCHAR_CHENA;
1052
      USBx_HC(chnum)->HCCHAR = tmpreg;
1053
    }
1054
 
1055
    __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
1056
    HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1057
  }
1058
}
1059
 
1060
/**
1061
  * @brief  This function handles Rx Queue Level interrupt requests.
1062
  * @param  hhcd: HCD handle
1063
  * @retval none
1064
  */
1065
static void HCD_RXQLVL_IRQHandler  (HCD_HandleTypeDef *hhcd)
1066
{
1067
  USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
1068
  uint8_t                       channelnum =0U;
1069
  uint32_t                      pktsts;
1070
  uint32_t                      pktcnt;
1071
  uint32_t                      temp = 0U;
1072
  uint32_t tmpreg = 0U;
1073
 
1074
  temp = hhcd->Instance->GRXSTSP;
1075
  channelnum = temp &  USB_OTG_GRXSTSP_EPNUM;
1076
  pktsts = (temp &  USB_OTG_GRXSTSP_PKTSTS) >> 17U;
1077
  pktcnt = (temp &  USB_OTG_GRXSTSP_BCNT) >> 4U;
1078
 
1079
  switch (pktsts)
1080
  {
1081
  case GRXSTS_PKTSTS_IN:
1082
    /* Read the data into the host buffer. */
1083
    if ((pktcnt > 0U) && (hhcd->hc[channelnum].xfer_buff != (void  *)0U))
1084
    {
1085
      USB_ReadPacket(hhcd->Instance, hhcd->hc[channelnum].xfer_buff, pktcnt);
1086
 
1087
      /*manage multiple Xfer */
1088
      hhcd->hc[channelnum].xfer_buff += pktcnt;
1089
      hhcd->hc[channelnum].xfer_count  += pktcnt;
1090
 
1091
      if((USBx_HC(channelnum)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) > 0U)
1092
      {
1093
        /* re-activate the channel when more packets are expected */
1094
        tmpreg = USBx_HC(channelnum)->HCCHAR;
1095
        tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1096
        tmpreg |= USB_OTG_HCCHAR_CHENA;
1097
        USBx_HC(channelnum)->HCCHAR = tmpreg;
1098
        hhcd->hc[channelnum].toggle_in ^= 1U;
1099
      }
1100
    }
1101
    break;
1102
 
1103
  case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
1104
    break;
1105
 
1106
  case GRXSTS_PKTSTS_IN_XFER_COMP:
1107
  case GRXSTS_PKTSTS_CH_HALTED:
1108
  default:
1109
    break;
1110
  }
1111
}
1112
 
1113
/**
1114
  * @brief  This function handles Host Port interrupt requests.
1115
  * @param  hhcd: HCD handle
1116
  * @retval None
1117
  */
1118
static void HCD_Port_IRQHandler (HCD_HandleTypeDef *hhcd)
1119
{
1120
  USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;  
1121
  __IO uint32_t hprt0 = 0, hprt0_dup = 0U;
1122
 
1123
  /* Handle Host Port Interrupts */
1124
  hprt0 = USBx_HPRT0;
1125
  hprt0_dup = USBx_HPRT0;
1126
 
1127
  hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
1128
                 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
1129
 
1130
  /* Check whether Port Connect Detected */
1131
  if((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET)
1132
  {
1133
    if((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS)
1134
    {
1135
      USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT);
1136
      HAL_HCD_Connect_Callback(hhcd);
1137
    }
1138
    hprt0_dup  |= USB_OTG_HPRT_PCDET;
1139
  }
1140
 
1141
  /* Check whether Port Enable Changed */
1142
  if((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG)
1143
  {
1144
    hprt0_dup |= USB_OTG_HPRT_PENCHNG;
1145
 
1146
    if((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA)
1147
    {
1148
      if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17U))
1149
      {
1150
        USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_6_MHZ );
1151
      }
1152
      else
1153
      {
1154
        USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ );
1155
      }
1156
      HAL_HCD_Connect_Callback(hhcd);
1157
    }
1158
    else
1159
    {
1160
      /* Cleanup HPRT */
1161
      USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
1162
        USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
1163
 
1164
      USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT);
1165
    }
1166
  }
1167
 
1168
  /* Check For an over current */
1169
  if((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG)
1170
  {
1171
    hprt0_dup |= USB_OTG_HPRT_POCCHNG;
1172
  }
1173
 
1174
  /* Clear Port Interrupts */
1175
  USBx_HPRT0 = hprt0_dup;
1176
}
1177
 
1178
/**
1179
  * @}
1180
  */
1181
 
1182
/**
1183
  * @}
1184
  */
1185
 
1186
#endif /* STM32F105xC || STM32F107xC */
1187
 
1188
#endif /* HAL_HCD_MODULE_ENABLED */
1189
 
1190
/**
1191
  * @}
1192
  */
1193
 
1194
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/