Subversion Repositories LedShow

Rev

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