Subversion Repositories dashGPS

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
  * @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 macros
27
             (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
28
        (##) Initialize the related GPIO clocks
29
        (##) Configure HCD pin-out
30
        (##) Configure HCD NVIC interrupt
31
 
32
    (#)Associate the Upper USB Host stack to the HAL HCD Driver:
33
        (##) hhcd.pData = phost;
34
 
35
    (#)Enable HCD transmission and reception:
36
        (##) HAL_HCD_Start();
37
 
38
  @endverbatim
39
  ******************************************************************************
40
  * @attention
41
  *
42
  * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
43
  * All rights reserved.</center></h2>
44
  *
45
  * This software component is licensed by ST under BSD 3-Clause license,
46
  * the "License"; You may not use this file except in compliance with the
47
  * License. You may obtain a copy of the License at:
48
  *                        opensource.org/licenses/BSD-3-Clause
49
  *
50
  ******************************************************************************
51
  */
52
 
53
/* Includes ------------------------------------------------------------------*/
54
#include "stm32f1xx_hal.h"
55
 
56
/** @addtogroup STM32F1xx_HAL_Driver
57
  * @{
58
  */
59
 
60
#ifdef HAL_HCD_MODULE_ENABLED
61
 
62
#if defined (USB_OTG_FS)
63
 
64
/** @defgroup HCD HCD
65
  * @brief HCD HAL module driver
66
  * @{
67
  */
68
 
69
/* Private typedef -----------------------------------------------------------*/
70
/* Private define ------------------------------------------------------------*/
71
/* Private macro -------------------------------------------------------------*/
72
/* Private variables ---------------------------------------------------------*/
73
/* Private function prototypes -----------------------------------------------*/
74
/** @defgroup HCD_Private_Functions HCD Private Functions
75
  * @{
76
  */
77
static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
78
static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
79
static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd);
80
static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd);
81
/**
82
  * @}
83
  */
84
 
85
/* Exported functions --------------------------------------------------------*/
86
/** @defgroup HCD_Exported_Functions HCD Exported Functions
87
  * @{
88
  */
89
 
90
/** @defgroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions
91
 *  @brief    Initialization and Configuration functions
92
 *
93
@verbatim
94
 ===============================================================================
95
          ##### Initialization and de-initialization functions #####
96
 ===============================================================================
97
    [..]  This section provides functions allowing to:
98
 
99
@endverbatim
100
  * @{
101
  */
102
 
103
/**
104
  * @brief  Initialize the host driver.
105
  * @param  hhcd HCD handle
106
  * @retval HAL status
107
  */
108
HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd)
109
{
110
  USB_OTG_GlobalTypeDef *USBx;
111
 
112
  /* Check the HCD handle allocation */
113
  if (hhcd == NULL)
114
  {
115
    return HAL_ERROR;
116
  }
117
 
118
  /* Check the parameters */
119
  assert_param(IS_HCD_ALL_INSTANCE(hhcd->Instance));
120
 
121
  USBx = hhcd->Instance;
122
 
123
  if (hhcd->State == HAL_HCD_STATE_RESET)
124
  {
125
    /* Allocate lock resource and initialize it */
126
    hhcd->Lock = HAL_UNLOCKED;
127
 
128
#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
129
    hhcd->SOFCallback = HAL_HCD_SOF_Callback;
130
    hhcd->ConnectCallback = HAL_HCD_Connect_Callback;
131
    hhcd->DisconnectCallback = HAL_HCD_Disconnect_Callback;
132
    hhcd->PortEnabledCallback = HAL_HCD_PortEnabled_Callback;
133
    hhcd->PortDisabledCallback = HAL_HCD_PortDisabled_Callback;
134
    hhcd->HC_NotifyURBChangeCallback = HAL_HCD_HC_NotifyURBChange_Callback;
135
 
136
    if (hhcd->MspInitCallback == NULL)
137
    {
138
      hhcd->MspInitCallback = HAL_HCD_MspInit;
139
    }
140
 
141
    /* Init the low level hardware */
142
    hhcd->MspInitCallback(hhcd);
143
#else
144
    /* Init the low level hardware : GPIO, CLOCK, NVIC... */
145
    HAL_HCD_MspInit(hhcd);
146
#endif /* (USE_HAL_HCD_REGISTER_CALLBACKS) */
147
  }
148
 
149
  hhcd->State = HAL_HCD_STATE_BUSY;
150
 
151
  /* Disable DMA mode for FS instance */
152
  if ((USBx->CID & (0x1U << 8)) == 0U)
153
  {
154
    hhcd->Init.dma_enable = 0U;
155
  }
156
 
157
  /* Disable the Interrupts */
158
  __HAL_HCD_DISABLE(hhcd);
159
 
160
  /* Init the Core (common init.) */
161
  (void)USB_CoreInit(hhcd->Instance, hhcd->Init);
162
 
163
  /* Force Host Mode*/
164
  (void)USB_SetCurrentMode(hhcd->Instance, USB_HOST_MODE);
165
 
166
  /* Init Host */
167
  (void)USB_HostInit(hhcd->Instance, hhcd->Init);
168
 
169
  hhcd->State = HAL_HCD_STATE_READY;
170
 
171
  return HAL_OK;
172
}
173
 
174
/**
175
  * @brief  Initialize a host channel.
176
  * @param  hhcd HCD handle
177
  * @param  ch_num Channel number.
178
  *         This parameter can be a value from 1 to 15
179
  * @param  epnum Endpoint number.
180
  *          This parameter can be a value from 1 to 15
181
  * @param  dev_address Current device address
182
  *          This parameter can be a value from 0 to 255
183
  * @param  speed Current device speed.
184
  *          This parameter can be one of these values:
185
  *            HCD_SPEED_FULL: Full speed mode,
186
  *            HCD_SPEED_LOW: Low speed mode
187
  * @param  ep_type Endpoint Type.
188
  *          This parameter can be one of these values:
189
  *            EP_TYPE_CTRL: Control type,
190
  *            EP_TYPE_ISOC: Isochronous type,
191
  *            EP_TYPE_BULK: Bulk type,
192
  *            EP_TYPE_INTR: Interrupt type
193
  * @param  mps Max Packet Size.
194
  *          This parameter can be a value from 0 to32K
195
  * @retval HAL status
196
  */
197
HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd,
198
                                  uint8_t ch_num,
199
                                  uint8_t epnum,
200
                                  uint8_t dev_address,
201
                                  uint8_t speed,
202
                                  uint8_t ep_type,
203
                                  uint16_t mps)
204
{
205
  HAL_StatusTypeDef status;
206
 
207
  __HAL_LOCK(hhcd);
208
  hhcd->hc[ch_num].do_ping = 0U;
209
  hhcd->hc[ch_num].dev_addr = dev_address;
210
  hhcd->hc[ch_num].max_packet = mps;
211
  hhcd->hc[ch_num].ch_num = ch_num;
212
  hhcd->hc[ch_num].ep_type = ep_type;
213
  hhcd->hc[ch_num].ep_num = epnum & 0x7FU;
214
 
215
  if ((epnum & 0x80U) == 0x80U)
216
  {
217
    hhcd->hc[ch_num].ep_is_in = 1U;
218
  }
219
  else
220
  {
221
    hhcd->hc[ch_num].ep_is_in = 0U;
222
  }
223
 
224
  hhcd->hc[ch_num].speed = speed;
225
 
226
  status =  USB_HC_Init(hhcd->Instance,
227
                        ch_num,
228
                        epnum,
229
                        dev_address,
230
                        speed,
231
                        ep_type,
232
                        mps);
233
  __HAL_UNLOCK(hhcd);
234
 
235
  return status;
236
}
237
 
238
/**
239
  * @brief  Halt a host channel.
240
  * @param  hhcd HCD handle
241
  * @param  ch_num Channel number.
242
  *         This parameter can be a value from 1 to 15
243
  * @retval HAL status
244
  */
245
HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd, uint8_t ch_num)
246
{
247
  HAL_StatusTypeDef status = HAL_OK;
248
 
249
  __HAL_LOCK(hhcd);
250
  (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
251
  __HAL_UNLOCK(hhcd);
252
 
253
  return status;
254
}
255
 
256
/**
257
  * @brief  DeInitialize the host driver.
258
  * @param  hhcd HCD handle
259
  * @retval HAL status
260
  */
261
HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd)
262
{
263
  /* Check the HCD handle allocation */
264
  if (hhcd == NULL)
265
  {
266
    return HAL_ERROR;
267
  }
268
 
269
  hhcd->State = HAL_HCD_STATE_BUSY;
270
 
271
#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
272
  if (hhcd->MspDeInitCallback == NULL)
273
  {
274
    hhcd->MspDeInitCallback = HAL_HCD_MspDeInit; /* Legacy weak MspDeInit  */
275
  }
276
 
277
  /* DeInit the low level hardware */
278
  hhcd->MspDeInitCallback(hhcd);
279
#else
280
  /* DeInit the low level hardware: CLOCK, NVIC.*/
281
  HAL_HCD_MspDeInit(hhcd);
282
#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
283
 
284
  __HAL_HCD_DISABLE(hhcd);
285
 
286
  hhcd->State = HAL_HCD_STATE_RESET;
287
 
288
  return HAL_OK;
289
}
290
 
291
/**
292
  * @brief  Initialize the HCD MSP.
293
  * @param  hhcd HCD handle
294
  * @retval None
295
  */
296
__weak void  HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd)
297
{
298
  /* Prevent unused argument(s) compilation warning */
299
  UNUSED(hhcd);
300
 
301
  /* NOTE : This function should not be modified, when the callback is needed,
302
            the HAL_HCD_MspInit could be implemented in the user file
303
   */
304
}
305
 
306
/**
307
  * @brief  DeInitialize the HCD MSP.
308
  * @param  hhcd HCD handle
309
  * @retval None
310
  */
311
__weak void  HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd)
312
{
313
  /* Prevent unused argument(s) compilation warning */
314
  UNUSED(hhcd);
315
 
316
  /* NOTE : This function should not be modified, when the callback is needed,
317
            the HAL_HCD_MspDeInit could be implemented in the user file
318
   */
319
}
320
 
321
/**
322
  * @}
323
  */
324
 
325
/** @defgroup HCD_Exported_Functions_Group2 Input and Output operation functions
326
  *  @brief   HCD IO operation functions
327
  *
328
@verbatim
329
 ===============================================================================
330
                      ##### IO operation functions #####
331
 ===============================================================================
332
 [..] This subsection provides a set of functions allowing to manage the USB Host Data
333
    Transfer
334
 
335
@endverbatim
336
  * @{
337
  */
338
 
339
/**
340
  * @brief  Submit a new URB for processing.
341
  * @param  hhcd HCD handle
342
  * @param  ch_num Channel number.
343
  *         This parameter can be a value from 1 to 15
344
  * @param  direction Channel number.
345
  *          This parameter can be one of these values:
346
  *           0 : Output / 1 : Input
347
  * @param  ep_type Endpoint Type.
348
  *          This parameter can be one of these values:
349
  *            EP_TYPE_CTRL: Control type/
350
  *            EP_TYPE_ISOC: Isochronous type/
351
  *            EP_TYPE_BULK: Bulk type/
352
  *            EP_TYPE_INTR: Interrupt type/
353
  * @param  token Endpoint Type.
354
  *          This parameter can be one of these values:
355
  *            0: HC_PID_SETUP / 1: HC_PID_DATA1
356
  * @param  pbuff pointer to URB data
357
  * @param  length Length of URB data
358
  * @param  do_ping activate do ping protocol (for high speed only).
359
  *          This parameter can be one of these values:
360
  *           0 : do ping inactive / 1 : do ping active
361
  * @retval HAL status
362
  */
363
HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd,
364
                                           uint8_t ch_num,
365
                                           uint8_t direction,
366
                                           uint8_t ep_type,
367
                                           uint8_t token,
368
                                           uint8_t *pbuff,
369
                                           uint16_t length,
370
                                           uint8_t do_ping)
371
{
372
  hhcd->hc[ch_num].ep_is_in = direction;
373
  hhcd->hc[ch_num].ep_type  = ep_type;
374
 
375
  if (token == 0U)
376
  {
377
    hhcd->hc[ch_num].data_pid = HC_PID_SETUP;
378
    hhcd->hc[ch_num].do_ping = do_ping;
379
  }
380
  else
381
  {
382
    hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
383
  }
384
 
385
  /* Manage Data Toggle */
386
  switch (ep_type)
387
  {
388
    case EP_TYPE_CTRL:
389
      if ((token == 1U) && (direction == 0U)) /*send data */
390
      {
391
        if (length == 0U)
392
        {
393
          /* For Status OUT stage, Length==0, Status Out PID = 1 */
394
          hhcd->hc[ch_num].toggle_out = 1U;
395
        }
396
 
397
        /* Set the Data Toggle bit as per the Flag */
398
        if (hhcd->hc[ch_num].toggle_out == 0U)
399
        {
400
          /* Put the PID 0 */
401
          hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
402
        }
403
        else
404
        {
405
          /* Put the PID 1 */
406
          hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
407
        }
408
      }
409
      break;
410
 
411
    case EP_TYPE_BULK:
412
      if (direction == 0U)
413
      {
414
        /* Set the Data Toggle bit as per the Flag */
415
        if (hhcd->hc[ch_num].toggle_out == 0U)
416
        {
417
          /* Put the PID 0 */
418
          hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
419
        }
420
        else
421
        {
422
          /* Put the PID 1 */
423
          hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
424
        }
425
      }
426
      else
427
      {
428
        if (hhcd->hc[ch_num].toggle_in == 0U)
429
        {
430
          hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
431
        }
432
        else
433
        {
434
          hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
435
        }
436
      }
437
 
438
      break;
439
    case EP_TYPE_INTR:
440
      if (direction == 0U)
441
      {
442
        /* Set the Data Toggle bit as per the Flag */
443
        if (hhcd->hc[ch_num].toggle_out == 0U)
444
        {
445
          /* Put the PID 0 */
446
          hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
447
        }
448
        else
449
        {
450
          /* Put the PID 1 */
451
          hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
452
        }
453
      }
454
      else
455
      {
456
        if (hhcd->hc[ch_num].toggle_in == 0U)
457
        {
458
          hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
459
        }
460
        else
461
        {
462
          hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
463
        }
464
      }
465
      break;
466
 
467
    case EP_TYPE_ISOC:
468
      hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
469
      break;
470
 
471
    default:
472
      break;
473
  }
474
 
475
  hhcd->hc[ch_num].xfer_buff = pbuff;
476
  hhcd->hc[ch_num].xfer_len  = length;
477
  hhcd->hc[ch_num].urb_state = URB_IDLE;
478
  hhcd->hc[ch_num].xfer_count = 0U;
479
  hhcd->hc[ch_num].ch_num = ch_num;
480
  hhcd->hc[ch_num].state = HC_IDLE;
481
 
482
  return USB_HC_StartXfer(hhcd->Instance, &hhcd->hc[ch_num]);
483
}
484
 
