Subversion Repositories AFRtranscoder

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