Introduction

The Nucleo-32 STM32F042 development board features the ARM Cortex-M0 based STM32F042K6 microcontroller with 48 MHz clock speed, 32 KB Flash storage and 6 KB static RAM.

Hardware

The hardware is described in the STM32 Nucleo-32 board user manual, which applies to all Nucleo-32 boards. The board is sized like an Arduino Micro, 20 pins tall (one-tenth-inch pin spacing) and 7 pins wide. The pins on the board are compatible with the Arduino Nano so that the same extension boards can be attached.

Pin Layout



Solder Bridges

There are a number of solder bridges on both sides of a Nucleo-32 board. They are labeled with the SB prefix. Solder bridges are used for (permanently) reconfiguring the board. They are cheaper than, for example, DIP switches and take little space on circuit boards. Some solder bridges on the Nucleo have solder on both ends and an air gap in between. These are in OFF state. The two ends need to be short-circuited with solder to switch them to the ON state. Other solder bridges have a resistor between the soldered ends. These bridges are in ON state. The resistor needs to be desoldered to switch them to the OFF state. Some of the solder bridges that are ON by default are explained in the table below.

Bridge Description
SB9 Connects the NRST reset signal from ST-LINK to the NRST pin of STM32. Disconnect when using an external power supply.
SB10 Connects VREF+ to VDD by default. Otherwise VREF+ is provided by pin 13 on header row CN4.
SB11 Connects VSS to pin 16 of the STM32 (U2). Disconnecting frees up pin 16 on Nucleo STM32F031 boards for use as GPIO pin PB2.
SB13 Connects VSS to pin 32 of the STM32. Disconnecting frees up pin 32 on Nucleo STM32F031 boards for use as GPIO pin PB8.
SB12 Connects pin 31 of the STM32 to Ground via a 10 kΩ pull-down resistor so that pin 31 is used as BOOT0 pin. Disconnecting frees pin 31 on Nucleo STM32F042 boards for use as GPIO pin PB8.
SB15 Connects the green LED LD3 to the Arduino pin D13.
SB16 Connects pin 7 on header row CN4 to STM32 pin PB6 so that Arduino Nano pin A5 can be used as I2C SDA. Disconnecting makes pin 7 usable as Arduino Nano analog input A5 while breaking I2C capability.
SB18 Connects pin 8 on header row CN4 to STM32 pin PB7 so that Arduino Nano pin A4 can be used as I2C SCL. Disconnecting makes pin 8 usable as Arduino Nano analog input A4 while breaking I2C capability.

SB2 and SB3 are for disconnecting the USART interface from ST-LINK/V2-1 with which the STM32 is can be flashed and debugged via USB.

Clock speed

The value for the high-speed external clock (HSE) speed is set by the HSE_VALUE preprocessor definition. The default value is 8 MHz. You shouldn't need to change this. The clock speed multiplier for is given by RCC_CFGR_PLLMULL (RCC = Reset and Clock Control, PLL = Phase Locked Loop). When setting up a new project, GNU MCU Eclipse Plugin pops up a dialog where CPU parameters such as Flash memory size, RAM size, and clock speed can be specified. The given value for the clock speed is then placed into the compiler command line argument -DHSE_VALUE.

Debugging

Debugging from Eclipse

Open the debug configurations window and create a new GDB OpenOCD Debugging configuration.

  • Under Main, enter Debug/<executable-name>.elf in the C/C++ Application text field
  • Under Debugger, enter the path to the configuration file for the target chip in the Config options text area in the OpenOCD Setup section. For a standard OpenOCD installation on Linux, the configuration files are located in /usr/share/openocd/scripts/board/. Don't forget the leading -f to indicate that the configuration is read from file. Example: -f /usr/share/openocd/scripts/board/st_nucleo_f0.cfg. Note that the scripts folder may be located elsewhere when OpenOCD is installed on your work system as part of a micro-controller development tools package.
  • The value for the GDB port field under Debugger should be 3333


Running without Debugging

Use OpenOCD to flash the Release build to the microcontroller

cd <project-directory>
openocd -f /usr/share/openocd/scripts/board/st_nucleo_f0.cfg -c "program Release/<executable-name>.elf verify reset exit"


Bootloader

STM32 microcontrollers come with a built-in bootloader on an integrated ROM. Depending on the logical value of the BOOT0 hardware pin or the value of the BOOT0 option byte (OB - stored in a special region in flash memory), the bootloader is executed instead of the user program in flash memory. The bootloader thus runs after the system has been initialized as usual (plus I2C and USB Full Speed drivers). The bootloader will check for data on the USART, I2C and USB serial communication lines, in that order, and run the appropriate subroutine for storing the incoming data in the user program region of the flash memory.

On STM32F042, the bootloader is activated by one of these combinations

  • Boot0 (hardware pin) = 1 and nBoot1(bit) = 1 and nBoot0_SW(bit) = 1
  • nBoot0 (software bit) = 0 and nBoot1(bit) = 1 and nBoot0_SW(bit) = 0
  • Boot0 (hardware pin) = 0 and nBoot0_SW (software bit) = 1 and main flash memory is empty


The BOOT0 hardware pin is pin 31 of the STM32. By default, it is connected to Ground via a pull-down resistor and a solder bridge that can be desoldered for changing the configuration permanently.

Refer to chapter 7 of the application note AN2606 for the specific of the STM32F04xxx bootloader.

OpenOCD and the USART Bootloader

Some STM32 experimentation boards are designed so that the user can select the boot mode with a jumper. The Nucleo STM32F042 does not expose the BOOT0 pin with a header. Furthermore, OpenOCD does not require a physical change on the board in order to flash the user program. So, how does this software-only method of activating the bootloader work?

Using the DFU Bootloader

DFU (Device Firmware Update) is part of the USB standard and specifies the process of sending (firmware) code to a USB-connected device.
The schematic below shows how an external pull-up resistor can be connected to USB_DP if needed.

STM32F04 configuration for DFU system memory boot mode (from AN2606)

Feature/Peripheral State Comment
USB Enabled USB used in FS mode
USB_DM line Input/Output Connect to pin PA11 on STM32.
USB_DP line Input/Output Connect to pin PA12 on STM32. No external pull-up resistor required.



Interestingly, connecting the USB cable to a USB power outlet prevents the Nucleo from booting into the flashed user program.

Programming

Please download from STMicroelectronics the Programming Manual PM0215 for their STM32F0xxx series Cortex-M0 microcontrollers. The manual is a guide to the low-level instruction set of the processor for programming in ARM Assembly.

STM32F0xxx Instruction Set

Being an ARM Cortex-M0 compatible processor, the STM32F042 implements the ARMv6-M architecture with a modified Thumb instruction set.

Mnemonic Operands Brief description Flags
ADCS {Rd,} Rn, Rm Add with Carry N,Z,C,V
ADD{S} {Rd,} Rn, <Rm|#imm> Add N,Z,C,V
ADR Rd label PC-relative Address to Register -
ANDS {Rd,} Rn, Rm Bitwise AND N,Z
ASRS {Rd,} Rm, <Rs|#imm> Arithmetic Shift Right N,Z,C
B{cc} label Branch {conditionally} -
BICS {Rd,} Rn, Rm Bit Clear N,Z
BKPT #imm Breakpoint -
BL label Branch with Link -
BLX Rm Branch indirect with Link -
BX Rm Branch indirect -
CMN Rn, Rm Compare Negative N,Z,C,V
CMP Rn, <Rm|#imm> Compare N,Z,C,V
CPSID i Change Processor State, Disable Interrupts -
CPSIE i Change Processor State, Enable Interrupts -
DMB - Data Memory Barrier -
DSB - Data Synchronization Barrier -
EORS {Rd,} Rn, Rm Exclusive OR N,Z
ISB - Instruction Synchronization Barrier -
LDM Rn{!}, reglist Load Multiple registers, increment after -
LDR Rt, label Load Register from PC-relative address -
LDR Rt, [Rn, <Rm|#imm>] Load Register with word -
LDRB Rt, [Rn, <Rm|#imm>] Load Register with byte -
LDRH Rt, [Rn, <Rm|#imm>] Load Register with halfword -
LDRSB Rt, [Rn, <Rm|#imm>] Load Register with signed byte -
LDRSH Rt, [Rn, <Rm|#imm>] Load Register with signed halfword -
LSLS {Rd,} Rn, <Rs|#imm> Logical Shift Left N,Z,C
LSRS {Rd,} Rn, <Rs|#imm> Logical Shift Right N,Z,C
MOV{S } Rd, Rm Move N,Z
MRS Rd, spec_reg Move to general register from special register -
MSR spec_reg, Rm Move to special register from general register N,Z,C,V
MULS Rd, Rn, Rm Multiply, 32-bit result N,Z
MVNS Rd, Rm Bitwise NOT N,Z
NOP - No Operation -
ORRS {Rd,} Rn, Rm Logical OR N,Z
POP reglist Pop registers from stack -
PUSH reglist Push registers onto stack -
REV Rd, Rm Byte-Reverse word -
REV16 Rd, Rm Byte-Reverse packed halfwords -
REVSH Rd, Rm Byte-Reverse signed halfword -
RORS {Rd,} Rn, Rs Rotate Right N,Z,C
RSBS {Rd,} Rn, #0 Reverse Subtract N,Z,C,V
SBCS {Rd,} Rn, Rm Subtract with Carry N,Z,C,V
SEV - Send Event -
STM Rn!, reglist Store Multiple registers, increment after -
STR Rt, [Rn, <Rm|#imm>] Store Register as word -
STRB Rt, [Rn, <Rm|#imm>] Store Register as byte -
STRH Rt, [Rn, <Rm|#imm>] Store Register as halfword -
SUB{S} {Rd,} Rn, <Rm|#imm> Subtract N,Z,C,V
SVC #imm Supervisor Call -
SXTB Rd, Rm Sign extend byte -
SXTH Rd, Rm Sign extend halfword -
TST Rn, Rm Logical AND based test N,Z
UXTB Rd, Rm Zero extend a byte -
UXTH Rd, Rm Zero extend a halfword -
WFE - Wait For Event -
WFI - Wait For Interrupt -


Memory Model

STM32F0xxx Memory Map
Start End Size Label Access Type Description
0x00000000 0x1FFFFFFF 512 MB Code Normal Region for executable code and data.
0x20000000 0x3FFFFFFF 512 MB SRAM Normal Region for executable code and data.
0x40000000 0x5FFFFFFF 512 MB Peripheral Device external
0x60000000 0x9FFFFFFF 1 GB External RAM Normal Data-only region
0xA0000000 0xDFFFFFFF 1 GB External Device Device external
0xE0000000 0xE00FFFFF 1 MB Private Peripheral Bus Strongly Ordered Reserved for core peripheral registers (NVIC, system timer, system control block). Access performed word by word.
0xE010.0000 0xFFFFFFFF 511 MB Device Device Includes all the STM32 standard peripherals.
Memory Access Types
Type Description
Normal The sequence of access can be changed by the processor in order to predictively minimize wait times.
Device The sequence is preserved relative to other memory accesses of this type or of the Strongly Ordered type.
Strongly Ordered The sequence is preserved relative to all other memory accesses

STM32F042 addresses of interest

  • On reset, the main stack pointer (MSP) points at 0x200017e8 in SRAM.
  • Option Bytes start at 0x1FFFF800
  • GPIO ports (only A, B, and F available)
    • A starts at 0x48000000
    • B starts at 0x48000400
    • F starts at 0x48001400
  • SysTick base address is 0xE000E010
  • NVIC base address is 0xE000E100
  • System Control Block (SCB) base address is 0xE000ED00


Memory Barrier Instructions

In order to optimize performance, the processor may fetch memory contents ahead of execution of a memory access instruction while a previous instruction is being executed. Memory barrier instructions should be used if the program logic depends on the sequence of memory access. These are

DMB             ; Data Memory Barrier
DSB             ; Data Synchronization Barrier
ISB             ; Instruction Synchronisation Barrier


GPIO

Control Registers

The GPIO port control registers are accessed through memory locations that connect to the Advanced High-performance Bus (AHB) of the Cortex-M0 processor. Each GPIO port is controlled by the registers listed below. In each register, the setting for an individual pin of a GPIO port is stored in certain bits inside the register. Since each port has up to 16 pins and registers are at most 32 bits wide, the setting for each pin can be up to 2 bits wide.

register name length (bytes) offset (bytes) description
MODER 4 0x00 mode register, 2 bits per pin, modes: In (0x00), Out (0x01), Alternate Function (0x02), Analog In/Out (0x03)
OTYPER 2 0x04 output type register, 1 bit per pin, two types defined: PP (0x00), OD (0x01)
RESERVED0 2 0x06 reserved
OSPEEDR 4 0x08 output speed register, 2 bits per pin, three speeds defined: Level1 (0x00), Level2 (0x01), Level3 (0x03)
PUPDR 4 0x0C pull-up/pull-down register, 2 bits per pin, three modes defined: NoPull (0x00), Up (0x01), Down (0x02)
IDR 2 0x10 input data register, 1 bit per pin, two modes defined:
RESERVED1 2 0x12 reserved
ODR 2 0x14 output data register, 1 bit per pin, two modes defined:
RESERVED2 2 0x16 reserved
BSRR 4 0x18 bit set/reset register, 2 bits per pin, 1 bit for set in the lower half word, 1 bit for reset in the upper half word
LCKR 4 0x1C configuration lock register, 1 bit per pin within the lower half word, upper half word for locking the complete port
AFRL 4 0x20 alternate function register for pins 0 through 7, 4 bits per pin
AFRH 4 0x24 alternate function register for pins 8 through 15, 4 bits per pin
BRR 2 0x28 bit reset register, 1 bit per pin, two modes defined:
RESERVED3 2 0x2A reserved


Available GPIO Pins

The Nucleo-32 STM32F042 board comes with GPIO header pins for ports A (registers' base address: 0x48000000), B (registers' base address: 0x48000400) and F (registers' base address: 0x48001400). Specifically, the pins are A0–A12, B0, B1, B3–B7, F0, and F1.

Initialization



System Timer (SysTick)

Control Registers

SysTick, the 24-bit system timer, is controlled and accessed through four consecutive 32-bit memory locations (starting at 0xE000E010) that connect to the registers of the timer over the Private Peripheral Bus.

Address Name Access Type Description
0xE000E010 CTRL (SYST_CSR) read/write Control and status
0xE000E014 LOAD (SYST_RVR) read/write Reload value
0xE000E018 VAL (SYST_CVR) read/write Current value
0xE000E01C CALIB (SYST_CALIB) read-only Calibration


Usage


Please refer to section 4.4 of the ARM Cortex-M0 Devices Generic User Guide to learn more about SysTick and how it is used.

CMSIS

We usually want to avoid programming in assembly because it's a tedious and error prone activity. Fortunately, ARM has specified a standard C interface for programming Cortex-M processor. The Cortex-M Standard Interface (CMSIS)

Configuration

Pretty much at the top of the CMSIS header file stm32f0xx.h are the defines for various STM32F0 CPUs. Remove the comment markers from the line

/* #define STM32F042 */


Intrinsic Functions
Functions that generate instructions not provided by ISO/IEC C
Instruction CMSIS intrinsic function
CPSIE I void __enable_irq(void)
CPSID I void __disable_irq(void)
ISB void __ISB(void)
DSB void __DSB(void)
DMB void __DMB(void)
NOP void __NOP(void)
REV uint32_t __REV(uint32_t int value)
REV16 uint32_t __REV16(uint32_t int value)
REVSH uint32_t __REVSH(uint32_t int value)
SEV void __SEV(void)
WFE void __WFE(void)
WFI void __WFI(void)
Functions for accessing special registers
Register CMSIS read function CMSIS write function
PRIMASK uint32_t __get_PRIMASK (void) void __set_PRIMASK (uint32_t value)
CONTROL uint32_t __get_CONTROL (void) void __set_CONTROL (uint32_t value)
MSP uint32_t __get_MSP (void) void __set_MSP (uint32_t TopOfMainStack)
PSP uint32_t __get_PSP (void) void __set_PSP (uint32_t TopOfProcStack)



Debug data: