devanlai / dapboot

DFU Bootloader for STM32 chips
Other
339 stars 111 forks source link

Enable specifying the alternate setting for the DFU interface per-target #43

Closed twelho closed 3 years ago

twelho commented 3 years ago

Continuation of my bug hunting and feature implementation round started in #41.

This works by "padding" the DFU alternate setting with dummy no-op descriptors that occupy all previous alternate setting values. AFAICT while these no-op interfaces are not documented in the USB defined class codes, they don't identify as anything in Linux and cause no driver to be loaded nor any warnings in the system logs, and they should be fine for other operating systems as well. When USB_ALT > 0, the DFU interface appears in the specific alternate setting, which dfu-util does automatically identify and use, alternatively it can be manually targeted with the -a flag. To have USB_ALT be a per-target (optional) property the target.h implementor must load it (since it has the macro value to keep everything compile-time), which is why I've had to split out the descriptor structs into their own file to be preprocessed as part of target_stm32f103.c or target_stm32l1.c. The USB initialization code can then call target_usb_descriptor() to get the pointer to the configuration descriptor defined by the target.

This is the smallest change I could come up with, and I'm keen to hear if this compile-time approach is acceptable. I'm aware that the macros used to repeat structs when generating the dummy descriptors aren't very aesthetically pleasing, but I'm not aware of any better way to this without causing runtime overhead and too much complexity.

twelho commented 3 years ago

You're right, usb_conf.c can read USB_ALT (now called USB_DFU_ALTN as per your suggestion). For some reason I could not get this to work when doing the initial implementation even though #38 has been in my development tree from the start. Oh well, it works now and is much cleaner like this. Good catch wrt. iInterface, that was left over from development back when I tried to isolate some warnings Linux gave about the alternate setting configuration. The warnings eventually turned out to be caused by cur_altsetting being a null pointer, and since there's no example on how to do multiple alternate settings with libopencm3 it took me a while to figure that out.