1 /**
2   ******************************************************************************
3   * @file    stm32l0xx_hal_flash_ramfunc.c
4   * @author  MCD Application Team
5   * @brief   FLASH RAMFUNC driver.
6   *          This file provides a Flash firmware functions which should be
7   *          executed from internal SRAM
8   *
9   *  @verbatim
10 
11     *** ARM Compiler ***
12     --------------------
13     [..] RAM functions are defined using the toolchain options.
14          Functions that are be executed in RAM should reside in a separate
15          source module. Using the 'Options for File' dialog you can simply change
16          the 'Code / Const' area of a module to a memory space in physical RAM.
17          Available memory areas are declared in the 'Target' tab of the
18          Options for Target' dialog.
19 
20     *** ICCARM Compiler ***
21     -----------------------
22     [..] RAM functions are defined using a specific toolchain keyword "__ramfunc".
23 
24     *** GNU Compiler ***
25     --------------------
26     [..] RAM functions are defined using a specific toolchain attribute
27          "__attribute__((section(".RamFunc")))".
28 
29 @endverbatim
30   ******************************************************************************
31   * @attention
32   *
33   * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
34   * All rights reserved.</center></h2>
35   *
36   * This software component is licensed by ST under BSD 3-Clause license,
37   * the "License"; You may not use this file except in compliance with the
38   * License. You may obtain a copy of the License at:
39   *                        opensource.org/licenses/BSD-3-Clause
40   *
41   ******************************************************************************
42   */
43 
44 /* Includes ------------------------------------------------------------------*/
45 #include "stm32l0xx_hal.h"
46 
47 /** @addtogroup STM32L0xx_HAL_Driver
48   * @{
49   */
50 
51 #ifdef HAL_FLASH_MODULE_ENABLED
52 
53 /** @addtogroup FLASH
54   * @{
55   */
56 /** @addtogroup FLASH_Private_Variables
57  * @{
58  */
59 extern FLASH_ProcessTypeDef pFlash;
60 /**
61   * @}
62   */
63 
64 /**
65   * @}
66   */
67 
68 /** @defgroup FLASH_RAMFUNC FLASH_RAMFUNC
69   * @brief FLASH functions executed from RAM
70   * @{
71   */
72 
73 
74 /* Private typedef -----------------------------------------------------------*/
75 /* Private define ------------------------------------------------------------*/
76 /* Private macro -------------------------------------------------------------*/
77 /* Private variables ---------------------------------------------------------*/
78 /* Private function prototypes -----------------------------------------------*/
79 /** @defgroup FLASH_RAMFUNC_Private_Functions FLASH RAM Private Functions
80  * @{
81  */
82 
83 static __RAM_FUNC HAL_StatusTypeDef FLASHRAM_WaitForLastOperation(uint32_t Timeout);
84 static __RAM_FUNC HAL_StatusTypeDef FLASHRAM_SetErrorCode(void);
85 
86 /**
87   * @}
88   */
89 
90 /* Private functions ---------------------------------------------------------*/
91 
92 /** @defgroup FLASH_RAMFUNC_Exported_Functions FLASH RAM Exported Functions
93  *
94 @verbatim
95  ===============================================================================
96                       ##### ramfunc functions #####
97  ===============================================================================
98     [..]
99     This subsection provides a set of functions that should be executed from RAM
100     transfers.
101 
102 @endverbatim
103   * @{
104   */
105 
106 /** @defgroup FLASH_RAMFUNC_Exported_Functions_Group1 Peripheral features functions
107   * @{
108   */
109 
110 /**
111   * @brief  Enable  the power down mode during RUN mode.
112   * @note  This function can be used only when the user code is running from Internal SRAM.
113   * @retval HAL status
114   */
HAL_FLASHEx_EnableRunPowerDown(void)115 __RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_EnableRunPowerDown(void)
116 {
117   /* Enable the Power Down in Run mode*/
118   __HAL_FLASH_POWER_DOWN_ENABLE();
119 
120   return HAL_OK;
121 }
122 
123 /**
124   * @brief  Disable the power down mode during RUN mode.
125   * @note  This function can be used only when the user code is running from Internal SRAM.
126   * @retval HAL status
127   */
HAL_FLASHEx_DisableRunPowerDown(void)128 __RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_DisableRunPowerDown(void)
129 {
130   /* Disable the Power Down in Run mode*/
131   __HAL_FLASH_POWER_DOWN_DISABLE();
132 
133   return HAL_OK;
134 }
135 
136 /**
137   * @}
138   */
139 
140 /** @defgroup FLASH_RAMFUNC_Exported_Functions_Group2 Programming and erasing operation functions
141  *
142 @verbatim
143 @endverbatim
144   * @{
145   */
146 
147 #if defined(FLASH_PECR_PARALLBANK)
148 /**
149   * @brief  Erases a specified 2 pages in program memory in parallel.
150   * @note   This function can be used only for STM32L07xxx/STM32L08xxx  devices.
151   *         To correctly run this function, the @ref HAL_FLASH_Unlock() function
152   *         must be called before.
153   *         Call the @ref HAL_FLASH_Lock() to disable the flash memory access
154   *        (recommended to protect the FLASH memory against possible unwanted operation).
155   * @param  Page_Address1: The page address in program memory to be erased in
156   *         the first Bank (BANK1). This parameter should be between FLASH_BASE
157   *         and FLASH_BANK1_END.
158   * @param  Page_Address2: The page address in program memory to be erased in
159   *         the second Bank (BANK2). This parameter should be between FLASH_BANK2_BASE
160   *         and FLASH_BANK2_END.
161   * @note   A Page is erased in the Program memory only if the address to load
162   *         is the start address of a page (multiple of @ref FLASH_PAGE_SIZE bytes).
163   * @retval HAL status
164   */
HAL_FLASHEx_EraseParallelPage(uint32_t Page_Address1,uint32_t Page_Address2)165 __RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_EraseParallelPage(uint32_t Page_Address1, uint32_t Page_Address2)
166 {
167   HAL_StatusTypeDef status = HAL_OK;
168 
169   /* Wait for last operation to be completed */
170   status = FLASHRAM_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
171 
172   if(status == HAL_OK)
173   {
174     /* Proceed to erase the page */
175     SET_BIT(FLASH->PECR, FLASH_PECR_PARALLBANK);
176     SET_BIT(FLASH->PECR, FLASH_PECR_ERASE);
177     SET_BIT(FLASH->PECR, FLASH_PECR_PROG);
178 
179     /* Write 00000000h to the first word of the first program page to erase */
180     *(__IO uint32_t *)Page_Address1 = 0x00000000U;
181     /* Write 00000000h to the first word of the second program page to erase */
182     *(__IO uint32_t *)Page_Address2 = 0x00000000U;
183 
184     /* Wait for last operation to be completed */
185     status = FLASHRAM_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
186 
187     /* If the erase operation is completed, disable the ERASE, PROG and PARALLBANK bits */
188     CLEAR_BIT(FLASH->PECR, FLASH_PECR_PROG);
189     CLEAR_BIT(FLASH->PECR, FLASH_PECR_ERASE);
190     CLEAR_BIT(FLASH->PECR, FLASH_PECR_PARALLBANK);
191   }
192   /* Return the Erase Status */
193   return status;
194 }
195 
196 /**
197   * @brief  Program 2 half pages in program memory in parallel (half page size is 16 Words).
198   * @note   This function can be used only for STM32L07xxx/STM32L08xxx  devices.
199   * @param  Address1: specifies the first address to be written in the first bank
200   *        (BANK1). This parameter should be between FLASH_BASE and (FLASH_BANK1_END - FLASH_PAGE_SIZE).
201   * @param  pBuffer1: pointer to the buffer  containing the data to be  written
202   *         to the first half page in the first bank.
203   * @param  Address2: specifies the second address to be written in the second bank
204   *        (BANK2). This parameter should be between FLASH_BANK2_BASE and (FLASH_BANK2_END - FLASH_PAGE_SIZE).
205   * @param  pBuffer2: pointer to the buffer containing the data to be  written
206   *         to the second half page in the second bank.
207   * @note   To correctly run this function, the @ref HAL_FLASH_Unlock() function
208   *         must be called before.
209   *         Call the @ref HAL_FLASH_Lock() to disable the flash memory access
210   *         (recommended to protect the FLASH memory against possible unwanted operation).
211   * @note   Half page write is possible only from SRAM.
212   * @note   A half page is written to the program memory only if the first
213   *         address to load is the start address of a half page (multiple of 64
214   *         bytes) and the 15 remaining words to load are in the same half page.
215   * @note   During the Program memory half page write all read operations are
216   *         forbidden (this includes DMA read operations and debugger read
217   *         operations such as breakpoints, periodic updates, etc.).
218   * @note   If a PGAERR is set during a Program memory half page write, the
219   *         complete write operation is aborted. Software should then reset the
220   *         FPRG and PROG/DATA bits and restart the write operation from the
221   *         beginning.
222   * @retval HAL status
223   */
HAL_FLASHEx_ProgramParallelHalfPage(uint32_t Address1,uint32_t * pBuffer1,uint32_t Address2,uint32_t * pBuffer2)224 __RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_ProgramParallelHalfPage(uint32_t Address1, uint32_t* pBuffer1, uint32_t Address2, uint32_t* pBuffer2)
225 {
226   uint32_t count = 0U;
227   HAL_StatusTypeDef status = HAL_OK;
228 
229   /* Wait for last operation to be completed */
230   status = FLASHRAM_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
231 
232   if(status == HAL_OK)
233   {
234     /* Proceed to program the new half page */
235     SET_BIT(FLASH->PECR, FLASH_PECR_PARALLBANK);
236     SET_BIT(FLASH->PECR, FLASH_PECR_FPRG);
237     SET_BIT(FLASH->PECR, FLASH_PECR_PROG);
238 
239     /* Wait for last operation to be completed */
240     status = FLASHRAM_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
241     if(status == HAL_OK)
242     {
243       /* Disable all IRQs */
244       __disable_irq();
245 
246       /* Write the first half page directly with 16 different words */
247       while(count < 16U)
248       {
249         /* Address1 doesn't need to be increased */
250         *(__IO uint32_t*) Address1 = *pBuffer1;
251         pBuffer1++;
252         count ++;
253       }
254 
255       /* Write the second half page directly with 16 different words */
256       count = 0U;
257       while(count < 16U)
258       {
259         /* Address2 doesn't need to be increased */
260         *(__IO uint32_t*) Address2 = *pBuffer2;
261         pBuffer2++;
262         count ++;
263       }
264 
265       /* Enable IRQs */
266       __enable_irq();
267 
268       /* Wait for last operation to be completed */
269       status = FLASHRAM_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
270     }
271 
272     /* if the write operation is completed, disable the PROG, FPRG and PARALLBANK bits */
273     CLEAR_BIT(FLASH->PECR, FLASH_PECR_PROG);
274     CLEAR_BIT(FLASH->PECR, FLASH_PECR_FPRG);
275     CLEAR_BIT(FLASH->PECR, FLASH_PECR_PARALLBANK);
276   }
277 
278   /* Return the Write Status */
279   return status;
280 }
281 #endif /* FLASH_PECR_PARALLBANK */
282 
283 /**
284   * @brief  Program a half page in program memory.
285   * @param  Address specifies the address to be written.
286   * @param  pBuffer pointer to the buffer  containing the data to be  written to
287   *         the half page.
288   * @note   To correctly run this function, the @ref HAL_FLASH_Unlock() function
289   *         must be called before.
290   *         Call the @ref HAL_FLASH_Lock() to disable the flash memory access
291   *         (recommended to protect the FLASH memory against possible unwanted operation)
292   * @note   Half page write is possible only from SRAM.
293   * @note   A half page is written to the program memory only if the first
294   *         address to load is the start address of a half page (multiple of 64
295   *         bytes) and the 15 remaining words to load are in the same half page.
296   * @note   During the Program memory half page write all read operations are
297   *         forbidden (this includes DMA read operations and debugger read
298   *         operations such as breakpoints, periodic updates, etc.).
299   * @note   If a PGAERR is set during a Program memory half page write, the
300   *         complete write operation is aborted. Software should then reset the
301   *         FPRG and PROG/DATA bits and restart the write operation from the
302   *         beginning.
303   * @retval HAL status
304   */
HAL_FLASHEx_HalfPageProgram(uint32_t Address,uint32_t * pBuffer)305 __RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_HalfPageProgram(uint32_t Address, uint32_t* pBuffer)
306 {
307   uint32_t count = 0U;
308   HAL_StatusTypeDef status = HAL_OK;
309 
310   /* Wait for last operation to be completed */
311   status = FLASHRAM_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
312 
313   if(status == HAL_OK)
314   {
315     /* Proceed to program the new half page */
316     SET_BIT(FLASH->PECR, FLASH_PECR_FPRG);
317     SET_BIT(FLASH->PECR, FLASH_PECR_PROG);
318 
319     /* Disable all IRQs */
320     __disable_irq();
321 
322     /* Write one half page directly with 16 different words */
323     while(count < 16U)
324     {
325       /* Address doesn't need to be increased */
326       *(__IO uint32_t*) Address = *pBuffer;
327       pBuffer++;
328       count ++;
329     }
330 
331     /* Enable IRQs */
332     __enable_irq();
333 
334     /* Wait for last operation to be completed */
335     status = FLASHRAM_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
336 
337     /* If the write operation is completed, disable the PROG and FPRG bits */
338     CLEAR_BIT(FLASH->PECR, FLASH_PECR_PROG);
339     CLEAR_BIT(FLASH->PECR, FLASH_PECR_FPRG);
340   }
341 
342   /* Return the Write Status */
343   return status;
344 }
345 
346 /**
347   * @}
348   */
349 
350 /** @defgroup FLASH_RAMFUNC_Exported_Functions_Group3 Peripheral errors functions
351  *  @brief    Peripheral errors functions
352  *
353 @verbatim
354  ===============================================================================
355                       ##### Peripheral errors functions #####
356  ===============================================================================
357     [..]
358     This subsection permit to get in run-time errors of  the FLASH peripheral.
359 
360 @endverbatim
361   * @{
362   */
363 
364 /**
365   * @brief  Get the specific FLASH errors flag.
366   * @param  Error pointer is the error value. It can be a mixed of:
367   *            @arg @ref HAL_FLASH_ERROR_RD      FLASH Read Protection error flag (PCROP)
368   *            @arg @ref HAL_FLASH_ERROR_SIZE    FLASH Programming Parallelism error flag
369   *            @arg @ref HAL_FLASH_ERROR_PGA     FLASH Programming Alignment error flag
370   *            @arg @ref HAL_FLASH_ERROR_WRP     FLASH Write protected error flag
371   *            @arg @ref HAL_FLASH_ERROR_OPTV    FLASH Option valid error flag
372   *            @arg @ref HAL_FLASH_ERROR_FWWERR  FLASH Write or Erase operation aborted
373   *            @arg @ref HAL_FLASH_ERROR_NOTZERO FLASH Write operation is done in a not-erased region
374   * @retval HAL Status
375   */
HAL_FLASHEx_GetError(uint32_t * Error)376 __RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_GetError(uint32_t * Error)
377 {
378   *Error = pFlash.ErrorCode;
379   return HAL_OK;
380 }
381 
382 /**
383   * @}
384   */
385 
386 /**
387   * @}
388   */
389 
390 /** @addtogroup FLASH_RAMFUNC_Private_Functions
391   * @{
392   */
393 
394 /**
395   * @brief  Set the specific FLASH error flag.
396   * @retval HAL Status
397   */
FLASHRAM_SetErrorCode(void)398 static __RAM_FUNC HAL_StatusTypeDef FLASHRAM_SetErrorCode(void)
399 {
400   uint32_t flags = 0;
401 
402   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR))
403   {
404     pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP;
405     flags |= FLASH_FLAG_WRPERR;
406   }
407   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR))
408   {
409     pFlash.ErrorCode |= HAL_FLASH_ERROR_PGA;
410     flags |= FLASH_FLAG_PGAERR;
411   }
412   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR))
413   {
414     pFlash.ErrorCode |= HAL_FLASH_ERROR_SIZE;
415     flags |= FLASH_FLAG_SIZERR;
416   }
417   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR))
418   {
419     /* WARNING : On the first cut of STM32L031xx and STM32L041xx devices,
420      *           (RefID = 0x1000) the FLASH_FLAG_OPTVERR bit was not behaving
421      *           as expected. If the user run an application using the first
422      *           cut of the STM32L031xx device or the first cut of the STM32L041xx
423      *           device, this error should be ignored. The revId of the device
424      *           can be retrieved via the HAL_GetREVID() function.
425      *
426      */
427     pFlash.ErrorCode |= HAL_FLASH_ERROR_OPTV;
428     flags |= FLASH_FLAG_OPTVERR;
429   }
430 
431   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR))
432   {
433     pFlash.ErrorCode |= HAL_FLASH_ERROR_RD;
434     flags |= FLASH_FLAG_RDERR;
435   }
436   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_FWWERR))
437   {
438     pFlash.ErrorCode |= HAL_FLASH_ERROR_FWWERR;
439     flags |= HAL_FLASH_ERROR_FWWERR;
440   }
441   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_NOTZEROERR))
442   {
443     pFlash.ErrorCode |= HAL_FLASH_ERROR_NOTZERO;
444     flags |= FLASH_FLAG_NOTZEROERR;
445   }
446 
447   /* Clear FLASH error pending bits */
448   __HAL_FLASH_CLEAR_FLAG(flags);
449 
450   return HAL_OK;
451 }
452 
453 /**
454   * @brief  Wait for a FLASH operation to complete.
455   * @param  Timeout maximum flash operationtimeout
456   * @retval HAL status
457   */
FLASHRAM_WaitForLastOperation(uint32_t Timeout)458 static __RAM_FUNC HAL_StatusTypeDef FLASHRAM_WaitForLastOperation(uint32_t Timeout)
459 {
460     /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
461        Even if the FLASH operation fails, the BUSY flag will be reset and an error
462        flag will be set */
463 
464     while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) && (Timeout != 0x00U))
465     {
466       Timeout--;
467     }
468 
469     if(Timeout == 0x00U)
470     {
471       return HAL_TIMEOUT;
472     }
473 
474   /* Check FLASH End of Operation flag  */
475   if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
476   {
477     /* Clear FLASH End of Operation pending bit */
478     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
479   }
480 
481   if( __HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)     ||
482       __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR)     ||
483       __HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR)     ||
484       __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR)    ||
485       __HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR)      ||
486       __HAL_FLASH_GET_FLAG(FLASH_FLAG_FWWERR)     ||
487       __HAL_FLASH_GET_FLAG(FLASH_FLAG_NOTZEROERR) )
488   {
489     /*Save the error code*/
490 
491     /* WARNING : On the first cut of STM32L031xx and STM32L041xx devices,
492      *           (RefID = 0x1000) the FLASH_FLAG_OPTVERR bit was not behaving
493      *           as expected. If the user run an application using the first
494      *           cut of the STM32L031xx device or the first cut of the STM32L041xx
495      *           device, this error should be ignored. The revId of the device
496      *           can be retrieved via the HAL_GetREVID() function.
497      *
498      */
499     FLASHRAM_SetErrorCode();
500     return HAL_ERROR;
501   }
502 
503   /* There is no error flag set */
504   return HAL_OK;
505 }
506 
507 /**
508   * @}
509   */
510 
511 /**
512   * @}
513   */
514 
515 #endif /* HAL_FLASH_MODULE_ENABLED */
516 /**
517   * @}
518   */
519 
520 
521 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
522