Skip to content

Commit b4eeea8

Browse files
zvecrptrxyz
authored andcommitted
Implement F4 eeprom (qmk#14195)
1 parent a8c6498 commit b4eeea8

File tree

5 files changed

+230
-6
lines changed

5 files changed

+230
-6
lines changed

common_features.mk

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,14 @@ else
177177
SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c
178178
SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c
179179
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
180187
else ifeq ($(MCU_SERIES)_$(MCU_LDSCRIPT), STM32F0xx_STM32F042x6)
181-
182188
# Stack sizes: Since this chip has limited RAM capacity, the stack area needs to be reduced.
183189
# This ensures that the EEPROM page buffer fits into RAM
184190
USE_PROCESS_STACKSIZE = 0x600
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

tmk_core/common/chibios/eeprom_stm32_defs.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@
3232
# ifndef FEE_PAGE_COUNT
3333
# define FEE_PAGE_COUNT 4 // How many pages are used
3434
# 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
3542
# endif
3643
#endif
3744

@@ -40,17 +47,19 @@
4047
# define FEE_MCU_FLASH_SIZE 32 // Size in Kb
4148
# elif defined(STM32F103xB) || defined(STM32F072xB) || defined(STM32F070xB)
4249
# define FEE_MCU_FLASH_SIZE 128 // Size in Kb
43-
# elif defined(STM32F303xC)
50+
# elif defined(STM32F303xC) || defined(STM32F401xC)
4451
# define FEE_MCU_FLASH_SIZE 256 // Size in Kb
45-
# elif defined(STM32F103xE)
52+
# elif defined(STM32F103xE) || defined(STM32F411xE)
4653
# define FEE_MCU_FLASH_SIZE 512 // Size in Kb
4754
# endif
4855
#endif
4956

5057
/* Start of the emulated eeprom */
5158
#if !defined(FEE_PAGE_BASE_ADDRESS)
52-
# if 0
53-
/* TODO: Add support for F4 */
59+
# if defined(STM32F401xC) || defined(STM32F411xE)
60+
# ifndef FEE_PAGE_BASE_ADDRESS
61+
# define FEE_PAGE_BASE_ADDRESS 0x08004000 // bodge to force 2nd 16k page
62+
# endif
5463
# else
5564
# ifndef FEE_FLASH_BASE
5665
# define FEE_FLASH_BASE 0x8000000

tmk_core/common/chibios/flash_stm32.c

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,29 @@
2323
# define FLASH_SR_WRPERR FLASH_SR_WRPRTERR
2424
#endif
2525

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+
2649
/* Delay definition */
2750
#define EraseTimeout ((uint32_t)0x00000FFF)
2851
#define ProgramTimeout ((uint32_t)0x0000001F)
@@ -53,7 +76,9 @@ FLASH_Status FLASH_GetStatus(void) {
5376

5477
if ((FLASH->SR & FLASH_SR_WRPERR) != 0) return FLASH_ERROR_WRP;
5578

79+
#if defined(FLASH_OBR_OPTERR)
5680
if ((FLASH->SR & FLASH_OBR_OPTERR) != 0) return FLASH_ERROR_OPT;
81+
#endif
5782

5883
return FLASH_COMPLETE;
5984
}
@@ -95,15 +120,24 @@ FLASH_Status FLASH_ErasePage(uint32_t Page_Address) {
95120

96121
if (status == FLASH_COMPLETE) {
97122
/* 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
98127
FLASH->CR |= FLASH_CR_PER;
99128
FLASH->AR = Page_Address;
129+
#endif
100130
FLASH->CR |= FLASH_CR_STRT;
101131

102132
/* Wait for last operation to be completed */
103133
status = FLASH_WaitForLastOperation(EraseTimeout);
104134
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
106139
FLASH->CR &= ~FLASH_CR_PER;
140+
#endif
107141
}
108142
FLASH->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR);
109143
}
@@ -126,6 +160,11 @@ FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) {
126160
status = FLASH_WaitForLastOperation(ProgramTimeout);
127161
if (status == FLASH_COMPLETE) {
128162
/* 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
129168
FLASH->CR |= FLASH_CR_PG;
130169
*(__IO uint16_t*)Address = Data;
131170
/* Wait for last operation to be completed */

0 commit comments

Comments
 (0)