By default mark OSD element as rendered in case it's in the off blink state (#14188...
[betaflight.git] / src / platform / common / stm32 / config_flash.c
blobc94fb082b18984d228f2f94c46205da7ab5ea71a
1 /*
2 * This file is part of Betaflight.
4 * Betaflight is free software. You can redistribute this software
5 * and/or modify this software under the terms of the GNU General
6 * Public License as published by the Free Software Foundation,
7 * either version 3 of the License, or (at your option) any later
8 * version.
10 * Betaflight is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public
17 * License along with this software.
19 * If not, see <http://www.gnu.org/licenses/>.
22 #include <string.h>
24 #include "platform.h"
25 #include "drivers/system.h"
26 #include "config/config_streamer.h"
28 #if defined(CONFIG_IN_FLASH)
30 #if !defined(FLASH_PAGE_SIZE)
31 #error "Flash page size not defined for STM (or clone) target."
32 #endif
34 #if defined(STM32F745xx) || defined(STM32F746xx) || defined(STM32F765xx)
36 Sector 0 0x08000000 - 0x08007FFF 32 Kbytes
37 Sector 1 0x08008000 - 0x0800FFFF 32 Kbytes
38 Sector 2 0x08010000 - 0x08017FFF 32 Kbytes
39 Sector 3 0x08018000 - 0x0801FFFF 32 Kbytes
40 Sector 4 0x08020000 - 0x0803FFFF 128 Kbytes
41 Sector 5 0x08040000 - 0x0807FFFF 256 Kbytes
42 Sector 6 0x08080000 - 0x080BFFFF 256 Kbytes
43 Sector 7 0x080C0000 - 0x080FFFFF 256 Kbytes
45 F7X5XI device with 2M flash
46 Sector 8 0x08100000 - 0x0813FFFF 256 Kbytes
47 Sector 9 0x08140000 - 0x0817FFFF 256 Kbytes
48 Sector 10 0x08180000 - 0x081BFFFF 256 Kbytes
49 Sector 11 0x081C0000 - 0x081FFFFF 256 Kbytes
52 uint32_t getFLASHSectorForEEPROM(void)
54 if ((uint32_t)&__config_start <= 0x08007FFF)
55 return FLASH_SECTOR_0;
56 if ((uint32_t)&__config_start <= 0x0800FFFF)
57 return FLASH_SECTOR_1;
58 if ((uint32_t)&__config_start <= 0x08017FFF)
59 return FLASH_SECTOR_2;
60 if ((uint32_t)&__config_start <= 0x0801FFFF)
61 return FLASH_SECTOR_3;
62 if ((uint32_t)&__config_start <= 0x0803FFFF)
63 return FLASH_SECTOR_4;
64 if ((uint32_t)&__config_start <= 0x0807FFFF)
65 return FLASH_SECTOR_5;
66 if ((uint32_t)&__config_start <= 0x080BFFFF)
67 return FLASH_SECTOR_6;
68 if ((uint32_t)&__config_start <= 0x080FFFFF)
69 return FLASH_SECTOR_7;
70 #if defined(STM32F765xx)
71 if ((uint32_t)&__config_start <= 0x0813FFFF)
72 return FLASH_SECTOR_8;
73 if ((uint32_t)&__config_start <= 0x0817FFFF)
74 return FLASH_SECTOR_9;
75 if ((uint32_t)&__config_start <= 0x081BFFFF)
76 return FLASH_SECTOR_10;
77 if ((uint32_t)&__config_start <= 0x081FFFFF)
78 return FLASH_SECTOR_11;
79 #endif
81 // Not good
82 while (1) {
83 failureMode(FAILURE_CONFIG_STORE_FAILURE);
87 #elif defined(STM32F722xx)
89 Sector 0 0x08000000 - 0x08003FFF 16 Kbytes
90 Sector 1 0x08004000 - 0x08007FFF 16 Kbytes
91 Sector 2 0x08008000 - 0x0800BFFF 16 Kbytes
92 Sector 3 0x0800C000 - 0x0800FFFF 16 Kbytes
93 Sector 4 0x08010000 - 0x0801FFFF 64 Kbytes
94 Sector 5 0x08020000 - 0x0803FFFF 128 Kbytes
95 Sector 6 0x08040000 - 0x0805FFFF 128 Kbytes
96 Sector 7 0x08060000 - 0x0807FFFF 128 Kbytes
99 uint32_t getFLASHSectorForEEPROM(void)
101 if ((uint32_t)&__config_start <= 0x08003FFF)
102 return FLASH_SECTOR_0;
103 if ((uint32_t)&__config_start <= 0x08007FFF)
104 return FLASH_SECTOR_1;
105 if ((uint32_t)&__config_start <= 0x0800BFFF)
106 return FLASH_SECTOR_2;
107 if ((uint32_t)&__config_start <= 0x0800FFFF)
108 return FLASH_SECTOR_3;
109 if ((uint32_t)&__config_start <= 0x0801FFFF)
110 return FLASH_SECTOR_4;
111 if ((uint32_t)&__config_start <= 0x0803FFFF)
112 return FLASH_SECTOR_5;
113 if ((uint32_t)&__config_start <= 0x0805FFFF)
114 return FLASH_SECTOR_6;
115 if ((uint32_t)&__config_start <= 0x0807FFFF)
116 return FLASH_SECTOR_7;
118 // Not good
119 while (1) {
120 failureMode(FAILURE_CONFIG_STORE_FAILURE);
124 #elif defined(STM32F4)
126 Sector 0 0x08000000 - 0x08003FFF 16 Kbytes
127 Sector 1 0x08004000 - 0x08007FFF 16 Kbytes
128 Sector 2 0x08008000 - 0x0800BFFF 16 Kbytes
129 Sector 3 0x0800C000 - 0x0800FFFF 16 Kbytes
130 Sector 4 0x08010000 - 0x0801FFFF 64 Kbytes
131 Sector 5 0x08020000 - 0x0803FFFF 128 Kbytes
132 Sector 6 0x08040000 - 0x0805FFFF 128 Kbytes
133 Sector 7 0x08060000 - 0x0807FFFF 128 Kbytes
134 Sector 8 0x08080000 - 0x0809FFFF 128 Kbytes
135 Sector 9 0x080A0000 - 0x080BFFFF 128 Kbytes
136 Sector 10 0x080C0000 - 0x080DFFFF 128 Kbytes
137 Sector 11 0x080E0000 - 0x080FFFFF 128 Kbytes
140 uint32_t getFLASHSectorForEEPROM(void)
142 if ((uint32_t)&__config_start <= 0x08003FFF)
143 return FLASH_Sector_0;
144 if ((uint32_t)&__config_start <= 0x08007FFF)
145 return FLASH_Sector_1;
146 if ((uint32_t)&__config_start <= 0x0800BFFF)
147 return FLASH_Sector_2;
148 if ((uint32_t)&__config_start <= 0x0800FFFF)
149 return FLASH_Sector_3;
150 if ((uint32_t)&__config_start <= 0x0801FFFF)
151 return FLASH_Sector_4;
152 if ((uint32_t)&__config_start <= 0x0803FFFF)
153 return FLASH_Sector_5;
154 if ((uint32_t)&__config_start <= 0x0805FFFF)
155 return FLASH_Sector_6;
156 if ((uint32_t)&__config_start <= 0x0807FFFF)
157 return FLASH_Sector_7;
158 if ((uint32_t)&__config_start <= 0x0809FFFF)
159 return FLASH_Sector_8;
160 if ((uint32_t)&__config_start <= 0x080DFFFF)
161 return FLASH_Sector_9;
162 if ((uint32_t)&__config_start <= 0x080BFFFF)
163 return FLASH_Sector_10;
164 if ((uint32_t)&__config_start <= 0x080FFFFF)
165 return FLASH_Sector_11;
167 // Not good
168 while (1) {
169 failureMode(FAILURE_CONFIG_STORE_FAILURE);
173 #elif defined(STM32H743xx) || defined(STM32G4) || defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H723xx) || defined(STM32H725xx)
175 MCUs with uniform array of equal size sectors, handled in two banks having contiguous address.
176 (Devices with non-contiguous flash layout is not currently useful anyways.)
178 H743
179 2 bank * 8 sector/bank * 128K/sector (2MB)
180 Bank 1 0x08000000 - 0x080FFFFF 128KB * 8
181 Bank 2 0x08100000 - 0x081FFFFF 128KB * 8
183 H743
184 1 bank * 8 sector/bank * 128K/sector (1MB)
185 Bank 1 0x08000000 - 0x080FFFFF 128KB * 8
187 H7A3
188 2 bank * 128 sector/bank * 8KB/sector (2MB)
189 Bank 1 0x08000000 - 0x080FFFFF 8KB * 128
190 Bank 2 0x08100000 - 0x081FFFFF 8KB * 128
192 G473/474 in dual bank mode
193 2 bank * 128 sector/bank * 2KB/sector (512KB)
194 Bank 1 0x08000000 - 0x0803FFFF 2KB * 128
195 Bank 2 0x08040000 - 0x0807FFFF 2KB * 128
197 Note that FLASH_BANK_SIZE constant used in the following code changes depending on
198 bank operation mode. The code assumes dual bank operation, in which case the
199 FLASH_BANK_SIZE constant is set to one half of the available flash size in HAL.
202 #if defined(STM32H743xx) || defined(STM32H723xx) || defined(STM32H725xx)
203 #define FLASH_PAGE_PER_BANK 8
204 #elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ)
205 #define FLASH_PAGE_PER_BANK 128
206 #elif defined(STM32G4)
207 #define FLASH_PAGE_PER_BANK 128
208 // These are not defined in CMSIS like H7
209 #define FLASH_BANK1_BASE FLASH_BASE
210 #define FLASH_BANK2_BASE (FLASH_BANK1_BASE + FLASH_BANK_SIZE)
211 #endif
213 void getFLASHSectorForEEPROM(uint32_t address, uint32_t *bank, uint32_t *sector)
215 #if defined(FLASH_BANK2_BASE)
216 if (address >= FLASH_BANK1_BASE && address < FLASH_BANK2_BASE) {
217 *bank = FLASH_BANK_1;
218 } else if (address >= FLASH_BANK2_BASE && address < FLASH_BANK2_BASE + FLASH_BANK_SIZE) {
219 *bank = FLASH_BANK_2;
220 address -= FLASH_BANK_SIZE;
222 #else
223 if (address >= FLASH_BANK1_BASE && address < FLASH_BANK1_BASE + FLASH_BANK_SIZE) {
224 *bank = FLASH_BANK_1;
226 #endif
227 else {
228 // Not good
229 while (1) {
230 failureMode(FAILURE_CONFIG_STORE_FAILURE);
234 address -= FLASH_BANK1_BASE;
235 *sector = address / FLASH_PAGE_SIZE;
237 #elif defined(STM32H750xx)
239 The memory map supports 2 banks of 8 128k sectors like the H743xx, but there is only one 128K sector so we save some code
240 space by using a smaller function.
242 Bank 1
243 Sector 0 0x08000000 - 0x0801FFFF 128 Kbytes
247 void getFLASHSectorForEEPROM(uint32_t *bank, uint32_t *sector)
250 uint32_t start = (uint32_t)&__config_start;
252 if (start == FLASH_BANK1_BASE) {
253 *sector = FLASH_SECTOR_0;
254 *bank = FLASH_BANK_1;
255 } else {
256 // Not good
257 while (1) {
258 failureMode(FAILURE_CONFIG_STORE_FAILURE);
262 #elif defined(APM32F4)
264 Sector 0 0x08000000 - 0x08003FFF 16 Kbytes
265 Sector 1 0x08004000 - 0x08007FFF 16 Kbytes
266 Sector 2 0x08008000 - 0x0800BFFF 16 Kbytes
267 Sector 3 0x0800C000 - 0x0800FFFF 16 Kbytes
268 Sector 4 0x08010000 - 0x0801FFFF 64 Kbytes
269 Sector 5 0x08020000 - 0x0803FFFF 128 Kbytes
270 Sector 6 0x08040000 - 0x0805FFFF 128 Kbytes
271 Sector 7 0x08060000 - 0x0807FFFF 128 Kbytes
272 Sector 8 0x08080000 - 0x0809FFFF 128 Kbytes
273 Sector 9 0x080A0000 - 0x080BFFFF 128 Kbytes
274 Sector 10 0x080C0000 - 0x080DFFFF 128 Kbytes
275 Sector 11 0x080E0000 - 0x080FFFFF 128 Kbytes
278 uint32_t getFLASHSectorForEEPROM(void)
280 if ((uint32_t)&__config_start <= 0x08003FFF)
281 return FLASH_SECTOR_0;
282 if ((uint32_t)&__config_start <= 0x08007FFF)
283 return FLASH_SECTOR_1;
284 if ((uint32_t)&__config_start <= 0x0800BFFF)
285 return FLASH_SECTOR_2;
286 if ((uint32_t)&__config_start <= 0x0800FFFF)
287 return FLASH_SECTOR_3;
288 if ((uint32_t)&__config_start <= 0x0801FFFF)
289 return FLASH_SECTOR_4;
290 if ((uint32_t)&__config_start <= 0x0803FFFF)
291 return FLASH_SECTOR_5;
292 if ((uint32_t)&__config_start <= 0x0805FFFF)
293 return FLASH_SECTOR_6;
294 if ((uint32_t)&__config_start <= 0x0807FFFF)
295 return FLASH_SECTOR_7;
296 if ((uint32_t)&__config_start <= 0x0809FFFF)
297 return FLASH_SECTOR_8;
298 if ((uint32_t)&__config_start <= 0x080DFFFF)
299 return FLASH_SECTOR_9;
300 if ((uint32_t)&__config_start <= 0x080BFFFF)
301 return FLASH_SECTOR_10;
302 if ((uint32_t)&__config_start <= 0x080FFFFF)
303 return FLASH_SECTOR_11;
305 // Not good
306 while (1) {
307 failureMode(FAILURE_CONFIG_STORE_FAILURE);
310 #endif
312 void configUnlock(void)
314 #if defined(STM32F7) || defined(STM32H7) || defined(STM32G4)
315 HAL_FLASH_Unlock();
316 #elif defined(APM32F4)
317 DAL_FLASH_Unlock();
318 #elif defined(AT32F4)
319 flash_unlock();
320 #else
321 FLASH_Unlock();
322 #endif
325 void configLock(void)
327 #if defined(STM32F7) || defined(STM32H7) || defined(STM32G4)
328 HAL_FLASH_Lock();
329 #elif defined(AT32F4)
330 flash_lock();
331 #elif defined(APM32F4)
332 DAL_FLASH_Lock();
333 #else
334 FLASH_Lock();
335 #endif
338 void configClearFlags(void)
340 #if defined(STM32F4)
341 FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
342 #elif defined(STM32F7)
343 // NOP
344 #elif defined(STM32H7)
345 // NOP
346 #elif defined(STM32G4)
347 // NOP
348 #elif defined(AT32F4)
349 flash_flag_clear(FLASH_ODF_FLAG | FLASH_PRGMERR_FLAG | FLASH_EPPERR_FLAG);
350 #elif defined(APM32F4)
351 __DAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
352 #elif defined(UNIT_TEST) || defined(SIMULATOR_BUILD)
353 // NOP
354 #else
355 # error "Unsupported CPU"
356 #endif
359 configStreamerResult_e configWriteWord(uintptr_t address, config_streamer_buffer_type_t *buffer)
361 #if defined(STM32H7)
362 if (address % FLASH_PAGE_SIZE == 0) {
363 FLASH_EraseInitTypeDef EraseInitStruct = {
364 .TypeErase = FLASH_TYPEERASE_SECTORS,
365 #if !(defined(STM32H7A3xx) || defined(STM32H7A3xxQ))
366 .VoltageRange = FLASH_VOLTAGE_RANGE_3, // 2.7-3.6V
367 #endif
368 .NbSectors = 1
370 getFLASHSectorForEEPROM(address, &EraseInitStruct.Banks, &EraseInitStruct.Sector);
371 uint32_t SECTORError;
372 const HAL_StatusTypeDef status = HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError);
373 if (status != HAL_OK) {
374 return CONFIG_RESULT_FAILURE;
378 // For H7
379 // HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint32_t DataAddress);
380 STATIC_ASSERT(CONFIG_STREAMER_BUFFER_SIZE == sizeof(uint32_t) * FLASH_NB_32BITWORD_IN_FLASHWORD, "CONFIG_STREAMER_BUFFER_SIZE does not match written size");
381 const HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, address, (uint32_t)buffer);
382 if (status != HAL_OK) {
383 return CONFIG_RESULT_ADDRESS_INVALID;
385 #elif defined(STM32F7)
386 if (address % FLASH_PAGE_SIZE == 0) {
387 FLASH_EraseInitTypeDef EraseInitStruct = {
388 .TypeErase = FLASH_TYPEERASE_SECTORS,
389 .VoltageRange = FLASH_VOLTAGE_RANGE_3, // 2.7-3.6V
390 .NbSectors = 1
392 EraseInitStruct.Sector = getFLASHSectorForEEPROM();
393 uint32_t SECTORError;
394 const HAL_StatusTypeDef status = HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError);
395 if (status != HAL_OK) {
396 return CONFIG_RESULT_FAILURE;
400 STATIC_ASSERT(CONFIG_STREAMER_BUFFER_SIZE == sizeof(uint32_t), "CONFIG_STREAMER_BUFFER_SIZE does not match written size");
401 // For F7
402 // HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data);
403 const HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, *buffer);
404 if (status != HAL_OK) {
405 return CONFIG_RESULT_INCOMPLETE;
407 #elif defined(STM32G4)
408 if (address % FLASH_PAGE_SIZE == 0) {
410 FLASH_EraseInitTypeDef EraseInitStruct = {
411 .TypeErase = FLASH_TYPEERASE_PAGES,
412 .NbPages = 1
414 getFLASHSectorForEEPROM(address, &EraseInitStruct.Banks, &EraseInitStruct.Page);
415 uint32_t SECTORError;
416 const HAL_StatusTypeDef status = HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError);
417 if (status != HAL_OK) {
418 return CONFIG_RESULT_FAILURE;
422 STATIC_ASSERT(CONFIG_STREAMER_BUFFER_SIZE == sizeof(uint64_t), "CONFIG_STREAMER_BUFFER_SIZE does not match written size");
423 const HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, *buffer);
424 if (status != HAL_OK) {
425 return CONFIG_RESULT_ADDRESS_INVALID;
427 #elif defined(AT32F4)
428 if (address % FLASH_PAGE_SIZE == 0) {
429 const flash_status_type status = flash_sector_erase(address);
430 if (status != FLASH_OPERATE_DONE) {
431 return CONFIG_RESULT_FAILURE;
435 STATIC_ASSERT(CONFIG_STREAMER_BUFFER_SIZE == sizeof(uint32_t), "CONFIG_STREAMER_BUFFER_SIZE does not match written size");
436 const flash_status_type status = flash_word_program(address, *buffer);
437 if (status != FLASH_OPERATE_DONE) {
438 return CONFIG_RESULT_ADDRESS_INVALID;
440 #elif defined(APM32F4)
441 if (address % FLASH_PAGE_SIZE == 0) {
442 FLASH_EraseInitTypeDef EraseInitStruct = {
443 .TypeErase = FLASH_TYPEERASE_SECTORS,
444 .VoltageRange = FLASH_VOLTAGE_RANGE_3, // 2.7-3.6V
445 .NbSectors = 1
447 EraseInitStruct.Sector = getFLASHSectorForEEPROM();
448 uint32_t SECTORError;
449 const DAL_StatusTypeDef status = DAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError);
450 if (status != DAL_OK) {
451 return CONFIG_RESULT_FAILURE;
455 STATIC_ASSERT(CONFIG_STREAMER_BUFFER_SIZE == sizeof(uint32_t), "CONFIG_STREAMER_BUFFER_SIZE does not match written size");
456 const DAL_StatusTypeDef status = DAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, *buffer);
457 if (status != DAL_OK) {
458 return CONFIG_RESULT_ADDRESS_INVALID;
460 #elif defined(STM32F4)
461 if (address % FLASH_PAGE_SIZE == 0) {
462 const FLASH_Status status = FLASH_EraseSector(getFLASHSectorForEEPROM(), VoltageRange_3); //0x08080000 to 0x080A0000
463 if (status != FLASH_COMPLETE) {
464 return CONFIG_RESULT_FAILURE;
468 STATIC_ASSERT(CONFIG_STREAMER_BUFFER_SIZE == sizeof(uint32_t), "CONFIG_STREAMER_BUFFER_SIZE does not match written size");
469 const FLASH_Status status = FLASH_ProgramWord(address, *buffer);
470 if (status != FLASH_COMPLETE) {
471 return CONFIG_RESULT_ADDRESS_INVALID;
473 #else
474 #error "MCU not catered for in configWriteWord for config_streamer"
475 #endif
476 return CONFIG_RESULT_SUCCESS;
479 #endif // CONFIG_IN_FLASH