Subversion Repositories dashGPS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
16 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
  * <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
10
  * All rights reserved.</center></h2>
11
  *
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
16
  *
17
  ******************************************************************************
18
  */
19
 
20
/* Includes ------------------------------------------------------------------*/
21
#include "usbd_core.h"
22
 
23
/** @addtogroup STM32_USBD_DEVICE_LIBRARY
24
* @{
25
*/
26
 
27
 
28
/** @defgroup USBD_CORE
29
* @brief usbd core module
30
* @{
31
*/
32
 
33
/** @defgroup USBD_CORE_Private_TypesDefinitions
34
* @{
35
*/
36
 
37
/**
38
* @}
39
*/
40
 
41
 
42
/** @defgroup USBD_CORE_Private_Defines
43
* @{
44
*/
45
 
46
/**
47
* @}
48
*/
49
 
50
 
51
/** @defgroup USBD_CORE_Private_Macros
52
* @{
53
*/
54
 
55
/**
56
* @}
57
*/
58
 
59
 
60
/** @defgroup USBD_CORE_Private_FunctionPrototypes
61
* @{
62
*/
63
 
64
/**
65
* @}
66
*/
67
 
68
/** @defgroup USBD_CORE_Private_Variables
69
* @{
70
*/
71
 
72
/**
73
* @}
74
*/
75
 
76
 
77
/** @defgroup USBD_CORE_Private_Functions
78
* @{
79
*/
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
*/
89
USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev,
90
                             USBD_DescriptorsTypeDef *pdesc, uint8_t id)
91
{
92
  /* Check whether the USB Host handle is valid */
93
  if (pdev == NULL)
94
  {
95
#if (USBD_DEBUG_LEVEL > 1U)
96
    USBD_ErrLog("Invalid Device handle");
97
#endif
98
    return USBD_FAIL;
99
  }
100
 
101
  /* Unlink previous class*/
102
  if (pdev->pClass != NULL)
103
  {
104
    pdev->pClass = NULL;
105
  }
106
 
107
  /* Assign USBD Descriptors */
108
  if (pdesc != NULL)
109
  {
110
    pdev->pDesc = pdesc;
111
  }
112
 
113
  /* Set Device initial State */
114
  pdev->dev_state = USBD_STATE_DEFAULT;
115
  pdev->id = id;
116
  /* Initialize low level driver */
117
  USBD_LL_Init(pdev);
118
 
119
  return USBD_OK;
120
}
121
 
122
/**
123
* @brief  USBD_DeInit
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 */
131
  pdev->dev_state = USBD_STATE_DEFAULT;
132
 
133
  /* Free Class Resources */
134
  pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
135
 
136
  /* Stop the low level driver  */
137
  USBD_LL_Stop(pdev);
138
 
139
  /* Initialize low level driver */
140
  USBD_LL_DeInit(pdev);
141
 
142
  return USBD_OK;
143
}
144
 
145
/**
146
  * @brief  USBD_RegisterClass
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
{
154
  USBD_StatusTypeDef status = USBD_OK;
155
  if (pclass != NULL)
156
  {
157
    /* link the class to the USB Device handle */
158
    pdev->pClass = pclass;
159
    status = USBD_OK;
160
  }
161
  else
162
  {
163
#if (USBD_DEBUG_LEVEL > 1U)
164
    USBD_ErrLog("Invalid Class handle");
165
#endif
166
    status = USBD_FAIL;
167
  }
168
 
169
  return status;
170
}
171
 
172
/**
173
  * @brief  USBD_Start
174
  *         Start the USB Device Core.
175
  * @param  pdev: Device Handle
176
  * @retval USBD Status
177
  */
178
USBD_StatusTypeDef  USBD_Start(USBD_HandleTypeDef *pdev)
179
{
180
  /* Start the low level driver  */
181
  USBD_LL_Start(pdev);
182
 
183
  return USBD_OK;
184
}
185
 
186
/**
187
  * @brief  USBD_Stop
188
  *         Stop the USB Device Core.
189
  * @param  pdev: Device Handle
190
  * @retval USBD Status
191
  */
192
USBD_StatusTypeDef  USBD_Stop(USBD_HandleTypeDef *pdev)
193
{
194
  /* Free Class Resources */
195
  pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
196
 
197
  /* Stop the low level driver */
198
  USBD_LL_Stop(pdev);
199
 
200
  return USBD_OK;
201
}
202
 
203
/**
204
* @brief  USBD_RunTestMode
205
*         Launch test mode process
206
* @param  pdev: device instance
207
* @retval status
208
*/
209
USBD_StatusTypeDef  USBD_RunTestMode(USBD_HandleTypeDef  *pdev)
210
{
211
  /* Prevent unused argument compilation warning */
212
  UNUSED(pdev);
213
 
214
  return USBD_OK;
215
}
216
 
217
/**
218
* @brief  USBD_SetClassConfig
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
{
227
  USBD_StatusTypeDef ret = USBD_FAIL;
228
 
229
  if (pdev->pClass != NULL)
230
  {
231
    /* Set configuration  and Start the Class*/
232
    if (pdev->pClass->Init(pdev, cfgidx) == 0U)
233
    {
234
      ret = USBD_OK;
235
    }
236
  }
237
 
238
  return ret;
239
}
240
 
241
/**
242
* @brief  USBD_ClrClassConfig
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*/
251
  pdev->pClass->DeInit(pdev, cfgidx);
252
 
253
  return USBD_OK;
254
}
255
 
256
 
257
/**
258
* @brief  USBD_SetupStage
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
{
265
  USBD_ParseSetupRequest(&pdev->request, psetup);
266
 
267
  pdev->ep0_state = USBD_EP0_SETUP;
268
 
269
  pdev->ep0_data_len = pdev->request.wLength;
270
 
271
  switch (pdev->request.bmRequest & 0x1FU)
272
  {
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;
291
}
292
 
293
/**
294
* @brief  USBD_DataOutStage
295
*         Handle data OUT stage
296
* @param  pdev: device instance
297
* @param  epnum: endpoint index
298
* @retval status
299
*/
300
USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev,
301
                                        uint8_t epnum, uint8_t *pdata)
302
{
303
  USBD_EndpointTypeDef *pep;
304
 
305
  if (epnum == 0U)
306
  {
307
    pep = &pdev->ep_out[0];
308
 
309
    if (pdev->ep0_state == USBD_EP0_DATA_OUT)
310
    {
311
      if (pep->rem_length > pep->maxpacket)
312
      {
313
        pep->rem_length -= pep->maxpacket;
314
 
315
        USBD_CtlContinueRx(pdev, pdata,
316
                           (uint16_t)MIN(pep->rem_length, pep->maxpacket));
317
      }
318
      else
319
      {
320
        if ((pdev->pClass->EP0_RxReady != NULL) &&
321
            (pdev->dev_state == USBD_STATE_CONFIGURED))
322
        {
323
          pdev->pClass->EP0_RxReady(pdev);
324
        }
325
        USBD_CtlSendStatus(pdev);
326
      }
327
    }
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
    }
339
  }
340
  else if ((pdev->pClass->DataOut != NULL) &&
341
           (pdev->dev_state == USBD_STATE_CONFIGURED))
342
  {
343
    pdev->pClass->DataOut(pdev, epnum);
344
  }
345
  else
346
  {
347
    /* should never be in this condition */
348
    return USBD_FAIL;
349
  }
350
 
351
  return USBD_OK;
352
}
353
 
354
/**
355
* @brief  USBD_DataInStage
356
*         Handle data in stage
357
* @param  pdev: device instance
358
* @param  epnum: endpoint index
359
* @retval status
360
*/
361
USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev,
362
                                       uint8_t epnum, uint8_t *pdata)
363
{
364
  USBD_EndpointTypeDef *pep;
365
 
366
  if (epnum == 0U)
367
  {
368
    pep = &pdev->ep_in[0];
369
 
370
    if (pdev->ep0_state == USBD_EP0_DATA_IN)
371
    {
372
      if (pep->rem_length > pep->maxpacket)
373
      {
374
        pep->rem_length -= pep->maxpacket;
375
 
376
        USBD_CtlContinueSendData(pdev, pdata, (uint16_t)pep->rem_length);
377
 
378
        /* Prepare endpoint for premature end of transfer */
379
        USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U);
380
      }
381
      else
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))
387
        {
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);
393
        }
394
        else
395
        {
396
          if ((pdev->pClass->EP0_TxSent != NULL) &&
397
              (pdev->dev_state == USBD_STATE_CONFIGURED))
398
          {
399
            pdev->pClass->EP0_TxSent(pdev);
400
          }
401
          USBD_LL_StallEP(pdev, 0x80U);
402
          USBD_CtlReceiveStatus(pdev);
403
        }
404
      }
405
    }
406
    else
407
    {
408
      if ((pdev->ep0_state == USBD_EP0_STATUS_IN) ||
409
          (pdev->ep0_state == USBD_EP0_IDLE))
410
      {
411
        USBD_LL_StallEP(pdev, 0x80U);
412
      }
413
    }
414
 
415
    if (pdev->dev_test_mode == 1U)
416
    {
417
      USBD_RunTestMode(pdev);
418
      pdev->dev_test_mode = 0U;
419
    }
420
  }
421
  else if ((pdev->pClass->DataIn != NULL) &&
422
           (pdev->dev_state == USBD_STATE_CONFIGURED))
423
  {
424
    pdev->pClass->DataIn(pdev, epnum);
425
  }
426
  else
427
  {
428
    /* should never be in this condition */
429
    return USBD_FAIL;
430
  }
431
 
432
  return USBD_OK;
433
}
434
 
435
/**
436
* @brief  USBD_LL_Reset
437
*         Handle Reset event
438
* @param  pdev: device instance
439
* @retval status
440
*/
441
 
442
USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev)
443
{
444
  /* Open EP0 OUT */
445
  USBD_LL_OpenEP(pdev, 0x00U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE);
446
  pdev->ep_out[0x00U & 0xFU].is_used = 1U;
447
 
448
  pdev->ep_out[0].maxpacket = USB_MAX_EP0_SIZE;
449
 
450
  /* Open EP0 IN */
451
  USBD_LL_OpenEP(pdev, 0x80U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE);
452
  pdev->ep_in[0x80U & 0xFU].is_used = 1U;
453
 
454
  pdev->ep_in[0].maxpacket = USB_MAX_EP0_SIZE;
455
 
456
  /* Upon Reset call user call back */
457
  pdev->dev_state = USBD_STATE_DEFAULT;
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
 
467
  return USBD_OK;
468
}
469
 
470
/**
471
* @brief  USBD_LL_Reset
472
*         Handle Reset event
473
* @param  pdev: device instance
474
* @retval status
475
*/
476
USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev,
477
                                    USBD_SpeedTypeDef speed)
478
{
479
  pdev->dev_speed = speed;
480
 
481
  return USBD_OK;
482
}
483
 
484
/**
485
* @brief  USBD_Suspend
486
*         Handle Suspend event
487
* @param  pdev: device instance
488
* @retval status
489
*/
490
 
491
USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev)
492
{
493
  pdev->dev_old_state =  pdev->dev_state;
494
  pdev->dev_state  = USBD_STATE_SUSPENDED;
495
 
496
  return USBD_OK;
497
}
498
 
499
/**
500
* @brief  USBD_Resume
501
*         Handle Resume event
502
* @param  pdev: device instance
503
* @retval status
504
*/
505
 
506
USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev)
507
{
508
  if (pdev->dev_state == USBD_STATE_SUSPENDED)
509
  {
510
    pdev->dev_state = pdev->dev_old_state;
511
  }
512
 
513
  return USBD_OK;
514
}
515
 
516
/**
517
* @brief  USBD_SOF
518
*         Handle SOF event
519
* @param  pdev: device instance
520
* @retval status
521
*/
522
 
523
USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev)
524
{
525
  if (pdev->dev_state == USBD_STATE_CONFIGURED)
526
  {
527
    if (pdev->pClass->SOF != NULL)
528
    {
529
      pdev->pClass->SOF(pdev);
530
    }
531
  }
532
 
533
  return USBD_OK;
534
}
535
 
536
/**
537
* @brief  USBD_IsoINIncomplete
538
*         Handle iso in incomplete event
539
* @param  pdev: device instance
540
* @retval status
541
*/
542
USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev,
543
                                           uint8_t epnum)
544
{
545
  /* Prevent unused arguments compilation warning */
546
  UNUSED(pdev);
547
  UNUSED(epnum);
548
 
549
  return USBD_OK;
550
}
551
 
552
/**
553
* @brief  USBD_IsoOUTIncomplete
554
*         Handle iso out incomplete event
555
* @param  pdev: device instance
556
* @retval status
557
*/
558
USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev,
559
                                            uint8_t epnum)
560
{
561
  /* Prevent unused arguments compilation warning */
562
  UNUSED(pdev);
563
  UNUSED(epnum);
564
 
565
  return USBD_OK;
566
}
567
 
568
/**
569
* @brief  USBD_DevConnected
570
*         Handle device connection event
571
* @param  pdev: device instance
572
* @retval status
573
*/
574
USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev)
575
{
576
  /* Prevent unused argument compilation warning */
577
  UNUSED(pdev);
578
 
579
  return USBD_OK;
580
}
581
 
582
/**
583
* @brief  USBD_DevDisconnected
584
*         Handle device disconnection event
585
* @param  pdev: device instance
586
* @retval status
587
*/
588
USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev)
589
{
590
  /* Free Class Resources */
591
  pdev->dev_state = USBD_STATE_DEFAULT;
592
  pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
593
 
594
  return USBD_OK;
595
}
596
/**
597
* @}
598
*/
599
 
600
 
601
/**
602
* @}
603
*/
604
 
605
 
606
/**
607
* @}
608
*/
609
 
610
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
611