Subversion Repositories DashDisplay

Rev

Rev 61 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
77 mjames 1
/**
2
  ******************************************************************************
3
  * @file    stm32l1xx_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
  ******************************************************************************
15
  * @attention
16
  *
17
  * Copyright (c) 2016 STMicroelectronics.
18
  * All rights reserved.
19
  *
20
  * This software is licensed under terms that can be found in the LICENSE file
21
  * in the root directory of this software component.
22
  * If no LICENSE file comes with this software, it is provided AS-IS.
23
  *
24
  ******************************************************************************
25
  @verbatim
26
  ==============================================================================
27
                    ##### How to use this driver #####
28
  ==============================================================================
29
    [..]
30
      (#) Fill parameters of Init structure in USB_CfgTypeDef structure.
31
 
32
      (#) Call USB_CoreInit() API to initialize the USB Core peripheral.
33
 
34
      (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes.
35
 
36
  @endverbatim
37
 
38
  ******************************************************************************
39
  */
40
 
41
/* Includes ------------------------------------------------------------------*/
42
#include "stm32l1xx_hal.h"
43
 
44
/** @addtogroup STM32L1xx_LL_USB_DRIVER
45
  * @{
46
  */
47
 
48
#if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED)
49
#if defined (USB)
50
/* Private typedef -----------------------------------------------------------*/
51
/* Private define ------------------------------------------------------------*/
52
/* Private macro -------------------------------------------------------------*/
53
/* Private variables ---------------------------------------------------------*/
54
/* Private function prototypes -----------------------------------------------*/
55
/* Private functions ---------------------------------------------------------*/
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;
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;
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
/**
176
  * @brief  USB_FlushTxFifo : Flush a Tx FIFO
177
  * @param  USBx : Selected device
178
  * @param  num : FIFO number
179
  *         This parameter can be a value from 1 to 15
180
            15 means Flush all Tx FIFOs
181
  * @retval HAL status
182
  */
183
HAL_StatusTypeDef USB_FlushTxFifo(USB_TypeDef const *USBx, uint32_t num)
184
{
185
  /* Prevent unused argument(s) compilation warning */
186
  UNUSED(USBx);
187
  UNUSED(num);
188
 
189
  /* NOTE : - This function is not required by USB Device FS peripheral, it is used
190
              only by USB OTG FS peripheral.
191
            - This function is added to ensure compatibility across platforms.
192
   */
193
 
194
  return HAL_OK;
195
}
196
 
197
/**
198
  * @brief  USB_FlushRxFifo : Flush Rx FIFO
199
  * @param  USBx : Selected device
200
  * @retval HAL status
201
  */
202
HAL_StatusTypeDef USB_FlushRxFifo(USB_TypeDef const *USBx)
203
{
204
  /* Prevent unused argument(s) compilation warning */
205
  UNUSED(USBx);
206
 
207
  /* NOTE : - This function is not required by USB Device FS peripheral, it is used
208
              only by USB OTG FS peripheral.
209
            - This function is added to ensure compatibility across platforms.
210
   */
211
 
212
  return HAL_OK;
213
}
214
 
215
 
216
#if defined (HAL_PCD_MODULE_ENABLED)
217
/**
218
  * @brief  Activate and configure an endpoint
219
  * @param  USBx Selected device
220
  * @param  ep pointer to endpoint structure
221
  * @retval HAL status
222
  */
