Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/test-configs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,12 @@ jobs:
config-file: ./config/examples/stm32wb.config
make-args: WOLFHAL=1 BOARD=stm32wb_nucleo

stm32wba_wolfhal_test:
uses: ./.github/workflows/test-build.yml
with:
arch: arm
config-file: ./config/examples/stm32wba.config

# TODO: ti-tms570lc435.config requires F021 Flash API (Windows installer only)
# ti_tms570lc435_test:
# uses: ./.github/workflows/test-build-ti-hercules.yml
Expand Down
6 changes: 6 additions & 0 deletions arch.mk
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,12 @@ ifeq ($(ARCH),ARM)
endif
endif

ifeq ($(TARGET),stm32wba)
CORTEX_M33=1
ARCH_FLASH_OFFSET=0x08000000
SPI_TARGET=stm32
endif

ifeq ($(TARGET),stm32l5)
CORTEX_M33=1
CFLAGS+=-Ihal
Expand Down
19 changes: 19 additions & 0 deletions config/examples/stm32wba.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# STM32WBA55CG Nucleo, wolfBoot on the wolfHAL backend.
#
# Flash: 1 MB at 0x08000000, 8 KB pages, 128-bit (16-byte) aligned writes.
# Non-secure / flat mode (the wolfHAL stm32wba flash driver uses the NS
# flash registers). Bootloader occupies the first 64 KB; two 128 KB
# partitions plus an 8 KB swap follow.
TARGET=stm32wba
BOARD=stm32wba55cg_nucleo
WOLFHAL=1
ARCH=ARM
SIGN=ECC256
HASH=SHA256
NO_MPU=1
Comment thread
dgarske marked this conversation as resolved.
WOLFBOOT_SECTOR_SIZE=0x2000
WOLFBOOT_PARTITION_SIZE=0x20000
WOLFBOOT_PARTITION_BOOT_ADDRESS=0x08010000
WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x08030000
WOLFBOOT_PARTITION_SWAP_ADDRESS=0x08050000
NVM_FLASH_WRITEONCE=1
133 changes: 133 additions & 0 deletions hal/boards/stm32wba55cg_nucleo/board.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/* board.c
*
* STM32WBA55CG Nucleo board configuration using upstream wolfHAL drivers.
* Flash/Gpio/Uart singletons are instantiated by the driver .c files from
* the WHAL_CFG_* initializer macros in board.h; board.c uses the
* BOARD_*_DEV handles for the rest. RCC is header-inlined and hardcodes
* its base — no dev pointer needed.
*
* Clock target: HSE32 -> PLL1 (M=1, N=25, R=3) -> SYSCLK = 100 MHz, which
* requires PWR voltage scaling Range 1 and 3 flash wait states (RM0493).
*
* Copyright (C) 2026 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 <stddef.h>
#include "hal.h"
#include "board.h"

/* Flash clock gate — enabled before raising the wait-state count. */
static const whal_Stm32wba_Rcc_PeriphClk g_flashClock = {WHAL_STM32WBA55_FLASH_CLOCK};

#ifdef DEBUG_UART
/* GPIO ports A (LED PA9, USART1 RX PA8) and B (USART1 TX PB12) plus USART1. */
static const whal_Stm32wba_Rcc_PeriphClk g_periphClks[] = {
{WHAL_STM32WBA55_GPIOA_CLOCK},
{WHAL_STM32WBA55_GPIOB_CLOCK},
{WHAL_STM32WBA55_USART1_CLOCK},
};
#define PERIPH_CLK_COUNT (sizeof(g_periphClks) / sizeof(g_periphClks[0]))
#endif

/*
* Switch PWR voltage scaling to Range 1 (required for >16 MHz operation).
* After reset the device is in Range 2 (max 16 MHz). Must switch to Range 1
* before configuring PLL or increasing SYSCLK.
*
* PWR base: 0x46020800, PWR_VOSR offset 0x00C
* bit 16 VOS: 0=Range2, 1=Range1
* bit 15 VOSRDY: read-only, 1 when stable
*/
#define PWR_BASE 0x46020800
#define PWR_VOSR_REG 0x00C
#define PWR_VOSR_VOS_Msk (1UL << 16)
#define PWR_VOSR_VOSRDY_Msk (1UL << 15)

static void set_vos_range1(void)
{
whal_Reg_Update(PWR_BASE, PWR_VOSR_REG, PWR_VOSR_VOS_Msk, PWR_VOSR_VOS_Msk);
while (!(whal_Reg_Read(PWR_BASE, PWR_VOSR_REG) & PWR_VOSR_VOSRDY_Msk))
;
}

