1 /**
2 ******************************************************************************
3 * @file EEPROM_Emul/Porting/STM32L4/flash_interface.c
4 * @author MCD Application Team
5 * @brief This file provides all the EEPROM emulation flash interface functions.
6 ******************************************************************************
7 * @attention
8 *
9 * <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V.
10 * All rights reserved.</center></h2>
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted, provided that the following conditions are met:
14 *
15 * 1. Redistribution of source code must retain the above copyright notice,
16 * this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright notice,
18 * this list of conditions and the following disclaimer in the documentation
19 * and/or other materials provided with the distribution.
20 * 3. Neither the name of STMicroelectronics nor the names of other
21 * contributors to this software may be used to endorse or promote products
22 * derived from this software without specific written permission.
23 * 4. This software, including modifications and/or derivative works of this
24 * software, must execute solely and exclusively on microcontroller or
25 * microprocessor devices manufactured by or for STMicroelectronics.
26 * 5. Redistribution and use of this software other than as permitted under
27 * this license is void and will automatically terminate your rights under
28 * this license.
29 *
30 * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
31 * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
33 * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
34 * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
35 * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
36 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
37 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
38 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
39 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
40 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
41 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 *
43 ******************************************************************************
44 */
45
46 /* Includes ------------------------------------------------------------------*/
47 #include "eeprom_emul.h"
48 #include "flash_interface.h"
49
50 /** @addtogroup EEPROM_Emulation
51 * @{
52 */
53
54 /* Private typedef -----------------------------------------------------------*/
55 /* Private constants ---------------------------------------------------------*/
56 /* Private macro -------------------------------------------------------------*/
57 /* Private variables ---------------------------------------------------------*/
58 /* Private function prototypes -----------------------------------------------*/
59 static uint32_t GetBankNumber(uint32_t Address);
60
61 /* Exported functions --------------------------------------------------------*/
62 /* Private functions ---------------------------------------------------------*/
63 /** @addtogroup EEPROM_Private_Functions
64 * @{
65 */
66
67 /**
68 * @brief Erase a page in polling mode
69 * @param Page Page number
70 * @param NbPages Number of pages to erase
71 * @retval EE_Status
72 * - EE_OK: on success
73 * - EE error code: if an error occurs
74 */
PageErase(uint32_t Page,uint16_t NbPages)75 EE_Status PageErase(uint32_t Page, uint16_t NbPages)
76 {
77 EE_Status status = EE_OK;
78 FLASH_EraseInitTypeDef s_eraseinit;
79 uint32_t bank = FLASH_BANK_1, page_error = 0U;
80
81 #if defined(FLASH_OPTR_BFB2)
82 bank = GetBankNumber(PAGE_ADDRESS(Page));
83 #endif
84
85 s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES;
86 s_eraseinit.NbPages = NbPages;
87 s_eraseinit.Page = Page;
88 s_eraseinit.Banks = bank;
89
90 /* Erase the Page: Set Page status to ERASED status */
91 if (HAL_FLASHEx_Erase(&s_eraseinit, &page_error) != HAL_OK)
92 {
93 status = EE_ERASE_ERROR;
94 }
95 return status;
96 }
97
98 /**
99 * @brief Erase a page with interrupt enabled
100 * @param Page Page number
101 * @param NbPages Number of pages to erase
102 * @retval EE_Status
103 * - EE_OK: on success
104 * - EE error code: if an error occurs
105 */
PageErase_IT(uint32_t Page,uint16_t NbPages)106 EE_Status PageErase_IT(uint32_t Page, uint16_t NbPages)
107 {
108 EE_Status status = EE_OK;
109 FLASH_EraseInitTypeDef s_eraseinit;
110 uint32_t bank = FLASH_BANK_1;
111
112 #if defined(FLASH_OPTR_BFB2)
113 bank = GetBankNumber(PAGE_ADDRESS(Page));
114 #endif
115
116 s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES;
117 s_eraseinit.NbPages = NbPages;
118 s_eraseinit.Page = Page;
119 s_eraseinit.Banks = bank;
120
121 /* Erase the Page: Set Page status to ERASED status */
122 if (HAL_FLASHEx_Erase_IT(&s_eraseinit) != HAL_OK)
123 {
124 status = EE_ERASE_ERROR;
125 }
126 return status;
127 }
128
129 /**
130 * @brief Gets the bank of a given address
131 * @param Address Address of the FLASH Memory
132 * @retval Bank_Number The bank of a given address
133 */
GetBankNumber(uint32_t Address)134 static uint32_t GetBankNumber(uint32_t Address)
135 {
136 uint32_t bank = 0U;
137
138 if (READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_FB_MODE) == 0U)
139 {
140 /* No Bank swap */
141 if (Address < (FLASH_BASE + FLASH_BANK_SIZE))
142 {
143 bank = FLASH_BANK_1;
144 }
145 else
146 {
147 bank = FLASH_BANK_2;
148 }
149 }
150 else
151 {
152 /* Bank swap */
153 if (Address < (FLASH_BASE + FLASH_BANK_SIZE))
154 {
155 bank = FLASH_BANK_2;
156 }
157 else
158 {
159 bank = FLASH_BANK_1;
160 }
161 }
162
163 return bank;
164 }
165
166 /**
167 * @brief Delete corrupted Flash address, can be called from NMI. No Timeout.
168 * @param Address Address of the FLASH Memory to delete
169 * @retval EE_Status
170 * - EE_OK: on success
171 * - EE error code: if an error occurs
172 */
DeleteCorruptedFlashAddress(uint32_t Address)173 EE_Status DeleteCorruptedFlashAddress(uint32_t Address)
174 {
175 uint32_t dcachetoreactivate = 0U;
176 EE_Status status = EE_OK;
177
178 /* Deactivate the data cache if they are activated to avoid data misbehavior */
179 if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != RESET)
180 {
181 /* Disable data cache */
182 __HAL_FLASH_DATA_CACHE_DISABLE();
183 dcachetoreactivate = 1U;
184 }
185
186 /* Set FLASH Programmation bit */
187 SET_BIT(FLASH->CR, FLASH_CR_PG);
188
189 /* Program double word of value 0 */
190 *(__IO uint32_t*)(Address) = (uint32_t)0U;
191 *(__IO uint32_t*)(Address+4U) = (uint32_t)0U;
192
193 /* Wait programmation completion */
194 while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY))
195 {
196 }
197
198 /* Check if error occured */
199 if((__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PROGERR)) ||
200 (__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR)) ||
201 (__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGSERR)))
202 {
203 status = EE_DELETE_ERROR;
204 }
205
206 /* Check FLASH End of Operation flag */
207 if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
208 {
209 /* Clear FLASH End of Operation pending bit */
210 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
211 }
212
213 /* Clear FLASH Programmation bit */
214 CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
215
216 /* Flush the caches to be sure of the data consistency */
217 if(dcachetoreactivate == 1U)
218 {
219 /* Reset data cache */
220 __HAL_FLASH_DATA_CACHE_RESET();
221 /* Enable data cache */
222 __HAL_FLASH_DATA_CACHE_ENABLE();
223 }
224
225 /* Clear FLASH ECCD bit */
226 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ECCD);
227
228 return status;
229 }
230
231 /**
232 * @brief Check if the configuration is 128-bits bank or 2*64-bits bank
233 * @param None
234 * @retval EE_Status
235 * - EE_OK: on success
236 * - EE error code: if an error occurs
237 */
CheckBankConfig(void)238 EE_Status CheckBankConfig(void)
239 {
240 #if defined (FLASH_OPTR_DBANK)
241 FLASH_OBProgramInitTypeDef sOBCfg;
242 EE_Status status;
243
244 /* Request the Option Byte configuration :
245 - User and RDP level are always returned
246 - WRP and PCROP are not requested */
247 sOBCfg.WRPArea = 0xFF;
248 sOBCfg.PCROPConfig = 0xFF;
249 HAL_FLASHEx_OBGetConfig(&sOBCfg);
250
251 /* Check the value of the DBANK user option byte */
252 if ((sOBCfg.USERConfig & OB_DBANK_64_BITS) != 0)
253 {
254 status = EE_OK;
255 }
256 else
257 {
258 status = EE_INVALID_BANK_CFG;
259 }
260
261 return status;
262 #else
263 /* No feature 128-bits single bank, so always 64-bits dual bank */
264 return EE_OK;
265 #endif
266 }
267
268
269 /**
270 * @}
271 */
272
273 /**
274 * @}
275 */
276
277 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
278