223
HAL_StatusTypeDef USB_ActivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
224
{
225
  HAL_StatusTypeDef ret = HAL_OK;
226
  uint16_t wEpRegVal;
227
 
228
  wEpRegVal = PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_T_MASK;
229
 
230
  /* initialize Endpoint */
231
  switch (ep->type)
232
  {
233
    case EP_TYPE_CTRL:
234
      wEpRegVal |= USB_EP_CONTROL;
235
      break;
236
 
237
    case EP_TYPE_BULK:
238
      wEpRegVal |= USB_EP_BULK;
239
      break;
240
 
241
    case EP_TYPE_INTR:
242
      wEpRegVal |= USB_EP_INTERRUPT;
243
      break;
244
 
245
    case EP_TYPE_ISOC:
246
      wEpRegVal |= USB_EP_ISOCHRONOUS;
247
      break;
248
 
249
    default:
250
      ret = HAL_ERROR;
251
      break;
252
  }
253
 
254
  PCD_SET_ENDPOINT(USBx, ep->num, (wEpRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX));
255
 
256
  PCD_SET_EP_ADDRESS(USBx, ep->num, ep->num);
257
 
258
  if (ep->doublebuffer == 0U)
259
  {
260
    if (ep->is_in != 0U)
261
    {
262
      /*Set the endpoint Transmit buffer address */
263
      PCD_SET_EP_TX_ADDRESS(USBx, ep->num, ep->pmaadress);
264
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
265
 
266
      if (ep->type != EP_TYPE_ISOC)
267
      {
268
        /* Configure NAK status for the Endpoint */
269
        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
270
      }
271
      else
272
      {
273
        /* Configure TX Endpoint to disabled state */
274
        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
275
      }
276
    }
277
    else
278
    {
279
      /* Set the endpoint Receive buffer address */
280
      PCD_SET_EP_RX_ADDRESS(USBx, ep->num, ep->pmaadress);
281
 
282
      /* Set the endpoint Receive buffer counter */
283
      PCD_SET_EP_RX_CNT(USBx, ep->num, ep->maxpacket);
284
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
285
 
286
      if (ep->num == 0U)
287
      {
288
        /* Configure VALID status for EP0 */
289
        PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
290
      }
291
      else
292
      {
293
        /* Configure NAK status for OUT Endpoint */
294
        PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_NAK);
295
      }
296
    }
297
  }
298
#if (USE_USB_DOUBLE_BUFFER == 1U)
299
  /* Double Buffer */
300
  else
301
  {
302
    if (ep->type == EP_TYPE_BULK)
303
    {
304
      /* Set bulk endpoint as double buffered */
305
      PCD_SET_BULK_EP_DBUF(USBx, ep->num);
306
    }
307
    else
308
    {
309
      /* Set the ISOC endpoint in double buffer mode */
310
      PCD_CLEAR_EP_KIND(USBx, ep->num);
311
    }
312
 
313
    /* Set buffer address for double buffered mode */
314
    PCD_SET_EP_DBUF_ADDR(USBx, ep->num, ep->pmaaddr0, ep->pmaaddr1);
315
 
316
    if (ep->is_in == 0U)
317
    {
318
      /* Clear the data toggle bits for the endpoint IN/OUT */
319
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
320
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
321
 
322
      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
323
      PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
324
    }
325
    else
326
    {
327
      /* Clear the data toggle bits for the endpoint IN/OUT */
328
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
329
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
330
 
331
      if (ep->type != EP_TYPE_ISOC)
332
      {
333
        /* Configure NAK status for the Endpoint */
334
        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
335
      }
336
      else
337
      {
338
        /* Configure TX Endpoint to disabled state */
339
        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
340
      }
341
 
342
      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
343
    }
344
  }
345
#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
346
 
347
  return ret;
348
}
349
 
350
/**
351
  * @brief  De-activate and de-initialize an endpoint
352
  * @param  USBx Selected device
353
  * @param  ep pointer to endpoint structure
354
  * @retval HAL status
355
  */
356
HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
357
{
358
  if (ep->doublebuffer == 0U)
359
  {
360
    if (ep->is_in != 0U)
361
    {
362
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
363
 
364
      /* Configure DISABLE status for the Endpoint */
365
      PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
366
    }
367
 
368
    else
369
    {
370
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
371
 
372
      /* Configure DISABLE status for the Endpoint */
373
      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
374
    }
375
  }
376
#if (USE_USB_DOUBLE_BUFFER == 1U)
377
  /* Double Buffer */
378
  else
379
  {
380
    if (ep->is_in == 0U)
381
    {
382
      /* Clear the data toggle bits for the endpoint IN/OUT*/
383
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
384
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
385
 
386
      /* Reset value of the data toggle bits for the endpoint out*/
387
      PCD_TX_DTOG(USBx, ep->num);
388
 
389
      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
390
      PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
391
    }
392
    else
393
    {
394
      /* Clear the data toggle bits for the endpoint IN/OUT*/
395
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
396
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
397
      PCD_RX_DTOG(USBx, ep->num);
398
 
399
      /* Configure DISABLE status for the Endpoint*/
400
      PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
401
      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
402
    }
403
  }
404
#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
405
 
406
  return HAL_OK;
407
}
408
 
409
/**
410
  * @brief  USB_EPStartXfer setup and starts a transfer over an EP
411
  * @param  USBx Selected device
412
  * @param  ep pointer to endpoint structure
413
  * @retval HAL status
414
  */
415
HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep)
416
{
417
  uint32_t len;
418
#if (USE_USB_DOUBLE_BUFFER == 1U)
419
  uint16_t pmabuffer;
420
  uint16_t wEPVal;
421
#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
422
 
423
  /* IN endpoint */
424
  if (ep->is_in == 1U)
425
  {
426
    /*Multi packet transfer*/
427
    if (ep->xfer_len > ep->maxpacket)
428
    {
429
      len = ep->maxpacket;
430
    }
431
    else
432
    {
433
      len = ep->xfer_len;
434
    }
435
 
436
    /* configure and validate Tx endpoint */
437
    if (ep->doublebuffer == 0U)
438
    {
439
      USB_WritePMA(USBx, ep->xfer_buff, ep->pmaadress, (uint16_t)len);
440
      PCD_SET_EP_TX_CNT(USBx, ep->num, len);
441
    }
442
#if (USE_USB_DOUBLE_BUFFER == 1U)
443
    else
444
    {
445
      /* double buffer bulk management */
446
      if (ep->type == EP_TYPE_BULK)
447
      {
448
        if (ep->xfer_len_db > ep->maxpacket)
449
        {
450
          /* enable double buffer */
451
          PCD_SET_BULK_EP_DBUF(USBx, ep->num);
452
 
453
          /* each Time to write in PMA xfer_len_db will */
454
          ep->xfer_len_db -= len;
455
 
456
          /* Fill the two first buffer in the Buffer0 & Buffer1 */
457
          if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
458
          {
459
            /* Set the Double buffer counter for pmabuffer1 */
460
            PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
461
            pmabuffer = ep->pmaaddr1;
462
 
463
            /* Write the user buffer to USB PMA */
464
            USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
465
            ep->xfer_buff += len;
466
 
467
            if (ep->xfer_len_db > ep->maxpacket)
468
            {
469
              ep->xfer_len_db -= len;
470
            }
471
            else
472
            {
473
              len = ep->xfer_len_db;
474
              ep->xfer_len_db = 0U;
475
            }
476
 
477
            /* Set the Double buffer counter for pmabuffer0 */
478
            PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
479
            pmabuffer = ep->pmaaddr0;
480
 
481
            /* Write the user buffer to USB PMA */
482
            USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
483
          }
484
          else
485
          {
486
            /* Set the Double buffer counter for pmabuffer0 */
487
            PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
488
            pmabuffer = ep->pmaaddr0;
489
 
490
            /* Write the user buffer to USB PMA */
491
            USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
492
            ep->xfer_buff += len;
493
 
494
            if (ep->xfer_len_db > ep->maxpacket)
495
            {
496
              ep->xfer_len_db -= len;
497
            }
498
            else
499
            {
500
              len = ep->xfer_len_db;
501
              ep->xfer_len_db = 0U;
502
            }
503
 
504
            /* Set the Double buffer counter for pmabuffer1 */
505
            PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
506
            pmabuffer = ep->pmaaddr1;
507
 
508
            /* Write the user buffer to USB PMA */
509
            USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
510
          }
511
        }
512
        /* auto Switch to single buffer mode when transfer <Mps no need to manage in double buffer */
513
        else
514
        {
515
          len = ep->xfer_len_db;
516
 
517
          /* disable double buffer mode for Bulk endpoint */
518
          PCD_CLEAR_BULK_EP_DBUF(USBx, ep->num);
519
 
520
          /* Set Tx count with nbre of byte to be transmitted */
521
          PCD_SET_EP_TX_CNT(USBx, ep->num, len);
522
          pmabuffer = ep->pmaaddr0;
523
 
524
          /* Write the user buffer to USB PMA */
525
          USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
526
        }
527
      }
528
      else /* manage isochronous double buffer IN mode */
529
      {
530
        /* each Time to write in PMA xfer_len_db will */
531
        ep->xfer_len_db -= len;
532
 
533
        /* Fill the data buffer */
534
        if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
535
        {
536
          /* Set the Double buffer counter for pmabuffer1 */
537
          PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
538
          pmabuffer = ep->pmaaddr1;
539
 
540
          /* Write the user buffer to USB PMA */
541
          USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
542
        }
543
        else
544
        {
545
          /* Set the Double buffer counter for pmabuffer0 */
546
          PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
547
          pmabuffer = ep->pmaaddr0;
548
 
549
          /* Write the user buffer to USB PMA */
550
          USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
551
        }
552
      }
553
    }
554
#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
555
 
556
    PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID);
557
  }
