Subversion Repositories DashDisplay

Rev

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

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