485
/**
486
  * @brief  Handle HCD interrupt request.
487
  * @param  hhcd HCD handle
488
  * @retval None
489
  */
490
void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd)
491
{
492
  USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
493
  uint32_t USBx_BASE = (uint32_t)USBx;
494
  uint32_t i, interrupt;
495
 
496
  /* Ensure that we are in device mode */
497
  if (USB_GetMode(hhcd->Instance) == USB_OTG_MODE_HOST)
498
  {
499
    /* Avoid spurious interrupt */
500
    if (__HAL_HCD_IS_INVALID_INTERRUPT(hhcd))
501
    {
502
      return;
503
    }
504
 
505
    if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
506
    {
507
      /* Incorrect mode, acknowledge the interrupt */
508
      __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
509
    }
510
 
511
    if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR))
512
    {
513
      /* Incorrect mode, acknowledge the interrupt */
514
      __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR);
515
    }
516
 
517
    if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE))
518
    {
519
      /* Incorrect mode, acknowledge the interrupt */
520
      __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE);
521
    }
522
 
523
    if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_MMIS))
524
    {
525
      /* Incorrect mode, acknowledge the interrupt */
526
      __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_MMIS);
527
    }
528
 
529
    /* Handle Host Disconnect Interrupts */
530
    if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT))
531
    {
532
      __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT);
533
 
534
      if ((USBx_HPRT0 & USB_OTG_HPRT_PCSTS) == 0U)
535
      {
536
        /* Handle Host Port Disconnect Interrupt */
537
#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
538
        hhcd->DisconnectCallback(hhcd);
539
#else
540
        HAL_HCD_Disconnect_Callback(hhcd);
541
#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
542
 
543
        (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_48_MHZ);
544
      }
545
    }
546
 
547
    /* Handle Host Port Interrupts */
548
    if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HPRTINT))
549
    {
550
      HCD_Port_IRQHandler(hhcd);
551
    }
552
 
553
    /* Handle Host SOF Interrupt */
554
    if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF))
555
    {
556
#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
557
      hhcd->SOFCallback(hhcd);
558
#else
559
      HAL_HCD_SOF_Callback(hhcd);
560
#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
561
 
562
      __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_SOF);
563
    }
564
 
565
    /* Handle Host channel Interrupt */
566
    if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT))
567
    {
568
      interrupt = USB_HC_ReadInterrupt(hhcd->Instance);
569
      for (i = 0U; i < hhcd->Init.Host_channels; i++)
570
      {
571
        if ((interrupt & (1UL << (i & 0xFU))) != 0U)
572
        {
573
          if ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_EPDIR) == USB_OTG_HCCHAR_EPDIR)
574
          {
575
            HCD_HC_IN_IRQHandler(hhcd, (uint8_t)i);
576
          }
577
          else
578
          {
579
            HCD_HC_OUT_IRQHandler(hhcd, (uint8_t)i);
580
          }
581
        }
582
      }
583
      __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_HCINT);
584
    }
585
 
586
    /* Handle Rx Queue Level Interrupts */
587
    if ((__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_RXFLVL)) != 0U)
588
    {
589
      USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
590
 
591
      HCD_RXQLVL_IRQHandler(hhcd);
592
 
593
      USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
594
    }
595
  }
596
}
597
 
598
/**
599
  * @brief  SOF callback.
600
  * @param  hhcd HCD handle
601
  * @retval None
602
  */
603
__weak void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
604
{
605
  /* Prevent unused argument(s) compilation warning */
606
  UNUSED(hhcd);
607
 
608
  /* NOTE : This function should not be modified, when the callback is needed,
609
            the HAL_HCD_SOF_Callback could be implemented in the user file
610
   */
611
}
612
 
613
/**
614
  * @brief Connection Event callback.
615
  * @param  hhcd HCD handle
616
  * @retval None
617
  */
618
__weak void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
619
{
620
  /* Prevent unused argument(s) compilation warning */
621
  UNUSED(hhcd);
622
 
623
  /* NOTE : This function should not be modified, when the callback is needed,
624
            the HAL_HCD_Connect_Callback could be implemented in the user file
625
   */
626
}
627
 
628
/**
629
  * @brief  Disconnection Event callback.
630
  * @param  hhcd HCD handle
631
  * @retval None
632
  */
633
__weak void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
634
{
635
  /* Prevent unused argument(s) compilation warning */
636
  UNUSED(hhcd);
637
 
638
  /* NOTE : This function should not be modified, when the callback is needed,
639
            the HAL_HCD_Disconnect_Callback could be implemented in the user file
640
   */
641
}
642
 
643
/**
644
  * @brief  Port Enabled  Event callback.
645
  * @param  hhcd HCD handle
646
  * @retval None
647
  */
648
__weak void HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef *hhcd)
649
{
650
  /* Prevent unused argument(s) compilation warning */
651
  UNUSED(hhcd);
652
 
653
  /* NOTE : This function should not be modified, when the callback is needed,
654
            the HAL_HCD_Disconnect_Callback could be implemented in the user file
655
   */
656
}
657
 
