|
5
|
1 /**
|
|
|
2 ******************************************************************************
|
|
|
3 * @file firmwareEraseProgram.c
|
|
36
|
4 * @author heinrichs weikamp gmbh
|
|
5
|
5 * @version V0.0.1
|
|
|
6 * @date 05-May-2015
|
|
|
7 * @version V0.0.1
|
|
|
8 * @since 05-May-2015
|
|
|
9 * @brief erase and program the STM32F4xx internal FLASH memory
|
|
|
10 *
|
|
|
11 @verbatim
|
|
|
12 ==============================================================================
|
|
|
13 ##### How to use #####
|
|
|
14 ==============================================================================
|
|
|
15 ADDR_FLASH_SECTOR_0 to/with ADDR_FLASH_SECTOR_5 (256KB) is used for this bootloader
|
|
|
16
|
|
|
17 ADDR_FLASH_SECTOR_23 is blocked and used for Font T48 and image_heinrichs_weikamp
|
|
|
18 Font T24 for button text is not blocked / protected
|
|
|
19 other fonts should not be used here
|
|
|
20
|
|
|
21
|
|
|
22 ==============================================================================
|
|
|
23 ##### From AN2557 #####
|
|
|
24 STM32F10xxx In-Application programming CD00161640.pdf 2010
|
|
|
25 ==============================================================================
|
|
|
26 User program conditions
|
|
|
27 The user application to be loaded into the Flash memory using IAP should be built with
|
|
|
28 these configuration settings:
|
|
|
29 1. Set the program load address at 0x08003000, using your toolchain linker file
|
|
|
30 2. Relocate the vector table at address 0x08003000, using the
|
|
|
31 "NVIC_SetVectorTable"function or the VECT_TAB_OFFSET definition inside the
|
|
|
32 "system_stm32f10x.c"
|
|
|
33
|
|
|
34 can be found here system_stm32f4xx.c
|
|
|
35
|
|
|
36
|
|
|
37 @endverbatim
|
|
|
38 ******************************************************************************
|
|
|
39 * @attention
|
|
|
40 *
|
|
|
41 * <h2><center>© COPYRIGHT(c) 2015 heinrichs weikamp</center></h2>
|
|
|
42 *
|
|
|
43 ******************************************************************************
|
|
|
44 */
|
|
|
45
|
|
|
46 /* Includes ------------------------------------------------------------------*/
|
|
|
47 #include "stm32f4xx_hal.h"
|
|
|
48 #include "stdio.h"
|
|
|
49 #include "firmwareEraseProgram.h"
|
|
|
50 #include "settings.h" // to access SHardwareData
|
|
|
51
|
|
|
52 /* Exported variables --------------------------------------------------------*/
|
|
|
53
|
|
|
54 /* Private types -------------------------------------------------------------*/
|
|
|
55
|
|
|
56 /* Base address of the Flash sectors Bank 1 */
|
|
|
57 #define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 16 Kbytes */
|
|
|
58 #define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) /* Base @ of Sector 1, 16 Kbytes */
|
|
|
59 #define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) /* Base @ of Sector 2, 16 Kbytes */
|
|
|
60 #define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) /* Base @ of Sector 3, 16 Kbytes */
|
|
|
61 #define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) /* Base @ of Sector 4, 64 Kbytes */
|
|
|
62 #define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) /* Base @ of Sector 5, 128 Kbytes */
|
|
|
63 #define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) /* Base @ of Sector 6, 128 Kbytes */
|
|
|
64 #define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) /* Base @ of Sector 7, 128 Kbytes */
|
|
|
65 #define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08080000) /* Base @ of Sector 8, 128 Kbytes */
|
|
|
66 #define ADDR_FLASH_SECTOR_9 ((uint32_t)0x080A0000) /* Base @ of Sector 9, 128 Kbytes */
|
|
|
67 #define ADDR_FLASH_SECTOR_10 ((uint32_t)0x080C0000) /* Base @ of Sector 10, 128 Kbytes */
|
|
|
68 #define ADDR_FLASH_SECTOR_11 ((uint32_t)0x080E0000) /* Base @ of Sector 11, 128 Kbytes */
|
|
|
69
|
|
|
70 /* Base address of the Flash sectors Bank 2 */
|
|
|
71 #define ADDR_FLASH_SECTOR_12 ((uint32_t)0x08100000) /* Base @ of Sector 0, 16 Kbytes */
|
|
|
72 #define ADDR_FLASH_SECTOR_13 ((uint32_t)0x08104000) /* Base @ of Sector 1, 16 Kbytes */
|
|
|
73 #define ADDR_FLASH_SECTOR_14 ((uint32_t)0x08108000) /* Base @ of Sector 2, 16 Kbytes */
|
|
|
74 #define ADDR_FLASH_SECTOR_15 ((uint32_t)0x0810C000) /* Base @ of Sector 3, 16 Kbytes */
|
|
|
75 #define ADDR_FLASH_SECTOR_16 ((uint32_t)0x08110000) /* Base @ of Sector 4, 64 Kbytes */
|
|
|
76 #define ADDR_FLASH_SECTOR_17 ((uint32_t)0x08120000) /* Base @ of Sector 5, 128 Kbytes */
|
|
|
77 #define ADDR_FLASH_SECTOR_18 ((uint32_t)0x08140000) /* Base @ of Sector 6, 128 Kbytes */
|
|
|
78 #define ADDR_FLASH_SECTOR_19 ((uint32_t)0x08160000) /* Base @ of Sector 7, 128 Kbytes */
|
|
|
79 #define ADDR_FLASH_SECTOR_20 ((uint32_t)0x08180000) /* Base @ of Sector 8, 128 Kbytes */
|
|
|
80 #define ADDR_FLASH_SECTOR_21 ((uint32_t)0x081A0000) /* Base @ of Sector 9, 128 Kbytes */
|
|
|
81 #define ADDR_FLASH_SECTOR_22 ((uint32_t)0x081C0000) /* Base @ of Sector 10, 128 Kbytes */
|
|
|
82 #define ADDR_FLASH_SECTOR_23 ((uint32_t)0x081E0000) /* Base @ of Sector 11, 128 Kbytes */
|
|
|
83
|
|
|
84 #define SECTOR_SIZE_128KB ((uint32_t)0x00020000)
|
|
|
85
|
|
1017
|
86 #define FLASH_BOOT_START_ADDR ADDR_FLASH_SECTOR_0
|
|
|
87 #define FLASH_BOOT_END_ADDR (ADDR_FLASH_SECTOR_5 - 1)
|
|
|
88
|
|
5
|
89 #define FLASH_FW_START_ADDR ADDR_FLASH_SECTOR_6
|
|
|
90 #define FLASH_FW_END_ADDR (ADDR_FLASH_SECTOR_12 - 1)
|
|
|
91
|
|
|
92 #define FLASH_FW2_START_ADDR ADDR_FLASH_SECTOR_12
|
|
|
93 #define FLASH_FW2_END_ADDR (ADDR_FLASH_SECTOR_22 + SECTOR_SIZE_128KB - 1)
|
|
|
94
|
|
|
95 /* Private variables ---------------------------------------------------------*/
|
|
|
96
|
|
|
97 static FLASH_EraseInitTypeDef EraseInitStruct; /*Variable used for Erase procedure*/
|
|
|
98
|
|
|
99 uint32_t FirstSector = 0, NbOfSectors = 0, Address = 0;
|
|
|
100 uint32_t SectorError = 0;
|
|
|
101 __IO uint32_t data32 = 0 , MemoryProgramStatus = 0;
|
|
|
102
|
|
|
103
|
|
|
104
|
|
|
105 /* Private function prototypes -----------------------------------------------*/
|
|
|
106 //static void firmware_Error_Handler(HAL_StatusTypeDef reason);
|
|
|
107 static uint32_t GetSector(uint32_t Address);
|
|
|
108 uint8_t hardware_programm_sub(uint8_t *buffer64, uint8_t length, uint32_t startAddress);
|
|
|
109
|
|
|
110 /* Exported functions --------------------------------------------------------*/
|
|
|
111
|
|
|
112 const SHardwareData* hardwareDataGetPointer(void)
|
|
|
113 {
|
|
|
114 return (SHardwareData*)HARDWAREDATA_ADDRESS;
|
|
|
115 }
|
|
|
116
|
|
|
117 uint8_t hardware_programmPrimaryBluetoothNameSet(void)
|
|
|
118 {
|
|
|
119 uint8_t data = 0xF0;
|
|
|
120 return hardware_programm_sub(&data, 1, HARDWAREDATA_ADDRESS + 7);
|
|
|
121 }
|
|
|
122
|
|
|
123
|
|
|
124 uint8_t hardware_programmSecondaryBluetoothNameSet(void)
|
|
|
125 {
|
|
|
126 uint8_t data = 0xF0;
|
|
|
127 return hardware_programm_sub(&data, 1, HARDWAREDATA_ADDRESS + 52 + 7);
|
|
|
128 }
|
|
|
129
|
|
|
130
|
|
|
131 uint8_t hardware_programmProductionData(uint8_t *buffer52)
|
|
|
132 {
|
|
|
133 buffer52[7] = 0xFF;// production_bluetooth_name_set
|
|
|
134 return hardware_programm_sub(buffer52, 52, HARDWAREDATA_ADDRESS);// check base_bootloader.c of OSTC4bootloader code and settings.h
|
|
|
135 }
|
|
|
136
|
|
|
137
|
|
|
138 uint8_t hardware_programmSecondarySerial(uint8_t *buffer12)
|
|
|
139 {
|
|
|
140 buffer12[7] = 0xFF;// secondary_bluetooth_name_set
|
|
|
141 return hardware_programm_sub(buffer12, 12, HARDWAREDATA_ADDRESS + 52);
|
|
|
142 }
|
|
|
143
|
|
|
144
|
|
|
145 uint8_t hardware_programm_sub(uint8_t *buffer, uint8_t length, uint32_t startAddress)
|
|
|
146 {
|
|
|
147 HAL_StatusTypeDef answer;
|
|
|
148
|
|
|
149 uint32_t ptr = 0;
|
|
|
150 uint8_t data8;
|
|
|
151
|
|
|
152 // test empty
|
|
|
153 Address = startAddress;
|
|
|
154 for(int i=0;i<length;i++)
|
|
|
155 {
|
|
|
156 if((*(uint8_t *)Address != 0xFF) && (buffer[i] != 0xFF))
|
|
|
157 return 0xE0;
|
|
|
158 Address = Address + 1;
|
|
|
159 }
|
|
|
160
|
|
|
161 // start programming
|
|
|
162 HAL_FLASH_Unlock();
|
|
|
163
|
|
|
164 Address = startAddress;
|
|
|
165 ptr = 0;
|
|
|
166 answer = HAL_OK;
|
|
|
167 while (ptr < length)
|
|
|
168 {
|
|
|
169 if(buffer[ptr] != 0xFF)
|
|
|
170 {
|
|
|
171 answer = HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, Address, buffer[ptr]);
|
|
|
172 }
|
|
|
173 if (answer == HAL_OK)
|
|
|
174 {
|
|
|
175 Address = Address + 1;
|
|
|
176 ptr++;
|
|
|
177 }
|
|
|
178 else
|
|
|
179 {
|
|
|
180 HAL_FLASH_Lock();
|
|
|
181 return answer;
|
|
|
182 }
|
|
|
183 }
|
|
|
184 HAL_FLASH_Lock();
|
|
|
185
|
|
|
186 /* Check if the programmed data is OK
|
|
|
187 MemoryProgramStatus = 0: data programmed correctly
|
|
|
188 MemoryProgramStatus != 0: number of words not programmed correctly ******/
|
|
|
189 Address = startAddress; // check base_bootloader.c of OSTC4bootloader code
|
|
|
190 MemoryProgramStatus = 0x0;
|
|
|
191
|
|
|
192 ptr = 0;
|
|
|
193 while(ptr < length)
|
|
|
194 {
|
|
|
195 data8 = *(__IO uint8_t*)Address;
|
|
|
196
|
|
|
197 if((buffer[ptr] != 0xFF) && (data8 != buffer[ptr]))
|
|
|
198 {
|
|
|
199 MemoryProgramStatus++;
|
|
|
200 }
|
|
|
201
|
|
|
202 Address = Address + 1;
|
|
|
203 ptr++;
|
|
|
204 }
|
|
|
205
|
|
|
206 /* Check if there is an issue to program data */
|
|
|
207 if (MemoryProgramStatus == 0)
|
|
|
208 {
|
|
|
209 return HAL_OK;
|
|
|
210 }
|
|
|
211 else
|
|
|
212 {
|
|
|
213 return 0xEE;
|
|
|
214 }
|
|
|
215 }
|
|
|
216
|
|
|
217
|
|
|
218 uint8_t firmware2_variable_upperpart_eraseFlashMemory(uint32_t length, uint32_t offset)
|
|
|
219 {
|
|
|
220 uint32_t startAddress, endAddress;
|
|
|
221
|
|
|
222 // HAL_StatusTypeDef answer;
|
|
|
223 HAL_FLASH_Unlock();
|
|
|
224
|
|
|
225 startAddress = FLASH_FW2_START_ADDR + offset;
|
|
|
226 endAddress = startAddress + length;
|
|
|
227
|
|
|
228 if(endAddress > FLASH_FW2_END_ADDR)
|
|
|
229 endAddress = FLASH_FW2_END_ADDR;
|
|
|
230
|
|
|
231 FirstSector = GetSector(startAddress);
|
|
|
232 NbOfSectors = GetSector(endAddress) - FirstSector + 1;
|
|
|
233
|
|
|
234 EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
|
|
|
235 EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_1;
|
|
|
236 EraseInitStruct.Sector = FirstSector;
|
|
|
237 EraseInitStruct.NbSectors = NbOfSectors;
|
|
|
238
|
|
|
239 return HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError);
|
|
|
240 }
|
|
|
241
|
|
|
242
|
|
|
243 uint8_t firmware2_variable_upperpart_programFlashMemory(uint32_t length, uint32_t offset, uint8_t *pBuffer1, uint32_t pBuffer1Size, uint8_t *pBuffer2)
|
|
|
244 {
|
|
|
245 HAL_StatusTypeDef answer;
|
|
|
246 uint32_t ptr = 0;
|
|
|
247 uint32_t length1, length2;
|
|
|
248
|
|
|
249 if((pBuffer2) && (length > pBuffer1Size))
|
|
|
250 {
|
|
|
251 length1 = pBuffer1Size;
|
|
|
252 length2 = length - length1;
|
|
|
253 }
|
|
|
254 else
|
|
|
255 {
|
|
|
256 length1 = length;
|
|
|
257 length2 = 0;
|
|
|
258 }
|
|
|
259
|
|
|
260 Address = FLASH_FW2_START_ADDR + offset;
|
|
|
261
|
|
|
262 ptr = 0;
|
|
|
263 while ((Address <= FLASH_FW2_END_ADDR) && (ptr < length1))
|
|
|
264 {
|
|
|
265 answer = HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, Address, pBuffer1[ptr]);
|
|
|
266 if (answer == HAL_OK)
|
|
|
267 {
|
|
|
268 Address = Address + 1;
|
|
|
269 ptr++;
|
|
|
270 }
|
|
|
271 else
|
|
|
272 {
|
|
|
273 return answer;
|
|
|
274 }
|
|
|
275 }
|
|
|
276 ptr = 0;
|
|
|
277 while ((Address <= FLASH_FW2_END_ADDR) && (ptr < length2))
|
|
|
278 {
|
|
|
279 answer = HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, Address, pBuffer2[ptr]);
|
|
|
280 if (answer == HAL_OK)
|
|
|
281 {
|
|
|
282 Address = Address + 1;
|
|
|
283 ptr++;
|
|
|
284 }
|
|
|
285 else
|
|
|
286 {
|
|
|
287 return answer;
|
|
|
288 }
|
|
|
289 }
|
|
|
290 HAL_FLASH_Lock();
|
|
|
291
|
|
|
292 Address = FLASH_FW2_START_ADDR + offset;;
|
|
|
293 MemoryProgramStatus = 0x0;
|
|
|
294
|
|
|
295 ptr = 0;
|
|
|
296 while ((Address <= FLASH_FW2_END_ADDR) && (ptr < length1))
|
|
|
297 {
|
|
|
298 data32 = *(__IO uint8_t*)Address;
|
|
|
299
|
|
|
300 if (data32 != pBuffer1[ptr])
|
|
|
301 {
|
|
|
302 MemoryProgramStatus++;
|
|
|
303 }
|
|
|
304
|
|
|
305 Address = Address + 1;
|
|
|
306 ptr++;
|
|
|
307 }
|
|
|
308 ptr = 0;
|
|
|
309 while ((Address <= FLASH_FW2_END_ADDR) && (ptr < length2))
|
|
|
310 {
|
|
|
311 data32 = *(__IO uint8_t*)Address;
|
|
|
312
|
|
|
313 if (data32 != pBuffer2[ptr])
|
|
|
314 {
|
|
|
315 MemoryProgramStatus++;
|
|
|
316 }
|
|
|
317
|
|
|
318 Address = Address + 1;
|
|
|
319 ptr++;
|
|
|
320 }
|
|
|
321
|
|
|
322 if (MemoryProgramStatus == 0)
|
|
|
323 {
|
|
|
324 return HAL_OK;
|
|
|
325 }
|
|
|
326 else
|
|
|
327 {
|
|
|
328 return 0xEE;
|
|
|
329 }
|
|
|
330 }
|
|
|
331
|
|
|
332 uint8_t firmware_eraseFlashMemory(void)
|
|
|
333 {
|
|
|
334 // HAL_StatusTypeDef answer;
|
|
|
335 /* Unlock the Flash to enable the flash control register access *************/
|
|
|
336 HAL_FLASH_Unlock();
|
|
|
337
|
|
|
338 /* Erase the user Flash area
|
|
|
339 (area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/
|
|
|
340
|
|
|
341 /* Get the 1st sector to erase */
|
|
|
342 FirstSector = GetSector(FLASH_FW_START_ADDR);
|
|
|
343 /* Get the number of sector to erase from 1st sector*/
|
|
|
344 NbOfSectors = GetSector(FLASH_FW_END_ADDR) - FirstSector + 1;
|
|
|
345
|
|
|
346 /* Fill EraseInit structure*/
|
|
|
347 EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
|
|
|
348 EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_1;
|
|
|
349 EraseInitStruct.Sector = FirstSector;
|
|
|
350 EraseInitStruct.NbSectors = NbOfSectors;
|
|
|
351
|
|
|
352 /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
|
|
|
353 you have to make sure that these data are rewritten before they are accessed during code
|
|
|
354 execution. If this cannot be done safely, it is recommended to flush the caches by setting the
|
|
|
355 DCRST and ICRST bits in the FLASH_CR register. */
|
|
|
356 return HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError);
|
|
|
357 }
|
|
|
358
|
|
|
359 uint8_t firmware_programFlashMemory(uint8_t *pBuffer1, uint32_t length1)//, uint8_t *pBuffer2, uint32_t length2)
|
|
|
360 {
|
|
|
361 HAL_StatusTypeDef answer;
|
|
|
362
|
|
|
363 /* Program the user Flash area word by word
|
|
|
364 (area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/
|
|
|
365
|
|
|
366 uint32_t ptr = 0;
|
|
|
367
|
|
|
368 Address = FLASH_FW_START_ADDR;
|
|
|
369
|
|
|
370 ptr = 0;
|
|
|
371 while ((Address <= FLASH_FW_END_ADDR) && (ptr < length1))
|
|
|
372 {
|
|
|
373 answer = HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, Address, pBuffer1[ptr]);
|
|
|
374 if (answer == HAL_OK)
|
|
|
375 // if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address, DATA_32) == HAL_OK)
|
|
|
376 {
|
|
|
377 Address = Address + 1;//4;
|
|
|
378 ptr++;
|
|
|
379 }
|
|
|
380 else
|
|
|
381 {
|
|
|
382 return answer;
|
|
|
383 }
|
|
|
384 }
|
|
|
385 /* same for pBuffer2
|
|
|
386 ptr = 0;
|
|
|
387 while ((Address < FLASH_FW_END_ADDR) && (ptr < length2))
|
|
|
388 {
|
|
|
389
|
|
|
390 if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, Address, pBuffer2[ptr]) == HAL_OK)
|
|
|
391 {
|
|
|
392 Address = Address + 1;
|
|
|
393 ptr++;
|
|
|
394 }
|
|
|
395 else
|
|
|
396 {
|
|
|
397 firmware_Error_Handler();
|
|
|
398 }
|
|
|
399 }
|
|
|
400 */
|
|
|
401 /* Lock the Flash to disable the flash control register access (recommended
|
|
|
402 to protect the FLASH memory against possible unwanted operation) *********/
|
|
|
403 HAL_FLASH_Lock();
|
|
|
404
|
|
|
405 /* Check if the programmed data is OK
|
|
|
406 MemoryProgramStatus = 0: data programmed correctly
|
|
|
407 MemoryProgramStatus != 0: number of words not programmed correctly ******/
|
|
|
408 Address = FLASH_FW_START_ADDR;
|
|
|
409 MemoryProgramStatus = 0x0;
|
|
|
410
|
|
|
411 ptr = 0;
|
|
|
412 while ((Address <= FLASH_FW_END_ADDR) && (ptr < length1))
|
|
|
413 {
|
|
|
414 data32 = *(__IO uint8_t*)Address;
|
|
|
415
|
|
|
416 if (data32 != pBuffer1[ptr])
|
|
|
417 {
|
|
|
418 MemoryProgramStatus++;
|
|
|
419 }
|
|
|
420
|
|
|
421 Address = Address + 1;//4;
|
|
|
422 ptr++;
|
|
|
423 }
|
|
|
424 /* same for pBuffer2
|
|
|
425 ptr = 0;
|
|
|
426 while ((Address < FLASH_FW_END_ADDR) && (ptr < length2))
|
|
|
427 {
|
|
|
428 data32 = *(__IO uint32_t*)Address;
|
|
|
429
|
|
|
430 if (data32 != pBuffer2[ptr])
|
|
|
431 {
|
|
|
432 MemoryProgramStatus++;
|
|
|
433 }
|
|
|
434
|
|
|
435 Address = Address + 1;//4;
|
|
|
436 ptr++;
|
|
|
437 }
|
|
|
438 */
|
|
|
439 /* Check if there is an issue to program data */
|
|
|
440 if (MemoryProgramStatus == 0)
|
|
|
441 {
|
|
|
442 return HAL_OK;
|
|
|
443 /* No error detected. Switch on LED3 */
|
|
|
444 }
|
|
|
445 else
|
|
|
446 {
|
|
|
447 return 0xEE;
|
|
|
448 }
|
|
|
449
|
|
|
450
|
|
|
451 }
|
|
|
452
|
|
1017
|
453
|
|
|
454 uint8_t bootloader_eraseFlashMemory(void)
|
|
|
455 {
|
|
|
456 // HAL_StatusTypeDef answer;
|
|
|
457 /* Unlock the Flash to enable the flash control register access *************/
|
|
|
458 HAL_FLASH_Unlock();
|
|
|
459
|
|
|
460 /* Erase the user Flash area
|
|
|
461 (area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/
|
|
|
462
|
|
|
463 /* Get the 1st sector to erase */
|
|
|
464 FirstSector = GetSector(FLASH_BOOT_START_ADDR);
|
|
|
465 /* Get the number of sector to erase from 1st sector*/
|
|
|
466 NbOfSectors = GetSector(FLASH_BOOT_END_ADDR) - FirstSector + 1;
|
|
|
467
|
|
|
468 /* Fill EraseInit structure*/
|
|
|
469 EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
|
|
|
470 EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_1;
|
|
|
471 EraseInitStruct.Sector = FirstSector;
|
|
|
472 EraseInitStruct.NbSectors = NbOfSectors;
|
|
|
473
|
|
|
474 /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
|
|
|
475 you have to make sure that these data are rewritten before they are accessed during code
|
|
|
476 execution. If this cannot be done safely, it is recommended to flush the caches by setting the
|
|
|
477 DCRST and ICRST bits in the FLASH_CR register. */
|
|
|
478 return HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError);
|
|
|
479 }
|
|
|
480
|
|
|
481 uint8_t bootloader_programFlashMemory(uint8_t *pBuffer1, uint32_t length1, SHardwareData* pHwInfo)
|
|
|
482 {
|
|
|
483 HAL_StatusTypeDef answer;
|
|
|
484
|
|
|
485 /* Program the user Flash area word by word
|
|
|
486 (area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/
|
|
|
487
|
|
|
488 uint32_t index = 0;
|
|
|
489 Address = FLASH_BOOT_START_ADDR;
|
|
|
490
|
|
|
491 uint8_t* pHardwareInfo = (uint8_t*) pHwInfo;
|
|
|
492 uint8_t tmp = 0;
|
|
|
493
|
|
|
494 index = 0;
|
|
|
495 while ((Address <= FLASH_FW_END_ADDR) && (index < length1))
|
|
|
496 {
|
|
|
497 if((Address >= HARDWAREDATA_ADDRESS) && (Address < HARDWAREDATA_ADDRESS + sizeof(SHardwareData)))
|
|
|
498 {
|
|
|
499 answer = HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, Address, *pHardwareInfo++);
|
|
|
500 }
|
|
|
501 else
|
|
|
502 {
|
|
|
503 answer = HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, Address, pBuffer1[index]);
|
|
|
504 }
|
|
|
505 if (answer == HAL_OK)
|
|
|
506 {
|
|
|
507 Address = Address + 1;
|
|
|
508 index++;
|
|
|
509 }
|
|
|
510 else
|
|
|
511 {
|
|
|
512 return answer;
|
|
|
513 }
|
|
|
514 }
|
|
|
515 /* Lock the Flash to disable the flash control register access (recommended
|
|
|
516 to protect the FLASH memory against possible unwanted operation) *********/
|
|
|
517 HAL_FLASH_Lock();
|
|
|
518
|
|
|
519 /* Check if the programmed data is OK
|
|
|
520 MemoryProgramStatus = 0: data programmed correctly
|
|
|
521 MemoryProgramStatus != 0: number of words not programmed correctly ******/
|
|
|
522 Address = FLASH_BOOT_START_ADDR;
|
|
|
523 MemoryProgramStatus = 0x0;
|
|
|
524
|
|
|
525 index = 0;
|
|
|
526 pHardwareInfo = (uint8_t*) pHwInfo;
|
|
|
527
|
|
|
528 while ((Address <= FLASH_FW_END_ADDR) && (index < length1))
|
|
|
529 {
|
|
|
530 if((Address >= HARDWAREDATA_ADDRESS) && (Address < HARDWAREDATA_ADDRESS + sizeof(SHardwareData)))
|
|
|
531 {
|
|
|
532 tmp = *pHardwareInfo++;
|
|
|
533 }
|
|
|
534 else
|
|
|
535 {
|
|
|
536 tmp = pBuffer1[index];
|
|
|
537 }
|
|
|
538
|
|
|
539 data32 = *(__IO uint8_t*)Address;
|
|
|
540 if (data32 != tmp)
|
|
|
541 {
|
|
|
542 MemoryProgramStatus++;
|
|
|
543 }
|
|
|
544
|
|
|
545 Address = Address + 1;
|
|
|
546 index++;
|
|
|
547 }
|
|
|
548 /* Check if there is an issue to program data */
|
|
|
549 if (MemoryProgramStatus == 0)
|
|
|
550 {
|
|
|
551 return HAL_OK;
|
|
|
552 /* No error detected. Switch on LED3 */
|
|
|
553 }
|
|
|
554 else
|
|
|
555 {
|
|
|
556 return 0xEE;
|
|
|
557 }
|
|
|
558 }
|
|
|
559
|
|
|
560
|
|
|
561 uint32_t CalcFletcher32(uint32_t startAddr, uint32_t endAddr)
|
|
|
562 {
|
|
|
563 uint32_t fletcher = 0;
|
|
|
564 uint16_t* pData = (uint16_t*) startAddr;
|
|
|
565 uint32_t index = 0;
|
|
|
566
|
|
|
567 uint16_t sum1 = 0;
|
|
|
568 uint16_t sum2 = 0;
|
|
|
569 for(index = startAddr; index <= endAddr; index +=2)
|
|
|
570 {
|
|
|
571 sum1 = sum1 + *pData++;
|
|
|
572 sum2 = (sum2 + sum1);
|
|
|
573 }
|
|
|
574 fletcher = (sum2 << 16) | sum1;
|
|
|
575
|
|
|
576 return fletcher;
|
|
|
577 }
|
|
|
578
|
|
|
579
|
|
5
|
580 /* Private functions ---------------------------------------------------------*/
|
|
|
581
|
|
|
582 /**
|
|
|
583 * @brief Gets the sector of a given address
|
|
|
584 * @param None
|
|
|
585 * @retval The sector of a given address
|
|
|
586 */
|
|
|
587 static uint32_t GetSector(uint32_t Address)
|
|
|
588 {
|
|
|
589 uint32_t sector = 0;
|
|
|
590
|
|
|
591 if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0))
|
|
|
592 {
|
|
|
593 sector = FLASH_SECTOR_0;
|
|
|
594 }
|
|
|
595 else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1))
|
|
|
596 {
|
|
|
597 sector = FLASH_SECTOR_1;
|
|
|
598 }
|
|
|
599 else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2))
|
|
|
600 {
|
|
|
601 sector = FLASH_SECTOR_2;
|
|
|
602 }
|
|
|
603 else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3))
|
|
|
604 {
|
|
|
605 sector = FLASH_SECTOR_3;
|
|
|
606 }
|
|
|
607 else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4))
|
|
|
608 {
|
|
|
609 sector = FLASH_SECTOR_4;
|
|
|
610 }
|
|
|
611 else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5))
|
|
|
612 {
|
|
|
613 sector = FLASH_SECTOR_5;
|
|
|
614 }
|
|
|
615 else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6))
|
|
|
616 {
|
|
|
617 sector = FLASH_SECTOR_6;
|
|
|
618 }
|
|
|
619 else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7))
|
|
|
620 {
|
|
|
621 sector = FLASH_SECTOR_7;
|
|
|
622 }
|
|
|
623 else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8))
|
|
|
624 {
|
|
|
625 sector = FLASH_SECTOR_8;
|
|
|
626 }
|
|
|
627 else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9))
|
|
|
628 {
|
|
|
629 sector = FLASH_SECTOR_9;
|
|
|
630 }
|
|
|
631 else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10))
|
|
|
632 {
|
|
|
633 sector = FLASH_SECTOR_10;
|
|
|
634 }
|
|
|
635 else if((Address < ADDR_FLASH_SECTOR_12) && (Address >= ADDR_FLASH_SECTOR_11))
|
|
|
636 {
|
|
|
637 sector = FLASH_SECTOR_11;
|
|
|
638 }
|
|
|
639 else if((Address < ADDR_FLASH_SECTOR_13) && (Address >= ADDR_FLASH_SECTOR_12))
|
|
|
640 {
|
|
|
641 sector = FLASH_SECTOR_12;
|
|
|
642 }
|
|
|
643 else if((Address < ADDR_FLASH_SECTOR_14) && (Address >= ADDR_FLASH_SECTOR_13))
|
|
|
644 {
|
|
|
645 sector = FLASH_SECTOR_13;
|
|
|
646 }
|
|
|
647 else if((Address < ADDR_FLASH_SECTOR_15) && (Address >= ADDR_FLASH_SECTOR_14))
|
|
|
648 {
|
|
|
649 sector = FLASH_SECTOR_14;
|
|
|
650 }
|
|
|
651 else if((Address < ADDR_FLASH_SECTOR_16) && (Address >= ADDR_FLASH_SECTOR_15))
|
|
|
652 {
|
|
|
653 sector = FLASH_SECTOR_15;
|
|
|
654 }
|
|
|
655 else if((Address < ADDR_FLASH_SECTOR_17) && (Address >= ADDR_FLASH_SECTOR_16))
|
|
|
656 {
|
|
|
657 sector = FLASH_SECTOR_16;
|
|
|
658 }
|
|
|
659 else if((Address < ADDR_FLASH_SECTOR_18) && (Address >= ADDR_FLASH_SECTOR_17))
|
|
|
660 {
|
|
|
661 sector = FLASH_SECTOR_17;
|
|
|
662 }
|
|
|
663 else if((Address < ADDR_FLASH_SECTOR_19) && (Address >= ADDR_FLASH_SECTOR_18))
|
|
|
664 {
|
|
|
665 sector = FLASH_SECTOR_18;
|
|
|
666 }
|
|
|
667 else if((Address < ADDR_FLASH_SECTOR_20) && (Address >= ADDR_FLASH_SECTOR_19))
|
|
|
668 {
|
|
|
669 sector = FLASH_SECTOR_19;
|
|
|
670 }
|
|
|
671 else if((Address < ADDR_FLASH_SECTOR_21) && (Address >= ADDR_FLASH_SECTOR_20))
|
|
|
672 {
|
|
|
673 sector = FLASH_SECTOR_20;
|
|
|
674 }
|
|
|
675 else if((Address < ADDR_FLASH_SECTOR_22) && (Address >= ADDR_FLASH_SECTOR_21))
|
|
|
676 {
|
|
|
677 sector = FLASH_SECTOR_21;
|
|
|
678 }
|
|
|
679 else if((Address < ADDR_FLASH_SECTOR_23) && (Address >= ADDR_FLASH_SECTOR_22))
|
|
|
680 {
|
|
|
681 sector = FLASH_SECTOR_22;
|
|
|
682 }
|
|
|
683 else/*(Address < FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_23))*/
|
|
|
684 {
|
|
|
685 sector = FLASH_SECTOR_23;
|
|
|
686 }
|
|
|
687
|
|
|
688 return sector;
|
|
|
689 }
|
|
|
690
|
|
|
691 /*
|
|
|
692 static void firmware_Error_Handler(HAL_StatusTypeDef reason)
|
|
|
693 {
|
|
|
694 static HAL_StatusTypeDef last_reason = HAL_OK;
|
|
|
695
|
|
|
696 last_reason = reason;
|
|
|
697 while(1)
|
|
|
698 {
|
|
|
699 }
|
|
|
700 }
|
|
|
701 */
|