Subversion Repositories canSerial

Rev

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

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