Subversion Repositories canSerial

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