Subversion Repositories AFRtranscoder

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 1
/**
2
  ******************************************************************************
3
  * @file    stm32f1xx_ll_usb.c
4
  * @author  MCD Application Team
5
  * @brief   USB Low Layer HAL module driver.
6
  *
7
  *          This file provides firmware functions to manage the following
8
  *          functionalities of the USB Peripheral Controller:
9
  *           + Initialization/de-initialization functions
10
  *           + I/O operation functions
11
  *           + Peripheral Control functions
12
  *           + Peripheral State functions
13
  *
14
  ******************************************************************************
15
  * @attention
16
  *
17
  * Copyright (c) 2016 STMicroelectronics.
18
  * All rights reserved.
19
  *
20
  * This software is licensed under terms that can be found in the LICENSE file
21
  * in the root directory of this software component.
22
  * If no LICENSE file comes with this software, it is provided AS-IS.
23
  *
24
  ******************************************************************************
25
  @verbatim
26
  ==============================================================================
27
                    ##### How to use this driver #####
28
  ==============================================================================
29
    [..]
30
      (#) Fill parameters of Init structure in USB_CfgTypeDef structure.
31
 
32
      (#) Call USB_CoreInit() API to initialize the USB Core peripheral.
33
 
34
      (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes.
35
 
36
  @endverbatim
37
 
38
  ******************************************************************************
39
  */
40
 
41
/* Includes ------------------------------------------------------------------*/
42
#include "stm32f1xx_hal.h"
43
 
44
/** @addtogroup STM32F1xx_LL_USB_DRIVER
45
  * @{
46
  */
47
 
48
#if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED)
49
#if defined (USB) || defined (USB_OTG_FS)
50
/* Private typedef -----------------------------------------------------------*/
51
/* Private define ------------------------------------------------------------*/
52
/* Private macro -------------------------------------------------------------*/
53
/* Private variables ---------------------------------------------------------*/
54
/* Private function prototypes -----------------------------------------------*/
55
/* Private functions ---------------------------------------------------------*/
56
#if defined (USB_OTG_FS)
57
static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx);
58
 
59
/* Exported functions --------------------------------------------------------*/
60
/** @defgroup USB_LL_Exported_Functions USB Low Layer Exported Functions
61
  * @{
62
  */
63
 
64
/** @defgroup USB_LL_Exported_Functions_Group1 Initialization/de-initialization functions
65
  *  @brief    Initialization and Configuration functions
66
  *
67
@verbatim
68
 ===============================================================================
69
                      ##### Initialization/de-initialization functions #####
70
 ===============================================================================
71
 
72
@endverbatim
73
  * @{
74
  */
75
 
76
/**
77
  * @brief  Initializes the USB Core
78
  * @param  USBx USB Instance
79
  * @param  cfg pointer to a USB_OTG_CfgTypeDef structure that contains
80
  *         the configuration information for the specified USBx peripheral.
81
  * @retval HAL status
82
  */
83
HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
84
{
85
  HAL_StatusTypeDef ret;
86
 
87
  /* Select FS Embedded PHY */
88
  USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
89
 
90
  /* Reset after a PHY select */
91
  ret = USB_CoreReset(USBx);
92
 
93
  /* Activate the USB Transceiver */
94
  USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
95
 
96
  return ret;
97
}
98
 
99
 
100
/**
101
  * @brief  Set the USB turnaround time
102
  * @param  USBx USB Instance
103
  * @param  hclk: AHB clock frequency
104
  * @retval USB turnaround time In PHY Clocks number
105
  */
106
HAL_StatusTypeDef USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef *USBx,
107
                                        uint32_t hclk, uint8_t speed)
108
{
109
  uint32_t UsbTrd;
110
 
111
  /* The USBTRD is configured according to the tables below, depending on AHB frequency
112
  used by application. In the low AHB frequency range it is used to stretch enough the USB response
113
  time to IN tokens, the USB turnaround time, so to compensate for the longer AHB read access
114
  latency to the Data FIFO */
115
  if (speed == USBD_FS_SPEED)
116
  {
117
    if ((hclk >= 14200000U) && (hclk < 15000000U))
118
    {
119
      /* hclk Clock Range between 14.2-15 MHz */
120
      UsbTrd = 0xFU;
121
    }
122
    else if ((hclk >= 15000000U) && (hclk < 16000000U))
123
    {
124
      /* hclk Clock Range between 15-16 MHz */
125
      UsbTrd = 0xEU;
126
    }
127
    else if ((hclk >= 16000000U) && (hclk < 17200000U))
128
    {
129
      /* hclk Clock Range between 16-17.2 MHz */
130
      UsbTrd = 0xDU;
131
    }
132
    else if ((hclk >= 17200000U) && (hclk < 18500000U))
133
    {
134
      /* hclk Clock Range between 17.2-18.5 MHz */
135
      UsbTrd = 0xCU;
136
    }
137
    else if ((hclk >= 18500000U) && (hclk < 20000000U))
138
    {
139
      /* hclk Clock Range between 18.5-20 MHz */
140
      UsbTrd = 0xBU;
141
    }
142
    else if ((hclk >= 20000000U) && (hclk < 21800000U))
143
    {
144
      /* hclk Clock Range between 20-21.8 MHz */
145
      UsbTrd = 0xAU;
146
    }
147
    else if ((hclk >= 21800000U) && (hclk < 24000000U))
148
    {
149
      /* hclk Clock Range between 21.8-24 MHz */
150
      UsbTrd = 0x9U;
151
    }
152
    else if ((hclk >= 24000000U) && (hclk < 27700000U))
153
    {
154
      /* hclk Clock Range between 24-27.7 MHz */
155
      UsbTrd = 0x8U;
156
    }
157
    else if ((hclk >= 27700000U) && (hclk < 32000000U))
158
    {
159
      /* hclk Clock Range between 27.7-32 MHz */
160
      UsbTrd = 0x7U;
161
    }
162
    else /* if(hclk >= 32000000) */
163
    {
164
      /* hclk Clock Range between 32-200 MHz */
165
      UsbTrd = 0x6U;
166
    }
167
  }
168
  else
169
  {
170
    UsbTrd = USBD_DEFAULT_TRDT_VALUE;
171
  }
172
 
173
  USBx->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
174
  USBx->GUSBCFG |= (uint32_t)((UsbTrd << 10) & USB_OTG_GUSBCFG_TRDT);
175
 
176
  return HAL_OK;
177
}
178
 
179
/**
180
  * @brief  USB_EnableGlobalInt
181
  *         Enables the controller's Global Int in the AHB Config reg
182
  * @param  USBx  Selected device
183
  * @retval HAL status
184
  */
185
HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
186
{
187
  USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
188
  return HAL_OK;
189
}
190
 
191
/**
192
  * @brief  USB_DisableGlobalInt
193
  *         Disable the controller's Global Int in the AHB Config reg
194
  * @param  USBx  Selected device
195
  * @retval HAL status
196
  */
197
HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
198
{
199
  USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
200
  return HAL_OK;
201
}
202
 
203
/**
204
  * @brief  USB_SetCurrentMode Set functional mode
205
  * @param  USBx  Selected device
206
  * @param  mode  current core mode
207
  *          This parameter can be one of these values:
208
  *            @arg USB_DEVICE_MODE Peripheral mode
209
  *            @arg USB_HOST_MODE Host mode
210
  * @retval HAL status
211
  */
212
HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx, USB_ModeTypeDef mode)
213
{
214
  uint32_t ms = 0U;
215
 
216
  USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
217
 
218
  if (mode == USB_HOST_MODE)
219
  {
220
    USBx->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD;
221
 
222
    do
223
    {
224
      HAL_Delay(1U);
225
      ms++;
226
    } while ((USB_GetMode(USBx) != (uint32_t)USB_HOST_MODE) && (ms < 50U));
227
  }
228
  else if (mode == USB_DEVICE_MODE)
229
  {
230
    USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
231
 
232
    do
233
    {
234
      HAL_Delay(1U);
235
      ms++;
236
    } while ((USB_GetMode(USBx) != (uint32_t)USB_DEVICE_MODE) && (ms < 50U));
237
  }
238
  else
239
  {
240
    return HAL_ERROR;
241
  }
242
 
243
  if (ms == 50U)
244
  {
245
    return HAL_ERROR;
246
  }
247
 
248
  return HAL_OK;
249
}
250
 
251
/**
252
  * @brief  USB_DevInit Initializes the USB_OTG controller registers
253
  *         for device mode
254
  * @param  USBx  Selected device
255
  * @param  cfg   pointer to a USB_OTG_CfgTypeDef structure that contains
256
  *         the configuration information for the specified USBx peripheral.
257
  * @retval HAL status
258
  */
259
HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
260
{
261
  HAL_StatusTypeDef ret = HAL_OK;
262
  uint32_t USBx_BASE = (uint32_t)USBx;
263
  uint32_t i;
264
 
265
  for (i = 0U; i < 15U; i++)
266
  {
267
    USBx->DIEPTXF[i] = 0U;
268
  }
269
 
270
  /* Enable HW VBUS sensing */
271
  USBx->GCCFG |= USB_OTG_GCCFG_VBUSBSEN;
272
 
273
  /* Restart the Phy Clock */
274
  USBx_PCGCCTL = 0U;
275
 
276
  /* Set Core speed to Full speed mode */
277
  (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_FULL);
278
 
279
  /* Flush the FIFOs */
280
  if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
281
  {
282
    ret = HAL_ERROR;
283
  }
284
 
285
  if (USB_FlushRxFifo(USBx) != HAL_OK)
286
  {
287
    ret = HAL_ERROR;
288
  }
289
 
290
  /* Clear all pending Device Interrupts */
291
  USBx_DEVICE->DIEPMSK = 0U;
292
  USBx_DEVICE->DOEPMSK = 0U;
293
  USBx_DEVICE->DAINTMSK = 0U;
294
 
295
  for (i = 0U; i < cfg.dev_endpoints; i++)
296
  {
297
    if ((USBx_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
298
    {
299
      if (i == 0U)
300
      {
301
        USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_SNAK;
302
      }
303
      else
304
      {
305
        USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK;
306
      }
307
    }
308
    else
309
    {
310
      USBx_INEP(i)->DIEPCTL = 0U;
311
    }
312
 
313
    USBx_INEP(i)->DIEPTSIZ = 0U;
314
    USBx_INEP(i)->DIEPINT  = 0xFB7FU;
315
  }
316
 
317
  for (i = 0U; i < cfg.dev_endpoints; i++)
318
  {
319
    if ((USBx_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
320
    {
321
      if (i == 0U)
322
      {
323
        USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_SNAK;
324
      }
325
      else
326
      {
327
        USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK;
328
      }
329
    }
330
    else
331
    {
332
      USBx_OUTEP(i)->DOEPCTL = 0U;
333
    }
334
 
335
    USBx_OUTEP(i)->DOEPTSIZ = 0U;
336
    USBx_OUTEP(i)->DOEPINT  = 0xFB7FU;
337
  }
338
 
339
  USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM);
340
 
341
  /* Disable all interrupts. */
342
  USBx->GINTMSK = 0U;
343
 
344
  /* Clear any pending interrupts */
345
  USBx->GINTSTS = 0xBFFFFFFFU;
346
 
347
  /* Enable the common interrupts */
348
  USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
349
 
350
  /* Enable interrupts matching to the Device mode ONLY */
351
  USBx->GINTMSK |= USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |
352
                   USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |
353
                   USB_OTG_GINTMSK_OEPINT   | USB_OTG_GINTMSK_IISOIXFRM |
354
                   USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM;
355
 
356
  if (cfg.Sof_enable != 0U)
357
  {
358
    USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;
359
  }
360
 
361
  if (cfg.vbus_sensing_enable == 1U)
362
  {
363
    USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT);
364
  }
365
 
366
  return ret;
367
}
368
 
369
/**
370
  * @brief  USB_FlushTxFifo Flush a Tx FIFO
371
  * @param  USBx  Selected device
372
  * @param  num  FIFO number
373
  *         This parameter can be a value from 1 to 15
374
            15 means Flush all Tx FIFOs
375
  * @retval HAL status
376
  */
377
HAL_StatusTypeDef USB_FlushTxFifo(USB_OTG_GlobalTypeDef *USBx, uint32_t num)
378
{
379
  __IO uint32_t count = 0U;
380
 
381
  /* Wait for AHB master IDLE state. */
382
  do
383
  {
384
    count++;
385
 
386
    if (count > 200000U)
387
    {
388
      return HAL_TIMEOUT;
389
    }
390
  } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
391
 
392
  /* Flush TX Fifo */
393
  count = 0U;
394
  USBx->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6));
395
 
396
  do
397
  {
398
    count++;
399
 
400
    if (count > 200000U)
401
    {
402
      return HAL_TIMEOUT;
403
    }
404
  } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
405
 
406
  return HAL_OK;
407
}
408
 
