Skip to content

Commit 08e9a6e

Browse files
committed
Use STM_BOARD env var to select which board to target on stm32-blink example
1 parent 147b43a commit 08e9a6e

File tree

10 files changed

+220
-234
lines changed

10 files changed

+220
-234
lines changed

.github/workflows/build-stm.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,5 @@ jobs:
4040
working-directory: ${{ matrix.example }}
4141
run: |
4242
pip3 install -r ../Tools/requirements.txt
43+
export STM_BOARD=STM32F746G_DISCOVERY
4344
./build-elf.sh

stm32-blink/Board.swift

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift open source project
4+
//
5+
// Copyright (c) 2023 Apple Inc. and the Swift project authors.
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
//
10+
//===----------------------------------------------------------------------===//
11+
12+
#if STM32F746G_DISCOVERY
13+
14+
typealias Board = STM32F746Board
15+
enum STM32F746Board {
16+
static func initialize() {
17+
// (1) AHB1ENR[lecConfig.0] = 1 ... enable clock
18+
setRegisterBit(
19+
baseAddress: RCC.BaseAddress, offset: RCC.Offsets.AHB1ENR,
20+
bit: RCC.AHB1ENRBit(for: ledConfig.0),
21+
value: 1)
22+
// (2) MODER[1] = 1 ... set mode to output
23+
setRegisterTwoBitField(
24+
baseAddress: GPIO.GPIOi_BaseAddress, offset: GPIO.Offsets.MODER,
25+
bitsStartingAt: 2 * ledConfig.1, value: 1)
26+
// (3) OTYPER[1] = 0 ... output type is push-pull
27+
setRegisterBit(
28+
baseAddress: GPIO.GPIOi_BaseAddress, offset: GPIO.Offsets.OTYPER,
29+
bit: ledConfig.1,
30+
value: 0)
31+
// (4) OSPEEDR[1] = 2 ... speed is high
32+
setRegisterTwoBitField(
33+
baseAddress: GPIO.GPIOi_BaseAddress, offset: GPIO.Offsets.OSPEEDR,
34+
bitsStartingAt: 2 * ledConfig.1, value: 2)
35+
// (5) PUPDR[1] = 2 ... set pull to down
36+
setRegisterTwoBitField(
37+
baseAddress: GPIO.GPIOi_BaseAddress, offset: GPIO.Offsets.PUPDR,
38+
bitsStartingAt: 2 * ledConfig.1, value: 2)
39+
40+
ledOff()
41+
}
42+
43+
static func ledOn() {
44+
// ODR[1] = 1
45+
setRegisterBit(
46+
baseAddress: GPIO.GPIOi_BaseAddress, offset: GPIO.Offsets.ODR, bit: 1,
47+
value: 1)
48+
}
49+
50+
static func ledOff() {
51+
// ODR[1] = 0
52+
setRegisterBit(
53+
baseAddress: GPIO.GPIOi_BaseAddress, offset: GPIO.Offsets.ODR, bit: 1,
54+
value: 0)
55+
}
56+
57+
static func delay(milliseconds: Int) {
58+
for _ in 0..<10_000 * milliseconds {
59+
nop()
60+
}
61+
}
62+
}
63+
64+
#elseif NUCLEO_F103RB
65+
66+
typealias Board = STM32F1Board
67+
enum STM32F1Board {
68+
static func initialize() {
69+
// (1) APB2ENR[ledConfig.0] = 1 ... enable clock
70+
setRegisterBit(
71+
baseAddress: RCC.BaseAddress, offset: RCC.Offsets.APB2ENR,
72+
bit: RCC.APB2ENRBit(for: ledConfig.0),
73+
value: 1)
74+
// (2) CRL.MODE[ledConfig.1] = 0b11 ... set mode to output, high speed
75+
setRegisterTwoBitField(
76+
baseAddress: GPIO.GPIOBaseAddress(for: ledConfig.0),
77+
offset: GPIO.Offsets.CRL,
78+
bitsStartingAt: 4 * ledConfig.1, value: 3)
79+
// (3) CRL.CNF[ledConfig.1] = 0b00 ... general purpose, push-pull
80+
setRegisterTwoBitField(
81+
baseAddress: GPIO.GPIOBaseAddress(for: ledConfig.0),
82+
offset: GPIO.Offsets.CRL,
83+
bitsStartingAt: 4 * ledConfig.1 + 2, value: 0)
84+
85+
ledOff()
86+
}
87+
88+
static func ledOn() {
89+
// ODR[ledConfig.1] = 1
90+
setRegisterBit(
91+
baseAddress: GPIO.GPIOBaseAddress(for: ledConfig.0),
92+
offset: GPIO.Offsets.ODR, bit: ledConfig.1,
93+
value: 1)
94+
}
95+
96+
static func ledOff() {
97+
// ODR[ledConfig.1] = 0
98+
setRegisterBit(
99+
baseAddress: GPIO.GPIOBaseAddress(for: ledConfig.0),
100+
offset: GPIO.Offsets.ODR, bit: ledConfig.1,
101+
value: 0)
102+
}
103+
104+
static func delay(milliseconds: Int) {
105+
for _ in 0..<10_000 * milliseconds {
106+
nop()
107+
}
108+
}
109+
}
110+
111+
#else
112+
113+
#error("Unknown board")
114+
115+
#endif

stm32-blink/BridgingHeader.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,6 @@
1111

1212
#pragma once
1313

14-
#include <stdint.h>
15-
16-
static inline __attribute((always_inline)) uint32_t volatile_load_uint32_t(const volatile uint32_t * _Nonnull source) {
17-
return *((const volatile uint32_t * _Nonnull) source);
18-
}
19-
20-
static inline __attribute((always_inline)) void volatile_store_uint32_t(volatile uint32_t * _Nonnull destination, uint32_t value) {
21-
*((volatile uint32_t * _Nonnull) destination) = value;
22-
}
23-
2414
static inline __attribute((always_inline)) void nop() {
2515
asm volatile("nop");
2616
}

stm32-blink/Main.swift

Lines changed: 10 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -9,158 +9,21 @@
99
//
1010
//===----------------------------------------------------------------------===//
1111

12-
enum GPIOBank: Int {
13-
case a, b, c, d, e, f, g, h, i, j, k
14-
}
15-
typealias GPIOPin = Int
16-
17-
// I1 pin on STM32F746 Discovery Board
18-
//let ledConfig: (GPIOBank, GPIOPin) = (.i, 1)
19-
20-
// A5 aka "Arduino D13" pin on Nucleo-64 boards
21-
let ledConfig: (GPIOBank, GPIOPin) = (.a, 5)
22-
23-
#if STM32F74_F75
24-
25-
typealias Board = STM32F746Board
26-
enum STM32F746Board {
27-
static func initialize() {
28-
// (1) AHB1ENR[i] = 1 ... enable clock
29-
setRegisterBit(
30-
baseAddress: RCC.BaseAddress, offset: RCC.Offsets.AHB1ENR, bit: 8,
31-
value: 1)
32-
// (2) MODER[1] = 1 ... set mode to output
33-
setRegisterTwoBitField(
34-
baseAddress: GPIO.GPIOi_BaseAddress, offset: GPIO.Offsets.MODER,
35-
bitsStartingAt: 2, value: 1)
36-
// (3) OTYPER[1] = 0 ... output type is push-pull
37-
setRegisterBit(
38-
baseAddress: GPIO.GPIOi_BaseAddress, offset: GPIO.Offsets.OTYPER, bit: 1,
39-
value: 0)
40-
// (4) OSPEEDR[1] = 2 ... speed is high
41-
setRegisterTwoBitField(
42-
baseAddress: GPIO.GPIOi_BaseAddress, offset: GPIO.Offsets.OSPEEDR,
43-
bitsStartingAt: 2, value: 2)
44-
// (5) PUPDR[1] = 2 ... set pull to down
45-
setRegisterTwoBitField(
46-
baseAddress: GPIO.GPIOi_BaseAddress, offset: GPIO.Offsets.PUPDR,
47-
bitsStartingAt: 2, value: 2)
48-
49-
ledOff()
50-
}
51-
52-
static func ledOn() {
53-
// ODR[1] = 1
54-
setRegisterBit(
55-
baseAddress: GPIO.GPIOi_BaseAddress, offset: GPIO.Offsets.ODR, bit: 1,
56-
value: 1)
57-
}
58-
59-
static func ledOff() {
60-
// ODR[1] = 0
61-
setRegisterBit(
62-
baseAddress: GPIO.GPIOi_BaseAddress, offset: GPIO.Offsets.ODR, bit: 1,
63-
value: 0)
64-
}
65-
66-
static func delay(milliseconds: Int) {
67-
for _ in 0..<10_000 * milliseconds {
68-
nop()
69-
}
70-
}
71-
}
72-
73-
#elseif STM32F1
74-
75-
typealias Board = STM32F1Board
76-
enum STM32F1Board {
77-
static func initialize() {
78-
// (1) IOPENR[ledConfig.0] = 1 ... enable clock
79-
setRegisterBit(
80-
baseAddress: RCC.BaseAddress, offset: RCC.Offsets.APB2ENR, bit: RCC.APB2ENRBit(for: ledConfig.0),
81-
value: 1)
82-
// (2) MODE[1] = 0b11 ... set mode to output, high speed
83-
setRegisterTwoBitField(
84-
baseAddress: GPIO.GPIOBaseAddress(for: ledConfig.0), offset: GPIO.Offsets.CRL,
85-
bitsStartingAt: 4 * ledConfig.1, value: 3)
86-
// (3) CNF[1] = 0b00 ... general purpose, push-pull
87-
setRegisterTwoBitField(
88-
baseAddress: GPIO.GPIOBaseAddress(for: ledConfig.0), offset: GPIO.Offsets.CRL,
89-
bitsStartingAt: 4 * ledConfig.1 + 2, value: 0)
12+
#if STM32F746G_DISCOVERY
9013

91-
ledOff()
92-
}
93-
94-
static func ledOn() {
95-
// ODR[1] = 1
96-
setRegisterBit(
97-
baseAddress: GPIO.GPIOBaseAddress(for: ledConfig.0), offset: GPIO.Offsets.ODR, bit: ledConfig.1,
98-
value: 1)
99-
}
100-
101-
static func ledOff() {
102-
// ODR[1] = 0
103-
setRegisterBit(
104-
baseAddress: GPIO.GPIOBaseAddress(for: ledConfig.0), offset: GPIO.Offsets.ODR, bit: ledConfig.1,
105-
value: 0)
106-
}
107-
108-
static func delay(milliseconds: Int) {
109-
for _ in 0..<10_000 * milliseconds {
110-
nop()
111-
}
112-
}
113-
}
14+
// I1 pin aka "Arduino D13" pin on STM32F746 Discovery Board
15+
// https://www.st.com/resource/en/schematic_pack/mb1191-f746ngh6-c01_schematic.pdf
16+
let ledConfig: (GPIOBank, GPIOPin) = (.i, 1)
11417

115-
#elseif STM32C0
18+
#elseif NUCLEO_F103RB
11619

117-
typealias Board = STM32C0Board
118-
enum STM32C0Board {
119-
static func initialize() {
120-
// (1) IOPENR[ledConfig.0] = 1 ... enable clock
121-
setRegisterBit(
122-
baseAddress: RCC.BaseAddress, offset: RCC.Offsets.IOPENR, bit: ledConfig.0.rawValue,
123-
value: 1)
124-
// (2) MODER[1] = 1 ... set mode to output
125-
setRegisterTwoBitField(
126-
baseAddress: GPIO.GPIOBaseAddress(for: ledConfig.0), offset: GPIO.Offsets.MODER,
127-
bitsStartingAt: 2 * ledConfig.1, value: 1)
128-
// (3) OTYPER[1] = 0 ... output type is push-pull
129-
setRegisterBit(
130-
baseAddress: GPIO.GPIOBaseAddress(for: ledConfig.0), offset: GPIO.Offsets.OTYPER, bit: ledConfig.1,
131-
value: 0)
132-
// (4) OSPEEDR[1] = 2 ... speed is high
133-
setRegisterTwoBitField(
134-
baseAddress: GPIO.GPIOBaseAddress(for: ledConfig.0), offset: GPIO.Offsets.OSPEEDR,
135-
bitsStartingAt: 2 * ledConfig.1, value: 2)
136-
// (5) PUPDR[1] = 2 ... set pull to down
137-
setRegisterTwoBitField(
138-
baseAddress: GPIO.GPIOBaseAddress(for: ledConfig.0), offset: GPIO.Offsets.PUPDR,
139-
bitsStartingAt: 2 * ledConfig.1, value: 2)
20+
// A5 pin aka "Arduino D13" pin on Nucleo-64 boards
21+
// https://www.st.com/resource/en/user_manual/um1724-stm32-nucleo64-boards-mb1136-stmicroelectronics.pdf
22+
let ledConfig: (GPIOBank, GPIOPin) = (.a, 5)
14023

141-
ledOff()
142-
}
24+
#else
14325

144-
static func ledOn() {
145-
// ODR[1] = 1
146-
setRegisterBit(
147-
baseAddress: GPIO.GPIOBaseAddress(for: ledConfig.0), offset: GPIO.Offsets.ODR, bit: ledConfig.1,
148-
value: 1)
149-
}
150-
151-
static func ledOff() {
152-
// ODR[1] = 0
153-
setRegisterBit(
154-
baseAddress: GPIO.GPIOBaseAddress(for: ledConfig.0), offset: GPIO.Offsets.ODR, bit: ledConfig.1,
155-
value: 0)
156-
}
157-
158-
static func delay(milliseconds: Int) {
159-
for _ in 0..<10_000 * milliseconds {
160-
nop()
161-
}
162-
}
163-
}
26+
#error("Unknown board")
16427

