// See flash.h for documentation of this function. status_t flash_program_once(flash_driver_t * driver, uint32_t index, uint32_t *src, uint32_t lengthInBytes) { if (src == NULL) { return kStatus_InvalidArgument; } status_t returnCode = flash_check_access_ifr_range(driver, index, lengthInBytes); if (kStatus_Success != returnCode) { return returnCode; } // pass paramters to FTFx HW_FTFx_FCCOBx_WR(FTFx_BASE, 0, FTFx_PROGRAM_ONCE); HW_FTFx_FCCOBx_WR(FTFx_BASE, 1, index); kFCCOBx[1] = *src; if (index > FLASH_PROGRAM_ONCE_MAX_ID_4BYTES) { kFCCOBx[2] = *(src + 1); } // calling flash command sequence function to execute the command returnCode = flash_command_sequence(); return returnCode; }
// See flash.h for documentation of this function. status_t flash_erase_all_unsecure(flash_driver_t * driver) { if (driver == NULL) { return kStatus_InvalidArgument; } // Prepare passing parameter to erase all flash blocks (unsecure). // 1st element for the FCCOB register. HW_FTFx_FCCOBx_WR(0, FTFx_ERASE_ALL_BLOCK_UNSECURE); // Call flash command sequence function to execute the command. return flash_command_sequence(); }
// See flash.h for documentation of this function. status_t flash_erase(flash_driver_t * driver, uint32_t start, uint32_t lengthInBytes) { // Check the supplied address range. status_t returnCode = flash_check_range(driver, start, lengthInBytes); if (returnCode) { return returnCode; } uint32_t endAddress; // storing end address uint32_t numberOfSectors; // number of sectors calculated by endAddress // calculating Flash end address endAddress = start + lengthInBytes - 1; // re-calculate the endAddress and align it to the start of the next sector // which will be used in the comparison below if (endAddress % FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE) { numberOfSectors = endAddress / FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE + 1; endAddress = numberOfSectors * FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE - 1; } // the start address will increment to the next sector address // until it reaches the endAdddress while (start <= endAddress) { // preparing passing parameter to erase a flash block kFCCOBx[0] = start; HW_FTFx_FCCOBx_WR(0, FTFx_ERASE_SECTOR); // calling flash command sequence function to execute the command returnCode = flash_command_sequence(); // checking the success of command execution if (kStatus_Success != returnCode) { break; } else { // Increment to the next sector start += FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE; } } return(returnCode); }
// See flash.h for documentation of this function. status_t flash_erase_all_unsecure(flash_driver_t * driver, uint32_t key) { // Validate the user key status_t returnCode = flash_check_user_key(key); if (returnCode) { return returnCode; } if (driver == NULL) { return kStatus_InvalidArgument; } // Prepare passing parameter to erase all flash blocks (unsecure). // 1st element for the FCCOB register. HW_FTFx_FCCOBx_WR(FTFx_BASE, 0, FTFx_ERASE_ALL_BLOCK_UNSECURE); // Call flash command sequence function to execute the command. return flash_command_sequence(); }
// See flash.h for documentation of this function. status_t flash_program_section(flash_driver_t * driver, uint32_t start, uint32_t * src, uint32_t lengthInBytes) { #if (!FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD) { return kStatus_FlashCommandNotSupported; } #else if (src == NULL) { return kStatus_InvalidArgument; } // Check the supplied address range. status_t returnCode = flash_check_range(driver, start, lengthInBytes, FSL_FEATURE_FLASH_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT); if (returnCode) { return returnCode; } #if FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD // Switch function of FlexRAM if needed bool needSwitchFlexRamMode = false; if (!(FTFx->FCNFG & BM_FTFx_FCNFG_RAMRDY)) { needSwitchFlexRamMode = true; returnCode = flash_set_flexram_function(driver, kFlash_FlexRAM_Available_As_RAM); if (returnCode != kStatus_Success) { return returnCode; } } #endif // FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD while(lengthInBytes > 0) { // Make sure the write operation doesn't span two sectors uint32_t endAddressOfCurrentSector = ALIGN_UP(start, driver->PFlashSectorSize); uint32_t lengthTobeProgrammedOfCurrentSector; if (lengthInBytes + start > endAddressOfCurrentSector) { lengthTobeProgrammedOfCurrentSector = endAddressOfCurrentSector - start; } else { lengthTobeProgrammedOfCurrentSector = lengthInBytes; } uint32_t currentOffset = 0; // Program Current Sector while(lengthTobeProgrammedOfCurrentSector > 0) { // Make sure the program size doesn't exceeds Accelearating RAM size uint32_t programSizeCurrentPass; if(lengthTobeProgrammedOfCurrentSector > kFlash_AccelerateRam_Size) { programSizeCurrentPass = kFlash_AccelerateRam_Size; } else { programSizeCurrentPass = lengthTobeProgrammedOfCurrentSector; } // Copy data to FlexRAM memcpy((void*)FSL_FEATURE_FLASH_FLEX_RAM_START_ADDRESS, (void*)(start + currentOffset), programSizeCurrentPass); // Set start address of the data to be programmed kFCCOBx[0] = start + currentOffset; // Set program size in terms of 128bits kFCCOBx[1] = programSizeCurrentPass / FSL_FEATURE_FLASH_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT; // Set FTFx Command to PSEC HW_FTFx_FCCOBx_WR(FTFx_BASE, 0, FTFx_PROGRAM_SECTION); // Peform command sequence returnCode = flash_command_sequence(); // calling flash callback function if it is available if (driver->PFlashCallback) { driver->PFlashCallback(); } if (returnCode != kStatus_Success) { break; } lengthTobeProgrammedOfCurrentSector -= programSizeCurrentPass; currentOffset += programSizeCurrentPass; } if (returnCode != kStatus_Success) { break; } start += currentOffset; lengthInBytes -= currentOffset; } #if FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD // Restore function of FlexRAM if needed. if (needSwitchFlexRamMode) { returnCode = flash_set_flexram_function(driver, kFlash_FlexRAM_Available_For_EEPROM); } #endif // FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD return returnCode; #endif // FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD }