cancel
Showing results for 
Search instead for 
Did you mean: 

Wrong wLength during USB enumeration

colin0325
Associate II

I am trying to perform USB enumeration on an STM32H503.  I am using HAL_PCD_SetupStageCallback inside of the USB interrupt, which is working perfectly: when I plug in the USB cable to the Nucleo board, the interrupt triggers and I can see that the callback is executing.  One thing that doesn't make sense is that the wLength field is always 0x8408 = 33800.  One would expect the field to be 0x12 = 18 for a GET_DESCRIPTOR command, but it's always 33800.  I don't think the host is the problem - it's a typical Ubuntu PC that has worked with plenty of other USB devices in the past - but I'm having a hard time seeing where there might be a problem in the code.  (The cast from hpcd->Setup to USB_SetupTypeDef isn't the problem, in the debugger window I can see that all fields except wLength are exactly as expected, and that 0x8408 is in the hpcd->Setup array as well.)

void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) {
    USB_SetupTypeDef *setup = (USB_SetupTypeDef *)hpcd->Setup;

    if (setup->bRequest == USB_REQ_GET_DESCRIPTOR) {
		if (setup->wValue >> 8 == USB_DESC_TYPE_DEVICE) {
			// this happens twice, always with setup->wLength == 33800
			send_control_data(device_descriptor, 18);
		}
		else if (setup->wValue >> 8 == USB_DESC_TYPE_CONFIGURATION) {
			// never gets here
		}
		else if (setup->wValue >> 8 == USB_DESC_TYPE_STRING) {
			// never gets here
		}
		else {
			stall_ep0();
		}
    }
	else if (setup->bRequest == USB_REQ_SET_CONFIGURATION) {
		// Accept configuration, no special action needed here
		send_control_data(NULL, 0);
	}
	else {
		stall_ep0();
    }
}

static void send_control_data(uint8_t *buf, uint16_t len) {
    if (len == 0) {
        // I have tried with both 0x80 and 0x00 endpoints
        HAL_PCD_EP_Transmit(&hpcd_USB_DRD_FS, 0x00, NULL, 0); // Status stage
    } else {
        HAL_PCD_EP_Transmit(&hpcd_USB_DRD_FS, 0x00, buf, len);
    }
}

 

0 REPLIES 0