Subversion Repositories DashDisplay

Rev

Rev 56 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
56 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
  @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 "stm32l1xx_hal.h"
42
 
43
/** @addtogroup STM32L1xx_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
61 mjames 59
  * @param  USBx USB Instance
60
  * @param  cfg pointer to a USB_CfgTypeDef structure that contains
56 mjames 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
61 mjames 81
  * @param  USBx Selected device
56 mjames 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
61 mjames 106
  * @param  USBx Selected device
56 mjames 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
/**
61 mjames 126
  * @brief  USB_SetCurrentMode Set functional mode
127
  * @param  USBx Selected device
128
  * @param  mode current core mode
56 mjames 129
  *          This parameter can be one of the these values:
61 mjames 130
  *            @arg USB_DEVICE_MODE Peripheral mode
56 mjames 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
/**
61 mjames 147
  * @brief  USB_DevInit Initializes the USB controller registers
56 mjames 148
  *         for device mode
61 mjames 149
  * @param  USBx Selected device
150
  * @param  cfg  pointer to a USB_CfgTypeDef structure that contains
56 mjames 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 */
61 mjames 160
  /* CNTR_FRES = 1 */
56 mjames 161
  USBx->CNTR = (uint16_t)USB_CNTR_FRES;
162
 
61 mjames 163
  /* CNTR_FRES = 0 */
56 mjames 164
  USBx->CNTR = 0U;
165
 
61 mjames 166
  /* Clear pending interrupts */
56 mjames 167
  USBx->ISTR = 0U;
168
 
169
  /*Set Btable Address*/
170
  USBx->BTABLE = BTABLE_ADDRESS;
171
 
172
  return HAL_OK;
173
}
174
 
61 mjames 175
#if defined (HAL_PCD_MODULE_ENABLED)
56 mjames 176
/**
177
  * @brief  Activate and configure an endpoint
61 mjames 178
  * @param  USBx Selected device
179
  * @param  ep pointer to endpoint structure
56 mjames 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);
61 mjames 240
 
56 mjames 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);
61 mjames 244
 
56 mjames 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
    /* Set the endpoint as double buffered */
253
    PCD_SET_EP_DBUF(USBx, ep->num);
61 mjames 254
 
56 mjames 255
    /* Set buffer address for double buffered mode */
256
    PCD_SET_EP_DBUF_ADDR(USBx, ep->num, ep->pmaaddr0, ep->pmaaddr1);
257
 
258
    if (ep->is_in == 0U)
259
    {
260
      /* Clear the data toggle bits for the endpoint IN/OUT */
261
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
262
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
263
 
264
      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
265
      PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
266
    }
267
    else
268
    {
269
      /* Clear the data toggle bits for the endpoint IN/OUT */
270
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
271
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
272
 
273
      if (ep->type != EP_TYPE_ISOC)
274
      {
275
        /* Configure NAK status for the Endpoint */
276
        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
277
      }
278
      else
279
      {
280
        /* Configure TX Endpoint to disabled state */
281
        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
282
      }
283
 
284
      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
285
    }
286
  }
287
 
288
  return ret;
289
}
290
 
291
/**
292
  * @brief  De-activate and de-initialize an endpoint
61 mjames 293
  * @param  USBx Selected device
294
  * @param  ep pointer to endpoint structure
56 mjames 295
  * @retval HAL status
296
  */
297
HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
298
{
299
  if (ep->doublebuffer == 0U)
300
  {
301
    if (ep->is_in != 0U)
302
    {
303
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
61 mjames 304
 
56 mjames 305
      /* Configure DISABLE status for the Endpoint*/
306
      PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
307
    }
308
    else
309
    {
310
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
61 mjames 311
 
56 mjames 312
      /* Configure DISABLE status for the Endpoint*/
313
      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
314
    }
315
  }
316
  /*Double Buffer*/
317
  else
318
  {
319
    if (ep->is_in == 0U)
320
    {
321
      /* Clear the data toggle bits for the endpoint IN/OUT*/
322
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
323
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
324
 
325
      /* Reset value of the data toggle bits for the endpoint out*/
326
      PCD_TX_DTOG(USBx, ep->num);
327
 
328
      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
329
      PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
330
    }
331
    else
332
    {
333
      /* Clear the data toggle bits for the endpoint IN/OUT*/
334
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
335
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
336
      PCD_RX_DTOG(USBx, ep->num);
61 mjames 337
 
56 mjames 338
      /* Configure DISABLE status for the Endpoint*/
339
      PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
340
      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
341
    }
342
  }
343
 
344
  return HAL_OK;
345
}
346
 
