Skip to content

USB endpoints (including trace) broken on Black Pill (STM32F4xx)Β #1671

@DavidCPlatt

Description

@DavidCPlatt

While waiting for my official BMP 2.3 order to arrive, I've been experimenting with "building my own" using a WeAct STM32F411 board.

Basic functionality (debug and flash) is working.

SWO tracing does not work at all, in either the current 1.10 pre-release, or in the 1.9.2 build I did. The symptom of the failure is that the host attempt to read from the trace endpoint fails immediately, with a "broken pipe" error (transfer stalled, apparently).

The identical version of 1.9.2, built for "stlink" and flashed into a "Baite" ST-Link v2 clone, does not exhibit this error. SWO doesn't capture anything on the host (due to the fact that the trace line isn't brought out to the connector) but the host-to-USB connection doesn't flail and die.

I've been digging into the problem for a day or so, and I've come to the sad conclusion that trace-capture may never be able to work on the Black Pill. In fact, I'm sorta surprised that BMP runs as well on this board/chip as it does. The reason: the USB OTG controller used in the STM32F411 (and apparently the F107 as well) has hardware support for one control endpoint (#0), three IN endpoints (0x81-0x83), and three OUT endpoints(1-3)... period. No others need apply. You can have zero, one, two or three. Counteth thee not to four. Five is right out.

BMP uses four IN endpoints (for the two CDC-ACM), so it's already out of range.

I looked through the logic in libopencm3/.../usb_dwc_common.c to see how it accesses the hardware registers, and was somewhat troubled to see that it doesn't bother to range-check the endpoint index at all. If you pass it endpoint numbers in the valid ranges (0, 1-3, 0x81-0x83) it hits the right hardware registers. If you pass larger numbers (like 0x85 for trace) it appears to just go ahead and read/write quite happily to unimplemented register addresses. This doesn't seem to cause hardware to throw exceptions, but I rather suspect that the results are quite undefined and may result in purple monkey bus dishwasher.

I've looked in detail at the hardware-register definitions, in the hope that one might be allowed three active IN endpoints at a time, and be able to multiplex those three slots among a larger number of logical endpoints. I haven't found any way to do so - the endpoint index/number is implied by the register offset, and isn't set explicitly in any register I've found.

I looked at a Wireshark/usbmon trace of the traffic between host and Black Pill when I try to start reading the trace data. The host fires off a bunch of bulk-read URBs in rapid sequence. A fraction of a second later the Black Pill starts sending responses - a combination of "broken pipe" and "no such address" is how Wireshark interprets them. I'd guess that the F411 USB-OTG core is taking exception to being asked to send data from endpoint numbers it has no registers/FIFO for.

In theory I suspect that this same problem might affect the VCP CDC-ACM, since it uses endpoint 0x84 for control. Maybe it's never sending anything of significance on that endpoint?

So, that's the unfortunate news. Unless I'm gravely wrong (and I certainly may be) it won't be possible to put a full-function BMP firmware into any of the STM32 devices that have this particular USB-OTG core. Some functionality will have to be sacrificed - either trace won't work, or the VCP "UART" will have to be configured out, and the trace endpoint moved down to 0x83.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BMP FirmwareBlack Magic Probe Firmware (not PC hosted software)Foreign Host BoardNon Native hardware to runing Black Magic firmware on

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions