Subversion Repositories FuelGauge

Rev

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

Rev Author Line No. Line
2 mjames 1
/**
2
  ******************************************************************************
3
  * @file    stm32f0xx_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 "stm32f0xx_hal.h"
58
 
59
/** @addtogroup STM32F0xx_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)
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
 
90
static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd);
91
 
92
/**
93
  * @}
94
  */
95
 
96
/* Exported functions --------------------------------------------------------*/
97
/** @defgroup PCD_Exported_Functions PCD Exported Functions
98
  * @{
99
  */
100
 
101
/** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
102
 *  @brief    Initialization and Configuration functions
103
 *
104
@verbatim
105
 ===============================================================================
106
            ##### Initialization and de-initialization functions #####
107
 ===============================================================================
108
    [..]  This section provides functions allowing to:
109
 
110
@endverbatim
111
  * @{
112
  */
113
 
114
/**
115
  * @brief  Initializes the PCD according to the specified
116
  *         parameters in the PCD_InitTypeDef and initialize the associated handle.
117
  * @param  hpcd PCD handle
118
  * @retval HAL status
119
  */
120
HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
121
{
122
  uint8_t i;
123
 
124
  /* Check the PCD handle allocation */
125
  if (hpcd == NULL)
126
  {
127
    return HAL_ERROR;
128
  }
129
 
130
  /* Check the parameters */
131
  assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));
132
 
133
  if (hpcd->State == HAL_PCD_STATE_RESET)
134
  {
135
    /* Allocate lock resource and initialize it */
136
    hpcd->Lock = HAL_UNLOCKED;
137
 
138
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
139
    hpcd->SOFCallback = HAL_PCD_SOFCallback;
140
    hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
141
    hpcd->ResetCallback = HAL_PCD_ResetCallback;
142
    hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
143
    hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
144
    hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
145
    hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
146
    hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback;
147
    hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback;
148
    hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback;
149
    hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback;
150
    hpcd->LPMCallback = HAL_PCDEx_LPM_Callback;
151
    hpcd->BCDCallback = HAL_PCDEx_BCD_Callback;
152
 
153
    if (hpcd->MspInitCallback == NULL)
154
    {
155
      hpcd->MspInitCallback = HAL_PCD_MspInit;
156
    }
157
 
158
    /* Init the low level hardware */
159
    hpcd->MspInitCallback(hpcd);
160
#else
161
    /* Init the low level hardware : GPIO, CLOCK, NVIC... */
162
    HAL_PCD_MspInit(hpcd);
163
#endif /* (USE_HAL_PCD_REGISTER_CALLBACKS) */
164
  }
165
 
166
  hpcd->State = HAL_PCD_STATE_BUSY;
167
 
168
  /* Disable the Interrupts */
169
  __HAL_PCD_DISABLE(hpcd);
170
 
171
  /* Init endpoints structures */
172
  for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
173
  {
174
    /* Init ep structure */
175
    hpcd->IN_ep[i].is_in = 1U;
176
    hpcd->IN_ep[i].num = i;
177
    hpcd->IN_ep[i].tx_fifo_num = i;
178
    /* Control until ep is activated */
179
    hpcd->IN_ep[i].type = EP_TYPE_CTRL;
180
    hpcd->IN_ep[i].maxpacket = 0U;
181
    hpcd->IN_ep[i].xfer_buff = 0U;
182
    hpcd->IN_ep[i].xfer_len = 0U;
183
  }
184
 
185
  for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
186
  {
187
    hpcd->OUT_ep[i].is_in = 0U;
188
    hpcd->OUT_ep[i].num = i;
189
    /* Control until ep is activated */
190
    hpcd->OUT_ep[i].type = EP_TYPE_CTRL;
191
    hpcd->OUT_ep[i].maxpacket = 0U;
192
    hpcd->OUT_ep[i].xfer_buff = 0U;
193
    hpcd->OUT_ep[i].xfer_len = 0U;
194
  }
195
 
196
  /* Init Device */
197
  (void)USB_DevInit(hpcd->Instance, hpcd->Init);
198
 
199
  hpcd->USB_Address = 0U;
200
  hpcd->State = HAL_PCD_STATE_READY;
201
 
202
  /* Activate LPM */
203
  if (hpcd->Init.lpm_enable == 1U)
204
  {
205
    (void)HAL_PCDEx_ActivateLPM(hpcd);
206
  }
207
 
208
  return HAL_OK;
209
}
210
 
211
/**
212
  * @brief  DeInitializes the PCD peripheral.
213
  * @param  hpcd PCD handle
214
  * @retval HAL status
215
  */
216
HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
217
{
218
  /* Check the PCD handle allocation */
219
  if (hpcd == NULL)
220
  {
221
    return HAL_ERROR;
222
  }
223
 
224
  hpcd->State = HAL_PCD_STATE_BUSY;
225
 
226
  /* Stop Device */
227
  (void)HAL_PCD_Stop(hpcd);
228
 
229
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
230
  if (hpcd->MspDeInitCallback == NULL)
231
  {
232
    hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; /* Legacy weak MspDeInit  */
233
  }
234
 
235
  /* DeInit the low level hardware */
236
  hpcd->MspDeInitCallback(hpcd);
237
#else
238
  /* DeInit the low level hardware: CLOCK, NVIC.*/
239
  HAL_PCD_MspDeInit(hpcd);
240
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
241
 
242
  hpcd->State = HAL_PCD_STATE_RESET;
243
 
244
  return HAL_OK;
245
}
246
 
247
/**
248
  * @brief  Initializes the PCD MSP.
249
  * @param  hpcd PCD handle
250
  * @retval None
251
  */
252
__weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
253
{
254
  /* Prevent unused argument(s) compilation warning */
255
  UNUSED(hpcd);
256
 
257
  /* NOTE : This function should not be modified, when the callback is needed,
258
            the HAL_PCD_MspInit could be implemented in the user file
259
   */
260
}
261
 
262
/**
263
  * @brief  DeInitializes PCD MSP.
264
  * @param  hpcd PCD handle
265
  * @retval None
266
  */
267
__weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
268
{
269
  /* Prevent unused argument(s) compilation warning */
270
  UNUSED(hpcd);
271
 
272
  /* NOTE : This function should not be modified, when the callback is needed,
273
            the HAL_PCD_MspDeInit could be implemented in the user file
274
   */
275
}
276
 
277
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
278
/**
279
  * @brief  Register a User USB PCD Callback
280
  *         To be used instead of the weak predefined callback
281
  * @param  hpcd USB PCD handle
282
  * @param  CallbackID ID of the callback to be registered
283
  *         This parameter can be one of the following values:
284
  *          @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
285
  *          @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
286
  *          @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
287
  *          @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
288
  *          @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
289
  *          @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
290
  *          @arg @ref HAL_PCD_DISCONNECT_CB_ID OTG PCD Disconnect callback ID
291
  *          @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
292
  *          @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
293
  * @param  pCallback pointer to the Callback function
294
  * @retval HAL status
295
  */
296
HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID, pPCD_CallbackTypeDef pCallback)
297
{
298
  HAL_StatusTypeDef status = HAL_OK;
299
 
300
  if (pCallback == NULL)
301
  {
302
    /* Update the error code */
303
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
304
    return HAL_ERROR;
305
  }
306
  /* Process locked */
307
  __HAL_LOCK(hpcd);
308
 
309
  if (hpcd->State == HAL_PCD_STATE_READY)
310
  {
311
    switch (CallbackID)
312
    {
313
      case HAL_PCD_SOF_CB_ID :
314
        hpcd->SOFCallback = pCallback;
315
        break;
316
 
317
      case HAL_PCD_SETUPSTAGE_CB_ID :
318
        hpcd->SetupStageCallback = pCallback;
319
        break;
320
 
321
      case HAL_PCD_RESET_CB_ID :
322
        hpcd->ResetCallback = pCallback;
323
        break;
324
 
325
      case HAL_PCD_SUSPEND_CB_ID :
326
        hpcd->SuspendCallback = pCallback;
327
        break;
328
 
329
      case HAL_PCD_RESUME_CB_ID :
330
        hpcd->ResumeCallback = pCallback;
331
        break;
332
 
333
      case HAL_PCD_CONNECT_CB_ID :
334
        hpcd->ConnectCallback = pCallback;
335
        break;
336
 
337
      case HAL_PCD_DISCONNECT_CB_ID :
338
        hpcd->DisconnectCallback = pCallback;
339
        break;
340
 
341
      case HAL_PCD_MSPINIT_CB_ID :
342
        hpcd->MspInitCallback = pCallback;
343
        break;
344
 
345
      case HAL_PCD_MSPDEINIT_CB_ID :
346
        hpcd->MspDeInitCallback = pCallback;
347
        break;
348
 
349
      default :
350
        /* Update the error code */
351
        hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
352
        /* Return error status */
353
        status =  HAL_ERROR;
354
        break;
355
    }
356
  }
357
  else if (hpcd->State == HAL_PCD_STATE_RESET)
358
  {
359
    switch (CallbackID)
360
    {
361
      case HAL_PCD_MSPINIT_CB_ID :
362
        hpcd->MspInitCallback = pCallback;
363
        break;
364
 
365
      case HAL_PCD_MSPDEINIT_CB_ID :
366
        hpcd->MspDeInitCallback = pCallback;
367
        break;
368
 
369
      default :
370
        /* Update the error code */
371
        hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
372
        /* Return error status */
373
        status =  HAL_ERROR;
374
        break;
375
    }
376
  }
377
  else
378
  {
379
    /* Update the error code */
380
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
381
    /* Return error status */
382
    status =  HAL_ERROR;
383
  }
384
 
385
  /* Release Lock */
386
  __HAL_UNLOCK(hpcd);
387
  return status;
388
}
389
 
390
/**
391
  * @brief  Unregister an USB PCD Callback
392
  *         USB PCD callabck is redirected to the weak predefined callback
393
  * @param  hpcd USB PCD handle
394
  * @param  CallbackID ID of the callback to be unregistered
395
  *         This parameter can be one of the following values:
396
  *          @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
397
  *          @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
398
  *          @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
399
  *          @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
400
  *          @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
401
  *          @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
402
  *          @arg @ref HAL_PCD_DISCONNECT_CB_ID OTG PCD Disconnect callback ID
403
  *          @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
404
  *          @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
405
  * @retval HAL status
406
  */
407
HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID)
408
{
409
  HAL_StatusTypeDef status = HAL_OK;
410
 
411
  /* Process locked */
412
  __HAL_LOCK(hpcd);
413
 
414
  /* Setup Legacy weak Callbacks  */
415
  if (hpcd->State == HAL_PCD_STATE_READY)
416
  {
417
    switch (CallbackID)
418
    {
419
      case HAL_PCD_SOF_CB_ID :
420
        hpcd->SOFCallback = HAL_PCD_SOFCallback;
421
        break;
422
 
423
      case HAL_PCD_SETUPSTAGE_CB_ID :
424
        hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
425
        break;
426
 
427
      case HAL_PCD_RESET_CB_ID :
428
        hpcd->ResetCallback = HAL_PCD_ResetCallback;
429
        break;
430
 
431
      case HAL_PCD_SUSPEND_CB_ID :
432
        hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
433
        break;
434
 
435
      case HAL_PCD_RESUME_CB_ID :
436
        hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
437
        break;
438
 
439
      case HAL_PCD_CONNECT_CB_ID :
440
        hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
441
        break;
442
 
443
      case HAL_PCD_DISCONNECT_CB_ID :
444
        hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
445
        break;
446
 
447
      case HAL_PCD_MSPINIT_CB_ID :
448
        hpcd->MspInitCallback = HAL_PCD_MspInit;
449
        break;
450
 
451
      case HAL_PCD_MSPDEINIT_CB_ID :
452
        hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
453
        break;
454
 
455
      default :
456
        /* Update the error code */
457
        hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
458
 
459
        /* Return error status */
460
        status =  HAL_ERROR;
461
        break;
462
    }
463
  }
464
  else if (hpcd->State == HAL_PCD_STATE_RESET)
465
  {
466
    switch (CallbackID)
467
    {
468
      case HAL_PCD_MSPINIT_CB_ID :
469
        hpcd->MspInitCallback = HAL_PCD_MspInit;
470
        break;
471
 
472
      case HAL_PCD_MSPDEINIT_CB_ID :
473
        hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
474
        break;
475
 
476
      default :
477
        /* Update the error code */
478
        hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
479
 
480
        /* Return error status */
481
        status =  HAL_ERROR;
482
        break;
483
    }
484
  }
485
  else
486
  {
487
    /* Update the error code */
488
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
489
 
490
    /* Return error status */
491
    status =  HAL_ERROR;
492
  }
493
 
494
  /* Release Lock */
495
  __HAL_UNLOCK(hpcd);
496
  return status;
497
}
498
 
499
/**
500
  * @brief  Register USB PCD Data OUT Stage Callback
501
  *         To be used instead of the weak HAL_PCD_DataOutStageCallback() predefined callback
502
  * @param  hpcd PCD handle
503
  * @param  pCallback pointer to the USB PCD Data OUT Stage Callback function
504
  * @retval HAL status
505
  */
