STM32
STM32 programming
Boot mode configuration
<syntaxhighlight lang="bash">BOOT1 BOOT0 Boot mode Address
x 0 Main Flash memory 0x8000000 0 1 System memory (built-in bootloader) 0x1FFFB000 1 1 Embedded SRAM 0x20000000
in Main flash memory and System memory boot modes address is aliased to 0x0</syntaxhighlight>
STM32F103C86T dev board boot pins
- https://www.aliexpress.com/item/Free-Shipping-STM32F103C8T6-ARM-STM32-Minimum-System-Development-Board-Module-Forarduino/32525208361.html
- http://www.ebay.com/itm/STM32F103C8T6-ARM-STM32-Minimum-System-Development-Board-Module-For-Arduino-DHUS-/321569700934?pt=LH_DefaultDomain_0&hash=item4adf0c3c46
Legend
o o o BOOT0 o o o BOOT1 --- |R| Reset button ---
Boot to bootloader (built-in bootloader)
- Allows flashing over USART
o [=] [=] o --- |R| ---
Boot to main flash (user code)
[=] o o o o --- |R| ---
Flashing
- Flashing is done via USART1 (A9 TX A10 RX)
Converting Elf to Bin
Required if you only have elf files produced by your toolchain - stm32flash accepts only *.bin files.
<syntaxhighlight lang="bash"> arm-none-eabi-objcopy -O binary miniblink.elf miniblink.bin </syntaxhighlight>
Using stm32flash
Test connection with
<syntaxhighlight lang="bash"> stm32flash /dev/ttyUSB0 </syntaxhighlight>
Flash and run from 0x0
<syntaxhighlight lang="bash"> stm32flash /dev/ttyUSB0 -w miniblink.bin -g 0x0 </syntaxhighlight>
Pinout
Libraries
libopencm3
Minimalistic firmware library/framework.
Bootstrapping on Fedora
Library
<syntaxhighlight lang="bash">dnf install arm-none-eabi* mkdir embedded git clone https://github.com/libopencm3/libopencm3 cd libopencm3
- Edit TARGETS in Makefile and keep only targets that you need (or just stm32/f1 for example).
make -j8 cd ..</syntaxhighlight>
DFU bootloader
This is a bootloader for Device Firmware Update via USB (stm32/f1).
<syntaxhighlight lang="bash">git clone https://git.48.io/libopencm3_dfu cd libopencm3_dfu
- connect JTAG
make flash
- or flash via USART & stm32flash, see flashing section above
make stm32flash</syntaxhighlight>
Sample application
For use with DFU bootloader (stm32/f1).
<syntaxhighlight lang="bash">git clone https://git.48.io/libopencm3_template cd libopencm3_template
- flash via dfu
make dfu
- or with JTAG
make flash</syntaxhighlight>
Library examples
<syntaxhighlight lang="bash">git clone https://github.com/libopencm3/libopencm3-examples
- Either fetch git submodule pointing to libopencm3 and repeat steps in Library section
- or symlink libopecm3 dir to previously built libopencm3
cd libopencm3-examples rmdir libopencm3 ln -s <PATH_TO-->/libopencm3 .
- try building miniblink example
cd examples/stm32/f1/stm32-h103/miniblink make</syntaxhighlight>
Troubleshooting
- use make V=1 when make fails
- make sure openocd is not running when doing 'make flash'
Locked device
If you can't flash and 'make V=1 flash' reports something similar
<syntaxhighlight lang="bash">Info : Device Security Bit Set stm32x unlocked</syntaxhighlight>
You need to unlock your device first (with JTAG):
<syntaxhighlight lang="bash">openocd -f jlink_swd_f103.cfg telnet 127.0.0.1 4444
- in telnet issue:
stm32f1x unlock 0</syntaxhighlight>
Debugging
Debugging hardware
ST-Link clones or Discovery boards are flashable with Black Magic Probe firmware.
JLink
<syntaxhighlight lang="bash"># add to Makefile to generate debuginfo CXXFLAGS = -g
- run openocd
openocd -f jlink_swd_f103.cfg
- connect to openocd via gdb
arm-none-eabi-gdb --ex 'target remote localhost:3333' <EXECUTABLE>.elf
- Use following commands when in gdb (more at http://www.yolinux.com/TUTORIALS/GDB-Commands.html)
- c (continue), stop execution with Ctrl-C
- bt (stacktrace)
- b (break), e.g. 'b main' or 'b template.c:360'</syntaxhighlight>
Black Magic probe
Running BMP on Discovery boards
- http://embdev.net/articles/STM_Discovery_as_Black_Magic_Probe
- https://esden.net/2014/12/29/black-magic-discovery/
F3 Discovery
Shorting solder bridges SB13 and SB15 connects UART1 port from STM32F303 to STM32F103 making it possible to use Black Magic Probe as UART bridge via /dev/ttyACM1
F4 Discovery
To enable UART bridge via BMP on older F4 discovery (STM32F407) you need to solder wires between UART2 (PA2/PA3) on STM32F407 to pins PA2/PA3 on STM32F103. These are located in the corners of the chips. Take care when soldering PA3 on F407 as it's positioned near VSS, if you manage to short these pins try lifting PA3 from the pad completely soldering wire directly to it.
Flashing
<syntaxhighlight lang="bash"># make PROBE_HOST=stlink
- flashing blackmagic_dfu via black magic probe
https://github.com/blacksphere/blackmagic/ cd blackmagic make PROBE_HOST=stlink arm-none-eabi-gdb --ex 'target extended-remote /dev/ttyACM0' src/blackmagic_dfu monitor swdp_scan attach 1 monitor option erase
- restart target so it unlocks, repeat up to 'monitor option erase' then issue
load
- restart target, it should boot to black magic dfu
- [ +0.000002] usb 1-1.2: Product: Black Magic (Upgrade) for STLink/Discovery, (Firmware v1.6-rc0-257-gd6e2977)
- upload black magic via dfu
sudo dfu-util -s 0x08002000:leave -D blackmagic.bin</syntaxhighlight>
Usage
<syntaxhighlight lang="bash">arm-none-eabi-gdb --ex 'target extended-remote /dev/ttyACM0'
- Use following commands when in gdb
monitor swdp_scan attach 1</syntaxhighlight>
Sample session:
<syntaxhighlight lang="bash">(gdb) monitor swdp_scan Target voltage: unknown Available Targets: No. Att Driver 1 STM32F4xx (gdb) attach 1 Attaching to Remote target Error while running hook_stop: Invalid type combination in equality test. 0x080035c2 in ?? () (gdb) bt
- 0 0x080035c2 in ?? ()
- 1 0x08001032 in ?? ()
- 2 0x08001032 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)</syntaxhighlight>
To access serial bridge:
<syntaxhighlight lang="bash">screen /dev/ttyACM1 115200</syntaxhighlight>
Links
DMA
DAC
Docs
- STM32 F3 Discovery (STM32F303VC) Manual
- STM32 F4 Discovery (STM32F407VG) Manual
- STM32F303VC
- STM32F407
- STM32F334
- Getting started with STM32F3 series
- Migrating from F1 to F3 series
Calculating Timer Frequency
MUCH WIP
period_target_ms = p1 period_hz = p2
1000ms / p1 = p2
E.g. for 20ms (servo) period
1000ms / 20 ms = 50 hz
cpu_freq = 72Mhz prescale = 72
72MHz / 72 = 1Mhz
This increases out count register CNT by 1 000 000 each second. To calculate what is the correct value for the ARR register (which defines the period), we divide the result of the prescaled frequency by the intended frequency for our period:
1 000 000 Hz / 50 Hz = 20 000
Now every time the CNT register is increased by one, this is the equivalent to 1us. The duty cycle now could by set easily. E.g. for a 1.5ms duty cycle we set the CCRx register to 1500.
Stepper
driver_max_duty = 250khz