From e331fae331c28b17358e65211f64e0619f55c8b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Dahlstr=C3=B6m?= Date: Sun, 26 Jan 2025 14:16:55 +0100 Subject: [PATCH 1/5] Add STM32F103 (Blue Pill) support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Blue Pill board is typically fitted with a STM32F103C8T6, but reports online seem to indicate that it sometimes can come with its bigger sibling the STM32F103C8TB as is the case with my board. This patch adds support for all low- to medium-density STM32F103 devices. All of these devices have their flash divided in 1 KB pages, up to 128 KB. The high-density and connectivity line of devices, sometimes called XL devices, use 2 KB pages and are not supported. Similar to the STM32F4 support, the code will spin up the PLL for maximum speed during init and turn it off just before booting the application. the maxium speed is 72 MHz. Signed-off-by: Patrik Dahlström --- arch.mk | 6 + hal/stm32f1.c | 334 +++++++++++++++++++++++++++++++++++++++++++++++++ hal/stm32f1.ld | 61 +++++++++ 3 files changed, 401 insertions(+) create mode 100644 hal/stm32f1.c create mode 100644 hal/stm32f1.ld diff --git a/arch.mk b/arch.mk index 3d3e24ef9d..3cd9a61b19 100644 --- a/arch.mk +++ b/arch.mk @@ -139,6 +139,12 @@ ifeq ($(ARCH),ARM) ARCH_FLASH_OFFSET=0x08000000 endif + ifeq ($(TARGET),stm32f1) + CORTEX_M3=1 + NO_ARM_ASM=1 + ARCH_FLASH_OFFSET=0x08000000 + endif + ifeq ($(TARGET),stm32f4) ARCH_FLASH_OFFSET=0x08000000 SPI_TARGET=stm32 diff --git a/hal/stm32f1.c b/hal/stm32f1.c new file mode 100644 index 0000000000..5874d63dd7 --- /dev/null +++ b/hal/stm32f1.c @@ -0,0 +1,334 @@ +/* stm32f1.c + * + * Copyright (C) 2025 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * wolfBoot is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfBoot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#include +#include + +#include "image.h" + +#ifndef ARCH_FLASH_OFFSET +#define ARCH_FLASH_OFFSET 0x08000000U +#endif + +/* STM32 F103 register Assembly helpers */ +#define DMB() asm volatile ("dmb") + +/*** RCC ***/ +#define RCC_BASE (0x40021000U) +#define RCC_CR (*(volatile uint32_t *)(RCC_BASE + 0x00U)) +#define RCC_CFGR (*(volatile uint32_t *)(RCC_BASE + 0x04U)) + +#define RCC_CR_PLLRDY (1 << 25) +#define RCC_CR_PLLON (1 << 24) +#define RCC_CR_HSERDY (1 << 17) +#define RCC_CR_HSEON (1 << 16) +#define RCC_CR_HSIRDY (1 << 1) +#define RCC_CR_HSION (1 << 0) + +#define RCC_CFGR_SW_MASK 0x0003 +#define RCC_CFGR_SW_HSI 0x0 +#define RCC_CFGR_SW_HSE 0x1 +#define RCC_CFGR_SW_PLL 0x2 + +#define RCC_CFGR_SWS_MASK 0x000C +#define RCC_CFGR_SWS_HSI (0 << 2) +#define RCC_CFGR_SWS_HSE (1 << 2) +#define RCC_CFGR_SWS_PLL (2 << 2) + +#define RCC_CFGR_HPRE_MASK 0x00F0 +#define RCC_CFGR_HPRE_DIV_NONE (0 << 4) +#define RCC_CFGR_HPRE_DIV_2 (8 << 4) +#define RCC_CFGR_HPRE_DIV_4 (9 << 4) + +#define RCC_CFGR_PPRE1_MASK 0x0700 +#define RCC_CFGR_PPRE1_DIV_NONE (0 << 8) +#define RCC_CFGR_PPRE1_DIV_2 (4 << 8) +#define RCC_CFGR_PPRE1_DIV_4 (5 << 8) + +#define RCC_CFGR_PPRE2_MASK 0x3800 +#define RCC_CFGR_PPRE2_DIV_NONE (0 << 11) +#define RCC_CFGR_PPRE2_DIV_2 (4 << 11) +#define RCC_CFGR_PPRE2_DIV_4 (5 << 11) + +#define PLL_FULL_MASK (0x003F0000) +#define RCC_CFGR_PLLSRC (1 << 22) +#define RCC_CFGR_PLLMUL_MUL_9 (7 << 18) + +/*** FLASH ***/ +#define RCC_APB1ENR (*(volatile uint32_t *)(RCC_BASE + 0x1C)) +#define RCC_APB1ENR_PWREN (1 << 28) + +#define FLASH_BASE (0x40022000U) +#define FLASH_ACR (*(volatile uint32_t *)(FLASH_BASE + 0x00U)) +#define FLASH_KEYR (*(volatile uint32_t *)(FLASH_BASE + 0x04U)) +#define FLASH_SR (*(volatile uint32_t *)(FLASH_BASE + 0x0CU)) +#define FLASH_CR (*(volatile uint32_t *)(FLASH_BASE + 0x10U)) +#define FLASH_AR (*(volatile uint32_t *)(FLASH_BASE + 0x14U)) + +#define FLASH_MAX_SZ (128*1024) /* only low- and medium-density devices supported */ +#define FLASH_PAGE_SZ (1024) + +/* Register values */ +#define FLASH_ACR_ENABLE_PRFT (1 << 4) + +#define FLASH_SR_BSY (1 << 0) + +#define FLASH_CR_LOCK (1 << 7) +#define FLASH_CR_STRT (1 << 6) +#define FLASH_CR_PER (1 << 1) +#define FLASH_CR_PG (1 << 0) + +#define FLASH_KEY1 (0x45670123U) +#define FLASH_KEY2 (0xCDEF89ABU) + +static void RAMFUNCTION flash_set_waitstates(int waitstates) +{ + FLASH_ACR |= waitstates | FLASH_ACR_ENABLE_PRFT; +} + +static int RAMFUNCTION valid_flash_area(uint32_t address, int len) +{ + if (len <= 0 || len > FLASH_MAX_SZ) + return -1; + if (address < ARCH_FLASH_OFFSET || address >= (ARCH_FLASH_OFFSET + FLASH_MAX_SZ)) + return -1; + if ((address + len) > (ARCH_FLASH_OFFSET + FLASH_MAX_SZ)) + return -1; + + return 0; +} + +static inline void RAMFUNCTION flash_wait_complete(void) +{ + while ((FLASH_SR & FLASH_SR_BSY) == FLASH_SR_BSY) + ; +} + +static int RAMFUNCTION flash_erase_page(uint32_t address) +{ + const uint32_t end = address + FLASH_PAGE_SZ; + + flash_wait_complete(); + + FLASH_CR |= FLASH_CR_PER; + FLASH_AR = address; + FLASH_CR |= FLASH_CR_STRT; + flash_wait_complete(); + FLASH_CR &= ~FLASH_CR_PER; + + /* verify erase */ + while (address < end) { + if (*(uint32_t*)address != (uint32_t)~0) + return -1; + + address += 4; + } + + return 0; +} + +static int RAMFUNCTION flash_w16(volatile uint16_t *dst, const uint16_t value) +{ + /* do the write */ + *dst = value; + DMB(); + flash_wait_complete(); + + /* verify */ + return (*dst == value) ? 0 : -1; +} + +int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len) +{ + uint16_t tmp; + const uint8_t *src = data; + const uint8_t * const end = src + len; + /* make sure dst is aligned to 16 bits */ + volatile uint16_t *dst = (volatile uint16_t*)(address & ~1); + + if (valid_flash_area(address, len) != 0) + return -1; + + flash_wait_complete(); + FLASH_CR |= FLASH_CR_PG; + /* writes are 16 bits. Check for unaligned initial write */ + if (address & 1) { + /* read-modify-write */ + tmp = (*dst & 0x00FF) | (data[0] << 8); + if (flash_w16(dst, tmp) != 0) { + FLASH_CR &= ~FLASH_CR_PG; + return -1; + } + /* advance dst 2 bytes, src 1 byte */ + dst++; + src++; + } + /* main write loop */ + while (src < end) { + /* check for unaligned last write */ + if (src + 1 == end) { + /* read-modify-write */ + tmp = (*dst & 0xFF00) | *src; + if (flash_w16(dst, tmp) != 0) { + FLASH_CR &= ~FLASH_CR_PG; + return -1; + } + break; + } + /* all systems go for a regular write */ + tmp = *(const uint16_t*)src; + if (flash_w16(dst, tmp) != 0) { + FLASH_CR &= ~FLASH_CR_PG; + return -1; + } + /* advance 2 bytes */ + src += 2; + dst++; + } + FLASH_CR &= ~FLASH_CR_PG; + return 0; +} + +void RAMFUNCTION hal_flash_unlock(void) +{ + FLASH_KEYR = FLASH_KEY1; + FLASH_KEYR = FLASH_KEY2; +} + +void RAMFUNCTION hal_flash_lock(void) +{ + FLASH_CR |= FLASH_CR_LOCK; +} + +int RAMFUNCTION hal_flash_erase(uint32_t address, int len) +{ + const uint32_t end_address = address + len; + + if (valid_flash_area(address, len) != 0) + return -1; + if (len % FLASH_PAGE_SZ) + return -1; + + while (address < end_address) { + if (flash_erase_page(address)) + return -1; + + address += FLASH_PAGE_SZ; + } + + return 0; +} + +static void clock_pll_off(void) +{ + uint32_t reg32; + + /* Enable internal high-speed oscillator. */ + RCC_CR |= RCC_CR_HSION; + DMB(); + while ((RCC_CR & RCC_CR_HSIRDY) == 0) {}; + + /* Select HSI as SYSCLK source. */ + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_SW_MASK); + RCC_CFGR = (reg32 | RCC_CFGR_SW_HSI); + DMB(); + + /* Turn off PLL */ + RCC_CR &= ~RCC_CR_PLLON; + DMB(); +} + +static void clock_pll_on(int powersave) +{ + uint32_t reg32; + + /* Enable Power controller */ + RCC_APB1ENR |= RCC_APB1ENR_PWREN; + + /* 2 wait states, if 48 MHz < SYSCLK <= 72 MHz */ + flash_set_waitstates(2); + + /* Enable internal high-speed oscillator. */ + RCC_CR |= RCC_CR_HSION; + DMB(); + while ((RCC_CR & RCC_CR_HSIRDY) == 0) {}; + + /* Select HSI as SYSCLK source. */ + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_SW_MASK); + RCC_CFGR = (reg32 | RCC_CFGR_SW_HSI); + DMB(); + + /* Enable external high-speed oscillator 8MHz. */ + RCC_CR |= RCC_CR_HSEON; + DMB(); + while ((RCC_CR & RCC_CR_HSERDY) == 0) {}; + + /* + * Set prescalers for AHB, ABP1, ABP2. + */ + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_HPRE_MASK); + RCC_CFGR = reg32 | RCC_CFGR_HPRE_DIV_NONE; + DMB(); + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_PPRE1_MASK); + RCC_CFGR = reg32 | RCC_CFGR_PPRE1_DIV_2; + DMB(); + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_PPRE2_MASK); + RCC_CFGR = reg32 | RCC_CFGR_PPRE1_DIV_NONE; + DMB(); + + /* Set PLL config */ + reg32 = RCC_CFGR; + reg32 &= ~(PLL_FULL_MASK); + /* PLL clock: 8 MHz (HSE) * 9 = 72 MHz */ + RCC_CFGR = reg32 | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL_MUL_9; + DMB(); + /* Enable PLL oscillator and wait for it to stabilize. */ + RCC_CR |= RCC_CR_PLLON; + DMB(); + while ((RCC_CR & RCC_CR_PLLRDY) == 0) {}; + + /* Select PLL as SYSCLK source. */ + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_SW_MASK); + RCC_CFGR = (reg32 | RCC_CFGR_SW_PLL); + DMB(); + + /* Wait for PLL clock to be selected. */ + while ((RCC_CFGR & RCC_CFGR_SWS_MASK) != RCC_CFGR_SWS_PLL) {}; + + /* Disable internal high-speed oscillator. */ + RCC_CR &= ~RCC_CR_HSION; +} + +void hal_init(void) +{ + clock_pll_on(0); +} + +void hal_prepare_boot(void) +{ + clock_pll_off(); +} diff --git a/hal/stm32f1.ld b/hal/stm32f1.ld new file mode 100644 index 0000000000..b811f36dc9 --- /dev/null +++ b/hal/stm32f1.ld @@ -0,0 +1,61 @@ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 20K +} + +SECTIONS +{ + .text : + { + _start_text = .; + KEEP(*(.isr_vector)) + *(.text*) + *(.rodata*) + . = ALIGN(4); + _end_text = .; + } > FLASH + .edidx : + { + . = ALIGN(4); + *(.ARM.exidx*) + } > FLASH + + .edidx : + { + . = ALIGN(4); + *(.ARM.exidx*) + } > FLASH + + + _stored_data = .; + .data : AT (_stored_data) + { + _start_data = .; + KEEP(*(.data*)) + . = ALIGN(4); + KEEP(*(.ramcode)) + . = ALIGN(4); + _end_data = .; + } > RAM + + .bss (NOLOAD) : + { + _start_bss = .; + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + _end_bss = .; + __bss_end__ = .; + _end = .; + } > RAM + . = ALIGN(4); +} + +_wolfboot_partition_boot_address = @WOLFBOOT_PARTITION_BOOT_ADDRESS@; +_wolfboot_partition_size = @WOLFBOOT_PARTITION_SIZE@; +_wolfboot_partition_update_address = @WOLFBOOT_PARTITION_UPDATE_ADDRESS@; +_wolfboot_partition_swap_address = @WOLFBOOT_PARTITION_SWAP_ADDRESS@; + +END_STACK = ORIGIN(RAM) + LENGTH(RAM); From c413717ad26f5a8caaf0ed83a0d1d15117ce4437 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Dahlstr=C3=B6m?= Date: Sun, 26 Jan 2025 14:40:46 +0100 Subject: [PATCH 2/5] stm32f103: add test application MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The test application used during development of STM32F103 support. If booting version 1 of the software, trigger an update. If running ver. 2, all is good. Signed-off-by: Patrik Dahlström --- test-app/app_stm32f1.c | 115 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 test-app/app_stm32f1.c diff --git a/test-app/app_stm32f1.c b/test-app/app_stm32f1.c new file mode 100644 index 0000000000..6075323aea --- /dev/null +++ b/test-app/app_stm32f1.c @@ -0,0 +1,115 @@ +/* app_stm32f1.c + * + * Test bare-metal application for Blue Pill (STM32F103) board. + * + * Copyright (C) 2025 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * wolfBoot is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfBoot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#include + +#include "hal.h" +#include "system.h" +#include "target.h" + +#include "wolfboot/wolfboot.h" + +/*** LED ***/ +#define RCC_BASE (0x40021000U) +#define RCC_APB2ENR (*(volatile uint32_t *)(RCC_BASE + 0x18)) +#define RCC_APB2ENR_IOPCEN (1 << 4) + +#define GPIOC_BASE (0x40011000) +#define GPIOC_CRL (*(volatile uint32_t *)(GPIOC_BASE + 0x00U)) +#define GPIOC_CRH (*(volatile uint32_t *)(GPIOC_BASE + 0x04U)) +#define GPIOC_IDR (*(volatile uint32_t *)(GPIOC_BASE + 0x08U)) +#define GPIOC_ODR (*(volatile uint32_t *)(GPIOC_BASE + 0x0CU)) +#define GPIOC_BSRR (*(volatile uint32_t *)(GPIOC_BASE + 0x10U)) +#define GPIOC_BRR (*(volatile uint32_t *)(GPIOC_BASE + 0x14U)) + +/* Register values */ +#define GPIOx_CRL_MASK(pin) (0xF << ((pin) * 4)) +#define GPIOx_CRH_MASK(pin) (0xF << (((pin) - 8) * 4)) + +#define GPIOx_CRL_CNF(pin, cnf) ((cnf) << (2 + ((pin) * 4))) +#define GPIOx_CRH_CNF(pin, cnf) ((cnf) << (2 + (((pin) - 8) * 4))) +#define GPIOx_CRy_CNF_ANALOG (0) +#define GPIOx_CRy_CNF_FLOATING (1) +#define GPIOx_CRy_CNF_PULL (2) +#define GPIOx_CRy_CNF_OUTPUT_PP (0) +#define GPIOx_CRy_CNF_OUTPUT_OD (1) +#define GPIOx_CRy_CNF_AF_PP (2) +#define GPIOx_CRy_CNF_AF_OD (3) + +#define GPIOx_CRL_MODE(pin, mode) ((mode) << ((pin) * 4)) +#define GPIOx_CRH_MODE(pin, mode) ((mode) << (((pin) - 8) * 4)) +#define GPIOx_CRy_MODE_INPUT (0) +#define GPIOx_CRy_MODE_OUT_10_MHZ (1) +#define GPIOx_CRy_MODE_OUT_2_MHZ (2) +#define GPIOx_CRy_MODE_OUT_50_MHZ (3) + +static void led_init(void) +{ + uint32_t reg32; + + /* Use PC13 as led output as it's connected to the onboard LED of the + * Blue Pill board. */ + + /* Enable GPIOC clock */ + RCC_APB2ENR |= RCC_APB2ENR_IOPCEN; + + /* Configure pin PC13 as slow (2 MHz) output */ + reg32 = GPIOC_CRH; + reg32 &= ~(GPIOx_CRH_MASK(13)); + reg32 |= GPIOx_CRH_CNF(13, GPIOx_CRy_CNF_OUTPUT_PP); + reg32 |= GPIOx_CRH_MODE(13, GPIOx_CRy_MODE_OUT_2_MHZ); + GPIOC_CRH = reg32; + + /* Set PC13 high to turn led OFF */ + GPIOC_BSRR |= 1 << 13; +} + +void led_toggle(void) +{ + if (GPIOC_IDR & (1 << 13)) + GPIOC_BRR |= 1 << 13; + else + GPIOC_BSRR |= 1 << 13; +} + +void main(void) { + hal_init(); + led_init(); + + switch (wolfBoot_current_firmware_version()) { + case 1: + wolfBoot_success(); + wolfBoot_update_trigger(); + led_toggle(); + break; + case 2: + wolfBoot_success(); + led_toggle(); + break; + default: + break; + } + + while(1) + WFI(); +} From d5fdd253a50a9d0ff14d4381146209762bab9406 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Dahlstr=C3=B6m?= Date: Sun, 26 Jan 2025 14:55:55 +0100 Subject: [PATCH 3/5] stm32f103: add example config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Config based on the STM32F4 ditto. Booting takes about 6 seconds and update around 15. Signed-off-by: Patrik Dahlström --- config/examples/stm32f1.config | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 config/examples/stm32f1.config diff --git a/config/examples/stm32f1.config b/config/examples/stm32f1.config new file mode 100644 index 0000000000..298cad608e --- /dev/null +++ b/config/examples/stm32f1.config @@ -0,0 +1,17 @@ +ARCH?=ARM +TARGET?=stm32f1 +SIGN?=ED25519 +HASH?=SHA256 +VTOR?=0 +SPMATH?=1 +DISABLE_BACKUP=0 +NVM_FLASH_WRITEONCE=1 +# 12 KB bootloader partition +# 2 * 25 KB application partitions +# 2 KB swap partition +# 64 KB total +WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08003000 +WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x08009400 +WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x0800F800 +WOLFBOOT_PARTITION_SIZE?=0x6400 +WOLFBOOT_SECTOR_SIZE?=0x400 From e9617770393750dd1946682c27182fa69c5b853b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Dahlstr=C3=B6m?= Date: Wed, 29 Jan 2025 21:53:41 +0100 Subject: [PATCH 4/5] stm32f1: add github build test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Patrik Dahlström --- .github/workflows/test-configs.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/test-configs.yml b/.github/workflows/test-configs.yml index d3d822e8af..e767cae205 100644 --- a/.github/workflows/test-configs.yml +++ b/.github/workflows/test-configs.yml @@ -236,6 +236,12 @@ jobs: arch: arm config-file: ./config/examples/stm32c0-lms-8-10-1.config + stm32f1_test: + uses: ./.github/workflows/test-build.yml + with: + arch: arm + config-file: ./config/examples/stm32f1.config + stm32f4_small_blocks_uart_update_test: uses: ./.github/workflows/test-build.yml with: From 54d286c5664b251b0f3a4f28300d9e25252fbe10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Dahlstr=C3=B6m?= Date: Sat, 15 Feb 2025 20:42:24 +0100 Subject: [PATCH 5/5] stm32f1: add short description to Targets.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Patrik Dahlström --- docs/Targets.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/docs/Targets.md b/docs/Targets.md index fdc1242c74..17db03b04b 100644 --- a/docs/Targets.md +++ b/docs/Targets.md @@ -30,6 +30,7 @@ This README describes configuration of supported targets. * [Renesas RZN2L](#renesas-rzn2l) * [SiFive HiFive1 RISC-V](#sifive-hifive1-risc-v) * [STM32C0](#stm32c0) +* [STM32F1](#stm32f1) * [STM32F4](#stm32f4) * [STM32F7](#stm32f7) * [STM32G0](#stm32g0) @@ -103,6 +104,36 @@ b main c ``` +## STM32F1 + +Similar layout as the STM32F4, but for a much smaller 64KB flash. + +WolfBoot occupy 12KB, followed by 2x25 KB firmware partitions, and a 2KB swap: + +``` +WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08003000 +WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x08009400 +WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x0800F800 +``` + +This is with the sample config in [config/examples/stm32f1.config](config/examples/stm32f1.config). + +Note that with this partition layout, WolfBoot cannot be compiled with debug support. + +The test application for STM32F1 is designed so that if it boots a version 1 software, it will trigger an update +If the running software version is 2, all is good. +In both cases, PC13 is cleared (lights up the green LED on a Blue Pill board). + +### STM32F1 Programming + +All STM32F1 devices come with a builtin bootloader that can be used to program the device. +It allows firmware upload on USART0 (pin A9 and A10 on the Blue Pill) using a usb-serial converter. +The bootloader is entered by pulling the BOOT0 pin high. +Once the builtin bootloader is active, the STM32F1 can be programmed with `stm32flash`: + +``` +stm32flash -w factory.bin -b 115200 -g 0 /dev/ttyUSB0 +``` ## STM32L4 Example 1MB partitioning on STM32L4