diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk index 7f07be5144d2..609d76d80082 100644 --- a/builddefs/common_features.mk +++ b/builddefs/common_features.mk @@ -249,7 +249,7 @@ else endif endif -VALID_WEAR_LEVELING_DRIVER_TYPES := custom embedded_flash spi_flash rp2040_flash legacy +VALID_WEAR_LEVELING_DRIVER_TYPES := custom embedded_flash spi_flash rp2040_flash legacy sn32 WEAR_LEVELING_DRIVER ?= none ifneq ($(strip $(WEAR_LEVELING_DRIVER)),none) ifeq ($(filter $(WEAR_LEVELING_DRIVER),$(VALID_WEAR_LEVELING_DRIVER_TYPES)),) @@ -277,6 +277,9 @@ ifneq ($(strip $(WEAR_LEVELING_DRIVER)),none) COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/flash SRC += flash_stm32.c wear_leveling_legacy.c POST_CONFIG_H += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/wear_leveling/wear_leveling_legacy_config.h + else ifeq ($(strip $(WEAR_LEVELING_DRIVER)), sn32) + SRC += wear_leveling_sn32.c + POST_CONFIG_H += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/wear_leveling/wear_leveling_sn32_config.h endif endif endif diff --git a/keyboards/handwired/onekey/sn32/rules.mk b/keyboards/handwired/onekey/sn32/rules.mk index e69de29bb2d1..11832616931b 100644 --- a/keyboards/handwired/onekey/sn32/rules.mk +++ b/keyboards/handwired/onekey/sn32/rules.mk @@ -0,0 +1,2 @@ +EEPROM_DRIVER = wear_leveling +WEAR_LEVELING_DRIVER = sn32 diff --git a/platforms/chibios/drivers/wear_leveling/wear_leveling_sn32.c b/platforms/chibios/drivers/wear_leveling/wear_leveling_sn32.c new file mode 100644 index 000000000000..e89b2eb7d35a --- /dev/null +++ b/platforms/chibios/drivers/wear_leveling/wear_leveling_sn32.c @@ -0,0 +1,56 @@ +// Copyright 2022 Jose Pablo Ramirez (@jpe230) +// SPDX-License-Identifier: GPL-2.0-or-later +#include +#include "timer.h" +#include "wear_leveling.h" +#include "wear_leveling_internal.h" +#include "Flash.h" + +bool backing_store_init(void) { + bs_dprintf("Init\n"); + return true; +} + +bool backing_store_unlock(void) { + bs_dprintf("Unlock\n"); + return true; +} + +bool backing_store_erase(void) { +#ifdef WEAR_LEVELING_DEBUG_OUTPUT + uint32_t start = timer_read32(); +#endif + + bool ret = true; + FLASH_Status status; + for (int i = 0; i < (WEAR_LEVELING_SN32_EMULATION_PAGE_COUNT); ++i) { + status = FLASH_EraseSector(WEAR_LEVELING_SN32_EMULATION_BASE_PAGE_ADDRESS + (i * WEAR_LEVELING_SN32_PAGE_SIZE)); + if (status != FLASH_FAIL) { + ret = false; + } + } + + bs_dprintf("Backing store erase took %ldms to complete\n", ((long)(timer_read32() - start))); + return ret; +} + +bool backing_store_write(uint32_t address, backing_store_int_t value) { + uint32_t offset = ((WEAR_LEVELING_SN32_EMULATION_BASE_PAGE_ADDRESS) + address); + bs_dprintf("Write "); + wl_dump(offset, &value, sizeof(backing_store_int_t)); + return FLASH_ProgramDWord(offset & 0xFFFFFFFC, value) == FLASH_OKAY; +} + +bool backing_store_lock(void) { + bs_dprintf("Lock \n"); + return true; +} + +bool backing_store_read(uint32_t address, backing_store_int_t* value) { + uint32_t offset = ((WEAR_LEVELING_SN32_EMULATION_BASE_PAGE_ADDRESS) + address); + backing_store_int_t* loc = (backing_store_int_t*)offset; + *value = *loc; + bs_dprintf("Read "); + wl_dump(offset, loc, sizeof(backing_store_int_t)); + return true; +} diff --git a/platforms/chibios/drivers/wear_leveling/wear_leveling_sn32_config.h b/platforms/chibios/drivers/wear_leveling/wear_leveling_sn32_config.h new file mode 100644 index 000000000000..0f3ccabf512a --- /dev/null +++ b/platforms/chibios/drivers/wear_leveling/wear_leveling_sn32_config.h @@ -0,0 +1,50 @@ +// Copyright 2022 Jose Pablo Ramirez (@jpe230) +// SPDX-License-Identifier: GPL-2.0-or-later +#pragma once + +// Work out the page size to use +#ifndef WEAR_LEVELING_SN32_PAGE_SIZE +# if defined(QMK_MCU_SERIES_SN32F240B) +# define WEAR_LEVELING_SN32_PAGE_SIZE 64 +# elif defined(QMK_MCU_SERIES_SN32F240) +# define WEAR_LEVELING_SN32_PAGE_SIZE 64 +# endif +#endif + +// Number of pages we have +#ifndef WEAR_LEVELING_SN32_EMULATION_TOTAL_PAGE +# if defined(QMK_MCU_SERIES_SN32F240B) +# define WEAR_LEVELING_SN32_EMULATION_TOTAL_PAGE 1024 +# elif defined(QMK_MCU_SERIES_SN32F260) +# define WEAR_LEVELING_SN32_EMULATION_TOTAL_PAGE 480 +# endif +#endif + +// The number of pages to use +#ifndef WEAR_LEVELING_SN32_EMULATION_PAGE_COUNT +# if defined(QMK_MCU_SERIES_SN32F240B) +# define WEAR_LEVELING_SN32_EMULATION_PAGE_COUNT 23 +# elif defined(QMK_MCU_SERIES_SN32F260) +# define WEAR_LEVELING_SN32_EMULATION_PAGE_COUNT 23 +# endif +#endif + +// The origin of the emulated eeprom +#ifndef WEAR_LEVELING_SN32_EMULATION_BASE_PAGE_ADDRESS +# define WEAR_LEVELING_SN32_EMULATION_BASE_PAGE_ADDRESS ((uint32_t)(WEAR_LEVELING_SN32_PAGE_SIZE * WEAR_LEVELING_SN32_EMULATION_TOTAL_PAGE - ((WEAR_LEVELING_SN32_EMULATION_PAGE_COUNT + 1) * WEAR_LEVELING_SN32_PAGE_SIZE))) +#endif + +// 4-byte writes +#ifndef BACKING_STORE_WRITE_SIZE +# define BACKING_STORE_WRITE_SIZE 4 +#endif + +// The amount of space to use for the entire set of emulation +#ifndef WEAR_LEVELING_BACKING_SIZE +# define WEAR_LEVELING_BACKING_SIZE ((WEAR_LEVELING_SN32_EMULATION_PAGE_COUNT)*WEAR_LEVELING_SN32_PAGE_SIZE) +#endif + +// The logical amount of eeprom available +#ifndef WEAR_LEVELING_LOGICAL_SIZE +# define WEAR_LEVELING_LOGICAL_SIZE ((WEAR_LEVELING_BACKING_SIZE) / 2) +#endif