Skip to content

driver/usbdev_synopsys_dwc2: use correct number of EPs #19380

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

gschorcht
Copy link
Contributor

@gschorcht gschorcht commented Mar 11, 2023

Contribution description

This PR fixes the problem that the driver uses the wrong number of EPs when using the USB OTG HS core.

The constant DWC2_USB_OTG_FS_NUM_EP was used in several places independent on whether the USB OTG FS core or the USB OTG HS core is used even though there is a function _max_endpoints which takes into account the configuration used. For most MCUs this was not a problem, because they have only a USB OTG FS core anyway. But for MCUs like the STM32, which have both a USB OTG FS core and a USB OTG HS core, it matters.

Testing procedure

Use either

USEMODULE='stdio_cdc_acm' BOARD=stm32f429i-disc1 make -j8 -C tests/usbus_cdc_ecm flash

or

BOARD=stm32f429i-disco make -j8 -C tests/usbus_cdc_ecm flash

Without this PR it just stucks due to an assert here:

cdcecm->ep_ctrl = usbus_add_endpoint(usbus, &cdcecm->iface_ctrl,
USB_EP_TYPE_INTERRUPT,
USB_EP_DIR_IN,
USBUS_CDCECM_EP_CTRL_SIZE);
assert(cdcecm->ep_ctrl);
The reason is that the USB OTG FS core has only 4 EPs but the application requires 5 IN EPS.

With the PR it works as expected.

Issues/PRs references

This commit fixes the problem that the driver uses the wrong number of EPs when using the USB OTG HS core. The reason is that the constant `DWC2_USB_OTG_FS_NUM_EP` is used in several places even though there is a function `_max_endpoints` which takes into account the configuration used. For most MCUs this is not a problem, because they have only a USB OTG FS core anyway. But for MCUs like the STM32, which has both a USB OTG FS core and a USB OTG HS core, it matters.
@github-actions github-actions bot added the Area: drivers Area: Device drivers label Mar 11, 2023
@gschorcht gschorcht requested a review from bergzand March 11, 2023 16:32
@gschorcht gschorcht added Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors) CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Mar 11, 2023
@riot-ci
Copy link

riot-ci commented Mar 11, 2023

Murdock results

✔️ PASSED

4d19f21 driver/usbdev_synopsys_dwc2: use correct number of EPs

Success Failures Total Runtime
6882 0 6882 11m:03s

Artifacts

@gschorcht
Copy link
Contributor Author

bors merge

@bors
Copy link
Contributor

bors bot commented Mar 12, 2023

Build succeeded:

@bors bors bot merged commit 2b225c4 into RIOT-OS:master Mar 12, 2023
@gschorcht
Copy link
Contributor Author

Thanks for reviewing.

@gschorcht
Copy link
Contributor Author

This is really really strange. This very small change leads for the stm32f723e-disco (CID 2.000) to the problem that the enumeration with examples/usbus_minimal and tests/usbus_cdc_ecm only works about every 10th time, while it works for tests/usbus_hid every time. The difference is that tests/usbus_hid does not use auto_init and waits 3 seconds before initializing the USB OTG core. So it seems to be something time critical. By the way, for stm32f746g-disco (CID 3.100) it works perfectly. I really hate this buggy USB OTG core.

@gschorcht
Copy link
Contributor Author

If I change it back here

for (unsigned idx = 1; idx < _max_endpoints(usbdev->config) && !ep; idx++) {
using the wrong constant DWC2_USB_OTG_FS_NUM_EP while finding an unused EP in _usbdev_new_ep, it works.

Even more strange, if I leave the code as is, i.e. using _max_endpoints functions here, but just add a simple if (ep == NULL) { printf("NULL"); } after the iteration

diff --git a/drivers/usbdev_synopsys_dwc2/usbdev_synopsys_dwc2.c b/drivers/usbdev_synopsys_dwc2/usbdev_synopsys_dwc2.c
index 5ea29f682c..27804d220c 100644
--- a/drivers/usbdev_synopsys_dwc2/usbdev_synopsys_dwc2.c
+++ b/drivers/usbdev_synopsys_dwc2/usbdev_synopsys_dwc2.c
@@ -539,6 +539,7 @@ static usbdev_ep_t *_usbdev_new_ep(usbdev_t *dev, usb_ep_type_t type,
                 ep->num = idx;
             }
         }
+        if (ep == NULL) { printf ("NULL"); }
     }
 
     if (ep && ep->type == USB_EP_TYPE_NONE) {

it works although the NULL case doesn't happen 🤔

So there seems to be something that is soooo time critical that it works with very small code changes, but doesn't work without those small code changes.

@gschorcht gschorcht deleted the drivers/usbdev_synopsys_dwc2/fix_ep_numof branch April 12, 2023 14:11
@MrKevinWeiss MrKevinWeiss added this to the Release 2023.04 milestone Apr 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: drivers Area: Device drivers CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants