2020-07-06 01:34 AM
On a 'F446 running out of FLASH at 168MHz, an already field-proven code using OTG_HS with FS PHY started to fail intermettently after being compiled by a newer version of gcc (due to more aggressive optimization of course).
The code hangs on
while ((OTG_HS->GRSTCTL AND USB_OTG_GRSTCTL_CSRST) != 0);
if it is "too close" to
OTG_HS->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
This sequence
08010df4 <USBD_Init>:
8010df4: 6803 ldr r3, [r0, #0]
8010df6: 681b ldr r3, [r3, #0]
usb->c->u->global.GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
8010df8: 689a ldr r2, [r3, #8] // OTG_GAHBCFG
8010dfa: f022 0201 bic.w r2, r2, #1
8010dfe: b570 push {r4, r5, r6, lr}
8010e00: 609a str r2, [r3, #8]
usb->c->u->global.GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL; // select (built-in) FS PHY *** in non-USBD_HS_capable this may be redundant
8010e02: 68da ldr r2, [r3, #12] // OTG_GUSBCFG
8010e04: f042 0240 orr.w r2, r2, #64 ; 0x40
8010e08: 4604 mov r4, r0
8010e0a: 60da str r2, [r3, #12]
while ((usb->c->u->global.GRSTCTL AND USB_OTG_GRSTCTL_AHBIDL) == 0);
8010e0c: 691a ldr r2, [r3, #16] // OTG_GRSTCTL
8010e0e: 2a00 cmp r2, #0
8010e10: dafc bge.n 8010e0c <USBD_Init+0x18>
usb->c->u->global.GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
8010e12: 691a ldr r2, [r3, #16]
8010e14: f042 0201 orr.w r2, r2, #1
8010e18: 611a str r2, [r3, #16]
while ((usb->c->u->global.GRSTCTL AND USB_OTG_GRSTCTL_CSRST) != 0);
8010e1a: 691a ldr r2, [r3, #16]
8010e1c: 07d1 lsls r1, r2, #31
8010e1e: d4fc bmi.n 8010e1a <USBD_Init+0x26>
tends to keep looping in that last loop in cca 20% of cases.
ST's code has timeouts in USB_CoreReset() (which of course won't ensure functionality), with the callers characteristically ignoring the return value.
JW