Subversion Repositories ScreenTimer

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 1
/**
2
  ******************************************************************************
3
  * @file    stm32f0xx_ll_usb.c
4
  * @author  MCD Application Team
5
  * @brief   USB Low Layer HAL module driver.
6
  *
7
  *          This file provides firmware functions to manage the following
8
  *          functionalities of the USB Peripheral Controller:
9
  *           + Initialization/de-initialization functions
10
  *           + I/O operation functions
11
  *           + Peripheral Control functions
12
  *           + Peripheral State functions
13
  *
14
  @verbatim
15
  ==============================================================================
16
                    ##### How to use this driver #####
17
  ==============================================================================
18
    [..]
19
      (#) Fill parameters of Init structure in USB_OTG_CfgTypeDef structure.
20
 
21
      (#) Call USB_CoreInit() API to initialize the USB Core peripheral.
22
 
23
      (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes.
24
 
25
  @endverbatim
26
  ******************************************************************************
27
  * @attention
28
  *
29
  * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
30
  * All rights reserved.</center></h2>
31
  *
32
  * This software component is licensed by ST under BSD 3-Clause license,
33
  * the "License"; You may not use this file except in compliance with the
34
  * License. You may obtain a copy of the License at:
35
  *                        opensource.org/licenses/BSD-3-Clause
36
  *
37
  ******************************************************************************
38
  */
39
 
40
/* Includes ------------------------------------------------------------------*/
41
#include "stm32f0xx_hal.h"
42
 
43
/** @addtogroup STM32F0xx_LL_USB_DRIVER
44
  * @{
45
  */
46
 
47
#if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED)
48
#if defined (USB)
49
/* Private typedef -----------------------------------------------------------*/
50
/* Private define ------------------------------------------------------------*/
51
/* Private macro -------------------------------------------------------------*/
52
/* Private variables ---------------------------------------------------------*/
53
/* Private function prototypes -----------------------------------------------*/
54
/* Private functions ---------------------------------------------------------*/
55
 
56
 
57
/**
58
  * @brief  Initializes the USB Core
59
  * @param  USBx USB Instance
60
  * @param  cfg pointer to a USB_CfgTypeDef structure that contains
61
  *         the configuration information for the specified USBx peripheral.
62
  * @retval HAL status
63
  */
64
HAL_StatusTypeDef USB_CoreInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg)
65
{
66
  /* Prevent unused argument(s) compilation warning */
67
  UNUSED(USBx);
68
  UNUSED(cfg);
69
 
70
  /* NOTE : - This function is not required by USB Device FS peripheral, it is used
71
              only by USB OTG FS peripheral.
72
            - This function is added to ensure compatibility across platforms.
73
   */
74
 
75
  return HAL_OK;
76
}
77
 
78
/**
79
  * @brief  USB_EnableGlobalInt
80
  *         Enables the controller's Global Int in the AHB Config reg
81
  * @param  USBx Selected device
82
  * @retval HAL status
83
  */
84
HAL_StatusTypeDef USB_EnableGlobalInt(USB_TypeDef *USBx)
85
{
86
  uint32_t winterruptmask;
87
 
88
  /* Clear pending interrupts */
89
  USBx->ISTR = 0U;
90
 
91
  /* Set winterruptmask variable */
92
  winterruptmask = USB_CNTR_CTRM  | USB_CNTR_WKUPM |
93
                   USB_CNTR_SUSPM | USB_CNTR_ERRM |
94
                   USB_CNTR_SOFM | USB_CNTR_ESOFM |
95
                   USB_CNTR_RESETM | USB_CNTR_L1REQM;
96
 
97
  /* Set interrupt mask */
98
  USBx->CNTR = (uint16_t)winterruptmask;
99
 
100
  return HAL_OK;
101
}
102
 
103
/**
104
  * @brief  USB_DisableGlobalInt
105
  *         Disable the controller's Global Int in the AHB Config reg
106
  * @param  USBx Selected device
107
  * @retval HAL status
108
  */
109
HAL_StatusTypeDef USB_DisableGlobalInt(USB_TypeDef *USBx)
110
{
111
  uint32_t winterruptmask;
112
 
113
  /* Set winterruptmask variable */
114
  winterruptmask = USB_CNTR_CTRM  | USB_CNTR_WKUPM |
115
                   USB_CNTR_SUSPM | USB_CNTR_ERRM |
116
                   USB_CNTR_SOFM | USB_CNTR_ESOFM |
117
                   USB_CNTR_RESETM | USB_CNTR_L1REQM;
118
 
119
  /* Clear interrupt mask */
120
  USBx->CNTR &= (uint16_t)(~winterruptmask);
121
 
122
  return HAL_OK;
123
}
124
 
125
/**
126
  * @brief  USB_SetCurrentMode Set functional mode
127
  * @param  USBx Selected device
128
  * @param  mode current core mode
129
  *          This parameter can be one of the these values:
130
  *            @arg USB_DEVICE_MODE Peripheral mode
131
  * @retval HAL status
132
  */
133
HAL_StatusTypeDef USB_SetCurrentMode(USB_TypeDef *USBx, USB_ModeTypeDef mode)
134
{
135
  /* Prevent unused argument(s) compilation warning */
136
  UNUSED(USBx);
137
  UNUSED(mode);
138
 
139
  /* NOTE : - This function is not required by USB Device FS peripheral, it is used
140
              only by USB OTG FS peripheral.
141
            - This function is added to ensure compatibility across platforms.
142
   */
143
  return HAL_OK;
144
}
145
 
146
/**
147
  * @brief  USB_DevInit Initializes the USB controller registers
148
  *         for device mode
149
  * @param  USBx Selected device
150
  * @param  cfg  pointer to a USB_CfgTypeDef structure that contains
151
  *         the configuration information for the specified USBx peripheral.
152
  * @retval HAL status
153
  */
154
HAL_StatusTypeDef USB_DevInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg)
155
{
156
  /* Prevent unused argument(s) compilation warning */
157
  UNUSED(cfg);
158
 
159
  /* Init Device */
160
  /* CNTR_FRES = 1 */
161
  USBx->CNTR = (uint16_t)USB_CNTR_FRES;
162
 
163
  /* CNTR_FRES = 0 */
164
  USBx->CNTR = 0U;
165
 
166
  /* Clear pending interrupts */
167
  USBx->ISTR = 0U;
168
 
169
  /*Set Btable Address*/
170
  USBx->BTABLE = BTABLE_ADDRESS;
171
 
172
  return HAL_OK;
173
}
174
 
175
#if defined (HAL_PCD_MODULE_ENABLED)
176
/**
177
  * @brief  Activate and configure an endpoint
178
  * @param  USBx Selected device
179
  * @param  ep pointer to endpoint structure
180
  * @retval HAL status
181
  */
182
HAL_StatusTypeDef USB_ActivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
183
{
184
  HAL_StatusTypeDef ret = HAL_OK;
185
  uint16_t wEpRegVal;
186
 
187
  wEpRegVal = PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_T_MASK;
188
 
189
  /* initialize Endpoint */
190
  switch (ep->type)
191
  {
192
    case EP_TYPE_CTRL:
193
      wEpRegVal |= USB_EP_CONTROL;
194
      break;
195
 
196
    case EP_TYPE_BULK:
197
      wEpRegVal |= USB_EP_BULK;
198
      break;
199
 
200
    case EP_TYPE_INTR:
201
      wEpRegVal |= USB_EP_INTERRUPT;
202
      break;
203
 
204
    case EP_TYPE_ISOC:
205
      wEpRegVal |= USB_EP_ISOCHRONOUS;
206
      break;
207
 
208
    default:
209
      ret = HAL_ERROR;
210
      break;
211
  }
212
 
213
  PCD_SET_ENDPOINT(USBx, ep->num, (wEpRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX));
214
 
215
  PCD_SET_EP_ADDRESS(USBx, ep->num, ep->num);
216
 
217
  if (ep->doublebuffer == 0U)
218
  {
219
    if (ep->is_in != 0U)
220
    {
221
      /*Set the endpoint Transmit buffer address */
222
      PCD_SET_EP_TX_ADDRESS(USBx, ep->num, ep->pmaadress);
223
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
224
 
225
      if (ep->type != EP_TYPE_ISOC)
226
      {
227
        /* Configure NAK status for the Endpoint */
228
        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
229
      }
230
      else
231
      {
232
        /* Configure TX Endpoint to disabled state */
233
        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
234
      }
235
    }
236
    else
237
    {
238
      /* Set the endpoint Receive buffer address */
239
      PCD_SET_EP_RX_ADDRESS(USBx, ep->num, ep->pmaadress);
240
 
241
      /* Set the endpoint Receive buffer counter */
242
      PCD_SET_EP_RX_CNT(USBx, ep->num, ep->maxpacket);
243
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
244
 
245
      /* Configure VALID status for the Endpoint */
246
      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
247
    }
248
  }
249
  /* Double Buffer */
250
  else
251
  {
252
    if (ep->type == EP_TYPE_BULK)
253
    {
254
      /* Set bulk endpoint as double buffered */
255
      PCD_SET_BULK_EP_DBUF(USBx, ep->num);
256
    }
257
    else
258
    {
259
      /* Set the ISOC endpoint in double buffer mode */
260
      PCD_CLEAR_EP_KIND(USBx, ep->num);
261
    }
262
 
263
    /* Set buffer address for double buffered mode */
264
    PCD_SET_EP_DBUF_ADDR(USBx, ep->num, ep->pmaaddr0, ep->pmaaddr1);
265
 
266
    if (ep->is_in == 0U)
267
    {
268
      /* Clear the data toggle bits for the endpoint IN/OUT */
269
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
270
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
271
 
272
      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
273
      PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
274
    }
275
    else
276
    {
277
      /* Clear the data toggle bits for the endpoint IN/OUT */
278
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
279
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
280
 
281
      if (ep->type != EP_TYPE_ISOC)
282
      {
283
        /* Configure NAK status for the Endpoint */
284
        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
285
      }
286
      else
287
      {
288
        /* Configure TX Endpoint to disabled state */
289
        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
290
      }
291
 
292
      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
293
    }
294
  }
295
 
296
  return ret;
297
}
298
 
299
/**
300
  * @brief  De-activate and de-initialize an endpoint
301
  * @param  USBx Selected device
302
  * @param  ep pointer to endpoint structure
303
  * @retval HAL status
304
  */
305
HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
306
{
307
  if (ep->doublebuffer == 0U)
308
  {
309
    if (ep->is_in != 0U)
310
    {
311
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
312
 
313
      /* Configure DISABLE status for the Endpoint*/
314
      PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
315
    }
316
    else
317
    {
318
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
319
 
320
      /* Configure DISABLE status for the Endpoint*/
321
      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
322
    }
323
  }
324
  /*Double Buffer*/
325
  else
326
  {
327
    if (ep->is_in == 0U)
328
    {
329
      /* Clear the data toggle bits for the endpoint IN/OUT*/
330
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
331
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
332
 
333
      /* Reset value of the data toggle bits for the endpoint out*/
334
      PCD_TX_DTOG(USBx, ep->num);
335
 
336
      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
337
      PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
338
    }
339
    else
340
    {
341
      /* Clear the data toggle bits for the endpoint IN/OUT*/
342
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
343
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
344
      PCD_RX_DTOG(USBx, ep->num);
345
 
346
      /* Configure DISABLE status for the Endpoint*/
347
      PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
348
      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
349
    }
350
  }
351
 
352
  return HAL_OK;
353
}
354
 
355
/**
356
  * @brief  USB_EPStartXfer setup and starts a transfer over an EP
357
  * @param  USBx Selected device
358
  * @param  ep pointer to endpoint structure
359
  * @retval HAL status
360
  */
