Subversion Repositories LedShow

Rev

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

Rev Author Line No. Line
2 mjames 1
/**
2
  ******************************************************************************
3
  * @file    usbd_core.c
4
  * @author  MCD Application Team
5
  * @brief   This file provides all the USBD core functions.
6
  ******************************************************************************
7
  * @attention
8
  *
9 mjames 9
  * <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
10
  * All rights reserved.</center></h2>
2 mjames 11
  *
9 mjames 12
  * This software component is licensed by ST under Ultimate Liberty license
13
  * SLA0044, the "License"; You may not use this file except in compliance with
14
  * the License. You may obtain a copy of the License at:
15
  *                      www.st.com/SLA0044
2 mjames 16
  *
17
  ******************************************************************************
9 mjames 18
  */
2 mjames 19
 
20
/* Includes ------------------------------------------------------------------*/
21
#include "usbd_core.h"
22
 
23
/** @addtogroup STM32_USBD_DEVICE_LIBRARY
24
* @{
25
*/
26
 
27
 
9 mjames 28
/** @defgroup USBD_CORE
2 mjames 29
* @brief usbd core module
30
* @{
9 mjames 31
*/
2 mjames 32
 
33
/** @defgroup USBD_CORE_Private_TypesDefinitions
34
* @{
9 mjames 35
*/
36
 
2 mjames 37
/**
38
* @}
9 mjames 39
*/
2 mjames 40
 
41
 
42
/** @defgroup USBD_CORE_Private_Defines
43
* @{
9 mjames 44
*/
2 mjames 45
 
46
/**
47
* @}
9 mjames 48
*/
2 mjames 49
 
50
 
51
/** @defgroup USBD_CORE_Private_Macros
52
* @{
9 mjames 53
*/
54
 
2 mjames 55
/**
56
* @}
9 mjames 57
*/
2 mjames 58
 
59
 
60
/** @defgroup USBD_CORE_Private_FunctionPrototypes
61
* @{
9 mjames 62
*/
2 mjames 63
 
64
/**
65
* @}
9 mjames 66
*/
2 mjames 67
 
68
/** @defgroup USBD_CORE_Private_Variables
69
* @{
9 mjames 70
*/
2 mjames 71
 
72
/**
73
* @}
9 mjames 74
*/
2 mjames 75
 
9 mjames 76
 
2 mjames 77
/** @defgroup USBD_CORE_Private_Functions
78
* @{
9 mjames 79
*/
2 mjames 80
 
81
/**
82
* @brief  USBD_Init
83
*         Initializes the device stack and load the class driver
84
* @param  pdev: device instance
85
* @param  pdesc: Descriptor structure address
86
* @param  id: Low level core index
87
* @retval None
88
*/
9 mjames 89
USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev,
90
                             USBD_DescriptorsTypeDef *pdesc, uint8_t id)
2 mjames 91
{
92
  /* Check whether the USB Host handle is valid */
9 mjames 93
  if (pdev == NULL)
2 mjames 94
  {
9 mjames 95
#if (USBD_DEBUG_LEVEL > 1U)
2 mjames 96
    USBD_ErrLog("Invalid Device handle");
9 mjames 97
#endif
98
    return USBD_FAIL;
2 mjames 99
  }
9 mjames 100
 
2 mjames 101
  /* Unlink previous class*/
9 mjames 102
  if (pdev->pClass != NULL)
2 mjames 103
  {
104
    pdev->pClass = NULL;
105
  }
9 mjames 106
 
2 mjames 107
  /* Assign USBD Descriptors */
9 mjames 108
  if (pdesc != NULL)
2 mjames 109
  {
110
    pdev->pDesc = pdesc;
111
  }
9 mjames 112
 
2 mjames 113
  /* Set Device initial State */
9 mjames 114
  pdev->dev_state = USBD_STATE_DEFAULT;
2 mjames 115
  pdev->id = id;
116
  /* Initialize low level driver */
117
  USBD_LL_Init(pdev);
9 mjames 118
 
119
  return USBD_OK;
2 mjames 120
}
121
 
