]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F1/stm32f1xx_hal_flash.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / cmsis / TARGET_STM / TARGET_STM32F1 / stm32f1xx_hal_flash.c
1 /**
2   ******************************************************************************
3   * @file    stm32f1xx_hal_flash.c
4   * @author  MCD Application Team
5   * @version V1.0.0
6   * @date    15-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 State functions
13   *         
14   @verbatim
15   ==============================================================================
16                         ##### FLASH peripheral features #####
17   ==============================================================================
18   [..] The Flash memory interface manages CPU AHB I-Code and D-Code accesses 
19        to the Flash memory. It implements the erase and program Flash memory operations 
20        and the read and write protection mechanisms.
21
22   [..] The Flash memory interface accelerates code execution with a system of instruction
23       prefetch. 
24
25   [..] The FLASH main features are:
26       (+) Flash memory read operations
27       (+) Flash memory program/erase operations
28       (+) Read / write protections
29       (+) Prefetch on I-Code
30       (+) Option Bytes programming
31
32
33                      ##### How to use this driver #####
34   ==============================================================================
35   [..]                             
36       This driver provides functions and macros to configure and program the FLASH 
37       memory of all STM32F1xx devices. These functions are split in 3 groups:
38     
39       (#) FLASH Memory I/O Programming functions: this group includes all needed
40           functions to erase and program the main memory:
41         (++) Lock and Unlock the FLASH interface
42         (++) Erase function: Erase page, erase all pages
43         (++) Program functions: half word, word and doubleword
44     
45       (#) Option Bytes Programming functions: this group includes all needed
46           functions to manage the Option Bytes:
47         (++) Lock and Unlock the Option Bytes
48         (++) Erase Option Bytes
49         (++) Set/Reset the write protection
50         (++) Set the Read protection Level
51         (++) Program the user Option Bytes
52         (++) Program the data Option Bytes
53         (++) Launch the Option Bytes loader
54     
55       (#) Interrupts and flags management functions : this group 
56           includes all needed functions to:
57         (++) Handle FLASH interrupts
58         (++) Wait for last FLASH operation according to its status
59         (++) Get error flag status           
60
61   [..] In addition to these function, this driver includes a set of macros allowing
62        to handle the following operations:
63       
64       (+) Set the latency
65       (+) Enable/Disable the prefetch buffer
66       (+) Enable/Disable the half cycle access
67       (+) Enable/Disable the FLASH interrupts
68       (+) Monitor the FLASH flags status
69           
70   @endverbatim
71   ******************************************************************************
72   * @attention
73   *
74   * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
75   *
76   * Redistribution and use in source and binary forms, with or without modification,
77   * are permitted provided that the following conditions are met:
78   *   1. Redistributions of source code must retain the above copyright notice,
79   *      this list of conditions and the following disclaimer.
80   *   2. Redistributions in binary form must reproduce the above copyright notice,
81   *      this list of conditions and the following disclaimer in the documentation
82   *      and/or other materials provided with the distribution.
83   *   3. Neither the name of STMicroelectronics nor the names of its contributors
84   *      may be used to endorse or promote products derived from this software
85   *      without specific prior written permission.
86   *
87   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
88   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
89   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
91   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
92   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
93   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
94   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
95   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
96   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97   *
98   ******************************************************************************  
99   */
100
101 /* Includes ------------------------------------------------------------------*/
102 #include "stm32f1xx_hal.h"
103
104 /** @addtogroup STM32F1xx_HAL_Driver
105   * @{
106   */
107
108 /** @defgroup FLASH FLASH
109   * @brief FLASH HAL module driver
110   * @{
111   */
112
113 #ifdef HAL_FLASH_MODULE_ENABLED
114
115 /* Private typedef -----------------------------------------------------------*/
116 /* Private define ------------------------------------------------------------*/
117 /** @defgroup FLASH_Private_Constants FLASH Private Constants
118  * @{
119  */
120 /**
121   * @}
122   */
123
124 /* Private macro -------------------------------------------------------------*/
125 /** @defgroup FLASH_Private_Macros FLASH Private Macros
126  * @{
127  */
128  
129 /**
130   * @}
131   */
132
133 /* Private variables ---------------------------------------------------------*/
134 /** @defgroup FLASH_Private_Variables FLASH Private Variables
135  * @{
136  */
137 /* Variables used for Erase pages under interruption*/
138 FLASH_ProcessTypeDef pFlash;
139 /**
140   * @}
141   */
142
143 /* Private function prototypes -----------------------------------------------*/
144 /** @defgroup FLASH_Private_Functions FLASH Private Functions
145  * @{
146  */
147 /**
148   * @}
149   */
150
151 /* Exported functions ---------------------------------------------------------*/
152 /** @defgroup FLASH_Exported_Functions FLASH Exported Functions
153   * @{
154   */
155   
156 /** @defgroup FLASH_Exported_Functions_Group1 Input and Output operation functions 
157  *  @brief   Data transfers functions 
158  *
159 @verbatim   
160  ===============================================================================
161                         ##### IO operation functions #####
162  ===============================================================================  
163     [..]
164     This subsection provides a set of functions allowing to manage the FLASH 
165     program operations (write/erase).
166
167 @endverbatim
168   * @{
169   */
170
171 /**
172   * @brief  Program halfword, word or double word at a specified address
173   * @note   The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
174   *         The function HAL_FLASH_Lock() should be called after to lock the FLASH interface
175   *
176   * @note   If an erase and a program operations are requested simultaneously,    
177   *         the erase operation is performed before the program one.
178   *  
179   * @note   FLASH should be previously erased before new programmation (only exception to this 
180   *         is when 0x0000 is programmed)
181   *  
182   * @param  TypeProgram:  Indicate the way to program at a specified address.
183   *                       This parameter can be a value of @ref FLASH_Type_Program
184   * @param  Address:      Specifies the address to be programmed.
185   * @param  Data:         Specifies the data to be programmed
186   * 
187   * @retval HAL_StatusTypeDef HAL Status
188   */
189 __weak HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
190 {
191   HAL_StatusTypeDef status = HAL_ERROR;
192   uint8_t index = 0;
193   uint8_t nbiterations = 0;
194   
195   /* Process Locked */
196   __HAL_LOCK(&pFlash);
197
198   /* Check the parameters */
199   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
200   assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
201
202   /* Wait for last operation to be completed */
203   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
204   
205   if(status == HAL_OK)
206   {
207     if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
208     {
209       /* Program halfword (16-bit) at a specified address. */
210       nbiterations = 1;
211     }
212     else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
213     {
214       /* Program word (32-bit = 2*16-bit) at a specified address. */
215       nbiterations = 2;
216     }
217     else
218     {
219       /* Program double word (64-bit = 4*16-bit) at a specified address. */
220       nbiterations = 4;
221     }
222
223     for (index = 0; index < nbiterations; index++)
224     {
225       FLASH_Program_HalfWord((Address + (2*index)), (uint16_t)(Data >> (16*index)));
226
227       /* Wait for last operation to be completed */
228       status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
229     
230       /* If the program operation is completed, disable the PG Bit */
231       CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
232       
233       /* In case of error, stop programation procedure */
234       if (status != HAL_OK)
235       {
236         break;
237       }
238     }
239   }
240
241   /* Process Unlocked */
242   __HAL_UNLOCK(&pFlash);
243
244   return status;
245 }
246
247 /**
248   * @brief  Program halfword, word or double word at a specified address  with interrupt enabled.
249   * @note   The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
250   *         The function HAL_FLASH_Lock() should be called after to lock the FLASH interface
251   *
252   * @note   If an erase and a program operations are requested simultaneously,    
253   *         the erase operation is performed before the program one.
254   *  
255   * @param  TypeProgram: Indicate the way to program at a specified address.
256   *                      This parameter can be a value of @ref FLASH_Type_Program
257   * @param  Address:     Specifies the address to be programmed.
258   * @param  Data:        Specifies the data to be programmed
259   * 
260   * @retval HAL_StatusTypeDef HAL Status
261   */
262 __weak HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
263 {
264   HAL_StatusTypeDef status = HAL_OK;
265   
266   /* Process Locked */
267   __HAL_LOCK(&pFlash);
268
269   /* Check the parameters */
270   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
271   assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
272
273   /* Enable End of FLASH Operation and Error source interrupts */
274   __HAL_FLASH_ENABLE_IT((FLASH_IT_EOP | FLASH_IT_ERR));
275   
276   pFlash.Address = Address;
277   pFlash.Data = Data;
278
279   if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
280   {
281     pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMHALFWORD;
282     /*Program halfword (16-bit) at a specified address.*/
283     pFlash.DataRemaining = 1;
284   }
285   else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
286   {
287     pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMWORD;
288     /*Program word (32-bit : 2*16-bit) at a specified address.*/
289     pFlash.DataRemaining = 2;
290   }
291   else
292   {
293     pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMDOUBLEWORD;
294     /*Program double word (64-bit : 4*16-bit) at a specified address.*/
295     pFlash.DataRemaining = 4;
296   }
297
298   /*Program halfword (16-bit) at a specified address.*/
299   FLASH_Program_HalfWord(Address, (uint16_t)Data);
300
301   return status;
302 }
303
304 /**
305   * @brief This function handles FLASH interrupt request.
306   * @retval None
307   */
308 __weak void HAL_FLASH_IRQHandler(void)
309 {
310   uint32_t addresstmp = 0;
311   
312   /* Check FLASH operation error flags */
313   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) ||__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR))
314   {
315     /*Save the Error code*/
316     FLASH_SetErrorCode();
317     
318     /* FLASH error interrupt user callback */
319     HAL_FLASH_OperationErrorCallback(pFlash.Address);
320
321     /* Reset address and stop the procedure ongoing*/
322     pFlash.Address = 0xFFFFFFFF;
323     pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
324   }
325
326   /* Check FLASH End of Operation flag  */
327   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
328   {
329     /* Clear FLASH End of Operation pending bit */
330     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
331     
332     /* Process can continue only if no error detected */
333     if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
334     {
335       if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
336       {
337         /* Nb of pages to erased can be decreased */
338         pFlash.DataRemaining--;
339
340         /* Indicate user which page address has been erased*/
341         HAL_FLASH_EndOfOperationCallback(pFlash.Address);
342
343         /* Check if there are still pages to erase*/
344         if(pFlash.DataRemaining != 0)
345         {
346           /* Increment page address to next page */
347           pFlash.Address += FLASH_PAGE_SIZE;
348           addresstmp = pFlash.Address;
349
350           /* Operation is completed, disable the PER Bit */
351           CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
352
353           FLASH_PageErase(addresstmp);
354         }
355         else
356         {
357           /*No more pages to Erase*/
358
359           /*Reset Address and stop Erase pages procedure*/
360           pFlash.Address = 0xFFFFFFFF;
361           pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
362         }
363       }
364       else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE)
365       {
366         /* Operation is completed, disable the MER Bit */
367         CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
368
369         /* MassErase ended. Return the selected bank*/
370         /* FLASH EOP interrupt user callback */
371         HAL_FLASH_EndOfOperationCallback(0);
372
373         /* Stop Mass Erase procedure*/
374         pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
375       }
376       else
377       {
378         /* Nb of 16-bit data to program can be decreased */
379         pFlash.DataRemaining--;
380         
381         /* Check if there are still 16-bit data to program */
382         if(pFlash.DataRemaining != 0)
383         {
384           /* Increment address to 16-bit */
385           pFlash.Address += 2;
386           addresstmp = pFlash.Address;
387
388           /* Shift to have next 16-bit data */
389           pFlash.Data = (pFlash.Data >> 16);
390
391           /* Operation is completed, disable the PG Bit */
392           CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
393
394           /* Program halfword (16-bit) at a specified address.*/
395           FLASH_Program_HalfWord(addresstmp, (uint16_t)pFlash.Data);
396         }
397         else
398         {
399           /* Program ended. Return the selected address*/
400           /* FLASH EOP interrupt user callback */
401           if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMHALFWORD)
402           {
403             HAL_FLASH_EndOfOperationCallback(pFlash.Address);
404           }
405           else if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMWORD)
406           {
407             HAL_FLASH_EndOfOperationCallback(pFlash.Address-2);
408           }
409           else 
410           {
411             HAL_FLASH_EndOfOperationCallback(pFlash.Address-6);
412           }
413
414           /* Reset Address and stop Program procedure*/
415           pFlash.Address = 0xFFFFFFFF;
416           pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
417         }
418       }
419     }
420   }
421   
422   if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
423   {
424     /* Operation is completed, disable the PG, PER and MER Bits */
425     CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_PER | FLASH_CR_MER));
426
427     /* Disable End of FLASH Operation and Error source interrupts */
428     __HAL_FLASH_DISABLE_IT((FLASH_IT_EOP | FLASH_IT_ERR));
429
430     /* Process Unlocked */
431     __HAL_UNLOCK(&pFlash);
432   }
433 }
434
435
436 /**
437   * @brief  FLASH end of operation interrupt callback
438   * @param  ReturnValue: The value saved in this parameter depends on the ongoing procedure
439   *                 - Mass Erase: No return value expected
440   *                 - Pages Erase: Address of the page which has been erased 
441   *                 - Program: Address which was selected for data program
442   * @retval none
443   */
444 __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
445 {
446   /* NOTE : This function Should not be modified, when the callback is needed,
447             the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
448    */ 
449 }
450
451 /**
452   * @brief  FLASH operation error interrupt callback
453   * @param  ReturnValue: The value saved in this parameter depends on the ongoing procedure
454   *                 - Mass Erase: No return value expected
455   *                 - Pages Erase: Address of the page which returned an error
456   *                 - Program: Address which was selected for data program
457   * @retval none
458   */
459 __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
460 {
461   /* NOTE : This function Should not be modified, when the callback is needed,
462             the HAL_FLASH_OperationErrorCallback could be implemented in the user file
463    */ 
464 }
465
466 /**
467   * @}
468   */
469
470 /** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions 
471  *  @brief   management functions 
472  *
473 @verbatim   
474  ===============================================================================
475                       ##### Peripheral Control functions #####
476  ===============================================================================  
477     [..]
478     This subsection provides a set of functions allowing to control the FLASH 
479     memory operations.
480
481 @endverbatim
482   * @{
483   */
484
485 /**
486   * @brief  Unlock the FLASH control register access
487   * @retval HAL Status
488   */
489 __weak HAL_StatusTypeDef HAL_FLASH_Unlock(void)
490 {
491   if (HAL_IS_BIT_SET(FLASH->CR, FLASH_CR_LOCK))
492   {
493     /* Authorize the FLASH Registers access */
494     WRITE_REG(FLASH->KEYR, FLASH_KEY1);
495     WRITE_REG(FLASH->KEYR, FLASH_KEY2);
496   }
497   else
498   {
499     return HAL_ERROR;
500   }
501   
502   return HAL_OK; 
503 }
504
505 /**
506   * @brief  Locks the FLASH control register access
507   * @retval HAL Status
508   */
509 __weak HAL_StatusTypeDef HAL_FLASH_Lock(void)
510 {
511   /* Set the LOCK Bit to lock the FLASH Registers access */
512   SET_BIT(FLASH->CR, FLASH_CR_LOCK);
513   
514   return HAL_OK;  
515 }
516
517
518 /**
519   * @brief  Unlock the FLASH Option Control Registers access.
520   * @retval HAL Status
521   */
522 HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
523 {
524   if (HAL_IS_BIT_CLR(FLASH->CR, FLASH_CR_OPTWRE))
525   {
526     /* Authorizes the Option Byte register programming */
527     WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1);
528     WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2);
529   }
530   else
531   {
532     return HAL_ERROR;
533   }  
534   
535   return HAL_OK;  
536 }
537
538 /**
539   * @brief  Lock the FLASH Option Control Registers access.
540   * @retval HAL Status 
541   */
542 HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
543 {
544   /* Clear the OPTWRE Bit to lock the FLASH Option Byte Registers access */
545   CLEAR_BIT(FLASH->CR, FLASH_CR_OPTWRE);
546   
547   return HAL_OK;  
548 }
549   
550 /**
551   * @brief  Launch the option byte loading.
552   * @note   This function will reset automatically the MCU.
553   * @retval HAL_StatusTypeDef HAL Status
554   */
555 HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
556 {
557   /* Initiates a system reset request to launch the option byte loading */
558   HAL_NVIC_SystemReset();
559   
560   return HAL_OK;  
561 }
562
563 /**
564   * @}
565   */  
566
567 /** @defgroup FLASH_Exported_Functions_Group3 Peripheral State functions 
568  *  @brief   Peripheral State functions 
569  *
570 @verbatim   
571  ===============================================================================
572                       ##### Peripheral State functions #####
573  ===============================================================================  
574     [..]
575     This subsection permit to get in run-time the status of the FLASH peripheral.
576
577 @endverbatim
578   * @{
579   */
580
581 /**
582   * @brief  Get the specific FLASH error flag.
583   * @retval FLASH_ErrorCode: The returned value can be:
584   *            @arg HAL_FLASH_ERROR_PROG:   FLASH Programming error flag 
585   *            @arg HAL_FLASH_ERROR_WRP:  FLASH Write protected error flag
586   *            @arg HAL_FLASH_ERROR_OPTV: Option byte error
587   */
588 uint32_t HAL_FLASH_GetError(void)
589
590    return pFlash.ErrorCode;
591 }  
592 /**
593   * @}
594   */
595
596 /**
597   * @}
598   */
599
600 /** @addtogroup FLASH_Private_Functions
601  * @{
602  */
603 /**
604   * @brief  Wait for a FLASH operation to complete.
605   * @param  Timeout: maximum flash operationtimeout
606   * @retval HAL_StatusTypeDef HAL Status
607   */
608 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
609 {
610   /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
611      Even if the FLASH operation fails, the BUSY flag will be reset and an error
612      flag will be set */
613      
614   uint32_t tickstart = HAL_GetTick();
615      
616   while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) 
617   { 
618     if (Timeout != HAL_MAX_DELAY)
619     {
620       if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
621       {
622         return HAL_TIMEOUT;
623       }
624     }
625   }
626   
627   /* Check FLASH End of Operation flag  */
628   if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
629   {
630     /* Clear FLASH End of Operation pending bit */
631     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
632   }
633   
634   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR) || \
635      __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR))
636   {
637     /*Save the error code*/
638     FLASH_SetErrorCode();
639     return HAL_ERROR;
640   }
641
642   /* If there is no error flag set */
643   return HAL_OK;
644   
645 }
646
647 /**
648   * @}
649   */    
650
651 #endif /* HAL_FLASH_MODULE_ENABLED */
652
653 /**
654   * @}
655   */
656
657 /**
658   * @}
659   */
660
661 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/