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