Subversion Repositories LedShow

Rev

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

Rev Author Line No. Line
2 mjames 1
/**
2
  ******************************************************************************
3
  * @file    stm32f1xx_hal_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 HCD 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 the following macro
29
              (+++) __HAL_RCC_USB_CLK_ENABLE(); For USB Device FS peripheral available
30
                    on STM32F102xx and STM32F103xx devices
31
              (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); For USB OTG FS peripheral available
32
                    on STM32F105xx and STM32F107xx devices
33
 
34
         (##) Initialize the related GPIO clocks
35
         (##) Configure PCD pin-out
36
         (##) Configure PCD NVIC interrupt
37
 
38
     (#)Associate the Upper USB device stack to the HAL PCD Driver:
39
         (##) hpcd.pData = pdev;
40
 
41
     (#)Enable HCD transmission and reception:
42
         (##) HAL_PCD_Start();
43
 
44
  @endverbatim
45
  ******************************************************************************
46
  * @attention
47
  *
48
  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
49
  *
50
  * Redistribution and use in source and binary forms, with or without modification,
51
  * are permitted provided that the following conditions are met:
52
  *   1. Redistributions of source code must retain the above copyright notice,
53
  *      this list of conditions and the following disclaimer.
54
  *   2. Redistributions in binary form must reproduce the above copyright notice,
55
  *      this list of conditions and the following disclaimer in the documentation
56
  *      and/or other materials provided with the distribution.
57
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
58
  *      may be used to endorse or promote products derived from this software
59
  *      without specific prior written permission.
60
  *
61
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
62
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
63
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
65
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
66
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
67
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
68
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
69
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
70
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
71
  *
72
  ******************************************************************************
73
  */
74
 
75
/* Includes ------------------------------------------------------------------*/
76
#include "stm32f1xx_hal.h"
77
 
78
/** @addtogroup STM32F1xx_HAL_Driver
79
  * @{
80
  */
81
 
82
 
83
 
84
#ifdef HAL_PCD_MODULE_ENABLED
85
 
86
#if defined(STM32F102x6) || defined(STM32F102xB) || \
87
    defined(STM32F103x6) || defined(STM32F103xB) || \
88
    defined(STM32F103xE) || defined(STM32F103xG) || \
89
    defined(STM32F105xC) || defined(STM32F107xC)
90
 
91
/** @defgroup PCD PCD
92
  * @brief PCD HAL module driver
93
  * @{
94
  */
95
 
96
/* Private types -------------------------------------------------------------*/
97
/* Private variables ---------------------------------------------------------*/
98
/* Private constants ---------------------------------------------------------*/
99
/* Private macros ------------------------------------------------------------*/
100
/** @defgroup PCD_Private_Macros PCD Private Macros
101
  * @{
102
  */
103
#define PCD_MIN(a, b)  (((a) < (b)) ? (a) : (b))
104
#define PCD_MAX(a, b)  (((a) > (b)) ? (a) : (b))
105
/**
106
  * @}
107
  */
108
 
109
/* Private functions ---------------------------------------------------------*/
110
/** @defgroup PCD_Private_Functions PCD Private Functions
111
  * @{
112
  */
113
#if defined (USB_OTG_FS)
114
static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum);
115
#endif /* USB_OTG_FS */
116
 
117
#if defined (USB)
118
static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd);
119
#endif /* USB */
120
/**
121
  * @}
122
  */
123
 
124
/* Exported functions --------------------------------------------------------*/
125
/** @defgroup PCD_Exported_Functions PCD Exported Functions
126
  * @{
127
  */
128
 
129
/** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
130
 *  @brief    Initialization and Configuration functions
131
 *
132
@verbatim
133
 ===============================================================================
134
            ##### Initialization and de-initialization functions #####
135
 ===============================================================================
136
    [..]  This section provides functions allowing to:
137
 
138
@endverbatim
139
  * @{
140
  */
141
 
142
/**
143
  * @brief  Initializes the PCD according to the specified
144
  *         parameters in the PCD_InitTypeDef and create the associated handle.
145
  * @param  hpcd: PCD handle
146
  * @retval HAL status
147
  */
148
HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
149
{
150
  uint32_t index = 0U;
151
 
152
  /* Check the PCD handle allocation */
153
  if(hpcd == NULL)
154
  {
155
    return HAL_ERROR;
156
  }
157
 
158
  /* Check the parameters */
159
  assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));
160
 
161
  if(hpcd->State == HAL_PCD_STATE_RESET)
162
  {  
163
    /* Allocate lock resource and initialize it */
164
    hpcd->Lock = HAL_UNLOCKED;
165
 
166
    /* Init the low level hardware : GPIO, CLOCK, NVIC... */
167
    HAL_PCD_MspInit(hpcd);
168
  }
169
 
170
  hpcd->State = HAL_PCD_STATE_BUSY;
171
 
172
  /* Disable the Interrupts */
173
  __HAL_PCD_DISABLE(hpcd);
174
 
175
  /*Init the Core (common init.) */
176
  USB_CoreInit(hpcd->Instance, hpcd->Init);
177
 
178
  /* Force Device Mode*/
179
  USB_SetCurrentMode(hpcd->Instance , USB_DEVICE_MODE);
180
 
181
  /* Init endpoints structures */
182
  for (index = 0U; index < 15U ; index++)
183
  {
184
    /* Init ep structure */
185
    hpcd->IN_ep[index].is_in = 1U;
186
    hpcd->IN_ep[index].num = index;
187
    hpcd->IN_ep[index].tx_fifo_num = index;
188
    /* Control until ep is actvated */
189
    hpcd->IN_ep[index].type = EP_TYPE_CTRL;
190
    hpcd->IN_ep[index].maxpacket =  0U;
191
    hpcd->IN_ep[index].xfer_buff = 0U;
192
    hpcd->IN_ep[index].xfer_len = 0U;
193
  }
194
 
195
  for (index = 0U; index < 15U ; index++)
196
  {
197
    hpcd->OUT_ep[index].is_in = 0U;
198
    hpcd->OUT_ep[index].num = index;
199
    hpcd->IN_ep[index].tx_fifo_num = index;
200
    /* Control until ep is activated */
201
    hpcd->OUT_ep[index].type = EP_TYPE_CTRL;
202
    hpcd->OUT_ep[index].maxpacket = 0U;
203
    hpcd->OUT_ep[index].xfer_buff = 0U;
204
    hpcd->OUT_ep[index].xfer_len = 0U;
205
  }
206
 
207
  /* Init Device */
208
  USB_DevInit(hpcd->Instance, hpcd->Init);
209
 
210
  hpcd->USB_Address = 0U;
211
  hpcd->State= HAL_PCD_STATE_READY;
212
 
213
  USB_DevDisconnect (hpcd->Instance);  
214
  return HAL_OK;
215
}
216
 
217
/**
218
  * @brief  DeInitializes the PCD peripheral
219
  * @param  hpcd: PCD handle
220
  * @retval HAL status
221
  */
222
HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
223
{
224
  /* Check the PCD handle allocation */
225
  if(hpcd == NULL)
226
  {
227
    return HAL_ERROR;
228
  }
229
 
230
  hpcd->State = HAL_PCD_STATE_BUSY;
231
 
232
  /* Stop Device */
233
  HAL_PCD_Stop(hpcd);
234
 
235
  /* DeInit the low level hardware */
236
  HAL_PCD_MspDeInit(hpcd);
237
 
238
  hpcd->State = HAL_PCD_STATE_RESET;
239
 
240
  return HAL_OK;
241
}
242
 
243
/**
244
  * @brief  Initializes the PCD MSP.
245
  * @param  hpcd: PCD handle
246
  * @retval None
247
  */
248
__weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
249
{
250
  /* Prevent unused argument(s) compilation warning */
251
  UNUSED(hpcd);
252
  /* NOTE : This function should not be modified, when the callback is needed,
253
            the HAL_PCD_MspInit could be implemented in the user file
254
   */
255
}
256
 
257
/**
258
  * @brief  DeInitializes PCD MSP.
259
  * @param  hpcd: PCD handle
260
  * @retval None
261
  */
262
__weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
263
{
264
  /* Prevent unused argument(s) compilation warning */
265
  UNUSED(hpcd);
266
  /* NOTE : This function should not be modified, when the callback is needed,
267
            the HAL_PCD_MspDeInit could be implemented in the user file
268
   */
269
}
270
 
271
/**
272
  * @}
273
  */
274
 
275
/** @defgroup PCD_Exported_Functions_Group2 IO operation functions
276
 *  @brief   Data transfers functions
277
 *
278
@verbatim
279
 ===============================================================================
280
                      ##### IO operation functions #####
281
 ===============================================================================
282
    [..]
283
    This subsection provides a set of functions allowing to manage the PCD data
284
    transfers.
285
 
286
@endverbatim
287
  * @{
288
  */
289
 
290
/**
291
  * @brief  Start The USB Device.
292
  * @param  hpcd: PCD handle
293
  * @retval HAL status
294
  */
295
HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
296
{
297
  __HAL_LOCK(hpcd);
298
  HAL_PCDEx_SetConnectionState (hpcd, 1);
299
  USB_DevConnect (hpcd->Instance);
300
  __HAL_PCD_ENABLE(hpcd);
301
  __HAL_UNLOCK(hpcd);
302
  return HAL_OK;
303
}
304
 
305
/**
306
  * @brief  Stop The USB Device.
307
  * @param  hpcd: PCD handle
308
  * @retval HAL status
309
  */
310
HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
311
{
312
  __HAL_LOCK(hpcd);
313
  __HAL_PCD_DISABLE(hpcd);
314
  USB_StopDevice(hpcd->Instance);
315
  USB_DevDisconnect (hpcd->Instance);
316
  __HAL_UNLOCK(hpcd);
317
  return HAL_OK;
318
}
319
 
320
#if defined (USB_OTG_FS)
321
/**
322
  * @brief  This function handles PCD interrupt request.
323
  * @param  hpcd: PCD handle
324
  * @retval HAL status
325
  */
326
void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
327
{
328
  USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
329
  uint32_t index = 0U, ep_intr = 0U, epint = 0U, epnum = 0U;
330
  uint32_t fifoemptymsk = 0U, temp = 0U;
331
  USB_OTG_EPTypeDef *ep = NULL;
332
 
333
  /* ensure that we are in device mode */
334
  if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)
335
  {
336
    /* avoid spurious interrupt */
337
    if(__HAL_PCD_IS_INVALID_INTERRUPT(hpcd))
338
    {
339
      return;
340
    }
341
 
342
    if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))
343
    {
344
     /* incorrect mode, acknowledge the interrupt */
345
      __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS);
346
    }
347
 
348
    if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))
349
    {
350
      epnum = 0U;
351
 
352
      /* Read in the device interrupt bits */
353
      ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance);
354
 
355
      while ( ep_intr )
356
      {
357
        if (ep_intr & 0x1U)
358
        {
359
          epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, epnum);
360
 
361
          if(( epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)
362
          {
363
            CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC);
364
 
365
            HAL_PCD_DataOutStageCallback(hpcd, epnum);
366
          }
367
 
368
          if(( epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)
369
          {
370
            /* Inform the upper layer that a setup packet is available */
371
            HAL_PCD_SetupStageCallback(hpcd);
372
            CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP);
373
          }
374
 
375
          if(( epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS)
376
          {
377
            CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS);
378
          }
379
        }
380
        epnum++;
381
        ep_intr >>= 1U;
382
      }
383
    }
384
 
385
    if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT))
386
    {
387
      /* Read in the device interrupt bits */
388
      ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance);
389
 
390
      epnum = 0U;
391
 
392
      while ( ep_intr )
393
      {
394
        if (ep_intr & 0x1U) /* In ITR */
395
        {
396
          epint = USB_ReadDevInEPInterrupt(hpcd->Instance, epnum);
397
 
398
          if(( epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)
399
          {
400
            fifoemptymsk = 0x1U << epnum;
401
            USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
402
 
403
            CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC);
404
 
405
            HAL_PCD_DataInStageCallback(hpcd, epnum);
406
          }
407
          if(( epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)
408
          {
409
            CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC);
410
          }
411
          if(( epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)
412
          {
413
            CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE);
414
          }
415
          if(( epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)
416
          {
417
            CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE);
418
          }
419
          if(( epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)
420
          {
421
            CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD);
422
          }
423
          if(( epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)
424
          {
425
            PCD_WriteEmptyTxFifo(hpcd , epnum);
426
          }
427
        }
428
        epnum++;
429
        ep_intr >>= 1U;
430
      }
431
    }
432
 
433
    /* Handle Resume Interrupt */
434
    if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))
435
    {
436
     /* Clear the Remote Wake-up signalling */
437
      USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
438
 
439
     HAL_PCD_ResumeCallback(hpcd);
440
 
441
     __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);
442
    }
443
 
444
    /* Handle Suspend Interrupt */
445
    if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))
446
    {
447
      if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
448
      {
449
 
450
        HAL_PCD_SuspendCallback(hpcd);
451
      }
452
      __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP);
453
    }
454
 
455
    /* Handle Reset Interrupt */
456
    if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))
457
    {
458
      USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
459
      USB_FlushTxFifo(hpcd->Instance ,  0x10U);
460
 
461
      for (index = 0U; index < hpcd->Init.dev_endpoints ; index++)
462
      {
463
        USBx_INEP(index)->DIEPINT = 0xFFU;
464
        USBx_OUTEP(index)->DOEPINT = 0xFFU;
465
      }
466
      USBx_DEVICE->DAINT = 0xFFFFFFFFU;
467
      USBx_DEVICE->DAINTMSK |= 0x10001U;
468
 
469
      USBx_DEVICE->DOEPMSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM);
470
      USBx_DEVICE->DIEPMSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM);
471
 
472
      /* Set Default Address to 0 */
473
      USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;
474
 
475
      /* setup EP0 to receive SETUP packets */
476
      USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
477
 
478
      __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST);
479
    }
480
 
481
    /* Handle Enumeration done Interrupt */
482
    if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))
483
    {
484
      USB_ActivateSetup(hpcd->Instance);
485
      hpcd->Instance->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
486
 
487
      hpcd->Init.speed            = USB_OTG_SPEED_FULL;
488
      hpcd->Init.ep0_mps          = USB_OTG_FS_MAX_PACKET_SIZE ;
489
      hpcd->Instance->GUSBCFG |= (uint32_t)((USBD_FS_TRDT_VALUE << 10U) & USB_OTG_GUSBCFG_TRDT);
490
 
491
      HAL_PCD_ResetCallback(hpcd);
492
 
493
      __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);
494
    }
495
 
496
    /* Handle RxQLevel Interrupt */
497
    if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))
498
    {
499
      USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
500
      temp = USBx->GRXSTSP;
501
      ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM];
502
 
503
      if(((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17U) ==  STS_DATA_UPDT)
504
      {
505
        if((temp & USB_OTG_GRXSTSP_BCNT) != 0U)
506
        {
507
          USB_ReadPacket(USBx, ep->xfer_buff, (temp & USB_OTG_GRXSTSP_BCNT) >> 4U);
508
          ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
509
          ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
510
        }
511
      }
512
      else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17U) ==  STS_SETUP_UPDT)
513
      {
514
        USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8U);
515
        ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
516
      }
517
      USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
518
    }
519
 
520
    /* Handle SOF Interrupt */
521
    if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))
522
    {
523
      HAL_PCD_SOFCallback(hpcd);
524
      __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF);
525
    }
526
 
527
    /* Handle Incomplete ISO IN Interrupt */
528
    if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))
529
    {
530
      HAL_PCD_ISOINIncompleteCallback(hpcd, epnum);
531
      __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR);
532
    }
533
 
534
    /* Handle Incomplete ISO OUT Interrupt */
535
    if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
536
    {
537
      HAL_PCD_ISOOUTIncompleteCallback(hpcd, epnum);
538
      __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
539
    }
540
 
541
    /* Handle Connection event Interrupt */
542
    if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))
543
    {
544
      HAL_PCD_ConnectCallback(hpcd);
545
      __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT);
546
    }
547
 
548
    /* Handle Disconnection event Interrupt */
549
    if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))
550
    {
551
      temp = hpcd->Instance->GOTGINT;
552
 
553
      if((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)
554
      {
555
        HAL_PCD_DisconnectCallback(hpcd);
556
      }
557
      hpcd->Instance->GOTGINT |= temp;
558
    }
559
  }
560
}
561
#endif /* USB_OTG_FS */
562
 
563
#if defined (USB)
564
/**
565
  * @brief  This function handles PCD interrupt request.
566
  * @param  hpcd: PCD handle
567
  * @retval HAL status
568
  */
569
void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
570
{
571
  if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_CTR))
572
  {
573
    /* servicing of the endpoint correct transfer interrupt */
574
    /* clear of the CTR flag into the sub */
575
    PCD_EP_ISR_Handler(hpcd);
576
  }
577
 
578
  if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_RESET))
579
  {
580
    __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET);
581
    HAL_PCD_ResetCallback(hpcd);
582
    HAL_PCD_SetAddress(hpcd, 0U);
583
  }
584
 
585
  if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_PMAOVR))
586
  {
587
    __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR);    
588
  }
589
  if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_ERR))
590
  {
591
    __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR);
592
  }
593
 
594
  if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_WKUP))
595
  {
596
    hpcd->Instance->CNTR &= ~(USB_CNTR_LP_MODE);
597
    hpcd->Instance->CNTR &= ~(USB_CNTR_FSUSP);
598
 
599
    HAL_PCD_ResumeCallback(hpcd);
600
 
601
    __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP);    
602
  }
603
 
604
  if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SUSP))
605
  {
606
    /* Force low-power mode in the macrocell */
607
    hpcd->Instance->CNTR |= USB_CNTR_FSUSP;
608
 
609
    /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
610
    __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP);  
611
 
612
    hpcd->Instance->CNTR |= USB_CNTR_LP_MODE;
613
    if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_WKUP) == 0U)
614
    {
615
      HAL_PCD_SuspendCallback(hpcd);
616
    }
617
  }
618
 
619
  if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SOF))
620
  {
621
    __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF);
622
    HAL_PCD_SOFCallback(hpcd);
623
  }
624
 
625
  if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_ESOF))
626
  {
627
    /* clear ESOF flag in ISTR */
628
    __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF);
629
  }
630
}
631
#endif /* USB */
632
 
633
/**
634
  * @brief  Data out stage callbacks
635
  * @param  hpcd: PCD handle
636
  * @param  epnum: endpoint number
637
  * @retval None
638
  */
639
 __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
640
{
641
  /* Prevent unused argument(s) compilation warning */
642
  UNUSED(hpcd);
643
  UNUSED(epnum);
644
  /* NOTE : This function should not be modified, when the callback is needed,
645
            the HAL_PCD_DataOutStageCallback could be implemented in the user file
646
   */
647
}
648
 
649
/**
650
  * @brief  Data IN stage callbacks
651
  * @param  hpcd: PCD handle
652
  * @param  epnum: endpoint number
653
  * @retval None
654
  */
655
 __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
656
{
657
  /* Prevent unused argument(s) compilation warning */
658
  UNUSED(hpcd);
659
  UNUSED(epnum);
660
  /* NOTE : This function should not be modified, when the callback is needed,
661
            the HAL_PCD_DataInStageCallback could be implemented in the user file
662
   */
663
}
664
/**
665
  * @brief  Setup stage callback
666
  * @param  hpcd: PCD handle
667
  * @retval None
668
  */
669
 __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
670
{
671
  /* Prevent unused argument(s) compilation warning */
672
  UNUSED(hpcd);
673
  /* NOTE : This function should not be modified, when the callback is needed,
674
            the HAL_PCD_SetupStageCallback could be implemented in the user file
675
   */
676
}
677
 
678
/**
679
  * @brief  USB Start Of Frame callbacks
680
  * @param  hpcd: PCD handle
681
  * @retval None
682
  */
683
 __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
684
{
685
  /* Prevent unused argument(s) compilation warning */
686
  UNUSED(hpcd);
687
  /* NOTE : This function should not be modified, when the callback is needed,
688
            the HAL_PCD_SOFCallback could be implemented in the user file
689
   */
690
}
691
 
692
/**
693
  * @brief  USB Reset callbacks
694
  * @param  hpcd: PCD handle
695
  * @retval None
696
  */
697
 __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
698
{
699
  /* Prevent unused argument(s) compilation warning */
700
  UNUSED(hpcd);
701
  /* NOTE : This function should not be modified, when the callback is needed,
702
            the HAL_PCD_ResetCallback could be implemented in the user file
703
   */
704
}
705
 
706
/**
707
  * @brief  Suspend event callbacks
708
  * @param  hpcd: PCD handle
709
  * @retval None
710
  */
711
 __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
712
{
713
  /* Prevent unused argument(s) compilation warning */
714
  UNUSED(hpcd);
715
  /* NOTE : This function should not be modified, when the callback is needed,
716
            the HAL_PCD_SuspendCallback could be implemented in the user file
717
   */
718
}
719
 
720
/**
721
  * @brief  Resume event callbacks
722
  * @param  hpcd: PCD handle
723
  * @retval None
724
  */
725
 __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
726
{
727
  /* Prevent unused argument(s) compilation warning */
728
  UNUSED(hpcd);
729
  /* NOTE : This function should not be modified, when the callback is needed,
730
            the HAL_PCD_ResumeCallback could be implemented in the user file
731
   */
732
}
733
 
734
/**
735
  * @brief  Incomplete ISO OUT callbacks
736
  * @param  hpcd: PCD handle
737
  * @param  epnum: endpoint number
738
  * @retval None
739
  */
740
 __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
741
{
742
  /* Prevent unused argument(s) compilation warning */
743
  UNUSED(hpcd);
744
  UNUSED(epnum);
745
  /* NOTE : This function should not be modified, when the callback is needed,
746
            the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
747
   */
748
}
749
 
750
/**
751
  * @brief  Incomplete ISO IN  callbacks
752
  * @param  hpcd: PCD handle
753
  * @param  epnum: endpoint number
754
  * @retval None
755
  */
756
 __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
757
{
758
  /* Prevent unused argument(s) compilation warning */
759
  UNUSED(hpcd);
760
  UNUSED(epnum);
761
  /* NOTE : This function should not be modified, when the callback is needed,
762
            the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
763
   */
764
}
765
 
766
/**
767
  * @brief  Connection event callbacks
768
  * @param  hpcd: PCD handle
769
  * @retval None
770
  */
771
 __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
772
{
773
  /* Prevent unused argument(s) compilation warning */
774
  UNUSED(hpcd);
775
  /* NOTE : This function should not be modified, when the callback is needed,
776
            the HAL_PCD_ConnectCallback could be implemented in the user file
777
   */
778
}
779
 
780
/**
781
  * @brief  Disconnection event callbacks
782
  * @param  hpcd: PCD handle
783
  * @retval None
784
  */
785
 __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
786
{
787
  /* Prevent unused argument(s) compilation warning */
788
  UNUSED(hpcd);
789
  /* NOTE : This function should not be modified, when the callback is needed,
790
            the HAL_PCD_DisconnectCallback could be implemented in the user file
791
   */
792
}
793
 
794
/**
795
  * @}
796
  */
797
 
798
/** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
799
 *  @brief   management functions
800
 *
801
@verbatim
802
 ===============================================================================
803
                      ##### Peripheral Control functions #####
804
 ===============================================================================  
805
    [..]
806
    This subsection provides a set of functions allowing to control the PCD data
807
    transfers.
808
 
809
@endverbatim
810
  * @{
811
  */
812
 
813
/**
814
  * @brief  Connect the USB device
815
  * @param  hpcd: PCD handle
816
  * @retval HAL status
817
  */
818
HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
819
{
820
  __HAL_LOCK(hpcd);
821
  HAL_PCDEx_SetConnectionState (hpcd, 1);
822
  USB_DevConnect(hpcd->Instance);
823
  __HAL_UNLOCK(hpcd);
824
  return HAL_OK;
825
}
826
 
827
/**
828
  * @brief  Disconnect the USB device
829
  * @param  hpcd: PCD handle
830
  * @retval HAL status
831
  */
832
HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
833
{
834
  __HAL_LOCK(hpcd);
835
  HAL_PCDEx_SetConnectionState (hpcd, 0U);
836
  USB_DevDisconnect(hpcd->Instance);
837
  __HAL_UNLOCK(hpcd);
838
  return HAL_OK;
839
}
840
 
841
/**
842
  * @brief  Set the USB Device address
843
  * @param  hpcd: PCD handle
844
  * @param  address: new device address
845
  * @retval HAL status
846
  */
847
HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
848
{
849
  __HAL_LOCK(hpcd);
850
  hpcd->USB_Address = address;
851
  USB_SetDevAddress(hpcd->Instance, address);
852
  __HAL_UNLOCK(hpcd);
853
  return HAL_OK;
854
}
855
/**
856
  * @brief  Open and configure an endpoint
857
  * @param  hpcd: PCD handle
858
  * @param  ep_addr: endpoint address
859
  * @param  ep_mps: endpoint max packet size
860
  * @param  ep_type: endpoint type  
861
  * @retval HAL status
862
  */
863
HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)
864
{
865
  HAL_StatusTypeDef  ret = HAL_OK;
866
  PCD_EPTypeDef *ep = NULL;
867
 
868
  if ((ep_addr & 0x80U) == 0x80U)
869
  {
870
    ep = &hpcd->IN_ep[ep_addr & 0x7FU];
871
  }
872
  else
873
  {
874
    ep = &hpcd->OUT_ep[ep_addr & 0x7FU];
875
  }
876
  ep->num   = ep_addr & 0x7FU;
877
 
878
  ep->is_in = (0x80U & ep_addr) != 0U;
879
  ep->maxpacket = ep_mps;
880
  ep->type = ep_type;
881
 
882
  __HAL_LOCK(hpcd);
883
  USB_ActivateEndpoint(hpcd->Instance , ep);
884
  __HAL_UNLOCK(hpcd);
885
  return ret;
886
}
887
 
888
/**
889
  * @brief  Deactivate an endpoint
890
  * @param  hpcd: PCD handle
891
  * @param  ep_addr: endpoint address
892
  * @retval HAL status
893
  */
894
HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
895
{  
896
  PCD_EPTypeDef *ep = NULL;
897
 
898
  if ((ep_addr & 0x80U) == 0x80U)
899
  {
900
    ep = &hpcd->IN_ep[ep_addr & 0x7FU];
901
  }
902
  else
903
  {
904
    ep = &hpcd->OUT_ep[ep_addr & 0x7FU];
905
  }
906
  ep->num   = ep_addr & 0x7FU;
907
 
908
  ep->is_in = (0x80U & ep_addr) != 0U;
909
 
910
  __HAL_LOCK(hpcd);
911
  USB_DeactivateEndpoint(hpcd->Instance , ep);
912
  __HAL_UNLOCK(hpcd);
913
  return HAL_OK;
914
}
915
 
916
 
917
/**
918
  * @brief  Receive an amount of data
919
  * @param  hpcd: PCD handle
920
  * @param  ep_addr: endpoint address
921
  * @param  pBuf: pointer to the reception buffer
922
  * @param  len: amount of data to be received
923
  * @retval HAL status
924
  */
925
HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
926
{
927
  PCD_EPTypeDef *ep = NULL;
928
 
929
  ep = &hpcd->OUT_ep[ep_addr & 0x7FU];
930
 
931
  /*setup and start the Xfer */
932
  ep->xfer_buff = pBuf;  
933
  ep->xfer_len = len;
934
  ep->xfer_count = 0U;
935
  ep->is_in = 0U;
936
  ep->num = ep_addr & 0x7FU;
937
 
938
  if ((ep_addr & 0x7FU) == 0U)
939
  {
940
    USB_EP0StartXfer(hpcd->Instance , ep);
941
  }
942
  else
943
  {
944
    USB_EPStartXfer(hpcd->Instance , ep);
945
  }
946
 
947
  return HAL_OK;
948
}
949
 
950
/**
951
  * @brief  Get Received Data Size
952
  * @param  hpcd: PCD handle
953
  * @param  ep_addr: endpoint address
954
  * @retval Data Size
955
  */
956
uint16_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
957
{
958
  return hpcd->OUT_ep[ep_addr & 0xF].xfer_count;
959
}
960
/**
961
  * @brief  Send an amount of data
962
  * @param  hpcd: PCD handle
963
  * @param  ep_addr: endpoint address
964
  * @param  pBuf: pointer to the transmission buffer
965
  * @param  len: amount of data to be sent
966
  * @retval HAL status
967
  */
968
HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
969
{
970
  PCD_EPTypeDef *ep = NULL;
971
 
972
  ep = &hpcd->IN_ep[ep_addr & 0x7FU];
973
 
974
  /*setup and start the Xfer */
975
  ep->xfer_buff = pBuf;  
976
  ep->xfer_len = len;
977
  ep->xfer_count = 0U;
978
  ep->is_in = 1U;
979
  ep->num = ep_addr & 0x7FU;
980
 
981
  if ((ep_addr & 0x7FU) == 0U)
982
  {
983
    USB_EP0StartXfer(hpcd->Instance , ep);
984
  }
985
  else
986
  {
987
    USB_EPStartXfer(hpcd->Instance , ep);
988
  }
989
 
990
  return HAL_OK;
991
}
992
 
993
/**
994
  * @brief  Set a STALL condition over an endpoint
995
  * @param  hpcd: PCD handle
996
  * @param  ep_addr: endpoint address
997
  * @retval HAL status
998
  */
999
HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1000
{
1001
  PCD_EPTypeDef *ep = NULL;
1002
 
1003
  if ((0x80U & ep_addr) == 0x80U)
1004
  {
1005
    ep = &hpcd->IN_ep[ep_addr & 0x7FU];
1006
  }
1007
  else
1008
  {
1009
    ep = &hpcd->OUT_ep[ep_addr];
1010
  }
1011
 
1012
  ep->is_stall = 1U;
1013
  ep->num   = ep_addr & 0x7FU;
1014
  ep->is_in = ((ep_addr & 0x80U) == 0x80U);
1015
 
1016
  __HAL_LOCK(hpcd);
1017
  USB_EPSetStall(hpcd->Instance , ep);
1018
  if((ep_addr & 0x7FU) == 0U)
1019
  {
1020
    USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
1021
  }
1022
  __HAL_UNLOCK(hpcd);
1023
 
1024
  return HAL_OK;
1025
}
1026
 
1027
/**
1028
  * @brief  Clear a STALL condition over in an endpoint
1029
  * @param  hpcd: PCD handle
1030
  * @param  ep_addr: endpoint address
1031
  * @retval HAL status
1032
  */
1033
HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1034
{
1035
  PCD_EPTypeDef *ep = NULL;
1036
 
1037
  if ((0x80U & ep_addr) == 0x80U)
1038
  {
1039
    ep = &hpcd->IN_ep[ep_addr & 0x7FU];
1040
  }
1041
  else
1042
  {
1043
    ep = &hpcd->OUT_ep[ep_addr];
1044
  }
1045
 
1046
  ep->is_stall = 0U;
1047
  ep->num   = ep_addr & 0x7FU;
1048
  ep->is_in = ((ep_addr & 0x80U) == 0x80U);
1049
 
1050
  __HAL_LOCK(hpcd);
1051
  USB_EPClearStall(hpcd->Instance , ep);
1052
  __HAL_UNLOCK(hpcd);
1053
 
1054
  return HAL_OK;
1055
}
1056
 
1057
/**
1058
  * @brief  Flush an endpoint
1059
  * @param  hpcd: PCD handle
1060
  * @param  ep_addr: endpoint address
1061
  * @retval HAL status
1062
  */
1063
HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1064
{
1065
  __HAL_LOCK(hpcd);
1066
 
1067
  if ((ep_addr & 0x80U) == 0x80U)
1068
  {
1069
    USB_FlushTxFifo(hpcd->Instance, ep_addr & 0x7FU);
1070
  }
1071
  else
1072
  {
1073
    USB_FlushRxFifo(hpcd->Instance);
1074
  }
1075
 
1076
  __HAL_UNLOCK(hpcd);
1077
 
1078
  return HAL_OK;
1079
}
1080
 
1081
/**
1082
  * @brief  HAL_PCD_ActivateRemoteWakeup : active remote wakeup signalling
1083
  * @param  hpcd: PCD handle
1084
  * @retval HAL status
1085
  */
1086
HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
1087
{
1088
  return(USB_ActivateRemoteWakeup(hpcd->Instance));
1089
}
1090
 
1091
/**
1092
  * @brief  HAL_PCD_DeActivateRemoteWakeup : de-active remote wakeup signalling
1093
  * @param  hpcd: PCD handle
1094
  * @retval HAL status
1095
  */
1096
HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
1097
{
1098
  return(USB_DeActivateRemoteWakeup(hpcd->Instance));
1099
}
1100
/**
1101
  * @}
1102
  */
1103
 
1104
/** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
1105
 *  @brief   Peripheral State functions
1106
 *
1107
@verbatim
1108
 ===============================================================================
1109
                      ##### Peripheral State functions #####
1110
 ===============================================================================
1111
    [..]
1112
    This subsection permits to get in run-time the status of the peripheral
1113
    and the data flow.
1114
 
1115
@endverbatim
1116
  * @{
1117
  */
1118
 
1119
/**
1120
  * @brief  Return the PCD state
1121
  * @param  hpcd: PCD handle
1122
  * @retval HAL state
1123
  */
1124
PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd)
1125
{
1126
  return hpcd->State;
1127
}
1128
 
1129
/**
1130
  * @}
1131
  */
1132
 
1133
/**
1134
  * @}
1135
  */
1136
 
1137
/** @addtogroup PCD_Private_Functions
1138
  * @{
1139
  */
1140
#if defined (USB_OTG_FS)
1141
/**
1142
  * @brief  DCD_WriteEmptyTxFifo
1143
  *         check FIFO for the next packet to be loaded
1144
  * @param  hpcd: PCD handle
1145
  * @param  epnum : endpoint number
1146
  *          This parameter can be a value from 0 to 15  
1147
  * @retval HAL status
1148
  */
1149
static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)
1150
{
1151
  USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;  
1152
  USB_OTG_EPTypeDef *ep = NULL;
1153
  int32_t len = 0;
1154
  uint32_t len32b = 0U;
1155
  uint32_t fifoemptymsk = 0U;
1156
 
1157
  ep = &hpcd->IN_ep[epnum];
1158
  len = ep->xfer_len - ep->xfer_count;
1159
 
1160
  if (len > ep->maxpacket)
1161
  {
1162
    len = ep->maxpacket;
1163
  }
1164
 
1165
  len32b = (len + 3U) / 4U;
1166
 
1167
  while ((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) > len32b &&
1168
         ep->xfer_count < ep->xfer_len &&
1169
         ep->xfer_len != 0U)
1170
  {
1171
    /* Write the FIFO */
1172
    len = ep->xfer_len - ep->xfer_count;
1173
 
1174
    if ((uint32_t)len > ep->maxpacket)
1175
    {
1176
      len = ep->maxpacket;
1177
    }
1178
    len32b = (len + 3U) / 4U;
1179
 
1180
    USB_WritePacket(USBx, ep->xfer_buff, epnum, len);
1181
 
1182
    ep->xfer_buff  += len;
1183
    ep->xfer_count += len;
1184
  }
1185
 
1186
  if(len <= 0)
1187
  {
1188
    fifoemptymsk = 0x01U << epnum;
1189
    USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
1190
 
1191
  }
1192
 
1193
  return HAL_OK;
1194
}
1195
#endif /* USB_OTG_FS */
1196
 
1197
#if defined (USB)
1198
/**
1199
  * @brief  This function handles PCD Endpoint interrupt request.
1200
  * @param  hpcd: PCD handle
1201
  * @retval HAL status
1202
  */
1203
static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
1204
{
1205
  PCD_EPTypeDef *ep = NULL;
1206
  uint16_t count = 0;
1207
  uint8_t epindex = 0;
1208
  __IO uint16_t wIstr = 0;  
1209
  __IO uint16_t wEPVal = 0;
1210
 
1211
  /* stay in loop while pending interrupts */
1212
  while (((wIstr = hpcd->Instance->ISTR) & USB_ISTR_CTR) != 0)
1213
  {
1214
    /* extract highest priority endpoint number */
1215
    epindex = (uint8_t)(wIstr & USB_ISTR_EP_ID);
1216
 
1217
    if (epindex == 0)
1218
    {
1219
      /* Decode and service control endpoint interrupt */
1220
 
1221
      /* DIR bit = origin of the interrupt */  
1222
      if ((wIstr & USB_ISTR_DIR) == 0)
1223
      {
1224
        /* DIR = 0 */
1225
 
1226
        /* DIR = 0      => IN  int */
1227
        /* DIR = 0 implies that (EP_CTR_TX = 1) always  */
1228
        PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0);
1229
        ep = &hpcd->IN_ep[0];
1230
 
1231
        ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
1232
        ep->xfer_buff += ep->xfer_count;
1233
 
1234
        /* TX COMPLETE */
1235
        HAL_PCD_DataInStageCallback(hpcd, 0U);
1236
 
1237
 
1238
        if((hpcd->USB_Address > 0U)&& ( ep->xfer_len == 0U))
1239
        {
1240
          hpcd->Instance->DADDR = (hpcd->USB_Address | USB_DADDR_EF);
1241
          hpcd->USB_Address = 0U;
1242
        }
1243
 
1244
      }
1245
      else
1246
      {
1247
        /* DIR = 1 */
1248
 
1249
        /* DIR = 1 & CTR_RX       => SETUP or OUT int */
1250
        /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
1251
        ep = &hpcd->OUT_ep[0U];
1252
        wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0);
1253
 
1254
        if ((wEPVal & USB_EP_SETUP) != 0U)
1255
        {
1256
          /* Get SETUP Packet*/
1257
          ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
1258
          USB_ReadPMA(hpcd->Instance, (uint8_t*)hpcd->Setup ,ep->pmaadress , ep->xfer_count);      
1259
          /* SETUP bit kept frozen while CTR_RX = 1*/
1260
          PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
1261
 
1262
          /* Process SETUP Packet*/
1263
          HAL_PCD_SetupStageCallback(hpcd);
1264
        }
1265
 
1266
        else if ((wEPVal & USB_EP_CTR_RX) != 0U)
1267
        {
1268
          PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
1269
          /* Get Control Data OUT Packet*/
1270
          ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
1271
 
1272
          if (ep->xfer_count != 0U)
1273
          {
1274
            USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, ep->xfer_count);
1275
            ep->xfer_buff+=ep->xfer_count;
1276
          }
1277
 
1278
          /* Process Control Data OUT Packet*/
1279
           HAL_PCD_DataOutStageCallback(hpcd, 0U);
1280
 
1281
          PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket);
1282
          PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID);