361
HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep)
362
{
363
  uint32_t len;
364
  uint16_t pmabuffer;
365
  uint16_t wEPVal;
366
 
367
  /* IN endpoint */
368
  if (ep->is_in == 1U)
369
  {
370
    /*Multi packet transfer*/
371
    if (ep->xfer_len > ep->maxpacket)
372
    {
373
      len = ep->maxpacket;
374
    }
375
    else
376
    {
377
      len = ep->xfer_len;
378
    }
379
 
380
    /* configure and validate Tx endpoint */
381
    if (ep->doublebuffer == 0U)
382
    {
383
      USB_WritePMA(USBx, ep->xfer_buff, ep->pmaadress, (uint16_t)len);
384
      PCD_SET_EP_TX_CNT(USBx, ep->num, len);
385
    }
386
    else
387
    {
388
      /* double buffer bulk management */
389
      if (ep->type == EP_TYPE_BULK)
390
      {
391
        if (ep->xfer_len_db > ep->maxpacket)
392
        {
393
          /* enable double buffer */
394
          PCD_SET_BULK_EP_DBUF(USBx, ep->num);
395
 
396
          /* each Time to write in PMA xfer_len_db will */
397
          ep->xfer_len_db -= len;
398
 
399
          /* Fill the two first buffer in the Buffer0 & Buffer1 */
400
          if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
401
          {
402
            /* Set the Double buffer counter for pmabuffer1 */
403
            PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
404
            pmabuffer = ep->pmaaddr1;
405
 
406
            /* Write the user buffer to USB PMA */
407
            USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
408
            ep->xfer_buff += len;
409
 
410
            if (ep->xfer_len_db > ep->maxpacket)
411
            {
412
              ep->xfer_len_db -= len;
413
            }
414
            else
415
            {
416
              len = ep->xfer_len_db;
417
              ep->xfer_len_db = 0U;
418
            }
419
 
420
            /* Set the Double buffer counter for pmabuffer0 */
421
            PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
422
            pmabuffer = ep->pmaaddr0;
423
 
424
            /* Write the user buffer to USB PMA */
425
            USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
426
          }
427
          else
428
          {
429
            /* Set the Double buffer counter for pmabuffer0 */
430
            PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
431
            pmabuffer = ep->pmaaddr0;
432
 
433
            /* Write the user buffer to USB PMA */
434
            USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
435
            ep->xfer_buff += len;
436
 
437
            if (ep->xfer_len_db > ep->maxpacket)
438
            {
439
              ep->xfer_len_db -= len;
440
            }
441
            else
442
            {
443
              len = ep->xfer_len_db;
444
              ep->xfer_len_db = 0U;
445
            }
446
 
447
            /* Set the Double buffer counter for pmabuffer1 */
448
            PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
449
            pmabuffer = ep->pmaaddr1;
450
 
451
            /* Write the user buffer to USB PMA */
452
            USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
453
          }
454
        }
455
        /* auto Switch to single buffer mode when transfer <Mps no need to manage in double buffer */
456
        else
457
        {
458
          len = ep->xfer_len_db;
459
 
460
          /* disable double buffer mode for Bulk endpoint */
461
          PCD_CLEAR_BULK_EP_DBUF(USBx, ep->num);
462
 
463
          /* Set Tx count with nbre of byte to be transmitted */
464
          PCD_SET_EP_TX_CNT(USBx, ep->num, len);
465
          pmabuffer = ep->pmaaddr0;
466
 
467
          /* Write the user buffer to USB PMA */
468
          USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
469
        }
470
      }
471
      else /* manage isochronous double buffer IN mode */
472
      {
473
        /* each Time to write in PMA xfer_len_db will */
474
        ep->xfer_len_db -= len;
475
 
476
        /* Fill the data buffer */
477
        if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
478
        {
479
          /* Set the Double buffer counter for pmabuffer1 */
480
          PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
481
          pmabuffer = ep->pmaaddr1;
482
 
483
          /* Write the user buffer to USB PMA */
484
          USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
485
        }
486
        else
487
        {
488
          /* Set the Double buffer counter for pmabuffer0 */
489
          PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
490
          pmabuffer = ep->pmaaddr0;
491
 
492
          /* Write the user buffer to USB PMA */
493
          USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
494
        }
495
      }
496
    }
497
 
498
    PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID);
499
  }
500
  else /* OUT endpoint */
501
  {
502
    if (ep->doublebuffer == 0U)
503
    {
504
      /* Multi packet transfer */
505
      if (ep->xfer_len > ep->maxpacket)
506
      {
507
        len = ep->maxpacket;
508
        ep->xfer_len -= len;
509
      }
510
      else
511
      {
512
        len = ep->xfer_len;
513
        ep->xfer_len = 0U;
514
      }
515
      /* configure and validate Rx endpoint */
516
      PCD_SET_EP_RX_CNT(USBx, ep->num, len);
517
    }
518
    else
519
    {
520
      /* First Transfer Coming From HAL_PCD_EP_Receive & From ISR */
521
      /* Set the Double buffer counter */
522
      if (ep->type == EP_TYPE_BULK)
523
      {
524
        PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, ep->maxpacket);
525
 
526
        /* Coming from ISR */
527
        if (ep->xfer_count != 0U)
528
        {
529
          /* update last value to check if there is blocking state */
530
          wEPVal = PCD_GET_ENDPOINT(USBx, ep->num);
531
 
532
          /*Blocking State */
533
          if ((((wEPVal & USB_EP_DTOG_RX) != 0U) && ((wEPVal & USB_EP_DTOG_TX) != 0U)) ||
534
              (((wEPVal & USB_EP_DTOG_RX) == 0U) && ((wEPVal & USB_EP_DTOG_TX) == 0U)))
535
          {
536
            PCD_FreeUserBuffer(USBx, ep->num, 0U);
537
          }
538
        }
539
      }
540
      /* iso out double */
541
      else if (ep->type == EP_TYPE_ISOC)
542
      {
543
        /* Multi packet transfer */
544
        if (ep->xfer_len > ep->maxpacket)
545
        {
546
          len = ep->maxpacket;
547
          ep->xfer_len -= len;
548
        }
549
        else
550
        {
551
          len = ep->xfer_len;
552
          ep->xfer_len = 0U;
553
        }
554
        PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, len);
555
      }
