1 /*
2 * Copyright 2018-2021 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 */
8
9 #include "fsl_k4_flash.h"
10
11 /*******************************************************************************
12 * Definitions
13 ******************************************************************************/
14
15 /* Component ID definition, used by tools. */
16 #ifndef FSL_COMPONENT_ID
17 #define FSL_COMPONENT_ID "platform.drivers.flash_k4"
18 #endif
19
20 #if defined(FLASH_DRIVER_IS_FLASH_RESIDENT) && FLASH_DRIVER_IS_FLASH_RESIDENT
21 /*!
22 * @brief Constants for execute-in-RAM flash function.
23 */
24 enum _ftfx_ram_func_constants
25 {
26 Flash_RunCommandCodeSize = 6U, /*!< The flash_run_command code size of execute-in-RAM.*/
27 Flash_ErsSequenceCommandSize = 25U, /*!< The flash_erase_sequence func code size of execute-in-RAM.*/
28 Flash_PgmSequenceCommandSize = 30U, /*!< The flash_program_sequence func size of execute-in-RAM.*/
29 };
30 #endif
31 /*******************************************************************************
32 * Prototypes
33 ******************************************************************************/
34 /*! @brief Init IFR memory related info */
35 static status_t flash_check_param(
36 flash_config_t *config, FMU_Type *base, uint32_t start, uint32_t lengthInBytes, uint32_t alignmentBaseline);
37 static status_t pflash_check_param(
38 flash_config_t *config, FMU_Type *base, uint32_t *start, uint32_t lengthInBytes, uint32_t alignmentBaseline);
39 static status_t ifr_check_param(
40 flash_config_t *config, FMU_Type *base, uint32_t *start, uint32_t lengthInBytes, uint32_t alignmentBaseline);
41 static status_t flash_check_user_key(uint32_t key);
42
43 /*******************************************************************************
44 * Variables
45 ******************************************************************************/
46
47 /*******************************************************************************
48 * Code
49 ******************************************************************************/
50
FLASH_Init(flash_config_t * config)51 status_t FLASH_Init(flash_config_t *config)
52 {
53 status_t status = kStatus_Fail;
54
55 if (config == NULL)
56 {
57 status = kStatus_FLASH_InvalidArgument;
58 }
59 else
60 {
61 /* CM33 flash */
62 config->msf1Config[0].flashDesc.blockBase = FLASH_FEATURE_PFLASH0_START_ADDRESS;
63 config->msf1Config[0].flashDesc.blockCount = FLASH_FEATURE_PFLASH0_BLOCK_COUNT;
64
65 #if (defined(CPU_KW45B41Z82AFPA) || defined(CPU_KW45B41Z82AFTA) || defined(CPU_KW45B41Z83AFPA) || \
66 defined(CPU_KW45B41Z83AFTA) || defined(CPU_KW45Z41082AFPA) || defined(CPU_KW45Z41082AFTA) || \
67 defined(CPU_KW45Z41083AFPA) || defined(CPU_KW45Z41083AFTA) || defined(CPU_K32W1480VFTA))
68 /* M33 flash size 1MB */
69 config->msf1Config[0].flashDesc.totalSize =
70 FLASH_FEATURE_PFLASH0_BLOCK_COUNT * FLASH_FEATURE_PFLASH0_BLOCK_SIZE;
71 #elif (defined(CPU_KW45B41Z52AFPA) || defined(CPU_KW45B41Z52AFTA) || defined(CPU_KW45B41Z53AFPA) || \
72 defined(CPU_KW45B41Z53AFTA) || defined(CPU_KW45Z41052AFPA) || defined(CPU_KW45Z41052AFTA) || \
73 defined(CPU_KW45Z41053AFPA) || defined(CPU_KW45Z41053AFTA))
74 /* M33 flash size 512KB */
75 config->msf1Config[0].flashDesc.totalSize =
76 FLASH_FEATURE_PFLASH0_BLOCK_COUNT * FLASH_FEATURE_PFLASH0_BLOCK_SIZE_512KB;
77 #elif (defined(CPU_KW47B42ZB7AFTA_cm33_core0))
78 config->msf1Config[0].flashDesc.totalSize =
79 FLASH_FEATURE_PFLASH0_BLOCK_COUNT * FLASH_FEATURE_PFLASH0_BLOCK_SIZE;
80 #elif (defined(CPU_MCXW716CMFTA) || (CPU_MCXW716CMFPA) || (CPU_MCXW716AMFTA) || (CPU_MCXW716AMFPA) || defined(CPU_MCXW727CMFTA_cm33_core0))
81 config->msf1Config[0].flashDesc.totalSize =
82 FLASH_FEATURE_PFLASH0_BLOCK_COUNT * FLASH_FEATURE_PFLASH0_BLOCK_SIZE;
83 #else
84 #error "No valid CPU defined!"
85 #endif
86
87 config->msf1Config[0].ifrDesc.pflashIfr0Start = FLASH_FEATURE_PFLASH0_IFR0_START_ADDRESS;
88 config->msf1Config[0].ifrDesc.pflashIfr0MemSize = FLASH_FEATURE_PFLASH0_IFR0_SIZE;
89
90 /* RF flash */
91 #if (defined(CPU_KW45B41Z82AFPA) || defined(CPU_KW45B41Z82AFTA) || defined(CPU_KW45B41Z83AFPA) || \
92 defined(CPU_KW45B41Z83AFTA) || defined(CPU_KW45B41Z52AFPA) || defined(CPU_KW45B41Z52AFTA) || \
93 defined(CPU_KW45B41Z53AFPA) || defined(CPU_KW45B41Z53AFTA) || defined(CPU_K32W1480VFTA))
94 config->msf1Config[1].flashDesc.blockBase = FLASH_FEATURE_PFLASH1_START_ADDRESS;
95 config->msf1Config[1].flashDesc.blockCount = FLASH_FEATURE_PFLASH1_BLOCK_COUNT;
96 config->msf1Config[1].flashDesc.totalSize =
97 FLASH_FEATURE_PFLASH1_BLOCK_COUNT * FLASH_FEATURE_PFLASH1_BLOCK_SIZE;
98
99 config->msf1Config[1].ifrDesc.pflashIfr0Start = FLASH_FEATURE_PFLASH1_IFR0_START_ADDRESS;
100 config->msf1Config[1].ifrDesc.pflashIfr0MemSize = FLASH_FEATURE_PFLASH1_IFR0_SIZE;
101
102 #elif (defined(CPU_KW45Z41082AFPA) || defined(CPU_KW45Z41082AFTA) || defined(CPU_KW45Z41083AFPA) || \
103 defined(CPU_KW45Z41083AFTA) || defined(CPU_KW45Z41052AFPA) || defined(CPU_KW45Z41052AFTA) || \
104 defined(CPU_KW45Z41053AFPA) || defined(CPU_KW45Z41053AFTA))
105 config->msf1Config[1].flashDesc.blockBase = FLASH_FEATURE_PFLASH1_START_ADDRESS;
106 config->msf1Config[1].flashDesc.blockCount = 0U;
107 config->msf1Config[1].flashDesc.totalSize = 0U;
108
109 config->msf1Config[1].ifrDesc.pflashIfr0Start = FLASH_FEATURE_PFLASH1_IFR0_START_ADDRESS;
110 config->msf1Config[1].ifrDesc.pflashIfr0MemSize = 0U;
111 #elif (defined(CPU_KW47B42ZB7AFTA_cm33_core0))
112 config->msf1Config[1].flashDesc.blockBase = FLASH_FEATURE_PFLASH1_START_ADDRESS;
113 config->msf1Config[1].flashDesc.blockCount = FLASH_FEATURE_PFLASH1_BLOCK_COUNT;
114 config->msf1Config[1].flashDesc.totalSize =
115 FLASH_FEATURE_PFLASH1_BLOCK_COUNT * FLASH_FEATURE_PFLASH1_BLOCK_SIZE;
116
117 config->msf1Config[1].ifrDesc.pflashIfr0Start = FLASH_FEATURE_PFLASH1_IFR0_START_ADDRESS;
118 config->msf1Config[1].ifrDesc.pflashIfr0MemSize = FLASH_FEATURE_PFLASH1_IFR0_SIZE;
119 #elif (defined(CPU_MCXW716CMFTA) || (CPU_MCXW716CMFPA) || (CPU_MCXW716AMFTA) || (CPU_MCXW716AMFPA)|| defined(CPU_MCXW727CMFTA_cm33_core0))
120 config->msf1Config[1].flashDesc.blockBase = FLASH_FEATURE_PFLASH1_START_ADDRESS;
121 config->msf1Config[1].flashDesc.blockCount = FLASH_FEATURE_PFLASH1_BLOCK_COUNT;
122 config->msf1Config[1].flashDesc.totalSize =
123 FLASH_FEATURE_PFLASH1_BLOCK_COUNT * FLASH_FEATURE_PFLASH1_BLOCK_SIZE;
124
125 config->msf1Config[1].ifrDesc.pflashIfr0Start = FLASH_FEATURE_PFLASH1_IFR0_START_ADDRESS;
126 config->msf1Config[1].ifrDesc.pflashIfr0MemSize = FLASH_FEATURE_PFLASH1_IFR0_SIZE;
127 #else
128 #error "No valid CPU defined!"
129 #endif
130
131 status = kStatus_FLASH_Success;
132 }
133
134 return status;
135 }
136
FLASH_Erase(flash_config_t * config,FMU_Type * base,uint32_t start,uint32_t lengthInBytes,uint32_t key)137 status_t FLASH_Erase(flash_config_t *config, FMU_Type *base, uint32_t start, uint32_t lengthInBytes, uint32_t key)
138 {
139 status_t status = kStatus_Fail;
140
141 status = flash_check_param(config, base, start, lengthInBytes, FLASH_FEATURE_PHRASE_SIZE);
142 if ((status == kStatus_FLASH_Success) && (flash_check_user_key(key) == kStatus_FLASH_Success))
143 {
144 uint32_t endAddress = start + lengthInBytes - 1U;
145
146 while (start <= endAddress)
147 {
148 status = FLASH_CMD_EraseSector(base, start);
149 if (kStatus_FLASH_Success != status)
150 {
151 break;
152 }
153 else
154 {
155 /* Increment to the next sector */
156 start += FLASH_FEATURE_SECTOR_SIZE;
157 }
158 }
159 }
160 else
161 {
162 ; // MISRA
163 }
164
165 return status;
166 }
167
FLASH_EraseAll(FMU_Type * base,uint32_t key)168 status_t FLASH_EraseAll(FMU_Type *base, uint32_t key)
169 {
170 status_t status = kStatus_Fail;
171 FMU_Type *baseTmp = (FMU_Type *)((uint32_t)base & FLASH_ADDR_MASK);
172 #if defined(RF_FMU)
173 if (base == NULL || (baseTmp != FLASH && baseTmp != NBU_FLASH))
174 #else
175 if (base == NULL || baseTmp != FLASH)
176 #endif
177 {
178 status = kStatus_FLASH_InvalidArgument;
179 }
180 else
181 {
182 /* Validate the user key */
183 status = flash_check_user_key(key);
184 }
185
186 if (kStatus_FLASH_Success == status)
187 {
188 status = FLASH_CMD_EraseAll(base);
189 }
190 else
191 {
192 ; // MISRA
193 }
194
195 return status;
196 }
197
FLASH_Program(flash_config_t * config,FMU_Type * base,uint32_t start,uint8_t * src,uint32_t lengthInBytes)198 status_t FLASH_Program(flash_config_t *config, FMU_Type *base, uint32_t start, uint8_t *src, uint32_t lengthInBytes)
199 {
200 status_t status = kStatus_Fail;
201
202 status = flash_check_param(config, base, start, lengthInBytes, FLASH_FEATURE_PHRASE_SIZE);
203 if (status == kStatus_FLASH_Success)
204 {
205 // Align length to whole phrase.
206 uint32_t alignedLength = ALIGN_DOWN(lengthInBytes, sizeof(uint8_t) * FLASH_FEATURE_PHRASE_SIZE);
207 uint32_t extraBytes = lengthInBytes - alignedLength;
208 uint32_t *srcWord = (uint32_t *)(uintptr_t)src;
209
210 if (alignedLength > 0U)
211 {
212 uint32_t endAddress = start + alignedLength - 1U;
213 while (start <= endAddress)
214 {
215 status = FLASH_CMD_ProgramPhrase(base, start, srcWord);
216 if (kStatus_FLASH_Success != status)
217 {
218 break;
219 }
220 else
221 {
222 /* Increment to the next sector */
223 start += FLASH_FEATURE_PHRASE_SIZE;
224 srcWord += FLASH_FEATURE_PHRASE_SIZE_IN_WORD;
225 }
226 }
227 }
228 else
229 {
230 ; // MISRA
231 }
232
233 if ((kStatus_FLASH_Success == status) && (extraBytes > 0U))
234 {
235 uint32_t extraData[4] = {0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu};
236
237 // Copy extra bytes to phrase buffer.
238 union
239 {
240 uint32_t *src;
241 const void *srcVoid;
242 } srcPtr;
243 srcPtr.src = srcWord;
244
245 union
246 {
247 uint32_t *xData;
248 void *xDataVoid;
249 } xDataPtr;
250 xDataPtr.xData = (uint32_t *)&extraData[0];
251
252 (void)memcpy(xDataPtr.xDataVoid, srcPtr.srcVoid, extraBytes);
253
254 status = FLASH_CMD_ProgramPhrase(base, start, extraData);
255 }
256 }
257 else
258 {
259 ; // MISRA
260 }
261
262 return status;
263 }
264
FLASH_ProgramPage(flash_config_t * config,FMU_Type * base,uint32_t start,uint8_t * src,uint32_t lengthInBytes)265 status_t FLASH_ProgramPage(flash_config_t *config, FMU_Type *base, uint32_t start, uint8_t *src, uint32_t lengthInBytes)
266 {
267 status_t status = kStatus_Fail;
268
269 status = flash_check_param(config, base, start, lengthInBytes, FLASH_FEATURE_PAGE_SIZE);
270 if (status == kStatus_FLASH_Success)
271 {
272 // Align length to whole phrase.
273 uint32_t alignedLength = ALIGN_DOWN(lengthInBytes, sizeof(uint8_t) * FLASH_FEATURE_PAGE_SIZE);
274 uint32_t extraBytes = lengthInBytes - alignedLength;
275 uint32_t *srcWord = (uint32_t *)(uintptr_t)src;
276
277 if (alignedLength > 0U)
278 {
279 uint32_t endAddress = start + alignedLength - 1U;
280 while (start <= endAddress)
281 {
282 status = FLASH_CMD_ProgramPage(base, start, srcWord);
283 if (kStatus_FLASH_Success != status)
284 {
285 break;
286 }
287 else
288 {
289 /* Increment to the next sector */
290 start += FLASH_FEATURE_PAGE_SIZE;
291 srcWord += FLASH_FEATURE_PAGE_SIZE_IN_WORD;
292 }
293 }
294 }
295 else
296 {
297 ; // MISRA
298 }
299
300 if ((kStatus_FLASH_Success == status) && (extraBytes > 0U))
301 {
302 uint32_t extraData[32] = {
303 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu,
304 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu,
305 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu,
306 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu};
307
308 // Copy extra bytes to page buffer.
309 union
310 {
311 uint32_t *src;
312 const void *srcVoid;
313 } srcPtr;
314 srcPtr.src = srcWord;
315
316 union
317 {
318 uint32_t *xData;
319 void *xDataVoid;
320 } xDataPtr;
321 xDataPtr.xData = (uint32_t *)&extraData[0];
322
323 (void)memcpy(xDataPtr.xDataVoid, srcPtr.srcVoid, extraBytes);
324
325 status = FLASH_CMD_ProgramPage(base, start, extraData);
326 }
327 }
328 else
329 {
330 ; // MISRA
331 }
332
333 return status;
334 }
335
FLASH_VerifyErasePhrase(flash_config_t * config,FMU_Type * base,uint32_t start,uint32_t lengthInBytes)336 status_t FLASH_VerifyErasePhrase(flash_config_t *config, FMU_Type *base, uint32_t start, uint32_t lengthInBytes)
337 {
338 status_t status = kStatus_Fail;
339 uint32_t startaddr = start;
340
341 status = pflash_check_param(config, base, &startaddr, lengthInBytes, FLASH_FEATURE_PHRASE_SIZE);
342 if (status == kStatus_FLASH_Success)
343 {
344 uint32_t endAddress = startaddr + lengthInBytes - 1U;
345 while (startaddr <= endAddress)
346 {
347 status = FLASH_CMD_VerifyErasePhrase(base, startaddr);
348 if (kStatus_FLASH_Success != status)
349 {
350 break;
351 }
352 else
353 {
354 /* Increment to the next phrase */
355 startaddr += FLASH_FEATURE_PHRASE_SIZE;
356 }
357 }
358 }
359 else
360 {
361 ; // MISRA
362 }
363
364 return status;
365 }
366
FLASH_VerifyErasePage(flash_config_t * config,FMU_Type * base,uint32_t start,uint32_t lengthInBytes)367 status_t FLASH_VerifyErasePage(flash_config_t *config, FMU_Type *base, uint32_t start, uint32_t lengthInBytes)
368 {
369 status_t status = kStatus_Fail;
370 uint32_t startaddr = start;
371
372 status = pflash_check_param(config, base, &startaddr, lengthInBytes, FLASH_FEATURE_PAGE_SIZE);
373 if (status == kStatus_FLASH_Success)
374 {
375 uint32_t endAddress = startaddr + lengthInBytes - 1U;
376 while (startaddr <= endAddress)
377 {
378 status = FLASH_CMD_VerifyErasePage(base, startaddr);
379 if (kStatus_FLASH_Success != status)
380 {
381 break;
382 }
383 else
384 {
385 /* Increment to the next page */
386 startaddr += FLASH_FEATURE_PAGE_SIZE;
387 }
388 }
389 }
390 else
391 {
392 ; // MISRA
393 }
394
395 return status;
396 }
397
FLASH_VerifyEraseSector(flash_config_t * config,FMU_Type * base,uint32_t start,uint32_t lengthInBytes)398 status_t FLASH_VerifyEraseSector(flash_config_t *config, FMU_Type *base, uint32_t start, uint32_t lengthInBytes)
399 {
400 status_t status = kStatus_Fail;
401 uint32_t startaddr = start;
402
403 status = pflash_check_param(config, base, &startaddr, lengthInBytes, FLASH_FEATURE_SECTOR_SIZE);
404 if (status == kStatus_FLASH_Success)
405 {
406 uint32_t endAddress = startaddr + lengthInBytes - 1U;
407 while (startaddr <= endAddress)
408 {
409 status = FLASH_CMD_VerifyEraseSector(base, startaddr);
410 if (kStatus_FLASH_Success != status)
411 {
412 break;
413 }
414 else
415 {
416 /* Increment to the next sector */
417 startaddr += FLASH_FEATURE_SECTOR_SIZE;
418 }
419 }
420 }
421 else
422 {
423 ; // MISRA
424 }
425
426 return status;
427 }
428
FLASH_VerifyEraseIFRPhrase(flash_config_t * config,FMU_Type * base,uint32_t start,uint32_t lengthInBytes)429 status_t FLASH_VerifyEraseIFRPhrase(flash_config_t *config, FMU_Type *base, uint32_t start, uint32_t lengthInBytes)
430 {
431 status_t status = kStatus_Fail;
432 uint32_t startaddr = start;
433
434 status = ifr_check_param(config, base, &startaddr, lengthInBytes, FLASH_FEATURE_PHRASE_SIZE);
435 if (status == kStatus_FLASH_Success)
436 {
437 uint32_t endAddress = startaddr + lengthInBytes - 1U;
438 while (startaddr <= endAddress)
439 {
440 status = FLASH_CMD_VerifyEraseIFRPhrase(base, startaddr);
441 if (kStatus_FLASH_Success != status)
442 {
443 break;
444 }
445 else
446 {
447 /* Increment to the next phrase */
448 startaddr += FLASH_FEATURE_PHRASE_SIZE;
449 }
450 }
451 }
452 else
453 {
454 ; // MISRA
455 }
456
457 return status;
458 }
459
FLASH_VerifyEraseIFRPage(flash_config_t * config,FMU_Type * base,uint32_t start,uint32_t lengthInBytes)460 status_t FLASH_VerifyEraseIFRPage(flash_config_t *config, FMU_Type *base, uint32_t start, uint32_t lengthInBytes)
461 {
462 status_t status = kStatus_Fail;
463 uint32_t startaddr = start;
464
465 status = ifr_check_param(config, base, &startaddr, lengthInBytes, FLASH_FEATURE_PAGE_SIZE);
466 if (status == kStatus_FLASH_Success)
467 {
468 uint32_t endAddress = startaddr + lengthInBytes - 1U;
469 while (startaddr <= endAddress)
470 {
471 status = FLASH_CMD_VerifyEraseIFRPage(base, startaddr);
472 if (kStatus_FLASH_Success != status)
473 {
474 break;
475 }
476 else
477 {
478 /* Increment to the next page */
479 startaddr += FLASH_FEATURE_PAGE_SIZE;
480 }
481 }
482 }
483 else
484 {
485 ; // MISRA
486 }
487
488 return status;
489 }
490
FLASH_VerifyEraseIFRSector(flash_config_t * config,FMU_Type * base,uint32_t start,uint32_t lengthInBytes)491 status_t FLASH_VerifyEraseIFRSector(flash_config_t *config, FMU_Type *base, uint32_t start, uint32_t lengthInBytes)
492 {
493 status_t status = kStatus_Fail;
494 uint32_t startaddr = start;
495
496 status = ifr_check_param(config, base, &startaddr, lengthInBytes, FLASH_FEATURE_SECTOR_SIZE);
497 if (status == kStatus_FLASH_Success)
498 {
499 uint32_t endAddress = startaddr + lengthInBytes - 1U;
500 while (startaddr <= endAddress)
501 {
502 status = FLASH_CMD_VerifyEraseIFRSector(base, startaddr);
503 if (kStatus_FLASH_Success != status)
504 {
505 break;
506 }
507 else
508 {
509 /* Increment to the next sector */
510 startaddr += FLASH_FEATURE_SECTOR_SIZE;
511 }
512 }
513 }
514 else
515 {
516 ; // MISRA
517 }
518
519 return status;
520 }
521
FLASH_VerifyEraseAll(FMU_Type * base)522 status_t FLASH_VerifyEraseAll(FMU_Type *base)
523 {
524 status_t status = kStatus_Fail;
525 FMU_Type *baseTmp = (FMU_Type *)((uint32_t)base & FLASH_ADDR_MASK);
526 #if defined(RF_FMU)
527 if (base == NULL || ((baseTmp != FLASH) && (baseTmp != NBU_FLASH)))
528 #else
529 if (base == NULL || baseTmp != FLASH)
530 #endif
531 {
532 status = kStatus_FLASH_InvalidArgument;
533 }
534 else
535 {
536 status = FLASH_CMD_VerifyEraseAll(base);
537 }
538
539 return status;
540 }
541
FLASH_VerifyEraseBlock(flash_config_t * config,FMU_Type * base,uint32_t blockaddr)542 status_t FLASH_VerifyEraseBlock(flash_config_t *config, FMU_Type *base, uint32_t blockaddr)
543 {
544 status_t status = kStatus_Fail;
545 uint32_t nsblockaddr = blockaddr & FLASH_ADDR_MASK;
546 FMU_Type *baseTmp = (FMU_Type *)((uint32_t)base & FLASH_ADDR_MASK);
547
548 #if defined(RF_FMU)
549 if (config == NULL || base == NULL || ((baseTmp != FLASH) && (baseTmp != NBU_FLASH)))
550 #else
551 if (config == NULL || base == NULL || baseTmp != FLASH)
552 #endif
553 {
554 status = kStatus_FLASH_InvalidArgument;
555 }
556 else if ((nsblockaddr != config->msf1Config[0].flashDesc.blockBase) &&
557 (nsblockaddr != config->msf1Config[1].flashDesc.blockBase))
558 {
559 status = kStatus_FLASH_AddressError;
560 }
561 else
562 {
563 /* K4W1 M33 and NBU flash both have only one block, so 0U is sufficient here */
564 status = FLASH_CMD_VerifyEraseBlock(base, 0U);
565 }
566
567 return status;
568 }
569
Read_Into_MISR(flash_config_t * config,FMU_Type * base,uint32_t start,uint32_t ending,uint32_t * seed,uint32_t * signature)570 status_t Read_Into_MISR(
571 flash_config_t *config, FMU_Type *base, uint32_t start, uint32_t ending, uint32_t *seed, uint32_t *signature)
572 {
573 status_t status = kStatus_Fail;
574 uint32_t startAddr = start;
575
576 if ((start >= ending) || (seed == NULL) ||
577 (((ending + FLASH_FEATURE_PHRASE_SIZE) & (FLASH_FEATURE_PAGE_SIZE - 1U)) != 0u))
578 {
579 status = kStatus_FLASH_InvalidArgument;
580 }
581 else if ((ending & (FLASH_FEATURE_PHRASE_SIZE - 1U)) != 0u)
582 {
583 status = kStatus_FLASH_AlignmentError;
584 }
585 else
586 {
587 status = pflash_check_param(config, base, &startAddr, (ending - start), FLASH_FEATURE_PAGE_SIZE);
588 if (status == kStatus_FLASH_Success)
589 {
590 uint32_t endAddr = startAddr + ending - start;
591 status = FLASH_CMD_ReadIntoMISR(base, startAddr, endAddr, seed, signature);
592 }
593 else
594 {
595 ; // MISRA
596 }
597 }
598
599 return status;
600 }
601
Read_IFR_Into_MISR(flash_config_t * config,FMU_Type * base,uint32_t start,uint32_t ending,uint32_t * seed,uint32_t * signature)602 status_t Read_IFR_Into_MISR(
603 flash_config_t *config, FMU_Type *base, uint32_t start, uint32_t ending, uint32_t *seed, uint32_t *signature)
604 {
605 status_t status = kStatus_Fail;
606 uint32_t startAddr = start;
607
608 if ((start >= ending) || (seed == NULL) ||
609 (((ending + FLASH_FEATURE_PHRASE_SIZE) & (FLASH_FEATURE_PAGE_SIZE - 1U)) != 0U))
610 {
611 status = kStatus_FLASH_InvalidArgument;
612 }
613 else if ((ending & (FLASH_FEATURE_PHRASE_SIZE - 1U)) != 0u)
614 {
615 status = kStatus_FLASH_AlignmentError;
616 }
617 else
618 {
619 status = ifr_check_param(config, base, &startAddr, (ending - start), FLASH_FEATURE_PAGE_SIZE);
620 if (status == kStatus_FLASH_Success)
621 {
622 uint32_t endAddr = startAddr + ending - start;
623 status = FLASH_CMD_ReadIFRIntoMISR(base, startAddr, endAddr, seed, signature);
624 }
625 else
626 {
627 ; // MISRA
628 }
629 }
630
631 return status;
632 }
633
FLASH_GetProperty(flash_config_t * config,flash_property_tag_t whichProperty,uint32_t * value)634 status_t FLASH_GetProperty(flash_config_t *config, flash_property_tag_t whichProperty, uint32_t *value)
635 {
636 status_t status = kStatus_FLASH_Success;
637
638 switch (whichProperty)
639 {
640 case kFLASH_PropertyPflash0TotalSize:
641 *value = config->msf1Config[0].flashDesc.totalSize;
642 break;
643 case kFLASH_PropertyPflash0BlockSize:
644 *value = config->msf1Config[0].flashDesc.totalSize / config->msf1Config[0].flashDesc.blockCount;
645 break;
646 case kFLASH_PropertyPflash0BlockCount:
647 *value = config->msf1Config[0].flashDesc.blockCount;
648 break;
649 case kFLASH_PropertyPflash0BlockBaseAddr:
650 *value = config->msf1Config[0].flashDesc.blockBase;
651 break;
652 case kFLASH_PropertyPflash0SectorSize:
653 *value = FLASH_FEATURE_SECTOR_SIZE;
654 break;
655 case kFLASH_PropertyPflash1TotalSize:
656 *value = config->msf1Config[1].flashDesc.totalSize;
657 break;
658 case kFLASH_PropertyPflash1BlockSize:
659 *value = config->msf1Config[1].flashDesc.totalSize / config->msf1Config[1].flashDesc.blockCount;
660 break;
661 case kFLASH_PropertyPflash1BlockCount:
662 *value = config->msf1Config[1].flashDesc.blockCount;
663 break;
664 case kFLASH_PropertyPflash1BlockBaseAddr:
665 *value = config->msf1Config[1].flashDesc.blockBase;
666 break;
667 default:
668 status = kStatus_FLASH_UnknownProperty;
669 /* To avoid MISRA-C 2012 rule 16.4 issue. */
670 break;
671 }
672 return status;
673 }
674
675 #if defined(FLASH_DRIVER_IS_FLASH_RESIDENT) && (FLASH_DRIVER_IS_FLASH_RESIDENT == 1)
676 #if defined(__IAR_SYSTEMS_ICC__)
677 __ramfunc
678 #elif defined(__GNUC__)
679 __attribute__ ((section (".ramfunc")))
680 #endif
681 #endif
682 void
flash_cache_disable(void)683 flash_cache_disable(void)
684 {
685 SMSCM->OCMDR0 = (SMSCM->OCMDR0 & (~SMSCM_FLASH_CACHE_CTRL_MASK)) | SMSCM_FLASH_CACHE_CTRL(0x1);
686 SMSCM->OCMDR0 = (SMSCM->OCMDR0 & (~SMSCM_FLASH_CACHE_CTRL_MASK)) | SMSCM_FLASH_CACHE_CTRL(0x8);
687 SMSCM->OCMDR0 = (SMSCM->OCMDR0 & (~SMSCM_FLASH_SPECULATION_CTRL_MASK)) | SMSCM_FLASH_SPECULATION_CTRL(0x3);
688 __ISB();
689 __DSB();
690 }
691
692 #if defined(FLASH_DRIVER_IS_FLASH_RESIDENT) && (FLASH_DRIVER_IS_FLASH_RESIDENT == 1)
693 #if defined(__IAR_SYSTEMS_ICC__)
694 __ramfunc
695 #elif defined(__GNUC__)
696 __attribute__ ((section (".ramfunc")))
697 #endif
698 #endif
699 void
flash_cache_speculation_control(bool isPreProcess,FMU_Type * base)700 flash_cache_speculation_control(bool isPreProcess, FMU_Type *base)
701 {
702 if (base == FLASH)
703 {
704 if (isPreProcess == false)
705 {
706 SMSCM->OCMDR0 = (SMSCM->OCMDR0 & (~SMSCM_FLASH_CACHE_CTRL_MASK)) | SMSCM_FLASH_CACHE_CTRL(0x1);
707 SMSCM->OCMDR0 = (SMSCM->OCMDR0 & (~SMSCM_FLASH_SPECULATION_CTRL_MASK)) | SMSCM_FLASH_SPECULATION_CTRL(0x0);
708 }
709 else
710 {
711 SMSCM->OCMDR0 = (SMSCM->OCMDR0 & (~SMSCM_FLASH_SPECULATION_CTRL_MASK)) | SMSCM_FLASH_SPECULATION_CTRL(0x3);
712 }
713 }
714 #if defined(RF_FMU)
715 else if (base == NBU_FLASH)
716 {
717 if (isPreProcess == false)
718 {
719 RF_FMCCFG->RFMCCFG = (RF_FMCCFG->RFMCCFG & (~NBU_FLASH_CACHE_CTRL_MASK)) | NBU_FLASH_CACHE_CTRL(0x1);
720 RF_FMCCFG->RFMCCFG =
721 (RF_FMCCFG->RFMCCFG & (~NBU_FLASH_SPECULATION_CTRL_MASK)) | NBU_FLASH_SPECULATION_CTRL(0x0);
722 }
723 else
724 {
725 RF_FMCCFG->RFMCCFG =
726 (RF_FMCCFG->RFMCCFG & (~NBU_FLASH_SPECULATION_CTRL_MASK)) | NBU_FLASH_SPECULATION_CTRL(0x3);
727 }
728 }
729 #endif
730 else
731 {
732 ; /* No action required */
733 }
734 /* Memory barriers for good measure.
735 * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */
736 __ISB();
737 __DSB();
738 }
739
flash_check_param(flash_config_t * config,FMU_Type * base,uint32_t start,uint32_t lengthInBytes,uint32_t alignmentBaseline)740 static status_t flash_check_param(
741 flash_config_t *config, FMU_Type *base, uint32_t start, uint32_t lengthInBytes, uint32_t alignmentBaseline)
742 {
743 status_t status = kStatus_FLASH_InvalidArgument;
744 FMU_Type *baseTmp = (FMU_Type *)((uint32_t)base & FLASH_ADDR_MASK);
745
746 if (lengthInBytes == 0U)
747 {
748 status = kStatus_FLASH_Success;
749 }
750 #if defined(RF_FMU)
751 else if (config == NULL || base == NULL || ((baseTmp != FLASH) && (baseTmp != NBU_FLASH)))
752 #else
753 else if (config == NULL || base == NULL || baseTmp != FLASH)
754 #endif
755 {
756 status = kStatus_FLASH_InvalidArgument;
757 }
758 else if ((start & (alignmentBaseline - 1U)) != 0u)
759 {
760 /* Verify the start is alignmentBaseline aligned. */
761 status = kStatus_FLASH_AlignmentError;
762 }
763 else
764 {
765 start = start & FLASH_ADDR_MASK;
766
767 if (baseTmp == FLASH)
768 {
769 /* Validates the range of the given address */
770 if ((start >= config->msf1Config[0].flashDesc.blockBase) &&
771 ((start + lengthInBytes) <=
772 (config->msf1Config[0].flashDesc.blockBase + config->msf1Config[0].flashDesc.totalSize)))
773 {
774 status = kStatus_FLASH_Success;
775 }
776 else
777
778 if ((start >= config->msf1Config[0].ifrDesc.pflashIfr0Start) &&
779 ((start + lengthInBytes) <=
780 (config->msf1Config[0].ifrDesc.pflashIfr0Start + config->msf1Config[0].ifrDesc.pflashIfr0MemSize)))
781 {
782 status = kStatus_FLASH_Success;
783 }
784 else
785 {
786 status = kStatus_FLASH_AddressError;
787 }
788 }
789 else // if (base == NBU_FLASH || base == NBU_FLASH_NS)
790 {
791 /* Validates the range of the given address */
792 if ((start >= config->msf1Config[1].flashDesc.blockBase) &&
793 ((start + lengthInBytes) <=
794 (config->msf1Config[1].flashDesc.blockBase + config->msf1Config[1].flashDesc.totalSize)))
795 {
796 status = kStatus_FLASH_Success;
797 }
798 else
799
800 if ((start >= config->msf1Config[1].ifrDesc.pflashIfr0Start) &&
801 ((start + lengthInBytes) <=
802 (config->msf1Config[1].ifrDesc.pflashIfr0Start + config->msf1Config[1].ifrDesc.pflashIfr0MemSize)))
803 {
804 status = kStatus_FLASH_Success;
805 }
806 else
807 {
808 status = kStatus_FLASH_AddressError;
809 }
810 }
811 }
812
813 return status;
814 }
815
pflash_check_param(flash_config_t * config,FMU_Type * base,uint32_t * start,uint32_t lengthInBytes,uint32_t alignmentBaseline)816 static status_t pflash_check_param(
817 flash_config_t *config, FMU_Type *base, uint32_t *start, uint32_t lengthInBytes, uint32_t alignmentBaseline)
818 {
819 status_t status = kStatus_FLASH_InvalidArgument;
820 FMU_Type *baseTmp = (FMU_Type *)((uint32_t)base & FLASH_ADDR_MASK);
821
822 if (lengthInBytes == 0U)
823 {
824 status = kStatus_FLASH_Success;
825 }
826 #if defined(RF_FMU)
827 else if ((config == NULL) || (base == NULL) || ((baseTmp != FLASH) && (baseTmp != NBU_FLASH)))
828 #else
829 else if ((config == NULL) || (base == NULL) || (baseTmp != FLASH))
830 #endif
831 {
832 status = kStatus_FLASH_InvalidArgument;
833 }
834 else if ((*start & (alignmentBaseline - 1U)) != 0u)
835 {
836 /* Verify the start is alignmentBaseline aligned. */
837 status = kStatus_FLASH_AlignmentError;
838 }
839 else
840 {
841 *start &= FLASH_ADDR_MASK;
842
843 if (baseTmp == FLASH)
844 {
845 /* Validates the range of the given address */
846 if ((*start >= config->msf1Config[0].flashDesc.blockBase) &&
847 ((*start + lengthInBytes) <=
848 (config->msf1Config[0].flashDesc.blockBase + config->msf1Config[0].flashDesc.totalSize)))
849 {
850 *start -= config->msf1Config[0].flashDesc.blockBase;
851 status = kStatus_FLASH_Success;
852 }
853 else
854 {
855 status = kStatus_FLASH_AddressError;
856 }
857 }
858 else // if (base == NBU_FLASH || base == NBU_FLASH_NS)
859 {
860 /* Validates the range of the given address */
861 if ((*start >= config->msf1Config[1].flashDesc.blockBase) &&
862 ((*start + lengthInBytes) <=
863 (config->msf1Config[1].flashDesc.blockBase + config->msf1Config[1].flashDesc.totalSize)))
864 {
865 *start -= config->msf1Config[1].flashDesc.blockBase;
866 status = kStatus_FLASH_Success;
867 }
868 else
869 {
870 status = kStatus_FLASH_AddressError;
871 }
872 }
873 }
874
875 return status;
876 }
877
ifr_check_param(flash_config_t * config,FMU_Type * base,uint32_t * start,uint32_t lengthInBytes,uint32_t alignmentBaseline)878 static status_t ifr_check_param(
879 flash_config_t *config, FMU_Type *base, uint32_t *start, uint32_t lengthInBytes, uint32_t alignmentBaseline)
880 {
881 status_t status = kStatus_FLASH_InvalidArgument;
882 FMU_Type *baseTmp = (FMU_Type *)((uint32_t)base & FLASH_ADDR_MASK);
883
884 if (lengthInBytes == 0U)
885 {
886 status = kStatus_FLASH_Success;
887 }
888 #if defined(RF_FMU)
889 else if (config == NULL || base == NULL || ((baseTmp != FLASH) && (baseTmp != NBU_FLASH)))
890 #else
891 else if (config == NULL || base == NULL || baseTmp != FLASH)
892 #endif
893 {
894 status = kStatus_FLASH_InvalidArgument;
895 }
896 else
897
898 /* Verify the start is alignmentBaseline aligned. */
899 if ((*start & (alignmentBaseline - 1U)) != 0u)
900 {
901 status = kStatus_FLASH_AlignmentError;
902 }
903 else
904 {
905 *start &= FLASH_ADDR_MASK;
906
907 if (baseTmp == FLASH)
908 {
909 if ((*start >= config->msf1Config[0].ifrDesc.pflashIfr0Start) &&
910 ((*start + lengthInBytes) <=
911 (config->msf1Config[0].ifrDesc.pflashIfr0Start + config->msf1Config[0].ifrDesc.pflashIfr0MemSize)))
912 {
913 *start -= config->msf1Config[0].ifrDesc.pflashIfr0Start;
914 status = kStatus_FLASH_Success;
915 }
916 else
917 {
918 status = kStatus_FLASH_AddressError;
919 }
920 }
921 else // if (base == NBU_FLASH || base == NBU_FLASH_NS)
922 {
923 if ((*start >= config->msf1Config[1].ifrDesc.pflashIfr0Start) &&
924 ((*start + lengthInBytes) <=
925 (config->msf1Config[1].ifrDesc.pflashIfr0Start + config->msf1Config[1].ifrDesc.pflashIfr0MemSize)))
926 {
927 *start -= config->msf1Config[1].ifrDesc.pflashIfr0Start;
928 status = kStatus_FLASH_Success;
929 }
930 else
931 {
932 status = kStatus_FLASH_AddressError;
933 }
934 }
935 }
936
937 return status;
938 }
939
940 /*! @brief Validates the given user key for flash erase APIs.*/
flash_check_user_key(uint32_t key)941 static status_t flash_check_user_key(uint32_t key)
942 {
943 status_t status = kStatus_Fail;
944
945 /* Validate the user key */
946 if (key != (uint32_t)kFLASH_ApiEraseKey)
947 {
948 status = kStatus_FLASH_EraseKeyError;
949 }
950 else
951 {
952 status = kStatus_FLASH_Success;
953 }
954
955 return status;
956 }
957