1 /**
2   ******************************************************************************
3   * @file    tae32f53xx_ll_flash.c
4   * @author  MCD Application Team
5   * @brief   FLASH LL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the internal FLASH memory:
8   *           + Program operations functions
9   *           + Erase operations functions
10   *           + Peripheral State functions
11   *           + Write Protection Area configure functions
12   *           + Read Protection Level configure functions
13   *           + Interrupt and Callback functions
14   *
15   ******************************************************************************
16   * @attention
17   *
18   * <h2><center>&copy; Copyright (c) 2020 Tai-Action.
19   * All rights reserved.</center></h2>
20   *
21   * This software is licensed by Tai-Action under BSD 3-Clause license,
22   * the "License"; You may not use this file except in compliance with the
23   * License. You may obtain a copy of the License at:
24   *                        opensource.org/licenses/BSD-3-Clause
25   *
26   ******************************************************************************
27   */
28 
29 /* Includes ------------------------------------------------------------------*/
30 #include "tae32f53xx_ll.h"
31 
32 
33 #define DBG_TAG             "FLASH LL"
34 #define DBG_LVL             DBG_ERROR
35 #include "dbg/tae32f53xx_dbg.h"
36 
37 
38 /** @addtogroup TAE32F53xx_LL_Driver
39   * @{
40   */
41 
42 /** @defgroup FLASH_LL FLASH LL
43   * @brief    Flash LL module driver.
44   * @{
45   */
46 
47 #ifdef LL_FLASH_MODULE_ENABLED
48 
49 /* Private typedef -----------------------------------------------------------*/
50 /* Private define ------------------------------------------------------------*/
51 /* Private macro -------------------------------------------------------------*/
52 /* Private variables ---------------------------------------------------------*/
53 /** @defgroup FLASH_LL_Private_Variables FLASH LL Private Variables
54   * @brief    FLASH LL Private Variables
55   * @{
56   */
57 
58 /** @brief Variable whitch recorded the error codes.
59   *        This parameter can be any combination of @ref FLASH_Error_Codes
60   */
61 static uint32_t FlashErrorCode = FLASH_ERROR_NONE;
62 
63 /**
64   * @}
65   */
66 
67 
68 /* Private function prototypes -----------------------------------------------*/
69 /** @defgroup FLASH_LL_Private_Functions FLASH LL Private Functions
70   * @brief    FLASH LL Private Functions
71   * @{
72   */
73 static void FLASH_SetErrorCode(void);
74 
75 /**
76   * @}
77   */
78 
79 
80 /* Exported functions --------------------------------------------------------*/
81 /** @defgroup FLASH_LL_Exported_Functions FLASH LL Exported Functions
82   * @brief    FLASH LL Exported Functions
83   * @{
84   */
85 
86 /** @defgroup FLASH_LL_Exported_Functions_Group1 FLASH Peripheral Control functions
87   * @brief    FLASH Peripheral Control functions
88 @verbatim
89   ===============================================================================
90                        ##### Peripheral Control functions #####
91   ===============================================================================
92   [..]
93     This section provides functions allowing to:
94     (+) Read Protection Level configure
95     (+) Write Protection Area configure
96 
97 @endverbatim
98   * @{
99   */
100 
101 /**
102   * @brief  Read Protection Level configuration.
103   * @param  RDPLevel specifies the read protection level
104   *         This parameter can be a value of @ref FLASH_Read_Protection_Level:
105   *             @arg FLASH_RDP_LEVEL_0 : No protection
106   *             @arg FLASH_RDP_LEVEL_1 : Memory Read protection
107   *             @arg FLASH_RDP_LEVEL_2 : Full chip protection
108   * @note   When enabling read protection level 2, it's no more possible to
109   *         go back to level 1 or level 0.
110   * @note   The function @ref LL_FLASH_Unlock() should be called before to unlock the FLASH interface
111   *         The function @ref LL_FLASH_PF_Unlock() should be called before to unlock the protection feature
112   *         The function @ref LL_FLASH_PF_Launch() should be called after to force the reload of the new configuration
113   * @return LL Status
114   */
LL_FLASH_ReadProtectLevelConfig(FLASH_RDPLVETypeDef RDPLevel)115 LL_StatusETypeDef LL_FLASH_ReadProtectLevelConfig(FLASH_RDPLVETypeDef RDPLevel)
116 {
117     LL_StatusETypeDef status = LL_OK;
118 
119     if ((status = LL_FLASH_WaitForLastOperation(FLASH_TIMEOUT_MAX_VALUE)) == LL_OK) {
120         /* Clear error code before operation */
121         FlashErrorCode = FLASH_ERROR_NONE;
122 
123         /* Configure the RDP level in the userdata register */
124         MODIFY_REG(FLASH->RDPR, FLASH_RDPR_RDP_Msk, RDPLevel);
125 
126         /* Wait until operation complete */
127         status = LL_FLASH_WaitForLastOperation(FLASH_TIMEOUT_MAX_VALUE);
128     }
129 
130     return status;
131 }
132 
133 /**
134   * @brief  Write Protection configuration.
135   * @param  WRPAreas specifies the area to configure Write Protection.
136   *         This parameter can be any combination value of @ref FLASH_Write_Protection_Area.
137   * @param  WRPState Enable/Disable WRP state for the specifies WPRAreas.
138   *         This parameter can be a value of @ref FLASH_WRP_State:
139   *             @arg FLASH_WRPSTATE_DISABLE: Disable specifies areas WRP
140   *             @arg FLASH_WRPSTATE_ENABLE: Enable specifies areas WRP
141   * @note   Once memory area Write Protection is enabled, user must not program the memory area
142   *         until the protection is disabled.
143   * @note   The function @ref LL_FLASH_Unlock() should be called before to unlock the FLASH interface
144   *         The function @ref LL_FLASH_PF_Unlock() should be called before to unlock the protection feature
145   *         The function @ref LL_FLASH_PF_Launch() should be called after to force the reload of the new configuration
146   * @return Status
147   */
LL_FLASH_WriteProtectConfig(FLASH_WRPAREAETypeDef WRPAreas,FLASH_WRPSTETypeDef WRPState)148 LL_StatusETypeDef LL_FLASH_WriteProtectConfig(FLASH_WRPAREAETypeDef WRPAreas, FLASH_WRPSTETypeDef WRPState)
149 {
150     LL_StatusETypeDef status = LL_OK;
151 
152     if ((status = LL_FLASH_WaitForLastOperation(FLASH_TIMEOUT_MAX_VALUE)) == LL_OK) {
153         /* Clear error code before operation */
154         FlashErrorCode = FLASH_ERROR_NONE;
155 
156         if (WRPState == FLASH_WRPSTATE_ENABLE) {
157             /* Enable the Write Protection */
158             CLEAR_BIT(FLASH->WRPR, WRPAreas);
159         } else {
160             /* Disable the Write Protection */
161             SET_BIT(FLASH->WRPR, WRPAreas);
162         }
163 
164         /* Wait until operation complete */
165         status = LL_FLASH_WaitForLastOperation(FLASH_TIMEOUT_MAX_VALUE);
166     }
167 
168     return status;
169 }
170 
171 /**
172   * @}
173   */
174 
175 
176 /** @defgroup FLASH_LL_Exported_Functions_Group2 FLASH Peripheral State functions
177   * @brief    FLASH Peripheral State functions
178 @verbatim
179   ===============================================================================
180                        ##### Peripheral State functions #####
181   ===============================================================================
182   [..]
183     This section provides functions allowing to:
184     (+) Peripheral State functions
185 
186 @endverbatim
187   * @{
188   */
189 
190 /**
191   * @brief  Wait for a FLASH operation to complete.
192   * @param  Timeout Maximum flash operation timeout
193   * @return LL Status
194   */
LL_FLASH_WaitForLastOperation(uint32_t Timeout)195 LL_StatusETypeDef LL_FLASH_WaitForLastOperation(uint32_t Timeout)
196 {
197     uint32_t tickstart = LL_GetTick();
198 
199     /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
200        Even if the FLASH operation fails, the BUSY flag will be reset and an error
201        flag will be set */
202     while (__LL_FLASH_GET_STATUS_FLAG(FLASH_FLAG_BSY) != RESET) {
203         if (Timeout != LL_WAIT_FOREVER) {
204             if ((Timeout == 0U) || ((LL_GetTick() - tickstart) > Timeout)) {
205                 return LL_TIMEOUT;
206             }
207         }
208     }
209 
210     /* Check and clear DIF flag */
211     if (__LL_FLASH_GET_PENDING_FLAG(FLASH_FLAG_DIF) != RESET) {
212         __LL_FLASH_CLEAR_PENDING_FLAG(FLASH_FLAG_DIF);
213     }
214 
215     /* Check if any errors occurred */
216     if ((__LL_FLASH_GET_PENDING_FLAG(FLASH_FLAG_RPEIF) != RESET)    ||
217         (__LL_FLASH_GET_PENDING_FLAG(FLASH_FLAG_WPEIF) != RESET)    ||
218         (__LL_FLASH_GET_PENDING_FLAG(FLASH_FLAG_OPTEIF) != RESET)   ||
219         (__LL_FLASH_GET_PENDING_FLAG(FLASH_FLAG_ECCEIF) != RESET)) {
220         /* Save the error code */
221         FLASH_SetErrorCode();
222         return LL_ERROR;
223     }
224 
225     /* Return function status */
226     return LL_OK;
227 }
228 
229 /**
230   * @brief  Get the specific FLASH error flags.
231   * @return The returned value can be any combination of @ref FLASH_Error_Codes
232   */
LL_FLASH_GetError(void)233 uint32_t LL_FLASH_GetError(void)
234 {
235     return FlashErrorCode;
236 }
237 
238 /**
239   * @}
240   */
241 
242 
243 /** @defgroup FLASH_LL_Exported_Functions_Group3 FLASH Input and Output operation functions
244   * @brief    FLASH Input and Output operation functions
245 @verbatim
246   ===============================================================================
247                   ##### Input and Output operation functions #####
248   ===============================================================================
249   [..]
250     This section provides functions allowing to:
251     (+) Program operations functions
252     (+) Erase operations functions
253 
254 @endverbatim
255   * @{
256   */
257 
258 /**
259   * @brief  Program 16 bytes (128 bit) at a specified address.
260   * @param  Address specifies the address to be programmed.
261   *         Notice that address must align to 128 bit
262   * @param  Data[] specifies the data to be programmed.
263   *         FLASH_PROG_DATA_WIDTH bytes will be programmed in a single operation.
264   * @note   LL_FLASH_Unlock() should be called before to unlock the FLASH interface
265   *         LL_FLASH_Lock() should be called after to lock the FLASH interface
266   * @return LL Status
267   */
LL_FLASH_Program(uint32_t Address,uint8_t Data[FLASH_PROG_DATA_WIDTH])268 LL_StatusETypeDef LL_FLASH_Program(uint32_t Address, uint8_t Data[FLASH_PROG_DATA_WIDTH])
269 {
270     LL_StatusETypeDef status = LL_OK;
271 
272     /* Check the parameters */
273     assert_param(Data != NULL);
274     assert_param(IS_FLASH_PROGRAM_ADDRESS_ALIGN_128BIT(Address));
275 
276     /* Address mask */
277     Address &= FLASH_PROGRAM_ADDRESS_MASK;
278 
279     if ((status = LL_FLASH_WaitForLastOperation(FLASH_TIMEOUT_MAX_VALUE)) == LL_OK) {
280         /* Clear error code before operation */
281         FlashErrorCode = FLASH_ERROR_NONE;
282 
283         /* Fill the data into FLASH Program Control Registers */
284         FLASH->DR0 = *((__IO uint32_t *)(Data +  0));
285         FLASH->DR1 = *((__IO uint32_t *)(Data +  4));
286         FLASH->DR2 = *((__IO uint32_t *)(Data +  8));
287         FLASH->DR3 = *((__IO uint32_t *)(Data + 12));
288 
289         /* Set Address */
290         FLASH->ADDR = Address;
291 
292         /* Ignore full 0xFF data programming */
293         if ((FLASH->DR0 != 0xFFFFFFFFU) &&
294             (FLASH->DR1 != 0xFFFFFFFFU) &&
295             (FLASH->DR2 != 0xFFFFFFFFU) &&
296             (FLASH->DR3 != 0xFFFFFFFFU)) {
297 
298             /* Pragram Start */
299             SET_BIT(FLASH->CR, FLASH_CR_PS);
300 
301             /* Wait until operation complete */
302             status = LL_FLASH_WaitForLastOperation(FLASH_TIMEOUT_MAX_VALUE);
303         }
304     }
305 
306     /* Return function status */
307     return status;
308 }
309 
310 /**
311   * @brief  Erase one specified FLASH memory sector.
312   * @param  sector The start sector number of the specified sectors to erase.
313   *         This parameter must be a value between 0 and (NB of sectors - 1)
314   * @note   LL_FLASH_Unlock() should be called before to unlock the FLASH interface
315   *         LL_FLASH_Lock() should be called after to lock the FLASH interface
316   * @return Status
317   */
LL_FLASH_SectorErase(uint16_t Sector)318 LL_StatusETypeDef LL_FLASH_SectorErase(uint16_t Sector)
319 {
320     LL_StatusETypeDef status = LL_OK;
321 
322     /* Check the parameters */
323     assert_param(IS_FLASH_NB_SECTORS(Sector));
324 
325     if ((status = LL_FLASH_WaitForLastOperation(FLASH_TIMEOUT_MAX_VALUE)) == LL_OK) {
326         /* Clear error code before operation */
327         FlashErrorCode = FLASH_ERROR_NONE;
328 
329         /* Set to Sector Erase mode */
330         CLEAR_BIT(FLASH->ECR, FLASH_ECR_EMODE);
331 
332         /* Set Sector to erase */
333         MODIFY_REG(FLASH->ECR, FLASH_ECR_ESNB_Msk, Sector);
334 
335         /* Erase Start */
336         SET_BIT(FLASH->CR, FLASH_CR_ES);
337 
338         /* Wait until operation complete */
339         status = LL_FLASH_WaitForLastOperation(FLASH_TIMEOUT_MAX_VALUE);
340     }
341 
342     /* Return function status */
343     return status;
344 }
345 
346 /**
347   * @brief  Erase the specified FLASH memory multiple sectors.
348   * @param  sector The start sector number of the specified sectors to erase.
349   *         This parameter must be a value between 0 and (NB of sectors - 1)
350   * @param  num Number of sectors to be erased.
351   *         This parameter must be a value between 1 and NB of sectors
352   * @note   Please notice that all specified sectors number must between 0 and (NB of sectors - 1)
353   * @param  *SectorError Pointer to variable that contains the configuration information on faulty
354   *         sector in case of error (0xFFFF means that all the sectors have been correctly erased).
355   *         Set this pointer to NULL if you do not need it.
356   * @note   LL_FLASH_Unlock() should be called before to unlock the FLASH interface
357   *         LL_FLASH_Lock() should be called after to lock the FLASH interface
358   * @return LL Status
359   */
LL_FLASH_MultiSectorsErase(uint16_t Sector,uint16_t Num,uint16_t * SectorError)360 LL_StatusETypeDef LL_FLASH_MultiSectorsErase(uint16_t Sector, uint16_t Num, uint16_t *SectorError)
361 {
362     LL_StatusETypeDef status = LL_OK;
363 
364     assert_param(Num != 0);
365     assert_param(IS_FLASH_NB_SECTORS(Sector));
366     assert_param(IS_FLASH_NB_SECTORS(Sector + Num - 1));
367 
368     if ((status = LL_FLASH_WaitForLastOperation(FLASH_TIMEOUT_MAX_VALUE)) == LL_OK) {
369         /* Clear error code before operation */
370         FlashErrorCode = FLASH_ERROR_NONE;
371 
372         /*Initialization of SectorError variable*/
373         if (SectorError != NULL) {
374             *SectorError = 0xFFFF;
375         }
376 
377         /* Set to Sector Erase mode */
378         CLEAR_BIT(FLASH->ECR, FLASH_ECR_EMODE);
379 
380         /* Erase the specified sectors */
381         for (uint16_t index = Sector; index < (Sector + Num); index++) {
382             /* Set current Sector to erase */
383             MODIFY_REG(FLASH->ECR, FLASH_ECR_ESNB_Msk, index);
384 
385             /* Erase Start */
386             SET_BIT(FLASH->CR, FLASH_CR_ES);
387 
388             /* Wait until operation complete */
389             if ((status = LL_FLASH_WaitForLastOperation(FLASH_TIMEOUT_MAX_VALUE)) != LL_OK) {
390                 /* In case of error, stop erase procedure and return the faulty Sector */
391                 if (SectorError != NULL) {
392                     *SectorError = index;
393                 }
394 
395                 break;
396             }
397         }
398     }
399 
400     /* Return function status */
401     return status;
402 }
403 
404 /**
405   * @brief  FLASH memory mass erase. This will erase the entire FLASH memory.
406   * @note   LL_FLASH_Unlock() should be called before to unlock the FLASH interface
407   *         LL_FLASH_Lock() should be called after to lock the FLASH interface
408   * @return LL Status
409   */
LL_FLASH_ChipErase(void)410 LL_StatusETypeDef LL_FLASH_ChipErase(void)
411 {
412     LL_StatusETypeDef status = LL_OK;
413 
414     if ((status = LL_FLASH_WaitForLastOperation(FLASH_TIMEOUT_MAX_VALUE)) == LL_OK) {
415         /* Clear error code before operation */
416         FlashErrorCode = FLASH_ERROR_NONE;
417 
418         /* Set to Chip Erase mode */
419         SET_BIT(FLASH->ECR, FLASH_ECR_EMODE);
420 
421         /* Erase Start */
422         SET_BIT(FLASH->CR, FLASH_CR_ES);
423 
424         /* Wait until operation complete */
425         status = LL_FLASH_WaitForLastOperation(FLASH_TIMEOUT_MAX_VALUE);
426     }
427 
428     /* Return function status */
429     return status;
430 }
431 
432 /**
433   * @}
434   */
435 
436 /**
437   * @}
438   */
439 
440 
441 /* Private functions ---------------------------------------------------------*/
442 /** @addtogroup FLASH_LL_Private_Functions
443   * @{
444   */
445 
446 /**
447   * @brief  Set the specific FLASH error flag.
448   * @return None
449   */
FLASH_SetErrorCode(void)450 static void FLASH_SetErrorCode(void)
451 {
452     if (__LL_FLASH_GET_PENDING_FLAG(FLASH_FLAG_RPEIF) != RESET) {
453         FlashErrorCode |= FLASH_ERROR_RDP;
454         __LL_FLASH_CLEAR_PENDING_FLAG(FLASH_FLAG_RPEIF);
455     }
456 
457     if (__LL_FLASH_GET_PENDING_FLAG(FLASH_FLAG_WPEIF) != RESET) {
458         FlashErrorCode |= FLASH_ERROR_WRP;
459         __LL_FLASH_CLEAR_PENDING_FLAG(FLASH_FLAG_WPEIF);
460     }
461 
462     if (__LL_FLASH_GET_PENDING_FLAG(FLASH_FLAG_OPTEIF) != RESET) {
463         FlashErrorCode |= FLASH_ERROR_OPT;
464         __LL_FLASH_CLEAR_PENDING_FLAG(FLASH_FLAG_OPTEIF);
465     }
466 
467     if (__LL_FLASH_GET_PENDING_FLAG(FLASH_FLAG_ECCEIF) != RESET) {
468         FlashErrorCode |= FLASH_ERROR_ECC;
469         __LL_FLASH_CLEAR_PENDING_FLAG(FLASH_FLAG_ECCEIF);
470     }
471 }
472 
473 /**
474   * @}
475   */
476 
477 
478 #endif /* LL_FLASH_MODULE_ENABLED */
479 
480 
481 /**
482   * @}
483   */
484 
485 /**
486   * @}
487   */
488 
489 
490 /************************* (C) COPYRIGHT Tai-Action *****END OF FILE***********/
491 
492