556
      else
557
      {
558
        return HAL_ERROR;
559
      }
560
    }
561
 
562
    PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
563
  }
564
 
565
  return HAL_OK;
566
}
567
 
568
 
569
/**
570
  * @brief  USB_EPSetStall set a stall condition over an EP
571
  * @param  USBx Selected device
572
  * @param  ep pointer to endpoint structure
573
  * @retval HAL status
574
  */
575
HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
576
{
577
  if (ep->is_in != 0U)
578
  {
579
    PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_STALL);
580
  }
581
  else
582
  {
583
    PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_STALL);
584
  }
585
 
586
  return HAL_OK;
587
}
588
 
589
/**
590
  * @brief  USB_EPClearStall Clear a stall condition over an EP
591
  * @param  USBx Selected device
592
  * @param  ep pointer to endpoint structure
593
  * @retval HAL status
594
  */
595
HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
596
{
597
  if (ep->doublebuffer == 0U)
598
  {
599
    if (ep->is_in != 0U)
600
    {
601
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
602
 
603
      if (ep->type != EP_TYPE_ISOC)
604
      {
605
        /* Configure NAK status for the Endpoint */
606
        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
607
      }
608
    }
609
    else
610
    {
611
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
612
 
613
      /* Configure VALID status for the Endpoint */
614
      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
615
    }
616
  }
617
 
618
  return HAL_OK;
619
}
620
#endif /* defined (HAL_PCD_MODULE_ENABLED) */
621
 
622
/**
623
  * @brief  USB_StopDevice Stop the usb device mode
624
  * @param  USBx Selected device
625
  * @retval HAL status
626
  */
627
HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx)
628
{
629
  /* disable all interrupts and force USB reset */
630
  USBx->CNTR = (uint16_t)USB_CNTR_FRES;
631
 
632
  /* clear interrupt status register */
633
  USBx->ISTR = 0U;
634
 
635
  /* switch-off device */
636
  USBx->CNTR = (uint16_t)(USB_CNTR_FRES | USB_CNTR_PDWN);
637
 
638
  return HAL_OK;
639
}
640
 
641
/**
642
  * @brief  USB_SetDevAddress Stop the usb device mode
643
  * @param  USBx Selected device
644
  * @param  address new device address to be assigned
645
  *          This parameter can be a value from 0 to 255
646
  * @retval HAL status
647
  */
648
HAL_StatusTypeDef  USB_SetDevAddress(USB_TypeDef *USBx, uint8_t address)
649
{
650
  if (address == 0U)
651
  {
652
    /* set device address and enable function */
653
    USBx->DADDR = (uint16_t)USB_DADDR_EF;
654
  }
655
 
656
  return HAL_OK;
657
}
658
 
659
/**
660
  * @brief  USB_DevConnect Connect the USB device by enabling the pull-up/pull-down
661
  * @param  USBx Selected device
662
  * @retval HAL status
663
  */
664
HAL_StatusTypeDef  USB_DevConnect(USB_TypeDef *USBx)
665
{
666
  /* Enabling DP Pull-UP bit to Connect internal PU resistor on USB DP line */
667
  USBx->BCDR |= (uint16_t)USB_BCDR_DPPU;
668
 
669
  return HAL_OK;
670
}
671
 
672
/**
673
  * @brief  USB_DevDisconnect Disconnect the USB device by disabling the pull-up/pull-down
674
  * @param  USBx Selected device
675
  * @retval HAL status
676
  */
677
HAL_StatusTypeDef  USB_DevDisconnect(USB_TypeDef *USBx)
678
{
679
  /* Disable DP Pull-Up bit to disconnect the Internal PU resistor on USB DP line */
680
  USBx->BCDR &= (uint16_t)(~(USB_BCDR_DPPU));
681
 
682
  return HAL_OK;
683
}
684
 
685
/**
686
  * @brief  USB_ReadInterrupts return the global USB interrupt status
687
  * @param  USBx Selected device
688
  * @retval HAL status
689
  */
690
uint32_t  USB_ReadInterrupts(USB_TypeDef *USBx)
691
{
692
  uint32_t tmpreg;
693
 
694
  tmpreg = USBx->ISTR;
695
  return tmpreg;
696
}
697
 
698
/**
699
  * @brief  USB_ActivateRemoteWakeup : active remote wakeup signalling
700
  * @param  USBx Selected device
701
  * @retval HAL status
702
  */
703
HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx)
704
{
705
  USBx->CNTR |= (uint16_t)USB_CNTR_RESUME;
706
 
707
  return HAL_OK;
708
}
709
 
710
/**
711
  * @brief  USB_DeActivateRemoteWakeup de-active remote wakeup signalling
712
  * @param  USBx Selected device
713
  * @retval HAL status
714
  */
715
HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx)
716
{
717
  USBx->CNTR &= (uint16_t)(~USB_CNTR_RESUME);
718
 
719
  return HAL_OK;
720
}
721
 
722
/**
723
  * @brief Copy a buffer from user memory area to packet memory area (PMA)
724
  * @param   USBx USB peripheral instance register address.
725
  * @param   pbUsrBuf pointer to user memory area.
726
  * @param   wPMABufAddr address into PMA.
727
  * @param   wNBytes no. of bytes to be copied.
728
  * @retval None
729
  */
730
void USB_WritePMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
731
{
732
  uint32_t n = ((uint32_t)wNBytes + 1U) >> 1;
733
  uint32_t BaseAddr = (uint32_t)USBx;
734
  uint32_t i, temp1, temp2;
735
  __IO uint16_t *pdwVal;
736
  uint8_t *pBuf = pbUsrBuf;
737
 
738
  pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
739
 
740
  for (i = n; i != 0U; i--)
741
  {
742
    temp1 = *pBuf;
743
    pBuf++;
744
    temp2 = temp1 | ((uint16_t)((uint16_t) *pBuf << 8));
745
    *pdwVal = (uint16_t)temp2;
746
    pdwVal++;
747
 
748
#if PMA_ACCESS > 1U
749
    pdwVal++;
750
#endif
751
 
752
    pBuf++;
753
  }
754
}
755
 
756
/**
757
  * @brief Copy data from packet memory area (PMA) to user memory buffer
758
  * @param   USBx USB peripheral instance register address.
759
  * @param   pbUsrBuf pointer to user memory area.
760
  * @param   wPMABufAddr address into PMA.
761
  * @param   wNBytes no. of bytes to be copied.
762
  * @retval None
763
  */
764
void USB_ReadPMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
765
{
766
  uint32_t n = (uint32_t)wNBytes >> 1;
767
  uint32_t BaseAddr = (uint32_t)USBx;
768
  uint32_t i, temp;
769
  __IO uint16_t *pdwVal;
770
  uint8_t *pBuf = pbUsrBuf;
771
 
772
  pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
773
 
774
  for (i = n; i != 0U; i--)
775
  {
776
    temp = *(__IO uint16_t *)pdwVal;
777
    pdwVal++;
778
    *pBuf = (uint8_t)((temp >> 0) & 0xFFU);
779
    pBuf++;
780
    *pBuf = (uint8_t)((temp >> 8) & 0xFFU);
781
    pBuf++;
782
 
783
#if PMA_ACCESS > 1U
784
    pdwVal++;
785
#endif
786
  }
787
 
788
  if ((wNBytes % 2U) != 0U)
789
  {
790
    temp = *pdwVal;
791
    *pBuf = (uint8_t)((temp >> 0) & 0xFFU);
792
  }
793
}
794
 
795
 
796
/**
797
  * @}
798
  */
799
 
800
/**
801
  * @}
802
  */
803
#endif /* defined (USB) */
804
#endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
805
 
806
/**
807
  * @}
808
  */
809
 
810
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/