diff options
| author | Joel Challis <git@zvecr.com> | 2021-09-15 16:30:26 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-09-15 16:30:26 +0100 |
| commit | 1a68feb842ebcc6a7d1aef7cd7f83865cc18fab1 (patch) | |
| tree | 4e792c29ce0587486d325c55fa3fb76cba6e1ede | |
| parent | 6cb8a658847b90f1633b4b331bd72bbc39e69132 (diff) | |
| download | qmk_firmware-1a68feb842ebcc6a7d1aef7cd7f83865cc18fab1.tar.gz qmk_firmware-1a68feb842ebcc6a7d1aef7cd7f83865cc18fab1.zip | |
Implement F4 eeprom (#14195)
| -rw-r--r-- | common_features.mk | 8 | ||||
| -rw-r--r-- | platforms/chibios/boards/common/ld/STM32F401xC.ld | 85 | ||||
| -rw-r--r-- | platforms/chibios/boards/common/ld/STM32F411xE.ld | 85 | ||||
| -rw-r--r-- | tmk_core/common/chibios/eeprom_stm32_defs.h | 17 | ||||
| -rw-r--r-- | tmk_core/common/chibios/flash_stm32.c | 41 |
5 files changed, 230 insertions, 6 deletions
diff --git a/common_features.mk b/common_features.mk index ddb7112fd..2cd78ceb6 100644 --- a/common_features.mk +++ b/common_features.mk | |||
| @@ -177,8 +177,14 @@ else | |||
| 177 | SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c | 177 | SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c |
| 178 | SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c | 178 | SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c |
| 179 | OPT_DEFS += -DEEPROM_EMU_STM32F072xB | 179 | OPT_DEFS += -DEEPROM_EMU_STM32F072xB |
| 180 | else ifneq ($(filter $(MCU_SERIES)_$(MCU_LDSCRIPT),STM32F4xx_STM32F401xC STM32F4xx_STM32F411xE),) | ||
| 181 | OPT_DEFS += -DEEPROM_DRIVER | ||
| 182 | COMMON_VPATH += $(DRIVER_PATH)/eeprom | ||
| 183 | SRC += eeprom_driver.c | ||
| 184 | SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c | ||
| 185 | SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c | ||
| 186 | OPT_DEFS += -DEEPROM_EMU_STM32F401xC | ||
| 180 | else ifeq ($(MCU_SERIES)_$(MCU_LDSCRIPT), STM32F0xx_STM32F042x6) | 187 | else ifeq ($(MCU_SERIES)_$(MCU_LDSCRIPT), STM32F0xx_STM32F042x6) |
| 181 | |||
| 182 | # Stack sizes: Since this chip has limited RAM capacity, the stack area needs to be reduced. | 188 | # Stack sizes: Since this chip has limited RAM capacity, the stack area needs to be reduced. |
| 183 | # This ensures that the EEPROM page buffer fits into RAM | 189 | # This ensures that the EEPROM page buffer fits into RAM |
| 184 | USE_PROCESS_STACKSIZE = 0x600 | 190 | USE_PROCESS_STACKSIZE = 0x600 |
diff --git a/platforms/chibios/boards/common/ld/STM32F401xC.ld b/platforms/chibios/boards/common/ld/STM32F401xC.ld new file mode 100644 index 000000000..8fae66cec --- /dev/null +++ b/platforms/chibios/boards/common/ld/STM32F401xC.ld | |||
| @@ -0,0 +1,85 @@ | |||
| 1 | /* | ||
| 2 | ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio | ||
| 3 | |||
| 4 | Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | you may not use this file except in compliance with the License. | ||
| 6 | You may obtain a copy of the License at | ||
| 7 | |||
| 8 | http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | |||
| 10 | Unless required by applicable law or agreed to in writing, software | ||
| 11 | distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | See the License for the specific language governing permissions and | ||
| 14 | limitations under the License. | ||
| 15 | */ | ||
| 16 | |||
| 17 | /* | ||
| 18 | * STM32F401xC memory setup. | ||
| 19 | */ | ||
| 20 | MEMORY | ||
| 21 | { | ||
| 22 | flash0 (rx) : org = 0x08000000, len = 16k /* Sector 0 - Init code as ROM bootloader assumes application starts here */ | ||
| 23 | flash1 (rx) : org = 0x08004000, len = 16k /* Sector 1 - Emulated eeprom */ | ||
| 24 | flash2 (rx) : org = 0x08008000, len = 256k - 32k /* Sector 2..6 - Rest of firmware */ | ||
| 25 | flash3 (rx) : org = 0x00000000, len = 0 | ||
| 26 | flash4 (rx) : org = 0x00000000, len = 0 | ||
| 27 | flash5 (rx) : org = 0x00000000, len = 0 | ||
| 28 | flash6 (rx) : org = 0x00000000, len = 0 | ||
| 29 | flash7 (rx) : org = 0x00000000, len = 0 | ||
| 30 | ram0 (wx) : org = 0x20000000, len = 64k | ||
| 31 | ram1 (wx) : org = 0x00000000, len = 0 | ||
| 32 | ram2 (wx) : org = 0x00000000, len = 0 | ||
| 33 | ram3 (wx) : org = 0x00000000, len = 0 | ||
| 34 | ram4 (wx) : org = 0x00000000, len = 0 | ||
| 35 | ram5 (wx) : org = 0x00000000, len = 0 | ||
| 36 | ram6 (wx) : org = 0x00000000, len = 0 | ||
| 37 | ram7 (wx) : org = 0x00000000, len = 0 | ||
| 38 | } | ||
| 39 | |||
| 40 | /* For each data/text section two region are defined, a virtual region | ||
| 41 | and a load region (_LMA suffix).*/ | ||
| 42 | |||
| 43 | /* Flash region to be used for exception vectors.*/ | ||
| 44 | REGION_ALIAS("VECTORS_FLASH", flash0); | ||
| 45 | REGION_ALIAS("VECTORS_FLASH_LMA", flash0); | ||
| 46 | |||
| 47 | /* Flash region to be used for constructors and destructors.*/ | ||
| 48 | REGION_ALIAS("XTORS_FLASH", flash2); | ||
| 49 | REGION_ALIAS("XTORS_FLASH_LMA", flash2); | ||
| 50 | |||
| 51 | /* Flash region to be used for code text.*/ | ||
| 52 | REGION_ALIAS("TEXT_FLASH", flash2); | ||
| 53 | REGION_ALIAS("TEXT_FLASH_LMA", flash2); | ||
| 54 | |||
| 55 | /* Flash region to be used for read only data.*/ | ||
| 56 | REGION_ALIAS("RODATA_FLASH", flash2); | ||
| 57 | REGION_ALIAS("RODATA_FLASH_LMA", flash2); | ||
| 58 | |||
| 59 | /* Flash region to be used for various.*/ | ||
| 60 | REGION_ALIAS("VARIOUS_FLASH", flash2); | ||
| 61 | REGION_ALIAS("VARIOUS_FLASH_LMA", flash2); | ||
| 62 | |||
| 63 | /* Flash region to be used for RAM(n) initialization data.*/ | ||
| 64 | REGION_ALIAS("RAM_INIT_FLASH_LMA", flash2); | ||
| 65 | |||
| 66 | /* RAM region to be used for Main stack. This stack accommodates the processing | ||
| 67 | of all exceptions and interrupts.*/ | ||
| 68 | REGION_ALIAS("MAIN_STACK_RAM", ram0); | ||
| 69 | |||
| 70 | /* RAM region to be used for the process stack. This is the stack used by | ||
| 71 | the main() function.*/ | ||
| 72 | REGION_ALIAS("PROCESS_STACK_RAM", ram0); | ||
| 73 | |||
| 74 | /* RAM region to be used for data segment.*/ | ||
| 75 | REGION_ALIAS("DATA_RAM", ram0); | ||
| 76 | REGION_ALIAS("DATA_RAM_LMA", flash2); | ||
| 77 | |||
| 78 | /* RAM region to be used for BSS segment.*/ | ||
| 79 | REGION_ALIAS("BSS_RAM", ram0); | ||
| 80 | |||
| 81 | /* RAM region to be used for the default heap.*/ | ||
| 82 | REGION_ALIAS("HEAP_RAM", ram0); | ||
| 83 | |||
| 84 | /* Generic rules inclusion.*/ | ||
| 85 | INCLUDE rules.ld | ||
diff --git a/platforms/chibios/boards/common/ld/STM32F411xE.ld b/platforms/chibios/boards/common/ld/STM32F411xE.ld new file mode 100644 index 000000000..aea8084b5 --- /dev/null +++ b/platforms/chibios/boards/common/ld/STM32F411xE.ld | |||
| @@ -0,0 +1,85 @@ | |||
| 1 | /* | ||
| 2 | ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio | ||
| 3 | |||
| 4 | Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | you may not use this file except in compliance with the License. | ||
| 6 | You may obtain a copy of the License at | ||
| 7 | |||
| 8 | http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | |||
| 10 | Unless required by applicable law or agreed to in writing, software | ||
| 11 | distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | See the License for the specific language governing permissions and | ||
| 14 | limitations under the License. | ||
| 15 | */ | ||
| 16 | |||
| 17 | /* | ||
| 18 | * STM32F411xE memory setup. | ||
| 19 | */ | ||
| 20 | MEMORY | ||
| 21 | { | ||
| 22 | flash0 (rx) : org = 0x08000000, len = 16k /* Sector 0 - Init code as ROM bootloader assumes application starts here */ | ||
| 23 | flash1 (rx) : org = 0x08004000, len = 16k /* Sector 1 - Emulated eeprom */ | ||
| 24 | flash2 (rx) : org = 0x08008000, len = 512k - 32k /* Sector 2..7 - Rest of firmware */ | ||
| 25 | flash3 (rx) : org = 0x00000000, len = 0 | ||
| 26 | flash4 (rx) : org = 0x00000000, len = 0 | ||
| 27 | flash5 (rx) : org = 0x00000000, len = 0 | ||
| 28 | flash6 (rx) : org = 0x00000000, len = 0 | ||
| 29 | flash7 (rx) : org = 0x00000000, len = 0 | ||
| 30 | ram0 (wx) : org = 0x20000000, len = 128k | ||
| 31 | ram1 (wx) : org = 0x00000000, len = 0 | ||
| 32 | ram2 (wx) : org = 0x00000000, len = 0 | ||
| 33 | ram3 (wx) : org = 0x00000000, len = 0 | ||
| 34 | ram4 (wx) : org = 0x00000000, len = 0 | ||
| 35 | ram5 (wx) : org = 0x00000000, len = 0 | ||
| 36 | ram6 (wx) : org = 0x00000000, len = 0 | ||
| 37 | ram7 (wx) : org = 0x00000000, len = 0 | ||
| 38 | } | ||
| 39 | |||
| 40 | /* For each data/text section two region are defined, a virtual region | ||
| 41 | and a load region (_LMA suffix).*/ | ||
| 42 | |||
| 43 | /* Flash region to be used for exception vectors.*/ | ||
| 44 | REGION_ALIAS("VECTORS_FLASH", flash0); | ||
| 45 | REGION_ALIAS("VECTORS_FLASH_LMA", flash0); | ||
| 46 | |||
| 47 | /* Flash region to be used for constructors and destructors.*/ | ||
| 48 | REGION_ALIAS("XTORS_FLASH", flash2); | ||
| 49 | REGION_ALIAS("XTORS_FLASH_LMA", flash2); | ||
| 50 | |||
| 51 | /* Flash region to be used for code text.*/ | ||
| 52 | REGION_ALIAS("TEXT_FLASH", flash2); | ||
| 53 | REGION_ALIAS("TEXT_FLASH_LMA", flash2); | ||
| 54 | |||
| 55 | /* Flash region to be used for read only data.*/ | ||
| 56 | REGION_ALIAS("RODATA_FLASH", flash2); | ||
| 57 | REGION_ALIAS("RODATA_FLASH_LMA", flash2); | ||
| 58 | |||
| 59 | /* Flash region to be used for various.*/ | ||
| 60 | REGION_ALIAS("VARIOUS_FLASH", flash2); | ||
| 61 | REGION_ALIAS("VARIOUS_FLASH_LMA", flash2); | ||
| 62 | |||
| 63 | /* Flash region to be used for RAM(n) initialization data.*/ | ||
| 64 | REGION_ALIAS("RAM_INIT_FLASH_LMA", flash2); | ||
| 65 | |||
| 66 | /* RAM region to be used for Main stack. This stack accommodates the processing | ||
| 67 | of all exceptions and interrupts.*/ | ||
| 68 | REGION_ALIAS("MAIN_STACK_RAM", ram0); | ||
| 69 | |||
| 70 | /* RAM region to be used for the process stack. This is the stack used by | ||
| 71 | the main() function.*/ | ||
| 72 | REGION_ALIAS("PROCESS_STACK_RAM", ram0); | ||
| 73 | |||
| 74 | /* RAM region to be used for data segment.*/ | ||
| 75 | REGION_ALIAS("DATA_RAM", ram0); | ||
| 76 | REGION_ALIAS("DATA_RAM_LMA", flash2); | ||
| 77 | |||
| 78 | /* RAM region to be used for BSS segment.*/ | ||
| 79 | REGION_ALIAS("BSS_RAM", ram0); | ||
| 80 | |||
| 81 | /* RAM region to be used for the default heap.*/ | ||
| 82 | REGION_ALIAS("HEAP_RAM", ram0); | ||
| 83 | |||
| 84 | /* Generic rules inclusion.*/ | ||
| 85 | INCLUDE rules.ld | ||
diff --git a/tmk_core/common/chibios/eeprom_stm32_defs.h b/tmk_core/common/chibios/eeprom_stm32_defs.h index 22b4ab858..57de42c6b 100644 --- a/tmk_core/common/chibios/eeprom_stm32_defs.h +++ b/tmk_core/common/chibios/eeprom_stm32_defs.h | |||
| @@ -32,6 +32,13 @@ | |||
| 32 | # ifndef FEE_PAGE_COUNT | 32 | # ifndef FEE_PAGE_COUNT |
| 33 | # define FEE_PAGE_COUNT 4 // How many pages are used | 33 | # define FEE_PAGE_COUNT 4 // How many pages are used |
| 34 | # endif | 34 | # endif |
| 35 | # elif defined(STM32F401xC) || defined(STM32F411xE) | ||
| 36 | # ifndef FEE_PAGE_SIZE | ||
| 37 | # define FEE_PAGE_SIZE 0x4000 // Page size = 16KByte | ||
| 38 | # endif | ||
| 39 | # ifndef FEE_PAGE_COUNT | ||
| 40 | # define FEE_PAGE_COUNT 1 // How many pages are used | ||
| 41 | # endif | ||
| 35 | # endif | 42 | # endif |
| 36 | #endif | 43 | #endif |
| 37 | 44 | ||
| @@ -40,17 +47,19 @@ | |||
| 40 | # define FEE_MCU_FLASH_SIZE 32 // Size in Kb | 47 | # define FEE_MCU_FLASH_SIZE 32 // Size in Kb |
| 41 | # elif defined(STM32F103xB) || defined(STM32F072xB) || defined(STM32F070xB) | 48 | # elif defined(STM32F103xB) || defined(STM32F072xB) || defined(STM32F070xB) |
| 42 | # define FEE_MCU_FLASH_SIZE 128 // Size in Kb | 49 | # define FEE_MCU_FLASH_SIZE 128 // Size in Kb |
| 43 | # elif defined(STM32F303xC) | 50 | # elif defined(STM32F303xC) || defined(STM32F401xC) |
| 44 | # define FEE_MCU_FLASH_SIZE 256 // Size in Kb | 51 | # define FEE_MCU_FLASH_SIZE 256 // Size in Kb |
| 45 | # elif defined(STM32F103xE) | 52 | # elif defined(STM32F103xE) || defined(STM32F411xE) |
| 46 | # define FEE_MCU_FLASH_SIZE 512 // Size in Kb | 53 | # define FEE_MCU_FLASH_SIZE 512 // Size in Kb |
| 47 | # endif | 54 | # endif |
| 48 | #endif | 55 | #endif |
| 49 | 56 | ||
| 50 | /* Start of the emulated eeprom */ | 57 | /* Start of the emulated eeprom */ |
| 51 | #if !defined(FEE_PAGE_BASE_ADDRESS) | 58 | #if !defined(FEE_PAGE_BASE_ADDRESS) |
| 52 | # if 0 | 59 | # if defined(STM32F401xC) || defined(STM32F411xE) |
| 53 | /* TODO: Add support for F4 */ | 60 | # ifndef FEE_PAGE_BASE_ADDRESS |
| 61 | # define FEE_PAGE_BASE_ADDRESS 0x08004000 // bodge to force 2nd 16k page | ||
| 62 | # endif | ||
| 54 | # else | 63 | # else |
| 55 | # ifndef FEE_FLASH_BASE | 64 | # ifndef FEE_FLASH_BASE |
| 56 | # define FEE_FLASH_BASE 0x8000000 | 65 | # define FEE_FLASH_BASE 0x8000000 |
diff --git a/tmk_core/common/chibios/flash_stm32.c b/tmk_core/common/chibios/flash_stm32.c index 6b80ff71c..8f10903d3 100644 --- a/tmk_core/common/chibios/flash_stm32.c +++ b/tmk_core/common/chibios/flash_stm32.c | |||
| @@ -23,6 +23,29 @@ | |||
| 23 | # define FLASH_SR_WRPERR FLASH_SR_WRPRTERR | 23 | # define FLASH_SR_WRPERR FLASH_SR_WRPRTERR |
| 24 | #endif | 24 | #endif |
| 25 | 25 | ||
| 26 | #if defined(EEPROM_EMU_STM32F401xC) | ||
| 27 | # define FLASH_SR_PGERR (FLASH_SR_PGSERR | FLASH_SR_PGPERR | FLASH_SR_PGAERR) | ||
| 28 | |||
| 29 | # define FLASH_KEY1 0x45670123U | ||
| 30 | # define FLASH_KEY2 0xCDEF89ABU | ||
| 31 | |||
| 32 | static uint8_t ADDR2PAGE(uint32_t Page_Address) { | ||
| 33 | switch (Page_Address) { | ||
| 34 | case 0x08000000 ... 0x08003FFF: | ||
| 35 | return 0; | ||
| 36 | case 0x08004000 ... 0x08007FFF: | ||
| 37 | return 1; | ||
| 38 | case 0x08008000 ... 0x0800BFFF: | ||
| 39 | return 2; | ||
| 40 | case 0x0800C000 ... 0x0800FFFF: | ||
| 41 | return 3; | ||
| 42 | } | ||
| 43 | |||
| 44 | // TODO: bad times... | ||
| 45 | return 7; | ||
| 46 | } | ||
| 47 | #endif | ||
| 48 | |||
| 26 | /* Delay definition */ | 49 | /* Delay definition */ |
| 27 | #define EraseTimeout ((uint32_t)0x00000FFF) | 50 | #define EraseTimeout ((uint32_t)0x00000FFF) |
| 28 | #define ProgramTimeout ((uint32_t)0x0000001F) | 51 | #define ProgramTimeout ((uint32_t)0x0000001F) |
| @@ -53,7 +76,9 @@ FLASH_Status FLASH_GetStatus(void) { | |||
| 53 | 76 | ||
| 54 | if ((FLASH->SR & FLASH_SR_WRPERR) != 0) return FLASH_ERROR_WRP; | 77 | if ((FLASH->SR & FLASH_SR_WRPERR) != 0) return FLASH_ERROR_WRP; |
| 55 | 78 | ||
| 79 | #if defined(FLASH_OBR_OPTERR) | ||
| 56 | if ((FLASH->SR & FLASH_OBR_OPTERR) != 0) return FLASH_ERROR_OPT; | 80 | if ((FLASH->SR & FLASH_OBR_OPTERR) != 0) return FLASH_ERROR_OPT; |
| 81 | #endif | ||
| 57 | 82 | ||
| 58 | return FLASH_COMPLETE; | 83 | return FLASH_COMPLETE; |
| 59 | } | 84 | } |
| @@ -95,15 +120,24 @@ FLASH_Status FLASH_ErasePage(uint32_t Page_Address) { | |||
| 95 | 120 | ||
| 96 | if (status == FLASH_COMPLETE) { | 121 | if (status == FLASH_COMPLETE) { |
| 97 | /* if the previous operation is completed, proceed to erase the page */ | 122 | /* if the previous operation is completed, proceed to erase the page */ |
| 123 | #if defined(FLASH_CR_SNB) | ||
| 124 | FLASH->CR &= ~FLASH_CR_SNB; | ||
| 125 | FLASH->CR |= FLASH_CR_SER | (ADDR2PAGE(Page_Address) << FLASH_CR_SNB_Pos); | ||
| 126 | #else | ||
| 98 | FLASH->CR |= FLASH_CR_PER; | 127 | FLASH->CR |= FLASH_CR_PER; |
| 99 | FLASH->AR = Page_Address; | 128 | FLASH->AR = Page_Address; |
| 129 | #endif | ||
| 100 | FLASH->CR |= FLASH_CR_STRT; | 130 | FLASH->CR |= FLASH_CR_STRT; |
| 101 | 131 | ||
| 102 | /* Wait for last operation to be completed */ | 132 | /* Wait for last operation to be completed */ |
| 103 | status = FLASH_WaitForLastOperation(EraseTimeout); | 133 | status = FLASH_WaitForLastOperation(EraseTimeout); |
| 104 | if (status != FLASH_TIMEOUT) { | 134 | if (status != FLASH_TIMEOUT) { |
| 105 | /* if the erase operation is completed, disable the PER Bit */ | 135 | /* if the erase operation is completed, disable the configured Bits */ |
| 136 | #if defined(FLASH_CR_SNB) | ||
| 137 | FLASH->CR &= ~(FLASH_CR_SER | FLASH_CR_SNB); | ||
| 138 | #else | ||
| 106 | FLASH->CR &= ~FLASH_CR_PER; | 139 | FLASH->CR &= ~FLASH_CR_PER; |
| 140 | #endif | ||
| 107 | } | 141 | } |
| 108 | FLASH->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR); | 142 | FLASH->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR); |
| 109 | } | 143 | } |
| @@ -126,6 +160,11 @@ FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) { | |||
| 126 | status = FLASH_WaitForLastOperation(ProgramTimeout); | 160 | status = FLASH_WaitForLastOperation(ProgramTimeout); |
| 127 | if (status == FLASH_COMPLETE) { | 161 | if (status == FLASH_COMPLETE) { |
| 128 | /* if the previous operation is completed, proceed to program the new data */ | 162 | /* if the previous operation is completed, proceed to program the new data */ |
| 163 | |||
| 164 | #if defined(FLASH_CR_PSIZE) | ||
| 165 | FLASH->CR &= ~FLASH_CR_PSIZE; | ||
| 166 | FLASH->CR |= FLASH_CR_PSIZE_0; | ||
| 167 | #endif | ||
| 129 | FLASH->CR |= FLASH_CR_PG; | 168 | FLASH->CR |= FLASH_CR_PG; |
| 130 | *(__IO uint16_t*)Address = Data; | 169 | *(__IO uint16_t*)Address = Data; |
| 131 | /* Wait for last operation to be completed */ | 170 | /* Wait for last operation to be completed */ |