506
HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd, pPCD_DataOutStageCallbackTypeDef pCallback)
507
{
508
  HAL_StatusTypeDef status = HAL_OK;
509
 
510
  if (pCallback == NULL)
511
  {
512
    /* Update the error code */
513
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
514
 
515
    return HAL_ERROR;
516
  }
517
 
518
  /* Process locked */
519
  __HAL_LOCK(hpcd);
520
 
521
  if (hpcd->State == HAL_PCD_STATE_READY)
522
  {
523
    hpcd->DataOutStageCallback = pCallback;
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
 
537
  return status;
538
}
539
 
540
/**
541
  * @brief  UnRegister the USB PCD Data OUT Stage Callback
542
  *         USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataOutStageCallback() predefined callback
543
  * @param  hpcd PCD handle
544
  * @retval HAL status
545
  */
546
HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd)
547
{
548
  HAL_StatusTypeDef status = HAL_OK;
549
 
550
  /* Process locked */
551
  __HAL_LOCK(hpcd);
552
 
553
  if (hpcd->State == HAL_PCD_STATE_READY)
554
  {
555
    hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback; /* Legacy weak DataOutStageCallback  */
556
  }
557
  else
558
  {
559
    /* Update the error code */
560
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
561
 
562
    /* Return error status */
563
    status =  HAL_ERROR;
564
  }
565
 
566
  /* Release Lock */
567
  __HAL_UNLOCK(hpcd);
568
 
569
  return status;
570
}
571
 
572
/**
573
  * @brief  Register USB PCD Data IN Stage Callback
574
  *         To be used instead of the weak HAL_PCD_DataInStageCallback() predefined callback
575
  * @param  hpcd PCD handle
576
  * @param  pCallback pointer to the USB PCD Data IN Stage Callback function
577
  * @retval HAL status
578
  */
579
HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd, pPCD_DataInStageCallbackTypeDef pCallback)
580
{
581
  HAL_StatusTypeDef status = HAL_OK;
582
 
583
  if (pCallback == NULL)
584
  {
585
    /* Update the error code */
586
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
587
 
588
    return HAL_ERROR;
589
  }
590
 
591
  /* Process locked */
592
  __HAL_LOCK(hpcd);
593
 
594
  if (hpcd->State == HAL_PCD_STATE_READY)
595
  {
596
    hpcd->DataInStageCallback = pCallback;
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  UnRegister the USB PCD Data IN Stage Callback
615
  *         USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataInStageCallback() predefined callback
616
  * @param  hpcd PCD handle
617
  * @retval HAL status
618
  */
619
HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd)
620
{
621
  HAL_StatusTypeDef status = HAL_OK;
622
 
623
  /* Process locked */
624
  __HAL_LOCK(hpcd);
625
 
626
  if (hpcd->State == HAL_PCD_STATE_READY)
627
  {
628
    hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; /* Legacy weak DataInStageCallback  */
629
  }
630
  else
631
  {
632
    /* Update the error code */
633
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
634
 
635
    /* Return error status */
636
    status =  HAL_ERROR;
637
  }
638
 
639
  /* Release Lock */
640
  __HAL_UNLOCK(hpcd);
641
 
642
  return status;
643
}
644
 
645
/**
646
  * @brief  Register USB PCD Iso OUT incomplete Callback
647
  *         To be used instead of the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
648
  * @param  hpcd PCD handle
649
  * @param  pCallback pointer to the USB PCD Iso OUT incomplete Callback function
650
  * @retval HAL status
651
  */
652
HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd, pPCD_IsoOutIncpltCallbackTypeDef pCallback)
653
{
654
  HAL_StatusTypeDef status = HAL_OK;
655
 
656
  if (pCallback == NULL)
657
  {
658
    /* Update the error code */
659
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
660
 
661
    return HAL_ERROR;
662
  }
663
 
664
  /* Process locked */
665
  __HAL_LOCK(hpcd);
666
 
667
  if (hpcd->State == HAL_PCD_STATE_READY)
668
  {
669
    hpcd->ISOOUTIncompleteCallback = pCallback;
670
  }
671
  else
672
  {
673
    /* Update the error code */
674
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
675
 
676
    /* Return error status */
677
    status =  HAL_ERROR;
678
  }
679
 
680
  /* Release Lock */
681
  __HAL_UNLOCK(hpcd);
682
 
683
  return status;
684
}
685
 
686
/**
687
  * @brief  UnRegister the USB PCD Iso OUT incomplete Callback
688
  *         USB PCD Iso OUT incomplete Callback is redirected to the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
689
  * @param  hpcd PCD handle
690
  * @retval HAL status
691
  */
692
HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd)
693
{
694
  HAL_StatusTypeDef status = HAL_OK;
695
 
696
  /* Process locked */
697
  __HAL_LOCK(hpcd);
698
 
699
  if (hpcd->State == HAL_PCD_STATE_READY)
700
  {
701
    hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; /* Legacy weak ISOOUTIncompleteCallback  */
702
  }
703
  else
704
  {
705
    /* Update the error code */
706
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
707
 
708
    /* Return error status */
709
    status =  HAL_ERROR;
710
  }
711
 
712
  /* Release Lock */
713
  __HAL_UNLOCK(hpcd);
714
 
715
  return status;
716
}
717
 
718
/**
719
  * @brief  Register USB PCD Iso IN incomplete Callback
720
  *         To be used instead of the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
721
  * @param  hpcd PCD handle
722
  * @param  pCallback pointer to the USB PCD Iso IN incomplete Callback function
723
  * @retval HAL status
724
  */
725
HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd, pPCD_IsoInIncpltCallbackTypeDef pCallback)
726
{
727
  HAL_StatusTypeDef status = HAL_OK;
728
 
729
  if (pCallback == NULL)
730
  {
731
    /* Update the error code */
732
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
733
 
734
    return HAL_ERROR;
735
  }
736
 
737
  /* Process locked */
738
  __HAL_LOCK(hpcd);
739
 
740
  if (hpcd->State == HAL_PCD_STATE_READY)
741
  {
742
    hpcd->ISOINIncompleteCallback = pCallback;
743
  }
744
  else
745
  {
746
    /* Update the error code */
747
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
748
 
749
    /* Return error status */
750
    status =  HAL_ERROR;
751
  }
752
 
753
  /* Release Lock */
754
  __HAL_UNLOCK(hpcd);
755
 
756
  return status;
757
}
758
 
759
/**
760
  * @brief  UnRegister the USB PCD Iso IN incomplete Callback
761
  *         USB PCD Iso IN incomplete Callback is redirected to the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
762
  * @param  hpcd PCD handle
763
  * @retval HAL status
764
  */
765
HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd)
766
{
767
  HAL_StatusTypeDef status = HAL_OK;
768
 
769
  /* Process locked */
770
  __HAL_LOCK(hpcd);
771
 
772
  if (hpcd->State == HAL_PCD_STATE_READY)
773
  {
774
    hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; /* Legacy weak ISOINIncompleteCallback  */
775
  }
776
  else
777
  {
778
    /* Update the error code */
779
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
780
 
781
    /* Return error status */
782
    status =  HAL_ERROR;
783
  }
784
 
785
  /* Release Lock */
786
  __HAL_UNLOCK(hpcd);
787
 
788
  return status;
789
}
790
 
791
/**
792
  * @brief  Register USB PCD BCD Callback
793
  *         To be used instead of the weak HAL_PCDEx_BCD_Callback() predefined callback
794
  * @param  hpcd PCD handle
795
  * @param  pCallback pointer to the USB PCD BCD Callback function
796
  * @retval HAL status
797
  */
798
HAL_StatusTypeDef HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef *hpcd, pPCD_BcdCallbackTypeDef pCallback)
799
{
800
  HAL_StatusTypeDef status = HAL_OK;
801
 
802
  if (pCallback == NULL)
803
  {
804
    /* Update the error code */
805
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
806
 
807
    return HAL_ERROR;
808
  }
809
 
810
  /* Process locked */
811
  __HAL_LOCK(hpcd);
812
 
813
  if (hpcd->State == HAL_PCD_STATE_READY)
814
  {
815
    hpcd->BCDCallback = pCallback;
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
/**
833
  * @brief  UnRegister the USB PCD BCD Callback
834
  *         USB BCD Callback is redirected to the weak HAL_PCDEx_BCD_Callback() predefined callback
835
  * @param  hpcd PCD handle
836
  * @retval HAL status
837
  */
838
HAL_StatusTypeDef HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef *hpcd)
839
{
840
  HAL_StatusTypeDef status = HAL_OK;
841
 
842
  /* Process locked */
843
  __HAL_LOCK(hpcd);
844
 
845
  if (hpcd->State == HAL_PCD_STATE_READY)
846
  {
847
    hpcd->BCDCallback = HAL_PCDEx_BCD_Callback; /* Legacy weak HAL_PCDEx_BCD_Callback  */
848
  }
849
  else
850
  {
851
    /* Update the error code */
852
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
853
 
854
    /* Return error status */
855
    status =  HAL_ERROR;
856
  }
857
 
858
  /* Release Lock */
859
  __HAL_UNLOCK(hpcd);
860
 
861
  return status;
862
}
863
 
864
/**
865
  * @brief  Register USB PCD LPM Callback
866
  *         To be used instead of the weak HAL_PCDEx_LPM_Callback() predefined callback
867
  * @param  hpcd PCD handle
868
  * @param  pCallback pointer to the USB PCD LPM Callback function
869
  * @retval HAL status
870
  */
871
HAL_StatusTypeDef HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef *hpcd, pPCD_LpmCallbackTypeDef pCallback)
872
{
873
  HAL_StatusTypeDef status = HAL_OK;
874
 
875
  if (pCallback == NULL)
876
  {
877
    /* Update the error code */
878
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
879
 
880
    return HAL_ERROR;
881
  }
882
 
883
  /* Process locked */
884
  __HAL_LOCK(hpcd);
885
 
886
  if (hpcd->State == HAL_PCD_STATE_READY)
887
  {
888
    hpcd->LPMCallback = pCallback;
889
  }
890
  else
891
  {
892
    /* Update the error code */
893
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
894
 
895
    /* Return error status */
896
    status =  HAL_ERROR;
897
  }
898
 
899
  /* Release Lock */
900
  __HAL_UNLOCK(hpcd);
901
 
902
  return status;
903
}
904
 
905
/**
906
  * @brief  UnRegister the USB PCD LPM Callback
907
  *         USB LPM Callback is redirected to the weak HAL_PCDEx_LPM_Callback() predefined callback
908
  * @param  hpcd PCD handle
909
  * @retval HAL status
910
  */
911
HAL_StatusTypeDef HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef *hpcd)
912
{
913
  HAL_StatusTypeDef status = HAL_OK;
914
 
915
  /* Process locked */
916
  __HAL_LOCK(hpcd);
917
 
918
  if (hpcd->State == HAL_PCD_STATE_READY)
919
  {
920
    hpcd->LPMCallback = HAL_PCDEx_LPM_Callback; /* Legacy weak HAL_PCDEx_LPM_Callback  */
921
  }
922
  else
923
  {
924
    /* Update the error code */
925
    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
926
 
927
    /* Return error status */
928
    status =  HAL_ERROR;
929
  }
930
 
931
  /* Release Lock */
932
  __HAL_UNLOCK(hpcd);
933
 
934
  return status;
935
}
936
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
937
 
938
/**
939
  * @}
940
  */
941
 
942
/** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions
943
 *  @brief   Data transfers functions
944
 *
945
@verbatim
946
 ===============================================================================
947
                      ##### IO operation functions #####
948
 ===============================================================================
949
    [..]
950
    This subsection provides a set of functions allowing to manage the PCD data
951
    transfers.
952
 
953
@endverbatim
954
  * @{
955
  */
956
 
957
/**
958
  * @brief  Start the USB device
959
  * @param  hpcd PCD handle
960
  * @retval HAL status
961
  */
962
HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
963
{
964
  __HAL_LOCK(hpcd);
965
  (void)USB_DevConnect(hpcd->Instance);
966
  __HAL_PCD_ENABLE(hpcd);
967
  __HAL_UNLOCK(hpcd);
968
  return HAL_OK;
969
}
970
 
971
/**
972
  * @brief  Stop the USB device.
973
  * @param  hpcd PCD handle
974
  * @retval HAL status
975
  */
976
HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
977
{
978
  __HAL_LOCK(hpcd);
979
  __HAL_PCD_DISABLE(hpcd);
980
 
981
  (void)USB_StopDevice(hpcd->Instance);
982
 
983
  __HAL_UNLOCK(hpcd);
984
 
985
  return HAL_OK;
986
}
987
 
988
 
989
/**
990
  * @brief  This function handles PCD interrupt request.
991
  * @param  hpcd PCD handle
992
  * @retval HAL status
993
  */
994
void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
995
{
996
  if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_CTR))
997
  {
998
    /* servicing of the endpoint correct transfer interrupt */
999
    /* clear of the CTR flag into the sub */
1000
    (void)PCD_EP_ISR_Handler(hpcd);
1001
  }
1002
 
1003
  if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_RESET))
1004
  {
1005
    __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET);
1006
 
1007
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1008
    hpcd->ResetCallback(hpcd);
1009
#else
1010
    HAL_PCD_ResetCallback(hpcd);
1011
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1012
 
1013
    (void)HAL_PCD_SetAddress(hpcd, 0U);
1014
  }
1015
 
1016
  if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_PMAOVR))
1017
  {
1018
    __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR);
1019
  }
1020
 
1021
  if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_ERR))
1022
  {
1023
    __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR);
1024
  }
1025
 
1026
  if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_WKUP))
1027
  {
1028
    hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_LPMODE);
1029
    hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_FSUSP);
1030
 
1031
    if (hpcd->LPM_State == LPM_L1)
1032
    {
1033
      hpcd->LPM_State = LPM_L0;
1034
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1035
      hpcd->LPMCallback(hpcd, PCD_LPM_L0_ACTIVE);
1036
#else
1037
      HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE);
1038
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1039
    }
1040
 
1041
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1042
    hpcd->ResumeCallback(hpcd);
1043
#else
1044
    HAL_PCD_ResumeCallback(hpcd);
1045
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1046
 
1047
    __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP);
1048
  }
1049
 
1050
  if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_SUSP))
1051
  {
1052
    /* Force low-power mode in the macrocell */
1053
    hpcd->Instance->CNTR |= USB_CNTR_FSUSP;
1054
 
1055
    /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
1056
    __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP);
1057
 
1058
    hpcd->Instance->CNTR |= USB_CNTR_LPMODE;
1059
 
1060
    if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_WKUP) == 0U)
1061
    {
1062
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1063
      hpcd->SuspendCallback(hpcd);
1064
#else
1065
      HAL_PCD_SuspendCallback(hpcd);
1066
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1067
    }
1068
  }
1069
 
1070
  /* Handle LPM Interrupt */
1071
  if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_L1REQ))
1072
  {
1073
    __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_L1REQ);
1074
    if (hpcd->LPM_State == LPM_L0)
1075
    {
1076
      /* Force suspend and low-power mode before going to L1 state*/
1077
      hpcd->Instance->CNTR |= USB_CNTR_LPMODE;
1078
      hpcd->Instance->CNTR |= USB_CNTR_FSUSP;
1079
 
1080
      hpcd->LPM_State = LPM_L1;
1081
      hpcd->BESL = ((uint32_t)hpcd->Instance->LPMCSR & USB_LPMCSR_BESL) >> 2;
1082
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1083
      hpcd->LPMCallback(hpcd, PCD_LPM_L1_ACTIVE);
1084
#else
1085
      HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE);
1086
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1087
    }
1088
    else
1089
    {
1090
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1091
      hpcd->SuspendCallback(hpcd);
1092
#else
1093
      HAL_PCD_SuspendCallback(hpcd);
1094
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1095
    }
1096
  }
1097
 
1098
  if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_SOF))
1099
  {
1100
    __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF);
1101
 
1102
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1103
    hpcd->SOFCallback(hpcd);
1104
#else
1105
    HAL_PCD_SOFCallback(hpcd);
1106
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1107
  }
1108
 
1109
  if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_ESOF))
1110
  {
1111
    /* clear ESOF flag in ISTR */
1112
    __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF);
1113
  }
1114
}
1115
 
1116
 
1117
/**
1118
  * @brief  Data OUT stage callback.
1119
  * @param  hpcd PCD handle
1120
  * @param  epnum endpoint number
1121
  * @retval None
1122
  */
1123
__weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1124
{
1125
  /* Prevent unused argument(s) compilation warning */
1126
  UNUSED(hpcd);
1127
  UNUSED(epnum);
1128
 
1129
  /* NOTE : This function should not be modified, when the callback is needed,
1130
            the HAL_PCD_DataOutStageCallback could be implemented in the user file
1131
   */
1132
}
1133
 
1134
/**
1135
  * @brief  Data IN stage callback
1136
  * @param  hpcd PCD handle
1137
  * @param  epnum endpoint number
1138
  * @retval None
1139
  */
1140
__weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1141
{
1142
  /* Prevent unused argument(s) compilation warning */
1143
  UNUSED(hpcd);
1144
  UNUSED(epnum);
1145
 
1146
  /* NOTE : This function should not be modified, when the callback is needed,
1147
            the HAL_PCD_DataInStageCallback could be implemented in the user file
1148
   */
1149
}
1150
/**
1151
  * @brief  Setup stage callback
1152
  * @param  hpcd PCD handle
1153
  * @retval None
1154
  */
1155
__weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
1156
{
1157
  /* Prevent unused argument(s) compilation warning */
1158
  UNUSED(hpcd);
1159
 
1160
  /* NOTE : This function should not be modified, when the callback is needed,
1161
            the HAL_PCD_SetupStageCallback could be implemented in the user file
1162
   */
1163
}
1164
 
1165
/**
1166
  * @brief  USB Start Of Frame callback.
1167
  * @param  hpcd PCD handle
1168
  * @retval None
1169
  */
1170
__weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
1171
{
1172
  /* Prevent unused argument(s) compilation warning */
1173
  UNUSED(hpcd);
1174
 
1175
  /* NOTE : This function should not be modified, when the callback is needed,
1176
            the HAL_PCD_SOFCallback could be implemented in the user file
1177
   */
1178
}
1179
 
1180
/**
1181
  * @brief  USB Reset callback.
1182
  * @param  hpcd PCD handle
1183
  * @retval None
1184
  */
1185
__weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
1186
{
1187
  /* Prevent unused argument(s) compilation warning */
1188
  UNUSED(hpcd);
1189
 
1190
  /* NOTE : This function should not be modified, when the callback is needed,
1191
            the HAL_PCD_ResetCallback could be implemented in the user file
1192
   */
1193
}
1194
 
1195
/**
1196
  * @brief  Suspend event callback.
1197
  * @param  hpcd PCD handle
1198
  * @retval None
1199
  */
1200
__weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
1201
{
1202
  /* Prevent unused argument(s) compilation warning */
1203
  UNUSED(hpcd);
1204
 
1205
  /* NOTE : This function should not be modified, when the callback is needed,
1206
            the HAL_PCD_SuspendCallback could be implemented in the user file
1207
   */
1208
}
1209
 
1210
/**
1211
  * @brief  Resume event callback.
1212
  * @param  hpcd PCD handle
1213
  * @retval None
1214
  */
1215
__weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
1216
{
1217
  /* Prevent unused argument(s) compilation warning */
1218
  UNUSED(hpcd);
1219
 
1220
  /* NOTE : This function should not be modified, when the callback is needed,
1221
            the HAL_PCD_ResumeCallback could be implemented in the user file
1222
   */
1223
}
1224
 
