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>&copy; 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