658
/**
659
  * @brief  Port Disabled  Event callback.
660
  * @param  hhcd HCD handle
661
  * @retval None
662
  */
663
__weak void HAL_HCD_PortDisabled_Callback(HCD_HandleTypeDef *hhcd)
664
{
665
  /* Prevent unused argument(s) compilation warning */
666
  UNUSED(hhcd);
667
 
668
  /* NOTE : This function should not be modified, when the callback is needed,
669
            the HAL_HCD_Disconnect_Callback could be implemented in the user file
670
   */
671
}
672
 
673
/**
674
  * @brief  Notify URB state change callback.
675
  * @param  hhcd HCD handle
676
  * @param  chnum Channel number.
677
  *         This parameter can be a value from 1 to 15
678
  * @param  urb_state:
679
  *          This parameter can be one of these values:
680
  *            URB_IDLE/
681
  *            URB_DONE/
682
  *            URB_NOTREADY/
683
  *            URB_NYET/
684
  *            URB_ERROR/
685
  *            URB_STALL/
686
  * @retval None
687
  */
688
__weak void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
689
{
690
  /* Prevent unused argument(s) compilation warning */
691
  UNUSED(hhcd);
692
  UNUSED(chnum);
693
  UNUSED(urb_state);
694
 
695
  /* NOTE : This function should not be modified, when the callback is needed,
696
            the HAL_HCD_HC_NotifyURBChange_Callback could be implemented in the user file
697
   */
698
}
699
 
700
#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
701
/**
702
  * @brief  Register a User USB HCD Callback
703
  *         To be used instead of the weak predefined callback
704
  * @param  hhcd USB HCD handle
705
  * @param  CallbackID ID of the callback to be registered
706
  *         This parameter can be one of the following values:
707
  *          @arg @ref HAL_HCD_SOF_CB_ID USB HCD SOF callback ID
708
  *          @arg @ref HAL_HCD_CONNECT_CB_ID USB HCD Connect callback ID
709
  *          @arg @ref HAL_HCD_DISCONNECT_CB_ID OTG HCD Disconnect callback ID
710
  *          @arg @ref HAL_HCD_PORT_ENABLED_CB_ID USB HCD Port Enable callback ID
711
  *          @arg @ref HAL_HCD_PORT_DISABLED_CB_ID USB HCD Port Disable callback ID
712
  *          @arg @ref HAL_HCD_MSPINIT_CB_ID MspDeInit callback ID
713
  *          @arg @ref HAL_HCD_MSPDEINIT_CB_ID MspDeInit callback ID
714
  * @param  pCallback pointer to the Callback function
715
  * @retval HAL status
716
  */
717
HAL_StatusTypeDef HAL_HCD_RegisterCallback(HCD_HandleTypeDef *hhcd, HAL_HCD_CallbackIDTypeDef CallbackID, pHCD_CallbackTypeDef pCallback)
718
{
719
  HAL_StatusTypeDef status = HAL_OK;
720
 
721
  if (pCallback == NULL)
722
  {
723
    /* Update the error code */
724
    hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
725
    return HAL_ERROR;
726
  }
727
  /* Process locked */
728
  __HAL_LOCK(hhcd);
729
 
730
  if (hhcd->State == HAL_HCD_STATE_READY)
731
  {
732
    switch (CallbackID)
733
    {
734
      case HAL_HCD_SOF_CB_ID :
735
        hhcd->SOFCallback = pCallback;
736
        break;
737
 
738
      case HAL_HCD_CONNECT_CB_ID :
739
        hhcd->ConnectCallback = pCallback;
740
        break;
741
 
742
      case HAL_HCD_DISCONNECT_CB_ID :
743
        hhcd->DisconnectCallback = pCallback;
744
        break;
745
 
746
      case HAL_HCD_PORT_ENABLED_CB_ID :
747
        hhcd->PortEnabledCallback = pCallback;
748
        break;
749
 
750
      case HAL_HCD_PORT_DISABLED_CB_ID :
751
        hhcd->PortDisabledCallback = pCallback;
752
        break;
753
 
754
      case HAL_HCD_MSPINIT_CB_ID :
755
        hhcd->MspInitCallback = pCallback;
756
        break;
757
 
758
      case HAL_HCD_MSPDEINIT_CB_ID :
759
        hhcd->MspDeInitCallback = pCallback;
760
        break;
761
 
762
      default :
763
        /* Update the error code */
764
        hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
765
        /* Return error status */
766
        status =  HAL_ERROR;
767
        break;
768
    }
769
  }
770
  else if (hhcd->State == HAL_HCD_STATE_RESET)
771
  {
772
    switch (CallbackID)
773
    {
774
      case HAL_HCD_MSPINIT_CB_ID :
775
        hhcd->MspInitCallback = pCallback;
776
        break;
777
 
778
      case HAL_HCD_MSPDEINIT_CB_ID :
779
        hhcd->MspDeInitCallback = pCallback;
780
        break;
781
 
782
      default :
783
        /* Update the error code */
784
        hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
785
        /* Return error status */
786
        status =  HAL_ERROR;
787
        break;
788
    }
789
  }
790
  else
791
  {
792
    /* Update the error code */
793
    hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
794
    /* Return error status */
795
    status =  HAL_ERROR;
796
  }
797
 
798
  /* Release Lock */
799
  __HAL_UNLOCK(hhcd);
800
  return status;
801
}
802
 
803
/**
804
  * @brief  Unregister an USB HCD Callback
805
  *         USB HCD callabck is redirected to the weak predefined callback
806
  * @param  hhcd USB HCD handle
807
  * @param  CallbackID ID of the callback to be unregistered
808
  *         This parameter can be one of the following values:
809
  *          @arg @ref HAL_HCD_SOF_CB_ID USB HCD SOF callback ID
810
  *          @arg @ref HAL_HCD_CONNECT_CB_ID USB HCD Connect callback ID
811
  *          @arg @ref HAL_HCD_DISCONNECT_CB_ID OTG HCD Disconnect callback ID
812
  *          @arg @ref HAL_HCD_PORT_ENABLED_CB_ID USB HCD Port Enabled callback ID
813
  *          @arg @ref HAL_HCD_PORT_DISABLED_CB_ID USB HCD Port Disabled callback ID
814
  *          @arg @ref HAL_HCD_MSPINIT_CB_ID MspDeInit callback ID
815
  *          @arg @ref HAL_HCD_MSPDEINIT_CB_ID MspDeInit callback ID
816
  * @retval HAL status
817
  */