1283
        }
1284
      }
1285
    }
1286
    else
1287
    {
1288
      /* Decode and service non control endpoints interrupt  */
1289
 
1290
      /* process related endpoint register */
1291
      wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, epindex);
1292
      if ((wEPVal & USB_EP_CTR_RX) != 0U)
1293
      {  
1294
        /* clear int flag */
1295
        PCD_CLEAR_RX_EP_CTR(hpcd->Instance, epindex);
1296
        ep = &hpcd->OUT_ep[epindex];
1297
 
1298
        /* OUT double Buffering*/
1299
        if (ep->doublebuffer == 0U)
1300
        {
1301
          count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
1302
          if (count != 0U)
1303
          {
1304
            USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count);
1305
          }
1306
        }
1307
        else
1308
        {
1309
          if (PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_RX)
1310
          {
1311
            /*read from endpoint BUF0Addr buffer*/
1312
            count = PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
1313
            if (count != 0U)
1314
            {
1315
              USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
1316
            }
1317
          }
1318
          else
1319
          {
1320
            /*read from endpoint BUF1Addr buffer*/
1321
            count = PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
1322
            if (count != 0U)
1323
            {
1324
              USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
1325
            }
1326
          }
1327
          PCD_FreeUserBuffer(hpcd->Instance, ep->num, PCD_EP_DBUF_OUT);  
1328
        }
1329
        /*multi-packet on the NON control OUT endpoint*/
1330
        ep->xfer_count+=count;
1331
        ep->xfer_buff+=count;
1332
 
1333
        if ((ep->xfer_len == 0U) || (count < ep->maxpacket))
1334
        {
1335
          /* RX COMPLETE */
1336
          HAL_PCD_DataOutStageCallback(hpcd, ep->num);
1337
        }
1338
        else
1339
        {
1340
          HAL_PCD_EP_Receive(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
1341
        }
1342
 
1343
      } /* if((wEPVal & EP_CTR_RX) */
1344
 
1345
      if ((wEPVal & USB_EP_CTR_TX) != 0U)
1346
      {
1347
        ep = &hpcd->IN_ep[epindex];
1348
 
1349
        /* clear int flag */
1350
        PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex);
1351
 
1352
        /* IN double Buffering*/
1353
        if (ep->doublebuffer == 0U)
1354
        {
1355
          ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
1356
          if (ep->xfer_count != 0U)
1357
          {
1358
            USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, ep->xfer_count);
1359
          }
1360
        }
1361
        else
1362
        {
1363
          if (PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_TX)
1364
          {
1365
            /*read from endpoint BUF0Addr buffer*/
1366
            ep->xfer_count = PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
1367
            if (ep->xfer_count != 0U)
1368
            {
1369
              USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, ep->xfer_count);
1370
            }
1371
          }
1372
          else
1373
          {
1374
            /*read from endpoint BUF1Addr buffer*/
1375
            ep->xfer_count = PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
1376
            if (ep->xfer_count != 0U)
1377
            {
1378
              USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, ep->xfer_count);
1379
            }
1380
          }
1381
          PCD_FreeUserBuffer(hpcd->Instance, ep->num, PCD_EP_DBUF_IN);  
1382
        }
1383
        /*multi-packet on the NON control IN endpoint*/
1384
        ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
1385
        ep->xfer_buff+=ep->xfer_count;
1386
 
1387
        /* Zero Length Packet? */
1388
        if (ep->xfer_len == 0U)
1389
        {
1390
          /* TX COMPLETE */
1391
          HAL_PCD_DataInStageCallback(hpcd, ep->num);
1392
        }
1393
        else
1394
        {
1395
          HAL_PCD_EP_Transmit(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
1396
        }
1397
      }
1398
    }
1399
  }
1400
  return HAL_OK;
1401
}
1402
#endif /* USB */
1403
 
1404
/**
1405
  * @}
1406
  */
1407
 
1408
/**
1409
  * @}
1410
  */
1411
 
1412
#endif /* STM32F102x6 || STM32F102xB || */
1413
       /* STM32F103x6 || STM32F103xB || */
1414
       /* STM32F103xE || STM32F103xG || */
1415
       /* STM32F105xC || STM32F107xC    */
1416
 
1417
#endif /* HAL_PCD_MODULE_ENABLED */
1418
 
1419
 
1420
/**
1421
  * @}
1422
  */
1423
 
1424
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/