Subversion Repositories dashGPS

Rev

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

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