818
HAL_StatusTypeDef HAL_HCD_UnRegisterCallback(HCD_HandleTypeDef *hhcd, HAL_HCD_CallbackIDTypeDef CallbackID)
819
{
820
  HAL_StatusTypeDef status = HAL_OK;
821
 
822
  /* Process locked */
823
  __HAL_LOCK(hhcd);
824
 
825
  /* Setup Legacy weak Callbacks  */
826
  if (hhcd->State == HAL_HCD_STATE_READY)
827
  {
828
    switch (CallbackID)
829
    {
830
      case HAL_HCD_SOF_CB_ID :
831
        hhcd->SOFCallback = HAL_HCD_SOF_Callback;
832
        break;
833
 
834
      case HAL_HCD_CONNECT_CB_ID :
835
        hhcd->ConnectCallback = HAL_HCD_Connect_Callback;
836
        break;
837
 
838
      case HAL_HCD_DISCONNECT_CB_ID :
839
        hhcd->DisconnectCallback = HAL_HCD_Disconnect_Callback;
840
        break;
841
 
842
      case HAL_HCD_PORT_ENABLED_CB_ID :
843
        hhcd->PortEnabledCallback = HAL_HCD_PortEnabled_Callback;
844
        break;
845
 
846
      case HAL_HCD_PORT_DISABLED_CB_ID :
847
        hhcd->PortDisabledCallback = HAL_HCD_PortDisabled_Callback;
848
        break;
849
 
850
      case HAL_HCD_MSPINIT_CB_ID :
851
        hhcd->MspInitCallback = HAL_HCD_MspInit;
852
        break;
853
 
854
      case HAL_HCD_MSPDEINIT_CB_ID :
855
        hhcd->MspDeInitCallback = HAL_HCD_MspDeInit;
856
        break;
857
 
858
      default :
859
        /* Update the error code */
860
        hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
861
 
862
        /* Return error status */
863
        status =  HAL_ERROR;
864
        break;
865
    }
866
  }
867
  else if (hhcd->State == HAL_HCD_STATE_RESET)
868
  {
869
    switch (CallbackID)
870
    {
871
      case HAL_HCD_MSPINIT_CB_ID :
872
        hhcd->MspInitCallback = HAL_HCD_MspInit;
873
        break;
874
 
875
      case HAL_HCD_MSPDEINIT_CB_ID :
876
        hhcd->MspDeInitCallback = HAL_HCD_MspDeInit;
877
        break;
878
 
879
      default :
880
        /* Update the error code */
881
        hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
882
 
883
        /* Return error status */
884
        status =  HAL_ERROR;
885
        break;
886
    }
887
  }
888
  else
889
  {
890
    /* Update the error code */
891
    hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
892
 
893
    /* Return error status */
894
    status =  HAL_ERROR;
895
  }
896
 
897
  /* Release Lock */
898
  __HAL_UNLOCK(hhcd);
899
  return status;
900
}
901
 
902
/**
903
  * @brief  Register USB HCD Host Channel Notify URB Change Callback
904
  *         To be used instead of the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback
905
  * @param  hhcd HCD handle
906
  * @param  pCallback pointer to the USB HCD Host Channel Notify URB Change Callback function
907
  * @retval HAL status
908
  */
909
HAL_StatusTypeDef HAL_HCD_RegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd, pHCD_HC_NotifyURBChangeCallbackTypeDef pCallback)
910
{
911
  HAL_StatusTypeDef status = HAL_OK;
912
 
913
  if (pCallback == NULL)
914
  {
915
    /* Update the error code */
916
    hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
917
 
918
    return HAL_ERROR;
919
  }
920
 
921
  /* Process locked */
922
  __HAL_LOCK(hhcd);
923
 
924
  if (hhcd->State == HAL_HCD_STATE_READY)
925
  {
926
    hhcd->HC_NotifyURBChangeCallback = pCallback;
927
  }
928
  else
929
  {
930
    /* Update the error code */
931
    hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
932
 
933
    /* Return error status */
934
    status =  HAL_ERROR;
935
  }
936
 
937
  /* Release Lock */
938
  __HAL_UNLOCK(hhcd);
939
 
940
  return status;
941
}
942
 
943
/**
944
  * @brief  UnRegister the USB HCD Host Channel Notify URB Change Callback
945
  *         USB HCD Host Channel Notify URB Change Callback is redirected to the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback
946
  * @param  hhcd HCD handle
947
  * @retval HAL status
948
  */
949
HAL_StatusTypeDef HAL_HCD_UnRegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd)
950
{
951
  HAL_StatusTypeDef status = HAL_OK;
952
 
953
  /* Process locked */
954
  __HAL_LOCK(hhcd);
955
 
956
  if (hhcd->State == HAL_HCD_STATE_READY)
957
  {
958
    hhcd->HC_NotifyURBChangeCallback = HAL_HCD_HC_NotifyURBChange_Callback; /* Legacy weak DataOutStageCallback  */
959
  }
960
  else
961
  {
962
    /* Update the error code */
963
    hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
964
 
965
    /* Return error status */
966
    status =  HAL_ERROR;
967
  }
968
 
969
  /* Release Lock */
970
  __HAL_UNLOCK(hhcd);
971
 
972
  return status;
973
}
974
#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
975
 
976
/**
977
  * @}
978
  */
979
 
980
/** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions
981
 *  @brief   Management functions
982
 *
983
@verbatim
984
 ===============================================================================
985
                      ##### Peripheral Control functions #####
986
 ===============================================================================
987
    [..]
988
    This subsection provides a set of functions allowing to control the HCD data
989
    transfers.
990
 
991
@endverbatim
992
  * @{
993
  */
994
 
995
/**
996
  * @brief  Start the host driver.
997
  * @param  hhcd HCD handle
998
  * @retval HAL status
999
  */
1000
HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd)
1001
{
1002
  __HAL_LOCK(hhcd);
1003
  __HAL_HCD_ENABLE(hhcd);
1004
  (void)USB_DriveVbus(hhcd->Instance, 1U);
1005
  __HAL_UNLOCK(hhcd);
1006
 
1007
  return HAL_OK;
1008
}
1009
 
1010
/**
1011
  * @brief  Stop the host driver.
1012
  * @param  hhcd HCD handle
1013
  * @retval HAL status
1014
  */
1015
 
1016
HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd)
1017
{
1018
  __HAL_LOCK(hhcd);
1019
  (void)USB_StopHost(hhcd->Instance);
1020
  __HAL_UNLOCK(hhcd);
1021
 
1022
  return HAL_OK;
1023
}
1024
 
1025
/**
1026
  * @brief  Reset the host port.
1027
  * @param  hhcd HCD handle
1028
  * @retval HAL status
1029
  */
1030
HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd)
1031
{
1032
  return (USB_ResetPort(hhcd->Instance));
1033
}
1034
 
1035
/**
1036
  * @}
1037
  */
