arduino / arduino/ArduinoCore-samd

USBCore double reset of EP0 bank0

Open
#482 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
C
Stars
502
Forks
740
PR merge metrics
No merged PRs in 30d

Description

I am having difficulties receiving control OUT transfers with data phase on control endpoint (EP0). The API call USBDeviceClass::recvControl should place the expected additional data in the user supplied buffer, but it simply locks up, at least until new setup packet is received...

First possible issue seems to be that bank0 is reset twice, once here: https://github.com/arduino/ArduinoCore-samd/blob/5dced38e81e6001a4b6e237e3462bc8db962127a/cores/arduino/USB/USBCore.cpp#L879 immediately after setup packet is copied away and again inside armRecvCtrlOUT: https://github.com/arduino/ArduinoCore-samd/blob/5dced38e81e6001a4b6e237e3462bc8db962127a/cores/arduino/USB/USBCore.cpp#L574 before the data packet (together with reseting the 'Ready' flag). In my case, this seems to drop the data packet which is already received (race condition) and then lock up waiting for next one. Commenting out the whole block (lines 561-574) seems to solve the immediate issue (locking up). The indication weather there are following data packets should be in the setup.wLength field.

The only place where USBDeviceClass::recvControl is used, that I could find, is within the CDC driver:
https://github.com/arduino/ArduinoCore-samd/blob/5dced38e81e6001a4b6e237e3462bc8db962127a/cores/arduino/USB/CDC.cpp#L147

Second issue might be that control OUT transfers, at least with my understanding of USB spec., are not limited to single data packet (64bytes). The AVR port seems to handle this case. Perhaps EP0OutHandler (i.e. similar to DoubleBufferedEPOutHandler) should be implemented to track the remaining data that should be additionally received (setup.wLength) and stall EP0 if setup function did not consume it. Recipient of the data should be confirmed with ZLP (zero lenght packet), which can be done in 'user land', but since AVR core seems to handle this automatically, perhaps an effort should be made to maintain compatibility? Any new setup packet should reset the state.

Thanks.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with cores/arduino/USB/USBCore.cpp around armRecvCtrlOUT and the setup-packet handling near the referenced lines, then inspect the recvControl call in cores/arduino/USB/CDC.cpp. Compare the SAMD control-OUT flow with the AVR port, focusing on data already received, setup.wLength, multi-packet transfers, and endpoint state reset; done means the reported lockup and dropped data are resolved.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
embedded-iot
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.