Olimex STM32 P103 Development Kit Demos
OVERVIEW This suite contains a number of small, simple demo programs for exercising the various peripherals of the STM32 Microcontroller.
A makefile is included which can compile the demos, program/debug the development board, and run/debug them in QEMU.
DEPENDENCIES The makefile and linker scripts are intended to be run in a GNU/Linux environment.
To compile, you need the ARM GCC compiler and utilities (arm-none-eabi-gcc, arm-none-eabi-ld, arm-none-eabi-as, arm-none-eabi-objcopy, arm-none-eabi-objdump).
I originally used the CodeSourcery G++ Lite toolchain for ARM (Sourcery CodeBench Lite 2012.03-56 for ARM EABI), but this no longer appears to be supported. A 2013 version is available at https://sourcery.sw.siemens.com/GNUToolchain/release2635, but I was not able to run the installer on my machine.
I currently use the GNU Arm Embedded Toolchain located at https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm (Version 10.3-2021.07). To install this: 1) Download and unpack the Linux x86_64 Tarball (or approriate version) 2) Add the bin folder (Which contains the toolchain binaries) to the path using the following command: export PATH="/path_to_tarball_contents/bin:$PATH" 3) You are ready to compile stm32_p103_demos - see the "USING THE MAKEFILE" section below.
To run the QEMU examples, you need a modifed version of QEMU which contains the STM32 peripherals. This can be found at: https://github.com/beckus/qemu_stm32 . The QEMU_ARM_DIR can be set to the location of the qemu_system_arm executable. If the variable is not set, it defaults to ../qemu_stm32/arm-softmmu/ .
For the UART examples, I used cutecom as my terminal software. For the echo examples, you need to use the "No line end" option. The FreeRTOS example needs to have "LF line end". Otherwise it will send a line feed and overflow the UART buffer (since we are not using flow control). Connect with these settings: 9600 Baud Rate 8 Data bits 1 Stop bit
Note that the peripheral library knows the clock rate of the board via the HSE_VALUE and HSI_VALUE macros in libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x.h .
DEMOS The following demos are provided. All of them except blink_flash_asm are written in C, and use ST's initialization library.
adc_single - Samples analog data using the Analog to Digitcal Converter (ADC). This program performs a series of single samples and prints the results to the UART.
There are several modes. To scroll through the modes, press the button on
the development board:
Mode 1 - Print the value of the internal temperature sensor.
Also attempts to calculate the actual temperature using the formula
in the reference manual. On my board, this gives a high
temperature which I assume is wrong. Further investigation is
needed.
Mode 2 - Print value of the internal voltage reference.
Mode 3 - Print value on the external pin PC.0
Mode 4 - A special mode that does not use the ADC, but prints
the clock configuration. This is useful for debugging.
All numbers are hexadecimal except for the degrees celsius temperature.
One way to drive pin PC.0 with an analog signal is to use a
potentiometer as follows:
VDDA
|
/
\
PC.0 --->/
\
/
\
|
GNDA
blink_flash - Flashes the LED on and off
blink_flash_asm - Same as blink_flash, but written in assembly language. This is the simplest demo, and probably the best example for low-level troubleshooting.
button - Example of using the button in non-interrupt mode. Continuously polls the button and toggles the LED when the button is pressed. Note that this example does not seem to work well in QEMU. When using "sendkey b" (see the button_int demo below), the LED does not toggle. Perhaps this is a timing issue?
button_int - Example of external interrupts. Toggles the LED every time the button is pressed. Note that in QEMU, the button press is simulated by pressing the b key. You will need to do this from the QEMU monitor, by typing the command "sendkey b".
button_int_infinite - Example of why the interrupt flag needs to be cleared. When the button is pressed, the interrupt fires, but the interrupt pending flag is not cleared. This causes the interrupt to repeatedly fire.
c_mem_model - Does not do anything. Declares various variables so that the memory organization can be studied (by viewing the listing or running through the debugger). There are also other listings (e.g. symbol listings) that you can produce, but these aren't automatically created by the makefile.
dac Pending documentation...
freertos_singlethread - Example of using a real time operating system (FreeRTOS). This runs a single task to flash the LED on and off.
freertos_multithread - Example of using a real time operating system (FreeRTOS). This runs the following tasks concurrently: 1) Blink the LED. 2) Print the string "Hello 1" to the RS232 port (twice a second). 3) Print the string "Hello 2" to the RS232 port (once every two seconds). 4) Listens to the RS232 port. When you type a line and then hit the enter key, the line is echoed back.
freertos_cycletask freertos_semaphore1 freertos_streambuffer Pending documentation...
qemu_test - Tests changes made in the QEMU_STM32. Unless you are really interested, you should probably skip this demo.
rtc Pending documentation...
software_int - Periodically generates a software interrupt that in turn toggles the LED.
stkalign Tests the STKALIGN bit in the NVIC CCR register. This example must be run in a debugger to verify the alignment is working. I have had limited success with running this with QEMU. Unless you are really interested, you should probably skip this demo.
systick Uses the Cortex NVIC system tick timer to flash the LED.
timer Uses the timer to count up and down.
There are several modes. To scroll through the modes, press the button on
the development board:
Mode 1 - Count up for five seconds. Once five seconds have elapsed, the
LED is toggled and the count resets to 1.
Mode 2 - Similar to Mode 1, but counts down instead of up.
Mode 3 - Similar to Modes 1 and 2, but alternately counts up and then down.
Mode 4 - Counts in one-shot mode. Each time the count is finished, the
timer will be re-enabled to do another one shot count.
Mode 4 - Counts up, but when the count reaches 3, the program interrupts the
count using the UG flag. This resets the count back to 1.
Mode 6 - A special mode that does not use the timer, but prints
the clock configuration. This is useful for debugging.
` All numbers are in decimal.
* Note that the timer in QEMU STM32 does not behave exactly like real
hardware. In particular, the counting does not always go in the right
direction, and the one shot mode does not appear to work properly.
uart_repeat_write Tests the UART write functionality. Continues to write the word "Hello" to the UART. This example uses polling.
uart_repeat_write_int Tests the UART write functionality, but using interrupts. It repeatedly writes an X to the UART.
uart_echo Tests the UART read/write functionality. Waits for a character to be received and then echoes the character back. This example uses polling.
uart_echo_int The same as uart_echo, except this example is interrupt driven.
FOLDER STRUCTURE demos Contains the demo source code. eclipse Contains Eclipse debug launchers that can be imported into Eclipse. Only launchers for the blink_flash example are included. Other launchers can be created by duplicating these. Debug blink_flash Starts a remote debug session to debug the blink_flash program. This will connect to QEMU or to OpenOCD, both of which must be in debug mode. Debug QEMU (blink_flash) Starts debugging QEMU's code while it is running the blink_flash example. Note that the SIGUSR1 signal will keep firing, so you will need to disable the signal breakpoint, or the debugger will keep pausing. libraries Contains shared libraries from external sources libraries/CMSIS Contains CMSIS source code (a common API for ARM Cortex cores that is vendor independent) - copied from STMicro's STM32F10x_StdPeriph_Lib.zip V3.5.0. Note that the file CMSIS/CM3/DeviceSupport/ST/STM32F10x/stm32f10x.h has been odified to uncomment the "#define STM32F10X_MD" and "#define USE_STDPERIPH_DRIVER" lines. libraries/FreeRTOS Contains the FreeRTOS real time operating system source code - this is a copy of the Source folder from FreeRTOSV7.1.1.zip libraries/STM32F10x_StdPeriph_Driver Contains STM32 peripheral libraries - copied from STMicro's STM32F10x_StdPeriph_Lib.zip V3.5.0 openocd Contains STM32 openocd configuration scripts.
USING THE MAKEFILE The makefile contains targets that can be used to compile, run, and debug the demo programs.
Compiling:
To compile one of the programs, run "make
Programming a Microcontroller: To program/debug a microcontroller, you will need a programmer that is compatible with openocd, and you will need openocd installed.
To program the microcontroller with
By default it uses openocd and assumes you are using an Olimex ARM-USB-TINYH programmer. This can be overriden by changing the OPENOCD_INTERFACE variable (or declaring an environment variable of the same name). Look inside the makefile for an example. Once the microntroller is programmed, the program will automatically start executing.
Running in QEMU:
See the DEPENDENCIES section for more details. To run
This should attach the RS232 UART (i.e. UART2) to standard in/out, but it doesn't seem to work for me. To test the UART, you can use one of these targets: