Subversion Repositories dashGPS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 1
/**
2
  ******************************************************************************
3
  * @file    stm32f1xx_hal_pcd.c
4
  * @author  MCD Application Team
5
  * @brief   PCD 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
      The PCD HAL driver can be used as follows:
19
 
20
     (#) Declare a PCD_HandleTypeDef handle structure, for example:
21
         PCD_HandleTypeDef  hpcd;
22
 
23
     (#) Fill parameters of Init structure in HCD handle
24
 
25
     (#) Call HAL_PCD_Init() API to initialize the PCD peripheral (Core, Device core, ...)
26
 
27
     (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API:
28
         (##) Enable the PCD/USB Low Level interface clock using
29
              (+++) __HAL_RCC_USB_CLK_ENABLE(); For USB Device only FS peripheral
30
 
31
         (##) Initialize the related GPIO clocks
32
         (##) Configure PCD pin-out
33
         (##) Configure PCD NVIC interrupt
34
 
35
     (#)Associate the Upper USB device stack to the HAL PCD Driver:
36
         (##) hpcd.pData = pdev;
37
 
38
     (#)Enable PCD transmission and reception:
39
         (##) HAL_PCD_Start();
40
 
41
  @endverbatim
42
  ******************************************************************************
43
  * @attention
44
  *
45
  * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
46
  * All rights reserved.</center></h2>
47
  *
48
  * This software component is licensed by ST under BSD 3-Clause license,
49
  * the "License"; You may not use this file except in compliance with the
50
  * License. You may obtain a copy of the License at:
51
  *                        opensource.org/licenses/BSD-3-Clause
52
  *
53
  ******************************************************************************
54
  */
55
 
56
/* Includes ------------------------------------------------------------------*/
57
#include "stm32f1xx_hal.h"
58
 
59
/** @addtogroup STM32F1xx_HAL_Driver
60
  * @{
61
  */
62
 
63
/** @defgroup PCD PCD
64
  * @brief PCD HAL module driver
65
  * @{
66
  */
67
 
68
#ifdef HAL_PCD_MODULE_ENABLED
69
 
70
#if defined (USB) || defined (USB_OTG_FS)
71
 
72
/* Private types -------------------------------------------------------------*/
73
/* Private variables ---------------------------------------------------------*/
74
/* Private constants ---------------------------------------------------------*/
75
/* Private macros ------------------------------------------------------------*/
76
/** @defgroup PCD_Private_Macros PCD Private Macros
77
  * @{
78
  */
79
#define PCD_MIN(a, b)  (((a) < (b)) ? (a) : (b))
80
#define PCD_MAX(a, b)  (((a) > (b)) ? (a) : (b))
81
/**
82
  * @}
83
  */
84
 
85
/* Private functions prototypes ----------------------------------------------*/
86
/** @defgroup PCD_Private_Functions PCD Private Functions
87
  * @{
88
  */
89
#if defined (USB_OTG_FS)
90
static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum);
91
static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum);
92
static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum);
93
#endif /* defined (USB_OTG_FS) */
94
 
95
#if defined (USB)
96
static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd);
97
#endif /* defined (USB) */
98
/**
99
  * @}
100
  */
101
 
102
/* Exported functions --------------------------------------------------------*/
103
/** @defgroup PCD_Exported_Functions PCD Exported Functions
104
  * @{
105
  */
106
 
107
/** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
108
 *  @brief    Initialization and Configuration functions
109
 *
110
@verbatim
111
 ===============================================================================
112
            ##### Initialization and de-initialization functions #####
113
 ===============================================================================
114
    [..]  This section provides functions allowing to:
115
 
116
@endverbatim
117
  * @{
118
  */
119
 
120
/**
121
  * @brief  Initializes the PCD according to the specified
122
  *         parameters in the PCD_InitTypeDef and initialize the associated handle.
123
  * @param  hpcd PCD handle
124
  * @retval HAL status
125
  */
126
HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
127
{
128
#if defined (USB_OTG_FS)
129
  USB_OTG_GlobalTypeDef *USBx;
130
#endif /* defined (USB_OTG_FS) */
131
  uint8_t i;
132
 
133
  /* Check the PCD handle allocation */
134
  if (hpcd == NULL)
135
  {
136
    return HAL_ERROR;
137
  }
138
 
139
  /* Check the parameters */
140
  assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));
141
 
142
#if defined (USB_OTG_FS)
143
  USBx = hpcd->Instance;
144
#endif /* defined (USB_OTG_FS) */
145
 
146
  if (hpcd->State == HAL_PCD_STATE_RESET)
147
  {
148
    /* Allocate lock resource and initialize it */
149
    hpcd->Lock = HAL_UNLOCKED;
150
 
151
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
152
    hpcd->SOFCallback = HAL_PCD_SOFCallback;
153
    hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
154
    hpcd->ResetCallback = HAL_PCD_ResetCallback;
155
    hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
156
    hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
157
    hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
158
    hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
159
    hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback;
160
    hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback;
161
    hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback;
162
    hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback;
163
 
164
    if (hpcd->MspInitCallback == NULL)
165
    {
166
      hpcd->MspInitCallback = HAL_PCD_MspInit;
167
    }
168
 
169
    /* Init the low level hardware */
170
    hpcd->MspInitCallback(hpcd);
171
#else
172
    /* Init the low level hardware : GPIO, CLOCK, NVIC... */
173
    HAL_PCD_MspInit(hpcd);
174
#endif /* (USE_HAL_PCD_REGISTER_CALLBACKS) */
175
  }
176
 
177
  hpcd->State = HAL_PCD_STATE_BUSY;
178
 
179
#if defined (USB_OTG_FS)
180
  /* Disable DMA mode for FS instance */
181
  if ((USBx->CID & (0x1U << 8)) == 0U)
182
  {
183
    hpcd->Init.dma_enable = 0U;
184
  }
185
#endif /* defined (USB_OTG_FS) */
186
 
187
  /* Disable the Interrupts */
188
  __HAL_PCD_DISABLE(hpcd);
189
 
190
  /*Init the Core (common init.) */
191
  if (USB_CoreInit(hpcd->Instance, hpcd->Init) != HAL_OK)
192
  {
193
    hpcd->State = HAL_PCD_STATE_ERROR;
194
    return HAL_ERROR;
195
  }
196
 
197
  /* Force Device Mode*/
198
  (void)USB_SetCurrentMode(hpcd->Instance, USB_DEVICE_MODE);
199
 
200
  /* Init endpoints structures */
201
  for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
202
  {
203
    /* Init ep structure */
204
    hpcd->IN_ep[i].is_in = 1U;
205
    hpcd->IN_ep[i].num = i;
206
    hpcd->IN_ep[i].tx_fifo_num = i;
207
    /* Control until ep is activated */
208
    hpcd->IN_ep[i].type = EP_TYPE_CTRL;
209
    hpcd->IN_ep[i].maxpacket = 0U;
210
    hpcd->IN_ep[i].xfer_buff = 0U;
211
    hpcd->IN_ep[i].xfer_len = 0U;
212
  }
213
 
214
  for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
215
  {
216
    hpcd->OUT_ep[i].is_in = 0U;
217
    hpcd->OUT_ep[i].num = i;
218
    /* Control until ep is activated */
219
    hpcd->OUT_ep[i].type = EP_TYPE_CTRL;
220
    hpcd->OUT_ep[i].maxpacket = 0U;
221
    hpcd->OUT_ep[i].xfer_buff = 0U;
222
    hpcd->OUT_ep[i].xfer_len = 0U;
223
  }
224
 
225
  /* Init Device */
226
  if (USB_DevInit(hpcd->Instance, hpcd->Init) != HAL_OK)
227
  {
228
    hpcd->State = HAL_PCD_STATE_ERROR;
229
    return HAL_ERROR;
230
  }
231
 
232
  hpcd->USB_Address = 0U;
233
  hpcd->State = HAL_PCD_STATE_READY;
234
  (void)USB_DevDisconnect(hpcd->Instance);
235
 
236
  return HAL_OK;
237
}
238
 
239
/**
240
  * @brief  DeInitializes the PCD peripheral.
241
  * @param  hpcd PCD handle
242
  * @retval HAL status
243
  */
