Thursday, November 17, 2016

STM32F042 USB quirks with libopencm3

Needed a simple microntroller for an RF project, so picked the STM32F042F6P6 from ST.  It's cheap, comes in a 20-pin package, and has a built-in full speed USB device interface. It has an internal oscillator that can be synced to the USB signals from the host, so it doesn't even need a crystal.
It has a built-in DFU bootloader (among other programming options), so it requires no additional hardware to load the program.
After getting a simple LED blinker program to run, I decided to run some USB demo programs from the LIBOPENCM3 package. None of the demos are for this exact chip, but some are for the STM32F072, which is similar. Tried the tests/gadget-zero sample and ... No Go. The program loads and the LED's blink, but the USB device does not show up.
Turns out, there are a couple of subtle differences between this chip and the ones in bigger packages
  • The USB interface pins are shared with two other pins, and by default the USB pins are not connected to the outside world. Need to set a configuration bit so they can be used.
  • The peripheral clock needs to be turned on for the SYSCFG subsystem. I'm not sure whether that's a difference in the chips, or a quirk in libopencm3, but it's needed.
The setup calls at the beginning of the program for crystal-less USB operation are:
rcc_clock_setup_in_hsi48_out_48mhz();
rcc_periph_clock_enable(RCC_SYSCFG_COMP);
SYSCFG_CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP;
crs_autotrim_usb_enable()
rcc_set_usbclk_source(RCC_HSI48)
where the highlighted lines had to be added. With those two lines, gadget-zero shows up as a USB device in Linux. I was also able to the a cdc_acm demo working.

Acknowledgments

Several websites mention the pin-remapping issue, but the IFUSB project (github.com/julbouln/ifusb) was where I found the clock-enable issue and solution. IFUSB looks like a nice little peripheral, by the way.
Libopencm3 is at github.com/libopencm3/libopencm3
For programming, I use dfu-util: dfu-util.sourceforge.net. It's already included in Debian and probably other distributions.