1 /**
2 ******************************************************************************
3 * @file tae32f53xx_ll_dflash.c
4 * @author MCD Application Team
5 * @brief Source file for DFLASH module.
6 *
7 ******************************************************************************
8 * @attention
9 *
10 * <h2><center>© Copyright (c) 2020 Tai-Action.
11 * All rights reserved.</center></h2>
12 *
13 * This software is licensed by Tai-Action under BSD 3-Clause license,
14 * the "License"; You may not use this file except in compliance with the
15 * License. You may obtain a copy of the License at:
16 * opensource.org/licenses/BSD-3-Clause
17 *
18 ******************************************************************************
19 */
20
21 /* Includes ------------------------------------------------------------------*/
22 #include "tae32f53xx_ll.h"
23
24
25 #define DBG_TAG "DFLASH LL"
26 #define DBG_LVL DBG_ERROR
27 #include "dbg/tae32f53xx_dbg.h"
28
29
30 /** @addtogroup TAE32F53xx_LL_Driver
31 * @{
32 */
33
34 /** @defgroup DFLASH_LL DFLASH LL
35 * @brief DFLASH LL module driver
36 * @{
37 */
38
39 #ifdef LL_DFLASH_MODULE_ENABLED
40
41 /* Private define ------------------------------------------------------------*/
42 /* Private macro -------------------------------------------------------------*/
43 /* Private typedef -----------------------------------------------------------*/
44 /* Private variables ---------------------------------------------------------*/
45 /* Private function prototypes -----------------------------------------------*/
46 /* Exported functions --------------------------------------------------------*/
47 /** @defgroup DFLASH_LL_Exported_Functions DFLASH LL Exported Functions
48 * @brief DFLASH LL Exported Functions
49 * @{
50 */
51
52 /** @defgroup DFLASH_LL_Exported_Functions_Group1 DFLASH Peripheral State functions
53 * @brief DFLASH Peripheral State functions
54 @verbatim
55 ===============================================================================
56 ##### Peripheral State functions #####
57 ===============================================================================
58 [..]
59 This section provides functions allowing to:
60 (+) Peripheral State functions
61
62 @endverbatim
63 * @{
64 */
65
66 /**
67 * @brief Wait for a DFLASH operation to complete.
68 * @param Timeout Maximum DataFlash operation timeout
69 * @return LL Status
70 */
LL_DFLASH_WaitForLastOperation(uint32_t Timeout)71 LL_StatusETypeDef LL_DFLASH_WaitForLastOperation(uint32_t Timeout)
72 {
73 uint32_t tickstart = LL_GetTick();
74
75 /* Wait for the DFLASH operation to complete by polling on BUSY flag to be reset.
76 Even if the DFLASH operation fails, the BUSY flag will be reset and an error
77 flag will be set */
78 while (__LL_DFLASH_STATUS_FLAG_GET(DFLASH_FLAG_BSY) != RESET) {
79 if (Timeout != LL_WAIT_FOREVER) {
80 if ((Timeout == 0U) || ((LL_GetTick() - tickstart) > Timeout)) {
81 return LL_TIMEOUT;
82 }
83 }
84 }
85
86 /* Check and clear DIF flag */
87 if (__LL_DFLASH_PENDING_FLAG_GET(DFLASH_FLAG_DIF) != RESET) {
88 __LL_DFLASH_PENDING_FLAG_CLEAR(DFLASH_FLAG_DIF);
89 }
90
91 /* Check if any errors occurred */
92 if (__LL_DFLASH_PENDING_FLAG_GET(DFLASH_FLAG_EIF) != RESET) {
93 return LL_ERROR;
94 }
95
96 /* Return function status */
97 return LL_OK;
98 }
99
100 /**
101 * @}
102 */
103
104
105 /** @defgroup DFLASH_LL_Exported_Functions_Group2 DFLASH Input and Output operation functions
106 * @brief DFLASH Input and Output operation functions
107 @verbatim
108 ===============================================================================
109 ##### Input and Output operation functions #####
110 ===============================================================================
111 [..]
112 This section provides functions allowing to:
113 (+) Byte/Word Program operations functions
114 (+) Byte/Word Read operations functions
115 (+) Erase operations functions
116
117 @endverbatim
118 * @{
119 */
120
121 /**
122 * @brief Program one byte at a specified address.
123 * @param Address specifies the address to be programmed.
124 * @param Data specifies the data to be programmed.
125 * @note LL_DFLASH_Unlock() should be called before to unlock the DFLASH interface
126 * LL_DFLASH_Lock() should be called after to lock the DFLASH interface
127 * @return LL Status
128 */
LL_DFLASH_Program_Byte(uint32_t Address,uint8_t Data)129 LL_StatusETypeDef LL_DFLASH_Program_Byte(uint32_t Address, uint8_t Data)
130 {
131 LL_StatusETypeDef status = LL_OK;
132
133 /* Check the parameters */
134 assert_param(IS_DFLASH_ADDRESS_MASK(Address));
135
136 /* Address mask */
137 Address &= DFLASH_PROGRAM_ADDRESS_MASK;
138
139 if ((status = LL_DFLASH_WaitForLastOperation(DFLASH_TIMEOUT_MAX_VALUE)) == LL_OK) {
140 /* Byte Program mode */
141 CLEAR_BIT(DFLASH->CR, DFLASH_CR_DS);
142
143 /* Fill the data into DFLASH_DR register */
144 WRITE_REG(DFLASH->DR, Data);
145
146 /* Set Address */
147 WRITE_REG(DFLASH->ADDR, Address);
148
149 /* Ignore full 0xFF data programming */
150 if ((DFLASH->DR & 0xFF) != 0xFFU) {
151 /* Pragram Start */
152 SET_BIT(DFLASH->CR, DFLASH_CR_PS);
153
154 /* Wait until operation complete */
155 status = LL_DFLASH_WaitForLastOperation(DFLASH_TIMEOUT_MAX_VALUE);
156 }
157 }
158
159 /* Return function status */
160 return status;
161 }
162
163 /**
164 * @brief Program one word at a specified address.
165 * @param Address specifies the address to be programmed.
166 * Notice that address must align to a word
167 * @param Data specifies the data to be programmed.
168 * @note LL_DFLASH_Unlock() should be called before to unlock the DFLASH interface
169 * LL_DFLASH_Lock() should be called after to lock the DFLASH interface
170 * @return LL Status
171 */
LL_DFLASH_Program_Word(uint32_t Address,uint32_t Data)172 LL_StatusETypeDef LL_DFLASH_Program_Word(uint32_t Address, uint32_t Data)
173 {
174 LL_StatusETypeDef status = LL_OK;
175
176 /* Check the parameters */
177 assert_param(IS_DFLASH_ADDRESS_MASK(Address));
178 assert_param(IS_DFLASH_ADDRESS_CHECK_ALIGN(Address));
179
180 /* Address mask */
181 Address &= DFLASH_PROGRAM_ADDRESS_MASK;
182
183 if ((status = LL_DFLASH_WaitForLastOperation(DFLASH_TIMEOUT_MAX_VALUE)) == LL_OK) {
184 /* Byte Program mode */
185 SET_BIT(DFLASH->CR, DFLASH_CR_DS);
186
187 /* Fill the data into DFLASH_DR register */
188 WRITE_REG(DFLASH->DR, Data);
189
190 /* Set Address */
191 WRITE_REG(DFLASH->ADDR, Address);
192
193 /* Ignore full 0xFF data programming */
194 if (DFLASH->DR != 0xFFFFFFFFU) {
195 /* Pragram Start */
196 SET_BIT(DFLASH->CR, DFLASH_CR_PS);
197
198 /* Wait until operation complete */
199 status = LL_DFLASH_WaitForLastOperation(DFLASH_TIMEOUT_MAX_VALUE);
200 }
201 }
202
203 /* Return function status */
204 return status;
205 }
206
207 /**
208 * @brief Read one byte from a specified address.
209 * @param Address specifies the address to read.
210 * @param Data specifies the data pointer to read in.
211 * @note LL_DFLASH_Unlock() should be called before to unlock the DFLASH interface
212 * LL_DFLASH_Lock() should be called after to lock the DFLASH interface
213 * @return LL Status
214 */
LL_DFLASH_Read_Byte(uint32_t Address,uint8_t * Data)215 LL_StatusETypeDef LL_DFLASH_Read_Byte(uint32_t Address, uint8_t *Data)
216 {
217 LL_StatusETypeDef status = LL_OK;
218
219 /* Check the parameters */
220 assert_param(IS_DFLASH_ADDRESS_MASK(Address));
221
222 /* Address mask */
223 Address &= DFLASH_PROGRAM_ADDRESS_MASK;
224 /* Initialize the value of Data */
225 *Data = 0;
226
227 if ((status = LL_DFLASH_WaitForLastOperation(DFLASH_TIMEOUT_MAX_VALUE)) == LL_OK) {
228 /* Byte Read mode */
229 CLEAR_BIT(DFLASH->CR, DFLASH_CR_DS);
230
231 /* Set Address */
232 WRITE_REG(DFLASH->ADDR, Address);
233
234 /* Read Start */
235 SET_BIT(DFLASH->CR, DFLASH_CR_RS);
236
237 /* Wait until operation complete */
238 if ((status = LL_DFLASH_WaitForLastOperation(DFLASH_TIMEOUT_MAX_VALUE)) == LL_OK) {
239 /* Read the data from DFLASH->DR Registers */
240 *Data = READ_REG(DFLASH->DR) & 0xFFU;
241 }
242 }
243
244 /* Return function status */
245 return status;
246 }
247
248 /**
249 * @brief Read one wrod from a specified address.
250 * @param Address specifies the address to read.
251 * Notice that address must align to a word
252 * @param Data specifies the data pointer to read in.
253 * @note LL_DFLASH_Unlock() should be called before to unlock the DFLASH interface
254 * LL_DFLASH_Lock() should be called after to lock the DFLASH interface
255 * @return LL Status
256 */
LL_DFLASH_Read_Word(uint32_t Address,uint32_t * Data)257 LL_StatusETypeDef LL_DFLASH_Read_Word(uint32_t Address, uint32_t *Data)
258 {
259 LL_StatusETypeDef status = LL_OK;
260
261 /* Check the parameters */
262 assert_param(IS_DFLASH_ADDRESS_MASK(Address));
263 assert_param(IS_DFLASH_ADDRESS_CHECK_ALIGN(Address));
264
265 /* Address mask */
266 Address &= DFLASH_PROGRAM_ADDRESS_MASK;
267 /* Initialize the value of Data */
268 *Data = 0;
269
270 if ((status = LL_DFLASH_WaitForLastOperation(DFLASH_TIMEOUT_MAX_VALUE)) == LL_OK) {
271 /* Byte Read mode */
272 CLEAR_BIT(DFLASH->CR, DFLASH_CR_DS);
273
274 /* Set Address */
275 WRITE_REG(DFLASH->ADDR, Address);
276
277 /* Read Start */
278 SET_BIT(DFLASH->CR, DFLASH_CR_RS);
279
280 /* Wait until operation complete */
281 if ((status = LL_DFLASH_WaitForLastOperation(DFLASH_TIMEOUT_MAX_VALUE)) == LL_OK) {
282 /* Read the data from DFLASH->DR Registers */
283 *Data = READ_REG(DFLASH->DR);
284 }
285 }
286
287 /* Return function status */
288 return status;
289 }
290
291 /**
292 * @brief DFLASH mass erase. This will mass erase the Main-Memory area.
293 * @note Please Notice this function has no effect to the Secondary-Memory.
294 * @note LL_DFLASH_Unlock() should be called before to unlock the DFLASH interface
295 * LL_DFLASH_Lock() should be called after to lock the DFLASH interface
296 * @return LL Status
297 */
LL_DFLASH_MassErase(void)298 LL_StatusETypeDef LL_DFLASH_MassErase(void)
299 {
300 LL_StatusETypeDef status = LL_OK;
301
302 if ((status = LL_DFLASH_WaitForLastOperation(DFLASH_TIMEOUT_MAX_VALUE)) == LL_OK) {
303 /* Set to Mass Erase mode */
304 SET_BIT(DFLASH->ECR, DFLASH_ECR_EMODE);
305
306 /* Erase Start */
307 SET_BIT(DFLASH->CR, DFLASH_CR_ES);
308
309 /* Wait until operation complete */
310 status = LL_DFLASH_WaitForLastOperation(DFLASH_TIMEOUT_MAX_VALUE);
311 }
312
313 /* Return function status */
314 return status;
315 }
316
317 /**
318 * @brief Erase one specified DFLASH memory sector. This function is effective for both
319 * Main-Memory and Secondary-Memory areas.
320 * @param sector The start sector number of the specified sectors to erase.
321 * This parameter must be a value between 0 and (NB of sectors - 1)
322 * @note LL_DFLASH_Unlock() should be called before to unlock the DFLASH interface
323 * LL_DFLASH_Lock() should be called after to lock the DFLASH interface
324 * @return Status
325 */
LL_DFLASH_SectorErase(uint16_t Sector)326 LL_StatusETypeDef LL_DFLASH_SectorErase(uint16_t Sector)
327 {
328 LL_StatusETypeDef status = LL_OK;
329
330 /* Check the parameters */
331 assert_param(IS_DFLASH_NB_SECTORS(Sector));
332
333 if ((status = LL_DFLASH_WaitForLastOperation(DFLASH_TIMEOUT_MAX_VALUE)) == LL_OK) {
334 /* Set to Sector Erase mode */
335 CLEAR_BIT(DFLASH->ECR, DFLASH_ECR_EMODE);
336
337 /* Set Sector to erase */
338 MODIFY_REG(DFLASH->ECR, DFLASH_ECR_ESNB_Msk, Sector);
339
340 /* Erase Start */
341 SET_BIT(DFLASH->CR, DFLASH_CR_ES);
342
343 /* Wait until operation complete */
344 status = LL_DFLASH_WaitForLastOperation(DFLASH_TIMEOUT_MAX_VALUE);
345 }
346
347 /* Return function status */
348 return status;
349 }
350
351 /**
352 * @brief Erase the specified DFLASH memory multiple sectors.
353 * @param sector The start sector number of the specified sectors to erase.
354 * This parameter must be a value between 0 and (NB of sectors - 1)
355 * @param num Number of sectors to be erased.
356 * This parameter must be a value between 1 and NB of sectors
357 * @note Please notice that all specified sectors number must between 0 and (NB of sectors - 1)
358 * @param *SectorError Pointer to variable that contains the configuration information on faulty
359 * sector in case of error (0xFFFF means that all the sectors have been correctly erased).
360 * Set this pointer to NULL if you do not need it.
361 * @note LL_DFLASH_Unlock() should be called before to unlock the DFLASH interface
362 * LL_DFLASH_Lock() should be called after to lock the DFLASH interface
363 * @return LL Status
364 */
LL_DFLASH_MultiSectorsErase(uint16_t Sector,uint16_t Num,uint16_t * SectorError)365 LL_StatusETypeDef LL_DFLASH_MultiSectorsErase(uint16_t Sector, uint16_t Num, uint16_t *SectorError)
366 {
367 LL_StatusETypeDef status = LL_OK;
368
369 assert_param(Num != 0);
370 assert_param(IS_DFLASH_NB_SECTORS(Sector));
371 assert_param(IS_DFLASH_NB_SECTORS(Sector + Num - 1));
372
373 if ((status = LL_DFLASH_WaitForLastOperation(DFLASH_TIMEOUT_MAX_VALUE)) == LL_OK) {
374 /*Initialization of SectorError variable*/
375 if (SectorError != NULL) {
376 *SectorError = 0xFFFF;
377 }
378
379 /* Set to Sector Erase mode */
380 CLEAR_BIT(DFLASH->ECR, DFLASH_ECR_EMODE);
381
382 /* Erase the specified sectors */
383 for (uint16_t index = Sector; index < (Sector + Num); index++) {
384 /* Set current Sector to erase */
385 MODIFY_REG(DFLASH->ECR, DFLASH_ECR_ESNB_Msk, index);
386
387 /* Erase Start */
388 SET_BIT(DFLASH->CR, DFLASH_CR_ES);
389
390 /* Wait until operation complete */
391 if ((status = LL_DFLASH_WaitForLastOperation(DFLASH_TIMEOUT_MAX_VALUE)) != LL_OK) {
392 /* In case of error, stop erase procedure and return the faulty Sector */
393 if (SectorError != NULL) {
394 *SectorError = index;
395 }
396
397 break;
398 }
399 }
400 }
401
402 /* Return function status */
403 return status;
404 }
405
406 /**
407 * @}
408 */
409
410 /**
411 * @}
412 */
413
414
415 /* Private functions ---------------------------------------------------------*/
416
417
418 #endif /* LL_DFLASH_MODULE_ENABLED */
419
420
421 /**
422 * @}
423 */
424
425 /**
426 * @}
427 */
428
429
430 /************************* (C) COPYRIGHT Tai-Action *****END OF FILE***********/
431
432