244
HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
245
{
246
  /* Check the PCD handle allocation */
247
  if (hpcd == NULL)
248
  {
249
    return HAL_ERROR;
250
  }
251
 
252
  hpcd->State = HAL_PCD_STATE_BUSY;
253
 
254
  /* Stop Device */
255
  (void)HAL_PCD_Stop(hpcd);
256
 
257
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
258
  if (hpcd->MspDeInitCallback == NULL)
259
  {
260
    hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; /* Legacy weak MspDeInit  */
261
  }
262
 
263
  /* DeInit the low level hardware */
264
  hpcd->MspDeInitCallback(hpcd);
265
#else
266
  /* DeInit the low level hardware: CLOCK, NVIC.*/
267
  HAL_PCD_MspDeInit(hpcd);
268
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
269
 
270
  hpcd->State = HAL_PCD_STATE_RESET;
271
 
272
  return HAL_OK;
273
}
274
 
275
/**
276
  * @brief  Initializes the PCD MSP.
277
  * @param  hpcd PCD handle
278
  * @retval None
279
  */
280
__weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
281
{
282
  /* Prevent unused argument(s) compilation warning */
283
  UNUSED(hpcd);
284
 
285
  /* NOTE : This function should not be modified, when the callback is needed,
286
            the HAL_PCD_MspInit could be implemented in the user file
287
   */
288
}
289
 
290
/**
291
  * @brief  DeInitializes PCD MSP.
292
  * @param  hpcd PCD handle
293
  * @retval None
294
  */
295
__weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
296
{
297
  /* Prevent unused argument(s) compilation warning */
298
  UNUSED(hpcd);
299
 
300
  /* NOTE : This function should not be modified, when the callback is needed,
301
            the HAL_PCD_MspDeInit could be implemented in the user file
302
   */
303
}
304
 
305
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
306
/**
307
  * @brief  Register a User USB PCD Callback
308
  *         To be used instead of the weak predefined callback
309
  * @param  hpcd USB PCD handle
310
  * @param  CallbackID ID of the callback to be registered
311
  *         This parameter can be one of the following values:
312
  *          @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
313
  *          @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
314
  *          @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
315
  *          @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
316
  *          @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
317
  *          @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
318
  *          @arg @ref HAL_PCD_DISCONNECT_CB_ID OTG PCD Disconnect callback ID
319
  *          @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
320
  *          @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
321
  * @param  pCallback pointer to the Callback function
322
  * @retval HAL status
323
  */
324
HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID, pPCD_CallbackTypeDef pCallback)
325
{
326
  HAL_StatusTypeDef status = HAL_OK;
327
 
328
  if (pCallback == NULL)
329
  {
330
    /* Update the error code */
331
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
332
    return HAL_ERROR;
333
  }
334
  /* Process locked */
335
  __HAL_LOCK(hpcd);
336
 
337
  if (hpcd->State == HAL_PCD_STATE_READY)
338
  {
339
    switch (CallbackID)
340
    {
341
      case HAL_PCD_SOF_CB_ID :
342
        hpcd->SOFCallback = pCallback;
343
        break;
344
 
345
      case HAL_PCD_SETUPSTAGE_CB_ID :
346
        hpcd->SetupStageCallback = pCallback;
347
        break;
348
 
349
      case HAL_PCD_RESET_CB_ID :
350
        hpcd->ResetCallback = pCallback;
351
        break;
352
 
353
      case HAL_PCD_SUSPEND_CB_ID :
354
        hpcd->SuspendCallback = pCallback;
355
        break;
356
 
357
      case HAL_PCD_RESUME_CB_ID :
358
        hpcd->ResumeCallback = pCallback;
359
        break;
360
 
361
      case HAL_PCD_CONNECT_CB_ID :
362
        hpcd->ConnectCallback = pCallback;
363
        break;
364
 
365
      case HAL_PCD_DISCONNECT_CB_ID :
366
        hpcd->DisconnectCallback = pCallback;
367
        break;
368
 
369
      case HAL_PCD_MSPINIT_CB_ID :
370
        hpcd->MspInitCallback = pCallback;
371
        break;
372
 
373
      case HAL_PCD_MSPDEINIT_CB_ID :
374
        hpcd->MspDeInitCallback = pCallback;
375
        break;
376
 
377
      default :
378
        /* Update the error code */
379
        hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
380
        /* Return error status */
381
        status =  HAL_ERROR;
382
        break;
383
    }
384
  }
385
  else if (hpcd->State == HAL_PCD_STATE_RESET)
386
  {
387
    switch (CallbackID)
388
    {
389
      case HAL_PCD_MSPINIT_CB_ID :
390
        hpcd->MspInitCallback = pCallback;
391
        break;
392
 
393
      case HAL_PCD_MSPDEINIT_CB_ID :
394
        hpcd->MspDeInitCallback = pCallback;
395
        break;
396
 
397
      default :
398
        /* Update the error code */
399
        hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
400
        /* Return error status */
401
        status =  HAL_ERROR;
402
        break;
403
    }
404
  }
405
  else
406
  {
407
    /* Update the error code */
408
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
409
    /* Return error status */
410
    status =  HAL_ERROR;
411
  }
412
 
413
  /* Release Lock */
414
  __HAL_UNLOCK(hpcd);
415
  return status;
416
}
417
 
418
/**
419
  * @brief  Unregister an USB PCD Callback
420
  *         USB PCD callabck is redirected to the weak predefined callback
421
  * @param  hpcd USB PCD handle
422
  * @param  CallbackID ID of the callback to be unregistered
423
  *         This parameter can be one of the following values:
424
  *          @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
425
  *          @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
426
  *          @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
427
  *          @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
428
  *          @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
429
  *          @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
430
  *          @arg @ref HAL_PCD_DISCONNECT_CB_ID OTG PCD Disconnect callback ID
431
  *          @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
432
  *          @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
433
  * @retval HAL status
434
  */
435
HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID)
436
{
437
  HAL_StatusTypeDef status = HAL_OK;
438
 
439
  /* Process locked */
440
  __HAL_LOCK(hpcd);
441
 
442
  /* Setup Legacy weak Callbacks  */
443
  if (hpcd->State == HAL_PCD_STATE_READY)
444
  {
445
    switch (CallbackID)
446
    {
447
      case HAL_PCD_SOF_CB_ID :
448
        hpcd->SOFCallback = HAL_PCD_SOFCallback;
449
        break;
450
 
451
      case HAL_PCD_SETUPSTAGE_CB_ID :
452
        hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
453
        break;
454
 
455
      case HAL_PCD_RESET_CB_ID :
456
        hpcd->ResetCallback = HAL_PCD_ResetCallback;
457
        break;
458
 
459
      case HAL_PCD_SUSPEND_CB_ID :
460
        hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
461
        break;
462
 
463
      case HAL_PCD_RESUME_CB_ID :
464
        hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
465
        break;
466
 
467
      case HAL_PCD_CONNECT_CB_ID :
468
        hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
469
        break;
470
 
471
      case HAL_PCD_DISCONNECT_CB_ID :
472
        hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
473
        break;
474
 
475
      case HAL_PCD_MSPINIT_CB_ID :
476
        hpcd->MspInitCallback = HAL_PCD_MspInit;
477
        break;
478
 
479
      case HAL_PCD_MSPDEINIT_CB_ID :
480
        hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
481
        break;
482
 
483
      default :
484
        /* Update the error code */
485
        hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
486
 
487
        /* Return error status */
488
        status =  HAL_ERROR;
489
        break;
490
    }
491
  }
492
  else if (hpcd->State == HAL_PCD_STATE_RESET)
493
  {
494
    switch (CallbackID)
495
    {
496
      case HAL_PCD_MSPINIT_CB_ID :
497
        hpcd->MspInitCallback = HAL_PCD_MspInit;
498
        break;
499
 
500
      case HAL_PCD_MSPDEINIT_CB_ID :
501
        hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
502
        break;
503
 
504
      default :
505
        /* Update the error code */
506
        hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
507
 
508
        /* Return error status */
509
        status =  HAL_ERROR;
510
        break;
511
    }
512
  }
513
  else
514
  {
515
    /* Update the error code */
516
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
517
 
518
    /* Return error status */
519
    status =  HAL_ERROR;
520
  }
521
 
522
  /* Release Lock */
523
  __HAL_UNLOCK(hpcd);
524
  return status;
525
}
526
 
