00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "conf_usb_host.h"
00039 #include "USBHDriver.h"
00040 #include "uhi.h"
00041 #include "USBH.h"
00042 #include <stdlib.h>
00043
00044 #ifndef USB_HOST_UHI
00045 # error USB_HOST_UHI must be defined with unless one UHI interface in conf_usb_host.h file.
00046 #endif
00047
00048 #ifdef USB_HOST_HUB_SUPPORT
00049 # error The USB HUB support is not available in this revision.
00050 #endif
00051
00052
00053 #ifndef UHC_CONNECTION_EVENT
00054 #define UHC_CONNECTION_EVENT(dev,b_present)
00055 #endif
00056 #ifndef UHC_DEVICE_CONF
00057 #define UHC_DEVICE_CONF(dev) 1
00058 #endif
00059 #ifndef UHC_ENUM_EVENT
00060 #define UHC_ENUM_EVENT(dev,event)
00061 #endif
00062 #ifndef UHC_WAKEUP_EVENT
00063 #define UHC_WAKEUP_EVENT()
00064 #endif
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 static USBH_device_t USBH_device_root;
00079
00080
00081 static uint8_t USBH_enum_try;
00082
00083
00084 #define UHC_ENUM_NB_TRY 4
00085
00086
00087 #define UHC_USB_ADD_NOT_VALID 0xFF
00088
00089 #ifdef USB_HOST_HUB_SUPPORT
00090
00091 #define UHC_DEVICE_ENUM_ADD USBH_dev_enum->address
00092
00093
00094 static USBH_device_t *USBH_dev_enum;
00095
00096
00097 static uint16_t USBH_power_running;
00098
00099 #else
00100
00101 #define UHC_DEVICE_ENUM_ADD 1 // Static without USB HUB
00102
00103
00104 #define USBH_dev_enum (&USBH_device_root) // Static without USB HUB
00105
00106
00107 #define USBH_power_running 0 // No used without USB HUB
00108 #endif
00109
00110
00111 typedef void (*USBH_sof_timeout_callback_t) (void);
00112
00113
00114 static USBH_sof_timeout_callback_t USBH_sof_timeout_callback;
00115
00116
00117 uint8_t USBH_sof_timeout;
00118
00119
00120 static uhi_api_t USBH_uhis[] = {USB_HOST_UHI};
00121
00122
00123 #define UHC_NB_UHI (sizeof(USBH_uhis)/sizeof(USBH_uhis[0]))
00124
00125
00126 static volatile bool USBH_setup_request_finish;
00127
00128
00129 static volatile bool USBH_setup_request_finish_status;
00130
00131
00132
00133
00134
00135
00136 static void USBH_enable_timeout_callback(
00137 uint8_t timeout,
00138 USBH_sof_timeout_callback_t callback);
00139 static void USBH_enumeration_suspend(void);
00140 static void USBH_enumeration_reset(uhd_callback_reset_t callback);
00141 static void USBH_connection_tree(bool b_plug, USBH_device_t *dev);
00142 static void USBH_enumeration_step1(void);
00143 static void USBH_enumeration_step2(void);
00144 static void USBH_enumeration_step3(void);
00145 static void USBH_enumeration_step4(void);
00146 static void USBH_enumeration_step5(void);
00147 static void USBH_enumeration_step6(
00148 USBHS_Add_t add,
00149 USBH_XfrStatus_t status,
00150 uint16_t payload_trans);
00151 static void USBH_enumeration_step7(void);
00152 static void USBH_enumeration_step8(void);
00153 static void USBH_enumeration_step9(void);
00154 static void USBH_enumeration_step10(
00155 USBHS_Add_t add,
00156 USBH_XfrStatus_t status,
00157 uint16_t payload_trans);
00158 static void USBH_enumeration_step11(void);
00159 static void USBH_enumeration_step12(
00160 USBHS_Add_t add,
00161 USBH_XfrStatus_t status,
00162 uint16_t payload_trans);
00163 static void USBH_enumeration_step13(
00164 USBHS_Add_t add,
00165 USBH_XfrStatus_t status,
00166 uint16_t payload_trans);
00167 static void USBH_enumeration_step14(
00168 USBHS_Add_t add,
00169 USBH_XfrStatus_t status,
00170 uint16_t payload_trans);
00171 static void USBH_enumeration_step15(
00172 USBHS_Add_t add,
00173 USBH_XfrStatus_t status,
00174 uint16_t payload_trans);
00175 #ifdef USB_HOST_LPM_SUPPORT
00176 static void USBH_enumeration_step16_lpm(void);
00177 static void USBH_enumeration_step17_lpm(
00178 USBHS_Add_t add,
00179 USBH_XfrStatus_t status,
00180 uint16_t payload_trans);
00181 #endif // USB_HOST_LPM_SUPPORT
00182 static void USBH_enumeration_error(USBH_enum_status_t status);
00183
00184
00185 static void USBH_remotewakeup(bool b_enable);
00186 static void USBH_setup_request_callback(
00187 USBHS_Add_t add,
00188 USBH_XfrStatus_t status,
00189 uint16_t payload_trans);
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 static void USBH_enable_timeout_callback(uint8_t timeout,
00200 USBH_sof_timeout_callback_t callback)
00201 {
00202 USBH_sof_timeout_callback = callback;
00203 USBH_sof_timeout = timeout;
00204 }
00205
00206
00207
00208
00209
00210 static void USBH_enumeration_suspend(void)
00211 {
00212 #ifdef USB_HOST_HUB_SUPPORT
00213
00214 if (&USBH_device_root != USBH_dev_enum) {
00215
00216 uhi_hub_suspend(USBH_dev_enum);
00217 } else
00218 #endif
00219 {
00220
00221 USBH_HAL_Suspend();
00222 }
00223 }
00224
00225
00226
00227
00228
00229
00230 static void USBH_enumeration_reset(uhd_callback_reset_t callback)
00231 {
00232
00233 #ifdef USB_HOST_HUB_SUPPORT
00234 if (&USBH_device_root != USBH_dev_enum) {
00235
00236 uhi_hub_send_reset(USBH_dev_enum, callback);
00237 } else
00238 #endif
00239 {
00240 USBH_HAL_Reset(callback);
00241 }
00242 }
00243
00244
00245
00246
00247
00248
00249
00250 static void USBH_connection_tree(bool b_plug, USBH_device_t *dev)
00251 {
00252 uint8_t i;
00253
00254 if (b_plug) {
00255 TRACE_INFO_WP("DevAdd ");
00256 USBH_enum_try = 1;
00257 #ifdef USB_HOST_HUB_SUPPORT
00258 USBH_dev_enum = dev;
00259 #endif
00260 USBH_dev_enum->conf_desc = NULL;
00261 USBH_dev_enum->address = 0;
00262 UHC_CONNECTION_EVENT(USBH_dev_enum, true);
00263 USBH_enumeration_step1();
00264 } else {
00265 TRACE_INFO_WP("DevRem");
00266
00267 if (USBH_dev_enum == dev) {
00268
00269 USBH_sof_timeout = 0;
00270 }
00271
00272
00273 USBH_HAL_FreePipe(dev->address, 0xFF);
00274
00275
00276 for (i = 0; i < UHC_NB_UHI; i++)
00277 USBH_uhis[i].uninstall(dev);
00278
00279 UHC_CONNECTION_EVENT(dev, false);
00280 dev->address = UHC_USB_ADD_NOT_VALID;
00281
00282
00283 if (dev->conf_desc != NULL)
00284 free(dev->conf_desc);
00285
00286 #ifdef USB_HOST_HUB_SUPPORT
00287 USBH_power_running -= dev->power;
00288
00289 if (&USBH_device_root != dev) {
00290
00291 dev->prev->next = dev->next;
00292 dev->next->prev = dev->prev;
00293 free(dev);
00294 }
00295
00296 #endif
00297 }
00298 }
00299
00300
00301
00302
00303
00304 static void USBH_enumeration_step1(void)
00305 {
00306 TRACE_INFO_WP("Enum1 ");
00307 USBH_enumeration_reset(USBH_enumeration_step2);
00308 }
00309
00310
00311
00312
00313
00314 static void USBH_enumeration_step2(void)
00315 {
00316 TRACE_INFO_WP("Enum2 ");
00317 USBH_enable_timeout_callback(20, USBH_enumeration_step3);
00318 }
00319
00320
00321
00322
00323
00324 static void USBH_enumeration_step3(void)
00325 {
00326 TRACE_INFO_WP("Enum3 ");
00327 USBH_enumeration_reset(USBH_enumeration_step4);
00328 }
00329
00330
00331
00332
00333
00334 static void USBH_enumeration_step4(void)
00335 {
00336 TRACE_INFO_WP("Enum4 ");
00337 USBH_dev_enum->speed = USBH_HAL_GetSpeed();
00338 USBH_enable_timeout_callback(100, USBH_enumeration_step5);
00339 }
00340
00341
00342
00343
00344
00345
00346
00347 static void USBH_enumeration_step5(void)
00348 {
00349 USBGenericRequest req;
00350 TRACE_INFO_WP("Enum5 ");
00351 req.bmRequestType = USB_REQ_RECIP_DEVICE | USB_REQ_TYPE_STANDARD |
00352 USB_REQ_DIR_IN;
00353 req.bRequest = USB_REQ_GET_DESCRIPTOR;
00354 req.wValue = (USBGenericDescriptor_DEVICE << 8);
00355 req.wIndex = 0;
00356 req.wLength = offsetof(USBH_device_t, dev_desc.bMaxPacketSize0)
00357 + sizeof(USBH_dev_enum->dev_desc.bMaxPacketSize0);
00358
00359
00360 USBH_HAL_FreePipe(0, 0);
00361
00362 if (!USBH_HAL_ConfigureControlPipe(0, 64)) {
00363 USBH_enumeration_error(UHC_ENUM_HARDWARE_LIMIT);
00364 return;
00365 }
00366
00367 if (!USBH_HAL_SetupReq(0,
00368 &req,
00369 (uint8_t *)&USBH_dev_enum->dev_desc,
00370 sizeof(USBDeviceDescriptor),
00371 NULL,
00372 USBH_enumeration_step6)) {
00373 USBH_enumeration_error(UHC_ENUM_MEMORY_LIMIT);
00374 return;
00375 }
00376 }
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 static void USBH_enumeration_step6(
00388 USBHS_Add_t add,
00389 USBH_XfrStatus_t status,
00390 uint16_t payload_trans)
00391 {
00392 UNUSED(add);
00393 TRACE_INFO_WP("Enum6 ");
00394
00395 if ((status != UHD_TRANS_NOERROR) || (payload_trans < 8)
00396 || (USBH_dev_enum->dev_desc.bDescriptorType != USBGenericDescriptor_DEVICE)) {
00397 USBH_enumeration_error((status == UHD_TRANS_DISCONNECT) ?
00398 UHC_ENUM_DISCONNECT : UHC_ENUM_FAIL);
00399 return;
00400 }
00401
00402
00403 USBH_enable_timeout_callback(20, USBH_enumeration_step7);
00404 }
00405
00406
00407
00408
00409
00410 static void USBH_enumeration_step7(void)
00411 {
00412 TRACE_INFO_WP("Enum7 ");
00413 USBH_enumeration_reset(USBH_enumeration_step8);
00414 }
00415
00416
00417
00418
00419
00420 static void USBH_enumeration_step8(void)
00421 {
00422
00423 TRACE_INFO_WP("Enum8 ");
00424 USBH_enable_timeout_callback(100, USBH_enumeration_step9);
00425 }
00426
00427
00428
00429
00430
00431 static void USBH_enumeration_step9(void)
00432 {
00433 USBGenericRequest req;
00434
00435 TRACE_INFO_WP("Enum9 ");
00436 req.bmRequestType = USB_REQ_RECIP_DEVICE
00437 | USB_REQ_TYPE_STANDARD | USB_REQ_DIR_OUT;
00438 req.bRequest = USB_REQ_SET_ADDRESS;
00439 #ifdef USB_HOST_HUB_SUPPORT
00440 uint8_t usb_addr_free = 0;
00441 USBH_device_t *dev;
00442
00443
00444 dev = &USBH_device_root;
00445
00446 while (usb_addr_free++) {
00447 if (dev->address == usb_addr_free)
00448 continue;
00449
00450 if (dev->next != NULL) {
00451 dev = dev->next;
00452 continue;
00453 }
00454
00455 break;
00456 }
00457
00458 req.wValue = usb_addr_free;
00459 USBH_dev_enum->address = usb_addr_free;
00460 #else
00461 req.wValue = UHC_DEVICE_ENUM_ADD;
00462 USBH_dev_enum->address = UHC_DEVICE_ENUM_ADD;
00463 #endif
00464 req.wIndex = 0;
00465 req.wLength = 0;
00466
00467
00468 USBH_HAL_FreePipe(0, 0);
00469
00470 if (!USBH_HAL_ConfigureControlPipe(0,
00471 USBH_dev_enum->dev_desc.bMaxPacketSize0)) {
00472 USBH_enumeration_error(UHC_ENUM_HARDWARE_LIMIT);
00473 return;
00474 }
00475
00476 if (!USBH_HAL_SetupReq(0,
00477 &req,
00478 (uint8_t *)&USBH_dev_enum->dev_desc,
00479 sizeof(USBDeviceDescriptor),
00480 NULL,
00481 USBH_enumeration_step10)) {
00482 USBH_enumeration_error(UHC_ENUM_MEMORY_LIMIT);
00483 return;
00484 }
00485 }
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496 static void USBH_enumeration_step10(
00497 USBHS_Add_t add,
00498 USBH_XfrStatus_t status,
00499 uint16_t payload_trans)
00500 {
00501 UNUSED(add);
00502 UNUSED(payload_trans);
00503 TRACE_INFO_WP("Enum10 ");
00504
00505 if (status != UHD_TRANS_NOERROR) {
00506 USBH_enumeration_error((status == UHD_TRANS_DISCONNECT) ?
00507 UHC_ENUM_DISCONNECT : UHC_ENUM_FAIL);
00508 return;
00509 }
00510
00511
00512 USBH_enable_timeout_callback(20, USBH_enumeration_step11);
00513 }
00514
00515
00516
00517
00518
00519
00520 static void USBH_enumeration_step11(void)
00521 {
00522 USBGenericRequest req;
00523
00524 TRACE_INFO_WP("Enum11 ");
00525
00526 USBH_HAL_FreePipe(0, 0);
00527
00528
00529 if (!USBH_HAL_ConfigureControlPipe(UHC_DEVICE_ENUM_ADD,
00530 USBH_dev_enum->dev_desc.bMaxPacketSize0)) {
00531 USBH_enumeration_error(UHC_ENUM_HARDWARE_LIMIT);
00532 return;
00533 }
00534
00535
00536 req.bmRequestType = USB_REQ_RECIP_DEVICE | USB_REQ_TYPE_STANDARD |
00537 USB_REQ_DIR_IN;
00538 req.bRequest = USB_REQ_GET_DESCRIPTOR;
00539 req.wValue = (USBGenericDescriptor_DEVICE << 8);
00540 req.wIndex = 0;
00541 req.wLength = sizeof(USBDeviceDescriptor);
00542
00543 if (!USBH_HAL_SetupReq(UHC_DEVICE_ENUM_ADD,
00544 &req,
00545 (uint8_t *) & USBH_dev_enum->dev_desc,
00546 sizeof(USBDeviceDescriptor),
00547 NULL, USBH_enumeration_step12)) {
00548 USBH_enumeration_error(UHC_ENUM_MEMORY_LIMIT);
00549 return;
00550 }
00551 }
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561 static void USBH_enumeration_step12(
00562 USBHS_Add_t add,
00563 USBH_XfrStatus_t status,
00564 uint16_t payload_trans)
00565 {
00566 USBGenericRequest req;
00567 uint8_t conf_num;
00568 UNUSED(add);
00569
00570 TRACE_INFO_WP("Enum12 ");
00571
00572 if ((status != UHD_TRANS_NOERROR)
00573 || (payload_trans != sizeof(USBDeviceDescriptor))
00574 || (USBH_dev_enum->dev_desc.bDescriptorType != USBGenericDescriptor_DEVICE)) {
00575 USBH_enumeration_error((status == UHD_TRANS_DISCONNECT) ?
00576 UHC_ENUM_DISCONNECT : UHC_ENUM_FAIL);
00577 return;
00578 }
00579
00580
00581 if (USBH_dev_enum->dev_desc.bNumConfigurations > 1)
00582 conf_num = UHC_DEVICE_CONF(USBH_dev_enum);
00583 else
00584 conf_num = 1;
00585
00586 USBH_dev_enum->conf_desc = malloc(sizeof(USBConfigurationDescriptor));
00587
00588 if (USBH_dev_enum->conf_desc == NULL) {
00589 assert(false);
00590 USBH_enumeration_error(UHC_ENUM_MEMORY_LIMIT);
00591 return;
00592 }
00593
00594
00595 req.bmRequestType = USB_REQ_RECIP_DEVICE | USB_REQ_TYPE_STANDARD |
00596 USB_REQ_DIR_IN;
00597 req.bRequest = USB_REQ_GET_DESCRIPTOR;
00598 req.wValue = (USBGenericDescriptor_CONFIGURATION << 8) | (conf_num - 1);
00599 req.wIndex = 0;
00600 req.wLength = sizeof(USBConfigurationDescriptor);
00601
00602 if (!USBH_HAL_SetupReq(UHC_DEVICE_ENUM_ADD,
00603 &req,
00604 (uint8_t *) USBH_dev_enum->conf_desc,
00605 sizeof(USBConfigurationDescriptor),
00606 NULL, USBH_enumeration_step13)) {
00607 USBH_enumeration_error(UHC_ENUM_MEMORY_LIMIT);
00608 return;
00609 }
00610 }
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620 static void USBH_enumeration_step13(
00621 USBHS_Add_t add,
00622 USBH_XfrStatus_t status,
00623 uint16_t payload_trans)
00624 {
00625 uint8_t conf_num;
00626 uint16_t conf_size;
00627 uint16_t bus_power = 0;
00628 USBGenericRequest req;
00629 UNUSED(add);
00630
00631 TRACE_INFO_WP("Enum13 ");
00632
00633 if ((status != UHD_TRANS_NOERROR)
00634 || (payload_trans != sizeof(USBConfigurationDescriptor))
00635 || (USBH_dev_enum->conf_desc->bDescriptorType !=
00636 USBGenericDescriptor_CONFIGURATION)) {
00637 USBH_enumeration_error((status == UHD_TRANS_DISCONNECT) ?
00638 UHC_ENUM_DISCONNECT : UHC_ENUM_FAIL);
00639 return;
00640 }
00641
00642 #ifdef USB_HOST_HUB_SUPPORT
00643 USBH_device_t *dev;
00644 dev = USBH_dev_enum;
00645
00646 while (1) {
00647 if (dev->conf_desc->bmAttributes & USB_CONFIG_ATTR_SELF_POWERED) {
00648
00649 break;
00650 }
00651
00652 if (dev == (&USBH_device_root)) {
00653 bus_power = USBH_dev_enum->conf_desc->bMaxPower * 2;
00654 break;
00655 }
00656
00657
00658 dev = dev->hub;
00659 }
00660
00661 #else
00662
00663 if (!(USBH_dev_enum->conf_desc->bmAttributes
00664 &USBConfigurationDescriptor_SELFPOWERED_NORWAKEUP))
00665 bus_power = USBH_dev_enum->conf_desc->bMaxPower * 2;
00666
00667 #endif
00668
00669 if ((bus_power + USBH_power_running) > USB_HOST_POWER_MAX) {
00670
00671 UHC_ENUM_EVENT(USBH_dev_enum, UHC_ENUM_OVERCURRENT);
00672
00673
00674 USBH_enumeration_suspend();
00675 return;
00676 }
00677
00678 #ifdef USB_HOST_HUB_SUPPORT
00679 USBH_dev_enum->power = bus_power;
00680 USBH_power_running += bus_power;
00681 #endif
00682
00683
00684 conf_size = (USBH_dev_enum->conf_desc->wTotalLength);
00685 conf_num = USBH_dev_enum->conf_desc->bConfigurationValue;
00686 assert(conf_num);
00687
00688 free(USBH_dev_enum->conf_desc);
00689 USBH_dev_enum->conf_desc = malloc(conf_size);
00690
00691 if (USBH_dev_enum->conf_desc == NULL) {
00692 assert(false);
00693 USBH_enumeration_error(UHC_ENUM_MEMORY_LIMIT);
00694 return;
00695 }
00696
00697
00698 req.bmRequestType =
00699 USB_REQ_RECIP_DEVICE | USB_REQ_TYPE_STANDARD |
00700 USB_REQ_DIR_IN;
00701 req.bRequest = USB_REQ_GET_DESCRIPTOR;
00702 req.wValue = (USBGenericDescriptor_CONFIGURATION << 8) | (conf_num - 1);
00703 req.wIndex = 0;
00704 req.wLength = conf_size;
00705
00706 if (!USBH_HAL_SetupReq(UHC_DEVICE_ENUM_ADD,
00707 &req,
00708 (uint8_t *) USBH_dev_enum->conf_desc,
00709 conf_size,
00710 NULL, USBH_enumeration_step14)) {
00711 USBH_enumeration_error(UHC_ENUM_MEMORY_LIMIT);
00712 return;
00713 }
00714 }
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724 static void USBH_enumeration_step14(
00725 USBHS_Add_t add,
00726 USBH_XfrStatus_t status,
00727 uint16_t payload_trans)
00728 {
00729 USBGenericRequest req;
00730 uint8_t i;
00731 bool b_conf_supported = false;
00732 UNUSED(add);
00733
00734 TRACE_INFO_WP("Enum14 ");
00735
00736 if ((status != UHD_TRANS_NOERROR)
00737 || (payload_trans < sizeof(USBConfigurationDescriptor))
00738 || (USBH_dev_enum->conf_desc->bDescriptorType !=
00739 USBGenericDescriptor_CONFIGURATION)
00740 || (payload_trans != (USBH_dev_enum->conf_desc->wTotalLength))) {
00741 USBH_enumeration_error((status == UHD_TRANS_DISCONNECT) ?
00742 UHC_ENUM_DISCONNECT : UHC_ENUM_FAIL);
00743 return;
00744 }
00745
00746
00747 for (i = 0; i < UHC_NB_UHI; i++) {
00748 switch (USBH_uhis[i].install(USBH_dev_enum)) {
00749 case UHC_ENUM_SUCCESS:
00750 TRACE_INFO("Device Driver installed");
00751 b_conf_supported = true;
00752 break;
00753
00754 case UHC_ENUM_UNSUPPORTED:
00755 TRACE_INFO(" \n\rUnsupported Device");
00756 TRACE_INFO(" \n\rRestarting enumeration");
00757 break;
00758
00759 default:
00760
00761
00762 USBH_HAL_FreePipe(UHC_DEVICE_ENUM_ADD, 0xFF);
00763 UHC_ENUM_EVENT(USBH_dev_enum, UHC_ENUM_HARDWARE_LIMIT);
00764
00765
00766 USBH_enumeration_suspend();
00767 return;
00768 }
00769 }
00770
00771 if (!b_conf_supported) {
00772
00773 UHC_ENUM_EVENT(USBH_dev_enum, UHC_ENUM_UNSUPPORTED);
00774
00775
00776 USBH_enumeration_suspend();
00777 return;
00778 }
00779
00780
00781 req.bmRequestType = USB_REQ_RECIP_DEVICE
00782 | USB_REQ_TYPE_STANDARD | USB_REQ_DIR_OUT;
00783 req.bRequest = USB_REQ_SET_CONFIGURATION;
00784 req.wValue = USBH_dev_enum->conf_desc->bConfigurationValue;
00785 req.wIndex = 0;
00786 req.wLength = 0;
00787
00788 if (!USBH_HAL_SetupReq(UHC_DEVICE_ENUM_ADD,
00789 &req,
00790 NULL,
00791 0,
00792 NULL, USBH_enumeration_step15)) {
00793 USBH_enumeration_error(UHC_ENUM_MEMORY_LIMIT);
00794 return;
00795 }
00796 }
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806 static void USBH_enumeration_step15(
00807 USBHS_Add_t add,
00808 USBH_XfrStatus_t status,
00809 uint16_t payload_trans)
00810 {
00811 UNUSED(add);
00812 uint8_t i;
00813 TRACE_INFO_WP("Enum15 ");
00814
00815 if ((status != UHD_TRANS_NOERROR) || (payload_trans != 0)) {
00816 for (i = 0; i < UHC_NB_UHI; i++)
00817 USBH_uhis[i].uninstall(USBH_dev_enum);
00818
00819 USBH_enumeration_error((status == UHD_TRANS_DISCONNECT) ?
00820 UHC_ENUM_DISCONNECT : UHC_ENUM_FAIL);
00821 return;
00822 }
00823
00824
00825 for (i = 0; i < UHC_NB_UHI; i++)
00826 USBH_uhis[i].enable(USBH_dev_enum);
00827
00828 #ifdef USB_HOST_LPM_SUPPORT
00829
00830
00831 if (USBH_device_root.dev_desc.bcdUSB >= (USBDeviceDescriptor_USB2_00)) {
00832
00833
00834 USBH_enumeration_step16_lpm();
00835 return;
00836 }
00837
00838 USBH_dev_enum->lpm_desc = NULL;
00839 #endif
00840
00841 USBH_enum_try = 0;
00842
00843 UHC_ENUM_EVENT(USBH_dev_enum, UHC_ENUM_SUCCESS);
00844 }
00845
00846 #ifdef USB_HOST_LPM_SUPPORT
00847
00848
00849
00850
00851 static void USBH_enumeration_step16_lpm(void)
00852 {
00853 USBGenericRequest req;
00854
00855 TRACE_INFO_WP("Enum16_lpm");
00856 USBH_dev_enum->lpm_desc = malloc(sizeof(USB_DeviceLPMDescriptor));
00857
00858 if (USBH_dev_enum->lpm_desc == NULL) {
00859 assert(false);
00860 USBH_enumeration_error(UHC_ENUM_MEMORY_LIMIT);
00861 return;
00862 }
00863
00864
00865 req.bmRequestType = USB_REQ_RECIP_DEVICE | USB_REQ_TYPE_STANDARD |
00866 USB_REQ_DIR_IN;
00867 req.bRequest = USB_REQ_GET_DESCRIPTOR;
00868 req.wValue = USB_DT_BOS << 8;
00869 req.wIndex = 0;
00870 req.wLength = sizeof(USB_DeviceLPMDescriptor);
00871
00872 if (!USBH_HAL_SetupReq(UHC_DEVICE_ENUM_ADD,
00873 &req,
00874 (uint8_t *) USBH_dev_enum->lpm_desc,
00875 sizeof(USB_DeviceLPMDescriptor),
00876 NULL, USBH_enumeration_step17_lpm)) {
00877 USBH_enumeration_error(UHC_ENUM_MEMORY_LIMIT);
00878 return;
00879 }
00880 }
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890 static void USBH_enumeration_step17_lpm(
00891 USBHS_Add_t add,
00892 USBH_XfrStatus_t status,
00893 uint16_t payload_trans)
00894 {
00895 UNUSED(add);
00896
00897 TRACE_INFO_WP("Enum17_lpm ");
00898
00899 if (status == UHD_TRANS_STALL) {
00900 free(USBH_dev_enum->lpm_desc);
00901 USBH_dev_enum->lpm_desc = NULL;
00902 } else if ((status != UHD_TRANS_NOERROR)
00903 || (payload_trans < sizeof(USB_DeviceLPMDescriptor))
00904 || (USBH_dev_enum->lpm_desc->bos.bDescriptorType != USB_DT_BOS)
00905 || (payload_trans != (USBH_dev_enum->lpm_desc->bos.wTotalLength))) {
00906 USBH_enumeration_error((status == UHD_TRANS_DISCONNECT) ?
00907 UHC_ENUM_DISCONNECT : UHC_ENUM_FAIL);
00908 return;
00909 } else if (status == UHD_TRANS_NOERROR) {
00910
00911 if ((USBH_dev_enum->lpm_desc->capa_ext.bDescriptorType !=
00912 USBGenericDescriptor_DEVICE_CAPABILITY)
00913 || (USBH_dev_enum->lpm_desc->capa_ext.bDevCapabilityType !=
00914 USB_DC_USB20_EXTENSION)
00915 || (!(USBH_dev_enum->lpm_desc->capa_ext.bmAttributes & (USB_DC_EXT_LPM)))) {
00916 free(USBH_dev_enum->lpm_desc);
00917 USBH_dev_enum->lpm_desc = NULL;
00918 }
00919 }
00920
00921 USBH_enum_try = 0;
00922 UHC_ENUM_EVENT(USBH_dev_enum, UHC_ENUM_SUCCESS);
00923 }
00924 #endif // USB_HOST_LPM_SUPPORT
00925
00926
00927
00928
00929
00930
00931 static void USBH_enumeration_error(USBH_enum_status_t status)
00932 {
00933 if (status == UHC_ENUM_DISCONNECT) {
00934 USBH_enum_try = 0;
00935 TRACE_INFO_WP("Enum_Abort ");
00936 return;
00937 }
00938
00939 USBH_HAL_FreePipe(USBH_dev_enum->address, 0xFF);
00940
00941
00942 if (USBH_dev_enum->conf_desc != NULL) {
00943 free(USBH_dev_enum->conf_desc);
00944 USBH_dev_enum->conf_desc = NULL;
00945 }
00946
00947 USBH_dev_enum->address = 0;
00948
00949 if (USBH_enum_try++ < UHC_ENUM_NB_TRY) {
00950
00951 USBH_enumeration_step1();
00952 return;
00953 }
00954
00955
00956 USBH_enumeration_suspend();
00957 UHC_ENUM_EVENT(USBH_dev_enum, status);
00958 USBH_enum_try = 0;
00959 }
00960
00961
00962
00963
00964
00965
00966
00967 static void USBH_remotewakeup(bool b_enable)
00968 {
00969 USBGenericRequest req;
00970 USBH_device_t *dev;
00971
00972 dev = &USBH_device_root;
00973
00974 while (1) {
00975 if (dev->conf_desc->bmAttributes & USBConfigurationDescriptor_REMOTE_WAKEUP) {
00976 if (b_enable)
00977 req.bRequest = USB_REQ_SET_FEATURE;
00978 else
00979 req.bRequest = USB_REQ_CLEAR_FEATURE;
00980
00981 req.bmRequestType = USB_REQ_RECIP_DEVICE
00982 | USB_REQ_TYPE_STANDARD | USB_REQ_DIR_OUT;
00983 req.wValue = USB_DEV_FEATURE_REMOTE_WAKEUP;
00984 req.wIndex = 0;
00985 req.wLength = 0;
00986 USBH_HAL_SetupReq(dev->address, &req, NULL, 0, NULL, NULL);
00987 }
00988
00989 #ifdef USB_HOST_HUB_SUPPORT
00990
00991 if (dev->next == NULL)
00992 break;
00993
00994 dev = dev->next;
00995 #else
00996 break;
00997 #endif
00998 }
00999 }
01000
01001
01002
01003
01004
01005
01006
01007
01008 static void USBH_setup_request_callback(
01009 USBHS_Add_t add,
01010 USBH_XfrStatus_t status,
01011 uint16_t payload_trans)
01012 {
01013 UNUSED(add);
01014 UNUSED(payload_trans);
01015 USBH_setup_request_finish_status = (status == UHD_TRANS_NOERROR);
01016 USBH_setup_request_finish = true;
01017 }
01018
01019
01020
01021
01022
01023
01024 void USBH_notify_connection(bool b_plug)
01025 {
01026 if (b_plug) {
01027 assert(USBH_device_root.address == UHC_USB_ADD_NOT_VALID);
01028
01029 #ifdef USB_HOST_HUB_SUPPORT
01030 USBH_power_running = 0;
01031 #endif
01032 } else {
01033 if (USBH_device_root.address == UHC_USB_ADD_NOT_VALID) {
01034
01035
01036 return;
01037 }
01038 }
01039
01040
01041 USBH_connection_tree(b_plug, &USBH_device_root);
01042 }
01043
01044 void USBH_notify_sof(bool b_micro)
01045 {
01046
01047 uint8_t i;
01048
01049 for (i = 0; i < UHC_NB_UHI; i++) {
01050 if (USBH_uhis[i].sof_notify != NULL)
01051 USBH_uhis[i].sof_notify(b_micro);
01052 }
01053
01054 if (!b_micro) {
01055
01056 if (USBH_sof_timeout) {
01057 if (--USBH_sof_timeout == 0)
01058 USBH_sof_timeout_callback();
01059 }
01060 }
01061 }
01062
01063 void USBH_notify_resume(void)
01064 {
01065 USBH_remotewakeup(false);
01066 UHC_WAKEUP_EVENT();
01067 }
01068
01069 #ifdef USB_HOST_LPM_SUPPORT
01070 void USBH_notify_resume_lpm(void)
01071 {
01072 UHC_WAKEUP_EVENT();
01073 }
01074 #endif
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084 void USBH_start(void)
01085 {
01086 USBH_device_root.address = UHC_USB_ADD_NOT_VALID;
01087 USBH_sof_timeout = 0;
01088 USBH_HAL_EnableUsbHost();
01089 }
01090
01091 void USBH_stop(bool b_id_stop)
01092 {
01093
01094 USBH_HAL_DisableUsb(b_id_stop);
01095 }
01096
01097 void USBH_suspend(bool b_remotewakeup)
01098 {
01099 if (USBH_enum_try) {
01100
01101 return;
01102 }
01103
01104 if (b_remotewakeup)
01105 USBH_remotewakeup(true);
01106
01107
01108 USBH_HAL_Suspend();
01109 }
01110
01111 bool USBH_is_suspend(void)
01112 {
01113 if (USBH_device_root.address == UHC_USB_ADD_NOT_VALID)
01114 return true;
01115
01116 return USBH_HAL_IsSuspended();
01117 }
01118
01119 void USBH_resume(void)
01120 {
01121 if (!USBH_is_suspend())
01122 return;
01123
01124
01125 USBH_HAL_Resume();
01126 }
01127
01128 #ifdef USB_HOST_LPM_SUPPORT
01129 bool USBH_suspend_lpm(bool b_remotewakeup, uint8_t besl)
01130 {
01131 if (USBH_enum_try) {
01132
01133 return false;
01134 }
01135
01136
01137 if (USBH_dev_enum->lpm_desc == NULL) {
01138
01139 return false;
01140 }
01141
01142
01143 return uhd_suspend_lpm(b_remotewakeup, besl);
01144 }
01145 #endif // USB_HOST_LPM_SUPPORT
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155 uint8_t USBH_get_device_number(void)
01156 {
01157 #ifdef USB_HOST_HUB_SUPPORT
01158 uint8_t nb_dev = 0;
01159 USBH_device_t *dev;
01160
01161 if (USBH_device_root.address != UHC_USB_ADD_NOT_VALID) {
01162 dev = &USBH_device_root;
01163
01164 while (nb_dev++) {
01165 if (dev->next == NULL)
01166 break;
01167
01168 dev = dev->next;
01169 }
01170 }
01171
01172 return nb_dev;
01173 #else
01174 return (USBH_device_root.address != UHC_USB_ADD_NOT_VALID) ? 1 : 0;
01175 #endif
01176 }
01177
01178 char *USBH_dev_get_string_manufacturer(USBH_device_t *dev)
01179 {
01180 if (!dev->dev_desc.iManufacturer) {
01181 return NULL;
01182 }
01183
01184 return USBH_dev_get_string(dev, dev->dev_desc.iManufacturer);
01185 }
01186
01187 char *USBH_dev_get_string_product(USBH_device_t *dev)
01188 {
01189 if (!dev->dev_desc.iProduct) {
01190 return NULL;
01191 }
01192
01193 return USBH_dev_get_string(dev, dev->dev_desc.iProduct);
01194 }
01195
01196 char *USBH_dev_get_string_serial(USBH_device_t *dev)
01197 {
01198 if (!dev->dev_desc.iSerialNumber) {
01199 return NULL;
01200 }
01201
01202 return USBH_dev_get_string(dev, dev->dev_desc.iSerialNumber);
01203 }
01204
01205 char *USBH_dev_get_string(USBH_device_t *dev, uint8_t str_id)
01206 {
01207 USBGenericRequest req;
01208 USBStringDescriptor str_header;
01209 USBStringLangIdDescriptor *str_desc;
01210 char *string;
01211 uint8_t i;
01212 UNUSED(dev);
01213
01214 req.bmRequestType = USB_REQ_RECIP_DEVICE | USB_REQ_TYPE_STANDARD |
01215 USB_REQ_DIR_IN;
01216 req.bRequest = USB_REQ_GET_DESCRIPTOR;
01217 req.wValue = (USBGenericDescriptor_STRING << 8) | str_id;
01218 req.wIndex = 0;
01219 req.wLength = sizeof(USBStringDescriptor);
01220
01221
01222 USBH_setup_request_finish = false;
01223
01224 if (!USBH_HAL_SetupReq(0,
01225 &req,
01226 (uint8_t *)&str_header,
01227 sizeof(USBStringDescriptor),
01228 NULL,
01229 USBH_setup_request_callback))
01230 return NULL;
01231
01232 while (!USBH_setup_request_finish);
01233
01234 if (!USBH_setup_request_finish_status)
01235 return NULL;
01236
01237
01238 str_desc = malloc(str_header.bLength);
01239
01240 if (str_desc == NULL)
01241 return NULL;
01242
01243 req.wLength = str_header.bLength;
01244 USBH_setup_request_finish = false;
01245
01246 if (!USBH_HAL_SetupReq(0,
01247 &req,
01248 (uint8_t *)str_desc,
01249 str_header.bLength,
01250 NULL,
01251 USBH_setup_request_callback))
01252 return NULL;
01253
01254 while (!USBH_setup_request_finish);
01255
01256 if (!USBH_setup_request_finish_status) {
01257 free(str_desc);
01258 return NULL;
01259 }
01260
01261
01262 str_header.bLength = (str_header.bLength - 2) / 2;
01263 string = malloc(str_header.bLength + 1);
01264
01265 if (string == NULL) {
01266 free(str_desc);
01267 return NULL;
01268 }
01269
01270 for (i = 0; i < str_header.bLength; i++)
01271 string[i] = (str_desc->string[i]) & 0xFF;
01272
01273 string[i] = 0;
01274 free(str_desc);
01275
01276 return string;
01277 }
01278
01279 uint16_t USBH_dev_get_power(USBH_device_t *dev)
01280 {
01281 return dev->conf_desc->bMaxPower * 2;
01282 }
01283
01284 USBH_Speed_t USBH_dev_get_speed(USBH_device_t *dev)
01285 {
01286 return dev->speed;
01287 }
01288
01289 bool USBH_dev_is_high_speed_support(USBH_device_t *dev)
01290 {
01291 USBGenericRequest req;
01292 USBDeviceQualifierDescriptor qualifier;
01293
01294 if (dev->speed == UHD_SPEED_HIGH)
01295 return true;
01296
01297 if (dev->speed == UHD_SPEED_FULL) {
01298 req.bmRequestType = USB_REQ_RECIP_DEVICE
01299 | USB_REQ_TYPE_STANDARD | USB_REQ_DIR_IN;
01300 req.bRequest = USB_REQ_GET_DESCRIPTOR;
01301 req.wValue = (USBGenericDescriptor_DEVICEQUALIFIER << 8);
01302 req.wIndex = 0;
01303 req.wLength = sizeof(qualifier);
01304
01305
01306 USBH_setup_request_finish = false;
01307
01308 if (!USBH_HAL_SetupReq(0,
01309 &req,
01310 (uint8_t *)&qualifier,
01311 sizeof(qualifier),
01312 NULL,
01313 USBH_setup_request_callback))
01314 return NULL;
01315
01316 while (!USBH_setup_request_finish);
01317
01318 return USBH_setup_request_finish_status;
01319 }
01320
01321 return false;
01322 }
01323
01324
01325
01326
01327
01328 void USBHS_SCB_CleanDCache_by_Addr(uint32_t *addr, int32_t dsize)
01329 {
01330 uint32_t *pTemp;
01331
01332 if ((uint32_t)addr % 32 == 0)
01333 pTemp = addr;
01334 else
01335 pTemp = (uint32_t *)(((uint32_t)addr) & (uint32_t)(~(32 - 1)));
01336
01337 SCB_CleanDCache_by_Addr(pTemp, dsize);
01338 }
01339
01340
01341
01342
01343 void USBHS_SCB_InvalidateDCache_by_Addr(uint32_t *addr, int32_t dsize)
01344 {
01345 uint32_t *pTemp;
01346
01347 if ((uint32_t)addr % 32 == 0)
01348 pTemp = addr;
01349 else
01350 pTemp = (uint32_t *)(((uint32_t)addr) & (uint32_t)(~(32 - 1)));
01351
01352 SCB_InvalidateDCache_by_Addr(pTemp, dsize);
01353 }
01354
01355
01356
01357