STM32L4xx_HAL_Driver  1.14.0
stm32l4xx_hal_flash.c
Go to the documentation of this file.
1 
89 /* Includes ------------------------------------------------------------------*/
90 #include "stm32l4xx_hal.h"
91 
101 #ifdef HAL_FLASH_MODULE_ENABLED
102 
103 /* Private typedef -----------------------------------------------------------*/
104 /* Private defines -----------------------------------------------------------*/
105 #if defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
106 #define FLASH_NB_DOUBLE_WORDS_IN_ROW 64
107 #else
108 #define FLASH_NB_DOUBLE_WORDS_IN_ROW 32
109 #endif
110 /* Private macros ------------------------------------------------------------*/
111 /* Private variables ---------------------------------------------------------*/
119  .ErrorCode = HAL_FLASH_ERROR_NONE, \
120  .ProcedureOnGoing = FLASH_PROC_NONE, \
121  .Address = 0U, \
122  .Bank = FLASH_BANK_1, \
123  .Page = 0U, \
124  .NbPagesToErase = 0U, \
125  .CacheToReactivate = FLASH_CACHE_DISABLED};
130 /* Private function prototypes -----------------------------------------------*/
134 static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data);
135 static void FLASH_Program_Fast(uint32_t Address, uint32_t DataAddress);
140 /* Exported functions --------------------------------------------------------*/
171 HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
172 {
173  HAL_StatusTypeDef status;
174  uint32_t prog_bit = 0;
175 
176  /* Process Locked */
177  __HAL_LOCK(&pFlash);
178 
179  /* Check the parameters */
180  assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
181 
182  /* Wait for last operation to be completed */
183  status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
184 
185  if(status == HAL_OK)
186  {
187  pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
188 
189  /* Deactivate the data cache if they are activated to avoid data misbehavior */
190  if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != 0U)
191  {
192  /* Disable data cache */
193  __HAL_FLASH_DATA_CACHE_DISABLE();
195  }
196  else
197  {
199  }
200 
201  if(TypeProgram == FLASH_TYPEPROGRAM_DOUBLEWORD)
202  {
203  /* Program double-word (64-bit) at a specified address */
204  FLASH_Program_DoubleWord(Address, Data);
205  prog_bit = FLASH_CR_PG;
206  }
207  else if((TypeProgram == FLASH_TYPEPROGRAM_FAST) || (TypeProgram == FLASH_TYPEPROGRAM_FAST_AND_LAST))
208  {
209  /* Fast program a 32 row double-word (64-bit) at a specified address */
210  FLASH_Program_Fast(Address, (uint32_t)Data);
211 
212  /* If it is the last row, the bit will be cleared at the end of the operation */
213  if(TypeProgram == FLASH_TYPEPROGRAM_FAST_AND_LAST)
214  {
215  prog_bit = FLASH_CR_FSTPG;
216  }
217  }
218  else
219  {
220  /* Nothing to do */
221  }
222 
223  /* Wait for last operation to be completed */
224  status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
225 
226  /* If the program operation is completed, disable the PG or FSTPG Bit */
227  if (prog_bit != 0U)
228  {
229  CLEAR_BIT(FLASH->CR, prog_bit);
230  }
231 
232  /* Flush the caches to be sure of the data consistency */
234  }
235 
236  /* Process Unlocked */
237  __HAL_UNLOCK(&pFlash);
238 
239  return status;
240 }
241 
253 HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
254 {
255  HAL_StatusTypeDef status = HAL_OK;
256 
257  /* Check the parameters */
258  assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
259 
260  /* Process Locked */
261  __HAL_LOCK(&pFlash);
262 
263  pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
264 
265  /* Deactivate the data cache if they are activated to avoid data misbehavior */
266  if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != 0U)
267  {
268  /* Disable data cache */
269  __HAL_FLASH_DATA_CACHE_DISABLE();
271  }
272  else
273  {
275  }
276 
277  /* Set internal variables used by the IRQ handler */
278  if(TypeProgram == FLASH_TYPEPROGRAM_FAST_AND_LAST)
279  {
281  }
282  else
283  {
285  }
286  pFlash.Address = Address;
287 
288  /* Enable End of Operation and Error interrupts */
289  __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR);
290 
291  if(TypeProgram == FLASH_TYPEPROGRAM_DOUBLEWORD)
292  {
293  /* Program double-word (64-bit) at a specified address */
294  FLASH_Program_DoubleWord(Address, Data);
295  }
296  else if((TypeProgram == FLASH_TYPEPROGRAM_FAST) || (TypeProgram == FLASH_TYPEPROGRAM_FAST_AND_LAST))
297  {
298  /* Fast program a 32 row double-word (64-bit) at a specified address */
299  FLASH_Program_Fast(Address, (uint32_t)Data);
300  }
301  else
302  {
303  /* Nothing to do */
304  }
305 
306  return status;
307 }
308 
314 {
315  uint32_t tmp_page;
316  uint32_t error;
317  FLASH_ProcedureTypeDef procedure;
318 
319  /* If the operation is completed, disable the PG, PNB, MER1, MER2 and PER Bit */
320  CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_MER1 | FLASH_CR_PER | FLASH_CR_PNB));
321 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
322  defined (STM32L496xx) || defined (STM32L4A6xx) || \
323  defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
324  CLEAR_BIT(FLASH->CR, FLASH_CR_MER2);
325 #endif
326 
327  /* Disable the FSTPG Bit only if it is the last row programmed */
329  {
330  CLEAR_BIT(FLASH->CR, FLASH_CR_FSTPG);
331  }
332 
333  /* Check FLASH operation error flags */
334  error = (FLASH->SR & FLASH_FLAG_SR_ERRORS);
335  error |= (FLASH->ECCR & FLASH_FLAG_ECCC);
336 
337  if (error !=0U)
338  {
339  /*Save the error code*/
340  pFlash.ErrorCode |= error;
341 
342  /* Clear error programming flags */
343  __HAL_FLASH_CLEAR_FLAG(error);
344 
345  /* Flush the caches to be sure of the data consistency */
347 
348  /* FLASH error interrupt user callback */
349  procedure = pFlash.ProcedureOnGoing;
350  if(procedure == FLASH_PROC_PAGE_ERASE)
351  {
353  }
354  else if(procedure == FLASH_PROC_MASS_ERASE)
355  {
357  }
358  else if((procedure == FLASH_PROC_PROGRAM) ||
359  (procedure == FLASH_PROC_PROGRAM_LAST))
360  {
362  }
363  else
364  {
366  }
367 
368  /*Stop the procedure ongoing*/
370  }
371 
372  /* Check FLASH End of Operation flag */
373  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != 0U)
374  {
375  /* Clear FLASH End of Operation pending bit */
376  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
377 
379  {
380  /* Nb of pages to erased can be decreased */
381  pFlash.NbPagesToErase--;
382 
383  /* Check if there are still pages to erase*/
384  if(pFlash.NbPagesToErase != 0U)
385  {
386  /* Indicate user which page has been erased*/
388 
389  /* Increment page number */
390  pFlash.Page++;
391  tmp_page = pFlash.Page;
392  FLASH_PageErase(tmp_page, pFlash.Bank);
393  }
394  else
395  {
396  /* No more pages to Erase */
397  /* Reset Address and stop Erase pages procedure */
398  pFlash.Page = 0xFFFFFFFFU;
400 
401  /* Flush the caches to be sure of the data consistency */
403 
404  /* FLASH EOP interrupt user callback */
406  }
407  }
408  else
409  {
410  /* Flush the caches to be sure of the data consistency */
412 
413  procedure = pFlash.ProcedureOnGoing;
414  if(procedure == FLASH_PROC_MASS_ERASE)
415  {
416  /* MassErase ended. Return the selected bank */
417  /* FLASH EOP interrupt user callback */
419  }
420  else if((procedure == FLASH_PROC_PROGRAM) ||
421  (procedure == FLASH_PROC_PROGRAM_LAST))
422  {
423  /* Program ended. Return the selected address */
424  /* FLASH EOP interrupt user callback */
426  }
427  else
428  {
429  /* Nothing to do */
430  }
431 
432  /*Clear the procedure ongoing*/
434  }
435  }
436 
437  if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
438  {
439  /* Disable End of Operation and Error interrupts */
440  __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR);
441 
442  /* Process Unlocked */
443  __HAL_UNLOCK(&pFlash);
444  }
445 }
446 
456 __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
457 {
458  /* Prevent unused argument(s) compilation warning */
459  UNUSED(ReturnValue);
460 
461  /* NOTE : This function should not be modified, when the callback is needed,
462  the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
463  */
464 }
465 
474 __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
475 {
476  /* Prevent unused argument(s) compilation warning */
477  UNUSED(ReturnValue);
478 
479  /* NOTE : This function should not be modified, when the callback is needed,
480  the HAL_FLASH_OperationErrorCallback could be implemented in the user file
481  */
482 }
483 
507 HAL_StatusTypeDef HAL_FLASH_Unlock(void)
508 {
509  HAL_StatusTypeDef status = HAL_OK;
510 
511  if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0U)
512  {
513  /* Authorize the FLASH Registers access */
514  WRITE_REG(FLASH->KEYR, FLASH_KEY1);
515  WRITE_REG(FLASH->KEYR, FLASH_KEY2);
516 
517  /* Verify Flash is unlocked */
518  if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0U)
519  {
520  status = HAL_ERROR;
521  }
522  }
523 
524  return status;
525 }
526 
531 HAL_StatusTypeDef HAL_FLASH_Lock(void)
532 {
533  /* Set the LOCK Bit to lock the FLASH Registers access */
534  SET_BIT(FLASH->CR, FLASH_CR_LOCK);
535 
536  return HAL_OK;
537 }
538 
543 HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
544 {
545  if(READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK) != 0U)
546  {
547  /* Authorizes the Option Byte register programming */
548  WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1);
549  WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2);
550  }
551  else
552  {
553  return HAL_ERROR;
554  }
555 
556  return HAL_OK;
557 }
558 
563 HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
564 {
565  /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
566  SET_BIT(FLASH->CR, FLASH_CR_OPTLOCK);
567 
568  return HAL_OK;
569 }
570 
575 HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
576 {
577  /* Set the bit to force the option byte reloading */
578  SET_BIT(FLASH->CR, FLASH_CR_OBL_LAUNCH);
579 
580  /* Wait for last operation to be completed */
581  return(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE));
582 }
583 
625 uint32_t HAL_FLASH_GetError(void)
626 {
627  return pFlash.ErrorCode;
628 }
629 
638 /* Private functions ---------------------------------------------------------*/
639 
649 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
650 {
651  /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
652  Even if the FLASH operation fails, the BUSY flag will be reset and an error
653  flag will be set */
654 
655  uint32_t tickstart = HAL_GetTick();
656  uint32_t error;
657 
658  while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY))
659  {
660  if(Timeout != HAL_MAX_DELAY)
661  {
662  if((HAL_GetTick() - tickstart) >= Timeout)
663  {
664  return HAL_TIMEOUT;
665  }
666  }
667  }
668 
669  error = (FLASH->SR & FLASH_FLAG_SR_ERRORS);
670  error |= (FLASH->ECCR & FLASH_FLAG_ECCD);
671 
672  if(error != 0u)
673  {
674  /*Save the error code*/
675  pFlash.ErrorCode |= error;
676 
677  /* Clear error programming flags */
678  __HAL_FLASH_CLEAR_FLAG(error);
679 
680  return HAL_ERROR;
681  }
682 
683  /* Check FLASH End of Operation flag */
684  if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
685  {
686  /* Clear FLASH End of Operation pending bit */
687  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
688  }
689 
690  /* If there is an error flag set */
691  return HAL_OK;
692 }
693 
700 static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data)
701 {
702  /* Check the parameters */
703  assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
704 
705  /* Set PG bit */
706  SET_BIT(FLASH->CR, FLASH_CR_PG);
707 
708  /* Program first word */
709  *(__IO uint32_t*)Address = (uint32_t)Data;
710 
711  /* Barrier to ensure programming is performed in 2 steps, in right order
712  (independently of compiler optimization behavior) */
713  __ISB();
714 
715  /* Program second word */
716  *(__IO uint32_t*)(Address+4U) = (uint32_t)(Data >> 32);
717 }
718 
725 static void FLASH_Program_Fast(uint32_t Address, uint32_t DataAddress)
726 {
727  uint32_t primask_bit;
728  uint8_t row_index = (2*FLASH_NB_DOUBLE_WORDS_IN_ROW);
729  __IO uint32_t *dest_addr = (__IO uint32_t*)Address;
730  __IO uint32_t *src_addr = (__IO uint32_t*)DataAddress;
731 
732  /* Check the parameters */
733  assert_param(IS_FLASH_MAIN_MEM_ADDRESS(Address));
734 
735  /* Set FSTPG bit */
736  SET_BIT(FLASH->CR, FLASH_CR_FSTPG);
737 
738  /* Disable interrupts to avoid any interruption during the loop */
739  primask_bit = __get_PRIMASK();
740  __disable_irq();
741 
742  /* Program the double word of the row */
743  do
744  {
745  *dest_addr = *src_addr;
746  dest_addr++;
747  src_addr++;
748  row_index--;
749  } while (row_index != 0U);
750 
751  /* Re-enable the interrupts */
752  __set_PRIMASK(primask_bit);
753 }
754 
759 #endif /* HAL_FLASH_MODULE_ENABLED */
760 
769 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
Program double word or fast program of a row at a specified address with interrupt enabled...
void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
FLASH operation error interrupt callback.
__IO FLASH_ProcedureTypeDef ProcedureOnGoing
void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
FLASH end of operation interrupt callback.
static void FLASH_Program_Fast(uint32_t Address, uint32_t DataAddress)
Fast program a row double-word (64-bit) at a specified address.
This file contains all the functions prototypes for the HAL module driver.
void FLASH_PageErase(uint32_t Page, uint32_t Banks)
Erase the specified FLASH memory page.
HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
Lock the FLASH Option Bytes Registers access.
HAL_StatusTypeDef HAL_FLASH_Lock(void)
Lock the FLASH control register access.
uint32_t HAL_GetTick(void)
Provide a tick value in millisecond.
__HAL_UNLOCK(hrtc)
HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
Launch the option byte loading.
FLASH_ProcedureTypeDef
FLASH Procedure structure definition.
CLEAR_BIT(hrtc->Instance->CR, RTC_CR_WUTE)
HAL_StatusTypeDef HAL_FLASH_Unlock(void)
Unlock the FLASH control register access.
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
Program double word or fast program of a row at a specified address.
void FLASH_FlushCaches(void)
Flush the instruction and data caches.
__HAL_LOCK(hrtc)
return HAL_OK
HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
Unlock the FLASH Option Bytes Registers access.
HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
Wait for a FLASH operation to complete.
void HAL_FLASH_IRQHandler(void)
Handle FLASH interrupt request.
FLASH handle Structure definition.
FLASH_ProcessTypeDef pFlash
Variable used for Program/Erase sectors under interruption.
uint32_t HAL_FLASH_GetError(void)
Get the specific FLASH error flag.
__IO FLASH_CacheTypeDef CacheToReactivate
static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data)
Program double-word (64-bit) at a specified address.
assert_param(IS_RTC_WAKEUP_CLOCK(WakeUpClock))