2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
25 #include "drivers/system.h"
27 #include "config/config_streamer.h"
30 extern uint8_t __config_start
; // configured via linker script when building binaries.
31 extern uint8_t __config_end
;
34 // @todo this is not strictly correct for F4/F7, where sector sizes are variable
35 #if !defined(FLASH_PAGE_SIZE)
37 # if defined(STM32F10X_MD)
38 # define FLASH_PAGE_SIZE (0x400)
39 # elif defined(STM32F10X_HD)
40 # define FLASH_PAGE_SIZE (0x800)
42 # elif defined(STM32F303xC)
43 # define FLASH_PAGE_SIZE (0x800)
45 # elif defined(STM32F40_41xxx)
46 # define FLASH_PAGE_SIZE ((uint32_t)0x4000) // 16K sectors
47 # elif defined (STM32F411xE)
48 # define FLASH_PAGE_SIZE ((uint32_t)0x4000)
49 # elif defined(STM32F427_437xx)
50 # define FLASH_PAGE_SIZE ((uint32_t)0x4000)
51 # elif defined (STM32F446xx)
52 # define FLASH_PAGE_SIZE ((uint32_t)0x4000)
54 #elif defined(STM32F722xx)
55 # define FLASH_PAGE_SIZE ((uint32_t)0x4000) // 16K sectors
56 # elif defined(STM32F745xx)
57 # define FLASH_PAGE_SIZE ((uint32_t)0x8000) // 32K sectors
58 # elif defined(STM32F746xx)
59 # define FLASH_PAGE_SIZE ((uint32_t)0x8000)
60 # elif defined(STM32F765xx)
61 # define FLASH_PAGE_SIZE ((uint32_t)0x8000)
62 # elif defined(UNIT_TEST)
63 # define FLASH_PAGE_SIZE (0x400)
65 # elif defined(SIMULATOR_BUILD)
66 # define FLASH_PAGE_SIZE (0x400)
68 # error "Flash page size not defined for target."
72 void config_streamer_init(config_streamer_t
*c
)
74 memset(c
, 0, sizeof(*c
));
77 void config_streamer_start(config_streamer_t
*c
, uintptr_t base
, int size
)
79 // base must start at FLASH_PAGE_SIZE boundary
91 #if defined(STM32F10X)
92 FLASH_ClearFlag(FLASH_FLAG_EOP
| FLASH_FLAG_PGERR
| FLASH_FLAG_WRPRTERR
);
93 #elif defined(STM32F303)
94 FLASH_ClearFlag(FLASH_FLAG_EOP
| FLASH_FLAG_PGERR
| FLASH_FLAG_WRPERR
);
95 #elif defined(STM32F4)
96 FLASH_ClearFlag(FLASH_FLAG_EOP
| FLASH_FLAG_OPERR
| FLASH_FLAG_WRPERR
| FLASH_FLAG_PGAERR
| FLASH_FLAG_PGPERR
| FLASH_FLAG_PGSERR
);
97 #elif defined(STM32F7)
99 #elif defined(UNIT_TEST) || defined(SIMULATOR_BUILD)
102 # error "Unsupported CPU"
107 #if defined(STM32F745xx) || defined(STM32F746xx) || defined(STM32F765xx)
109 Sector 0 0x08000000 - 0x08007FFF 32 Kbytes
110 Sector 1 0x08008000 - 0x0800FFFF 32 Kbytes
111 Sector 2 0x08010000 - 0x08017FFF 32 Kbytes
112 Sector 3 0x08018000 - 0x0801FFFF 32 Kbytes
113 Sector 4 0x08020000 - 0x0803FFFF 128 Kbytes
114 Sector 5 0x08040000 - 0x0807FFFF 256 Kbytes
115 Sector 6 0x08080000 - 0x080BFFFF 256 Kbytes
116 Sector 7 0x080C0000 - 0x080FFFFF 256 Kbytes
118 F7X5XI device with 2M flash
119 Sector 8 0x08100000 - 0x0813FFFF 256 Kbytes
120 Sector 9 0x08140000 - 0x0817FFFF 256 Kbytes
121 Sector 10 0x08180000 - 0x081BFFFF 256 Kbytes
122 Sector 11 0x081C0000 - 0x081FFFFF 256 Kbytes
125 static uint32_t getFLASHSectorForEEPROM(void)
127 if ((uint32_t)&__config_start
<= 0x08007FFF)
128 return FLASH_SECTOR_0
;
129 if ((uint32_t)&__config_start
<= 0x0800FFFF)
130 return FLASH_SECTOR_1
;
131 if ((uint32_t)&__config_start
<= 0x08017FFF)
132 return FLASH_SECTOR_2
;
133 if ((uint32_t)&__config_start
<= 0x0801FFFF)
134 return FLASH_SECTOR_3
;
135 if ((uint32_t)&__config_start
<= 0x0803FFFF)
136 return FLASH_SECTOR_4
;
137 if ((uint32_t)&__config_start
<= 0x0807FFFF)
138 return FLASH_SECTOR_5
;
139 if ((uint32_t)&__config_start
<= 0x080BFFFF)
140 return FLASH_SECTOR_6
;
141 if ((uint32_t)&__config_start
<= 0x080FFFFF)
142 return FLASH_SECTOR_7
;
143 #if defined(STM32F765xx)
144 if ((uint32_t)&__config_start
<= 0x0813FFFF)
145 return FLASH_SECTOR_8
;
146 if ((uint32_t)&__config_start
<= 0x0817FFFF)
147 return FLASH_SECTOR_9
;
148 if ((uint32_t)&__config_start
<= 0x081BFFFF)
149 return FLASH_SECTOR_10
;
150 if ((uint32_t)&__config_start
<= 0x081FFFFF)
151 return FLASH_SECTOR_11
;
156 failureMode(FAILURE_FLASH_WRITE_FAILED
);
160 #elif defined(STM32F722xx)
162 Sector 0 0x08000000 - 0x08003FFF 16 Kbytes
163 Sector 1 0x08004000 - 0x08007FFF 16 Kbytes
164 Sector 2 0x08008000 - 0x0800BFFF 16 Kbytes
165 Sector 3 0x0800C000 - 0x0800FFFF 16 Kbytes
166 Sector 4 0x08010000 - 0x0801FFFF 64 Kbytes
167 Sector 5 0x08020000 - 0x0803FFFF 128 Kbytes
168 Sector 6 0x08040000 - 0x0805FFFF 128 Kbytes
169 Sector 7 0x08060000 - 0x0807FFFF 128 Kbytes
172 static uint32_t getFLASHSectorForEEPROM(void)
174 if ((uint32_t)&__config_start
<= 0x08003FFF)
175 return FLASH_SECTOR_0
;
176 if ((uint32_t)&__config_start
<= 0x08007FFF)
177 return FLASH_SECTOR_1
;
178 if ((uint32_t)&__config_start
<= 0x0800BFFF)
179 return FLASH_SECTOR_2
;
180 if ((uint32_t)&__config_start
<= 0x0800FFFF)
181 return FLASH_SECTOR_3
;
182 if ((uint32_t)&__config_start
<= 0x0801FFFF)
183 return FLASH_SECTOR_4
;
184 if ((uint32_t)&__config_start
<= 0x0803FFFF)
185 return FLASH_SECTOR_5
;
186 if ((uint32_t)&__config_start
<= 0x0805FFFF)
187 return FLASH_SECTOR_6
;
188 if ((uint32_t)&__config_start
<= 0x0807FFFF)
189 return FLASH_SECTOR_7
;
193 failureMode(FAILURE_FLASH_WRITE_FAILED
);
197 #elif defined(STM32F4)
199 Sector 0 0x08000000 - 0x08003FFF 16 Kbytes
200 Sector 1 0x08004000 - 0x08007FFF 16 Kbytes
201 Sector 2 0x08008000 - 0x0800BFFF 16 Kbytes
202 Sector 3 0x0800C000 - 0x0800FFFF 16 Kbytes
203 Sector 4 0x08010000 - 0x0801FFFF 64 Kbytes
204 Sector 5 0x08020000 - 0x0803FFFF 128 Kbytes
205 Sector 6 0x08040000 - 0x0805FFFF 128 Kbytes
206 Sector 7 0x08060000 - 0x0807FFFF 128 Kbytes
207 Sector 8 0x08080000 - 0x0809FFFF 128 Kbytes
208 Sector 9 0x080A0000 - 0x080BFFFF 128 Kbytes
209 Sector 10 0x080C0000 - 0x080DFFFF 128 Kbytes
210 Sector 11 0x080E0000 - 0x080FFFFF 128 Kbytes
213 static uint32_t getFLASHSectorForEEPROM(void)
215 if ((uint32_t)&__config_start
<= 0x08003FFF)
216 return FLASH_Sector_0
;
217 if ((uint32_t)&__config_start
<= 0x08007FFF)
218 return FLASH_Sector_1
;
219 if ((uint32_t)&__config_start
<= 0x0800BFFF)
220 return FLASH_Sector_2
;
221 if ((uint32_t)&__config_start
<= 0x0800FFFF)
222 return FLASH_Sector_3
;
223 if ((uint32_t)&__config_start
<= 0x0801FFFF)
224 return FLASH_Sector_4
;
225 if ((uint32_t)&__config_start
<= 0x0803FFFF)
226 return FLASH_Sector_5
;
227 if ((uint32_t)&__config_start
<= 0x0805FFFF)
228 return FLASH_Sector_6
;
229 if ((uint32_t)&__config_start
<= 0x0807FFFF)
230 return FLASH_Sector_7
;
231 if ((uint32_t)&__config_start
<= 0x0809FFFF)
232 return FLASH_Sector_8
;
233 if ((uint32_t)&__config_start
<= 0x080DFFFF)
234 return FLASH_Sector_9
;
235 if ((uint32_t)&__config_start
<= 0x080BFFFF)
236 return FLASH_Sector_10
;
237 if ((uint32_t)&__config_start
<= 0x080FFFFF)
238 return FLASH_Sector_11
;
242 failureMode(FAILURE_FLASH_WRITE_FAILED
);
247 static int write_word(config_streamer_t
*c
, uint32_t value
)
253 if (c
->address
% FLASH_PAGE_SIZE
== 0) {
254 FLASH_EraseInitTypeDef EraseInitStruct
= {
255 .TypeErase
= FLASH_TYPEERASE_SECTORS
,
256 .VoltageRange
= FLASH_VOLTAGE_RANGE_3
, // 2.7-3.6V
259 EraseInitStruct
.Sector
= getFLASHSectorForEEPROM();
260 uint32_t SECTORError
;
261 const HAL_StatusTypeDef status
= HAL_FLASHEx_Erase(&EraseInitStruct
, &SECTORError
);
262 if (status
!= HAL_OK
) {
266 const HAL_StatusTypeDef status
= HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD
, c
->address
, value
);
267 if (status
!= HAL_OK
) {
271 if (c
->address
% FLASH_PAGE_SIZE
== 0) {
273 const FLASH_Status status
= FLASH_EraseSector(getFLASHSectorForEEPROM(), VoltageRange_3
); //0x08080000 to 0x080A0000
275 const FLASH_Status status
= FLASH_ErasePage(c
->address
);
277 if (status
!= FLASH_COMPLETE
) {
281 const FLASH_Status status
= FLASH_ProgramWord(c
->address
, value
);
282 if (status
!= FLASH_COMPLETE
) {
286 c
->address
+= sizeof(value
);
290 int config_streamer_write(config_streamer_t
*c
, const uint8_t *p
, uint32_t size
)
292 for (const uint8_t *pat
= p
; pat
!= (uint8_t*)p
+ size
; pat
++) {
293 c
->buffer
.b
[c
->at
++] = *pat
;
295 if (c
->at
== sizeof(c
->buffer
)) {
296 c
->err
= write_word(c
, c
->buffer
.w
);
303 int config_streamer_status(config_streamer_t
*c
)
308 int config_streamer_flush(config_streamer_t
*c
)
311 memset(c
->buffer
.b
+ c
->at
, 0, sizeof(c
->buffer
) - c
->at
);
312 c
->err
= write_word(c
, c
->buffer
.w
);
318 int config_streamer_finish(config_streamer_t
*c
)