diff --git a/common_features.mk b/common_features.mk index 26eaf4829b..5ec5c2e96c 100644 --- a/common_features.mk +++ b/common_features.mk @@ -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 diff --git a/tmk_core/common/chibios/eeprom_stm32.c b/tmk_core/common/chibios/eeprom_stm32.c index 2b0c78f714..056f886c6f 100644 --- a/tmk_core/common/chibios/eeprom_stm32.c +++ b/tmk_core/common/chibios/eeprom_stm32.c @@ -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(); diff --git a/tmk_core/common/chibios/eeprom_stm32.h b/tmk_core/common/chibios/eeprom_stm32.h index 4fefd29f30..4a15ee7cc2 100644 --- a/tmk_core/common/chibios/eeprom_stm32.h +++ b/tmk_core/common/chibios/eeprom_stm32.h @@ -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 */ diff --git a/tmk_core/common/chibios/flash_stm32.c b/tmk_core/common/chibios/flash_stm32.c index e8b3dc4bc9..0bead21039 100644 --- a/tmk_core/common/chibios/flash_stm32.c +++ b/tmk_core/common/chibios/flash_stm32.c @@ -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; diff --git a/tmk_core/common/chibios/flash_stm32.h b/tmk_core/common/chibios/flash_stm32.h index 90d5bff47e..f50507f3a5 100644 --- a/tmk_core/common/chibios/flash_stm32.h +++ b/tmk_core/common/chibios/flash_stm32.h @@ -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 #include