rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
fsl_ftfx_controller.c
Go to the documentation of this file.
1/*
2* The Clear BSD License
3* Copyright 2013-2016 Freescale Semiconductor, Inc.
4* Copyright 2016-2018 NXP
5* All rights reserved.
6*
7* Redistribution and use in source and binary forms, with or without
8* modification, are permitted (subject to the limitations in the
9* disclaimer below) provided that the following conditions are met:
10*
11* * Redistributions of source code must retain the above copyright
12* notice, this list of conditions and the following disclaimer.
13*
14* * Redistributions in binary form must reproduce the above copyright
15* notice, this list of conditions and the following disclaimer in the
16* documentation and/or other materials provided with the distribution.
17*
18* * Neither the name of the copyright holder nor the names of its
19* contributors may be used to endorse or promote products derived from
20* this software without specific prior written permission.
21*
22* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
23* GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
24* HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
25* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
28* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
31* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
33* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
34* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35*
36*/
37
38#include "hal.h"
39#include "fsl_ftfx_controller.h"
40
41/*******************************************************************************
42 * Definitions
43 ******************************************************************************/
44
45/*!
46 * @name Flash controller command numbers
47 * @{
48 */
49#define FTFx_VERIFY_BLOCK 0x00U /*!< RD1BLK*/
50#define FTFx_VERIFY_SECTION 0x01U /*!< RD1SEC*/
51#define FTFx_PROGRAM_CHECK 0x02U /*!< PGMCHK*/
52#define FTFx_READ_RESOURCE 0x03U /*!< RDRSRC*/
53#define FTFx_PROGRAM_LONGWORD 0x06U /*!< PGM4*/
54#define FTFx_PROGRAM_PHRASE 0x07U /*!< PGM8*/
55#define FTFx_ERASE_BLOCK 0x08U /*!< ERSBLK*/
56#define FTFx_ERASE_SECTOR 0x09U /*!< ERSSCR*/
57#define FTFx_PROGRAM_SECTION 0x0BU /*!< PGMSEC*/
58#define FTFx_GENERATE_CRC 0x0CU /*!< CRCGEN*/
59#define FTFx_VERIFY_ALL_BLOCK 0x40U /*!< RD1ALL*/
60#define FTFx_READ_ONCE 0x41U /*!< RDONCE or RDINDEX*/
61#define FTFx_PROGRAM_ONCE 0x43U /*!< PGMONCE or PGMINDEX*/
62#define FTFx_ERASE_ALL_BLOCK 0x44U /*!< ERSALL*/
63#define FTFx_SECURITY_BY_PASS 0x45U /*!< VFYKEY*/
64#define FTFx_SWAP_CONTROL 0x46U /*!< SWAP*/
65#define FTFx_ERASE_ALL_BLOCK_UNSECURE 0x49U /*!< ERSALLU*/
66#define FTFx_VERIFY_ALL_EXECUTE_ONLY_SEGMENT 0x4AU /*!< RD1XA*/
67#define FTFx_ERASE_ALL_EXECUTE_ONLY_SEGMENT 0x4BU /*!< ERSXA*/
68#define FTFx_PROGRAM_PARTITION 0x80U /*!< PGMPART*/
69#define FTFx_SET_FLEXRAM_FUNCTION 0x81U /*!< SETRAM*/
70/*@}*/
71
72/*!
73 * @brief Constants for execute-in-RAM flash function.
74 */
76{
77 kFTFx_RamFuncMaxSizeInWords = 16U, /*!< The maximum size of execute-in-RAM function.*/
78};
79
80/*! @brief A function pointer used to point to relocated flash_run_command() */
81typedef void (*callFtfxRunCommand_t)(FTFx_REG8_ACCESS_TYPE ftfx_fstat);
82
83/*!
84 * @name Enumeration for Flash security register code
85 * @{
86 */
92/*@}*/
93
94/*!
95 * @brief Enumeration for flash config area.
96 */
102
103
104/*******************************************************************************
105 * Prototypes
106 ******************************************************************************/
107
108/*! @brief Init IFR memory related info */
110
111#if FTFx_DRIVER_IS_FLASH_RESIDENT
112/*! @brief Copy flash_run_command() to RAM*/
113static void ftfx_copy_run_command_to_ram(uint32_t *ftfxRunCommand);
114#endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */
115
116/*! @brief Internal function Flash command sequence. Called by driver APIs only*/
118
119/*! @brief Validates the range and alignment of the given address range.*/
121 uint32_t startAddress,
122 uint32_t lengthInBytes,
123 uint8_t alignmentBaseline);
124
125/*! @brief Validates the given user key for flash erase APIs.*/
126static status_t ftfx_check_user_key(uint32_t key);
127
128/*! @brief Reads word from byte address.*/
129static uint32_t ftfx_read_word_from_byte_address(const uint8_t *src);
130
131/*! @brief Writes word to byte address.*/
132static void ftfx_write_word_to_byte_address(uint8_t *dst, uint32_t word);
133
134#if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD
135/*! @brief Validates the range of the given resource address.*/
137 uint32_t start,
138 uint32_t lengthInBytes,
139 uint32_t alignmentBaseline,
141#endif /* FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD */
142
143#if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD
144/*! @brief Validates the gived flexram function option.*/
146#endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */
147
148#if defined(FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD) && FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD
149/*! @brief Validates the gived swap control option.*/
151#endif /* FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD */
152
153/*******************************************************************************
154 * Variables
155 ******************************************************************************/
156
157#if FTFx_DRIVER_IS_FLASH_RESIDENT
158/*!
159 * @brief Position independent code of flash_run_command()
160 *
161 * Note1: The prototype of C function is shown as below:
162 * @code
163 * void flash_run_command(FTFx_REG8_ACCESS_TYPE ftfx_fstat)
164 * {
165 * // clear CCIF bit
166 * *ftfx_fstat = FTFx_FSTAT_CCIF_MASK;
167 *
168 * // Check CCIF bit of the flash status register, wait till it is set.
169 * // IP team indicates that this loop will always complete.
170 * while (!((*ftfx_fstat) & FTFx_FSTAT_CCIF_MASK))
171 * {
172 * }
173 * }
174 * @endcode
175 * Note2: The binary code is generated by IAR 7.70.1
176 */
177static const uint16_t s_ftfxRunCommandFunctionCode[] = {
178 0x2180, /* MOVS R1, #128 ; 0x80 */
179 0x7001, /* STRB R1, [R0] */
180 /* @4: */
181 0x7802, /* LDRB R2, [R0] */
182 0x420a, /* TST R2, R1 */
183 0xd0fc, /* BEQ.N @4 */
184 0x4770 /* BX LR */
185};
186#if (!FTFx_DRIVER_IS_EXPORTED)
187/*! @brief A static buffer used to hold flash_run_command() */
189#endif /* (!FTFx_DRIVER_IS_EXPORTED) */
190#endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */
191
192/*! @brief Access to FTFx Registers */
193static volatile uint32_t *const kFCCOBx = (volatile uint32_t *)&FTFx_FCCOB3_REG;
194
195#if FSL_FEATURE_FLASH_HAS_FLEX_NVM
196/*! @brief Table of eeprom sizes. */
197static const uint16_t kEepromDensities[16] = {
198 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0000,
199 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0001,
200 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0010,
201 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0011,
202 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0100,
203 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0101,
204 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0110,
205 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0111,
206 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1000,
207 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1001,
208 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1010,
209 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1011,
210 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1100,
211 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1101,
212 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1110,
213 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1111
214};
215/*! @brief Table of dflash sizes. */
216static const uint32_t kDflashDensities[16] = {
217 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0000,
218 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0001,
219 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0010,
220 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0011,
221 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0100,
222 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0101,
223 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0110,
224 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0111,
225 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1000,
226 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1001,
227 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1010,
228 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1011,
229 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1100,
230 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1101,
231 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1110,
232 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1111
233};
234#endif /* FSL_FEATURE_FLASH_HAS_FLEX_NVM */
235
236/*******************************************************************************
237 * Code
238 ******************************************************************************/
239
241{
242 if (config == NULL)
243 {
245 }
246
247 config->flexramBlockBase = FSL_FEATURE_FLASH_FLEX_RAM_START_ADDRESS;
248 config->flexramTotalSize = FSL_FEATURE_FLASH_FLEX_RAM_SIZE;
249
250 /* copy required flash command to RAM */
251#if FTFx_DRIVER_IS_FLASH_RESIDENT
252 if (NULL == config->runCmdFuncAddr)
253 {
254#if FTFx_DRIVER_IS_EXPORTED
256#else
257 config->runCmdFuncAddr = s_ftfxRunCommand;
258#endif /* FTFx_DRIVER_IS_EXPORTED */
259 }
260 ftfx_copy_run_command_to_ram(config->runCmdFuncAddr);
261#endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */
262
264
266}
267
268#if FSL_FEATURE_FLASH_HAS_FLEX_NVM
270{
271 struct _dflash_ifr_field_config
272 {
273 uint32_t reserved0;
274 uint8_t FlexNVMPartitionCode;
275 uint8_t EEPROMDataSetSize;
276 uint16_t reserved1;
277 } dataIFRReadOut;
278 uint32_t flexnvmInfoIfrAddr;
279 status_t returnCode;
280
281 if (config == NULL)
282 {
284 }
285
286 flexnvmInfoIfrAddr = config->ifrDesc.resRange.dflashIfrStart + config->ifrDesc.resRange.ifrMemSize - sizeof(dataIFRReadOut);
287
288#if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD
289 /* Get FlexNVM memory partition info from data flash IFR */
290 returnCode = FTFx_CMD_ReadResource(config, flexnvmInfoIfrAddr, (uint8_t *)&dataIFRReadOut,
291 sizeof(dataIFRReadOut), kFTFx_ResourceOptionFlashIfr);
292 if (returnCode != kStatus_FTFx_Success)
293 {
295 }
296#else
297#error "Cannot get FlexNVM memory partition info"
298#endif
299
300 /* Fill out partitioned EEPROM size */
301 dataIFRReadOut.EEPROMDataSetSize &= 0x0FU;
302 config->eepromTotalSize = kEepromDensities[dataIFRReadOut.EEPROMDataSetSize];
303
304 /* Fill out partitioned DFlash size */
305 dataIFRReadOut.FlexNVMPartitionCode &= 0x0FU;
306 config->flashDesc.totalSize = kDflashDensities[dataIFRReadOut.FlexNVMPartitionCode];
307
309}
310#endif /* FSL_FEATURE_FLASH_HAS_FLEX_NVM */
311
313 uint32_t start,
314 uint32_t lengthInBytes,
315 uint32_t key)
316{
317 uint32_t sectorSize;
318 uint32_t endAddress; /* storing end address */
319 uint32_t numberOfSectors; /* number of sectors calculated by endAddress */
320 status_t returnCode;
321
322 /* Check the supplied address range. */
323 returnCode = ftfx_check_mem_range(config, start, lengthInBytes, config->opsConfig.addrAligment.sectorCmd);
324 if (returnCode)
325 {
326 return returnCode;
327 }
328
329 /* Validate the user key */
330 returnCode = ftfx_check_user_key(key);
331 if (returnCode)
332 {
333 return returnCode;
334 }
335
336 start = config->opsConfig.convertedAddress;
337 sectorSize = config->flashDesc.sectorSize;
338
339 /* calculating Flash end address */
340 endAddress = start + lengthInBytes - 1;
341
342 /* re-calculate the endAddress and align it to the start of the next sector
343 * which will be used in the comparison below */
344 if (endAddress % sectorSize)
345 {
346 numberOfSectors = endAddress / sectorSize + 1;
347 endAddress = numberOfSectors * sectorSize - 1;
348 }
349
350 /* the start address will increment to the next sector address
351 * until it reaches the endAdddress */
352 while (start <= endAddress)
353 {
354 /* preparing passing parameter to erase a flash block */
355 kFCCOBx[0] = BYTE2WORD_1_3(FTFx_ERASE_SECTOR, start);
356
357 /* calling flash command sequence function to execute the command */
358 returnCode = ftfx_command_sequence(config);
359
360 /* checking the success of command execution */
361 if (kStatus_FTFx_Success != returnCode)
362 {
363 break;
364 }
365 else
366 {
367 /* Increment to the next sector */
368 start += sectorSize;
369 }
370 }
371
372 return (returnCode);
373}
374
376{
377 status_t returnCode;
378
379 if (config == NULL)
380 {
382 }
383
384 /* preparing passing parameter to erase all flash blocks */
385 kFCCOBx[0] = BYTE2WORD_1_3(FTFx_ERASE_ALL_BLOCK, 0xFFFFFFU);
386
387 /* Validate the user key */
388 returnCode = ftfx_check_user_key(key);
389 if (returnCode)
390 {
391 return returnCode;
392 }
393
394 /* calling flash command sequence function to execute the command */
395 returnCode = ftfx_command_sequence(config);
396
397#if FSL_FEATURE_FLASH_HAS_FLEX_NVM
398 /* Data flash IFR will be erased by erase all command, so we need to
399 * update FlexNVM memory partition status synchronously */
400 if (returnCode == kStatus_FTFx_Success)
401 {
403 }
404#endif
405
406 return returnCode;
407}
408
409#if defined(FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD) && FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD
411{
412 status_t returnCode;
413
414 if (config == NULL)
415 {
417 }
418
419 /* Prepare passing parameter to erase all flash blocks (unsecure). */
420 kFCCOBx[0] = BYTE2WORD_1_3(FTFx_ERASE_ALL_BLOCK_UNSECURE, 0xFFFFFFU);
421
422 /* Validate the user key */
423 returnCode = ftfx_check_user_key(key);
424 if (returnCode)
425 {
426 return returnCode;
427 }
428
429 /* calling flash command sequence function to execute the command */
430 returnCode = ftfx_command_sequence(config);
431
432#if FSL_FEATURE_FLASH_HAS_FLEX_NVM
433 /* Data flash IFR will be erased by erase all unsecure command, so we need to
434 * update FlexNVM memory partition status synchronously */
435 if (returnCode == kStatus_FTFx_Success)
436 {
438 }
439#endif
440
441 return returnCode;
442}
443#endif /* FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD */
444
446{
447 status_t returnCode;
448
449 if (config == NULL)
450 {
452 }
453
454 /* preparing passing parameter to erase all execute-only segments
455 * 1st element for the FCCOB register */
456 kFCCOBx[0] = BYTE2WORD_1_3(FTFx_ERASE_ALL_EXECUTE_ONLY_SEGMENT, 0xFFFFFFU);
457
458 /* Validate the user key */
459 returnCode = ftfx_check_user_key(key);
460 if (returnCode)
461 {
462 return returnCode;
463 }
464
465 /* calling flash command sequence function to execute the command */
466 returnCode = ftfx_command_sequence(config);
467
468 return returnCode;
469}
470
472 uint32_t start,
473 uint8_t *src,
474 uint32_t lengthInBytes)
475{
476 status_t returnCode;
477 uint8_t blockWriteUnitSize = config->opsConfig.addrAligment.blockWriteUnitSize;
478
479 if (src == NULL)
480 {
482 }
483
484 /* Check the supplied address range. */
485 returnCode = ftfx_check_mem_range(config, start, lengthInBytes, blockWriteUnitSize);
486 if (returnCode)
487 {
488 return returnCode;
489 }
490
491 start = config->opsConfig.convertedAddress;
492
493 while (lengthInBytes > 0)
494 {
495 /* preparing passing parameter to program the flash block */
496 kFCCOBx[1] = ftfx_read_word_from_byte_address((const uint8_t*)src);
497 src += 4;
498
499 if (4 == blockWriteUnitSize)
500 {
501 kFCCOBx[0] = BYTE2WORD_1_3(FTFx_PROGRAM_LONGWORD, start);
502 }
503 else if (8 == blockWriteUnitSize)
504 {
505 kFCCOBx[2] = ftfx_read_word_from_byte_address((const uint8_t*)src);
506 src += 4;
507 kFCCOBx[0] = BYTE2WORD_1_3(FTFx_PROGRAM_PHRASE, start);
508 }
509 else
510 {
511 }
512
513 /* calling flash command sequence function to execute the command */
514 returnCode = ftfx_command_sequence(config);
515
516 /* checking for the success of command execution */
517 if (kStatus_FTFx_Success != returnCode)
518 {
519 break;
520 }
521 else
522 {
523 /* update start address for next iteration */
524 start += blockWriteUnitSize;
525
526 /* update lengthInBytes for next iteration */
527 lengthInBytes -= blockWriteUnitSize;
528 }
529 }
530
531 return (returnCode);
532}
533
534status_t FTFx_CMD_ProgramOnce(ftfx_config_t *config, uint32_t index, uint8_t *src, uint32_t lengthInBytes)
535{
536 status_t returnCode;
537
538 if ((config == NULL) || (src == NULL))
539 {
541 }
542
543 /* pass paramters to FTFx */
544 kFCCOBx[0] = BYTE2WORD_1_1_2(FTFx_PROGRAM_ONCE, index, 0xFFFFU);
545
546 kFCCOBx[1] = ftfx_read_word_from_byte_address((const uint8_t*)src);
547
548 /* Note: Have to seperate the first index from the rest if it equals 0
549 * to avoid a pointless comparison of unsigned int to 0 compiler warning */
550 if (config->ifrDesc.feature.has8ByteIdxSupport)
551 {
552 if (config->ifrDesc.feature.has4ByteIdxSupport)
553 {
554 if (((index == config->ifrDesc.idxInfo.mix8byteIdxStart) ||
555 ((index >= config->ifrDesc.idxInfo.mix8byteIdxStart + 1) && (index <= config->ifrDesc.idxInfo.mix8byteIdxStart))) &&
556 (lengthInBytes == 8))
557 {
558 kFCCOBx[2] = ftfx_read_word_from_byte_address((const uint8_t*)src + 4);
559 }
560 }
561 else
562 {
563 kFCCOBx[2] = ftfx_read_word_from_byte_address((const uint8_t*)src + 4);
564 }
565 }
566
567 /* calling flash command sequence function to execute the command */
568 returnCode = ftfx_command_sequence(config);
569
570 return returnCode;
571}
572
573#if defined(FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD) && FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD
575 uint32_t start,
576 uint8_t *src,
577 uint32_t lengthInBytes)
578{
579 status_t returnCode;
580 uint32_t sectorSize;
581 uint8_t aligmentInBytes = config->opsConfig.addrAligment.sectionCmd;
582#if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD
583 bool needSwitchFlexRamMode = false;
584#endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */
585
586 if (src == NULL)
587 {
589 }
590
591 /* Check the supplied address range. */
592 returnCode = ftfx_check_mem_range(config, start, lengthInBytes, aligmentInBytes);
593 if (returnCode)
594 {
595 return returnCode;
596 }
597
598 start = config->opsConfig.convertedAddress;
599 sectorSize = config->flashDesc.sectorSize;
600
601#if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD
602 /* Switch function of FlexRAM if needed */
603 if (!(FTFx->FCNFG & FTFx_FCNFG_RAMRDY_MASK))
604 {
605 needSwitchFlexRamMode = true;
606
608 if (returnCode != kStatus_FTFx_Success)
609 {
611 }
612 }
613#endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */
614
615 while (lengthInBytes > 0)
616 {
617 /* Make sure the write operation doesn't span two sectors */
618 uint32_t endAddressOfCurrentSector = ALIGN_UP(start, sectorSize);
619 uint32_t lengthTobeProgrammedOfCurrentSector;
620 uint32_t currentOffset = 0;
621
622 if (endAddressOfCurrentSector == start)
623 {
624 endAddressOfCurrentSector += sectorSize;
625 }
626
627 if (lengthInBytes + start > endAddressOfCurrentSector)
628 {
629 lengthTobeProgrammedOfCurrentSector = endAddressOfCurrentSector - start;
630 }
631 else
632 {
633 lengthTobeProgrammedOfCurrentSector = lengthInBytes;
634 }
635
636 /* Program Current Sector */
637 while (lengthTobeProgrammedOfCurrentSector > 0)
638 {
639 /* Make sure the program size doesn't exceeds Acceleration RAM size */
640 uint32_t programSizeOfCurrentPass;
641 uint32_t numberOfPhases;
642
643 if (lengthTobeProgrammedOfCurrentSector > config->flexramTotalSize)
644 {
645 programSizeOfCurrentPass = config->flexramTotalSize;
646 }
647 else
648 {
649 programSizeOfCurrentPass = lengthTobeProgrammedOfCurrentSector;
650 }
651
652 /* Copy data to FlexRAM */
653 memcpy((void *)config->flexramBlockBase, src + currentOffset, programSizeOfCurrentPass);
654 /* Set start address of the data to be programmed */
655 kFCCOBx[0] = BYTE2WORD_1_3(FTFx_PROGRAM_SECTION, start + currentOffset);
656 /* Set program size in terms of FEATURE_FLASH_SECTION_CMD_ADDRESS_ALIGMENT */
657 numberOfPhases = programSizeOfCurrentPass / aligmentInBytes;
658
659 kFCCOBx[1] = BYTE2WORD_2_2(numberOfPhases, 0xFFFFU);
660
661 /* Peform command sequence */
662 returnCode = ftfx_command_sequence(config);
663
664 if (returnCode != kStatus_FTFx_Success)
665 {
666 return returnCode;
667 }
668
669 lengthTobeProgrammedOfCurrentSector -= programSizeOfCurrentPass;
670 currentOffset += programSizeOfCurrentPass;
671 }
672
673 src += currentOffset;
674 start += currentOffset;
675 lengthInBytes -= currentOffset;
676 }
677
678#if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD
679 /* Restore function of FlexRAM if needed. */
680 if (needSwitchFlexRamMode)
681 {
683 if (returnCode != kStatus_FTFx_Success)
684 {
686 }
687 }
688#endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */
689
690 return returnCode;
691}
692#endif /* FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD */
693
694#if defined(FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD) && FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD
697 uint32_t eepromDataSizeCode,
698 uint32_t flexnvmPartitionCode)
699{
700 status_t returnCode;
701
702 if (config == NULL)
703 {
705 }
706
707 /* eepromDataSizeCode[7:6], flexnvmPartitionCode[7:4] should be all 1'b0
708 * or it will cause access error. */
709 /* eepromDataSizeCode &= 0x3FU; */
710 /* flexnvmPartitionCode &= 0x0FU; */
711
712 /* preparing passing parameter to program the flash block */
713 kFCCOBx[0] = BYTE2WORD_1_2_1(FTFx_PROGRAM_PARTITION, 0xFFFFU, option);
714 kFCCOBx[1] = BYTE2WORD_1_1_2(eepromDataSizeCode, flexnvmPartitionCode, 0xFFFFU);
715
716 /* calling flash command sequence function to execute the command */
717 returnCode = ftfx_command_sequence(config);
718
719#if FSL_FEATURE_FLASH_HAS_FLEX_NVM
720 /* Data flash IFR will be updated by program partition command during reset sequence,
721 * so we just set reserved values for partitioned FlexNVM size here */
722 config->eepromTotalSize = 0xFFFFU;
723 config->flashDesc.totalSize = 0xFFFFFFFFU;
724#endif
725
726 return (returnCode);
727}
728#endif /* FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD */
729
730status_t FTFx_CMD_ReadOnce(ftfx_config_t *config, uint32_t index, uint8_t *dst, uint32_t lengthInBytes)
731{
732 status_t returnCode;
733
734 if ((config == NULL) || (dst == NULL))
735 {
737 }
738
739 /* pass paramters to FTFx */
740 kFCCOBx[0] = BYTE2WORD_1_1_2(FTFx_READ_ONCE, index, 0xFFFFU);
741
742 /* calling flash command sequence function to execute the command */
743 returnCode = ftfx_command_sequence(config);
744
745 if (kStatus_FTFx_Success == returnCode)
746 {
748 /* Note: Have to seperate the first index from the rest if it equals 0
749 * to avoid a pointless comparison of unsigned int to 0 compiler warning */
750 if (config->ifrDesc.feature.has8ByteIdxSupport)
751 {
752 if (config->ifrDesc.feature.has4ByteIdxSupport)
753 {
754 if (((index == config->ifrDesc.idxInfo.mix8byteIdxStart) ||
755 ((index >= config->ifrDesc.idxInfo.mix8byteIdxStart + 1) && (index <= config->ifrDesc.idxInfo.mix8byteIdxStart))) &&
756 (lengthInBytes == 8))
757 {
759 }
760 }
761 else
762 {
764 }
765 }
766 }
767
768 return returnCode;
769}
770
771#if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD
773 uint32_t start,
774 uint8_t *dst,
775 uint32_t lengthInBytes,
777{
778 status_t returnCode;
779
780 if ((config == NULL) || (dst == NULL))
781 {
783 }
784
785 uint8_t aligmentInBytes = config->opsConfig.addrAligment.resourceCmd;
786
787 /* Check the supplied address range. */
788 returnCode = ftfx_check_resource_range(config, start, lengthInBytes, aligmentInBytes, option);
789 if (returnCode != kStatus_FTFx_Success)
790 {
791 return returnCode;
792 }
793
794 while (lengthInBytes > 0)
795 {
796 /* preparing passing parameter */
797 kFCCOBx[0] = BYTE2WORD_1_3(FTFx_READ_RESOURCE, start);
798 if (aligmentInBytes == 4)
799 {
800 kFCCOBx[2] = BYTE2WORD_1_3(option, 0xFFFFFFU);
801 }
802 else if (aligmentInBytes == 8)
803 {
804 kFCCOBx[1] = BYTE2WORD_1_3(option, 0xFFFFFFU);
805 }
806 else
807 {
808 }
809
810 /* calling flash command sequence function to execute the command */
811 returnCode = ftfx_command_sequence(config);
812
813 if (kStatus_FTFx_Success != returnCode)
814 {
815 break;
816 }
817
818 /* fetch data */
820 dst += 4;
821 if (aligmentInBytes == 8)
822 {
824 dst += 4;
825 }
826 /* update start address for next iteration */
827 start += aligmentInBytes;
828 /* update lengthInBytes for next iteration */
829 lengthInBytes -= aligmentInBytes;
830 }
831
832 return (returnCode);
833}
834#endif /* FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD */
835
837 uint32_t start,
838 uint32_t lengthInBytes,
839 ftfx_margin_value_t margin)
840{
841 /* Check arguments. */
842 uint32_t blockSize;
843 uint32_t nextBlockStartAddress;
844 uint32_t remainingBytes;
845 uint8_t aligmentInBytes = config->opsConfig.addrAligment.sectionCmd;
846 status_t returnCode;
847
848 returnCode = ftfx_check_mem_range(config, start, lengthInBytes, aligmentInBytes);
849 if (returnCode)
850 {
851 return returnCode;
852 }
853
854 start = config->opsConfig.convertedAddress;
855 blockSize = config->flashDesc.totalSize / config->flashDesc.blockCount;
856
857 nextBlockStartAddress = ALIGN_UP(start, blockSize);
858 if (nextBlockStartAddress == start)
859 {
860 nextBlockStartAddress += blockSize;
861 }
862
863 remainingBytes = lengthInBytes;
864
865 while (remainingBytes)
866 {
867 uint32_t numberOfPhrases;
868 uint32_t verifyLength = nextBlockStartAddress - start;
869 if (verifyLength > remainingBytes)
870 {
871 verifyLength = remainingBytes;
872 }
873
874 numberOfPhrases = verifyLength / aligmentInBytes;
875
876 /* Fill in verify section command parameters. */
877 kFCCOBx[0] = BYTE2WORD_1_3(FTFx_VERIFY_SECTION, start);
878 kFCCOBx[1] = BYTE2WORD_2_1_1(numberOfPhrases, margin, 0xFFU);
879
880 /* calling flash command sequence function to execute the command */
881 returnCode = ftfx_command_sequence(config);
882 if (returnCode)
883 {
884 return returnCode;
885 }
886
887 remainingBytes -= verifyLength;
888 start += verifyLength;
889 nextBlockStartAddress += blockSize;
890 }
891
893}
894
896{
897 if (config == NULL)
898 {
900 }
901
902 /* preparing passing parameter to verify all block command */
903 kFCCOBx[0] = BYTE2WORD_1_1_2(FTFx_VERIFY_ALL_BLOCK, margin, 0xFFFFU);
904
905 /* calling flash command sequence function to execute the command */
907}
908
910{
911 if (config == NULL)
912 {
914 }
915
916 /* preparing passing parameter to verify erase all execute-only segments command */
917 kFCCOBx[0] = BYTE2WORD_1_1_2(FTFx_VERIFY_ALL_EXECUTE_ONLY_SEGMENT, margin, 0xFFFFU);
918
919 /* calling flash command sequence function to execute the command */
921}
922
924 uint32_t start,
925 uint32_t lengthInBytes,
926 const uint8_t *expectedData,
927 ftfx_margin_value_t margin,
928 uint32_t *failedAddress,
929 uint32_t *failedData)
930{
931 status_t returnCode;
932 uint8_t aligmentInBytes = config->opsConfig.addrAligment.checkCmd;
933 if (expectedData == NULL)
934 {
936 }
937
938 returnCode = ftfx_check_mem_range(config, start, lengthInBytes, aligmentInBytes);
939 if (returnCode)
940 {
941 return returnCode;
942 }
943
944 start = config->opsConfig.convertedAddress;
945
946 while (lengthInBytes)
947 {
948 /* preparing passing parameter to program check the flash block */
949 kFCCOBx[0] = BYTE2WORD_1_3(FTFx_PROGRAM_CHECK, start);
950 kFCCOBx[1] = BYTE2WORD_1_3(margin, 0xFFFFFFU);
951 kFCCOBx[2] = ftfx_read_word_from_byte_address((const uint8_t*)expectedData);
952
953 /* calling flash command sequence function to execute the command */
954 returnCode = ftfx_command_sequence(config);
955
956 /* checking for the success of command execution */
957 if (kStatus_FTFx_Success != returnCode)
958 {
959 if (failedAddress)
960 {
961 *failedAddress = start;
962 }
963 if (failedData)
964 {
965 *failedData = 0;
966 }
967 break;
968 }
969
970 lengthInBytes -= aligmentInBytes;
971 expectedData += aligmentInBytes;
972 start += aligmentInBytes;
973 }
974
975 return (returnCode);
976}
977
979{
980 uint8_t registerValue; /* registerValue */
981 status_t returnCode; /* return code variable */
982
983 if ((config == NULL) || (backdoorKey == NULL))
984 {
986 }
987
988 /* set the default return code as kStatus_Success */
989 returnCode = kStatus_FTFx_Success;
990
991 /* Get flash security register value */
992 registerValue = FTFx->FSEC;
993
994 /* Check to see if flash is in secure state (any state other than 0x2)
995 * If not, then skip this since flash is not secure */
996 if (0x02 != (registerValue & 0x03))
997 {
998 /* preparing passing parameter to erase a flash block */
999 kFCCOBx[0] = BYTE2WORD_1_3(FTFx_SECURITY_BY_PASS, 0xFFFFFFU);
1000 kFCCOBx[1] = BYTE2WORD_1_1_1_1(backdoorKey[0], backdoorKey[1], backdoorKey[2], backdoorKey[3]);
1001 kFCCOBx[2] = BYTE2WORD_1_1_1_1(backdoorKey[4], backdoorKey[5], backdoorKey[6], backdoorKey[7]);
1002
1003 /* calling flash command sequence function to execute the command */
1004 returnCode = ftfx_command_sequence(config);
1005 }
1006
1007 return (returnCode);
1008}
1009
1011{
1012 /* store data read from flash register */
1013 uint8_t registerValue;
1014
1015 if ((config == NULL) || (state == NULL))
1016 {
1018 }
1019
1020 /* Get flash security register value */
1021 registerValue = FTFx->FSEC;
1022
1023 /* check the status of the flash security bits in the security register */
1024 if (kFTFx_FsecRegCode_SEC_Unsecured == (registerValue & FTFx_FSEC_SEC_MASK))
1025 {
1026 /* Flash in unsecured state */
1028 }
1029 else
1030 {
1031 /* Flash in secured state
1032 * check for backdoor key security enable bit */
1033 if (kFTFx_FsecRegCode_KEYEN_Enabled == (registerValue & FTFx_FSEC_KEYEN_MASK))
1034 {
1035 /* Backdoor key security enabled */
1037 }
1038 else
1039 {
1040 /* Backdoor key security disabled */
1042 }
1043 }
1044
1045 return (kStatus_FTFx_Success);
1046}
1047
1048#if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD
1050 {
1051 status_t status;
1052
1053 if (config == NULL)
1054 {
1056 }
1057
1058 status = ftfx_check_flexram_function_option(option);
1059 if (status != kStatus_FTFx_Success)
1060 {
1061 return status;
1062 }
1063
1064 /* preparing passing parameter to verify all block command */
1065 kFCCOBx[0] = BYTE2WORD_1_1_2(FTFx_SET_FLEXRAM_FUNCTION, option, 0xFFFFU);
1066
1067 /* calling flash command sequence function to execute the command */
1069 }
1070#endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */
1071
1072#if defined(FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD) && FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD
1074 uint32_t address,
1076 ftfx_swap_state_config_t *returnInfo)
1077{
1078 status_t returnCode;
1079
1080 if ((config == NULL) || (returnInfo == NULL))
1081 {
1083 }
1084
1085 if (address & (FSL_FEATURE_FLASH_PFLASH_SWAP_CONTROL_CMD_ADDRESS_ALIGMENT - 1))
1086 {
1088 }
1089
1090 /* Make sure address provided is in the lower half of Program flash but not in the Flash Configuration Field */
1091 if ((address >= (config->flashDesc.totalSize / 2)) ||
1092 ((address >= kFTFx_PflashConfigAreaStart) && (address <= kFTFx_PflashConfigAreaEnd)))
1093 {
1095 }
1096
1097 /* Check the option. */
1098 returnCode = ftfx_check_swap_control_option(option);
1099 if (returnCode)
1100 {
1101 return returnCode;
1102 }
1103
1104 kFCCOBx[0] = BYTE2WORD_1_3(FTFx_SWAP_CONTROL, address);
1105 kFCCOBx[1] = BYTE2WORD_1_3(option, 0xFFFFFFU);
1106
1107 returnCode = ftfx_command_sequence(config);
1108
1109 returnInfo->flashSwapState = (ftfx_swap_state_t)FTFx_FCCOB5_REG;
1110 returnInfo->currentSwapBlockStatus = (ftfx_swap_block_status_t)FTFx_FCCOB6_REG;
1111 returnInfo->nextSwapBlockStatus = (ftfx_swap_block_status_t)FTFx_FCCOB7_REG;
1112
1113 return returnCode;
1114}
1115#endif /* FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD */
1116
1118{
1119 if (config == NULL)
1120 {
1122 }
1123
1124#if FSL_FEATURE_FLASH_IS_FTFA
1125 /* FTFA parts(eg. K80, KL80, L5K) support both 4-bytes and 8-bytes unit size */
1126 config->ifrDesc.feature.has4ByteIdxSupport = 1;
1127 config->ifrDesc.feature.has8ByteIdxSupport = 1;
1128 config->ifrDesc.idxInfo.mix8byteIdxStart = 0x10U;
1129 config->ifrDesc.idxInfo.mix8byteIdxEnd = 0x13U;
1130#elif FSL_FEATURE_FLASH_IS_FTFE
1131 /* FTFE parts(eg. K65, KE18) only support 8-bytes unit size */
1132 config->ifrDesc.feature.has4ByteIdxSupport = 0;
1133 config->ifrDesc.feature.has8ByteIdxSupport = 1;
1134#elif FSL_FEATURE_FLASH_IS_FTFL
1135 /* FTFL parts(eg. K20) only support 4-bytes unit size */
1136 config->ifrDesc.feature.has4ByteIdxSupport = 1;
1137 config->ifrDesc.feature.has8ByteIdxSupport = 0;
1138#endif
1139
1140 config->ifrDesc.resRange.pflashIfrStart = 0x0000U;
1141 config->ifrDesc.resRange.versionIdSize = 0x08U;
1142#if FSL_FEATURE_FLASH_IS_FTFE
1143 config->ifrDesc.resRange.versionIdStart = 0x08U;
1144 config->ifrDesc.resRange.ifrMemSize = 0x0400U;
1145#else /* FSL_FEATURE_FLASH_IS_FTFL == 1 or FSL_FEATURE_FLASH_IS_FTFA = =1 */
1146 config->ifrDesc.resRange.versionIdStart = 0x00U;
1147 config->ifrDesc.resRange.ifrMemSize = 0x0100U;
1148#endif
1149
1150#if FSL_FEATURE_FLASH_HAS_FLEX_NVM
1151 config->ifrDesc.resRange.dflashIfrStart = 0x800000U;
1152#endif
1153
1154#if FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD
1155#if FSL_FEATURE_FLASH_IS_FTFE
1156 config->ifrDesc.resRange.pflashSwapIfrStart = 0x40000U;
1157#else /* FSL_FEATURE_FLASH_IS_FTFL == 1 or FSL_FEATURE_FLASH_IS_FTFA == 1 */
1158 config->ifrDesc.resRange.pflashSwapIfrStart = config->flashDesc.totalSize / 4;
1159#endif
1160#endif /* FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD */
1161
1162 return kStatus_FTFx_Success;
1163}
1164
1165#if FTFx_DRIVER_IS_FLASH_RESIDENT
1166/*!
1167 * @brief Copy PIC of flash_run_command() to RAM
1168 */
1169static void ftfx_copy_run_command_to_ram(uint32_t *ftfxRunCommand)
1170{
1172
1173 /* Since the value of ARM function pointer is always odd, but the real start address
1174 * of function memory should be even, that's why +1 operation exist. */
1175 memcpy((uint8_t *)ftfxRunCommand, (const uint8_t *)s_ftfxRunCommandFunctionCode, sizeof(s_ftfxRunCommandFunctionCode));
1176}
1177#endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */
1178
1179/*!
1180 * @brief FTFx Command Sequence
1181 *
1182 * This function is used to perform the command write sequence to the flash.
1183 *
1184 * @param driver Pointer to storage for the driver runtime state.
1185 * @return An error code or kStatus_FTFx_Success
1186 */
1188{
1189 uint8_t registerValue;
1190
1191#if FTFx_DRIVER_IS_FLASH_RESIDENT
1192 /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register */
1193 FTFx->FSTAT = FTFx_FSTAT_RDCOLERR_MASK | FTFx_FSTAT_ACCERR_MASK | FTFx_FSTAT_FPVIOL_MASK;
1194
1195 /* Since the value of ARM function pointer is always odd, but the real start address
1196 * of function memory should be even, that's why +1 operation exist. */
1197 callFtfxRunCommand_t callFtfxRunCommand = (callFtfxRunCommand_t)((uint32_t)config->runCmdFuncAddr + 1);
1198
1199 /* We pass the ftfx_fstat address as a parameter to flash_run_comamnd() instead of using
1200 * pre-processed MICRO sentences or operating global variable in flash_run_comamnd()
1201 * to make sure that flash_run_command() will be compiled into position-independent code (PIC). */
1202 callFtfxRunCommand((FTFx_REG8_ACCESS_TYPE)(&FTFx->FSTAT));
1203#else
1204 /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register */
1205 FTFx->FSTAT = FTFx_FSTAT_RDCOLERR_MASK | FTFx_FSTAT_ACCERR_MASK | FTFx_FSTAT_FPVIOL_MASK;
1206
1207 /* clear CCIF bit */
1208 FTFx->FSTAT = FTFx_FSTAT_CCIF_MASK;
1209
1210 /* Check CCIF bit of the flash status register, wait till it is set.
1211 * IP team indicates that this loop will always complete. */
1212 while (!(FTFx->FSTAT & FTFx_FSTAT_CCIF_MASK))
1213 {
1214 }
1215#endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */
1216
1217 /* Check error bits */
1218 /* Get flash status register value */
1219 registerValue = FTFx->FSTAT;
1220
1221 /* checking access error */
1222 if (registerValue & FTFx_FSTAT_ACCERR_MASK)
1223 {
1225 }
1226 /* checking protection error */
1227 else if (registerValue & FTFx_FSTAT_FPVIOL_MASK)
1228 {
1230 }
1231 /* checking MGSTAT0 non-correctable error */
1232 else if (registerValue & FTFx_FSTAT_MGSTAT0_MASK)
1233 {
1235 }
1236 else
1237 {
1238 return kStatus_FTFx_Success;
1239 }
1240}
1241
1242/*! @brief Validates the range and alignment of the given address range.*/
1244 uint32_t startAddress,
1245 uint32_t lengthInBytes,
1246 uint8_t alignmentBaseline)
1247{
1248 if (config == NULL)
1249 {
1251 }
1252
1253 /* Verify the start and length are alignmentBaseline aligned. */
1254 if ((startAddress & (alignmentBaseline - 1)) || (lengthInBytes & (alignmentBaseline - 1)))
1255 {
1257 }
1258
1259 /* check for valid range of the target addresses */
1260 if ((startAddress >= config->flashDesc.blockBase) &&
1261 ((startAddress + lengthInBytes) <= (config->flashDesc.blockBase + config->flashDesc.totalSize)))
1262 {
1263 return kStatus_FTFx_Success;
1264 }
1265
1267}
1268
1269/*! @brief Validates the given user key for flash erase APIs.*/
1270static status_t ftfx_check_user_key(uint32_t key)
1271{
1272 /* Validate the user key */
1273 if (key != kFTFx_ApiEraseKey)
1274 {
1276 }
1277
1278 return kStatus_FTFx_Success;
1279}
1280
1281/*! @brief Reads word from byte address.*/
1282static uint32_t ftfx_read_word_from_byte_address(const uint8_t *src)
1283{
1284 uint32_t word = 0;
1285
1286 if (!((uint32_t)src % 4))
1287 {
1288 word = *(const uint32_t *)src;
1289 }
1290 else
1291 {
1292 for (uint32_t i = 0; i < 4; i++)
1293 {
1294 word |= (uint32_t)(*src) << (i * 8);
1295 src++;
1296 }
1297 }
1298
1299 return word;
1300}
1301
1302/*! @brief Writes word to byte address.*/
1303static void ftfx_write_word_to_byte_address(uint8_t *dst, uint32_t word)
1304{
1305 if (!((uint32_t)dst % 4))
1306 {
1307 *(uint32_t *)dst = word;
1308 }
1309 else
1310 {
1311 for (uint32_t i = 0; i < 4; i++)
1312 {
1313 *dst = (uint8_t)((word >> (i * 8)) & 0xFFU);
1314 dst++;
1315 }
1316 }
1317}
1318
1319#if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD
1320/*! @brief Validates the range of the given resource address.*/
1322 uint32_t start,
1323 uint32_t lengthInBytes,
1324 uint32_t alignmentBaseline,
1326{
1327 status_t status;
1328 uint32_t maxReadbleAddress;
1329
1330 if ((start & (alignmentBaseline - 1)) || (lengthInBytes & (alignmentBaseline - 1)))
1331 {
1333 }
1334
1335 status = kStatus_FTFx_Success;
1336
1337 maxReadbleAddress = start + lengthInBytes - 1;
1338 if (option == kFTFx_ResourceOptionVersionId)
1339 {
1340 if ((start != config->ifrDesc.resRange.versionIdStart) ||
1341 (lengthInBytes != config->ifrDesc.resRange.versionIdSize))
1342 {
1344 }
1345 }
1346 else if (option == kFTFx_ResourceOptionFlashIfr)
1347 {
1348 if ((start >= config->ifrDesc.resRange.pflashIfrStart) &&
1349 (maxReadbleAddress < (config->ifrDesc.resRange.pflashIfrStart + config->ifrDesc.resRange.ifrMemSize)))
1350 {
1351 }
1352#if FSL_FEATURE_FLASH_HAS_FLEX_NVM
1353 else if ((start >= config->ifrDesc.resRange.dflashIfrStart) &&
1354 (maxReadbleAddress < (config->ifrDesc.resRange.dflashIfrStart + config->ifrDesc.resRange.ifrMemSize)))
1355 {
1356 }
1357#endif
1358#if FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD
1359 else if ((start >= config->ifrDesc.resRange.pflashSwapIfrStart) &&
1360 (maxReadbleAddress < (config->ifrDesc.resRange.pflashSwapIfrStart + config->ifrDesc.resRange.ifrMemSize)))
1361 {
1362 }
1363#endif
1364 else
1365 {
1367 }
1368 }
1369 else
1370 {
1372 }
1373
1374 return status;
1375}
1376#endif /* FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD */
1377
1378#if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD
1379/*! @brief Validates the gived flexram function option.*/
1381{
1382 if ((option != kFTFx_FlexramFuncOptAvailableAsRam) &&
1384 {
1386 }
1387
1388 return kStatus_FTFx_Success;
1389}
1390#endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */
1391
1392#if defined(FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD) && FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD
1393/*! @brief Validates the gived swap control option.*/
1405#endif /* FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD */
static constexpr persistent_config_s * config
_ftfx_pflash_config_area_range
Enumeration for flash config area.
@ kFTFx_PflashConfigAreaEnd
@ kFTFx_PflashConfigAreaStart
status_t FTFx_CMD_SwapControl(ftfx_config_t *config, uint32_t address, ftfx_swap_control_opt_t option, ftfx_swap_state_config_t *returnInfo)
Configures the Swap function or checks the swap state of the Flash module.
_ftfx_fsec_register_code
@ kFTFx_FsecRegCode_SEC_Unsecured
@ kFTFx_FsecRegCode_KEYEN_Enabled
status_t FTFx_CMD_Program(ftfx_config_t *config, uint32_t start, uint8_t *src, uint32_t lengthInBytes)
Programs flash with data at locations passed in through parameters.
status_t FTFx_REG_GetSecurityState(ftfx_config_t *config, ftfx_security_state_t *state)
Returns the security state via the pointer passed into the function.
static volatile uint32_t *const kFCCOBx
Access to FTFx Registers.
status_t FTFx_CMD_ProgramSection(ftfx_config_t *config, uint32_t start, uint8_t *src, uint32_t lengthInBytes)
Programs flash with data at locations passed in through parameters via the Program Section command.
status_t FTFx_CMD_VerifyProgram(ftfx_config_t *config, uint32_t start, uint32_t lengthInBytes, const uint8_t *expectedData, ftfx_margin_value_t margin, uint32_t *failedAddress, uint32_t *failedData)
Verifies programming of the desired flash area at a specified margin level.
static uint32_t ftfx_read_word_from_byte_address(const uint8_t *src)
Reads word from byte address.
status_t FTFx_API_UpdateFlexnvmPartitionStatus(ftfx_config_t *config)
Updates FlexNVM memory partition status according to data flash 0 IFR.
void(* callFtfxRunCommand_t)(FTFx_REG8_ACCESS_TYPE ftfx_fstat)
A function pointer used to point to relocated flash_run_command()
static status_t ftfx_command_sequence(ftfx_config_t *config)
Internal function Flash command sequence. Called by driver APIs only.
status_t FTFx_CMD_ProgramOnce(ftfx_config_t *config, uint32_t index, uint8_t *src, uint32_t lengthInBytes)
Programs Program Once Field through parameters.
static status_t ftfx_check_mem_range(ftfx_config_t *config, uint32_t startAddress, uint32_t lengthInBytes, uint8_t alignmentBaseline)
Validates the range and alignment of the given address range.
status_t FTFx_API_Init(ftfx_config_t *config)
Initializes the global flash properties structure members.
static status_t ftfx_check_flexram_function_option(ftfx_flexram_func_opt_t option)
Validates the gived flexram function option.
static const uint16_t kEepromDensities[16]
Table of eeprom sizes.
static status_t ftfx_check_resource_range(ftfx_config_t *config, uint32_t start, uint32_t lengthInBytes, uint32_t alignmentBaseline, ftfx_read_resource_opt_t option)
Validates the range of the given resource address.
status_t FTFx_CMD_EraseAll(ftfx_config_t *config, uint32_t key)
Erases entire flash.
status_t FTFx_CMD_EraseAllUnsecure(ftfx_config_t *config, uint32_t key)
Erases the entire flash, including protected sectors.
_ftfx_ram_func_constants
Constants for execute-in-RAM flash function.
@ kFTFx_RamFuncMaxSizeInWords
status_t FTFx_CMD_VerifyEraseAllExecuteOnlySegments(ftfx_config_t *config, ftfx_margin_value_t margin)
Verifies whether the program flash execute-only segments have been erased to the specified read margi...
static uint32_t s_ftfxRunCommand[kFTFx_RamFuncMaxSizeInWords]
A static buffer used to hold flash_run_command()
status_t FTFx_CMD_VerifyEraseAll(ftfx_config_t *config, ftfx_margin_value_t margin)
Verifies erasure of the entire flash at a specified margin level.
status_t FTFx_CMD_ReadResource(ftfx_config_t *config, uint32_t start, uint8_t *dst, uint32_t lengthInBytes, ftfx_read_resource_opt_t option)
Reads the resource with data at locations passed in through parameters.
static status_t ftfx_check_user_key(uint32_t key)
Validates the given user key for flash erase APIs.
status_t FTFx_CMD_Erase(ftfx_config_t *config, uint32_t start, uint32_t lengthInBytes, uint32_t key)
Erases the flash sectors encompassed by parameters passed into function.
static status_t ftfx_init_ifr(ftfx_config_t *config)
Init IFR memory related info.
static const uint32_t kDflashDensities[16]
Table of dflash sizes.
static void ftfx_copy_run_command_to_ram(uint32_t *ftfxRunCommand)
Copy flash_run_command() to RAM.
status_t FTFx_CMD_SecurityBypass(ftfx_config_t *config, const uint8_t *backdoorKey)
Allows users to bypass security with a backdoor key.
status_t FTFx_CMD_VerifyErase(ftfx_config_t *config, uint32_t start, uint32_t lengthInBytes, ftfx_margin_value_t margin)
Verifies an erasure of the desired flash area at a specified margin level.
static void ftfx_write_word_to_byte_address(uint8_t *dst, uint32_t word)
Writes word to byte address.
status_t FTFx_CMD_SetFlexramFunction(ftfx_config_t *config, ftfx_flexram_func_opt_t option)
Sets the FlexRAM function command.
static const uint16_t s_ftfxRunCommandFunctionCode[]
Position independent code of flash_run_command()
status_t FTFx_CMD_ProgramPartition(ftfx_config_t *config, ftfx_partition_flexram_load_opt_t option, uint32_t eepromDataSizeCode, uint32_t flexnvmPartitionCode)
Prepares the FlexNVM block for use as data flash, EEPROM backup, or a combination of both and initial...
static status_t ftfx_check_swap_control_option(ftfx_swap_control_opt_t option)
Validates the gived swap control option.
status_t FTFx_CMD_ReadOnce(ftfx_config_t *config, uint32_t index, uint8_t *dst, uint32_t lengthInBytes)
Reads the Program Once Field through parameters.
status_t FTFx_CMD_EraseAllExecuteOnlySegments(ftfx_config_t *config, uint32_t key)
Erases all program flash execute-only segments defined by the FXACC registers.
enum _ftfx_read_resource_opt ftfx_read_resource_opt_t
Enumeration for the two possible options of flash read resource command.
@ kFTFx_SecurityStateBackdoorEnabled
@ kFTFx_SecurityStateNotSecure
@ kFTFx_SecurityStateBackdoorDisabled
enum _ftfx_swap_control_option ftfx_swap_control_opt_t
Enumeration for the possible options of Swap control commands.
@ kFTFx_SwapControlOptionReportStatus
@ kFTFx_SwapControlOptionSetInCompleteState
@ kFTFx_SwapControlOptionDisableSystem
@ kFTFx_SwapControlOptionSetInUpdateState
@ kFTFx_SwapControlOptionIntializeSystem
@ kStatus_FTFx_AlignmentError
@ kStatus_FTFx_SetFlexramAsRamError
@ kStatus_FTFx_CommandFailure
@ kStatus_FTFx_EraseKeyError
@ kStatus_FTFx_RecoverFlexramAsEepromError
@ kStatus_FTFx_Success
@ kStatus_FTFx_InvalidArgument
@ kStatus_FTFx_AddressError
@ kStatus_FTFx_ExecuteInRamFunctionNotReady
@ kStatus_FTFx_PartitionStatusUpdateFailure
@ kStatus_FTFx_SwapIndicatorAddressError
@ kStatus_FTFx_ProtectionViolation
@ kStatus_FTFx_AccessError
enum _ftfx_swap_block_status ftfx_swap_block_status_t
enum _ftfx_margin_value ftfx_margin_value_t
Enumeration for supported FTFx margin levels.
@ kFTFx_FlexramFuncOptAvailableForEeprom
@ kFTFx_FlexramFuncOptAvailableAsRam
enum _ftfx_swap_state ftfx_swap_state_t
Enumeration for the possible flash Swap status.
enum _ftfx_flexram_function_option ftfx_flexram_func_opt_t
Enumeration for the two possilbe options of set FlexRAM function command.
@ kFTFx_ApiEraseKey
enum _ftfx_security_state ftfx_security_state_t
Enumeration for the three possible FTFx security states.
@ kFTFx_ResourceOptionVersionId
@ kFTFx_ResourceOptionFlashIfr
enum _ftfx_partition_flexram_load_option ftfx_partition_flexram_load_opt_t
Enumeration for the FlexRAM load during reset option.
int32_t status_t
Type used for all status and error return values.
Definition fsl_common.h:169
state("state", SensorCategory.SENSOR_INPUTS, FieldType.INT8, 1871, 1.0, -1.0, -1.0, "")
Flash driver state information.
Flash Swap information.
ftfx_swap_block_status_t nextSwapBlockStatus
ftfx_swap_state_t flashSwapState
ftfx_swap_block_status_t currentSwapBlockStatus