Implement F4 eeprom (#14195)

This commit is contained in:
Joel Challis 2021-09-15 16:30:26 +01:00 committed by GitHub
parent 6cb8a65884
commit 1a68feb842
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 230 additions and 6 deletions

View file

@ -177,8 +177,14 @@ else
SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c
SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c
OPT_DEFS += -DEEPROM_EMU_STM32F072xB OPT_DEFS += -DEEPROM_EMU_STM32F072xB
else ifneq ($(filter $(MCU_SERIES)_$(MCU_LDSCRIPT),STM32F4xx_STM32F401xC STM32F4xx_STM32F411xE),)
OPT_DEFS += -DEEPROM_DRIVER
COMMON_VPATH += $(DRIVER_PATH)/eeprom
SRC += eeprom_driver.c
SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c
SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c
OPT_DEFS += -DEEPROM_EMU_STM32F401xC
else ifeq ($(MCU_SERIES)_$(MCU_LDSCRIPT), STM32F0xx_STM32F042x6) else ifeq ($(MCU_SERIES)_$(MCU_LDSCRIPT), STM32F0xx_STM32F042x6)
# Stack sizes: Since this chip has limited RAM capacity, the stack area needs to be reduced. # Stack sizes: Since this chip has limited RAM capacity, the stack area needs to be reduced.
# This ensures that the EEPROM page buffer fits into RAM # This ensures that the EEPROM page buffer fits into RAM
USE_PROCESS_STACKSIZE = 0x600 USE_PROCESS_STACKSIZE = 0x600

View file

@ -0,0 +1,85 @@
/*
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* STM32F401xC memory setup.
*/
MEMORY
{
flash0 (rx) : org = 0x08000000, len = 16k /* Sector 0 - Init code as ROM bootloader assumes application starts here */
flash1 (rx) : org = 0x08004000, len = 16k /* Sector 1 - Emulated eeprom */
flash2 (rx) : org = 0x08008000, len = 256k - 32k /* Sector 2..6 - Rest of firmware */
flash3 (rx) : org = 0x00000000, len = 0
flash4 (rx) : org = 0x00000000, len = 0
flash5 (rx) : org = 0x00000000, len = 0
flash6 (rx) : org = 0x00000000, len = 0
flash7 (rx) : org = 0x00000000, len = 0
ram0 (wx) : org = 0x20000000, len = 64k
ram1 (wx) : org = 0x00000000, len = 0
ram2 (wx) : org = 0x00000000, len = 0
ram3 (wx) : org = 0x00000000, len = 0
ram4 (wx) : org = 0x00000000, len = 0
ram5 (wx) : org = 0x00000000, len = 0
ram6 (wx) : org = 0x00000000, len = 0
ram7 (wx) : org = 0x00000000, len = 0
}
/* For each data/text section two region are defined, a virtual region
and a load region (_LMA suffix).*/
/* Flash region to be used for exception vectors.*/
REGION_ALIAS("VECTORS_FLASH", flash0);
REGION_ALIAS("VECTORS_FLASH_LMA", flash0);
/* Flash region to be used for constructors and destructors.*/
REGION_ALIAS("XTORS_FLASH", flash2);
REGION_ALIAS("XTORS_FLASH_LMA", flash2);
/* Flash region to be used for code text.*/
REGION_ALIAS("TEXT_FLASH", flash2);
REGION_ALIAS("TEXT_FLASH_LMA", flash2);
/* Flash region to be used for read only data.*/
REGION_ALIAS("RODATA_FLASH", flash2);
REGION_ALIAS("RODATA_FLASH_LMA", flash2);
/* Flash region to be used for various.*/
REGION_ALIAS("VARIOUS_FLASH", flash2);
REGION_ALIAS("VARIOUS_FLASH_LMA", flash2);
/* Flash region to be used for RAM(n) initialization data.*/
REGION_ALIAS("RAM_INIT_FLASH_LMA", flash2);
/* RAM region to be used for Main stack. This stack accommodates the processing
of all exceptions and interrupts.*/
REGION_ALIAS("MAIN_STACK_RAM", ram0);
/* RAM region to be used for the process stack. This is the stack used by
the main() function.*/
REGION_ALIAS("PROCESS_STACK_RAM", ram0);
/* RAM region to be used for data segment.*/
REGION_ALIAS("DATA_RAM", ram0);
REGION_ALIAS("DATA_RAM_LMA", flash2);
/* RAM region to be used for BSS segment.*/
REGION_ALIAS("BSS_RAM", ram0);
/* RAM region to be used for the default heap.*/
REGION_ALIAS("HEAP_RAM", ram0);
/* Generic rules inclusion.*/
INCLUDE rules.ld

View file

@ -0,0 +1,85 @@
/*
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* STM32F411xE memory setup.
*/
MEMORY
{
flash0 (rx) : org = 0x08000000, len = 16k /* Sector 0 - Init code as ROM bootloader assumes application starts here */
flash1 (rx) : org = 0x08004000, len = 16k /* Sector 1 - Emulated eeprom */
flash2 (rx) : org = 0x08008000, len = 512k - 32k /* Sector 2..7 - Rest of firmware */
flash3 (rx) : org = 0x00000000, len = 0
flash4 (rx) : org = 0x00000000, len = 0
flash5 (rx) : org = 0x00000000, len = 0
flash6 (rx) : org = 0x00000000, len = 0
flash7 (rx) : org = 0x00000000, len = 0
ram0 (wx) : org = 0x20000000, len = 128k
ram1 (wx) : org = 0x00000000, len = 0
ram2 (wx) : org = 0x00000000, len = 0
ram3 (wx) : org = 0x00000000, len = 0
ram4 (wx) : org = 0x00000000, len = 0
ram5 (wx) : org = 0x00000000, len = 0
ram6 (wx) : org = 0x00000000, len = 0
ram7 (wx) : org = 0x00000000, len = 0
}
/* For each data/text section two region are defined, a virtual region
and a load region (_LMA suffix).*/
/* Flash region to be used for exception vectors.*/
REGION_ALIAS("VECTORS_FLASH", flash0);
REGION_ALIAS("VECTORS_FLASH_LMA", flash0);
/* Flash region to be used for constructors and destructors.*/
REGION_ALIAS("XTORS_FLASH", flash2);
REGION_ALIAS("XTORS_FLASH_LMA", flash2);
/* Flash region to be used for code text.*/
REGION_ALIAS("TEXT_FLASH", flash2);
REGION_ALIAS("TEXT_FLASH_LMA", flash2);
/* Flash region to be used for read only data.*/
REGION_ALIAS("RODATA_FLASH", flash2);
REGION_ALIAS("RODATA_FLASH_LMA", flash2);
/* Flash region to be used for various.*/
REGION_ALIAS("VARIOUS_FLASH", flash2);
REGION_ALIAS("VARIOUS_FLASH_LMA", flash2);
/* Flash region to be used for RAM(n) initialization data.*/
REGION_ALIAS("RAM_INIT_FLASH_LMA", flash2);
/* RAM region to be used for Main stack. This stack accommodates the processing
of all exceptions and interrupts.*/
REGION_ALIAS("MAIN_STACK_RAM", ram0);
/* RAM region to be used for the process stack. This is the stack used by
the main() function.*/
REGION_ALIAS("PROCESS_STACK_RAM", ram0);
/* RAM region to be used for data segment.*/
REGION_ALIAS("DATA_RAM", ram0);
REGION_ALIAS("DATA_RAM_LMA", flash2);
/* RAM region to be used for BSS segment.*/
REGION_ALIAS("BSS_RAM", ram0);
/* RAM region to be used for the default heap.*/
REGION_ALIAS("HEAP_RAM", ram0);
/* Generic rules inclusion.*/
INCLUDE rules.ld

View file

@ -32,6 +32,13 @@
# ifndef FEE_PAGE_COUNT # ifndef FEE_PAGE_COUNT
# define FEE_PAGE_COUNT 4 // How many pages are used # define FEE_PAGE_COUNT 4 // How many pages are used
# endif # endif
# elif defined(STM32F401xC) || defined(STM32F411xE)
# ifndef FEE_PAGE_SIZE
# define FEE_PAGE_SIZE 0x4000 // Page size = 16KByte
# endif
# ifndef FEE_PAGE_COUNT
# define FEE_PAGE_COUNT 1 // How many pages are used
# endif
# endif # endif
#endif #endif
@ -40,17 +47,19 @@
# define FEE_MCU_FLASH_SIZE 32 // Size in Kb # define FEE_MCU_FLASH_SIZE 32 // Size in Kb
# elif defined(STM32F103xB) || defined(STM32F072xB) || defined(STM32F070xB) # elif defined(STM32F103xB) || defined(STM32F072xB) || defined(STM32F070xB)
# define FEE_MCU_FLASH_SIZE 128 // Size in Kb # define FEE_MCU_FLASH_SIZE 128 // Size in Kb
# elif defined(STM32F303xC) # elif defined(STM32F303xC) || defined(STM32F401xC)
# define FEE_MCU_FLASH_SIZE 256 // Size in Kb # define FEE_MCU_FLASH_SIZE 256 // Size in Kb
# elif defined(STM32F103xE) # elif defined(STM32F103xE) || defined(STM32F411xE)
# define FEE_MCU_FLASH_SIZE 512 // Size in Kb # define FEE_MCU_FLASH_SIZE 512 // Size in Kb
# endif # endif
#endif #endif
/* Start of the emulated eeprom */ /* Start of the emulated eeprom */
#if !defined(FEE_PAGE_BASE_ADDRESS) #if !defined(FEE_PAGE_BASE_ADDRESS)
# if 0 # if defined(STM32F401xC) || defined(STM32F411xE)
/* TODO: Add support for F4 */ # ifndef FEE_PAGE_BASE_ADDRESS
# define FEE_PAGE_BASE_ADDRESS 0x08004000 // bodge to force 2nd 16k page
# endif
# else # else
# ifndef FEE_FLASH_BASE # ifndef FEE_FLASH_BASE
# define FEE_FLASH_BASE 0x8000000 # define FEE_FLASH_BASE 0x8000000

View file

@ -23,6 +23,29 @@
# define FLASH_SR_WRPERR FLASH_SR_WRPRTERR # define FLASH_SR_WRPERR FLASH_SR_WRPRTERR
#endif #endif
#if defined(EEPROM_EMU_STM32F401xC)
# define FLASH_SR_PGERR (FLASH_SR_PGSERR | FLASH_SR_PGPERR | FLASH_SR_PGAERR)
# define FLASH_KEY1 0x45670123U
# define FLASH_KEY2 0xCDEF89ABU
static uint8_t ADDR2PAGE(uint32_t Page_Address) {
switch (Page_Address) {
case 0x08000000 ... 0x08003FFF:
return 0;
case 0x08004000 ... 0x08007FFF:
return 1;
case 0x08008000 ... 0x0800BFFF:
return 2;
case 0x0800C000 ... 0x0800FFFF:
return 3;
}
// TODO: bad times...
return 7;
}
#endif
/* Delay definition */ /* Delay definition */
#define EraseTimeout ((uint32_t)0x00000FFF) #define EraseTimeout ((uint32_t)0x00000FFF)
#define ProgramTimeout ((uint32_t)0x0000001F) #define ProgramTimeout ((uint32_t)0x0000001F)
@ -53,7 +76,9 @@ FLASH_Status FLASH_GetStatus(void) {
if ((FLASH->SR & FLASH_SR_WRPERR) != 0) return FLASH_ERROR_WRP; if ((FLASH->SR & FLASH_SR_WRPERR) != 0) return FLASH_ERROR_WRP;
#if defined(FLASH_OBR_OPTERR)
if ((FLASH->SR & FLASH_OBR_OPTERR) != 0) return FLASH_ERROR_OPT; if ((FLASH->SR & FLASH_OBR_OPTERR) != 0) return FLASH_ERROR_OPT;
#endif
return FLASH_COMPLETE; return FLASH_COMPLETE;
} }
@ -95,15 +120,24 @@ FLASH_Status FLASH_ErasePage(uint32_t Page_Address) {
if (status == FLASH_COMPLETE) { if (status == FLASH_COMPLETE) {
/* if the previous operation is completed, proceed to erase the page */ /* if the previous operation is completed, proceed to erase the page */
#if defined(FLASH_CR_SNB)
FLASH->CR &= ~FLASH_CR_SNB;
FLASH->CR |= FLASH_CR_SER | (ADDR2PAGE(Page_Address) << FLASH_CR_SNB_Pos);
#else
FLASH->CR |= FLASH_CR_PER; FLASH->CR |= FLASH_CR_PER;
FLASH->AR = Page_Address; FLASH->AR = Page_Address;
#endif
FLASH->CR |= FLASH_CR_STRT; FLASH->CR |= FLASH_CR_STRT;
/* Wait for last operation to be completed */ /* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(EraseTimeout); status = FLASH_WaitForLastOperation(EraseTimeout);
if (status != FLASH_TIMEOUT) { if (status != FLASH_TIMEOUT) {
/* if the erase operation is completed, disable the PER Bit */ /* if the erase operation is completed, disable the configured Bits */
#if defined(FLASH_CR_SNB)
FLASH->CR &= ~(FLASH_CR_SER | FLASH_CR_SNB);
#else
FLASH->CR &= ~FLASH_CR_PER; FLASH->CR &= ~FLASH_CR_PER;
#endif
} }
FLASH->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR); FLASH->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR);
} }
@ -126,6 +160,11 @@ FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) {
status = FLASH_WaitForLastOperation(ProgramTimeout); status = FLASH_WaitForLastOperation(ProgramTimeout);
if (status == FLASH_COMPLETE) { if (status == FLASH_COMPLETE) {
/* if the previous operation is completed, proceed to program the new data */ /* if the previous operation is completed, proceed to program the new data */
#if defined(FLASH_CR_PSIZE)
FLASH->CR &= ~FLASH_CR_PSIZE;
FLASH->CR |= FLASH_CR_PSIZE_0;
#endif
FLASH->CR |= FLASH_CR_PG; FLASH->CR |= FLASH_CR_PG;
*(__IO uint16_t*)Address = Data; *(__IO uint16_t*)Address = Data;
/* Wait for last operation to be completed */ /* Wait for last operation to be completed */