1225
/**
1226
  * @brief  Incomplete ISO OUT callback.
1227
  * @param  hpcd PCD handle
1228
  * @param  epnum endpoint number
1229
  * @retval None
1230
  */
1231
__weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1232
{
1233
  /* Prevent unused argument(s) compilation warning */
1234
  UNUSED(hpcd);
1235
  UNUSED(epnum);
1236
 
1237
  /* NOTE : This function should not be modified, when the callback is needed,
1238
            the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
1239
   */
1240
}
1241
 
1242
/**
1243
  * @brief  Incomplete ISO IN callback.
1244
  * @param  hpcd PCD handle
1245
  * @param  epnum endpoint number
1246
  * @retval None
1247
  */
1248
__weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1249
{
1250
  /* Prevent unused argument(s) compilation warning */
1251
  UNUSED(hpcd);
1252
  UNUSED(epnum);
1253
 
1254
  /* NOTE : This function should not be modified, when the callback is needed,
1255
            the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
1256
   */
1257
}
1258
 
1259
/**
1260
  * @brief  Connection event callback.
1261
  * @param  hpcd PCD handle
1262
  * @retval None
1263
  */
1264
__weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
1265
{
1266
  /* Prevent unused argument(s) compilation warning */
1267
  UNUSED(hpcd);
1268
 
1269
  /* NOTE : This function should not be modified, when the callback is needed,
1270
            the HAL_PCD_ConnectCallback could be implemented in the user file
1271
   */
1272
}
1273
 
1274
/**
1275
  * @brief  Disconnection event callback.
1276
  * @param  hpcd PCD handle
1277
  * @retval None
1278
  */
1279
__weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
1280
{
1281
  /* Prevent unused argument(s) compilation warning */
1282
  UNUSED(hpcd);
1283
 
1284
  /* NOTE : This function should not be modified, when the callback is needed,
1285
            the HAL_PCD_DisconnectCallback could be implemented in the user file
1286
   */
1287
}
1288
 
1289
/**
1290
  * @}
1291
  */
1292
 
1293
/** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
1294
 *  @brief   management functions
1295
 *
1296
@verbatim
1297
 ===============================================================================
1298
                      ##### Peripheral Control functions #####
1299
 ===============================================================================
1300
    [..]
1301
    This subsection provides a set of functions allowing to control the PCD data
1302
    transfers.
1303
 
1304
@endverbatim
1305
  * @{
1306
  */
1307
 
1308
/**
1309
  * @brief  Connect the USB device
1310
  * @param  hpcd PCD handle
1311
  * @retval HAL status
1312
  */
1313
HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
1314
{
1315
  __HAL_LOCK(hpcd);
1316
  (void)USB_DevConnect(hpcd->Instance);
1317
  __HAL_UNLOCK(hpcd);
1318
  return HAL_OK;
1319
}
1320
 
1321
/**
1322
  * @brief  Disconnect the USB device.
1323
  * @param  hpcd PCD handle
1324
  * @retval HAL status
1325
  */
1326
HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
1327
{
1328
  __HAL_LOCK(hpcd);
1329
  (void)USB_DevDisconnect(hpcd->Instance);
1330
  __HAL_UNLOCK(hpcd);
1331
  return HAL_OK;
1332
}
1333
 
1334
/**
1335
  * @brief  Set the USB Device address.
1336
  * @param  hpcd PCD handle
1337
  * @param  address new device address
1338
  * @retval HAL status
1339
  */
1340
HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
1341
{
1342
  __HAL_LOCK(hpcd);
1343
  hpcd->USB_Address = address;
1344
  (void)USB_SetDevAddress(hpcd->Instance, address);
1345
  __HAL_UNLOCK(hpcd);
1346
  return HAL_OK;
1347
}
1348
/**
1349
  * @brief  Open and configure an endpoint.
1350
  * @param  hpcd PCD handle
1351
  * @param  ep_addr endpoint address
1352
  * @param  ep_mps endpoint max packet size
1353
  * @param  ep_type endpoint type
1354
  * @retval HAL status
1355
  */
1356
HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)
1357
{
1358
  HAL_StatusTypeDef  ret = HAL_OK;
1359
  PCD_EPTypeDef *ep;
1360
 
1361
  if ((ep_addr & 0x80U) == 0x80U)
1362
  {
1363
    ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1364
    ep->is_in = 1U;
1365
  }
1366
  else
1367
  {
1368
    ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
1369
    ep->is_in = 0U;
1370
  }
1371
 
1372
  ep->num = ep_addr & EP_ADDR_MSK;
1373
  ep->maxpacket = ep_mps;
1374
  ep->type = ep_type;
1375
 
1376
  if (ep->is_in != 0U)
1377
  {
1378
    /* Assign a Tx FIFO */
1379
    ep->tx_fifo_num = ep->num;
1380
  }
1381
  /* Set initial data PID. */
1382
  if (ep_type == EP_TYPE_BULK)
1383
  {
1384
    ep->data_pid_start = 0U;
1385
  }
1386
 
1387
  __HAL_LOCK(hpcd);
1388
  (void)USB_ActivateEndpoint(hpcd->Instance, ep);
1389
  __HAL_UNLOCK(hpcd);
1390
 
1391
  return ret;
1392
}
1393
 
1394
/**
1395
  * @brief  Deactivate an endpoint.
1396
  * @param  hpcd PCD handle
1397
  * @param  ep_addr endpoint address
1398
  * @retval HAL status
1399
  */
1400
HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1401
{
1402
  PCD_EPTypeDef *ep;
1403
 
1404
  if ((ep_addr & 0x80U) == 0x80U)
1405
  {
1406
    ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1407
    ep->is_in = 1U;
1408
  }
1409
  else
1410
  {
1411
    ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
1412
    ep->is_in = 0U;
1413
  }
1414
  ep->num   = ep_addr & EP_ADDR_MSK;
1415
 
1416
  __HAL_LOCK(hpcd);
1417
  (void)USB_DeactivateEndpoint(hpcd->Instance, ep);
1418
  __HAL_UNLOCK(hpcd);
1419
  return HAL_OK;
1420
}
1421
 
1422
 
1423
/**
1424
  * @brief  Receive an amount of data.
1425
  * @param  hpcd PCD handle
1426
  * @param  ep_addr endpoint address
1427
  * @param  pBuf pointer to the reception buffer
1428
  * @param  len amount of data to be received
1429
  * @retval HAL status
1430
  */
1431
HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
1432
{
1433
  PCD_EPTypeDef *ep;
1434
 
1435
  ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
1436
 
1437
  /*setup and start the Xfer */
1438
  ep->xfer_buff = pBuf;
1439
  ep->xfer_len = len;
1440
  ep->xfer_count = 0U;
1441
  ep->is_in = 0U;
1442
  ep->num = ep_addr & EP_ADDR_MSK;
1443
 
1444
  if ((ep_addr & EP_ADDR_MSK) == 0U)
1445
  {
1446
    (void)USB_EP0StartXfer(hpcd->Instance, ep);
1447
  }
1448
  else
1449
  {
1450
    (void)USB_EPStartXfer(hpcd->Instance, ep);
1451
  }
1452
 
1453
  return HAL_OK;
1454
}
1455
 
1456
/**
1457
  * @brief  Get Received Data Size
1458
  * @param  hpcd PCD handle
1459
  * @param  ep_addr endpoint address
1460
  * @retval Data Size
1461
  */
1462
uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1463
{
1464
  return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count;
1465
}
1466
/**
1467
  * @brief  Send an amount of data
1468
  * @param  hpcd PCD handle
1469
  * @param  ep_addr endpoint address
1470
  * @param  pBuf pointer to the transmission buffer
1471
  * @param  len amount of data to be sent
1472
  * @retval HAL status
1473
  */
1474
HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
1475
{
1476
  PCD_EPTypeDef *ep;
1477
 
1478
  ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1479
 
1480
  /*setup and start the Xfer */
1481
  ep->xfer_buff = pBuf;
1482
  ep->xfer_len = len;
1483
  ep->xfer_count = 0U;
1484
  ep->is_in = 1U;
1485
  ep->num = ep_addr & EP_ADDR_MSK;
1486
 
1487
  if ((ep_addr & EP_ADDR_MSK) == 0U)
1488
  {
1489
    (void)USB_EP0StartXfer(hpcd->Instance, ep);
1490
  }
1491
  else
1492
  {
1493
    (void)USB_EPStartXfer(hpcd->Instance, ep);
1494
  }
1495
 
1496
  return HAL_OK;
1497
}
1498
 
1499
/**
1500
  * @brief  Set a STALL condition over an endpoint
1501
  * @param  hpcd PCD handle
1502
  * @param  ep_addr endpoint address
1503
  * @retval HAL status
1504
  */
1505
HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1506
{
1507
  PCD_EPTypeDef *ep;
1508
 
1509
  if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.dev_endpoints)
1510
  {
1511
    return HAL_ERROR;
1512
  }
1513
 
1514
  if ((0x80U & ep_addr) == 0x80U)
1515
  {
1516
    ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1517
    ep->is_in = 1U;
1518
  }
1519
  else
1520
  {
1521
    ep = &hpcd->OUT_ep[ep_addr];
1522
    ep->is_in = 0U;
1523
  }
1524
 
1525
  ep->is_stall = 1U;
1526
  ep->num = ep_addr & EP_ADDR_MSK;
1527
 
1528
  __HAL_LOCK(hpcd);
1529
 
1530
  (void)USB_EPSetStall(hpcd->Instance, ep);
1531
  if ((ep_addr & EP_ADDR_MSK) == 0U)
1532
  {
1533
    (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
1534
  }
1535
  __HAL_UNLOCK(hpcd);
1536
 
1537
  return HAL_OK;
1538
}
1539
 
1540
/**
1541
  * @brief  Clear a STALL condition over in an endpoint
1542
  * @param  hpcd PCD handle
1543
  * @param  ep_addr endpoint address
1544
  * @retval HAL status
1545
  */
1546
HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1547
{
1548
  PCD_EPTypeDef *ep;
1549
 
1550
  if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints)
1551
  {
1552
    return HAL_ERROR;
1553
  }
1554
 
1555
  if ((0x80U & ep_addr) == 0x80U)
1556
  {
1557
    ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1558
    ep->is_in = 1U;
1559
  }
1560
  else
1561
  {
1562
    ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
1563
    ep->is_in = 0U;
1564
  }
1565
 
1566
  ep->is_stall = 0U;
1567
  ep->num = ep_addr & EP_ADDR_MSK;
1568
 
1569
  __HAL_LOCK(hpcd);
1570
  (void)USB_EPClearStall(hpcd->Instance, ep);
1571
  __HAL_UNLOCK(hpcd);
1572
 
1573
  return HAL_OK;
1574
}
1575
 
1576
/**
1577
  * @brief  Flush an endpoint
1578
  * @param  hpcd PCD handle
1579
  * @param  ep_addr endpoint address
1580
  * @retval HAL status
1581
  */
1582
HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1583
{
1584
  /* Prevent unused argument(s) compilation warning */
1585
  UNUSED(hpcd);
1586
  UNUSED(ep_addr);
1587
 
1588
  return HAL_OK;
1589
}
1590
 
1591
/**
1592
  * @brief  Activate remote wakeup signalling
1593
  * @param  hpcd PCD handle
1594
  * @retval HAL status
1595
  */
1596
HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
1597
{
1598
  return (USB_ActivateRemoteWakeup(hpcd->Instance));
1599
}
1600
 
1601
/**
1602
  * @brief  De-activate remote wakeup signalling.
1603
  * @param  hpcd PCD handle
1604
  * @retval HAL status
1605
  */
1606
HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
1607
{
1608
  return (USB_DeActivateRemoteWakeup(hpcd->Instance));
1609
}
1610
 
1611
/**
1612
  * @}
1613
  */
1614
 
1615
/** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
1616
 *  @brief   Peripheral State functions
1617
 *
1618
@verbatim
1619
 ===============================================================================
1620
                      ##### Peripheral State functions #####
1621
 ===============================================================================
1622
    [..]
1623
    This subsection permits to get in run-time the status of the peripheral
1624
    and the data flow.
1625
 
1626
@endverbatim
1627
  * @{
1628
  */
1629
 
1630
/**
1631
  * @brief  Return the PCD handle state.
1632
  * @param  hpcd PCD handle
1633
  * @retval HAL state
1634
  */
1635
PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd)
1636
{
1637
  return hpcd->State;
1638
}
1639
 
1640
/**
1641
  * @}
1642
  */
1643
 
1644
/**
1645
  * @}
1646
  */
1647
 
1648
/* Private functions ---------------------------------------------------------*/
1649
/** @addtogroup PCD_Private_Functions
1650
  * @{
1651
  */
1652
 
1653
 
1654
/**
1655
  * @brief  This function handles PCD Endpoint interrupt request.
1656
  * @param  hpcd PCD handle
1657
  * @retval HAL status
1658
  */
1659
static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
1660
{
1661
  PCD_EPTypeDef *ep;
1662
  uint16_t count;
1663
  uint16_t wIstr;
1664
  uint16_t wEPVal;
1665
  uint8_t epindex;
1666
 
1667
  /* stay in loop while pending interrupts */
1668
  while ((hpcd->Instance->ISTR & USB_ISTR_CTR) != 0U)
1669
  {
1670
    wIstr = hpcd->Instance->ISTR;
1671
    /* extract highest priority endpoint number */
1672
    epindex = (uint8_t)(wIstr & USB_ISTR_EP_ID);
1673
 
1674
    if (epindex == 0U)
1675
    {
1676
      /* Decode and service control endpoint interrupt */
1677
 
1678
      /* DIR bit = origin of the interrupt */
1679
      if ((wIstr & USB_ISTR_DIR) == 0U)
1680
      {
1681
        /* DIR = 0 */
1682
 
1683
        /* DIR = 0      => IN  int */
1684
        /* DIR = 0 implies that (EP_CTR_TX = 1) always  */
1685
        PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0);
1686
        ep = &hpcd->IN_ep[0];
1687
 
1688
        ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
1689
        ep->xfer_buff += ep->xfer_count;
1690
 
1691
        /* TX COMPLETE */
1692
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1693
        hpcd->DataInStageCallback(hpcd, 0U);
1694
#else
1695
        HAL_PCD_DataInStageCallback(hpcd, 0U);
1696
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1697
 
1698
        if ((hpcd->USB_Address > 0U) && (ep->xfer_len == 0U))
1699
        {
1700
          hpcd->Instance->DADDR = ((uint16_t)hpcd->USB_Address | USB_DADDR_EF);
1701
          hpcd->USB_Address = 0U;
1702
        }
1703
      }
1704
      else
1705
      {
1706
        /* DIR = 1 */
1707
 
1708
        /* DIR = 1 & CTR_RX       => SETUP or OUT int */
1709
        /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
1710
        ep = &hpcd->OUT_ep[0];
1711
        wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0);
1712
 
1713
        if ((wEPVal & USB_EP_SETUP) != 0U)
1714
        {
1715
          /* Get SETUP Packet*/
1716
          ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
1717
 
1718
          USB_ReadPMA(hpcd->Instance, (uint8_t *)hpcd->Setup,
1719
                      ep->pmaadress, (uint16_t)ep->xfer_count);
1720
 
1721
          /* SETUP bit kept frozen while CTR_RX = 1*/
1722
          PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
1723
 
1724
          /* Process SETUP Packet*/
1725
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1726
          hpcd->SetupStageCallback(hpcd);
1727
#else
1728
          HAL_PCD_SetupStageCallback(hpcd);
1729
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1730
        }
1731
 
1732
        else if ((wEPVal & USB_EP_CTR_RX) != 0U)
1733
        {
1734
          PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
1735
 
1736
          /* Get Control Data OUT Packet*/
1737
          ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
1738
 
1739
          if ((ep->xfer_count != 0U) && (ep->xfer_buff != 0U))
1740
          {
1741
            USB_ReadPMA(hpcd->Instance, ep->xfer_buff,
1742
                        ep->pmaadress, (uint16_t)ep->xfer_count);
1743
 
1744
            ep->xfer_buff += ep->xfer_count;
1745
 
1746
            /* Process Control Data OUT Packet*/
1747
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1748
            hpcd->DataOutStageCallback(hpcd, 0U);
1749
#else
1750
            HAL_PCD_DataOutStageCallback(hpcd, 0U);
1751
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1752
          }
1753
 
1754
          PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket);
1755
          PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID);
1756
        }
1757
      }
1758
    }
1759
    else
1760
    {
1761
      /* Decode and service non control endpoints interrupt  */
1762
 
1763
      /* process related endpoint register */
1764
      wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, epindex);
1765
      if ((wEPVal & USB_EP_CTR_RX) != 0U)
1766
      {
1767
        /* clear int flag */
1768
        PCD_CLEAR_RX_EP_CTR(hpcd->Instance, epindex);
1769
        ep = &hpcd->OUT_ep[epindex];
1770
 
1771
        /* OUT double Buffering*/
1772
        if (ep->doublebuffer == 0U)
1773
        {
1774
          count = (uint16_t)PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
1775
          if (count != 0U)
1776
          {
1777
            USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count);
1778
          }
1779
        }
1780
        else
1781
        {
1782
          if ((PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_RX) != 0U)
1783
          {
1784
            /*read from endpoint BUF0Addr buffer*/
1785
            count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
1786
            if (count != 0U)
1787
            {
1788
              USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
1789
            }
1790
          }
1791
          else
1792
          {
1793
            /*read from endpoint BUF1Addr buffer*/
1794
            count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
1795
            if (count != 0U)
1796
            {
1797
              USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
1798
            }
1799
          }
1800
          /* free EP OUT Buffer */
1801
          PCD_FreeUserBuffer(hpcd->Instance, ep->num, 0U);
1802
        }
1803
        /*multi-packet on the NON control OUT endpoint*/
1804
        ep->xfer_count += count;
1805
        ep->xfer_buff += count;
1806
 
1807
        if ((ep->xfer_len == 0U) || (count < ep->maxpacket))
1808
        {
1809
          /* RX COMPLETE */
1810
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1811
          hpcd->DataOutStageCallback(hpcd, ep->num);
1812
#else
1813
          HAL_PCD_DataOutStageCallback(hpcd, ep->num);
1814
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1815
        }
1816
        else
1817
        {
1818
          (void)HAL_PCD_EP_Receive(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
1819
        }
1820
 
1821
      } /* if((wEPVal & EP_CTR_RX) */
1822
 
1823
      if ((wEPVal & USB_EP_CTR_TX) != 0U)
1824
      {
1825
        ep = &hpcd->IN_ep[epindex];
1826
 
1827
        /* clear int flag */
1828
        PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex);
1829
 
1830
        /*multi-packet on the NON control IN endpoint*/
1831
        ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
1832
        ep->xfer_buff += ep->xfer_count;
1833
 
1834
        /* Zero Length Packet? */
1835
        if (ep->xfer_len == 0U)
1836
        {
1837
          /* TX COMPLETE */
1838
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1839
          hpcd->DataInStageCallback(hpcd, ep->num);
1840
#else
1841
          HAL_PCD_DataInStageCallback(hpcd, ep->num);
1842
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1843
        }
1844
        else
1845
        {
1846
          (void)HAL_PCD_EP_Transmit(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
1847
        }
1848
      }
1849
    }
1850
  }
1851
  return HAL_OK;
1852
}
1853
 
1854
 
1855
/**
1856
  * @}
1857
  */
1858
#endif /* defined (USB) */
1859
#endif /* HAL_PCD_MODULE_ENABLED */
1860
 
1861
/**
1862
  * @}
1863
  */
1864
 
1865
/**
1866
  * @}
1867
  */
1868
 
1869
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/