Subversion Repositories DashDisplay

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