122
/**
9 mjames 123
* @brief  USBD_DeInit
2 mjames 124
*         Re-Initialize th device library
125
* @param  pdev: device instance
126
* @retval status: status
127
*/
128
USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev)
129
{
130
  /* Set Default State */
9 mjames 131
  pdev->dev_state = USBD_STATE_DEFAULT;
132
 
2 mjames 133
  /* Free Class Resources */
9 mjames 134
  pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
135
 
136
  /* Stop the low level driver  */
137
  USBD_LL_Stop(pdev);
138
 
2 mjames 139
  /* Initialize low level driver */
140
  USBD_LL_DeInit(pdev);
9 mjames 141
 
2 mjames 142
  return USBD_OK;
143
}
144
 
145
/**
9 mjames 146
  * @brief  USBD_RegisterClass
2 mjames 147
  *         Link class driver to Device Core.
148
  * @param  pDevice : Device Handle
149
  * @param  pclass: Class handle
150
  * @retval USBD Status
151
  */
152
USBD_StatusTypeDef  USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass)
153
{
9 mjames 154
  USBD_StatusTypeDef status = USBD_OK;
155
  if (pclass != NULL)
2 mjames 156
  {
157
    /* link the class to the USB Device handle */
158
    pdev->pClass = pclass;
159
    status = USBD_OK;
160
  }
161
  else
162
  {
9 mjames 163
#if (USBD_DEBUG_LEVEL > 1U)
2 mjames 164
    USBD_ErrLog("Invalid Class handle");
9 mjames 165
#endif
166
    status = USBD_FAIL;
2 mjames 167
  }
9 mjames 168
 
2 mjames 169
  return status;
170
}
171
 
172
/**
9 mjames 173
  * @brief  USBD_Start
2 mjames 174
  *         Start the USB Device Core.
175
  * @param  pdev: Device Handle
176
  * @retval USBD Status
177
  */
9 mjames 178
USBD_StatusTypeDef  USBD_Start(USBD_HandleTypeDef *pdev)
2 mjames 179
{
180
  /* Start the low level driver  */
9 mjames 181
  USBD_LL_Start(pdev);
182
 
183
  return USBD_OK;
2 mjames 184
}
185
 
186
/**
9 mjames 187
  * @brief  USBD_Stop
2 mjames 188
  *         Stop the USB Device Core.
189
  * @param  pdev: Device Handle
190
  * @retval USBD Status
191
  */
9 mjames 192
USBD_StatusTypeDef  USBD_Stop(USBD_HandleTypeDef *pdev)
2 mjames 193
{
194
  /* Free Class Resources */
9 mjames 195
  pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
2 mjames 196
 
9 mjames 197
  /* Stop the low level driver */
198
  USBD_LL_Stop(pdev);
199
 
200
  return USBD_OK;
2 mjames 201
}
202
 
203
/**
9 mjames 204
* @brief  USBD_RunTestMode
2 mjames 205
*         Launch test mode process
206
* @param  pdev: device instance
207
* @retval status
208
*/
9 mjames 209
USBD_StatusTypeDef  USBD_RunTestMode(USBD_HandleTypeDef  *pdev)
2 mjames 210
{
9 mjames 211
  /* Prevent unused argument compilation warning */
212
  UNUSED(pdev);
213
 
2 mjames 214
  return USBD_OK;
215
}
216
 
217
/**
9 mjames 218
* @brief  USBD_SetClassConfig
2 mjames 219
*        Configure device and start the interface
220
* @param  pdev: device instance
221
* @param  cfgidx: configuration index
222
* @retval status
223
*/
224
 
225
USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef  *pdev, uint8_t cfgidx)
226
{
9 mjames 227
  USBD_StatusTypeDef ret = USBD_FAIL;
228
 
229
  if (pdev->pClass != NULL)
2 mjames 230
  {
231
    /* Set configuration  and Start the Class*/
9 mjames 232
    if (pdev->pClass->Init(pdev, cfgidx) == 0U)
2 mjames 233
    {
234
      ret = USBD_OK;
235
    }
236
  }
9 mjames 237
 
238
  return ret;
2 mjames 239
}
240
 
241
/**
9 mjames 242
* @brief  USBD_ClrClassConfig
2 mjames 243
*         Clear current configuration
244
* @param  pdev: device instance
245
* @param  cfgidx: configuration index
246
* @retval status: USBD_StatusTypeDef
247
*/
248
USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef  *pdev, uint8_t cfgidx)
249
{
250
  /* Clear configuration  and De-initialize the Class process*/
9 mjames 251
  pdev->pClass->DeInit(pdev, cfgidx);
252
 
2 mjames 253
  return USBD_OK;
254
}
255
 