527
/**
528
  * @brief  Register USB PCD Data OUT Stage Callback
529
  *         To be used instead of the weak HAL_PCD_DataOutStageCallback() predefined callback
530
  * @param  hpcd PCD handle
531
  * @param  pCallback pointer to the USB PCD Data OUT Stage Callback function
532
  * @retval HAL status
533
  */
534
HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd, pPCD_DataOutStageCallbackTypeDef pCallback)
535
{
536
  HAL_StatusTypeDef status = HAL_OK;
537
 
538
  if (pCallback == NULL)
539
  {
540
    /* Update the error code */
541
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
542
 
543
    return HAL_ERROR;
544
  }
545
 
546
  /* Process locked */
547
  __HAL_LOCK(hpcd);
548
 
549
  if (hpcd->State == HAL_PCD_STATE_READY)
550
  {
551
    hpcd->DataOutStageCallback = pCallback;
552
  }
553
  else
554
  {
555
    /* Update the error code */
556
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
557
 
558
    /* Return error status */
559
    status =  HAL_ERROR;
560
  }
561
 
562
  /* Release Lock */
563
  __HAL_UNLOCK(hpcd);
564
 
565
  return status;
566
}
567
 
568
/**
569
  * @brief  UnRegister the USB PCD Data OUT Stage Callback
570
  *         USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataOutStageCallback() predefined callback
571
  * @param  hpcd PCD handle
572
  * @retval HAL status
573
  */
574
HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd)
575
{
576
  HAL_StatusTypeDef status = HAL_OK;
577
 
578
  /* Process locked */
579
  __HAL_LOCK(hpcd);
580
 
581
  if (hpcd->State == HAL_PCD_STATE_READY)
582
  {
583
    hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback; /* Legacy weak DataOutStageCallback  */
584
  }
585
  else
586
  {
587
    /* Update the error code */
588
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
589
 
590
    /* Return error status */
591
    status =  HAL_ERROR;
592
  }
593
 
594
  /* Release Lock */
595
  __HAL_UNLOCK(hpcd);
596
 
597
  return status;
598
}
599
 
600
/**
601
  * @brief  Register USB PCD Data IN Stage Callback
602
  *         To be used instead of the weak HAL_PCD_DataInStageCallback() predefined callback
603
  * @param  hpcd PCD handle
604
  * @param  pCallback pointer to the USB PCD Data IN Stage Callback function
605
  * @retval HAL status
606
  */
607
HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd, pPCD_DataInStageCallbackTypeDef pCallback)
608
{
609
  HAL_StatusTypeDef status = HAL_OK;
610
 
611
  if (pCallback == NULL)
612
  {
613
    /* Update the error code */
614
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
615
 
616
    return HAL_ERROR;
617
  }
618
 
619
  /* Process locked */
620
  __HAL_LOCK(hpcd);
621
 
622
  if (hpcd->State == HAL_PCD_STATE_READY)
623
  {
624
    hpcd->DataInStageCallback = pCallback;
625
  }
626
  else
627
  {
628
    /* Update the error code */
629
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
630
 
631
    /* Return error status */
632
    status =  HAL_ERROR;
633
  }
634
 
635
  /* Release Lock */
636
  __HAL_UNLOCK(hpcd);
637
 
638
  return status;
639
}
640
 
641
/**
642
  * @brief  UnRegister the USB PCD Data IN Stage Callback
643
  *         USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataInStageCallback() predefined callback
644
  * @param  hpcd PCD handle
645
  * @retval HAL status
646
  */
647
HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd)
648
{
649
  HAL_StatusTypeDef status = HAL_OK;
650
 
651
  /* Process locked */
652
  __HAL_LOCK(hpcd);
653
 
654
  if (hpcd->State == HAL_PCD_STATE_READY)
655
  {
656
    hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; /* Legacy weak DataInStageCallback  */
657
  }
658
  else
659
  {
660
    /* Update the error code */
661
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
662
 
663
    /* Return error status */
664
    status =  HAL_ERROR;
665
  }
666
 
667
  /* Release Lock */
668
  __HAL_UNLOCK(hpcd);
669
 
670
  return status;
671
}
672
 
673
/**
674
  * @brief  Register USB PCD Iso OUT incomplete Callback
675
  *         To be used instead of the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
676
  * @param  hpcd PCD handle
677
  * @param  pCallback pointer to the USB PCD Iso OUT incomplete Callback function
678
  * @retval HAL status
679
  */
680
HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd, pPCD_IsoOutIncpltCallbackTypeDef pCallback)
681
{
682
  HAL_StatusTypeDef status = HAL_OK;
683
 
684
  if (pCallback == NULL)
685
  {
686
    /* Update the error code */
687
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
688
 
689
    return HAL_ERROR;
690
  }
691
 
692
  /* Process locked */
693
  __HAL_LOCK(hpcd);
694
 
695
  if (hpcd->State == HAL_PCD_STATE_READY)
696
  {
697
    hpcd->ISOOUTIncompleteCallback = pCallback;
698
  }
699
  else
700
  {
701
    /* Update the error code */
702
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
703
 
704
    /* Return error status */
705
    status =  HAL_ERROR;
706
  }
707
 
708
  /* Release Lock */
709
  __HAL_UNLOCK(hpcd);
710
 
711
  return status;
712
}
713
 
714
/**
715
  * @brief  UnRegister the USB PCD Iso OUT incomplete Callback
716
  *         USB PCD Iso OUT incomplete Callback is redirected to the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
717
  * @param  hpcd PCD handle
718
  * @retval HAL status
719
  */
720
HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd)
721
{
722
  HAL_StatusTypeDef status = HAL_OK;
723
 
724
  /* Process locked */
725
  __HAL_LOCK(hpcd);
726
 
727
  if (hpcd->State == HAL_PCD_STATE_READY)
728
  {
729
    hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; /* Legacy weak ISOOUTIncompleteCallback  */
730
  }
731
  else
732
  {
733
    /* Update the error code */
734
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
735
 
736
    /* Return error status */
737
    status =  HAL_ERROR;
738
  }
739
 
740
  /* Release Lock */
741
  __HAL_UNLOCK(hpcd);
742
 
743
  return status;
744
}
745
 
746
/**
747
  * @brief  Register USB PCD Iso IN incomplete Callback
748
  *         To be used instead of the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
749
  * @param  hpcd PCD handle
750
  * @param  pCallback pointer to the USB PCD Iso IN incomplete Callback function
751
  * @retval HAL status
752
  */
753
HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd, pPCD_IsoInIncpltCallbackTypeDef pCallback)
754
{
755
  HAL_StatusTypeDef status = HAL_OK;
756
 
757
  if (pCallback == NULL)
758
  {
759
    /* Update the error code */
760
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
761
 
762
    return HAL_ERROR;
763
  }
764
 
765
  /* Process locked */
766
  __HAL_LOCK(hpcd);
767
 
768
  if (hpcd->State == HAL_PCD_STATE_READY)
769
  {
770
    hpcd->ISOINIncompleteCallback = pCallback;
771
  }
772
  else
773
  {
774
    /* Update the error code */
775
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
776
 
777
    /* Return error status */
778
    status =  HAL_ERROR;
779
  }
780
 
781
  /* Release Lock */
782
  __HAL_UNLOCK(hpcd);
783
 
784
  return status;
785
}
786
 
787
/**
788
  * @brief  UnRegister the USB PCD Iso IN incomplete Callback
789
  *         USB PCD Iso IN incomplete Callback is redirected to the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
790
  * @param  hpcd PCD handle
791
  * @retval HAL status
792
  */
793
HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd)
794
{
795
  HAL_StatusTypeDef status = HAL_OK;
796
 
797
  /* Process locked */
798
  __HAL_LOCK(hpcd);
799
 
800
  if (hpcd->State == HAL_PCD_STATE_READY)
801
  {
802
    hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; /* Legacy weak ISOINIncompleteCallback  */
803
  }
804
  else
805
  {
806
    /* Update the error code */
807
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
808
 
809
    /* Return error status */
810
    status =  HAL_ERROR;
811
  }
812
 
813
  /* Release Lock */
814
  __HAL_UNLOCK(hpcd);
815
 
816
  return status;
817
}
818
 
819
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
820
 
821
/**
822
  * @}
823
  */
824
 
825
/** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions
826
 *  @brief   Data transfers functions
827
 *
828
@verbatim
829
 ===============================================================================
830
                      ##### IO operation functions #####
831
 ===============================================================================
832
    [..]
833
    This subsection provides a set of functions allowing to manage the PCD data
834
    transfers.
835
 
836
@endverbatim
837
  * @{
838
  */
839
 
840
/**
841
  * @brief  Start the USB device
842
  * @param  hpcd PCD handle
843
  * @retval HAL status
844
  */
845
HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
846
{
847
  __HAL_LOCK(hpcd);
848
#if defined (USB)
849
  HAL_PCDEx_SetConnectionState(hpcd, 1U);
850
#endif /* defined (USB) */
851
  (void)USB_DevConnect(hpcd->Instance);
852
  __HAL_PCD_ENABLE(hpcd);
853
  __HAL_UNLOCK(hpcd);
854
  return HAL_OK;
855
}
856
 
857
/**
858
  * @brief  Stop the USB device.
859
  * @param  hpcd PCD handle
860
  * @retval HAL status
861
  */
862
HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
863
{
864
  __HAL_LOCK(hpcd);
865
  __HAL_PCD_DISABLE(hpcd);
866
 
867
  if (USB_StopDevice(hpcd->Instance) != HAL_OK)
868
  {
869
    __HAL_UNLOCK(hpcd);
870
    return HAL_ERROR;
871
  }
872
 
873
  (void)USB_DevDisconnect(hpcd->Instance);
874
  __HAL_UNLOCK(hpcd);
875
 
876
  return HAL_OK;
877
}
878
#if defined (USB_OTG_FS)
879
/**
880
  * @brief  Handles PCD interrupt request.
881
  * @param  hpcd PCD handle
882
  * @retval HAL status
883
  */
884
void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
885
{
886
  USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
887
  uint32_t USBx_BASE = (uint32_t)USBx;
888
  uint32_t i, ep_intr, epint, epnum;
889
  uint32_t fifoemptymsk, temp;
890
  USB_OTG_EPTypeDef *ep;
891
 
892
  /* ensure that we are in device mode */
893
  if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)
894
  {
895
    /* avoid spurious interrupt */
896
    if (__HAL_PCD_IS_INVALID_INTERRUPT(hpcd))
897
    {
898
      return;
899
    }
900
 
901
    if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))
902
    {
903
      /* incorrect mode, acknowledge the interrupt */
904
      __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS);
905
    }
906
 
907
    if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))
908
    {
909
      epnum = 0U;
910
 
911
      /* Read in the device interrupt bits */
912
      ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance);
913
 
914
      while (ep_intr != 0U)
915
      {
916
        if ((ep_intr & 0x1U) != 0U)
917
        {
918
          epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, (uint8_t)epnum);
919
 
920
          if ((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)
921
          {
922
            CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC);
923
            (void)PCD_EP_OutXfrComplete_int(hpcd, epnum);
924
          }
925
 
926
          if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)
927
          {
928
            /* Class B setup phase done for previous decoded setup */
929
            (void)PCD_EP_OutSetupPacket_int(hpcd, epnum);
930
            CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP);
931
          }
932
 
933
          if ((epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS)
934
          {
935
            CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS);
936
          }
937
 
938
          /* Clear Status Phase Received interrupt */
939
          if ((epint & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
940
          {
941
            CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
942
          }
943
 
944
          /* Clear OUT NAK interrupt */
945
          if ((epint & USB_OTG_DOEPINT_NAK) == USB_OTG_DOEPINT_NAK)
946
          {
947
            CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_NAK);
948
          }
949
        }
950
        epnum++;
951
        ep_intr >>= 1U;
952
      }
953
    }
954
 
955
    if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT))
956
    {
957
      /* Read in the device interrupt bits */
958
      ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance);
959
 
960
      epnum = 0U;
961
 
962
      while (ep_intr != 0U)
963
      {
964
        if ((ep_intr & 0x1U) != 0U) /* In ITR */
965
        {
966
          epint = USB_ReadDevInEPInterrupt(hpcd->Instance, (uint8_t)epnum);
967
 
968
          if ((epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)
969
          {
970
            fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK));
971
            USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
972
 
973
            CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC);
974
 
975
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
976
            hpcd->DataInStageCallback(hpcd, (uint8_t)epnum);
977
#else
978
            HAL_PCD_DataInStageCallback(hpcd, (uint8_t)epnum);
979
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
980
          }
981
          if ((epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)
982
          {
983
            CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC);
984
          }
985
          if ((epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)
986
          {
987
            CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE);
988
          }
989
          if ((epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)
990
          {
991
            CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE);
992
          }
993
          if ((epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)
994
          {
995
            CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD);
996
          }
997
          if ((epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)
998
          {
999
            (void)PCD_WriteEmptyTxFifo(hpcd, epnum);
1000
          }
1001
        }
1002
        epnum++;
1003
        ep_intr >>= 1U;
1004
      }
1005
    }
1006
 
1007
    /* Handle Resume Interrupt */
1008
    if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))
1009
    {
1010
      /* Clear the Remote Wake-up Signaling */
1011
      USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
1012
 
1013
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1014
      hpcd->ResumeCallback(hpcd);
1015
#else
1016
      HAL_PCD_ResumeCallback(hpcd);
1017
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1018
 
1019
      __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);
1020
    }
1021
 
1022
    /* Handle Suspend Interrupt */
1023
    if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))
1024
    {
1025
      if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
1026
      {
1027
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1028
        hpcd->SuspendCallback(hpcd);
1029
#else
1030
        HAL_PCD_SuspendCallback(hpcd);
1031
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1032
      }
1033
      __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP);
1034
    }
1035
    /* Handle Reset Interrupt */
1036
    if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))
1037
    {
1038
      USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
1039
      (void)USB_FlushTxFifo(hpcd->Instance, 0x10U);
1040
 
1041
      for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
1042
      {
1043
        USBx_INEP(i)->DIEPINT = 0xFB7FU;
1044
        USBx_INEP(i)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
1045
        USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
1046
        USBx_OUTEP(i)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
1047
      }
1048
      USBx_DEVICE->DAINTMSK |= 0x10001U;
1049
 
1050
      if (hpcd->Init.use_dedicated_ep1 != 0U)
1051
      {
1052
        USBx_DEVICE->DOUTEP1MSK |= USB_OTG_DOEPMSK_STUPM |
1053
                                   USB_OTG_DOEPMSK_XFRCM |
1054
                                   USB_OTG_DOEPMSK_EPDM;
1055
 
1056
        USBx_DEVICE->DINEP1MSK |= USB_OTG_DIEPMSK_TOM |
1057
                                  USB_OTG_DIEPMSK_XFRCM |
1058
                                  USB_OTG_DIEPMSK_EPDM;
1059
      }
1060
      else
1061
      {
1062
        USBx_DEVICE->DOEPMSK |= USB_OTG_DOEPMSK_STUPM |
1063
                                USB_OTG_DOEPMSK_XFRCM |
1064
                                USB_OTG_DOEPMSK_EPDM |
1065
                                USB_OTG_DOEPMSK_OTEPSPRM |
1066
                                USB_OTG_DOEPMSK_NAKM;
1067
 
1068
        USBx_DEVICE->DIEPMSK |= USB_OTG_DIEPMSK_TOM |
1069
                                USB_OTG_DIEPMSK_XFRCM |
1070
                                USB_OTG_DIEPMSK_EPDM;
1071
      }
1072
 
1073
      /* Set Default Address to 0 */
1074
      USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;
1075
 
1076
      /* setup EP0 to receive SETUP packets */
1077
      (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
1078
 
1079
      __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST);
1080
    }
1081
 
1082
    /* Handle Enumeration done Interrupt */
1083
    if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))
1084
    {
1085
      (void)USB_ActivateSetup(hpcd->Instance);
1086
      hpcd->Init.speed = USB_GetDevSpeed(hpcd->Instance);
1087
 
1088
      /* Set USB Turnaround time */
1089
      (void)USB_SetTurnaroundTime(hpcd->Instance,
1090
                                  HAL_RCC_GetHCLKFreq(),
1091
                                  (uint8_t)hpcd->Init.speed);
1092
 
1093
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1094
      hpcd->ResetCallback(hpcd);
1095
#else
1096
      HAL_PCD_ResetCallback(hpcd);
1097
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1098
 
1099
      __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);
1100
    }
1101
 
1102
    /* Handle RxQLevel Interrupt */
1103
    if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))
1104
    {
1105
      USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
1106
 
1107
      temp = USBx->GRXSTSP;
1108
 
1109
      ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM];
1110
 
1111
      if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) ==  STS_DATA_UPDT)
1112
      {
1113
        if ((temp & USB_OTG_GRXSTSP_BCNT) != 0U)
1114
        {
1115
          (void)USB_ReadPacket(USBx, ep->xfer_buff,
1116
                               (uint16_t)((temp & USB_OTG_GRXSTSP_BCNT) >> 4));
1117
 
1118
          ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
1119
          ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
1120
        }
1121
      }
1122
      else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) ==  STS_SETUP_UPDT)
1123
      {
1124
        (void)USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8U);
1125
        ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
1126
      }
1127
      else
1128
      {
1129
        /* ... */
1130
      }
1131
      USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
1132
    }
1133
 
1134
    /* Handle SOF Interrupt */
1135
    if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))
1136
    {
1137
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1138
      hpcd->SOFCallback(hpcd);
1139
#else
1140
      HAL_PCD_SOFCallback(hpcd);
1141
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1142
 
1143
      __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF);
1144
    }
1145
 
1146
    /* Handle Incomplete ISO IN Interrupt */
1147
    if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))
1148
    {
1149
      /* Keep application checking the corresponding Iso IN endpoint
1150
      causing the incomplete Interrupt */
1151
      epnum = 0U;
1152
 
1153
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1154
      hpcd->ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
1155
#else
1156
      HAL_PCD_ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
1157
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1158
 
1159
      __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR);
1160
    }
1161
 
1162
    /* Handle Incomplete ISO OUT Interrupt */
1163
    if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
1164
    {
1165
      /* Keep application checking the corresponding Iso OUT endpoint
1166
      causing the incomplete Interrupt */
1167
      epnum = 0U;
1168
 
1169
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1170
      hpcd->ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
1171
#else
1172
      HAL_PCD_ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
1173
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1174
 
1175
      __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
1176
    }
1177
 
1178
    /* Handle Connection event Interrupt */
1179
    if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))
1180
    {
1181
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1182
      hpcd->ConnectCallback(hpcd);
1183
#else
1184
      HAL_PCD_ConnectCallback(hpcd);
1185
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1186
 
1187
      __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT);
1188
    }
1189
 
1190
    /* Handle Disconnection event Interrupt */
1191
    if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))
1192
    {
1193
      temp = hpcd->Instance->GOTGINT;
1194
 
1195
      if ((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)
1196
      {
1197
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1198
        hpcd->DisconnectCallback(hpcd);
1199
#else
1200
        HAL_PCD_DisconnectCallback(hpcd);
1201
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1202
      }
1203
      hpcd->Instance->GOTGINT |= temp;
1204
    }
1205
  }
1206
}
1207
#endif /* defined (USB_OTG_FS) */
1208
 
1209
#if defined (USB)
1210
/**
1211
  * @brief  This function handles PCD interrupt request.
1212
  * @param  hpcd PCD handle
1213
  * @retval HAL status
1214
  */
1215
void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
1216
{
1217
  if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_CTR))
1218
  {
1219
    /* servicing of the endpoint correct transfer interrupt */
1220
    /* clear of the CTR flag into the sub */
1221
    (void)PCD_EP_ISR_Handler(hpcd);
1222
  }
1223
 
1224
  if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_RESET))
1225
  {
1226
    __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET);
1227
 
1228
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1229
    hpcd->ResetCallback(hpcd);
1230
#else
1231
    HAL_PCD_ResetCallback(hpcd);
1232
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1233
 
1234
    (void)HAL_PCD_SetAddress(hpcd, 0U);
1235
  }
1236
 
1237
  if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_PMAOVR))
1238
  {
1239
    __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR);
1240
  }
1241
 
1242
  if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_ERR))
1243
  {
1244
    __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR);
1245
  }
1246
 
1247
  if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_WKUP))
1248
  {
1249
    hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_LP_MODE);
1250
    hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_FSUSP);
1251
 
1252
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1253
    hpcd->ResumeCallback(hpcd);
1254
#else
1255
    HAL_PCD_ResumeCallback(hpcd);
1256
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1257
 
1258
    __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP);
1259
  }
1260
 
1261
  if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_SUSP))
1262
  {
1263
    /* Force low-power mode in the macrocell */
1264
    hpcd->Instance->CNTR |= USB_CNTR_FSUSP;
1265
 
1266
    /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
1267
    __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP);
1268
 
1269
    hpcd->Instance->CNTR |= USB_CNTR_LP_MODE;
1270
 
1271
    /* WA: Clear Wakeup flag if raised with suspend signal */
1272
    if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_WKUP))
1273
    {
1274
       __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP);
1275
    }
1276
 
1277
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1278
    hpcd->SuspendCallback(hpcd);
1279
#else
1280
    HAL_PCD_SuspendCallback(hpcd);
1281
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1282
  }
1283
 
1284
  if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_SOF))
1285
  {
1286
    __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF);
1287
 
1288
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1289
    hpcd->SOFCallback(hpcd);
1290
#else
1291
    HAL_PCD_SOFCallback(hpcd);
1292
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1293
  }
1294
 
1295
  if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_ESOF))
1296
  {
1297
    /* clear ESOF flag in ISTR */
1298
    __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF);
1299
  }
1300
}
1301
#endif /* defined (USB) */
1302
 
1303
/**
1304
  * @brief  Data OUT stage callback.
1305
  * @param  hpcd PCD handle
1306
  * @param  epnum endpoint number
1307
  * @retval None
1308
  */
1309
__weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1310
{
1311
  /* Prevent unused argument(s) compilation warning */
1312
  UNUSED(hpcd);
1313
  UNUSED(epnum);
1314
 
1315
  /* NOTE : This function should not be modified, when the callback is needed,
1316
            the HAL_PCD_DataOutStageCallback could be implemented in the user file
1317
   */
1318
}
1319
 
1320
/**
1321
  * @brief  Data IN stage callback
1322
  * @param  hpcd PCD handle
1323
  * @param  epnum endpoint number
1324
  * @retval None
1325
  */
1326
__weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1327
{
1328
  /* Prevent unused argument(s) compilation warning */
1329
  UNUSED(hpcd);
1330
  UNUSED(epnum);
1331
 
1332
  /* NOTE : This function should not be modified, when the callback is needed,
1333
            the HAL_PCD_DataInStageCallback could be implemented in the user file
1334
   */
1335
}
1336
/**
1337
  * @brief  Setup stage callback
1338
  * @param  hpcd PCD handle
1339
  * @retval None
1340
  */
1341
__weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
1342
{
1343
  /* Prevent unused argument(s) compilation warning */
1344
  UNUSED(hpcd);
1345
 
1346
  /* NOTE : This function should not be modified, when the callback is needed,
1347
            the HAL_PCD_SetupStageCallback could be implemented in the user file
1348
   */
1349
}
1350
 
1351
/**
1352
  * @brief  USB Start Of Frame callback.
1353
  * @param  hpcd PCD handle
1354
  * @retval None
1355
  */
1356
__weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
1357
{
1358
  /* Prevent unused argument(s) compilation warning */
1359
  UNUSED(hpcd);
1360
 
1361
  /* NOTE : This function should not be modified, when the callback is needed,
1362
            the HAL_PCD_SOFCallback could be implemented in the user file
1363
   */
1364
}
1365
 
1366
/**
1367
  * @brief  USB Reset callback.
1368
  * @param  hpcd PCD handle
1369
  * @retval None
1370
  */
1371
__weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
1372
{
1373
  /* Prevent unused argument(s) compilation warning */
1374
  UNUSED(hpcd);
1375
 
1376
  /* NOTE : This function should not be modified, when the callback is needed,
1377
            the HAL_PCD_ResetCallback could be implemented in the user file
1378
   */
1379
}
1380
 
1381
/**
1382
  * @brief  Suspend event callback.
1383
  * @param  hpcd PCD handle
1384
  * @retval None
1385
  */
1386
__weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
1387
{
1388
  /* Prevent unused argument(s) compilation warning */
1389
  UNUSED(hpcd);
1390
 
1391
  /* NOTE : This function should not be modified, when the callback is needed,
1392
            the HAL_PCD_SuspendCallback could be implemented in the user file
1393
   */
1394
}
1395
 
