Subversion Repositories DashDisplay

Rev

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