Skip to content

Commit 865c681

Browse files
authored
Merge pull request #572 from AlexLanzano/stm32f411-support
Implement clock and uart configuration macros for the stm32f4
2 parents 374d605 + 1b37378 commit 865c681

File tree

15 files changed

+300
-116
lines changed

15 files changed

+300
-116
lines changed

.github/workflows/footprint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
3131
- name: Select config
3232
run: |
33-
cp config/examples/stm32f4.config .config && make include/target.h
33+
cp config/examples/stm32f407-discovery.config .config && make include/target.h
3434
3535
- name: Build key tools
3636
run: |

.github/workflows/test-build-cmake.yml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,17 @@ jobs:
3030
- name: Build wolfBoot
3131
run: make -C build
3232

33-
- name: Run CMake build for STM32F4
33+
- name: Run CMake build for STM32F407-DISCOVERY
3434
run: |
3535
rm -rf ./build
36-
cmake -B build -DWOLFBOOT_TARGET=stm32f4 -DWOLFBOOT_PARTITION_SIZE=0x20000 -DWOLFBOOT_SECTOR_SIZE=0x20000 -DWOLFBOOT_PARTITION_BOOT_ADDRESS=0x08020000 -DWOLFBOOT_PARTITION_UPDATE_ADDRESS=0x08040000 -DWOLFBOOT_PARTITION_SWAP_ADDRESS=0x08060000
36+
cmake -B build -DWOLFBOOT_TARGET=stm32f4 -DWOLFBOOT_PARTITION_SIZE=0x20000 -DWOLFBOOT_SECTOR_SIZE=0x20000 -DWOLFBOOT_PARTITION_BOOT_ADDRESS=0x08020000 -DWOLFBOOT_PARTITION_UPDATE_ADDRESS=0x08040000 -DWOLFBOOT_PARTITION_SWAP_ADDRESS=0x08060000 -DCLOCK_SPEED=160000000 -DSTM32_PLLM=8 -DSTM32_PLLN=336 -DSTM32_PLLP=2 -DSTM32_PLLQ=7
37+
- name: Build wolfBoot
38+
run: make -C build
39+
40+
- name: Run CMake build for STM32F411-BLACKPILL
41+
run: |
42+
rm -rf ./build
43+
cmake -B build -DWOLFBOOT_TARGET=stm32f4 -DWOLFBOOT_PARTITION_SIZE=0x20000 -DWOLFBOOT_SECTOR_SIZE=0x20000 -DWOLFBOOT_PARTITION_BOOT_ADDRESS=0x08020000 -DWOLFBOOT_PARTITION_UPDATE_ADDRESS=0x08040000 -DWOLFBOOT_PARTITION_SWAP_ADDRESS=0x08060000 -DCLOCK_SPEED=84000000 -DSTM32_PLLM=25 -DSTM32_PLLN=336 -DSTM32_PLLP=4 -DSTM32_PLLQ=7
3744
- name: Build wolfBoot
3845
run: make -C build
3946

.github/workflows/test-configs.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,11 +272,17 @@ jobs:
272272
arch: arm
273273
config-file: ./config/examples/stm32f4-small-blocks-uart-update.config
274274

275-
stm32f4_test:
275+
stm32f407_discovery_test:
276276
uses: ./.github/workflows/test-build.yml
277277
with:
278278
arch: arm
279-
config-file: ./config/examples/stm32f4.config
279+
config-file: ./config/examples/stm32f407-discovery.config
280+
281+
stm32f411_blackpill_test:
282+
uses: ./.github/workflows/test-build.yml
283+
with:
284+
arch: arm
285+
config-file: ./config/examples/stm32f411-blackpill.config
280286

281287
stm32f7_dualbank_test:
282288
uses: ./.github/workflows/test-build.yml

CMakeLists.txt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,29 @@ if(ARCH STREQUAL "ARM")
238238
if(${WOLFBOOT_TARGET} STREQUAL "stm32f4")
239239
set(ARCH_FLASH_OFFSET 0x08000000)
240240
set(WOLFBOOT_ORIGIN ${ARCH_FLASH_OFFSET})
241+
242+
if(NOT DEFINED CLOCK_SPEED)
243+
message(FATAL_ERROR "CLOCK_SPEED must be defined")
244+
endif()
245+
if(NOT DEFINED STM32_PLLM)
246+
message(FATAL_ERROR "STM32_PLLM must be defined")
247+
endif()
248+
if(NOT DEFINED STM32_PLLN)
249+
message(FATAL_ERROR "STM32_PLLN must be defined")
250+
endif()
251+
if(NOT DEFINED STM32_PLLP)
252+
message(FATAL_ERROR "STM32_PLLP must be defined")
253+
endif()
254+
if(NOT DEFINED STM32_PLLQ)
255+
message(FATAL_ERROR "STM32_PLLQ must be defined")
256+
endif()
257+
add_compile_definitions(
258+
CLOCK_SPEED=${CLOCK_SPEED}
259+
STM32_PLLM=${STM32_PLLM}
260+
STM32_PLLN=${STM32_PLLN}
261+
STM32_PLLP=${STM32_PLLP}
262+
STM32_PLLQ=${STM32_PLLQ}
263+
)
241264
endif()
242265

243266
if(${WOLFBOOT_TARGET} STREQUAL "stm32u5")

IDE/IAR/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ application image starts at address 0x08020000.
1212

1313
```
1414
$template=Get-Content -path ..\..\include\target.h.in;
15-
Get-Content -path ..\..\config\examples\stm32f4.config | ForEach-Object {$v=$_.Split('?='); $a=$v[0]; $b=$v[2]; $template=($template -replace "##$a##",$b) };
15+
Get-Content -path ..\..\config\examples\stm32f407-discovery.config | ForEach-Object {$v=$_.Split('?='); $a=$v[0]; $b=$v[2]; $template=($template -replace "##$a##",$b) };
1616
$template=($template -replace "##.*##","");
1717
Set-Content -path target.h $template
1818
```
@@ -91,4 +91,4 @@ If you are using a STM32F407-discovery board, a red LED will turn on upon applic
9191

9292
## Armored Mode (Glitch Resistance)
9393

94-
If you would like to enable the "Armored" mode (glitch resistance) in IAR you can set the compiler pre-processor macro `WOLFBOOT_ARMORED`. Note: This has only been tested with ECDSA on Cortex-M.
94+
If you would like to enable the "Armored" mode (glitch resistance) in IAR you can set the compiler pre-processor macro `WOLFBOOT_ARMORED`. Note: This has only been tested with ECDSA on Cortex-M.

config/examples/stm32f4-small-blocks-uart-update.config

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,8 @@ WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x00000
2727
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x4000
2828
WOLFBOOT_LOAD_ADDRESS?=0x200000
2929
WOLFBOOT_LOAD_DTS_ADDRESS?=0x400000
30+
CLOCK_SPEED?=160000000
31+
STM32_PLLM?=8
32+
STM32_PLLN?=336
33+
STM32_PLLP?=2
34+
STM32_PLLQ?=7

config/examples/stm32f4.config renamed to config/examples/stm32f407-discovery.config

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,8 @@ WOLFBOOT_SECTOR_SIZE?=0x20000
99
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08020000
1010
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x08040000
1111
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x08060000
12+
CLOCK_SPEED?=160000000
13+
STM32_PLLM?=8
14+
STM32_PLLN?=336
15+
STM32_PLLP?=2
16+
STM32_PLLQ?=7
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
ARCH?=ARM
2+
TARGET?=stm32f4
3+
SIGN?=ED25519
4+
HASH?=SHA256
5+
VTOR?=1
6+
SPMATH?=1
7+
WOLFBOOT_ORIGIN?=0x08000000
8+
WOLFBOOT_PARTITION_SIZE?=0x20000
9+
WOLFBOOT_SECTOR_SIZE?=0x20000
10+
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08020000
11+
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x08040000
12+
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x08060000
13+
CLOCK_SPEED?=84000000
14+
STM32_PLLM?=25
15+
STM32_PLLN?=336
16+
STM32_PLLP?=4
17+
STM32_PLLQ?=7
18+
USE_UART1?=1
19+
UART_FLASH?=1
20+
DEBUG?=1
21+
STM32?=1

hal/stm32f4.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -261,11 +261,11 @@ static void clock_pll_on(int powersave)
261261
APB1_CLOCK_ER |= PWR_APB1_CLOCK_ER_VAL;
262262

