上一篇:【飞思卡尔 MC9S12】内部Flash读写

上一篇讲到内部Flash的读写,本篇讲述使用D-Flash模拟EEPROM。其实使用P-Flash也可以模拟,只不过D-Flash的Page更小(擦除复写占用更少时间),而且不会占用代码空间。

最近刚换工作,一直比较忙,更新会比较慢。若是需要源码可自行下载:https://download.csdn.net/download/u010875635/11435913

没有积分可以自己新建工程,下面的代码基本可以直接使用。

本篇关于Flash读写就不在赘述,跟PFlash除了Sector大小和指令不同,其余一致,后面直接贴出代码。

模拟EEPROM其实就是模拟其单字节读写功能,原理就是要修改某个Sector内某个字节的数据时,先读出这个扇区内所有数据(256Bytes)到数组,然后擦除这个Sector,再在RAM中修改那个字节的数据,最后将这个数组写回该扇区。修改多字节数据原理相似。

另外大家可以想一下,若是要往EEPROM中写入跨Sector的数组怎么办?(需要判断数组地址范围)

使用范例:

main.c

#include <hidef.h>      /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */
#include "Typedefs.h"
#include "gpio.h"
#include "System.h"
#include "flash.h"
#include "EmulationEEPROM.h"UINT32 m_maincount=0;
void main(void)
{/* put your own code here */int result;UINT32 index = 0;UINT32 globalDFlashAddr1 = 0x100000,globalDFlashAddr2 = 0x100002,globalDFlashAddr3=0x13F800;UINT32 globalAddr1 = 0x7F4000,globalAddr2 = 0x7F4002,globalAddr3=0x7db460;UINT8 datas1[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F};UINT8 datas2[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09};UINT8 readDatas[100];McuDrivers_System_Init();McuDrivers_GPIO_Init();EnableInterrupts;//for(index = 0;index<129;index++)//    HDL_Flash_PFlash_ProgramMultiSectors(globalAddr2+index*8,datas,sizeof(datas));//HDL_Flash_PFlash_EraseOneSector(0x7F4000);
//  HDL_Flash_PFlash_EraseMultiSectors(globalAddr2,globalAddr2+1001); //IFsh1_EraseSector(globalAddr2);    //HDL_Flash_PFlash_ProgramMultiSectors(globalAddr1,datas,sizeof(datas));//HDL_Flash_PFlash_ProgramMultiSectors(globalAddr3,datas2,sizeof(datas2));//HDL_Flash_DFlash_EraseMultiSectors(globalDFlashAddr1,globalDFlashAddr1+1000);//for(index = 0;index<33;index++)//    HDL_Flash_DFlash_ProgramMultiSectors(globalDFlashAddr1+index*16,datas1,sizeof(datas1));//HDL_Flash_DFlash_EraseMultiSectors(globalDFlashAddr1,globalDFlashAddr1+1000);//HDL_Flash_DFlash_ProgramMultiSectors(globalDFlashAddr2,datas1,sizeof(datas1));result = HAL_EEE_ChangeValue(globalDFlashAddr1,datas1,sizeof(datas1));result = HAL_EEE_ChangeValue(globalDFlashAddr1+10,datas1,sizeof(datas1));HAL_EEE_GetValue(globalDFlashAddr1,30,readDatas);for(;;) {m_maincount++;if(m_maincount>100000){m_maincount = 0;PORTB_PB0 ^=1;}_FEED_COP(); /* feeds the dog */} /* loop forever *//* please make sure that you never leave main */
}

EmulationEEPROM.h

#ifndef _HAL_EmulationEEPROM_H_
#define _HAL_EmulationEEPROM_H_#include "Typedefs.h"//get value
int HAL_EEE_GetValue(UINT32 startGlobalAddr, UINT8 newDataLength, UINT8 * pNewData);//change value
int HAL_EEE_ChangeValue(UINT32 startGlobalAddr, UINT8 * pNewData,UINT8 newDataLength);#endif

EmulationEEPROM.c

#include "EmulationEEPROM.h"
#include "flash.h"#define DFLASH_SECTOR_ADDR_MASK         0xFFFFFF00      //256 bytes
#define DFLASH_SECTOR_SIZE              256U#define PROGRAM_DFlash_Phrase_SIZE              8U
#define PROGRAM_DFlash_Phrase_MASK          0xFFFFFFF8//get value
int HAL_EEE_GetValue(UINT32 startGlobalAddr, UINT8 newDataLength, UINT8 * pNewData)
{UINT16 i;UINT8 *far readTmpData;//读取DFlash中内容for(i=0;i<newDataLength;i++){readTmpData = (UINT8 *far)(startGlobalAddr+i);pNewData[i] = (*readTmpData); }
}//change value
int HAL_EEE_ChangeValue(UINT32 startGlobalAddr, UINT8 * pNewData,UINT8 newDataLength)
{UINT32 sectorStartAddr = startGlobalAddr&DFLASH_SECTOR_ADDR_MASK;UINT8 dataContainer[DFLASH_SECTOR_SIZE]={0};UINT16 *far readTmpData;UINT16 i;volatile int result = 0;//读取DFlash中此扇区内容for(i=0;i<DFLASH_SECTOR_SIZE;i+=2){readTmpData = (UINT16 *far)(sectorStartAddr+i);dataContainer[i] =  ((*readTmpData)>>8)&0xFF;  //高位在前dataContainer[i+1] = (*readTmpData)&0xFF; }//更新要写入的内容for(i=startGlobalAddr-sectorStartAddr;i<startGlobalAddr-sectorStartAddr+newDataLength;i++)dataContainer[i] =  pNewData[i-startGlobalAddr+sectorStartAddr];result = HDL_Flash_DFlash_EraseMultiSectors(sectorStartAddr,sectorStartAddr);result = HDL_Flash_DFlash_ProgramMultiSectors(sectorStartAddr,dataContainer,DFLASH_SECTOR_SIZE);return result;
}

flash.h

#ifndef _HDL_FLASH_H_
#define _HDL_FLASH_H_#define FLASH_BOOT_SEQUENCE_ERROR          (-2)
#define FLASH_ADDRESS_ERROR                 (-3)
#define FLASH_ERASE_ERROR                   (-4)
#define FLASH_PROGRAM_ERROR                 (-5)
#define FLASH_VERIFICATION_ERROR            (-6)
#define FLASH_DATALENGTH_ERROR              (-8)#define FLASH_NOTAVAIL_ERROR                (-9)
#define FLASH_PROTECTED_ERROR               (-10)
#define FLASH_MGSTAT_ERROR                  (-11)
#define FLASH_BUSY_ERROR                    (-12)#define FLASH_SUCCESS                      (1)//erase multiple sector
int HDL_Flash_DFlash_EraseMultiSectors(UINT32 startGlobalAddr, UINT32 endGlobalAddr);//program multiple phrases
int HDL_Flash_DFlash_ProgramMultiSectors(UINT32 globalAddr, UINT8 * pData,UINT16 dataLength);//erase multiple sector
int HDL_Flash_PFlash_EraseMultiSectors(UINT32 startGlobalAddr, UINT32 endGlobalAddr);//program multiple phrases
int HDL_Flash_PFlash_ProgramMultiSectors(UINT32 globalAddr, UINT8 * pData,UINT16 dataLength);#endif

flash.c

