Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
fsl_flash.c
00001 /* 00002 * Copyright (c) 2015, Freescale Semiconductor, Inc. 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without modification, 00006 * are permitted provided that the following conditions are met: 00007 * 00008 * o Redistributions of source code must retain the above copyright notice, this list 00009 * of conditions and the following disclaimer. 00010 * 00011 * o Redistributions in binary form must reproduce the above copyright notice, this 00012 * list of conditions and the following disclaimer in the documentation and/or 00013 * other materials provided with the distribution. 00014 * 00015 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its 00016 * contributors may be used to endorse or promote products derived from this 00017 * software without specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 00023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 00026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 */ 00030 00031 #include "fsl_flash.h" 00032 00033 /******************************************************************************* 00034 * Definitions 00035 ******************************************************************************/ 00036 00037 /*! 00038 * @name Misc utility defines 00039 * @{ 00040 */ 00041 #ifndef ALIGN_DOWN 00042 #define ALIGN_DOWN(x, a) ((x) & (uint32_t)(-((int32_t)(a)))) 00043 #endif 00044 #ifndef ALIGN_UP 00045 #define ALIGN_UP(x, a) (-((int32_t)((uint32_t)(-((int32_t)(x))) & (uint32_t)(-((int32_t)(a)))))) 00046 #endif 00047 00048 #define BYTES_JOIN_TO_WORD_1_3(x, y) ((((uint32_t)(x)&0xFFU) << 24) | ((uint32_t)(y)&0xFFFFFFU)) 00049 #define BYTES_JOIN_TO_WORD_2_2(x, y) ((((uint32_t)(x)&0xFFFFU) << 16) | ((uint32_t)(y)&0xFFFFU)) 00050 #define BYTES_JOIN_TO_WORD_3_1(x, y) ((((uint32_t)(x)&0xFFFFFFU) << 8) | ((uint32_t)(y)&0xFFU)) 00051 #define BYTES_JOIN_TO_WORD_1_1_2(x, y, z) \ 00052 ((((uint32_t)(x)&0xFFU) << 24) | (((uint32_t)(y)&0xFFU) << 16) | ((uint32_t)(z)&0xFFFFU)) 00053 #define BYTES_JOIN_TO_WORD_1_2_1(x, y, z) \ 00054 ((((uint32_t)(x)&0xFFU) << 24) | (((uint32_t)(y)&0xFFFFU) << 8) | ((uint32_t)(z)&0xFFU)) 00055 #define BYTES_JOIN_TO_WORD_2_1_1(x, y, z) \ 00056 ((((uint32_t)(x)&0xFFFFU) << 16) | (((uint32_t)(y)&0xFFU) << 8) | ((uint32_t)(z)&0xFFU)) 00057 #define BYTES_JOIN_TO_WORD_1_1_1_1(x, y, z, w) \ 00058 ((((uint32_t)(x)&0xFFU) << 24) | (((uint32_t)(y)&0xFFU) << 16) | (((uint32_t)(z)&0xFFU) << 8) | \ 00059 ((uint32_t)(w)&0xFFU)) 00060 /*@}*/ 00061 00062 /*! @brief Data flash IFR map Field*/ 00063 #if defined(FSL_FEATURE_FLASH_IS_FTFE) && FSL_FEATURE_FLASH_IS_FTFE 00064 #define DFLASH_IFR_READRESOURCE_START_ADDRESS 0x8003F8U 00065 #else /* FSL_FEATURE_FLASH_IS_FTFL == 1 or FSL_FEATURE_FLASH_IS_FTFA = =1 */ 00066 #define DFLASH_IFR_READRESOURCE_START_ADDRESS 0x8000F8U 00067 #endif 00068 00069 /*! 00070 * @name Reserved FlexNVM size (For a variety of purposes) defines 00071 * @{ 00072 */ 00073 #define FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED 0xFFFFFFFFU 00074 #define FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_RESERVED 0xFFFFU 00075 /*@}*/ 00076 00077 /*! 00078 * @name Flash Program Once Field defines 00079 * @{ 00080 */ 00081 #if defined(FSL_FEATURE_FLASH_IS_FTFA) && FSL_FEATURE_FLASH_IS_FTFA 00082 /* FTFA parts(eg. K80, KL80, L5K) support both 4-bytes and 8-bytes unit size */ 00083 #define FLASH_PROGRAM_ONCE_MIN_ID_8BYTES \ 00084 0x10U /* Minimum Index indcating one of Progam Once Fields which is accessed in 8-byte records */ 00085 #define FLASH_PROGRAM_ONCE_MAX_ID_8BYTES \ 00086 0x13U /* Maximum Index indcating one of Progam Once Fields which is accessed in 8-byte records */ 00087 #define FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT 1 00088 #define FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT 1 00089 #elif defined(FSL_FEATURE_FLASH_IS_FTFE) && FSL_FEATURE_FLASH_IS_FTFE 00090 /* FTFE parts(eg. K65, KE18) only support 8-bytes unit size */ 00091 #define FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT 0 00092 #define FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT 1 00093 #elif defined(FSL_FEATURE_FLASH_IS_FTFL) && FSL_FEATURE_FLASH_IS_FTFL 00094 /* FTFL parts(eg. K20) only support 4-bytes unit size */ 00095 #define FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT 1 00096 #define FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT 0 00097 #endif 00098 /*@}*/ 00099 00100 /*! 00101 * @name Flash security status defines 00102 * @{ 00103 */ 00104 #define FLASH_SECURITY_STATE_KEYEN 0x80U 00105 #define FLASH_SECURITY_STATE_UNSECURED 0x02U 00106 #define FLASH_NOT_SECURE 0x01U 00107 #define FLASH_SECURE_BACKDOOR_ENABLED 0x02U 00108 #define FLASH_SECURE_BACKDOOR_DISABLED 0x04U 00109 /*@}*/ 00110 00111 /*! 00112 * @name Flash controller command numbers 00113 * @{ 00114 */ 00115 #define FTFx_VERIFY_BLOCK 0x00U /*!< RD1BLK*/ 00116 #define FTFx_VERIFY_SECTION 0x01U /*!< RD1SEC*/ 00117 #define FTFx_PROGRAM_CHECK 0x02U /*!< PGMCHK*/ 00118 #define FTFx_READ_RESOURCE 0x03U /*!< RDRSRC*/ 00119 #define FTFx_PROGRAM_LONGWORD 0x06U /*!< PGM4*/ 00120 #define FTFx_PROGRAM_PHRASE 0x07U /*!< PGM8*/ 00121 #define FTFx_ERASE_BLOCK 0x08U /*!< ERSBLK*/ 00122 #define FTFx_ERASE_SECTOR 0x09U /*!< ERSSCR*/ 00123 #define FTFx_PROGRAM_SECTION 0x0BU /*!< PGMSEC*/ 00124 #define FTFx_VERIFY_ALL_BLOCK 0x40U /*!< RD1ALL*/ 00125 #define FTFx_READ_ONCE 0x41U /*!< RDONCE or RDINDEX*/ 00126 #define FTFx_PROGRAM_ONCE 0x43U /*!< PGMONCE or PGMINDEX*/ 00127 #define FTFx_ERASE_ALL_BLOCK 0x44U /*!< ERSALL*/ 00128 #define FTFx_SECURITY_BY_PASS 0x45U /*!< VFYKEY*/ 00129 #define FTFx_SWAP_CONTROL 0x46U /*!< SWAP*/ 00130 #define FTFx_ERASE_ALL_BLOCK_UNSECURE 0x49U /*!< ERSALLU*/ 00131 #define FTFx_VERIFY_ALL_EXECUTE_ONLY_SEGMENT 0x4AU /*!< RD1XA*/ 00132 #define FTFx_ERASE_ALL_EXECUTE_ONLY_SEGMENT 0x4BU /*!< ERSXA*/ 00133 #define FTFx_PROGRAM_PARTITION 0x80U /*!< PGMPART)*/ 00134 #define FTFx_SET_FLEXRAM_FUNCTION 0x81U /*!< SETRAM*/ 00135 /*@}*/ 00136 00137 /*! 00138 * @name Common flash register info defines 00139 * @{ 00140 */ 00141 #if defined(FTFA) 00142 #define FTFx FTFA 00143 #define FTFx_BASE FTFA_BASE 00144 #define FTFx_FSTAT_CCIF_MASK FTFA_FSTAT_CCIF_MASK 00145 #define FTFx_FSTAT_RDCOLERR_MASK FTFA_FSTAT_RDCOLERR_MASK 00146 #define FTFx_FSTAT_ACCERR_MASK FTFA_FSTAT_ACCERR_MASK 00147 #define FTFx_FSTAT_FPVIOL_MASK FTFA_FSTAT_FPVIOL_MASK 00148 #define FTFx_FSTAT_MGSTAT0_MASK FTFA_FSTAT_MGSTAT0_MASK 00149 #define FTFx_FSEC_SEC_MASK FTFA_FSEC_SEC_MASK 00150 #define FTFx_FSEC_KEYEN_MASK FTFA_FSEC_KEYEN_MASK 00151 #if defined(FSL_FEATURE_FLASH_HAS_FLEX_RAM) && FSL_FEATURE_FLASH_HAS_FLEX_RAM 00152 #define FTFx_FCNFG_RAMRDY_MASK FTFA_FCNFG_RAMRDY_MASK 00153 #endif /* FSL_FEATURE_FLASH_HAS_FLEX_RAM */ 00154 #if defined(FSL_FEATURE_FLASH_HAS_FLEX_NVM) && FSL_FEATURE_FLASH_HAS_FLEX_NVM 00155 #define FTFx_FCNFG_EEERDY_MASK FTFA_FCNFG_EEERDY_MASK 00156 #endif /* FSL_FEATURE_FLASH_HAS_FLEX_NVM */ 00157 #elif defined(FTFE) 00158 #define FTFx FTFE 00159 #define FTFx_BASE FTFE_BASE 00160 #define FTFx_FSTAT_CCIF_MASK FTFE_FSTAT_CCIF_MASK 00161 #define FTFx_FSTAT_RDCOLERR_MASK FTFE_FSTAT_RDCOLERR_MASK 00162 #define FTFx_FSTAT_ACCERR_MASK FTFE_FSTAT_ACCERR_MASK 00163 #define FTFx_FSTAT_FPVIOL_MASK FTFE_FSTAT_FPVIOL_MASK 00164 #define FTFx_FSTAT_MGSTAT0_MASK FTFE_FSTAT_MGSTAT0_MASK 00165 #define FTFx_FSEC_SEC_MASK FTFE_FSEC_SEC_MASK 00166 #define FTFx_FSEC_KEYEN_MASK FTFE_FSEC_KEYEN_MASK 00167 #if defined(FSL_FEATURE_FLASH_HAS_FLEX_RAM) && FSL_FEATURE_FLASH_HAS_FLEX_RAM 00168 #define FTFx_FCNFG_RAMRDY_MASK FTFE_FCNFG_RAMRDY_MASK 00169 #endif /* FSL_FEATURE_FLASH_HAS_FLEX_RAM */ 00170 #if defined(FSL_FEATURE_FLASH_HAS_FLEX_NVM) && FSL_FEATURE_FLASH_HAS_FLEX_NVM 00171 #define FTFx_FCNFG_EEERDY_MASK FTFE_FCNFG_EEERDY_MASK 00172 #endif /* FSL_FEATURE_FLASH_HAS_FLEX_NVM */ 00173 #elif defined(FTFL) 00174 #define FTFx FTFL 00175 #define FTFx_BASE FTFL_BASE 00176 #define FTFx_FSTAT_CCIF_MASK FTFL_FSTAT_CCIF_MASK 00177 #define FTFx_FSTAT_RDCOLERR_MASK FTFL_FSTAT_RDCOLERR_MASK 00178 #define FTFx_FSTAT_ACCERR_MASK FTFL_FSTAT_ACCERR_MASK 00179 #define FTFx_FSTAT_FPVIOL_MASK FTFL_FSTAT_FPVIOL_MASK 00180 #define FTFx_FSTAT_MGSTAT0_MASK FTFL_FSTAT_MGSTAT0_MASK 00181 #define FTFx_FSEC_SEC_MASK FTFL_FSEC_SEC_MASK 00182 #define FTFx_FSEC_KEYEN_MASK FTFL_FSEC_KEYEN_MASK 00183 #if defined(FSL_FEATURE_FLASH_HAS_FLEX_RAM) && FSL_FEATURE_FLASH_HAS_FLEX_RAM 00184 #define FTFx_FCNFG_RAMRDY_MASK FTFL_FCNFG_RAMRDY_MASK 00185 #endif /* FSL_FEATURE_FLASH_HAS_FLEX_RAM */ 00186 #if defined(FSL_FEATURE_FLASH_HAS_FLEX_NVM) && FSL_FEATURE_FLASH_HAS_FLEX_NVM 00187 #define FTFx_FCNFG_EEERDY_MASK FTFL_FCNFG_EEERDY_MASK 00188 #endif /* FSL_FEATURE_FLASH_HAS_FLEX_NVM */ 00189 #else 00190 #error "Unknown flash controller" 00191 #endif 00192 /*@}*/ 00193 00194 /*! 00195 * @brief Enumeration for access segment property. 00196 */ 00197 enum _flash_access_segment_property 00198 { 00199 kFLASH_accessSegmentBase = 256UL, 00200 }; 00201 00202 /*! 00203 * @brief Enumeration for acceleration ram property. 00204 */ 00205 enum _flash_acceleration_ram_property 00206 { 00207 kFLASH_accelerationRamSize = 0x400U 00208 }; 00209 00210 /*! 00211 * @brief Enumeration for flash config area. 00212 */ 00213 enum _flash_config_area_range 00214 { 00215 kFLASH_configAreaStart = 0x400U, 00216 kFLASH_configAreaEnd = 0x40FU 00217 }; 00218 00219 /*! @brief program Flash block base address*/ 00220 #define PFLASH_BLOCK_BASE 0x00U 00221 00222 /*! @brief Total flash region count*/ 00223 #define FSL_FEATURE_FTFx_REGION_COUNT (32U) 00224 00225 /*! 00226 * @name Flash register access type defines 00227 * @{ 00228 */ 00229 #if FLASH_DRIVER_IS_FLASH_RESIDENT 00230 #define FTFx_REG_ACCESS_TYPE volatile uint8_t * 00231 #define FTFx_REG32_ACCESS_TYPE volatile uint32_t * 00232 #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ 00233 /*@}*/ 00234 00235 /******************************************************************************* 00236 * Prototypes 00237 ******************************************************************************/ 00238 00239 #if FLASH_DRIVER_IS_FLASH_RESIDENT 00240 /*! @brief Copy flash_run_command() to RAM*/ 00241 static void copy_flash_run_command(uint8_t *flashRunCommand); 00242 /*! @brief Copy flash_cache_clear_command() to RAM*/ 00243 static void copy_flash_cache_clear_command(uint8_t *flashCacheClearCommand); 00244 /*! @brief Check whether flash execute-in-ram functions are ready*/ 00245 static status_t flash_check_execute_in_ram_function_info(flash_config_t *config); 00246 #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ 00247 00248 /*! @brief Internal function Flash command sequence. Called by driver APIs only*/ 00249 static status_t flash_command_sequence(flash_config_t *config); 00250 00251 /*! @brief Perform the cache clear to the flash*/ 00252 void flash_cache_clear(flash_config_t *config); 00253 00254 /*! @brief Validates the range and alignment of the given address range.*/ 00255 static status_t flash_check_range(flash_config_t *config, 00256 uint32_t startAddress, 00257 uint32_t lengthInBytes, 00258 uint32_t alignmentBaseline); 00259 /*! @brief Gets the right address, sector and block size of current flash type which is indicated by address.*/ 00260 static status_t flash_get_matched_operation_info(flash_config_t *config, 00261 uint32_t address, 00262 flash_operation_config_t *info); 00263 /*! @brief Validates the given user key for flash erase APIs.*/ 00264 static status_t flash_check_user_key(uint32_t key); 00265 00266 // #if FLASH_SSD_IS_FLEXNVM_ENABLED 00267 // /*! @brief Updates FlexNVM memory partition status according to data flash 0 IFR.*/ 00268 // static status_t flash_update_flexnvm_memory_partition_status(flash_config_t *config); 00269 // #endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ 00270 00271 // #if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD 00272 // /*! @brief Validates the range of the given resource address.*/ 00273 // static status_t flash_check_resource_range(uint32_t start, 00274 // uint32_t lengthInBytes, 00275 // uint32_t alignmentBaseline, 00276 // flash_read_resource_option_t option); 00277 // #endif /* FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD */ 00278 // 00279 // #if defined(FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD) && FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD 00280 // /*! @brief Validates the gived swap control option.*/ 00281 // static status_t flash_check_swap_control_option(flash_swap_control_option_t option); 00282 // #endif /* FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD */ 00283 // 00284 // #if defined(FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP) && FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP 00285 // /*! @brief Validates the gived address to see if it is equal to swap indicator address in pflash swap IFR.*/ 00286 // static status_t flash_validate_swap_indicator_address(flash_config_t *config, uint32_t address); 00287 // #endif /* FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP */ 00288 // 00289 // #if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD 00290 // /*! @brief Validates the gived flexram function option.*/ 00291 // static inline status_t flasn_check_flexram_function_option_range(flash_flexram_function_option_t option); 00292 // #endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */ 00293 00294 /******************************************************************************* 00295 * Variables 00296 ******************************************************************************/ 00297 00298 /*! @brief Access to FTFx->FCCOB */ 00299 #if defined(FSL_FEATURE_FLASH_IS_FTFA) && FSL_FEATURE_FLASH_IS_FTFA 00300 volatile uint32_t *const kFCCOBx = (volatile uint32_t *)&FTFA->FCCOB3; 00301 #elif defined(FSL_FEATURE_FLASH_IS_FTFE) && FSL_FEATURE_FLASH_IS_FTFE 00302 volatile uint32_t *const kFCCOBx = (volatile uint32_t *)&FTFE->FCCOB3; 00303 #elif defined(FSL_FEATURE_FLASH_IS_FTFL) && FSL_FEATURE_FLASH_IS_FTFL 00304 volatile uint32_t *const kFCCOBx = (volatile uint32_t *)&FTFL->FCCOB3; 00305 #else 00306 #error "Unknown flash controller" 00307 #endif 00308 00309 /*! @brief Access to FTFx->FPROT */ 00310 #if defined(FSL_FEATURE_FLASH_IS_FTFA) && FSL_FEATURE_FLASH_IS_FTFA 00311 volatile uint32_t *const kFPROT = (volatile uint32_t *)&FTFA->FPROT3; 00312 #elif defined(FSL_FEATURE_FLASH_IS_FTFE) && FSL_FEATURE_FLASH_IS_FTFE 00313 volatile uint32_t *const kFPROT = (volatile uint32_t *)&FTFE->FPROT3; 00314 #elif defined(FSL_FEATURE_FLASH_IS_FTFL) && FSL_FEATURE_FLASH_IS_FTFL 00315 volatile uint32_t *const kFPROT = (volatile uint32_t *)&FTFL->FPROT3; 00316 #else 00317 #error "Unknown flash controller" 00318 #endif 00319 00320 #if FLASH_DRIVER_IS_FLASH_RESIDENT 00321 /*! @brief A function pointer used to point to relocated flash_run_command() */ 00322 static void (*callFlashRunCommand)(FTFx_REG_ACCESS_TYPE ftfx_fstat); 00323 /*! @brief A function pointer used to point to relocated flash_cache_clear_command() */ 00324 static void (*callFlashCacheClearCommand)(FTFx_REG32_ACCESS_TYPE ftfx_reg); 00325 #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ 00326 00327 #if (FLASH_DRIVER_IS_FLASH_RESIDENT && !FLASH_DRIVER_IS_EXPORTED) 00328 /*! @brief A static buffer used to hold flash_run_command() */ 00329 static uint8_t s_flashRunCommand[kFLASH_executeInRamFunctionMaxSize ]; 00330 /*! @brief A static buffer used to hold flash_cache_clear_command() */ 00331 static uint8_t s_flashCacheClearCommand[kFLASH_executeInRamFunctionMaxSize ]; 00332 /*! @brief Flash execute-in-ram function information */ 00333 static flash_execute_in_ram_function_config_t s_flashExecuteInRamFunctionInfo; 00334 #endif 00335 00336 /*! 00337 * @brief Table of pflash sizes. 00338 * 00339 * The index into this table is the value of the SIM_FCFG1.PFSIZE bitfield. 00340 * 00341 * The values in this table have been right shifted 10 bits so that they will all fit within 00342 * an 16-bit integer. To get the actual flash density, you must left shift the looked up value 00343 * by 10 bits. 00344 * 00345 * Elements of this table have a value of 0 in cases where the PFSIZE bitfield value is 00346 * reserved. 00347 * 00348 * Code to use the table: 00349 * @code 00350 * uint8_t pfsize = (SIM->FCFG1 & SIM_FCFG1_PFSIZE_MASK) >> SIM_FCFG1_PFSIZE_SHIFT; 00351 * flashDensity = ((uint32_t)kPFlashDensities[pfsize]) << 10; 00352 * @endcode 00353 */ 00354 const uint16_t kPFlashDensities[] = { 00355 8, /* 0x0 - 8192, 8KB */ 00356 16, /* 0x1 - 16384, 16KB */ 00357 24, /* 0x2 - 24576, 24KB */ 00358 32, /* 0x3 - 32768, 32KB */ 00359 48, /* 0x4 - 49152, 48KB */ 00360 64, /* 0x5 - 65536, 64KB */ 00361 96, /* 0x6 - 98304, 96KB */ 00362 128, /* 0x7 - 131072, 128KB */ 00363 192, /* 0x8 - 196608, 192KB */ 00364 256, /* 0x9 - 262144, 256KB */ 00365 384, /* 0xa - 393216, 384KB */ 00366 512, /* 0xb - 524288, 512KB */ 00367 768, /* 0xc - 786432, 768KB */ 00368 1024, /* 0xd - 1048576, 1MB */ 00369 1536, /* 0xe - 1572864, 1.5MB */ 00370 /* 2048, 0xf - 2097152, 2MB */ 00371 }; 00372 00373 /******************************************************************************* 00374 * Code 00375 ******************************************************************************/ 00376 00377 status_t FLASH_Init(flash_config_t *config) 00378 { 00379 uint32_t flashDensity; 00380 00381 if (config == NULL) 00382 { 00383 return kStatus_FLASH_InvalidArgument ; 00384 } 00385 00386 /* calculate the flash density from SIM_FCFG1.PFSIZE */ 00387 uint8_t pfsize = (SIM->FCFG1 & SIM_FCFG1_PFSIZE_MASK) >> SIM_FCFG1_PFSIZE_SHIFT; 00388 /* PFSIZE=0xf means that on customer parts the IFR was not correctly programmed. 00389 * We just use the pre-defined flash size in feature file here to support pre-production parts */ 00390 if (pfsize == 0xf) 00391 { 00392 flashDensity = FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT * FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE; 00393 } 00394 else 00395 { 00396 flashDensity = ((uint32_t)kPFlashDensities[pfsize]) << 10; 00397 } 00398 00399 /* fill out a few of the structure members */ 00400 config->PFlashBlockBase = PFLASH_BLOCK_BASE; 00401 config->PFlashTotalSize = flashDensity; 00402 config->PFlashBlockCount = FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT; 00403 config->PFlashSectorSize = FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE; 00404 00405 #if defined(FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL) && FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL 00406 config->PFlashAccessSegmentSize = kFLASH_accessSegmentBase << FTFx->FACSS; 00407 config->PFlashAccessSegmentCount = FTFx->FACSN; 00408 #else 00409 config->PFlashAccessSegmentSize = 0; 00410 config->PFlashAccessSegmentCount = 0; 00411 #endif /* FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL */ 00412 00413 config->PFlashCallback = NULL; 00414 00415 /* copy required flash commands to RAM */ 00416 #if (FLASH_DRIVER_IS_FLASH_RESIDENT && !FLASH_DRIVER_IS_EXPORTED) 00417 if (kStatus_FLASH_Success != flash_check_execute_in_ram_function_info(config)) 00418 { 00419 s_flashExecuteInRamFunctionInfo.activeFunctionCount = 0; 00420 s_flashExecuteInRamFunctionInfo.flashRunCommand = s_flashRunCommand; 00421 s_flashExecuteInRamFunctionInfo.flashCacheClearCommand = s_flashCacheClearCommand; 00422 config->flashExecuteInRamFunctionInfo = &s_flashExecuteInRamFunctionInfo.activeFunctionCount ; 00423 FLASH_PrepareExecuteInRamFunctions(config); 00424 } 00425 #endif 00426 00427 config->FlexRAMBlockBase = FSL_FEATURE_FLASH_FLEX_RAM_START_ADDRESS; 00428 config->FlexRAMTotalSize = FSL_FEATURE_FLASH_FLEX_RAM_SIZE; 00429 00430 #if FLASH_SSD_IS_FLEXNVM_ENABLED 00431 { 00432 status_t returnCode; 00433 config->DFlashBlockBase = FSL_FEATURE_FLASH_FLEX_NVM_START_ADDRESS; 00434 returnCode = flash_update_flexnvm_memory_partition_status(config); 00435 if (returnCode != kStatus_FLASH_Success ) 00436 { 00437 return returnCode; 00438 } 00439 } 00440 #endif 00441 00442 return kStatus_FLASH_Success ; 00443 } 00444 00445 status_t FLASH_SetCallback(flash_config_t *config, flash_callback_t callback) 00446 { 00447 if (config == NULL) 00448 { 00449 return kStatus_FLASH_InvalidArgument ; 00450 } 00451 00452 config->PFlashCallback = callback; 00453 00454 return kStatus_FLASH_Success ; 00455 } 00456 00457 #if FLASH_DRIVER_IS_FLASH_RESIDENT 00458 status_t FLASH_PrepareExecuteInRamFunctions(flash_config_t *config) 00459 { 00460 flash_execute_in_ram_function_config_t *flashExecuteInRamFunctionInfo; 00461 00462 if (config == NULL) 00463 { 00464 return kStatus_FLASH_InvalidArgument ; 00465 } 00466 00467 flashExecuteInRamFunctionInfo = (flash_execute_in_ram_function_config_t *)config->flashExecuteInRamFunctionInfo ; 00468 00469 copy_flash_run_command(flashExecuteInRamFunctionInfo->flashRunCommand ); 00470 copy_flash_cache_clear_command(flashExecuteInRamFunctionInfo->flashCacheClearCommand ); 00471 flashExecuteInRamFunctionInfo->activeFunctionCount = kFLASH_executeInRamFunctionTotalNum ; 00472 00473 return kStatus_FLASH_Success ; 00474 } 00475 #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ 00476 00477 status_t FLASH_EraseAll(flash_config_t *config, uint32_t key) 00478 { 00479 status_t returnCode; 00480 00481 if (config == NULL) 00482 { 00483 return kStatus_FLASH_InvalidArgument ; 00484 } 00485 00486 /* preparing passing parameter to erase all flash blocks */ 00487 kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_ERASE_ALL_BLOCK, 0xFFFFFFU); 00488 00489 /* Validate the user key */ 00490 returnCode = flash_check_user_key(key); 00491 if (returnCode) 00492 { 00493 return returnCode; 00494 } 00495 00496 /* calling flash command sequence function to execute the command */ 00497 returnCode = flash_command_sequence(config); 00498 00499 flash_cache_clear(config); 00500 00501 #if FLASH_SSD_IS_FLEXNVM_ENABLED 00502 /* Data flash IFR will be erased by erase all command, so we need to 00503 * update FlexNVM memory partition status synchronously */ 00504 if (returnCode == kStatus_FLASH_Success ) 00505 { 00506 returnCode = flash_update_flexnvm_memory_partition_status(config); 00507 } 00508 #endif 00509 00510 return returnCode; 00511 } 00512 00513 status_t FLASH_Erase(flash_config_t *config, uint32_t start, uint32_t lengthInBytes, uint32_t key) 00514 { 00515 uint32_t sectorSize; 00516 flash_operation_config_t flashInfo; 00517 uint32_t endAddress; /* storing end address */ 00518 uint32_t numberOfSectors; /* number of sectors calculated by endAddress */ 00519 status_t returnCode; 00520 00521 flash_get_matched_operation_info(config, start, &flashInfo); 00522 00523 /* Check the supplied address range. */ 00524 returnCode = flash_check_range(config, start, lengthInBytes, flashInfo.sectorCmdAddressAligment ); 00525 if (returnCode) 00526 { 00527 return returnCode; 00528 } 00529 00530 start = flashInfo.convertedAddress ; 00531 sectorSize = flashInfo.activeSectorSize ; 00532 00533 /* calculating Flash end address */ 00534 endAddress = start + lengthInBytes - 1; 00535 00536 /* re-calculate the endAddress and align it to the start of the next sector 00537 * which will be used in the comparison below */ 00538 if (endAddress % sectorSize) 00539 { 00540 numberOfSectors = endAddress / sectorSize + 1; 00541 endAddress = numberOfSectors * sectorSize - 1; 00542 } 00543 00544 /* the start address will increment to the next sector address 00545 * until it reaches the endAdddress */ 00546 while (start <= endAddress) 00547 { 00548 /* preparing passing parameter to erase a flash block */ 00549 kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_ERASE_SECTOR, start); 00550 00551 /* Validate the user key */ 00552 returnCode = flash_check_user_key(key); 00553 if (returnCode) 00554 { 00555 return returnCode; 00556 } 00557 00558 /* calling flash command sequence function to execute the command */ 00559 returnCode = flash_command_sequence(config); 00560 00561 /* calling flash callback function if it is available */ 00562 if (config->PFlashCallback ) 00563 { 00564 config->PFlashCallback (); 00565 } 00566 00567 /* checking the success of command execution */ 00568 if (kStatus_FLASH_Success != returnCode) 00569 { 00570 break; 00571 } 00572 else 00573 { 00574 /* Increment to the next sector */ 00575 start += sectorSize; 00576 } 00577 } 00578 00579 flash_cache_clear(config); 00580 00581 return (returnCode); 00582 } 00583 00584 // #if defined(FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD) && FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD 00585 // status_t FLASH_EraseAllUnsecure(flash_config_t *config, uint32_t key) 00586 // { 00587 // status_t returnCode; 00588 // 00589 // if (config == NULL) 00590 // { 00591 // return kStatus_FLASH_InvalidArgument; 00592 // } 00593 // 00594 // /* Prepare passing parameter to erase all flash blocks (unsecure). */ 00595 // kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_ERASE_ALL_BLOCK_UNSECURE, 0xFFFFFFU); 00596 // 00597 // /* Validate the user key */ 00598 // returnCode = flash_check_user_key(key); 00599 // if (returnCode) 00600 // { 00601 // return returnCode; 00602 // } 00603 // 00604 // /* calling flash command sequence function to execute the command */ 00605 // returnCode = flash_command_sequence(config); 00606 // 00607 // flash_cache_clear(config); 00608 // 00609 // #if FLASH_SSD_IS_FLEXNVM_ENABLED 00610 // /* Data flash IFR will be erased by erase all unsecure command, so we need to 00611 // * update FlexNVM memory partition status synchronously */ 00612 // if (returnCode == kStatus_FLASH_Success) 00613 // { 00614 // returnCode = flash_update_flexnvm_memory_partition_status(config); 00615 // } 00616 // #endif 00617 // 00618 // return returnCode; 00619 // } 00620 // #endif /* FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD */ 00621 // 00622 // status_t FLASH_EraseAllExecuteOnlySegments(flash_config_t *config, uint32_t key) 00623 // { 00624 // status_t returnCode; 00625 // 00626 // if (config == NULL) 00627 // { 00628 // return kStatus_FLASH_InvalidArgument; 00629 // } 00630 // 00631 // /* preparing passing parameter to erase all execute-only segments 00632 // * 1st element for the FCCOB register */ 00633 // kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_ERASE_ALL_EXECUTE_ONLY_SEGMENT, 0xFFFFFFU); 00634 // 00635 // /* Validate the user key */ 00636 // returnCode = flash_check_user_key(key); 00637 // if (returnCode) 00638 // { 00639 // return returnCode; 00640 // } 00641 // 00642 // /* calling flash command sequence function to execute the command */ 00643 // returnCode = flash_command_sequence(config); 00644 // 00645 // flash_cache_clear(config); 00646 // 00647 // return returnCode; 00648 // } 00649 00650 status_t FLASH_Program(flash_config_t *config, uint32_t start, uint32_t *src, uint32_t lengthInBytes) 00651 { 00652 status_t returnCode; 00653 flash_operation_config_t flashInfo; 00654 00655 if (src == NULL) 00656 { 00657 return kStatus_FLASH_InvalidArgument ; 00658 } 00659 00660 flash_get_matched_operation_info(config, start, &flashInfo); 00661 00662 /* Check the supplied address range. */ 00663 returnCode = flash_check_range(config, start, lengthInBytes, flashInfo.blockWriteUnitSize ); 00664 if (returnCode) 00665 { 00666 return returnCode; 00667 } 00668 00669 start = flashInfo.convertedAddress ; 00670 00671 while (lengthInBytes > 0) 00672 { 00673 /* preparing passing parameter to program the flash block */ 00674 kFCCOBx[1] = *src++; 00675 if (4 == flashInfo.blockWriteUnitSize ) 00676 { 00677 kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_PROGRAM_LONGWORD, start); 00678 } 00679 else if (8 == flashInfo.blockWriteUnitSize ) 00680 { 00681 kFCCOBx[2] = *src++; 00682 kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_PROGRAM_PHRASE, start); 00683 } 00684 else 00685 { 00686 } 00687 00688 /* calling flash command sequence function to execute the command */ 00689 returnCode = flash_command_sequence(config); 00690 00691 /* calling flash callback function if it is available */ 00692 if (config->PFlashCallback ) 00693 { 00694 config->PFlashCallback (); 00695 } 00696 00697 /* checking for the success of command execution */ 00698 if (kStatus_FLASH_Success != returnCode) 00699 { 00700 break; 00701 } 00702 else 00703 { 00704 /* update start address for next iteration */ 00705 start += flashInfo.blockWriteUnitSize ; 00706 00707 /* update lengthInBytes for next iteration */ 00708 lengthInBytes -= flashInfo.blockWriteUnitSize ; 00709 } 00710 } 00711 00712 flash_cache_clear(config); 00713 00714 return (returnCode); 00715 } 00716 00717 // status_t FLASH_ProgramOnce(flash_config_t *config, uint32_t index, uint32_t *src, uint32_t lengthInBytes) 00718 // { 00719 // status_t returnCode; 00720 // 00721 // if ((config == NULL) || (src == NULL)) 00722 // { 00723 // return kStatus_FLASH_InvalidArgument; 00724 // } 00725 // 00726 // /* pass paramters to FTFx */ 00727 // kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_1_2(FTFx_PROGRAM_ONCE, index, 0xFFFFU); 00728 // 00729 // kFCCOBx[1] = *src; 00730 // 00731 // /* Note: Have to seperate the first index from the rest if it equals 0 00732 // * to avoid a pointless comparison of unsigned int to 0 compiler warning */ 00733 // #if FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT 00734 // #if FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT 00735 // if (((index == FLASH_PROGRAM_ONCE_MIN_ID_8BYTES) || 00736 // /* Range check */ 00737 // ((index >= FLASH_PROGRAM_ONCE_MIN_ID_8BYTES + 1) && (index <= FLASH_PROGRAM_ONCE_MAX_ID_8BYTES))) && 00738 // (lengthInBytes == 8)) 00739 // #endif /* FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT */ 00740 // { 00741 // kFCCOBx[2] = *(src + 1); 00742 // } 00743 // #endif /* FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT */ 00744 // 00745 // /* calling flash command sequence function to execute the command */ 00746 // returnCode = flash_command_sequence(config); 00747 // 00748 // flash_cache_clear(config); 00749 // 00750 // return returnCode; 00751 // } 00752 // 00753 // #if defined(FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD) && FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD 00754 // status_t FLASH_ProgramSection(flash_config_t *config, uint32_t start, uint32_t *src, uint32_t lengthInBytes) 00755 // { 00756 // status_t returnCode; 00757 // uint32_t sectorSize; 00758 // flash_operation_config_t flashInfo; 00759 // #if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD 00760 // bool needSwitchFlexRamMode = false; 00761 // #endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */ 00762 // 00763 // if (src == NULL) 00764 // { 00765 // return kStatus_FLASH_InvalidArgument; 00766 // } 00767 // 00768 // flash_get_matched_operation_info(config, start, &flashInfo); 00769 // 00770 // /* Check the supplied address range. */ 00771 // returnCode = flash_check_range(config, start, lengthInBytes, flashInfo.sectionCmdAddressAligment); 00772 // if (returnCode) 00773 // { 00774 // return returnCode; 00775 // } 00776 // 00777 // start = flashInfo.convertedAddress; 00778 // sectorSize = flashInfo.activeSectorSize; 00779 // 00780 // #if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD 00781 // /* Switch function of FlexRAM if needed */ 00782 // if (!(FTFx->FCNFG & FTFx_FCNFG_RAMRDY_MASK)) 00783 // { 00784 // needSwitchFlexRamMode = true; 00785 // 00786 // returnCode = FLASH_SetFlexramFunction(config, kFLASH_flexramFunctionOptionAvailableAsRam); 00787 // if (returnCode != kStatus_FLASH_Success) 00788 // { 00789 // return kStatus_FLASH_SetFlexramAsRamError; 00790 // } 00791 // } 00792 // #endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */ 00793 // 00794 // while (lengthInBytes > 0) 00795 // { 00796 // /* Make sure the write operation doesn't span two sectors */ 00797 // uint32_t endAddressOfCurrentSector = ALIGN_UP(start, sectorSize); 00798 // uint32_t lengthTobeProgrammedOfCurrentSector; 00799 // uint32_t currentOffset = 0; 00800 // 00801 // if (endAddressOfCurrentSector == start) 00802 // { 00803 // endAddressOfCurrentSector += sectorSize; 00804 // } 00805 // 00806 // if (lengthInBytes + start > endAddressOfCurrentSector) 00807 // { 00808 // lengthTobeProgrammedOfCurrentSector = endAddressOfCurrentSector - start; 00809 // } 00810 // else 00811 // { 00812 // lengthTobeProgrammedOfCurrentSector = lengthInBytes; 00813 // } 00814 // 00815 // /* Program Current Sector */ 00816 // while (lengthTobeProgrammedOfCurrentSector > 0) 00817 // { 00818 // /* Make sure the program size doesn't exceeds Acceleration RAM size */ 00819 // uint32_t programSizeOfCurrentPass; 00820 // uint32_t numberOfPhases; 00821 // 00822 // if (lengthTobeProgrammedOfCurrentSector > kFLASH_accelerationRamSize) 00823 // { 00824 // programSizeOfCurrentPass = kFLASH_accelerationRamSize; 00825 // } 00826 // else 00827 // { 00828 // programSizeOfCurrentPass = lengthTobeProgrammedOfCurrentSector; 00829 // } 00830 // 00831 // /* Copy data to FlexRAM */ 00832 // memcpy((void *)FSL_FEATURE_FLASH_FLEX_RAM_START_ADDRESS, src + currentOffset / 4, programSizeOfCurrentPass); 00833 // /* Set start address of the data to be programmed */ 00834 // kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_PROGRAM_SECTION, start + currentOffset); 00835 // /* Set program size in terms of FEATURE_FLASH_SECTION_CMD_ADDRESS_ALIGMENT */ 00836 // numberOfPhases = programSizeOfCurrentPass / flashInfo.sectionCmdAddressAligment; 00837 // 00838 // kFCCOBx[1] = BYTES_JOIN_TO_WORD_2_2(numberOfPhases, 0xFFFFU); 00839 // 00840 // /* Peform command sequence */ 00841 // returnCode = flash_command_sequence(config); 00842 // 00843 // /* calling flash callback function if it is available */ 00844 // if (config->PFlashCallback) 00845 // { 00846 // config->PFlashCallback(); 00847 // } 00848 // 00849 // if (returnCode != kStatus_FLASH_Success) 00850 // { 00851 // flash_cache_clear(config); 00852 // return returnCode; 00853 // } 00854 // 00855 // lengthTobeProgrammedOfCurrentSector -= programSizeOfCurrentPass; 00856 // currentOffset += programSizeOfCurrentPass; 00857 // } 00858 // 00859 // src += currentOffset / 4; 00860 // start += currentOffset; 00861 // lengthInBytes -= currentOffset; 00862 // } 00863 // 00864 // flash_cache_clear(config); 00865 // 00866 // #if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD 00867 // /* Restore function of FlexRAM if needed. */ 00868 // if (needSwitchFlexRamMode) 00869 // { 00870 // returnCode = FLASH_SetFlexramFunction(config, kFLASH_flexramFunctionOptionAvailableForEeprom); 00871 // if (returnCode != kStatus_FLASH_Success) 00872 // { 00873 // return kStatus_FLASH_RecoverFlexramAsEepromError; 00874 // } 00875 // } 00876 // #endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */ 00877 // 00878 // return returnCode; 00879 // } 00880 // #endif /* FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD */ 00881 // 00882 // #if FLASH_SSD_IS_FLEXNVM_ENABLED 00883 // status_t FLASH_EepromWrite(flash_config_t *config, uint32_t start, uint8_t *src, uint32_t lengthInBytes) 00884 // { 00885 // status_t returnCode; 00886 // bool needSwitchFlexRamMode = false; 00887 // 00888 // if (config == NULL) 00889 // { 00890 // return kStatus_FLASH_InvalidArgument; 00891 // } 00892 // 00893 // /* Validates the range of the given address */ 00894 // if ((start < config->FlexRAMBlockBase) || 00895 // ((start + lengthInBytes) > (config->FlexRAMBlockBase + config->EEpromTotalSize))) 00896 // { 00897 // return kStatus_FLASH_AddressError; 00898 // } 00899 // 00900 // returnCode = kStatus_FLASH_Success; 00901 // 00902 // /* Switch function of FlexRAM if needed */ 00903 // if (!(FTFx->FCNFG & FTFx_FCNFG_EEERDY_MASK)) 00904 // { 00905 // needSwitchFlexRamMode = true; 00906 // 00907 // returnCode = FLASH_SetFlexramFunction(config, kFLASH_flexramFunctionOptionAvailableForEeprom); 00908 // if (returnCode != kStatus_FLASH_Success) 00909 // { 00910 // return kStatus_FLASH_SetFlexramAsEepromError; 00911 // } 00912 // } 00913 // 00914 // /* Write data to FlexRAM when it is used as EEPROM emulator */ 00915 // while (lengthInBytes > 0) 00916 // { 00917 // if ((!(start & 0x3U)) && (lengthInBytes >= 4)) 00918 // { 00919 // *(uint32_t *)start = *(uint32_t *)src; 00920 // start += 4; 00921 // src += 4; 00922 // lengthInBytes -= 4; 00923 // } 00924 // else if ((!(start & 0x1U)) && (lengthInBytes >= 2)) 00925 // { 00926 // *(uint16_t *)start = *(uint16_t *)src; 00927 // start += 2; 00928 // src += 2; 00929 // lengthInBytes -= 2; 00930 // } 00931 // else 00932 // { 00933 // *(uint8_t *)start = *src; 00934 // start += 1; 00935 // src += 1; 00936 // lengthInBytes -= 1; 00937 // } 00938 // /* Wait till EEERDY bit is set */ 00939 // while (!(FTFx->FCNFG & FTFx_FCNFG_EEERDY_MASK)) 00940 // { 00941 // } 00942 // 00943 // /* Check for protection violation error */ 00944 // if (FTFx->FSTAT & FTFx_FSTAT_FPVIOL_MASK) 00945 // { 00946 // return kStatus_FLASH_ProtectionViolation; 00947 // } 00948 // } 00949 // 00950 // /* Switch function of FlexRAM if needed */ 00951 // if (needSwitchFlexRamMode) 00952 // { 00953 // returnCode = FLASH_SetFlexramFunction(config, kFLASH_flexramFunctionOptionAvailableAsRam); 00954 // if (returnCode != kStatus_FLASH_Success) 00955 // { 00956 // return kStatus_FLASH_RecoverFlexramAsRamError; 00957 // } 00958 // } 00959 // 00960 // return returnCode; 00961 // } 00962 // #endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ 00963 // 00964 // #if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD 00965 // status_t FLASH_ReadResource( 00966 // flash_config_t *config, uint32_t start, uint32_t *dst, uint32_t lengthInBytes, flash_read_resource_option_t option) 00967 // { 00968 // status_t returnCode; 00969 // flash_operation_config_t flashInfo; 00970 // 00971 // if ((config == NULL) || (dst == NULL)) 00972 // { 00973 // return kStatus_FLASH_InvalidArgument; 00974 // } 00975 // 00976 // flash_get_matched_operation_info(config, start, &flashInfo); 00977 // 00978 // /* Check the supplied address range. */ 00979 // returnCode = flash_check_resource_range(start, lengthInBytes, flashInfo.resourceCmdAddressAligment, option); 00980 // if (returnCode != kStatus_FLASH_Success) 00981 // { 00982 // return returnCode; 00983 // } 00984 // 00985 // while (lengthInBytes > 0) 00986 // { 00987 // /* preparing passing parameter */ 00988 // kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_READ_RESOURCE, start); 00989 // if (flashInfo.resourceCmdAddressAligment == 4) 00990 // { 00991 // kFCCOBx[2] = BYTES_JOIN_TO_WORD_1_3(option, 0xFFFFFFU); 00992 // } 00993 // else if (flashInfo.resourceCmdAddressAligment == 8) 00994 // { 00995 // kFCCOBx[1] = BYTES_JOIN_TO_WORD_1_3(option, 0xFFFFFFU); 00996 // } 00997 // else 00998 // { 00999 // } 01000 // 01001 // /* calling flash command sequence function to execute the command */ 01002 // returnCode = flash_command_sequence(config); 01003 // 01004 // if (kStatus_FLASH_Success != returnCode) 01005 // { 01006 // break; 01007 // } 01008 // 01009 // /* fetch data */ 01010 // *dst++ = kFCCOBx[1]; 01011 // if (flashInfo.resourceCmdAddressAligment == 8) 01012 // { 01013 // *dst++ = kFCCOBx[2]; 01014 // } 01015 // /* update start address for next iteration */ 01016 // start += flashInfo.resourceCmdAddressAligment; 01017 // /* update lengthInBytes for next iteration */ 01018 // lengthInBytes -= flashInfo.resourceCmdAddressAligment; 01019 // } 01020 // 01021 // return (returnCode); 01022 // } 01023 // #endif /* FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD */ 01024 // 01025 // status_t FLASH_ReadOnce(flash_config_t *config, uint32_t index, uint32_t *dst, uint32_t lengthInBytes) 01026 // { 01027 // status_t returnCode; 01028 // 01029 // if ((config == NULL) || (dst == NULL)) 01030 // { 01031 // return kStatus_FLASH_InvalidArgument; 01032 // } 01033 // 01034 // /* pass paramters to FTFx */ 01035 // kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_1_2(FTFx_READ_ONCE, index, 0xFFFFU); 01036 // 01037 // /* calling flash command sequence function to execute the command */ 01038 // returnCode = flash_command_sequence(config); 01039 // 01040 // if (kStatus_FLASH_Success == returnCode) 01041 // { 01042 // *dst = kFCCOBx[1]; 01043 // /* Note: Have to seperate the first index from the rest if it equals 0 01044 // * to avoid a pointless comparison of unsigned int to 0 compiler warning */ 01045 // #if FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT 01046 // #if FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT 01047 // if (((index == FLASH_PROGRAM_ONCE_MIN_ID_8BYTES) || 01048 // /* Range check */ 01049 // ((index >= FLASH_PROGRAM_ONCE_MIN_ID_8BYTES + 1) && (index <= FLASH_PROGRAM_ONCE_MAX_ID_8BYTES))) && 01050 // (lengthInBytes == 8)) 01051 // #endif /* FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT */ 01052 // { 01053 // *(dst + 1) = kFCCOBx[2]; 01054 // } 01055 // #endif /* FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT */ 01056 // } 01057 // 01058 // return returnCode; 01059 // } 01060 // 01061 // status_t FLASH_GetSecurityState(flash_config_t *config, flash_security_state_t *state) 01062 // { 01063 // /* store data read from flash register */ 01064 // uint8_t registerValue; 01065 // 01066 // if ((config == NULL) || (state == NULL)) 01067 // { 01068 // return kStatus_FLASH_InvalidArgument; 01069 // } 01070 // 01071 // /* Get flash security register value */ 01072 // registerValue = FTFx->FSEC; 01073 // 01074 // /* check the status of the flash security bits in the security register */ 01075 // if (FLASH_SECURITY_STATE_UNSECURED == (registerValue & FTFx_FSEC_SEC_MASK)) 01076 // { 01077 // /* Flash in unsecured state */ 01078 // *state = kFLASH_securityStateNotSecure; 01079 // } 01080 // else 01081 // { 01082 // /* Flash in secured state 01083 // * check for backdoor key security enable bit */ 01084 // if (FLASH_SECURITY_STATE_KEYEN == (registerValue & FTFx_FSEC_KEYEN_MASK)) 01085 // { 01086 // /* Backdoor key security enabled */ 01087 // *state = kFLASH_securityStateBackdoorEnabled; 01088 // } 01089 // else 01090 // { 01091 // /* Backdoor key security disabled */ 01092 // *state = kFLASH_securityStateBackdoorDisabled; 01093 // } 01094 // } 01095 // 01096 // return (kStatus_FLASH_Success); 01097 // } 01098 // 01099 // status_t FLASH_SecurityBypass(flash_config_t *config, const uint8_t *backdoorKey) 01100 // { 01101 // uint8_t registerValue; /* registerValue */ 01102 // status_t returnCode; /* return code variable */ 01103 // 01104 // if ((config == NULL) || (backdoorKey == NULL)) 01105 // { 01106 // return kStatus_FLASH_InvalidArgument; 01107 // } 01108 // 01109 // /* set the default return code as kStatus_Success */ 01110 // returnCode = kStatus_FLASH_Success; 01111 // 01112 // /* Get flash security register value */ 01113 // registerValue = FTFx->FSEC; 01114 // 01115 // /* Check to see if flash is in secure state (any state other than 0x2) 01116 // * If not, then skip this since flash is not secure */ 01117 // if (0x02 != (registerValue & 0x03)) 01118 // { 01119 // /* preparing passing parameter to erase a flash block */ 01120 // kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_SECURITY_BY_PASS, 0xFFFFFFU); 01121 // kFCCOBx[1] = BYTES_JOIN_TO_WORD_1_1_1_1(backdoorKey[0], backdoorKey[1], backdoorKey[2], backdoorKey[3]); 01122 // kFCCOBx[2] = BYTES_JOIN_TO_WORD_1_1_1_1(backdoorKey[4], backdoorKey[5], backdoorKey[6], backdoorKey[7]); 01123 // 01124 // /* calling flash command sequence function to execute the command */ 01125 // returnCode = flash_command_sequence(config); 01126 // } 01127 // 01128 // return (returnCode); 01129 // } 01130 01131 status_t FLASH_VerifyEraseAll(flash_config_t *config, flash_margin_value_t margin) 01132 { 01133 if (config == NULL) 01134 { 01135 return kStatus_FLASH_InvalidArgument ; 01136 } 01137 01138 /* preparing passing parameter to verify all block command */ 01139 kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_1_2(FTFx_VERIFY_ALL_BLOCK, margin, 0xFFFFU); 01140 01141 /* calling flash command sequence function to execute the command */ 01142 return flash_command_sequence(config); 01143 } 01144 01145 status_t FLASH_VerifyErase(flash_config_t *config, uint32_t start, uint32_t lengthInBytes, flash_margin_value_t margin) 01146 { 01147 /* Check arguments. */ 01148 uint32_t blockSize; 01149 flash_operation_config_t flashInfo; 01150 uint32_t nextBlockStartAddress; 01151 uint32_t remainingBytes; 01152 status_t returnCode; 01153 01154 flash_get_matched_operation_info(config, start, &flashInfo); 01155 01156 returnCode = flash_check_range(config, start, lengthInBytes, flashInfo.sectionCmdAddressAligment ); 01157 if (returnCode) 01158 { 01159 return returnCode; 01160 } 01161 01162 flash_get_matched_operation_info(config, start, &flashInfo); 01163 start = flashInfo.convertedAddress ; 01164 blockSize = flashInfo.activeBlockSize ; 01165 01166 nextBlockStartAddress = ALIGN_UP(start, blockSize); 01167 if (nextBlockStartAddress == start) 01168 { 01169 nextBlockStartAddress += blockSize; 01170 } 01171 01172 remainingBytes = lengthInBytes; 01173 01174 while (remainingBytes) 01175 { 01176 uint32_t numberOfPhrases; 01177 uint32_t verifyLength = nextBlockStartAddress - start; 01178 if (verifyLength > remainingBytes) 01179 { 01180 verifyLength = remainingBytes; 01181 } 01182 01183 numberOfPhrases = verifyLength / flashInfo.sectionCmdAddressAligment ; 01184 01185 /* Fill in verify section command parameters. */ 01186 kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_VERIFY_SECTION, start); 01187 kFCCOBx[1] = BYTES_JOIN_TO_WORD_2_1_1(numberOfPhrases, margin, 0xFFU); 01188 01189 /* calling flash command sequence function to execute the command */ 01190 returnCode = flash_command_sequence(config); 01191 if (returnCode) 01192 { 01193 return returnCode; 01194 } 01195 01196 remainingBytes -= verifyLength; 01197 start += verifyLength; 01198 nextBlockStartAddress += blockSize; 01199 } 01200 01201 return kStatus_FLASH_Success ; 01202 } 01203 01204 status_t FLASH_VerifyProgram(flash_config_t *config, 01205 uint32_t start, 01206 uint32_t lengthInBytes, 01207 const uint32_t *expectedData, 01208 flash_margin_value_t margin, 01209 uint32_t *failedAddress, 01210 uint32_t *failedData) 01211 { 01212 status_t returnCode; 01213 flash_operation_config_t flashInfo; 01214 01215 if (expectedData == NULL) 01216 { 01217 return kStatus_FLASH_InvalidArgument ; 01218 } 01219 01220 flash_get_matched_operation_info(config, start, &flashInfo); 01221 01222 returnCode = flash_check_range(config, start, lengthInBytes, flashInfo.checkCmdAddressAligment ); 01223 if (returnCode) 01224 { 01225 return returnCode; 01226 } 01227 01228 start = flashInfo.convertedAddress ; 01229 01230 while (lengthInBytes) 01231 { 01232 /* preparing passing parameter to program check the flash block */ 01233 kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_PROGRAM_CHECK, start); 01234 kFCCOBx[1] = BYTES_JOIN_TO_WORD_1_3(margin, 0xFFFFFFU); 01235 kFCCOBx[2] = *expectedData; 01236 01237 /* calling flash command sequence function to execute the command */ 01238 returnCode = flash_command_sequence(config); 01239 01240 /* checking for the success of command execution */ 01241 if (kStatus_FLASH_Success != returnCode) 01242 { 01243 if (failedAddress) 01244 { 01245 *failedAddress = start; 01246 } 01247 if (failedData) 01248 { 01249 *failedData = 0; 01250 } 01251 break; 01252 } 01253 01254 lengthInBytes -= flashInfo.checkCmdAddressAligment ; 01255 expectedData += flashInfo.checkCmdAddressAligment / sizeof(*expectedData); 01256 start += flashInfo.checkCmdAddressAligment ; 01257 } 01258 01259 return (returnCode); 01260 } 01261 01262 // status_t FLASH_VerifyEraseAllExecuteOnlySegments(flash_config_t *config, flash_margin_value_t margin) 01263 // { 01264 // if (config == NULL) 01265 // { 01266 // return kStatus_FLASH_InvalidArgument; 01267 // } 01268 // 01269 // /* preparing passing parameter to verify erase all execute-only segments command */ 01270 // kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_1_2(FTFx_VERIFY_ALL_EXECUTE_ONLY_SEGMENT, margin, 0xFFFFU); 01271 // 01272 // /* calling flash command sequence function to execute the command */ 01273 // return flash_command_sequence(config); 01274 // } 01275 // 01276 // status_t FLASH_IsProtected(flash_config_t *config, 01277 // uint32_t start, 01278 // uint32_t lengthInBytes, 01279 // flash_protection_state_t *protection_state) 01280 // { 01281 // uint32_t endAddress; /* end address for protection check */ 01282 // uint32_t protectionRegionSize; /* size of flash protection region */ 01283 // uint32_t regionCheckedCounter; /* increments each time the flash address was checked for 01284 // * protection status */ 01285 // uint32_t regionCounter; /* incrementing variable used to increment through the flash 01286 // * protection regions */ 01287 // uint32_t protectStatusCounter; /* increments each time a flash region was detected as protected */ 01288 // 01289 // uint8_t flashRegionProtectStatus[FSL_FEATURE_FTFx_REGION_COUNT]; /* array of the protection status for each 01290 // * protection region */ 01291 // uint32_t flashRegionAddress[FSL_FEATURE_FTFx_REGION_COUNT + 1]; /* array of the start addresses for each flash 01292 // * protection region. Note this is REGION_COUNT+1 01293 // * due to requiring the next start address after 01294 // * the end of flash for loop-check purposes below */ 01295 // status_t returnCode; 01296 // 01297 // if (protection_state == NULL) 01298 // { 01299 // return kStatus_FLASH_InvalidArgument; 01300 // } 01301 // 01302 // /* Check the supplied address range. */ 01303 // returnCode = flash_check_range(config, start, lengthInBytes, FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE); 01304 // if (returnCode) 01305 // { 01306 // return returnCode; 01307 // } 01308 // 01309 // /* calculating Flash end address */ 01310 // endAddress = start + lengthInBytes; 01311 // 01312 // /* Calculate the size of the flash protection region 01313 // * If the flash density is > 32KB, then protection region is 1/32 of total flash density 01314 // * Else if flash density is < 32KB, then flash protection region is set to 1KB */ 01315 // if (config->PFlashTotalSize > 32 * 1024) 01316 // { 01317 // protectionRegionSize = (config->PFlashTotalSize) / FSL_FEATURE_FTFx_REGION_COUNT; 01318 // } 01319 // else 01320 // { 01321 // protectionRegionSize = 1024; 01322 // } 01323 // 01324 // /* populate the flashRegionAddress array with the start address of each flash region */ 01325 // regionCounter = 0; /* make sure regionCounter is initialized to 0 first */ 01326 // 01327 // /* populate up to 33rd element of array, this is the next address after end of flash array */ 01328 // while (regionCounter <= FSL_FEATURE_FTFx_REGION_COUNT) 01329 // { 01330 // flashRegionAddress[regionCounter] = config->PFlashBlockBase + protectionRegionSize * regionCounter; 01331 // regionCounter++; 01332 // } 01333 // 01334 // /* populate flashRegionProtectStatus array with status information 01335 // * Protection status for each region is stored in the FPROT[3:0] registers 01336 // * Each bit represents one region of flash 01337 // * 4 registers * 8-bits-per-register = 32-bits (32-regions) 01338 // * The convention is: 01339 // * FPROT3[bit 0] is the first protection region (start of flash memory) 01340 // * FPROT0[bit 7] is the last protection region (end of flash memory) 01341 // * regionCounter is used to determine which FPROT[3:0] register to check for protection status 01342 // * Note: FPROT=1 means NOT protected, FPROT=0 means protected */ 01343 // regionCounter = 0; /* make sure regionCounter is initialized to 0 first */ 01344 // while (regionCounter < FSL_FEATURE_FTFx_REGION_COUNT) 01345 // { 01346 // if (regionCounter < 8) 01347 // { 01348 // flashRegionProtectStatus[regionCounter] = ((FTFx->FPROT3) >> regionCounter) & (0x01u); 01349 // } 01350 // else if ((regionCounter >= 8) && (regionCounter < 16)) 01351 // { 01352 // flashRegionProtectStatus[regionCounter] = ((FTFx->FPROT2) >> (regionCounter - 8)) & (0x01u); 01353 // } 01354 // else if ((regionCounter >= 16) && (regionCounter < 24)) 01355 // { 01356 // flashRegionProtectStatus[regionCounter] = ((FTFx->FPROT1) >> (regionCounter - 16)) & (0x01u); 01357 // } 01358 // else 01359 // { 01360 // flashRegionProtectStatus[regionCounter] = ((FTFx->FPROT0) >> (regionCounter - 24)) & (0x01u); 01361 // } 01362 // regionCounter++; 01363 // } 01364 // 01365 // /* loop through the flash regions and check 01366 // * desired flash address range for protection status 01367 // * loop stops when it is detected that start has exceeded the endAddress */ 01368 // regionCounter = 0; /* make sure regionCounter is initialized to 0 first */ 01369 // regionCheckedCounter = 0; 01370 // protectStatusCounter = 0; /* make sure protectStatusCounter is initialized to 0 first */ 01371 // while (start < endAddress) 01372 // { 01373 // /* check to see if the address falls within this protection region 01374 // * Note that if the entire flash is to be checked, the last protection 01375 // * region checked would consist of the last protection start address and 01376 // * the start address following the end of flash */ 01377 // if ((start >= flashRegionAddress[regionCounter]) && (start < flashRegionAddress[regionCounter + 1])) 01378 // { 01379 // /* increment regionCheckedCounter to indicate this region was checked */ 01380 // regionCheckedCounter++; 01381 // 01382 // /* check the protection status of this region 01383 // * Note: FPROT=1 means NOT protected, FPROT=0 means protected */ 01384 // if (!flashRegionProtectStatus[regionCounter]) 01385 // { 01386 // /* increment protectStatusCounter to indicate this region is protected */ 01387 // protectStatusCounter++; 01388 // } 01389 // start += protectionRegionSize; /* increment to an address within the next region */ 01390 // } 01391 // regionCounter++; /* increment regionCounter to check for the next flash protection region */ 01392 // } 01393 // 01394 // /* if protectStatusCounter == 0, then no region of the desired flash region is protected */ 01395 // if (protectStatusCounter == 0) 01396 // { 01397 // *protection_state = kFLASH_protectionStateUnprotected; 01398 // } 01399 // /* if protectStatusCounter == regionCheckedCounter, then each region checked was protected */ 01400 // else if (protectStatusCounter == regionCheckedCounter) 01401 // { 01402 // *protection_state = kFLASH_protectionStateProtected; 01403 // } 01404 // /* if protectStatusCounter != regionCheckedCounter, then protection status is mixed 01405 // * In other words, some regions are protected while others are unprotected */ 01406 // else 01407 // { 01408 // *protection_state = kFLASH_protectionStateMixed; 01409 // } 01410 // 01411 // return (returnCode); 01412 // } 01413 // 01414 // status_t FLASH_IsExecuteOnly(flash_config_t *config, 01415 // uint32_t start, 01416 // uint32_t lengthInBytes, 01417 // flash_execute_only_access_state_t *access_state) 01418 // { 01419 // status_t returnCode; 01420 // 01421 // if (access_state == NULL) 01422 // { 01423 // return kStatus_FLASH_InvalidArgument; 01424 // } 01425 // 01426 // /* Check the supplied address range. */ 01427 // returnCode = flash_check_range(config, start, lengthInBytes, FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE); 01428 // if (returnCode) 01429 // { 01430 // return returnCode; 01431 // } 01432 // 01433 // #if defined(FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL) && FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL 01434 // { 01435 // uint32_t executeOnlySegmentCounter = 0; 01436 // 01437 // /* calculating end address */ 01438 // uint32_t endAddress = start + lengthInBytes; 01439 // 01440 // /* Aligning start address and end address */ 01441 // uint32_t alignedStartAddress = ALIGN_DOWN(start, config->PFlashAccessSegmentSize); 01442 // uint32_t alignedEndAddress = ALIGN_UP(endAddress, config->PFlashAccessSegmentSize); 01443 // 01444 // uint32_t segmentIndex = 0; 01445 // uint32_t maxSupportedExecuteOnlySegmentCount = 01446 // (alignedEndAddress - alignedStartAddress) / config->PFlashAccessSegmentSize; 01447 // 01448 // while (start < endAddress) 01449 // { 01450 // uint32_t xacc; 01451 // 01452 // segmentIndex = start / config->PFlashAccessSegmentSize; 01453 // 01454 // if (segmentIndex < 32) 01455 // { 01456 // xacc = *(const volatile uint32_t *)&FTFx->XACCL3; 01457 // } 01458 // else if (segmentIndex < config->PFlashAccessSegmentCount) 01459 // { 01460 // xacc = *(const volatile uint32_t *)&FTFx->XACCH3; 01461 // segmentIndex -= 32; 01462 // } 01463 // else 01464 // { 01465 // break; 01466 // } 01467 // 01468 // /* Determine if this address range is in a execute-only protection flash segment. */ 01469 // if ((~xacc) & (1u << segmentIndex)) 01470 // { 01471 // executeOnlySegmentCounter++; 01472 // } 01473 // 01474 // start += config->PFlashAccessSegmentSize; 01475 // } 01476 // 01477 // if (executeOnlySegmentCounter < 1u) 01478 // { 01479 // *access_state = kFLASH_accessStateUnLimited; 01480 // } 01481 // else if (executeOnlySegmentCounter < maxSupportedExecuteOnlySegmentCount) 01482 // { 01483 // *access_state = kFLASH_accessStateMixed; 01484 // } 01485 // else 01486 // { 01487 // *access_state = kFLASH_accessStateExecuteOnly; 01488 // } 01489 // } 01490 // #else 01491 // *access_state = kFLASH_accessStateUnLimited; 01492 // #endif /* FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL */ 01493 // 01494 // return (returnCode); 01495 // } 01496 01497 // status_t FLASH_GetProperty(flash_config_t *config, flash_property_tag_t whichProperty, uint32_t *value) 01498 // { 01499 // if ((config == NULL) || (value == NULL)) 01500 // { 01501 // return kStatus_FLASH_InvalidArgument; 01502 // } 01503 // 01504 // switch (whichProperty) 01505 // { 01506 // case kFLASH_propertyPflashSectorSize: 01507 // *value = config->PFlashSectorSize; 01508 // break; 01509 // 01510 // case kFLASH_propertyPflashTotalSize: 01511 // *value = config->PFlashTotalSize; 01512 // break; 01513 // 01514 // case kFLASH_propertyPflashBlockSize: 01515 // *value = config->PFlashTotalSize / FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT; 01516 // break; 01517 // 01518 // case kFLASH_propertyPflashBlockCount: 01519 // *value = config->PFlashBlockCount; 01520 // break; 01521 // 01522 // case kFLASH_propertyPflashBlockBaseAddr: 01523 // *value = config->PFlashBlockBase; 01524 // break; 01525 // 01526 // case kFLASH_propertyPflashFacSupport: 01527 // #if defined(FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL) 01528 // *value = FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL; 01529 // #else 01530 // *value = 0; 01531 // #endif /* FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL */ 01532 // break; 01533 // 01534 // case kFLASH_propertyPflashAccessSegmentSize: 01535 // *value = config->PFlashAccessSegmentSize; 01536 // break; 01537 // 01538 // case kFLASH_propertyPflashAccessSegmentCount: 01539 // *value = config->PFlashAccessSegmentCount; 01540 // break; 01541 // 01542 // #if FLASH_SSD_IS_FLEXNVM_ENABLED 01543 // case kFLASH_propertyDflashSectorSize: 01544 // *value = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SECTOR_SIZE; 01545 // break; 01546 // case kFLASH_propertyDflashTotalSize: 01547 // *value = config->DFlashTotalSize; 01548 // break; 01549 // case kFLASH_propertyDflashBlockSize: 01550 // *value = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SIZE; 01551 // break; 01552 // case kFLASH_propertyDflashBlockCount: 01553 // *value = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_COUNT; 01554 // break; 01555 // case kFLASH_propertyDflashBlockBaseAddr: 01556 // *value = config->DFlashBlockBase; 01557 // break; 01558 // case kFLASH_propertyEepromTotalSize: 01559 // *value = config->EEpromTotalSize; 01560 // break; 01561 // #endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ 01562 // 01563 // default: /* catch inputs that are not recognized */ 01564 // return kStatus_FLASH_UnknownProperty; 01565 // } 01566 // 01567 // return kStatus_FLASH_Success; 01568 // } 01569 01570 // #if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD 01571 // status_t FLASH_SetFlexramFunction(flash_config_t *config, flash_flexram_function_option_t option) 01572 // { 01573 // status_t status; 01574 // 01575 // if (config == NULL) 01576 // { 01577 // return kStatus_FLASH_InvalidArgument; 01578 // } 01579 // 01580 // status = flasn_check_flexram_function_option_range(option); 01581 // if (status != kStatus_FLASH_Success) 01582 // { 01583 // return status; 01584 // } 01585 // 01586 // /* preparing passing parameter to verify all block command */ 01587 // kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_1_2(FTFx_SET_FLEXRAM_FUNCTION, option, 0xFFFFU); 01588 // 01589 // /* calling flash command sequence function to execute the command */ 01590 // return flash_command_sequence(config); 01591 // } 01592 // #endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */ 01593 // 01594 // #if defined(FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD) && FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD 01595 // status_t FLASH_SwapControl(flash_config_t *config, 01596 // uint32_t address, 01597 // flash_swap_control_option_t option, 01598 // flash_swap_state_config_t *returnInfo) 01599 // { 01600 // status_t returnCode; 01601 // 01602 // if ((config == NULL) || (returnInfo == NULL)) 01603 // { 01604 // return kStatus_FLASH_InvalidArgument; 01605 // } 01606 // 01607 // if (address & (FSL_FEATURE_FLASH_PFLASH_SWAP_CONTROL_CMD_ADDRESS_ALIGMENT - 1)) 01608 // { 01609 // return kStatus_FLASH_AlignmentError; 01610 // } 01611 // 01612 // /* Make sure address provided is in the lower half of Program flash but not in the Flash Configuration Field */ 01613 // if ((address >= (config->PFlashTotalSize / 2)) || 01614 // ((address >= kFLASH_configAreaStart) && (address <= kFLASH_configAreaEnd))) 01615 // { 01616 // return kStatus_FLASH_SwapIndicatorAddressError; 01617 // } 01618 // 01619 // /* Check the option. */ 01620 // returnCode = flash_check_swap_control_option(option); 01621 // if (returnCode) 01622 // { 01623 // return returnCode; 01624 // } 01625 // 01626 // kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_SWAP_CONTROL, address); 01627 // kFCCOBx[1] = BYTES_JOIN_TO_WORD_1_3(option, 0xFFFFFFU); 01628 // 01629 // returnCode = flash_command_sequence(config); 01630 // 01631 // returnInfo->flashSwapState = (flash_swap_state_t)FTFx->FCCOB5; 01632 // returnInfo->currentSwapBlockStatus = (flash_swap_block_status_t)FTFx->FCCOB6; 01633 // returnInfo->nextSwapBlockStatus = (flash_swap_block_status_t)FTFx->FCCOB7; 01634 // 01635 // return returnCode; 01636 // } 01637 // #endif /* FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD */ 01638 // 01639 // #if defined(FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP) && FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP 01640 // status_t FLASH_Swap(flash_config_t *config, uint32_t address, flash_swap_function_option_t option) 01641 // { 01642 // flash_swap_state_config_t returnInfo; 01643 // status_t returnCode; 01644 // 01645 // memset(&returnInfo, 0xFFU, sizeof(returnInfo)); 01646 // 01647 // do 01648 // { 01649 // returnCode = FLASH_SwapControl(config, address, kFLASH_swapControlOptionReportStatus, &returnInfo); 01650 // if (returnCode != kStatus_FLASH_Success) 01651 // { 01652 // return returnCode; 01653 // } 01654 // 01655 // if (kFLASH_swapFunctionOptionDisable == option) 01656 // { 01657 // if (returnInfo.flashSwapState == kFLASH_swapStateDisabled) 01658 // { 01659 // return kStatus_FLASH_Success; 01660 // } 01661 // else if (returnInfo.flashSwapState == kFLASH_swapStateUninitialized) 01662 // { 01663 // /* The swap system changed to the DISABLED state with Program flash block 0 01664 // * located at relative flash address 0x0_0000 */ 01665 // returnCode = FLASH_SwapControl(config, address, kFLASH_swapControlOptionDisableSystem, &returnInfo); 01666 // } 01667 // else 01668 // { 01669 // /* Swap disable should be requested only when swap system is in the uninitialized state */ 01670 // return kStatus_FLASH_SwapSystemNotInUninitialized; 01671 // } 01672 // } 01673 // else 01674 // { 01675 // /* When first swap: the initial swap state is Uninitialized, flash swap inidicator address is unset, 01676 // * the swap procedure should be Uninitialized -> Update-Erased -> Complete. 01677 // * After the first swap has been completed, the flash swap inidicator address cannot be modified 01678 // * unless EraseAllBlocks command is issued, the swap procedure is changed to Update -> Update-Erased -> 01679 // * Complete. */ 01680 // switch (returnInfo.flashSwapState) 01681 // { 01682 // case kFLASH_swapStateUninitialized: 01683 // /* If current swap mode is Uninitialized, Initialize Swap to Initialized/READY state. */ 01684 // returnCode = 01685 // FLASH_SwapControl(config, address, kFLASH_swapControlOptionIntializeSystem, &returnInfo); 01686 // break; 01687 // case kFLASH_swapStateReady: 01688 // /* Validate whether the address provided to the swap system is matched to 01689 // * swap indicator address in the IFR */ 01690 // returnCode = flash_validate_swap_indicator_address(config, address); 01691 // if (returnCode == kStatus_FLASH_Success) 01692 // { 01693 // /* If current swap mode is Initialized/Ready, Initialize Swap to UPDATE state. */ 01694 // returnCode = 01695 // FLASH_SwapControl(config, address, kFLASH_swapControlOptionSetInUpdateState, &returnInfo); 01696 // } 01697 // break; 01698 // case kFLASH_swapStateUpdate: 01699 // /* If current swap mode is Update, Erase indicator sector in non active block 01700 // * to proceed swap system to update-erased state */ 01701 // returnCode = FLASH_Erase(config, address + (config->PFlashTotalSize >> 1), 01702 // FSL_FEATURE_FLASH_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT, kFLASH_apiEraseKey); 01703 // break; 01704 // case kFLASH_swapStateUpdateErased: 01705 // /* If current swap mode is Update or Update-Erased, progress Swap to COMPLETE State */ 01706 // returnCode = 01707 // FLASH_SwapControl(config, address, kFLASH_swapControlOptionSetInCompleteState, &returnInfo); 01708 // break; 01709 // case kFLASH_swapStateComplete: 01710 // break; 01711 // case kFLASH_swapStateDisabled: 01712 // /* When swap system is in disabled state, We need to clear swap system back to uninitialized 01713 // * by issuing EraseAllBlocks command */ 01714 // returnCode = kStatus_FLASH_SwapSystemNotInUninitialized; 01715 // break; 01716 // default: 01717 // returnCode = kStatus_FLASH_InvalidArgument; 01718 // break; 01719 // } 01720 // } 01721 // if (returnCode != kStatus_FLASH_Success) 01722 // { 01723 // break; 01724 // } 01725 // } while (!((kFLASH_swapStateComplete == returnInfo.flashSwapState) && (kFLASH_swapFunctionOptionEnable == option))); 01726 // 01727 // return returnCode; 01728 // } 01729 // #endif /* FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP */ 01730 // 01731 // #if defined(FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD) && FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD 01732 // status_t FLASH_ProgramPartition(flash_config_t *config, 01733 // flash_partition_flexram_load_option_t option, 01734 // uint32_t eepromDataSizeCode, 01735 // uint32_t flexnvmPartitionCode) 01736 // { 01737 // status_t returnCode; 01738 // 01739 // if (config == NULL) 01740 // { 01741 // return kStatus_FLASH_InvalidArgument; 01742 // } 01743 // 01744 // /* eepromDataSizeCode[7:6], flexnvmPartitionCode[7:4] should be all 1'b0 01745 // * or it will cause access error. */ 01746 // /* eepromDataSizeCode &= 0x3FU; */ 01747 // /* flexnvmPartitionCode &= 0x0FU; */ 01748 // 01749 // /* preparing passing parameter to program the flash block */ 01750 // kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_2_1(FTFx_PROGRAM_PARTITION, 0xFFFFU, option); 01751 // kFCCOBx[1] = BYTES_JOIN_TO_WORD_1_1_2(eepromDataSizeCode, flexnvmPartitionCode, 0xFFFFU); 01752 // 01753 // /* calling flash command sequence function to execute the command */ 01754 // returnCode = flash_command_sequence(config); 01755 // 01756 // flash_cache_clear(config); 01757 // 01758 // #if FLASH_SSD_IS_FLEXNVM_ENABLED 01759 // /* Data flash IFR will be updated by program partition command during reset sequence, 01760 // * so we just set reserved values for partitioned FlexNVM size here */ 01761 // config->EEpromTotalSize = FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_RESERVED; 01762 // config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; 01763 // #endif 01764 // 01765 // return (returnCode); 01766 // } 01767 // #endif /* FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD */ 01768 // 01769 // status_t FLASH_PflashSetProtection(flash_config_t *config, uint32_t protectStatus) 01770 // { 01771 // if (config == NULL) 01772 // { 01773 // return kStatus_FLASH_InvalidArgument; 01774 // } 01775 // 01776 // *kFPROT = protectStatus; 01777 // 01778 // if (protectStatus != *kFPROT) 01779 // { 01780 // return kStatus_FLASH_CommandFailure; 01781 // } 01782 // 01783 // return kStatus_FLASH_Success; 01784 // } 01785 // 01786 // status_t FLASH_PflashGetProtection(flash_config_t *config, uint32_t *protectStatus) 01787 // { 01788 // if ((config == NULL) || (protectStatus == NULL)) 01789 // { 01790 // return kStatus_FLASH_InvalidArgument; 01791 // } 01792 // 01793 // *protectStatus = *kFPROT; 01794 // 01795 // return kStatus_FLASH_Success; 01796 // } 01797 // 01798 // #if FLASH_SSD_IS_FLEXNVM_ENABLED 01799 // status_t FLASH_DflashSetProtection(flash_config_t *config, uint8_t protectStatus) 01800 // { 01801 // if (config == NULL) 01802 // { 01803 // return kStatus_FLASH_InvalidArgument; 01804 // } 01805 // 01806 // if ((config->DFlashTotalSize == 0) || (config->DFlashTotalSize == FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED)) 01807 // { 01808 // return kStatus_FLASH_CommandNotSupported; 01809 // } 01810 // 01811 // FTFx->FDPROT = protectStatus; 01812 // 01813 // if (FTFx->FDPROT != protectStatus) 01814 // { 01815 // return kStatus_FLASH_CommandFailure; 01816 // } 01817 // 01818 // return kStatus_FLASH_Success; 01819 // } 01820 // #endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ 01821 // 01822 // #if FLASH_SSD_IS_FLEXNVM_ENABLED 01823 // status_t FLASH_DflashGetProtection(flash_config_t *config, uint8_t *protectStatus) 01824 // { 01825 // if ((config == NULL) || (protectStatus == NULL)) 01826 // { 01827 // return kStatus_FLASH_InvalidArgument; 01828 // } 01829 // 01830 // if ((config->DFlashTotalSize == 0) || (config->DFlashTotalSize == FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED)) 01831 // { 01832 // return kStatus_FLASH_CommandNotSupported; 01833 // } 01834 // 01835 // *protectStatus = FTFx->FDPROT; 01836 // 01837 // return kStatus_FLASH_Success; 01838 // } 01839 // #endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ 01840 // 01841 // #if FLASH_SSD_IS_FLEXNVM_ENABLED 01842 // status_t FLASH_EepromSetProtection(flash_config_t *config, uint8_t protectStatus) 01843 // { 01844 // if (config == NULL) 01845 // { 01846 // return kStatus_FLASH_InvalidArgument; 01847 // } 01848 // 01849 // if ((config->EEpromTotalSize == 0) || (config->EEpromTotalSize == FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_RESERVED)) 01850 // { 01851 // return kStatus_FLASH_CommandNotSupported; 01852 // } 01853 // 01854 // FTFx->FEPROT = protectStatus; 01855 // 01856 // if (FTFx->FEPROT != protectStatus) 01857 // { 01858 // return kStatus_FLASH_CommandFailure; 01859 // } 01860 // 01861 // return kStatus_FLASH_Success; 01862 // } 01863 // #endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ 01864 // 01865 // #if FLASH_SSD_IS_FLEXNVM_ENABLED 01866 // status_t FLASH_EepromGetProtection(flash_config_t *config, uint8_t *protectStatus) 01867 // { 01868 // if ((config == NULL) || (protectStatus == NULL)) 01869 // { 01870 // return kStatus_FLASH_InvalidArgument; 01871 // } 01872 // 01873 // if ((config->EEpromTotalSize == 0) || (config->EEpromTotalSize == FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_RESERVED)) 01874 // { 01875 // return kStatus_FLASH_CommandNotSupported; 01876 // } 01877 // 01878 // *protectStatus = FTFx->FEPROT; 01879 // 01880 // return kStatus_FLASH_Success; 01881 // } 01882 // #endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ 01883 01884 #if FLASH_DRIVER_IS_FLASH_RESIDENT 01885 /*! 01886 * @brief Run flash command 01887 * 01888 * This function should be copied to RAM for execution to make sure that code works 01889 * properly even flash cache is disabled. 01890 * It is for flash-resident bootloader only, not technically required for ROM or 01891 * flashloader (RAM-resident bootloader). 01892 */ 01893 void flash_run_command(FTFx_REG_ACCESS_TYPE ftfx_fstat) 01894 { 01895 /* clear CCIF bit */ 01896 *ftfx_fstat = FTFx_FSTAT_CCIF_MASK; 01897 01898 /* Check CCIF bit of the flash status register, wait till it is set. 01899 * IP team indicates that this loop will always complete. */ 01900 while (!((*ftfx_fstat) & FTFx_FSTAT_CCIF_MASK)) 01901 { 01902 } 01903 } 01904 01905 /*! 01906 * @brief Be used for determining the size of flash_run_command() 01907 * 01908 * This function must be defined that lexically follows flash_run_command(), 01909 * so we can determine the size of flash_run_command() at runtime and not worry 01910 * about toolchain or code generation differences. 01911 */ 01912 void flash_run_command_end(void) 01913 { 01914 } 01915 01916 /*! 01917 * @brief Copy flash_run_command() to RAM 01918 * 01919 * This function copys the memory between flash_run_command() and flash_run_command_end() 01920 * into the buffer which is also means that copying flash_run_command() to RAM. 01921 */ 01922 static void copy_flash_run_command(uint8_t *flashRunCommand) 01923 { 01924 /* Calculate the valid length of flash_run_command() memory. 01925 * Set max size(64 bytes) as default function size, in case some compiler allocates 01926 * flash_run_command_end ahead of flash_run_command. */ 01927 uint32_t funcLength = kFLASH_executeInRamFunctionMaxSize ; 01928 uint32_t flash_run_command_start_addr = (uint32_t)flash_run_command & (~1U); 01929 uint32_t flash_run_command_end_addr = (uint32_t)flash_run_command_end & (~1U); 01930 if (flash_run_command_end_addr > flash_run_command_start_addr) 01931 { 01932 funcLength = flash_run_command_end_addr - flash_run_command_start_addr; 01933 01934 assert(funcLength <= kFLASH_executeInRamFunctionMaxSize ); 01935 01936 /* In case some compiler allocates other function in the middle of flash_run_command 01937 * and flash_run_command_end. */ 01938 if (funcLength > kFLASH_executeInRamFunctionMaxSize ) 01939 { 01940 funcLength = kFLASH_executeInRamFunctionMaxSize ; 01941 } 01942 } 01943 01944 /* Since the value of ARM function pointer is always odd, but the real start address 01945 * of function memory should be even, that's why -1 and +1 operation exist. */ 01946 memcpy((void *)flashRunCommand, (void *)flash_run_command_start_addr, funcLength); 01947 callFlashRunCommand = (void (*)(FTFx_REG_ACCESS_TYPE ftfx_fstat))((uint32_t)flashRunCommand + 1); 01948 } 01949 #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ 01950 01951 /*! 01952 * @brief Flash Command Sequence 01953 * 01954 * This function is used to perform the command write sequence to the flash. 01955 * 01956 * @param driver Pointer to storage for the driver runtime state. 01957 * @return An error code or kStatus_FLASH_Success 01958 */ 01959 static status_t flash_command_sequence(flash_config_t *config) 01960 { 01961 uint8_t registerValue; 01962 01963 #if FLASH_DRIVER_IS_FLASH_RESIDENT 01964 /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register */ 01965 FTFx->FSTAT = FTFx_FSTAT_RDCOLERR_MASK | FTFx_FSTAT_ACCERR_MASK | FTFx_FSTAT_FPVIOL_MASK; 01966 01967 status_t returnCode = flash_check_execute_in_ram_function_info(config); 01968 if (kStatus_FLASH_Success != returnCode) 01969 { 01970 return returnCode; 01971 } 01972 01973 /* We pass the ftfx_fstat address as a parameter to flash_run_comamnd() instead of using 01974 * pre-processed MICRO sentences or operating global variable in flash_run_comamnd() 01975 * to make sure that flash_run_command() will be compiled into position-independent code (PIC). */ 01976 callFlashRunCommand((FTFx_REG_ACCESS_TYPE)(&FTFx->FSTAT)); 01977 #else 01978 /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register */ 01979 FTFx->FSTAT = FTFx_FSTAT_RDCOLERR_MASK | FTFx_FSTAT_ACCERR_MASK | FTFx_FSTAT_FPVIOL_MASK; 01980 01981 /* clear CCIF bit */ 01982 FTFx->FSTAT = FTFx_FSTAT_CCIF_MASK; 01983 01984 /* Check CCIF bit of the flash status register, wait till it is set. 01985 * IP team indicates that this loop will always complete. */ 01986 while (!(FTFx->FSTAT & FTFx_FSTAT_CCIF_MASK)) 01987 { 01988 } 01989 #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ 01990 01991 /* Check error bits */ 01992 /* Get flash status register value */ 01993 registerValue = FTFx->FSTAT; 01994 01995 /* checking access error */ 01996 if (registerValue & FTFx_FSTAT_ACCERR_MASK) 01997 { 01998 return kStatus_FLASH_AccessError ; 01999 } 02000 /* checking protection error */ 02001 else if (registerValue & FTFx_FSTAT_FPVIOL_MASK) 02002 { 02003 return kStatus_FLASH_ProtectionViolation ; 02004 } 02005 /* checking MGSTAT0 non-correctable error */ 02006 else if (registerValue & FTFx_FSTAT_MGSTAT0_MASK) 02007 { 02008 return kStatus_FLASH_CommandFailure ; 02009 } 02010 else 02011 { 02012 return kStatus_FLASH_Success ; 02013 } 02014 } 02015 02016 #if FLASH_DRIVER_IS_FLASH_RESIDENT 02017 /*! 02018 * @brief Run flash cache clear command 02019 * 02020 * This function should be copied to RAM for execution to make sure that code works 02021 * properly even flash cache is disabled. 02022 * It is for flash-resident bootloader only, not technically required for ROM or 02023 * flashloader (RAM-resident bootloader). 02024 */ 02025 void flash_cache_clear_command(FTFx_REG32_ACCESS_TYPE ftfx_reg) 02026 { 02027 #if defined(FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS 02028 *ftfx_reg |= MCM_PLACR_CFCC_MASK; 02029 #elif defined(FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS 02030 #if defined(FMC_PFB01CR_CINV_WAY_MASK) 02031 *ftfx_reg = (*ftfx_reg & ~FMC_PFB01CR_CINV_WAY_MASK) | FMC_PFB01CR_CINV_WAY(~0); 02032 #else 02033 *ftfx_reg = (*ftfx_reg & ~FMC_PFB0CR_CINV_WAY_MASK) | FMC_PFB0CR_CINV_WAY(~0); 02034 #endif 02035 #elif defined(FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS 02036 *ftfx_reg |= MSCM_OCMDR_OCMC1(2); 02037 *ftfx_reg |= MSCM_OCMDR_OCMC1(1); 02038 #else 02039 /* #error "Unknown flash cache controller" */ 02040 #endif /* FSL_FEATURE_FTFx_MCM_FLASH_CACHE_CONTROLS */ 02041 /* Memory barriers for good measure. 02042 * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */ 02043 __ISB(); 02044 __DSB(); 02045 } 02046 02047 /*! 02048 * @brief Be used for determining the size of flash_cache_clear_command() 02049 * 02050 * This function must be defined that lexically follows flash_cache_clear_command(), 02051 * so we can determine the size of flash_cache_clear_command() at runtime and not worry 02052 * about toolchain or code generation differences. 02053 */ 02054 void flash_cache_clear_command_end(void) 02055 { 02056 } 02057 02058 /*! 02059 * @brief Copy flash_cache_clear_command() to RAM 02060 * 02061 * This function copys the memory between flash_cache_clear_command() and flash_cache_clear_command_end() 02062 * into the buffer which is also means that copying flash_cache_clear_command() to RAM. 02063 */ 02064 static void copy_flash_cache_clear_command(uint8_t *flashCacheClearCommand) 02065 { 02066 /* Calculate the valid length of flash_cache_clear_command() memory. 02067 * Set max size(64 bytes) as default function size, in case some compiler allocates 02068 * flash_cache_clear_command_end ahead of flash_cache_clear_command. */ 02069 uint32_t funcLength = kFLASH_executeInRamFunctionMaxSize ; 02070 uint32_t flash_cache_clear_command_start_addr = (uint32_t)flash_cache_clear_command & (~1U); 02071 uint32_t flash_cache_clear_command_end_addr = (uint32_t)flash_cache_clear_command_end & (~1U); 02072 if (flash_cache_clear_command_end_addr > flash_cache_clear_command_start_addr) 02073 { 02074 funcLength = flash_cache_clear_command_end_addr - flash_cache_clear_command_start_addr; 02075 02076 assert(funcLength <= kFLASH_executeInRamFunctionMaxSize ); 02077 02078 /* In case some compiler allocates other function in the middle of flash_cache_clear_command 02079 * and flash_cache_clear_command_end. */ 02080 if (funcLength > kFLASH_executeInRamFunctionMaxSize ) 02081 { 02082 funcLength = kFLASH_executeInRamFunctionMaxSize ; 02083 } 02084 } 02085 02086 /* Since the value of ARM function pointer is always odd, but the real start address 02087 * of function memory should be even, that's why -1 and +1 operation exist. */ 02088 memcpy((void *)flashCacheClearCommand, (void *)flash_cache_clear_command_start_addr, funcLength); 02089 callFlashCacheClearCommand = (void (*)(FTFx_REG32_ACCESS_TYPE ftfx_reg))((uint32_t)flashCacheClearCommand + 1); 02090 } 02091 #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ 02092 02093 /*! 02094 * @brief Flash Cache Clear 02095 * 02096 * This function is used to perform the cache clear to the flash. 02097 */ 02098 #if (defined(__ICCARM__)) 02099 #pragma optimize = none 02100 void flash_cache_clear(flash_config_t *config) 02101 #elif (defined(__CC_ARM)) 02102 #pragma push 02103 #pragma O0 02104 void flash_cache_clear(flash_config_t *config) 02105 #elif (!defined(__GNUC__)) 02106 /* #pragma GCC push_options */ 02107 /* #pragma GCC optimize("O0") */ 02108 void __attribute__((optimize("O0"))) flash_cache_clear(flash_config_t *config) 02109 #else 02110 #error "Unknown compiler" 02111 #endif 02112 { 02113 #if FLASH_DRIVER_IS_FLASH_RESIDENT 02114 status_t returnCode = flash_check_execute_in_ram_function_info(config); 02115 if (kStatus_FLASH_Success != returnCode) 02116 { 02117 return; 02118 } 02119 02120 /* We pass the ftfx register address as a parameter to flash_cache_clear_comamnd() instead of using 02121 * pre-processed MACROs or a global variable in flash_cache_clear_comamnd() 02122 * to make sure that flash_cache_clear_command() will be compiled into position-independent code (PIC). */ 02123 #if defined(FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS 02124 #if defined(MCM) 02125 callFlashCacheClearCommand((FTFx_REG32_ACCESS_TYPE)&MCM->PLACR); 02126 #endif 02127 #if defined(MCM0) 02128 callFlashCacheClearCommand((FTFx_REG32_ACCESS_TYPE)&MCM0->PLACR); 02129 #endif 02130 #if defined(MCM1) 02131 callFlashCacheClearCommand((FTFx_REG32_ACCESS_TYPE)&MCM1->PLACR); 02132 #endif 02133 #elif defined(FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS 02134 #if defined(FMC_PFB01CR_CINV_WAY_MASK) 02135 callFlashCacheClearCommand((FTFx_REG32_ACCESS_TYPE)&FMC->PFB01CR); 02136 #else 02137 callFlashCacheClearCommand((FTFx_REG32_ACCESS_TYPE)&FMC->PFB0CR); 02138 #endif 02139 #elif defined(FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS 02140 callFlashCacheClearCommand((FTFx_REG32_ACCESS_TYPE)&MSCM->OCMDR[0]); 02141 #else 02142 /* #error "Unknown flash cache controller" */ 02143 /* meaningless code, just a workaround to solve warning*/ 02144 callFlashCacheClearCommand((FTFx_REG32_ACCESS_TYPE)0); 02145 #endif /* FSL_FEATURE_FTFx_MCM_FLASH_CACHE_CONTROLS */ 02146 02147 #else 02148 02149 #if defined(FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS 02150 #if defined(MCM) 02151 MCM->PLACR |= MCM_PLACR_CFCC_MASK; 02152 #endif 02153 #if defined(MCM0) 02154 MCM0->PLACR |= MCM_PLACR_CFCC_MASK; 02155 #endif 02156 #if defined(MCM1) 02157 MCM1->PLACR |= MCM_PLACR_CFCC_MASK; 02158 #endif 02159 #elif defined(FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS 02160 #if defined(FMC_PFB01CR_CINV_WAY_MASK) 02161 FMC->PFB01CR = (FMC->PFB01CR & ~FMC_PFB01CR_CINV_WAY_MASK) | FMC_PFB01CR_CINV_WAY(~0); 02162 #else 02163 FMC->PFB0CR = (FMC->PFB0CR & ~FMC_PFB0CR_CINV_WAY_MASK) | FMC_PFB0CR_CINV_WAY(~0); 02164 #endif 02165 #elif defined(FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS 02166 MSCM->OCMDR[0] |= MSCM_OCMDR_OCMC1(2); 02167 MSCM->OCMDR[0] |= MSCM_OCMDR_OCMC1(1); 02168 #else 02169 /* #error "Unknown flash cache controller" */ 02170 #endif /* FSL_FEATURE_FTFx_MCM_FLASH_CACHE_CONTROLS */ 02171 #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ 02172 } 02173 #if (defined(__CC_ARM)) 02174 #pragma pop 02175 #endif 02176 #if (defined(__GNUC__)) 02177 /* #pragma GCC pop_options */ 02178 #endif 02179 02180 #if FLASH_DRIVER_IS_FLASH_RESIDENT 02181 /*! @brief Check whether flash execute-in-ram functions are ready */ 02182 static status_t flash_check_execute_in_ram_function_info(flash_config_t *config) 02183 { 02184 flash_execute_in_ram_function_config_t *flashExecuteInRamFunctionInfo; 02185 02186 if (config == NULL) 02187 { 02188 return kStatus_FLASH_InvalidArgument ; 02189 } 02190 02191 flashExecuteInRamFunctionInfo = (flash_execute_in_ram_function_config_t *)config->flashExecuteInRamFunctionInfo ; 02192 02193 if ((config->flashExecuteInRamFunctionInfo ) && 02194 (kFLASH_executeInRamFunctionTotalNum == flashExecuteInRamFunctionInfo->activeFunctionCount )) 02195 { 02196 return kStatus_FLASH_Success ; 02197 } 02198 02199 return kStatus_FLASH_ExecuteInRamFunctionNotReady ; 02200 } 02201 #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ 02202 02203 /*! @brief Validates the range and alignment of the given address range.*/ 02204 static status_t flash_check_range(flash_config_t *config, 02205 uint32_t startAddress, 02206 uint32_t lengthInBytes, 02207 uint32_t alignmentBaseline) 02208 { 02209 if (config == NULL) 02210 { 02211 return kStatus_FLASH_InvalidArgument ; 02212 } 02213 02214 /* Verify the start and length are alignmentBaseline aligned. */ 02215 if ((startAddress & (alignmentBaseline - 1)) || (lengthInBytes & (alignmentBaseline - 1))) 02216 { 02217 return kStatus_FLASH_AlignmentError ; 02218 } 02219 02220 /* check for valid range of the target addresses */ 02221 #if !FLASH_SSD_IS_FLEXNVM_ENABLED 02222 if ((startAddress < config->PFlashBlockBase) || 02223 ((startAddress + lengthInBytes) > (config->PFlashBlockBase + config->PFlashTotalSize ))) 02224 #else 02225 if (!(((startAddress >= config->PFlashBlockBase ) && 02226 ((startAddress + lengthInBytes) <= (config->PFlashBlockBase + config->PFlashTotalSize ))) || 02227 ((startAddress >= config->DFlashBlockBase ) && 02228 ((startAddress + lengthInBytes) <= (config->DFlashBlockBase + config->DFlashTotalSize ))))) 02229 #endif 02230 { 02231 return kStatus_FLASH_AddressError ; 02232 } 02233 02234 return kStatus_FLASH_Success ; 02235 } 02236 02237 /*! @brief Gets the right address, sector and block size of current flash type which is indicated by address.*/ 02238 static status_t flash_get_matched_operation_info(flash_config_t *config, 02239 uint32_t address, 02240 flash_operation_config_t *info) 02241 { 02242 if (config == NULL) 02243 { 02244 return kStatus_FLASH_InvalidArgument ; 02245 } 02246 02247 /* Clean up info Structure*/ 02248 memset(info, 0, sizeof(flash_operation_config_t)); 02249 02250 #if FLASH_SSD_IS_FLEXNVM_ENABLED 02251 if ((address >= config->DFlashBlockBase ) && (address <= (config->DFlashBlockBase + config->DFlashTotalSize ))) 02252 { 02253 info->convertedAddress = address - config->DFlashBlockBase + 0x800000U; 02254 info->activeSectorSize = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SECTOR_SIZE; 02255 info->activeBlockSize = config->DFlashTotalSize / FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_COUNT; 02256 02257 info->blockWriteUnitSize = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_WRITE_UNIT_SIZE; 02258 info->sectorCmdAddressAligment = FSL_FEATURE_FLASH_FLEX_NVM_SECTOR_CMD_ADDRESS_ALIGMENT; 02259 info->sectionCmdAddressAligment = FSL_FEATURE_FLASH_FLEX_NVM_SECTION_CMD_ADDRESS_ALIGMENT; 02260 info->resourceCmdAddressAligment = FSL_FEATURE_FLASH_FLEX_NVM_RESOURCE_CMD_ADDRESS_ALIGMENT; 02261 info->checkCmdAddressAligment = FSL_FEATURE_FLASH_FLEX_NVM_CHECK_CMD_ADDRESS_ALIGMENT; 02262 } 02263 else 02264 #endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ 02265 { 02266 info->convertedAddress = address; 02267 info->activeSectorSize = config->PFlashSectorSize ; 02268 info->activeBlockSize = config->PFlashTotalSize / config->PFlashBlockCount ; 02269 02270 info->blockWriteUnitSize = FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE; 02271 info->sectorCmdAddressAligment = FSL_FEATURE_FLASH_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT; 02272 info->sectionCmdAddressAligment = FSL_FEATURE_FLASH_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT; 02273 info->resourceCmdAddressAligment = FSL_FEATURE_FLASH_PFLASH_RESOURCE_CMD_ADDRESS_ALIGMENT; 02274 info->checkCmdAddressAligment = FSL_FEATURE_FLASH_PFLASH_CHECK_CMD_ADDRESS_ALIGMENT; 02275 } 02276 02277 return kStatus_FLASH_Success ; 02278 } 02279 02280 /*! @brief Validates the given user key for flash erase APIs.*/ 02281 static status_t flash_check_user_key(uint32_t key) 02282 { 02283 /* Validate the user key */ 02284 if (key != kFLASH_apiEraseKey ) 02285 { 02286 return kStatus_FLASH_EraseKeyError ; 02287 } 02288 02289 return kStatus_FLASH_Success ; 02290 } 02291 02292 // #if FLASH_SSD_IS_FLEXNVM_ENABLED 02293 // /*! @brief Updates FlexNVM memory partition status according to data flash 0 IFR.*/ 02294 // static status_t flash_update_flexnvm_memory_partition_status(flash_config_t *config) 02295 // { 02296 // struct 02297 // { 02298 // uint32_t reserved0; 02299 // uint8_t FlexNVMPartitionCode; 02300 // uint8_t EEPROMDataSetSize; 02301 // uint16_t reserved1; 02302 // } dataIFRReadOut; 02303 // status_t returnCode; 02304 // 02305 // if (config == NULL) 02306 // { 02307 // return kStatus_FLASH_InvalidArgument; 02308 // } 02309 // 02310 // /* Get FlexNVM memory partition info from data flash IFR */ 02311 // returnCode = FLASH_ReadResource(config, DFLASH_IFR_READRESOURCE_START_ADDRESS, (uint32_t *)&dataIFRReadOut, 02312 // sizeof(dataIFRReadOut), kFLASH_resourceOptionFlashIfr); 02313 // if (returnCode != kStatus_FLASH_Success) 02314 // { 02315 // return kStatus_FLASH_PartitionStatusUpdateFailure; 02316 // } 02317 // 02318 // /* Fill out partitioned EEPROM size */ 02319 // dataIFRReadOut.EEPROMDataSetSize &= 0x0FU; 02320 // switch (dataIFRReadOut.EEPROMDataSetSize) 02321 // { 02322 // case 0x00U: 02323 // config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0000; 02324 // break; 02325 // case 0x01U: 02326 // config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0001; 02327 // break; 02328 // case 0x02U: 02329 // config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0010; 02330 // break; 02331 // case 0x03U: 02332 // config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0011; 02333 // break; 02334 // case 0x04U: 02335 // config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0100; 02336 // break; 02337 // case 0x05U: 02338 // config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0101; 02339 // break; 02340 // case 0x06U: 02341 // config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0110; 02342 // break; 02343 // case 0x07U: 02344 // config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0111; 02345 // break; 02346 // case 0x08U: 02347 // config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1000; 02348 // break; 02349 // case 0x09U: 02350 // config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1001; 02351 // break; 02352 // case 0x0AU: 02353 // config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1010; 02354 // break; 02355 // case 0x0BU: 02356 // config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1011; 02357 // break; 02358 // case 0x0CU: 02359 // config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1100; 02360 // break; 02361 // case 0x0DU: 02362 // config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1101; 02363 // break; 02364 // case 0x0EU: 02365 // config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1110; 02366 // break; 02367 // case 0x0FU: 02368 // config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1111; 02369 // break; 02370 // default: 02371 // config->EEpromTotalSize = FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_RESERVED; 02372 // break; 02373 // } 02374 // 02375 // /* Fill out partitioned DFlash size */ 02376 // dataIFRReadOut.FlexNVMPartitionCode &= 0x0FU; 02377 // switch (dataIFRReadOut.FlexNVMPartitionCode) 02378 // { 02379 // case 0x00U: 02380 // #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0000 != 0xFFFFFFFF) 02381 // config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0000; 02382 // #else 02383 // config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; 02384 // #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0000 */ 02385 // break; 02386 // case 0x01U: 02387 // #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0001 != 0xFFFFFFFF) 02388 // config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0001; 02389 // #else 02390 // config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; 02391 // #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0001 */ 02392 // break; 02393 // case 0x02U: 02394 // #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0010 != 0xFFFFFFFF) 02395 // config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0010; 02396 // #else 02397 // config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; 02398 // #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0010 */ 02399 // break; 02400 // case 0x03U: 02401 // #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0011 != 0xFFFFFFFF) 02402 // config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0011; 02403 // #else 02404 // config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; 02405 // #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0011 */ 02406 // break; 02407 // case 0x04U: 02408 // #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0100 != 0xFFFFFFFF) 02409 // config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0100; 02410 // #else 02411 // config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; 02412 // #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0100 */ 02413 // break; 02414 // case 0x05U: 02415 // #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0101 != 0xFFFFFFFF) 02416 // config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0101; 02417 // #else 02418 // config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; 02419 // #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0101 */ 02420 // break; 02421 // case 0x06U: 02422 // #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0110 != 0xFFFFFFFF) 02423 // config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0110; 02424 // #else 02425 // config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; 02426 // #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0110 */ 02427 // break; 02428 // case 0x07U: 02429 // #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0111 != 0xFFFFFFFF) 02430 // config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0111; 02431 // #else 02432 // config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; 02433 // #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0111 */ 02434 // break; 02435 // case 0x08U: 02436 // #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1000 != 0xFFFFFFFF) 02437 // config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1000; 02438 // #else 02439 // config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; 02440 // #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1000 */ 02441 // break; 02442 // case 0x09U: 02443 // #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1001 != 0xFFFFFFFF) 02444 // config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1001; 02445 // #else 02446 // config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; 02447 // #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1001 */ 02448 // break; 02449 // case 0x0AU: 02450 // #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1010 != 0xFFFFFFFF) 02451 // config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1010; 02452 // #else 02453 // config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; 02454 // #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1010 */ 02455 // break; 02456 // case 0x0BU: 02457 // #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1011 != 0xFFFFFFFF) 02458 // config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1011; 02459 // #else 02460 // config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; 02461 // #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1011 */ 02462 // break; 02463 // case 0x0CU: 02464 // #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1100 != 0xFFFFFFFF) 02465 // config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1100; 02466 // #else 02467 // config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; 02468 // #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1100 */ 02469 // break; 02470 // case 0x0DU: 02471 // #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1101 != 0xFFFFFFFF) 02472 // config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1101; 02473 // #else 02474 // config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; 02475 // #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1101 */ 02476 // break; 02477 // case 0x0EU: 02478 // #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1110 != 0xFFFFFFFF) 02479 // config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1110; 02480 // #else 02481 // config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; 02482 // #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1110 */ 02483 // break; 02484 // case 0x0FU: 02485 // #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1111 != 0xFFFFFFFF) 02486 // config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1111; 02487 // #else 02488 // config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; 02489 // #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1111 */ 02490 // break; 02491 // default: 02492 // config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; 02493 // break; 02494 // } 02495 // 02496 // return kStatus_FLASH_Success; 02497 // } 02498 // #endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ 02499 02500 // #if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD 02501 // /*! @brief Validates the range of the given resource address.*/ 02502 // static status_t flash_check_resource_range(uint32_t start, 02503 // uint32_t lengthInBytes, 02504 // uint32_t alignmentBaseline, 02505 // flash_read_resource_option_t option) 02506 // { 02507 // status_t status; 02508 // uint32_t maxReadbleAddress; 02509 // 02510 // if ((start & (alignmentBaseline - 1)) || (lengthInBytes & (alignmentBaseline - 1))) 02511 // { 02512 // return kStatus_FLASH_AlignmentError; 02513 // } 02514 // 02515 // status = kStatus_FLASH_Success; 02516 // 02517 // maxReadbleAddress = start + lengthInBytes - 1; 02518 // if (option == kFLASH_resourceOptionVersionId) 02519 // { 02520 // if ((start != kFLASH_resourceRangeVersionIdStart) || 02521 // ((start + lengthInBytes - 1) != kFLASH_resourceRangeVersionIdEnd)) 02522 // { 02523 // status = kStatus_FLASH_InvalidArgument; 02524 // } 02525 // } 02526 // else if (option == kFLASH_resourceOptionFlashIfr) 02527 // { 02528 // if (maxReadbleAddress < kFLASH_resourceRangePflashIfrSizeInBytes) 02529 // { 02530 // } 02531 // #if defined(FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP) && FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP 02532 // else if ((start >= kFLASH_resourceRangePflashSwapIfrStart) && 02533 // (maxReadbleAddress <= kFLASH_resourceRangePflashSwapIfrEnd)) 02534 // { 02535 // } 02536 // #endif /* FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP */ 02537 // else if ((start >= kFLASH_resourceRangeDflashIfrStart) && 02538 // (maxReadbleAddress <= kFLASH_resourceRangeDflashIfrEnd)) 02539 // { 02540 // } 02541 // else 02542 // { 02543 // status = kStatus_FLASH_InvalidArgument; 02544 // } 02545 // } 02546 // else 02547 // { 02548 // status = kStatus_FLASH_InvalidArgument; 02549 // } 02550 // 02551 // return status; 02552 // } 02553 // #endif /* FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD */ 02554 02555 // #if defined(FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD) && FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD 02556 // /*! @brief Validates the gived swap control option.*/ 02557 // static status_t flash_check_swap_control_option(flash_swap_control_option_t option) 02558 // { 02559 // if ((option == kFLASH_swapControlOptionIntializeSystem) || (option == kFLASH_swapControlOptionSetInUpdateState) || 02560 // (option == kFLASH_swapControlOptionSetInCompleteState) || (option == kFLASH_swapControlOptionReportStatus) || 02561 // (option == kFLASH_swapControlOptionDisableSystem)) 02562 // { 02563 // return kStatus_FLASH_Success; 02564 // } 02565 // 02566 // return kStatus_FLASH_InvalidArgument; 02567 // } 02568 // #endif /* FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD */ 02569 // 02570 // #if defined(FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP) && FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP 02571 // /*! @brief Validates the gived address to see if it is equal to swap indicator address in pflash swap IFR.*/ 02572 // static status_t flash_validate_swap_indicator_address(flash_config_t *config, uint32_t address) 02573 // { 02574 // flash_swap_ifr_field_config_t flashSwapIfrField; 02575 // uint32_t swapIndicatorAddress; 02576 // 02577 // status_t returnCode; 02578 // returnCode = FLASH_ReadResource(config, kFLASH_resourceRangePflashSwapIfrStart, (uint32_t *)&flashSwapIfrField, 02579 // sizeof(flash_swap_ifr_field_config_t), kFLASH_resourceOptionFlashIfr); 02580 // if (returnCode != kStatus_FLASH_Success) 02581 // { 02582 // return returnCode; 02583 // } 02584 // 02585 // /* The high 2 byte value of Swap Indicator Address is stored in Program Flash Swap IFR Field, 02586 // * the low 4 bit value of Swap Indicator Address is always 4'b0000 */ 02587 // swapIndicatorAddress = 02588 // (uint32_t)flashSwapIfrField.swapIndicatorAddress * FSL_FEATURE_FLASH_PFLASH_SWAP_CONTROL_CMD_ADDRESS_ALIGMENT; 02589 // if (address != swapIndicatorAddress) 02590 // { 02591 // return kStatus_FLASH_SwapIndicatorAddressError; 02592 // } 02593 // 02594 // return returnCode; 02595 // } 02596 // #endif /* FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP */ 02597 // 02598 // #if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD 02599 // /*! @brief Validates the gived flexram function option.*/ 02600 // static inline status_t flasn_check_flexram_function_option_range(flash_flexram_function_option_t option) 02601 // { 02602 // if ((option != kFLASH_flexramFunctionOptionAvailableAsRam) && 02603 // (option != kFLASH_flexramFunctionOptionAvailableForEeprom)) 02604 // { 02605 // return kStatus_FLASH_InvalidArgument; 02606 // } 02607 // 02608 // return kStatus_FLASH_Success; 02609 // } 02610 // #endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */
Generated on Tue Jul 12 2022 15:37:17 by
