/** * \brief Device enumeration step 5 * Requests the USB device descriptor. * This setup request can be aborted * because the control endpoint size is unknown. */ static void uhc_enumeration_step5(void) { usb_setup_req_t req; req.bmRequestType = USB_REQ_RECIP_DEVICE|USB_REQ_TYPE_STANDARD|USB_REQ_DIR_IN; req.bRequest = USB_REQ_GET_DESCRIPTOR; req.wValue = (USB_DT_DEVICE << 8); req.wIndex = 0; req.wLength = offsetof(uhc_device_t, dev_desc.bMaxPacketSize0) + sizeof(uhc_dev_enum->dev_desc.bMaxPacketSize0); // After a USB reset, the reallocation is required uhd_ep_free(0, 0); if (!uhd_ep0_alloc(0, 64)) { uhc_enumeration_error(UHC_ENUM_HARDWARE_LIMIT); return; } if (!uhd_setup_request(0, &req, (uint8_t*)&uhc_dev_enum->dev_desc, sizeof(usb_dev_desc_t), NULL, uhc_enumeration_step6)) { uhc_enumeration_error(UHC_ENUM_MEMORY_LIMIT); return; } }
/** * \brief Device enumeration step 11 * Updates USB host pipe with the new USB address. * Requests a complete USB device descriptor. */ static void uhc_enumeration_step11(void) { usb_setup_req_t req; // Free address 0 used to start enumeration uhd_ep_free(0, 0); // Alloc control endpoint with the new USB address if (!uhd_ep0_alloc(UHC_DEVICE_ENUM_ADD, uhc_dev_enum->dev_desc.bMaxPacketSize0)) { uhc_enumeration_error(UHC_ENUM_HARDWARE_LIMIT); return; } // Send USB device descriptor request req.bmRequestType = USB_REQ_RECIP_DEVICE|USB_REQ_TYPE_STANDARD|USB_REQ_DIR_IN; req.bRequest = USB_REQ_GET_DESCRIPTOR; req.wValue = (USB_DT_DEVICE << 8); req.wIndex = 0; req.wLength = sizeof(usb_dev_desc_t); if (!uhd_setup_request(UHC_DEVICE_ENUM_ADD, &req, (uint8_t *) & uhc_dev_enum->dev_desc, sizeof(usb_dev_desc_t), NULL, uhc_enumeration_step12)) { uhc_enumeration_error(UHC_ENUM_MEMORY_LIMIT); return; } }
/** * \brief Device enumeration step 9 * Send a Set address setup request. */ static void uhc_enumeration_step9(void) { usb_setup_req_t req; req.bmRequestType = USB_REQ_RECIP_DEVICE | USB_REQ_TYPE_STANDARD | USB_REQ_DIR_OUT; req.bRequest = USB_REQ_SET_ADDRESS; #ifdef USB_HOST_HUB_SUPPORT uint8_t usb_addr_free = 0; uhc_device_t *dev; // Search free address dev = &g_uhc_device_root; while (usb_addr_free++) { if (dev->address == usb_addr_free) { continue; } if (dev->next != NULL) { dev = dev->next; continue; } break; } req.wValue = usb_addr_free; uhc_dev_enum->address = usb_addr_free; #else req.wValue = UHC_DEVICE_ENUM_ADD; uhc_dev_enum->address = UHC_DEVICE_ENUM_ADD; #endif req.wIndex = 0; req.wLength = 0; // After a USB reset, the reallocation is required uhd_ep_free(0, 0); if (!uhd_ep0_alloc(0, uhc_dev_enum->dev_desc.bMaxPacketSize0)) { uhc_enumeration_error(UHC_ENUM_HARDWARE_LIMIT); return; } if (!uhd_setup_request(0, &req, (uint8_t*)&uhc_dev_enum->dev_desc, sizeof(usb_dev_desc_t), NULL, uhc_enumeration_step10)) { uhc_enumeration_error(UHC_ENUM_MEMORY_LIMIT); return; } }