347
/**
61 mjames 348
  * @brief  USB_EPStartXfer setup and starts a transfer over an EP
349
  * @param  USBx Selected device
350
  * @param  ep pointer to endpoint structure
56 mjames 351
  * @retval HAL status
352
  */
353
HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep)
354
{
61 mjames 355
  uint32_t len;
56 mjames 356
  uint16_t pmabuffer;
357
  uint16_t wEPVal;
358
 
359
  /* IN endpoint */
360
  if (ep->is_in == 1U)
361
  {
362
    /*Multi packet transfer*/
363
    if (ep->xfer_len > ep->maxpacket)
364
    {
365
      len = ep->maxpacket;
366
    }
367
    else
368
    {
369
      len = ep->xfer_len;
370
    }
371
 
372
    /* configure and validate Tx endpoint */
373
    if (ep->doublebuffer == 0U)
374
    {
375
      USB_WritePMA(USBx, ep->xfer_buff, ep->pmaadress, (uint16_t)len);
376
      PCD_SET_EP_TX_CNT(USBx, ep->num, len);
377
    }
378
    else
379
    {
61 mjames 380
      /* double buffer bulk management */
56 mjames 381
      if (ep->type == EP_TYPE_BULK)
382
      {
383
        if (ep->xfer_len_db > ep->maxpacket)
384
        {
61 mjames 385
          /* enable double buffer */
56 mjames 386
          PCD_SET_EP_DBUF(USBx, ep->num);
61 mjames 387
 
388
          /* each Time to write in PMA xfer_len_db will */
56 mjames 389
          ep->xfer_len_db -= len;
390
 
61 mjames 391
          /* Fill the two first buffer in the Buffer0 & Buffer1 */
56 mjames 392
          if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
393
          {
394
            /* Set the Double buffer counter for pmabuffer1 */
395
            PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
396
            pmabuffer = ep->pmaaddr1;
397
 
61 mjames 398
            /* Write the user buffer to USB PMA */
56 mjames 399
            USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
400
            ep->xfer_buff += len;
401
 
402
            if (ep->xfer_len_db > ep->maxpacket)
403
            {
404
              ep->xfer_len_db -= len;
405
            }
406
            else
407
            {
408
              len = ep->xfer_len_db;
61 mjames 409
              ep->xfer_len_db = 0U;
56 mjames 410
            }
411
 
412
            /* Set the Double buffer counter for pmabuffer0 */
413
            PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
414
            pmabuffer = ep->pmaaddr0;
61 mjames 415
 
416
            /* Write the user buffer to USB PMA */
56 mjames 417
            USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
418
          }
419
          else
420
          {
421
            /* Set the Double buffer counter for pmabuffer0 */
422
            PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
423
            pmabuffer = ep->pmaaddr0;
61 mjames 424
 
425
            /* Write the user buffer to USB PMA */
56 mjames 426
            USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
427
            ep->xfer_buff += len;
428
 
429
            if (ep->xfer_len_db > ep->maxpacket)
430
            {
431
              ep->xfer_len_db -= len;
432
            }
433
            else
434
            {
435
              len = ep->xfer_len_db;
61 mjames 436
              ep->xfer_len_db = 0U;
56 mjames 437
            }
438
 
439
            /* Set the Double buffer counter for pmabuffer1 */
440
            PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
441
            pmabuffer = ep->pmaaddr1;
61 mjames 442
 
443
            /* Write the user buffer to USB PMA */
56 mjames 444
            USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
445
          }
446
        }
61 mjames 447
        /* auto Switch to single buffer mode when transfer <Mps no need to manage in double buffer */
56 mjames 448
        else
449
        {
450
          len = ep->xfer_len_db;
61 mjames 451
 
452
          /* disable double buffer mode */
56 mjames 453
          PCD_CLEAR_EP_DBUF(USBx, ep->num);
61 mjames 454
 
455
          /* Set Tx count with nbre of byte to be transmitted */
56 mjames 456
          PCD_SET_EP_TX_CNT(USBx, ep->num, len);
457
          pmabuffer = ep->pmaaddr0;
61 mjames 458
 
459
          /* Write the user buffer to USB PMA */
56 mjames 460
          USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
461
        }
61 mjames 462
      }/* end if bulk double buffer */
56 mjames 463
 
61 mjames 464
      /* manage isochronous double buffer IN mode */
56 mjames 465
      else
466
      {
61 mjames 467
        /* enable double buffer */
468
        PCD_SET_EP_DBUF(USBx, ep->num);
469
 
470
        /* each Time to write in PMA xfer_len_db will */
471
        ep->xfer_len_db -= len;
472
 
473
        /* Fill the data buffer */
56 mjames 474
        if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
475
        {
476
          /* Set the Double buffer counter for pmabuffer1 */
477
          PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
478
          pmabuffer = ep->pmaaddr1;
61 mjames 479
 
480
          /* Write the user buffer to USB PMA */
481
          USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
482
          ep->xfer_buff += len;
483
 
484
          if (ep->xfer_len_db > ep->maxpacket)
485
          {
486
            ep->xfer_len_db -= len;
487
          }
488
          else
489
          {
490
            len = ep->xfer_len_db;
491
            ep->xfer_len_db = 0U;
492
          }
493
 
494
          if (len > 0U)
495
          {
496
            /* Set the Double buffer counter for pmabuffer0 */
497
            PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
498
            pmabuffer = ep->pmaaddr0;
499
 
500
            /* Write the user buffer to USB PMA */
501
            USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
502
          }
56 mjames 503
        }
504
        else
505
        {
506
          /* Set the Double buffer counter for pmabuffer0 */
507
          PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
508
          pmabuffer = ep->pmaaddr0;
61 mjames 509
 
510
          /* Write the user buffer to USB PMA */
511
          USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
512
          ep->xfer_buff += len;
513
 
514
          if (ep->xfer_len_db > ep->maxpacket)
515
          {
516
            ep->xfer_len_db -= len;
517
          }
518
          else
519
          {
520
            len = ep->xfer_len_db;
521
            ep->xfer_len_db = 0U;
522
          }
523
 
524
          if (len > 0U)
525
          {
526
            /* Set the Double buffer counter for pmabuffer1 */
527
            PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
528
            pmabuffer = ep->pmaaddr1;
529
 
530
            /* Write the user buffer to USB PMA */
531
            USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
532
          }
56 mjames 533
        }
534
      }
535
    }
536
 
537
    PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID);
538
  }
