Subversion Repositories DashDisplay

Rev

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