/* HSE32 -> PLL1 (M=1, N=25, R=3 -> 100 MHz) -> SYSCLK */
Comment thread
dgarske marked this conversation as resolved.
Outdated
static void pll_clock_on(void)
{
/* Enable PWR clock so the PWR registers are accessible, then move to
* voltage Range 1 (Range 2 after reset caps SYSCLK at 16 MHz). */
static const whal_Stm32wba_Rcc_PeriphClk pwrClock = {WHAL_STM32WBA55_PWR_CLOCK};
whal_Stm32wba_Rcc_EnablePeriphClk(&pwrClock);
set_vos_range1();

/* Enable flash clock and set latency before increasing clock speed.
* 100 MHz @ 3.3V needs 3 wait states (RM0493 Table 69). */
whal_Stm32wba_Rcc_EnablePeriphClk(&g_flashClock);
whal_Stm32wba_Flash_Ext_SetLatency(BOARD_FLASH_DEV, 3);

/* AHB5 max 32 MHz: prescale 100 MHz / 4 = 25 MHz (0b101 = div 4). */
whal_Stm32wba_Rcc_SetHpre5(5);

whal_Stm32wba_Rcc_EnableOsc(
&(whal_Stm32wba_Rcc_OscCfg){WHAL_STM32WBA_RCC_HSE32_CFG});
whal_Stm32wba_Rcc_EnablePll1(&(whal_Stm32wba_Rcc_Pll1Cfg){
.clkSrc = WHAL_STM32WBA_RCC_PLL1SRC_HSE32,
.rge = WHAL_STM32WBA_RCC_PLL1RGE_8_16,
.m = 1, .n = 25, .r = 3, .q = 0, .p = 0,
});
whal_Stm32wba_Rcc_SetSysClock(WHAL_STM32WBA_RCC_SYSCLK_SRC_PLL1);
}

static void pll_clock_off(void)
{
whal_Stm32wba_Rcc_SetSysClock(WHAL_STM32WBA_RCC_SYSCLK_SRC_HSI16);
whal_Stm32wba_Rcc_DisablePll1();
whal_Stm32wba_Rcc_DisableOsc(
&(whal_Stm32wba_Rcc_OscCfg){WHAL_STM32WBA_RCC_HSE32_CFG});
whal_Stm32wba_Flash_Ext_SetLatency(BOARD_FLASH_DEV, 1);
}

void hal_init(void)
{
pll_clock_on();
whal_Flash_Init(BOARD_FLASH_DEV);

#ifdef DEBUG_UART
for (size_t i = 0; i < PERIPH_CLK_COUNT; i++) {
Comment thread
dgarske marked this conversation as resolved.
Outdated
whal_Stm32wba_Rcc_EnablePeriphClk(&g_periphClks[i]);
}

whal_Gpio_Init(BOARD_GPIO_DEV);
whal_Uart_Init(BOARD_UART_DEV);
#endif
}

void hal_prepare_boot(void)
{
#ifdef DEBUG_UART
whal_Uart_Deinit(BOARD_UART_DEV);
whal_Gpio_Deinit(BOARD_GPIO_DEV);

for (size_t i = PERIPH_CLK_COUNT; i-- > 0; ) {
whal_Stm32wba_Rcc_DisablePeriphClk(&g_periphClks[i]);
}
#endif

whal_Flash_Deinit(BOARD_FLASH_DEV);
pll_clock_off();
}
117 changes: 117 additions & 0 deletions hal/boards/stm32wba55cg_nucleo/board.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/* board.h
*
* STM32WBA55CG Nucleo wolfHAL board header. Provides the WHAL_CFG_*_DEV
* initializer macros that the upstream chip drivers use to instantiate the
* device singletons (in their own .c file), plus the BOARD_X_DEV handles
* that the wolfBoot adapter (hal/wolfhal.c) and board.c pass into the
* wolfHAL API.
*
* The STM32WBA GPIO/UART peripherals are register-compatible with the
* STM32WB; the upstream stm32wba_{gpio,uart}.c TUs simply include the
* stm32wb implementation. The alias headers bridge the names: the GPIO
* alias maps WHAL_CFG_STM32WB_GPIO_DEV onto the WBA-named macro below,
* while the UART driver consumes WHAL_CFG_STM32WB_UART_DEV directly (the
* UART alias header bridges only the singleton symbol). Flash is a native
* STM32WBA driver and uses the WBA-named macro.
*
* Copyright (C) 2026 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
*/

#ifndef WOLFHAL_BOARD_H
#define WOLFHAL_BOARD_H

#include <wolfHAL/wolfHAL.h>
#include <wolfHAL/platform/st/stm32wba55cg.h>
#include <wolfHAL/clock/stm32wba_rcc.h>
#include <wolfHAL/flash/stm32wba_flash.h>
#include <wolfHAL/gpio/stm32wba_gpio.h>
#include <wolfHAL/uart/stm32wba_uart.h>

/* GPIO pin indices used by the runtime-addressable pinCfg table. */
enum {
BOARD_LED_PIN,
BOARD_UART_TX_PIN,
BOARD_UART_RX_PIN,
BOARD_PIN_COUNT,
};

/* Singletons owned by the upstream driver .c files. Declared here so a
* handle could take their address in the future; the SINGLE_INSTANCE /
* DIRECT_API_MAPPING drivers read their static singleton directly and
* ignore the passed dev pointer. (whal_Stm32wba_{Gpio,Uart}_Dev are
* macro-aliased onto the whal_Stm32wb_* symbols by the alias headers.) */
extern const whal_Flash whal_Stm32wba_Flash_Dev;
extern const whal_Gpio whal_Stm32wba_Gpio_Dev;
extern const whal_Uart whal_Stm32wba_Uart_Dev;

/* Device handles passed into the wolfHAL API. The direct-mapped /
* single-instance drivers ignore the dev pointer and read from their
* static singleton, so the INTERNAL_DEV sentinel is sufficient. */
#define BOARD_GPIO_DEV WHAL_INTERNAL_DEV
#define BOARD_UART_DEV WHAL_INTERNAL_DEV
#define BOARD_FLASH_DEV WHAL_INTERNAL_DEV

/* Flash singleton initializer — instantiated by stm32wba_flash.c.
* STM32WBA55: 1 MB flash at 0x08000000, 8 KB pages, 128-bit writes. */
#define WHAL_CFG_STM32WBA_FLASH_DEV { \
.base = WHAL_STM32WBA55_FLASH_BASE, \
.cfg = (void *)&(const whal_Stm32wba_Flash_Cfg){ \
.startAddr = 0x08000000, \
.size = 0x100000, \
}, \
}

/* GPIO singleton initializer — consumed by the stm32wb gpio driver via
* the WHAL_CFG_STM32WB_GPIO_DEV alias in stm32wba_gpio.h. */
#define WHAL_CFG_STM32WBA_GPIO_DEV { \
.base = WHAL_STM32WBA55_GPIO_BASE, \
.cfg = (void *)&(const whal_Stm32wba_Gpio_Cfg){ \
.pinCfg = (const whal_Stm32wba_Gpio_PinCfg[BOARD_PIN_COUNT]){ \
/* LED: PA9 (LD2, green), output push-pull, low speed, pull-up */ \
[BOARD_LED_PIN] = WHAL_STM32WBA_GPIO_PIN( \
WHAL_STM32WBA_GPIO_PORT_A, 9, WHAL_STM32WBA_GPIO_MODE_OUT, \
WHAL_STM32WBA_GPIO_OUTTYPE_PUSHPULL, WHAL_STM32WBA_GPIO_SPEED_LOW, \
WHAL_STM32WBA_GPIO_PULL_UP, 0), \
/* USART1 TX: PB12, AF7 */ \
[BOARD_UART_TX_PIN] = WHAL_STM32WBA_GPIO_PIN( \
WHAL_STM32WBA_GPIO_PORT_B, 12, WHAL_STM32WBA_GPIO_MODE_ALTFN, \
WHAL_STM32WBA_GPIO_OUTTYPE_PUSHPULL, WHAL_STM32WBA_GPIO_SPEED_FAST, \
WHAL_STM32WBA_GPIO_PULL_UP, 7), \
/* USART1 RX: PA8, AF7 */ \
[BOARD_UART_RX_PIN] = WHAL_STM32WBA_GPIO_PIN( \
WHAL_STM32WBA_GPIO_PORT_A, 8, WHAL_STM32WBA_GPIO_MODE_ALTFN, \
WHAL_STM32WBA_GPIO_OUTTYPE_PUSHPULL, WHAL_STM32WBA_GPIO_SPEED_FAST, \
WHAL_STM32WBA_GPIO_PULL_UP, 7), \
}, \
.pinCount = BOARD_PIN_COUNT, \
}, \
}

/* UART singleton initializer — instantiated by stm32wb_uart.c (included by
* stm32wba_uart.c) when WHAL_CFG_STM32WB_UART_SINGLE_INSTANCE is defined.
* The UART alias header does not bridge the CFG macro, so the WB name is
* used directly here. USART1 is clocked from SYSCLK (PLL1 = 100 MHz). */
#define WHAL_CFG_STM32WB_UART_DEV { \
.base = WHAL_STM32WBA55_USART1_BASE, \
.cfg = (void *)&(const whal_Stm32wba_Uart_Cfg){ \
.brr = WHAL_STM32WBA_UART_BRR(100000000, 115200), \
}, \
}

#endif /* WOLFHAL_BOARD_H */
42 changes: 42 additions & 0 deletions hal/boards/stm32wba55cg_nucleo/board.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
ARCH_FLASH_OFFSET=0x08000000
LSCRIPT_IN=hal/stm32wba.ld

CFLAGS+=-DWHAL_CFG_NO_TIMEOUT

# Upstream wolfHAL drivers from lib/wolfHAL/src/. wolfBoot's hal_flash_*
# contract is satisfied by hal/wolfhal.c (added automatically because
# WOLFHAL=1) calling whal_Flash_*.
#
# Direct API mapping binds each driver's functions straight to the
# top-level whal_* symbols (no vtable dispatch source compiled).

# Flash is a native STM32WBA driver — it checks the WBA-prefixed flag.
CFLAGS+=-DWHAL_CFG_STM32WBA_FLASH_DIRECT_API_MAPPING

# GPIO/UART reuse the STM32WB implementation (the stm32wba_*.c TUs include
# stm32wb_*.c). The UART wrapper forwards its WBA flags to the WB names, so
# it takes the WBA-prefixed flags. The GPIO wrapper does NOT forward, so the
# underlying stm32wb_gpio.c must be given the WB-prefixed flag directly.
CFLAGS+=-DWHAL_CFG_STM32WB_GPIO_DIRECT_API_MAPPING
CFLAGS+=-DWHAL_CFG_STM32WBA_UART_DIRECT_API_MAPPING
# UART is single-instance — reads its singleton from board.h instead of the
# passed dev pointer.
CFLAGS+=-DWHAL_CFG_STM32WBA_UART_SINGLE_INSTANCE

WOLFHAL_OBJS+=$(WOLFHAL_ROOT)/src/reg.o
WOLFHAL_OBJS+=$(WOLFHAL_ROOT)/src/flash/stm32wba_flash.o
ifeq ($(DEBUG_UART),1)
Comment thread
dgarske marked this conversation as resolved.
WOLFHAL_OBJS+=$(WOLFHAL_ROOT)/src/gpio/stm32wba_gpio.o
WOLFHAL_OBJS+=$(WOLFHAL_ROOT)/src/uart/stm32wba_uart.o
endif

OBJS+=$(WOLFHAL_OBJS)
APP_OBJS+=$(WOLFHAL_OBJS)

# With RAM_CODE=1, place the flash driver in RAM so erase/program runs while
# the same flash bank is being modified.
ifeq ($(RAM_CODE),1)
WOLFHAL_FLASH_EXCLUDE_TEXT=*(EXCLUDE_FILE(*stm32wba_flash.o) .text*)
WOLFHAL_FLASH_EXCLUDE_RODATA=*(EXCLUDE_FILE(*stm32wba_flash.o) .rodata*)
WOLFHAL_FLASH_RAM_SECTIONS=*stm32wba_flash.o(.text* .rodata*)
endif
50 changes: 50 additions & 0 deletions hal/stm32wba.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000
}

SECTIONS
{
.text :
{
_start_text = .;
KEEP(*(.isr_vector))
@WOLFHAL_FLASH_EXCLUDE_TEXT@
@WOLFHAL_FLASH_EXCLUDE_RODATA@
. = ALIGN(4);
_end_text = .;
} > FLASH
.edidx :
{
. = ALIGN(4);
*(.ARM.exidx*)
} > FLASH

_stored_data = .;
.data : AT (_stored_data)
{
_start_data = .;
KEEP(*(.data*))
. = ALIGN(4);
KEEP(*(.ramcode))
@WOLFHAL_FLASH_RAM_SECTIONS@
. = ALIGN(4);
_end_data = .;
} > RAM

.bss (NOLOAD) :
{
_start_bss = .;
__bss_start__ = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
_end_bss = .;
__bss_end__ = .;
_end = .;
} > RAM
. = ALIGN(4);
}

END_STACK = ORIGIN(RAM) + LENGTH(RAM);
2 changes: 1 addition & 1 deletion lib/wolfHAL
Submodule wolfHAL updated 166 files
Loading