#include <hidef.h>      /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */#include "Typedefs.h"
#include "flash.h"
#include "string.h"/*默认情况下(ROMHM=0 RAMHM=0)Global Memory Map 如下:
0x000000-0x0007FF   Registers   2KB
0x000800-0x000FFF   2K RAM , 扩展空间CS3
0x001000-0x0FDFFF   253*4K Paged RAM
0x0FE000-0x0FFFFF   8K RAM(2*4K)
0x100000-0x13FBFF   255*1K Paged EEPROM0x100000-0x1003FF    1K (EPAGE 0x00) ……0x103C00-0x103FFF 1K (EPAGE 0x1F) ---0x13F000-0x13F3FF    1K (EPAGE 0xFC)             --0x13F400-0x13F7FF 1K (EPAGE 0xFD)             |   RAM Bufferd0x13F800-0x13FBFF    1K (EPAGE 0xFE)             |
0x13FC00-0x13FFFF   1K EEPROM(EPAGE 0xFF)           --
0x140000-0x1FFFFF   扩展空间CS2
0x200000-0x3FFFFF   扩展空间CS1
0x400000-0x7F3FFF   253*16K Paged Flash, 扩展空间CS00x700000-0x73FFFF   B3(256KB)0x740000-0x77FFFF  B2(256KB)0x780000-0x79FFFF  B1S(128KB)0x7A0000-0x7BFFFF B1N(128KB)0x7C0000-0x7F3FFF B0(208KB)
0x7F4000-0x7F7FFF   16KB Flash(PPAGE 0xFD)0x7F4000-0x7F7FFF B0(16KB)
0x7F8000-0x7FBFFF   16KB Flash(PPAGE 0xFE)0x7F8000-0x7FBFFF B0(16KB)
0x7FC000-0x7FFFFF   16KB Flash(PPAGE 0xFF)0x7FC000-0x7FFFFF B0(16KB)*//**** P-Flash and D-Flash Commands ****/#define ERASE_VERIFY_ALL_BLOCKS  0x01
/* Verify that all program and data Flash blocks are erased. */
/* CCOBIX end = 0 */
/* CCOB Params - NONE */
/* MGSTAT set if fault */#define ERASE_VERIFY_BLOCK       0x02
/* Verify that a Flash block is erased. */
/* CCOBIX end = 0 */
/* CCOB Params - gpage */
/* MGSTAT set if fault */#define ERASE_ALL_BLOCKS         0x08
/* Erase all program and data Flash blocks.An erase of all Flash blocks is only possible when the FPLDIS, FPHDIS, and FPOPENbits in the FPROT register and the EPDIS and EPOPEN bits in the EPROM register areset prior to launching the command. */
/* CCOBIX end = 0 */
/* CCOB Params - NONE */
/* MGSTAT set if fault, FPVIOL / ACCERR set where appropriate */#define UNSECURE_FLASH           0x0B
/*Supports a method of releasing MCU security by erasing all program and data Flashblocks and verifying that all program and data Flash blocks are erased. */
/* CCOBIX end = 0 */
/* CCOB Params - NONE */
/* MGSTAT set if fault */#define SET_USER_MARGIN_LEVEL    0x0D
/*Specifies a user margin read level for all program Flash blocks. */
/* CCOBIX end = 1 */
/* CCOB Params - gpage, level setting (0-2) in CCOB[1] */
/* ACCERR set if invalid level */#define SET_FIELD_MARGIN_LEVEL   0x0E
/*Specifies a field margin read level for all program Flash blocks (special modes only). */
/* CCOBIX end = 1 */
/* CCOB Params - gpage, level setting (0-4) in CCOB[1] */
/* ACCERR set if invalid level *//*-------------------------------*/
/* **** P-Flash Only Commands ****/#define ERASE_VERIFY_P_FLASH_SECTION 0x03
/*Verify that a given number of words starting at the address provided are erased. */
/* CCOBIX end = 2 */
/* CCOB Params - global address, number of phrases in CCOB[2]*/
/* MGSTAT set if fault */#define READ_ONCE                 0x04
/* Read a phrase from a dedicated 64 word area in a hidden region of a programFlash blockthat was previously programmed using the Program Once command. */
/* CCOBIX end = 1 */
/* CCOB Params - read once index (0-3) in CCOB[1], phrase in CCOB [5:2] */
/* returns phrase in CCOB [4:1] */#define PROGRAM_P_FLASH          0x06
/* Program a phrase in a program Flash block and any previously loaded phrases for anyother program Flash block (see Load Data Field command). */
/* CCOBIX end = 5 */
/* CCOB Params - global address, phrase in CCOB [5:2] */
/* MGSTAT set if fault, FPVIOL / ACCERR set where appropriate */#define PROGRAM_ONCE             0x07
/* Program a dedicated 64 word area in a hidden region of a program Flash block that isallowed to be programmed only once. */
/* CCOBIX end = 5 */
/* CCOB Params - read once index (0-3) in CCOB[1], phrase in CCOB [5:2] */
/* MGSTAT set if fault */#define ERASE_P_FLASH_BLOCK      0x09
/* Erase a program Flash block.An erase of the full program Flash block is only possible when FPLDIS, FPHDIS andFPOPEN bits in the FPROT register are set prior to launching the command. */
/* CCOBIX end = 1 */
/* CCOB Params - global address */
/* MGSTAT set if fault, FPVIOL / ACCERR set where appropriate */#define ERASE_P_FLASH_SECTOR 0x0A
/* Erase all bytes in a program Flash sector. */
/* CCOBIX end = 1 */
/* CCOB Params - global address */
/* MGSTAT set if fault, FPVIOL / ACCERR set where appropriate */#define VERIFY_BACKDOOR_ACCESS_KEY 0x0C
/*Supports a method of releasing MCU security by verifying a set of security keys. */
/* CCOBIX end = 4 */
/* CCOB Params - backdoor key in CCOB [1:4] */
/* ACCERR set if not verified *//*-------------------------------*/
/**** D-Flash Only Commands ****/
#define ERASE_D_FLASH_BLOCK      0x09
/* Erase a program Flash block.An erase of the full program Flash block is only possible when DPOPEN bit in the DFPROTregister is set prior to launching the command. */
/* CCOBIX end = 1 */
/* CCOB Params - global address */
/* MGSTAT set if fault, FPVIOL / ACCERR set where appropriate */#define ERASE_VERIFY_D_FLASH_SECTION 0x10
/* Verify that a given number of words starting at the address provided are erased. */
/* CCOBIX end = 2 */
/* CCOB Params - global address of first word, number of words to verify CCOB[2]*/
/* MGSTAT set if fault */#define PROGRAM_D_FLASH         0x11
/* Program up to four words in the data Flash block (see Load Data Field command). */
/* CCOBIX end = 2 */
/* CCOB Params - global address, up to 4 data words in CCOB [2:5] */
/* MGSTAT set if fault, EPVIOL / ACCERR set where appropriate */#define ERASE_D_FLASH_SECTOR    0x12
/* Erase all bytes in a data Flash sector. */
/* CCOBIX end = 2 */
/* CCOB Params - global address */
/* MGSTAT set if fault, EPVIOL  set where appropriate *//*--------------------------------*/
#define ENABLE_EEPROM_EMULATION    0x13
// Requests the FTMSM to enable EEPROM emulation.
// CCOBIX end = 0
// CCOB Params - NONE#define DISABLE_EEPROM_EMULATION   0x14
// Requests the FTMSM to suspend all current erase and program activity related to
// EEPROM emulation but leave current EEE tags set.
// CCOBIX end = 0
// CCOB Params - NONE#define CANCEL_EEPROM_EMULATION    0x15   /* M22E mask only */
// Requests the FTMSM to suspend all current erase and program activity related to
// EEPROM emulation and clear all outstanding EEE tags.
// CCOBIX end = 0
// CCOB Params - NONE#define EEPROM_QUERY    0x15   /* M48H mask only */
// Requests EEE status information.
// CCOBIX end = 0
// CCOB Return Params -
// CCOB[1] DFPART - size of D-Flash user partition (x256 bytes)
// CCOB[2] ERPART - size of EEE ram (x256 bytes)
// CCOB[3] ECOUNT - typical number of erase cycles for the EEE sectors
// CCOB[4] Dead sector count / Ready sector count#define PARTITION_D_FLASH 0x20  /* M48H mask only */
// Partition a section of D-Flash for user access and EEE.
// CCOBIX end = 2
// CCOB Params - number of sectors for D-Flash in CCOB[1],  number of sectors for EEE in CCOB[2]
// ACCERR set if fault#define FULL_PARTITION_D_FLASH 0x0F
// Partition a section of D-Flash for user access and EEE.
// CCOBIX end = 2
// CCOB Params - number of sectors for D-Flash in CCOB[1],  number of sectors for EEE in CCOB[2]
// ACCERR set if fault#define DFLASH_SECTOR_ADDR_MASK           0xFFFFFF00      //256 bytes
#define DFLASH_SECTOR_SIZE              256U#define PROGRAM_DFlash_Phrase_SIZE              8U
#define PROGRAM_DFlash_Phrase_MASK          0xFFFFFFF8#define PFLASH_SECTOR_ADDR_MASK           0xFFFFFC00      //1024 bytes
#define PFLASH_SECTOR_SIZE              1024U#define PROGRAM_PFlash_Phrase_SIZE             8U
#define PROGRAM_PFlash_Phrase_MASK          0xFFFFFFF8#define TRANSFER_BUFFER_SIZE          1024U#define ClearFlags()  (FSTAT = 0x30U)typedef struct
{UINT8 flashCmd;UINT32 globalAddr;UINT8 Datas[PROGRAM_PFlash_Phrase_SIZE];UINT8 dataLength;}HDL_FLASH_SCM_FCCO_PARA;/*the function run in ram,
clear CCIF, then wait CCIF to set
*/
/*use CALL for this function*/
//unsigned char HDL_Flash_Burn_And_WaitFinished[10]={0x1C,0x01,0x06,0x80,0x1F,0x01,0x06,0x80,0xFB,0x0A};
/*use JSR for this function*/
unsigned char HDL_Flash_Burn_And_WaitFinished[11]={0xC6,0x80,0x7B,0x01,0x06,0x1F,0x01,0x06,0x80,0xFB,0x3D};//check the flash operating frequency and ccif and accerr and fpviol
void HDL_Flash_CheckRegisterBeforeOperate(void)
{   //check if the clock for flash is valid, for 16MHz OSC, the divider should be 0x0F, here is 8MHzif(FCLKDIV_FDIVLD == 0){#ifdef ON_DEVELOP_BOARDFCLKDIV = 0x0F;    //osc=16MHz#elseFCLKDIV = 0x07;    //osc=8MHz#endif}//check and wait for an ongoing flash command  while(FSTAT_CCIF == 0){_asm(nop);}//must clear ACCERR or FPVIOL bits before starting any command write sequenceif((FSTAT_ACCERR != 0)||(FSTAT_FPVIOL !=0)){FSTAT_ACCERR = 1;FSTAT_FPVIOL = 1;}
}//return 0-busy, return 1=ok
int HDL_Flash_GetFlashState(void)
{return FSTAT_CCIF;
}/******************************** D Flash **********************************///check the address is whether the phrase start, 8bytes is a phrase
int HDL_DFlash_CheckAddressIsPhraseStart(UINT32 globalAddr)
{int nRetval = FLASH_SUCCESS;if(globalAddr%PROGRAM_DFlash_Phrase_SIZE != 0){nRetval = FLASH_ADDRESS_ERROR;}return nRetval;
}#pragma MESSAGE DISABLE C1420 //result of function call is ignore
//execute one flash command
int HDL_D_Flash_ExecOneFlashCmd(HDL_FLASH_SCM_FCCO_PARA* pFCCOpara)
{UINT8 uIndex = FLASH_SUCCESS;HDL_Flash_CheckRegisterBeforeOperate();if (FSTAT_CCIF == 0U)     /* Is command buffer full ? */{              //ExitCritical();                    /* Exit critical section */return FLASH_BUSY_ERROR;                   /* If yes then error */}FCCOBIX = 0x00;FCCOBHI = pFCCOpara->flashCmd;FCCOBLO = (UINT)((pFCCOpara->globalAddr & 0x00130000) >> 16);FCCOBIX = 0x01;FCCOB = (UINT16)(pFCCOpara->globalAddr & 0x0000FFFF) ;if(pFCCOpara->flashCmd==PROGRAM_D_FLASH){for(uIndex = 0; uIndex < pFCCOpara->dataLength; uIndex++){FCCOBIX = 0x02 + uIndex / 2;FCCOBHI = * (pFCCOpara->Datas + uIndex);FCCOBLO = * (pFCCOpara->Datas + uIndex + 1);uIndex++;}}DisableInterrupts;  //_asm("CALL HDL_Flash_Burn_And_WaitFinished");_asm("JSR HDL_Flash_Burn_And_WaitFinished");EnableInterrupts;if (FSTAT_FPVIOL == 1U) {            /* Is protection violation detected ? */return FLASH_PROTECTED_ERROR;               /* If yes then error */}if (FSTAT_ACCERR == 1U) {            /* Is acces error detected ? */return FLASH_NOTAVAIL_ERROR;               /* If yes then error */}if (FSTAT_MGSTAT) {                  /* Was attempt to write data to the given address errorneous? */return FLASH_MGSTAT_ERROR;                  /* If yes then error */}return FLASH_SUCCESS;                      /* Exit critical section */}//check the address is whether valid
int HDL_D_Flash_CheckAddressIsValid(UINT32 globalAddr)
{int nRetval = FLASH_SUCCESS;if(! (globalAddr >= 0x100000) && (globalAddr <= 0x13FBFF) ){nRetval = FLASH_ADDRESS_ERROR;}return nRetval;
}#pragma MESSAGE DISABLE C1420 //result of function call is ignore
//erase one sector,1024bytes
int HDL_Flash_DFlash_EraseOneSector(UINT32 sectorAddr)
{int nRetval = FLASH_SUCCESS;HDL_FLASH_SCM_FCCO_PARA fccoPara;if(HDL_D_Flash_CheckAddressIsValid(sectorAddr)){fccoPara.flashCmd = ERASE_D_FLASH_SECTOR;       fccoPara.globalAddr = sectorAddr&PROGRAM_DFlash_Phrase_MASK; //erase start address must be phrase start address    fccoPara.dataLength = 0;nRetval = HDL_D_Flash_ExecOneFlashCmd(&fccoPara);}else{nRetval = FLASH_ADDRESS_ERROR;}return nRetval;
}#pragma MESSAGE DISABLE C1420 //result of function call is ignore
//erase multiple sector
int HDL_Flash_DFlash_EraseMultiSectors(UINT32 startGlobalAddr, UINT32 endGlobalAddr)
{int nRetval = FLASH_SUCCESS;if(HDL_D_Flash_CheckAddressIsValid(startGlobalAddr) && HDL_D_Flash_CheckAddressIsValid(endGlobalAddr) && startGlobalAddr<=endGlobalAddr ){    UINT32 addr = 0;for(addr = startGlobalAddr; addr <= endGlobalAddr; addr+=DFLASH_SECTOR_SIZE){nRetval = HDL_Flash_DFlash_EraseOneSector(addr);if(nRetval!=FLASH_SUCCESS)return nRetval;}}else{nRetval = FLASH_ADDRESS_ERROR;}return nRetval;
}#pragma MESSAGE DISABLE C1420 //result of function call is ignore
//program one phrase,8bytes
int HDL_Flash_DFlash_ProgramOneSector(UINT32 globalAddr, UINT8 * pData,UINT16 dataLength)
{int nRetval = FLASH_SUCCESS;HDL_FLASH_SCM_FCCO_PARA fccoPara;if(dataLength!=PROGRAM_DFlash_Phrase_SIZE)return FLASH_DATALENGTH_ERROR;if(HDL_D_Flash_CheckAddressIsValid(globalAddr) && HDL_DFlash_CheckAddressIsPhraseStart(globalAddr)){fccoPara.flashCmd = PROGRAM_D_FLASH;       fccoPara.globalAddr = globalAddr; fccoPara.dataLength = dataLength;memcpy(fccoPara.Datas,pData,dataLength);HDL_D_Flash_ExecOneFlashCmd(&fccoPara);}elsenRetval =  FLASH_ADDRESS_ERROR;return nRetval;
}#pragma MESSAGE DISABLE C1420 //result of function call is ignore
//program multiple phrases
int HDL_Flash_DFlash_ProgramMultiSectors(UINT32 globalAddr, UINT8 * pData, UINT16 dataLength)
{int nRetval = FLASH_SUCCESS;UINT32 addr = 0, offsetFromPhraseStartAddr = 0, endAddr = 0;//UINT8 *dataInFlash=&addr;UINT8 datas[8];UINT32 phraseStarAddr = globalAddr&PROGRAM_DFlash_Phrase_MASK;   //first phrase start addressif (!HDL_D_Flash_CheckAddressIsValid(globalAddr))return FLASH_ADDRESS_ERROR;/*************************************************start0 1 2 3 4 5 6 7 8 .....  0 1 2 3 4 5 6 7 8|offset|<-   dataLength   ->| no 8 left data**************************************************///the offset of phrase startoffsetFromPhraseStartAddr = globalAddr - phraseStarAddr;endAddr = globalAddr + dataLength-1;//首组不对齐if (offsetFromPhraseStartAddr != 0){//first contain offset area,read offset area data from flashfor (addr = phraseStarAddr; addr<globalAddr; addr++){//dataInFlash = (UINT8 *)addr; //get the maintain valuedatas[addr - phraseStarAddr] = 0xff;//*dataInFlash; //0xFF;}//first contain offset fill the left with data    for (addr = globalAddr; addr<globalAddr+ PROGRAM_DFlash_Phrase_SIZE - offsetFromPhraseStartAddr; addr++)datas[addr - phraseStarAddr] = pData[addr - globalAddr];//program first one phraseHDL_Flash_DFlash_ProgramOneSector(phraseStarAddr,datas, PROGRAM_DFlash_Phrase_SIZE);//下一组要偏移一个PhrasephraseStarAddr += PROGRAM_DFlash_Phrase_SIZE;}//other data for (addr = phraseStarAddr ; addr <= endAddr + 1 - PROGRAM_DFlash_Phrase_SIZE; addr += PROGRAM_DFlash_Phrase_SIZE){//program dataHDL_Flash_DFlash_ProgramOneSector(addr, &pData[addr - globalAddr], PROGRAM_DFlash_Phrase_SIZE);}//endaddr phrase start addrphraseStarAddr = endAddr&PROGRAM_DFlash_Phrase_MASK;   //last phrase start address//endaddr is not the phrase last oneif (endAddr != (phraseStarAddr+ PROGRAM_DFlash_Phrase_SIZE-1)){//the last no 8 left datafor (addr = phraseStarAddr; addr <= endAddr; addr++)datas[addr - phraseStarAddr] = pData[addr - globalAddr];for (addr = endAddr + 1; addr<8+phraseStarAddr; addr++){//dataInFlash = (UINT8 *)addr;  //get the maintain valuedatas[addr - phraseStarAddr] = 0xff;//*dataInFlash;//0xFF;}//program first one phraseHDL_Flash_DFlash_ProgramOneSector(phraseStarAddr, datas, PROGRAM_DFlash_Phrase_SIZE);}return nRetval;
}/******************************** P Flash **********************************///check the address is whether the phrase start, 8bytes is a phrase
int HDL_PFlash_CheckAddressIsPhraseStart(UINT32 globalAddr)
{int nRetval = FLASH_SUCCESS;if(globalAddr%PROGRAM_DFlash_Phrase_SIZE != 0){nRetval = FLASH_ADDRESS_ERROR;}return nRetval;
}#pragma MESSAGE DISABLE C1420 //result of function call is ignore
//execute one flash command
int HDL_P_Flash_ExecOneFlashCmd(HDL_FLASH_SCM_FCCO_PARA* pFCCOpara)
{UINT8 uIndex = FLASH_SUCCESS;HDL_Flash_CheckRegisterBeforeOperate();if (FSTAT_CCIF == 0U)     /* Is command buffer full ? */{              //ExitCritical();                    /* Exit critical section */return FLASH_BUSY_ERROR;                   /* If yes then error */}FCCOBIX = 0x00;FCCOBHI = pFCCOpara->flashCmd;FCCOBLO = (UINT)((pFCCOpara->globalAddr & 0x007F0000) >> 16);FCCOBIX = 0x01;FCCOB = (UINT16)(pFCCOpara->globalAddr & 0x0000FFFF) ;if(pFCCOpara->flashCmd==PROGRAM_P_FLASH){for(uIndex = 0; uIndex < pFCCOpara->dataLength; uIndex++){FCCOBIX = 0x02 + uIndex / 2;FCCOBHI = * (pFCCOpara->Datas + uIndex);FCCOBLO = * (pFCCOpara->Datas + uIndex + 1);uIndex++;}}DisableInterrupts;  //_asm("CALL HDL_Flash_Burn_And_WaitFinished");_asm("JSR HDL_Flash_Burn_And_WaitFinished");EnableInterrupts;if (FSTAT_FPVIOL == 1U) {            /* Is protection violation detected ? */return FLASH_PROTECTED_ERROR;               /* If yes then error */}if (FSTAT_ACCERR == 1U) {            /* Is acces error detected ? */return FLASH_NOTAVAIL_ERROR;               /* If yes then error */}if (FSTAT_MGSTAT) {                  /* Was attempt to write data to the given address errorneous? */return FLASH_MGSTAT_ERROR;                  /* If yes then error */}return FLASH_SUCCESS;                      /* Exit critical section */}//check the address is whether valid
int HDL_P_Flash_CheckAddressIsValid(UINT32 globalAddr)
{int nRetval = FLASH_SUCCESS;if(! (globalAddr >= 0x700000) && (globalAddr <= 0x7FFFFF) ){nRetval = FLASH_ADDRESS_ERROR;}return nRetval;
}#pragma MESSAGE DISABLE C1420 //result of function call is ignore
//erase one sector,1024bytes
int HDL_Flash_PFlash_EraseOneSector(UINT32 sectorAddr)
{int nRetval = FLASH_SUCCESS;HDL_FLASH_SCM_FCCO_PARA fccoPara;if(HDL_P_Flash_CheckAddressIsValid(sectorAddr)){fccoPara.flashCmd = ERASE_P_FLASH_SECTOR;       fccoPara.globalAddr = sectorAddr&PROGRAM_PFlash_Phrase_MASK; //erase start address must be phrase start address    fccoPara.dataLength = 0;nRetval = HDL_P_Flash_ExecOneFlashCmd(&fccoPara);}else{nRetval = FLASH_ADDRESS_ERROR;}return nRetval;
}#pragma MESSAGE DISABLE C1420 //result of function call is ignore
//erase multiple sector
int HDL_Flash_PFlash_EraseMultiSectors(UINT32 startGlobalAddr, UINT32 endGlobalAddr)
{int nRetval = FLASH_SUCCESS;if(HDL_P_Flash_CheckAddressIsValid(startGlobalAddr) && HDL_P_Flash_CheckAddressIsValid(endGlobalAddr) && startGlobalAddr<=endGlobalAddr ){    UINT32 addr = 0;for(addr = startGlobalAddr; addr <= endGlobalAddr; addr+=PFLASH_SECTOR_SIZE){nRetval = HDL_Flash_PFlash_EraseOneSector(addr);if(nRetval!=FLASH_SUCCESS)return nRetval;}}else{nRetval = FLASH_ADDRESS_ERROR;}return nRetval;
}#pragma MESSAGE DISABLE C1420 //result of function call is ignore
//program one phrase,8bytes
int HDL_Flash_PFlash_ProgramOneSector(UINT32 globalAddr, UINT8 * pData,UINT16 dataLength)
{int nRetval = FLASH_SUCCESS;HDL_FLASH_SCM_FCCO_PARA fccoPara;if(dataLength!=PROGRAM_PFlash_Phrase_SIZE)return FLASH_DATALENGTH_ERROR;if(HDL_P_Flash_CheckAddressIsValid(globalAddr) && HDL_PFlash_CheckAddressIsPhraseStart(globalAddr)){fccoPara.flashCmd = PROGRAM_P_FLASH;       fccoPara.globalAddr = globalAddr; fccoPara.dataLength = dataLength;memcpy(fccoPara.Datas,pData,dataLength);HDL_P_Flash_ExecOneFlashCmd(&fccoPara);}elsenRetval =  FLASH_ADDRESS_ERROR;return nRetval;
}#pragma MESSAGE DISABLE C1420 //result of function call is ignore
//program multiple phrases
int HDL_Flash_PFlash_ProgramMultiSectors(UINT32 globalAddr, UINT8 * pData, UINT16 dataLength)
{int nRetval = FLASH_SUCCESS;UINT32 addr = 0, offsetFromPhraseStartAddr = 0, endAddr = 0;//UINT8 *dataInFlash=&addr;UINT8 datas[8];UINT32 phraseStarAddr = globalAddr&PROGRAM_PFlash_Phrase_MASK;   //first phrase start addressif (!HDL_P_Flash_CheckAddressIsValid(globalAddr))return FLASH_ADDRESS_ERROR;/*************************************************start0 1 2 3 4 5 6 7 8 .....  0 1 2 3 4 5 6 7 8|offset|<-   dataLength   ->| no 8 left data**************************************************///the offset of phrase startoffsetFromPhraseStartAddr = globalAddr - phraseStarAddr;endAddr = globalAddr + dataLength-1;//首组不对齐if (offsetFromPhraseStartAddr != 0){//first contain offset area,read offset area data from flashfor (addr = phraseStarAddr; addr<globalAddr; addr++){//dataInFlash = (UINT8 *)addr; //get the maintain valuedatas[addr - phraseStarAddr] = 0xff;//*dataInFlash; //0xFF;}//first contain offset fill the left with data    for (addr = globalAddr; addr<globalAddr+ PROGRAM_PFlash_Phrase_SIZE - offsetFromPhraseStartAddr; addr++)datas[addr - phraseStarAddr] = pData[addr - globalAddr];//program first one phraseHDL_Flash_PFlash_ProgramOneSector(phraseStarAddr,datas, PROGRAM_PFlash_Phrase_SIZE);//下一组要偏移一个PhrasephraseStarAddr += PROGRAM_PFlash_Phrase_SIZE;}//other data for (addr = phraseStarAddr ; addr <= endAddr + 1 - PROGRAM_PFlash_Phrase_SIZE; addr += PROGRAM_PFlash_Phrase_SIZE){//program dataHDL_Flash_PFlash_ProgramOneSector(addr, &pData[addr - globalAddr], PROGRAM_PFlash_Phrase_SIZE);}//endaddr phrase start addrphraseStarAddr = endAddr&PROGRAM_PFlash_Phrase_MASK;   //last phrase start address//endaddr is not the phrase last oneif (endAddr != (phraseStarAddr+ PROGRAM_PFlash_Phrase_SIZE-1)){//the last no 8 left datafor (addr = phraseStarAddr; addr <= endAddr; addr++)datas[addr - phraseStarAddr] = pData[addr - globalAddr];for (addr = endAddr + 1; addr<8+phraseStarAddr; addr++){//dataInFlash = (UINT8 *)addr;  //get the maintain valuedatas[addr - phraseStarAddr] = 0xff;//*dataInFlash;//0xFF;}//program first one phraseHDL_Flash_PFlash_ProgramOneSector(phraseStarAddr, datas, PROGRAM_PFlash_Phrase_SIZE);}return nRetval;
}

下一篇:【飞思卡尔 MC9S12】BootLoader 下位机

【飞思卡尔 MC9S12】内部D-Flash模拟EEPROM相关推荐

  1. 【飞思卡尔 MC9S12】内部Flash读写

    上一篇:[飞思卡尔 MC9S12]PRM文件与内存映射(Flash.RAM.EEE) 上一篇讲到PRM文件与内存映射,其中有个重要寄存器叫做GPAGE,可以全局访问所有地址范围,Flash操作也是基于 ...

  2. 【飞思卡尔 MC9S12】PRM文件与内存映射(Flash、RAM、EEE)

    本篇介绍飞思卡尔MC9S12系列芯片基本内存映射知识,主要是其特有的分页机制.一般的小型项目可能很多人都不会去专门了解这些内容,但是对于大型项目(代码超过16KB 或 内部变量过多超过4KB),势必要 ...

  3. STM32F407 内部自带FLASH 模拟 EEPROM

    STM32F407 内部自带FLASH 模拟 EEPROM 一.STM32F407自带FLASH STM32F4 本身没有自带 EEPROM,但是 STM32F4 具有 IAP(在应用编程)功能,所以 ...

  4. 【飞思卡尔 MC9S12】BootLoader 下位机

    上一篇:[飞思卡尔 MC9S12]内部D-Flash模拟EEPROM 本篇讲述BootLoader下位机的开发. 刚到新公司第三天就接了一个项目,搞到现在才局部完成,更新比较慢了. 先上传源码比较实际 ...

  5. 【飞思卡尔 MC9S12】BootLoader 上位机

    上一篇:飞思卡尔 MC9S12]BootLoader 下位机 本篇讲述BootLoader上位机开发. 源码地址:https://download.csdn.net/download/u0108756 ...

  6. 小猫爪:这些年遇过的Bug1-KW36 FLASH模拟EEPROM读写错误

    小猫爪:这些年遇过的Bug1-KW36 FLASH模拟EEPROM读写错误 1 背景 2 场景描述 3 分析原因 4 解决方案 1 背景 芯片型号:MKW36A512VFT4(NXP) 操作系统:Fr ...

  7. 【正点原子STM32连载】 第四十五章 FLASH模拟EEPROM实验 摘自【正点原子】STM32F103 战舰开发指南V1.2

    第四十五章 FLASH模拟EEPROM实验 STM32本身没有自带EEPROM,但是STM32具有IAP(在应用编程)功能,所以我们可以把它的FLASH当成EEPROM来使用.本章,我们将利用STM3 ...

  8. FLASH 模拟 EEPROM

    FLASH 模拟 EEPROM 一.STM32 FLASH 简介   STM32F4 的闪存模块由主存储器.系统存储器.OPT 区域和选项字节等 4 部分组成.   主存储器,该部分用来存放代码和数据 ...

  9. 【正点原子STM32连载】第四十二章 FLASH模拟EEPROM实验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1

    1)实验平台:正点原子MiniPro H750开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=677017430560 3)全套实验源码+手册+视频 ...

最新文章

  1. 前端工程师的mysql笔记
  2. vue实现进度条隐藏_Vue 中使用 NProgress 实现进度条
  3. 如何在容器内高效编程?
  4. 移动端点击a链接出现蓝色背景问题解决
  5. Python之抖音快手代码舞--字符舞
  6. solidity import @是什么意思
  7. cnn程序流程图_GitHub - suqcnn/vue: vue源码逐行注释分析+40多m的vue源码程序流程图思维导图 (diff部分待后续更新)...
  8. 魔兽争霸修改器,局域网内使用!防封号!!!!!!!!
  9. 2011年电子科技大学博士生招生参考书目
  10. coreldraw是什么软件好学吗?cdr矢量图形制作工具
  11. android opengl滤镜,Android OpenGL ES滤镜开发之美颜效果
  12. 源码分享:打造「螃蟹火星车」,遥控、拍照、测距,还能做人脸检测;
  13. 【模板】普通平衡树,洛谷P3369,splay
  14. MTTF、MTTR、MTBF
  15. ppt编辑数据链接文件不可用_office 高手进,PPT图片编辑中显示链接的文件不可用,请使用编辑链接命令查找文件...
  16. 论文导读:TOWARDS END-TO-END SPOKEN LANGUAGE UNDERSTANDING
  17. org.apache.thrift.transport.TTransportException: SASL authentication not complete
  18. 机器人中的坐标转换关系(个人记录学习)
  19. CSS样式书写顺序 与 浏览器内部加载原理
  20. 基于FPG的温湿度实时采集与显示

热门文章

  1. 线段树 + 扫描线 + 离散化:亚特兰蒂斯
  2. 解决sed替换文本,里面含有“/“、“#”等特殊字符的问题
  3. 使用 Gradle 编译 Java 项目时报错: Could not find Tools.jar
  4. Google 要把 Quickoffice 下架,要用就快下载了
  5. 导出Google身份校验器otp密钥迁移到web
  6. 装修 —— 石膏粉和腻子粉的区别
  7. “人工智能影响世界”
  8. 创建VUE项目,vue-cli2.0版本和3.0版本的区别,将vue2.0项目升级为vue3.0项目
  9. arctime字幕工具--批量字幕工具
  10. windows服务启动失败解决流程