1 /**
2 ******************************************************************************
3 * @file usbd_core.c
4 * @author MCD Application Team
5 * @version V2.4.2
6 * @date 11-December-2015
7 * @brief This file provides all the USBD core functions.
8 ******************************************************************************
9 * @attention
10 *
11 * <h2><center>© 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 */
USBD_Init(USBD_HandleTypeDef * pdev,USBD_DescriptorsTypeDef * pdesc,uint8_t id)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 */
USBD_DeInit(USBD_HandleTypeDef * pdev)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 */
USBD_RegisterClass(USBD_HandleTypeDef * pdev,USBD_ClassTypeDef * pclass)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 */
USBD_Start(USBD_HandleTypeDef * pdev)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 */
USBD_Stop(USBD_HandleTypeDef * pdev)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 */
USBD_RunTestMode(USBD_HandleTypeDef * pdev)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
USBD_SetClassConfig(USBD_HandleTypeDef * pdev,uint8_t cfgidx)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 */
USBD_ClrClassConfig(USBD_HandleTypeDef * pdev,uint8_t cfgidx)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 */
USBD_LL_SetupStage(USBD_HandleTypeDef * pdev,uint8_t * psetup)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 */
USBD_LL_DataOutStage(USBD_HandleTypeDef * pdev,uint8_t epnum,uint8_t * pdata)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 */
USBD_LL_DataInStage(USBD_HandleTypeDef * pdev,uint8_t epnum,uint8_t * pdata)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
USBD_LL_Reset(USBD_HandleTypeDef * pdev)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 */
USBD_LL_SetSpeed(USBD_HandleTypeDef * pdev,USBD_SpeedTypeDef speed)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
USBD_LL_Suspend(USBD_HandleTypeDef * pdev)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
USBD_LL_Resume(USBD_HandleTypeDef * pdev)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
USBD_LL_SOF(USBD_HandleTypeDef * pdev)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 */
USBD_LL_IsoINIncomplete(USBD_HandleTypeDef * pdev,uint8_t epnum)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 */
USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef * pdev,uint8_t epnum)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 */
USBD_LL_DevConnected(USBD_HandleTypeDef * pdev)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 */
USBD_LL_DevDisconnected(USBD_HandleTypeDef * pdev)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
566