2 ******************************************************************************
3 * @file stm32f3xx_hal_flash.c
4 * @author MCD Application Team
7 * @brief FLASH HAL module driver.
9 * This file provides firmware functions to manage the following
10 * functionalities of the internal FLASH memory:
11 * + Program operations functions
12 * + Memory Control functions
13 * + Peripheral State functions
16 ==============================================================================
17 ##### FLASH peripheral features #####
18 ==============================================================================
20 [..] The Flash memory interface manages CPU AHB I-Code and D-Code accesses
21 to the Flash memory. It implements the erase and program Flash memory operations
22 and the read and write protection mechanisms.
24 [..] The Flash memory interface accelerates code execution with a system of instruction
27 [..] The FLASH main features are:
28 (+) Flash memory read operations
29 (+) Flash memory program/erase operations
30 (+) Read / write protections
31 (+) Prefetch on I-Code
34 ##### How to use this driver #####
35 ==============================================================================
37 This driver provides functions and macros to configure and program the FLASH
38 memory of all STM32F3xx devices. These functions are split in 3 groups:
40 (#) FLASH Memory I/O Programming functions: this group includes all needed
41 functions to erase and program the main memory:
42 (++) Lock and Unlock the FLASH interface
43 (++) Erase function: Erase page, erase all pages
44 (++) Program functions: half word and word
46 (#) Option Bytes Programming functions: this group includes all needed
47 functions to manage the Option Bytes:
48 (++) Lock and Unlock the Option Bytes
49 (++) Erase Option Bytes
50 (++) Set/Reset the write protection
51 (++) Set the Read protection Level
52 (++) Program the user Option Bytes
53 (++) Program the data Option Bytes
54 (++) Launch the Option Bytes loader
56 (#) Interrupts and flags management functions : this group
57 includes all needed functions to:
58 (++) Handle FLASH interrupts
59 (++) Wait for last FLASH operation according to its status
60 (++) Get error flag status
62 [..] In addition to these function, this driver includes a set of macros allowing
63 to handle the following operations:
66 (+) Enable/Disable the prefetch buffer
67 (+) Enable/Disable the half cycle access
68 (+) Enable/Disable the FLASH interrupts
69 (+) Monitor the FLASH flags status
72 ******************************************************************************
75 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
77 * Redistribution and use in source and binary forms, with or without modification,
78 * are permitted provided that the following conditions are met:
79 * 1. Redistributions of source code must retain the above copyright notice,
80 * this list of conditions and the following disclaimer.
81 * 2. Redistributions in binary form must reproduce the above copyright notice,
82 * this list of conditions and the following disclaimer in the documentation
83 * and/or other materials provided with the distribution.
84 * 3. Neither the name of STMicroelectronics nor the names of its contributors
85 * may be used to endorse or promote products derived from this software
86 * without specific prior written permission.
88 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
89 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
90 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
92 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
93 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
94 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
95 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
96 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
97 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99 ******************************************************************************
102 /* Includes ------------------------------------------------------------------*/
103 #include "stm32f3xx_hal.h"
105 /** @addtogroup STM32F3xx_HAL_Driver
109 /** @defgroup FLASH FLASH HAL module driver
110 * @brief FLASH HAL module driver
114 #ifdef HAL_FLASH_MODULE_ENABLED
116 /* Private typedef -----------------------------------------------------------*/
117 /* Private define ------------------------------------------------------------*/
118 /** @defgroup FLASH_Private_Defines FLASH Private Define
121 #define HAL_FLASH_TIMEOUT_VALUE ((uint32_t)50000)/* 50 s */
126 /* Private macro -------------------------------------------------------------*/
127 /* Private variables ---------------------------------------------------------*/
128 /** @defgroup FLASH_Private_Variables FLASH Private Variables
131 /* Variables used for Erase pages under interruption*/
132 FLASH_ProcessTypeDef pFlash;
137 /* Private function prototypes -----------------------------------------------*/
138 /** @defgroup FLASH_Private_Functions FLASH Private Functions
141 /* Program operations */
142 static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data);
143 static void FLASH_SetErrorCode(void);
148 /* Exported functions ---------------------------------------------------------*/
149 /** @defgroup FLASH_Exported_Functions FLASH Exported Functions
153 /** @defgroup FLASH_Exported_Functions_Group1 Input and Output operation functions
154 * @brief Data transfers functions
157 ===============================================================================
158 ##### IO operation functions #####
159 ===============================================================================
161 This subsection provides a set of functions allowing to manage the FLASH
162 program operations (write/erase).
169 * @brief Program halfword, word or double word at a specified address
170 * @note The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
171 * The function HAL_FLASH_Lock() should be called after to lock the FLASH interface
173 * @note If an erase and a program operations are requested simultaneously,
174 * the erase operation is performed before the program one.
176 * @param TypeProgram: Indicate the way to program at a specified address.
177 * This parameter can be a value of @ref FLASH_Type_Program
178 * @param Address: Specifies the address to be programmed.
179 * @param Data: Specifies the data to be programmed
181 * @retval HAL_StatusTypeDef HAL Status
183 HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
185 HAL_StatusTypeDef status = HAL_ERROR;
187 uint8_t nbiterations = 0;
192 /* Check the parameters */
193 assert_param(IS_TYPEPROGRAM(TypeProgram));
194 assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
196 /* Wait for last operation to be completed */
197 status = FLASH_WaitForLastOperation((uint32_t)HAL_FLASH_TIMEOUT_VALUE);
201 if(TypeProgram == TYPEPROGRAM_HALFWORD)
203 /* Program halfword (16-bit) at a specified address. */
206 else if(TypeProgram == TYPEPROGRAM_WORD)
208 /* Program word (32-bit = 2*16-bit) at a specified address. */
213 /* Program double word (64-bit = 4*16-bit) at a specified address. */
217 for (index = 0; index < nbiterations; index++)
219 FLASH_Program_HalfWord((Address + (2*index)), (uint16_t)(Data >> (16*index)));
221 /* Wait for last operation to be completed */
222 status = FLASH_WaitForLastOperation((uint32_t)HAL_FLASH_TIMEOUT_VALUE);
224 /* Check FLASH End of Operation flag */
225 if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
227 /* Clear FLASH End of Operation pending bit */
228 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
231 /* If the program operation is completed, disable the PG Bit */
232 CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
236 /* Process Unlocked */
237 __HAL_UNLOCK(&pFlash);
243 * @brief Program halfword, word or double word at a specified address with interrupt enabled.
244 * @note The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
245 * The function HAL_FLASH_Lock() should be called after to lock the FLASH interface
247 * @note If an erase and a program operations are requested simultaneously,
248 * the erase operation is performed before the program one.
250 * @param TypeProgram: Indicate the way to program at a specified address.
251 * This parameter can be a value of @ref FLASH_Type_Program
252 * @param Address: Specifies the address to be programmed.
253 * @param Data: Specifies the data to be programmed
255 * @retval HAL_StatusTypeDef HAL Status
257 HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
259 HAL_StatusTypeDef status = HAL_OK;
264 /* Check the parameters */
265 assert_param(IS_TYPEPROGRAM(TypeProgram));
266 assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
268 /* Enable End of FLASH Operation and Error source interrupts */
269 __HAL_FLASH_ENABLE_IT((FLASH_IT_EOP | FLASH_IT_ERR));
271 pFlash.Address = Address;
274 if(TypeProgram == TYPEPROGRAM_HALFWORD)
276 pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMHALFWORD;
277 /*Program halfword (16-bit) at a specified address.*/
278 pFlash.DataRemaining = 1;
280 else if(TypeProgram == TYPEPROGRAM_WORD)
282 pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMWORD;
283 /*Program word (32-bit : 2*16-bit) at a specified address.*/
284 pFlash.DataRemaining = 2;
288 pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMDOUBLEWORD;
289 /*Program double word (64-bit : 4*16-bit) at a specified address.*/
290 pFlash.DataRemaining = 4;
293 /*Program halfword (16-bit) at a specified address.*/
294 FLASH_Program_HalfWord(Address, (uint16_t)Data);
300 * @brief This function handles FLASH interrupt request.
303 void HAL_FLASH_IRQHandler(void)
306 /* If the operation is completed, disable the PG, PER and MER Bits */
307 CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_PER | FLASH_CR_MER));
309 /* Check FLASH End of Operation flag */
310 if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
312 /* Clear FLASH End of Operation pending bit */
313 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
315 if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
317 /* Nb of pages to erased can be decreased */
318 pFlash.DataRemaining--;
320 /* Indicate user which page address has been erased*/
321 HAL_FLASH_EndOfOperationCallback(pFlash.Address);
323 /* Check if there are still pages to erase*/
324 if(pFlash.DataRemaining != 0)
326 /* Increment page address to next page */
327 pFlash.Address += FLASH_PAGE_SIZE;
328 addresstmp = pFlash.Address;
329 FLASH_PageErase(addresstmp);
333 /*No more pages to Erase*/
335 /*Reset Address and stop Erase pages procedure*/
336 pFlash.Address = 0xFFFFFFFF;
337 pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
340 else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE)
342 /*MassErase ended. Return the selected bank*/
343 /* FLASH EOP interrupt user callback */
344 HAL_FLASH_EndOfOperationCallback(0);
346 /* Stop Mass Erase procedure*/
347 pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
351 /* Nb of 16-bit data to program can be decreased */
352 pFlash.DataRemaining--;
354 /* Check if there are still 16-bit data to program */
355 if(pFlash.DataRemaining != 0)
357 /* Increment address to 16-bit */
359 addresstmp = pFlash.Address;
361 /* Shift to have next 16-bit data */
362 pFlash.Data = (pFlash.Data >> 16);
364 /*Program halfword (16-bit) at a specified address.*/
365 FLASH_Program_HalfWord(addresstmp, (uint16_t)pFlash.Data);
369 /*Program ended. Return the selected address*/
370 /* FLASH EOP interrupt user callback */
371 if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMHALFWORD)
373 HAL_FLASH_EndOfOperationCallback(pFlash.Address);
375 else if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMWORD)
377 HAL_FLASH_EndOfOperationCallback(pFlash.Address-2);
381 HAL_FLASH_EndOfOperationCallback(pFlash.Address-6);
384 /* Reset Address and stop Program procedure*/
385 pFlash.Address = 0xFFFFFFFF;
386 pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
391 /* Check FLASH operation error flags */
392 if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR))
394 /*Save the Error code*/
395 FLASH_SetErrorCode();
397 /* FLASH error interrupt user callback */
398 HAL_FLASH_OperationErrorCallback(pFlash.Address);
400 /* Clear FLASH error pending bits */
401 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR);
403 /* Reset address and stop the procedure ongoing*/
404 pFlash.Address = 0xFFFFFFFF;
405 pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
408 if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
410 /* Disable End of FLASH Operation and Error source interrupts */
411 __HAL_FLASH_DISABLE_IT((FLASH_IT_EOP | FLASH_IT_ERR));
413 /* Process Unlocked */
414 __HAL_UNLOCK(&pFlash);
420 * @brief FLASH end of operation interrupt callback
421 * @param ReturnValue: The value saved in this parameter depends on the ongoing procedure
422 * - Mass Erase: No return value expected
423 * - Pages Erase: Address of the page which has been erased
424 * - Program: Address which was selected for data program
427 __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
429 /* NOTE : This function Should not be modified, when the callback is needed,
430 the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
435 * @brief FLASH operation error interrupt callback
436 * @param ReturnValue: The value saved in this parameter depends on the ongoing procedure
437 * - Mass Erase: No return value expected
438 * - Pages Erase: Address of the page which returned an error
439 * - Program: Address which was selected for data program
442 __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
444 /* NOTE : This function Should not be modified, when the callback is needed,
445 the HAL_FLASH_OperationErrorCallback could be implemented in the user file
453 /** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
454 * @brief management functions
457 ===============================================================================
458 ##### Peripheral Control functions #####
459 ===============================================================================
461 This subsection provides a set of functions allowing to control the FLASH
469 * @brief Unlock the FLASH control register access
472 HAL_StatusTypeDef HAL_FLASH_Unlock(void)
474 if((READ_BIT(FLASH->CR, FLASH_CR_LOCK)) != RESET)
476 /* Authorize the FLASH Registers access */
477 WRITE_REG(FLASH->KEYR, FLASH_KEY1);
478 WRITE_REG(FLASH->KEYR, FLASH_KEY2);
489 * @brief Locks the FLASH control register access
492 HAL_StatusTypeDef HAL_FLASH_Lock(void)
494 /* Set the LOCK Bit to lock the FLASH Registers access */
495 SET_BIT(FLASH->CR, FLASH_CR_LOCK);
502 * @brief Unlock the FLASH Option Control Registers access.
505 HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
507 if((READ_BIT(FLASH->CR, FLASH_CR_OPTWRE)) == RESET)
509 /* Authorizes the Option Byte register programming */
510 WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1);
511 WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2);
522 * @brief Lock the FLASH Option Control Registers access.
525 HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
527 /* Clear the OPTWRE Bit to lock the FLASH Option Byte Registers access */
528 CLEAR_BIT(FLASH->CR, FLASH_CR_OPTWRE);
534 * @brief Launch the option byte loading.
537 HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
539 /* Set the bit to force the option byte reloading */
540 SET_BIT(FLASH->CR, FLASH_CR_OBL_LAUNCH);
542 /* Wait for last operation to be completed */
543 return(FLASH_WaitForLastOperation((uint32_t)HAL_FLASH_TIMEOUT_VALUE));
551 /** @defgroup FLASH_Exported_Functions_Group3 Peripheral State functions
552 * @brief Peripheral State functions
555 ===============================================================================
556 ##### Peripheral State functions #####
557 ===============================================================================
559 This subsection permit to get in run-time the status of the FLASH peripheral.
566 * @brief Get the specific FLASH error flag.
567 * @retval FLASH_ErrorCode: The returned value can be:
568 * @arg FLASH_ERROR_PG: FLASH Programming error flag
569 * @arg FLASH_ERROR_WRP: FLASH Write protected error flag
571 FLASH_ErrorTypeDef HAL_FLASH_GetError(void)
573 return pFlash.ErrorCode;
584 /** @addtogroup FLASH_Private_Functions FLASH Private Functions
588 * @brief Program a half-word (16-bit) at a specified address.
589 * @param Address: specifies the address to be programmed.
590 * @param Data: specifies the data to be programmed.
593 static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data)
595 /* Clear pending flags (if any) */
596 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR);
598 /* Proceed to program the new data */
599 SET_BIT(FLASH->CR, FLASH_CR_PG);
601 *(__IO uint16_t*)Address = Data;
605 * @brief Wait for a FLASH operation to complete.
606 * @param Timeout: maximum flash operationtimeout
607 * @retval HAL_StatusTypeDef HAL Status
609 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
611 /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
612 Even if the FLASH operation fails, the BUSY flag will be reset and an error
615 uint32_t tickstart = HAL_GetTick();
617 while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY))
619 if (Timeout != HAL_MAX_DELAY)
621 if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
628 if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR))
630 /*Save the error code*/
631 FLASH_SetErrorCode();
635 /* If there is an error flag set */
641 * @brief Erase the specified FLASH memory page
642 * @param PageAddress: FLASH page to erase
643 * The value of this parameter depend on device used within the same series
647 void FLASH_PageErase(uint32_t PageAddress)
649 /* Clear pending flags (if any) */
650 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR);
652 /* Proceed to erase the page */
653 SET_BIT(FLASH->CR, FLASH_CR_PER);
654 WRITE_REG(FLASH->AR, PageAddress);
655 SET_BIT(FLASH->CR, FLASH_CR_STRT);
659 * @brief Set the specific FLASH error flag.
662 static void FLASH_SetErrorCode(void)
664 if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR))
666 pFlash.ErrorCode = FLASH_ERROR_WRP;
668 if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR))
670 pFlash.ErrorCode |= FLASH_ERROR_PG;
678 #endif /* HAL_FLASH_MODULE_ENABLED */
688 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/