STM32F4xx_HAL_Driver  1.8.3
stm32f4xx_hal_flash.c
Go to the documentation of this file.
1 
75 /* Includes ------------------------------------------------------------------*/
76 #include "stm32f4xx_hal.h"
77 
87 #ifdef HAL_FLASH_MODULE_ENABLED
88 
89 /* Private typedef -----------------------------------------------------------*/
90 /* Private define ------------------------------------------------------------*/
94 #define FLASH_TIMEOUT_VALUE 50000U /* 50 s */
98 /* Private macro -------------------------------------------------------------*/
99 /* Private variables ---------------------------------------------------------*/
103 /* Variable used for Erase sectors under interruption */
104 FLASH_ProcessTypeDef pFlash;
109 /* Private function prototypes -----------------------------------------------*/
113 /* Program operations */
114 static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data);
115 static void FLASH_Program_Word(uint32_t Address, uint32_t Data);
116 static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data);
117 static void FLASH_Program_Byte(uint32_t Address, uint8_t Data);
118 static void FLASH_SetErrorCode(void);
119 
120 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout);
125 /* Exported functions --------------------------------------------------------*/
154 HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
155 {
156  HAL_StatusTypeDef status = HAL_ERROR;
157 
158  /* Process Locked */
159  __HAL_LOCK(&pFlash);
160 
161  /* Check the parameters */
162  assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
163 
164  /* Wait for last operation to be completed */
165  status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
166 
167  if (status == HAL_OK)
168  {
169  if (TypeProgram == FLASH_TYPEPROGRAM_BYTE)
170  {
171  /*Program byte (8-bit) at a specified address.*/
172  FLASH_Program_Byte(Address, (uint8_t) Data);
173  }
174  else if (TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
175  {
176  /*Program halfword (16-bit) at a specified address.*/
177  FLASH_Program_HalfWord(Address, (uint16_t) Data);
178  }
179  else if (TypeProgram == FLASH_TYPEPROGRAM_WORD)
180  {
181  /*Program word (32-bit) at a specified address.*/
182  FLASH_Program_Word(Address, (uint32_t) Data);
183  }
184  else
185  {
186  /*Program double word (64-bit) at a specified address.*/
187  FLASH_Program_DoubleWord(Address, Data);
188  }
189 
190  /* Wait for last operation to be completed */
191  status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
192 
193  /* If the program operation is completed, disable the PG Bit */
194  FLASH->CR &= (~FLASH_CR_PG);
195  }
196 
197  /* Process Unlocked */
198  __HAL_UNLOCK(&pFlash);
199 
200  return status;
201 }
202 
212 HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
213 {
214  HAL_StatusTypeDef status = HAL_OK;
215 
216  /* Check the parameters */
217  assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
218 
219  /* Enable End of FLASH Operation interrupt */
220  __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP);
221 
222  /* Enable Error source interrupt */
223  __HAL_FLASH_ENABLE_IT(FLASH_IT_ERR);
224 
225  pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM;
226  pFlash.Address = Address;
227 
228  if (TypeProgram == FLASH_TYPEPROGRAM_BYTE)
229  {
230  /*Program byte (8-bit) at a specified address.*/
231  FLASH_Program_Byte(Address, (uint8_t) Data);
232  }
233  else if (TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
234  {
235  /*Program halfword (16-bit) at a specified address.*/
236  FLASH_Program_HalfWord(Address, (uint16_t) Data);
237  }
238  else if (TypeProgram == FLASH_TYPEPROGRAM_WORD)
239  {
240  /*Program word (32-bit) at a specified address.*/
241  FLASH_Program_Word(Address, (uint32_t) Data);
242  }
243  else
244  {
245  /*Program double word (64-bit) at a specified address.*/
246  FLASH_Program_DoubleWord(Address, Data);
247  }
248 
249  return status;
250 }
251 
257 {
258  uint32_t addresstmp = 0U;
259 
260  /* Check FLASH operation error flags */
261 #if defined(FLASH_SR_RDERR)
262  if (__HAL_FLASH_GET_FLAG((FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | \
263  FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR | FLASH_FLAG_RDERR)) != RESET)
264 #else
265  if (__HAL_FLASH_GET_FLAG((FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | \
266  FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR)) != RESET)
267 #endif /* FLASH_SR_RDERR */
268  {
269  if (pFlash.ProcedureOnGoing == FLASH_PROC_SECTERASE)
270  {
271  /*return the faulty sector*/
272  addresstmp = pFlash.Sector;
273  pFlash.Sector = 0xFFFFFFFFU;
274  }
275  else if (pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE)
276  {
277  /*return the faulty bank*/
278  addresstmp = pFlash.Bank;
279  }
280  else
281  {
282  /*return the faulty address*/
283  addresstmp = pFlash.Address;
284  }
285 
286  /*Save the Error code*/
287  FLASH_SetErrorCode();
288 
289  /* FLASH error interrupt user callback */
291 
292  /*Stop the procedure ongoing*/
293  pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
294  }
295 
296  /* Check FLASH End of Operation flag */
297  if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != RESET)
298  {
299  /* Clear FLASH End of Operation pending bit */
300  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
301 
302  if (pFlash.ProcedureOnGoing == FLASH_PROC_SECTERASE)
303  {
304  /*Nb of sector to erased can be decreased*/
305  pFlash.NbSectorsToErase--;
306 
307  /* Check if there are still sectors to erase*/
308  if (pFlash.NbSectorsToErase != 0U)
309  {
310  addresstmp = pFlash.Sector;
311  /*Indicate user which sector has been erased*/
313 
314  /*Increment sector number*/
315  pFlash.Sector++;
316  addresstmp = pFlash.Sector;
317  FLASH_Erase_Sector(addresstmp, pFlash.VoltageForErase);
318  }
319  else
320  {
321  /*No more sectors to Erase, user callback can be called.*/
322  /*Reset Sector and stop Erase sectors procedure*/
323  pFlash.Sector = addresstmp = 0xFFFFFFFFU;
324  pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
325 
326  /* Flush the caches to be sure of the data consistency */
328 
329  /* FLASH EOP interrupt user callback */
331  }
332  }
333  else
334  {
335  if (pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE)
336  {
337  /* MassErase ended. Return the selected bank */
338  /* Flush the caches to be sure of the data consistency */
340 
341  /* FLASH EOP interrupt user callback */
343  }
344  else
345  {
346  /*Program ended. Return the selected address*/
347  /* FLASH EOP interrupt user callback */
348  HAL_FLASH_EndOfOperationCallback(pFlash.Address);
349  }
350  pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
351  }
352  }
353 
354  if (pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
355  {
356  /* Operation is completed, disable the PG, SER, SNB and MER Bits */
357  CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_SER | FLASH_CR_SNB | FLASH_MER_BIT));
358 
359  /* Disable End of FLASH Operation interrupt */
360  __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP);
361 
362  /* Disable Error source interrupt */
363  __HAL_FLASH_DISABLE_IT(FLASH_IT_ERR);
364  }
365 }
366 
376 __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
377 {
378  /* Prevent unused argument(s) compilation warning */
379  UNUSED(ReturnValue);
380  /* NOTE : This function Should not be modified, when the callback is needed,
381  the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
382  */
383 }
384 
393 __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
394 {
395  /* Prevent unused argument(s) compilation warning */
396  UNUSED(ReturnValue);
397  /* NOTE : This function Should not be modified, when the callback is needed,
398  the HAL_FLASH_OperationErrorCallback could be implemented in the user file
399  */
400 }
401 
425 HAL_StatusTypeDef HAL_FLASH_Unlock(void)
426 {
427  HAL_StatusTypeDef status = HAL_OK;
428 
429  if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET)
430  {
431  /* Authorize the FLASH Registers access */
432  WRITE_REG(FLASH->KEYR, FLASH_KEY1);
433  WRITE_REG(FLASH->KEYR, FLASH_KEY2);
434 
435  /* Verify Flash is unlocked */
436  if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET)
437  {
438  status = HAL_ERROR;
439  }
440  }
441 
442  return status;
443 }
444 
449 HAL_StatusTypeDef HAL_FLASH_Lock(void)
450 {
451  /* Set the LOCK Bit to lock the FLASH Registers access */
452  FLASH->CR |= FLASH_CR_LOCK;
453 
454  return HAL_OK;
455 }
456 
461 HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
462 {
463  if ((FLASH->OPTCR & FLASH_OPTCR_OPTLOCK) != RESET)
464  {
465  /* Authorizes the Option Byte register programming */
466  FLASH->OPTKEYR = FLASH_OPT_KEY1;
467  FLASH->OPTKEYR = FLASH_OPT_KEY2;
468  }
469  else
470  {
471  return HAL_ERROR;
472  }
473 
474  return HAL_OK;
475 }
476 
481 HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
482 {
483  /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
484  FLASH->OPTCR |= FLASH_OPTCR_OPTLOCK;
485 
486  return HAL_OK;
487 }
488 
493 HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
494 {
495  /* Set the OPTSTRT bit in OPTCR register */
496  *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS |= FLASH_OPTCR_OPTSTRT;
497 
498  /* Wait for last operation to be completed */
499  return (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE));
500 }
501 
530 uint32_t HAL_FLASH_GetError(void)
531 {
532  return pFlash.ErrorCode;
533 }
534 
544 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
545 {
546  uint32_t tickstart = 0U;
547 
548  /* Clear Error Code */
549  pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
550 
551  /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
552  Even if the FLASH operation fails, the BUSY flag will be reset and an error
553  flag will be set */
554  /* Get tick */
555  tickstart = HAL_GetTick();
556 
557  while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != RESET)
558  {
559  if (Timeout != HAL_MAX_DELAY)
560  {
561  if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
562  {
563  return HAL_TIMEOUT;
564  }
565  }
566  }
567 
568  /* Check FLASH End of Operation flag */
569  if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != RESET)
570  {
571  /* Clear FLASH End of Operation pending bit */
572  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
573  }
574 #if defined(FLASH_SR_RDERR)
575  if (__HAL_FLASH_GET_FLAG((FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | \
576  FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR | FLASH_FLAG_RDERR)) != RESET)
577 #else
578  if (__HAL_FLASH_GET_FLAG((FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | \
579  FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR)) != RESET)
580 #endif /* FLASH_SR_RDERR */
581  {
582  /*Save the error code*/
583  FLASH_SetErrorCode();
584  return HAL_ERROR;
585  }
586 
587  /* If there is no error flag set */
588  return HAL_OK;
589 
590 }
591 
604 static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data)
605 {
606  /* Check the parameters */
607  assert_param(IS_FLASH_ADDRESS(Address));
608 
609  /* If the previous operation is completed, proceed to program the new data */
610  CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
611  FLASH->CR |= FLASH_PSIZE_DOUBLE_WORD;
612  FLASH->CR |= FLASH_CR_PG;
613 
614  /* Program first word */
615  *(__IO uint32_t *)Address = (uint32_t)Data;
616 
617  /* Barrier to ensure programming is performed in 2 steps, in right order
618  (independently of compiler optimization behavior) */
619  __ISB();
620 
621  /* Program second word */
622  *(__IO uint32_t *)(Address + 4) = (uint32_t)(Data >> 32);
623 }
624 
625 
638 static void FLASH_Program_Word(uint32_t Address, uint32_t Data)
639 {
640  /* Check the parameters */
641  assert_param(IS_FLASH_ADDRESS(Address));
642 
643  /* If the previous operation is completed, proceed to program the new data */
644  CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
645  FLASH->CR |= FLASH_PSIZE_WORD;
646  FLASH->CR |= FLASH_CR_PG;
647 
648  *(__IO uint32_t *)Address = Data;
649 }
650 
663 static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data)
664 {
665  /* Check the parameters */
666  assert_param(IS_FLASH_ADDRESS(Address));
667 
668  /* If the previous operation is completed, proceed to program the new data */
669  CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
670  FLASH->CR |= FLASH_PSIZE_HALF_WORD;
671  FLASH->CR |= FLASH_CR_PG;
672 
673  *(__IO uint16_t *)Address = Data;
674 }
675 
688 static void FLASH_Program_Byte(uint32_t Address, uint8_t Data)
689 {
690  /* Check the parameters */
691  assert_param(IS_FLASH_ADDRESS(Address));
692 
693  /* If the previous operation is completed, proceed to program the new data */
694  CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
695  FLASH->CR |= FLASH_PSIZE_BYTE;
696  FLASH->CR |= FLASH_CR_PG;
697 
698  *(__IO uint8_t *)Address = Data;
699 }
700 
705 static void FLASH_SetErrorCode(void)
706 {
707  if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) != RESET)
708  {
709  pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP;
710 
711  /* Clear FLASH write protection error pending bit */
712  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR);
713  }
714 
715  if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR) != RESET)
716  {
717  pFlash.ErrorCode |= HAL_FLASH_ERROR_PGA;
718 
719  /* Clear FLASH Programming alignment error pending bit */
720  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGAERR);
721  }
722 
723  if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGPERR) != RESET)
724  {
725  pFlash.ErrorCode |= HAL_FLASH_ERROR_PGP;
726 
727  /* Clear FLASH Programming parallelism error pending bit */
728  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGPERR);
729  }
730 
731  if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGSERR) != RESET)
732  {
733  pFlash.ErrorCode |= HAL_FLASH_ERROR_PGS;
734 
735  /* Clear FLASH Programming sequence error pending bit */
736  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGSERR);
737  }
738 #if defined(FLASH_SR_RDERR)
739  if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR) != RESET)
740  {
741  pFlash.ErrorCode |= HAL_FLASH_ERROR_RD;
742 
743  /* Clear FLASH Proprietary readout protection error pending bit */
744  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_RDERR);
745  }
746 #endif /* FLASH_SR_RDERR */
747  if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPERR) != RESET)
748  {
749  pFlash.ErrorCode |= HAL_FLASH_ERROR_OPERATION;
750 
751  /* Clear FLASH Operation error pending bit */
752  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPERR);
753  }
754 }
755 
760 #endif /* HAL_FLASH_MODULE_ENABLED */
761 
void FLASH_FlushCaches(void)
Flush the instruction and data caches.
void FLASH_Erase_Sector(uint32_t Sector, uint8_t VoltageRange)
Erase the specified FLASH memory sector.
void HAL_FLASH_IRQHandler(void)
This function handles FLASH interrupt request.
void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
FLASH operation error interrupt callback.
void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
FLASH end of operation interrupt callback.
HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
Program byte, halfword, word or double word at a specified address with interrupt enabled.
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
Program byte, halfword, word or double 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.
FLASH handle Structure definition.
HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
Wait for a FLASH operation to complete.
uint32_t HAL_GetTick(void)
Provides a tick value in millisecond.
This file contains all the functions prototypes for the HAL module driver.