1396
/**
1397
  * @brief  Resume event callback.
1398
  * @param  hpcd PCD handle
1399
  * @retval None
1400
  */
1401
__weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
1402
{
1403
  /* Prevent unused argument(s) compilation warning */
1404
  UNUSED(hpcd);
1405
 
1406
  /* NOTE : This function should not be modified, when the callback is needed,
1407
            the HAL_PCD_ResumeCallback could be implemented in the user file
1408
   */
1409
}
1410
 
1411
/**
1412
  * @brief  Incomplete ISO OUT callback.
1413
  * @param  hpcd PCD handle
1414
  * @param  epnum endpoint number
1415
  * @retval None
1416
  */
1417
__weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1418
{
1419
  /* Prevent unused argument(s) compilation warning */
1420
  UNUSED(hpcd);
1421
  UNUSED(epnum);
1422
 
1423
  /* NOTE : This function should not be modified, when the callback is needed,
1424
            the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
1425
   */
1426
}
1427
 
1428
/**
1429
  * @brief  Incomplete ISO IN callback.
1430
  * @param  hpcd PCD handle
1431
  * @param  epnum endpoint number
1432
  * @retval None
1433
  */
1434
__weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1435
{
1436
  /* Prevent unused argument(s) compilation warning */
1437
  UNUSED(hpcd);
1438
  UNUSED(epnum);
1439
 
1440
  /* NOTE : This function should not be modified, when the callback is needed,
1441
            the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
1442
   */
1443
}
1444
 
1445
/**
1446
  * @brief  Connection event callback.
1447
  * @param  hpcd PCD handle
1448
  * @retval None
1449
  */
1450
__weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
1451
{
1452
  /* Prevent unused argument(s) compilation warning */
1453
  UNUSED(hpcd);
1454
 
1455
  /* NOTE : This function should not be modified, when the callback is needed,
1456
            the HAL_PCD_ConnectCallback could be implemented in the user file
1457
   */
1458
}
1459
 
1460
/**
1461
  * @brief  Disconnection event callback.
1462
  * @param  hpcd PCD handle
1463
  * @retval None
1464
  */
1465
__weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
1466
{
1467
  /* Prevent unused argument(s) compilation warning */
1468
  UNUSED(hpcd);
1469
 
1470
  /* NOTE : This function should not be modified, when the callback is needed,
1471
            the HAL_PCD_DisconnectCallback could be implemented in the user file
1472
   */
1473
}
1474
 
1475
/**
1476
  * @}
1477
  */
1478
 
1479
/** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
1480
 *  @brief   management functions
1481
 *
1482
@verbatim
1483
 ===============================================================================
1484
                      ##### Peripheral Control functions #####
1485
 ===============================================================================
1486
    [..]
1487
    This subsection provides a set of functions allowing to control the PCD data
1488
    transfers.
1489
 
1490
@endverbatim
1491
  * @{
1492
  */
1493
 
1494
/**
1495
  * @brief  Connect the USB device
1496
  * @param  hpcd PCD handle
1497
  * @retval HAL status
1498
  */
1499
HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
1500
{
1501
  __HAL_LOCK(hpcd);
1502
#if defined (USB)
1503
  HAL_PCDEx_SetConnectionState(hpcd, 1U);
1504
#endif /* defined (USB) */
1505
  (void)USB_DevConnect(hpcd->Instance);
1506
  __HAL_UNLOCK(hpcd);
1507
  return HAL_OK;
1508
}
1509
 
1510
/**
1511
  * @brief  Disconnect the USB device.
1512
  * @param  hpcd PCD handle
1513
  * @retval HAL status
1514
  */
1515
HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
1516
{
1517
  __HAL_LOCK(hpcd);
1518
#if defined (USB)
1519
  HAL_PCDEx_SetConnectionState(hpcd, 0U);
1520
#endif /* defined (USB) */
1521
  (void)USB_DevDisconnect(hpcd->Instance);
1522
  __HAL_UNLOCK(hpcd);
1523
  return HAL_OK;
1524
}
1525
 
1526
/**
1527
  * @brief  Set the USB Device address.
1528
  * @param  hpcd PCD handle
1529
  * @param  address new device address
1530
  * @retval HAL status
1531
  */
1532
HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
1533
{
1534
  __HAL_LOCK(hpcd);
1535
  hpcd->USB_Address = address;
1536
  (void)USB_SetDevAddress(hpcd->Instance, address);
1537
  __HAL_UNLOCK(hpcd);
1538
  return HAL_OK;
1539
}
1540
/**
1541
  * @brief  Open and configure an endpoint.
1542
  * @param  hpcd PCD handle
1543
  * @param  ep_addr endpoint address
1544
  * @param  ep_mps endpoint max packet size
1545
  * @param  ep_type endpoint type
1546
  * @retval HAL status
1547
  */
1548
HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)
1549
{
1550
  HAL_StatusTypeDef  ret = HAL_OK;
1551
  PCD_EPTypeDef *ep;
1552
 
1553
  if ((ep_addr & 0x80U) == 0x80U)
1554
  {
1555
    ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1556
    ep->is_in = 1U;
1557
  }
1558
  else
1559
  {
1560
    ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
1561
    ep->is_in = 0U;
1562
  }
1563
 
1564
  ep->num = ep_addr & EP_ADDR_MSK;
1565
  ep->maxpacket = ep_mps;
1566
  ep->type = ep_type;
1567
 
1568
  if (ep->is_in != 0U)
1569
  {
1570
    /* Assign a Tx FIFO */
1571
    ep->tx_fifo_num = ep->num;
1572
  }
1573
  /* Set initial data PID. */
1574
  if (ep_type == EP_TYPE_BULK)
1575
  {
1576
    ep->data_pid_start = 0U;
1577
  }
1578
 
1579
  __HAL_LOCK(hpcd);
1580
  (void)USB_ActivateEndpoint(hpcd->Instance, ep);
1581
  __HAL_UNLOCK(hpcd);
1582
 
1583
  return ret;
1584
}
1585
 
1586
/**
1587
  * @brief  Deactivate an endpoint.
1588
  * @param  hpcd PCD handle
1589
  * @param  ep_addr endpoint address
1590
  * @retval HAL status
1591
  */
1592
HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1593
{
1594
  PCD_EPTypeDef *ep;
1595
 
1596
  if ((ep_addr & 0x80U) == 0x80U)
1597
  {
1598
    ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1599
    ep->is_in = 1U;
1600
  }
1601
  else
1602
  {
1603
    ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
1604
    ep->is_in = 0U;
1605
  }
1606
  ep->num   = ep_addr & EP_ADDR_MSK;
1607
 
1608
  __HAL_LOCK(hpcd);
1609
  (void)USB_DeactivateEndpoint(hpcd->Instance, ep);
1610
  __HAL_UNLOCK(hpcd);
1611
  return HAL_OK;
1612
}
1613
 
1614
 
1615
/**
1616
  * @brief  Receive an amount of data.
1617
  * @param  hpcd PCD handle
1618
  * @param  ep_addr endpoint address
1619
  * @param  pBuf pointer to the reception buffer
1620
  * @param  len amount of data to be received
1621
  * @retval HAL status
1622
  */
1623
HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
1624
{
1625
  PCD_EPTypeDef *ep;
1626
 
1627
  ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
1628
 
1629
  /*setup and start the Xfer */
1630
  ep->xfer_buff = pBuf;
1631
  ep->xfer_len = len;
1632
  ep->xfer_count = 0U;
1633
  ep->is_in = 0U;
1634
  ep->num = ep_addr & EP_ADDR_MSK;
1635
 
1636
  if ((ep_addr & EP_ADDR_MSK) == 0U)
1637
  {
1638
    (void)USB_EP0StartXfer(hpcd->Instance, ep);
1639
  }
1640
  else
1641
  {
1642
    (void)USB_EPStartXfer(hpcd->Instance, ep);
1643
  }
1644
 
1645
  return HAL_OK;
1646
}
1647
 
1648
/**
1649
  * @brief  Get Received Data Size
1650
  * @param  hpcd PCD handle
1651
  * @param  ep_addr endpoint address
1652
  * @retval Data Size
1653
  */
1654
uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1655
{
1656
  return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count;
1657
}
1658
/**
1659
  * @brief  Send an amount of data
1660
  * @param  hpcd PCD handle
1661
  * @param  ep_addr endpoint address
1662
  * @param  pBuf pointer to the transmission buffer
1663
  * @param  len amount of data to be sent
1664
  * @retval HAL status
1665
  */
1666
HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
1667
{
1668
  PCD_EPTypeDef *ep;
1669
 
1670
  ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1671
 
1672
  /*setup and start the Xfer */
1673
  ep->xfer_buff = pBuf;
1674
  ep->xfer_len = len;
1675
  ep->xfer_count = 0U;
1676
  ep->is_in = 1U;
1677
  ep->num = ep_addr & EP_ADDR_MSK;
1678
 
1679
  if ((ep_addr & EP_ADDR_MSK) == 0U)
1680
  {
1681
    (void)USB_EP0StartXfer(hpcd->Instance, ep);
1682
  }
1683
  else
1684
  {
1685
    (void)USB_EPStartXfer(hpcd->Instance, ep);
1686
  }
1687
 
1688
  return HAL_OK;
1689
}
1690
 
1691
/**
1692
  * @brief  Set a STALL condition over an endpoint
1693
  * @param  hpcd PCD handle
1694
  * @param  ep_addr endpoint address
1695
  * @retval HAL status
1696
  */
1697
HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1698
{
1699
  PCD_EPTypeDef *ep;
1700
 
1701
  if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.dev_endpoints)
1702
  {
1703
    return HAL_ERROR;
1704
  }
1705
 
1706
  if ((0x80U & ep_addr) == 0x80U)
1707
  {
1708
    ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1709
    ep->is_in = 1U;
1710
  }
1711
  else
1712
  {
1713
    ep = &hpcd->OUT_ep[ep_addr];
1714
    ep->is_in = 0U;
1715
  }
1716
 
1717
  ep->is_stall = 1U;
1718
  ep->num = ep_addr & EP_ADDR_MSK;
1719
 
1720
  __HAL_LOCK(hpcd);
1721
 
1722
  (void)USB_EPSetStall(hpcd->Instance, ep);
1723
  if ((ep_addr & EP_ADDR_MSK) == 0U)
1724
  {
1725
    (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
1726
  }
1727
  __HAL_UNLOCK(hpcd);
1728
 
1729
  return HAL_OK;
1730
}
1731
 
1732
/**
1733
  * @brief  Clear a STALL condition over in an endpoint
1734
  * @param  hpcd PCD handle
1735
  * @param  ep_addr endpoint address
1736
  * @retval HAL status
1737
  */
1738
HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1739
{
1740
  PCD_EPTypeDef *ep;
1741
 
1742
  if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints)
1743
  {
1744
    return HAL_ERROR;
1745
  }
1746
 
1747
  if ((0x80U & ep_addr) == 0x80U)
1748
  {
1749
    ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1750
    ep->is_in = 1U;
1751
  }
1752
  else
1753
  {
1754
    ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
1755
    ep->is_in = 0U;
1756
  }
1757
 
1758
  ep->is_stall = 0U;
1759
  ep->num = ep_addr & EP_ADDR_MSK;
1760
 
1761
  __HAL_LOCK(hpcd);
1762
  (void)USB_EPClearStall(hpcd->Instance, ep);
1763
  __HAL_UNLOCK(hpcd);
1764
 
1765
  return HAL_OK;
1766
}
1767
 
1768
/**
1769
  * @brief  Flush an endpoint
1770
  * @param  hpcd PCD handle
1771
  * @param  ep_addr endpoint address
1772
  * @retval HAL status
1773
  */
1774
HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1775
{
1776
  __HAL_LOCK(hpcd);
1777
 
1778
  if ((ep_addr & 0x80U) == 0x80U)
1779
  {
1780
    (void)USB_FlushTxFifo(hpcd->Instance, (uint32_t)ep_addr & EP_ADDR_MSK);
1781
  }
1782
  else
1783
  {
1784
    (void)USB_FlushRxFifo(hpcd->Instance);
1785
  }
1786
 
1787
  __HAL_UNLOCK(hpcd);
1788
 
1789
  return HAL_OK;
1790
}
1791
 
1792
/**
1793
  * @brief  Activate remote wakeup signalling
1794
  * @param  hpcd PCD handle
1795
  * @retval HAL status
1796
  */
1797
HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
1798
{
1799
  return (USB_ActivateRemoteWakeup(hpcd->Instance));
1800
}
1801
 
1802
/**
1803
  * @brief  De-activate remote wakeup signalling.
1804
  * @param  hpcd PCD handle
1805
  * @retval HAL status
1806
  */
1807
HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
1808
{
1809
  return (USB_DeActivateRemoteWakeup(hpcd->Instance));
1810
}
1811
 
1812
/**
1813
  * @}
1814
  */
1815
 
1816
/** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
1817
 *  @brief   Peripheral State functions
1818
 *
1819
@verbatim
1820
 ===============================================================================
1821
                      ##### Peripheral State functions #####
1822
 ===============================================================================
1823
    [..]
1824
    This subsection permits to get in run-time the status of the peripheral
1825
    and the data flow.
1826
 
1827
@endverbatim
1828
  * @{
1829
  */
1830
 
1831
/**
1832
  * @brief  Return the PCD handle state.
1833
  * @param  hpcd PCD handle
1834
  * @retval HAL state
1835
  */
1836
PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd)
1837
{
1838
  return hpcd->State;
1839
}
1840
 
1841
/**
1842
  * @}
1843
  */
1844
 
1845
/**
1846
  * @}
1847
  */
1848
 
1849
/* Private functions ---------------------------------------------------------*/
1850
/** @addtogroup PCD_Private_Functions
1851
  * @{
1852
  */
1853
#if defined (USB_OTG_FS)
1854
/**
1855
  * @brief  Check FIFO for the next packet to be loaded.
1856
  * @param  hpcd PCD handle
1857
  * @param  epnum endpoint number
1858
  * @retval HAL status
1859
  */
1860
static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)
1861
{
1862
  USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1863
  uint32_t USBx_BASE = (uint32_t)USBx;
1864
  USB_OTG_EPTypeDef *ep;
1865
  uint32_t len;
1866
  uint32_t len32b;
1867
  uint32_t fifoemptymsk;
1868
 
1869
  ep = &hpcd->IN_ep[epnum];
1870
 
1871
  if (ep->xfer_count > ep->xfer_len)
1872
  {
1873
    return HAL_ERROR;
1874
  }
1875
 
1876
  len = ep->xfer_len - ep->xfer_count;
1877
 
1878
  if (len > ep->maxpacket)
1879
  {
1880
    len = ep->maxpacket;
1881
  }
1882
 
1883
  len32b = (len + 3U) / 4U;
1884
 
1885
  while (((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= len32b) &&
1886
         (ep->xfer_count < ep->xfer_len) && (ep->xfer_len != 0U))
1887
  {
1888
    /* Write the FIFO */
1889
    len = ep->xfer_len - ep->xfer_count;
1890
 
1891
    if (len > ep->maxpacket)
1892
    {
1893
      len = ep->maxpacket;
1894
    }
1895
    len32b = (len + 3U) / 4U;
1896
 
1897
    (void)USB_WritePacket(USBx, ep->xfer_buff, (uint8_t)epnum, (uint16_t)len);
1898
 
1899
    ep->xfer_buff  += len;
1900
    ep->xfer_count += len;
1901
  }
1902
 
1903
  if (ep->xfer_len <= ep->xfer_count)
1904
  {
1905
    fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK));
1906
    USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
1907
  }
1908
 
1909
  return HAL_OK;
1910
}
1911
 
1912
 
1913
/**
1914
  * @brief  process EP OUT transfer complete interrupt.
1915
  * @param  hpcd PCD handle
1916
  * @param  epnum endpoint number
1917
  * @retval HAL status
1918
  */
1919
static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum)
1920
{
1921
  USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1922
  uint32_t USBx_BASE = (uint32_t)USBx;
1923
  uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U);
1924
  uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT;
1925
 
1926
  if (gSNPSiD == USB_OTG_CORE_ID_310A)
1927
  {
1928
    /* StupPktRcvd = 1 this is a setup packet */
1929
    if ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX)
1930
    {
1931
      CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
1932
    }
1933
    else
