38
|
1 /**
|
|
2 ******************************************************************************
|
|
3 * @file stm32f4xx_hal_flash.c
|
|
4 * @author MCD Application Team
|
|
5 * @version V1.2.0
|
|
6 * @date 26-December-2014
|
|
7 * @brief FLASH HAL module driver.
|
|
8 * This file provides firmware functions to manage the following
|
|
9 * functionalities of the internal FLASH memory:
|
|
10 * + Program operations functions
|
|
11 * + Memory Control functions
|
|
12 * + Peripheral Errors functions
|
|
13 *
|
|
14 @verbatim
|
|
15 ==============================================================================
|
|
16 ##### FLASH peripheral features #####
|
|
17 ==============================================================================
|
|
18
|
|
19 [..] The Flash memory interface manages CPU AHB I-Code and D-Code accesses
|
|
20 to the Flash memory. It implements the erase and program Flash memory operations
|
|
21 and the read and write protection mechanisms.
|
|
22
|
|
23 [..] The Flash memory interface accelerates code execution with a system of instruction
|
|
24 prefetch and cache lines.
|
|
25
|
|
26 [..] The FLASH main features are:
|
|
27 (+) Flash memory read operations
|
|
28 (+) Flash memory program/erase operations
|
|
29 (+) Read / write protections
|
|
30 (+) Prefetch on I-Code
|
|
31 (+) 64 cache lines of 128 bits on I-Code
|
|
32 (+) 8 cache lines of 128 bits on D-Code
|
|
33
|
|
34
|
|
35 ##### How to use this driver #####
|
|
36 ==============================================================================
|
|
37 [..]
|
|
38 This driver provides functions and macros to configure and program the FLASH
|
|
39 memory of all STM32F4xx devices.
|
|
40
|
|
41 (#) FLASH Memory IO Programming functions:
|
|
42 (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
|
|
43 HAL_FLASH_Lock() functions
|
|
44 (++) Program functions: byte, half word, word and double word
|
|
45 (++) There Two modes of programming :
|
|
46 (+++) Polling mode using HAL_FLASH_Program() function
|
|
47 (+++) Interrupt mode using HAL_FLASH_Program_IT() function
|
|
48
|
|
49 (#) Interrupts and flags management functions :
|
|
50 (++) Handle FLASH interrupts by calling HAL_FLASH_IRQHandler()
|
|
51 (++) Wait for last FLASH operation according to its status
|
|
52 (++) Get error flag status by calling HAL_SetErrorCode()
|
|
53
|
|
54 [..]
|
|
55 In addition to these functions, this driver includes a set of macros allowing
|
|
56 to handle the following operations:
|
|
57 (+) Set the latency
|
|
58 (+) Enable/Disable the prefetch buffer
|
|
59 (+) Enable/Disable the Instruction cache and the Data cache
|
|
60 (+) Reset the Instruction cache and the Data cache
|
|
61 (+) Enable/Disable the FLASH interrupts
|
|
62 (+) Monitor the FLASH flags status
|
|
63
|
|
64 @endverbatim
|
|
65 ******************************************************************************
|
|
66 * @attention
|
|
67 *
|
|
68 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
|
|
69 *
|
|
70 * Redistribution and use in source and binary forms, with or without modification,
|
|
71 * are permitted provided that the following conditions are met:
|
|
72 * 1. Redistributions of source code must retain the above copyright notice,
|
|
73 * this list of conditions and the following disclaimer.
|
|
74 * 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
75 * this list of conditions and the following disclaimer in the documentation
|
|
76 * and/or other materials provided with the distribution.
|
|
77 * 3. Neither the name of STMicroelectronics nor the names of its contributors
|
|
78 * may be used to endorse or promote products derived from this software
|
|
79 * without specific prior written permission.
|
|
80 *
|
|
81 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
82 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
83 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
84 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
85 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
86 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
87 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
88 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
89 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
90 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
91 *
|
|
92 ******************************************************************************
|
|
93 */
|
|
94
|
|
95 /* Includes ------------------------------------------------------------------*/
|
|
96 #include "stm32f4xx_hal.h"
|
|
97
|
|
98 /** @addtogroup STM32F4xx_HAL_Driver
|
|
99 * @{
|
|
100 */
|
|
101
|
|
102 /** @defgroup FLASH FLASH
|
|
103 * @brief FLASH HAL module driver
|
|
104 * @{
|
|
105 */
|
|
106
|
|
107 #ifdef HAL_FLASH_MODULE_ENABLED
|
|
108
|
|
109 /* Private typedef -----------------------------------------------------------*/
|
|
110 /* Private define ------------------------------------------------------------*/
|
|
111 /** @addtogroup FLASH_Private_Constants
|
|
112 * @{
|
|
113 */
|
|
114 #define SECTOR_MASK ((uint32_t)0xFFFFFF07)
|
|
115 #define FLASH_TIMEOUT_VALUE ((uint32_t)50000)/* 50 s */
|
|
116 /**
|
|
117 * @}
|
|
118 */
|
|
119 /* Private macro -------------------------------------------------------------*/
|
|
120 /* Private variables ---------------------------------------------------------*/
|
|
121 /** @addtogroup FLASH_Private_Variables
|
|
122 * @{
|
|
123 */
|
|
124 /* Variable used for Erase sectors under interruption */
|
|
125 FLASH_ProcessTypeDef pFlash;
|
|
126 /**
|
|
127 * @}
|
|
128 */
|
|
129
|
|
130 /* Private function prototypes -----------------------------------------------*/
|
|
131 /** @addtogroup FLASH_Private_Functions
|
|
132 * @{
|
|
133 */
|
|
134 /* Program operations */
|
|
135 static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data);
|
|
136 static void FLASH_Program_Word(uint32_t Address, uint32_t Data);
|
|
137 static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data);
|
|
138 static void FLASH_Program_Byte(uint32_t Address, uint8_t Data);
|
|
139 static void FLASH_SetErrorCode(void);
|
|
140
|
|
141 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout);
|
|
142 /**
|
|
143 * @}
|
|
144 */
|
|
145
|
|
146 /* Exported functions --------------------------------------------------------*/
|
|
147 /** @defgroup FLASH_Exported_Functions FLASH Exported Functions
|
|
148 * @{
|
|
149 */
|
|
150
|
|
151 /** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions
|
|
152 * @brief Programming operation functions
|
|
153 *
|
|
154 @verbatim
|
|
155 ===============================================================================
|
|
156 ##### Programming operation functions #####
|
|
157 ===============================================================================
|
|
158 [..]
|
|
159 This subsection provides a set of functions allowing to manage the FLASH
|
|
160 program operations.
|
|
161
|
|
162 @endverbatim
|
|
163 * @{
|
|
164 */
|
|
165
|
|
166 /**
|
|
167 * @brief Program byte, halfword, word or double word at a specified address
|
|
168 * @param TypeProgram: Indicate the way to program at a specified address.
|
|
169 * This parameter can be a value of @ref FLASH_Type_Program
|
|
170 * @param Address: specifies the address to be programmed.
|
|
171 * @param Data: specifies the data to be programmed
|
|
172 *
|
|
173 * @retval HAL_StatusTypeDef HAL Status
|
|
174 */
|
|
175 HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
|
|
176 {
|
|
177 HAL_StatusTypeDef status = HAL_ERROR;
|
|
178
|
|
179 /* Process Locked */
|
|
180 __HAL_LOCK(&pFlash);
|
|
181
|
|
182 /* Check the parameters */
|
|
183 assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
|
|
184
|
|
185 /* Wait for last operation to be completed */
|
|
186 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
|
|
187
|
|
188 if(status == HAL_OK)
|
|
189 {
|
|
190 if(TypeProgram == FLASH_TYPEPROGRAM_BYTE)
|
|
191 {
|
|
192 /*Program byte (8-bit) at a specified address.*/
|
|
193 FLASH_Program_Byte(Address, (uint8_t) Data);
|
|
194 }
|
|
195 else if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
|
|
196 {
|
|
197 /*Program halfword (16-bit) at a specified address.*/
|
|
198 FLASH_Program_HalfWord(Address, (uint16_t) Data);
|
|
199 }
|
|
200 else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
|
|
201 {
|
|
202 /*Program word (32-bit) at a specified address.*/
|
|
203 FLASH_Program_Word(Address, (uint32_t) Data);
|
|
204 }
|
|
205 else
|
|
206 {
|
|
207 /*Program double word (64-bit) at a specified address.*/
|
|
208 FLASH_Program_DoubleWord(Address, Data);
|
|
209 }
|
|
210
|
|
211 /* Wait for last operation to be completed */
|
|
212 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
|
|
213
|
|
214 /* If the program operation is completed, disable the PG Bit */
|
|
215 FLASH->CR &= (~FLASH_CR_PG);
|
|
216 }
|
|
217
|
|
218 /* Process Unlocked */
|
|
219 __HAL_UNLOCK(&pFlash);
|
|
220
|
|
221 return status;
|
|
222 }
|
|
223
|
|
224 /**
|
|
225 * @brief Program byte, halfword, word or double word at a specified address with interrupt enabled.
|
|
226 * @param TypeProgram: Indicate the way to program at a specified address.
|
|
227 * This parameter can be a value of @ref FLASH_Type_Program
|
|
228 * @param Address: specifies the address to be programmed.
|
|
229 * @param Data: specifies the data to be programmed
|
|
230 *
|
|
231 * @retval HAL Status
|
|
232 */
|
|
233 HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
|
|
234 {
|
|
235 HAL_StatusTypeDef status = HAL_OK;
|
|
236
|
|
237 /* Process Locked */
|
|
238 __HAL_LOCK(&pFlash);
|
|
239
|
|
240 /* Check the parameters */
|
|
241 assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
|
|
242
|
|
243 /* Enable End of FLASH Operation interrupt */
|
|
244 __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP);
|
|
245
|
|
246 /* Enable Error source interrupt */
|
|
247 __HAL_FLASH_ENABLE_IT(FLASH_IT_ERR);
|
|
248
|
|
249 /* Clear pending flags (if any) */
|
|
250 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |\
|
|
251 FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR| FLASH_FLAG_PGSERR);
|
|
252
|
|
253 pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM;
|
|
254 pFlash.Address = Address;
|
|
255
|
|
256 if(TypeProgram == FLASH_TYPEPROGRAM_BYTE)
|
|
257 {
|
|
258 /*Program byte (8-bit) at a specified address.*/
|
|
259 FLASH_Program_Byte(Address, (uint8_t) Data);
|
|
260 }
|
|
261 else if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
|
|
262 {
|
|
263 /*Program halfword (16-bit) at a specified address.*/
|
|
264 FLASH_Program_HalfWord(Address, (uint16_t) Data);
|
|
265 }
|
|
266 else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
|
|
267 {
|
|
268 /*Program word (32-bit) at a specified address.*/
|
|
269 FLASH_Program_Word(Address, (uint32_t) Data);
|
|
270 }
|
|
271 else
|
|
272 {
|
|
273 /*Program double word (64-bit) at a specified address.*/
|
|
274 FLASH_Program_DoubleWord(Address, Data);
|
|
275 }
|
|
276
|
|
277 return status;
|
|
278 }
|
|
279
|
|
280 /**
|
|
281 * @brief This function handles FLASH interrupt request.
|
|
282 * @retval None
|
|
283 */
|
|
284 void HAL_FLASH_IRQHandler(void)
|
|
285 {
|
|
286 uint32_t temp;
|
|
287
|
|
288 /* If the program operation is completed, disable the PG Bit */
|
|
289 FLASH->CR &= (~FLASH_CR_PG);
|
|
290
|
|
291 /* If the erase operation is completed, disable the SER Bit */
|
|
292 FLASH->CR &= (~FLASH_CR_SER);
|
|
293 FLASH->CR &= SECTOR_MASK;
|
|
294
|
|
295 /* if the erase operation is completed, disable the MER Bit */
|
|
296 FLASH->CR &= (~FLASH_MER_BIT);
|
|
297
|
|
298 /* Check FLASH End of Operation flag */
|
|
299 if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != RESET)
|
|
300 {
|
|
301 if(pFlash.ProcedureOnGoing == FLASH_PROC_SECTERASE)
|
|
302 {
|
|
303 /*Nb of sector to erased can be decreased*/
|
|
304 pFlash.NbSectorsToErase--;
|
|
305
|
|
306 /* Check if there are still sectors to erase*/
|
|
307 if(pFlash.NbSectorsToErase != 0)
|
|
308 {
|
|
309 temp = pFlash.Sector;
|
|
310 /*Indicate user which sector has been erased*/
|
|
311 HAL_FLASH_EndOfOperationCallback(temp);
|
|
312
|
|
313 /* Clear pending flags (if any) */
|
|
314 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |\
|
|
315 FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR| FLASH_FLAG_PGSERR);
|
|
316
|
|
317 /*Increment sector number*/
|
|
318 temp = ++pFlash.Sector;
|
|
319 FLASH_Erase_Sector(temp, pFlash.VoltageForErase);
|
|
320 }
|
|
321 else
|
|
322 {
|
|
323 /*No more sectors to Erase, user callback can be called.*/
|
|
324 /*Reset Sector and stop Erase sectors procedure*/
|
|
325 pFlash.Sector = temp = 0xFFFFFFFF;
|
|
326 pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
|
|
327 /* FLASH EOP interrupt user callback */
|
|
328 HAL_FLASH_EndOfOperationCallback(temp);
|
|
329 /* Clear FLASH End of Operation pending bit */
|
|
330 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
|
|
331 }
|
|
332 }
|
|
333 else
|
|
334 {
|
|
335 if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE)
|
|
336 {
|
|
337 /*MassErase ended. Return the selected bank*/
|
|
338 /* FLASH EOP interrupt user callback */
|
|
339 HAL_FLASH_EndOfOperationCallback(pFlash.Bank);
|
|
340 }
|
|
341 else
|
|
342 {
|
|
343 /*Program ended. Return the selected address*/
|
|
344 /* FLASH EOP interrupt user callback */
|
|
345 HAL_FLASH_EndOfOperationCallback(pFlash.Address);
|
|
346 }
|
|
347 pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
|
|
348 /* Clear FLASH End of Operation pending bit */
|
|
349 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
|
|
350 }
|
|
351
|
|
352 }
|
|
353
|
|
354 /* Check FLASH operation error flags */
|
|
355 if(__HAL_FLASH_GET_FLAG((FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | \
|
|
356 FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR | FLASH_FLAG_RDERR)) != RESET)
|
|
357 {
|
|
358 if(pFlash.ProcedureOnGoing == FLASH_PROC_SECTERASE)
|
|
359 {
|
|
360 /*return the faulty sector*/
|
|
361 temp = pFlash.Sector;
|
|
362 pFlash.Sector = 0xFFFFFFFF;
|
|
363 }
|
|
364 else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE)
|
|
365 {
|
|
366 /*return the faulty bank*/
|
|
367 temp = pFlash.Bank;
|
|
368 }
|
|
369 else
|
|
370 {
|
|
371 /*return the faulty address*/
|
|
372 temp = pFlash.Address;
|
|
373 }
|
|
374
|
|
375 /*Save the Error code*/
|
|
376 FLASH_SetErrorCode();
|
|
377
|
|
378 /* FLASH error interrupt user callback */
|
|
379 HAL_FLASH_OperationErrorCallback(temp);
|
|
380 /* Clear FLASH error pending bits */
|
|
381 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR |\
|
|
382 FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR | FLASH_FLAG_RDERR);
|
|
383
|
|
384 /*Stop the procedure ongoing*/
|
|
385 pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
|
|
386 }
|
|
387
|
|
388 if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
|
|
389 {
|
|
390 /* Disable End of FLASH Operation interrupt */
|
|
391 __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP);
|
|
392
|
|
393 /* Disable Error source interrupt */
|
|
394 __HAL_FLASH_DISABLE_IT(FLASH_IT_ERR);
|
|
395
|
|
396 /* Process Unlocked */
|
|
397 __HAL_UNLOCK(&pFlash);
|
|
398 }
|
|
399
|
|
400 }
|
|
401
|
|
402 /**
|
|
403 * @brief FLASH end of operation interrupt callback
|
|
404 * @param ReturnValue: The value saved in this parameter depends on the ongoing procedure
|
|
405 * Mass Erase: Bank number which has been requested to erase
|
|
406 * Sectors Erase: Sector which has been erased
|
|
407 * (if 0xFFFFFFFF, it means that all the selected sectors have been erased)
|
|
408 * Program: Address which was selected for data program
|
|
409 * @retval None
|
|
410 */
|
|
411 __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
|
|
412 {
|
|
413 /* NOTE : This function Should not be modified, when the callback is needed,
|
|
414 the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
|
|
415 */
|
|
416 }
|
|
417
|
|
418 /**
|
|
419 * @brief FLASH operation error interrupt callback
|
|
420 * @param ReturnValue: The value saved in this parameter depends on the ongoing procedure
|
|
421 * Mass Erase: Bank number which has been requested to erase
|
|
422 * Sectors Erase: Sector number which returned an error
|
|
423 * Program: Address which was selected for data program
|
|
424 * @retval None
|
|
425 */
|
|
426 __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
|
|
427 {
|
|
428 /* NOTE : This function Should not be modified, when the callback is needed,
|
|
429 the HAL_FLASH_OperationErrorCallback could be implemented in the user file
|
|
430 */
|
|
431 }
|
|
432
|
|
433 /**
|
|
434 * @}
|
|
435 */
|
|
436
|
|
437 /** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
|
|
438 * @brief management functions
|
|
439 *
|
|
440 @verbatim
|
|
441 ===============================================================================
|
|
442 ##### Peripheral Control functions #####
|
|
443 ===============================================================================
|
|
444 [..]
|
|
445 This subsection provides a set of functions allowing to control the FLASH
|
|
446 memory operations.
|
|
447
|
|
448 @endverbatim
|
|
449 * @{
|
|
450 */
|
|
451
|
|
452 /**
|
|
453 * @brief Unlock the FLASH control register access
|
|
454 * @retval HAL Status
|
|
455 */
|
|
456 HAL_StatusTypeDef HAL_FLASH_Unlock(void)
|
|
457 {
|
|
458 if((FLASH->CR & FLASH_CR_LOCK) != RESET)
|
|
459 {
|
|
460 /* Authorize the FLASH Registers access */
|
|
461 FLASH->KEYR = FLASH_KEY1;
|
|
462 FLASH->KEYR = FLASH_KEY2;
|
|
463 }
|
|
464 else
|
|
465 {
|
|
466 return HAL_ERROR;
|
|
467 }
|
|
468
|
|
469 return HAL_OK;
|
|
470 }
|
|
471
|
|
472 /**
|
|
473 * @brief Locks the FLASH control register access
|
|
474 * @retval HAL Status
|
|
475 */
|
|
476 HAL_StatusTypeDef HAL_FLASH_Lock(void)
|
|
477 {
|
|
478 /* Set the LOCK Bit to lock the FLASH Registers access */
|
|
479 FLASH->CR |= FLASH_CR_LOCK;
|
|
480
|
|
481 return HAL_OK;
|
|
482 }
|
|
483
|
|
484 /**
|
|
485 * @brief Unlock the FLASH Option Control Registers access.
|
|
486 * @retval HAL Status
|
|
487 */
|
|
488 HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
|
|
489 {
|
|
490 if((FLASH->OPTCR & FLASH_OPTCR_OPTLOCK) != RESET)
|
|
491 {
|
|
492 /* Authorizes the Option Byte register programming */
|
|
493 FLASH->OPTKEYR = FLASH_OPT_KEY1;
|
|
494 FLASH->OPTKEYR = FLASH_OPT_KEY2;
|
|
495 }
|
|
496 else
|
|
497 {
|
|
498 return HAL_ERROR;
|
|
499 }
|
|
500
|
|
501 return HAL_OK;
|
|
502 }
|
|
503
|
|
504 /**
|
|
505 * @brief Lock the FLASH Option Control Registers access.
|
|
506 * @retval HAL Status
|
|
507 */
|
|
508 HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
|
|
509 {
|
|
510 /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
|
|
511 FLASH->OPTCR |= FLASH_OPTCR_OPTLOCK;
|
|
512
|
|
513 return HAL_OK;
|
|
514 }
|
|
515
|
|
516 /**
|
|
517 * @brief Launch the option byte loading.
|
|
518 * @retval HAL Status
|
|
519 */
|
|
520 HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
|
|
521 {
|
|
522 /* Set the OPTSTRT bit in OPTCR register */
|
|
523 *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS |= FLASH_OPTCR_OPTSTRT;
|
|
524
|
|
525 /* Wait for last operation to be completed */
|
|
526 return(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE));
|
|
527 }
|
|
528
|
|
529 /**
|
|
530 * @}
|
|
531 */
|
|
532
|
|
533 /** @defgroup FLASH_Exported_Functions_Group3 Peripheral State and Errors functions
|
|
534 * @brief Peripheral Errors functions
|
|
535 *
|
|
536 @verbatim
|
|
537 ===============================================================================
|
|
538 ##### Peripheral Errors functions #####
|
|
539 ===============================================================================
|
|
540 [..]
|
|
541 This subsection permits to get in run-time Errors of the FLASH peripheral.
|
|
542
|
|
543 @endverbatim
|
|
544 * @{
|
|
545 */
|
|
546
|
|
547 /**
|
|
548 * @brief Get the specific FLASH error flag.
|
|
549 * @retval FLASH_ErrorCode: The returned value can be a combination of:
|
|
550 * @arg HAL_FLASH_ERROR_RD: FLASH Read Protection error flag (PCROP)
|
|
551 * @arg HAL_FLASH_ERROR_PGS: FLASH Programming Sequence error flag
|
|
552 * @arg HAL_FLASH_ERROR_PGP: FLASH Programming Parallelism error flag
|
|
553 * @arg HAL_FLASH_ERROR_PGA: FLASH Programming Alignment error flag
|
|
554 * @arg HAL_FLASH_ERROR_WRP: FLASH Write protected error flag
|
|
555 * @arg HAL_FLASH_ERROR_OPERATION: FLASH operation Error flag
|
|
556 */
|
|
557 uint32_t HAL_FLASH_GetError(void)
|
|
558 {
|
|
559 return pFlash.ErrorCode;
|
|
560 }
|
|
561
|
|
562 /**
|
|
563 * @}
|
|
564 */
|
|
565
|
|
566 /**
|
|
567 * @brief Wait for a FLASH operation to complete.
|
|
568 * @param Timeout: maximum flash operationtimeout
|
|
569 * @retval HAL Status
|
|
570 */
|
|
571 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
|
|
572 {
|
|
573 uint32_t tickstart = 0;
|
|
574
|
|
575 /* Clear Error Code */
|
|
576 pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
|
|
577
|
|
578 /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
|
|
579 Even if the FLASH operation fails, the BUSY flag will be reset and an error
|
|
580 flag will be set */
|
|
581 /* Get tick */
|
|
582 tickstart = HAL_GetTick();
|
|
583
|
|
584 while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != RESET)
|
|
585 {
|
|
586 if(Timeout != HAL_MAX_DELAY)
|
|
587 {
|
|
588 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
|
|
589 {
|
|
590 return HAL_TIMEOUT;
|
|
591 }
|
|
592 }
|
|
593 }
|
|
594
|
|
595 if(__HAL_FLASH_GET_FLAG((FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | \
|
|
596 FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR | FLASH_FLAG_RDERR)) != RESET)
|
|
597 {
|
|
598 /*Save the error code*/
|
|
599 FLASH_SetErrorCode();
|
|
600 return HAL_ERROR;
|
|
601 }
|
|
602
|
|
603 /* If there is an error flag set */
|
|
604 return HAL_OK;
|
|
605
|
|
606 }
|
|
607
|
|
608 /**
|
|
609 * @brief Program a double word (64-bit) at a specified address.
|
|
610 * @note This function must be used when the device voltage range is from
|
|
611 * 2.7V to 3.6V and an External Vpp is present.
|
|
612 *
|
|
613 * @note If an erase and a program operations are requested simultaneously,
|
|
614 * the erase operation is performed before the program one.
|
|
615 *
|
|
616 * @param Address: specifies the address to be programmed.
|
|
617 * @param Data: specifies the data to be programmed.
|
|
618 * @retval None
|
|
619 */
|
|
620 static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data)
|
|
621 {
|
|
622 /* Check the parameters */
|
|
623 assert_param(IS_FLASH_ADDRESS(Address));
|
|
624
|
|
625 /* If the previous operation is completed, proceed to program the new data */
|
|
626 FLASH->CR &= CR_PSIZE_MASK;
|
|
627 FLASH->CR |= FLASH_PSIZE_DOUBLE_WORD;
|
|
628 FLASH->CR |= FLASH_CR_PG;
|
|
629
|
|
630 *(__IO uint64_t*)Address = Data;
|
|
631 }
|
|
632
|
|
633
|
|
634 /**
|
|
635 * @brief Program word (32-bit) at a specified address.
|
|
636 * @note This function must be used when the device voltage range is from
|
|
637 * 2.7V to 3.6V.
|
|
638 *
|
|
639 * @note If an erase and a program operations are requested simultaneously,
|
|
640 * the erase operation is performed before the program one.
|
|
641 *
|
|
642 * @param Address: specifies the address to be programmed.
|
|
643 * @param Data: specifies the data to be programmed.
|
|
644 * @retval None
|
|
645 */
|
|
646 static void FLASH_Program_Word(uint32_t Address, uint32_t Data)
|
|
647 {
|
|
648 /* Check the parameters */
|
|
649 assert_param(IS_FLASH_ADDRESS(Address));
|
|
650
|
|
651 /* If the previous operation is completed, proceed to program the new data */
|
|
652 FLASH->CR &= CR_PSIZE_MASK;
|
|
653 FLASH->CR |= FLASH_PSIZE_WORD;
|
|
654 FLASH->CR |= FLASH_CR_PG;
|
|
655
|
|
656 *(__IO uint32_t*)Address = Data;
|
|
657 }
|
|
658
|
|
659 /**
|
|
660 * @brief Program a half-word (16-bit) at a specified address.
|
|
661 * @note This function must be used when the device voltage range is from
|
|
662 * 2.7V to 3.6V.
|
|
663 *
|
|
664 * @note If an erase and a program operations are requested simultaneously,
|
|
665 * the erase operation is performed before the program one.
|
|
666 *
|
|
667 * @param Address: specifies the address to be programmed.
|
|
668 * @param Data: specifies the data to be programmed.
|
|
669 * @retval None
|
|
670 */
|
|
671 static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data)
|
|
672 {
|
|
673 /* Check the parameters */
|
|
674 assert_param(IS_FLASH_ADDRESS(Address));
|
|
675
|
|
676 /* If the previous operation is completed, proceed to program the new data */
|
|
677 FLASH->CR &= CR_PSIZE_MASK;
|
|
678 FLASH->CR |= FLASH_PSIZE_HALF_WORD;
|
|
679 FLASH->CR |= FLASH_CR_PG;
|
|
680
|
|
681 *(__IO uint16_t*)Address = Data;
|
|
682 }
|
|
683
|
|
684 /**
|
|
685 * @brief Program byte (8-bit) at a specified address.
|
|
686 * @note This function must be used when the device voltage range is from
|
|
687 * 2.7V to 3.6V.
|
|
688 *
|
|
689 * @note If an erase and a program operations are requested simultaneously,
|
|
690 * the erase operation is performed before the program one.
|
|
691 *
|
|
692 * @param Address: specifies the address to be programmed.
|
|
693 * @param Data: specifies the data to be programmed.
|
|
694 * @retval None
|
|
695 */
|
|
696 static void FLASH_Program_Byte(uint32_t Address, uint8_t Data)
|
|
697 {
|
|
698 /* Check the parameters */
|
|
699 assert_param(IS_FLASH_ADDRESS(Address));
|
|
700
|
|
701 /* If the previous operation is completed, proceed to program the new data */
|
|
702 FLASH->CR &= CR_PSIZE_MASK;
|
|
703 FLASH->CR |= FLASH_PSIZE_BYTE;
|
|
704 FLASH->CR |= FLASH_CR_PG;
|
|
705
|
|
706 *(__IO uint8_t*)Address = Data;
|
|
707 }
|
|
708
|
|
709 /**
|
|
710 * @brief Set the specific FLASH error flag.
|
|
711 * @retval None
|
|
712 */
|
|
713 static void FLASH_SetErrorCode(void)
|
|
714 {
|
|
715 if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) != RESET)
|
|
716 {
|
|
717 pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP;
|
|
718 }
|
|
719
|
|
720 if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR) != RESET)
|
|
721 {
|
|
722 pFlash.ErrorCode |= HAL_FLASH_ERROR_PGA;
|
|
723 }
|
|
724
|
|
725 if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGPERR) != RESET)
|
|
726 {
|
|
727 pFlash.ErrorCode |= HAL_FLASH_ERROR_PGP;
|
|
728 }
|
|
729
|
|
730 if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGSERR) != RESET)
|
|
731 {
|
|
732 pFlash.ErrorCode |= HAL_FLASH_ERROR_PGS;
|
|
733 }
|
|
734
|
|
735 if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR) != RESET)
|
|
736 {
|
|
737 pFlash.ErrorCode |= HAL_FLASH_ERROR_RD;
|
|
738 }
|
|
739
|
|
740 if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPERR) != RESET)
|
|
741 {
|
|
742 pFlash.ErrorCode |= HAL_FLASH_ERROR_OPERATION;
|
|
743 }
|
|
744 }
|
|
745
|
|
746 /**
|
|
747 * @}
|
|
748 */
|
|
749
|
|
750 #endif /* HAL_FLASH_MODULE_ENABLED */
|
|
751
|
|
752 /**
|
|
753 * @}
|
|
754 */
|
|
755
|
|
756 /**
|
|
757 * @}
|
|
758 */
|
|
759
|
|
760 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|