558
  else /* OUT endpoint */
559
  {
560
    if (ep->doublebuffer == 0U)
561
    {
562
      /* Multi packet transfer */
563
      if (ep->xfer_len > ep->maxpacket)
564
      {
565
        len = ep->maxpacket;
566
        ep->xfer_len -= len;
567
      }
568
      else
569
      {
570
        len = ep->xfer_len;
571
        ep->xfer_len = 0U;
572
      }
573
      /* configure and validate Rx endpoint */
574
      PCD_SET_EP_RX_CNT(USBx, ep->num, len);
575
    }
576
#if (USE_USB_DOUBLE_BUFFER == 1U)
577
    else
578
    {
579
      /* First Transfer Coming From HAL_PCD_EP_Receive & From ISR */
580
      /* Set the Double buffer counter */
581
      if (ep->type == EP_TYPE_BULK)
582
      {
583
        PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, ep->maxpacket);
584
 
585
        /* Coming from ISR */
586
        if (ep->xfer_count != 0U)
587
        {
588
          /* update last value to check if there is blocking state */
589
          wEPVal = PCD_GET_ENDPOINT(USBx, ep->num);
590
 
591
          /*Blocking State */
592
          if ((((wEPVal & USB_EP_DTOG_RX) != 0U) && ((wEPVal & USB_EP_DTOG_TX) != 0U)) ||
593
              (((wEPVal & USB_EP_DTOG_RX) == 0U) && ((wEPVal & USB_EP_DTOG_TX) == 0U)))
594
          {
595
            PCD_FREE_USER_BUFFER(USBx, ep->num, 0U);
596
          }
597
        }
598
      }
599
      /* iso out double */
600
      else if (ep->type == EP_TYPE_ISOC)
601
      {
602
        /* Multi packet transfer */
603
        if (ep->xfer_len > ep->maxpacket)
604
        {
605
          len = ep->maxpacket;
606
          ep->xfer_len -= len;
607
        }
608
        else
609
        {
610
          len = ep->xfer_len;
611
          ep->xfer_len = 0U;
612
        }
613
        PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, len);
614
      }
615
      else
616
      {
617
        return HAL_ERROR;
618
      }
619
    }
620
#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
621
 
622
    PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
623
  }
624
 
625
  return HAL_OK;
626
}
627
 
628
 
629
/**
630
  * @brief  USB_EPSetStall set a stall condition over an EP
631
  * @param  USBx Selected device
632
  * @param  ep pointer to endpoint structure
633
  * @retval HAL status
634
  */
635
HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
636
{
637
  if (ep->is_in != 0U)
638
  {
639
    PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_STALL);
640
  }
641
  else
642
  {
643
    PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_STALL);
644
  }
645
 
646
  return HAL_OK;
647
}
648
 
649
/**
650
  * @brief  USB_EPClearStall Clear a stall condition over an EP
651
  * @param  USBx Selected device
652
  * @param  ep pointer to endpoint structure
653
  * @retval HAL status
654
  */
655
HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
656
{
657
  if (ep->doublebuffer == 0U)
658
  {
659
    if (ep->is_in != 0U)
660
    {
661
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
662
 
663
      if (ep->type != EP_TYPE_ISOC)
664
      {
665
        /* Configure NAK status for the Endpoint */
666
        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
667
      }
668
    }
669
    else
670
    {
671
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
672
 
673
      /* Configure VALID status for the Endpoint */
674
      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
675
    }
676
  }
677
 
678
  return HAL_OK;
679
}
680
 
681
/**
682
   * @brief  USB_EPStoptXfer  Stop transfer on an EP
683
   * @param  USBx  usb device instance
684
   * @param  ep pointer to endpoint structure
685
   * @retval HAL status
686
   */
687
HAL_StatusTypeDef USB_EPStopXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep)
688
{
689
  /* IN endpoint */
690
  if (ep->is_in == 1U)
691
  {
692
    if (ep->doublebuffer == 0U)
693
    {
694
      if (ep->type != EP_TYPE_ISOC)
695
      {
696
        /* Configure NAK status for the Endpoint */
697
        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
698
      }
699
      else
700
      {
701
        /* Configure TX Endpoint to disabled state */
702
        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
703
      }
704
    }
705
  }
706
  else /* OUT endpoint */
707
  {
708
    if (ep->doublebuffer == 0U)
709
    {
710
      if (ep->type != EP_TYPE_ISOC)
711
      {
712
        /* Configure NAK status for the Endpoint */
713
        PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_NAK);
714
      }
715
      else
716
      {
717
        /* Configure RX Endpoint to disabled state */
718
        PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
719
      }
720
    }
721
  }
722
 
723
  return HAL_OK;
724
}
725
#endif /* defined (HAL_PCD_MODULE_ENABLED) */
726
 
727
/**
728
  * @brief  USB_StopDevice Stop the usb device mode
729
  * @param  USBx Selected device
730
  * @retval HAL status
731
  */
732
HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx)
733
{
734
  /* disable all interrupts and force USB reset */
735
  USBx->CNTR = (uint16_t)USB_CNTR_FRES;
736
 
737
  /* clear interrupt status register */
738
  USBx->ISTR = 0U;
739
 
740
  /* switch-off device */
741
  USBx->CNTR = (uint16_t)(USB_CNTR_FRES | USB_CNTR_PDWN);
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_TypeDef *USBx, uint8_t address)
754
{
755
  if (address == 0U)
756
  {
757
    /* set device address and enable function */
758
    USBx->DADDR = (uint16_t)USB_DADDR_EF;
759
  }
760
 
761
  return HAL_OK;
762
}
763
 
764
/**
765
  * @brief  USB_DevConnect Connect the USB device by enabling the pull-up/pull-down
766
  * @param  USBx Selected device
767
  * @retval HAL status
768
  */
769
HAL_StatusTypeDef  USB_DevConnect(USB_TypeDef *USBx)
770
{
771
  /* Prevent unused argument(s) compilation warning */
772
  UNUSED(USBx);
773
 
774
  /* NOTE : - This function is not required by USB Device FS peripheral, it is used
775
              only by USB OTG FS peripheral.
776
            - This function is added to ensure compatibility across platforms.
777
   */
778
 
779
  return HAL_OK;
780
}
781
 
782
/**
783
  * @brief  USB_DevDisconnect Disconnect the USB device by disabling the pull-up/pull-down
784
  * @param  USBx Selected device
785
  * @retval HAL status
786
  */
787
HAL_StatusTypeDef  USB_DevDisconnect(USB_TypeDef *USBx)
788
{
789
  /* Prevent unused argument(s) compilation warning */
790
  UNUSED(USBx);
791
 
792
  /* NOTE : - This function is not required by USB Device FS peripheral, it is used
793
              only by USB OTG FS peripheral.
794
            - This function is added to ensure compatibility across platforms.
795
   */
796
 
797
  return HAL_OK;
798
}
799
 