1934
    {
1935
      if ((DoepintReg & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
1936
      {
1937
        CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
1938
      }
1939
 
1940
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1941
      hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
1942
#else
1943
      HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
1944
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1945
    }
1946
  }
1947
  else
1948
  {
1949
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1950
    hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
1951
#else
1952
    HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
1953
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1954
  }
1955
 
1956
  return HAL_OK;
1957
}
1958
 
1959
 
1960
/**
1961
  * @brief  process EP OUT setup packet received interrupt.
1962
  * @param  hpcd PCD handle
1963
  * @param  epnum endpoint number
1964
  * @retval HAL status
1965
  */
1966
static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum)
1967
{
1968
  USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1969
  uint32_t USBx_BASE = (uint32_t)USBx;
1970
  uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U);
1971
  uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT;
1972
 
1973
 
1974
  if ((gSNPSiD == USB_OTG_CORE_ID_310A) &&
1975
      ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX))
1976
  {
1977
    CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
1978
  }
1979
 
1980
  /* Inform the upper layer that a setup packet is available */
1981
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1982
  hpcd->SetupStageCallback(hpcd);
1983
#else
1984
  HAL_PCD_SetupStageCallback(hpcd);
1985
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1986
 
1987
  return HAL_OK;
1988
}
1989
#endif /* defined (USB_OTG_FS) */
1990
 
1991
#if defined (USB)
1992
/**
1993
  * @brief  This function handles PCD Endpoint interrupt request.
1994
  * @param  hpcd PCD handle
1995
  * @retval HAL status
1996
  */
1997
static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
1998
{
1999
  PCD_EPTypeDef *ep;
2000
  uint16_t count;
2001
  uint16_t wIstr;
2002
  uint16_t wEPVal;
2003
  uint8_t epindex;
2004
 
2005
  /* stay in loop while pending interrupts */
2006
  while ((hpcd->Instance->ISTR & USB_ISTR_CTR) != 0U)
2007
  {
2008
    wIstr = hpcd->Instance->ISTR;
2009
    /* extract highest priority endpoint number */
2010
    epindex = (uint8_t)(wIstr & USB_ISTR_EP_ID);
2011
 
2012
    if (epindex == 0U)
2013
    {
2014
      /* Decode and service control endpoint interrupt */
2015
 
2016
      /* DIR bit = origin of the interrupt */
2017
      if ((wIstr & USB_ISTR_DIR) == 0U)
2018
      {
2019
        /* DIR = 0 */
2020
 
2021
        /* DIR = 0      => IN  int */
2022
        /* DIR = 0 implies that (EP_CTR_TX = 1) always  */
2023
        PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0);
2024
        ep = &hpcd->IN_ep[0];
2025
 
2026
        ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
2027
        ep->xfer_buff += ep->xfer_count;
2028
 
2029
        /* TX COMPLETE */
2030
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2031
        hpcd->DataInStageCallback(hpcd, 0U);
2032
#else
2033
        HAL_PCD_DataInStageCallback(hpcd, 0U);
2034
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2035
 
2036
        if ((hpcd->USB_Address > 0U) && (ep->xfer_len == 0U))
2037
        {
2038
          hpcd->Instance->DADDR = ((uint16_t)hpcd->USB_Address | USB_DADDR_EF);
2039
          hpcd->USB_Address = 0U;
2040
        }
2041
      }
2042
      else
2043
      {
2044
        /* DIR = 1 */
2045
 
2046
        /* DIR = 1 & CTR_RX       => SETUP or OUT int */
2047
        /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
2048
        ep = &hpcd->OUT_ep[0];
2049
        wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0);
2050
 
2051
        if ((wEPVal & USB_EP_SETUP) != 0U)
2052
        {
2053
          /* Get SETUP Packet*/
2054
          ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
2055
 
2056
          USB_ReadPMA(hpcd->Instance, (uint8_t *)hpcd->Setup,
2057
                      ep->pmaadress, (uint16_t)ep->xfer_count);
2058
 
2059
          /* SETUP bit kept frozen while CTR_RX = 1*/
2060
          PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
2061
 
2062
          /* Process SETUP Packet*/
2063
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2064
          hpcd->SetupStageCallback(hpcd);
2065
#else
2066
          HAL_PCD_SetupStageCallback(hpcd);
2067
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2068
        }
2069
 
2070
        else if ((wEPVal & USB_EP_CTR_RX) != 0U)
2071
        {
2072
          PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
2073
 
2074
          /* Get Control Data OUT Packet*/
2075
          ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
2076
 
2077
          if ((ep->xfer_count != 0U) && (ep->xfer_buff != 0U))
2078
          {
2079
            USB_ReadPMA(hpcd->Instance, ep->xfer_buff,
2080
                        ep->pmaadress, (uint16_t)ep->xfer_count);
2081
 
2082
            ep->xfer_buff += ep->xfer_count;
2083
 
2084
            /* Process Control Data OUT Packet*/
2085
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2086
            hpcd->DataOutStageCallback(hpcd, 0U);
2087
#else
2088
            HAL_PCD_DataOutStageCallback(hpcd, 0U);
2089
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2090
          }
2091
 
2092
          PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket);
2093
          PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID);
2094
        }
2095
      }
2096
    }
2097
    else
2098
    {
2099
      /* Decode and service non control endpoints interrupt  */
2100
 
2101
      /* process related endpoint register */
2102
      wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, epindex);
2103
      if ((wEPVal & USB_EP_CTR_RX) != 0U)
2104
      {
2105
        /* clear int flag */
2106
        PCD_CLEAR_RX_EP_CTR(hpcd->Instance, epindex);
2107
        ep = &hpcd->OUT_ep[epindex];
2108
 
2109
        /* OUT double Buffering*/
2110
        if (ep->doublebuffer == 0U)
2111
        {
2112
          count = (uint16_t)PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
2113
          if (count != 0U)
2114
          {
2115
            USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count);
2116
          }
2117
        }
2118
        else
2119
        {
2120
          if ((PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_RX) != 0U)
2121
          {
2122
            /*read from endpoint BUF0Addr buffer*/
2123
            count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
2124
            if (count != 0U)
2125
            {
2126
              USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
2127
            }
2128
          }
2129
          else
2130
          {
2131
            /*read from endpoint BUF1Addr buffer*/
2132
            count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
2133
            if (count != 0U)
2134
            {
2135
              USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
2136
            }
2137
          }
2138
          /* free EP OUT Buffer */
2139
          PCD_FreeUserBuffer(hpcd->Instance, ep->num, 0U);
2140
        }
2141
        /*multi-packet on the NON control OUT endpoint*/
2142
        ep->xfer_count += count;
2143
        ep->xfer_buff += count;
2144
 
2145
        if ((ep->xfer_len == 0U) || (count < ep->maxpacket))
2146
        {
2147
          /* RX COMPLETE */
2148
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2149
          hpcd->DataOutStageCallback(hpcd, ep->num);
2150
#else
2151
          HAL_PCD_DataOutStageCallback(hpcd, ep->num);
2152
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2153
        }
2154
        else
2155
        {
2156
          (void)HAL_PCD_EP_Receive(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
2157
        }
2158
 
2159
      } /* if((wEPVal & EP_CTR_RX) */
2160
 
2161
      if ((wEPVal & USB_EP_CTR_TX) != 0U)
2162
      {
2163
        ep = &hpcd->IN_ep[epindex];
2164
 
2165
        /* clear int flag */
2166
        PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex);
2167
 
2168
        /*multi-packet on the NON control IN endpoint*/
2169
        ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
2170
        ep->xfer_buff += ep->xfer_count;
2171
 
2172
        /* Zero Length Packet? */
2173
        if (ep->xfer_len == 0U)
2174
        {
2175
          /* TX COMPLETE */
2176
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2177
          hpcd->DataInStageCallback(hpcd, ep->num);
2178
#else
2179
          HAL_PCD_DataInStageCallback(hpcd, ep->num);
2180
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2181
        }
2182
        else
2183
        {
2184
          (void)HAL_PCD_EP_Transmit(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
2185
        }
2186
      }
2187
    }
2188
  }
2189
  return HAL_OK;
2190
}
2191
#endif /* defined (USB) */
2192
 
2193
/**
2194
  * @}
2195
  */
2196
#endif /* defined (USB) || defined (USB_OTG_FS) */
2197
#endif /* HAL_PCD_MODULE_ENABLED */
2198
 
2199
/**
2200
  * @}
2201
  */
2202
 
2203
/**
2204
  * @}
2205
  */
2206
 
2207
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/