1038
 
1039
/** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions
1040
 *  @brief   Peripheral State functions
1041
 *
1042
@verbatim
1043
 ===============================================================================
1044
                      ##### Peripheral State functions #####
1045
 ===============================================================================
1046
    [..]
1047
    This subsection permits to get in run-time the status of the peripheral
1048
    and the data flow.
1049
 
1050
@endverbatim
1051
  * @{
1052
  */
1053
 
1054
/**
1055
  * @brief  Return the HCD handle state.
1056
  * @param  hhcd HCD handle
1057
  * @retval HAL state
1058
  */
1059
HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef *hhcd)
1060
{
1061
  return hhcd->State;
1062
}
1063
 
1064
/**
1065
  * @brief  Return  URB state for a channel.
1066
  * @param  hhcd HCD handle
1067
  * @param  chnum Channel number.
1068
  *         This parameter can be a value from 1 to 15
1069
  * @retval URB state.
1070
  *          This parameter can be one of these values:
1071
  *            URB_IDLE/
1072
  *            URB_DONE/
1073
  *            URB_NOTREADY/
1074
  *            URB_NYET/
1075
  *            URB_ERROR/
1076
  *            URB_STALL
1077
  */
1078
HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
1079
{
1080
  return hhcd->hc[chnum].urb_state;
1081
}
1082
 
1083
 
1084
/**
1085
  * @brief  Return the last host transfer size.
1086
  * @param  hhcd HCD handle
1087
  * @param  chnum Channel number.
1088
  *         This parameter can be a value from 1 to 15
1089
  * @retval last transfer size in byte
1090
  */
1091
uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef *hhcd, uint8_t chnum)
1092
{
1093
  return hhcd->hc[chnum].xfer_count;
1094
}
1095
 
1096
/**
1097
  * @brief  Return the Host Channel state.
1098
  * @param  hhcd HCD handle
1099
  * @param  chnum Channel number.
1100
  *         This parameter can be a value from 1 to 15
1101
  * @retval Host channel state
1102
  *          This parameter can be one of these values:
1103
  *            HC_IDLE/
1104
  *            HC_XFRC/
1105
  *            HC_HALTED/
1106
  *            HC_NYET/
1107
  *            HC_NAK/
1108
  *            HC_STALL/
1109
  *            HC_XACTERR/
1110
  *            HC_BBLERR/
1111
  *            HC_DATATGLERR
1112
  */
1113
HCD_HCStateTypeDef  HAL_HCD_HC_GetState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
1114
{
1115
  return hhcd->hc[chnum].state;
1116
}
1117
 
1118
/**
1119
  * @brief  Return the current Host frame number.
1120
  * @param  hhcd HCD handle
1121
  * @retval Current Host frame number
1122
  */
1123
uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd)
1124
{
1125
  return (USB_GetCurrentFrame(hhcd->Instance));
1126
}
1127
 
1128
/**
1129
  * @brief  Return the Host enumeration speed.
1130
  * @param  hhcd HCD handle
1131
  * @retval Enumeration speed
1132
  */
1133
uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd)
1134
{
1135
  return (USB_GetHostSpeed(hhcd->Instance));
1136
}
1137
 
1138
/**
1139
  * @}
1140
  */
1141
 
1142
/**
1143
  * @}
1144
  */
1145
 
1146
/** @addtogroup HCD_Private_Functions
1147
  * @{
1148
  */
1149
/**
1150
  * @brief  Handle Host Channel IN interrupt requests.
1151
  * @param  hhcd HCD handle
1152
  * @param  chnum Channel number.
1153
  *         This parameter can be a value from 1 to 15
1154
  * @retval none
1155
  */
1156
static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
1157
{
1158
  USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
1159
  uint32_t USBx_BASE = (uint32_t)USBx;
1160
  uint32_t ch_num = (uint32_t)chnum;
1161
 
1162
  uint32_t tmpreg;
1163
 
1164
  if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_AHBERR) == USB_OTG_HCINT_AHBERR)
1165
  {
1166
    __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_AHBERR);
1167
    __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1168
  }
1169
  else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_ACK) == USB_OTG_HCINT_ACK)
1170
  {
1171
    __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_ACK);
1172
  }
1173
  else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_STALL) == USB_OTG_HCINT_STALL)
1174
  {
1175
    __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1176
    hhcd->hc[ch_num].state = HC_STALL;
1177
    __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
1178
    __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_STALL);
1179
    (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1180
  }
1181
  else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_DTERR) == USB_OTG_HCINT_DTERR)
1182
  {
1183
    __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1184
    (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1185
    __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
1186
    hhcd->hc[ch_num].state = HC_DATATGLERR;
1187
    __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_DTERR);
1188
  }
1189
  else
1190
  {
1191
    /* ... */
1192
  }
1193
 
1194
  if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_FRMOR) == USB_OTG_HCINT_FRMOR)
1195
  {
1196
    __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1197
    (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1198
    __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_FRMOR);
1199
  }
1200
  else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_XFRC) == USB_OTG_HCINT_XFRC)
1201
  {
1202
    hhcd->hc[ch_num].state = HC_XFRC;
1203
    hhcd->hc[ch_num].ErrCnt = 0U;
1204
    __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_XFRC);
1205
 
1206
    if ((hhcd->hc[ch_num].ep_type == EP_TYPE_CTRL) ||
1207
        (hhcd->hc[ch_num].ep_type == EP_TYPE_BULK))
1208
    {
1209
      __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1210
      (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1211
      __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
1212
    }
1213
    else if (hhcd->hc[ch_num].ep_type == EP_TYPE_INTR)
1214
    {
1215
      USBx_HC(ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
1216
      hhcd->hc[ch_num].urb_state = URB_DONE;
1217
 
1218
#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1219
      hhcd->HC_NotifyURBChangeCallback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
1220
#else
1221
      HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
1222
#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1223
    }
1224
    else if (hhcd->hc[ch_num].ep_type == EP_TYPE_ISOC)
1225
    {
1226
      hhcd->hc[ch_num].urb_state = URB_DONE;
1227
 
1228
#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1229
      hhcd->HC_NotifyURBChangeCallback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
1230
#else
1231
      HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
1232
#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1233
    }
1234
    else
1235
    {
1236
      /* ... */
1237
    }
1238
    hhcd->hc[ch_num].toggle_in ^= 1U;
1239
 
1240
  }
1241
  else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_CHH) == USB_OTG_HCINT_CHH)
1242
  {
1243
    __HAL_HCD_MASK_HALT_HC_INT(ch_num);
1244
 
1245
    if (hhcd->hc[ch_num].state == HC_XFRC)
1246
    {
1247
      hhcd->hc[ch_num].urb_state  = URB_DONE;
1248
    }
1249
    else if (hhcd->hc[ch_num].state == HC_STALL)
1250
    {
1251
      hhcd->hc[ch_num].urb_state  = URB_STALL;
1252
    }
1253
    else if ((hhcd->hc[ch_num].state == HC_XACTERR) ||
1254
             (hhcd->hc[ch_num].state == HC_DATATGLERR))
1255
    {
1256
      hhcd->hc[ch_num].ErrCnt++;
1257
      if (hhcd->hc[ch_num].ErrCnt > 3U)
1258
      {
1259
        hhcd->hc[ch_num].ErrCnt = 0U;
1260
        hhcd->hc[ch_num].urb_state = URB_ERROR;
1261
      }
1262
      else
1263
      {
1264
        hhcd->hc[ch_num].urb_state = URB_NOTREADY;
1265
      }
1266
 
1267
      /* re-activate the channel  */
1268
      tmpreg = USBx_HC(ch_num)->HCCHAR;
1269
      tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1270
      tmpreg |= USB_OTG_HCCHAR_CHENA;
1271
      USBx_HC(ch_num)->HCCHAR = tmpreg;
1272
    }
1273
    else if (hhcd->hc[ch_num].state == HC_NAK)
1274
    {
1275
      hhcd->hc[ch_num].urb_state  = URB_NOTREADY;
1276
      /* re-activate the channel  */
1277
      tmpreg = USBx_HC(ch_num)->HCCHAR;
1278
      tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1279
      tmpreg |= USB_OTG_HCCHAR_CHENA;
1280
      USBx_HC(ch_num)->HCCHAR = tmpreg;
1281
    }
1282
    else
1283
    {
1284
      /* ... */
1285
    }
1286
    __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_CHH);
1287
    HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
1288
  }
1289
  else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_TXERR) == USB_OTG_HCINT_TXERR)
1290
  {
1291
    __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1292
    hhcd->hc[ch_num].ErrCnt++;
1293
    hhcd->hc[ch_num].state = HC_XACTERR;
1294
    (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1295
    __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_TXERR);
1296
  }
1297
  else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NAK) == USB_OTG_HCINT_NAK)
1298
  {
1299
    if (hhcd->hc[ch_num].ep_type == EP_TYPE_INTR)
1300
    {
1301
      hhcd->hc[ch_num].ErrCnt = 0U;
1302
      __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1303
      (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1304
    }
1305
    else if ((hhcd->hc[ch_num].ep_type == EP_TYPE_CTRL) ||
1306
             (hhcd->hc[ch_num].ep_type == EP_TYPE_BULK))
1307
    {
1308
      hhcd->hc[ch_num].ErrCnt = 0U;
1309
      hhcd->hc[ch_num].state = HC_NAK;
1310
      __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1311
      (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1312
    }
1313
    else
1314
    {
1315
      /* ... */
1316
    }
1317
    __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
1318
  }
1319
  else
1320
  {
1321
    /* ... */
1322
  }
1323
}
1324
 
1325
/**
1326
  * @brief  Handle Host Channel OUT interrupt requests.
1327
  * @param  hhcd HCD handle
1328
  * @param  chnum Channel number.
1329
  *         This parameter can be a value from 1 to 15
1330
  * @retval none
1331
  */
1332
static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
1333
{
1334
  USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
1335
  uint32_t USBx_BASE = (uint32_t)USBx;
1336
  uint32_t ch_num = (uint32_t)chnum;
1337
  uint32_t tmpreg;
1338
 
1339
  if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_AHBERR) == USB_OTG_HCINT_AHBERR)
1340
  {
1341
    __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_AHBERR);
1342
    __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1343
  }
1344
  else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_ACK) == USB_OTG_HCINT_ACK)
1345
  {
1346
    __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_ACK);
1347
 
1348
    if (hhcd->hc[ch_num].do_ping == 1U)
1349
    {
1350
      hhcd->hc[ch_num].do_ping = 0U;
1351
      hhcd->hc[ch_num].urb_state  = URB_NOTREADY;
1352
      __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1353
      (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1354
    }
1355
  }
1356
  else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NYET) == USB_OTG_HCINT_NYET)
1357
  {
1358
    hhcd->hc[ch_num].state = HC_NYET;
1359
    hhcd->hc[ch_num].do_ping = 1U;
1360
    hhcd->hc[ch_num].ErrCnt = 0U;
1361
    __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1362
    (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1363
    __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NYET);
1364
  }
1365
  else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_FRMOR) == USB_OTG_HCINT_FRMOR)
1366
  {
1367
    __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1368
    (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1369
    __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_FRMOR);
1370
  }
1371
  else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_XFRC) == USB_OTG_HCINT_XFRC)
1372
  {
1373
    hhcd->hc[ch_num].ErrCnt = 0U;
1374
    __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1375
    (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1376
    __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_XFRC);
1377
    hhcd->hc[ch_num].state = HC_XFRC;
1378
  }
1379
  else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_STALL) == USB_OTG_HCINT_STALL)
1380
  {
1381
    __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_STALL);
1382
    __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1383
    (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1384
    hhcd->hc[ch_num].state = HC_STALL;
1385
  }
1386
  else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NAK) == USB_OTG_HCINT_NAK)
1387
  {
1388
    hhcd->hc[ch_num].ErrCnt = 0U;
1389
    hhcd->hc[ch_num].state = HC_NAK;
1390
 
1391
    __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1392
    (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1393
    __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
1394
  }
1395
  else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_TXERR) == USB_OTG_HCINT_TXERR)
1396
  {
1397
    __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1398
    (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1399
    hhcd->hc[ch_num].state = HC_XACTERR;
1400
    __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_TXERR);
1401
  }
1402
  else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_DTERR) == USB_OTG_HCINT_DTERR)
1403
  {
1404
    __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1405
    (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1406
    __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
1407
    __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_DTERR);
1408
    hhcd->hc[ch_num].state = HC_DATATGLERR;
1409
  }
1410
  else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_CHH) == USB_OTG_HCINT_CHH)
1411
  {
1412
    __HAL_HCD_MASK_HALT_HC_INT(ch_num);
1413
 
1414
    if (hhcd->hc[ch_num].state == HC_XFRC)
1415
    {
1416
      hhcd->hc[ch_num].urb_state  = URB_DONE;
1417
      if ((hhcd->hc[ch_num].ep_type == EP_TYPE_BULK) ||
1418
          (hhcd->hc[ch_num].ep_type == EP_TYPE_INTR))
1419
      {
1420
        hhcd->hc[ch_num].toggle_out ^= 1U;
1421
      }
1422
    }
1423
    else if (hhcd->hc[ch_num].state == HC_NAK)
1424
    {
1425
      hhcd->hc[ch_num].urb_state = URB_NOTREADY;
1426
    }
1427
    else if (hhcd->hc[ch_num].state == HC_NYET)
1428
    {
1429
      hhcd->hc[ch_num].urb_state  = URB_NOTREADY;
1430
    }
1431
    else if (hhcd->hc[ch_num].state == HC_STALL)
1432
    {
1433
      hhcd->hc[ch_num].urb_state  = URB_STALL;
1434
    }
1435
    else if ((hhcd->hc[ch_num].state == HC_XACTERR) ||
1436
             (hhcd->hc[ch_num].state == HC_DATATGLERR))
1437
    {
1438
      hhcd->hc[ch_num].ErrCnt++;
1439
      if (hhcd->hc[ch_num].ErrCnt > 3U)
1440
      {
1441
        hhcd->hc[ch_num].ErrCnt = 0U;
1442
        hhcd->hc[ch_num].urb_state = URB_ERROR;
1443
      }
1444
      else
1445
      {
1446
        hhcd->hc[ch_num].urb_state = URB_NOTREADY;
1447
      }
1448
 
1449
      /* re-activate the channel  */
1450
      tmpreg = USBx_HC(ch_num)->HCCHAR;
1451
      tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1452
      tmpreg |= USB_OTG_HCCHAR_CHENA;
1453
      USBx_HC(ch_num)->HCCHAR = tmpreg;
1454
    }
1455
    else
1456
    {
1457
      /* ... */
1458
    }
1459
 
1460
    __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_CHH);
1461
    HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
1462
  }
1463
  else
1464
  {
1465
    /* ... */
1466
  }
1467
}
1468
 
1469
/**
1470
  * @brief  Handle Rx Queue Level interrupt requests.
1471
  * @param  hhcd HCD handle
1472
  * @retval none
1473
  */
1474
static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd)
1475
{
1476
  USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
1477
  uint32_t USBx_BASE = (uint32_t)USBx;
1478
  uint32_t pktsts;
1479
  uint32_t pktcnt;
1480
  uint32_t temp;
1481
  uint32_t tmpreg;
1482
  uint32_t ch_num;
1483
 
1484
  temp = hhcd->Instance->GRXSTSP;
1485
  ch_num = temp & USB_OTG_GRXSTSP_EPNUM;
1486
  pktsts = (temp & USB_OTG_GRXSTSP_PKTSTS) >> 17;
1487
  pktcnt = (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
1488
 
1489
  switch (pktsts)
1490
  {
1491
    case GRXSTS_PKTSTS_IN:
1492
      /* Read the data into the host buffer. */
1493
      if ((pktcnt > 0U) && (hhcd->hc[ch_num].xfer_buff != (void *)0))
1494
      {
1495
        (void)USB_ReadPacket(hhcd->Instance, hhcd->hc[ch_num].xfer_buff, (uint16_t)pktcnt);
1496
 
1497
        /*manage multiple Xfer */
1498
        hhcd->hc[ch_num].xfer_buff += pktcnt;
1499
        hhcd->hc[ch_num].xfer_count  += pktcnt;
1500
 
1501
        if ((USBx_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) > 0U)
1502
        {
1503
          /* re-activate the channel when more packets are expected */
1504
          tmpreg = USBx_HC(ch_num)->HCCHAR;
1505
          tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1506
          tmpreg |= USB_OTG_HCCHAR_CHENA;
1507
          USBx_HC(ch_num)->HCCHAR = tmpreg;
1508
          hhcd->hc[ch_num].toggle_in ^= 1U;
1509
        }
1510
      }
1511
      break;
1512
 
1513
    case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
1514
      break;
1515
 
1516
    case GRXSTS_PKTSTS_IN_XFER_COMP:
1517
    case GRXSTS_PKTSTS_CH_HALTED:
1518
    default:
1519
      break;
1520
  }
1521
}
1522
 
1523
/**
1524
  * @brief  Handle Host Port interrupt requests.
1525
  * @param  hhcd HCD handle
1526
  * @retval None
1527
  */
1528
static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd)
1529
{
1530
  USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
1531
  uint32_t USBx_BASE = (uint32_t)USBx;
1532
  __IO uint32_t hprt0, hprt0_dup;
1533
 
1534
  /* Handle Host Port Interrupts */
1535
  hprt0 = USBx_HPRT0;
1536
  hprt0_dup = USBx_HPRT0;
1537
 
1538
  hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET | \
1539
                 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1540
 
1541
  /* Check whether Port Connect detected */
1542
  if ((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET)
1543
  {
1544
    if ((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS)
1545
    {
1546
#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1547
      hhcd->ConnectCallback(hhcd);
1548
#else
1549
      HAL_HCD_Connect_Callback(hhcd);
1550
#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1551
    }
1552
    hprt0_dup  |= USB_OTG_HPRT_PCDET;
1553
  }
1554
 
1555
  /* Check whether Port Enable Changed */
1556
  if ((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG)
1557
  {
1558
    hprt0_dup |= USB_OTG_HPRT_PENCHNG;
1559
 
1560
    if ((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA)
1561
    {
1562
      if (hhcd->Init.phy_itface  == USB_OTG_EMBEDDED_PHY)
1563
      {
1564
        if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17))
1565
        {
1566
          (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_6_MHZ);
1567
        }
1568
        else
1569
        {
1570
          (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_48_MHZ);
1571
        }
1572
      }
1573
      else
1574
      {
1575
        if (hhcd->Init.speed == HCD_SPEED_FULL)
1576
        {
1577
          USBx_HOST->HFIR = 60000U;
1578
        }
1579
      }
1580
#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1581
      hhcd->PortEnabledCallback(hhcd);
1582
#else
1583
      HAL_HCD_PortEnabled_Callback(hhcd);
1584
#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1585
 
1586
    }
1587
    else
1588
    {
1589
#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1590
      hhcd->PortDisabledCallback(hhcd);
1591
#else
1592
      HAL_HCD_PortDisabled_Callback(hhcd);
1593
#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1594
    }
1595
  }
1596
 
1597
  /* Check for an overcurrent */
1598
  if ((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG)
1599
  {
1600
    hprt0_dup |= USB_OTG_HPRT_POCCHNG;
1601
  }
1602
 
1603
  /* Clear Port Interrupts */
1604
  USBx_HPRT0 = hprt0_dup;
1605
}
1606
 
1607
/**
1608
  * @}
1609
  */
1610
 
1611
/**
1612
  * @}
1613
  */
1614
 
1615
#endif /* defined (USB_OTG_FS) */
1616
#endif /* HAL_HCD_MODULE_ENABLED */
1617
 
1618
/**
1619
  * @}
1620
  */
1621
 
1622
/**
1623
  * @}
1624
  */
1625
 
1626
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/