Don't make EEPROM size assumptions with dynamic keymaps. (#16054)
* Don't make EEPROM size assumptions with dynamic keymaps. * Add support for checking against emulated flash, error out if someone attempts to build a board without specifying EEPROM size. * Reorder defines so that MCU is considered last. * Refactor EEPROM definitions for simplicity. * Fix max sizing of kabedon/kabedon980. * Fix max sizing of mechlovin/olly/jf. * Fix unit tests. * Review comments, add messages with values during build failures.
This commit is contained in:
parent
da5cb5fd6f
commit
e22efc037a
17 changed files with 185 additions and 153 deletions
|
@ -18,11 +18,7 @@
|
|||
#include "samd51j18a.h"
|
||||
#include "core_cm4.h"
|
||||
#include "component/nvmctrl.h"
|
||||
|
||||
#ifndef EEPROM_SIZE
|
||||
# include "eeconfig.h"
|
||||
# define EEPROM_SIZE (((EECONFIG_SIZE + 3) / 4) * 4) // based off eeconfig's current usage, aligned to 4-byte sizes, to deal with LTO
|
||||
#endif
|
||||
#include "eeprom_samd.h"
|
||||
|
||||
#ifndef MAX
|
||||
# define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
|
8
platforms/arm_atsam/eeprom_samd.h
Executable file
8
platforms/arm_atsam/eeprom_samd.h
Executable file
|
@ -0,0 +1,8 @@
|
|||
// Copyright 2022 Nick Brassel (@tzarc)
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#ifndef EEPROM_SIZE
|
||||
# include "eeconfig.h"
|
||||
# define EEPROM_SIZE (((EECONFIG_SIZE + 3) / 4) * 4) // based off eeconfig's current usage, aligned to 4-byte sizes, to deal with LTO
|
||||
#endif
|
|
@ -133,10 +133,6 @@
|
|||
*/
|
||||
|
||||
#include "eeprom_stm32_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
|
||||
|
||||
/* These bits are used for optimizing encoding of bytes, 0 and 1 */
|
||||
#define FEE_WORD_ENCODING 0x8000
|
||||
#define FEE_VALUE_NEXT 0x6000
|
||||
|
@ -144,69 +140,11 @@
|
|||
#define FEE_VALUE_ENCODED 0x2000
|
||||
#define FEE_BYTE_RANGE 0x80
|
||||
|
||||
/* Addressable range 16KByte: 0 <-> (0x1FFF << 1) */
|
||||
#define FEE_ADDRESS_MAX_SIZE 0x4000
|
||||
|
||||
/* Flash word value after erase */
|
||||
#define FEE_EMPTY_WORD ((uint16_t)0xFFFF)
|
||||
|
||||
/* Size of combined compacted eeprom and write log pages */
|
||||
#define FEE_DENSITY_MAX_SIZE (FEE_PAGE_COUNT * FEE_PAGE_SIZE)
|
||||
|
||||
#ifndef FEE_MCU_FLASH_SIZE_IGNORE_CHECK /* *TODO: Get rid of this check */
|
||||
# if FEE_DENSITY_MAX_SIZE > (FEE_MCU_FLASH_SIZE * 1024)
|
||||
# pragma message STR(FEE_DENSITY_MAX_SIZE) " > " STR(FEE_MCU_FLASH_SIZE * 1024)
|
||||
# error emulated eeprom: FEE_DENSITY_MAX_SIZE is greater than available flash size
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Size of emulated eeprom */
|
||||
#ifdef FEE_DENSITY_BYTES
|
||||
# if (FEE_DENSITY_BYTES > FEE_DENSITY_MAX_SIZE)
|
||||
# pragma message STR(FEE_DENSITY_BYTES) " > " STR(FEE_DENSITY_MAX_SIZE)
|
||||
# error emulated eeprom: FEE_DENSITY_BYTES exceeds FEE_DENSITY_MAX_SIZE
|
||||
# endif
|
||||
# if (FEE_DENSITY_BYTES == FEE_DENSITY_MAX_SIZE)
|
||||
# pragma message STR(FEE_DENSITY_BYTES) " == " STR(FEE_DENSITY_MAX_SIZE)
|
||||
# warning emulated eeprom: FEE_DENSITY_BYTES leaves no room for a write log. This will greatly increase the flash wear rate!
|
||||
# endif
|
||||
# if FEE_DENSITY_BYTES > FEE_ADDRESS_MAX_SIZE
|
||||
# pragma message STR(FEE_DENSITY_BYTES) " > " STR(FEE_ADDRESS_MAX_SIZE)
|
||||
# error emulated eeprom: FEE_DENSITY_BYTES is greater than FEE_ADDRESS_MAX_SIZE allows
|
||||
# endif
|
||||
# if ((FEE_DENSITY_BYTES) % 2) == 1
|
||||
# error emulated eeprom: FEE_DENSITY_BYTES must be even
|
||||
# endif
|
||||
#else
|
||||
/* Default to half of allocated space used for emulated eeprom, half for write log */
|
||||
# define FEE_DENSITY_BYTES (FEE_PAGE_COUNT * FEE_PAGE_SIZE / 2)
|
||||
#endif
|
||||
|
||||
/* Size of write log */
|
||||
#ifdef FEE_WRITE_LOG_BYTES
|
||||
# if ((FEE_DENSITY_BYTES + FEE_WRITE_LOG_BYTES) > FEE_DENSITY_MAX_SIZE)
|
||||
# pragma message STR(FEE_DENSITY_BYTES) " + " STR(FEE_WRITE_LOG_BYTES) " > " STR(FEE_DENSITY_MAX_SIZE)
|
||||
# error emulated eeprom: FEE_WRITE_LOG_BYTES exceeds remaining FEE_DENSITY_MAX_SIZE
|
||||
# endif
|
||||
# if ((FEE_WRITE_LOG_BYTES) % 2) == 1
|
||||
# error emulated eeprom: FEE_WRITE_LOG_BYTES must be even
|
||||
# endif
|
||||
#else
|
||||
/* Default to use all remaining space */
|
||||
# define FEE_WRITE_LOG_BYTES (FEE_PAGE_COUNT * FEE_PAGE_SIZE - FEE_DENSITY_BYTES)
|
||||
#endif
|
||||
|
||||
/* Start of the emulated eeprom compacted flash area */
|
||||
#define FEE_COMPACTED_BASE_ADDRESS FEE_PAGE_BASE_ADDRESS
|
||||
/* End of the emulated eeprom compacted flash area */
|
||||
#define FEE_COMPACTED_LAST_ADDRESS (FEE_COMPACTED_BASE_ADDRESS + FEE_DENSITY_BYTES)
|
||||
/* Start of the emulated eeprom write log */
|
||||
#define FEE_WRITE_LOG_BASE_ADDRESS FEE_COMPACTED_LAST_ADDRESS
|
||||
/* End of the emulated eeprom write log */
|
||||
#define FEE_WRITE_LOG_LAST_ADDRESS (FEE_WRITE_LOG_BASE_ADDRESS + FEE_WRITE_LOG_BYTES)
|
||||
|
||||
#if defined(DYNAMIC_KEYMAP_EEPROM_MAX_ADDR) && (DYNAMIC_KEYMAP_EEPROM_MAX_ADDR >= FEE_DENSITY_BYTES)
|
||||
# error emulated eeprom: DYNAMIC_KEYMAP_EEPROM_MAX_ADDR is greater than the FEE_DENSITY_BYTES available
|
||||
#if !defined(FEE_PAGE_SIZE) || !defined(FEE_PAGE_COUNT) || !defined(FEE_MCU_FLASH_SIZE) || !defined(FEE_PAGE_BASE_ADDRESS)
|
||||
# error "not implemented."
|
||||
#endif
|
||||
|
||||
/* In-memory contents of emulated eeprom for faster access */
|
||||
|
|
|
@ -72,3 +72,65 @@
|
|||
# define FEE_PAGE_BASE_ADDRESS ((uintptr_t)(FEE_FLASH_BASE) + FEE_MCU_FLASH_SIZE * 1024 - (FEE_PAGE_COUNT * FEE_PAGE_SIZE))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Addressable range 16KByte: 0 <-> (0x1FFF << 1) */
|
||||
#define FEE_ADDRESS_MAX_SIZE 0x4000
|
||||
|
||||
/* Size of combined compacted eeprom and write log pages */
|
||||
#define FEE_DENSITY_MAX_SIZE (FEE_PAGE_COUNT * FEE_PAGE_SIZE)
|
||||
|
||||
#ifndef FEE_MCU_FLASH_SIZE_IGNORE_CHECK /* *TODO: Get rid of this check */
|
||||
# if FEE_DENSITY_MAX_SIZE > (FEE_MCU_FLASH_SIZE * 1024)
|
||||
# pragma message STR(FEE_DENSITY_MAX_SIZE) " > " STR(FEE_MCU_FLASH_SIZE * 1024)
|
||||
# error emulated eeprom: FEE_DENSITY_MAX_SIZE is greater than available flash size
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Size of emulated eeprom */
|
||||
#ifdef FEE_DENSITY_BYTES
|
||||
# if (FEE_DENSITY_BYTES > FEE_DENSITY_MAX_SIZE)
|
||||
# pragma message STR(FEE_DENSITY_BYTES) " > " STR(FEE_DENSITY_MAX_SIZE)
|
||||
# error emulated eeprom: FEE_DENSITY_BYTES exceeds FEE_DENSITY_MAX_SIZE
|
||||
# endif
|
||||
# if (FEE_DENSITY_BYTES == FEE_DENSITY_MAX_SIZE)
|
||||
# pragma message STR(FEE_DENSITY_BYTES) " == " STR(FEE_DENSITY_MAX_SIZE)
|
||||
# warning emulated eeprom: FEE_DENSITY_BYTES leaves no room for a write log. This will greatly increase the flash wear rate!
|
||||
# endif
|
||||
# if FEE_DENSITY_BYTES > FEE_ADDRESS_MAX_SIZE
|
||||
# pragma message STR(FEE_DENSITY_BYTES) " > " STR(FEE_ADDRESS_MAX_SIZE)
|
||||
# error emulated eeprom: FEE_DENSITY_BYTES is greater than FEE_ADDRESS_MAX_SIZE allows
|
||||
# endif
|
||||
# if ((FEE_DENSITY_BYTES) % 2) == 1
|
||||
# error emulated eeprom: FEE_DENSITY_BYTES must be even
|
||||
# endif
|
||||
#else
|
||||
/* Default to half of allocated space used for emulated eeprom, half for write log */
|
||||
# define FEE_DENSITY_BYTES (FEE_PAGE_COUNT * FEE_PAGE_SIZE / 2)
|
||||
#endif
|
||||
|
||||
/* Size of write log */
|
||||
#ifdef FEE_WRITE_LOG_BYTES
|
||||
# if ((FEE_DENSITY_BYTES + FEE_WRITE_LOG_BYTES) > FEE_DENSITY_MAX_SIZE)
|
||||
# pragma message STR(FEE_DENSITY_BYTES) " + " STR(FEE_WRITE_LOG_BYTES) " > " STR(FEE_DENSITY_MAX_SIZE)
|
||||
# error emulated eeprom: FEE_WRITE_LOG_BYTES exceeds remaining FEE_DENSITY_MAX_SIZE
|
||||
# endif
|
||||
# if ((FEE_WRITE_LOG_BYTES) % 2) == 1
|
||||
# error emulated eeprom: FEE_WRITE_LOG_BYTES must be even
|
||||
# endif
|
||||
#else
|
||||
/* Default to use all remaining space */
|
||||
# define FEE_WRITE_LOG_BYTES (FEE_PAGE_COUNT * FEE_PAGE_SIZE - FEE_DENSITY_BYTES)
|
||||
#endif
|
||||
|
||||
/* Start of the emulated eeprom compacted flash area */
|
||||
#define FEE_COMPACTED_BASE_ADDRESS FEE_PAGE_BASE_ADDRESS
|
||||
/* End of the emulated eeprom compacted flash area */
|
||||
#define FEE_COMPACTED_LAST_ADDRESS (FEE_COMPACTED_BASE_ADDRESS + FEE_DENSITY_BYTES)
|
||||
/* Start of the emulated eeprom write log */
|
||||
#define FEE_WRITE_LOG_BASE_ADDRESS FEE_COMPACTED_LAST_ADDRESS
|
||||
/* End of the emulated eeprom write log */
|
||||
#define FEE_WRITE_LOG_LAST_ADDRESS (FEE_WRITE_LOG_BASE_ADDRESS + FEE_WRITE_LOG_BYTES)
|
||||
|
||||
#if defined(DYNAMIC_KEYMAP_EEPROM_MAX_ADDR) && (DYNAMIC_KEYMAP_EEPROM_MAX_ADDR >= FEE_DENSITY_BYTES)
|
||||
# error emulated eeprom: DYNAMIC_KEYMAP_EEPROM_MAX_ADDR is greater than the FEE_DENSITY_BYTES available
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <ch.h>
|
||||
#include <hal.h>
|
||||
|
||||
#include "eeprom_teensy.h"
|
||||
#include "eeconfig.h"
|
||||
|
||||
/*************************************/
|
||||
|
@ -42,18 +43,6 @@
|
|||
#if defined(K20x) /* chip selection */
|
||||
/* Teensy 3.0, 3.1, 3.2; mchck; infinity keyboard */
|
||||
|
||||
// The EEPROM is really RAM with a hardware-based backup system to
|
||||
// flash memory. Selecting a smaller size EEPROM allows more wear
|
||||
// leveling, for higher write endurance. If you edit this file,
|
||||
// set this to the smallest size your application can use. Also,
|
||||
// due to Freescale's implementation, writing 16 or 32 bit words
|
||||
// (aligned to 2 or 4 byte boundaries) has twice the endurance
|
||||
// compared to writing 8 bit bytes.
|
||||
//
|
||||
# ifndef EEPROM_SIZE
|
||||
# define EEPROM_SIZE 32
|
||||
# endif
|
||||
|
||||
/*
|
||||
^^^ Here be dragons:
|
||||
NXP AppNote AN4282 section 3.1 states that partitioning must only be done once.
|
||||
|
@ -350,8 +339,6 @@ void do_flash_cmd(volatile uint8_t *fstat)
|
|||
extern uint32_t __eeprom_workarea_start__;
|
||||
extern uint32_t __eeprom_workarea_end__;
|
||||
|
||||
# define EEPROM_SIZE 128
|
||||
|
||||
static uint32_t flashend = 0;
|
||||
|
||||
void eeprom_initialize(void) {
|
||||
|
|
22
platforms/chibios/eeprom_teensy.h
Executable file
22
platforms/chibios/eeprom_teensy.h
Executable file
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2022 Nick Brassel (@tzarc)
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#if defined(K20x)
|
||||
/* Teensy 3.0, 3.1, 3.2; mchck; infinity keyboard */
|
||||
// The EEPROM is really RAM with a hardware-based backup system to
|
||||
// flash memory. Selecting a smaller size EEPROM allows more wear
|
||||
// leveling, for higher write endurance. If you edit this file,
|
||||
// set this to the smallest size your application can use. Also,
|
||||
// due to Freescale's implementation, writing 16 or 32 bit words
|
||||
// (aligned to 2 or 4 byte boundaries) has twice the endurance
|
||||
// compared to writing 8 bit bytes.
|
||||
//
|
||||
# ifndef EEPROM_SIZE
|
||||
# define EEPROM_SIZE 32
|
||||
# endif
|
||||
#elif defined(KL2x) /* Teensy LC (emulated) */
|
||||
# define EEPROM_SIZE 128
|
||||
#else
|
||||
# error Unsupported Teensy EEPROM.
|
||||
#endif
|
|
@ -1,3 +1,5 @@
|
|||
// Copyright 2018-2022 QMK
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#if defined(__AVR__) && !defined(EEPROM_DRIVER)
|
||||
|
@ -19,3 +21,50 @@ void eeprom_update_word(uint16_t *__p, uint16_t __value);
|
|||
void eeprom_update_dword(uint32_t *__p, uint32_t __value);
|
||||
void eeprom_update_block(const void *__src, void *__dst, size_t __n);
|
||||
#endif
|
||||
|
||||
#if defined(EEPROM_CUSTOM)
|
||||
# ifndef EEPROM_SIZE
|
||||
# error EEPROM_SIZE has not been defined for custom driver.
|
||||
# endif
|
||||
# define TOTAL_EEPROM_BYTE_COUNT (EEPROM_SIZE)
|
||||
#elif defined(EEPROM_TRANSIENT)
|
||||
# include "eeprom_transient.h"
|
||||
# define TOTAL_EEPROM_BYTE_COUNT (TRANSIENT_EEPROM_SIZE)
|
||||
#elif defined(EEPROM_I2C)
|
||||
# include "eeprom_i2c.h"
|
||||
# define TOTAL_EEPROM_BYTE_COUNT (EXTERNAL_EEPROM_BYTE_COUNT)
|
||||
#elif defined(EEPROM_SPI)
|
||||
# include "eeprom_spi.h"
|
||||
# define TOTAL_EEPROM_BYTE_COUNT (EXTERNAL_EEPROM_BYTE_COUNT)
|
||||
#elif defined(EEPROM_STM32_L0_L1)
|
||||
# include "eeprom_stm32_L0_L1.h"
|
||||
# define TOTAL_EEPROM_BYTE_COUNT (STM32_ONBOARD_EEPROM_SIZE)
|
||||
#elif defined(EEPROM_TEENSY)
|
||||
# include "eeprom_teensy.h"
|
||||
# define TOTAL_EEPROM_BYTE_COUNT (EEPROM_SIZE)
|
||||
#elif defined(EEPROM_STM32_FLASH_EMULATED)
|
||||
# include "eeprom_stm32_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)
|
||||
#elif defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega16U4__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATtiny85__)
|
||||
# define TOTAL_EEPROM_BYTE_COUNT 512
|
||||
#elif defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega32A__)
|
||||
# define TOTAL_EEPROM_BYTE_COUNT 1024
|
||||
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__)
|
||||
# define TOTAL_EEPROM_BYTE_COUNT 2048
|
||||
#elif defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
|
||||
# define TOTAL_EEPROM_BYTE_COUNT 4096
|
||||
#elif defined(EEPROM_TEST_HARNESS)
|
||||
# ifndef FLASH_STM32_MOCKED
|
||||
// Normal tests
|
||||
# define TOTAL_EEPROM_BYTE_COUNT 32
|
||||
# else
|
||||
// Flash wear-leveling testing
|
||||
# include "eeprom_stm32_tests.h"
|
||||
# define TOTAL_EEPROM_BYTE_COUNT (EEPROM_SIZE)
|
||||
# endif
|
||||
#else
|
||||
# error Unknown EEPROM driver.
|
||||
#endif
|
||||
|
|
|
@ -16,9 +16,7 @@
|
|||
|
||||
#include "eeprom.h"
|
||||
|
||||
#define EEPROM_SIZE 32
|
||||
|
||||
static uint8_t buffer[EEPROM_SIZE];
|
||||
static uint8_t buffer[TOTAL_EEPROM_BYTE_COUNT];
|
||||
|
||||
uint8_t eeprom_read_byte(const uint8_t *addr) {
|
||||
uintptr_t offset = (uintptr_t)addr;
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
#include "gtest/gtest.h"
|
||||
|
||||
extern "C" {
|
||||
#include "flash_stm32.h"
|
||||
#include "eeprom_stm32.h"
|
||||
#include "eeprom.h"
|
||||
}
|
||||
|
||||
|
@ -46,7 +44,6 @@ extern "C" {
|
|||
*
|
||||
*/
|
||||
|
||||
#define EEPROM_SIZE (FEE_PAGE_SIZE * FEE_PAGE_COUNT / 2)
|
||||
#define LOG_SIZE EEPROM_SIZE
|
||||
#define LOG_BASE (MOCK_FLASH_SIZE - LOG_SIZE)
|
||||
#define EEPROM_BASE (LOG_BASE - EEPROM_SIZE)
|
||||
|
|
8
platforms/test/eeprom_stm32_tests.h
Normal file
8
platforms/test/eeprom_stm32_tests.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
// Copyright 2018-2022 Nick Brassel (@tzarc)
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include "flash_stm32.h"
|
||||
#include "eeprom_stm32.h"
|
||||
|
||||
#define EEPROM_SIZE (FEE_PAGE_SIZE * FEE_PAGE_COUNT / 2)
|
|
@ -1,4 +1,4 @@
|
|||
eeprom_stm32_DEFS := -DFLASH_STM32_MOCKED -DNO_PRINT -DFEE_FLASH_BASE=FlashBuf
|
||||
eeprom_stm32_DEFS := -DEEPROM_TEST_HARNESS -DFLASH_STM32_MOCKED -DNO_PRINT -DFEE_FLASH_BASE=FlashBuf
|
||||
eeprom_stm32_tiny_DEFS := $(eeprom_stm32_DEFS) \
|
||||
-DFEE_MCU_FLASH_SIZE=1 \
|
||||
-DMOCK_FLASH_SIZE=1024 \
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue