Added MSP for dterm filter 2 type.
[betaflight.git] / src / main / config / config_streamer.c
bloba47f1d4f9b83d6889ff118bb5773165ca8046066
1 /*
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)
8 * any later version.
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/>.
21 #include <string.h>
23 #include "platform.h"
25 #include "drivers/system.h"
27 #include "config/config_streamer.h"
29 #ifndef EEPROM_IN_RAM
30 extern uint8_t __config_start; // configured via linker script when building binaries.
31 extern uint8_t __config_end;
32 #endif
34 // @todo this is not strictly correct for F4/F7, where sector sizes are variable
35 #if !defined(FLASH_PAGE_SIZE)
36 // F1
37 # if defined(STM32F10X_MD)
38 # define FLASH_PAGE_SIZE (0x400)
39 # elif defined(STM32F10X_HD)
40 # define FLASH_PAGE_SIZE (0x800)
41 // F3
42 # elif defined(STM32F303xC)
43 # define FLASH_PAGE_SIZE (0x800)
44 // F4
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)
53 // F7
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)
64 // SIMULATOR
65 # elif defined(SIMULATOR_BUILD)
66 # define FLASH_PAGE_SIZE (0x400)
67 # else
68 # error "Flash page size not defined for target."
69 # endif
70 #endif
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
80 c->address = base;
81 c->size = size;
82 if (!c->unlocked) {
83 #if defined(STM32F7)
84 HAL_FLASH_Unlock();
85 #else
86 FLASH_Unlock();
87 #endif
88 c->unlocked = true;
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)
98 // NOP
99 #elif defined(UNIT_TEST) || defined(SIMULATOR_BUILD)
100 // NOP
101 #else
102 # error "Unsupported CPU"
103 #endif
104 c->err = 0;
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;
152 #endif
154 // Not good
155 while (1) {
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;
191 // Not good
192 while (1) {
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;
240 // Not good
241 while (1) {
242 failureMode(FAILURE_FLASH_WRITE_FAILED);
245 #endif
247 static int write_word(config_streamer_t *c, uint32_t value)
249 if (c->err != 0) {
250 return c->err;
252 #if defined(STM32F7)
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
257 .NbSectors = 1
259 EraseInitStruct.Sector = getFLASHSectorForEEPROM();
260 uint32_t SECTORError;
261 const HAL_StatusTypeDef status = HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError);
262 if (status != HAL_OK) {
263 return -1;
266 const HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, c->address, value);
267 if (status != HAL_OK) {
268 return -2;
270 #else
271 if (c->address % FLASH_PAGE_SIZE == 0) {
272 #if defined(STM32F4)
273 const FLASH_Status status = FLASH_EraseSector(getFLASHSectorForEEPROM(), VoltageRange_3); //0x08080000 to 0x080A0000
274 #else
275 const FLASH_Status status = FLASH_ErasePage(c->address);
276 #endif
277 if (status != FLASH_COMPLETE) {
278 return -1;
281 const FLASH_Status status = FLASH_ProgramWord(c->address, value);
282 if (status != FLASH_COMPLETE) {
283 return -2;
285 #endif
286 c->address += sizeof(value);
287 return 0;
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);
297 c->at = 0;
300 return c->err;
303 int config_streamer_status(config_streamer_t *c)
305 return c->err;
308 int config_streamer_flush(config_streamer_t *c)
310 if (c->at != 0) {
311 memset(c->buffer.b + c->at, 0, sizeof(c->buffer) - c->at);
312 c->err = write_word(c, c->buffer.w);
313 c->at = 0;
315 return c-> err;
318 int config_streamer_finish(config_streamer_t *c)
320 if (c->unlocked) {
321 #if defined(STM32F7)
322 HAL_FLASH_Lock();
323 #else
324 FLASH_Lock();
325 #endif
326 c->unlocked = false;
328 return c->err;