2022-08-25 08:51 PM
MCU: STMF32F401CCU6
On a Black pill board.
STM32CubeIDE
Version: 1.10.1
Build: 12716_20220707_0928 (UTC)
OS: Linux, v.5.15.0-46-lowlatency, x86_64 / gtk 3.24.33
Java vendor: Eclipse Adoptium
Java runtime version: 11.0.14.1+1
Java version: 11.0.14.1
Ubuntu 22.04.01
The device code is based on the CDC class
The device is just plugged in, no drivers are using it. After plugging in the device Linux transacted the the address (0x05) and configure (0x09) and retreved the string descriptors successfully.
No drivers are install as the class in not CDC but a custom class.
Using (linux) Libusb function (written in C code) to retrieve an class specific intetrface descriptor. Type:0x81 Request 0x06, Value:0x2601 . This fails
Added debug code in USBD_StatusTypeDef USBD_LL_SetupStage in usbdcore.c. All seems fine and this function is reached for retrieving device descriptor, serialnumber etc.. (request type 0x80). (See tranasctions below)
When making a USB transfer with bRequestType 0x81 or 0x82 (interface or endpoint ) This function is not called. Example: Type:0x81 Request 0x06, Value:0x2601.
Libusb return an error -1: Input/Output Error
When changing this call to retrieve a device descritpor: Type:0x80 Request 0x06, Value:0x2601 the USBD_LL_SetupStage function is reached.
Any hints how to debug the HAL code why this is ?
Trying to figure out if this is due to uslib or the HAL code.
Per UM1734 p 17 :Most of the requests specified in Table 4 of the USB specification are handled as standard requests in the library. Table 4 lists all the standard requests and their valid parameters in
the library. Requests that are not in Table 4 are considered as non-standard requests.
Thus: it states that CONFIGURATION 0x80 are standard, As such 0x81 is non standard,
The library passes all the non-standard requests to the class-specific code with the
callback pdev->pClass->Setup (pdev, req) function. user code is responsible, in the pdev->pClass->Setup (pdev, req) to parse the content of the SETUP packet (req). If a request is invalid,
.. but ,, it seems USBD_StatusTypeDef USBD_LL_SetupStage is never called to handle this.
USBD_ClassTypeDef does contain the pointer to the function.
Solved! Go to Solution.
2023-09-15 07:24 AM - edited 2023-09-15 07:26 AM
Mote then one year later ! The cause was the OS not sending the specific packet. It never reached the device, the Linux driver was changed and now does send the USB message. The MCU code was changed to reply the specific USB packet and things are working now
2022-08-26 01:16 AM
Cube is open source, so you can/shall debug it as your own code.
The USB code is entangled, follow the path from the ISR (upon USB_OTG_DOEPINT_STUP flag being set) where it receives setup packets, down to USBD_LL_SetupStage. Note, that it goes through what is considered user code (probably generated by CubeMX within CubeIDE for you, I don't use Cube just look at the examples).
An USB bus analyzer (hardware) is of immense help when working with USB.
JW
2022-08-26 03:17 AM
Thanks for this.
The only point I could find where USB_OTG_DOEPINT_STUP is used is in
stm32f4xx_hal_pcd.c. void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd).
line 1125: if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)
Is that the right point ot start? When i trace the called from there it does not end up to USBD_LL_SetupStage. Trying to find out att what point the code filters out interface from the device decscriptor requests.
UM1734 states: The library passes all the non-standard requests to the class-specific code with the callback pdev->pClass->Setup (pdev, req) function.
But which function is that ? is that USBD_LL_SetupStage ?
Set a debug point at every (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req); in the usb_ctlreq() and none of these are ever reached
What I currently do is to output debug data forom the device over an UART, so I can see all USB transactions coming in.
Something particular is that USB_LL_Setup is only called when the next request to StdDevReq is being processed. In others words, only when StdDev code is excuted the USB_LL_Setup gets executed bedfre that. that means, if there is no next transfer, USB_LL won't be executed, but only oncel the next request comes in. Maybe its a UART buffer/flsuh issue. need to check that.
FW0.00
USBD_LL_SetupStage bmRequest:00 bRequest:00 wValue:0000 wIndex:0000 wLength:0000
USBD_ParseSetupRequest req->bmRequest:00 req->bRequest:00 req->wValue:0000, req->wIndex:0000, req->wLength:0000
StdDevReq req->bmRequest:80 req->bRequest:06 req->wValue:0100, req->wIndex:0000, req->wLength:0040
USBD_GetDescriptor req->bmRequest:80 req->bRequest:06 req->wValue:0100 , req->wIndex:0000, req->wLength:0040
USBD_LL_SetupStage bmRequest:80 bRequest:06 wValue:0100 wIndex:0000 wLength:0040
USBD_ParseSetupRequest req->bmRequest:80 req->bRequest:06 req->wValue:0100, req->wIndex:0000, req->wLength:0040
StdDevReq req->bmRequest:00 req->bRequest:05 req->wValue:0049, req->wIndex:0000, req->wLength:0000
USBD_SetAddress req->bmRequest:00 req->bRequest:05 req->wValue:0049, req->wIndex:0000, req->wLength:0000
USBD_LL_SetupStage bmRequest:00 bRequest:05 wValue:0049 wIndex:0000 wLength:0000
USBD_ParseSetupRequest req->bmRequest:00 req->bRequest:05 req->wValue:0049, req->wIndex:0000, req->wLength:0000
StdDevReq req->bmRequest:80 req->bRequest:06 req->wValue:0100, req->wIndex:0000, req->wLength:0012
USBD_GetDescriptor req->bmRequest:80 req->bRequest:06 req->wValue:0100 , req->wIndex:0000, req->wLength:0012
USBD_LL_SetupStage bmRequest:80 bRequest:06 wValue:0100 wIndex:0000 wLength:0012
USBD_ParseSetupRequest req->bmRequest:80 req->bRequest:06 req->wValue:0100, req->wIndex:0000, req->wLength:0012
StdDevReq req->bmRequest:80 req->bRequest:06 req->wValue:0600, req->wIndex:0000, req->wLength:000A
USBD_GetDescriptor req->bmRequest:80 req->bRequest:06 req->wValue:0600 , req->wIndex:0000, req->wLength:000A
USBD_CtllError req->bmRequest:80 req->bRequest:06 req->wValue:0600, req->wIndex:0000, req->wLength:000A
USBD_LL_SetupStage bmRequest:80 bRequest:06 wValue:0600 wIndex:0000 wLength:000A
USBD_ParseSetupRequest req->bmRequest:80 req->bRequest:06 req->wValue:0600, req->wIndex:0000, req->wLength:000A
StdDevReq req->bmRequest:80 req->bRequest:06 req->wValue:0600, req->wIndex:0000, req->wLength:000A
USBD_GetDescriptor req->bmRequest:80 req->bRequest:06 req->wValue:0600 , req->wIndex:0000, req->wLength:000A
USBD_CtllError req->bmRequest:80 req->bRequest:06 req->wValue:0600, req->wIndex:0000, req->wLength:000A
USBD_LL_SetupStage bmRequest:80 bRequest:06 wValue:0600 wIndex:0000 wLength:000A
USBD_ParseSetupRequest req->bmRequest:80 req->bRequest:06 req->wValue:0600, req->wIndex:0000, req->wLength:000A
StdDevReq req->bmRequest:80 req->bRequest:06 req->wValue:0600, req->wIndex:0000, req->wLength:000A
USBD_GetDescriptor req->bmRequest:80 req->bRequest:06 req->wValue:0600 , req->wIndex:0000, req->wLength:000A
USBD_CtllError req->bmRequest:80 req->bRequest:06 req->wValue:0600, req->wIndex:0000, req->wLength:000A
USBD_LL_SetupStage bmRequest:80 bRequest:06 wValue:0600 wIndex:0000 wLength:000A
USBD_ParseSetupRequest req->bmRequest:80 req->bRequest:06 req->wValue:0600, req->wIndex:0000, req->wLength:000A
StdDevReq req->bmRequest:80 req->bRequest:06 req->wValue:0200, req->wIndex:0000, req->wLength:0009
USBD_GetDescriptor req->bmRequest:80 req->bRequest:06 req->wValue:0200 , req->wIndex:0000, req->wLength:0009
USBD_LL_SetupStage bmRequest:80 bRequest:06 wValue:0200 wIndex:0000 wLength:0009
USBD_ParseSetupRequest req->bmRequest:80 req->bRequest:06 req->wValue:0200, req->wIndex:0000, req->wLength:0009
StdDevReq req->bmRequest:80 req->bRequest:06 req->wValue:0200, req->wIndex:0000, req->wLength:0065
USBD_GetDescriptor req->bmRequest:80 req->bRequest:06 req->wValue:0200 , req->wIndex:0000, req->wLength:0065
USBD_LL_SetupStage bmRequest:80 bRequest:06 wValue:0200 wIndex:0000 wLength:0065
USBD_ParseSetupRequest req->bmRequest:80 req->bRequest:06 req->wValue:0200, req->wIndex:0000, req->wLength:0065
StdDevReq req->bmRequest:80 req->bRequest:06 req->wValue:0300, req->wIndex:0000, req->wLength:00FF
USBD_GetDescriptor req->bmRequest:80 req->bRequest:06 req->wValue:0300 , req->wIndex:0000, req->wLength:00FF
USBD_LL_SetupStage bmRequest:80 bRequest:06 wValue:0300 wIndex:0000 wLength:00FF
USBD_ParseSetupRequest req->bmRequest:80 req->bRequest:06 req->wValue:0300, req->wIndex:0000, req->wLength:00FF
StdDevReq req->bmRequest:80 req->bRequest:06 req->wValue:0302, req->wIndex:0409, req->wLength:00FF
USBD_GetDescriptor req->bmRequest:80 req->bRequest:06 req->wValue:0302 , req->wIndex:0409, req->wLength:00FF
USBD_LL_SetupStage bmRequest:80 bRequest:06 wValue:0302 wIndex:0409 wLength:00FF
USBD_ParseSetupRequest req->bmRequest:80 req->bRequest:06 req->wValue:0302, req->wIndex:0409, req->wLength:00FF
StdDevReq req->bmRequest:80 req->bRequest:06 req->wValue:0301, req->wIndex:0409, req->wLength:00FF
USBD_GetDescriptor req->bmRequest:80 req->bRequest:06 req->wValue:0301 , req->wIndex:0409, req->wLength:00FF
USBD_LL_SetupStage bmRequest:80 bRequest:06 wValue:0301 wIndex:0409 wLength:00FF
USBD_ParseSetupRequest req->bmRequest:80 req->bRequest:06 req->wValue:0301, req->wIndex:0409, req->wLength:00FF
StdDevReq req->bmRequest:80 req->bRequest:06 req->wValue:0303, req->wIndex:0409, req->wLength:00FF
USBD_GetDescriptor req->bmRequest:80 req->bRequest:06 req->wValue:0303 , req->wIndex:0409, req->wLength:00FF
USBD_LL_SetupStage bmRequest:80 bRequest:06 wValue:0303 wIndex:0409 wLength:00FF
USBD_ParseSetupRequest req->bmRequest:80 req->bRequest:06 req->wValue:0303, req->wIndex:0409, req->wLength:00FF
StdDevReq req->bmRequest:00 req->bRequest:09 req->wValue:0001, req->wIndex:0000, req->wLength:0000
USBD_SetConfig req->bmRequest:00 req->bRequest:09 req->wValue:0001, req->wIndex:0000, req->wLength:0000
USBD_LL_SetupStage bmRequest:00 bRequest:09 wValue:0001 wIndex:0000 wLength:0000
USBD_ParseSetupRequest req->bmRequest:00 req->bRequest:09 req->wValue:0001, req->wIndex:0000, req->wLength:0000
StdDevReq req->bmRequest:80 req->bRequest:06 req->wValue:0302, req->wIndex:0409, req->wLength:00FF
USBD_GetDescriptor req->bmRequest:80 req->bRequest:06 req->wValue:0302 , req->wIndex:0409, req->wLength:00FF
USBD_LL_SetupStage bmRequest:80 bRequest:06 wValue:0302 wIndex:0409 wLength:00FF
USBD_ParseSetupRequest req->bmRequest:80 req->bRequest:06 req->wValue:0302, req->wIndex:0409, req->wLength:00FF
StdDevReq req->bmRequest:80 req->bRequest:06 req->wValue:0301, req->wIndex:0409, req->wLength:00FF
USBD_GetDescriptor req->bmRequest:80 req->bRequest:06 req->wValue:0301 , req->wIndex:0409, req->wLength:00FF
An anlayzer seems to be a good idea, But I did succesfully buld several devices without, just bumping into this interface descriptor issue now. The RPPico one look to cover most, if not getting a DS pro 3. might be the last option. Prefer linux software. Not windows
But an analyzer does not help to debug what the firmware is doingm it only can show the transaction on the bus, and that is what I can't verify this moment.
2022-08-26 10:40 AM
> Is that the right point ot start?
Probably.
> When i trace the called from there it does not end up to USBD_LL_SetupStage.
And where does it end up?
Also, from where is USBD_LL_SetupStage() called? Textual search the sources (and Cube *is* *your* sources now).
JW
2022-08-27 07:19 AM
[1] And where does it end up?
USB_OTG_DOEPINT_STUP only used i stmf4xxx_hal_pcd.c
code:
either ends up in:
a CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX); for SETUP packet
clears out flags
d (USBx_OUTEP(epnum)->DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ); for EO packet
clears out flags
c. (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup); for ZLP
stm32Fxx_ll_usb, sets some flags
d. HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
UNUSED(hpcd);
UNUSED(epnum);
[2] Also, from where is USBD_LL_SetupStage() called? Textual search the sources (and Cube *is* *your* sources now).
That is exactly the answer I was looking for, : -)
Did that text search and failed to find anything. that why posting this, being stuck here and looking for clues...
2022-08-28 07:05 AM
P.S Using wireshark as an USB anallyzer, A transaction with 0x80 transaction show up, but when using 0x81 is does not. (just one bit change in the source code...)
Analyzers:
https://www.ellisys.com/products/usbcompare.php (LS/FS/HS/SS)
http://www.internationaltestinstruments.com/products/97-1480a-usb-20-protocol-analyzer.aspx (LS/FS/HS)
https://teledynelecroy.com/protocolanalyzer/usb (LS/FS/HS/SS)
https://www.totalphase.com/protocols/usb/ (LS/FS/HS)
https://www.dreamsourcelab.com/product/dslogic-series/ (LS/FS)
https://www.acute.com.tw/logic-analyzer-en/product/logic-analyzer/travelbus (LS/FS)
https://www.eejournal.com/article/4-logic-analyzer-based-on-raspberry-pi-pico/
ITI is lowest cost for HS for about $695 but only USB
LS/HS and multiprotocol DSLogic for $199 or the DYI the RP2040 is the choice
2023-09-15 07:24 AM - edited 2023-09-15 07:26 AM
Mote then one year later ! The cause was the OS not sending the specific packet. It never reached the device, the Linux driver was changed and now does send the USB message. The MCU code was changed to reply the specific USB packet and things are working now