1 /**
2 ******************************************************************************
3 * @file usbh_core.c
4 * @author MCD Application Team
5 * @version V3.0.0
6 * @date 18-February-2014
7 * @brief This file implements the functions for the core state machine process
8 * the enumeration and the control transfer process
9 ******************************************************************************
10 * @attention
11 *
12 * <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2>
13 *
14 * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
15 * You may not use this file except in compliance with the License.
16 * You may obtain a copy of the License at:
17 *
18 * http://www.st.com/software_license_agreement_liberty_v2
19 *
20 * Unless required by applicable law or agreed to in writing, software
21 * distributed under the License is distributed on an "AS IS" BASIS,
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 * See the License for the specific language governing permissions and
24 * limitations under the License.
25 *
26 ******************************************************************************
27 */
28 /* Includes ------------------------------------------------------------------*/
29
30 #include "usbh_core.h"
31
32
33 /** @addtogroup USBH_LIB
34 * @{
35 */
36
37 /** @addtogroup USBH_LIB_CORE
38 * @{
39 */
40
41 /** @defgroup USBH_CORE
42 * @brief TThis file handles the basic enumaration when a device is connected
43 * to the host.
44 * @{
45 */
46
47
48 /** @defgroup USBH_CORE_Private_Defines
49 * @{
50 */
51 #define USBH_ADDRESS_DEFAULT 0
52 #define USBH_ADDRESS_ASSIGNED 1
53 #define USBH_MPS_DEFAULT 0x40
54 /**
55 * @}
56 */
57
58 /** @defgroup USBH_CORE_Private_Macros
59 * @{
60 */
61 /**
62 * @}
63 */
64
65
66 /** @defgroup USBH_CORE_Private_Variables
67 * @{
68 */
69 /**
70 * @}
71 */
72
73
74 /** @defgroup USBH_CORE_Private_Functions
75 * @{
76 */
77 static USBH_StatusTypeDef USBH_HandleEnum (USBH_HandleTypeDef *phost);
78 static void USBH_HandleSof (USBH_HandleTypeDef *phost);
79 static USBH_StatusTypeDef DeInitStateMachine(USBH_HandleTypeDef *phost);
80
81 #if (USBH_USE_OS == 1)
82 static void USBH_Process_OS(void const * argument);
83 #endif
84
85 /**
86 * @brief HCD_Init
87 * Initialize the HOST Core.
88 * @param phost: Host Handle
89 * @param pUsrFunc: User Callback
90 * @retval USBH Status
91 */
USBH_Init(USBH_HandleTypeDef * phost,void (* pUsrFunc)(USBH_HandleTypeDef * phost,uint8_t),uint8_t id)92 USBH_StatusTypeDef USBH_Init(USBH_HandleTypeDef *phost, void (*pUsrFunc)(USBH_HandleTypeDef *phost, uint8_t ), uint8_t id)
93 {
94 /* Check whether the USB Host handle is valid */
95 if(phost == NULL)
96 {
97 USBH_ErrLog("Invalid Host handle");
98 return USBH_FAIL;
99 }
100
101 /* Set DRiver ID */
102 phost->id = id;
103
104 /* Unlink class*/
105 phost->pActiveClass = NULL;
106 phost->ClassNumber = 0;
107
108 /* Restore default states and prepare EP0 */
109 DeInitStateMachine(phost);
110
111 /* Assign User process */
112 if(pUsrFunc != NULL)
113 {
114 phost->pUser = pUsrFunc;
115 }
116
117 #if (USBH_USE_OS == 1)
118
119 /* Create USB Host Queue */
120 osMessageQDef(USBH_Queue, 10, uint16_t);
121 phost->os_event = osMessageCreate (osMessageQ(USBH_Queue), NULL);
122
123 /*Create USB Host Task */
124 osThreadDef(USBH_Thread, USBH_Process_OS, USBH_PROCESS_PRIO, 0, 8 * configMINIMAL_STACK_SIZE);
125 phost->thread = osThreadCreate (osThread(USBH_Thread), phost);
126 #endif
127
128 /* Initialize low level driver */
129 USBH_LL_Init(phost);
130 return USBH_OK;
131 }
132
133 /**
134 * @brief HCD_Init
135 * De-Initialize the Host portion of the driver.
136 * @param phost: Host Handle
137 * @retval USBH Status
138 */
USBH_DeInit(USBH_HandleTypeDef * phost)139 USBH_StatusTypeDef USBH_DeInit(USBH_HandleTypeDef *phost)
140 {
141 DeInitStateMachine(phost);
142
143 if(phost->pData != NULL)
144 {
145 phost->pActiveClass->pData = NULL;
146 USBH_LL_Stop(phost);
147 }
148
149 return USBH_OK;
150 }
151
152 /**
153 * @brief DeInitStateMachine
154 * De-Initialize the Host state machine.
155 * @param phost: Host Handle
156 * @retval USBH Status
157 */
DeInitStateMachine(USBH_HandleTypeDef * phost)158 static USBH_StatusTypeDef DeInitStateMachine(USBH_HandleTypeDef *phost)
159 {
160 uint32_t i = 0;
161
162 /* Clear Pipes flags*/
163 for ( ; i < USBH_MAX_PIPES_NBR; i++)
164 {
165 phost->Pipes[i] = 0;
166 }
167
168 for(i = 0; i< USBH_MAX_DATA_BUFFER; i++)
169 {
170 phost->device.Data[i] = 0;
171 }
172
173 phost->gState = HOST_IDLE;
174 phost->EnumState = ENUM_IDLE;
175 phost->RequestState = CMD_SEND;
176 phost->Timer = 0;
177
178 phost->Control.state = CTRL_SETUP;
179 phost->Control.pipe_size = USBH_MPS_DEFAULT;
180 phost->Control.errorcount = 0;
181
182 phost->device.address = USBH_ADDRESS_DEFAULT;
183 phost->device.speed = USBH_SPEED_FULL;
184
185 return USBH_OK;
186 }
187
188 /**
189 * @brief USBH_RegisterClass
190 * Link class driver to Host Core.
191 * @param phost : Host Handle
192 * @param pclass: Class handle
193 * @retval USBH Status
194 */
USBH_RegisterClass(USBH_HandleTypeDef * phost,USBH_ClassTypeDef * pclass)195 USBH_StatusTypeDef USBH_RegisterClass(USBH_HandleTypeDef *phost, USBH_ClassTypeDef *pclass)
196 {
197 USBH_StatusTypeDef status = USBH_OK;
198
199 if(pclass != 0)
200 {
201 if(phost->ClassNumber < USBH_MAX_NUM_SUPPORTED_CLASS)
202 {
203 /* link the class tgo the USB Host handle */
204 phost->pClass[phost->ClassNumber++] = pclass;
205 status = USBH_OK;
206 }
207 else
208 {
209 USBH_ErrLog("Max Class Number reached");
210 status = USBH_FAIL;
211 }
212 }
213 else
214 {
215 USBH_ErrLog("Invalid Class handle");
216 status = USBH_FAIL;
217 }
218
219 return status;
220 }
221
222 /**
223 * @brief USBH_SelectInterface
224 * Select current interface.
225 * @param phost: Host Handle
226 * @param interface: Interface number
227 * @retval USBH Status
228 */
USBH_SelectInterface(USBH_HandleTypeDef * phost,uint8_t interface)229 USBH_StatusTypeDef USBH_SelectInterface(USBH_HandleTypeDef *phost, uint8_t interface)
230 {
231 USBH_StatusTypeDef status = USBH_OK;
232
233 if(interface < phost->device.CfgDesc.bNumInterfaces)
234 {
235 phost->device.current_interface = interface;
236 USBH_UsrLog ("Switching to Interface (#%d)", interface);
237 USBH_UsrLog ("Class : %xh", phost->device.CfgDesc.Itf_Desc[interface].bInterfaceClass );
238 USBH_UsrLog ("SubClass : %xh", phost->device.CfgDesc.Itf_Desc[interface].bInterfaceSubClass );
239 USBH_UsrLog ("Protocol : %xh", phost->device.CfgDesc.Itf_Desc[interface].bInterfaceProtocol );
240 }
241 else
242 {
243 USBH_ErrLog ("Cannot Select This Interface.");
244 status = USBH_FAIL;
245 }
246 return status;
247 }
248
249 /**
250 * @brief USBH_GetActiveClass
251 * Return Device Class.
252 * @param phost: Host Handle
253 * @param interface: Interface index
254 * @retval Class Code
255 */
USBH_GetActiveClass(USBH_HandleTypeDef * phost)256 uint8_t USBH_GetActiveClass(USBH_HandleTypeDef *phost)
257 {
258 return (phost->device.CfgDesc.Itf_Desc[0].bInterfaceClass);
259 }
260 /**
261 * @brief USBH_FindInterface
262 * Find the interface index for a specific class.
263 * @param phost: Host Handle
264 * @param Class: Class code
265 * @param SubClass: SubClass code
266 * @param Protocol: Protocol code
267 * @retval interface index in the configuration structure
268 * @note : (1)interface index 0xFF means interface index not found
269 */
USBH_FindInterface(USBH_HandleTypeDef * phost,uint8_t Class,uint8_t SubClass,uint8_t Protocol)270 uint8_t USBH_FindInterface(USBH_HandleTypeDef *phost, uint8_t Class, uint8_t SubClass, uint8_t Protocol)
271 {
272 USBH_InterfaceDescTypeDef *pif ;
273 USBH_CfgDescTypeDef *pcfg ;
274 int8_t if_ix = 0;
275
276 pif = (USBH_InterfaceDescTypeDef *)0;
277 pcfg = &phost->device.CfgDesc;
278
279 if((pif->bInterfaceClass == 0xFF) &&(pif->bInterfaceSubClass == 0xFF) && (pif->bInterfaceProtocol == 0xFF))
280 {
281 return 0xFF;
282 }
283
284 while (if_ix < USBH_MAX_NUM_INTERFACES)
285 {
286 pif = &pcfg->Itf_Desc[if_ix];
287 if(((pif->bInterfaceClass == Class) || (Class == 0xFF))&&
288 ((pif->bInterfaceSubClass == SubClass) || (SubClass == 0xFF))&&
289 ((pif->bInterfaceProtocol == Protocol) || (Protocol == 0xFF)))
290 {
291 return if_ix;
292 }
293 if_ix++;
294 }
295 return 0xFF;
296 }
297
298 /**
299 * @brief USBH_FindInterfaceIndex
300 * Find the interface index for a specific class interface and alternate setting number.
301 * @param phost: Host Handle
302 * @param interface_number: interface number
303 * @param alt_settings : alaternate setting number
304 * @retval interface index in the configuration structure
305 * @note : (1)interface index 0xFF means interface index not found
306 */
USBH_FindInterfaceIndex(USBH_HandleTypeDef * phost,uint8_t interface_number,uint8_t alt_settings)307 uint8_t USBH_FindInterfaceIndex(USBH_HandleTypeDef *phost, uint8_t interface_number, uint8_t alt_settings)
308 {
309 USBH_InterfaceDescTypeDef *pif ;
310 USBH_CfgDescTypeDef *pcfg ;
311 int8_t if_ix = 0;
312
313 pif = (USBH_InterfaceDescTypeDef *)0;
314 pcfg = &phost->device.CfgDesc;
315
316 while (if_ix < USBH_MAX_NUM_INTERFACES)
317 {
318 pif = &pcfg->Itf_Desc[if_ix];
319 if((pif->bInterfaceNumber == interface_number) && (pif->bAlternateSetting == alt_settings))
320 {
321 return if_ix;
322 }
323 if_ix++;
324 }
325 return 0xFF;
326 }
327
328 /**
329 * @brief USBH_Start
330 * Start the USB Host Core.
331 * @param phost: Host Handle
332 * @retval USBH Status
333 */
USBH_Start(USBH_HandleTypeDef * phost)334 USBH_StatusTypeDef USBH_Start (USBH_HandleTypeDef *phost)
335 {
336 /* Start the low level driver */
337 USBH_LL_Start(phost);
338
339 /* Activate VBUS on the port */
340 USBH_LL_DriverVBUS (phost, TRUE);
341
342 return USBH_OK;
343 }
344
345 /**
346 * @brief USBH_Stop
347 * Stop the USB Host Core.
348 * @param phost: Host Handle
349 * @retval USBH Status
350 */
USBH_Stop(USBH_HandleTypeDef * phost)351 USBH_StatusTypeDef USBH_Stop (USBH_HandleTypeDef *phost)
352 {
353 /* Stop and cleanup the low level driver */
354 USBH_LL_Stop(phost);
355
356 /* DeActivate VBUS on the port */
357 USBH_LL_DriverVBUS (phost, FALSE);
358
359 /* FRee Control Pipes */
360 USBH_FreePipe (phost, phost->Control.pipe_in);
361 USBH_FreePipe (phost, phost->Control.pipe_out);
362
363 return USBH_OK;
364 }
365
366 /**
367 * @brief HCD_ReEnumerate
368 * Perform a new Enumeration phase.
369 * @param phost: Host Handle
370 * @retval USBH Status
371 */
USBH_ReEnumerate(USBH_HandleTypeDef * phost)372 USBH_StatusTypeDef USBH_ReEnumerate (USBH_HandleTypeDef *phost)
373 {
374 /*Stop Host */
375 USBH_Stop(phost);
376
377 /*Device has disconnected, so wait for 200 ms */
378 USBH_Delay(200);
379
380 /* Set State machines in default state */
381 DeInitStateMachine(phost);
382
383 /* Start again the host */
384 USBH_Start(phost);
385
386 #if (USBH_USE_OS == 1)
387 osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0);
388 #endif
389 return USBH_OK;
390 }
391
392 /**
393 * @brief USBH_Process
394 * Background process of the USB Core.
395 * @param phost: Host Handle
396 * @retval USBH Status
397 */
USBH_Process(USBH_HandleTypeDef * phost)398 USBH_StatusTypeDef USBH_Process(USBH_HandleTypeDef *phost)
399 {
400 __IO USBH_StatusTypeDef status = USBH_FAIL;
401 uint8_t idx = 0;
402
403 switch (phost->gState)
404 {
405 case HOST_IDLE :
406
407 if (phost->device.is_connected)
408 {
409 /* Wait for 200 ms after connection */
410 phost->gState = HOST_DEV_WAIT_FOR_ATTACHMENT;
411 USBH_Delay(200);
412 USBH_LL_ResetPort(phost);
413 #if (USBH_USE_OS == 1)
414 osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0);
415 #endif
416 }
417 break;
418
419 case HOST_DEV_WAIT_FOR_ATTACHMENT:
420 break;
421
422 case HOST_DEV_ATTACHED :
423
424 USBH_UsrLog("USB Device Attached");
425
426 /* Wait for 100 ms after Reset */
427 USBH_Delay(100);
428
429 phost->device.speed = USBH_LL_GetSpeed(phost);
430
431 phost->gState = HOST_ENUMERATION;
432
433 phost->Control.pipe_out = USBH_AllocPipe (phost, 0x00);
434 phost->Control.pipe_in = USBH_AllocPipe (phost, 0x80);
435
436
437 /* Open Control pipes */
438 USBH_OpenPipe (phost,
439 phost->Control.pipe_in,
440 0x80,
441 phost->device.address,
442 phost->device.speed,
443 USBH_EP_CONTROL,
444 phost->Control.pipe_size);
445
446 /* Open Control pipes */
447 USBH_OpenPipe (phost,
448 phost->Control.pipe_out,
449 0x00,
450 phost->device.address,
451 phost->device.speed,
452 USBH_EP_CONTROL,
453 phost->Control.pipe_size);
454
455 #if (USBH_USE_OS == 1)
456 osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0);
457 #endif
458
459 break;
460
461 case HOST_ENUMERATION:
462 /* Check for enumeration status */
463 if ( USBH_HandleEnum(phost) == USBH_OK)
464 {
465 /* The function shall return USBH_OK when full enumeration is complete */
466 USBH_UsrLog ("Enumeration done.");
467 phost->device.current_interface = 0;
468 if(phost->device.DevDesc.bNumConfigurations == 1)
469 {
470 USBH_UsrLog ("This device has only 1 configuration.");
471 phost->gState = HOST_SET_CONFIGURATION;
472
473 }
474 else
475 {
476 phost->gState = HOST_INPUT;
477 }
478
479 }
480 break;
481
482 case HOST_INPUT:
483 {
484 /* user callback for end of device basic enumeration */
485 if(phost->pUser != NULL)
486 {
487 phost->pUser(phost, HOST_USER_SELECT_CONFIGURATION);
488 phost->gState = HOST_SET_CONFIGURATION;
489
490 #if (USBH_USE_OS == 1)
491 osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
492 #endif
493 }
494 }
495 break;
496
497 case HOST_SET_CONFIGURATION:
498 /* set configuration */
499 if (USBH_SetCfg(phost, phost->device.CfgDesc.bConfigurationValue) == USBH_OK)
500 {
501 phost->gState = HOST_CHECK_CLASS;
502 USBH_UsrLog ("Default configuration set.");
503
504 }
505
506 break;
507
508 case HOST_CHECK_CLASS:
509
510 if(phost->ClassNumber == 0)
511 {
512 USBH_UsrLog ("No Class has been registered.");
513 }
514 else
515 {
516 phost->pActiveClass = NULL;
517
518 for (idx = 0; idx < USBH_MAX_NUM_SUPPORTED_CLASS ; idx ++)
519 {
520 if(phost->pClass[idx]->ClassCode == phost->device.CfgDesc.Itf_Desc[0].bInterfaceClass)
521 {
522 phost->pActiveClass = phost->pClass[idx];
523 }
524 }
525
526 if(phost->pActiveClass != NULL)
527 {
528 if(phost->pActiveClass->Init(phost)== USBH_OK)
529 {
530 phost->gState = HOST_CLASS_REQUEST;
531 USBH_UsrLog ("%s class started.", phost->pActiveClass->Name);
532
533 /* Inform user that a class has been activated */
534 phost->pUser(phost, HOST_USER_CLASS_SELECTED);
535 }
536 else
537 {
538 phost->gState = HOST_ABORT_STATE;
539 USBH_UsrLog ("Device not supporting %s class.", phost->pActiveClass->Name);
540 }
541 }
542 else
543 {
544 phost->gState = HOST_ABORT_STATE;
545 USBH_UsrLog ("No registered class for this device.");
546 }
547 }
548
549 #if (USBH_USE_OS == 1)
550 osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
551 #endif
552 break;
553
554 case HOST_CLASS_REQUEST:
555 /* process class standard contol requests state machine */
556
557 if(phost->pActiveClass != NULL)
558 {
559 status = phost->pActiveClass->Requests(phost);
560
561 if(status == USBH_OK)
562 {
563 phost->gState = HOST_CLASS;
564 }
565 }
566 else
567 {
568 phost->gState = HOST_ABORT_STATE;
569 USBH_ErrLog ("Invalid Class Driver.");
570
571 #if (USBH_USE_OS == 1)
572 osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
573 #endif
574 }
575
576 break;
577 case HOST_CLASS:
578 /* process class state machine */
579 if(phost->pActiveClass != NULL)
580 {
581 phost->pActiveClass->BgndProcess(phost);
582 }
583 break;
584
585 case HOST_DEV_DISCONNECTED :
586
587 DeInitStateMachine(phost);
588
589 /* Re-Initilaize Host for new Enumeration */
590 if(phost->pActiveClass != NULL)
591 {
592 phost->pActiveClass->DeInit(phost);
593 phost->pActiveClass = NULL;
594 }
595 break;
596
597 case HOST_ABORT_STATE:
598 default :
599 break;
600 }
601 return USBH_OK;
602 }
603
604
605 /**
606 * @brief USBH_HandleEnum
607 * This function includes the complete enumeration process
608 * @param phost: Host Handle
609 * @retval USBH_Status
610 */
USBH_HandleEnum(USBH_HandleTypeDef * phost)611 static USBH_StatusTypeDef USBH_HandleEnum (USBH_HandleTypeDef *phost)
612 {
613 USBH_StatusTypeDef Status = USBH_BUSY;
614
615 switch (phost->EnumState)
616 {
617 case ENUM_IDLE:
618 /* Get Device Desc for only 1st 8 bytes : To get EP0 MaxPacketSize */
619 if ( USBH_Get_DevDesc(phost, 8) == USBH_OK)
620 {
621 phost->Control.pipe_size = phost->device.DevDesc.bMaxPacketSize;
622
623 phost->EnumState = ENUM_GET_FULL_DEV_DESC;
624
625 /* modify control channels configuration for MaxPacket size */
626 USBH_OpenPipe (phost,
627 phost->Control.pipe_in,
628 0x80,
629 phost->device.address,
630 phost->device.speed,
631 USBH_EP_CONTROL,
632 phost->Control.pipe_size);
633
634 /* Open Control pipes */
635 USBH_OpenPipe (phost,
636 phost->Control.pipe_out,
637 0x00,
638 phost->device.address,
639 phost->device.speed,
640 USBH_EP_CONTROL,
641 phost->Control.pipe_size);
642
643 }
644 break;
645
646 case ENUM_GET_FULL_DEV_DESC:
647 /* Get FULL Device Desc */
648 if ( USBH_Get_DevDesc(phost, USB_DEVICE_DESC_SIZE)== USBH_OK)
649 {
650 USBH_UsrLog("PID: %xh", phost->device.DevDesc.idProduct );
651 USBH_UsrLog("VID: %xh", phost->device.DevDesc.idVendor );
652
653 phost->EnumState = ENUM_SET_ADDR;
654
655 }
656 break;
657
658 case ENUM_SET_ADDR:
659 /* set address */
660 if ( USBH_SetAddress(phost, USBH_DEVICE_ADDRESS) == USBH_OK)
661 {
662 USBH_Delay(2);
663 phost->device.address = USBH_DEVICE_ADDRESS;
664
665 /* user callback for device address assigned */
666 USBH_UsrLog("Address (#%d) assigned.", phost->device.address);
667 phost->EnumState = ENUM_GET_CFG_DESC;
668
669 /* modify control channels to update device address */
670 USBH_OpenPipe (phost,
671 phost->Control.pipe_in,
672 0x80,
673 phost->device.address,
674 phost->device.speed,
675 USBH_EP_CONTROL,
676 phost->Control.pipe_size);
677
678 /* Open Control pipes */
679 USBH_OpenPipe (phost,
680 phost->Control.pipe_out,
681 0x00,
682 phost->device.address,
683 phost->device.speed,
684 USBH_EP_CONTROL,
685 phost->Control.pipe_size);
686 }
687 break;
688
689 case ENUM_GET_CFG_DESC:
690 /* get standard configuration descriptor */
691 if ( USBH_Get_CfgDesc(phost,
692 USB_CONFIGURATION_DESC_SIZE) == USBH_OK)
693 {
694 phost->EnumState = ENUM_GET_FULL_CFG_DESC;
695 }
696 break;
697
698 case ENUM_GET_FULL_CFG_DESC:
699 /* get FULL config descriptor (config, interface, endpoints) */
700 if (USBH_Get_CfgDesc(phost,
701 phost->device.CfgDesc.wTotalLength) == USBH_OK)
702 {
703 phost->EnumState = ENUM_GET_MFC_STRING_DESC;
704 }
705 break;
706
707 case ENUM_GET_MFC_STRING_DESC:
708 if (phost->device.DevDesc.iManufacturer != 0)
709 { /* Check that Manufacturer String is available */
710
711 if ( USBH_Get_StringDesc(phost,
712 phost->device.DevDesc.iManufacturer,
713 phost->device.Data ,
714 0xff) == USBH_OK)
715 {
716 /* User callback for Manufacturing string */
717 USBH_UsrLog("Manufacturer : %s", (char *)phost->device.Data);
718 phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC;
719
720 #if (USBH_USE_OS == 1)
721 osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
722 #endif
723 }
724 }
725 else
726 {
727 USBH_UsrLog("Manufacturer : N/A");
728 phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC;
729 #if (USBH_USE_OS == 1)
730 osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
731 #endif
732 }
733 break;
734
735 case ENUM_GET_PRODUCT_STRING_DESC:
736 if (phost->device.DevDesc.iProduct != 0)
737 { /* Check that Product string is available */
738 if ( USBH_Get_StringDesc(phost,
739 phost->device.DevDesc.iProduct,
740 phost->device.Data,
741 0xff) == USBH_OK)
742 {
743 /* User callback for Product string */
744 USBH_UsrLog("Product : %s", (char *)phost->device.Data);
745 phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC;
746 }
747 }
748 else
749 {
750 USBH_UsrLog("Product : N/A");
751 phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC;
752 #if (USBH_USE_OS == 1)
753 osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
754 #endif
755 }
756 break;
757
758 case ENUM_GET_SERIALNUM_STRING_DESC:
759 if (phost->device.DevDesc.iSerialNumber != 0)
760 { /* Check that Serial number string is available */
761 if ( USBH_Get_StringDesc(phost,
762 phost->device.DevDesc.iSerialNumber,
763 phost->device.Data,
764 0xff) == USBH_OK)
765 {
766 /* User callback for Serial number string */
767 USBH_UsrLog("Serial Number : %s", (char *)phost->device.Data);
768 Status = USBH_OK;
769 }
770 }
771 else
772 {
773 USBH_UsrLog("Serial Number : N/A");
774 Status = USBH_OK;
775 #if (USBH_USE_OS == 1)
776 osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
777 #endif
778 }
779 break;
780
781 default:
782 break;
783 }
784 return Status;
785 }
786
787 /**
788 * @brief USBH_LL_SetTimer
789 * Set the initial Host Timer tick
790 * @param phost: Host Handle
791 * @retval None
792 */
USBH_LL_SetTimer(USBH_HandleTypeDef * phost,uint32_t time)793 void USBH_LL_SetTimer (USBH_HandleTypeDef *phost, uint32_t time)
794 {
795 phost->Timer = time;
796 }
797 /**
798 * @brief USBH_LL_IncTimer
799 * Increment Host Timer tick
800 * @param phost: Host Handle
801 * @retval None
802 */
USBH_LL_IncTimer(USBH_HandleTypeDef * phost)803 void USBH_LL_IncTimer (USBH_HandleTypeDef *phost)
804 {
805 phost->Timer ++;
806 USBH_HandleSof(phost);
807 }
808
809 /**
810 * @brief USBH_HandleSof
811 * Call SOF process
812 * @param phost: Host Handle
813 * @retval None
814 */
USBH_HandleSof(USBH_HandleTypeDef * phost)815 void USBH_HandleSof (USBH_HandleTypeDef *phost)
816 {
817 if((phost->gState == HOST_CLASS)&&(phost->pActiveClass != NULL))
818 {
819 phost->pActiveClass->SOFProcess(phost);
820 }
821 }
822 /**
823 * @brief USBH_LL_Connect
824 * Handle USB Host connexion event
825 * @param phost: Host Handle
826 * @retval USBH_Status
827 */
USBH_LL_Connect(USBH_HandleTypeDef * phost)828 USBH_StatusTypeDef USBH_LL_Connect (USBH_HandleTypeDef *phost)
829 {
830 if(phost->gState == HOST_IDLE )
831 {
832 phost->device.is_connected = 1;
833 phost->gState = HOST_IDLE ;
834
835 if(phost->pUser != NULL)
836 {
837 phost->pUser(phost, HOST_USER_CONNECTION);
838 }
839 }
840 else if(phost->gState == HOST_DEV_WAIT_FOR_ATTACHMENT )
841 {
842 phost->gState = HOST_DEV_ATTACHED ;
843 }
844 #if (USBH_USE_OS == 1)
845 osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0);
846 #endif
847
848 return USBH_OK;
849 }
850
851 /**
852 * @brief USBH_LL_Disconnect
853 * Handle USB Host disconnexion event
854 * @param phost: Host Handle
855 * @retval USBH_Status
856 */
USBH_LL_Disconnect(USBH_HandleTypeDef * phost)857 USBH_StatusTypeDef USBH_LL_Disconnect (USBH_HandleTypeDef *phost)
858 {
859 /*Stop Host */
860 USBH_LL_Stop(phost);
861
862 /* FRee Control Pipes */
863 USBH_FreePipe (phost, phost->Control.pipe_in);
864 USBH_FreePipe (phost, phost->Control.pipe_out);
865
866 phost->device.is_connected = 0;
867
868 if(phost->pUser != NULL)
869 {
870 phost->pUser(phost, HOST_USER_DISCONNECTION);
871 }
872 USBH_UsrLog("USB Device disconnected");
873
874 /* Start the low level driver */
875 USBH_LL_Start(phost);
876
877 phost->gState = HOST_DEV_DISCONNECTED;
878
879 #if (USBH_USE_OS == 1)
880 osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0);
881 #endif
882
883 return USBH_OK;
884 }
885
886
887 #if (USBH_USE_OS == 1)
888 /**
889 * @brief USB Host Thread task
890 * @param pvParameters not used
891 * @retval None
892 */
USBH_Process_OS(void const * argument)893 static void USBH_Process_OS(void const * argument)
894 {
895 osEvent event;
896
897 for(;;)
898 {
899 event = osMessageGet(((USBH_HandleTypeDef *)argument)->os_event, osWaitForever );
900
901 if( event.status == osEventMessage )
902 {
903 USBH_Process((USBH_HandleTypeDef *)argument);
904 }
905 }
906 }
907
908 /**
909 * @brief USBH_LL_NotifyURBChange
910 * Notify URB state Change
911 * @param phost: Host handle
912 * @retval USBH Status
913 */
USBH_LL_NotifyURBChange(USBH_HandleTypeDef * phost)914 USBH_StatusTypeDef USBH_LL_NotifyURBChange (USBH_HandleTypeDef *phost)
915 {
916 osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
917 return USBH_OK;
918 }
919 #endif
920 /**
921 * @}
922 */
923
924 /**
925 * @}
926 */
927
928 /**
929 * @}
930 */
931
932 /**
933 * @}
934 */
935
936 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
937