stm32f1xx
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
stm32f1xx [2016/02/13 18:17] – [USB DFU] kingkevin | stm32f1xx [2019/09/19 10:02] – [blue pill] RTC issue kingkevin | ||
---|---|---|---|
Line 72: | Line 72: | ||
* proper USB disconnect circuit (useful for using the DFU bootloader it comes with) | * proper USB disconnect circuit (useful for using the DFU bootloader it comes with) | ||
* small | * small | ||
- | * good analogue | + | * good analog |
* more flash (128 vs 64 kB) | * more flash (128 vs 64 kB) | ||
* small, fits breadboard (600 mil wide) | * small, fits breadboard (600 mil wide) | ||
Line 79: | Line 79: | ||
* no additional connections (SWD, power, GND) | * no additional connections (SWD, power, GND) | ||
* the pin silkscreen are not the chip pins (you always need the schematic at hand) | * the pin silkscreen are not the chip pins (you always need the schematic at hand) | ||
- | * the clones don't provide a second voltage regulator for the analague | + | * the clones don't provide a second voltage regulator for the analog |
===== blue pill ===== | ===== blue pill ===== | ||
- | {{ : | + | {{ : |
+ | {{ : | ||
This cheap board is often referred as blue pill in forums and sold under $2.50 as [[http:// | This cheap board is often referred as blue pill in forums and sold under $2.50 as [[http:// | ||
Line 96: | Line 97: | ||
* 6: -40 to 85 °C | * 6: -40 to 85 °C | ||
* peripherals: | * peripherals: | ||
- | * 2x20 GPIO pins on the side (most MCU pins are accessible) | + | * two 1x20 GPIO pins headers |
* USB micro-B | * USB micro-B | ||
* SWD on the top | * SWD on the top | ||
* boot select | * boot select | ||
* power LED | * power LED | ||
- | * user LED, on P13 | + | * user LED, on PC13 (warning: switching this LED heavily affects the RTC) |
* reset button (NRST) | * reset button (NRST) | ||
* 32.768 kHz real time clock (RTC) | * 32.768 kHz real time clock (RTC) | ||
Line 113: | Line 114: | ||
* no user button | * no user button | ||
* board extends over headers | * board extends over headers | ||
+ | * the RTC is not stable when the on-board LED is toggled | ||
Here a rough {{: | Here a rough {{: | ||
Mine for example has a 10 kΩ pull-up (to 3.3 V) resistor on USB D+/PA12 instead if a 4.7kΩ (to 5 V), although USB devices use a 1.5 kΩ resistor to pull up (to 3.3 V) usually. | Mine for example has a 10 kΩ pull-up (to 3.3 V) resistor on USB D+/PA12 instead if a 4.7kΩ (to 5 V), although USB devices use a 1.5 kΩ resistor to pull up (to 3.3 V) usually. | ||
+ | ===== core board ===== | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | You can often find this versatile board for $6 by searching for "51 core board" | ||
+ | |||
+ | It has: | ||
+ | * [[http:// | ||
+ | * STM32: 32-bit ARM | ||
+ | * F: general purpose | ||
+ | * 103: medium density (performance line) | ||
+ | * C: 48 pins | ||
+ | * 8: 64 kB flash | ||
+ | * T: LQFP | ||
+ | * 6: -40 to 85 °C | ||
+ | * peripherals: | ||
+ | * two 2x10 GPIO pin headers on the side (most MCU pins are accessible) | ||
+ | * USB micro-B | ||
+ | * 2x3 SWD+UART port | ||
+ | * boot select | ||
+ | * power LED | ||
+ | * user LED, on PA1 | ||
+ | * reset button (NRST) | ||
+ | * user button (PA8) | ||
+ | * 32.768 kHz real time clock (RTC) | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | It offers quite a lot of peripheral options: | ||
+ | * 2x4 header for the ESP-01 WiFi module (base on the ESP8266) | ||
+ | * 2x4 header for the nRF24L01 transceiver module | ||
+ | * 1x4 header for a Bluetooth module (using as UART port) | ||
+ | * 1x8 header for an OLED/TFT screen | ||
+ | * 2x5 header for a VS1053/ | ||
+ | * space and pads for a CR1220 coin cell (with knife pins) connected to VBAT (for the the RTC circuit of the micro-controller), | ||
+ | * footprint for a flash chip (W25xxx, SOP-8) connected to an SPI port (SPI1) | ||
+ | * footprint for a EEPROM chip (24Cxx, SOP-8) connected to an I2C port (I2C1), but don't forget to add the pull-up resistors (R12 and R13) | ||
+ | * footprint for a [[https:// | ||
+ | |||
+ | advantages: | ||
+ | * user LED and button | ||
+ | * large AMS1117 voltage regulator | ||
+ | * fuse on USB 5V | ||
+ | * separate 5V connection | ||
+ | * SWD+UART header (ideal for the black magic probe) | ||
+ | * RTC oscillator included | ||
+ | * compact (42x53 mm) | ||
+ | * M3 mounting holes | ||
+ | drawbacks: | ||
+ | * very few power pins | ||
+ | |||
+ | **warning**: | ||
====== flashing ====== | ====== flashing ====== | ||
Flashing refers to programming your application into flash, so the micro-controller can run it. | Flashing refers to programming your application into flash, so the micro-controller can run it. | ||
There are several ways to program the flash, as explained in [[http:// | There are several ways to program the flash, as explained in [[http:// | ||
- | * In-Circuit Programming (ICP): using SWJ (serial wire and JTAG) or the built-in boot loader. This mechanism is provided natively by the micro-controller | + | * [[#ICP|In-Circuit Programming (ICP)]]: using SWJ (serial wire and JTAG) or the embedded bootloader. This mechanism is provided natively by the micro-controller |
- | * In-Application Programming (IAP): using a custom application which can write into flash. But for that you first need to flash this application (often called boot loader) using an ICP method | + | * [[#IAP|In-Application Programming (IAP)]]: using a custom application which can write into flash. But for that you first need to flash this application (often called boot loader) using an ICP method |
It's also possible to program it into RAM and run it from there, but this is not the focus here. | It's also possible to program it into RAM and run it from there, but this is not the focus here. | ||
Line 129: | Line 183: | ||
But if you are interested, the documents referred in this section provide the information you need. | But if you are interested, the documents referred in this section provide the information you need. | ||
- | ===== in-circuit programming | + | ===== ICP ===== |
+ | |||
+ | In-Circuit Programming methods: | ||
+ | * [[#embedded bootloader]]: | ||
+ | * [[#SWJ]]: complex but fast, and allows debugging | ||
- | ==== built-in | + | ==== embedded |
- | The STM32 micro-controller come with a built-in boot loader | + | The STM32 micro-controller come with a embedded bootloader |
How to start this bootloader is described in [[http:// | How to start this bootloader is described in [[http:// | ||
Line 149: | Line 207: | ||
* ST provides a [[http:// | * ST provides a [[http:// | ||
* [[https:// | * [[https:// | ||
- | * I use [[https:// | + | * I use [[https:// |
./ | ./ | ||
</ | </ | ||
Line 165: | Line 223: | ||
You first need a SWD or JTAG adapter. | You first need a SWD or JTAG adapter. | ||
I am using a [[jtag# | I am using a [[jtag# | ||
- | + | Don't forget to add a udev rule to allow the user to access the SWD adapter: < | |
- | To control the SWD adapter several software are available: | + | |
- | * [[https:// | + | |
- | * but I am using [[http:// | + | |
- | + | ||
- | Using OpenOCD: | + | |
- | - install PpenOCD: < | + | |
- | sudo apt-get install openocd | + | |
- | </ | + | |
- | - add a udev rule to allow the user to access the SWD adapter: < | + | |
sudo tee / | sudo tee / | ||
# STMicroelectronics ST-LINK/V2 | # STMicroelectronics ST-LINK/V2 | ||
Line 181: | Line 230: | ||
sudo service udev reload | sudo service udev reload | ||
</ | </ | ||
- | | + | |
- | - start openOCD: < | + | To control the SWD adapter several software are available: |
+ | * the dedicated [[#st-link]] tool | ||
+ | * but I am using [[# | ||
+ | |||
+ | === st-link === | ||
+ | |||
+ | [[https:// | ||
+ | |||
+ | To install st-link: | ||
+ | <code bash> | ||
+ | git clone https:// | ||
+ | cd stlink/ | ||
+ | ./ | ||
+ | ./ | ||
+ | make | ||
+ | </ | ||
+ | |||
+ | To write the firmware at 0x0800 0000 (the flash memory start address) you can simply use: | ||
+ | <code bash> | ||
+ | ./st-flash write firmware.bin 0x08000000 | ||
+ | |||
+ | 2016-02-14T10: | ||
+ | 2016-02-14T10: | ||
+ | 2016-02-14T10: | ||
+ | 2016-02-14T10: | ||
+ | Flash page at addr: 0x08001800 erased | ||
+ | 2016-02-14T10: | ||
+ | 2016-02-14T10: | ||
+ | 2016-02-14T10: | ||
+ | 6/6 pages written | ||
+ | 2016-02-14T10: | ||
+ | 2016-02-14T10: | ||
+ | </ | ||
+ | |||
+ | What is useful is that it show some information about the chip at the beginning. | ||
+ | You can also get this information using '' | ||
+ | |||
+ | You can also use it combination with [[#GDB]] to [[# | ||
+ | - start the st-util server: <code bash> | ||
+ | ./st-util | ||
+ | |||
+ | INFO src/ | ||
+ | INFO src/ | ||
+ | INFO src/ | ||
+ | INFO gdbserver/ | ||
+ | INFO gdbserver/ | ||
+ | INFO gdbserver/ | ||
+ | </ | ||
+ | - start GDB with the firmware to flash/ | ||
+ | arm-none-eabi-gdb firmware.elf | ||
+ | |||
+ | ... | ||
+ | Reading symbols from firmware.elf...done. | ||
+ | (gdb) tar extended-remote :4242 | ||
+ | Remote debugging using :4242 | ||
+ | 0x0800016c in ?? () | ||
+ | (gdb) load | ||
+ | Loading section .text, size 0x85d8 lma 0x8002000 | ||
+ | Loading section .ARM.exidx, size 0x8 lma 0x800a5d8 | ||
+ | Loading section .data, size 0x8b4 lma 0x800a5e0 | ||
+ | Start address 0x80043fc, load size 36500 | ||
+ | Transfer rate: 9 KB/sec, 7300 bytes/ | ||
+ | </ | ||
+ | |||
+ | === OpenOCD === | ||
+ | |||
+ | [[http:// | ||
+ | It supports numerous adapters and micro-controllers (targets). | ||
+ | You just have to specify what you are using. | ||
+ | |||
+ | To use OpenOCD: | ||
+ | - install OpenOCD: <code bash> | ||
+ | sudo apt-get install openocd | ||
+ | </ | ||
+ | - start openOCD | ||
openocd --file interface/ | openocd --file interface/ | ||
</ | </ | ||
- | - connect to openOCD to open a session: < | + | - connect to openOCD to open a session: < |
telnet localhost 4444 | telnet localhost 4444 | ||
</ | </ | ||
- | - in this session reset and halt the MCU: < | + | - in this session reset and halt the MCU: < |
reset halt | reset halt | ||
</ | </ | ||
- | - you can dump the current flash content (from 0x0800 0000 to 0x0801 ffff): < | + | - you can dump the current flash content (from 0x0800 0000 to 0x0801 ffff): < |
dump_image dump.bin 0x08000000 0x1ffff | dump_image dump.bin 0x08000000 0x1ffff | ||
</ | </ | ||
- | - and write to flash a new firmware at 0x0800 0000 (the flash memory address). firmware.bin must be in the working directory where you started openOCD: < | + | - and write the firmware at 0x0800 0000 (the flash memory |
flash write_image erase firmware.bin 0x08000000 | flash write_image erase firmware.bin 0x08000000 | ||
</ | </ | ||
You can also use this openOCD one-liner to flash a firmware: | You can also use this openOCD one-liner to flash a firmware: | ||
- | < | + | < |
openocd --file interface/ | openocd --file interface/ | ||
Line 230: | Line 353: | ||
</ | </ | ||
- | ===== in-application programming | + | Like with [[# |
+ | ===== IAP ===== | ||
Instead of always having to use one of the ICP methods (UART or SWD), it would be nice to be able to flash using an more convenient way (i.e. over USB). | Instead of always having to use one of the ICP methods (UART or SWD), it would be nice to be able to flash using an more convenient way (i.e. over USB). | ||
Line 241: | Line 365: | ||
==== USB DFU ==== | ==== USB DFU ==== | ||
- | There are several USB DFU bootloader. | + | There are several USB DFU bootloaders available (one from [[http:// |
- | I am using [[https:// | + | |
- | It works well on most generic boards and is small (8kB). | + | |
- | To flash using the bootloader: | + | Here I will explain how to use USB DFU with the [[https:// |
+ | |||
+ | If you want to make use of USB in your actual application after the bootloader started it, don't forget to force re-enumerating USB so the host computer sees the new interface: | ||
+ | * you can do this on the board by signalling a USB reset. On the [[#maple mini]] there is a dedicated circuit. On generic boards you can pull USB D+/PA12 low for a short time | ||
+ | * you can also force this on the host using [[https:// | ||
+ | sudo ./usb-reset "/ | ||
+ | </ | ||
+ | |||
+ | To flash using the USB DFU bootloader: | ||
- download the [[https:// | - download the [[https:// | ||
* [[https:// | * [[https:// | ||
- | * [[https:// | + | * [[https:// |
* [[https:// | * [[https:// | ||
- flash bootloader (at 0x0800 0000) using [[#ICP]] | - flash bootloader (at 0x0800 0000) using [[#ICP]] | ||
- | - install DFU-util (>=0.8): < | + | - install DFU-util (>=0.8): < |
sudo apt-get install dfu-util | sudo apt-get install dfu-util | ||
</ | </ | ||
- | - install the rules to allow users to use the DFU devices: < | + | - install the rules to allow users to use the DFU devices: < |
sudo tee / | sudo tee / | ||
# LeafLabs STM32 DFU USB | # LeafLabs STM32 DFU USB | ||
Line 265: | Line 395: | ||
- remove flashing device | - remove flashing device | ||
- re-plug USB | - re-plug USB | ||
- | - the board should enumerate as DFU device. verify in the logs: < | + | - the board should enumerate as DFU device. verify in the logs: < |
tail -f / | tail -f / | ||
Line 277: | Line 407: | ||
... | ... | ||
</ | </ | ||
- | - check the available DFU profiles: < | + | - check the available DFU profiles: < |
dfu-util --list | dfu-util --list | ||
Line 291: | Line 421: | ||
Found DFU: [1eaf:0003] ver=0201, devnum=4, cfg=1, intf=0, alt=0, name=" | Found DFU: [1eaf:0003] ver=0201, devnum=4, cfg=1, intf=0, alt=0, name=" | ||
</ | </ | ||
- | - you can flash the firmware (at 0x800 2000): < | + | - you can flash the firmware (at 0x800 2000): < |
dfu-util --verbose --device 1eaf:0003 --cfg 1 --intf 0 --alt 2 --download firmware.bin | dfu-util --verbose --device 1eaf:0003 --cfg 1 --intf 0 --alt 2 --download firmware.bin | ||
Line 320: | Line 450: | ||
</ | </ | ||
- after the device is powered you have 0.5 seconds to flash the firmware before if starts the main firmware | - after the device is powered you have 0.5 seconds to flash the firmware before if starts the main firmware | ||
- | - on [[https:// | ||
- | sudo ./usb-reset "/ | ||
- | </ | ||
====== developing ====== | ====== developing ====== | ||
Line 337: | Line 464: | ||
I am using [[http:// | I am using [[http:// | ||
I still keep the [[http:// | I still keep the [[http:// | ||
+ | |||
+ | ====== debugging ====== | ||
+ | |||
+ | Here are methods I use to debug my firmware, in increasing order of difficulty and power. | ||
+ | |||
+ | ===== LED ===== | ||
+ | |||
+ | Most of the development boards come with a user LED connected to a GPIO. | ||
+ | Switching it on an off is pretty easy. | ||
+ | I use it to show a current state (on/off) or activity (toggling). | ||
+ | |||
+ | The advantage is that you can also use it in interrupt service routines, or see the signal on the oscilloscope (to measure the speed, frequency, or use it as trigger). | ||
+ | |||
+ | ===== prinft ===== | ||
+ | |||
+ | The LED is pretty simple but also very limited. | ||
+ | The next step is printing messages on the console about what is being done. | ||
+ | For the communication I use a USART port. | ||
+ | They are easy to configure and run, reliable, and simple to connect to. | ||
+ | It's also fast enough to send debug messages. | ||
+ | |||
+ | With these messages I can show multiple states, the history of events, and ongoing actions. | ||
+ | But don't use USART in interrupt service routines. | ||
+ | That just creates a mess. | ||
+ | |||
+ | ===== GDB ===== | ||
+ | |||
+ | The [[https:// | ||
+ | |||
+ | Often it's used to debug local computer software, but it can also be used to debug software running on a remote micro-controller. | ||
+ | For that you just need as [[#SWJ]] adapter to be able to control the hardware, and software making use of this adapter such as [[# | ||
+ | Then tell GDB to connect to this remote target, through this SWJ software. | ||
+ | |||
+ | Here a quick example using [[# | ||
+ | arm-none-eabi-gdb --eval-command=" | ||
+ | |||
+ | ... | ||
+ | Reading symbols from firmware.elf...done. | ||
+ | Remote debugging using | openocd --file interface/ | ||
+ | Open On-Chip Debugger 0.10.0-dev-00189-g554313b (2016-01-12-16: | ||
+ | ... | ||
+ | Info : STLINK v2 JTAG v17 API v2 SWIM v4 VID 0x0483 PID 0x3748 | ||
+ | Info : using stlink api v2 | ||
+ | Info : Target voltage: 3.286573 | ||
+ | Info : stm32f1x.cpu: | ||
+ | Info : accepting ' | ||
+ | Info : device id = 0x20036410 | ||
+ | Info : flash size = 128kbytes | ||
+ | undefined debug reason 7 - target needs reset | ||
+ | 0x00000000 in ?? () | ||
+ | |||
+ | (gdb) monitor halt | ||
+ | stm32f1x.cpu: | ||
+ | target halted due to debug-request, | ||
+ | xPSR: 0x21000000 pc: 0x08002314 msp: 0x20004f80 | ||
+ | stm32f1x.cpu: | ||
+ | target halted due to debug-request, | ||
+ | xPSR: 0x21000000 pc: 0x08002314 msp: 0x20004f80 | ||
+ | |||
+ | (gdb) backtrace | ||
+ | #0 0x08002314 in main () at main.c:193 | ||
+ | |||
+ | (gdb) frame | ||
+ | #0 0x08002314 in main () at main.c:193 | ||
+ | 193 __WFI(); | ||
+ | </ | ||
+ | |||
+ | This is pretty useful to check the state (to figure out where the code runs havoc) and control the flow, even in interrupt service routines. | ||
+ | |||
+ | ===== SWO ===== | ||
+ | |||
+ | TODO |
stm32f1xx.txt · Last modified: 2024/01/07 17:49 by 127.0.0.1