Subversion Repositories AFRtranscoder

Rev

Details | Last modification | View Log | RSS feed

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