409
/**
410
  * @brief  USB_FlushRxFifo  Flush Rx FIFO
411
  * @param  USBx  Selected device
412
  * @retval HAL status
413
  */
414
HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx)
415
{
416
  __IO uint32_t count = 0U;
417
 
418
  /* Wait for AHB master IDLE state. */
419
  do
420
  {
421
    count++;
422
 
423
    if (count > 200000U)
424
    {
425
      return HAL_TIMEOUT;
426
    }
427
  } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
428
 
429
  /* Flush RX Fifo */
430
  count = 0U;
431
  USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
432
 
433
  do
434
  {
435
    count++;
436
 
437
    if (count > 200000U)
438
    {
439
      return HAL_TIMEOUT;
440
    }
441
  } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
442
 
443
  return HAL_OK;
444
}
445
 
446
/**
447
  * @brief  USB_SetDevSpeed  Initializes the DevSpd field of DCFG register
448
  *         depending the PHY type and the enumeration speed of the device.
449
  * @param  USBx  Selected device
450
  * @param  speed  device speed
451
  *          This parameter can be one of these values:
452
  *            @arg USB_OTG_SPEED_FULL: Full speed mode
453
  * @retval  Hal status
454
  */
455
HAL_StatusTypeDef USB_SetDevSpeed(USB_OTG_GlobalTypeDef *USBx, uint8_t speed)
456
{
457
  uint32_t USBx_BASE = (uint32_t)USBx;
458
 
459
  USBx_DEVICE->DCFG |= speed;
460
  return HAL_OK;
461
}
462
 
463
/**
464
  * @brief  USB_GetDevSpeed  Return the Dev Speed
465
  * @param  USBx  Selected device
466
  * @retval speed  device speed
467
  *          This parameter can be one of these values:
468
  *            @arg USBD_FS_SPEED: Full speed mode
469
  */
470
uint8_t USB_GetDevSpeed(USB_OTG_GlobalTypeDef *USBx)
471
{
472
  uint32_t USBx_BASE = (uint32_t)USBx;
473
  uint8_t speed;
474
  uint32_t DevEnumSpeed = USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD;
475
 
476
  if ((DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ) ||
477
      (DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_48MHZ))
478
  {
479
    speed = USBD_FS_SPEED;
480
  }
481
  else
482
  {
483
    speed = 0xFU;
484
  }
485
 
486
  return speed;
487
}
488
 
489
/**
490
  * @brief  Activate and configure an endpoint
491
  * @param  USBx  Selected device
492
  * @param  ep pointer to endpoint structure
493
  * @retval HAL status
494
  */
495
HAL_StatusTypeDef USB_ActivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
496
{
497
  uint32_t USBx_BASE = (uint32_t)USBx;
498
  uint32_t epnum = (uint32_t)ep->num;
499
 
500
  if (ep->is_in == 1U)
501
  {
502
    USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
503
 
504
    if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_USBAEP) == 0U)
505
    {
506
      USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
507
                                   ((uint32_t)ep->type << 18) | (epnum << 22) |
508
                                   USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
509
                                   USB_OTG_DIEPCTL_USBAEP;
510
    }
511
  }
512
  else
513
  {
514
    USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
515
 
516
    if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
517
    {
518
      USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
519
                                    ((uint32_t)ep->type << 18) |
520
                                    USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
521
                                    USB_OTG_DOEPCTL_USBAEP;
522
    }
523
  }
524
  return HAL_OK;
525
}
526
 
527
/**
528
  * @brief  Activate and configure a dedicated endpoint
529
  * @param  USBx  Selected device
530
  * @param  ep pointer to endpoint structure
531
  * @retval HAL status
532
  */
533
HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
534
{
535
  uint32_t USBx_BASE = (uint32_t)USBx;
536
  uint32_t epnum = (uint32_t)ep->num;
537
 
538
  /* Read DEPCTLn register */
539
  if (ep->is_in == 1U)
540
  {
541
    if (((USBx_INEP(epnum)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0U)
542
    {
543
      USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
544
                                   ((uint32_t)ep->type << 18) | (epnum << 22) |
545
                                   USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
546
                                   USB_OTG_DIEPCTL_USBAEP;
547
    }
548
 
549
    USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
550
  }
551
  else
552
  {
553
    if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
554
    {
555
      USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
556
                                    ((uint32_t)ep->type << 18) | (epnum << 22) |
557
                                    USB_OTG_DOEPCTL_USBAEP;
558
    }
559
 
560
    USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
561
  }
562
 
563
  return HAL_OK;
564
}
565
 
566
/**
567
  * @brief  De-activate and de-initialize an endpoint
568
  * @param  USBx  Selected device
569
  * @param  ep pointer to endpoint structure
570
  * @retval HAL status
571
  */
572
HAL_StatusTypeDef USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
573
{
574
  uint32_t USBx_BASE = (uint32_t)USBx;
575
  uint32_t epnum = (uint32_t)ep->num;
576
 
577
  /* Read DEPCTLn register */
578
  if (ep->is_in == 1U)
579
  {
580
    if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
581
    {
582
      USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
583
      USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS;
584
    }
585
 
586
    USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
587
    USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
588
    USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_USBAEP |
589
                                   USB_OTG_DIEPCTL_MPSIZ |
590
                                   USB_OTG_DIEPCTL_TXFNUM |
591
                                   USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
592
                                   USB_OTG_DIEPCTL_EPTYP);
593
  }
594
  else
595
  {
596
    if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
597
    {
598
      USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
599
      USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;
600
    }
601
 
602
    USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
603
    USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
604
    USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_USBAEP |
605
                                    USB_OTG_DOEPCTL_MPSIZ |
606
                                    USB_OTG_DOEPCTL_SD0PID_SEVNFRM |
607
                                    USB_OTG_DOEPCTL_EPTYP);
608
  }
609
 
610
  return HAL_OK;
611
}
612
 
613
/**
614
  * @brief  De-activate and de-initialize a dedicated endpoint
615
  * @param  USBx  Selected device
616
  * @param  ep pointer to endpoint structure
617
  * @retval HAL status
618
  */
619
HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
620
{
621
  uint32_t USBx_BASE = (uint32_t)USBx;
622
  uint32_t epnum = (uint32_t)ep->num;
623
 
624
  /* Read DEPCTLn register */
625
  if (ep->is_in == 1U)
626
  {
627
    if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
628
    {
629
      USBx_INEP(epnum)->DIEPCTL  |= USB_OTG_DIEPCTL_SNAK;
630
      USBx_INEP(epnum)->DIEPCTL  |= USB_OTG_DIEPCTL_EPDIS;
631
    }
632
 
633
    USBx_INEP(epnum)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP;
634
    USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
635
  }
636
  else
637
  {
638
    if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
639
    {
640
      USBx_OUTEP(epnum)->DOEPCTL  |= USB_OTG_DOEPCTL_SNAK;
641
      USBx_OUTEP(epnum)->DOEPCTL  |= USB_OTG_DOEPCTL_EPDIS;
642
    }
643
 
644
    USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
645
    USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
646
  }
647
 
648
  return HAL_OK;
649
}
650
 
651
/**
652
  * @brief  USB_EPStartXfer : setup and starts a transfer over an EP
653
  * @param  USBx  Selected device
654
  * @param  ep pointer to endpoint structure
655
  * @retval HAL status
656
  */
657
HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
658
{
659
  uint32_t USBx_BASE = (uint32_t)USBx;
660
  uint32_t epnum = (uint32_t)ep->num;
661
  uint16_t pktcnt;
662
 
663
  /* IN endpoint */
664
  if (ep->is_in == 1U)
665
  {
666
    /* Zero Length Packet? */
667
    if (ep->xfer_len == 0U)
668
    {
669
      USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
670
      USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
671
      USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
672
    }
673
    else
674
    {
675
      /* Program the transfer size and packet count
676
      * as follows: xfersize = N * maxpacket +
677
      * short_packet pktcnt = N + (short_packet
678
      * exist ? 1 : 0)
679
      */
680
      USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
681
      USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
682
 
683
      if (epnum == 0U)
684
      {
685
        if (ep->xfer_len > ep->maxpacket)
686
        {
687
          ep->xfer_len = ep->maxpacket;
688
        }
689
 
690
        USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
691
      }
692
      else
693
      {
694
        USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT &
695
                                       (((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket) << 19));
696
      }
697
 
698
      USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
699
 
700
      if (ep->type == EP_TYPE_ISOC)
701
      {
702
        USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT);
703
        USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1U << 29));
704
      }
705
    }
706
    /* EP enable, IN data in FIFO */
707
    USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
708
 
709
    if (ep->type != EP_TYPE_ISOC)
710
    {
711
      /* Enable the Tx FIFO Empty Interrupt for this EP */
712
      if (ep->xfer_len > 0U)
713
      {
714
        USBx_DEVICE->DIEPEMPMSK |= 1UL << (ep->num & EP_ADDR_MSK);
715
      }
716
    }
717
    else
718
    {
719
      if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
720
      {
721
        USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
722
      }
723
      else
724
      {
725
        USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
726
      }
727
 
728
      (void)USB_WritePacket(USBx, ep->xfer_buff, ep->num, (uint16_t)ep->xfer_len);
729
    }
730
  }
731
  else /* OUT endpoint */
732
  {
733
    /* Program the transfer size and packet count as follows:
734
    * pktcnt = N
735
    * xfersize = N * maxpacket
736
    */
737
    USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
738
    USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
739
 
740
    if (epnum == 0U)
741
    {
742
      if (ep->xfer_len > 0U)
743
      {
744
        ep->xfer_len = ep->maxpacket;
745
      }
746
 
747
      /* Store transfer size, for EP0 this is equal to endpoint max packet size */
748
      ep->xfer_size = ep->maxpacket;
749
 
750
      USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->xfer_size);
751
      USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
752
    }
753
    else
754
    {
755
      if (ep->xfer_len == 0U)
756
      {
757
        USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket);
758
        USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
759
      }
760
      else
761
      {
762
        pktcnt = (uint16_t)((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket);
763
        ep->xfer_size = ep->maxpacket * pktcnt;
764
 
765
        USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_PKTCNT & ((uint32_t)pktcnt << 19);
766
        USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_XFRSIZ & ep->xfer_size;
767
      }
768
    }
769
 
770
    if (ep->type == EP_TYPE_ISOC)
771
    {
772
      if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
773
      {
774
        USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM;
775
      }
776
      else
777
      {
778
        USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
779
      }
780
    }
781
    /* EP enable */
782
    USBx_OUTEP(epnum)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
783
  }
784
 
785
  return HAL_OK;
786
}
787
 
788
 
789
/**
790
   * @brief  USB_EPStoptXfer  Stop transfer on an EP
791
   * @param  USBx  usb device instance
792
   * @param  ep pointer to endpoint structure
793
   * @retval HAL status
794
   */
795
HAL_StatusTypeDef USB_EPStopXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
796
{
797
  __IO uint32_t count = 0U;
798
  HAL_StatusTypeDef ret = HAL_OK;
799
  uint32_t USBx_BASE = (uint32_t)USBx;
800
 
801
  /* IN endpoint */
802
  if (ep->is_in == 1U)
803
  {
804
    /* EP enable, IN data in FIFO */
805
    if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
806
    {
807
      USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_SNAK);
808
      USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_EPDIS);
809
 
810
      do
811
      {
812
        count++;
813
 
814
        if (count > 10000U)
815
        {
816
          ret = HAL_ERROR;
817
          break;
818
        }
819
      } while (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) ==  USB_OTG_DIEPCTL_EPENA);
820
    }
821
  }
822
  else /* OUT endpoint */
823
  {
824
    if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
825
    {
826
      USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_SNAK);
827
      USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_EPDIS);
828
 
829
      do
830
      {
831
        count++;
832
 
833
        if (count > 10000U)
834
        {
835
          ret = HAL_ERROR;
836
          break;
837
        }
838
      } while (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) ==  USB_OTG_DOEPCTL_EPENA);
839
    }
840
  }
841
 
842
  return ret;
843
}
844
 
845
 
846
/**
847
  * @brief  USB_WritePacket : Writes a packet into the Tx FIFO associated
848
  *         with the EP/channel
849
  * @param  USBx  Selected device
850
  * @param  src   pointer to source buffer
851
  * @param  ch_ep_num  endpoint or host channel number
852
  * @param  len  Number of bytes to write
853
  * @retval HAL status
854
  */
855
HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src,
856
                                  uint8_t ch_ep_num, uint16_t len)
857
{
858
  uint32_t USBx_BASE = (uint32_t)USBx;
859
  uint8_t *pSrc = src;
860
  uint32_t count32b;
861
  uint32_t i;
862
 
863
  count32b = ((uint32_t)len + 3U) / 4U;
864
  for (i = 0U; i < count32b; i++)
865
  {
866
    USBx_DFIFO((uint32_t)ch_ep_num) = __UNALIGNED_UINT32_READ(pSrc);
867
    pSrc++;
868
    pSrc++;
869
    pSrc++;
870
    pSrc++;
871
  }
872
 
873
  return HAL_OK;
874
}
875
 
876
/**
877
  * @brief  USB_ReadPacket : read a packet from the RX FIFO
878
  * @param  USBx  Selected device
879
  * @param  dest  source pointer
880
  * @param  len  Number of bytes to read
881
  * @retval pointer to destination buffer
882
  */
883
void *USB_ReadPacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len)
884
{
885
  uint32_t USBx_BASE = (uint32_t)USBx;
886
  uint8_t *pDest = dest;
887
  uint32_t pData;
888
  uint32_t i;
889
  uint32_t count32b = (uint32_t)len >> 2U;
890
  uint16_t remaining_bytes = len % 4U;
891
 
892
  for (i = 0U; i < count32b; i++)
893
  {
894
    __UNALIGNED_UINT32_WRITE(pDest, USBx_DFIFO(0U));
895
    pDest++;
896
    pDest++;
897
    pDest++;
898
    pDest++;
899
  }
900
 
901
  /* When Number of data is not word aligned, read the remaining byte */
902
  if (remaining_bytes != 0U)
903
  {
904
    i = 0U;
905
    __UNALIGNED_UINT32_WRITE(&pData, USBx_DFIFO(0U));
906
 
907
    do
908
    {
909
      *(uint8_t *)pDest = (uint8_t)(pData >> (8U * (uint8_t)(i)));
910
      i++;
911
      pDest++;
912
      remaining_bytes--;
913
    } while (remaining_bytes != 0U);
914
  }
915
 
916
  return ((void *)pDest);
917
}
918
 
919
/**
920
  * @brief  USB_EPSetStall : set a stall condition over an EP
921
  * @param  USBx  Selected device
922
  * @param  ep pointer to endpoint structure
923
  * @retval HAL status
924
  */
925
HAL_StatusTypeDef USB_EPSetStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
926
{
927
  uint32_t USBx_BASE = (uint32_t)USBx;
928
  uint32_t epnum = (uint32_t)ep->num;
929
 
930
  if (ep->is_in == 1U)
931
  {
932
    if (((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == 0U) && (epnum != 0U))
933
    {
934
      USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS);
935
    }
936
    USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
937
  }
938
  else
939
  {
940
    if (((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == 0U) && (epnum != 0U))
941
    {
942
      USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS);
943
    }
944
    USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
945
  }
946
 
947
  return HAL_OK;
948
}
949
 
950
/**
951
  * @brief  USB_EPClearStall : Clear a stall condition over an EP
952
  * @param  USBx  Selected device
953
  * @param  ep pointer to endpoint structure
954
  * @retval HAL status
955
  */
956
HAL_StatusTypeDef USB_EPClearStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
957
{
958
  uint32_t USBx_BASE = (uint32_t)USBx;
959
  uint32_t epnum = (uint32_t)ep->num;
960
 
961
  if (ep->is_in == 1U)
962
  {
963
    USBx_INEP(epnum)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
964
    if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
965
    {
966
      USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
967
    }
968
  }
969
  else
970
  {
971
    USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
972
    if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
973
    {
974
      USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
975
    }
976
  }
977
  return HAL_OK;
978
}
979
 
980
/**
981
  * @brief  USB_StopDevice : Stop the usb device mode
982
  * @param  USBx  Selected device
983
  * @retval HAL status
984
  */
985
HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx)
986
{
987
  HAL_StatusTypeDef ret;
988
  uint32_t USBx_BASE = (uint32_t)USBx;
989
  uint32_t i;
990
 
991
  /* Clear Pending interrupt */
992
  for (i = 0U; i < 15U; i++)
993
  {
994
    USBx_INEP(i)->DIEPINT = 0xFB7FU;
995
    USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
996
  }
997
 
998
  /* Clear interrupt masks */
999
  USBx_DEVICE->DIEPMSK  = 0U;
1000
  USBx_DEVICE->DOEPMSK  = 0U;
1001
  USBx_DEVICE->DAINTMSK = 0U;
1002
 
1003
  /* Flush the FIFO */
1004
  ret = USB_FlushRxFifo(USBx);
1005
  if (ret != HAL_OK)
1006
  {
1007
    return ret;
1008
  }
1009
 
1010
  ret = USB_FlushTxFifo(USBx,  0x10U);
1011
  if (ret != HAL_OK)
1012
  {
1013
    return ret;
1014
  }
1015
 
1016
  return ret;
1017
}
1018
 
1019
/**
1020
  * @brief  USB_SetDevAddress : Stop the usb device mode
1021
  * @param  USBx  Selected device
1022
  * @param  address  new device address to be assigned
1023
  *          This parameter can be a value from 0 to 255
1024
  * @retval HAL status
1025
  */
1026
HAL_StatusTypeDef USB_SetDevAddress(USB_OTG_GlobalTypeDef *USBx, uint8_t address)
1027
{
1028
  uint32_t USBx_BASE = (uint32_t)USBx;
1029
 
1030
  USBx_DEVICE->DCFG &= ~(USB_OTG_DCFG_DAD);
1031
  USBx_DEVICE->DCFG |= ((uint32_t)address << 4) & USB_OTG_DCFG_DAD;
1032
 
1033
  return HAL_OK;
1034
}
1035
 
1036
/**
1037
  * @brief  USB_DevConnect : Connect the USB device by enabling Rpu
1038
  * @param  USBx  Selected device
1039
  * @retval HAL status
1040
  */
1041
HAL_StatusTypeDef USB_DevConnect(USB_OTG_GlobalTypeDef *USBx)
1042
{
1043
  uint32_t USBx_BASE = (uint32_t)USBx;
1044
 
1045
  /* In case phy is stopped, ensure to ungate and restore the phy CLK */
1046
  USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
1047
 
1048
  USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS;
1049
 
1050
  return HAL_OK;
1051
}
1052
 
1053
/**
1054
  * @brief  USB_DevDisconnect : Disconnect the USB device by disabling Rpu
1055
  * @param  USBx  Selected device
1056
  * @retval HAL status
1057
  */
1058
HAL_StatusTypeDef USB_DevDisconnect(USB_OTG_GlobalTypeDef *USBx)
1059
{
1060
  uint32_t USBx_BASE = (uint32_t)USBx;
1061
 
1062
  /* In case phy is stopped, ensure to ungate and restore the phy CLK */
1063
  USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
1064
 
1065
  USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
1066
 
1067
  return HAL_OK;
1068
}
1069
 
1070
/**
1071
  * @brief  USB_ReadInterrupts: return the global USB interrupt status
1072
  * @param  USBx  Selected device
1073
  * @retval USB Global Interrupt status
1074
  */
1075
uint32_t USB_ReadInterrupts(USB_OTG_GlobalTypeDef const *USBx)
1076
{
1077
  uint32_t tmpreg;
1078
 
1079
  tmpreg = USBx->GINTSTS;
1080
  tmpreg &= USBx->GINTMSK;
1081
 
1082
  return tmpreg;
1083
}
1084
 
1085
/**
1086
  * @brief  USB_ReadChInterrupts: return USB channel interrupt status
1087
  * @param  USBx  Selected device
1088
  * @param  chnum Channel number
1089
  * @retval USB Channel Interrupt status
1090
  */
1091
uint32_t USB_ReadChInterrupts(USB_OTG_GlobalTypeDef *USBx, uint8_t chnum)
1092
{
1093
  uint32_t USBx_BASE = (uint32_t)USBx;
1094
  uint32_t tmpreg;
1095
 
1096
  tmpreg = USBx_HC(chnum)->HCINT;
1097
  tmpreg &= USBx_HC(chnum)->HCINTMSK;
1098
 
1099
  return tmpreg;
1100
}
1101
 
1102
/**
1103
  * @brief  USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
1104
  * @param  USBx  Selected device
1105
  * @retval USB Device OUT EP interrupt status
1106
  */
1107
uint32_t USB_ReadDevAllOutEpInterrupt(USB_OTG_GlobalTypeDef *USBx)
1108
{
1109
  uint32_t USBx_BASE = (uint32_t)USBx;
1110
  uint32_t tmpreg;
1111
 
1112
  tmpreg  = USBx_DEVICE->DAINT;
1113
  tmpreg &= USBx_DEVICE->DAINTMSK;
1114
 
1115
  return ((tmpreg & 0xffff0000U) >> 16);
1116
}
1117
 
1118
/**
1119
  * @brief  USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
1120
  * @param  USBx  Selected device
1121
  * @retval USB Device IN EP interrupt status
1122
  */
1123
uint32_t USB_ReadDevAllInEpInterrupt(USB_OTG_GlobalTypeDef *USBx)
1124
{
1125
  uint32_t USBx_BASE = (uint32_t)USBx;
1126
  uint32_t tmpreg;
1127
 
1128
  tmpreg  = USBx_DEVICE->DAINT;
1129
  tmpreg &= USBx_DEVICE->DAINTMSK;
1130
 
1131
  return ((tmpreg & 0xFFFFU));
1132
}
1133
 
1134
/**
1135
  * @brief  Returns Device OUT EP Interrupt register
1136
  * @param  USBx  Selected device
1137
  * @param  epnum  endpoint number
1138
  *          This parameter can be a value from 0 to 15
1139
  * @retval Device OUT EP Interrupt register
1140
  */
1141
uint32_t USB_ReadDevOutEPInterrupt(USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
1142
{
1143
  uint32_t USBx_BASE = (uint32_t)USBx;
1144
  uint32_t tmpreg;
1145
 
1146
  tmpreg  = USBx_OUTEP((uint32_t)epnum)->DOEPINT;
1147
  tmpreg &= USBx_DEVICE->DOEPMSK;
1148
 
1149
  return tmpreg;
1150
}
1151
 
1152
/**
1153
  * @brief  Returns Device IN EP Interrupt register
1154
  * @param  USBx  Selected device
1155
  * @param  epnum  endpoint number
1156
  *          This parameter can be a value from 0 to 15
1157
  * @retval Device IN EP Interrupt register
1158
  */
1159
uint32_t USB_ReadDevInEPInterrupt(USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
1160
{
1161
  uint32_t USBx_BASE = (uint32_t)USBx;
1162
  uint32_t tmpreg;
1163
  uint32_t msk;
1164
  uint32_t emp;
1165
 
1166
  msk = USBx_DEVICE->DIEPMSK;
1167
  emp = USBx_DEVICE->DIEPEMPMSK;
1168
  msk |= ((emp >> (epnum & EP_ADDR_MSK)) & 0x1U) << 7;
1169
  tmpreg = USBx_INEP((uint32_t)epnum)->DIEPINT & msk;
1170
 
1171
  return tmpreg;
1172
}
1173
 
1174
/**
1175
  * @brief  USB_ClearInterrupts: clear a USB interrupt
1176
  * @param  USBx  Selected device
1177
  * @param  interrupt  flag
1178
  * @retval None
1179
  */
1180
void  USB_ClearInterrupts(USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt)
1181
{
1182
  USBx->GINTSTS &= interrupt;
1183
}
1184
 
1185
/**
1186
  * @brief  Returns USB core mode
1187
  * @param  USBx  Selected device
1188
  * @retval return core mode : Host or Device
1189
  *          This parameter can be one of these values:
1190
  *           0 : Host
1191
  *           1 : Device
1192
  */
1193
uint32_t USB_GetMode(USB_OTG_GlobalTypeDef *USBx)
1194
{
1195
  return ((USBx->GINTSTS) & 0x1U);
1196
}
1197
 
1198
/**
1199
  * @brief  Activate EP0 for Setup transactions
1200
  * @param  USBx  Selected device
1201
  * @retval HAL status
1202
  */
1203
HAL_StatusTypeDef USB_ActivateSetup(USB_OTG_GlobalTypeDef *USBx)
1204
{
1205
  uint32_t USBx_BASE = (uint32_t)USBx;
1206
 
1207
  /* Set the MPS of the IN EP0 to 64 bytes */
1208
  USBx_INEP(0U)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ;
1209
 
1210
  USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;
1211
 
1212
  return HAL_OK;
1213
}
1214
 
1215
/**
1216
  * @brief  Prepare the EP0 to start the first control setup
1217
  * @param  USBx  Selected device
1218
  * @param  psetup  pointer to setup packet
1219
  * @retval HAL status
1220
  */
1221
HAL_StatusTypeDef USB_EP0_OutStart(USB_OTG_GlobalTypeDef *USBx, uint8_t *psetup)
1222
{
1223
  uint32_t USBx_BASE = (uint32_t)USBx;
1224
  uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U);
1225
  UNUSED(psetup);
1226
 
1227
  if (gSNPSiD > USB_OTG_CORE_ID_300A)
1228
  {
1229
    if ((USBx_OUTEP(0U)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
1230
    {
1231
      return HAL_OK;
1232
    }
1233
  }
1234
 
1235
  USBx_OUTEP(0U)->DOEPTSIZ = 0U;
1236
  USBx_OUTEP(0U)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
1237
  USBx_OUTEP(0U)->DOEPTSIZ |= (3U * 8U);
1238
  USBx_OUTEP(0U)->DOEPTSIZ |=  USB_OTG_DOEPTSIZ_STUPCNT;
1239
 
1240
  return HAL_OK;
1241
}
1242
 
1243
/**
1244
  * @brief  Reset the USB Core (needed after USB clock settings change)
1245
  * @param  USBx  Selected device
1246
  * @retval HAL status
1247
  */
1248
static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
1249
{
1250
  __IO uint32_t count = 0U;
1251
 
1252
  /* Wait for AHB master IDLE state. */
1253
  do
1254
  {
1255
    count++;
1256
 
1257
    if (count > 200000U)
1258
    {
1259
      return HAL_TIMEOUT;
1260
    }
1261
  } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
1262
 
1263
  /* Core Soft Reset */
1264
  count = 0U;
1265
  USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
1266
 
1267
  do
1268
  {
1269
    count++;
1270
 
1271
    if (count > 200000U)
1272
    {
1273
      return HAL_TIMEOUT;
1274
    }
1275
  } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
1276
 
1277
  return HAL_OK;
1278
}
1279
 
1280
/**
1281
  * @brief  USB_HostInit : Initializes the USB OTG controller registers
1282
  *         for Host mode
1283
  * @param  USBx  Selected device
1284
  * @param  cfg   pointer to a USB_OTG_CfgTypeDef structure that contains
1285
  *         the configuration information for the specified USBx peripheral.
1286
  * @retval HAL status
1287
  */
1288
HAL_StatusTypeDef USB_HostInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
1289
{
1290
  HAL_StatusTypeDef ret = HAL_OK;
1291
  uint32_t USBx_BASE = (uint32_t)USBx;
1292
  uint32_t i;
1293
 
1294
  /* Restart the Phy Clock */
1295
  USBx_PCGCCTL = 0U;
1296
 
1297
  /* Disable VBUS sensing */
1298
  USBx->GCCFG &= ~(USB_OTG_GCCFG_VBUSASEN);
1299
  USBx->GCCFG &= ~(USB_OTG_GCCFG_VBUSBSEN);
1300
  /* Set default Max speed support */
1301
  USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
1302
 
1303
  /* Make sure the FIFOs are flushed. */
1304
  if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
1305
  {
1306
    ret = HAL_ERROR;
1307
  }
1308
 
1309
  if (USB_FlushRxFifo(USBx) != HAL_OK)
1310
  {
1311
    ret = HAL_ERROR;
1312
  }
1313
 
1314
  /* Clear all pending HC Interrupts */
1315
  for (i = 0U; i < cfg.Host_channels; i++)
1316
  {
1317
    USBx_HC(i)->HCINT = CLEAR_INTERRUPT_MASK;
1318
    USBx_HC(i)->HCINTMSK = 0U;
1319
  }
1320
 
1321
  /* Disable all interrupts. */
1322
  USBx->GINTMSK = 0U;
1323
 
1324
  /* Clear any pending interrupts */
1325
  USBx->GINTSTS = CLEAR_INTERRUPT_MASK;
1326
 
1327
  /* set Rx FIFO size */
1328
  USBx->GRXFSIZ  = 0x80U;
1329
  USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((0x60U << 16) & USB_OTG_NPTXFD) | 0x80U);
1330
  USBx->HPTXFSIZ = (uint32_t)(((0x40U << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0xE0U);
1331
  /* Enable the common interrupts */
1332
  USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
1333
 
1334
  /* Enable interrupts matching to the Host mode ONLY */
1335
  USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM            | USB_OTG_GINTMSK_HCIM | \
1336
                    USB_OTG_GINTMSK_SOFM             | USB_OTG_GINTSTS_DISCINT | \
1337
                    USB_OTG_GINTMSK_PXFRM_IISOOXFRM  | USB_OTG_GINTMSK_WUIM);
1338
 
1339
  return ret;
1340
}
1341
 
1342
/**
1343
  * @brief  USB_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the
1344
  *         HCFG register on the PHY type and set the right frame interval
1345
  * @param  USBx  Selected device
1346
  * @param  freq  clock frequency
1347
  *          This parameter can be one of these values:
1348
  *           HCFG_48_MHZ : Full Speed 48 MHz Clock
1349
  *           HCFG_6_MHZ : Low Speed 6 MHz Clock
1350
  * @retval HAL status
1351
  */
1352
HAL_StatusTypeDef USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef *USBx, uint8_t freq)
1353
{
1354
  uint32_t USBx_BASE = (uint32_t)USBx;
1355
 
1356
  USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSPCS);
1357
  USBx_HOST->HCFG |= (uint32_t)freq & USB_OTG_HCFG_FSLSPCS;
1358
 
1359
  if (freq == HCFG_48_MHZ)
1360
  {
1361
    USBx_HOST->HFIR = HFIR_48_MHZ;
1362
  }
1363
  else if (freq == HCFG_6_MHZ)
1364
  {
1365
    USBx_HOST->HFIR = HFIR_6_MHZ;
1366
  }
1367
  else
1368
  {
1369
    return HAL_ERROR;
1370
  }
1371
 
1372
  return HAL_OK;
1373
}
1374
 
1375
/**
1376
  * @brief  USB_OTG_ResetPort : Reset Host Port
1377
  * @param  USBx  Selected device
1378
  * @retval HAL status
1379
  * @note (1)The application must wait at least 10 ms
1380
  *   before clearing the reset bit.
1381
  */
1382
HAL_StatusTypeDef USB_ResetPort(USB_OTG_GlobalTypeDef *USBx)
1383
{
1384
  uint32_t USBx_BASE = (uint32_t)USBx;
1385
 
1386
  __IO uint32_t hprt0 = 0U;
1387
 
1388
  hprt0 = USBx_HPRT0;
1389
 
1390
  hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
1391
             USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1392
 
1393
  USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0);
1394
  HAL_Delay(100U);                                 /* See Note #1 */
1395
  USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0);
1396
  HAL_Delay(10U);
1397
 
1398
  return HAL_OK;
1399
}
1400
 
1401
/**
1402
  * @brief  USB_DriveVbus : activate or de-activate vbus
1403
  * @param  state  VBUS state
1404
  *          This parameter can be one of these values:
1405
  *           0 : Deactivate VBUS
1406
  *           1 : Activate VBUS
1407
  * @retval HAL status
1408
  */
1409
HAL_StatusTypeDef USB_DriveVbus(USB_OTG_GlobalTypeDef *USBx, uint8_t state)
1410
{
1411
  uint32_t USBx_BASE = (uint32_t)USBx;
1412
  __IO uint32_t hprt0 = 0U;
1413
 
1414
  hprt0 = USBx_HPRT0;
1415
 
1416
  hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
1417
             USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1418
 
1419
  if (((hprt0 & USB_OTG_HPRT_PPWR) == 0U) && (state == 1U))
1420
  {
1421
    USBx_HPRT0 = (USB_OTG_HPRT_PPWR | hprt0);
1422
  }
1423
  if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0U))
1424
  {
1425
    USBx_HPRT0 = ((~USB_OTG_HPRT_PPWR) & hprt0);
1426
  }
1427
  return HAL_OK;
1428
}
1429
 
1430
/**
1431
  * @brief  Return Host Core speed
1432
  * @param  USBx  Selected device
1433
  * @retval speed : Host speed
1434
  *          This parameter can be one of these values:
1435
  *            @arg HCD_SPEED_FULL: Full speed mode
1436
  *            @arg HCD_SPEED_LOW: Low speed mode
1437
  */
1438
uint32_t USB_GetHostSpeed(USB_OTG_GlobalTypeDef const *USBx)
1439
{
1440
  uint32_t USBx_BASE = (uint32_t)USBx;
1441
  __IO uint32_t hprt0 = 0U;
1442
 
1443
  hprt0 = USBx_HPRT0;
1444
  return ((hprt0 & USB_OTG_HPRT_PSPD) >> 17);
1445
}
1446
 
1447
/**
1448
  * @brief  Return Host Current Frame number
1449
  * @param  USBx  Selected device
1450
  * @retval current frame number
1451
  */
1452
uint32_t USB_GetCurrentFrame(USB_OTG_GlobalTypeDef const *USBx)
1453
{
1454
  uint32_t USBx_BASE = (uint32_t)USBx;
1455
 
1456
  return (USBx_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);
1457
}
1458
 
1459
/**
1460
  * @brief  Initialize a host channel
1461
  * @param  USBx  Selected device
1462
  * @param  ch_num  Channel number
1463
  *         This parameter can be a value from 1 to 15
1464
  * @param  epnum  Endpoint number
1465
  *          This parameter can be a value from 1 to 15
1466
  * @param  dev_address  Current device address
1467
  *          This parameter can be a value from 0 to 255
1468
  * @param  speed  Current device speed
1469
  *          This parameter can be one of these values:
1470
  *            @arg USB_OTG_SPEED_FULL: Full speed mode
1471
  *            @arg USB_OTG_SPEED_LOW: Low speed mode
1472
  * @param  ep_type  Endpoint Type
1473
  *          This parameter can be one of these values:
1474
  *            @arg EP_TYPE_CTRL: Control type
1475
  *            @arg EP_TYPE_ISOC: Isochronous type
1476
  *            @arg EP_TYPE_BULK: Bulk type
1477
  *            @arg EP_TYPE_INTR: Interrupt type
1478
  * @param  mps  Max Packet Size
1479
  *          This parameter can be a value from 0 to 32K
1480
  * @retval HAL state
1481
  */
1482
HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num,
1483
                              uint8_t epnum, uint8_t dev_address, uint8_t speed,
1484
                              uint8_t ep_type, uint16_t mps)
1485
{
1486
  HAL_StatusTypeDef ret = HAL_OK;
1487
  uint32_t USBx_BASE = (uint32_t)USBx;
1488
  uint32_t HCcharEpDir;
1489
  uint32_t HCcharLowSpeed;
1490
  uint32_t HostCoreSpeed;
1491
 
1492
  /* Clear old interrupt conditions for this host channel. */
1493
  USBx_HC((uint32_t)ch_num)->HCINT = CLEAR_INTERRUPT_MASK;
1494
 
1495
  /* Enable channel interrupts required for this transfer. */
1496
  switch (ep_type)
1497
  {
1498
    case EP_TYPE_CTRL:
1499
    case EP_TYPE_BULK:
1500
      USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM  |
1501
                                            USB_OTG_HCINTMSK_STALLM |
1502
                                            USB_OTG_HCINTMSK_TXERRM |
1503
                                            USB_OTG_HCINTMSK_DTERRM |
1504
                                            USB_OTG_HCINTMSK_AHBERR |
1505
                                            USB_OTG_HCINTMSK_NAKM;
1506
 
1507
      if ((epnum & 0x80U) == 0x80U)
1508
      {
1509
        USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1510
      }
1511
      break;
1512
 
1513
    case EP_TYPE_INTR:
1514
      USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM  |
1515
                                            USB_OTG_HCINTMSK_STALLM |
1516
                                            USB_OTG_HCINTMSK_TXERRM |
1517
                                            USB_OTG_HCINTMSK_DTERRM |
1518
                                            USB_OTG_HCINTMSK_NAKM   |
1519
                                            USB_OTG_HCINTMSK_AHBERR |
1520
                                            USB_OTG_HCINTMSK_FRMORM;
1521
 
1522
      if ((epnum & 0x80U) == 0x80U)
1523
      {
1524
        USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1525
      }
1526
 
1527
      break;
1528
 
1529
    case EP_TYPE_ISOC:
1530
      USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM  |
1531
                                            USB_OTG_HCINTMSK_ACKM   |
1532
                                            USB_OTG_HCINTMSK_AHBERR |
1533
                                            USB_OTG_HCINTMSK_FRMORM;
1534
 
1535
      if ((epnum & 0x80U) == 0x80U)
1536
      {
1537
        USBx_HC((uint32_t)ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM);
1538
      }
1539
      break;
1540
 
1541
    default:
1542
      ret = HAL_ERROR;
1543
      break;
1544
  }
1545
 
1546
  /* Enable host channel Halt interrupt */
1547
  USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_CHHM;
1548
 
1549
  /* Enable the top level host channel interrupt. */
1550
  USBx_HOST->HAINTMSK |= 1UL << (ch_num & 0xFU);
1551
 
1552
  /* Make sure host channel interrupts are enabled. */
1553
  USBx->GINTMSK |= USB_OTG_GINTMSK_HCIM;
1554
 
1555
  /* Program the HCCHAR register */
1556
  if ((epnum & 0x80U) == 0x80U)
1557
  {
1558
    HCcharEpDir = (0x1U << 15) & USB_OTG_HCCHAR_EPDIR;
1559
  }
1560
  else
1561
  {
1562
    HCcharEpDir = 0U;
1563
  }
1564
 
1565
  HostCoreSpeed = USB_GetHostSpeed(USBx);
1566
 
1567
  /* LS device plugged to HUB */
1568
  if ((speed == HPRT0_PRTSPD_LOW_SPEED) && (HostCoreSpeed != HPRT0_PRTSPD_LOW_SPEED))
1569
  {
1570
    HCcharLowSpeed = (0x1U << 17) & USB_OTG_HCCHAR_LSDEV;
1571
  }
1572
  else
1573
  {
1574
    HCcharLowSpeed = 0U;
1575
  }
1576
 
1577
  USBx_HC((uint32_t)ch_num)->HCCHAR = (((uint32_t)dev_address << 22) & USB_OTG_HCCHAR_DAD) |
1578
                                      ((((uint32_t)epnum & 0x7FU) << 11) & USB_OTG_HCCHAR_EPNUM) |
1579
                                      (((uint32_t)ep_type << 18) & USB_OTG_HCCHAR_EPTYP) |
1580
                                      ((uint32_t)mps & USB_OTG_HCCHAR_MPSIZ) |
1581
                                      USB_OTG_HCCHAR_MC_0 | HCcharEpDir | HCcharLowSpeed;
1582
 
1583
  if ((ep_type == EP_TYPE_INTR) || (ep_type == EP_TYPE_ISOC))
1584
  {
1585
    USBx_HC((uint32_t)ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
1586
  }
1587
 
1588
  return ret;
1589
}
1590
 
1591
/**
1592
  * @brief  Start a transfer over a host channel
1593
  * @param  USBx  Selected device
1594
  * @param  hc  pointer to host channel structure
1595
  * @retval HAL state
1596
  */
1597
HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc)
1598
{
1599
  uint32_t USBx_BASE = (uint32_t)USBx;
1600
  uint32_t ch_num = (uint32_t)hc->ch_num;
1601
  __IO uint32_t tmpreg;
1602
  uint8_t  is_oddframe;
1603
  uint16_t len_words;
1604
  uint16_t num_packets;
1605
  uint16_t max_hc_pkt_count = HC_MAX_PKT_CNT;
1606
 
1607
  /* Compute the expected number of packets associated to the transfer */
1608
  if (hc->xfer_len > 0U)
1609
  {
1610
    num_packets = (uint16_t)((hc->xfer_len + hc->max_packet - 1U) / hc->max_packet);
1611
 
1612
    if (num_packets > max_hc_pkt_count)
1613
    {
1614
      num_packets = max_hc_pkt_count;
1615
      hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1616
    }
1617
  }
1618
  else
1619
  {
1620
    num_packets = 1U;
1621
  }
1622
 
1623
  /*
1624
   * For IN channel HCTSIZ.XferSize is expected to be an integer multiple of
1625
   * max_packet size.
1626
   */
1627
  if (hc->ep_is_in != 0U)
1628
  {
1629
    hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1630
  }
1631
  else
1632
  {
1633
    hc->XferSize = hc->xfer_len;
1634
  }
1635
 
1636
  /* Initialize the HCTSIZn register */
1637
  USBx_HC(ch_num)->HCTSIZ = (hc->XferSize & USB_OTG_HCTSIZ_XFRSIZ) |
1638
                            (((uint32_t)num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
1639
                            (((uint32_t)hc->data_pid << 29) & USB_OTG_HCTSIZ_DPID);
1640
 
1641
  is_oddframe = (((uint32_t)USBx_HOST->HFNUM & 0x01U) != 0U) ? 0U : 1U;
1642
  USBx_HC(ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM;
1643
  USBx_HC(ch_num)->HCCHAR |= (uint32_t)is_oddframe << 29;
1644
 
1645
  /* Set host channel enable */
1646
  tmpreg = USBx_HC(ch_num)->HCCHAR;
1647
  tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1648
 
1649
  /* make sure to set the correct ep direction */
1650
  if (hc->ep_is_in != 0U)
1651
  {
1652
    tmpreg |= USB_OTG_HCCHAR_EPDIR;
1653
  }
1654
  else
1655
  {
1656
    tmpreg &= ~USB_OTG_HCCHAR_EPDIR;
1657
  }
1658
  tmpreg |= USB_OTG_HCCHAR_CHENA;
1659
  USBx_HC(ch_num)->HCCHAR = tmpreg;
1660
 
1661
  if ((hc->ep_is_in == 0U) && (hc->xfer_len > 0U))
1662
  {
1663
    switch (hc->ep_type)
1664
    {
1665
      /* Non periodic transfer */
1666
      case EP_TYPE_CTRL:
1667
      case EP_TYPE_BULK:
1668
 
1669
        len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
1670
 
1671
        /* check if there is enough space in FIFO space */
1672
        if (len_words > (USBx->HNPTXSTS & 0xFFFFU))
1673
        {
1674
          /* need to process data in nptxfempty interrupt */
1675
          USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM;
1676
        }
1677
        break;
1678
 
1679
      /* Periodic transfer */
1680
      case EP_TYPE_INTR:
1681
      case EP_TYPE_ISOC:
1682
        len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
1683
        /* check if there is enough space in FIFO space */
1684
        if (len_words > (USBx_HOST->HPTXSTS & 0xFFFFU)) /* split the transfer */
1685
        {
1686
          /* need to process data in ptxfempty interrupt */
1687
          USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM;
1688
        }
1689
        break;
1690
 
1691
      default:
1692
        break;
1693
    }
1694
 
1695
    /* Write packet into the Tx FIFO. */
1696
    (void)USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, (uint16_t)hc->xfer_len);
1697
  }
1698
 
1699
  return HAL_OK;
1700
}
1701
 
1702
/**
1703
  * @brief Read all host channel interrupts status
1704
  * @param  USBx  Selected device
1705
  * @retval HAL state
1706
  */
1707
uint32_t USB_HC_ReadInterrupt(USB_OTG_GlobalTypeDef *USBx)
1708
{
1709
  uint32_t USBx_BASE = (uint32_t)USBx;
1710
 
1711
  return ((USBx_HOST->HAINT) & 0xFFFFU);
1712
}
1713
 
1714
/**
1715
  * @brief  Halt a host channel
1716
  * @param  USBx  Selected device
1717
  * @param  hc_num  Host Channel number
1718
  *         This parameter can be a value from 1 to 15
1719
  * @retval HAL state
1720
  */
1721
HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx, uint8_t hc_num)
1722
{
1723
  uint32_t USBx_BASE = (uint32_t)USBx;
1724
  uint32_t hcnum = (uint32_t)hc_num;
1725
  __IO uint32_t count = 0U;
1726
  uint32_t HcEpType = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_EPTYP) >> 18;
1727
  uint32_t ChannelEna = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) >> 31;
1728
  uint32_t SplitEna = (USBx_HC(hcnum)->HCSPLT & USB_OTG_HCSPLT_SPLITEN) >> 31;
1729
 
1730
  /* In buffer DMA, Channel disable must not be programmed for non-split periodic channels.
1731
     At the end of the next uframe/frame (in the worst case), the core generates a channel halted
1732
     and disables the channel automatically. */
1733
 
