2025-07-31 4:01 AM
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);
}
}
2025-08-01 8:43 AM
Hi @colin0325
Did you refer to the example provided in CubeH5? The code example is your own implementation ?
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2025-08-02 6:26 AM
The endinanness was my first instinct as well, but I went through the actual received binary and compared it to the output structure. Everything except the wLength is correct, and none of the bytes in the binary are 0x12, so even if it were in the wrong order, the correct wLength value is nowhere to be found.
2025-08-02 6:28 AM
No, the instructions for generating the middleware are all out of date, and I'd rather have code that I actually understand anyway.
2025-08-04 6:11 AM
Hi @colin0325
At this level, you can't be sure. If your custom HAL-based code casts hpcd->Setup directly to a struct without packing, you risk misinterpreting fields like wLength. Maybe if you define your USB_SetupTypeDef struct with the packed attribute to prevent padding issues.
Typically, USBX parses the setup packet fields: byte-by-byte from the raw buffer, not relying on direct struct casting. This prevents padding or alignment problems.
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.