Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
142 changes: 128 additions & 14 deletions .claude/skills/port-stm32-platform/SKILL.md

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

wolfHAL is a lightweight, OS-agnostic, compiler-agnostic hardware abstraction
layer for embedded targets written in C. It provides a uniform driver model
based on vtable dispatch.
with vtable dispatch by default and an opt-in single-instance fast path for
size-constrained builds.

## Repository layout

Expand Down
11 changes: 7 additions & 4 deletions boards/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,13 @@ Each board directory contains:
- **`board.mk`** - Build configuration: toolchain, CPU flags, platform
drivers, and linker script. Included by application Makefiles via
`include $(BOARD_DIR)/board.mk`.
- **`board.h`** - Board-level declarations: global peripheral instances,
pin definitions, and `Board_Init()`/`Board_Deinit()` prototypes.
- **`board.c`** - Peripheral instantiation and `Board_Init()` implementation
(power, clock, GPIO, UART, flash, timer).
- **`board.h`** - Board-level declarations: `extern` globals for vtable-dispatched
peripherals, `static const` singletons for single-instance drivers,
`BOARD_<PERIPH>_DEV` macros that resolve to `WHAL_SINGLETON` or
`&g_whal<X>` depending on how each peripheral is wired, pin definitions,
and `Board_Init()`/`Board_Deinit()` prototypes.
- **`board.c`** - Peripheral instantiation for vtable-dispatched drivers and
`Board_Init()` implementation (power, clock, GPIO, UART, flash, timer).
- **`linker.ld`** - Linker script defining memory regions (flash, RAM).
- Any additional board-specific source files (e.g. interrupt vector table,
architecture-specific startup code).
Expand Down
4 changes: 2 additions & 2 deletions boards/peripheral/block/sdhc_spi_sdcard32gb.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ static whal_Spi_ComCfg g_sdcardComCfg = {
whal_Block g_whalSdhcSpiSdcard32gb = {
.driver = &whal_SdhcSpi_Driver,
.cfg = &(whal_SdhcSpi_Cfg) {
.spiDev = &g_whalSpi,
.spiDev = BOARD_SPI_DEV,
.spiComCfg = &g_sdcardComCfg,
.gpioDev = &g_whalGpio,
.gpioDev = BOARD_GPIO_DEV,
.csPin = SPI_CS_PIN,
.timeout = &g_whalTimeout,
},
Expand Down
4 changes: 2 additions & 2 deletions boards/peripheral/flash/spi_nor_w25q64.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ static whal_Spi_ComCfg g_w25q64ComCfg = {
whal_Flash g_whalSpiNorW25q64 = {
.driver = &whal_SpiNor_Driver,
.cfg = &(whal_SpiNor_Cfg) {
.spiDev = &g_whalSpi,
.spiDev = BOARD_SPI_DEV,
.spiComCfg = &g_w25q64ComCfg,
.gpioDev = &g_whalGpio,
.gpioDev = BOARD_GPIO_DEV,
.csPin = SPI_CS_PIN,
.timeout = &g_whalTimeout,
.pageSz = W25Q64_PAGE_SZ,
Expand Down
2 changes: 1 addition & 1 deletion boards/peripheral/sensor/imu/bmi270.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ whal_I2c_ComCfg g_bmi270ComCfg = {
whal_Sensor g_whalBmi270 = {
.driver = &whal_Bmi270_Driver,
.cfg = &(whal_Bmi270_Cfg) {
.i2c = &g_whalI2c,
.i2c = BOARD_I2C_DEV,
.comCfg = &g_bmi270ComCfg,
.configData = whal_bmi270_config_data,
.configDataSz = WHAL_BMI270_CONFIG_DATA_SZ,
Expand Down
87 changes: 27 additions & 60 deletions boards/pic32cz_curiosity_ultra/board.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,26 @@
#include <wolfHAL/platform/microchip/pic32cz.h>
#include "peripheral.h"

/* Power */
static whal_Power g_whalPower = {
.regmap = { WHAL_PIC32CZ_SUPC_REGMAP },
/* SysTick timing (must precede g_whalTimeout below) */
volatile uint32_t g_tick = 0;
volatile uint8_t g_waiting = 0;
volatile uint8_t g_tickOverflow = 0;

uint32_t Board_GetTick(void)
{
return g_tick;
}

whal_Timeout g_whalTimeout = {
.timeoutTicks = 1000,
.GetTick = Board_GetTick,
};

/* SUPC singleton lives in board.h as `static const`. */

/* Clock */
whal_Clock g_whalClock = {
.regmap = { WHAL_PIC32CZ_CLOCK_REGMAP },
.base = WHAL_PIC32CZ_CLOCK_BASE,
};

/* Peripheral clocks */
Expand All @@ -28,39 +40,10 @@ static const whal_Pic32cz_Clock_PeriphClk g_periphClks[] = {
};
#define PERIPH_CLK_COUNT (sizeof(g_periphClks) / sizeof(g_periphClks[0]))

/* GPIO */
whal_Gpio g_whalGpio = {
.regmap = { WHAL_PIC32CZ_GPIO_REGMAP },
/* .driver: direct API mapping */

.cfg = &(whal_Pic32cz_Gpio_Cfg) {
.pinCfgCount = 3,
.pinCfg = (whal_Pic32cz_Gpio_PinCfg[]) {
{ /* LED */
.port = 1,
.pin = 21,
.dir = WHAL_PIC32CZ_DIR_OUTPUT,
.out = 0,
},
{ /* UART TX */
.port = 2,
.pin = 21,
.pmuxEn = 1,
.pmux = WHAL_PIC32CZ_PMUX_SERCOM_ALT,
},
{ /* UART RX */
.port = 2,
.pin = 22,
.pmuxEn = 1,
.pmux = WHAL_PIC32CZ_PMUX_SERCOM_ALT,
},
},
},
};

/* UART */
whal_Uart g_whalUart = {
.regmap = { WHAL_PIC32CZ_SERCOM4_UART_REGMAP },
.base = WHAL_PIC32CZ_SERCOM4_UART_BASE,
/* .driver: direct API mapping */

.cfg = &(whal_Pic32cz_Uart_Cfg) {
Expand All @@ -70,29 +53,13 @@ whal_Uart g_whalUart = {
},
};

/* Timer */
whal_Timer g_whalTimer = {
.regmap = { WHAL_CORTEX_M7_SYSTICK_REGMAP },
.driver = WHAL_CORTEX_M7_SYSTICK_DRIVER,

.cfg = &(whal_SysTick_Cfg) {
.cyclesPerTick = 300000000 / 1000,
.clkSrc = WHAL_SYSTICK_CLKSRC_SYSCLK,
.tickInt = WHAL_SYSTICK_TICKINT_ENABLED,
},
};

/* Flash */
/* Flash — dispatcher stub. The const cfg lives in board.h as
* whal_Pic32cz_Flash_Dev; this only carries .driver so whal_Flash_* can
* dispatch through the vtable. */
whal_Flash g_whalFlash = {
.regmap = { WHAL_PIC32CZ_FLASH_REGMAP },
.driver = WHAL_PIC32CZ_FLASH_DRIVER,
};

/* SysTick timing */
volatile uint32_t g_tick = 0;
volatile uint8_t g_waiting = 0;
volatile uint8_t g_tickOverflow = 0;

void SysTick_Handler()
{
uint32_t tickBefore = g_tick++;
Expand Down Expand Up @@ -126,7 +93,7 @@ whal_Error Board_Init(void)
whal_Error err;

/* Enable PLL power supply before clock init */
err = whal_Pic32cz_Supc_EnableSupply(&g_whalPower,
err = whal_Pic32cz_Supc_EnableSupply(WHAL_SINGLETON,
&(whal_Pic32cz_Supc_Supply){WHAL_PIC32CZ_SUPC_PLL});
if (err) {
return err;
Expand Down Expand Up @@ -169,7 +136,7 @@ whal_Error Board_Init(void)
return err;
}

err = whal_Gpio_Init(&g_whalGpio);
err = whal_Gpio_Init(WHAL_SINGLETON);
if (err) {
return err;
}
Expand All @@ -184,12 +151,12 @@ whal_Error Board_Init(void)
return err;
}

err = whal_Timer_Init(&g_whalTimer);
err = whal_Timer_Init(WHAL_SINGLETON);
if (err) {
return err;
}

err = whal_Timer_Start(&g_whalTimer);
err = whal_Timer_Start(WHAL_SINGLETON);
if (err) {
return err;
}
Expand All @@ -211,12 +178,12 @@ whal_Error Board_Deinit(void)
return err;
}

err = whal_Timer_Stop(&g_whalTimer);
err = whal_Timer_Stop(WHAL_SINGLETON);
if (err) {
return err;
}

err = whal_Timer_Deinit(&g_whalTimer);
err = whal_Timer_Deinit(WHAL_SINGLETON);
if (err) {
return err;
}
Expand All @@ -231,7 +198,7 @@ whal_Error Board_Deinit(void)
return err;
}

err = whal_Gpio_Deinit(&g_whalGpio);
err = whal_Gpio_Deinit(WHAL_SINGLETON);
if (err) {
return err;
}
Expand Down
70 changes: 68 additions & 2 deletions boards/pic32cz_curiosity_ultra/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,85 @@
#include <stdint.h>
#include <stddef.h>
#include <wolfHAL/wolfHAL.h>
#include <wolfHAL/platform/microchip/pic32cz.h>
#include <wolfHAL/power/pic32cz_supc.h>

extern whal_Clock g_whalClock;
extern whal_Gpio g_whalGpio;
extern whal_Timer g_whalTimer;
extern whal_Uart g_whalUart;
extern whal_Flash g_whalFlash;
extern whal_Timeout g_whalTimeout;

extern volatile uint32_t g_tick;

#define BOARD_LED_PIN 0
#define BOARD_FLASH_TEST_ADDR 0x0C000000
#define BOARD_FLASH_SECTOR_SZ 0x1000

/* BOARD_*_DEV: how this board reaches each peripheral. */
#define BOARD_GPIO_DEV WHAL_SINGLETON
#define BOARD_UART_DEV (&g_whalUart)
#define BOARD_FLASH_DEV (&g_whalFlash)
#define BOARD_CLOCK_DEV (&g_whalClock)

/* SUPC singleton — referenced by pic32cz_supc.c directly. */
static const whal_Power whal_Pic32cz_Supc_Dev = {
.base = WHAL_PIC32CZ_SUPC_BASE,
};

/* Flash singleton — referenced by pic32cz_flash.c directly. Const cfg lives
* here; the dispatcher stub g_whalFlash in board.c carries only .driver so
* whal_Flash_* can be vtable-dispatched alongside other flash drivers (e.g.
* SPI NOR W25Q64). */
static const whal_Flash whal_Pic32cz_Flash_Dev = {
.base = WHAL_PIC32CZ_FLASH_BASE,

.cfg = (void *)&(const whal_Pic32cz_Flash_Cfg){
.startAddr = 0x0C000000,
.size = 0x00800000, /* 8 MB max */
.timeout = &g_whalTimeout,
},
};

static const whal_Gpio whal_Pic32cz_Gpio_Dev = {
.base = WHAL_PIC32CZ_GPIO_BASE,

.cfg = (void *)&(const whal_Pic32cz_Gpio_Cfg){
.pinCfgCount = 3,
.pinCfg = (whal_Pic32cz_Gpio_PinCfg[]) {
{ /* LED */
.port = 1,
.pin = 21,
.dir = WHAL_PIC32CZ_DIR_OUTPUT,
.out = 0,
},
{ /* UART TX */
.port = 2,
.pin = 21,
.pmuxEn = 1,
.pmux = WHAL_PIC32CZ_PMUX_SERCOM_ALT,
},
{ /* UART RX */
.port = 2,
.pin = 22,
.pmuxEn = 1,
.pmux = WHAL_PIC32CZ_PMUX_SERCOM_ALT,
},
},
},
};

/* SysTick singleton — referenced by systick.c directly. */
static const whal_Timer whal_SysTick_Dev = {
.base = WHAL_CORTEX_M7_SYSTICK_BASE,
/* .driver: direct API mapping */

.cfg = (void *)&(const whal_SysTick_Cfg){
.cyclesPerTick = 300000000 / 1000,
.clkSrc = WHAL_SYSTICK_CLKSRC_SYSCLK,
.tickInt = WHAL_SYSTICK_TICKINT_ENABLED,
},
};

whal_Error Board_Init(void);
whal_Error Board_Deinit(void);
void Board_WaitMs(size_t ms);
Expand Down
8 changes: 4 additions & 4 deletions boards/pic32cz_curiosity_ultra/board.mk
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ GCC = $(GCC_PATH)arm-none-eabi-gcc
LD = $(GCC_PATH)arm-none-eabi-ld
OBJCOPY = $(GCC_PATH)arm-none-eabi-objcopy

CFLAGS += -Wall -Werror $(INCLUDE) -g3 \
CFLAGS += -Wall -Werror $(INCLUDE) -g3 -Os -ffunction-sections -fdata-sections \
-ffreestanding -nostdlib -mcpu=cortex-m7 \
-DPLATFORM_PIC32CZ -MMD -MP \
-DWHAL_CFG_PIC32CZ_GPIO_DIRECT_API_MAPPING \
-DWHAL_CFG_PIC32CZ_CLOCK_DIRECT_API_MAPPING \
-DWHAL_CFG_PIC32CZ_UART_DIRECT_API_MAPPING
LDFLAGS = --omagic -static
-DWHAL_CFG_PIC32CZ_UART_DIRECT_API_MAPPING \
-DWHAL_CFG_SYSTICK_TIMER_DIRECT_API_MAPPING
LDFLAGS = --omagic -static --gc-sections

LINKER_SCRIPT ?= $(_BOARD_DIR)/linker.ld

Expand All @@ -22,7 +23,6 @@ INCLUDE += -I$(_BOARD_DIR) -I$(WHAL_DIR)/boards/peripheral
BOARD_SOURCE = $(_BOARD_DIR)/ivt.c
BOARD_SOURCE += $(_BOARD_DIR)/board.c
BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*.c)
BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/timer.c)
BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/flash.c)
BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/rng.c)
BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/block.c)
Expand Down
Loading
Loading