eeprom_stm32: implement denser emulation, default to 4k
This commit is contained in:
parent
cdf16e79a3
commit
ae1d581ca7
@ -22,6 +22,10 @@
|
||||
#include "dynamic_keymap.h"
|
||||
#include "via.h" // for default VIA_EEPROM_ADDR_END
|
||||
|
||||
#ifdef STM32_EEPROM_ENABLE
|
||||
# include "eeprom_stm32.h"
|
||||
#endif
|
||||
|
||||
#ifdef VIAL_ENABLE
|
||||
#include "vial.h"
|
||||
#endif
|
||||
@ -41,6 +45,8 @@
|
||||
# define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR 4095
|
||||
# elif defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega16U4__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATtiny85__)
|
||||
# define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR 511
|
||||
# elif defined(FEE_DENSITY_BYTES)
|
||||
# define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR FEE_DENSITY_BYTES-1
|
||||
# else
|
||||
# define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR 1023
|
||||
# endif
|
||||
|
@ -21,18 +21,24 @@
|
||||
#include <string.h>
|
||||
#include "eeprom_stm32.h"
|
||||
|
||||
/* In-memory contents of emulated eeprom for faster access */
|
||||
#define SNAPSHOT_START (FEE_BASE_ADDRESS)
|
||||
#define SNAPSHOT_END (FEE_BASE_ADDRESS+FEE_SNAPSHOT_SIZE)
|
||||
#define WRITELOG_START (SNAPSHOT_END)
|
||||
#define WRITELOG_END (WRITELOG_START+FEE_WRITELOG_SIZE)
|
||||
|
||||
/* In-memory contents of emulated eeprom for direct faster access */
|
||||
static uint8_t DataBuf[FEE_DENSITY_BYTES];
|
||||
|
||||
/* Pointer to the first available slot within flash area */
|
||||
/* Pointer to the first available slot within the writelog */
|
||||
static uint8_t *empty_slot;
|
||||
|
||||
void EEPROM_Init(void) {
|
||||
memset(DataBuf, 0, sizeof(DataBuf));
|
||||
/* First, load the snapshot directly from flash */
|
||||
memcpy(DataBuf, (void*)FEE_BASE_ADDRESS, FEE_SNAPSHOT_SIZE);
|
||||
|
||||
/* Load emulated eeprom contents from flash into memory */
|
||||
/* Then, process writelog to update DataBuf entries */
|
||||
uint8_t *addr;
|
||||
for (addr = (uint8_t*)FEE_PAGE_BASE_ADDRESS; addr < (uint8_t*)FEE_LAST_PAGE_ADDRESS; addr += 4) {
|
||||
for (addr = (uint8_t*)WRITELOG_START; addr < (uint8_t*)WRITELOG_END; addr += 4) {
|
||||
uint16_t address;
|
||||
uint8_t value;
|
||||
memcpy(&address, addr, sizeof(address));
|
||||
@ -46,16 +52,16 @@ void EEPROM_Init(void) {
|
||||
empty_slot = addr;
|
||||
}
|
||||
|
||||
/* Clear flash contents (doesn't touch in-memory DataBuf) */
|
||||
/* Erase flash contents so we can put updated data in (doesn't touch in-memory DataBuf) */
|
||||
static void eeprom_clear(void) {
|
||||
FLASH_Unlock();
|
||||
|
||||
for (uint32_t page_num = 0; page_num < FEE_DENSITY_PAGES; ++page_num)
|
||||
FLASH_ErasePage(FEE_PAGE_BASE_ADDRESS + (page_num * FEE_PAGE_SIZE));
|
||||
for (uint32_t erase_address = SNAPSHOT_START; erase_address < WRITELOG_END; erase_address += FEE_PAGE_SIZE)
|
||||
FLASH_ErasePage(erase_address);
|
||||
|
||||
FLASH_Lock();
|
||||
|
||||
empty_slot = (void*)FEE_PAGE_BASE_ADDRESS;
|
||||
empty_slot = (void*)WRITELOG_START;
|
||||
}
|
||||
|
||||
/* Erase emulated eeprom */
|
||||
@ -67,29 +73,28 @@ void EEPROM_Erase(void) {
|
||||
|
||||
static void eeprom_writedatabyte(uint16_t Address, uint8_t DataByte);
|
||||
|
||||
/* Dump in-memory contents into flash */
|
||||
static void eeprom_restore(void) {
|
||||
for (uint32_t i = 0; i < FEE_DENSITY_BYTES; ++i) {
|
||||
/* don't bother writing zeroes */
|
||||
if (DataBuf[i]) {
|
||||
eeprom_writedatabyte(i, DataBuf[i]);
|
||||
}
|
||||
/* Dump in-memory eeprom contents into the snapshot area */
|
||||
static void eeprom_write_snapshot(void) {
|
||||
FLASH_Unlock();
|
||||
|
||||
for (uint32_t i = 0; i < FEE_DENSITY_BYTES; i += 2) {
|
||||
uint16_t halfword;
|
||||
memcpy(&halfword, &DataBuf[i], sizeof(halfword));
|
||||
|
||||
FLASH_ProgramHalfWord(SNAPSHOT_START + i, halfword);
|
||||
}
|
||||
|
||||
FLASH_Lock();
|
||||
}
|
||||
|
||||
static void eeprom_writedatabyte(uint16_t Address, uint8_t DataByte) {
|
||||
/* if couldn't find an empty spot, we must re-initialize emulated eeprom */
|
||||
if (empty_slot >= (uint8_t*)FEE_LAST_PAGE_ADDRESS) {
|
||||
/* ensure that the following call to eeprom_restore will write our desired byte value */
|
||||
DataBuf[Address] = DataByte;
|
||||
|
||||
if (empty_slot >= (uint8_t*)WRITELOG_END) {
|
||||
/* fully erase emulated eeprom */
|
||||
eeprom_clear();
|
||||
|
||||
/* and then write DataBuf contents back into flash */
|
||||
eeprom_restore();
|
||||
|
||||
/* don't need to do anything else as eeprom_restore already wrote our value */
|
||||
eeprom_write_snapshot();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -106,7 +111,7 @@ static void eeprom_writedatabyte(uint16_t Address, uint8_t DataByte) {
|
||||
empty_slot += 4;
|
||||
}
|
||||
|
||||
void EEPROM_WriteDataByte(uint16_t Address, uint8_t DataByte) {
|
||||
static void EEPROM_WriteDataByte(uint16_t Address, uint8_t DataByte) {
|
||||
/* if the address is out-of-bounds, do nothing */
|
||||
if (Address >= FEE_DENSITY_BYTES)
|
||||
return;
|
||||
@ -115,14 +120,14 @@ void EEPROM_WriteDataByte(uint16_t Address, uint8_t DataByte) {
|
||||
if (DataBuf[Address] == DataByte)
|
||||
return;
|
||||
|
||||
/* perform the write into flash memory */
|
||||
eeprom_writedatabyte(Address, DataByte);
|
||||
|
||||
/* keep DataBuf cache in sync */
|
||||
DataBuf[Address] = DataByte;
|
||||
|
||||
/* perform the write into flash memory */
|
||||
eeprom_writedatabyte(Address, DataByte);
|
||||
}
|
||||
|
||||
uint8_t EEPROM_ReadDataByte(uint16_t Address) {
|
||||
static uint8_t EEPROM_ReadDataByte(uint16_t Address) {
|
||||
uint8_t DataByte = 0x00;
|
||||
|
||||
if (Address < FEE_DENSITY_BYTES)
|
||||
|
@ -37,11 +37,10 @@
|
||||
# define MCU_STM32F072CB
|
||||
#elif defined(EEPROM_EMU_STM32F042x6)
|
||||
# define MCU_STM32F042K6
|
||||
#else
|
||||
# error "not implemented."
|
||||
#endif
|
||||
|
||||
#ifndef EEPROM_PAGE_SIZE
|
||||
/* The page_size * density_pages should provide 8k of space, split 4k/4k between snapshot and writelog in the default config */
|
||||
#ifndef FEE_DENSITY_PAGES
|
||||
# if defined(MCU_STM32F103RB) || defined(MCU_STM32F042K6)
|
||||
# define FEE_PAGE_SIZE (uint16_t)0x400 // Page size = 1KByte
|
||||
# define FEE_DENSITY_PAGES 8 // How many pages are used
|
||||
@ -49,11 +48,13 @@
|
||||
# define FEE_PAGE_SIZE (uint16_t)0x800 // Page size = 2KByte
|
||||
# define FEE_DENSITY_PAGES 4 // How many pages are used
|
||||
# else
|
||||
# error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)."
|
||||
# error "No MCU type specified and FEE_DENSITY_PAGES not defined.\
|
||||
Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)\
|
||||
or define FEE_DENSITY_PAGES yourself."
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef EEPROM_START_ADDRESS
|
||||
#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)
|
||||
@ -65,23 +66,32 @@
|
||||
# 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)."
|
||||
# error "No MCU type specified and FEE_MCU_FLASH_SIZE not defined.\
|
||||
Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)\
|
||||
or define FEE_MCU_FLASH_SIZE yourself."
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Start of the emulated eeprom flash area */
|
||||
#define FEE_PAGE_BASE_ADDRESS ((uint32_t)(0x8000000 + FEE_MCU_FLASH_SIZE * 1024 - FEE_DENSITY_PAGES * FEE_PAGE_SIZE))
|
||||
/* End of the emulated eeprom flash area */
|
||||
#define FEE_LAST_PAGE_ADDRESS (FEE_PAGE_BASE_ADDRESS + (FEE_PAGE_SIZE * FEE_DENSITY_PAGES))
|
||||
/* Size of emulated eeprom */
|
||||
#define FEE_DENSITY_BYTES 1024
|
||||
#ifndef FEE_BASE_ADDRESS
|
||||
/* Start of the emulated eeprom flash area, place it at the end of the flash memory */
|
||||
#define FEE_BASE_ADDRESS ((uint32_t)(0x8000000 + FEE_MCU_FLASH_SIZE * 1024 - FEE_DENSITY_PAGES * FEE_PAGE_SIZE))
|
||||
#endif
|
||||
|
||||
#ifndef FEE_SNAPSHOT_SIZE
|
||||
/* Size of eeprom snapshot, in bytes. This is equal to emulated eeprom size. */
|
||||
#define FEE_SNAPSHOT_SIZE 4096
|
||||
#endif
|
||||
|
||||
#ifndef FEE_WRITELOG_SIZE
|
||||
/* Size of eeprom writelog, in bytes */
|
||||
#define FEE_WRITELOG_SIZE 4096
|
||||
#endif
|
||||
|
||||
/* Flash word value after erase */
|
||||
#define FEE_EMPTY_WORD ((uint16_t)0xFFFF)
|
||||
|
||||
_Static_assert(FEE_DENSITY_PAGES * FEE_PAGE_SIZE >= FEE_DENSITY_BYTES * 8,
|
||||
"flash memory for emulated eeprom is too small; for correct functionality ensure it is at least 8x FEE_DENSITY_BYTES");
|
||||
/* Size of emulated eeprom */
|
||||
#define FEE_DENSITY_BYTES FEE_SNAPSHOT_SIZE
|
||||
|
||||
void EEPROM_Init(void);
|
||||
void EEPROM_Erase(void);
|
||||
void EEPROM_WriteDataByte(uint16_t Address, uint8_t DataByte);
|
||||
uint8_t EEPROM_ReadDataByte(uint16_t Address);
|
||||
|
Loading…
Reference in New Issue
Block a user