16528
#endif
16629

stm32-blink/README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ This example shows a simple baremetal firmware for an STM32 board that blinks an
1616
```console
1717
$ cd stm32-blink
1818
$ export TOOLCHAINS=$(plutil -extract CFBundleIdentifier raw /Library/Developer/Toolchains/swift-latest.xctoolchain/Info.plist)
19+
$ export STM_BOARD=STM32F746G_DISCOVERY # or NUCLEO_F103RB
1920
$ ./build-macho.sh
2021
$ st-flash --reset write .build/blink.bin 0x08000000
2122
```
@@ -26,11 +27,13 @@ $ st-flash --reset write .build/blink.bin 0x08000000
2627
- Build and upload the program to flash memory of the microcontroller:
2728
```console
2829
$ cd stm32-blink
30+
31+
# If on macOS, select the right latest nightly toolchain (on Linux this is not needed):
2932
$ export TOOLCHAINS=$(plutil -extract CFBundleIdentifier raw /Library/Developer/Toolchains/swift-latest.xctoolchain/Info.plist)
33+
34+
$ export STM_BOARD=STM32F746G_DISCOVERY # or NUCLEO_F103RB
3035
$ ./build-elf.sh
31-
$ st-util
32-
(then in a separate terminal)
33-
$ st-flash --reset write .build/blink.elf 0x08000000
36+
$ st-flash --format ihex --reset write .build/blink.hex
3437
```
3538
- The green LED next to the RESET button should now be blinking in a pattern.
3639

0 commit comments

Comments
 (0)