From dca6275d1925c42a91fe784592bcab3bb81ca1e4 Mon Sep 17 00:00:00 2001 From: Alex Lanzano Date: Wed, 22 Apr 2026 08:33:46 -0400 Subject: [PATCH] [stm32f3] Implement initial support for stm32f3 --- .claude/skills/port-stm32-platform/SKILL.md | 22 ++ .github/workflows/boards.yml | 2 +- boards/README.md | 1 + boards/stm32f302r8_nucleo/Makefile.inc | 43 +++ boards/stm32f302r8_nucleo/board.c | 294 ++++++++++++++++++++ boards/stm32f302r8_nucleo/board.h | 46 +++ boards/stm32f302r8_nucleo/ivt.c | 225 +++++++++++++++ boards/stm32f302r8_nucleo/linker.ld | 121 ++++++++ src/clock/stm32f3_rcc.c | 285 +++++++++++++++++++ src/flash/stm32f0_flash.c | 10 +- src/flash/stm32f3_flash.c | 1 + src/gpio/stm32f3_gpio.c | 1 + src/gpio/stm32wb_gpio.c | 6 +- src/i2c/stm32f3_i2c.c | 1 + src/i2c/stm32wb_i2c.c | 6 +- src/spi/stm32f3_spi.c | 1 + src/spi/stm32wb_spi.c | 6 +- src/uart/stm32f0_uart.c | 10 +- src/uart/stm32f3_uart.c | 1 + src/watchdog/stm32f0_iwdg.c | 3 - src/watchdog/stm32f0_wwdg.c | 10 +- src/watchdog/stm32f3_iwdg.c | 1 + src/watchdog/stm32f3_wwdg.c | 1 + src/watchdog/stm32wb_iwdg.c | 12 +- tests/gpio/test_stm32f3_gpio.c | 1 + wolfHAL/clock/stm32f3_rcc.h | 160 +++++++++++ wolfHAL/flash/stm32f3_flash.h | 34 +++ wolfHAL/gpio/stm32f3_gpio.h | 52 ++++ wolfHAL/i2c/stm32f3_i2c.h | 25 ++ wolfHAL/platform/st/stm32f302r8.h | 241 ++++++++++++++++ wolfHAL/spi/stm32f3_spi.h | 25 ++ wolfHAL/uart/stm32f3_uart.h | 26 ++ wolfHAL/watchdog/stm32f3_iwdg.h | 30 ++ wolfHAL/watchdog/stm32f3_wwdg.h | 23 ++ 34 files changed, 1700 insertions(+), 26 deletions(-) create mode 100644 boards/stm32f302r8_nucleo/Makefile.inc create mode 100644 boards/stm32f302r8_nucleo/board.c create mode 100644 boards/stm32f302r8_nucleo/board.h create mode 100644 boards/stm32f302r8_nucleo/ivt.c create mode 100644 boards/stm32f302r8_nucleo/linker.ld create mode 100644 src/clock/stm32f3_rcc.c create mode 100644 src/flash/stm32f3_flash.c create mode 100644 src/gpio/stm32f3_gpio.c create mode 100644 src/i2c/stm32f3_i2c.c create mode 100644 src/spi/stm32f3_spi.c create mode 100644 src/uart/stm32f3_uart.c create mode 100644 src/watchdog/stm32f3_iwdg.c create mode 100644 src/watchdog/stm32f3_wwdg.c create mode 100644 tests/gpio/test_stm32f3_gpio.c create mode 100644 wolfHAL/clock/stm32f3_rcc.h create mode 100644 wolfHAL/flash/stm32f3_flash.h create mode 100644 wolfHAL/gpio/stm32f3_gpio.h create mode 100644 wolfHAL/i2c/stm32f3_i2c.h create mode 100644 wolfHAL/platform/st/stm32f302r8.h create mode 100644 wolfHAL/spi/stm32f3_spi.h create mode 100644 wolfHAL/uart/stm32f3_uart.h create mode 100644 wolfHAL/watchdog/stm32f3_iwdg.h create mode 100644 wolfHAL/watchdog/stm32f3_wwdg.h diff --git a/.claude/skills/port-stm32-platform/SKILL.md b/.claude/skills/port-stm32-platform/SKILL.md index 6d529c3..e7d841d 100644 --- a/.claude/skills/port-stm32-platform/SKILL.md +++ b/.claude/skills/port-stm32-platform/SKILL.md @@ -140,6 +140,28 @@ typedef whal__PinCfg whal__PinCfg; That is the entire file. Examples in-tree: `src/gpio/stm32f4_gpio.c`, `src/gpio/stm32wba_gpio.c`, `src/i2c/stm32wba_i2c.c`, `src/uart/stm32wba_uart.c`, `src/watchdog/stm32wba_iwdg.c` — each is one line. The stub exists so the board's Makefile wildcard (`src/*/_*.c`) compiles the original implementation under the new-prefix filename. The original `.c` is NOT added to the Makefile separately; the `#include` pulls it into this translation unit exactly once. +**API mapping macros stay in the leaf driver, not in the alias .c.** Most leaf drivers contain a guarded block that aliases the platform-specific function names directly to the generic `whal__*` API: + +```c +/* in src//_.c — the LEAF */ +#if defined(WHAL_CFG__API_MAPPING_) || \ + defined(WHAL_CFG__API_MAPPING_) +#define whal__Init whal__Init +/* ...one #define per driver entry point... */ +#endif + +/* ...driver implementation... */ + +#if !defined(WHAL_CFG__API_MAPPING_) && \ + !defined(WHAL_CFG__API_MAPPING_) +const whal_Driver whal__Driver = { ... }; +#endif +``` + +Add the new platform's `WHAL_CFG__API_MAPPING_` macro to **both** guards in the leaf driver. Do **not** translate the macro inside the alias `.c` stub like `#ifdef #define #endif` — every leaf has to learn about every alias platform anyway, and putting the recognition in two places (alias shim + leaf driver) creates drift. Keep the alias `.c` as a single `#include` line. + +**Alias the leaf directly — never daisy-chain.** If `` itself aliases another driver, alias `` to the **leaf** (the one with the actual implementation), not to the intermediate alias. Two-hop chains (`` → `` → ``) make every macro recognition twice as painful and obscure the dependency graph. Trace the include chain in the existing `.h` and `.c` files until you find the file with real driver code, and point your new alias at that. + **Test alias** — when a driver is reused via alias AND the original driver already has a platform-specific test file (`tests//test__.c`), create a matching test alias at `tests//test__.c`: ```c diff --git a/.github/workflows/boards.yml b/.github/workflows/boards.yml index a531cfa..2ebc41b 100644 --- a/.github/workflows/boards.yml +++ b/.github/workflows/boards.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - board: [stm32wb55xx_nucleo, stm32wba55cg_nucleo, pic32cz_curiosity_ultra, stm32h563zi_nucleo, stm32f411_blackpill, stm32c031_nucleo, stm32f091rc_nucleo] + board: [stm32wb55xx_nucleo, stm32wba55cg_nucleo, pic32cz_curiosity_ultra, stm32h563zi_nucleo, stm32f411_blackpill, stm32c031_nucleo, stm32f091rc_nucleo, stm32f302r8_nucleo] extra_cflags: ["", "-DWHAL_CFG_NO_TIMEOUT"] include: - board: stm32wb55xx_nucleo diff --git a/boards/README.md b/boards/README.md index 0d6bd6c..2d0b3e3 100644 --- a/boards/README.md +++ b/boards/README.md @@ -17,6 +17,7 @@ build configuration. | Microchip PIC32CZ CA Curiosity Ultra | PIC32CZ | Cortex-M7 | `pic32cz_curiosity_ultra/` | | ST NUCLEO-C031C6 | STM32C0 | Cortex-M0+ | `stm32c031_nucleo/` | | ST NUCLEO-F091RC | STM32F0 | Cortex-M0 | `stm32f091rc_nucleo/` | +| ST NUCLEO-F302R8 | STM32F3 | Cortex-M4 | `stm32f302r8_nucleo/` | | WeAct BlackPill STM32F411 | STM32F4 | Cortex-M4 | `stm32f411_blackpill/` | | ST NUCLEO-H563ZI | STM32H5 | Cortex-M33 | `stm32h563zi_nucleo/` | | ST NUCLEO-WB55RG | STM32WB | Cortex-M4 | `stm32wb55xx_nucleo/` | diff --git a/boards/stm32f302r8_nucleo/Makefile.inc b/boards/stm32f302r8_nucleo/Makefile.inc new file mode 100644 index 0000000..fd1b0a3 --- /dev/null +++ b/boards/stm32f302r8_nucleo/Makefile.inc @@ -0,0 +1,43 @@ +_BOARD_DIR := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST)))) + +PLATFORM = stm32f3 +TESTS ?= clock gpio timer flash uart spi + +GCC = $(GCC_PATH)arm-none-eabi-gcc +LD = $(GCC_PATH)arm-none-eabi-gcc +OBJCOPY = $(GCC_PATH)arm-none-eabi-objcopy + +CFLAGS += -Wall -Werror $(INCLUDE) -g3 \ + -ffreestanding -nostdlib \ + -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 \ + -DPLATFORM_STM32F3 -MMD -MP \ + -DWHAL_CFG_GPIO_API_MAPPING_STM32F3 \ + -DWHAL_CFG_CLOCK_API_MAPPING_STM32F3 \ + -DWHAL_CFG_UART_API_MAPPING_STM32F3 \ + -DWHAL_CFG_SPI_API_MAPPING_STM32F3 \ + -DWHAL_CFG_I2C_API_MAPPING_STM32F3 \ + $(if $(filter iwdg,$(WATCHDOG)),-DBOARD_WATCHDOG_IWDG) \ + $(if $(filter wwdg,$(WATCHDOG)),-DBOARD_WATCHDOG_WWDG) +LDFLAGS = -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 \ + -ffreestanding -nostartfiles -Wl,--omagic -static + +LINKER_SCRIPT ?= $(_BOARD_DIR)/linker.ld + +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/*/supply.c) +BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/flash.c) +BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/rng.c) +BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/crypto.c) +BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/sensor.c) +BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/block.c) +BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/watchdog.c) +BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/stm32f3_*.c) +BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/systick.c) + +# Peripheral devices +include $(WHAL_DIR)/boards/peripheral/Makefile.inc diff --git a/boards/stm32f302r8_nucleo/board.c b/boards/stm32f302r8_nucleo/board.c new file mode 100644 index 0000000..bc2e14d --- /dev/null +++ b/boards/stm32f302r8_nucleo/board.c @@ -0,0 +1,294 @@ +#include +#include +#include "board.h" +#include +#include "peripheral.h" + +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++; + if (g_waiting) { + if (tickBefore > g_tick) + g_tickOverflow = 1; + } +} + +uint32_t Board_GetTick(void) +{ + return g_tick; +} + +whal_Timeout g_whalTimeout = { + .timeoutTicks = 1000, + .GetTick = Board_GetTick, +}; + +/* Clock — PLL at 48 MHz (HSI/2 * 12) */ +whal_Clock g_whalClock = { + .regmap = { WHAL_STM32F302_RCC_REGMAP }, + + .cfg = &(whal_Stm32f3Rcc_Cfg) { + .sysClkSrc = WHAL_STM32F3_RCC_SYSCLK_SRC_PLL, + .pllCfg = &(whal_Stm32f3Rcc_PllCfg) { + .clkSrc = WHAL_STM32F3_RCC_PLLSRC_HSI_DIV2, + .prediv = 1, + .pllmul = 12, + }, + }, +}; + +static const whal_Stm32f3Rcc_Clk g_clocks[] = { + {WHAL_STM32F302_GPIOA_CLOCK}, + {WHAL_STM32F302_GPIOB_CLOCK}, + {WHAL_STM32F302_GPIOC_CLOCK}, + {WHAL_STM32F302_USART2_CLOCK}, + {WHAL_STM32F302_SPI3_CLOCK}, + {WHAL_STM32F302_I2C1_CLOCK}, +#ifdef BOARD_WATCHDOG_WWDG + {WHAL_STM32F302_WWDG_CLOCK}, +#endif +}; +#define CLOCK_COUNT (sizeof(g_clocks) / sizeof(g_clocks[0])) + +/* GPIO */ +whal_Gpio g_whalGpio = { + .regmap = { WHAL_STM32F302_GPIO_REGMAP }, + + .cfg = &(whal_Stm32f3Gpio_Cfg) { + .pinCfg = (whal_Stm32f3Gpio_PinCfg[PIN_COUNT]) { + /* LD2 Green LED on PB13 (per UM1724 Figure 14, NUCLEO-F302R8) */ + [LED_PIN] = WHAL_STM32F3_GPIO_PIN( + WHAL_STM32F3_GPIO_PORT_B, 13, WHAL_STM32F3_GPIO_MODE_OUT, + WHAL_STM32F3_GPIO_OUTTYPE_PUSHPULL, WHAL_STM32F3_GPIO_SPEED_LOW, + WHAL_STM32F3_GPIO_PULL_NONE, 0), + /* USART2 TX on PA2, AF7 */ + [UART_TX_PIN] = WHAL_STM32F3_GPIO_PIN( + WHAL_STM32F3_GPIO_PORT_A, 2, WHAL_STM32F3_GPIO_MODE_ALTFN, + WHAL_STM32F3_GPIO_OUTTYPE_PUSHPULL, WHAL_STM32F3_GPIO_SPEED_FAST, + WHAL_STM32F3_GPIO_PULL_UP, 7), + /* USART2 RX on PA3, AF7 */ + [UART_RX_PIN] = WHAL_STM32F3_GPIO_PIN( + WHAL_STM32F3_GPIO_PORT_A, 3, WHAL_STM32F3_GPIO_MODE_ALTFN, + WHAL_STM32F3_GPIO_OUTTYPE_PUSHPULL, WHAL_STM32F3_GPIO_SPEED_FAST, + WHAL_STM32F3_GPIO_PULL_UP, 7), + /* SPI3 SCK on PB3, AF6 */ + [SPI_SCK_PIN] = WHAL_STM32F3_GPIO_PIN( + WHAL_STM32F3_GPIO_PORT_B, 3, WHAL_STM32F3_GPIO_MODE_ALTFN, + WHAL_STM32F3_GPIO_OUTTYPE_PUSHPULL, WHAL_STM32F3_GPIO_SPEED_FAST, + WHAL_STM32F3_GPIO_PULL_NONE, 6), + /* SPI3 MISO on PB4, AF6 */ + [SPI_MISO_PIN] = WHAL_STM32F3_GPIO_PIN( + WHAL_STM32F3_GPIO_PORT_B, 4, WHAL_STM32F3_GPIO_MODE_ALTFN, + WHAL_STM32F3_GPIO_OUTTYPE_PUSHPULL, WHAL_STM32F3_GPIO_SPEED_FAST, + WHAL_STM32F3_GPIO_PULL_NONE, 6), + /* SPI3 MOSI on PB5, AF6 */ + [SPI_MOSI_PIN] = WHAL_STM32F3_GPIO_PIN( + WHAL_STM32F3_GPIO_PORT_B, 5, WHAL_STM32F3_GPIO_MODE_ALTFN, + WHAL_STM32F3_GPIO_OUTTYPE_PUSHPULL, WHAL_STM32F3_GPIO_SPEED_FAST, + WHAL_STM32F3_GPIO_PULL_NONE, 6), + /* SPI CS on PB12, output, push-pull */ + [SPI_CS_PIN] = WHAL_STM32F3_GPIO_PIN( + WHAL_STM32F3_GPIO_PORT_B, 12, WHAL_STM32F3_GPIO_MODE_OUT, + WHAL_STM32F3_GPIO_OUTTYPE_PUSHPULL, WHAL_STM32F3_GPIO_SPEED_FAST, + WHAL_STM32F3_GPIO_PULL_UP, 0), + /* I2C1 SCL on PB8, AF4, open-drain */ + [I2C_SCL_PIN] = WHAL_STM32F3_GPIO_PIN( + WHAL_STM32F3_GPIO_PORT_B, 8, WHAL_STM32F3_GPIO_MODE_ALTFN, + WHAL_STM32F3_GPIO_OUTTYPE_OPENDRAIN, WHAL_STM32F3_GPIO_SPEED_FAST, + WHAL_STM32F3_GPIO_PULL_UP, 4), + /* I2C1 SDA on PB9, AF4, open-drain */ + [I2C_SDA_PIN] = WHAL_STM32F3_GPIO_PIN( + WHAL_STM32F3_GPIO_PORT_B, 9, WHAL_STM32F3_GPIO_MODE_ALTFN, + WHAL_STM32F3_GPIO_OUTTYPE_OPENDRAIN, WHAL_STM32F3_GPIO_SPEED_FAST, + WHAL_STM32F3_GPIO_PULL_UP, 4), + }, + .pinCount = PIN_COUNT, + }, +}; + +/* Timer — SysTick at 1 ms */ +whal_Timer g_whalTimer = { + .regmap = { WHAL_CORTEX_M4_SYSTICK_REGMAP }, + .driver = WHAL_CORTEX_M4_SYSTICK_DRIVER, + + .cfg = &(whal_SysTick_Cfg) { + .cyclesPerTick = 48000000 / 1000, + .clkSrc = WHAL_SYSTICK_CLKSRC_SYSCLK, + .tickInt = WHAL_SYSTICK_TICKINT_ENABLED, + }, +}; + +/* UART — USART2 at 115200 baud */ +whal_Uart g_whalUart = { + .regmap = { WHAL_STM32F302_USART2_REGMAP }, + + .cfg = &(whal_Stm32f3Uart_Cfg) { + .timeout = &g_whalTimeout, + .brr = WHAL_STM32F3_UART_BRR(48000000, 115200), + }, +}; + +/* SPI — SPI3 */ +whal_Spi g_whalSpi = { + .regmap = { WHAL_STM32F302_SPI3_REGMAP }, + + .cfg = &(whal_Stm32f3Spi_Cfg) { + .pclk = 48000000, + .timeout = &g_whalTimeout, + }, +}; + +/* I2C — I2C1 (HSI at 8 MHz per RCC_CFGR3.I2C1SW reset default) */ +whal_I2c g_whalI2c = { + .regmap = { WHAL_STM32F302_I2C1_REGMAP }, + + .cfg = &(whal_Stm32f3I2c_Cfg) { + .pclk = 8000000, + .timeout = &g_whalTimeout, + }, +}; + +/* Flash — 64 KB */ +whal_Flash g_whalFlash = { + .regmap = { WHAL_STM32F302_FLASH_REGMAP }, + .driver = WHAL_STM32F302_FLASH_DRIVER, + + .cfg = &(whal_Stm32f3Flash_Cfg) { + .startAddr = 0x08000000, + .size = 0x10000, + .timeout = &g_whalTimeout, + }, +}; + +#ifdef BOARD_WATCHDOG_IWDG +whal_Watchdog g_whalWatchdog = { + .regmap = { WHAL_STM32F302_IWDG_REGMAP }, + .driver = WHAL_STM32F302_IWDG_DRIVER, + + .cfg = &(whal_Stm32f3Iwdg_Cfg) { + .prescaler = WHAL_STM32F3_IWDG_PR_64, + .reload = 500, + .timeout = &g_whalTimeout, + }, +}; +#elif defined(BOARD_WATCHDOG_WWDG) +whal_Watchdog g_whalWatchdog = { + .regmap = { WHAL_STM32F302_WWDG_REGMAP }, + .driver = WHAL_STM32F302_WWDG_DRIVER, + + .cfg = &(whal_Stm32f3Wwdg_Cfg) { + .prescaler = 3, + .window = 0x7F, + .counter = 0x7F, + }, +}; +#endif + +void Board_WaitMs(size_t ms) +{ + uint32_t startCount = g_tick; + while ((g_tick - startCount) < ms) + ; +} + +whal_Error Board_Init(void) +{ + whal_Error err; + + /* Set flash latency before increasing clock speed. + * STM32F3: 0 WS for HCLK <= 24 MHz, 1 WS for 24 < HCLK <= 48 MHz, + * 2 WS for 48 < HCLK <= 72 MHz. */ + err = whal_Stm32f3Flash_Ext_SetLatency(&g_whalFlash, + WHAL_STM32F3_FLASH_LATENCY_1); + if (err) + return err; + + err = whal_Clock_Init(&g_whalClock); + if (err) + return err; + + for (size_t i = 0; i < CLOCK_COUNT; i++) { + err = whal_Clock_Enable(&g_whalClock, &g_clocks[i]); + if (err) + return err; + } + + err = whal_Gpio_Init(&g_whalGpio); + if (err) + return err; + + err = whal_Uart_Init(&g_whalUart); + if (err) + return err; + + err = whal_Spi_Init(&g_whalSpi); + if (err) + return err; + + err = whal_I2c_Init(&g_whalI2c); + if (err) + return err; + + err = whal_Timer_Init(&g_whalTimer); + if (err) + return err; + + err = whal_Timer_Start(&g_whalTimer); + if (err) + return err; + + err = Peripheral_Init(); + if (err) + return err; + + return WHAL_SUCCESS; +} + +whal_Error Board_Deinit(void) +{ + whal_Error err; + + err = Peripheral_Deinit(); + if (err) + return err; + + err = whal_Timer_Stop(&g_whalTimer); + if (err) + return err; + + err = whal_Timer_Deinit(&g_whalTimer); + if (err) + return err; + + err = whal_Spi_Deinit(&g_whalSpi); + if (err) + return err; + + err = whal_I2c_Deinit(&g_whalI2c); + if (err) + return err; + + err = whal_Uart_Deinit(&g_whalUart); + if (err) + return err; + + err = whal_Gpio_Deinit(&g_whalGpio); + if (err) + return err; + + for (size_t i = 0; i < CLOCK_COUNT; i++) { + err = whal_Clock_Disable(&g_whalClock, &g_clocks[i]); + if (err) + return err; + } + + err = whal_Clock_Deinit(&g_whalClock); + if (err) + return err; + + return WHAL_SUCCESS; +} diff --git a/boards/stm32f302r8_nucleo/board.h b/boards/stm32f302r8_nucleo/board.h new file mode 100644 index 0000000..01469c0 --- /dev/null +++ b/boards/stm32f302r8_nucleo/board.h @@ -0,0 +1,46 @@ +#ifndef BOARD_H +#define BOARD_H + +#include +#include +#include + +extern whal_Clock g_whalClock; +extern whal_Gpio g_whalGpio; +extern whal_Timer g_whalTimer; +extern whal_Uart g_whalUart; +extern whal_Spi g_whalSpi; +extern whal_I2c g_whalI2c; +extern whal_Flash g_whalFlash; +extern whal_Watchdog g_whalWatchdog; + +extern whal_Timeout g_whalTimeout; +extern volatile uint32_t g_tick; + +enum { + LED_PIN, + UART_TX_PIN, + UART_RX_PIN, + SPI_SCK_PIN, + SPI_MISO_PIN, + SPI_MOSI_PIN, + SPI_CS_PIN, + I2C_SCL_PIN, + I2C_SDA_PIN, + PIN_COUNT, +}; + +#define BOARD_LED_PIN 0 +#define BOARD_LED_PORT_OFFSET 0x400 /* GPIOB */ +#define BOARD_LED_PIN_NUM 13 + +#define BOARD_FLASH_START_ADDR 0x08000000 +#define BOARD_FLASH_SIZE 0x10000 +#define BOARD_FLASH_TEST_ADDR 0x0800F800 +#define BOARD_FLASH_SECTOR_SZ 0x800 + +whal_Error Board_Init(void); +whal_Error Board_Deinit(void); +void Board_WaitMs(size_t ms); + +#endif /* BOARD_H */ diff --git a/boards/stm32f302r8_nucleo/ivt.c b/boards/stm32f302r8_nucleo/ivt.c new file mode 100644 index 0000000..9f53bc6 --- /dev/null +++ b/boards/stm32f302r8_nucleo/ivt.c @@ -0,0 +1,225 @@ +#include +#include + +extern uint32_t _estack[]; +extern uint32_t _sidata[]; +extern uint32_t _sdata[]; +extern uint32_t _edata[]; +extern uint32_t _sbss[]; +extern uint32_t _ebss[]; + +extern void main(); + +void __attribute__((naked,noreturn)) Default_Handler() +{ + while(1); +} + +void Reset_Handler() __attribute__((weak)); +void NMI_Handler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void HardFault_Handler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void MemManage_Handler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void BusFault_Handler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void UsageFault_Handler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void SVC_Handler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void DebugMon_Handler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void PendSV_Handler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void SysTick_Handler() __attribute__((weak, noreturn, alias("Default_Handler"))); + +/* STM32F302x6/x8 peripheral interrupts (RM0365 Table 41) */ +void WWDG_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void PVD_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void TAMPER_STAMP_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void RTC_WKUP_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void FLASH_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void RCC_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void EXTI0_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void EXTI1_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void EXTI2_TS_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void EXTI3_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void EXTI4_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void DMA1_Channel1_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void DMA1_Channel2_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void DMA1_Channel3_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void DMA1_Channel4_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void DMA1_Channel5_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void DMA1_Channel6_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void DMA1_Channel7_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void ADC1_2_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void CAN_TX_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void CAN_RX0_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void CAN_RX1_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void CAN_SCE_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void EXTI9_5_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void TIM1_BRK_TIM15_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void TIM1_UP_TIM16_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void TIM1_TRG_COM_TIM17_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void TIM1_CC_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void TIM2_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void I2C1_EV_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void I2C1_ER_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void I2C2_EV_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void I2C2_ER_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void SPI2_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void USART1_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void USART2_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void USART3_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void EXTI15_10_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void RTC_Alarm_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void USBWakeUp_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void SPI3_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void TIM6_DAC_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void COMP2_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void COMP4_6_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void I2C3_EV_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void I2C3_ER_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void USB_HP_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void USB_LP_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void USBWakeUp_RMP_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); +void FPU_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler"))); + +#define RESERVED Default_Handler + +void *memcpy(void *dest, const void *src, size_t n) +{ + unsigned char *d = dest; + const unsigned char *s = src; + + for (size_t i = 0; i < n; i++) + d[i] = s[i]; + + return dest; +} + +void *memset(void *s, int c, size_t n) +{ + unsigned char *p = s; + unsigned char v = (unsigned char)c; + + for (size_t i = 0; i < n; i++) + p[i] = v; + + return s; +} + +void (* const interrupt_vector_table[])() __attribute__((section(".isr_vector"))) = { + (void (*)())_estack, + Reset_Handler, + NMI_Handler, + HardFault_Handler, + MemManage_Handler, + BusFault_Handler, + UsageFault_Handler, + RESERVED, /* Reserved */ + RESERVED, /* Reserved */ + RESERVED, /* Reserved */ + RESERVED, /* Reserved */ + SVC_Handler, + DebugMon_Handler, + RESERVED, /* Reserved */ + PendSV_Handler, + SysTick_Handler, + /* STM32F302x6/x8 peripheral interrupts (position 0-81) */ + WWDG_IRQHandler, /* 0 */ + PVD_IRQHandler, /* 1 */ + TAMPER_STAMP_IRQHandler, /* 2 */ + RTC_WKUP_IRQHandler, /* 3 */ + FLASH_IRQHandler, /* 4 */ + RCC_IRQHandler, /* 5 */ + EXTI0_IRQHandler, /* 6 */ + EXTI1_IRQHandler, /* 7 */ + EXTI2_TS_IRQHandler, /* 8 */ + EXTI3_IRQHandler, /* 9 */ + EXTI4_IRQHandler, /* 10 */ + DMA1_Channel1_IRQHandler, /* 11 */ + DMA1_Channel2_IRQHandler, /* 12 */ + DMA1_Channel3_IRQHandler, /* 13 */ + DMA1_Channel4_IRQHandler, /* 14 */ + DMA1_Channel5_IRQHandler, /* 15 */ + DMA1_Channel6_IRQHandler, /* 16 */ + DMA1_Channel7_IRQHandler, /* 17 */ + ADC1_2_IRQHandler, /* 18 */ + CAN_TX_IRQHandler, /* 19 */ + CAN_RX0_IRQHandler, /* 20 */ + CAN_RX1_IRQHandler, /* 21 */ + CAN_SCE_IRQHandler, /* 22 */ + EXTI9_5_IRQHandler, /* 23 */ + TIM1_BRK_TIM15_IRQHandler, /* 24 */ + TIM1_UP_TIM16_IRQHandler, /* 25 */ + TIM1_TRG_COM_TIM17_IRQHandler, /* 26 */ + TIM1_CC_IRQHandler, /* 27 */ + TIM2_IRQHandler, /* 28 */ + RESERVED, /* 29 */ + RESERVED, /* 30 */ + I2C1_EV_IRQHandler, /* 31 */ + I2C1_ER_IRQHandler, /* 32 */ + I2C2_EV_IRQHandler, /* 33 */ + I2C2_ER_IRQHandler, /* 34 */ + RESERVED, /* 35 */ + SPI2_IRQHandler, /* 36 */ + USART1_IRQHandler, /* 37 */ + USART2_IRQHandler, /* 38 */ + USART3_IRQHandler, /* 39 */ + EXTI15_10_IRQHandler, /* 40 */ + RTC_Alarm_IRQHandler, /* 41 */ + USBWakeUp_IRQHandler, /* 42 */ + RESERVED, /* 43 */ + RESERVED, /* 44 */ + RESERVED, /* 45 */ + RESERVED, /* 46 */ + RESERVED, /* 47 */ + RESERVED, /* 48 */ + RESERVED, /* 49 */ + RESERVED, /* 50 */ + SPI3_IRQHandler, /* 51 */ + RESERVED, /* 52 */ + RESERVED, /* 53 */ + TIM6_DAC_IRQHandler, /* 54 */ + RESERVED, /* 55 */ + RESERVED, /* 56 */ + RESERVED, /* 57 */ + RESERVED, /* 58 */ + RESERVED, /* 59 */ + RESERVED, /* 60 */ + RESERVED, /* 61 */ + RESERVED, /* 62 */ + RESERVED, /* 63 */ + COMP2_IRQHandler, /* 64 */ + COMP4_6_IRQHandler, /* 65 */ + RESERVED, /* 66 */ + RESERVED, /* 67 */ + RESERVED, /* 68 */ + RESERVED, /* 69 */ + RESERVED, /* 70 */ + RESERVED, /* 71 */ + I2C3_EV_IRQHandler, /* 72 */ + I2C3_ER_IRQHandler, /* 73 */ + USB_HP_IRQHandler, /* 74 */ + USB_LP_IRQHandler, /* 75 */ + USBWakeUp_RMP_IRQHandler, /* 76 */ + RESERVED, /* 77 */ + RESERVED, /* 78 */ + RESERVED, /* 79 */ + RESERVED, /* 80 */ + FPU_IRQHandler, /* 81 */ +}; + +void __attribute__((naked)) Reset_Handler() +{ + __asm__("ldr r0, =_estack\n\t" + "mov sp, r0"); + + /* Copy data section from flash to RAM */ + uint32_t data_section_size = _edata - _sdata; + memcpy(_sdata, _sidata, data_section_size * 4); + + /* Zero out bss */ + uint32_t bss_section_size = _ebss - _sbss; + memset(_sbss, 0, bss_section_size * 4); + + /* Set Interrupt Vector Table Offset */ + uint32_t *vtor = (uint32_t *)0xE000ED08; + *vtor = (uint32_t)interrupt_vector_table; + + main(); +} diff --git a/boards/stm32f302r8_nucleo/linker.ld b/boards/stm32f302r8_nucleo/linker.ld new file mode 100644 index 0000000..1f4655a --- /dev/null +++ b/boards/stm32f302r8_nucleo/linker.ld @@ -0,0 +1,121 @@ +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20004000; /* end of 16 KB RAM */ +/* Generate a link error if the stack don't fit into RAM */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K +RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 16K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM +} diff --git a/src/clock/stm32f3_rcc.c b/src/clock/stm32f3_rcc.c new file mode 100644 index 0000000..d265ee2 --- /dev/null +++ b/src/clock/stm32f3_rcc.c @@ -0,0 +1,285 @@ +#include +#include +#include +#include +#include + +/* + * STM32F3 RCC register offsets and bit definitions. + * From RM0365 Section 9.4 (RCC registers). + * + * RCC_CR (0x00): + * Bit 0 HSION, Bit 1 HSIRDY + * Bit 16 HSEON, Bit 17 HSERDY + * Bit 24 PLLON, Bit 25 PLLRDY + * + * RCC_CFGR (0x04): + * Bits 1:0 SW (system clock switch) + * Bits 3:2 SWS (system clock switch status) + * Bits 7:4 HPRE (AHB prescaler) + * Bits 10:8 PPRE1 (APB1 prescaler) + * Bits 13:11 PPRE2 (APB2 prescaler) + * Bit 16 PLLSRC (0=HSI/2, 1=HSE/PREDIV) + * Bits 21:18 PLLMUL (multiplication factor) + * + * RCC_CFGR2 (0x2C): + * Bits 3:0 PREDIV (HSE divider for PLL) + */ + +#define RCC_CR_REG 0x00 +#define RCC_CR_HSION_Pos 0 +#define RCC_CR_HSION_Msk (1UL << RCC_CR_HSION_Pos) +#define RCC_CR_HSIRDY_Pos 1 +#define RCC_CR_HSIRDY_Msk (1UL << RCC_CR_HSIRDY_Pos) +#define RCC_CR_HSEON_Pos 16 +#define RCC_CR_HSEON_Msk (1UL << RCC_CR_HSEON_Pos) +#define RCC_CR_HSERDY_Pos 17 +#define RCC_CR_HSERDY_Msk (1UL << RCC_CR_HSERDY_Pos) +#define RCC_CR_PLLON_Pos 24 +#define RCC_CR_PLLON_Msk (1UL << RCC_CR_PLLON_Pos) +#define RCC_CR_PLLRDY_Pos 25 +#define RCC_CR_PLLRDY_Msk (1UL << RCC_CR_PLLRDY_Pos) + +#define RCC_CFGR_REG 0x04 +#define RCC_CFGR_SW_Pos 0 +#define RCC_CFGR_SW_Msk (WHAL_BITMASK(2) << RCC_CFGR_SW_Pos) +#define RCC_CFGR_SWS_Pos 2 +#define RCC_CFGR_SWS_Msk (WHAL_BITMASK(2) << RCC_CFGR_SWS_Pos) +#define RCC_CFGR_PLLSRC_Pos 16 +#define RCC_CFGR_PLLSRC_Msk (1UL << RCC_CFGR_PLLSRC_Pos) +#define RCC_CFGR_PLLMUL_Pos 18 +#define RCC_CFGR_PLLMUL_Msk (WHAL_BITMASK(4) << RCC_CFGR_PLLMUL_Pos) + +#define RCC_CFGR_SW_HSI 0 +#define RCC_CFGR_SW_HSE 1 +#define RCC_CFGR_SW_PLL 2 + +#define RCC_CFGR2_REG 0x2C +#define RCC_CFGR2_PREDIV_Pos 0 +#define RCC_CFGR2_PREDIV_Msk (WHAL_BITMASK(4) << RCC_CFGR2_PREDIV_Pos) + +#define RCC_CFGR3_REG 0x30 +#define RCC_CFGR3_I2C1SW_Pos 4 +#define RCC_CFGR3_I2C1SW_Msk (1UL << RCC_CFGR3_I2C1SW_Pos) + +#ifdef WHAL_CFG_CLOCK_API_MAPPING_STM32F3 +#define whal_Stm32f3Rcc_Init whal_Clock_Init +#define whal_Stm32f3Rcc_Deinit whal_Clock_Deinit +#define whal_Stm32f3Rcc_Enable whal_Clock_Enable +#define whal_Stm32f3Rcc_Disable whal_Clock_Disable +#endif /* WHAL_CFG_CLOCK_API_MAPPING_STM32F3 */ + +static whal_Error Stm32f3Rcc_EnablePllSource(size_t base, + whal_Stm32f3Rcc_PllCfg *pll) +{ + size_t rdy; + + switch (pll->clkSrc) { + case WHAL_STM32F3_RCC_PLLSRC_HSI_DIV2: + whal_Reg_Update(base, RCC_CR_REG, RCC_CR_HSION_Msk, + whal_SetBits(RCC_CR_HSION_Msk, RCC_CR_HSION_Pos, 1)); + do { + whal_Reg_Get(base, RCC_CR_REG, + RCC_CR_HSIRDY_Msk, RCC_CR_HSIRDY_Pos, &rdy); + } while (!rdy); + break; + + case WHAL_STM32F3_RCC_PLLSRC_HSE_PREDIV: + whal_Reg_Update(base, RCC_CR_REG, RCC_CR_HSEON_Msk, + whal_SetBits(RCC_CR_HSEON_Msk, RCC_CR_HSEON_Pos, 1)); + do { + whal_Reg_Get(base, RCC_CR_REG, + RCC_CR_HSERDY_Msk, RCC_CR_HSERDY_Pos, &rdy); + } while (!rdy); + break; + } + + return WHAL_SUCCESS; +} + +static void Stm32f3Rcc_ConfigurePll(size_t base, whal_Stm32f3Rcc_PllCfg *pll) +{ + uint32_t pllsrc; + + /* Disable PLL before reconfiguring */ + whal_Reg_Update(base, RCC_CR_REG, RCC_CR_PLLON_Msk, + whal_SetBits(RCC_CR_PLLON_Msk, RCC_CR_PLLON_Pos, 0)); + + /* Set PREDIV (only meaningful for HSE source, but safe to set always) */ + whal_Reg_Update(base, RCC_CFGR2_REG, RCC_CFGR2_PREDIV_Msk, + whal_SetBits(RCC_CFGR2_PREDIV_Msk, RCC_CFGR2_PREDIV_Pos, + pll->prediv - 1)); + + /* Set PLLMUL */ + whal_Reg_Update(base, RCC_CFGR_REG, RCC_CFGR_PLLMUL_Msk, + whal_SetBits(RCC_CFGR_PLLMUL_Msk, RCC_CFGR_PLLMUL_Pos, + pll->pllmul - 2)); + + /* Set PLL source: 0 = HSI/2, 1 = HSE/PREDIV */ + pllsrc = (pll->clkSrc == WHAL_STM32F3_RCC_PLLSRC_HSE_PREDIV) ? 1 : 0; + whal_Reg_Update(base, RCC_CFGR_REG, RCC_CFGR_PLLSRC_Msk, + whal_SetBits(RCC_CFGR_PLLSRC_Msk, RCC_CFGR_PLLSRC_Pos, + pllsrc)); + + /* Enable PLL and wait for lock */ + whal_Reg_Update(base, RCC_CR_REG, RCC_CR_PLLON_Msk, + whal_SetBits(RCC_CR_PLLON_Msk, RCC_CR_PLLON_Pos, 1)); + + size_t rdy; + do { + whal_Reg_Get(base, RCC_CR_REG, + RCC_CR_PLLRDY_Msk, RCC_CR_PLLRDY_Pos, &rdy); + } while (!rdy); +} + +whal_Error whal_Stm32f3Rcc_Init(whal_Clock *clkDev) +{ + whal_Stm32f3Rcc_Cfg *cfg; + size_t base; + uint32_t sw; + size_t sws; + + if (!clkDev || !clkDev->cfg) + return WHAL_EINVAL; + + cfg = (whal_Stm32f3Rcc_Cfg *)clkDev->cfg; + base = clkDev->regmap.base; + + switch (cfg->sysClkSrc) { + case WHAL_STM32F3_RCC_SYSCLK_SRC_HSI: { + size_t rdy; + whal_Reg_Update(base, RCC_CR_REG, RCC_CR_HSION_Msk, + whal_SetBits(RCC_CR_HSION_Msk, RCC_CR_HSION_Pos, 1)); + do { + whal_Reg_Get(base, RCC_CR_REG, + RCC_CR_HSIRDY_Msk, RCC_CR_HSIRDY_Pos, &rdy); + } while (!rdy); + sw = RCC_CFGR_SW_HSI; + break; + } + + case WHAL_STM32F3_RCC_SYSCLK_SRC_HSE: { + size_t rdy; + whal_Reg_Update(base, RCC_CR_REG, RCC_CR_HSEON_Msk, + whal_SetBits(RCC_CR_HSEON_Msk, RCC_CR_HSEON_Pos, 1)); + do { + whal_Reg_Get(base, RCC_CR_REG, + RCC_CR_HSERDY_Msk, RCC_CR_HSERDY_Pos, &rdy); + } while (!rdy); + sw = RCC_CFGR_SW_HSE; + break; + } + + case WHAL_STM32F3_RCC_SYSCLK_SRC_PLL: + if (!cfg->pllCfg || + cfg->pllCfg->prediv < 1 || cfg->pllCfg->prediv > 16 || + cfg->pllCfg->pllmul < 2 || cfg->pllCfg->pllmul > 16) + return WHAL_EINVAL; + + Stm32f3Rcc_EnablePllSource(base, cfg->pllCfg); + Stm32f3Rcc_ConfigurePll(base, cfg->pllCfg); + sw = RCC_CFGR_SW_PLL; + break; + + default: + return WHAL_EINVAL; + } + + /* Switch system clock */ + whal_Reg_Update(base, RCC_CFGR_REG, RCC_CFGR_SW_Msk, + whal_SetBits(RCC_CFGR_SW_Msk, RCC_CFGR_SW_Pos, sw)); + + /* Wait for switch status to confirm */ + do { + whal_Reg_Get(base, RCC_CFGR_REG, + RCC_CFGR_SWS_Msk, RCC_CFGR_SWS_Pos, &sws); + } while (sws != sw); + + return WHAL_SUCCESS; +} + +whal_Error whal_Stm32f3Rcc_Deinit(whal_Clock *clkDev) +{ + size_t sws; + + if (!clkDev) + return WHAL_EINVAL; + + /* Switch back to HSI */ + whal_Reg_Update(clkDev->regmap.base, RCC_CR_REG, RCC_CR_HSION_Msk, + whal_SetBits(RCC_CR_HSION_Msk, RCC_CR_HSION_Pos, 1)); + + size_t rdy; + do { + whal_Reg_Get(clkDev->regmap.base, RCC_CR_REG, + RCC_CR_HSIRDY_Msk, RCC_CR_HSIRDY_Pos, &rdy); + } while (!rdy); + + whal_Reg_Update(clkDev->regmap.base, RCC_CFGR_REG, RCC_CFGR_SW_Msk, + whal_SetBits(RCC_CFGR_SW_Msk, RCC_CFGR_SW_Pos, + RCC_CFGR_SW_HSI)); + + do { + whal_Reg_Get(clkDev->regmap.base, RCC_CFGR_REG, + RCC_CFGR_SWS_Msk, RCC_CFGR_SWS_Pos, &sws); + } while (sws != RCC_CFGR_SW_HSI); + + /* Disable PLL */ + whal_Reg_Update(clkDev->regmap.base, RCC_CR_REG, RCC_CR_PLLON_Msk, + whal_SetBits(RCC_CR_PLLON_Msk, RCC_CR_PLLON_Pos, 0)); + + return WHAL_SUCCESS; +} + +whal_Error whal_Stm32f3Rcc_Enable(whal_Clock *clkDev, const void *clk) +{ + whal_Stm32f3Rcc_Clk *stClk; + + if (!clkDev || !clk) + return WHAL_EINVAL; + + stClk = (whal_Stm32f3Rcc_Clk *)clk; + + whal_Reg_Update(clkDev->regmap.base, stClk->regOffset, stClk->enableMask, + whal_SetBits(stClk->enableMask, stClk->enablePos, 1)); + + return WHAL_SUCCESS; +} + +whal_Error whal_Stm32f3Rcc_Disable(whal_Clock *clkDev, const void *clk) +{ + whal_Stm32f3Rcc_Clk *stClk; + + if (!clkDev || !clk) + return WHAL_EINVAL; + + stClk = (whal_Stm32f3Rcc_Clk *)clk; + + whal_Reg_Update(clkDev->regmap.base, stClk->regOffset, stClk->enableMask, + whal_SetBits(stClk->enableMask, stClk->enablePos, 0)); + + return WHAL_SUCCESS; +} + +whal_Error whal_Stm32f3Rcc_Ext_SetI2c1ClkSrc(whal_Clock *clkDev, + whal_Stm32f3Rcc_I2c1ClkSrc src) +{ + if (!clkDev) { + return WHAL_EINVAL; + } + + whal_Reg_Update(clkDev->regmap.base, RCC_CFGR3_REG, RCC_CFGR3_I2C1SW_Msk, + whal_SetBits(RCC_CFGR3_I2C1SW_Msk, + RCC_CFGR3_I2C1SW_Pos, src)); + + return WHAL_SUCCESS; +} + +#ifndef WHAL_CFG_CLOCK_API_MAPPING_STM32F3 +const whal_ClockDriver whal_Stm32f3Rcc_Driver = { + .Init = whal_Stm32f3Rcc_Init, + .Deinit = whal_Stm32f3Rcc_Deinit, + .Enable = whal_Stm32f3Rcc_Enable, + .Disable = whal_Stm32f3Rcc_Disable, +}; +#endif /* !WHAL_CFG_CLOCK_API_MAPPING_STM32F3 */ diff --git a/src/flash/stm32f0_flash.c b/src/flash/stm32f0_flash.c index 17babf5..202094e 100644 --- a/src/flash/stm32f0_flash.c +++ b/src/flash/stm32f0_flash.c @@ -36,7 +36,8 @@ #define FLASH_AR_REG 0x14 -#ifdef WHAL_CFG_FLASH_API_MAPPING_STM32F0 +#if defined(WHAL_CFG_FLASH_API_MAPPING_STM32F0) || \ + defined(WHAL_CFG_FLASH_API_MAPPING_STM32F3) #define whal_Stm32f0Flash_Init whal_Flash_Init #define whal_Stm32f0Flash_Deinit whal_Flash_Deinit #define whal_Stm32f0Flash_Lock whal_Flash_Lock @@ -44,7 +45,7 @@ #define whal_Stm32f0Flash_Read whal_Flash_Read #define whal_Stm32f0Flash_Write whal_Flash_Write #define whal_Stm32f0Flash_Erase whal_Flash_Erase -#endif /* WHAL_CFG_FLASH_API_MAPPING_STM32F0 */ +#endif whal_Error whal_Stm32f0Flash_Init(whal_Flash *flashDev) { @@ -224,7 +225,8 @@ whal_Error whal_Stm32f0Flash_Ext_SetLatency(whal_Flash *flashDev, return WHAL_SUCCESS; } -#ifndef WHAL_CFG_FLASH_API_MAPPING_STM32F0 +#if !defined(WHAL_CFG_FLASH_API_MAPPING_STM32F0) && \ + !defined(WHAL_CFG_FLASH_API_MAPPING_STM32F3) const whal_FlashDriver whal_Stm32f0Flash_Driver = { .Init = whal_Stm32f0Flash_Init, .Deinit = whal_Stm32f0Flash_Deinit, @@ -234,4 +236,4 @@ const whal_FlashDriver whal_Stm32f0Flash_Driver = { .Write = whal_Stm32f0Flash_Write, .Erase = whal_Stm32f0Flash_Erase, }; -#endif /* !WHAL_CFG_FLASH_API_MAPPING_STM32F0 */ +#endif diff --git a/src/flash/stm32f3_flash.c b/src/flash/stm32f3_flash.c new file mode 100644 index 0000000..4407c6d --- /dev/null +++ b/src/flash/stm32f3_flash.c @@ -0,0 +1 @@ +#include "stm32f0_flash.c" diff --git a/src/gpio/stm32f3_gpio.c b/src/gpio/stm32f3_gpio.c new file mode 100644 index 0000000..7ddf812 --- /dev/null +++ b/src/gpio/stm32f3_gpio.c @@ -0,0 +1 @@ +#include "stm32wb_gpio.c" diff --git a/src/gpio/stm32wb_gpio.c b/src/gpio/stm32wb_gpio.c index 96dd1df..4515224 100644 --- a/src/gpio/stm32wb_gpio.c +++ b/src/gpio/stm32wb_gpio.c @@ -36,7 +36,8 @@ defined(WHAL_CFG_GPIO_API_MAPPING_STM32F4) || \ defined(WHAL_CFG_GPIO_API_MAPPING_STM32H5) || \ defined(WHAL_CFG_GPIO_API_MAPPING_STM32C0) || \ - defined(WHAL_CFG_GPIO_API_MAPPING_STM32F0) + defined(WHAL_CFG_GPIO_API_MAPPING_STM32F0) || \ + defined(WHAL_CFG_GPIO_API_MAPPING_STM32F3) #define whal_Stm32wbGpio_Init whal_Gpio_Init #define whal_Stm32wbGpio_Deinit whal_Gpio_Deinit #define whal_Stm32wbGpio_Get whal_Gpio_Get @@ -181,7 +182,8 @@ whal_Error whal_Stm32wbGpio_Set(whal_Gpio *gpioDev, size_t pin, size_t value) !defined(WHAL_CFG_GPIO_API_MAPPING_STM32F4) && \ !defined(WHAL_CFG_GPIO_API_MAPPING_STM32H5) && \ !defined(WHAL_CFG_GPIO_API_MAPPING_STM32C0) && \ - !defined(WHAL_CFG_GPIO_API_MAPPING_STM32F0) + !defined(WHAL_CFG_GPIO_API_MAPPING_STM32F0) && \ + !defined(WHAL_CFG_GPIO_API_MAPPING_STM32F3) const whal_GpioDriver whal_Stm32wbGpio_Driver = { .Init = whal_Stm32wbGpio_Init, .Deinit = whal_Stm32wbGpio_Deinit, diff --git a/src/i2c/stm32f3_i2c.c b/src/i2c/stm32f3_i2c.c new file mode 100644 index 0000000..394f909 --- /dev/null +++ b/src/i2c/stm32f3_i2c.c @@ -0,0 +1 @@ +#include "stm32wb_i2c.c" diff --git a/src/i2c/stm32wb_i2c.c b/src/i2c/stm32wb_i2c.c index f93dce7..283029b 100644 --- a/src/i2c/stm32wb_i2c.c +++ b/src/i2c/stm32wb_i2c.c @@ -122,7 +122,8 @@ #define I2C_FMP_THIGH_NS 260 /* Fast mode plus tHIGH min */ #if defined(WHAL_CFG_I2C_API_MAPPING_STM32WB) || \ - defined(WHAL_CFG_I2C_API_MAPPING_STM32F0) + defined(WHAL_CFG_I2C_API_MAPPING_STM32F0) || \ + defined(WHAL_CFG_I2C_API_MAPPING_STM32F3) #define whal_Stm32wbI2c_Init whal_I2c_Init #define whal_Stm32wbI2c_Deinit whal_I2c_Deinit #define whal_Stm32wbI2c_StartCom whal_I2c_StartCom @@ -510,7 +511,8 @@ whal_Error whal_Stm32wbI2c_Transfer(whal_I2c *i2cDev, whal_I2c_Msg *msgs, } #if !defined(WHAL_CFG_I2C_API_MAPPING_STM32WB) && \ - !defined(WHAL_CFG_I2C_API_MAPPING_STM32F0) + !defined(WHAL_CFG_I2C_API_MAPPING_STM32F0) && \ + !defined(WHAL_CFG_I2C_API_MAPPING_STM32F3) const whal_I2cDriver whal_Stm32wbI2c_Driver = { .Init = whal_Stm32wbI2c_Init, .Deinit = whal_Stm32wbI2c_Deinit, diff --git a/src/spi/stm32f3_spi.c b/src/spi/stm32f3_spi.c new file mode 100644 index 0000000..b28e2b9 --- /dev/null +++ b/src/spi/stm32f3_spi.c @@ -0,0 +1 @@ +#include "stm32wb_spi.c" diff --git a/src/spi/stm32wb_spi.c b/src/spi/stm32wb_spi.c index 11ecdbb..14b0e93 100644 --- a/src/spi/stm32wb_spi.c +++ b/src/spi/stm32wb_spi.c @@ -62,7 +62,8 @@ #if defined(WHAL_CFG_SPI_API_MAPPING_STM32WB) || \ defined(WHAL_CFG_SPI_API_MAPPING_STM32C0) || \ - defined(WHAL_CFG_SPI_API_MAPPING_STM32F0) + defined(WHAL_CFG_SPI_API_MAPPING_STM32F0) || \ + defined(WHAL_CFG_SPI_API_MAPPING_STM32F3) #define whal_Stm32wbSpi_Init whal_Spi_Init #define whal_Stm32wbSpi_Deinit whal_Spi_Deinit #define whal_Stm32wbSpi_StartCom whal_Spi_StartCom @@ -251,7 +252,8 @@ whal_Error whal_Stm32wbSpi_SendRecv(whal_Spi *spiDev, #if !defined(WHAL_CFG_SPI_API_MAPPING_STM32WB) && \ !defined(WHAL_CFG_SPI_API_MAPPING_STM32C0) && \ - !defined(WHAL_CFG_SPI_API_MAPPING_STM32F0) + !defined(WHAL_CFG_SPI_API_MAPPING_STM32F0) && \ + !defined(WHAL_CFG_SPI_API_MAPPING_STM32F3) const whal_SpiDriver whal_Stm32wbSpi_Driver = { .Init = whal_Stm32wbSpi_Init, .Deinit = whal_Stm32wbSpi_Deinit, diff --git a/src/uart/stm32f0_uart.c b/src/uart/stm32f0_uart.c index 61e1d15..0f8a4c2 100644 --- a/src/uart/stm32f0_uart.c +++ b/src/uart/stm32f0_uart.c @@ -34,14 +34,15 @@ #define UART_TDR_Pos 0 #define UART_TDR_Msk (WHAL_BITMASK(9) << UART_TDR_Pos) -#ifdef WHAL_CFG_UART_API_MAPPING_STM32F0 +#if defined(WHAL_CFG_UART_API_MAPPING_STM32F0) || \ + defined(WHAL_CFG_UART_API_MAPPING_STM32F3) #define whal_Stm32f0Uart_Init whal_Uart_Init #define whal_Stm32f0Uart_Deinit whal_Uart_Deinit #define whal_Stm32f0Uart_Send whal_Uart_Send #define whal_Stm32f0Uart_Recv whal_Uart_Recv #define whal_Stm32f0Uart_SendAsync whal_Uart_SendAsync #define whal_Stm32f0Uart_RecvAsync whal_Uart_RecvAsync -#endif /* WHAL_CFG_UART_API_MAPPING_STM32F0 */ +#endif whal_Error whal_Stm32f0Uart_Init(whal_Uart *uartDev) { @@ -160,7 +161,8 @@ whal_Error whal_Stm32f0Uart_RecvAsync(whal_Uart *uartDev, void *data, return WHAL_ENOTSUP; } -#ifndef WHAL_CFG_UART_API_MAPPING_STM32F0 +#if !defined(WHAL_CFG_UART_API_MAPPING_STM32F0) && \ + !defined(WHAL_CFG_UART_API_MAPPING_STM32F3) const whal_UartDriver whal_Stm32f0Uart_Driver = { .Init = whal_Stm32f0Uart_Init, .Deinit = whal_Stm32f0Uart_Deinit, @@ -169,4 +171,4 @@ const whal_UartDriver whal_Stm32f0Uart_Driver = { .SendAsync = whal_Stm32f0Uart_SendAsync, .RecvAsync = whal_Stm32f0Uart_RecvAsync, }; -#endif /* !WHAL_CFG_UART_API_MAPPING_STM32F0 */ +#endif diff --git a/src/uart/stm32f3_uart.c b/src/uart/stm32f3_uart.c new file mode 100644 index 0000000..12735f7 --- /dev/null +++ b/src/uart/stm32f3_uart.c @@ -0,0 +1 @@ +#include "stm32f0_uart.c" diff --git a/src/watchdog/stm32f0_iwdg.c b/src/watchdog/stm32f0_iwdg.c index a0cd8a4..130c617 100644 --- a/src/watchdog/stm32f0_iwdg.c +++ b/src/watchdog/stm32f0_iwdg.c @@ -1,4 +1 @@ -#ifdef WHAL_CFG_WATCHDOG_API_MAPPING_STM32F0_IWDG -#define WHAL_CFG_WATCHDOG_API_MAPPING_STM32WB_IWDG -#endif #include "stm32wb_iwdg.c" diff --git a/src/watchdog/stm32f0_wwdg.c b/src/watchdog/stm32f0_wwdg.c index 38ab207..541cac6 100644 --- a/src/watchdog/stm32f0_wwdg.c +++ b/src/watchdog/stm32f0_wwdg.c @@ -18,11 +18,12 @@ #define CFR_EWI_Pos 9 #define CFR_EWI_Msk (1UL << CFR_EWI_Pos) -#ifdef WHAL_CFG_WATCHDOG_API_MAPPING_STM32F0_WWDG +#if defined(WHAL_CFG_WATCHDOG_API_MAPPING_STM32F0_WWDG) || \ + defined(WHAL_CFG_WATCHDOG_API_MAPPING_STM32F3_WWDG) #define whal_Stm32f0Wwdg_Init whal_Watchdog_Init #define whal_Stm32f0Wwdg_Deinit whal_Watchdog_Deinit #define whal_Stm32f0Wwdg_Refresh whal_Watchdog_Refresh -#endif /* WHAL_CFG_WATCHDOG_API_MAPPING_STM32F0_WWDG */ +#endif whal_Error whal_Stm32f0Wwdg_Init(whal_Watchdog *wdgDev) { @@ -71,10 +72,11 @@ whal_Error whal_Stm32f0Wwdg_Refresh(whal_Watchdog *wdgDev) return WHAL_SUCCESS; } -#ifndef WHAL_CFG_WATCHDOG_API_MAPPING_STM32F0_WWDG +#if !defined(WHAL_CFG_WATCHDOG_API_MAPPING_STM32F0_WWDG) && \ + !defined(WHAL_CFG_WATCHDOG_API_MAPPING_STM32F3_WWDG) const whal_WatchdogDriver whal_Stm32f0Wwdg_Driver = { .Init = whal_Stm32f0Wwdg_Init, .Deinit = whal_Stm32f0Wwdg_Deinit, .Refresh = whal_Stm32f0Wwdg_Refresh, }; -#endif /* !WHAL_CFG_WATCHDOG_API_MAPPING_STM32F0_WWDG */ +#endif diff --git a/src/watchdog/stm32f3_iwdg.c b/src/watchdog/stm32f3_iwdg.c new file mode 100644 index 0000000..130c617 --- /dev/null +++ b/src/watchdog/stm32f3_iwdg.c @@ -0,0 +1 @@ +#include "stm32wb_iwdg.c" diff --git a/src/watchdog/stm32f3_wwdg.c b/src/watchdog/stm32f3_wwdg.c new file mode 100644 index 0000000..2651cfc --- /dev/null +++ b/src/watchdog/stm32f3_wwdg.c @@ -0,0 +1 @@ +#include "stm32f0_wwdg.c" diff --git a/src/watchdog/stm32wb_iwdg.c b/src/watchdog/stm32wb_iwdg.c index c95ef2c..7c988b2 100644 --- a/src/watchdog/stm32wb_iwdg.c +++ b/src/watchdog/stm32wb_iwdg.c @@ -34,11 +34,13 @@ #define IWDG_SR_RVU_Pos 1 /* Reload value update */ #define IWDG_SR_RVU_Msk (1UL << IWDG_SR_RVU_Pos) -#ifdef WHAL_CFG_WATCHDOG_API_MAPPING_STM32WB_IWDG +#if defined(WHAL_CFG_WATCHDOG_API_MAPPING_STM32WB_IWDG) || \ + defined(WHAL_CFG_WATCHDOG_API_MAPPING_STM32F0_IWDG) || \ + defined(WHAL_CFG_WATCHDOG_API_MAPPING_STM32F3_IWDG) #define whal_Stm32wbIwdg_Init whal_Watchdog_Init #define whal_Stm32wbIwdg_Deinit whal_Watchdog_Deinit #define whal_Stm32wbIwdg_Refresh whal_Watchdog_Refresh -#endif /* WHAL_CFG_WATCHDOG_API_MAPPING_STM32WB_IWDG */ +#endif whal_Error whal_Stm32wbIwdg_Init(whal_Watchdog *wdgDev) { @@ -102,10 +104,12 @@ whal_Error whal_Stm32wbIwdg_Refresh(whal_Watchdog *wdgDev) return WHAL_SUCCESS; } -#ifndef WHAL_CFG_WATCHDOG_API_MAPPING_STM32WB_IWDG +#if !defined(WHAL_CFG_WATCHDOG_API_MAPPING_STM32WB_IWDG) && \ + !defined(WHAL_CFG_WATCHDOG_API_MAPPING_STM32F0_IWDG) && \ + !defined(WHAL_CFG_WATCHDOG_API_MAPPING_STM32F3_IWDG) const whal_WatchdogDriver whal_Stm32wbIwdg_Driver = { .Init = whal_Stm32wbIwdg_Init, .Deinit = whal_Stm32wbIwdg_Deinit, .Refresh = whal_Stm32wbIwdg_Refresh, }; -#endif /* !WHAL_CFG_WATCHDOG_API_MAPPING_STM32WB_IWDG */ +#endif diff --git a/tests/gpio/test_stm32f3_gpio.c b/tests/gpio/test_stm32f3_gpio.c new file mode 100644 index 0000000..2e72afc --- /dev/null +++ b/tests/gpio/test_stm32f3_gpio.c @@ -0,0 +1 @@ +#include "test_stm32f0_gpio.c" diff --git a/wolfHAL/clock/stm32f3_rcc.h b/wolfHAL/clock/stm32f3_rcc.h new file mode 100644 index 0000000..58e446b --- /dev/null +++ b/wolfHAL/clock/stm32f3_rcc.h @@ -0,0 +1,160 @@ +#ifndef WHAL_STM32F3_RCC_H +#define WHAL_STM32F3_RCC_H + +#include +#include +#include + +/* + * @file stm32f3_rcc.h + * @brief STM32F3 RCC (Reset and Clock Control) driver configuration. + * + * The STM32F3 RCC peripheral controls: + * - System clock source selection (HSI, HSE, PLL) + * - PLL with PREDIV prescaler and PLLMUL multiplier + * - Peripheral clock gating (AHB, APB1, APB2 buses) + * + * Clock sources: + * HSI = 8 MHz internal RC oscillator + * HSE = 4-32 MHz external oscillator + * PLL = HSI/2 or HSE/PREDIV * PLLMUL (output must not exceed 72 MHz) + * + * RCC register map (RM0365 Table 29): + * RCC_CR = 0x00 (HSION, HSIRDY, HSEON, HSERDY, PLLON, PLLRDY) + * RCC_CFGR = 0x04 (SW, SWS, PLLSRC, PLLMUL, HPRE, PPRE1, PPRE2) + * RCC_CIR = 0x08 + * RCC_AHBENR = 0x14 + * RCC_APB2ENR = 0x18 + * RCC_APB1ENR = 0x1C + * RCC_CFGR2 = 0x2C (PREDIV) + * RCC_CFGR3 = 0x30 (USARTxSW, I2CxSW, TIMxSW) + */ + +/* + * @brief System clock source selection. + * + * Determines which oscillator/PLL drives the system clock (SYSCLK). + */ +typedef enum { + WHAL_STM32F3_RCC_SYSCLK_SRC_HSI, /* 8 MHz internal RC oscillator */ + WHAL_STM32F3_RCC_SYSCLK_SRC_HSE, /* External crystal/oscillator */ + WHAL_STM32F3_RCC_SYSCLK_SRC_PLL, /* PLL output */ +} whal_Stm32f3Rcc_SysClockSrc; + +/* + * @brief PLL input clock source selection. + * + * Determines which oscillator feeds the PLL input. + */ +typedef enum { + WHAL_STM32F3_RCC_PLLSRC_HSI_DIV2, /* HSI divided by 2 */ + WHAL_STM32F3_RCC_PLLSRC_HSE_PREDIV, /* HSE divided by PREDIV */ +} whal_Stm32f3Rcc_PllClockSrc; + +/* + * @brief I2C1 peripheral clock source selection (RCC_CFGR3.I2C1SW). + */ +typedef enum { + WHAL_STM32F3_RCC_I2C1_SRC_HSI = 0, /* HSI (8 MHz), reset default */ + WHAL_STM32F3_RCC_I2C1_SRC_SYSCLK = 1, /* System clock */ +} whal_Stm32f3Rcc_I2c1ClkSrc; + +/* + * @brief PLL configuration parameters. + * + * The PLL output frequency is (input / prediv) * pllmul, where input is + * HSI/2 (fixed) or HSE. Output must not exceed 72 MHz. + */ +typedef struct { + whal_Stm32f3Rcc_PllClockSrc clkSrc; + uint8_t prediv; /* 1-16 (written as value - 1) */ + uint8_t pllmul; /* 2-16 (written as value - 2) */ +} whal_Stm32f3Rcc_PllCfg; + +/* + * @brief Peripheral clock enable descriptor. + * + * Describes the register offset and bit position needed to enable/disable + * a peripheral's bus clock. Used with whal_Stm32f3Rcc_Enable/Disable. + */ +typedef struct { + size_t regOffset; /* Offset from RCC base to enable register */ + size_t enableMask; /* Bit mask for the peripheral enable bit */ + size_t enablePos; /* Bit position for the peripheral enable bit */ +} whal_Stm32f3Rcc_Clk; + +/* + * @brief RCC driver configuration. + * + * Contains all parameters needed to configure the system clock. + */ +typedef struct whal_Stm32f3Rcc_Cfg { + whal_Stm32f3Rcc_SysClockSrc sysClkSrc; /* System clock source */ + whal_Stm32f3Rcc_PllCfg *pllCfg; /* Required when sysClkSrc == PLL */ +} whal_Stm32f3Rcc_Cfg; + +#ifndef WHAL_CFG_CLOCK_API_MAPPING_STM32F3 +/* + * @brief Driver instance for the STM32F3 RCC clock controller. + */ +extern const whal_ClockDriver whal_Stm32f3Rcc_Driver; + +/* + * @brief Initialize the RCC peripheral and switch to the configured SYSCLK. + * + * @param clkDev Clock device instance. + * + * @retval WHAL_SUCCESS Initialization completed. + * @retval WHAL_EINVAL Invalid arguments. + */ +whal_Error whal_Stm32f3Rcc_Init(whal_Clock *clkDev); + +/* + * @brief Deinitialize the RCC peripheral and switch SYSCLK back to HSI. + * + * @param clkDev Clock device instance. + * + * @retval WHAL_SUCCESS Deinit completed. + * @retval WHAL_EINVAL Invalid arguments. + */ +whal_Error whal_Stm32f3Rcc_Deinit(whal_Clock *clkDev); + +/* + * @brief Enable a peripheral clock gate. + * + * @param clkDev Clock device instance. + * @param clk Pointer to a whal_Stm32f3Rcc_Clk descriptor. + * + * @retval WHAL_SUCCESS Clock enabled. + * @retval WHAL_EINVAL Invalid arguments. + */ +whal_Error whal_Stm32f3Rcc_Enable(whal_Clock *clkDev, const void *clk); + +/* + * @brief Disable a peripheral clock gate. + * + * @param clkDev Clock device instance. + * @param clk Pointer to a whal_Stm32f3Rcc_Clk descriptor. + * + * @retval WHAL_SUCCESS Clock disabled. + * @retval WHAL_EINVAL Invalid arguments. + */ +whal_Error whal_Stm32f3Rcc_Disable(whal_Clock *clkDev, const void *clk); +#endif /* !WHAL_CFG_CLOCK_API_MAPPING_STM32F3 */ + +/* + * @brief Select the I2C1 peripheral clock source via RCC_CFGR3.I2C1SW. + * + * Reset default is HSI (8 MHz). Select SYSCLK to drive I2C1 timing from the + * main system clock instead. + * + * @param clkDev Clock controller instance. + * @param src I2C1 clock source (HSI or SYSCLK). + * + * @retval WHAL_SUCCESS Clock source updated. + * @retval WHAL_EINVAL Invalid arguments. + */ +whal_Error whal_Stm32f3Rcc_Ext_SetI2c1ClkSrc(whal_Clock *clkDev, + whal_Stm32f3Rcc_I2c1ClkSrc src); + +#endif /* WHAL_STM32F3_RCC_H */ diff --git a/wolfHAL/flash/stm32f3_flash.h b/wolfHAL/flash/stm32f3_flash.h new file mode 100644 index 0000000..59ffde1 --- /dev/null +++ b/wolfHAL/flash/stm32f3_flash.h @@ -0,0 +1,34 @@ +#ifndef WHAL_STM32F3_FLASH_H +#define WHAL_STM32F3_FLASH_H + +/* + * @file stm32f3_flash.h + * @brief STM32F3 flash driver (alias for STM32F0 flash). + * + * The STM32F3 embedded flash uses the same register layout as the STM32F0: + * ACR/KEYR/SR/CR/AR with identical bit positions, 2 KB page erase, and + * half-word (16-bit) programming. + */ + +#include + +typedef whal_Stm32f0Flash_Cfg whal_Stm32f3Flash_Cfg; + +#define WHAL_STM32F3_FLASH_LATENCY_0 WHAL_STM32F0_FLASH_LATENCY_0 +#define WHAL_STM32F3_FLASH_LATENCY_1 WHAL_STM32F0_FLASH_LATENCY_1 +#define WHAL_STM32F3_FLASH_LATENCY_2 2 + +#ifndef WHAL_CFG_FLASH_API_MAPPING_STM32F3 +#define whal_Stm32f3Flash_Driver whal_Stm32f0Flash_Driver +#define whal_Stm32f3Flash_Init whal_Stm32f0Flash_Init +#define whal_Stm32f3Flash_Deinit whal_Stm32f0Flash_Deinit +#define whal_Stm32f3Flash_Lock whal_Stm32f0Flash_Lock +#define whal_Stm32f3Flash_Unlock whal_Stm32f0Flash_Unlock +#define whal_Stm32f3Flash_Read whal_Stm32f0Flash_Read +#define whal_Stm32f3Flash_Write whal_Stm32f0Flash_Write +#define whal_Stm32f3Flash_Erase whal_Stm32f0Flash_Erase +#endif /* !WHAL_CFG_FLASH_API_MAPPING_STM32F3 */ + +#define whal_Stm32f3Flash_Ext_SetLatency whal_Stm32f0Flash_Ext_SetLatency + +#endif /* WHAL_STM32F3_FLASH_H */ diff --git a/wolfHAL/gpio/stm32f3_gpio.h b/wolfHAL/gpio/stm32f3_gpio.h new file mode 100644 index 0000000..e13bd01 --- /dev/null +++ b/wolfHAL/gpio/stm32f3_gpio.h @@ -0,0 +1,52 @@ +#ifndef WHAL_STM32F3_GPIO_H +#define WHAL_STM32F3_GPIO_H + +/* + * @file stm32f3_gpio.h + * @brief STM32F3 GPIO driver (alias for STM32WB GPIO). + * + * The STM32F3 GPIO peripheral is register-compatible with the STM32WB GPIO + * (MODER/OTYPER/OSPEEDR/PUPDR/IDR/ODR/BSRR/LCKR/AFRL/AFRH at identical + * offsets). This header re-exports under STM32F3-specific names. + */ + +#include + +typedef whal_Stm32wbGpio_Cfg whal_Stm32f3Gpio_Cfg; +typedef whal_Stm32wbGpio_PinCfg whal_Stm32f3Gpio_PinCfg; + +#ifndef WHAL_CFG_GPIO_API_MAPPING_STM32F3 +#define whal_Stm32f3Gpio_Driver whal_Stm32wbGpio_Driver +#define whal_Stm32f3Gpio_Init whal_Stm32wbGpio_Init +#define whal_Stm32f3Gpio_Deinit whal_Stm32wbGpio_Deinit +#define whal_Stm32f3Gpio_Get whal_Stm32wbGpio_Get +#define whal_Stm32f3Gpio_Set whal_Stm32wbGpio_Set +#endif /* !WHAL_CFG_GPIO_API_MAPPING_STM32F3 */ + +#define WHAL_STM32F3_GPIO_MODE_IN WHAL_STM32WB_GPIO_MODE_IN +#define WHAL_STM32F3_GPIO_MODE_OUT WHAL_STM32WB_GPIO_MODE_OUT +#define WHAL_STM32F3_GPIO_MODE_ALTFN WHAL_STM32WB_GPIO_MODE_ALTFN +#define WHAL_STM32F3_GPIO_MODE_ANALOG WHAL_STM32WB_GPIO_MODE_ANALOG + +#define WHAL_STM32F3_GPIO_OUTTYPE_PUSHPULL WHAL_STM32WB_GPIO_OUTTYPE_PUSHPULL +#define WHAL_STM32F3_GPIO_OUTTYPE_OPENDRAIN WHAL_STM32WB_GPIO_OUTTYPE_OPENDRAIN + +#define WHAL_STM32F3_GPIO_SPEED_LOW WHAL_STM32WB_GPIO_SPEED_LOW +#define WHAL_STM32F3_GPIO_SPEED_MEDIUM WHAL_STM32WB_GPIO_SPEED_MEDIUM +#define WHAL_STM32F3_GPIO_SPEED_FAST WHAL_STM32WB_GPIO_SPEED_FAST +#define WHAL_STM32F3_GPIO_SPEED_HIGH WHAL_STM32WB_GPIO_SPEED_HIGH + +#define WHAL_STM32F3_GPIO_PULL_NONE WHAL_STM32WB_GPIO_PULL_NONE +#define WHAL_STM32F3_GPIO_PULL_UP WHAL_STM32WB_GPIO_PULL_UP +#define WHAL_STM32F3_GPIO_PULL_DOWN WHAL_STM32WB_GPIO_PULL_DOWN + +#define WHAL_STM32F3_GPIO_PORT_A WHAL_STM32WB_GPIO_PORT_A +#define WHAL_STM32F3_GPIO_PORT_B WHAL_STM32WB_GPIO_PORT_B +#define WHAL_STM32F3_GPIO_PORT_C WHAL_STM32WB_GPIO_PORT_C +#define WHAL_STM32F3_GPIO_PORT_D WHAL_STM32WB_GPIO_PORT_D +#define WHAL_STM32F3_GPIO_PORT_E WHAL_STM32WB_GPIO_PORT_E +#define WHAL_STM32F3_GPIO_PORT_F WHAL_STM32WB_GPIO_PORT_F + +#define WHAL_STM32F3_GPIO_PIN WHAL_STM32WB_GPIO_PIN + +#endif /* WHAL_STM32F3_GPIO_H */ diff --git a/wolfHAL/i2c/stm32f3_i2c.h b/wolfHAL/i2c/stm32f3_i2c.h new file mode 100644 index 0000000..347e37d --- /dev/null +++ b/wolfHAL/i2c/stm32f3_i2c.h @@ -0,0 +1,25 @@ +#ifndef WHAL_STM32F3_I2C_H +#define WHAL_STM32F3_I2C_H + +/* + * @file stm32f3_i2c.h + * @brief STM32F3 I2C driver (alias for STM32WB I2C). + * + * The STM32F3 I2C peripheral is register-compatible with the STM32WB I2C + * (I2C v2 with CR1/CR2/TIMINGR). + */ + +#include + +typedef whal_Stm32wbI2c_Cfg whal_Stm32f3I2c_Cfg; + +#ifndef WHAL_CFG_I2C_API_MAPPING_STM32F3 +#define whal_Stm32f3I2c_Driver whal_Stm32wbI2c_Driver +#define whal_Stm32f3I2c_Init whal_Stm32wbI2c_Init +#define whal_Stm32f3I2c_Deinit whal_Stm32wbI2c_Deinit +#define whal_Stm32f3I2c_StartCom whal_Stm32wbI2c_StartCom +#define whal_Stm32f3I2c_EndCom whal_Stm32wbI2c_EndCom +#define whal_Stm32f3I2c_Transfer whal_Stm32wbI2c_Transfer +#endif /* !WHAL_CFG_I2C_API_MAPPING_STM32F3 */ + +#endif /* WHAL_STM32F3_I2C_H */ diff --git a/wolfHAL/platform/st/stm32f302r8.h b/wolfHAL/platform/st/stm32f302r8.h new file mode 100644 index 0000000..aa4b8aa --- /dev/null +++ b/wolfHAL/platform/st/stm32f302r8.h @@ -0,0 +1,241 @@ +#ifndef WHAL_STM32F302R8_H +#define WHAL_STM32F302R8_H + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * @file stm32f302r8.h + * @brief Convenience initializers for STM32F302R8 device instances. + * + * Base addresses from RM0365 Table 4 (STM32F302x6/x8 memory map). + * RCC: 0x40021000 + * GPIO: 0x48000000 (port A), 0x400 spacing per port + * USART1: 0x40013800, USART2: 0x40004400, USART3: 0x40004800 + * SPI2: 0x40003800, SPI3: 0x40003C00 + * I2C1: 0x40005400, I2C2: 0x40005800, I2C3: 0x40007800 + * Flash interface: 0x40022000 + * IWDG: 0x40003000, WWDG: 0x40002C00 + * DMA1: 0x40020000 + * PWR: 0x40007000 + */ + +/* --- Device macros --- */ + +#define WHAL_STM32F302_RCC_REGMAP \ + .base = 0x40021000, \ + .size = 0x400 +#define WHAL_STM32F302_RCC_DRIVER &whal_Stm32f3Rcc_Driver + +#define WHAL_STM32F302_GPIO_REGMAP \ + .base = 0x48000000, \ + .size = 0x1800 +#define WHAL_STM32F302_GPIO_DRIVER &whal_Stm32f3Gpio_Driver + +#define WHAL_STM32F302_USART1_REGMAP \ + .base = 0x40013800, \ + .size = 0x400 +#define WHAL_STM32F302_USART1_DRIVER &whal_Stm32f3Uart_Driver + +#define WHAL_STM32F302_USART2_REGMAP \ + .base = 0x40004400, \ + .size = 0x400 +#define WHAL_STM32F302_USART2_DRIVER &whal_Stm32f3Uart_Driver + +#define WHAL_STM32F302_USART3_REGMAP \ + .base = 0x40004800, \ + .size = 0x400 +#define WHAL_STM32F302_USART3_DRIVER &whal_Stm32f3Uart_Driver + +#define WHAL_STM32F302_SPI2_REGMAP \ + .base = 0x40003800, \ + .size = 0x400 +#define WHAL_STM32F302_SPI2_DRIVER &whal_Stm32f3Spi_Driver + +#define WHAL_STM32F302_SPI3_REGMAP \ + .base = 0x40003C00, \ + .size = 0x400 +#define WHAL_STM32F302_SPI3_DRIVER &whal_Stm32f3Spi_Driver + +#define WHAL_STM32F302_I2C1_REGMAP \ + .base = 0x40005400, \ + .size = 0x400 +#define WHAL_STM32F302_I2C1_DRIVER &whal_Stm32f3I2c_Driver + +#define WHAL_STM32F302_I2C2_REGMAP \ + .base = 0x40005800, \ + .size = 0x400 +#define WHAL_STM32F302_I2C2_DRIVER &whal_Stm32f3I2c_Driver + +#define WHAL_STM32F302_I2C3_REGMAP \ + .base = 0x40007800, \ + .size = 0x400 +#define WHAL_STM32F302_I2C3_DRIVER &whal_Stm32f3I2c_Driver + +#define WHAL_STM32F302_FLASH_REGMAP \ + .base = 0x40022000, \ + .size = 0x400 +#define WHAL_STM32F302_FLASH_DRIVER &whal_Stm32f3Flash_Driver + +#define WHAL_STM32F302_IWDG_REGMAP \ + .base = 0x40003000, \ + .size = 0x400 +#define WHAL_STM32F302_IWDG_DRIVER &whal_Stm32f3Iwdg_Driver + +#define WHAL_STM32F302_WWDG_REGMAP \ + .base = 0x40002C00, \ + .size = 0x400 +#define WHAL_STM32F302_WWDG_DRIVER &whal_Stm32f3Wwdg_Driver + +/* --- Clock gate macros --- */ + +/* RCC_AHBENR (offset 0x014) */ + +#define WHAL_STM32F302_GPIOA_CLOCK \ + .regOffset = 0x014, \ + .enableMask = (1UL << 17), \ + .enablePos = 17 + +#define WHAL_STM32F302_GPIOB_CLOCK \ + .regOffset = 0x014, \ + .enableMask = (1UL << 18), \ + .enablePos = 18 + +#define WHAL_STM32F302_GPIOC_CLOCK \ + .regOffset = 0x014, \ + .enableMask = (1UL << 19), \ + .enablePos = 19 + +#define WHAL_STM32F302_GPIOD_CLOCK \ + .regOffset = 0x014, \ + .enableMask = (1UL << 20), \ + .enablePos = 20 + +#define WHAL_STM32F302_GPIOF_CLOCK \ + .regOffset = 0x014, \ + .enableMask = (1UL << 22), \ + .enablePos = 22 + +#define WHAL_STM32F302_FLASH_CLOCK \ + .regOffset = 0x014, \ + .enableMask = (1UL << 4), \ + .enablePos = 4 + +#define WHAL_STM32F302_DMA1_CLOCK \ + .regOffset = 0x014, \ + .enableMask = (1UL << 0), \ + .enablePos = 0 + +/* RCC_APB2ENR (offset 0x018) */ + +#define WHAL_STM32F302_SYSCFG_CLOCK \ + .regOffset = 0x018, \ + .enableMask = (1UL << 0), \ + .enablePos = 0 + +#define WHAL_STM32F302_USART1_CLOCK \ + .regOffset = 0x018, \ + .enableMask = (1UL << 14), \ + .enablePos = 14 + +#define WHAL_STM32F302_TIM1_CLOCK \ + .regOffset = 0x018, \ + .enableMask = (1UL << 11), \ + .enablePos = 11 + +#define WHAL_STM32F302_TIM15_CLOCK \ + .regOffset = 0x018, \ + .enableMask = (1UL << 16), \ + .enablePos = 16 + +#define WHAL_STM32F302_TIM16_CLOCK \ + .regOffset = 0x018, \ + .enableMask = (1UL << 17), \ + .enablePos = 17 + +#define WHAL_STM32F302_TIM17_CLOCK \ + .regOffset = 0x018, \ + .enableMask = (1UL << 18), \ + .enablePos = 18 + +/* RCC_APB1ENR (offset 0x01C) */ + +#define WHAL_STM32F302_TIM2_CLOCK \ + .regOffset = 0x01C, \ + .enableMask = (1UL << 0), \ + .enablePos = 0 + +#define WHAL_STM32F302_TIM6_CLOCK \ + .regOffset = 0x01C, \ + .enableMask = (1UL << 4), \ + .enablePos = 4 + +#define WHAL_STM32F302_WWDG_CLOCK \ + .regOffset = 0x01C, \ + .enableMask = (1UL << 11), \ + .enablePos = 11 + +#define WHAL_STM32F302_SPI2_CLOCK \ + .regOffset = 0x01C, \ + .enableMask = (1UL << 14), \ + .enablePos = 14 + +#define WHAL_STM32F302_SPI3_CLOCK \ + .regOffset = 0x01C, \ + .enableMask = (1UL << 15), \ + .enablePos = 15 + +#define WHAL_STM32F302_USART2_CLOCK \ + .regOffset = 0x01C, \ + .enableMask = (1UL << 17), \ + .enablePos = 17 + +#define WHAL_STM32F302_USART3_CLOCK \ + .regOffset = 0x01C, \ + .enableMask = (1UL << 18), \ + .enablePos = 18 + +#define WHAL_STM32F302_I2C1_CLOCK \ + .regOffset = 0x01C, \ + .enableMask = (1UL << 21), \ + .enablePos = 21 + +#define WHAL_STM32F302_I2C2_CLOCK \ + .regOffset = 0x01C, \ + .enableMask = (1UL << 22), \ + .enablePos = 22 + +#define WHAL_STM32F302_USB_CLOCK \ + .regOffset = 0x01C, \ + .enableMask = (1UL << 23), \ + .enablePos = 23 + +#define WHAL_STM32F302_CAN_CLOCK \ + .regOffset = 0x01C, \ + .enableMask = (1UL << 25), \ + .enablePos = 25 + +#define WHAL_STM32F302_PWR_CLOCK \ + .regOffset = 0x01C, \ + .enableMask = (1UL << 28), \ + .enablePos = 28 + +#define WHAL_STM32F302_DAC1_CLOCK \ + .regOffset = 0x01C, \ + .enableMask = (1UL << 29), \ + .enablePos = 29 + +#define WHAL_STM32F302_I2C3_CLOCK \ + .regOffset = 0x01C, \ + .enableMask = (1UL << 30), \ + .enablePos = 30 + +#endif /* WHAL_STM32F302R8_H */ diff --git a/wolfHAL/spi/stm32f3_spi.h b/wolfHAL/spi/stm32f3_spi.h new file mode 100644 index 0000000..44dcfa6 --- /dev/null +++ b/wolfHAL/spi/stm32f3_spi.h @@ -0,0 +1,25 @@ +#ifndef WHAL_STM32F3_SPI_H +#define WHAL_STM32F3_SPI_H + +/* + * @file stm32f3_spi.h + * @brief STM32F3 SPI driver (alias for STM32WB SPI). + * + * The STM32F3 SPI peripheral is register-compatible with the STM32WB SPI + * (SPI v2 with DS[3:0] data size field in CR2). + */ + +#include + +typedef whal_Stm32wbSpi_Cfg whal_Stm32f3Spi_Cfg; + +#ifndef WHAL_CFG_SPI_API_MAPPING_STM32F3 +#define whal_Stm32f3Spi_Driver whal_Stm32wbSpi_Driver +#define whal_Stm32f3Spi_Init whal_Stm32wbSpi_Init +#define whal_Stm32f3Spi_Deinit whal_Stm32wbSpi_Deinit +#define whal_Stm32f3Spi_StartCom whal_Stm32wbSpi_StartCom +#define whal_Stm32f3Spi_EndCom whal_Stm32wbSpi_EndCom +#define whal_Stm32f3Spi_SendRecv whal_Stm32wbSpi_SendRecv +#endif /* !WHAL_CFG_SPI_API_MAPPING_STM32F3 */ + +#endif /* WHAL_STM32F3_SPI_H */ diff --git a/wolfHAL/uart/stm32f3_uart.h b/wolfHAL/uart/stm32f3_uart.h new file mode 100644 index 0000000..fd7cd9f --- /dev/null +++ b/wolfHAL/uart/stm32f3_uart.h @@ -0,0 +1,26 @@ +#ifndef WHAL_STM32F3_UART_H +#define WHAL_STM32F3_UART_H + +/* + * @file stm32f3_uart.h + * @brief STM32F3 UART driver (alias for STM32F0 UART). + * + * The STM32F3 USART uses the same ISR/TDR/RDR register layout as the + * STM32F0. This header re-exports under STM32F3-specific names. + */ + +#include + +typedef whal_Stm32f0Uart_Cfg whal_Stm32f3Uart_Cfg; + +#define WHAL_STM32F3_UART_BRR(clk, baud) WHAL_STM32F0_UART_BRR(clk, baud) + +#ifndef WHAL_CFG_UART_API_MAPPING_STM32F3 +#define whal_Stm32f3Uart_Driver whal_Stm32f0Uart_Driver +#define whal_Stm32f3Uart_Init whal_Stm32f0Uart_Init +#define whal_Stm32f3Uart_Deinit whal_Stm32f0Uart_Deinit +#define whal_Stm32f3Uart_Send whal_Stm32f0Uart_Send +#define whal_Stm32f3Uart_Recv whal_Stm32f0Uart_Recv +#endif /* !WHAL_CFG_UART_API_MAPPING_STM32F3 */ + +#endif /* WHAL_STM32F3_UART_H */ diff --git a/wolfHAL/watchdog/stm32f3_iwdg.h b/wolfHAL/watchdog/stm32f3_iwdg.h new file mode 100644 index 0000000..8af5932 --- /dev/null +++ b/wolfHAL/watchdog/stm32f3_iwdg.h @@ -0,0 +1,30 @@ +#ifndef WHAL_STM32F3_IWDG_H +#define WHAL_STM32F3_IWDG_H + +/* + * @file stm32f3_iwdg.h + * @brief STM32F3 IWDG driver (alias for STM32WB IWDG). + * + * The STM32F3 IWDG peripheral is register-compatible with the STM32WB IWDG. + */ + +#include + +typedef whal_Stm32wbIwdg_Cfg whal_Stm32f3Iwdg_Cfg; + +#ifndef WHAL_CFG_WATCHDOG_API_MAPPING_STM32F3_IWDG +#define whal_Stm32f3Iwdg_Driver whal_Stm32wbIwdg_Driver +#define whal_Stm32f3Iwdg_Init whal_Stm32wbIwdg_Init +#define whal_Stm32f3Iwdg_Deinit whal_Stm32wbIwdg_Deinit +#define whal_Stm32f3Iwdg_Refresh whal_Stm32wbIwdg_Refresh +#endif /* !WHAL_CFG_WATCHDOG_API_MAPPING_STM32F3_IWDG */ + +#define WHAL_STM32F3_IWDG_PR_4 WHAL_STM32WB_IWDG_PR_4 +#define WHAL_STM32F3_IWDG_PR_8 WHAL_STM32WB_IWDG_PR_8 +#define WHAL_STM32F3_IWDG_PR_16 WHAL_STM32WB_IWDG_PR_16 +#define WHAL_STM32F3_IWDG_PR_32 WHAL_STM32WB_IWDG_PR_32 +#define WHAL_STM32F3_IWDG_PR_64 WHAL_STM32WB_IWDG_PR_64 +#define WHAL_STM32F3_IWDG_PR_128 WHAL_STM32WB_IWDG_PR_128 +#define WHAL_STM32F3_IWDG_PR_256 WHAL_STM32WB_IWDG_PR_256 + +#endif /* WHAL_STM32F3_IWDG_H */ diff --git a/wolfHAL/watchdog/stm32f3_wwdg.h b/wolfHAL/watchdog/stm32f3_wwdg.h new file mode 100644 index 0000000..339abd5 --- /dev/null +++ b/wolfHAL/watchdog/stm32f3_wwdg.h @@ -0,0 +1,23 @@ +#ifndef WHAL_STM32F3_WWDG_H +#define WHAL_STM32F3_WWDG_H + +/* + * @file stm32f3_wwdg.h + * @brief STM32F3 WWDG driver (alias for STM32F0 WWDG). + * + * The STM32F3 WWDG peripheral uses the same register layout as the STM32F0 + * (2-bit WDGTB prescaler at CFR bits 8:7). + */ + +#include + +typedef whal_Stm32f0Wwdg_Cfg whal_Stm32f3Wwdg_Cfg; + +#ifndef WHAL_CFG_WATCHDOG_API_MAPPING_STM32F3_WWDG +#define whal_Stm32f3Wwdg_Driver whal_Stm32f0Wwdg_Driver +#define whal_Stm32f3Wwdg_Init whal_Stm32f0Wwdg_Init +#define whal_Stm32f3Wwdg_Deinit whal_Stm32f0Wwdg_Deinit +#define whal_Stm32f3Wwdg_Refresh whal_Stm32f0Wwdg_Refresh +#endif /* !WHAL_CFG_WATCHDOG_API_MAPPING_STM32F3_WWDG */ + +#endif /* WHAL_STM32F3_WWDG_H */