256
 
257
/**
9 mjames 258
* @brief  USBD_SetupStage
2 mjames 259
*         Handle the setup stage
260
* @param  pdev: device instance
261
* @retval status
262
*/
263
USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup)
264
{
9 mjames 265
  USBD_ParseSetupRequest(&pdev->request, psetup);
2 mjames 266
 
267
  pdev->ep0_state = USBD_EP0_SETUP;
9 mjames 268
 
2 mjames 269
  pdev->ep0_data_len = pdev->request.wLength;
9 mjames 270
 
271
  switch (pdev->request.bmRequest & 0x1FU)
2 mjames 272
  {
9 mjames 273
    case USB_REQ_RECIPIENT_DEVICE:
274
      USBD_StdDevReq(pdev, &pdev->request);
275
      break;
276
 
277
    case USB_REQ_RECIPIENT_INTERFACE:
278
      USBD_StdItfReq(pdev, &pdev->request);
279
      break;
280
 
281
    case USB_REQ_RECIPIENT_ENDPOINT:
282
      USBD_StdEPReq(pdev, &pdev->request);
283
      break;
284
 
285
    default:
286
      USBD_LL_StallEP(pdev, (pdev->request.bmRequest & 0x80U));
287
      break;
288
  }
289
 
290
  return USBD_OK;
2 mjames 291
}
292
 
293
/**
9 mjames 294
* @brief  USBD_DataOutStage
2 mjames 295
*         Handle data OUT stage
296
* @param  pdev: device instance
297
* @param  epnum: endpoint index
298
* @retval status
299
*/
9 mjames 300
USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev,
301
                                        uint8_t epnum, uint8_t *pdata)
2 mjames 302
{
9 mjames 303
  USBD_EndpointTypeDef *pep;
304
 
305
  if (epnum == 0U)
2 mjames 306
  {
307
    pep = &pdev->ep_out[0];
9 mjames 308
 
309
    if (pdev->ep0_state == USBD_EP0_DATA_OUT)
2 mjames 310
    {
9 mjames 311
      if (pep->rem_length > pep->maxpacket)
2 mjames 312
      {
9 mjames 313
        pep->rem_length -= pep->maxpacket;
314
 
315
        USBD_CtlContinueRx(pdev, pdata,
316
                           (uint16_t)MIN(pep->rem_length, pep->maxpacket));
2 mjames 317
      }
318
      else
319
      {
9 mjames 320
        if ((pdev->pClass->EP0_RxReady != NULL) &&
321
            (pdev->dev_state == USBD_STATE_CONFIGURED))
2 mjames 322
        {
9 mjames 323
          pdev->pClass->EP0_RxReady(pdev);
2 mjames 324
        }
325
        USBD_CtlSendStatus(pdev);
326
      }
327
    }
9 mjames 328
    else
329
    {
330
      if (pdev->ep0_state == USBD_EP0_STATUS_OUT)
331
      {
332
        /*
333
         * STATUS PHASE completed, update ep0_state to idle
334
         */
335
        pdev->ep0_state = USBD_EP0_IDLE;
336
        USBD_LL_StallEP(pdev, 0U);
337
      }
338
    }
2 mjames 339
  }
9 mjames 340
  else if ((pdev->pClass->DataOut != NULL) &&
341
           (pdev->dev_state == USBD_STATE_CONFIGURED))
2 mjames 342
  {
9 mjames 343
    pdev->pClass->DataOut(pdev, epnum);
344
  }
345
  else
346
  {
347
    /* should never be in this condition */
348
    return USBD_FAIL;
349
  }
350
 
2 mjames 351
  return USBD_OK;
352
}
353
 
354
/**
9 mjames 355
* @brief  USBD_DataInStage
2 mjames 356
*         Handle data in stage
357
* @param  pdev: device instance
358
* @param  epnum: endpoint index
359
* @retval status
360
*/
9 mjames 361
USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev,
362
                                       uint8_t epnum, uint8_t *pdata)