539
  else /* OUT endpoint */
540
  {
541
    if (ep->doublebuffer == 0U)
542
    {
61 mjames 543
      /* Multi packet transfer */
56 mjames 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
      /* configure and validate Rx endpoint */
555
      PCD_SET_EP_RX_CNT(USBx, ep->num, len);
556
    }
557
    else
558
    {
61 mjames 559
      /* First Transfer Coming From HAL_PCD_EP_Receive & From ISR */
560
      /* Set the Double buffer counter */
56 mjames 561
      if (ep->type == EP_TYPE_BULK)
562
      {
563
        PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, ep->maxpacket);
61 mjames 564
 
565
        /* Coming from ISR */
56 mjames 566
        if (ep->xfer_count != 0U)
567
        {
61 mjames 568
          /* update last value to check if there is blocking state */
56 mjames 569
          wEPVal = PCD_GET_ENDPOINT(USBx, ep->num);
61 mjames 570
 
56 mjames 571
          /*Blocking State */
572
          if ((((wEPVal & USB_EP_DTOG_RX) != 0U) && ((wEPVal & USB_EP_DTOG_TX) != 0U)) ||
573
              (((wEPVal & USB_EP_DTOG_RX) == 0U) && ((wEPVal & USB_EP_DTOG_TX) == 0U)))
574
          {
575
            PCD_FreeUserBuffer(USBx, ep->num, 0U);
576
          }
577
        }
578
      }
61 mjames 579
      /* iso out double */
56 mjames 580
      else if (ep->type == EP_TYPE_ISOC)
581
      {
61 mjames 582
        /* Multi packet transfer */
56 mjames 583
        if (ep->xfer_len > ep->maxpacket)
584
        {
585
          len = ep->maxpacket;
586
          ep->xfer_len -= len;
587
        }
588
        else
589
        {
590
          len = ep->xfer_len;
591
          ep->xfer_len = 0U;
592
        }
593
        PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, len);
594
      }
595
      else
596
      {
597
        return HAL_ERROR;
598
      }
599
    }
600
 
601
    PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
602
  }
603
 
604
  return HAL_OK;
605
}
606
 
607
 
608
/**
61 mjames 609
  * @brief  USB_EPSetStall set a stall condition over an EP
610
  * @param  USBx Selected device
611
  * @param  ep pointer to endpoint structure
56 mjames 612
  * @retval HAL status
613
  */
614
HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
615
{
616
  if (ep->is_in != 0U)
617
  {
618
    PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_STALL);
619
  }
620
  else
621
  {
622
    PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_STALL);
623
  }
624
 
625
  return HAL_OK;
626
}
627
 
628
/**
61 mjames 629
  * @brief  USB_EPClearStall Clear a stall condition over an EP
630
  * @param  USBx Selected device
631
  * @param  ep pointer to endpoint structure
56 mjames 632
  * @retval HAL status
633
  */
634
HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
635
{
636
  if (ep->doublebuffer == 0U)
637
  {
638
    if (ep->is_in != 0U)
639
    {
640
      PCD_CLEAR_TX_DTOG(USBx, ep->num);
641
 
642
      if (ep->type != EP_TYPE_ISOC)
643
      {
644
        /* Configure NAK status for the Endpoint */
645
        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
646
      }
647
    }
648
    else
649
    {
650
      PCD_CLEAR_RX_DTOG(USBx, ep->num);
651
 
61 mjames 652
      /* Configure VALID status for the Endpoint */
56 mjames 653
      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
654
    }
655
  }
656
 
657
  return HAL_OK;
658
}
61 mjames 659
#endif
56 mjames 660
 
661
/**
61 mjames 662
  * @brief  USB_StopDevice Stop the usb device mode
663
  * @param  USBx Selected device
56 mjames 664
  * @retval HAL status
665
  */
666
HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx)
667
{
668
  /* disable all interrupts and force USB reset */
669
  USBx->CNTR = (uint16_t)USB_CNTR_FRES;
670
 
671
  /* clear interrupt status register */
672
  USBx->ISTR = 0U;
673
 
674
  /* switch-off device */
675
  USBx->CNTR = (uint16_t)(USB_CNTR_FRES | USB_CNTR_PDWN);
676
 
677
  return HAL_OK;
678
}
679
 
680
/**
61 mjames 681
  * @brief  USB_SetDevAddress Stop the usb device mode
682
  * @param  USBx Selected device
683
  * @param  address new device address to be assigned
56 mjames 684
  *          This parameter can be a value from 0 to 255
685
  * @retval HAL status
686
  */
687
HAL_StatusTypeDef  USB_SetDevAddress(USB_TypeDef *USBx, uint8_t address)
688
{
689
  if (address == 0U)
690
  {
691
    /* set device address and enable function */
692
    USBx->DADDR = (uint16_t)USB_DADDR_EF;
693
  }
694
 
695
  return HAL_OK;
696
}
697
 
698
/**
61 mjames 699
  * @brief  USB_DevConnect Connect the USB device by enabling the pull-up/pull-down
700
  * @param  USBx Selected device
56 mjames 701
  * @retval HAL status
702
  */
703
HAL_StatusTypeDef  USB_DevConnect(USB_TypeDef *USBx)
704
{
705
  /* Prevent unused argument(s) compilation warning */
706
  UNUSED(USBx);
707
 
708
  /* NOTE : - This function is not required by USB Device FS peripheral, it is used
709
              only by USB OTG FS peripheral.
710
            - This function is added to ensure compatibility across platforms.
711
   */
712
 
713
  return HAL_OK;
714
}
715
 
716
/**
61 mjames 717
  * @brief  USB_DevDisconnect Disconnect the USB device by disabling the pull-up/pull-down
718
  * @param  USBx Selected device
56 mjames 719
  * @retval HAL status
720
  */
721
HAL_StatusTypeDef  USB_DevDisconnect(USB_TypeDef *USBx)
722
{
723
  /* Prevent unused argument(s) compilation warning */
724
  UNUSED(USBx);
725
 
726
  /* NOTE : - This function is not required by USB Device FS peripheral, it is used
727
              only by USB OTG FS peripheral.
728
            - This function is added to ensure compatibility across platforms.
729
   */
730
 
731
  return HAL_OK;
732
}
733
 