1734
  if ((((USBx->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == USB_OTG_GAHBCFG_DMAEN) && (SplitEna == 0U)) &&
1735
      ((ChannelEna == 0U) || (((HcEpType == HCCHAR_ISOC) || (HcEpType == HCCHAR_INTR)))))
1736
  {
1737
    return HAL_OK;
1738
  }
1739
 
1740
  /* Check for space in the request queue to issue the halt. */
1741
  if ((HcEpType == HCCHAR_CTRL) || (HcEpType == HCCHAR_BULK))
1742
  {
1743
    USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
1744
 
1745
    if ((USBx->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == 0U)
1746
    {
1747
      if ((USBx->HNPTXSTS & (0xFFU << 16)) == 0U)
1748
      {
1749
        USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
1750
        USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1751
        do
1752
        {
1753
          count++;
1754
 
1755
          if (count > 1000U)
1756
          {
1757
            break;
1758
          }
1759
        } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1760
      }
1761
      else
1762
      {
1763
        USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1764
      }
1765
    }
1766
    else
1767
    {
1768
      USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1769
    }
1770
  }
1771
  else
1772
  {
1773
    USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
1774
 
1775
    if ((USBx_HOST->HPTXSTS & (0xFFU << 16)) == 0U)
1776
    {
1777
      USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
1778
      USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1779
      do
1780
      {
1781
        count++;
1782
 
1783
        if (count > 1000U)
1784
        {
1785
          break;
1786
        }
1787
      } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1788
    }
1789
    else
1790
    {
1791
      USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1792
    }
1793
  }
1794
 
1795
  return HAL_OK;
1796
}
1797
 
1798
/**
1799
  * @brief  Initiate Do Ping protocol
1800
  * @param  USBx  Selected device
1801
  * @param  hc_num  Host Channel number
1802
  *         This parameter can be a value from 1 to 15
1803
  * @retval HAL state
1804
  */
1805
HAL_StatusTypeDef USB_DoPing(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num)
1806
{
1807
  uint32_t USBx_BASE = (uint32_t)USBx;
1808
  uint32_t chnum = (uint32_t)ch_num;
1809
  uint32_t num_packets = 1U;
1810
  uint32_t tmpreg;
1811
 
1812
  USBx_HC(chnum)->HCTSIZ = ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
1813
                           USB_OTG_HCTSIZ_DOPING;
1814
 
1815
  /* Set host channel enable */
1816
  tmpreg = USBx_HC(chnum)->HCCHAR;
1817
  tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1818
  tmpreg |= USB_OTG_HCCHAR_CHENA;
1819
  USBx_HC(chnum)->HCCHAR = tmpreg;
1820
 
1821
  return HAL_OK;
1822
}
1823
 
1824
/**
1825
  * @brief  Stop Host Core
1826
  * @param  USBx  Selected device
1827
  * @retval HAL state
1828
  */
1829
HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx)
1830
{
1831
  HAL_StatusTypeDef ret = HAL_OK;
1832
  uint32_t USBx_BASE = (uint32_t)USBx;
1833
  __IO uint32_t count = 0U;
1834
  uint32_t value;
1835
  uint32_t i;
1836
 
1837
  (void)USB_DisableGlobalInt(USBx);
1838
 
1839
  /* Flush USB FIFO */
1840
  if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
1841
  {
1842
    ret = HAL_ERROR;
1843
  }
1844
 
1845
  if (USB_FlushRxFifo(USBx) != HAL_OK)
1846
  {
1847
    ret = HAL_ERROR;
1848
  }
1849
 
1850
  /* Flush out any leftover queued requests. */
1851
  for (i = 0U; i <= 15U; i++)
1852
  {
1853
    value = USBx_HC(i)->HCCHAR;
1854
    value |=  USB_OTG_HCCHAR_CHDIS;
1855
    value &= ~USB_OTG_HCCHAR_CHENA;
1856
    value &= ~USB_OTG_HCCHAR_EPDIR;
1857
    USBx_HC(i)->HCCHAR = value;
1858
  }
1859
 
1860
  /* Halt all channels to put them into a known state. */
1861
  for (i = 0U; i <= 15U; i++)
1862
  {
1863
    value = USBx_HC(i)->HCCHAR;
1864
    value |= USB_OTG_HCCHAR_CHDIS;
1865
    value |= USB_OTG_HCCHAR_CHENA;
1866
    value &= ~USB_OTG_HCCHAR_EPDIR;
1867
    USBx_HC(i)->HCCHAR = value;
1868
 
1869
    do
1870
    {
1871
      count++;
1872
 
1873
      if (count > 1000U)
1874
      {
1875
        break;
1876
      }
1877
    } while ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1878
  }
1879
 
1880
  /* Clear any pending Host interrupts */
1881
  USBx_HOST->HAINT = CLEAR_INTERRUPT_MASK;
1882
  USBx->GINTSTS = CLEAR_INTERRUPT_MASK;
1883
 
1884
  (void)USB_EnableGlobalInt(USBx);
1885
 
1886
  return ret;
1887
}
1888
 
1889
/**
1890
  * @brief  USB_ActivateRemoteWakeup active remote wakeup signalling
1891
  * @param  USBx Selected device
1892
  * @retval HAL status
1893
  */
1894
HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx)
1895
{
1896
  uint32_t USBx_BASE = (uint32_t)USBx;
1897
 
1898
  if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
1899
  {
1900
    /* active Remote wakeup signalling */
1901
    USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG;
1902
  }
1903
 
1904
  return HAL_OK;
1905
}
1906
 
1907
/**
1908
  * @brief  USB_DeActivateRemoteWakeup de-active remote wakeup signalling
1909
  * @param  USBx Selected device
1910
  * @retval HAL status
1911
  */
1912
HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx)
1913
{
1914
  uint32_t USBx_BASE = (uint32_t)USBx;
1915
 
1916
  /* active Remote wakeup signalling */
1917
  USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG);
1918
 
1919
  return HAL_OK;
1920
}
1921
#endif /* defined (USB_OTG_FS) */
1922
 
1923
#if defined (USB)
1924
/**
1925
  * @brief  Initializes the USB Core
1926
  * @param  USBx USB Instance
1927
  * @param  cfg pointer to a USB_CfgTypeDef structure that contains
1928
  *         the configuration information for the specified USBx peripheral.
1929
  * @retval HAL status
1930
  */
1931
HAL_StatusTypeDef USB_CoreInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg)
1932
{
1933
  /* Prevent unused argument(s) compilation warning */
1934
  UNUSED(USBx);
1935
  UNUSED(cfg);
1936
 
1937
  /* NOTE : - This function is not required by USB Device FS peripheral, it is used
1938
              only by USB OTG FS peripheral.
1939
            - This function is added to ensure compatibility across platforms.
1940
   */
1941
 
1942
  return HAL_OK;
1943
}
1944
 
1945
/**
1946
  * @brief  USB_EnableGlobalInt
1947
  *         Enables the controller's Global Int in the AHB Config reg
1948
  * @param  USBx Selected device
1949
  * @retval HAL status
1950
  */
1951
HAL_StatusTypeDef USB_EnableGlobalInt(USB_TypeDef *USBx)
1952
{
1953
  uint32_t winterruptmask;
1954
 
1955
  /* Clear pending interrupts */
1956
  USBx->ISTR = 0U;
1957
 
1958
  /* Set winterruptmask variable */
1959
  winterruptmask = USB_CNTR_CTRM  | USB_CNTR_WKUPM |
1960
                   USB_CNTR_SUSPM | USB_CNTR_ERRM |
1961
                   USB_CNTR_SOFM | USB_CNTR_ESOFM |
1962
                   USB_CNTR_RESETM;
1963
 
1964
  /* Set interrupt mask */
1965
  USBx->CNTR = (uint16_t)winterruptmask;
1966
 
1967
  return HAL_OK;
1968
}
1969
 
1970
/**
1971
  * @brief  USB_DisableGlobalInt
1972
  *         Disable the controller's Global Int in the AHB Config reg
1973
  * @param  USBx Selected device
1974
  * @retval HAL status
1975
  */
1976
HAL_StatusTypeDef USB_DisableGlobalInt(USB_TypeDef *USBx)
1977
{
1978
  uint32_t winterruptmask;
1979
 
1980
  /* Set winterruptmask variable */
1981
  winterruptmask = USB_CNTR_CTRM  | USB_CNTR_WKUPM |
1982
                   USB_CNTR_SUSPM | USB_CNTR_ERRM |
1983
                   USB_CNTR_SOFM | USB_CNTR_ESOFM |
1984
                   USB_CNTR_RESETM;
1985
 
1986
  /* Clear interrupt mask */
1987
  USBx->CNTR &= (uint16_t)(~winterruptmask);
1988
 
1989
  return HAL_OK;
1990
}
1991
 
1992
/**
1993
  * @brief  USB_SetCurrentMode Set functional mode
1994
  * @param  USBx Selected device
1995
  * @param  mode current core mode
1996
  *          This parameter can be one of the these values:
1997
  *            @arg USB_DEVICE_MODE Peripheral mode
1998
  * @retval HAL status
1999
  */
2000
HAL_StatusTypeDef USB_SetCurrentMode(USB_TypeDef *USBx, USB_ModeTypeDef mode)
2001
{
2002
  /* Prevent unused argument(s) compilation warning */
2003
  UNUSED(USBx);
2004
  UNUSED(mode);
2005
 
2006
  /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2007
              only by USB OTG FS peripheral.
2008
            - This function is added to ensure compatibility across platforms.
2009
   */
2010
  return HAL_OK;
2011
}
2012
 
2013
/**
2014
  * @brief  USB_DevInit Initializes the USB controller registers
2015
  *         for device mode
2016
  * @param  USBx Selected device
2017
  * @param  cfg  pointer to a USB_CfgTypeDef structure that contains
2018
  *         the configuration information for the specified USBx peripheral.
2019
  * @retval HAL status
2020
  */
2021
HAL_StatusTypeDef USB_DevInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg)
2022
{
2023
  /* Prevent unused argument(s) compilation warning */
2024
  UNUSED(cfg);
2025
 
2026
  /* Init Device */
2027
  /* CNTR_FRES = 1 */
2028
  USBx->CNTR = (uint16_t)USB_CNTR_FRES;
2029
 
2030
  /* CNTR_FRES = 0 */
2031
  USBx->CNTR = 0U;
2032
 
2033
  /* Clear pending interrupts */
2034
  USBx->ISTR = 0U;
2035
 
2036
  /*Set Btable Address*/
2037
  USBx->BTABLE = BTABLE_ADDRESS;
2038
 
2039
  return HAL_OK;
2040
}
2041
 
2042
/**
2043
  * @brief  USB_FlushTxFifo : Flush a Tx FIFO
2044
  * @param  USBx : Selected device
2045
  * @param  num : FIFO number
2046
  *         This parameter can be a value from 1 to 15
2047
            15 means Flush all Tx FIFOs
2048
  * @retval HAL status
2049
  */
2050
HAL_StatusTypeDef USB_FlushTxFifo(USB_TypeDef const *USBx, uint32_t num)
2051
{
2052
  /* Prevent unused argument(s) compilation warning */
2053
  UNUSED(USBx);
2054
  UNUSED(num);
2055
 
2056
  /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2057
              only by USB OTG FS peripheral.
2058
            - This function is added to ensure compatibility across platforms.
2059
   */
2060
 
2061
  return HAL_OK;
2062
}
2063
 
2064
/**
2065
  * @brief  USB_FlushRxFifo : Flush Rx FIFO
2066
  * @param  USBx : Selected device
2067
  * @retval HAL status
2068
  */
2069
HAL_StatusTypeDef USB_FlushRxFifo(USB_TypeDef const *USBx)
2070
{
2071
  /* Prevent unused argument(s) compilation warning */
2072
  UNUSED(USBx);
2073
 
2074
  /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2075
              only by USB OTG FS peripheral.
2076
            - This function is added to ensure compatibility across platforms.
2077
   */
2078
 
2079
  return HAL_OK;
2080
}
2081
 
2082
 
2083
#if defined (HAL_PCD_MODULE_ENABLED)
2084
/**
2085
  * @brief  Activate and configure an endpoint
2086
  * @param  USBx Selected device
2087
  * @param  ep pointer to endpoint structure
2088
  * @retval HAL status
2089
  */
2090
HAL_StatusTypeDef USB_ActivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
2091
{
2092
  HAL_StatusTypeDef ret = HAL_OK;
2093
  uint16_t wEpRegVal;
2094
 
2095
  wEpRegVal = PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_T_MASK;
2096
 
2097
  /* initialize Endpoint */
2098
  switch (ep->type)
2099
  {
2100
    case EP_TYPE_CTRL:
2101
      wEpRegVal |= USB_EP_CONTROL;
2102
      break;
2103
 
2104
    case EP_TYPE_BULK:
2105
      wEpRegVal |= USB_EP_BULK;
2106
      break;
2107
 
2108
    case EP_TYPE_INTR:
2109
      wEpRegVal |= USB_EP_INTERRUPT;
2110
      break;
2111
 
2112
    case EP_TYPE_ISOC:
2113
      wEpRegVal |= USB_EP_ISOCHRONOUS;
2114
      break;
2115
 
2116
    default:
2117
      ret = HAL_ERROR;
2118
      break;
2119
  }
2120
 
2121
  PCD_SET_ENDPOINT(USBx, ep->num, (wEpRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX));
2122
 
2123
  PCD_SET_EP_ADDRESS(USBx, ep->num, ep->num);
2124
 
2125
  if (ep->doublebuffer == 0U)
2126
  {
2127
    if (ep->is_in != 0U)
2128
    {
2129
      /*Set the endpoint Transmit buffer address */
2130
      PCD_SET_EP_TX_ADDRESS(USBx, ep->num, ep->pmaadress);
2131
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
2132
 
2133
      if (ep->type != EP_TYPE_ISOC)
2134
      {
2135
        /* Configure NAK status for the Endpoint */
2136
        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
2137
      }
2138
      else
2139
      {
2140
        /* Configure TX Endpoint to disabled state */
2141
        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2142
      }
2143
    }
2144
    else
2145
    {
2146
      /* Set the endpoint Receive buffer address */
2147
      PCD_SET_EP_RX_ADDRESS(USBx, ep->num, ep->pmaadress);
2148
 
2149
      /* Set the endpoint Receive buffer counter */
2150
      PCD_SET_EP_RX_CNT(USBx, ep->num, ep->maxpacket);
2151
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
2152
 
2153
      if (ep->num == 0U)
2154
      {
2155
        /* Configure VALID status for EP0 */
2156
        PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
2157
      }
2158
      else
2159
      {
2160
        /* Configure NAK status for OUT Endpoint */
2161
        PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_NAK);
2162
      }
2163
    }
2164
  }
2165
#if (USE_USB_DOUBLE_BUFFER == 1U)
2166
  /* Double Buffer */
2167
  else
2168
  {
2169
    if (ep->type == EP_TYPE_BULK)
2170
    {
2171
      /* Set bulk endpoint as double buffered */
2172
      PCD_SET_BULK_EP_DBUF(USBx, ep->num);
2173
    }
2174
    else
2175
    {
2176
      /* Set the ISOC endpoint in double buffer mode */
2177
      PCD_CLEAR_EP_KIND(USBx, ep->num);
2178
    }
2179
 
2180
    /* Set buffer address for double buffered mode */
2181
    PCD_SET_EP_DBUF_ADDR(USBx, ep->num, ep->pmaaddr0, ep->pmaaddr1);
2182
 
2183
    if (ep->is_in == 0U)
2184
    {
2185
      /* Clear the data toggle bits for the endpoint IN/OUT */
2186
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
2187
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
2188
 
2189
      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
2190
      PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2191
    }
2192
    else
2193
    {
2194
      /* Clear the data toggle bits for the endpoint IN/OUT */
2195
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
2196
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
2197
 
2198
      if (ep->type != EP_TYPE_ISOC)
2199
      {
2200
        /* Configure NAK status for the Endpoint */
2201
        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
2202
      }
2203
      else
2204
      {
2205
        /* Configure TX Endpoint to disabled state */
2206
        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2207
      }
2208
 
2209
      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
2210
    }
2211
  }
2212
#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
2213
 
2214
  return ret;
2215
}
2216
 
2217
/**
2218
  * @brief  De-activate and de-initialize an endpoint
2219
  * @param  USBx Selected device
2220
  * @param  ep pointer to endpoint structure
2221
  * @retval HAL status
2222
  */
2223
HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
2224
{
2225
  if (ep->doublebuffer == 0U)
2226
  {
2227
    if (ep->is_in != 0U)
2228
    {
2229
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
2230
 
2231
      /* Configure DISABLE status for the Endpoint */
2232
      PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2233
    }
2234
 
2235
    else
2236
    {
2237
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
2238
 
2239
      /* Configure DISABLE status for the Endpoint */
2240
      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
2241
    }
2242
  }
2243
#if (USE_USB_DOUBLE_BUFFER == 1U)
2244
  /* Double Buffer */
2245
  else
2246
  {
2247
    if (ep->is_in == 0U)
2248
    {
2249
      /* Clear the data toggle bits for the endpoint IN/OUT*/
2250
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
2251
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
2252
 
2253
      /* Reset value of the data toggle bits for the endpoint out*/
2254
      PCD_TX_DTOG(USBx, ep->num);
2255
 
2256
      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
2257
      PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2258
    }
2259
    else
2260
    {
2261
      /* Clear the data toggle bits for the endpoint IN/OUT*/
2262
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
2263
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
2264
      PCD_RX_DTOG(USBx, ep->num);
2265
 
2266
      /* Configure DISABLE status for the Endpoint*/
2267
      PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2268
      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
2269
    }
2270
  }
2271
#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
2272
 
2273
  return HAL_OK;
2274
}
2275
 
2276
/**
2277
  * @brief  USB_EPStartXfer setup and starts a transfer over an EP
2278
  * @param  USBx Selected device
2279
  * @param  ep pointer to endpoint structure
2280
  * @retval HAL status
2281
  */
2282
HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep)
2283
{
2284
  uint32_t len;
2285
#if (USE_USB_DOUBLE_BUFFER == 1U)
2286
  uint16_t pmabuffer;
2287
  uint16_t wEPVal;
2288
#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
2289
 
2290
  /* IN endpoint */
2291
  if (ep->is_in == 1U)
2292
  {
2293
    /*Multi packet transfer*/
2294
    if (ep->xfer_len > ep->maxpacket)
2295
    {
2296
      len = ep->maxpacket;
2297
    }
2298
    else
2299
    {
2300
      len = ep->xfer_len;
2301
    }
2302
 
2303
    /* configure and validate Tx endpoint */
2304
    if (ep->doublebuffer == 0U)
2305
    {
2306
      USB_WritePMA(USBx, ep->xfer_buff, ep->pmaadress, (uint16_t)len);
2307
      PCD_SET_EP_TX_CNT(USBx, ep->num, len);
2308
    }
2309
#if (USE_USB_DOUBLE_BUFFER == 1U)
2310
    else
2311
    {
2312
      /* double buffer bulk management */
2313
      if (ep->type == EP_TYPE_BULK)
2314
      {
2315
        if (ep->xfer_len_db > ep->maxpacket)
2316
        {
2317
          /* enable double buffer */
2318
          PCD_SET_BULK_EP_DBUF(USBx, ep->num);
2319
 
2320
          /* each Time to write in PMA xfer_len_db will */
2321
          ep->xfer_len_db -= len;
2322
 
2323
          /* Fill the two first buffer in the Buffer0 & Buffer1 */
2324
          if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
2325
          {
2326
            /* Set the Double buffer counter for pmabuffer1 */
2327
            PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
2328
            pmabuffer = ep->pmaaddr1;
2329
 
2330
            /* Write the user buffer to USB PMA */
2331
            USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2332
            ep->xfer_buff += len;
2333
 
2334
            if (ep->xfer_len_db > ep->maxpacket)
2335
            {
2336
              ep->xfer_len_db -= len;
2337
            }
2338
            else
2339
            {
2340
              len = ep->xfer_len_db;
2341
              ep->xfer_len_db = 0U;
2342
            }
2343
 
2344
            /* Set the Double buffer counter for pmabuffer0 */
2345
            PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
2346
            pmabuffer = ep->pmaaddr0;
2347
 
2348
            /* Write the user buffer to USB PMA */
2349
            USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2350
          }
2351
          else
2352
          {
2353
            /* Set the Double buffer counter for pmabuffer0 */
2354
            PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
2355
            pmabuffer = ep->pmaaddr0;
2356
 
2357
            /* Write the user buffer to USB PMA */
2358
            USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2359
            ep->xfer_buff += len;
2360
 
2361
            if (ep->xfer_len_db > ep->maxpacket)
2362
            {
2363
              ep->xfer_len_db -= len;
2364
            }
2365
            else
2366
            {
2367
              len = ep->xfer_len_db;
2368
              ep->xfer_len_db = 0U;
2369
            }
2370
 
2371
            /* Set the Double buffer counter for pmabuffer1 */
2372
            PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
2373
            pmabuffer = ep->pmaaddr1;
2374
 
2375
            /* Write the user buffer to USB PMA */
2376
            USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2377
          }
2378
        }
2379
        /* auto Switch to single buffer mode when transfer <Mps no need to manage in double buffer */
2380
        else
2381
        {
2382
          len = ep->xfer_len_db;
2383
 
2384
          /* disable double buffer mode for Bulk endpoint */
2385
          PCD_CLEAR_BULK_EP_DBUF(USBx, ep->num);
2386
 
2387
          /* Set Tx count with nbre of byte to be transmitted */
2388
          PCD_SET_EP_TX_CNT(USBx, ep->num, len);
2389
          pmabuffer = ep->pmaaddr0;
2390
 
2391
          /* Write the user buffer to USB PMA */
2392
          USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2393
        }
2394
      }
2395
      else /* manage isochronous double buffer IN mode */
2396
      {
2397
        /* each Time to write in PMA xfer_len_db will */
2398
        ep->xfer_len_db -= len;
2399
 
2400
        /* Fill the data buffer */
2401
        if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
2402
        {
2403
          /* Set the Double buffer counter for pmabuffer1 */
2404
          PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
2405
          pmabuffer = ep->pmaaddr1;
2406
 
2407
          /* Write the user buffer to USB PMA */
2408
          USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2409
        }
2410
        else
2411
        {
2412
          /* Set the Double buffer counter for pmabuffer0 */
2413
          PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
2414
          pmabuffer = ep->pmaaddr0;
2415
 
2416
          /* Write the user buffer to USB PMA */
2417
          USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2418
        }
2419
      }
2420
    }
2421
#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
2422
 
2423
    PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID);
2424
  }
2425
  else /* OUT endpoint */
2426
  {
2427
    if (ep->doublebuffer == 0U)
2428
    {
2429
      /* Multi packet transfer */
2430
      if (ep->xfer_len > ep->maxpacket)
2431
      {
2432
        len = ep->maxpacket;
2433
        ep->xfer_len -= len;
2434
      }
2435
      else
2436
      {
2437
        len = ep->xfer_len;
2438
        ep->xfer_len = 0U;
2439
      }
2440
      /* configure and validate Rx endpoint */
2441
      PCD_SET_EP_RX_CNT(USBx, ep->num, len);
2442
    }
2443
#if (USE_USB_DOUBLE_BUFFER == 1U)
2444
    else
2445
    {
2446
      /* First Transfer Coming From HAL_PCD_EP_Receive & From ISR */
2447
      /* Set the Double buffer counter */
2448
      if (ep->type == EP_TYPE_BULK)
2449
      {
2450
        PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, ep->maxpacket);
2451
 
2452
        /* Coming from ISR */
2453
        if (ep->xfer_count != 0U)
2454
        {
2455
          /* update last value to check if there is blocking state */
2456
          wEPVal = PCD_GET_ENDPOINT(USBx, ep->num);
2457
 
2458
          /*Blocking State */
2459
          if ((((wEPVal & USB_EP_DTOG_RX) != 0U) && ((wEPVal & USB_EP_DTOG_TX) != 0U)) ||
2460
              (((wEPVal & USB_EP_DTOG_RX) == 0U) && ((wEPVal & USB_EP_DTOG_TX) == 0U)))
2461
          {
2462
            PCD_FREE_USER_BUFFER(USBx, ep->num, 0U);
2463
          }
2464
        }
2465
      }
2466
      /* iso out double */
2467
      else if (ep->type == EP_TYPE_ISOC)
2468
      {
2469
        /* Multi packet transfer */
2470
        if (ep->xfer_len > ep->maxpacket)
2471
        {
2472
          len = ep->maxpacket;
2473
          ep->xfer_len -= len;
2474
        }
2475
        else
2476
        {
2477
          len = ep->xfer_len;
2478
          ep->xfer_len = 0U;
2479
        }
2480
        PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, len);
2481
      }
2482
      else
2483
      {
2484
        return HAL_ERROR;
2485
      }
2486
    }
2487
#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
2488
 
2489
    PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
2490
  }
2491
 
2492
  return HAL_OK;
2493
}
2494
 
2495
 
2496
/**
2497
  * @brief  USB_EPSetStall set a stall condition over an EP
2498
  * @param  USBx Selected device
2499
  * @param  ep pointer to endpoint structure
2500
  * @retval HAL status
2501
  */
2502
HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
2503
{
2504
  if (ep->is_in != 0U)
2505
  {
2506
    PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_STALL);
2507
  }
2508
  else
2509
  {
2510
    PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_STALL);
2511
  }
2512
 
2513
  return HAL_OK;
2514
}
2515
 
2516
/**
2517
  * @brief  USB_EPClearStall Clear a stall condition over an EP
2518
  * @param  USBx Selected device
2519
  * @param  ep pointer to endpoint structure
2520
  * @retval HAL status
2521
  */
2522
HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
2523
{
2524
  if (ep->doublebuffer == 0U)
2525
  {
2526
    if (ep->is_in != 0U)
2527
    {
2528
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
2529
 
2530
      if (ep->type != EP_TYPE_ISOC)
2531
      {
2532
        /* Configure NAK status for the Endpoint */
2533
        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
2534
      }
2535
    }
2536
    else
2537
    {
2538
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
2539
 
2540
      /* Configure VALID status for the Endpoint */
2541
      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
2542
    }
2543
  }
2544
 
2545
  return HAL_OK;
2546
}
2547
 
2548
/**
2549
   * @brief  USB_EPStoptXfer  Stop transfer on an EP
2550
   * @param  USBx  usb device instance
2551
   * @param  ep pointer to endpoint structure
2552
   * @retval HAL status
2553
   */
2554
HAL_StatusTypeDef USB_EPStopXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep)
2555
{
2556
  /* IN endpoint */
2557
  if (ep->is_in == 1U)
2558
  {
2559
    if (ep->doublebuffer == 0U)
2560
    {
2561
      if (ep->type != EP_TYPE_ISOC)
2562
      {
2563
        /* Configure NAK status for the Endpoint */
2564
        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
2565
      }
2566
      else
2567
      {
2568
        /* Configure TX Endpoint to disabled state */
2569
        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2570
      }
2571
    }
2572
  }
2573
  else /* OUT endpoint */
2574
  {
2575
    if (ep->doublebuffer == 0U)
2576
    {
2577
      if (ep->type != EP_TYPE_ISOC)
2578
      {
2579
        /* Configure NAK status for the Endpoint */
2580
        PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_NAK);
2581
      }
2582
      else
2583
      {
2584
        /* Configure RX Endpoint to disabled state */
2585
        PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
2586
      }
2587
    }
2588
  }
2589
 
2590
  return HAL_OK;
2591
}
2592
#endif /* defined (HAL_PCD_MODULE_ENABLED) */
2593
 
2594
/**
2595
  * @brief  USB_StopDevice Stop the usb device mode
2596
  * @param  USBx Selected device
2597
  * @retval HAL status
2598
  */
2599
HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx)
2600
{
2601
  /* disable all interrupts and force USB reset */
2602
  USBx->CNTR = (uint16_t)USB_CNTR_FRES;
2603
 
2604
  /* clear interrupt status register */
2605
  USBx->ISTR = 0U;
2606
 
2607
  /* switch-off device */
2608
  USBx->CNTR = (uint16_t)(USB_CNTR_FRES | USB_CNTR_PDWN);
2609
 
2610
  return HAL_OK;
2611
}
2612
 
2613
/**
2614
  * @brief  USB_SetDevAddress Stop the usb device mode
2615
  * @param  USBx Selected device
2616
  * @param  address new device address to be assigned
2617
  *          This parameter can be a value from 0 to 255
2618
  * @retval HAL status
2619
  */
2620
HAL_StatusTypeDef  USB_SetDevAddress(USB_TypeDef *USBx, uint8_t address)
2621
{
2622
  if (address == 0U)
2623
  {
2624
    /* set device address and enable function */
2625
    USBx->DADDR = (uint16_t)USB_DADDR_EF;
2626
  }
2627
 
2628
  return HAL_OK;
2629
}
2630
 
2631
/**
2632
  * @brief  USB_DevConnect Connect the USB device by enabling the pull-up/pull-down
2633
  * @param  USBx Selected device
2634
  * @retval HAL status
2635
  */
2636
HAL_StatusTypeDef  USB_DevConnect(USB_TypeDef *USBx)
2637
{
2638
  /* Prevent unused argument(s) compilation warning */
2639
  UNUSED(USBx);
2640
 
2641
  /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2642
              only by USB OTG FS peripheral.
2643
            - This function is added to ensure compatibility across platforms.
2644
   */
2645
 
2646
  return HAL_OK;
2647
}
2648
 
2649
/**
2650
  * @brief  USB_DevDisconnect Disconnect the USB device by disabling the pull-up/pull-down
2651
  * @param  USBx Selected device
2652
  * @retval HAL status
2653
  */
2654
HAL_StatusTypeDef  USB_DevDisconnect(USB_TypeDef *USBx)
2655
{
2656
  /* Prevent unused argument(s) compilation warning */
2657
  UNUSED(USBx);
2658
 
2659
  /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2660
              only by USB OTG FS peripheral.
2661
            - This function is added to ensure compatibility across platforms.
2662
   */
2663
 
2664
  return HAL_OK;
2665
}
2666
 
2667
/**
2668
  * @brief  USB_ReadInterrupts return the global USB interrupt status
2669
  * @param  USBx Selected device
2670
  * @retval USB Global Interrupt status
2671
  */
2672
uint32_t USB_ReadInterrupts(USB_TypeDef const *USBx)
2673
{
2674
  uint32_t tmpreg;
2675
 
2676
  tmpreg = USBx->ISTR;
2677
  return tmpreg;
2678
}
2679
 
2680
/**
2681
  * @brief  USB_ReadDevAllOutEpInterrupt return the USB device OUT endpoints interrupt status
2682
  * @param  USBx Selected device
2683
  * @retval HAL status
2684
  */
2685
uint32_t USB_ReadDevAllOutEpInterrupt(USB_TypeDef *USBx)
2686
{
2687
  /* Prevent unused argument(s) compilation warning */
2688
  UNUSED(USBx);
2689
  /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2690
              only by USB OTG FS peripheral.
2691
            - This function is added to ensure compatibility across platforms.
2692
   */
2693
  return (0);
2694
}
2695
 
2696
/**
2697
  * @brief  USB_ReadDevAllInEpInterrupt return the USB device IN endpoints interrupt status
2698
  * @param  USBx Selected device
2699
  * @retval HAL status
2700
  */
2701
uint32_t USB_ReadDevAllInEpInterrupt(USB_TypeDef *USBx)
2702
{
2703
  /* Prevent unused argument(s) compilation warning */
2704
  UNUSED(USBx);
2705
  /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2706
              only by USB OTG FS peripheral.
2707
            - This function is added to ensure compatibility across platforms.
2708
   */
2709
  return (0);
2710
}
2711
 
2712
/**
2713
  * @brief  Returns Device OUT EP Interrupt register
2714
  * @param  USBx Selected device
2715
  * @param  epnum endpoint number
2716
  *          This parameter can be a value from 0 to 15
2717
  * @retval Device OUT EP Interrupt register
2718
  */
2719
uint32_t USB_ReadDevOutEPInterrupt(USB_TypeDef *USBx, uint8_t epnum)
2720
{
2721
  /* Prevent unused argument(s) compilation warning */
2722
  UNUSED(USBx);
2723
  UNUSED(epnum);
2724
  /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2725
              only by USB OTG FS peripheral.
2726
            - This function is added to ensure compatibility across platforms.
2727
   */
2728
  return (0);
2729
}
2730
 
2731
/**
2732
  * @brief  Returns Device IN EP Interrupt register
2733
  * @param  USBx Selected device
2734
  * @param  epnum endpoint number
2735
  *          This parameter can be a value from 0 to 15
2736
  * @retval Device IN EP Interrupt register
2737
  */
2738
uint32_t USB_ReadDevInEPInterrupt(USB_TypeDef *USBx, uint8_t epnum)
2739
{
2740
  /* Prevent unused argument(s) compilation warning */
2741
  UNUSED(USBx);
2742
  UNUSED(epnum);
2743
  /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2744
              only by USB OTG FS peripheral.
2745
            - This function is added to ensure compatibility across platforms.
2746
   */
2747
  return (0);
2748
}
2749
 
2750
/**
2751
  * @brief  USB_ClearInterrupts: clear a USB interrupt
2752
  * @param  USBx Selected device
2753
  * @param  interrupt  flag
2754
  * @retval None
2755
  */
2756
void  USB_ClearInterrupts(USB_TypeDef *USBx, uint32_t interrupt)
2757
{
2758
  /* Prevent unused argument(s) compilation warning */
2759
  UNUSED(USBx);
2760
  UNUSED(interrupt);
2761
  /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2762
              only by USB OTG FS peripheral.
2763
            - This function is added to ensure compatibility across platforms.
2764
   */
2765
}
2766
 
2767
/**
2768
  * @brief  Prepare the EP0 to start the first control setup
2769
  * @param  USBx Selected device
2770
  * @param  psetup pointer to setup packet
2771
  * @retval HAL status
2772
  */
2773
HAL_StatusTypeDef USB_EP0_OutStart(USB_TypeDef *USBx, uint8_t *psetup)
2774
{
2775
  /* Prevent unused argument(s) compilation warning */
2776
  UNUSED(USBx);
2777
  UNUSED(psetup);
2778
  /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2779
              only by USB OTG FS peripheral.
2780
            - This function is added to ensure compatibility across platforms.
2781
   */
2782
  return HAL_OK;
2783
}
2784
 
2785
/**
2786
  * @brief  USB_ActivateRemoteWakeup : active remote wakeup signalling
2787
  * @param  USBx Selected device
2788
  * @retval HAL status
2789
  */
2790
HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx)
2791
{
2792
  USBx->CNTR |= (uint16_t)USB_CNTR_RESUME;
2793
 
2794
  return HAL_OK;
2795
}
2796
 
2797
/**
2798
  * @brief  USB_DeActivateRemoteWakeup de-active remote wakeup signalling
2799
  * @param  USBx Selected device
2800
  * @retval HAL status
2801
  */
2802
HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx)
2803
{
2804
  USBx->CNTR &= (uint16_t)(~USB_CNTR_RESUME);
2805
 
2806
  return HAL_OK;
2807
}
2808
 
2809
/**
2810
  * @brief Copy a buffer from user memory area to packet memory area (PMA)
2811
  * @param   USBx USB peripheral instance register address.
2812
  * @param   pbUsrBuf pointer to user memory area.
2813
  * @param   wPMABufAddr address into PMA.
2814
  * @param   wNBytes no. of bytes to be copied.
2815
  * @retval None
2816
  */
2817
void USB_WritePMA(USB_TypeDef const *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
2818
{
2819
  uint32_t n = ((uint32_t)wNBytes + 1U) >> 1;
2820
  uint32_t BaseAddr = (uint32_t)USBx;
2821
  uint32_t count;
2822
  uint16_t WrVal;
2823
  __IO uint16_t *pdwVal;
2824
  uint8_t *pBuf = pbUsrBuf;
2825
 
2826
  pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
2827
 
2828
  for (count = n; count != 0U; count--)
2829
  {
2830
    WrVal = pBuf[0];
2831
    WrVal |= (uint16_t)pBuf[1] << 8;
2832
    *pdwVal = (WrVal & 0xFFFFU);
2833
    pdwVal++;
2834
 
2835
#if PMA_ACCESS > 1U
2836
    pdwVal++;
2837
#endif /* PMA_ACCESS */
2838
 
2839
    pBuf++;
2840
    pBuf++;
2841
  }
2842
}
2843
 
2844
/**
2845
  * @brief Copy data from packet memory area (PMA) to user memory buffer
2846
  * @param   USBx USB peripheral instance register address.
2847
  * @param   pbUsrBuf pointer to user memory area.
2848
  * @param   wPMABufAddr address into PMA.
2849
  * @param   wNBytes no. of bytes to be copied.
2850
  * @retval None
2851
  */
2852
void USB_ReadPMA(USB_TypeDef const *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
2853
{
2854
  uint32_t n = (uint32_t)wNBytes >> 1;
2855
  uint32_t BaseAddr = (uint32_t)USBx;
2856
  uint32_t count;
2857
  uint32_t RdVal;
2858
  __IO uint16_t *pdwVal;
2859
  uint8_t *pBuf = pbUsrBuf;
2860
 
2861
  pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
2862
 
2863
  for (count = n; count != 0U; count--)
2864
  {
2865
    RdVal = *(__IO uint16_t *)pdwVal;
2866
    pdwVal++;
2867
    *pBuf = (uint8_t)((RdVal >> 0) & 0xFFU);
2868
    pBuf++;
2869
    *pBuf = (uint8_t)((RdVal >> 8) & 0xFFU);
2870
    pBuf++;
2871
 
2872
#if PMA_ACCESS > 1U
2873
    pdwVal++;
2874
#endif /* PMA_ACCESS */
2875
  }
2876
 
2877
  if ((wNBytes % 2U) != 0U)
2878
  {
2879
    RdVal = *pdwVal;
2880
    *pBuf = (uint8_t)((RdVal >> 0) & 0xFFU);
2881
  }
2882
}
2883
 
2884
#endif /* defined (USB) */
2885
/**
2886
  * @}
2887
  */
2888
 
2889
/**
2890
  * @}
2891
  */
2892
#endif /* defined (USB) || defined (USB_OTG_FS) */
2893
#endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
2894
 
2895
/**
2896
  * @}
2897
  */