1 /**
2   ******************************************************************************
3   * @file    stm32l5xx_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   *            + Option Byte DBANK Programming
9   *            + FLASH Power Down in Run mode
10   *
11   *  @verbatim
12   ==============================================================================
13                    ##### Flash RAM functions #####
14   ==============================================================================
15 
16     *** ARM Compiler ***
17     --------------------
18     [..] RAM functions are defined using the toolchain options.
19          Functions that are executed in RAM should reside in a separate
20          source module. Using the 'Options for File' dialog you can simply change
21          the 'Code / Const' area of a module to a memory space in physical RAM.
22          Available memory areas are declared in the 'Target' tab of the
23          Options for Target' dialog.
24 
25     *** ICCARM Compiler ***
26     -----------------------
27     [..] RAM functions are defined using a specific toolchain keyword "__ramfunc".
28 
29     *** GNU Compiler ***
30     --------------------
31     [..] RAM functions are defined using a specific toolchain attribute
32          "__attribute__((section(".RamFunc")))".
33 
34   @endverbatim
35   ******************************************************************************
36   * @attention
37   *
38   * Copyright (c) 2019 STMicroelectronics.
39   * All rights reserved.
40   *
41   * This software is licensed under terms that can be found in the LICENSE file in
42   * the root directory of this software component.
43   * If no LICENSE file comes with this software, it is provided AS-IS.
44   ******************************************************************************
45   */
46 
47 /* Includes ------------------------------------------------------------------*/
48 #include "stm32l5xx_hal.h"
49 
50 /** @addtogroup STM32L5xx_HAL_Driver
51   * @{
52   */
53 
54 /** @defgroup FLASH_RAMFUNC FLASH RAMFUNC
55   * @brief FLASH functions executed from RAM
56   * @{
57   */
58 
59 #ifdef HAL_FLASH_MODULE_ENABLED
60 
61 /* Private typedef -----------------------------------------------------------*/
62 /* Private define ------------------------------------------------------------*/
63 /* Private macro -------------------------------------------------------------*/
64 /* Private variables ---------------------------------------------------------*/
65 /* Private function prototypes -----------------------------------------------*/
66 /* Exported functions --------------------------------------------------------*/
67 
68 /** @defgroup FLASH_RAMFUNC_Exported_Functions FLASH in RAM function Exported Functions
69   * @{
70   */
71 
72 /** @defgroup FLASH_RAMFUNC_Exported_Functions_Group1 RAM Execution functions
73  *  @brief   RAM Execution functions
74  *
75 @verbatim
76  ===============================================================================
77                       ##### RAM Execution functions #####
78  ===============================================================================
79     [..]
80     This subsection provides a set of functions that should be executed from RAM.
81 
82 @endverbatim
83   * @{
84   */
85 
86 /**
87   * @brief  Enable the Power down in Run Mode
88   * @note   This function should be called and executed from SRAM memory
89   * @retval HAL status
90   */
HAL_FLASHEx_EnableRunPowerDown(void)91 __RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_EnableRunPowerDown(void)
92 {
93   /* Enable the Power Down in Run mode*/
94   __HAL_FLASH_POWER_DOWN_ENABLE();
95 
96   return HAL_OK;
97 }
98 
99 /**
100   * @brief  Disable the Power down in Run Mode
101   * @note   This function should be called and executed from SRAM memory
102   * @retval HAL status
103   */
HAL_FLASHEx_DisableRunPowerDown(void)104 __RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_DisableRunPowerDown(void)
105 {
106   /* Disable the Power Down in Run mode*/
107   __HAL_FLASH_POWER_DOWN_DISABLE();
108 
109   return HAL_OK;
110 }
111 
112 /**
113   * @brief  Program the FLASH DBANK User Option Byte.
114   *
115   * @note   To configure the user option bytes, the option lock bit OPTLOCK must
116   *         be cleared with the call of the HAL_FLASH_OB_Unlock() function.
117   * @note   To modify the DBANK option byte, all secure protection mechanism
118   *         should be deactivated. It should be done before DBANK modification
119   *         otherwise OPTWERR will be set. The secure areas should be reactived after
120   *         the modifications
121   *
122   * @param  DBankConfig: The FLASH DBANK User Option Byte value.
123   *          This parameter  can be one of the following values:
124   *            @arg OB_DBANK_128_BITS: Single-bank with 128-bits data
125   *            @arg OB_DBANK_64_BITS: Dual-bank with 64-bits data
126   *
127   * @retval HAL status
128   */
HAL_FLASHEx_OB_DBankConfig(uint32_t DBankConfig)129 __RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_OB_DBankConfig(uint32_t DBankConfig)
130 {
131   uint32_t count, reg;
132   HAL_StatusTypeDef status = HAL_ERROR;
133 
134   /* Process Locked */
135   __HAL_LOCK(&pFlash);
136 
137 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
138   /* Check if the Watermark-based secure area of 1st bank is deactivated */
139   reg = FLASH->SECWM1R1;
140   if ((reg & FLASH_SECWM1R1_SECWM1_PSTRT) > ((reg & FLASH_SECWM1R1_SECWM1_PEND) >> FLASH_SECWM1R1_SECWM1_PEND_Pos))
141   {
142     /* Check if the Watermark-based secure area of 2nd bank is deactivated */
143     reg = FLASH->SECWM2R1;
144     if ((reg & FLASH_SECWM2R1_SECWM2_PSTRT) > ((reg & FLASH_SECWM2R1_SECWM2_PEND) >> FLASH_SECWM2R1_SECWM2_PEND_Pos))
145     {
146 #endif
147       /* Disable WRP zone 1 of 1st bank if needed */
148       reg = FLASH->WRP1AR;
149       if ((reg & FLASH_WRP1AR_WRP1A_PSTRT) <= ((reg & FLASH_WRP1AR_WRP1A_PEND) >> FLASH_WRP1AR_WRP1A_PEND_Pos))
150       {
151         MODIFY_REG(FLASH->WRP1AR, (FLASH_WRP1AR_WRP1A_PSTRT | FLASH_WRP1AR_WRP1A_PEND), FLASH_WRP1AR_WRP1A_PSTRT);
152       }
153 
154       /* Disable WRP zone 1 of 2nd bank if needed */
155       reg = FLASH->WRP1BR;
156       if ((reg & FLASH_WRP1BR_WRP1B_PSTRT) <= ((reg & FLASH_WRP1BR_WRP1B_PEND) >> FLASH_WRP1BR_WRP1B_PEND_Pos))
157       {
158         MODIFY_REG(FLASH->WRP1BR, (FLASH_WRP1BR_WRP1B_PSTRT | FLASH_WRP1BR_WRP1B_PEND), FLASH_WRP1BR_WRP1B_PSTRT);
159       }
160 
161       /* Disable WRP zone 2 of 1st bank if needed */
162       reg = FLASH->WRP2AR;
163       if ((reg & FLASH_WRP2AR_WRP2A_PSTRT) <= ((reg & FLASH_WRP2AR_WRP2A_PEND) >> FLASH_WRP2AR_WRP2A_PEND_Pos))
164       {
165         MODIFY_REG(FLASH->WRP2AR, (FLASH_WRP2AR_WRP2A_PSTRT | FLASH_WRP2AR_WRP2A_PEND), FLASH_WRP2AR_WRP2A_PSTRT);
166       }
167 
168       /* Disable WRP zone 2 of 2nd bank if needed */
169       reg = FLASH->WRP2BR;
170       if ((reg & FLASH_WRP2BR_WRP2B_PSTRT) <= ((reg & FLASH_WRP2BR_WRP2B_PEND) >> FLASH_WRP2BR_WRP2B_PEND_Pos))
171       {
172         MODIFY_REG(FLASH->WRP2BR, (FLASH_WRP2BR_WRP2B_PSTRT | FLASH_WRP2BR_WRP2B_PEND), FLASH_WRP2BR_WRP2B_PSTRT);
173       }
174 
175 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
176       /* Disable the Block-based secure area of 1st bank if needed */
177       if (FLASH->SECBB1R1 != 0u)
178       {
179         FLASH->SECBB1R1 = 0u;
180       }
181 
182       if (FLASH->SECBB1R2 != 0u)
183       {
184         FLASH->SECBB1R2 = 0u;
185       }
186 
187       if (FLASH->SECBB1R3 != 0u)
188       {
189         FLASH->SECBB1R3 = 0u;
190       }
191 
192       if (FLASH->SECBB1R4 != 0u)
193       {
194         FLASH->SECBB1R4 = 0u;
195       }
196 
197       /* Disable the Block-based secure area of 2nd bank if needed */
198       if (FLASH->SECBB2R1 != 0u)
199       {
200         FLASH->SECBB2R1 = 0u;
201       }
202 
203       if (FLASH->SECBB2R2 != 0u)
204       {
205         FLASH->SECBB2R2 = 0u;
206       }
207 
208       if (FLASH->SECBB2R3 != 0u)
209       {
210         FLASH->SECBB2R3 = 0u;
211       }
212 
213       if (FLASH->SECBB2R4 != 0u)
214       {
215         FLASH->SECBB2R4 = 0u;
216       }
217 #endif
218 
219       /* Modify the DBANK user option byte */
220       MODIFY_REG(FLASH->OPTR, FLASH_OPTR_DBANK, DBankConfig);
221 
222       /* Set OPTSTRT Bit */
223       SET_BIT(FLASH->NSCR, FLASH_NSCR_OPTSTRT);
224 
225       /* Wait for last operation to be completed */
226       /* 8 is the number of required instruction cycles for the below loop statement (timeout expressed in ms) */
227       count = FLASH_TIMEOUT_VALUE * (SystemCoreClock / 8U / 1000U);
228       do
229       {
230         if (count == 0U)
231         {
232           break;
233         }
234         count--;
235       } while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != 0U);
236 
237       /* If the option byte program operation is completed, disable the OPTSTRT Bit */
238       CLEAR_BIT(FLASH->NSCR, FLASH_NSCR_OPTSTRT);
239 
240       /* Process Unlocked */
241       __HAL_UNLOCK(&pFlash);
242 
243       if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTWERR) == 0U)
244       {
245         /* Set the bit to force the option byte reloading */
246         SET_BIT(FLASH->NSCR, FLASH_NSCR_OBL_LAUNCH);
247       }
248       else
249       {
250         __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTWERR);
251         pFlash.ErrorCode |= FLASH_FLAG_OPTWERR;
252       }
253 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
254     }
255   }
256 #endif
257   return status;
258 }
259 
260 /**
261   * @}
262   */
263 
264 /**
265   * @}
266   */
267 #endif /* HAL_FLASH_MODULE_ENABLED */
268 
269 /**
270   * @}
271   */
272 
273 /**
274   * @}
275   */
276 
277