Skip to content

Commit

Permalink
eeprom_stm32: add stm32f4 series support
Browse files Browse the repository at this point in the history
based on code by @yulei in qmk/qmk_firmware#7803
  • Loading branch information
xyzz committed Jul 12, 2021
1 parent 5acac22 commit a22cb46
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 25 deletions.
5 changes: 5 additions & 0 deletions common_features.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions tmk_core/common/chibios/eeprom_stm32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
12 changes: 10 additions & 2 deletions tmk_core/common/chibios/eeprom_stm32.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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)\
Expand All @@ -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)\
Expand All @@ -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 */
Expand Down
60 changes: 37 additions & 23 deletions tmk_core/common/chibios/flash_stm32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
Expand All @@ -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 */
Expand All @@ -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;
Expand Down
20 changes: 20 additions & 0 deletions tmk_core/common/chibios/flash_stm32.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down

2 comments on commit a22cb46

@yulei
Copy link
Contributor

@yulei yulei commented on a22cb46 Jul 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, I'm start to switch all my boards to vial-qmk, could I submit vial supported codes to this reposity?

@xyzz
Copy link
Contributor Author

@xyzz xyzz commented on a22cb46 Jul 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, just wait for 0.4 release first (that's when it will be merged into the main vial branch).

Please sign in to comment.