rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
stm32h7xx_hal_flash.c
Go to the documentation of this file.
1/**
2 ******************************************************************************
3 * @file stm32h7xx_hal_flash.c
4 * @author MCD Application Team
5 * @brief FLASH HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the internal FLASH memory:
8 * + Program operations functions
9 * + Memory Control functions
10 * + Peripheral Errors functions
11 *
12 @verbatim
13 ==============================================================================
14 ##### FLASH peripheral features #####
15 ==============================================================================
16
17 [..] The Flash memory interface manages CPU AXI I-Code and D-Code accesses
18 to the Flash memory. It implements the erase and program Flash memory operations
19 and the read and write protection mechanisms.
20
21 [..] The FLASH main features are:
22 (+) Flash memory read operations
23 (+) Flash memory program/erase operations
24 (+) Read / write protections
25 (+) Option bytes programming
26 (+) Error code correction (ECC) : Data in flash are 266-bits word
27 (10 bits added per flash word)
28
29 ##### How to use this driver #####
30 ==============================================================================
31 [..]
32 This driver provides functions and macros to configure and program the FLASH
33 memory of all STM32H7xx devices.
34
35 (#) FLASH Memory IO Programming functions:
36 (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
37 HAL_FLASH_Lock() functions
38 (++) Program functions: 256-bit word only
39 (++) There Two modes of programming :
40 (+++) Polling mode using HAL_FLASH_Program() function
41 (+++) Interrupt mode using HAL_FLASH_Program_IT() function
42
43 (#) Interrupts and flags management functions :
44 (++) Handle FLASH interrupts by calling HAL_FLASH_IRQHandler()
45 (++) Callback functions are called when the flash operations are finished :
46 HAL_FLASH_EndOfOperationCallback() when everything is ok, otherwise
47 HAL_FLASH_OperationErrorCallback()
48 (++) Get error flag status by calling HAL_FLASH_GetError()
49
50 (#) Option bytes management functions :
51 (++) Lock and Unlock the option bytes using HAL_FLASH_OB_Unlock() and
52 HAL_FLASH_OB_Lock() functions
53 (++) Launch the reload of the option bytes using HAL_FLASH_OB_Launch() function.
54 In this case, a reset is generated
55 [..]
56 In addition to these functions, this driver includes a set of macros allowing
57 to handle the following operations:
58 (+) Set the latency
59 (+) Enable/Disable the FLASH interrupts
60 (+) Monitor the FLASH flags status
61 [..]
62 (@) For any Flash memory program operation (erase or program), the CPU clock frequency
63 (HCLK) must be at least 1MHz.
64 (@) The contents of the Flash memory are not guaranteed if a device reset occurs during
65 a Flash memory operation.
66 (@) The application can simultaneously request a read and a write operation through each AXI
67 interface.
68 As the Flash memory is divided into two independent banks, the embedded Flash
69 memory interface can drive different operations at the same time on each bank. For
70 example a read, write or erase operation can be executed on bank 1 while another read,
71 write or erase operation is executed on bank 2.
72
73 @endverbatim
74 ******************************************************************************
75 * @attention
76 *
77 * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics.
78 * All rights reserved.</center></h2>
79 *
80 * This software component is licensed by ST under BSD 3-Clause license,
81 * the "License"; You may not use this file except in compliance with the
82 * License. You may obtain a copy of the License at:
83 * opensource.org/licenses/BSD-3-Clause
84 *
85 ******************************************************************************
86 */
87
88/* Includes ------------------------------------------------------------------*/
89//#include "stm32h7xx_hal.h"
91#include "stm32h7xx_hal_flash.h"
92
93#define assert_param(expr) ((void)0)
94
95/** @addtogroup STM32H7xx_HAL_Driver
96 * @{
97 */
98
99/** @defgroup FLASH FLASH
100 * @brief FLASH HAL module driver
101 * @{
102 */
103
104#define HAL_FLASH_MODULE_ENABLED
105
106#ifdef HAL_FLASH_MODULE_ENABLED
107
108/* Private typedef -----------------------------------------------------------*/
109/* Private define ------------------------------------------------------------*/
110/** @addtogroup FLASH_Private_Constants
111 * @{
112 */
113#define FLASH_TIMEOUT_VALUE 50000U /* 50 s */
114/**
115 * @}
116 */
117/* Private macro -------------------------------------------------------------*/
118/* Private variables ---------------------------------------------------------*/
120/* Private function prototypes -----------------------------------------------*/
121/* Exported functions ---------------------------------------------------------*/
122
123/** @defgroup FLASH_Exported_Functions FLASH Exported functions
124 * @{
125 */
126
127/** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions
128 * @brief Programming operation functions
129 *
130@verbatim
131 ===============================================================================
132 ##### Programming operation functions #####
133 ===============================================================================
134 [..]
135 This subsection provides a set of functions allowing to manage the FLASH
136 program operations.
137
138@endverbatim
139 * @{
140 */
141
142/**
143 * @brief Program flash word at a specified address
144 * @param TypeProgram Indicate the way to program at a specified address.
145 * This parameter can be a value of @ref FLASH_Type_Program
146 * @param FlashAddress specifies the address to be programmed.
147 * @param DataAddress specifies the address of data to be programmed
148 *
149 * @retval HAL_StatusTypeDef HAL Status
150 */
151HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
152{
153 HAL_StatusTypeDef status;
154 __IO uint32_t *dest_addr = (__IO uint32_t *)FlashAddress;
155 __IO uint32_t *src_addr = (__IO uint32_t*)DataAddress;
156 uint32_t bank;
157 uint8_t row_index = FLASH_NB_32BITWORD_IN_FLASHWORD;
158
159 /* Check the parameters */
160 assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
161 assert_param(IS_FLASH_PROGRAM_ADDRESS(FlashAddress));
162
163 /* Process Locked */
164 __HAL_LOCK(&pFlash);
165
166#if defined (FLASH_OPTCR_PG_OTP)
167 if((IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress)) || (IS_FLASH_PROGRAM_ADDRESS_OTP(FlashAddress)))
168#else
169 if(IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress))
170#endif /* FLASH_OPTCR_PG_OTP */
171 {
172 bank = FLASH_BANK_1;
173 }
174#if defined (DUAL_BANK)
175 else if(IS_FLASH_PROGRAM_ADDRESS_BANK2(FlashAddress))
176 {
177 bank = FLASH_BANK_2;
178 }
179#endif /* DUAL_BANK */
180 else
181 {
182 return HAL_ERROR;
183 }
184
185 /* Reset error code */
186 pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
187
188 /* Wait for last operation to be completed */
189 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);
190
191 if(status == HAL_OK)
192 {
193#if defined (DUAL_BANK)
194 if(bank == FLASH_BANK_1)
195 {
196#if defined (FLASH_OPTCR_PG_OTP)
197 if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
198 {
199 /* Set OTP_PG bit */
200 SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
201 }
202 else
203#endif /* FLASH_OPTCR_PG_OTP */
204 {
205 /* Set PG bit */
206 SET_BIT(FLASH->CR1, FLASH_CR_PG);
207 }
208 }
209 else
210 {
211 /* Set PG bit */
212 SET_BIT(FLASH->CR2, FLASH_CR_PG);
213 }
214#else /* Single Bank */
215#if defined (FLASH_OPTCR_PG_OTP)
216 if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
217 {
218 /* Set OTP_PG bit */
219 SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
220 }
221 else
222#endif /* FLASH_OPTCR_PG_OTP */
223 {
224 /* Set PG bit */
225 SET_BIT(FLASH->CR1, FLASH_CR_PG);
226 }
227#endif /* DUAL_BANK */
228
229 __ISB();
230 __DSB();
231
232#if defined (FLASH_OPTCR_PG_OTP)
233 if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
234 {
235 /* Program an OTP word (16 bits) */
236 *(__IO uint16_t *)FlashAddress = *(__IO uint16_t*)DataAddress;
237 }
238 else
239#endif /* FLASH_OPTCR_PG_OTP */
240 {
241 /* Program the flash word */
242 do
243 {
244 *dest_addr = *src_addr;
245 dest_addr++;
246 src_addr++;
247 row_index--;
248 } while (row_index != 0U);
249 }
250
251 __ISB();
252 __DSB();
253
254 /* Wait for last operation to be completed */
255 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);
256
257#if defined (DUAL_BANK)
258#if defined (FLASH_OPTCR_PG_OTP)
259 if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
260 {
261 /* If the program operation is completed, disable the OTP_PG */
262 CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
263 }
264 else
265#endif /* FLASH_OPTCR_PG_OTP */
266 {
267 if(bank == FLASH_BANK_1)
268 {
269 /* If the program operation is completed, disable the PG */
270 CLEAR_BIT(FLASH->CR1, FLASH_CR_PG);
271 }
272 else
273 {
274 /* If the program operation is completed, disable the PG */
275 CLEAR_BIT(FLASH->CR2, FLASH_CR_PG);
276 }
277 }
278#else /* Single Bank */
279#if defined (FLASH_OPTCR_PG_OTP)
280 if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
281 {
282 /* If the program operation is completed, disable the OTP_PG */
283 CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
284 }
285 else
286#endif /* FLASH_OPTCR_PG_OTP */
287 {
288 /* If the program operation is completed, disable the PG */
289 CLEAR_BIT(FLASH->CR1, FLASH_CR_PG);
290 }
291#endif /* DUAL_BANK */
292 }
293
294 /* Process Unlocked */
295 __HAL_UNLOCK(&pFlash);
296
297 return status;
298}
299
300/**
301 * @brief Program flash words of 256 bits at a specified address with interrupt enabled.
302 * @param TypeProgram Indicate the way to program at a specified address.
303 * This parameter can be a value of @ref FLASH_Type_Program
304 * @param FlashAddress specifies the address to be programmed.
305 * @param DataAddress specifies the address of data (256 bits) to be programmed
306 *
307 * @retval HAL Status
308 */
309HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
310{
311 HAL_StatusTypeDef status;
312 __IO uint32_t *dest_addr = (__IO uint32_t*)FlashAddress;
313 __IO uint32_t *src_addr = (__IO uint32_t*)DataAddress;
314 uint32_t bank;
315 uint8_t row_index = FLASH_NB_32BITWORD_IN_FLASHWORD;
316
317 /* Check the parameters */
318 assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
319 assert_param(IS_FLASH_PROGRAM_ADDRESS(FlashAddress));
320
321 /* Process Locked */
322 __HAL_LOCK(&pFlash);
323
324 /* Reset error code */
325 pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
326
327#if defined (FLASH_OPTCR_PG_OTP)
328 if((IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress)) || (IS_FLASH_PROGRAM_ADDRESS_OTP(FlashAddress)))
329#else
330 if(IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress))
331#endif /* FLASH_OPTCR_PG_OTP */
332 {
333 bank = FLASH_BANK_1;
334 }
335#if defined (DUAL_BANK)
336 else if(IS_FLASH_PROGRAM_ADDRESS_BANK2(FlashAddress))
337 {
338 bank = FLASH_BANK_2;
339 }
340#endif /* DUAL_BANK */
341 else
342 {
343 return HAL_ERROR;
344 }
345
346 /* Wait for last operation to be completed */
347 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);
348
349 if (status != HAL_OK)
350 {
351 /* Process Unlocked */
352 __HAL_UNLOCK(&pFlash);
353 }
354 else
355 {
356 pFlash.Address = FlashAddress;
357
358#if defined (DUAL_BANK)
359 if(bank == FLASH_BANK_1)
360 {
361 /* Set internal variables used by the IRQ handler */
362 pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM_BANK1;
363
364#if defined (FLASH_OPTCR_PG_OTP)
365 if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
366 {
367 /* Set OTP_PG bit */
368 SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
369 }
370 else
371#endif /* FLASH_OPTCR_PG_OTP */
372 {
373 /* Set PG bit */
374 SET_BIT(FLASH->CR1, FLASH_CR_PG);
375 }
376
377 /* Enable End of Operation and Error interrupts for Bank 1 */
378#if defined (FLASH_CR_OPERRIE)
379 __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1 | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
380 FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1 | FLASH_IT_OPERR_BANK1);
381#else
382 __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1 | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
383 FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1);
384#endif /* FLASH_CR_OPERRIE */
385 }
386 else
387 {
388 /* Set internal variables used by the IRQ handler */
389 pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM_BANK2;
390
391 /* Set PG bit */
392 SET_BIT(FLASH->CR2, FLASH_CR_PG);
393
394 /* Enable End of Operation and Error interrupts for Bank2 */
395#if defined (FLASH_CR_OPERRIE)
396 __HAL_FLASH_ENABLE_IT_BANK2(FLASH_IT_EOP_BANK2 | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \
397 FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2 | FLASH_IT_OPERR_BANK2);
398#else
399 __HAL_FLASH_ENABLE_IT_BANK2(FLASH_IT_EOP_BANK2 | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \
400 FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2);
401#endif /* FLASH_CR_OPERRIE */
402 }
403#else /* Single Bank */
404 /* Set internal variables used by the IRQ handler */
405 pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM_BANK1;
406
407#if defined (FLASH_OPTCR_PG_OTP)
408 if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
409 {
410 /* Set OTP_PG bit */
411 SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
412 }
413 else
414#endif /* FLASH_OPTCR_PG_OTP */
415 {
416 /* Set PG bit */
417 SET_BIT(FLASH->CR1, FLASH_CR_PG);
418 }
419
420 /* Enable End of Operation and Error interrupts for Bank 1 */
421#if defined (FLASH_CR_OPERRIE)
422 __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1 | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
423 FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1 | FLASH_IT_OPERR_BANK1);
424#else
425 __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1 | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
426 FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1);
427#endif /* FLASH_CR_OPERRIE */
428#endif /* DUAL_BANK */
429
430 __ISB();
431 __DSB();
432
433#if defined (FLASH_OPTCR_PG_OTP)
434 if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
435 {
436 /* Program an OTP word (16 bits) */
437 *(__IO uint16_t *)FlashAddress = *(__IO uint16_t*)DataAddress;
438 }
439 else
440#endif /* FLASH_OPTCR_PG_OTP */
441 {
442 /* Program the flash word */
443 do
444 {
445 *dest_addr = *src_addr;
446 dest_addr++;
447 src_addr++;
448 row_index--;
449 } while (row_index != 0U);
450 }
451
452 __ISB();
453 __DSB();
454 }
455
456 return status;
457}
458
459/**
460 * @brief This function handles FLASH interrupt request.
461 * @retval None
462 */
463void HAL_FLASH_IRQHandler(void)
464{
465 uint32_t temp;
466 uint32_t errorflag;
467 FLASH_ProcedureTypeDef procedure;
468
469 /* Check FLASH Bank1 End of Operation flag */
470 if(__HAL_FLASH_GET_FLAG_BANK1(FLASH_SR_EOP) != RESET)
471 {
472 if(pFlash.ProcedureOnGoing == FLASH_PROC_SECTERASE_BANK1)
473 {
474 /* Nb of sector to erased can be decreased */
476
477 /* Check if there are still sectors to erase */
478 if(pFlash.NbSectorsToErase != 0U)
479 {
480 /* Indicate user which sector has been erased */
482
483 /* Clear bank 1 End of Operation pending bit */
484 __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_EOP_BANK1);
485
486 /* Increment sector number */
487 pFlash.Sector++;
488 temp = pFlash.Sector;
489 FLASH_Erase_Sector(temp, FLASH_BANK_1, pFlash.VoltageForErase);
490 }
491 else
492 {
493 /* No more sectors to Erase, user callback can be called */
494 /* Reset Sector and stop Erase sectors procedure */
495 pFlash.Sector = 0xFFFFFFFFU;
496 pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
497
498 /* FLASH EOP interrupt user callback */
500
501 /* Clear FLASH End of Operation pending bit */
502 __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_EOP_BANK1);
503 }
504 }
505 else
506 {
507 procedure = pFlash.ProcedureOnGoing;
508
509 if((procedure == FLASH_PROC_MASSERASE_BANK1) || (procedure == FLASH_PROC_ALLBANK_MASSERASE))
510 {
511 /* MassErase ended. Return the selected bank */
512 /* FLASH EOP interrupt user callback */
514 }
515 else if(procedure == FLASH_PROC_PROGRAM_BANK1)
516 {
517 /* Program ended. Return the selected address */
518 /* FLASH EOP interrupt user callback */
520 }
521 else
522 {
523 /* Nothing to do */
524 }
525
526 if((procedure != FLASH_PROC_SECTERASE_BANK2) && \
527 (procedure != FLASH_PROC_MASSERASE_BANK2) && \
528 (procedure != FLASH_PROC_PROGRAM_BANK2))
529 {
530 pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
531 /* Clear FLASH End of Operation pending bit */
532 __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_EOP_BANK1);
533 }
534 }
535 }
536
537#if defined (DUAL_BANK)
538 /* Check FLASH Bank2 End of Operation flag */
539 if(__HAL_FLASH_GET_FLAG_BANK2(FLASH_SR_EOP) != RESET)
540 {
541 if(pFlash.ProcedureOnGoing == FLASH_PROC_SECTERASE_BANK2)
542 {
543 /*Nb of sector to erased can be decreased*/
545
546 /* Check if there are still sectors to erase*/
547 if(pFlash.NbSectorsToErase != 0U)
548 {
549 /*Indicate user which sector has been erased*/
551
552 /* Clear bank 2 End of Operation pending bit */
553 __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_EOP_BANK2);
554
555 /*Increment sector number*/
556 pFlash.Sector++;
557 temp = pFlash.Sector;
558 FLASH_Erase_Sector(temp, FLASH_BANK_2, pFlash.VoltageForErase);
559 }
560 else
561 {
562 /* No more sectors to Erase, user callback can be called */
563 /* Reset Sector and stop Erase sectors procedure */
564 pFlash.Sector = 0xFFFFFFFFU;
565 pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
566
567 /* FLASH EOP interrupt user callback */
569
570 /* Clear FLASH End of Operation pending bit */
571 __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_EOP_BANK2);
572 }
573 }
574 else
575 {
576 procedure = pFlash.ProcedureOnGoing;
577
578 if((procedure == FLASH_PROC_MASSERASE_BANK2) || (procedure == FLASH_PROC_ALLBANK_MASSERASE))
579 {
580 /*MassErase ended. Return the selected bank*/
581 /* FLASH EOP interrupt user callback */
583 }
584 else if(procedure == FLASH_PROC_PROGRAM_BANK2)
585 {
586 /* Program ended. Return the selected address */
587 /* FLASH EOP interrupt user callback */
589 }
590 else
591 {
592 /* Nothing to do */
593 }
594
595 if((procedure != FLASH_PROC_SECTERASE_BANK1) && \
596 (procedure != FLASH_PROC_MASSERASE_BANK1) && \
597 (procedure != FLASH_PROC_PROGRAM_BANK1))
598 {
599 pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
600 /* Clear FLASH End of Operation pending bit */
601 __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_EOP_BANK2);
602 }
603 }
604 }
605#endif /* DUAL_BANK */
606
607 /* Check FLASH Bank1 operation error flags */
608#if defined (FLASH_SR_OPERR)
609 errorflag = FLASH->SR1 & (FLASH_FLAG_WRPERR_BANK1 | FLASH_FLAG_PGSERR_BANK1 | FLASH_FLAG_STRBERR_BANK1 | \
610 FLASH_FLAG_INCERR_BANK1 | FLASH_FLAG_OPERR_BANK1);
611#else
612 errorflag = FLASH->SR1 & (FLASH_FLAG_WRPERR_BANK1 | FLASH_FLAG_PGSERR_BANK1 | FLASH_FLAG_STRBERR_BANK1 | \
613 FLASH_FLAG_INCERR_BANK1);
614#endif /* FLASH_SR_OPERR */
615
616 if(errorflag != 0U)
617 {
618 /* Save the error code */
619 pFlash.ErrorCode |= errorflag;
620
621 /* Clear error programming flags */
622 __HAL_FLASH_CLEAR_FLAG_BANK1(errorflag);
623
624 procedure = pFlash.ProcedureOnGoing;
625
626 if(procedure == FLASH_PROC_SECTERASE_BANK1)
627 {
628 /* Return the faulty sector */
629 temp = pFlash.Sector;
630 pFlash.Sector = 0xFFFFFFFFU;
631 }
632 else if((procedure == FLASH_PROC_MASSERASE_BANK1) || (procedure == FLASH_PROC_ALLBANK_MASSERASE))
633 {
634 /* Return the faulty bank */
635 temp = FLASH_BANK_1;
636 }
637 else
638 {
639 /* Return the faulty address */
640 temp = pFlash.Address;
641 }
642
643 /* Stop the procedure ongoing*/
644 pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
645
646 /* FLASH error interrupt user callback */
648 }
649
650#if defined (DUAL_BANK)
651 /* Check FLASH Bank2 operation error flags */
652#if defined (FLASH_SR_OPERR)
653 errorflag = FLASH->SR2 & ((FLASH_FLAG_WRPERR_BANK2 | FLASH_FLAG_PGSERR_BANK2 | FLASH_FLAG_STRBERR_BANK2 | \
654 FLASH_FLAG_INCERR_BANK2 | FLASH_FLAG_OPERR_BANK2) & 0x7FFFFFFFU);
655#else
656 errorflag = FLASH->SR2 & ((FLASH_FLAG_WRPERR_BANK2 | FLASH_FLAG_PGSERR_BANK2 | FLASH_FLAG_STRBERR_BANK2 | \
657 FLASH_FLAG_INCERR_BANK2) & 0x7FFFFFFFU);
658#endif /* FLASH_SR_OPERR */
659
660 if(errorflag != 0U)
661 {
662 /* Save the error code */
663 pFlash.ErrorCode |= (errorflag | 0x80000000U);
664
665 /* Clear error programming flags */
666 __HAL_FLASH_CLEAR_FLAG_BANK2(errorflag);
667
668 procedure = pFlash.ProcedureOnGoing;
669
670 if(procedure== FLASH_PROC_SECTERASE_BANK2)
671 {
672 /*return the faulty sector*/
673 temp = pFlash.Sector;
674 pFlash.Sector = 0xFFFFFFFFU;
675 }
676 else if((procedure == FLASH_PROC_MASSERASE_BANK2) || (procedure == FLASH_PROC_ALLBANK_MASSERASE))
677 {
678 /*return the faulty bank*/
679 temp = FLASH_BANK_2;
680 }
681 else
682 {
683 /*return the faulty address*/
684 temp = pFlash.Address;
685 }
686
687 /*Stop the procedure ongoing*/
688 pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
689
690 /* FLASH error interrupt user callback */
692 }
693#endif /* DUAL_BANK */
694
695 if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
696 {
697#if defined (FLASH_CR_OPERRIE)
698 /* Disable Bank1 Operation and Error source interrupt */
699 __HAL_FLASH_DISABLE_IT_BANK1(FLASH_IT_EOP_BANK1 | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
700 FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1 | FLASH_IT_OPERR_BANK1);
701
702#if defined (DUAL_BANK)
703 /* Disable Bank2 Operation and Error source interrupt */
704 __HAL_FLASH_DISABLE_IT_BANK2(FLASH_IT_EOP_BANK2 | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \
705 FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2 | FLASH_IT_OPERR_BANK2);
706#endif /* DUAL_BANK */
707#else
708 /* Disable Bank1 Operation and Error source interrupt */
709 __HAL_FLASH_DISABLE_IT_BANK1(FLASH_IT_EOP_BANK1 | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
710 FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1);
711
712#if defined (DUAL_BANK)
713 /* Disable Bank2 Operation and Error source interrupt */
714 __HAL_FLASH_DISABLE_IT_BANK2(FLASH_IT_EOP_BANK2 | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \
715 FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2);
716#endif /* DUAL_BANK */
717#endif /* FLASH_CR_OPERRIE */
718
719 /* Process Unlocked */
720 __HAL_UNLOCK(&pFlash);
721 }
722}
723
724/**
725 * @brief FLASH end of operation interrupt callback
726 * @param ReturnValue The value saved in this parameter depends on the ongoing procedure
727 * Mass Erase: Bank number which has been requested to erase
728 * Sectors Erase: Sector which has been erased
729 * (if 0xFFFFFFFF, it means that all the selected sectors have been erased)
730 * Program: Address which was selected for data program
731 * @retval None
732 */
733__weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
734{
735 /* Prevent unused argument(s) compilation warning */
736 (void)ReturnValue;
737
738 /* NOTE : This function Should not be modified, when the callback is needed,
739 the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
740 */
741}
742
743/**
744 * @brief FLASH operation error interrupt callback
745 * @param ReturnValue The value saved in this parameter depends on the ongoing procedure
746 * Mass Erase: Bank number which has been requested to erase
747 * Sectors Erase: Sector number which returned an error
748 * Program: Address which was selected for data program
749 * @retval None
750 */
751__weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
752{
753 /* Prevent unused argument(s) compilation warning */
754 (void)ReturnValue;
755
756 /* NOTE : This function Should not be modified, when the callback is needed,
757 the HAL_FLASH_OperationErrorCallback could be implemented in the user file
758 */
759}
760
761/**
762 * @}
763 */
764
765/** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
766 * @brief Management functions
767 *
768@verbatim
769 ===============================================================================
770 ##### Peripheral Control functions #####
771 ===============================================================================
772 [..]
773 This subsection provides a set of functions allowing to control the FLASH
774 memory operations.
775
776@endverbatim
777 * @{
778 */
779
780/**
781 * @brief Unlock the FLASH control registers access
782 * @retval HAL Status
783 */
784HAL_StatusTypeDef HAL_FLASH_Unlock(void)
785{
786 if(READ_BIT(FLASH->CR1, FLASH_CR_LOCK) != 0U)
787 {
788 /* Authorize the FLASH Bank1 Registers access */
789 WRITE_REG(FLASH->KEYR1, FLASH_KEY1);
790 WRITE_REG(FLASH->KEYR1, FLASH_KEY2);
791
792 /* Verify Flash Bank1 is unlocked */
793 if (READ_BIT(FLASH->CR1, FLASH_CR_LOCK) != 0U)
794 {
795 return HAL_ERROR;
796 }
797 }
798
799#if defined (DUAL_BANK)
800 if(READ_BIT(FLASH->CR2, FLASH_CR_LOCK) != 0U)
801 {
802 /* Authorize the FLASH Bank2 Registers access */
803 WRITE_REG(FLASH->KEYR2, FLASH_KEY1);
804 WRITE_REG(FLASH->KEYR2, FLASH_KEY2);
805
806 /* Verify Flash Bank2 is unlocked */
807 if (READ_BIT(FLASH->CR2, FLASH_CR_LOCK) != 0U)
808 {
809 return HAL_ERROR;
810 }
811 }
812#endif /* DUAL_BANK */
813
814 return HAL_OK;
815}
816
817/**
818 * @brief Locks the FLASH control registers access
819 * @retval HAL Status
820 */
821HAL_StatusTypeDef HAL_FLASH_Lock(void)
822{
823 /* Set the LOCK Bit to lock the FLASH Bank1 Control Register access */
824 SET_BIT(FLASH->CR1, FLASH_CR_LOCK);
825
826 /* Verify Flash Bank1 is locked */
827 if (READ_BIT(FLASH->CR1, FLASH_CR_LOCK) == 0U)
828 {
829 return HAL_ERROR;
830 }
831
832#if defined (DUAL_BANK)
833 /* Set the LOCK Bit to lock the FLASH Bank2 Control Register access */
834 SET_BIT(FLASH->CR2, FLASH_CR_LOCK);
835
836 /* Verify Flash Bank2 is locked */
837 if (READ_BIT(FLASH->CR2, FLASH_CR_LOCK) == 0U)
838 {
839 return HAL_ERROR;
840 }
841#endif /* DUAL_BANK */
842
843 return HAL_OK;
844}
845
846/**
847 * @brief Unlock the FLASH Option Control Registers access.
848 * @retval HAL Status
849 */
850HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
851{
852 if(READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) != 0U)
853 {
854 /* Authorizes the Option Byte registers programming */
855 WRITE_REG(FLASH->OPTKEYR, FLASH_OPT_KEY1);
856 WRITE_REG(FLASH->OPTKEYR, FLASH_OPT_KEY2);
857
858 /* Verify that the Option Bytes are unlocked */
859 if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) != 0U)
860 {
861 return HAL_ERROR;
862 }
863 }
864
865 return HAL_OK;
866}
867
868/**
869 * @brief Lock the FLASH Option Control Registers access.
870 * @retval HAL Status
871 */
872HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
873{
874 /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
875 SET_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK);
876
877 /* Verify that the Option Bytes are locked */
878 if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) == 0U)
879 {
880 return HAL_ERROR;
881 }
882
883 return HAL_OK;
884}
885
886/**
887 * @brief Launch the option bytes loading.
888 * @retval HAL Status
889 */
890HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
891{
892 HAL_StatusTypeDef status;
893
894 /* Wait for CRC computation to be completed */
895 if (FLASH_CRC_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK)
896 {
897 status = HAL_ERROR;
898 }
899#if defined (DUAL_BANK)
900 else if (FLASH_CRC_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK)
901 {
902 status = HAL_ERROR;
903 }
904#endif /* DUAL_BANK */
905 else
906 {
907 status = HAL_OK;
908 }
909
910 if (status == HAL_OK)
911 {
912 /* Set OPTSTRT Bit */
913 SET_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTSTART);
914
915 /* Wait for OB change operation to be completed */
916 status = FLASH_OB_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
917 }
918
919 return status;
920}
921
922/**
923 * @}
924 */
925
926/** @defgroup FLASH_Exported_Functions_Group3 Peripheral State and Errors functions
927 * @brief Peripheral Errors functions
928 *
929@verbatim
930 ===============================================================================
931 ##### Peripheral Errors functions #####
932 ===============================================================================
933 [..]
934 This subsection permits to get in run-time Errors of the FLASH peripheral.
935
936@endverbatim
937 * @{
938 */
939
940/**
941 * @brief Get the specific FLASH error flag.
942 * @retval HAL_FLASH_ERRORCode The returned value can be:
943 * @arg HAL_FLASH_ERROR_NONE : No error set
944 *
945 * @arg HAL_FLASH_ERROR_WRP_BANK1 : Write Protection Error on Bank 1
946 * @arg HAL_FLASH_ERROR_PGS_BANK1 : Program Sequence Error on Bank 1
947 * @arg HAL_FLASH_ERROR_STRB_BANK1 : Strobe Error on Bank 1
948 * @arg HAL_FLASH_ERROR_INC_BANK1 : Inconsistency Error on Bank 1
949 * @arg HAL_FLASH_ERROR_OPE_BANK1 : Operation Error on Bank 1
950 * @arg HAL_FLASH_ERROR_RDP_BANK1 : Read Protection Error on Bank 1
951 * @arg HAL_FLASH_ERROR_RDS_BANK1 : Read Secured Error on Bank 1
952 * @arg HAL_FLASH_ERROR_SNECC_BANK1: ECC Single Correction Error on Bank 1
953 * @arg HAL_FLASH_ERROR_DBECC_BANK1: ECC Double Detection Error on Bank 1
954 * @arg HAL_FLASH_ERROR_CRCRD_BANK1: CRC Read Error on Bank 1
955 *
956 * @arg HAL_FLASH_ERROR_WRP_BANK2 : Write Protection Error on Bank 2
957 * @arg HAL_FLASH_ERROR_PGS_BANK2 : Program Sequence Error on Bank 2
958 * @arg HAL_FLASH_ERROR_STRB_BANK2 : Strobe Error on Bank 2
959 * @arg HAL_FLASH_ERROR_INC_BANK2 : Inconsistency Error on Bank 2
960 * @arg HAL_FLASH_ERROR_OPE_BANK2 : Operation Error on Bank 2
961 * @arg HAL_FLASH_ERROR_RDP_BANK2 : Read Protection Error on Bank 2
962 * @arg HAL_FLASH_ERROR_RDS_BANK2 : Read Secured Error on Bank 2
963 * @arg HAL_FLASH_ERROR_SNECC_BANK2: SNECC Error on Bank 2
964 * @arg HAL_FLASH_ERROR_DBECC_BANK2: Double Detection ECC on Bank 2
965 * @arg HAL_FLASH_ERROR_CRCRD_BANK2: CRC Read Error on Bank 2
966*/
967
968uint32_t HAL_FLASH_GetError(void)
969{
970 return pFlash.ErrorCode;
971}
972
973/**
974 * @}
975 */
976
977/**
978 * @}
979 */
980
981/* Private functions ---------------------------------------------------------*/
982
983/** @addtogroup FLASH_Private_Functions
984 * @{
985 */
986
987/**
988 * @brief Wait for a FLASH operation to complete.
989 * @param Timeout maximum flash operation timeout
990 * @param Bank flash FLASH_BANK_1 or FLASH_BANK_2
991 * @retval HAL_StatusTypeDef HAL Status
992 */
993HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout, uint32_t Bank)
994{
995 (void)Timeout;
996
997 /* Wait for the FLASH operation to complete by polling on QW flag to be reset.
998 Even if the FLASH operation fails, the QW flag will be reset and an error
999 flag will be set */
1000
1001 uint32_t bsyflag = FLASH_FLAG_QW_BANK1;
1002 uint32_t errorflag = FLASH->SR1 & FLASH_FLAG_ALL_ERRORS_BANK1;
1003 //uint32_t tickstart = HAL_GetTick();
1004
1005 assert_param(IS_FLASH_BANK_EXCLUSIVE(Bank));
1006
1007#if defined (DUAL_BANK)
1008
1009 if (Bank == FLASH_BANK_2)
1010 {
1011 /* Get Error Flags */
1012 errorflag = (FLASH->SR2 & FLASH_FLAG_ALL_ERRORS_BANK2) | 0x80000000U;
1013 /* Select bsyflag depending on Bank */
1014 bsyflag = FLASH_FLAG_QW_BANK2;
1015 }
1016#endif /* DUAL_BANK */
1017
1018 while(__HAL_FLASH_GET_FLAG(bsyflag))
1019 {
1020 if(Timeout != HAL_MAX_DELAY)
1021 {
1022 // todo: implement rusEfi own timeout
1023 // if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1024 // {
1025 // return HAL_TIMEOUT;
1026 // }
1027 }
1028 }
1029
1030 /* In case of error reported in Flash SR1 or SR2 register */
1031 if((errorflag & 0x7FFFFFFFU) != 0U)
1032 {
1033 /*Save the error code*/
1034 pFlash.ErrorCode |= errorflag;
1035
1036 /* Clear error programming flags */
1037 __HAL_FLASH_CLEAR_FLAG(errorflag);
1038
1039 return HAL_ERROR;
1040 }
1041
1042 /* Check FLASH End of Operation flag */
1043 if(Bank == FLASH_BANK_1)
1044 {
1045 if (__HAL_FLASH_GET_FLAG_BANK1(FLASH_FLAG_EOP_BANK1))
1046 {
1047 /* Clear FLASH End of Operation pending bit */
1048 __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_EOP_BANK1);
1049 }
1050 }
1051#if defined (DUAL_BANK)
1052 else
1053 {
1054 if (__HAL_FLASH_GET_FLAG_BANK2(FLASH_FLAG_EOP_BANK2))
1055 {
1056 /* Clear FLASH End of Operation pending bit */
1057 __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_EOP_BANK2);
1058 }
1059 }
1060#endif /* DUAL_BANK */
1061
1062 return HAL_OK;
1063}
1064
1065/**
1066 * @brief Wait for a FLASH Option Bytes change operation to complete.
1067 * @param Timeout maximum flash operation timeout
1068 * @retval HAL_StatusTypeDef HAL Status
1069 */
1070HAL_StatusTypeDef FLASH_OB_WaitForLastOperation(uint32_t Timeout)
1071{
1072 (void)Timeout;
1073 /* Get timeout */
1074 //uint32_t tickstart = HAL_GetTick();
1075
1076 /* Wait for the FLASH Option Bytes change operation to complete by polling on OPT_BUSY flag to be reset */
1077 while(READ_BIT(FLASH->OPTSR_CUR, FLASH_OPTSR_OPT_BUSY) != 0U)
1078 {
1079 // TODO: rusefi own timeout
1080 /*if(Timeout != HAL_MAX_DELAY)
1081 {
1082 if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1083 {
1084 return HAL_TIMEOUT;
1085 }
1086 }*/
1087 }
1088
1089 /* Check option byte change error */
1090 if(READ_BIT(FLASH->OPTSR_CUR, FLASH_OPTSR_OPTCHANGEERR) != 0U)
1091 {
1092 /* Save the error code */
1093 pFlash.ErrorCode |= HAL_FLASH_ERROR_OB_CHANGE;
1094
1095 /* Clear the OB error flag */
1096 FLASH->OPTCCR |= FLASH_OPTCCR_CLR_OPTCHANGEERR;
1097
1098 return HAL_ERROR;
1099 }
1100
1101 /* If there is no error flag set */
1102 return HAL_OK;
1103}
1104
1105/**
1106 * @brief Wait for a FLASH CRC computation to complete.
1107 * @param Timeout maximum flash operation timeout
1108 * @param Bank flash FLASH_BANK_1 or FLASH_BANK_2
1109 * @retval HAL_StatusTypeDef HAL Status
1110 */
1111HAL_StatusTypeDef FLASH_CRC_WaitForLastOperation(uint32_t Timeout, uint32_t Bank)
1112{
1113 uint32_t bsyflag;
1114 (void)Timeout;
1115 //uint32_t tickstart = HAL_GetTick();
1116
1117 assert_param(IS_FLASH_BANK_EXCLUSIVE(Bank));
1118
1119 /* Select bsyflag depending on Bank */
1120 if(Bank == FLASH_BANK_1)
1121 {
1122 bsyflag = FLASH_FLAG_CRC_BUSY_BANK1;
1123 }
1124 else
1125 {
1126 bsyflag = FLASH_FLAG_CRC_BUSY_BANK2;
1127 }
1128
1129 /* Wait for the FLASH CRC computation to complete by polling on CRC_BUSY flag to be reset */
1130 while(__HAL_FLASH_GET_FLAG(bsyflag))
1131 {
1132 // TODO: rusefi own timeout
1133 // if(Timeout != HAL_MAX_DELAY)
1134 // {
1135 // if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1136 // {
1137 // return HAL_TIMEOUT;
1138 // }
1139 // }
1140 }
1141
1142 /* Check FLASH CRC read error flag */
1143 if(Bank == FLASH_BANK_1)
1144 {
1145 if (__HAL_FLASH_GET_FLAG_BANK1(FLASH_FLAG_CRCRDERR_BANK1))
1146 {
1147 /* Save the error code */
1148 pFlash.ErrorCode |= HAL_FLASH_ERROR_CRCRD_BANK1;
1149
1150 /* Clear FLASH CRC read error pending bit */
1151 __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_CRCRDERR_BANK1);
1152
1153 return HAL_ERROR;
1154 }
1155 }
1156#if defined (DUAL_BANK)
1157 else
1158 {
1159 if (__HAL_FLASH_GET_FLAG_BANK2(FLASH_FLAG_CRCRDERR_BANK2))
1160 {
1161 /* Save the error code */
1162 pFlash.ErrorCode |= HAL_FLASH_ERROR_CRCRD_BANK2;
1163
1164 /* Clear FLASH CRC read error pending bit */
1165 __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_CRCRDERR_BANK2);
1166
1167 return HAL_ERROR;
1168 }
1169 }
1170#endif /* DUAL_BANK */
1171
1172 /* If there is no error flag set */
1173 return HAL_OK;
1174}
1175
1176/**
1177 * @}
1178 */
1179
1180#endif /* HAL_FLASH_MODULE_ENABLED */
1181
1182/**
1183 * @}
1184 */
1185
1186/**
1187 * @}
1188 */
1189
1190/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
void HAL_FLASH_IRQHandler(void)
This function handles FLASH interrupt request.
__weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
FLASH operation error interrupt callback.
__weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
FLASH end of operation interrupt callback.
HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
Program flash words of 256 bits at a specified address with interrupt enabled.
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
Program flash word at a specified address.
HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
Launch the option byte loading.
HAL_StatusTypeDef HAL_FLASH_Unlock(void)
Unlock the FLASH control register access.
HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
Lock the FLASH Option Control Registers access.
HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
Unlock the FLASH Option Control Registers access.
HAL_StatusTypeDef HAL_FLASH_Lock(void)
Locks the FLASH control register access.
uint32_t HAL_FLASH_GetError(void)
Get the specific FLASH error flag.
HAL_StatusTypeDef FLASH_CRC_WaitForLastOperation(uint32_t Timeout, uint32_t Bank)
Wait for a FLASH CRC computation to complete.
HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout, uint32_t Bank)
Wait for a FLASH operation to complete.
HAL_StatusTypeDef FLASH_OB_WaitForLastOperation(uint32_t Timeout)
Wait for a FLASH Option Bytes change operation to complete.
void FLASH_Erase_Sector(uint32_t Sector, uint8_t VoltageRange)
Erase the specified FLASH memory sector.
FLASH_ProcessTypeDef pFlash
Header file of FLASH HAL module.
Header file of FLASH HAL module.
FLASH handle Structure definition
__IO FLASH_ProcedureTypeDef ProcedureOnGoing