📄 flash_mtd.intel.c
字号:
fp[k*PAGE_BUFFER_SIZE] = INTEL_CMD_BUF_PGM_CNF; // set confirm command to flush buffer to flash
#ifdef _LOW_COST_SINGLE_BANK_FLASH_
WaitReady_INTEL((kal_uint32)&fp[k*PAGE_BUFFER_SIZE], INTEL_WAIT_PROGRAM);
RestoreIRQMask(savedMask);
#else
RestoreIRQMask(savedMask);
WaitReady_INTEL((kal_uint32)&fp[k*PAGE_BUFFER_SIZE], INTEL_WAIT_PROGRAM);
#endif
}
#endif
}
}
break;
default:
{
kal_uint32 i, j;
volatile FLASH_CELL *fp;
fp = (volatile FLASH_CELL *)Address;
if((((kal_uint32)Data) % sizeof(FLASH_CELL))) // Data address is not word-aligned
{
kal_uint8 *bdp = (kal_uint8*)Data;
FLASH_CELL Cell;
kal_uint8 *b = (kal_uint8*)&Cell;
j = 0;
for(i = 0; i < Length/sizeof(FLASH_CELL); i++)
{
b[0] = bdp[j++];
b[1] = bdp[j++];
savedMask = SaveAndSetIRQMask();
fp[i] = INTEL_CMD_PGM_WORD;
fp[i] = Cell;
#ifdef _LOW_COST_SINGLE_BANK_FLASH_
WaitReady_INTEL((kal_uint32)&fp[i], INTEL_WAIT_PROGRAM);
RestoreIRQMask(savedMask);
#else
RestoreIRQMask(savedMask);
WaitReady_INTEL((kal_uint32)&fp[i], INTEL_WAIT_PROGRAM);
#endif
}
}
else // Data address is word-aligned
{
FLASH_CELL *dp = (FLASH_CELL*)Data;
for(i = 0; i < Length/sizeof(FLASH_CELL); i++)
{
savedMask = SaveAndSetIRQMask();
fp[i] = INTEL_CMD_PGM_WORD;
fp[i] = dp[i];
#ifdef _LOW_COST_SINGLE_BANK_FLASH_
WaitReady_INTEL((kal_uint32)&fp[i], INTEL_WAIT_PROGRAM);
RestoreIRQMask(savedMask);
#else
RestoreIRQMask(savedMask);
WaitReady_INTEL((kal_uint32)&fp[i], INTEL_WAIT_PROGRAM);
#endif
}
}
}
break;
}
return FS_NO_ERROR;
}
#else //__INTEL_SIBLEY__
extern volatile kal_uint32 processing_irqCnt;
void CompareData(void * Address, void * Data, kal_uint32 Length)
{
kal_uint32 i;
if((kal_uint32)Address&0x11==0 && (kal_uint32)Address&0x11==0)
{
kal_uint32* Source = (kal_uint32*)Address;
kal_uint32* Dest = (kal_uint32*)Address;
if ((Length&0x11) != 0 )
ASSERT(0);
for(i=0;i<(Length>>2);i++)
{
if(Source[i] != Dest[i])
ASSERT(0);
}
}
else if((kal_uint32)Address&0x1==0 && (kal_uint32)Address&0x1==0)
{
kal_uint16* Source = (kal_uint16*)Address;
kal_uint16* Dest = (kal_uint16*)Address;
if ((Length&0x1) != 0 )
ASSERT(0);
for(i=0;i<(Length>>1);i++)
{
if(Source[i] != Dest[i])
ASSERT(0);
}
}
else
{
kal_uint8* Source = (kal_uint8*)Address;
kal_uint8* Dest = (kal_uint8*)Address;
for(i=0;i<Length;i++)
{
if(Source[i] != Dest[i])
ASSERT(0);
}
}
}
static int ProgramData_SIB(void * DriveData, void * Address, void * Data, kal_uint32 Length){
volatile FLASH_CELL* fp = (volatile FLASH_CELL*)Address;
FLASH_CELL *dp = (FLASH_CELL*)Data;
kal_uint8 *Bdp = (kal_uint8 *)Data;
kal_uint32 savedMask,i;
kal_uint32 ISRCountBefore,ISRCountAfter;
#ifndef __NOR_FDM5__
NOR_Flash_MTD_Data * D = DriveData;
ASSERT((~D->Signature == (kal_uint32)D->RegionInfo));
#else
NOR_MTD_DATA *D= DriveData;
ASSERT(D->Signature == ~((kal_uint32)D->LayoutInfo));
#endif
ISRCountBefore = processing_irqCnt;
// buffer program, data address is word-aligned
if(Length > 16)
{
ASSERT((Length&1)==0);
if (((kal_uint32)Data&0x1)==0)
{
fp[0] = INTEL_CMD_CLR_SR; //clear status register first
fp[0] = SIB_CMD_PGM_BUF_C1;
fp[0] = (Length>>1)-1;
for(i = 0; i < Length/sizeof(FLASH_CELL); i++)
{
fp[i] = dp[i];
}
fp[0] = SIB_CMD_PGM_BUF_C2;
}
// buffer program, data address is not word-aligned
else
{
FLASH_CELL Cell;
kal_uint8 *b = (kal_uint8*) &Cell;
//buffered program
fp[0] = INTEL_CMD_CLR_SR; //clear status register first
fp[0] = SIB_CMD_PGM_BUF_C1;
fp[0] = (Length>>1)-1;
for(i = 0; i < Length/sizeof(FLASH_CELL); i++)
{
b[0] = Bdp[0];
b[1] = Bdp[1];
fp[i] = Cell;
Bdp+=2;
}
fp[0] = SIB_CMD_PGM_BUF_C2;
}
ISRCountAfter = processing_irqCnt;
WaitReady_SIB((kal_uint32)&fp[0], INTEL_WAIT_PROGRAM, Length >> 5 );
if(ISRCountBefore != ISRCountAfter)
{
CompareData(Address,Data,Length);
}
}
//word program
else if(Length <= 16)
{
kal_uint32 AddrPtr = (kal_uint32)Address;
kal_uint32 DataPtr = (kal_uint32)Data;
kal_uint32 ofs;
FLASH_CELL Cell;
kal_uint8 *b = (kal_uint8*) &Cell;
// A3 must equal to zero
ASSERT(((kal_uint32)Address&0x10)==0 &&(((kal_uint32)Address+Length-1)&0x10)==0);
while(Length >0)
{
if ((AddrPtr % sizeof(FLASH_CELL) !=0) || (Length < sizeof(FLASH_CELL)))
{
ofs = (AddrPtr) & (sizeof(FLASH_CELL)-1);
fp = (FLASH_CELL*) (AddrPtr & ~(sizeof(FLASH_CELL)-1)); // round it down
Cell = fp[0];
b[ofs] = ((kal_uint8*)DataPtr)[0];
Length=Length-1;
AddrPtr=AddrPtr+1;
DataPtr=DataPtr+1;
}
else
{
fp = (FLASH_CELL*) (AddrPtr);
b[0] = ((kal_uint8*)DataPtr)[0];
b[1] = ((kal_uint8*)DataPtr)[1];
Length=Length-2;
AddrPtr=AddrPtr+2;
DataPtr=DataPtr+2;
}
savedMask = SaveAndSetIRQMask();
fp[0] = SIB_CMD_PGM_WORD;
fp[0] = Cell;
RestoreIRQMask(savedMask);
WaitReady_SIB((kal_uint32)fp, INTEL_WAIT_PROGRAM,0);
}
}
else
{
ASSERT(0);
}
return FS_NO_ERROR;
}
#endif //__INTEL_SIBLEY__
/*-----------------------------------*/
static int NonBlockEraseBlock_INTEL(void * DriveData, kal_uint32 BlockIndex) /* Added by Eric */
{
kal_uint32 savedMask;
#ifndef __NOR_FDM5__
NOR_Flash_MTD_Data * D = DriveData;
volatile FLASH_CELL *fp = (volatile FLASH_CELL *) D->CurrAddr;
ASSERT((~D->Signature == (kal_uint32)D->RegionInfo));
#else
NOR_MTD_DATA *D= DriveData;
volatile FLASH_CELL * fp = (volatile FLASH_CELL *)BlockAddress(D,BlockIndex);;
ASSERT(D->Signature == ~((kal_uint32)D->LayoutInfo));
#endif
savedMask = SaveAndSetIRQMask();
//Erase command
fp[0] = INTEL_CMD_ERASE_SETUP;
fp[0] = INTEL_CMD_ERASE_CONFIRM;
RestoreIRQMask(savedMask);
return FS_NO_ERROR;
}
/*-----------------------------------*/
static int CheckDeviceReady_INTEL(void * DriveData, kal_uint32 BlockIndex) /* Added by Eric */
{
kal_uint16 stat_data;
kal_uint32 data_cache_id;
kal_uint32 savedMask;
#ifndef __NOR_FDM5__
NOR_Flash_MTD_Data * D = DriveData;
volatile FLASH_CELL * fp = (volatile FLASH_CELL *) D->CurrAddr;
ASSERT((~D->Signature == (kal_uint32)D->RegionInfo));
#else
NOR_MTD_DATA *D= DriveData;
volatile FLASH_CELL * fp = (volatile FLASH_CELL *)BlockAddress(D,BlockIndex);
ASSERT(D->Signature == ~((kal_uint32)D->LayoutInfo));
#endif
data_cache_id = INT_DisableDataCache();
savedMask = SaveAndSetIRQMask();
fp[0] = INTEL_CMD_RD_SR;
stat_data = fp[0];
fp[0] = INTEL_CMD_RD_ARRAY;
RestoreIRQMask(savedMask);
INT_RestoreDataCache(data_cache_id);
if(stat_data & INTEL_READY_FLAG)
return FS_NO_ERROR;
else
return FS_FLASH_ERASE_BUSY;
}
/*-----------------------------------*/
static int SuspendErase_INTEL(void * DriveData, kal_uint32 BlockIndex) /* Added by Eric */
{
#ifndef __NOR_FDM5__
NOR_Flash_MTD_Data * D = DriveData;
volatile FLASH_CELL *fp = (volatile FLASH_CELL *) D->CurrAddr;
#else
NOR_MTD_DATA *D= DriveData;
volatile FLASH_CELL * fp = (volatile FLASH_CELL *)BlockAddress(D,BlockIndex);
#endif
FLASH_CELL s = 0;
kal_uint32 data_cache_id;
#ifdef _LOW_COST_SINGLE_BANK_FLASH_
kal_uint32 savedMask;
savedMask = SaveAndSetIRQMask();
#endif
data_cache_id = INT_DisableDataCache();
fp[0] = INTEL_CMD_SUSPEND;
fp[0] = INTEL_CMD_RD_SR;
s = fp[0];
while(!(s&INTEL_READY_FLAG))
{
fp[0] = INTEL_CMD_RD_SR;
s = fp[0];
}
fp[0] = INTEL_CMD_RD_ARRAY;
#ifdef _LOW_COST_SINGLE_BANK_FLASH_
RestoreIRQMask(savedMask);
#endif
INT_RestoreDataCache(data_cache_id);
return FS_NO_ERROR;
}
/*-----------------------------------*/
static int ResumeErase_INTEL(void * DriveData, kal_uint32 BlockIndex) /* Added by Eric */
{
#ifndef __NOR_FDM5__
NOR_Flash_MTD_Data * D = DriveData;
volatile FLASH_CELL *fp = (volatile FLASH_CELL *) D->CurrAddr;
#else
NOR_MTD_DATA *D= DriveData;
volatile FLASH_CELL * fp = (volatile FLASH_CELL *)BlockAddress(D,BlockIndex);
#endif
fp[0] = INTEL_CMD_RESUME;
return FS_NO_ERROR;
}
/*-----------------------------------*/
#ifdef __INTEL_SIBLEY__
static int BlankCheck_SIB(void * DriveData, kal_uint32 BlockIndex) //Especially for Sibley
{
kal_uint32 savedMask;
kal_uint16 stat_data;
#ifndef __NOR_FDM5__
NOR_Flash_MTD_Data * D = DriveData;
volatile FLASH_CELL * fp = (volatile FLASH_CELL *) D->CurrAddr;
ASSERT((~D->Signature == (kal_uint32)D->RegionInfo));
#else
NOR_MTD_DATA *D= DriveData;
volatile FLASH_CELL * fp = (volatile FLASH_CELL *)BlockAddress(D,BlockIndex);
ASSERT(D->Signature == ~((kal_uint32)D->LayoutInfo));
#endif
savedMask = SaveAndSetIRQMask();
//Blank Check Command
fp[0] = SIB_CMD_BLANK_CK_C1;
fp[0] = SIB_CMD_BLANK_CK_C2;
RestoreIRQMask(savedMask);
WaitReady_INTEL((kal_uint32)fp, SIB_WAIT_BLANK_CHECK);
//Read Status Command
fp[0] = INTEL_CMD_RD_SR;
stat_data = fp[0];
fp[0] = INTEL_CMD_CLR_SR;
fp[0] = INTEL_CMD_RD_ARRAY;
return (stat_data & SIB_NOT_ALL_ERASED_FLAG)?0:1; // SR[5]=1 means not all erased
}
#endif
/********************************************/
/* */
/* FDM5.0 MTD SUPPORT */
/* */
/********************************************/
#ifdef __NOR_FDM5__
static int MountDevice_INTEL(void * DriveData, void * Info)
{
NOR_MTD_DATA * D = DriveData;
NORLayoutInfo * Layout = D->LayoutInfo;
kal_uint32 TotalPhysicalPages;
kal_uint32 TblEntryShift=0,j=1;
kal_uint32 block;
volatile FLASH_CELL * fp;
kal_uint32 savedMask;
kal_uint32 data_cache_id;
// check and assign D->LayoutInfo
TotalPhysicalPages = (Layout->BlkSize)/(Layout->PageSize)*(Layout->TotalBlks);
while(j<TotalPhysicalPages)
{
j = j << 1;
TblEntryShift++;
}
TblEntryShift = TblEntryShift>>1;
if((TblEntryShift) >8)
TblEntryShift=8;
Layout->TblEntrys = 1<<TblEntryShift;
if ( (Layout->TblEntrys * Layout->TotalLSMT) < TotalPhysicalPages)
ASSERT(0);
/* unlock all blocks */
for(block=0; block< Layout->TotalBlks; block++)
{
fp = (volatile FLASH_CELL *) BlockAddress(D, block);
savedMask = SaveAndSetIRQMask();
data_cache_id = INT_DisableDataCache();
UNLOCK_COMMAND(0)
fp[0] = INTEL_CMD_RD_ID;
if( fp[2] & INTEL_BLOCK_LOCK_FLAG)
ASSERT(0);
fp[0] = INTEL_CMD_RD_ARRAY;
INT_RestoreDataCache(data_cache_id);
RestoreIRQMask(savedMask);
}
return FS_NO_ERROR;
}
static int ShutDown_INTEL(void * DriveData)
{
NOR_MTD_DATA * D = DriveData;
NORBankInfo * BankInfo = D->LayoutInfo->BankInfo;
kal_uint32 fp = (kal_uint32)D->BaseAddr;
kal_uint32 i=0,j=0;
for(i=0;BankInfo[i].Banks !=0;i++)
for(j=0;j<BankInfo[i].Banks;j++)
{
WaitReady_INTEL((kal_uint32)fp, INTEL_WAIT_ERASE);
fp+=(kal_uint32)BankInfo[i].BankSize;
}
return FS_NO_ERROR;
}
#endif
#if (defined(_LOW_COST_SINGLE_BANK_FLASH_) && defined(__MTK_TARGET__))
#pragma arm section code
#endif
/*-----------------------------------*/
NOR_MTD_Driver DriverName =
{
MountDevice_INTEL,
ShutDown_INTEL,
MapWindow,
EraseBlock_INTEL,
#ifndef __INTEL_SIBLEY__
ProgramData_INTEL,
#else
ProgramData_SIB,
#endif
NonBlockEraseBlock_INTEL,
CheckDeviceReady_INTEL,
SuspendErase_INTEL,
ResumeErase_INTEL,
#ifndef __INTEL_SIBLEY__
NULL
#else
BlankCheck_SIB
#endif
};
#endif //__INTEL_SERIES_NOR__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -