cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L073 USB PMA issue - HAL lib misinterpreting SETUP packets

Stephen Whittle
Associate
Posted on August 30, 2017 at 02:52

So I'm currently working on a custom HID with STM32L073CZ using code generated by the latest version of Cube and CubeMX, and I'm running into an issue with intermittent enumeration being caused by SETUP packets not always being recognised properly. Enumeration begins without issues (you can see here the on-device log, showing the PMA contents, on the left matching up with my protocol analyzer output on the right):

0690X000006083qQAA.png

However, at some point during the enumeration process (not always on the same request), the device receives a SETUP packet, that it wrongly interprets as being of length 0 (xfer_count is 0 after the following line executes):

ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);

This means that when PCD_ReadPMA is called with wNBytes == 0, that nothing is copied from the PMA into hpcd->Setup. All fine and dandy, but hpcd->Setup still contains the SETUP information from the previous packet.

This is a problem, because HAL_PCD_SetupStageCallback is called regardless, meaning that the previous SETUP packet is handled again with the stale hpcd->Setup contents, leading to the following problem:

0690X000006083vQAA.png

The protocol analyzer clearly shows SETUP packets with their contents changing, but the device believes the setup packet to be empty, and further logging of the PMA contents directly inside ReadPMA shows that the PMA contents don't change either.

680 200 0 FF

PMA read

Setup request parsed as: bmReq 80 - bReq 6 - wVal 200 - wIndex 0 - wLen FF

fsconfig

680 200 0 FF

PMA read

Setup request parsed as: bmReq 80 - bReq 6 - wVal 200 - wIndex 0 - wLen FF

fsconfig

680 200 0 FF

PMA read

Setup request parsed as: bmReq 80 - bReq 6 - wVal 200 - wIndex 0 - wLen FF

fsconfig

680 200 0 FF

PMA read

Setup request parsed as: bmReq 80 - bReq 6 - wVal 200 - wIndex 0 - wLen FF

fsconfig

680 200 0 FF

PMA read

Setup request parsed as: bmReq 80 - bReq 6 - wVal 200 - wIndex 0 - wLen FF

fsconfig

 

This issue is still present in the current version of Cube I am using,  

https://community.st.com/0D50X00009Xkev8SAB

 , but applying the fixes from that thread don't do anything to fix this issue as that is related to data rather than setup packets. 

I've attached my current elf file to this thread. Has anybody encountered anything like this before? 

null
6 REPLIES 6
zyu
Associate

How do you solve this problem? I encountered the same issue in stm32f070.:persevering_face:

It might be interesting to record and observe the USB_ISTR register (maybe together with USB_FNR register), especially the ERR bit.

JW

AAdad
Associate II

I have the same issue with setup packets on STM32F103C8T6. Host sends a request, and the code around line 1276 of stm32f1xx_hal_pcd.c processes a previously received setup packet, as there are no checks for the number of bytes received.

Was anyone able to solve this already?

In my case, the PC app requests string descriptors (with indexes 0, 1, 2, 3) and the issue occurs quite frequently (but not always) if descriptor with index 2 is > 64 bytes.

dst
Associate II

I am having the same issue with STM32F103C8T6. The device descriptor request is received, the device address gets set and after that I receive a SETUP with "80 06 00 01 00 00 12 00" for my just assigned address which triggers the setup interrupt routine but PCD_GET_EP_RX_CNT() returns 0. The data was seen in a logic analyzer together with an ACK from the device. But the previous device address setup remains untouched in the buffer due to the wrong reception length and results in an endpoint stall. Is there any solution to receive the setup properly? I have this issue always at the same point.

dst
Associate II

I had a deeper look into the PCD HAL code to verify this issue. It turns out that in stm32f1xx_ll_usb.c the maximum receive packet size gets correctly set in USB_ActivateEndpoint() but not in USB_EPStartXfer(). Here the requested length from HAL_PCD_EP_Receive() is used in PCD_SET_EP_RX_CNT() which truncates the received SETUP packet to 0 bytes. An easy bug fix is to pass ep->maxpacket instead of len to PCD_SET_EP_RX_CNT(). Though, I am not sure what should be used in PCD_SET_EP_DBUF_CNT() instead. Note that it makes no sense to receive a packet smaller than the maximum negotiated packet size as there is no means to instruct the host to do so.

AAdad
Associate II

Disclaimer: My issue (3 posts above) could be something totally different, but I post it here just in case anyone runs into a similar problem.

I was able to solve my issue (see above) with a setup packet being handled as if its length is 0 bytes on 2 STM32F103 chips: STM32F103C8T6 on a BluePill and with STM32F103RBT6 on an STM32-P103.

I examined the content of the problematic packets in PMA and found that when the issue occurred, the PMA wasn't updated with the content of the recent SETUP packet. I disabled all the hardware features I used for this project (I2C and all timers except one) except USB and the issue disappeared. Next steps confirmed that I2C was the culprit. So I had to use a software I2C (bit-banging) instead of using the hardware feature, which is a pity.

Strange thing is that this is not mentioned in any errata documents I could find, but happens quite consistently on both extremely cheap and more expensive boards.