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>© 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