~ruther/qmk_firmware

8d6d8cfadfd1522b3dd2cc8ac1ce7393b45bbe64 — Joel Challis 4 years ago fe6d6cf
Tidy up defines within STM EEPROM emulation (#14275)

* Tidy up defines within stm eeprom emulation

* Fix tests

* Resolve todo

* Still use page notion in clear

* Remove more f4 refs
M keyboards/nk65/config.h => keyboards/nk65/config.h +1 -1
@@ 151,7 151,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
#ifndef FLASHSIZE_BASE
#  define FLASHSIZE_BASE ((uint32_t)0x1FFFF7CCU) /*!< FLASH Size register base address */
#endif
#define EEPROM_START_ADDRESS
#define FEE_MCU_FLASH_SIZE_IGNORE_CHECK
#define FEE_MCU_FLASH_SIZE                              \
({                                                      \
    uint16_t (*flash_size) = (uint16_t*)FLASHSIZE_BASE;  \

M tmk_core/common/chibios/eeprom_stm32.c => tmk_core/common/chibios/eeprom_stm32.c +37 -73
@@ 51,13 51,13 @@
 *
 * The following configuration defines can be set:
 *
 * FEE_DENSITY_PAGES   # Total number of pages to use for eeprom simulation (Compact + Write log)
 * FEE_DENSITY_BYTES   # Size of simulated eeprom. (Defaults to half the space allocated by FEE_DENSITY_PAGES)
 * FEE_PAGE_COUNT   # Total number of pages to use for eeprom simulation (Compact + Write log)
 * FEE_DENSITY_BYTES   # Size of simulated eeprom. (Defaults to half the space allocated by FEE_PAGE_COUNT)
 * NOTE: The current implementation does not include page swapping,
 * and FEE_DENSITY_BYTES will consume that amount of RAM as a cached view of actual EEPROM contents.
 *
 * The maximum size of FEE_DENSITY_BYTES is currently 16384. The write log size equals
 * FEE_DENSITY_PAGES * FEE_PAGE_SIZE - FEE_DENSITY_BYTES.
 * FEE_PAGE_COUNT * FEE_PAGE_SIZE - FEE_DENSITY_BYTES.
 * The larger the write log, the less frequently the compacted area needs to be rewritten.
 *
 *


@@ 132,6 132,11 @@
 *
 */

#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


@@ 139,65 144,19 @@
#define FEE_VALUE_ENCODED 0x2000
#define FEE_BYTE_RANGE 0x80

// HACK ALERT. This definition may not match your processor
// To Do. Work out correct value for EEPROM_PAGE_SIZE on the STM32F103CT6 etc
#if defined(EEPROM_EMU_STM32F303xC)
#    define MCU_STM32F303CC
#elif defined(EEPROM_EMU_STM32F103xB)
#    define MCU_STM32F103RB
#elif defined(EEPROM_EMU_STM32F072xB)
#    define MCU_STM32F072CB
#elif defined(EEPROM_EMU_STM32F042x6)
#    define MCU_STM32F042K6
#elif !defined(FEE_PAGE_SIZE) || !defined(FEE_DENSITY_PAGES) || !defined(FEE_MCU_FLASH_SIZE)
#    error "not implemented."
#endif

#if !defined(FEE_PAGE_SIZE) || !defined(FEE_DENSITY_PAGES)
#    if defined(MCU_STM32F103RB) || defined(MCU_STM32F042K6)
#        ifndef FEE_PAGE_SIZE
#            define FEE_PAGE_SIZE 0x400  // Page size = 1KByte
#        endif
#        ifndef FEE_DENSITY_PAGES
#            define FEE_DENSITY_PAGES 2  // How many pages are used
#        endif
#    elif defined(MCU_STM32F103ZE) || defined(MCU_STM32F103RE) || defined(MCU_STM32F103RD) || defined(MCU_STM32F303CC) || defined(MCU_STM32F072CB)
#        ifndef FEE_PAGE_SIZE
#            define FEE_PAGE_SIZE 0x800  // Page size = 2KByte
#        endif
#        ifndef FEE_DENSITY_PAGES
#            define FEE_DENSITY_PAGES 4  // How many pages are used
#        endif
#    else
#        error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)."
#    endif
#endif
/* Addressable range 16KByte: 0 <-> (0x1FFF << 1) */
#define FEE_ADDRESS_MAX_SIZE 0x4000

#ifndef FEE_MCU_FLASH_SIZE
#    if defined(MCU_STM32F103RB) || defined(MCU_STM32F072CB)
#        define FEE_MCU_FLASH_SIZE 128  // Size in Kb
#    elif defined(MCU_STM32F042K6)
#        define FEE_MCU_FLASH_SIZE 32  // Size in Kb
#    elif defined(MCU_STM32F103ZE) || defined(MCU_STM32F103RE)
#        define FEE_MCU_FLASH_SIZE 512  // Size in Kb
#    elif defined(MCU_STM32F103RD)
#        define FEE_MCU_FLASH_SIZE 384  // Size in Kb
#    elif defined(MCU_STM32F303CC)
#        define FEE_MCU_FLASH_SIZE 256  // Size in Kb
#    else
#        error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)."
#    endif
#endif
/* 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_DENSITY_PAGES * FEE_PAGE_SIZE)
/* Addressable range 16KByte: 0 <-> (0x1FFF << 1) */
#define FEE_ADDRESS_MAX_SIZE 0x4000
#define FEE_DENSITY_MAX_SIZE (FEE_PAGE_COUNT * FEE_PAGE_SIZE)

#ifndef EEPROM_START_ADDRESS /* *TODO: Get rid of this check */
#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_PAGES is greater than available flash size
#        error emulated eeprom: FEE_DENSITY_MAX_SIZE is greater than available flash size
#    endif
#endif



@@ 220,27 179,32 @@
#    endif
#else
/* Default to half of allocated space used for emulated eeprom, half for write log */
#    define FEE_DENSITY_BYTES (FEE_DENSITY_PAGES * FEE_PAGE_SIZE / 2)
#    define FEE_DENSITY_BYTES (FEE_PAGE_COUNT * FEE_PAGE_SIZE / 2)
#endif

/* Size of write log */
#define FEE_WRITE_LOG_BYTES (FEE_DENSITY_PAGES * FEE_PAGE_SIZE - FEE_DENSITY_BYTES)
#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 */
#ifndef FEE_FLASH_BASE
#    define FEE_FLASH_BASE 0x8000000
#endif
#define FEE_PAGE_BASE_ADDRESS ((uintptr_t)(FEE_FLASH_BASE) + FEE_MCU_FLASH_SIZE * 1024 - FEE_WRITE_LOG_BYTES - FEE_DENSITY_BYTES)
#define FEE_COMPACTED_BASE_ADDRESS FEE_PAGE_BASE_ADDRESS
/* End of the emulated eeprom compacted flash area */
#define FEE_PAGE_LAST_ADDRESS (FEE_PAGE_BASE_ADDRESS + FEE_DENSITY_BYTES)
#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_PAGE_LAST_ADDRESS
#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)

/* Flash word value after erase */
#define FEE_EMPTY_WORD ((uint16_t)0xFFFF)

#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


@@ 313,9 277,9 @@ void print_eeprom(void) {

uint16_t EEPROM_Init(void) {
    /* Load emulated eeprom contents from compacted flash into memory */
    uint16_t *src  = (uint16_t *)FEE_PAGE_BASE_ADDRESS;
    uint16_t *src  = (uint16_t *)FEE_COMPACTED_BASE_ADDRESS;
    uint16_t *dest = (uint16_t *)DataBuf;
    for (; src < (uint16_t *)FEE_PAGE_LAST_ADDRESS; ++src, ++dest) {
    for (; src < (uint16_t *)FEE_COMPACTED_LAST_ADDRESS; ++src, ++dest) {
        *dest = ~*src;
    }



@@ 390,7 354,7 @@ uint16_t EEPROM_Init(void) {
static void eeprom_clear(void) {
    FLASH_Unlock();

    for (uint16_t page_num = 0; page_num < FEE_DENSITY_PAGES; ++page_num) {
    for (uint16_t page_num = 0; page_num < FEE_PAGE_COUNT; ++page_num) {
        eeprom_printf("FLASH_ErasePage(0x%04x)\n", (uint32_t)(FEE_PAGE_BASE_ADDRESS + (page_num * FEE_PAGE_SIZE)));
        FLASH_ErasePage(FEE_PAGE_BASE_ADDRESS + (page_num * FEE_PAGE_SIZE));
    }


@@ 421,9 385,9 @@ static uint8_t eeprom_compact(void) {

    /* Write emulated eeprom contents from memory to compacted flash */
    uint16_t *src  = (uint16_t *)DataBuf;
    uintptr_t dest = FEE_PAGE_BASE_ADDRESS;
    uintptr_t dest = FEE_COMPACTED_BASE_ADDRESS;
    uint16_t  value;
    for (; dest < FEE_PAGE_LAST_ADDRESS; ++src, dest += 2) {
    for (; dest < FEE_COMPACTED_LAST_ADDRESS; ++src, dest += 2) {
        value = *src;
        if (value) {
            eeprom_printf("FLASH_ProgramHalfWord(0x%04x, 0x%04x)\n", (uint32_t)dest, ~value);


@@ 444,7 408,7 @@ static uint8_t eeprom_compact(void) {

static uint8_t eeprom_write_direct_entry(uint16_t Address) {
    /* Check if we can just write this directly to the compacted flash area */
    uintptr_t directAddress = FEE_PAGE_BASE_ADDRESS + (Address & 0xFFFE);
    uintptr_t directAddress = FEE_COMPACTED_BASE_ADDRESS + (Address & 0xFFFE);
    if (*(uint16_t *)directAddress == FEE_EMPTY_WORD) {
        /* Write the value directly to the compacted area without a log entry */
        uint16_t value = ~*(uint16_t *)(&DataBuf[Address & 0xFFFE]);

A tmk_core/common/chibios/eeprom_stm32_defs.h => tmk_core/common/chibios/eeprom_stm32_defs.h +61 -0
@@ 0,0 1,61 @@
/* Copyright 2021 QMK
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#pragma once

#include <hal.h>

#if !defined(FEE_PAGE_SIZE) || !defined(FEE_PAGE_COUNT)
#    if defined(STM32F103xB) || defined(STM32F042x6)
#        ifndef FEE_PAGE_SIZE
#            define FEE_PAGE_SIZE 0x400  // Page size = 1KByte
#        endif
#        ifndef FEE_PAGE_COUNT
#            define FEE_PAGE_COUNT 2  // How many pages are used
#        endif
#    elif defined(STM32F103xE) || defined(STM32F303xC) || defined(STM32F072xB)
#        ifndef FEE_PAGE_SIZE
#            define FEE_PAGE_SIZE 0x800  // Page size = 2KByte
#        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(STM32F042x6)
#        define FEE_MCU_FLASH_SIZE 32  // Size in Kb
#    elif defined(STM32F103xB) || defined(STM32F072xB)
#        define FEE_MCU_FLASH_SIZE 128  // Size in Kb
#    elif defined(STM32F303xC)
#        define FEE_MCU_FLASH_SIZE 256  // Size in Kb
#    elif defined(STM32F103xE)
#        define FEE_MCU_FLASH_SIZE 512  // Size in Kb
#    endif
#endif

/* Start of the emulated eeprom */
#if !defined(FEE_PAGE_BASE_ADDRESS)
#    if 0
/* TODO: Add support for F4 */
#    else
#        ifndef FEE_FLASH_BASE
#            define FEE_FLASH_BASE 0x8000000
#        endif
/* Default to end of flash */
#        define FEE_PAGE_BASE_ADDRESS ((uintptr_t)(FEE_FLASH_BASE) + FEE_MCU_FLASH_SIZE * 1024 - (FEE_PAGE_COUNT * FEE_PAGE_SIZE))
#    endif
#endif

M tmk_core/common/test/eeprom_stm32_tests.cpp => tmk_core/common/test/eeprom_stm32_tests.cpp +1 -1
@@ 46,7 46,7 @@ extern "C" {
 *
 */

#define EEPROM_SIZE (FEE_PAGE_SIZE * FEE_DENSITY_PAGES / 2)
#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)

A tmk_core/common/test/hal.h => tmk_core/common/test/hal.h +18 -0
@@ 0,0 1,18 @@
/* Copyright 2021 QMK
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#pragma once

// Just here to please eeprom tests

M tmk_core/common/test/rules.mk => tmk_core/common/test/rules.mk +2 -2
@@ 3,12 3,12 @@ eeprom_stm32_tiny_DEFS := $(eeprom_stm32_DEFS) \
	-DFEE_MCU_FLASH_SIZE=1 \
	-DMOCK_FLASH_SIZE=1024 \
	-DFEE_PAGE_SIZE=512 \
	-DFEE_DENSITY_PAGES=1
	-DFEE_PAGE_COUNT=1
eeprom_stm32_large_DEFS := $(eeprom_stm32_DEFS) \
	-DFEE_MCU_FLASH_SIZE=64 \
	-DMOCK_FLASH_SIZE=65536 \
	-DFEE_PAGE_SIZE=2048 \
	-DFEE_DENSITY_PAGES=16
	-DFEE_PAGE_COUNT=16

eeprom_stm32_INC := \
	$(TMK_PATH)/common/chibios/