From 43094257d5eb61230d1fa4112c57456508cd5b6b Mon Sep 17 00:00:00 2001 From: wb-joy Date: Tue, 12 Apr 2022 19:54:10 +0800 Subject: [PATCH] Modify zhou65 keyboard to WB32 --- builddefs/common_features.mk | 8 +- keyboards/yandrstudio/zhou65/config.h | 2 + keyboards/yandrstudio/zhou65/mcuconf.h | 130 ++++++----- keyboards/yandrstudio/zhou65/rules.mk | 3 +- platforms/chibios/eeprom_wb32.c | 302 +++++++++++++++++++++++++ platforms/chibios/eeprom_wb32_defs.h | 55 +++++ platforms/eeprom.h | 3 + 7 files changed, 444 insertions(+), 59 deletions(-) create mode 100644 platforms/chibios/eeprom_wb32.c create mode 100644 platforms/chibios/eeprom_wb32_defs.h diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk index 08d186d656c7..d58ed3292941 100644 --- a/builddefs/common_features.mk +++ b/builddefs/common_features.mk @@ -201,7 +201,13 @@ else # Teensy EEPROM implementations OPT_DEFS += -DEEPROM_TEENSY SRC += eeprom_teensy.c - else + else ifneq ($(filter %_WB32F3G71x9 %_WB32F3G71xB %_WB32F3G71xC, $(MCU_SERIES)_$(MCU_LDSCRIPT)),) + OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_WB32_FLASH_EMULATED + OPT_DEFS += -DEEPROM_DRIVER + COMMON_VPATH += $(DRIVER_PATH)/eeprom + SRC += eeprom_driver.c + SRC += $(PLATFORM_COMMON_DIR)/eeprom_wb32.c + else # Fall back to transient, i.e. non-persistent OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT COMMON_VPATH += $(DRIVER_PATH)/eeprom diff --git a/keyboards/yandrstudio/zhou65/config.h b/keyboards/yandrstudio/zhou65/config.h index f4d8199e133b..3a96ff9ba9aa 100644 --- a/keyboards/yandrstudio/zhou65/config.h +++ b/keyboards/yandrstudio/zhou65/config.h @@ -45,3 +45,5 @@ #define DEBOUNCE 5 #define QMK_KEYS_PER_SCAN 4 + +#define KEYBOARD_SHARED_EP diff --git a/keyboards/yandrstudio/zhou65/mcuconf.h b/keyboards/yandrstudio/zhou65/mcuconf.h index 85376734f495..236132ab7a33 100644 --- a/keyboards/yandrstudio/zhou65/mcuconf.h +++ b/keyboards/yandrstudio/zhou65/mcuconf.h @@ -18,61 +18,77 @@ #include_next -#undef STM32_NO_INIT -#undef STM32_HSI_ENABLED -#undef STM32_LSI_ENABLED -#undef STM32_HSE_ENABLED -#undef STM32_LSE_ENABLED -#undef STM32_CLOCK48_REQUIRED -#undef STM32_SW -#undef STM32_PLLSRC -#undef STM32_PLLM_VALUE -#undef STM32_PLLN_VALUE -#undef STM32_PLLP_VALUE -#undef STM32_PLLQ_VALUE -#undef STM32_HPRE -#undef STM32_PPRE1 -#undef STM32_PPRE2 -#undef STM32_RTCSEL -#undef STM32_RTCPRE_VALUE -#undef STM32_MCO1SEL -#undef STM32_MCO1PRE -#undef STM32_MCO2SEL -#undef STM32_MCO2PRE -#undef STM32_I2SSRC -#undef STM32_PLLI2SN_VALUE -#undef STM32_PLLI2SR_VALUE -#undef STM32_PVD_ENABLE -#undef STM32_PLS -#undef STM32_BKPRAM_ENABLE +// #define WB32_NO_INIT FALSE +// #define WB32_MHSI_ENABLED TRUE +// #define WB32_FHSI_ENABLED FALSE +// #define WB32_LSI_ENABLED FALSE +// #define WB32_HSE_ENABLED TRUE +// #define WB32_LSE_ENABLED FALSE +// #define WB32_PLL_ENABLED TRUE +// #define WB32_MAINCLKSRC WB32_MAINCLKSRC_PLL +// #define WB32_PLLSRC WB32_PLLSRC_HSE +// #define WB32_PLLDIV_VALUE 2 +// #define WB32_PLLMUL_VALUE 12 //The allowed range is 12,16,20,24. +// #define WB32_HPRE 1 +// #define WB32_PPRE1 1 +// #define WB32_PPRE2 1 +// #define WB32_USBPRE WB32_USBPRE_DIV1P5 -#define STM32_NO_INIT FALSE -#define STM32_HSI_ENABLED TRUE -#define STM32_LSI_ENABLED TRUE -#define STM32_HSE_ENABLED TRUE -#define STM32_LSE_ENABLED FALSE -#define STM32_CLOCK48_REQUIRED TRUE -#define STM32_SW STM32_SW_PLL -#define STM32_PLLSRC STM32_PLLSRC_HSE -#define STM32_PLLM_VALUE 8 -#define STM32_PLLN_VALUE 192 -#define STM32_PLLP_VALUE 4 -#define STM32_PLLQ_VALUE 4 -// AHB prescaler value. -#define STM32_HPRE STM32_HPRE_DIV1 -//APB1 prescaler value. -#define STM32_PPRE1 STM32_PPRE1_DIV4 -//APB2 prescaler value. -#define STM32_PPRE2 STM32_PPRE2_DIV2 -#define STM32_RTCSEL STM32_RTCSEL_LSI -#define STM32_RTCPRE_VALUE 8 -#define STM32_MCO1SEL STM32_MCO1SEL_HSI -#define STM32_MCO1PRE STM32_MCO1PRE_DIV1 -#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK -#define STM32_MCO2PRE STM32_MCO2PRE_DIV5 -#define STM32_I2SSRC STM32_I2SSRC_CKIN -#define STM32_PLLI2SN_VALUE 192 -#define STM32_PLLI2SR_VALUE 5 -#define STM32_PVD_ENABLE FALSE -#define STM32_PLS STM32_PLS_LEV0 -#define STM32_BKPRAM_ENABLE FALSE +// #undef STM32_NO_INIT +// #undef STM32_HSI_ENABLED +// #undef STM32_LSI_ENABLED +// #undef STM32_HSE_ENABLED +// #undef STM32_LSE_ENABLED +// #undef STM32_CLOCK48_REQUIRED +// #undef STM32_SW +// #undef STM32_PLLSRC +// #undef STM32_PLLM_VALUE +// #undef STM32_PLLN_VALUE +// #undef STM32_PLLP_VALUE +// #undef STM32_PLLQ_VALUE +// #undef STM32_HPRE +// #undef STM32_PPRE1 +// #undef STM32_PPRE2 +// #undef STM32_RTCSEL +// #undef STM32_RTCPRE_VALUE +// #undef STM32_MCO1SEL +// #undef STM32_MCO1PRE +// #undef STM32_MCO2SEL +// #undef STM32_MCO2PRE +// #undef STM32_I2SSRC +// #undef STM32_PLLI2SN_VALUE +// #undef STM32_PLLI2SR_VALUE +// #undef STM32_PVD_ENABLE +// #undef STM32_PLS +// #undef STM32_BKPRAM_ENABLE + +// #define STM32_NO_INIT FALSE +// #define STM32_HSI_ENABLED TRUE +// #define STM32_LSI_ENABLED TRUE +// #define STM32_HSE_ENABLED TRUE +// #define STM32_LSE_ENABLED FALSE +// #define STM32_CLOCK48_REQUIRED TRUE +// #define STM32_SW STM32_SW_PLL +// #define STM32_PLLSRC STM32_PLLSRC_HSE +// #define STM32_PLLM_VALUE 8 +// #define STM32_PLLN_VALUE 192 +// #define STM32_PLLP_VALUE 4 +// #define STM32_PLLQ_VALUE 4 +// // AHB prescaler value. +// #define STM32_HPRE STM32_HPRE_DIV1 +// //APB1 prescaler value. +// #define STM32_PPRE1 STM32_PPRE1_DIV4 +// //APB2 prescaler value. +// #define STM32_PPRE2 STM32_PPRE2_DIV2 +// #define STM32_RTCSEL STM32_RTCSEL_LSI +// #define STM32_RTCPRE_VALUE 8 +// #define STM32_MCO1SEL STM32_MCO1SEL_HSI +// #define STM32_MCO1PRE STM32_MCO1PRE_DIV1 +// #define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK +// #define STM32_MCO2PRE STM32_MCO2PRE_DIV5 +// #define STM32_I2SSRC STM32_I2SSRC_CKIN +// #define STM32_PLLI2SN_VALUE 192 +// #define STM32_PLLI2SR_VALUE 5 +// #define STM32_PVD_ENABLE FALSE +// #define STM32_PLS STM32_PLS_LEV0 +// #define STM32_BKPRAM_ENABLE FALSE diff --git a/keyboards/yandrstudio/zhou65/rules.mk b/keyboards/yandrstudio/zhou65/rules.mk index 35a39a549a60..d35ad19f472f 100644 --- a/keyboards/yandrstudio/zhou65/rules.mk +++ b/keyboards/yandrstudio/zhou65/rules.mk @@ -1,5 +1,5 @@ # MCU name -MCU = STM32F401 +MCU = WB32F3G71 # Bootloader selection BOOTLOADER = stm32-dfu @@ -16,3 +16,4 @@ NKRO_ENABLE = yes # Enable N-Key Rollover BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow AUDIO_ENABLE = no # Audio output +EEPROM_DRIVER = vendor diff --git a/platforms/chibios/eeprom_wb32.c b/platforms/chibios/eeprom_wb32.c new file mode 100644 index 000000000000..b9de4221b724 --- /dev/null +++ b/platforms/chibios/eeprom_wb32.c @@ -0,0 +1,302 @@ +/* + Copyright (C) 2021 Westberry Technology (ChangZhou) Corp., Ltd + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include +#include +#include +#include "util.h" +#include "debug.h" + +#include "eeprom_wb32_defs.h" +#if !defined(FEE_PAGE_SIZE) || !defined(FEE_PAGE_COUNT) || !defined(FEE_MCU_FLASH_SIZE) || !defined(FEE_PAGE_BASE_ADDRESS) +# error "not implemented." +#endif + +// #define DEBUG_EEPROM_OUTPUT + +/* + * Debug print utils + */ + +#if defined(DEBUG_EEPROM_OUTPUT) + +# define debug_eeprom debug_enable +# define eeprom_println(s) println(s) +# define eeprom_printf(fmt, ...) xprintf(fmt, ##__VA_ARGS__); + +#else /* NO_DEBUG */ + +# define debug_eeprom false +# define eeprom_println(s) +# define eeprom_printf(fmt, ...) + +#endif /* NO_DEBUG */ + +/***************************************************************************** + * Allows to use the internal flash to store non volatile data. To initialize + * the functionality use the EEPROM_Init() function. Be sure that by reprogramming + * of the controller just affected pages will be deleted. In other case the non + * volatile data will be lost. + ******************************************************************************/ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +// __ASM void FLASH_OP_EXEC_RAM(uint32_t code, uint32_t fmc_base) +// { +// STR R0, [R1, #0x00] // FMC->CON = 0x00800080; # WR=1 +// NOP +// LB_CK +// LDR R0, [R1, #0x00] +// LSLS R0, R0, #24 +// BMI LB_CK // while(FMC->CON & FMC_CON_WR); +// BX LR +// } +/* Do not change if it is not necessary */ +// #define FLASH_OP_RAM_CODE {0xBF006008, 0x06006808, 0x4770D4FC} + +typedef enum { FLASH_BUSY = 1, FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_ERROR_OPT, FLASH_COMPLETE, FLASH_TIMEOUT, FLASH_BAD_ADDRESS } FLASH_Status; +static const uint32_t pre_op_code[] = {0x4FF0E92D, 0x21034832, 0x210C6281, 0xF8DF62C1, 0x2100C0C4, 0x1000F8CC, 0xF44F4608, 0x1C40767A, 0xDBFC42B0, 0xF8CC2201, 0x20002000, 0x42B01C40, 0x4829DBFC, 0xF0436803, 0x60030380, 0x302C4826, 0xF4436803, 0x60036320, 0x46104691, 0x323C4A22, 0x468A6010, 0x49214608, 0x48216008, 0x0340F8D0, 0x25004F1E, 0x5107F3C0, 0x3BFFF04F, 0x22001F3F, 0x4610465C, 0xEA5F683B, 0xD10678C0, 0xD10142A3, 0xE0002401, 0x44222400, 0x1C40461C, 0xDBF12814, 0xD91B2A02, 0xD9012910, 0xE0003910, 0x480D2100, 0x68021F00, 0x627FF022, 0x5201EA42, 0xF8CC6002, 0x2000A000, 0x42B01C40, 0xF8CCDBFC, 0x20009000, 0x42B01C40, 0x1C6DDBFC, 0xDBD02D05, 0x8FF0E8BD, 0x40010000, 0x40010438, 0x40010C20, 0x4000B804, 0x1FFFF000}; +#define PRE_OP() ((void (*)(void))((unsigned int)(pre_op_code) | 0x01))() +/* Functions -----------------------------------------------------------------*/ + +uint8_t DataBuf[FEE_PAGE_SIZE]; +/***************************************************************************** + * Delete Flash Space used for user Data, deletes the whole space between + * RW_PAGE_BASE_ADDRESS and the last uC Flash Page + ******************************************************************************/ +static uint16_t EEPROM_Init(void) { + /* Unlocks write to ANCTL registers */ + PWR->ANAKEY1 = 0x03; + PWR->ANAKEY2 = 0x0C; + /* Enables or disables the Internal 48MHz oscillator (FHSI). */ + ANCTL->FHSIENR = (uint32_t)ENABLE; + /* Locks write to ANCTL registers */ + PWR->ANAKEY1 = 0x00; + PWR->ANAKEY2 = 0x00; + + return FEE_DENSITY_BYTES; +} + +/***************************************************************************** + * Execute FLASH operation. + ******************************************************************************/ + +static uint32_t FLASH_OP_EXEC(uint32_t op) { + // volatile uint32_t flash_op_ram_code[] = FLASH_OP_RAM_CODE; + + /* Start FLASH operation and wait for a FLASH operation to complete */ + RCC->PCLKENR = 0x01; + FMC->CON = 0x7F5F0D40 | (op & 0x1F); /* [14:8]=0x0D, WREN=1, [4:0]=op */ + FMC->KEY = 0x5188DA08; + FMC->KEY = 0x12586590; + // ((void(*)(uint32_t, uint32_t))((unsigned int)(flash_op_ram_code) | 0x01))(0x00800080, FMC_BASE); + FMC->CON = 0x00800080; + while (FMC->CON & FMC_CON_WR) + ; + + RCC->PCLKENR = 0x00; + /* Clear WREN and OP[4:0] bits */ + FMC->CON = 0x005F0000; + + if (FMC->STAT & FMC_STAT_ERR) + return 1; /* Any error occur */ + else + return 0; /* FLASH operation complete */ +} + +/***************************************************************************** + * Programs the data to the specified page address. + ******************************************************************************/ +static uint32_t FMC_ProgramPage(uint32_t Page_Address) { + uint32_t ret; + int state; + + state = __get_PRIMASK(); + __disable_irq(); + PRE_OP(); + FMC->ADDR = Page_Address; + ret = FLASH_OP_EXEC(0x0C); + if (!state) { + __enable_irq(); + } + + return ret; +} + +/***************************************************************************** + * Erase a specified FLASH page. + ******************************************************************************/ +static uint32_t FMC_ErasePage(uint32_t Page_Address) { + uint32_t ret; + int state; + + state = __get_PRIMASK(); + __disable_irq(); + PRE_OP(); + FMC->ADDR = Page_Address; + ret = FLASH_OP_EXEC(0x08); + if (!state) { + __enable_irq(); + } + + return ret; +} + +/***************************************************************************** + * Clear page latches. + ******************************************************************************/ +static uint32_t FMC_ClearPageLatch(void) { + uint32_t ret; + int state; + + state = __get_PRIMASK(); + __disable_irq(); + ret = FLASH_OP_EXEC(0x04); + if (!state) { + __enable_irq(); + } + + return ret; +} + +/***************************************************************************** + * Erase the whole reserved Flash Space used for user Data. + ******************************************************************************/ +static void EEPROM_Erase(void) { + int page_num = 0; + + eeprom_println("EEPROM_Erase"); + + /* delete all pages from specified start page to the last page.*/ + do { + FMC_ErasePage(FEE_PAGE_BASE_ADDRESS + (page_num * FEE_PAGE_SIZE)); + page_num++; + } while (page_num < FEE_PAGE_COUNT); +} + +/***************************************************************************** + * Read flash data. + ******************************************************************************/ +static void WBFLASH_Read(uint32_t ReadAddr, uint8_t *ReadDest, uint16_t ReadLen) { + uint16_t i; + + for (i = 0; i < ReadLen; i++) { + ReadDest[i] = (__IO uint8_t)(*(__IO uint8_t *)ReadAddr); + ReadAddr++; + } +} +/***************************************************************************** + * Writes once data byte to flash on specified address. If a byte is already + * written, the whole page must be copied to a buffer, the byte changed and + * the manipulated buffer written after PageErase. + *******************************************************************************/ +static uint8_t wb_flash_buffer[FEE_PAGE_SIZE] = {0}; +static int EEPROM_WriteDataPage(uint16_t Addr, uint8_t *WriteSrc, size_t Len) { + uint16_t PageReamin; + uint16_t PageOff; + uint32_t PagePos; + uint32_t WriteAddr; + uint32_t WriteLen; + + /* exit if desired address is above the limit (Over maximum capacity).*/ + if (Addr > FEE_DENSITY_BYTES) { + eeprom_printf("EEPROM_WriteDataByte(0x%04x) [BAD ADDRESS]\n", Addr); + return -1; + } + + /* calculate which page is affected (Pagenum1/Pagenum2...PagenumN).*/ + PagePos = (Addr + FEE_PAGE_BASE_ADDRESS) / FEE_PAGE_SIZE; + PageOff = (Addr + FEE_PAGE_BASE_ADDRESS) % FEE_PAGE_SIZE; + PageReamin = FEE_PAGE_SIZE - PageOff; + WriteAddr = PagePos * FEE_PAGE_SIZE; + + WriteLen = (Len < PageReamin) ? Len : PageReamin; + + if (WriteLen != FEE_PAGE_SIZE) { + WBFLASH_Read(WriteAddr, wb_flash_buffer, FEE_PAGE_SIZE); + memcpy(wb_flash_buffer + PageOff, WriteSrc, WriteLen); + /* Erase the specified FLASH page */ + FMC_ErasePage(WriteAddr); + /* Clear page latch */ + FMC_ClearPageLatch(); + + for (int i = 0; i < (FEE_PAGE_SIZE >> 2); i++) { + FMC->BUF[i] = (*((volatile uint32_t *)(wb_flash_buffer + i * 4))); + } + /* Program data in page latch to the specified FLASH page */ + FMC_ProgramPage(WriteAddr); + return WriteLen; + } else { + /* Erase the specified FLASH page */ + FMC_ErasePage(WriteAddr); + /* Clear page latch */ + FMC_ClearPageLatch(); + + for (int i = 0; i < (FEE_PAGE_SIZE >> 2); i++) { + FMC->BUF[i] = (*((volatile uint32_t *)(WriteSrc + i * 4))); + } + /* Program data in page latch to the specified FLASH page */ + FMC_ProgramPage(WriteAddr); + return WriteLen; + } + + return -1; +} +/***************************************************************************** + * Read once data byte from a specified address. + *******************************************************************************/ +static uint8_t EEPROM_ReadDataByte(uint16_t Address) { + uint8_t DataByte = 0x00; + + // Get Byte from specified address + DataByte = (*(__IO uint8_t *)(FEE_PAGE_BASE_ADDRESS + (Address))); + + return DataByte; +} + +/***************************************************************************** + * Bind to eeprom_driver.c + *******************************************************************************/ +void eeprom_driver_init(void) { EEPROM_Init(); } + +void eeprom_driver_erase(void) { EEPROM_Erase(); } + +void eeprom_read_block(void *buf, const void *addr, size_t len) { + const uint8_t *p = (const uint8_t *)addr; + uint8_t * dest = (uint8_t *)buf; + while (len--) { + *dest++ = EEPROM_ReadDataByte((uint32_t)p++); + } +} + +void eeprom_write_block(const void *buf, void *addr, size_t len) { + uint8_t *dest = (uint8_t *)addr; + uint8_t *src = (uint8_t *)buf; + int retval; + + while (len) { + retval = EEPROM_WriteDataPage((uintptr_t)((uint16_t *)dest), src, len); + if (retval == -1) { + eeprom_println("EEPROM Write Failed"); + return; + } + + len -= retval; + dest += retval; + src += retval; + } +} diff --git a/platforms/chibios/eeprom_wb32_defs.h b/platforms/chibios/eeprom_wb32_defs.h new file mode 100644 index 000000000000..69c02a5a2417 --- /dev/null +++ b/platforms/chibios/eeprom_wb32_defs.h @@ -0,0 +1,55 @@ +/* + Copyright (C) 2021 Westberry Technology (ChangZhou) Corp., Ltd + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#pragma once + +#include + +#if !defined(FEE_PAGE_SIZE) || !defined(FEE_PAGE_COUNT) +# if defined(WB32F3G71x9) || defined(WB32F3G71xB) || defined(WB32F3G71xC) +# ifndef FEE_PAGE_SIZE +# define FEE_PAGE_SIZE 0x100 // Page size = 256Byte +# endif +# ifndef FEE_PAGE_COUNT +# define FEE_PAGE_COUNT 4 // How many pages are used +# endif +# endif +#endif + +#if !defined(FEE_MCU_FLASH_SIZE) +# if defined(WB32F3G71x9) +# define FEE_MCU_FLASH_SIZE 96 // Size in Kb +# elif defined(WB32F3G71xB) +# define FEE_MCU_FLASH_SIZE 128 // Size in Kb +# elif defined(WB32F3G71xC) +# define FEE_MCU_FLASH_SIZE 256 // Size in Kb +# endif +#endif + +/* Start of the emulated eeprom */ +#if !defined(FEE_PAGE_BASE_ADDRESS) +# if defined(WB32F3G71x9) || defined(WB32F3G71xB) || defined(WB32F3G71xC) +# ifndef WB32_FLASH_BASE +# define WB32_FLASH_BASE 0x8000000 +# endif +# ifndef FEE_PAGE_BASE_ADDRESS +# define FEE_PAGE_BASE_ADDRESS ((uint32_t)(WB32_FLASH_BASE + FEE_MCU_FLASH_SIZE * 1024 - FEE_PAGE_COUNT * FEE_PAGE_SIZE)) // bodge to force 2nd 16k page +# endif +# ifndef FEE_DENSITY_BYTES +# define FEE_DENSITY_BYTES (FEE_PAGE_SIZE * FEE_PAGE_COUNT - 1) +# endif +# endif +#endif diff --git a/platforms/eeprom.h b/platforms/eeprom.h index 091e6e440091..4a78a079fa21 100644 --- a/platforms/eeprom.h +++ b/platforms/eeprom.h @@ -45,6 +45,9 @@ void eeprom_update_block(const void *__src, void *__dst, size_t __n); #elif defined(EEPROM_STM32_FLASH_EMULATED) # include "eeprom_stm32_defs.h" # define TOTAL_EEPROM_BYTE_COUNT (FEE_DENSITY_BYTES) +#elif defined(EEPROM_WB32_FLASH_EMULATED) +# include "eeprom_wb32_defs.h" +# define TOTAL_EEPROM_BYTE_COUNT (FEE_DENSITY_BYTES) #elif defined(EEPROM_SAMD) # include "eeprom_samd.h" # define TOTAL_EEPROM_BYTE_COUNT (EEPROM_SIZE)