263263
/* Select clock parameters (CPU Speed = 168MHz) */
264-
cpu_freq = 168000000; (void)cpu_freq; /* not used */
265-
pllm = 8;
266-
plln = 336;
267-
pllp = 2;
268-
pllq = 7;
264+
cpu_freq = CLOCK_SPEED; (void)cpu_freq; /* not used */
265+
pllm = STM32_PLLM;
266+
plln = STM32_PLLN;
267+
pllp = STM32_PLLP;
268+
pllq = STM32_PLLQ;
269269
pllr = 0; (void)pllr; /* not used */
270270
hpre = RCC_PRESCALER_DIV_NONE;
271271
ppre1 = RCC_PRESCALER_DIV_4;

hal/uart/uart_drv_stm32f4.c

Lines changed: 100 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,11 @@
2929

3030
#include <stdint.h>
3131

32-
/* Driver hardcoded to work on UART3 (PD8/PD9) */
33-
#define UART3 (0x40004800)
34-
#define UART3_PIN_AF 7
35-
#define UART3_RX_PIN 9
36-
#define UART3_TX_PIN 8
37-
38-
#define UART3_SR (*(volatile uint32_t *)(UART3))
39-
#define UART3_DR (*(volatile uint32_t *)(UART3 + 0x04))
40-
#define UART3_BRR (*(volatile uint32_t *)(UART3 + 0x08))
41-
#define UART3_CR1 (*(volatile uint32_t *)(UART3 + 0x0c))
42-
#define UART3_CR2 (*(volatile uint32_t *)(UART3 + 0x10))
43-
32+
/* Common UART Config */
33+
#if !defined(USE_UART1) && !defined(USE_UART3)
34+
#define USE_UART3
35+
#endif
36+
#define UART_PIN_AF 7
4437
#define UART_CR1_UART_ENABLE (1 << 13)
4538
#define UART_CR1_SYMBOL_LEN (1 << 12)
4639
#define UART_CR1_PARITY_ENABLED (1 << 10)
@@ -51,52 +44,110 @@
5144
#define UART_SR_TX_EMPTY (1 << 7)
5245
#define UART_SR_RX_NOTEMPTY (1 << 5)
5346

54-
47+
#ifndef CLOCK_SPEED
5548
#define CLOCK_SPEED (168000000)
49+
#endif
50+
51+
/* Common GPIO Config */
52+
#define GPIO_MODE_AF (2)
5653

57-
#define APB1_CLOCK_ER (*(volatile uint32_t *)(0x40023840))
58-
#define UART3_APB1_CLOCK_ER_VAL (1 << 18)
54+
/* UART1 Config */
55+
#ifdef USE_UART1
56+
#define UART_RX_PIN 7
57+
#define UART_TX_PIN 6
58+
59+
#define UART1 (0x40011000)
60+
#define UART_SR (*(volatile uint32_t *)(UART1))
61+
#define UART_DR (*(volatile uint32_t *)(UART1 + 0x04))
62+
#define UART_BRR (*(volatile uint32_t *)(UART1 + 0x08))
63+
#define UART_CR1 (*(volatile uint32_t *)(UART1 + 0x0c))
64+
#define UART_CR2 (*(volatile uint32_t *)(UART1 + 0x10))
65+
66+
#define UART_CLOCK_ER (*(volatile uint32_t *)(0x40023844))
67+
#define UART_CLOCK_ER_VAL (1 << 4)
68+
69+
#define GPIO_CLOCK_ER (*(volatile uint32_t *)(0x40023830))
70+
#define GPIO_CLOCK_ER_VAL (1 << 1)
71+
#define GPIOB_BASE 0x40020400
72+
#define GPIO_MODE (*(volatile uint32_t *)(GPIOB_BASE + 0x00))
73+
#define GPIO_AFL (*(volatile uint32_t *)(GPIOB_BASE + 0x20))
74+
#define GPIO_AFH (*(volatile uint32_t *)(GPIOB_BASE + 0x24))
75+
#endif
76+
77+
/* UART3 Config */
78+
#ifdef USE_UART3
79+
#define UART_RX_PIN 9
80+
#define UART_TX_PIN 8
5981

60-
#define AHB1_CLOCK_ER (*(volatile uint32_t *)(0x40023830))
61-
#define GPIOD_AHB1_CLOCK_ER (1 << 3)
82+
#define UART3 (0x40004800)
83+
#define UART_SR (*(volatile uint32_t *)(UART3))
84+
#define UART_DR (*(volatile uint32_t *)(UART3 + 0x04))
85+
#define UART_BRR (*(volatile uint32_t *)(UART3 + 0x08))
86+
#define UART_CR1 (*(volatile uint32_t *)(UART3 + 0x0c))
87+
#define UART_CR2 (*(volatile uint32_t *)(UART3 + 0x10))
88+
89+
#define UART_CLOCK_ER (*(volatile uint32_t *)(0x40023840))
90+
#define UART_CLOCK_ER_VAL (1 << 18)
91+
92+
#define GPIO_CLOCK_ER (*(volatile uint32_t *)(0x40023830))
93+
#define GPIO_CLOCK_ER_VAL (1 << 3)
6294
#define GPIOD_BASE 0x40020c00
63-
#define GPIOD_MODE (*(volatile uint32_t *)(GPIOD_BASE + 0x00))
64-
#define GPIOD_AFL (*(volatile uint32_t *)(GPIOD_BASE + 0x20))
65-
#define GPIOD_AFH (*(volatile uint32_t *)(GPIOD_BASE + 0x24))
66-
#define GPIO_MODE_AF (2)
95+
#define GPIO_MODE (*(volatile uint32_t *)(GPIOD_BASE + 0x00))
96+
#define GPIO_AFL (*(volatile uint32_t *)(GPIOD_BASE + 0x20))
97+
#define GPIO_AFH (*(volatile uint32_t *)(GPIOD_BASE + 0x24))
98+
#endif
99+
67100

68101
static void uart_pins_setup(void)
69102
{
70103
uint32_t reg;
71-
AHB1_CLOCK_ER |= GPIOD_AHB1_CLOCK_ER;
104+
GPIO_CLOCK_ER |= GPIO_CLOCK_ER_VAL;
72105
/* Set mode = AF */
73-
reg = GPIOD_MODE & ~ (0x03 << (UART3_RX_PIN * 2));
74-
GPIOD_MODE = reg | (2 << (UART3_RX_PIN * 2));
75-
reg = GPIOD_MODE & ~ (0x03 << (UART3_TX_PIN * 2));
76-
GPIOD_MODE = reg | (2 << (UART3_TX_PIN * 2));
77-
78-
/* Alternate function: use high pins (8 and 9) */
79-
reg = GPIOD_AFH & ~(0xf << ((UART3_TX_PIN - 8) * 4));
80-
GPIOD_AFH = reg | (UART3_PIN_AF << ((UART3_TX_PIN - 8) * 4));
81-
reg = GPIOD_AFH & ~(0xf << ((UART3_RX_PIN - 8) * 4));
82-
GPIOD_AFH = reg | (UART3_PIN_AF << ((UART3_RX_PIN - 8) * 4));
106+
reg = GPIO_MODE & ~ (0x03 << (UART_RX_PIN * 2));
107+
GPIO_MODE = reg | (2 << (UART_RX_PIN * 2));
108+
reg = GPIO_MODE & ~ (0x03 << (UART_TX_PIN * 2));
109+
GPIO_MODE = reg | (2 << (UART_TX_PIN * 2));
110+
111+
/* The alternate function register is split across two 32bit
112+
* registers (AFL, AFH). AFL covers pins 0 through 7, and
113+
* AFH covers pins 8 through 15. The code below determines
114+
* which register to use at compile time based on the chosen
115+
* pin number
116+
*/
117+
118+
#if UART_TX_PIN > 7
119+
reg = GPIO_AFH & ~(0xf << ((UART_TX_PIN - 8) * 4));
120+
GPIO_AFH = reg | (UART_PIN_AF << ((UART_TX_PIN - 8) * 4));
121+
#else
122+
reg = GPIO_AFL & ~(0xf << (UART_TX_PIN * 4));
123+
GPIO_AFL = reg | (UART_PIN_AF << (UART_TX_PIN * 4));
124+
#endif
125+
126+
#if UART_RX_PIN > 7
127+
reg = GPIO_AFH & ~(0xf << ((UART_RX_PIN - 8) * 4));
128+
GPIO_AFH = reg | (UART_PIN_AF << ((UART_RX_PIN - 8) * 4));
129+
#else
130+
reg = GPIO_AFL & ~(0xf << (UART_RX_PIN * 4));
131+
GPIO_AFL = reg | (UART_PIN_AF << (UART_RX_PIN * 4));
132+
#endif
133+
83134
}
84135

