1 /*
2 * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016 - 2019 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "usb_host_config.h"
10 #include "fsl_common.h"
11 #include "usb_host.h"
12 #include "usb_host_hci.h"
13 #include "usb_host_devices.h"
14 #include "fsl_device_registers.h"
15
16 /*******************************************************************************
17 * Definitions
18 ******************************************************************************/
19
20 /* Component ID definition, used by tools. */
21 #ifndef FSL_COMPONENT_ID
22 #define FSL_COMPONENT_ID "middleware.usb.host_stack"
23 #endif
24
25 /*******************************************************************************
26 * Prototypes
27 ******************************************************************************/
28 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
29
30 #include "usb_host_hub.h"
31 #include "usb_host_hub_app.h"
32 #endif
33
34 /*!
35 * @brief get the idle host instance.
36 *
37 * @return host instance pointer.
38 */
39 static usb_host_instance_t *USB_HostGetInstance(void);
40
41 /*!
42 * @brief release host instance.
43 *
44 * @param hostInstance host instance pointer.
45 */
46 static void USB_HostReleaseInstance(usb_host_instance_t *hostInstance);
47
48 /*!
49 * @brief get the khci/ehci interface.
50 *
51 * @param controllerId controller id.
52 * @param controllerTable return controller interface structure.
53 */
54 static void USB_HostGetControllerInterface(uint8_t controllerId,
55 const usb_host_controller_interface_t **controllerTable);
56
57 /*******************************************************************************
58 * Variables
59 ******************************************************************************/
60 /*! @brief USB host instance resource */
61 usb_host_instance_t g_UsbHostInstance[USB_HOST_CONFIG_MAX_HOST];
62
63 #if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
64 #include "usb_host_ehci.h"
65 static const usb_host_controller_interface_t s_EhciInterface = {
66 USB_HostEhciCreate, USB_HostEhciDestory, USB_HostEhciOpenPipe, USB_HostEhciClosePipe,
67 USB_HostEhciWritePipe, USB_HostEhciReadpipe, USB_HostEhciIoctl,
68 };
69 #endif /* USB_HOST_CONFIG_EHCI */
70
71 #if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI))
72 #include "usb_host_khci.h"
73 static const usb_host_controller_interface_t s_KhciInterface = {
74 USB_HostKhciCreate, USB_HostKhciDestory, USB_HostKhciOpenPipe, USB_HostKhciClosePipe,
75 USB_HostKhciWritePipe, USB_HostKhciReadpipe, USB_HostKciIoctl,
76 };
77 #endif /* USB_HOST_CONFIG_KHCI */
78
79 #if ((defined USB_HOST_CONFIG_OHCI) && (USB_HOST_CONFIG_OHCI > 0U))
80 #include "usb_host_ohci.h"
81 static const usb_host_controller_interface_t s_OhciInterface = {
82 USB_HostOhciCreate, USB_HostOhciDestory, USB_HostOhciOpenPipe, USB_HostOhciClosePipe,
83 USB_HostOhciWritePipe, USB_HostOhciReadPipe, USB_HostOhciIoctl,
84 };
85 #endif /* USB_HOST_CONFIG_OHCI */
86
87 #if ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS > 0U))
88 #include "usb_host_ip3516hs.h"
89 static const usb_host_controller_interface_t s_Ip3516HsInterface = {
90 USB_HostIp3516HsCreate, USB_HostIp3516HsDestory, USB_HostIp3516HsOpenPipe, USB_HostIp3516HsClosePipe,
91 USB_HostIp3516HsWritePipe, USB_HostIp3516HsReadPipe, USB_HostIp3516HsIoctl,
92 };
93 #endif /* USB_HOST_CONFIG_IP3516HS */
94
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)95 USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
96 static uint8_t s_Setupbuffer[USB_HOST_CONFIG_MAX_HOST][USB_HOST_CONFIG_MAX_TRANSFERS][USB_DATA_ALIGN_SIZE_MULTIPLE(8)];
97 /*******************************************************************************
98 * Code
99 ******************************************************************************/
100
101 #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
102 /*FUNCTION*----------------------------------------------------------------
103 *
104 * Function Name : usb_test_mode_init
105 * Returned Value : None
106 * Comments :
107 * This function is called by common class to initialize the class driver. It
108 * is called in response to a select interface call by application
109 *
110 *END*--------------------------------------------------------------------*/
111 usb_status_t USB_HostTestModeInit(usb_device_handle deviceHandle)
112 {
113 #if (((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI)) || \
114 ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS)))
115 usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
116 usb_host_instance_t *hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle;
117 #endif
118 uint32_t productId;
119 uint32_t vendorId;
120
121 (void)usb_echo("usb host test init\r\n");
122 (void)USB_HostHelperGetPeripheralInformation(deviceHandle, (uint32_t)kUSB_HostGetDevicePID, &productId);
123 (void)USB_HostHelperGetPeripheralInformation(deviceHandle, (uint32_t)kUSB_HostGetDeviceVID, &vendorId);
124 (void)usb_echo(" vendor id :0x%x product id:0x%x \r\n", vendorId, productId);
125
126 if ((productId != 0x0200U) && (productId != 0x0101U) && (productId != 0x0102U) && (productId != 0x0103U) &&
127 (productId != 0x0104U) && (productId != 0x0105U) && (productId != 0x0106U) && (productId != 0x0107U) &&
128 (productId != 0x0108U))
129 {
130 (void)usb_echo("Unsupported Device\r\n");
131 }
132
133 if (productId == 0x0200U)
134 {
135 (void)usb_echo("PET test device attached\r\n");
136 }
137 else
138 {
139 #if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
140 if (hostInstance->controllerTable == &s_EhciInterface)
141 {
142 (void)hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostTestModeInit,
143 (void *)deviceHandle);
144 }
145 #elif ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS))
146 if (hostInstance->controllerTable == &s_Ip3516HsInterface)
147 {
148 (void)hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostTestModeInit,
149 (void *)deviceHandle);
150 }
151 #endif
152 }
153
154 return kStatus_USB_Success;
155 }
156 #endif
157
USB_HostGetInstance(void)158 static usb_host_instance_t *USB_HostGetInstance(void)
159 {
160 uint8_t i = 0;
161 uint32_t index = 0;
162 void *temp;
163 OSA_SR_ALLOC();
164 OSA_ENTER_CRITICAL();
165 for (; i < (uint8_t)USB_HOST_CONFIG_MAX_HOST; i++)
166 {
167 if (g_UsbHostInstance[i].occupied != 1U)
168 {
169 uint8_t *buffer = (uint8_t *)&g_UsbHostInstance[i];
170 for (uint32_t j = 0U; j < sizeof(usb_host_instance_t); j++)
171 {
172 buffer[j] = 0x00U;
173 }
174 g_UsbHostInstance[i].occupied = 1;
175 OSA_EXIT_CRITICAL();
176 for (index = 0; index < (uint32_t)USB_HOST_CONFIG_MAX_TRANSFERS; ++index)
177 {
178 temp = (void *)&(s_Setupbuffer[i][index][0]);
179 g_UsbHostInstance[i].transferList[index].setupPacket = (usb_setup_struct_t *)temp;
180 }
181 return &g_UsbHostInstance[i];
182 }
183 }
184 OSA_EXIT_CRITICAL();
185 return NULL;
186 }
187
USB_HostReleaseInstance(usb_host_instance_t * hostInstance)188 static void USB_HostReleaseInstance(usb_host_instance_t *hostInstance)
189 {
190 OSA_SR_ALLOC();
191 OSA_ENTER_CRITICAL();
192 hostInstance->occupied = 0;
193 OSA_EXIT_CRITICAL();
194 }
195
USB_HostGetControllerInterface(uint8_t controllerId,const usb_host_controller_interface_t ** controllerTable)196 static void USB_HostGetControllerInterface(uint8_t controllerId,
197 const usb_host_controller_interface_t **controllerTable)
198 {
199 #if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI))
200 if (controllerId == (uint8_t)kUSB_ControllerKhci0)
201 {
202 *controllerTable = &s_KhciInterface;
203 }
204 #endif /* USB_HOST_CONFIG_KHCI */
205
206 #if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
207 if ((controllerId == (uint8_t)kUSB_ControllerEhci0) || (controllerId == (uint8_t)kUSB_ControllerEhci1))
208 {
209 *controllerTable = &s_EhciInterface;
210 }
211 #endif /* USB_HOST_CONFIG_EHCI */
212
213 #if ((defined USB_HOST_CONFIG_OHCI) && (USB_HOST_CONFIG_OHCI > 0U))
214 if (controllerId == (uint8_t)kUSB_ControllerOhci0)
215 {
216 *controllerTable = &s_OhciInterface;
217 }
218 #endif /* USB_HOST_CONFIG_OHCI */
219
220 #if ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS > 0U))
221 if (controllerId == (uint8_t)kUSB_ControllerIp3516Hs0)
222 {
223 *controllerTable = &s_Ip3516HsInterface;
224 }
225 #endif /* USB_HOST_CONFIG_IP3516HS */
226 }
227
USB_HostInit(uint8_t controllerId,usb_host_handle * hostHandle,host_callback_t callbackFn)228 usb_status_t USB_HostInit(uint8_t controllerId, usb_host_handle *hostHandle, host_callback_t callbackFn)
229 {
230 usb_status_t status = kStatus_USB_Success;
231 usb_host_instance_t *hostInstance = NULL;
232 usb_host_transfer_t *transferPrev = NULL;
233 uint8_t i = 0;
234
235 hostInstance = USB_HostGetInstance(); /* get one host instance */
236 if (hostInstance == NULL)
237 {
238 return kStatus_USB_InvalidHandle;
239 }
240
241 /* get khci/ehci API table */
242 USB_HostGetControllerInterface(controllerId, &hostInstance->controllerTable);
243 if (hostInstance->controllerTable == NULL)
244 {
245 USB_HostReleaseInstance(hostInstance);
246 return kStatus_USB_ControllerNotFound;
247 }
248
249 /* judge the controller interface one time at here */
250 if ((hostInstance->controllerTable->controllerCreate == NULL) ||
251 (hostInstance->controllerTable->controllerDestory == NULL) ||
252 (hostInstance->controllerTable->controllerOpenPipe == NULL) ||
253 (hostInstance->controllerTable->controllerClosePipe == NULL) ||
254 (hostInstance->controllerTable->controllerWritePipe == NULL) ||
255 (hostInstance->controllerTable->controllerReadPipe == NULL) ||
256 (hostInstance->controllerTable->controllerIoctl == NULL))
257 {
258 return kStatus_USB_Error;
259 }
260
261 /* HOST instance init*/
262 hostInstance->controllerId = controllerId;
263 hostInstance->deviceCallback = callbackFn;
264 hostInstance->deviceList = NULL;
265 hostInstance->hostMutex = (osa_mutex_handle_t)(&hostInstance->mutexBuffer[0]);
266 if (KOSA_StatusSuccess != OSA_MutexCreate(hostInstance->hostMutex))
267 {
268 USB_HostReleaseInstance(hostInstance);
269 #ifdef HOST_ECHO
270 usb_echo("host init: create host mutex fail\r\n");
271 #endif
272 return kStatus_USB_Error;
273 }
274
275 /* initialize transfer list */
276
277 hostInstance->transferHead = &hostInstance->transferList[0];
278 transferPrev = hostInstance->transferHead;
279 for (i = 1; i < USB_HOST_CONFIG_MAX_TRANSFERS; ++i)
280 {
281 transferPrev->next = &hostInstance->transferList[i];
282 transferPrev = transferPrev->next;
283 }
284
285 /* controller create, the callbackFn is initialized in USB_HostGetControllerInterface */
286 status =
287 hostInstance->controllerTable->controllerCreate(controllerId, hostInstance, &(hostInstance->controllerHandle));
288 if ((status != kStatus_USB_Success) || (hostInstance->controllerHandle == NULL))
289 {
290 (void)OSA_MutexDestroy(hostInstance->hostMutex);
291 USB_HostReleaseInstance(hostInstance);
292 #ifdef HOST_ECHO
293 usb_echo("host init: controller init fail\r\n");
294 #endif
295 return kStatus_USB_Error;
296 }
297
298 *hostHandle = hostInstance;
299 return kStatus_USB_Success;
300 }
301
USB_HostDeinit(usb_host_handle hostHandle)302 usb_status_t USB_HostDeinit(usb_host_handle hostHandle)
303 {
304 usb_status_t status = kStatus_USB_Success;
305 usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
306 usb_host_device_instance_t *deviceInstance = NULL;
307
308 if (hostHandle == NULL)
309 {
310 return kStatus_USB_InvalidHandle;
311 }
312
313 /* device list detach */
314 deviceInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
315 while (deviceInstance != NULL)
316 {
317 deviceInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
318 (void)USB_HostDetachDeviceInternal(hostHandle, deviceInstance);
319 }
320
321 /* controller instance destroy, the callbackFn is initialized in USB_HostGetControllerInterface */
322 status = hostInstance->controllerTable->controllerDestory(hostInstance->controllerHandle);
323 hostInstance->controllerHandle = NULL;
324 if (status != kStatus_USB_Success)
325 {
326 #ifdef HOST_ECHO
327 usb_echo("host controller destroy fail\r\n");
328 #endif
329 }
330
331 /* resource release */
332 if (NULL != hostInstance->hostMutex)
333 {
334 (void)OSA_MutexDestroy(hostInstance->hostMutex);
335 hostInstance->hostMutex = NULL;
336 }
337 USB_HostReleaseInstance(hostInstance);
338
339 return status;
340 }
341
USB_HostOpenPipe(usb_host_handle hostHandle,usb_host_pipe_handle * pipeHandle,usb_host_pipe_init_t * pipeInit)342 usb_status_t USB_HostOpenPipe(usb_host_handle hostHandle,
343 usb_host_pipe_handle *pipeHandle,
344 usb_host_pipe_init_t *pipeInit)
345 {
346 usb_status_t status = kStatus_USB_Success;
347 usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
348
349 if ((hostHandle == NULL) || (pipeInit == NULL))
350 {
351 return kStatus_USB_InvalidHandle;
352 }
353
354 /* call controller open pipe interface, the callbackFn is initialized in USB_HostGetControllerInterface */
355 status = hostInstance->controllerTable->controllerOpenPipe(hostInstance->controllerHandle, pipeHandle, pipeInit);
356
357 return status;
358 }
359
USB_HostClosePipe(usb_host_handle hostHandle,usb_host_pipe_handle pipeHandle)360 usb_status_t USB_HostClosePipe(usb_host_handle hostHandle, usb_host_pipe_handle pipeHandle)
361 {
362 usb_status_t status = kStatus_USB_Success;
363 usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
364
365 if ((hostHandle == NULL) || (pipeHandle == NULL))
366 {
367 return kStatus_USB_InvalidHandle;
368 }
369
370 /* call controller close pipe interface, the callbackFn is initialized in USB_HostGetControllerInterface */
371 status = hostInstance->controllerTable->controllerClosePipe(hostInstance->controllerHandle, pipeHandle);
372
373 return status;
374 }
375
USB_HostSend(usb_host_handle hostHandle,usb_host_pipe_handle pipeHandle,usb_host_transfer_t * transfer)376 usb_status_t USB_HostSend(usb_host_handle hostHandle, usb_host_pipe_handle pipeHandle, usb_host_transfer_t *transfer)
377 {
378 usb_status_t status = kStatus_USB_Success;
379 usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
380
381 if ((hostHandle == NULL) || (pipeHandle == NULL) || (transfer == NULL))
382 {
383 return kStatus_USB_InvalidHandle;
384 }
385
386 /* initialize transfer */
387 transfer->transferSofar = 0;
388 transfer->direction = USB_OUT;
389
390 (void)USB_HostLock(); /* This api can be called by host task and app task */
391 /* keep this code: in normal situation application will guarantee the device is attached when call send/receive function
392 */
393 #if 0
394 if ((USB_HostValidateDevice(pipe_ptr->deviceHandle) != kStatus_USB_Success) || (!(USB_HostGetDeviceAttachState(pipe_ptr->deviceHandle))))
395 {
396 USB_HostUnlock();
397 return status;
398 }
399 #endif
400 /* call controller write pipe interface */
401 /* the callbackFn is initialized in USB_HostGetControllerInterface */
402 status = hostInstance->controllerTable->controllerWritePipe(hostInstance->controllerHandle, pipeHandle, transfer);
403
404 (void)USB_HostUnlock();
405 return status;
406 }
407
USB_HostSendSetup(usb_host_handle hostHandle,usb_host_pipe_handle pipeHandle,usb_host_transfer_t * transfer)408 usb_status_t USB_HostSendSetup(usb_host_handle hostHandle,
409 usb_host_pipe_handle pipeHandle,
410 usb_host_transfer_t *transfer)
411 {
412 usb_status_t status = kStatus_USB_Success;
413 usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
414
415 if ((hostHandle == NULL) || (pipeHandle == NULL) || (transfer == NULL))
416 {
417 return kStatus_USB_InvalidHandle;
418 }
419
420 /* initialize transfer */
421 transfer->transferSofar = 0;
422 transfer->next = NULL;
423 transfer->setupStatus = 0;
424 if ((transfer->setupPacket->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_IN)
425 {
426 transfer->direction = USB_IN;
427 }
428 else
429 {
430 transfer->direction = USB_OUT;
431 }
432
433 (void)USB_HostLock(); /* This API can be called by host task and application task */
434 /* keep this code: in normal situation application will guarantee the device is attached when call send/receive function
435 */
436 #if 0
437 if ((USB_HostValidateDevice(pipe_ptr->deviceHandle) != kStatus_USB_Success) || (!(USB_HostGetDeviceAttachState(pipe_ptr->deviceHandle))))
438 {
439 USB_HostUnlock();
440 return status;
441 }
442 #endif
443 /* call controller write pipe interface */
444 /* the callbackFn is initialized in USB_HostGetControllerInterface */
445 status = hostInstance->controllerTable->controllerWritePipe(hostInstance->controllerHandle, pipeHandle, transfer);
446
447 (void)USB_HostUnlock();
448 return status;
449 }
450
USB_HostRecv(usb_host_handle hostHandle,usb_host_pipe_handle pipeHandle,usb_host_transfer_t * transfer)451 usb_status_t USB_HostRecv(usb_host_handle hostHandle, usb_host_pipe_handle pipeHandle, usb_host_transfer_t *transfer)
452 {
453 usb_status_t status = kStatus_USB_Success;
454 usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
455
456 if ((hostHandle == NULL) || (pipeHandle == NULL) || (transfer == NULL))
457 {
458 return kStatus_USB_InvalidHandle;
459 }
460
461 /* initialize transfer */
462 transfer->transferSofar = 0;
463 transfer->direction = USB_IN;
464
465 (void)USB_HostLock(); /* This API can be called by host task and application task */
466 /* keep this code: in normal situation application will guarantee the device is attached when call send/receive function
467 */
468 #if 0
469 if ((USB_HostValidateDevice(pipe_ptr->deviceHandle) != kStatus_USB_Success) || (!(USB_HostGetDeviceAttachState(pipe_ptr->deviceHandle))))
470 {
471 USB_HostUnlock();
472 return status;
473 }
474 #endif
475
476 /* the callbackFn is initialized in USB_HostGetControllerInterface */
477 status = hostInstance->controllerTable->controllerReadPipe(hostInstance->controllerHandle, pipeHandle, transfer);
478
479 (void)USB_HostUnlock();
480 return status;
481 }
482
USB_HostCancelTransfer(usb_host_handle hostHandle,usb_host_pipe_handle pipeHandle,usb_host_transfer_t * transfer)483 usb_status_t USB_HostCancelTransfer(usb_host_handle hostHandle,
484 usb_host_pipe_handle pipeHandle,
485 usb_host_transfer_t *transfer)
486 {
487 usb_status_t status = kStatus_USB_Success;
488 usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
489 usb_host_cancel_param_t cancelParam;
490
491 if ((hostHandle == NULL) || (pipeHandle == NULL))
492 {
493 return kStatus_USB_InvalidHandle;
494 }
495
496 /* initialize cancel parameter */
497 cancelParam.pipeHandle = pipeHandle;
498 cancelParam.transfer = transfer;
499
500 /* USB_HostLock(); This api can be called by host task and app task */
501 /* the callbackFn is initialized in USB_HostGetControllerInterface */
502 status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostCancelTransfer,
503 &cancelParam);
504 /* USB_HostUnlock(); */
505
506 return status;
507 }
508
USB_HostMallocTransfer(usb_host_handle hostHandle,usb_host_transfer_t ** transfer)509 usb_status_t USB_HostMallocTransfer(usb_host_handle hostHandle, usb_host_transfer_t **transfer)
510 {
511 usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
512
513 if ((hostHandle == NULL) || (transfer == NULL))
514 {
515 return kStatus_USB_InvalidHandle;
516 }
517
518 /* get one from the transfer_head */
519 (void)USB_HostLock();
520 if (hostInstance->transferHead != NULL)
521 {
522 *transfer = hostInstance->transferHead;
523 hostInstance->transferHead = hostInstance->transferHead->next;
524 (void)USB_HostUnlock();
525 return kStatus_USB_Success;
526 }
527 else
528 {
529 *transfer = NULL;
530 (void)USB_HostUnlock();
531 return kStatus_USB_Error;
532 }
533 }
534
USB_HostFreeTransfer(usb_host_handle hostHandle,usb_host_transfer_t * transfer)535 usb_status_t USB_HostFreeTransfer(usb_host_handle hostHandle, usb_host_transfer_t *transfer)
536 {
537 usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
538
539 if (hostHandle == NULL)
540 {
541 return kStatus_USB_InvalidHandle;
542 }
543 if (transfer == NULL)
544 {
545 return kStatus_USB_Success;
546 }
547
548 /* release one to the transfer_head */
549 (void)USB_HostLock();
550 transfer->next = hostInstance->transferHead;
551 hostInstance->transferHead = transfer;
552 (void)USB_HostUnlock();
553 return kStatus_USB_Success;
554 }
555
USB_HostHelperGetPeripheralInformation(usb_device_handle deviceHandle,uint32_t infoCode,uint32_t * infoValue)556 usb_status_t USB_HostHelperGetPeripheralInformation(usb_device_handle deviceHandle,
557 uint32_t infoCode,
558 uint32_t *infoValue)
559 {
560 usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
561 uint32_t *temp;
562 usb_host_dev_info_t devInfo;
563 if ((deviceHandle == NULL) || (infoValue == NULL))
564 {
565 return kStatus_USB_InvalidParameter;
566 }
567 devInfo = (usb_host_dev_info_t)infoCode;
568 switch (devInfo)
569 {
570 case kUSB_HostGetDeviceAddress: /* device address */
571
572 *infoValue = (uint32_t)deviceInstance->setAddress;
573 break;
574
575 case kUSB_HostGetDeviceControlPipe: /* device control pipe */
576 temp = (uint32_t *)deviceInstance->controlPipe;
577 *infoValue = (uint32_t)temp;
578 break;
579
580 case kUSB_HostGetHostHandle: /* device host handle */
581 temp = (uint32_t *)deviceInstance->hostHandle;
582 *infoValue = (uint32_t)temp;
583 break;
584
585 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
586 case kUSB_HostGetDeviceHubNumber: /* device hub address */
587 *infoValue = (uint32_t)deviceInstance->hubNumber;
588 break;
589
590 case kUSB_HostGetDevicePortNumber: /* device port no */
591 *infoValue = (uint32_t)deviceInstance->portNumber;
592 break;
593
594 case kUSB_HostGetDeviceLevel: /* device level */
595 *infoValue = (uint32_t)deviceInstance->level;
596 break;
597
598 case kUSB_HostGetDeviceHSHubNumber: /* device high-speed hub address */
599 *infoValue = (uint32_t)deviceInstance->hsHubNumber;
600 break;
601
602 case kUSB_HostGetDeviceHSHubPort: /* device high-speed hub port no */
603 *infoValue = (uint32_t)deviceInstance->hsHubPort;
604 break;
605
606 case kUSB_HostGetHubThinkTime: /* device hub think time */
607 *infoValue = USB_HostHubGetTotalThinkTime(deviceInstance->hostHandle, deviceInstance->hubNumber);
608 break;
609 #else
610 case kUSB_HostGetDeviceHubNumber: /* device hub address */
611 case kUSB_HostGetDevicePortNumber: /* device port no */
612 case kUSB_HostGetDeviceHSHubNumber: /* device high-speed hub address */
613 case kUSB_HostGetDeviceHSHubPort: /* device high-speed hub port no */
614 case kUSB_HostGetHubThinkTime: /* device hub think time */
615 *infoValue = 0;
616 break;
617 case kUSB_HostGetDeviceLevel: /* device level */
618 *infoValue = 1;
619 break;
620 #endif /* USB_HOST_CONFIG_HUB */
621
622 case kUSB_HostGetDeviceSpeed: /* device speed */
623 *infoValue = (uint32_t)deviceInstance->speed;
624 break;
625
626 case kUSB_HostGetDevicePID: /* device pid */
627 *infoValue = (uint32_t)USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(deviceInstance->deviceDescriptor->idProduct);
628 break;
629
630 case kUSB_HostGetDeviceVID: /* device vid */
631 *infoValue = (uint32_t)USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(deviceInstance->deviceDescriptor->idVendor);
632 break;
633
634 case kUSB_HostGetDeviceConfigIndex: /* device config index */
635 *infoValue = (uint32_t)deviceInstance->configurationValue - 1U;
636 break;
637
638 case kUSB_HostGetConfigurationDes: /* configuration descriptor pointer */
639 *infoValue = (uint32_t)deviceInstance->configurationDesc;
640 break;
641
642 case kUSB_HostGetConfigurationLength: /* configuration descriptor length */
643 *infoValue = (uint32_t)deviceInstance->configurationLen;
644 break;
645
646 default:
647 /*no action*/
648 break;
649 }
650
651 return kStatus_USB_Success;
652 }
653
USB_HostHelperParseAlternateSetting(usb_host_interface_handle interfaceHandle,uint8_t alternateSetting,usb_host_interface_t * interface)654 usb_status_t USB_HostHelperParseAlternateSetting(usb_host_interface_handle interfaceHandle,
655 uint8_t alternateSetting,
656 usb_host_interface_t *interface)
657 {
658 uint32_t endPosition;
659 usb_descriptor_union_t *unionDes;
660 usb_host_ep_t *epParse;
661 void *temp;
662 if (interfaceHandle == NULL)
663 {
664 return kStatus_USB_InvalidHandle;
665 }
666
667 if (alternateSetting == 0U)
668 {
669 return kStatus_USB_InvalidParameter;
670 }
671
672 /* parse configuration descriptor */
673 temp = (void *)((usb_host_interface_t *)interfaceHandle)->interfaceExtension;
674 unionDes = (usb_descriptor_union_t *)temp; /* interface extend descriptor start */
675 endPosition =
676 (uint32_t)unionDes +
677 ((usb_host_interface_t *)interfaceHandle)->interfaceExtensionLength; /* interface extend descriptor end */
678
679 /* search for the alternate setting interface descriptor */
680 while ((uint32_t)unionDes < endPosition)
681 {
682 if (unionDes->interface.bDescriptorType == USB_DESCRIPTOR_TYPE_INTERFACE)
683 {
684 if (unionDes->interface.bAlternateSetting == alternateSetting)
685 {
686 break;
687 }
688 else
689 {
690 unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
691 }
692 }
693 else
694 {
695 unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
696 }
697 }
698 if ((uint32_t)unionDes >= endPosition)
699 {
700 return kStatus_USB_Error;
701 }
702
703 /* initialize interface handle structure instance */
704 interface->interfaceDesc = &unionDes->interface;
705 interface->alternateSettingNumber = 0U;
706 interface->epCount = 0U;
707 interface->interfaceExtension = NULL;
708 interface->interfaceExtensionLength = 0U;
709 interface->interfaceIndex = unionDes->interface.bInterfaceNumber;
710
711 /* search for endpoint descriptor start position */
712 unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
713 while ((uint32_t)unionDes < endPosition)
714 {
715 if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE) &&
716 (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT))
717 {
718 if (interface->interfaceExtension == NULL)
719 {
720 interface->interfaceExtension = (uint8_t *)unionDes;
721 }
722 interface->interfaceExtensionLength += unionDes->common.bLength;
723 unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
724 }
725 else
726 {
727 break;
728 }
729 }
730
731 /* parse endpoint descriptor */
732 if (interface->interfaceDesc->bNumEndpoints != 0U)
733 {
734 if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT) ||
735 (interface->interfaceDesc->bNumEndpoints > USB_HOST_CONFIG_INTERFACE_MAX_EP))
736 {
737 #ifdef HOST_ECHO
738 usb_echo("interface descriptor error\n");
739 #endif
740 return kStatus_USB_Error;
741 }
742 for (; interface->epCount < interface->interfaceDesc->bNumEndpoints; (interface->epCount)++)
743 {
744 if (((uint32_t)unionDes >= endPosition) ||
745 (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT))
746 {
747 #ifdef HOST_ECHO
748 usb_echo("endpoint descriptor error\n");
749 #endif
750 return kStatus_USB_Error;
751 }
752 epParse = (usb_host_ep_t *)&interface->epList[interface->epCount];
753 temp = (void *)unionDes;
754 epParse->epDesc = (usb_descriptor_endpoint_t *)temp;
755 epParse->epExtensionLength = 0;
756 epParse->epExtension = NULL;
757 unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
758 while ((uint32_t)unionDes < endPosition)
759 {
760 if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT) &&
761 (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE))
762 {
763 if (epParse->epExtension == NULL)
764 {
765 epParse->epExtension = (uint8_t *)unionDes;
766 }
767 epParse->epExtensionLength += unionDes->common.bLength;
768 unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
769 }
770 else
771 {
772 break;
773 }
774 }
775 }
776 }
777
778 return kStatus_USB_Success;
779 }
780
USB_HostGetVersion(uint32_t * version)781 void USB_HostGetVersion(uint32_t *version)
782 {
783 if (NULL != version)
784 {
785 *version =
786 (uint32_t)USB_MAKE_VERSION(USB_STACK_VERSION_MAJOR, USB_STACK_VERSION_MINOR, USB_STACK_VERSION_BUGFIX);
787 }
788 }
789
790 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
791 /* Send BUS or specific device suspend request */
USB_HostSuspendDeviceResquest(usb_host_handle hostHandle,usb_device_handle deviceHandle)792 usb_status_t USB_HostSuspendDeviceResquest(usb_host_handle hostHandle, usb_device_handle deviceHandle)
793 {
794 usb_host_instance_t *hostInstance;
795 usb_host_device_instance_t *deviceInstance;
796 usb_status_t status = kStatus_USB_Error;
797 usb_host_bus_control_t type = kUSB_HostBusSuspend;
798
799 if (hostHandle == NULL)
800 {
801 return kStatus_USB_InvalidHandle;
802 }
803 hostInstance = (usb_host_instance_t *)hostHandle;
804
805 hostInstance->suspendedDevice = (void *)deviceHandle;
806
807 if (NULL == deviceHandle)
808 {
809 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
810 status = USB_HostHubSuspendDevice(hostInstance);
811 #else
812 /* the callbackFn is initialized in USB_HostGetControllerInterface */
813 status =
814 hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, &type);
815 #endif
816 }
817 else
818 {
819 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
820 deviceInstance = (usb_host_device_instance_t *)deviceHandle;
821 if (0U == deviceInstance->hubNumber)
822 {
823 #endif
824 if (hostInstance->deviceList == deviceHandle)
825 {
826 /* the callbackFn is initialized in USB_HostGetControllerInterface */
827 status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle,
828 kUSB_HostBusControl, &type);
829 }
830 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
831 }
832 else
833 {
834 if (kStatus_USB_Success == USB_HostValidateDevice(hostInstance, deviceHandle))
835 {
836 status = USB_HostHubSuspendDevice(hostInstance);
837 }
838 }
839 #endif
840 }
841 if (kStatus_USB_Error == status)
842 {
843 hostInstance->suspendedDevice = NULL;
844 }
845 return status;
846 }
847
848 /* Send BUS or specific device resume request */
USB_HostResumeDeviceResquest(usb_host_handle hostHandle,usb_device_handle deviceHandle)849 usb_status_t USB_HostResumeDeviceResquest(usb_host_handle hostHandle, usb_device_handle deviceHandle)
850 {
851 usb_host_instance_t *hostInstance;
852 usb_host_device_instance_t *deviceInstance;
853 usb_status_t status = kStatus_USB_Error;
854 usb_host_bus_control_t type = kUSB_HostBusResume;
855
856 if (hostHandle == NULL)
857 {
858 return kStatus_USB_InvalidHandle;
859 }
860 hostInstance = (usb_host_instance_t *)hostHandle;
861
862 if (hostInstance->suspendedDevice != deviceHandle)
863 {
864 return kStatus_USB_InvalidParameter;
865 }
866 hostInstance->suspendedDevice = (void *)deviceHandle;
867
868 if (NULL == deviceHandle)
869 {
870 /* the callbackFn is initialized in USB_HostGetControllerInterface */
871 status =
872 hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, &type);
873 }
874 else
875 {
876 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
877 deviceInstance = (usb_host_device_instance_t *)deviceHandle;
878 if (0U == deviceInstance->hubNumber)
879 {
880 #endif
881 if (hostInstance->deviceList == deviceHandle)
882 {
883 /* the callbackFn is initialized in USB_HostGetControllerInterface */
884 status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle,
885 kUSB_HostBusControl, &type);
886 }
887 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
888 }
889 else
890 {
891 if (kStatus_USB_Success == USB_HostValidateDevice(hostInstance, deviceHandle))
892 {
893 status = USB_HostHubResumeDevice(hostInstance);
894 }
895 }
896 #endif
897 }
898
899 return status;
900 }
901 #if ((defined(USB_HOST_CONFIG_LPM_L1)) && (USB_HOST_CONFIG_LPM_L1 > 0U))
902 /* Send BUS or specific device suspend request */
USB_HostL1SleepDeviceResquest(usb_host_handle hostHandle,usb_device_handle deviceHandle,uint8_t sleepType)903 usb_status_t USB_HostL1SleepDeviceResquest(usb_host_handle hostHandle,
904 usb_device_handle deviceHandle,
905 uint8_t sleepType)
906 {
907 usb_host_instance_t *hostInstance;
908 usb_status_t status = kStatus_USB_Error;
909 usb_host_bus_control_t type = kUSB_HostBusL1Sleep;
910
911 if (hostHandle == NULL)
912 {
913 return kStatus_USB_InvalidHandle;
914 }
915 hostInstance = (usb_host_instance_t *)hostHandle;
916
917 hostInstance->suspendedDevice = (void *)deviceHandle;
918
919 if (1U == sleepType)
920 {
921 /*#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))*/
922 /*To do, incomplete hub L1 suspend device*/
923 /*#else*/
924 /* the callbackFn is initialized in USB_HostGetControllerInterface */
925 status =
926 hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, &type);
927 /*#endif*/
928 }
929 else
930 {
931 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
932 /*To do, if device hub number is 0, need suspend the bus ,else suspend the corresponding device*/
933 #endif
934 if (hostInstance->deviceList == deviceHandle)
935 {
936 /* the callbackFn is initialized in USB_HostGetControllerInterface */
937 status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl,
938 &type);
939 }
940 }
941 if (kStatus_USB_Error == status)
942 {
943 hostInstance->suspendedDevice = NULL;
944 }
945 return status;
946 }
947 /* Send BUS or specific device suspend request */
USB_HostL1SleepDeviceResquestConfig(usb_host_handle hostHandle,uint8_t * lpmParam)948 usb_status_t USB_HostL1SleepDeviceResquestConfig(usb_host_handle hostHandle, uint8_t *lpmParam)
949 {
950 usb_host_instance_t *hostInstance;
951 usb_status_t status = kStatus_USB_Error;
952
953 if (hostHandle == NULL)
954 {
955 return kStatus_USB_InvalidHandle;
956 }
957 hostInstance = (usb_host_instance_t *)hostHandle;
958 /* the callbackFn is initialized in USB_HostGetControllerInterface */
959 status =
960 hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostL1Config, lpmParam);
961
962 return status;
963 }
964
965 /* Send BUS or specific device resume request */
USB_HostL1ResumeDeviceResquest(usb_host_handle hostHandle,usb_device_handle deviceHandle,uint8_t sleepType)966 usb_status_t USB_HostL1ResumeDeviceResquest(usb_host_handle hostHandle,
967 usb_device_handle deviceHandle,
968 uint8_t sleepType)
969 {
970 usb_host_instance_t *hostInstance;
971
972 usb_status_t status = kStatus_USB_Error;
973 usb_host_bus_control_t type = kUSB_HostBusL1Resume;
974
975 if (hostHandle == NULL)
976 {
977 return kStatus_USB_InvalidHandle;
978 }
979 hostInstance = (usb_host_instance_t *)hostHandle;
980
981 if (1U == sleepType)
982 {
983 /* the callbackFn is initialized in USB_HostGetControllerInterface */
984 status =
985 hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, &type);
986 }
987 else
988 {
989 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
990 /*To do, if device hub number is 0, need suspend the bus ,else suspend the corresponding device*/
991
992 #endif
993 if (hostInstance->deviceList == deviceHandle)
994 {
995 /* the callbackFn is initialized in USB_HostGetControllerInterface */
996 status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl,
997 &type);
998 }
999 }
1000
1001 return status;
1002 }
1003 #endif
1004 /* Update HW tick(unit is ms) */
USB_HostUpdateHwTick(usb_host_handle hostHandle,uint64_t tick)1005 usb_status_t USB_HostUpdateHwTick(usb_host_handle hostHandle, uint64_t tick)
1006 {
1007 usb_host_instance_t *hostInstance;
1008 usb_status_t status = kStatus_USB_Success;
1009
1010 if (hostHandle == NULL)
1011 {
1012 return kStatus_USB_InvalidHandle;
1013 }
1014 hostInstance = (usb_host_instance_t *)hostHandle;
1015
1016 hostInstance->hwTick = tick;
1017
1018 return status;
1019 }
1020 #endif
1021
1022 #if ((defined(USB_HOST_CONFIG_BATTERY_CHARGER)) && (USB_HOST_CONFIG_BATTERY_CHARGER > 0U))
USB_HostSetChargerType(usb_host_handle hostHandle,uint8_t type)1023 usb_status_t USB_HostSetChargerType(usb_host_handle hostHandle, uint8_t type)
1024 {
1025 usb_host_instance_t *hostInstance;
1026
1027 if (hostHandle == NULL)
1028 {
1029 return kStatus_USB_InvalidHandle;
1030 }
1031 hostInstance = (usb_host_instance_t *)hostHandle;
1032 return hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostSetChargerType,
1033 &type);
1034 }
1035 #endif
1036