123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404 |
- /*
- * The Clear BSD License
- * Copyright 2013-2016 Freescale Semiconductor, Inc.
- * Copyright 2016-2018 NXP
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted (subject to the limitations in the
- * disclaimer below) provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
- * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
- * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
- #include "fsl_ftfx_controller.h"
- /*******************************************************************************
- * Definitions
- ******************************************************************************/
- /*!
- * @name Flash controller command numbers
- * @{
- */
- #define FTFx_VERIFY_BLOCK 0x00U /*!< RD1BLK*/
- #define FTFx_VERIFY_SECTION 0x01U /*!< RD1SEC*/
- #define FTFx_PROGRAM_CHECK 0x02U /*!< PGMCHK*/
- #define FTFx_READ_RESOURCE 0x03U /*!< RDRSRC*/
- #define FTFx_PROGRAM_LONGWORD 0x06U /*!< PGM4*/
- #define FTFx_PROGRAM_PHRASE 0x07U /*!< PGM8*/
- #define FTFx_ERASE_BLOCK 0x08U /*!< ERSBLK*/
- #define FTFx_ERASE_SECTOR 0x09U /*!< ERSSCR*/
- #define FTFx_PROGRAM_SECTION 0x0BU /*!< PGMSEC*/
- #define FTFx_GENERATE_CRC 0x0CU /*!< CRCGEN*/
- #define FTFx_VERIFY_ALL_BLOCK 0x40U /*!< RD1ALL*/
- #define FTFx_READ_ONCE 0x41U /*!< RDONCE or RDINDEX*/
- #define FTFx_PROGRAM_ONCE 0x43U /*!< PGMONCE or PGMINDEX*/
- #define FTFx_ERASE_ALL_BLOCK 0x44U /*!< ERSALL*/
- #define FTFx_SECURITY_BY_PASS 0x45U /*!< VFYKEY*/
- #define FTFx_SWAP_CONTROL 0x46U /*!< SWAP*/
- #define FTFx_ERASE_ALL_BLOCK_UNSECURE 0x49U /*!< ERSALLU*/
- #define FTFx_VERIFY_ALL_EXECUTE_ONLY_SEGMENT 0x4AU /*!< RD1XA*/
- #define FTFx_ERASE_ALL_EXECUTE_ONLY_SEGMENT 0x4BU /*!< ERSXA*/
- #define FTFx_PROGRAM_PARTITION 0x80U /*!< PGMPART*/
- #define FTFx_SET_FLEXRAM_FUNCTION 0x81U /*!< SETRAM*/
- /*@}*/
- /*!
- * @brief Constants for execute-in-RAM flash function.
- */
- enum _ftfx_ram_func_constants
- {
- kFTFx_RamFuncMaxSizeInWords = 16U, /*!< The maximum size of execute-in-RAM function.*/
- };
- /*! @brief A function pointer used to point to relocated flash_run_command() */
- typedef void (*callFtfxRunCommand_t)(FTFx_REG8_ACCESS_TYPE ftfx_fstat);
- /*!
- * @name Enumeration for Flash security register code
- * @{
- */
- enum _ftfx_fsec_register_code
- {
- kFTFx_FsecRegCode_KEYEN_Enabled = 0x80U,
- kFTFx_FsecRegCode_SEC_Unsecured = 0x02U
- };
- /*@}*/
- /*!
- * @brief Enumeration for flash config area.
- */
- enum _ftfx_pflash_config_area_range
- {
- kFTFx_PflashConfigAreaStart = 0x400U,
- kFTFx_PflashConfigAreaEnd = 0x40FU
- };
- /*******************************************************************************
- * Prototypes
- ******************************************************************************/
- /*! @brief Init IFR memory related info */
- static status_t ftfx_init_ifr(ftfx_config_t *config);
- #if FTFx_DRIVER_IS_FLASH_RESIDENT
- /*! @brief Copy flash_run_command() to RAM*/
- static void ftfx_copy_run_command_to_ram(uint32_t *ftfxRunCommand);
- #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */
- /*! @brief Internal function Flash command sequence. Called by driver APIs only*/
- static status_t ftfx_command_sequence(ftfx_config_t *config);
- /*! @brief Validates the range and alignment of the given address range.*/
- static status_t ftfx_check_mem_range(ftfx_config_t *config,
- uint32_t startAddress,
- uint32_t lengthInBytes,
- uint8_t alignmentBaseline);
- /*! @brief Validates the given user key for flash erase APIs.*/
- static status_t ftfx_check_user_key(uint32_t key);
- /*! @brief Reads word from byte address.*/
- static uint32_t ftfx_read_word_from_byte_address(const uint8_t *src);
- /*! @brief Writes word to byte address.*/
- static void ftfx_write_word_to_byte_address(uint8_t *dst, uint32_t word);
- #if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD
- /*! @brief Validates the range of the given resource address.*/
- 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);
- #endif /* FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD */
- #if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD
- /*! @brief Validates the gived flexram function option.*/
- static inline status_t ftfx_check_flexram_function_option(ftfx_flexram_func_opt_t option);
- #endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */
- #if defined(FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD) && FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD
- /*! @brief Validates the gived swap control option.*/
- static status_t ftfx_check_swap_control_option(ftfx_swap_control_opt_t option);
- #endif /* FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD */
- /*******************************************************************************
- * Variables
- ******************************************************************************/
- #if FTFx_DRIVER_IS_FLASH_RESIDENT
- /*!
- * @brief Position independent code of flash_run_command()
- *
- * Note1: The prototype of C function is shown as below:
- * @code
- * void flash_run_command(FTFx_REG8_ACCESS_TYPE ftfx_fstat)
- * {
- * // clear CCIF bit
- * *ftfx_fstat = FTFx_FSTAT_CCIF_MASK;
- *
- * // Check CCIF bit of the flash status register, wait till it is set.
- * // IP team indicates that this loop will always complete.
- * while (!((*ftfx_fstat) & FTFx_FSTAT_CCIF_MASK))
- * {
- * }
- * }
- * @endcode
- * Note2: The binary code is generated by IAR 7.70.1
- */
- static const uint16_t s_ftfxRunCommandFunctionCode[] = {
- 0x2180, /* MOVS R1, #128 ; 0x80 */
- 0x7001, /* STRB R1, [R0] */
- /* @4: */
- 0x7802, /* LDRB R2, [R0] */
- 0x420a, /* TST R2, R1 */
- 0xd0fc, /* BEQ.N @4 */
- 0x4770 /* BX LR */
- };
- #if (!FTFx_DRIVER_IS_EXPORTED)
- /*! @brief A static buffer used to hold flash_run_command() */
- static uint32_t s_ftfxRunCommand[kFTFx_RamFuncMaxSizeInWords];
- #endif /* (!FTFx_DRIVER_IS_EXPORTED) */
- #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */
- /*! @brief Access to FTFx Registers */
- static volatile uint32_t *const kFCCOBx = (volatile uint32_t *)&FTFx_FCCOB3_REG;
- #if FSL_FEATURE_FLASH_HAS_FLEX_NVM
- /*! @brief Table of eeprom sizes. */
- static const uint16_t kEepromDensities[16] = {
- FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0000,
- FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0001,
- FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0010,
- FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0011,
- FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0100,
- FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0101,
- FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0110,
- FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0111,
- FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1000,
- FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1001,
- FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1010,
- FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1011,
- FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1100,
- FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1101,
- FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1110,
- FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1111
- };
- /*! @brief Table of dflash sizes. */
- static const uint32_t kDflashDensities[16] = {
- FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0000,
- FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0001,
- FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0010,
- FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0011,
- FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0100,
- FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0101,
- FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0110,
- FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0111,
- FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1000,
- FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1001,
- FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1010,
- FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1011,
- FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1100,
- FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1101,
- FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1110,
- FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1111
- };
- #endif /* FSL_FEATURE_FLASH_HAS_FLEX_NVM */
- /*******************************************************************************
- * Code
- ******************************************************************************/
- status_t FTFx_API_Init(ftfx_config_t *config)
- {
- if (config == NULL)
- {
- return kStatus_FTFx_InvalidArgument;
- }
- config->flexramBlockBase = FSL_FEATURE_FLASH_FLEX_RAM_START_ADDRESS;
- config->flexramTotalSize = FSL_FEATURE_FLASH_FLEX_RAM_SIZE;
- /* copy required flash command to RAM */
- #if FTFx_DRIVER_IS_FLASH_RESIDENT
- if (NULL == config->runCmdFuncAddr)
- {
- #if FTFx_DRIVER_IS_EXPORTED
- return kStatus_FTFx_ExecuteInRamFunctionNotReady;
- #else
- config->runCmdFuncAddr = s_ftfxRunCommand;
- #endif /* FTFx_DRIVER_IS_EXPORTED */
- }
- ftfx_copy_run_command_to_ram(config->runCmdFuncAddr);
- #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */
- ftfx_init_ifr(config);
- return kStatus_FTFx_Success;
- }
- #if FSL_FEATURE_FLASH_HAS_FLEX_NVM
- status_t FTFx_API_UpdateFlexnvmPartitionStatus(ftfx_config_t *config)
- {
- struct _dflash_ifr_field_config
- {
- uint32_t reserved0;
- uint8_t FlexNVMPartitionCode;
- uint8_t EEPROMDataSetSize;
- uint16_t reserved1;
- } dataIFRReadOut;
- uint32_t flexnvmInfoIfrAddr;
- status_t returnCode;
- if (config == NULL)
- {
- return kStatus_FTFx_InvalidArgument;
- }
- flexnvmInfoIfrAddr = config->ifrDesc.resRange.dflashIfrStart + config->ifrDesc.resRange.ifrMemSize - sizeof(dataIFRReadOut);
- #if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD
- /* Get FlexNVM memory partition info from data flash IFR */
- returnCode = FTFx_CMD_ReadResource(config, flexnvmInfoIfrAddr, (uint8_t *)&dataIFRReadOut,
- sizeof(dataIFRReadOut), kFTFx_ResourceOptionFlashIfr);
- if (returnCode != kStatus_FTFx_Success)
- {
- return kStatus_FTFx_PartitionStatusUpdateFailure;
- }
- #else
- #error "Cannot get FlexNVM memory partition info"
- #endif
- /* Fill out partitioned EEPROM size */
- dataIFRReadOut.EEPROMDataSetSize &= 0x0FU;
- config->eepromTotalSize = kEepromDensities[dataIFRReadOut.EEPROMDataSetSize];
- /* Fill out partitioned DFlash size */
- dataIFRReadOut.FlexNVMPartitionCode &= 0x0FU;
- config->flashDesc.totalSize = kDflashDensities[dataIFRReadOut.FlexNVMPartitionCode];
- return kStatus_FTFx_Success;
- }
- #endif /* FSL_FEATURE_FLASH_HAS_FLEX_NVM */
- status_t FTFx_CMD_Erase(ftfx_config_t *config,
- uint32_t start,
- uint32_t lengthInBytes,
- uint32_t key)
- {
- uint32_t sectorSize;
- uint32_t endAddress; /* storing end address */
- uint32_t numberOfSectors; /* number of sectors calculated by endAddress */
- status_t returnCode;
- /* Check the supplied address range. */
- returnCode = ftfx_check_mem_range(config, start, lengthInBytes, config->opsConfig.addrAligment.sectorCmd);
- if (returnCode)
- {
- return returnCode;
- }
- /* Validate the user key */
- returnCode = ftfx_check_user_key(key);
- if (returnCode)
- {
- return returnCode;
- }
- start = config->opsConfig.convertedAddress;
- sectorSize = config->flashDesc.sectorSize;
- /* calculating Flash end address */
- endAddress = start + lengthInBytes - 1;
- /* re-calculate the endAddress and align it to the start of the next sector
- * which will be used in the comparison below */
- if (endAddress % sectorSize)
- {
- numberOfSectors = endAddress / sectorSize + 1;
- endAddress = numberOfSectors * sectorSize - 1;
- }
- /* the start address will increment to the next sector address
- * until it reaches the endAdddress */
- while (start <= endAddress)
- {
- /* preparing passing parameter to erase a flash block */
- kFCCOBx[0] = BYTE2WORD_1_3(FTFx_ERASE_SECTOR, start);
- /* calling flash command sequence function to execute the command */
- returnCode = ftfx_command_sequence(config);
- /* checking the success of command execution */
- if (kStatus_FTFx_Success != returnCode)
- {
- break;
- }
- else
- {
- /* Increment to the next sector */
- start += sectorSize;
- }
- }
- return (returnCode);
- }
- status_t FTFx_CMD_EraseAll(ftfx_config_t *config, uint32_t key)
- {
- status_t returnCode;
- if (config == NULL)
- {
- return kStatus_FTFx_InvalidArgument;
- }
- /* preparing passing parameter to erase all flash blocks */
- kFCCOBx[0] = BYTE2WORD_1_3(FTFx_ERASE_ALL_BLOCK, 0xFFFFFFU);
- /* Validate the user key */
- returnCode = ftfx_check_user_key(key);
- if (returnCode)
- {
- return returnCode;
- }
- /* calling flash command sequence function to execute the command */
- returnCode = ftfx_command_sequence(config);
- #if FSL_FEATURE_FLASH_HAS_FLEX_NVM
- /* Data flash IFR will be erased by erase all command, so we need to
- * update FlexNVM memory partition status synchronously */
- if (returnCode == kStatus_FTFx_Success)
- {
- returnCode = FTFx_API_UpdateFlexnvmPartitionStatus(config);
- }
- #endif
- return returnCode;
- }
- #if defined(FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD) && FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD
- status_t FTFx_CMD_EraseAllUnsecure(ftfx_config_t *config, uint32_t key)
- {
- status_t returnCode;
- if (config == NULL)
- {
- return kStatus_FTFx_InvalidArgument;
- }
- /* Prepare passing parameter to erase all flash blocks (unsecure). */
- kFCCOBx[0] = BYTE2WORD_1_3(FTFx_ERASE_ALL_BLOCK_UNSECURE, 0xFFFFFFU);
- /* Validate the user key */
- returnCode = ftfx_check_user_key(key);
- if (returnCode)
- {
- return returnCode;
- }
- /* calling flash command sequence function to execute the command */
- returnCode = ftfx_command_sequence(config);
- #if FSL_FEATURE_FLASH_HAS_FLEX_NVM
- /* Data flash IFR will be erased by erase all unsecure command, so we need to
- * update FlexNVM memory partition status synchronously */
- if (returnCode == kStatus_FTFx_Success)
- {
- returnCode = FTFx_API_UpdateFlexnvmPartitionStatus(config);
- }
- #endif
- return returnCode;
- }
- #endif /* FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD */
- status_t FTFx_CMD_EraseAllExecuteOnlySegments(ftfx_config_t *config, uint32_t key)
- {
- status_t returnCode;
- if (config == NULL)
- {
- return kStatus_FTFx_InvalidArgument;
- }
- /* preparing passing parameter to erase all execute-only segments
- * 1st element for the FCCOB register */
- kFCCOBx[0] = BYTE2WORD_1_3(FTFx_ERASE_ALL_EXECUTE_ONLY_SEGMENT, 0xFFFFFFU);
- /* Validate the user key */
- returnCode = ftfx_check_user_key(key);
- if (returnCode)
- {
- return returnCode;
- }
- /* calling flash command sequence function to execute the command */
- returnCode = ftfx_command_sequence(config);
- return returnCode;
- }
- status_t FTFx_CMD_Program(ftfx_config_t *config,
- uint32_t start,
- uint8_t *src,
- uint32_t lengthInBytes)
- {
- status_t returnCode;
- uint8_t blockWriteUnitSize = config->opsConfig.addrAligment.blockWriteUnitSize;
- if (src == NULL)
- {
- return kStatus_FTFx_InvalidArgument;
- }
- /* Check the supplied address range. */
- returnCode = ftfx_check_mem_range(config, start, lengthInBytes, blockWriteUnitSize);
- if (returnCode)
- {
- return returnCode;
- }
- start = config->opsConfig.convertedAddress;
- while (lengthInBytes > 0)
- {
- /* preparing passing parameter to program the flash block */
- kFCCOBx[1] = ftfx_read_word_from_byte_address((const uint8_t*)src);
- src += 4;
- if (4 == blockWriteUnitSize)
- {
- kFCCOBx[0] = BYTE2WORD_1_3(FTFx_PROGRAM_LONGWORD, start);
- }
- else if (8 == blockWriteUnitSize)
- {
- kFCCOBx[2] = ftfx_read_word_from_byte_address((const uint8_t*)src);
- src += 4;
- kFCCOBx[0] = BYTE2WORD_1_3(FTFx_PROGRAM_PHRASE, start);
- }
- else
- {
- }
- /* calling flash command sequence function to execute the command */
- returnCode = ftfx_command_sequence(config);
- /* checking for the success of command execution */
- if (kStatus_FTFx_Success != returnCode)
- {
- break;
- }
- else
- {
- /* update start address for next iteration */
- start += blockWriteUnitSize;
- /* update lengthInBytes for next iteration */
- lengthInBytes -= blockWriteUnitSize;
- }
- }
- return (returnCode);
- }
- status_t FTFx_CMD_ProgramOnce(ftfx_config_t *config, uint32_t index, uint8_t *src, uint32_t lengthInBytes)
- {
- status_t returnCode;
- if ((config == NULL) || (src == NULL))
- {
- return kStatus_FTFx_InvalidArgument;
- }
- /* pass paramters to FTFx */
- kFCCOBx[0] = BYTE2WORD_1_1_2(FTFx_PROGRAM_ONCE, index, 0xFFFFU);
- kFCCOBx[1] = ftfx_read_word_from_byte_address((const uint8_t*)src);
- /* Note: Have to seperate the first index from the rest if it equals 0
- * to avoid a pointless comparison of unsigned int to 0 compiler warning */
- if (config->ifrDesc.feature.has8ByteIdxSupport)
- {
- if (config->ifrDesc.feature.has4ByteIdxSupport)
- {
- if (((index == config->ifrDesc.idxInfo.mix8byteIdxStart) ||
- ((index >= config->ifrDesc.idxInfo.mix8byteIdxStart + 1) && (index <= config->ifrDesc.idxInfo.mix8byteIdxStart))) &&
- (lengthInBytes == 8))
- {
- kFCCOBx[2] = ftfx_read_word_from_byte_address((const uint8_t*)src + 4);
- }
- }
- else
- {
- kFCCOBx[2] = ftfx_read_word_from_byte_address((const uint8_t*)src + 4);
- }
- }
- /* calling flash command sequence function to execute the command */
- returnCode = ftfx_command_sequence(config);
- return returnCode;
- }
- #if defined(FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD) && FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD
- status_t FTFx_CMD_ProgramSection(ftfx_config_t *config,
- uint32_t start,
- uint8_t *src,
- uint32_t lengthInBytes)
- {
- status_t returnCode;
- uint32_t sectorSize;
- uint8_t aligmentInBytes = config->opsConfig.addrAligment.sectionCmd;
- #if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD
- bool needSwitchFlexRamMode = false;
- #endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */
- if (src == NULL)
- {
- return kStatus_FTFx_InvalidArgument;
- }
- /* Check the supplied address range. */
- returnCode = ftfx_check_mem_range(config, start, lengthInBytes, aligmentInBytes);
- if (returnCode)
- {
- return returnCode;
- }
- start = config->opsConfig.convertedAddress;
- sectorSize = config->flashDesc.sectorSize;
- #if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD
- /* Switch function of FlexRAM if needed */
- if (!(FTFx->FCNFG & FTFx_FCNFG_RAMRDY_MASK))
- {
- needSwitchFlexRamMode = true;
- returnCode = FTFx_CMD_SetFlexramFunction(config, kFTFx_FlexramFuncOptAvailableAsRam);
- if (returnCode != kStatus_FTFx_Success)
- {
- return kStatus_FTFx_SetFlexramAsRamError;
- }
- }
- #endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */
- while (lengthInBytes > 0)
- {
- /* Make sure the write operation doesn't span two sectors */
- uint32_t endAddressOfCurrentSector = ALIGN_UP(start, sectorSize);
- uint32_t lengthTobeProgrammedOfCurrentSector;
- uint32_t currentOffset = 0;
- if (endAddressOfCurrentSector == start)
- {
- endAddressOfCurrentSector += sectorSize;
- }
- if (lengthInBytes + start > endAddressOfCurrentSector)
- {
- lengthTobeProgrammedOfCurrentSector = endAddressOfCurrentSector - start;
- }
- else
- {
- lengthTobeProgrammedOfCurrentSector = lengthInBytes;
- }
- /* Program Current Sector */
- while (lengthTobeProgrammedOfCurrentSector > 0)
- {
- /* Make sure the program size doesn't exceeds Acceleration RAM size */
- uint32_t programSizeOfCurrentPass;
- uint32_t numberOfPhases;
- if (lengthTobeProgrammedOfCurrentSector > config->flexramTotalSize)
- {
- programSizeOfCurrentPass = config->flexramTotalSize;
- }
- else
- {
- programSizeOfCurrentPass = lengthTobeProgrammedOfCurrentSector;
- }
- /* Copy data to FlexRAM */
- memcpy((void *)config->flexramBlockBase, src + currentOffset, programSizeOfCurrentPass);
- /* Set start address of the data to be programmed */
- kFCCOBx[0] = BYTE2WORD_1_3(FTFx_PROGRAM_SECTION, start + currentOffset);
- /* Set program size in terms of FEATURE_FLASH_SECTION_CMD_ADDRESS_ALIGMENT */
- numberOfPhases = programSizeOfCurrentPass / aligmentInBytes;
- kFCCOBx[1] = BYTE2WORD_2_2(numberOfPhases, 0xFFFFU);
- /* Peform command sequence */
- returnCode = ftfx_command_sequence(config);
- if (returnCode != kStatus_FTFx_Success)
- {
- return returnCode;
- }
- lengthTobeProgrammedOfCurrentSector -= programSizeOfCurrentPass;
- currentOffset += programSizeOfCurrentPass;
- }
- src += currentOffset;
- start += currentOffset;
- lengthInBytes -= currentOffset;
- }
- #if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD
- /* Restore function of FlexRAM if needed. */
- if (needSwitchFlexRamMode)
- {
- returnCode = FTFx_CMD_SetFlexramFunction(config, kFTFx_FlexramFuncOptAvailableForEeprom);
- if (returnCode != kStatus_FTFx_Success)
- {
- return kStatus_FTFx_RecoverFlexramAsEepromError;
- }
- }
- #endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */
- return returnCode;
- }
- #endif /* FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD */
- #if defined(FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD) && FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD
- status_t FTFx_CMD_ProgramPartition(ftfx_config_t *config,
- ftfx_partition_flexram_load_opt_t option,
- uint32_t eepromDataSizeCode,
- uint32_t flexnvmPartitionCode)
- {
- status_t returnCode;
- if (config == NULL)
- {
- return kStatus_FTFx_InvalidArgument;
- }
- /* eepromDataSizeCode[7:6], flexnvmPartitionCode[7:4] should be all 1'b0
- * or it will cause access error. */
- /* eepromDataSizeCode &= 0x3FU; */
- /* flexnvmPartitionCode &= 0x0FU; */
- /* preparing passing parameter to program the flash block */
- kFCCOBx[0] = BYTE2WORD_1_2_1(FTFx_PROGRAM_PARTITION, 0xFFFFU, option);
- kFCCOBx[1] = BYTE2WORD_1_1_2(eepromDataSizeCode, flexnvmPartitionCode, 0xFFFFU);
- /* calling flash command sequence function to execute the command */
- returnCode = ftfx_command_sequence(config);
- #if FSL_FEATURE_FLASH_HAS_FLEX_NVM
- /* Data flash IFR will be updated by program partition command during reset sequence,
- * so we just set reserved values for partitioned FlexNVM size here */
- config->eepromTotalSize = 0xFFFFU;
- config->flashDesc.totalSize = 0xFFFFFFFFU;
- #endif
- return (returnCode);
- }
- #endif /* FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD */
- status_t FTFx_CMD_ReadOnce(ftfx_config_t *config, uint32_t index, uint8_t *dst, uint32_t lengthInBytes)
- {
- status_t returnCode;
- if ((config == NULL) || (dst == NULL))
- {
- return kStatus_FTFx_InvalidArgument;
- }
- /* pass paramters to FTFx */
- kFCCOBx[0] = BYTE2WORD_1_1_2(FTFx_READ_ONCE, index, 0xFFFFU);
- /* calling flash command sequence function to execute the command */
- returnCode = ftfx_command_sequence(config);
- if (kStatus_FTFx_Success == returnCode)
- {
- ftfx_write_word_to_byte_address(dst, kFCCOBx[1]);
- /* Note: Have to seperate the first index from the rest if it equals 0
- * to avoid a pointless comparison of unsigned int to 0 compiler warning */
- if (config->ifrDesc.feature.has8ByteIdxSupport)
- {
- if (config->ifrDesc.feature.has4ByteIdxSupport)
- {
- if (((index == config->ifrDesc.idxInfo.mix8byteIdxStart) ||
- ((index >= config->ifrDesc.idxInfo.mix8byteIdxStart + 1) && (index <= config->ifrDesc.idxInfo.mix8byteIdxStart))) &&
- (lengthInBytes == 8))
- {
- ftfx_write_word_to_byte_address(dst + 4, kFCCOBx[2]);
- }
- }
- else
- {
- ftfx_write_word_to_byte_address(dst + 4, kFCCOBx[2]);
- }
- }
- }
- return returnCode;
- }
- #if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD
- status_t FTFx_CMD_ReadResource(ftfx_config_t *config,
- uint32_t start,
- uint8_t *dst,
- uint32_t lengthInBytes,
- ftfx_read_resource_opt_t option)
- {
- status_t returnCode;
- if ((config == NULL) || (dst == NULL))
- {
- return kStatus_FTFx_InvalidArgument;
- }
- uint8_t aligmentInBytes = config->opsConfig.addrAligment.resourceCmd;
- /* Check the supplied address range. */
- returnCode = ftfx_check_resource_range(config, start, lengthInBytes, aligmentInBytes, option);
- if (returnCode != kStatus_FTFx_Success)
- {
- return returnCode;
- }
- while (lengthInBytes > 0)
- {
- /* preparing passing parameter */
- kFCCOBx[0] = BYTE2WORD_1_3(FTFx_READ_RESOURCE, start);
- if (aligmentInBytes == 4)
- {
- kFCCOBx[2] = BYTE2WORD_1_3(option, 0xFFFFFFU);
- }
- else if (aligmentInBytes == 8)
- {
- kFCCOBx[1] = BYTE2WORD_1_3(option, 0xFFFFFFU);
- }
- else
- {
- }
- /* calling flash command sequence function to execute the command */
- returnCode = ftfx_command_sequence(config);
- if (kStatus_FTFx_Success != returnCode)
- {
- break;
- }
- /* fetch data */
- ftfx_write_word_to_byte_address(dst, kFCCOBx[1]);
- dst += 4;
- if (aligmentInBytes == 8)
- {
- ftfx_write_word_to_byte_address(dst, kFCCOBx[2]);
- dst += 4;
- }
- /* update start address for next iteration */
- start += aligmentInBytes;
- /* update lengthInBytes for next iteration */
- lengthInBytes -= aligmentInBytes;
- }
- return (returnCode);
- }
- #endif /* FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD */
- status_t FTFx_CMD_VerifyErase(ftfx_config_t *config,
- uint32_t start,
- uint32_t lengthInBytes,
- ftfx_margin_value_t margin)
- {
- /* Check arguments. */
- uint32_t blockSize;
- uint32_t nextBlockStartAddress;
- uint32_t remainingBytes;
- uint8_t aligmentInBytes = config->opsConfig.addrAligment.sectionCmd;
- status_t returnCode;
- returnCode = ftfx_check_mem_range(config, start, lengthInBytes, aligmentInBytes);
- if (returnCode)
- {
- return returnCode;
- }
- start = config->opsConfig.convertedAddress;
- blockSize = config->flashDesc.totalSize / config->flashDesc.blockCount;
- nextBlockStartAddress = ALIGN_UP(start, blockSize);
- if (nextBlockStartAddress == start)
- {
- nextBlockStartAddress += blockSize;
- }
- remainingBytes = lengthInBytes;
- while (remainingBytes)
- {
- uint32_t numberOfPhrases;
- uint32_t verifyLength = nextBlockStartAddress - start;
- if (verifyLength > remainingBytes)
- {
- verifyLength = remainingBytes;
- }
- numberOfPhrases = verifyLength / aligmentInBytes;
- /* Fill in verify section command parameters. */
- kFCCOBx[0] = BYTE2WORD_1_3(FTFx_VERIFY_SECTION, start);
- kFCCOBx[1] = BYTE2WORD_2_1_1(numberOfPhrases, margin, 0xFFU);
- /* calling flash command sequence function to execute the command */
- returnCode = ftfx_command_sequence(config);
- if (returnCode)
- {
- return returnCode;
- }
- remainingBytes -= verifyLength;
- start += verifyLength;
- nextBlockStartAddress += blockSize;
- }
- return kStatus_FTFx_Success;
- }
- status_t FTFx_CMD_VerifyEraseAll(ftfx_config_t *config, ftfx_margin_value_t margin)
- {
- if (config == NULL)
- {
- return kStatus_FTFx_InvalidArgument;
- }
- /* preparing passing parameter to verify all block command */
- kFCCOBx[0] = BYTE2WORD_1_1_2(FTFx_VERIFY_ALL_BLOCK, margin, 0xFFFFU);
- /* calling flash command sequence function to execute the command */
- return ftfx_command_sequence(config);
- }
- status_t FTFx_CMD_VerifyEraseAllExecuteOnlySegments(ftfx_config_t *config, ftfx_margin_value_t margin)
- {
- if (config == NULL)
- {
- return kStatus_FTFx_InvalidArgument;
- }
- /* preparing passing parameter to verify erase all execute-only segments command */
- kFCCOBx[0] = BYTE2WORD_1_1_2(FTFx_VERIFY_ALL_EXECUTE_ONLY_SEGMENT, margin, 0xFFFFU);
- /* calling flash command sequence function to execute the command */
- return ftfx_command_sequence(config);
- }
- 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)
- {
- status_t returnCode;
- uint8_t aligmentInBytes = config->opsConfig.addrAligment.checkCmd;
- if (expectedData == NULL)
- {
- return kStatus_FTFx_InvalidArgument;
- }
- returnCode = ftfx_check_mem_range(config, start, lengthInBytes, aligmentInBytes);
- if (returnCode)
- {
- return returnCode;
- }
- start = config->opsConfig.convertedAddress;
- while (lengthInBytes)
- {
- /* preparing passing parameter to program check the flash block */
- kFCCOBx[0] = BYTE2WORD_1_3(FTFx_PROGRAM_CHECK, start);
- kFCCOBx[1] = BYTE2WORD_1_3(margin, 0xFFFFFFU);
- kFCCOBx[2] = ftfx_read_word_from_byte_address((const uint8_t*)expectedData);
- /* calling flash command sequence function to execute the command */
- returnCode = ftfx_command_sequence(config);
- /* checking for the success of command execution */
- if (kStatus_FTFx_Success != returnCode)
- {
- if (failedAddress)
- {
- *failedAddress = start;
- }
- if (failedData)
- {
- *failedData = 0;
- }
- break;
- }
- lengthInBytes -= aligmentInBytes;
- expectedData += aligmentInBytes;
- start += aligmentInBytes;
- }
- return (returnCode);
- }
- status_t FTFx_CMD_SecurityBypass(ftfx_config_t *config, const uint8_t *backdoorKey)
- {
- uint8_t registerValue; /* registerValue */
- status_t returnCode; /* return code variable */
- if ((config == NULL) || (backdoorKey == NULL))
- {
- return kStatus_FTFx_InvalidArgument;
- }
- /* set the default return code as kStatus_Success */
- returnCode = kStatus_FTFx_Success;
- /* Get flash security register value */
- registerValue = FTFx->FSEC;
- /* Check to see if flash is in secure state (any state other than 0x2)
- * If not, then skip this since flash is not secure */
- if (0x02 != (registerValue & 0x03))
- {
- /* preparing passing parameter to erase a flash block */
- kFCCOBx[0] = BYTE2WORD_1_3(FTFx_SECURITY_BY_PASS, 0xFFFFFFU);
- kFCCOBx[1] = BYTE2WORD_1_1_1_1(backdoorKey[0], backdoorKey[1], backdoorKey[2], backdoorKey[3]);
- kFCCOBx[2] = BYTE2WORD_1_1_1_1(backdoorKey[4], backdoorKey[5], backdoorKey[6], backdoorKey[7]);
- /* calling flash command sequence function to execute the command */
- returnCode = ftfx_command_sequence(config);
- }
- return (returnCode);
- }
- status_t FTFx_REG_GetSecurityState(ftfx_config_t *config, ftfx_security_state_t *state)
- {
- /* store data read from flash register */
- uint8_t registerValue;
- if ((config == NULL) || (state == NULL))
- {
- return kStatus_FTFx_InvalidArgument;
- }
- /* Get flash security register value */
- registerValue = FTFx->FSEC;
- /* check the status of the flash security bits in the security register */
- if (kFTFx_FsecRegCode_SEC_Unsecured == (registerValue & FTFx_FSEC_SEC_MASK))
- {
- /* Flash in unsecured state */
- *state = kFTFx_SecurityStateNotSecure;
- }
- else
- {
- /* Flash in secured state
- * check for backdoor key security enable bit */
- if (kFTFx_FsecRegCode_KEYEN_Enabled == (registerValue & FTFx_FSEC_KEYEN_MASK))
- {
- /* Backdoor key security enabled */
- *state = kFTFx_SecurityStateBackdoorEnabled;
- }
- else
- {
- /* Backdoor key security disabled */
- *state = kFTFx_SecurityStateBackdoorDisabled;
- }
- }
- return (kStatus_FTFx_Success);
- }
- #if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD
- status_t FTFx_CMD_SetFlexramFunction(ftfx_config_t *config, ftfx_flexram_func_opt_t option)
- {
- status_t status;
- if (config == NULL)
- {
- return kStatus_FTFx_InvalidArgument;
- }
- status = ftfx_check_flexram_function_option(option);
- if (status != kStatus_FTFx_Success)
- {
- return status;
- }
- /* preparing passing parameter to verify all block command */
- kFCCOBx[0] = BYTE2WORD_1_1_2(FTFx_SET_FLEXRAM_FUNCTION, option, 0xFFFFU);
- /* calling flash command sequence function to execute the command */
- return ftfx_command_sequence(config);
- }
- #endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */
- #if defined(FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD) && FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD
- status_t FTFx_CMD_SwapControl(ftfx_config_t *config,
- uint32_t address,
- ftfx_swap_control_opt_t option,
- ftfx_swap_state_config_t *returnInfo)
- {
- status_t returnCode;
- if ((config == NULL) || (returnInfo == NULL))
- {
- return kStatus_FTFx_InvalidArgument;
- }
- if (address & (FSL_FEATURE_FLASH_PFLASH_SWAP_CONTROL_CMD_ADDRESS_ALIGMENT - 1))
- {
- return kStatus_FTFx_AlignmentError;
- }
- /* Make sure address provided is in the lower half of Program flash but not in the Flash Configuration Field */
- if ((address >= (config->flashDesc.totalSize / 2)) ||
- ((address >= kFTFx_PflashConfigAreaStart) && (address <= kFTFx_PflashConfigAreaEnd)))
- {
- return kStatus_FTFx_SwapIndicatorAddressError;
- }
- /* Check the option. */
- returnCode = ftfx_check_swap_control_option(option);
- if (returnCode)
- {
- return returnCode;
- }
- kFCCOBx[0] = BYTE2WORD_1_3(FTFx_SWAP_CONTROL, address);
- kFCCOBx[1] = BYTE2WORD_1_3(option, 0xFFFFFFU);
- returnCode = ftfx_command_sequence(config);
- returnInfo->flashSwapState = (ftfx_swap_state_t)FTFx_FCCOB5_REG;
- returnInfo->currentSwapBlockStatus = (ftfx_swap_block_status_t)FTFx_FCCOB6_REG;
- returnInfo->nextSwapBlockStatus = (ftfx_swap_block_status_t)FTFx_FCCOB7_REG;
- return returnCode;
- }
- #endif /* FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD */
- static status_t ftfx_init_ifr(ftfx_config_t *config)
- {
- if (config == NULL)
- {
- return kStatus_FTFx_InvalidArgument;
- }
- #if FSL_FEATURE_FLASH_IS_FTFA
- /* FTFA parts(eg. K80, KL80, L5K) support both 4-bytes and 8-bytes unit size */
- config->ifrDesc.feature.has4ByteIdxSupport = 1;
- config->ifrDesc.feature.has8ByteIdxSupport = 1;
- config->ifrDesc.idxInfo.mix8byteIdxStart = 0x10U;
- config->ifrDesc.idxInfo.mix8byteIdxEnd = 0x13U;
- #elif FSL_FEATURE_FLASH_IS_FTFE
- /* FTFE parts(eg. K65, KE18) only support 8-bytes unit size */
- config->ifrDesc.feature.has4ByteIdxSupport = 0;
- config->ifrDesc.feature.has8ByteIdxSupport = 1;
- #elif FSL_FEATURE_FLASH_IS_FTFL
- /* FTFL parts(eg. K20) only support 4-bytes unit size */
- config->ifrDesc.feature.has4ByteIdxSupport = 1;
- config->ifrDesc.feature.has8ByteIdxSupport = 0;
- #endif
- config->ifrDesc.resRange.pflashIfrStart = 0x0000U;
- config->ifrDesc.resRange.versionIdSize = 0x08U;
- #if FSL_FEATURE_FLASH_IS_FTFE
- config->ifrDesc.resRange.versionIdStart = 0x08U;
- config->ifrDesc.resRange.ifrMemSize = 0x0400U;
- #else /* FSL_FEATURE_FLASH_IS_FTFL == 1 or FSL_FEATURE_FLASH_IS_FTFA = =1 */
- config->ifrDesc.resRange.versionIdStart = 0x00U;
- config->ifrDesc.resRange.ifrMemSize = 0x0100U;
- #endif
- #if FSL_FEATURE_FLASH_HAS_FLEX_NVM
- config->ifrDesc.resRange.dflashIfrStart = 0x800000U;
- #endif
- #if FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD
- #if FSL_FEATURE_FLASH_IS_FTFE
- config->ifrDesc.resRange.pflashSwapIfrStart = 0x40000U;
- #else /* FSL_FEATURE_FLASH_IS_FTFL == 1 or FSL_FEATURE_FLASH_IS_FTFA == 1 */
- config->ifrDesc.resRange.pflashSwapIfrStart = config->flashDesc.totalSize / 4;
- #endif
- #endif /* FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD */
- return kStatus_FTFx_Success;
- }
- #if FTFx_DRIVER_IS_FLASH_RESIDENT
- /*!
- * @brief Copy PIC of flash_run_command() to RAM
- */
- static void ftfx_copy_run_command_to_ram(uint32_t *ftfxRunCommand)
- {
- assert(sizeof(s_ftfxRunCommandFunctionCode) <= (kFTFx_RamFuncMaxSizeInWords * 4));
- /* Since the value of ARM function pointer is always odd, but the real start address
- * of function memory should be even, that's why +1 operation exist. */
- memcpy((uint8_t *)ftfxRunCommand, (const uint8_t *)s_ftfxRunCommandFunctionCode, sizeof(s_ftfxRunCommandFunctionCode));
- }
- #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */
- /*!
- * @brief FTFx Command Sequence
- *
- * This function is used to perform the command write sequence to the flash.
- *
- * @param driver Pointer to storage for the driver runtime state.
- * @return An error code or kStatus_FTFx_Success
- */
- static status_t ftfx_command_sequence(ftfx_config_t *config)
- {
- uint8_t registerValue;
- #if FTFx_DRIVER_IS_FLASH_RESIDENT
- /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register */
- FTFx->FSTAT = FTFx_FSTAT_RDCOLERR_MASK | FTFx_FSTAT_ACCERR_MASK | FTFx_FSTAT_FPVIOL_MASK;
- /* Since the value of ARM function pointer is always odd, but the real start address
- * of function memory should be even, that's why +1 operation exist. */
- callFtfxRunCommand_t callFtfxRunCommand = (callFtfxRunCommand_t)((uint32_t)config->runCmdFuncAddr + 1);
- /* We pass the ftfx_fstat address as a parameter to flash_run_comamnd() instead of using
- * pre-processed MICRO sentences or operating global variable in flash_run_comamnd()
- * to make sure that flash_run_command() will be compiled into position-independent code (PIC). */
- callFtfxRunCommand((FTFx_REG8_ACCESS_TYPE)(&FTFx->FSTAT));
- #else
- /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register */
- FTFx->FSTAT = FTFx_FSTAT_RDCOLERR_MASK | FTFx_FSTAT_ACCERR_MASK | FTFx_FSTAT_FPVIOL_MASK;
- /* clear CCIF bit */
- FTFx->FSTAT = FTFx_FSTAT_CCIF_MASK;
- /* Check CCIF bit of the flash status register, wait till it is set.
- * IP team indicates that this loop will always complete. */
- while (!(FTFx->FSTAT & FTFx_FSTAT_CCIF_MASK))
- {
- }
- #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */
- /* Check error bits */
- /* Get flash status register value */
- registerValue = FTFx->FSTAT;
- /* checking access error */
- if (registerValue & FTFx_FSTAT_ACCERR_MASK)
- {
- return kStatus_FTFx_AccessError;
- }
- /* checking protection error */
- else if (registerValue & FTFx_FSTAT_FPVIOL_MASK)
- {
- return kStatus_FTFx_ProtectionViolation;
- }
- /* checking MGSTAT0 non-correctable error */
- else if (registerValue & FTFx_FSTAT_MGSTAT0_MASK)
- {
- return kStatus_FTFx_CommandFailure;
- }
- else
- {
- return kStatus_FTFx_Success;
- }
- }
- /*! @brief Validates the range and alignment of the given address range.*/
- static status_t ftfx_check_mem_range(ftfx_config_t *config,
- uint32_t startAddress,
- uint32_t lengthInBytes,
- uint8_t alignmentBaseline)
- {
- if (config == NULL)
- {
- return kStatus_FTFx_InvalidArgument;
- }
- /* Verify the start and length are alignmentBaseline aligned. */
- if ((startAddress & (alignmentBaseline - 1)) || (lengthInBytes & (alignmentBaseline - 1)))
- {
- return kStatus_FTFx_AlignmentError;
- }
- /* check for valid range of the target addresses */
- if ((startAddress >= config->flashDesc.blockBase) &&
- ((startAddress + lengthInBytes) <= (config->flashDesc.blockBase + config->flashDesc.totalSize)))
- {
- return kStatus_FTFx_Success;
- }
- return kStatus_FTFx_AddressError;
- }
- /*! @brief Validates the given user key for flash erase APIs.*/
- static status_t ftfx_check_user_key(uint32_t key)
- {
- /* Validate the user key */
- if (key != kFTFx_ApiEraseKey)
- {
- return kStatus_FTFx_EraseKeyError;
- }
- return kStatus_FTFx_Success;
- }
- /*! @brief Reads word from byte address.*/
- static uint32_t ftfx_read_word_from_byte_address(const uint8_t *src)
- {
- uint32_t word = 0;
- if (!((uint32_t)src % 4))
- {
- word = *(const uint32_t *)src;
- }
- else
- {
- for (uint32_t i = 0; i < 4; i++)
- {
- word |= (uint32_t)(*src) << (i * 8);
- src++;
- }
- }
- return word;
- }
- /*! @brief Writes word to byte address.*/
- static void ftfx_write_word_to_byte_address(uint8_t *dst, uint32_t word)
- {
- if (!((uint32_t)dst % 4))
- {
- *(uint32_t *)dst = word;
- }
- else
- {
- for (uint32_t i = 0; i < 4; i++)
- {
- *dst = (uint8_t)((word >> (i * 8)) & 0xFFU);
- dst++;
- }
- }
- }
- #if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD
- /*! @brief Validates the range of the given resource address.*/
- 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)
- {
- status_t status;
- uint32_t maxReadbleAddress;
- if ((start & (alignmentBaseline - 1)) || (lengthInBytes & (alignmentBaseline - 1)))
- {
- return kStatus_FTFx_AlignmentError;
- }
- status = kStatus_FTFx_Success;
- maxReadbleAddress = start + lengthInBytes - 1;
- if (option == kFTFx_ResourceOptionVersionId)
- {
- if ((start != config->ifrDesc.resRange.versionIdStart) ||
- (lengthInBytes != config->ifrDesc.resRange.versionIdSize))
- {
- status = kStatus_FTFx_InvalidArgument;
- }
- }
- else if (option == kFTFx_ResourceOptionFlashIfr)
- {
- if ((start >= config->ifrDesc.resRange.pflashIfrStart) &&
- (maxReadbleAddress < (config->ifrDesc.resRange.pflashIfrStart + config->ifrDesc.resRange.ifrMemSize)))
- {
- }
- #if FSL_FEATURE_FLASH_HAS_FLEX_NVM
- else if ((start >= config->ifrDesc.resRange.dflashIfrStart) &&
- (maxReadbleAddress < (config->ifrDesc.resRange.dflashIfrStart + config->ifrDesc.resRange.ifrMemSize)))
- {
- }
- #endif
- #if FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD
- else if ((start >= config->ifrDesc.resRange.pflashSwapIfrStart) &&
- (maxReadbleAddress < (config->ifrDesc.resRange.pflashSwapIfrStart + config->ifrDesc.resRange.ifrMemSize)))
- {
- }
- #endif
- else
- {
- status = kStatus_FTFx_InvalidArgument;
- }
- }
- else
- {
- status = kStatus_FTFx_InvalidArgument;
- }
- return status;
- }
- #endif /* FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD */
- #if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD
- /*! @brief Validates the gived flexram function option.*/
- static inline status_t ftfx_check_flexram_function_option(ftfx_flexram_func_opt_t option)
- {
- if ((option != kFTFx_FlexramFuncOptAvailableAsRam) &&
- (option != kFTFx_FlexramFuncOptAvailableForEeprom))
- {
- return kStatus_FTFx_InvalidArgument;
- }
- return kStatus_FTFx_Success;
- }
- #endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */
- #if defined(FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD) && FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD
- /*! @brief Validates the gived swap control option.*/
- static status_t ftfx_check_swap_control_option(ftfx_swap_control_opt_t option)
- {
- if ((option == kFTFx_SwapControlOptionIntializeSystem) || (option == kFTFx_SwapControlOptionSetInUpdateState) ||
- (option == kFTFx_SwapControlOptionSetInCompleteState) || (option == kFTFx_SwapControlOptionReportStatus) ||
- (option == kFTFx_SwapControlOptionDisableSystem))
- {
- return kStatus_FTFx_Success;
- }
- return kStatus_FTFx_InvalidArgument;
- }
- #endif /* FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD */
|