85136
int uart_tx(const uint8_t c)
86137
{
87138
uint32_t reg;
88139
do {
89-
reg = UART3_SR;
140+
reg = UART_SR;
90141
} while ((reg & UART_SR_TX_EMPTY) == 0);
91-
UART3_DR = c;
142+
UART_DR = c;
92143
return 1;
93144
}
94145

95146
int uart_rx(uint8_t *c)
96147
{
97-
volatile uint32_t reg = UART3_SR;
148+
volatile uint32_t reg = UART_SR;
98149
if ((reg & UART_SR_RX_NOTEMPTY) != 0) {
99-
reg = UART3_DR;
150+
reg = UART_DR;
100151
*c = (uint8_t)(reg & 0xff);
101152
return 1;
102153
}
@@ -109,42 +160,42 @@ int uart_init(uint32_t bitrate, uint8_t data, char parity, uint8_t stop)
109160
/* Enable pins and configure for AF7 */
110161
uart_pins_setup();
111162
/* Turn on the device */
112-
APB1_CLOCK_ER |= UART3_APB1_CLOCK_ER_VAL;
113-
UART3_CR1 &= ~(UART_CR1_UART_ENABLE);
163+
UART_CLOCK_ER |= UART_CLOCK_ER_VAL;
164+
UART_CR1 &= ~(UART_CR1_UART_ENABLE);
114165

115166
/* Configure for TX + RX */
116-
UART3_CR1 |= (UART_CR1_TX_ENABLE | UART_CR1_RX_ENABLE);
167+
UART_CR1 |= (UART_CR1_TX_ENABLE | UART_CR1_RX_ENABLE);
117168

118169
/* Configure clock */
119-
UART3_BRR = CLOCK_SPEED / bitrate;
170+
UART_BRR = CLOCK_SPEED / bitrate;
120171

121172
/* Configure data bits */
122173
if (data == 8)
123-
UART3_CR1 &= ~UART_CR1_SYMBOL_LEN;
174+
UART_CR1 &= ~UART_CR1_SYMBOL_LEN;
124175
else
125-
UART3_CR1 |= UART_CR1_SYMBOL_LEN;
176+
UART_CR1 |= UART_CR1_SYMBOL_LEN;
126177

127178
/* Configure parity */
128179
switch (parity) {
129180
case 'O':
130-
UART3_CR1 |= UART_CR1_PARITY_ODD;
181+
UART_CR1 |= UART_CR1_PARITY_ODD;
131182
/* fall through to enable parity */
132183
/* FALL THROUGH */
133184
case 'E':
134-
UART3_CR1 |= UART_CR1_PARITY_ENABLED;
185+
UART_CR1 |= UART_CR1_PARITY_ENABLED;
135186
break;
136187
default:
137-
UART3_CR1 &= ~(UART_CR1_PARITY_ENABLED | UART_CR1_PARITY_ODD);
188+
UART_CR1 &= ~(UART_CR1_PARITY_ENABLED | UART_CR1_PARITY_ODD);
138189
}
139190
/* Set stop bits */
140-
reg = UART3_CR2 & ~UART_CR2_STOPBITS;
191+
reg = UART_CR2 & ~UART_CR2_STOPBITS;
141192
if (stop > 1)
142-
UART3_CR2 = reg & (2 << 12);
193+
UART_CR2 = reg & (2 << 12);
143194
else
144-
UART3_CR2 = reg;
195+
UART_CR2 = reg;
145196

146197
/* Turn on uart */
147-
UART3_CR1 |= UART_CR1_UART_ENABLE;
198+
UART_CR1 |= UART_CR1_UART_ENABLE;
148199
return 0;
149200
}
150201

0 commit comments

Comments
 (0)