2 mjames 363
{
9 mjames 364
  USBD_EndpointTypeDef *pep;
365
 
366
  if (epnum == 0U)
2 mjames 367
  {
368
    pep = &pdev->ep_in[0];
9 mjames 369
 
370
    if (pdev->ep0_state == USBD_EP0_DATA_IN)
2 mjames 371
    {
9 mjames 372
      if (pep->rem_length > pep->maxpacket)
2 mjames 373
      {
9 mjames 374
        pep->rem_length -= pep->maxpacket;
375
 
376
        USBD_CtlContinueSendData(pdev, pdata, (uint16_t)pep->rem_length);
377
 
2 mjames 378
        /* Prepare endpoint for premature end of transfer */
9 mjames 379
        USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U);
2 mjames 380
      }
381
      else
9 mjames 382
      {
383
        /* last packet is MPS multiple, so send ZLP packet */
384
        if ((pep->total_length % pep->maxpacket == 0U) &&
385
            (pep->total_length >= pep->maxpacket) &&
386
            (pep->total_length < pdev->ep0_data_len))
2 mjames 387
        {
9 mjames 388
          USBD_CtlContinueSendData(pdev, NULL, 0U);
389
          pdev->ep0_data_len = 0U;
390
 
391
          /* Prepare endpoint for premature end of transfer */
392
          USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U);
2 mjames 393
        }
394
        else
395
        {
9 mjames 396
          if ((pdev->pClass->EP0_TxSent != NULL) &&
397
              (pdev->dev_state == USBD_STATE_CONFIGURED))
2 mjames 398
          {
9 mjames 399
            pdev->pClass->EP0_TxSent(pdev);
400
          }
401
          USBD_LL_StallEP(pdev, 0x80U);
2 mjames 402
          USBD_CtlReceiveStatus(pdev);
403
        }
404
      }
405
    }
9 mjames 406
    else
2 mjames 407
    {
9 mjames 408
      if ((pdev->ep0_state == USBD_EP0_STATUS_IN) ||
409
          (pdev->ep0_state == USBD_EP0_IDLE))
410
      {
411
        USBD_LL_StallEP(pdev, 0x80U);
412
      }
2 mjames 413
    }
9 mjames 414
 
415
    if (pdev->dev_test_mode == 1U)
416
    {
417
      USBD_RunTestMode(pdev);
418
      pdev->dev_test_mode = 0U;
419
    }
2 mjames 420
  }
9 mjames 421
  else if ((pdev->pClass->DataIn != NULL) &&
422
           (pdev->dev_state == USBD_STATE_CONFIGURED))
2 mjames 423
  {
9 mjames 424
    pdev->pClass->DataIn(pdev, epnum);
425
  }
426
  else
427
  {
428
    /* should never be in this condition */
429
    return USBD_FAIL;
430
  }
431
 
2 mjames 432
  return USBD_OK;
433
}
434
 
435
/**
9 mjames 436
* @brief  USBD_LL_Reset
2 mjames 437
*         Handle Reset event
438
* @param  pdev: device instance
439
* @retval status
440
*/
441
 
9 mjames 442
USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev)
2 mjames 443
{
444
  /* Open EP0 OUT */
9 mjames 445
  USBD_LL_OpenEP(pdev, 0x00U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE);
446
  pdev->ep_out[0x00U & 0xFU].is_used = 1U;
447
 
2 mjames 448
  pdev->ep_out[0].maxpacket = USB_MAX_EP0_SIZE;
9 mjames 449
 
2 mjames 450
  /* Open EP0 IN */
9 mjames 451
  USBD_LL_OpenEP(pdev, 0x80U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE);
452
  pdev->ep_in[0x80U & 0xFU].is_used = 1U;
453
 
2 mjames 454
  pdev->ep_in[0].maxpacket = USB_MAX_EP0_SIZE;
9 mjames 455
 
2 mjames 456
  /* Upon Reset call user call back */
457
  pdev->dev_state = USBD_STATE_DEFAULT;
9 mjames 458
  pdev->ep0_state = USBD_EP0_IDLE;
459
  pdev->dev_config = 0U;
460
  pdev->dev_remote_wakeup = 0U;
461
 
462
  if (pdev->pClassData)
463
  {
464
    pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
465
  }
466
 
2 mjames 467
  return USBD_OK;
468
}
469
 
470
/**
9 mjames 471
* @brief  USBD_LL_Reset
2 mjames 472
*         Handle Reset event
473
* @param  pdev: device instance
474
* @retval status
475
*/
9 mjames 476
USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev,
477
                                    USBD_SpeedTypeDef speed)
2 mjames 478
{
479
  pdev->dev_speed = speed;
9 mjames 480
 
2 mjames 481
  return USBD_OK;
482
}
483
 
484
/**
9 mjames 485
* @brief  USBD_Suspend
2 mjames 486
*         Handle Suspend event
487
* @param  pdev: device instance
488
* @retval status
489
*/
490
 
9 mjames 491
USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev)
2 mjames 492
{
493
  pdev->dev_old_state =  pdev->dev_state;
494
  pdev->dev_state  = USBD_STATE_SUSPENDED;
9 mjames 495
 
2 mjames 496
  return USBD_OK;
497
}
498
 
499
/**
9 mjames 500
* @brief  USBD_Resume
2 mjames 501
*         Handle Resume event
502
* @param  pdev: device instance
503
* @retval status
504
*/
505
 
9 mjames 506
USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev)
2 mjames 507
{
9 mjames 508
  if (pdev->dev_state == USBD_STATE_SUSPENDED)
509
  {
510
    pdev->dev_state = pdev->dev_old_state;
511
  }
512
 
2 mjames 513
  return USBD_OK;
514
}
515
 
516
/**
9 mjames 517
* @brief  USBD_SOF
2 mjames 518
*         Handle SOF event
519
* @param  pdev: device instance
520
* @retval status
521
*/
522
 
9 mjames 523
USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev)
2 mjames 524
{
9 mjames 525
  if (pdev->dev_state == USBD_STATE_CONFIGURED)
2 mjames 526
  {
9 mjames 527
    if (pdev->pClass->SOF != NULL)
2 mjames 528
    {
529
      pdev->pClass->SOF(pdev);
530
    }
531
  }
9 mjames 532
 
2 mjames 533
  return USBD_OK;
534
}
535
 
536
/**
9 mjames 537
* @brief  USBD_IsoINIncomplete
2 mjames 538
*         Handle iso in incomplete event
539
* @param  pdev: device instance
540
* @retval status
541
*/
9 mjames 542
USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev,
543
                                           uint8_t epnum)
2 mjames 544
{
9 mjames 545
  /* Prevent unused arguments compilation warning */
546
  UNUSED(pdev);
547
  UNUSED(epnum);
548
 
2 mjames 549
  return USBD_OK;
550
}
551
 
552
/**
9 mjames 553
* @brief  USBD_IsoOUTIncomplete
2 mjames 554
*         Handle iso out incomplete event
555
* @param  pdev: device instance
556
* @retval status
557
*/
9 mjames 558
USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev,
559
                                            uint8_t epnum)
2 mjames 560
{
9 mjames 561
  /* Prevent unused arguments compilation warning */
562
  UNUSED(pdev);
563
  UNUSED(epnum);
564
 
2 mjames 565
  return USBD_OK;
566
}
567
 
568
/**
9 mjames 569
* @brief  USBD_DevConnected
2 mjames 570
*         Handle device connection event
571
* @param  pdev: device instance
572
* @retval status
573
*/
9 mjames 574
USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev)
2 mjames 575
{
9 mjames 576
  /* Prevent unused argument compilation warning */
577
  UNUSED(pdev);
578
 
2 mjames 579
  return USBD_OK;
580
}
581
 
582
/**
9 mjames 583
* @brief  USBD_DevDisconnected
2 mjames 584
*         Handle device disconnection event
585
* @param  pdev: device instance
586
* @retval status
587
*/
9 mjames 588
USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev)
2 mjames 589
{
590
  /* Free Class Resources */
591
  pdev->dev_state = USBD_STATE_DEFAULT;
9 mjames 592
  pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
593
 
2 mjames 594
  return USBD_OK;
595
}
596
/**
597
* @}
9 mjames 598
*/
2 mjames 599
 
600
 
601
/**
602
* @}
9 mjames 603
*/
2 mjames 604
 
605
 
606
/**
607
* @}
9 mjames 608
*/
2 mjames 609
 
610
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
611