800
/**
801
  * @brief  USB_ReadInterrupts return the global USB interrupt status
802
  * @param  USBx Selected device
803
  * @retval USB Global Interrupt status
804
  */
805
uint32_t USB_ReadInterrupts(USB_TypeDef const *USBx)
806
{
807
  uint32_t tmpreg;
808
 
809
  tmpreg = USBx->ISTR;
810
  return tmpreg;
811
}
812
 
813
/**
814
  * @brief  USB_ActivateRemoteWakeup : active remote wakeup signalling
815
  * @param  USBx Selected device
816
  * @retval HAL status
817
  */
818
HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx)
819
{
820
  USBx->CNTR |= (uint16_t)USB_CNTR_RESUME;
821
 
822
  return HAL_OK;
823
}
824
 
825
/**
826
  * @brief  USB_DeActivateRemoteWakeup de-active remote wakeup signalling
827
  * @param  USBx Selected device
828
  * @retval HAL status
829
  */
830
HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx)
831
{
832
  USBx->CNTR &= (uint16_t)(~USB_CNTR_RESUME);
833
 
834
  return HAL_OK;
835
}
836
 
837
/**
838
  * @brief Copy a buffer from user memory area to packet memory area (PMA)
839
  * @param   USBx USB peripheral instance register address.
840
  * @param   pbUsrBuf pointer to user memory area.
841
  * @param   wPMABufAddr address into PMA.
842
  * @param   wNBytes no. of bytes to be copied.
843
  * @retval None
844
  */
845
void USB_WritePMA(USB_TypeDef const *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
846
{
847
  uint32_t n = ((uint32_t)wNBytes + 1U) >> 1;
848
  uint32_t BaseAddr = (uint32_t)USBx;
849
  uint32_t count;
850
  uint16_t WrVal;
851
  __IO uint16_t *pdwVal;
852
  uint8_t *pBuf = pbUsrBuf;
853
 
854
  pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
855
 
856
  for (count = n; count != 0U; count--)
857
  {
858
    WrVal = pBuf[0];
859
    WrVal |= (uint16_t)pBuf[1] << 8;
860
    *pdwVal = (WrVal & 0xFFFFU);
861
    pdwVal++;
862
 
863
#if PMA_ACCESS > 1U
864
    pdwVal++;
865
#endif /* PMA_ACCESS */
866
 
867
    pBuf++;
868
    pBuf++;
869
  }
870
}
871
 
872
/**
873
  * @brief Copy data from packet memory area (PMA) to user memory buffer
874
  * @param   USBx USB peripheral instance register address.
875
  * @param   pbUsrBuf pointer to user memory area.
876
  * @param   wPMABufAddr address into PMA.
877
  * @param   wNBytes no. of bytes to be copied.
878
  * @retval None
879
  */
880
void USB_ReadPMA(USB_TypeDef const *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
881
{
882
  uint32_t n = (uint32_t)wNBytes >> 1;
883
  uint32_t BaseAddr = (uint32_t)USBx;
884
  uint32_t count;
885
  uint32_t RdVal;
886
  __IO uint16_t *pdwVal;
887
  uint8_t *pBuf = pbUsrBuf;
888
 
889
  pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
890
 
891
  for (count = n; count != 0U; count--)
892
  {
893
    RdVal = *(__IO uint16_t *)pdwVal;
894
    pdwVal++;
895
    *pBuf = (uint8_t)((RdVal >> 0) & 0xFFU);
896
    pBuf++;
897
    *pBuf = (uint8_t)((RdVal >> 8) & 0xFFU);
898
    pBuf++;
899
 
900
#if PMA_ACCESS > 1U
901
    pdwVal++;
902
#endif /* PMA_ACCESS */
903
  }
904
 
905
  if ((wNBytes % 2U) != 0U)
906
  {
907
    RdVal = *pdwVal;
908
    *pBuf = (uint8_t)((RdVal >> 0) & 0xFFU);
909
  }
910
}
911
 
912
 
913
/**
914
  * @}
915
  */
916
 
917
/**
918
  * @}
919
  */
920
#endif /* defined (USB) */
921
#endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
922
 
923
/**
924
  * @}
925
  */