734
/**
61 mjames 735
  * @brief  USB_ReadInterrupts return the global USB interrupt status
736
  * @param  USBx Selected device
56 mjames 737
  * @retval HAL status
738
  */
739
uint32_t  USB_ReadInterrupts(USB_TypeDef *USBx)
740
{
741
  uint32_t tmpreg;
742
 
743
  tmpreg = USBx->ISTR;
744
  return tmpreg;
745
}
746
 
747
/**
748
  * @brief  USB_ActivateRemoteWakeup : active remote wakeup signalling
61 mjames 749
  * @param  USBx Selected device
56 mjames 750
  * @retval HAL status
751
  */
752
HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx)
753
{
754
  USBx->CNTR |= (uint16_t)USB_CNTR_RESUME;
755
 
756
  return HAL_OK;
757
}
758
 
759
/**
61 mjames 760
  * @brief  USB_DeActivateRemoteWakeup de-active remote wakeup signalling
761
  * @param  USBx Selected device
56 mjames 762
  * @retval HAL status
763
  */
764
HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx)
765
{
766
  USBx->CNTR &= (uint16_t)(~USB_CNTR_RESUME);
61 mjames 767
 
56 mjames 768
  return HAL_OK;
769
}
770
 
771
/**
772
  * @brief Copy a buffer from user memory area to packet memory area (PMA)
773
  * @param   USBx USB peripheral instance register address.
774
  * @param   pbUsrBuf pointer to user memory area.
775
  * @param   wPMABufAddr address into PMA.
61 mjames 776
  * @param   wNBytes no. of bytes to be copied.
56 mjames 777
  * @retval None
778
  */
779
void USB_WritePMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
780
{
781
  uint32_t n = ((uint32_t)wNBytes + 1U) >> 1;
782
  uint32_t BaseAddr = (uint32_t)USBx;
783
  uint32_t i, temp1, temp2;
784
  __IO uint16_t *pdwVal;
785
  uint8_t *pBuf = pbUsrBuf;
786
 
787
  pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
788
 
789
  for (i = n; i != 0U; i--)
790
  {
791
    temp1 = *pBuf;
792
    pBuf++;
793
    temp2 = temp1 | ((uint16_t)((uint16_t) *pBuf << 8));
794
    *pdwVal = (uint16_t)temp2;
795
    pdwVal++;
796
 
797
#if PMA_ACCESS > 1U
798
    pdwVal++;
799
#endif
800
 
801
    pBuf++;
802
  }
803
}
804
 
805
/**
806
  * @brief Copy data from packet memory area (PMA) to user memory buffer
61 mjames 807
  * @param   USBx USB peripheral instance register address.
56 mjames 808
  * @param   pbUsrBuf pointer to user memory area.
809
  * @param   wPMABufAddr address into PMA.
61 mjames 810
  * @param   wNBytes no. of bytes to be copied.
56 mjames 811
  * @retval None
812
  */
813
void USB_ReadPMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
814
{
815
  uint32_t n = (uint32_t)wNBytes >> 1;
816
  uint32_t BaseAddr = (uint32_t)USBx;
817
  uint32_t i, temp;
818
  __IO uint16_t *pdwVal;
819
  uint8_t *pBuf = pbUsrBuf;
820
 
821
  pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
822
 
823
  for (i = n; i != 0U; i--)
824
  {
825
    temp = *(__IO uint16_t *)pdwVal;
826
    pdwVal++;
827
    *pBuf = (uint8_t)((temp >> 0) & 0xFFU);
828
    pBuf++;
829
    *pBuf = (uint8_t)((temp >> 8) & 0xFFU);
830
    pBuf++;
831
 
832
#if PMA_ACCESS > 1U
833
    pdwVal++;
834
#endif
835
  }
836
 
837
  if ((wNBytes % 2U) != 0U)
838
  {
839
    temp = *pdwVal;
840
    *pBuf = (uint8_t)((temp >> 0) & 0xFFU);
841
  }
842
}
843
 
844
 
845
/**
846
  * @}
847
  */
848
 
849
/**
850
  * @}
851
  */
852
#endif /* defined (USB) */
853
#endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
854
 
855
/**
856
  * @}
857
  */
858
 
859
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/