eeprom_stm32: add stm32f4 series support

based on code by @yulei in https://github.com/qmk/qmk_firmware/pull/7803
This commit is contained in:
Ilya Zhuravlev 2021-07-11 19:20:41 -04:00
parent ae1d581ca7
commit 1ba3126ae4
5 changed files with 76 additions and 25 deletions

View File

@ -171,6 +171,11 @@ else
OPT_DEFS += -DEEPROM_DRIVER
COMMON_VPATH += $(DRIVER_PATH)/eeprom
SRC += eeprom_driver.c eeprom_stm32_L0_L1.c
else ifeq ($(MCU_SERIES), STM32F4xx)
SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c
SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c
OPT_DEFS += -DEEPROM_EMU_STM32F411xC
OPT_DEFS += -DSTM32_EEPROM_ENABLE
else
# This will effectively work the same as "transient" if not supported by the chip
SRC += $(PLATFORM_COMMON_DIR)/eeprom_teensy.c

View File

@ -56,8 +56,12 @@ void EEPROM_Init(void) {
static void eeprom_clear(void) {
FLASH_Unlock();
#if defined(EEPROM_EMU_STM32F4)
FLASH_ErasePage(FEE_SECTOR_ID);
#else
for (uint32_t erase_address = SNAPSHOT_START; erase_address < WRITELOG_END; erase_address += FEE_PAGE_SIZE)
FLASH_ErasePage(erase_address);
#endif
FLASH_Lock();

View File

@ -37,6 +37,8 @@
# define MCU_STM32F072CB
#elif defined(EEPROM_EMU_STM32F042x6)
# define MCU_STM32F042K6
#elif defined(EEPROM_EMU_STM32F411xC)
# define MCU_STM32F411xC
#endif
/* The page_size * density_pages should provide 8k of space, split 4k/4k between snapshot and writelog in the default config */
@ -47,6 +49,10 @@
# elif defined(MCU_STM32F103ZE) || defined(MCU_STM32F103RE) || defined(MCU_STM32F103RD) || defined(MCU_STM32F303CC) || defined(MCU_STM32F072CB)
# define FEE_PAGE_SIZE (uint16_t)0x800 // Page size = 2KByte
# define FEE_DENSITY_PAGES 4 // How many pages are used
# elif defined(MCU_STM32F411xC)
# define FEE_PAGE_SIZE (uint32_t)0x20000 // Page size = 128KByte
# define FEE_DENSITY_PAGES 1 // How many pages are used
# define FEE_SECTOR_ID 5 // sector id of the flash
# else
# error "No MCU type specified and FEE_DENSITY_PAGES not defined.\
Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)\
@ -65,6 +71,8 @@ or define FEE_DENSITY_PAGES yourself."
# define FEE_MCU_FLASH_SIZE 384 // Size in Kb
# elif defined(MCU_STM32F303CC)
# define FEE_MCU_FLASH_SIZE 256 // Size in Kb
# elif defined(MCU_STM32F411xC)
# define FEE_MCU_FLASH_SIZE 256 // Size in Kb
# else
# 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)\
@ -83,8 +91,8 @@ or define FEE_MCU_FLASH_SIZE yourself."
#endif
#ifndef FEE_WRITELOG_SIZE
/* Size of eeprom writelog, in bytes */
#define FEE_WRITELOG_SIZE 4096
/* Size of eeprom writelog, in bytes. By default, use all the remaining amount of flash bank. */
#define FEE_WRITELOG_SIZE (FEE_DENSITY_PAGES * FEE_PAGE_SIZE - FEE_SNAPSHOT_SIZE)
#endif
/* Flash word value after erase */

View File

@ -16,28 +16,24 @@
* Modifications for QMK and STM32F303 by Yiancar
*/
#if defined(EEPROM_EMU_STM32F303xC)
# define STM32F303xC
# include "stm32f3xx.h"
#elif defined(EEPROM_EMU_STM32F103xB)
# define STM32F103xB
# include "stm32f1xx.h"
#elif defined(EEPROM_EMU_STM32F072xB)
# define STM32F072xB
# include "stm32f0xx.h"
#elif defined(EEPROM_EMU_STM32F042x6)
# define STM32F042x6
# include "stm32f0xx.h"
#else
# error "not implemented."
#endif
#include "flash_stm32.h"
#if defined(EEPROM_EMU_STM32F103xB)
# define FLASH_SR_WRPERR FLASH_SR_WRPRTERR
#endif
#if defined(EEPROM_EMU_STM32F4)
# define FLASH_PSIZE_HFWORD FLASH_CR_PSIZE_0
# define FLASH_PSIZE_WORD FLASH_CR_PSIZE_1
# define FLASH_CR_SNB_POS 3
/* the flash key was not defined in the CMSIS used by current chibios */
# define FLASH_KEY1 0x45670123
# define FLASH_KEY2 0xCDEF89AB
# define FLASH_SR_FLAGS (FLASH_SR_PGAERR|FLASH_SR_PGPERR|FLASH_SR_PGSERR|FLASH_SR_WRPERR)
#else
# define FLASH_SR_FLAGS (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR)
#endif
/* Delay definition */
#define EraseTimeout ((uint32_t)0x00000FFF)
#define ProgramTimeout ((uint32_t)0x0000001F)
@ -64,11 +60,14 @@ static void delay(void) {
FLASH_Status FLASH_GetStatus(void) {
if ((FLASH->SR & FLASH_SR_BSY) == FLASH_SR_BSY) return FLASH_BUSY;
#if defined(EEPROM_EMU_STM32F4)
if ((FLASH->SR & (FLASH_SR_PGSERR | FLASH_SR_PGPERR | FLASH_SR_PGAERR))) return FLASH_ERROR_PG;
if ((FLASH->SR & FLASH_SR_WRPERR)) return FLASH_ERROR_WRP;
#else
if ((FLASH->SR & FLASH_SR_PGERR) != 0) return FLASH_ERROR_PG;
if ((FLASH->SR & FLASH_SR_WRPERR) != 0) return FLASH_ERROR_WRP;
if ((FLASH->SR & FLASH_OBR_OPTERR) != 0) return FLASH_ERROR_OPT;
#endif
return FLASH_COMPLETE;
}
@ -97,30 +96,41 @@ FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout) {
/**
* @brief Erases a specified FLASH page.
* @param Page_Address: The page address to be erased.
* @param Page_Address: The page address or sector to be erased.
* @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
*/
FLASH_Status FLASH_ErasePage(uint32_t Page_Address) {
FLASH_Status status = FLASH_COMPLETE;
#ifndef EEPROM_EMU_STM32F4
/* Check the parameters */
ASSERT(IS_FLASH_ADDRESS(Page_Address));
#endif
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(EraseTimeout);
if (status == FLASH_COMPLETE) {
/* if the previous operation is completed, proceed to erase the page */
#if defined(EEPROM_EMU_STM32F4)
FLASH->CR &= ~FLASH_CR_SNB;
FLASH->CR |= FLASH_CR_SER | (Page_Address << FLASH_CR_SNB_POS);
#else
FLASH->CR |= FLASH_CR_PER;
FLASH->AR = Page_Address;
#endif
FLASH->CR |= FLASH_CR_STRT;
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(EraseTimeout);
if (status != FLASH_TIMEOUT) {
/* if the erase operation is completed, disable the PER Bit */
/* clear the SER or PER Bit */
#if defined(EEPROM_EMU_STM32F4)
FLASH->CR &= ~(FLASH_CR_SER | FLASH_CR_SNB);
#else
FLASH->CR &= ~FLASH_CR_PER;
#endif
}
FLASH->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR);
FLASH_ClearFlag(FLASH_SR_FLAGS);
}
/* Return the Erase Status */
return status;
@ -136,11 +146,15 @@ FLASH_Status FLASH_ErasePage(uint32_t Page_Address) {
FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) {
FLASH_Status status = FLASH_BAD_ADDRESS;
if (IS_FLASH_ADDRESS(Address)) {
if (IS_FLASH_ADDRESS(Address) && (Address % sizeof(Data)) == 0) {
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(ProgramTimeout);
if (status == FLASH_COMPLETE) {
/* if the previous operation is completed, proceed to program the new data */
#if defined(EEPROM_EMU_STM32F4)
FLASH->CR &= ~FLASH_CR_PSIZE;
FLASH->CR |= FLASH_PSIZE_HFWORD;
#endif
FLASH->CR |= FLASH_CR_PG;
*(__IO uint16_t*)Address = Data;
/* Wait for last operation to be completed */
@ -149,7 +163,7 @@ FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) {
/* if the program operation is completed, disable the PG Bit */
FLASH->CR &= ~FLASH_CR_PG;
}
FLASH->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR);
FLASH_ClearFlag(FLASH_SR_FLAGS);
}
}
return status;

View File

@ -22,6 +22,26 @@
extern "C" {
#endif
#if defined(EEPROM_EMU_STM32F303xC)
# define STM32F303xC
# include "stm32f3xx.h"
#elif defined(EEPROM_EMU_STM32F103xB)
# define STM32F103xB
# include "stm32f1xx.h"
#elif defined(EEPROM_EMU_STM32F072xB)
# define STM32F072xB
# include "stm32f0xx.h"
#elif defined(EEPROM_EMU_STM32F042x6)
# define STM32F042x6
# include "stm32f0xx.h"
#elif defined(EEPROM_EMU_STM32F411xC)
# define EEPROM_EMU_STM32F4
# define STM32F411xE
# include "stm32f4xx.h"
#else
# error "not implemented."
#endif
#include <ch.h>
#include <hal.h>