Subversion Repositories CharLCD

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