1 /**
2   ******************************************************************************
3   * @file    stm32f7xx_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 AHB 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 memory interface accelerates code execution with a system of instruction
22        prefetch and cache lines.
23 
24   [..] The FLASH main features are:
25       (+) Flash memory read operations
26       (+) Flash memory program/erase operations
27       (+) Read / write protections
28       (+) Prefetch on I-Code
29       (+) 64 cache lines of 128 bits on I-Code
30       (+) 8 cache lines of 128 bits on D-Code
31 
32                      ##### How to use this driver #####
33   ==============================================================================
34     [..]
35       This driver provides functions and macros to configure and program the FLASH
36       memory of all STM32F7xx devices.
37 
38       (#) FLASH Memory IO Programming functions:
39            (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
40                 HAL_FLASH_Lock() functions
41            (++) Program functions: byte, half word, word and double word
42            (++) There Two modes of programming :
43             (+++) Polling mode using HAL_FLASH_Program() function
44             (+++) Interrupt mode using HAL_FLASH_Program_IT() function
45 
46       (#) Interrupts and flags management functions :
47            (++) Handle FLASH interrupts by calling HAL_FLASH_IRQHandler()
48            (++) Wait for last FLASH operation according to its status
49            (++) Get error flag status by calling HAL_SetErrorCode()
50     [..]
51       In addition to these functions, this driver includes a set of macros allowing
52       to handle the following operations:
53        (+) Set the latency
54        (+) Enable/Disable the prefetch buffer
55        (+) Enable/Disable the Instruction cache and the Data cache
56        (+) Reset the Instruction cache and the Data cache
57        (+) Enable/Disable the FLASH interrupts
58        (+) Monitor the FLASH flags status
59     [..]
60 	(@) For any Flash memory program operation (erase or program), the CPU clock frequency
61         (HCLK) must be at least 1MHz.
62 	(@) The contents of the Flash memory are not guaranteed if a device reset occurs during
63 	    a Flash memory operation.
64     (@) Any attempt to read the Flash memory while it is being written or erased, causes the
65 	    bus to stall. Read operations are processed correctly once the program operation has
66 		completed. This means that code or data fetches cannot be performed while a write/erase
67 		operation is ongoing.
68 
69   @endverbatim
70   ******************************************************************************
71   * @attention
72   *
73   * Copyright (c) 2017 STMicroelectronics.
74   * All rights reserved.
75   *
76   * This software is licensed under terms that can be found in the LICENSE file in
77   * the root directory of this software component.
78   * If no LICENSE file comes with this software, it is provided AS-IS.
79   ******************************************************************************
80   */
81 
82 /* Includes ------------------------------------------------------------------*/
83 #include "stm32f7xx_hal.h"
84 
85 /** @addtogroup STM32F7xx_HAL_Driver
86   * @{
87   */
88 
89 /** @defgroup FLASH FLASH
90   * @brief FLASH HAL module driver
91   * @{
92   */
93 
94 #ifdef HAL_FLASH_MODULE_ENABLED
95 
96 /* Private typedef -----------------------------------------------------------*/
97 /* Private define ------------------------------------------------------------*/
98 /** @addtogroup FLASH_Private_Constants
99   * @{
100   */
101 #define SECTOR_MASK               ((uint32_t)0xFFFFFF07U)
102 #define FLASH_TIMEOUT_VALUE       ((uint32_t)50000U)/* 50 s */
103 /**
104   * @}
105   */
106 /* Private macro -------------------------------------------------------------*/
107 /* Private variables ---------------------------------------------------------*/
108 /** @addtogroup FLASH_Private_Variables
109   * @{
110   */
111 /* Variable used for Erase sectors under interruption */
112 FLASH_ProcessTypeDef pFlash;
113 /**
114   * @}
115   */
116 
117 /* Private function prototypes -----------------------------------------------*/
118 /** @addtogroup FLASH_Private_Functions
119   * @{
120   */
121 /* Program operations */
122 static void   FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data);
123 static void   FLASH_Program_Word(uint32_t Address, uint32_t Data);
124 static void   FLASH_Program_HalfWord(uint32_t Address, uint16_t Data);
125 static void   FLASH_Program_Byte(uint32_t Address, uint8_t Data);
126 static void   FLASH_SetErrorCode(void);
127 
128 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout);
129 /**
130   * @}
131   */
132 
133 /* Exported functions --------------------------------------------------------*/
134 /** @defgroup FLASH_Exported_Functions FLASH Exported Functions
135   * @{
136   */
137 
138 /** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions
139  *  @brief   Programming operation functions
140  *
141 @verbatim
142  ===============================================================================
143                   ##### Programming operation functions #####
144  ===============================================================================
145     [..]
146     This subsection provides a set of functions allowing to manage the FLASH
147     program operations.
148 
149 @endverbatim
150   * @{
151   */
152 
153 /**
154   * @brief  Program byte, halfword, word or double word at a specified address
155   * @param  TypeProgram  Indicate the way to program at a specified address.
156   *                           This parameter can be a value of @ref FLASH_Type_Program
157   * @param  Address  specifies the address to be programmed.
158   * @param  Data specifies the data to be programmed
159   *
160   * @retval HAL_StatusTypeDef HAL Status
161   */
HAL_FLASH_Program(uint32_t TypeProgram,uint32_t Address,uint64_t Data)162 HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
163 {
164   HAL_StatusTypeDef status = HAL_ERROR;
165 
166   /* Process Locked */
167   __HAL_LOCK(&pFlash);
168 
169   /* Check the parameters */
170   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
171 
172   /* Wait for last operation to be completed */
173   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
174 
175   if(status == HAL_OK)
176   {
177     switch(TypeProgram)
178     {
179       case FLASH_TYPEPROGRAM_BYTE :
180       {
181         /*Program byte (8-bit) at a specified address.*/
182         FLASH_Program_Byte(Address, (uint8_t) Data);
183         break;
184       }
185 
186       case FLASH_TYPEPROGRAM_HALFWORD :
187       {
188         /*Program halfword (16-bit) at a specified address.*/
189         FLASH_Program_HalfWord(Address, (uint16_t) Data);
190         break;
191       }
192 
193       case FLASH_TYPEPROGRAM_WORD :
194       {
195         /*Program word (32-bit) at a specified address.*/
196         FLASH_Program_Word(Address, (uint32_t) Data);
197         break;
198       }
199 
200       case FLASH_TYPEPROGRAM_DOUBLEWORD :
201       {
202         /*Program double word (64-bit) at a specified address.*/
203         FLASH_Program_DoubleWord(Address, Data);
204         break;
205       }
206       default :
207         break;
208     }
209     /* Wait for last operation to be completed */
210     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
211 
212     /* If the program operation is completed, disable the PG Bit */
213     FLASH->CR &= (~FLASH_CR_PG);
214   }
215 
216   /* Process Unlocked */
217   __HAL_UNLOCK(&pFlash);
218 
219   return status;
220 }
221 
222 /**
223   * @brief   Program byte, halfword, word or double word at a specified address  with interrupt enabled.
224   * @param  TypeProgram  Indicate the way to program at a specified address.
225   *                           This parameter can be a value of @ref FLASH_Type_Program
226   * @param  Address  specifies the address to be programmed.
227   * @param  Data specifies the data to be programmed
228   *
229   * @retval HAL Status
230   */
HAL_FLASH_Program_IT(uint32_t TypeProgram,uint32_t Address,uint64_t Data)231 HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
232 {
233   HAL_StatusTypeDef status = HAL_OK;
234 
235   /* Process Locked */
236   __HAL_LOCK(&pFlash);
237 
238   /* Check the parameters */
239   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
240 
241   /* Enable End of FLASH Operation interrupt */
242   __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP);
243 
244   /* Enable Error source interrupt */
245   __HAL_FLASH_ENABLE_IT(FLASH_IT_ERR);
246 
247   /* Clear pending flags (if any) */
248   __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP    | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |\
249                          FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR| FLASH_FLAG_ERSERR);
250 
251   pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM;
252   pFlash.Address = Address;
253 
254   switch(TypeProgram)
255   {
256     case FLASH_TYPEPROGRAM_BYTE :
257     {
258       /*Program byte (8-bit) at a specified address.*/
259       FLASH_Program_Byte(Address, (uint8_t) Data);
260       break;
261     }
262 
263     case FLASH_TYPEPROGRAM_HALFWORD :
264     {
265       /*Program halfword (16-bit) at a specified address.*/
266       FLASH_Program_HalfWord(Address, (uint16_t) Data);
267       break;
268     }
269 
270     case FLASH_TYPEPROGRAM_WORD :
271     {
272       /*Program word (32-bit) at a specified address.*/
273       FLASH_Program_Word(Address, (uint32_t) Data);
274       break;
275     }
276 
277     case FLASH_TYPEPROGRAM_DOUBLEWORD :
278     {
279       /*Program double word (64-bit) at a specified address.*/
280       FLASH_Program_DoubleWord(Address, Data);
281       break;
282     }
283     default :
284       break;
285   }
286   return status;
287 }
288 
289 /**
290   * @brief This function handles FLASH interrupt request.
291   * @retval None
292   */
HAL_FLASH_IRQHandler(void)293 void HAL_FLASH_IRQHandler(void)
294 {
295   uint32_t temp = 0;
296 
297   /* If the program operation is completed, disable the PG Bit */
298   FLASH->CR &= (~FLASH_CR_PG);
299 
300   /* If the erase operation is completed, disable the SER Bit */
301   FLASH->CR &= (~FLASH_CR_SER);
302   FLASH->CR &= SECTOR_MASK;
303 
304   /* if the erase operation is completed, disable the MER Bit */
305   FLASH->CR &= (~FLASH_MER_BIT);
306 
307   /* Check FLASH End of Operation flag  */
308   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != RESET)
309   {
310     /* Clear FLASH End of Operation pending bit */
311     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
312 
313     switch (pFlash.ProcedureOnGoing)
314     {
315       case FLASH_PROC_SECTERASE :
316       {
317         /* Nb of sector to erased can be decreased */
318         pFlash.NbSectorsToErase--;
319 
320         /* Check if there are still sectors to erase */
321         if(pFlash.NbSectorsToErase != 0)
322         {
323           temp = pFlash.Sector;
324           /* Indicate user which sector has been erased */
325           HAL_FLASH_EndOfOperationCallback(temp);
326 
327           /* Increment sector number */
328           temp = ++pFlash.Sector;
329           FLASH_Erase_Sector(temp, pFlash.VoltageForErase);
330         }
331         else
332         {
333           /* No more sectors to Erase, user callback can be called.*/
334           /* Reset Sector and stop Erase sectors procedure */
335           pFlash.Sector = temp = 0xFFFFFFFFU;
336           /* FLASH EOP interrupt user callback */
337           HAL_FLASH_EndOfOperationCallback(temp);
338           /* Sector Erase procedure is completed */
339           pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
340         }
341         break;
342       }
343 
344       case FLASH_PROC_MASSERASE :
345       {
346         /* MassErase ended. Return the selected bank : in this product we don't have Banks */
347         /* FLASH EOP interrupt user callback */
348         HAL_FLASH_EndOfOperationCallback(0);
349         /* MAss Erase procedure is completed */
350         pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
351         break;
352       }
353 
354       case FLASH_PROC_PROGRAM :
355       {
356         /*Program ended. Return the selected address*/
357         /* FLASH EOP interrupt user callback */
358         HAL_FLASH_EndOfOperationCallback(pFlash.Address);
359         /* Programming procedure is completed */
360         pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
361         break;
362       }
363       default :
364         break;
365     }
366   }
367 
368   /* Check FLASH operation error flags */
369   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_ALL_ERRORS) != RESET)
370   {
371     switch (pFlash.ProcedureOnGoing)
372     {
373       case FLASH_PROC_SECTERASE :
374       {
375         /* return the faulty sector */
376         temp = pFlash.Sector;
377         pFlash.Sector = 0xFFFFFFFFU;
378         break;
379       }
380       case FLASH_PROC_MASSERASE :
381       {
382         /* No return in case of Mass Erase */
383         temp = 0;
384         break;
385       }
386       case FLASH_PROC_PROGRAM :
387       {
388         /*return the faulty address*/
389         temp = pFlash.Address;
390         break;
391       }
392     default :
393       break;
394     }
395     /*Save the Error code*/
396     FLASH_SetErrorCode();
397 
398     /* FLASH error interrupt user callback */
399     HAL_FLASH_OperationErrorCallback(temp);
400 
401     /*Stop the procedure ongoing */
402     pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
403   }
404 
405   if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
406   {
407     /* Disable End of FLASH Operation interrupt */
408     __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP);
409 
410     /* Disable Error source interrupt */
411     __HAL_FLASH_DISABLE_IT(FLASH_IT_ERR);
412 
413     /* Process Unlocked */
414     __HAL_UNLOCK(&pFlash);
415   }
416 
417 }
418 
419 /**
420   * @brief  FLASH end of operation interrupt callback
421   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure
422   *                 - Sectors Erase: Sector which has been erased (if 0xFFFFFFFF, it means that
423   *                                  all the selected sectors have been erased)
424   *                 - Program      : Address which was selected for data program
425   *                 - Mass Erase   : No return value expected
426   * @retval None
427   */
HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)428 __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
429 {
430   /* Prevent unused argument(s) compilation warning */
431   UNUSED(ReturnValue);
432   /* NOTE : This function Should not be modified, when the callback is needed,
433   the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
434   */
435 }
436 
437 /**
438   * @brief  FLASH operation error interrupt callback
439   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure
440   *                 - Sectors Erase: Sector which has been erased (if 0xFFFFFFFF, it means that
441   *                                  all the selected sectors have been erased)
442   *                 - Program      : Address which was selected for data program
443   *                 - Mass Erase   : No return value expected
444   * @retval None
445   */
HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)446 __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
447 {
448   /* Prevent unused argument(s) compilation warning */
449   UNUSED(ReturnValue);
450   /* NOTE : This function Should not be modified, when the callback is needed,
451   the HAL_FLASH_OperationErrorCallback could be implemented in the user file
452    */
453 }
454 
455 /**
456   * @}
457   */
458 
459 /** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
460  *  @brief   management functions
461  *
462 @verbatim
463  ===============================================================================
464                       ##### Peripheral Control functions #####
465  ===============================================================================
466     [..]
467     This subsection provides a set of functions allowing to control the FLASH
468     memory operations.
469 
470 @endverbatim
471   * @{
472   */
473 
474 /**
475   * @brief  Unlock the FLASH control register access
476   * @retval HAL Status
477   */
HAL_FLASH_Unlock(void)478 HAL_StatusTypeDef HAL_FLASH_Unlock(void)
479 {
480   HAL_StatusTypeDef status = HAL_OK;
481 
482   if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET)
483   {
484     /* Authorize the FLASH Registers access */
485     WRITE_REG(FLASH->KEYR, FLASH_KEY1);
486     WRITE_REG(FLASH->KEYR, FLASH_KEY2);
487 
488     /* Verify Flash is unlocked */
489     if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET)
490     {
491       status = HAL_ERROR;
492     }
493   }
494 
495   return status;
496 }
497 
498 /**
499   * @brief  Locks the FLASH control register access
500   * @retval HAL Status
501   */
HAL_FLASH_Lock(void)502 HAL_StatusTypeDef HAL_FLASH_Lock(void)
503 {
504   /* Set the LOCK Bit to lock the FLASH Registers access */
505   FLASH->CR |= FLASH_CR_LOCK;
506 
507   return HAL_OK;
508 }
509 
510 /**
511   * @brief  Unlock the FLASH Option Control Registers access.
512   * @retval HAL Status
513   */
HAL_FLASH_OB_Unlock(void)514 HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
515 {
516   if((FLASH->OPTCR & FLASH_OPTCR_OPTLOCK) != RESET)
517   {
518     /* Authorizes the Option Byte register programming */
519     FLASH->OPTKEYR = FLASH_OPT_KEY1;
520     FLASH->OPTKEYR = FLASH_OPT_KEY2;
521   }
522   else
523   {
524     return HAL_ERROR;
525   }
526 
527   return HAL_OK;
528 }
529 
530 /**
531   * @brief  Lock the FLASH Option Control Registers access.
532   * @retval HAL Status
533   */
HAL_FLASH_OB_Lock(void)534 HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
535 {
536   /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
537   FLASH->OPTCR |= FLASH_OPTCR_OPTLOCK;
538 
539   return HAL_OK;
540 }
541 
542 /**
543   * @brief  Launch the option byte loading.
544   * @retval HAL Status
545   */
HAL_FLASH_OB_Launch(void)546 HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
547 {
548   /* Set the OPTSTRT bit in OPTCR register */
549   FLASH->OPTCR |= FLASH_OPTCR_OPTSTRT;
550 
551   /* Wait for last operation to be completed */
552   return(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE));
553 }
554 
555 /**
556   * @}
557   */
558 
559 /** @defgroup FLASH_Exported_Functions_Group3 Peripheral State and Errors functions
560  *  @brief   Peripheral Errors functions
561  *
562 @verbatim
563  ===============================================================================
564                 ##### Peripheral Errors functions #####
565  ===============================================================================
566     [..]
567     This subsection permits to get in run-time Errors of the FLASH peripheral.
568 
569 @endverbatim
570   * @{
571   */
572 
573 /**
574   * @brief  Get the specific FLASH error flag.
575   * @retval FLASH_ErrorCode: The returned value can be:
576   *            @arg FLASH_ERROR_ERS: FLASH Erasing Sequence error flag
577   *            @arg FLASH_ERROR_PGP: FLASH Programming Parallelism error flag
578   *            @arg FLASH_ERROR_PGA: FLASH Programming Alignment error flag
579   *            @arg FLASH_ERROR_WRP: FLASH Write protected error flag
580   *            @arg FLASH_ERROR_OPERATION: FLASH operation Error flag
581   */
HAL_FLASH_GetError(void)582 uint32_t HAL_FLASH_GetError(void)
583 {
584    return pFlash.ErrorCode;
585 }
586 
587 /**
588   * @}
589   */
590 
591 /**
592   * @brief  Wait for a FLASH operation to complete.
593   * @param  Timeout maximum flash operationtimeout
594   * @retval HAL Status
595   */
FLASH_WaitForLastOperation(uint32_t Timeout)596 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
597 {
598   uint32_t tickstart = 0;
599 
600   /* Clear Error Code */
601   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
602 
603   /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
604      Even if the FLASH operation fails, the BUSY flag will be reset and an error
605      flag will be set */
606   /* Get tick */
607   tickstart = HAL_GetTick();
608 
609   while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != RESET)
610   {
611     if(Timeout != HAL_MAX_DELAY)
612     {
613       if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
614       {
615         return HAL_TIMEOUT;
616       }
617     }
618   }
619 
620   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_ALL_ERRORS) != RESET)
621   {
622     /*Save the error code*/
623     FLASH_SetErrorCode();
624     return HAL_ERROR;
625   }
626 
627   /* Check FLASH End of Operation flag  */
628   if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != RESET)
629   {
630     /* Clear FLASH End of Operation pending bit */
631     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
632   }
633 
634   /* If there is an error flag set */
635   return HAL_OK;
636 
637 }
638 
639 /**
640   * @brief  Program a double word (64-bit) at a specified address.
641   * @note   This function must be used when the device voltage range is from
642   *         2.7V to 3.6V and an External Vpp is present.
643   *
644   * @note   If an erase and a program operations are requested simultaneously,
645   *         the erase operation is performed before the program one.
646   *
647   * @param  Address specifies the address to be programmed.
648   * @param  Data specifies the data to be programmed.
649   * @retval None
650   */
FLASH_Program_DoubleWord(uint32_t Address,uint64_t Data)651 static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data)
652 {
653   /* Check the parameters */
654   assert_param(IS_FLASH_ADDRESS(Address));
655 
656   /* If the previous operation is completed, proceed to program the new data */
657   FLASH->CR &= CR_PSIZE_MASK;
658   FLASH->CR |= FLASH_PSIZE_DOUBLE_WORD;
659   FLASH->CR |= FLASH_CR_PG;
660 
661   /* Program first word */
662   *(__IO uint32_t*)Address = (uint32_t)Data;
663   /* Barrier to ensure programming is performed in 2 steps, in right order
664     (independently of compiler optimization behavior) */
665   __ISB();
666 
667   /* Program second word */
668   *(__IO uint32_t*)(Address+4) = (uint32_t)(Data >> 32);
669 
670   /* Data synchronous Barrier (DSB) Just after the write operation
671      This will force the CPU to respect the sequence of instruction (no optimization).*/
672   __DSB();
673 }
674 
675 
676 /**
677   * @brief  Program word (32-bit) at a specified address.
678   * @note   This function must be used when the device voltage range is from
679   *         2.7V to 3.3V.
680   *
681   * @note   If an erase and a program operations are requested simultaneously,
682   *         the erase operation is performed before the program one.
683   *
684   * @param  Address specifies the address to be programmed.
685   * @param  Data specifies the data to be programmed.
686   * @retval None
687   */
FLASH_Program_Word(uint32_t Address,uint32_t Data)688 static void FLASH_Program_Word(uint32_t Address, uint32_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   FLASH->CR &= CR_PSIZE_MASK;
695   FLASH->CR |= FLASH_PSIZE_WORD;
696   FLASH->CR |= FLASH_CR_PG;
697 
698   *(__IO uint32_t*)Address = Data;
699 
700   /* Data synchronous Barrier (DSB) Just after the write operation
701      This will force the CPU to respect the sequence of instruction (no optimization).*/
702   __DSB();
703 }
704 
705 /**
706   * @brief  Program a half-word (16-bit) at a specified address.
707   * @note   This function must be used when the device voltage range is from
708   *         2.1V to 3.6V.
709   *
710   * @note   If an erase and a program operations are requested simultaneously,
711   *         the erase operation is performed before the program one.
712   *
713   * @param  Address specifies the address to be programmed.
714   * @param  Data specifies the data to be programmed.
715   * @retval None
716   */
FLASH_Program_HalfWord(uint32_t Address,uint16_t Data)717 static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data)
718 {
719   /* Check the parameters */
720   assert_param(IS_FLASH_ADDRESS(Address));
721 
722   /* If the previous operation is completed, proceed to program the new data */
723   FLASH->CR &= CR_PSIZE_MASK;
724   FLASH->CR |= FLASH_PSIZE_HALF_WORD;
725   FLASH->CR |= FLASH_CR_PG;
726 
727   *(__IO uint16_t*)Address = Data;
728 
729   /* Data synchronous Barrier (DSB) Just after the write operation
730      This will force the CPU to respect the sequence of instruction (no optimization).*/
731   __DSB();
732 
733 }
734 
735 /**
736   * @brief  Program byte (8-bit) at a specified address.
737   * @note   This function must be used when the device voltage range is from
738   *         1.7V to 3.6V.
739   *
740   * @note   If an erase and a program operations are requested simultaneously,
741   *         the erase operation is performed before the program one.
742   *
743   * @param  Address specifies the address to be programmed.
744   * @param  Data specifies the data to be programmed.
745   * @retval None
746   */
FLASH_Program_Byte(uint32_t Address,uint8_t Data)747 static void FLASH_Program_Byte(uint32_t Address, uint8_t Data)
748 {
749   /* Check the parameters */
750   assert_param(IS_FLASH_ADDRESS(Address));
751 
752   /* If the previous operation is completed, proceed to program the new data */
753   FLASH->CR &= CR_PSIZE_MASK;
754   FLASH->CR |= FLASH_PSIZE_BYTE;
755   FLASH->CR |= FLASH_CR_PG;
756 
757   *(__IO uint8_t*)Address = Data;
758 
759   /* Data synchronous Barrier (DSB) Just after the write operation
760      This will force the CPU to respect the sequence of instruction (no optimization).*/
761   __DSB();
762 }
763 
764 /**
765   * @brief  Set the specific FLASH error flag.
766   * @retval None
767   */
FLASH_SetErrorCode(void)768 static void FLASH_SetErrorCode(void)
769 {
770   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPERR) != RESET)
771   {
772     pFlash.ErrorCode |= HAL_FLASH_ERROR_OPERATION;
773   }
774 
775   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) != RESET)
776   {
777    pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP;
778   }
779 
780   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR) != RESET)
781   {
782    pFlash.ErrorCode |= HAL_FLASH_ERROR_PGA;
783   }
784 
785   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGPERR) != RESET)
786   {
787     pFlash.ErrorCode |= HAL_FLASH_ERROR_PGP;
788   }
789 
790   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_ERSERR) != RESET)
791   {
792     pFlash.ErrorCode |= HAL_FLASH_ERROR_ERS;
793   }
794 
795 #if defined (FLASH_OPTCR2_PCROP)
796   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR) != RESET)
797   {
798    pFlash.ErrorCode |= HAL_FLASH_ERROR_RD;
799   }
800 #endif /* FLASH_OPTCR2_PCROP */
801 
802   /* Clear error programming flags */
803   __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
804 }
805 
806 /**
807   * @}
808   */
809 
810 #endif /* HAL_FLASH_MODULE_ENABLED */
811 
812 /**
813   * @}
814   */
815 
816 /**
817   * @}
818   */
819 
820