📄 flash_mtd.amd.c
字号:
savedMask = SaveAndSetIRQMask();
bp[ADDR_UNLOCK_1] = CMD_UNLOCK_1;
bp[ADDR_UNLOCK_2] = CMD_UNLOCK_2;
bp[ADDR_UNLOCK_1] = CMD_PROG;
((volatile FLASH_CELL*)Address)[0] = ((FLASH_CELL*)Data)[0];
#ifdef _LOW_COST_SINGLE_BANK_FLASH_
WaitReady_AMD((kal_uint32)Address, *(kal_uint16*)Data);
RestoreIRQMask(savedMask);
#else
RestoreIRQMask(savedMask);
WaitReady_AMD((kal_uint32)Address, *(kal_uint16*)Data);
#endif
break;
case 1:
{
volatile FLASH_CELL *fp;
kal_uint32 ofs = ((kal_uint32) Address) & (sizeof(FLASH_CELL)-1);
FLASH_CELL Cell;
kal_uint8 *b = (kal_uint8*) &Cell;
fp = (void*) (((kal_uint32) Address) & ~(sizeof(FLASH_CELL)-1)); // round it down
Cell = fp[0];
b[ofs] = ((kal_uint8*)Data)[0];
#ifdef DEBUG
//Attempt to set bits in flash!
ASSERT(!((~fp[0]) & Cell))
#endif
savedMask = SaveAndSetIRQMask();
bp[ADDR_UNLOCK_1] = CMD_UNLOCK_1;
bp[ADDR_UNLOCK_2] = CMD_UNLOCK_2;
bp[ADDR_UNLOCK_1] = CMD_PROG;
fp[0] = Cell;
#ifdef _LOW_COST_SINGLE_BANK_FLASH_
WaitReady_AMD((kal_uint32)fp, (kal_uint16)Cell);
RestoreIRQMask(savedMask);
#else
RestoreIRQMask(savedMask);
WaitReady_AMD((kal_uint32)fp, (kal_uint16)Cell);
#endif
}
break;
default:
#ifdef DEBUG
//Misaligned write into flash
ASSERT(!(((kal_uint32)Address) % sizeof(FLASH_CELL)));
//Misaligned length write into flash
ASSERT(!(Length % sizeof(FLASH_CELL)));
#endif
#ifdef DEBUG
{
kal_uint32 i;
volatile FLASH_CELL *fp = (void*) Address;
FLASH_CELL * V = Data;
for (i=0; i<Length/sizeof(FLASH_CELL); i++)
ASSERT(!((~fp[i]) & V[i]));//Attempt to set bits in flash!
}
#endif
{
kal_uint32 i, j;
#ifdef __PAGE_BUFFER_PROGRAM__
kal_uint32 Words;
kal_uint32 ProgramWords;
#endif
volatile FLASH_CELL *fp;
fp = (volatile FLASH_CELL *)Address;
if((((kal_uint32)Data) % sizeof(FLASH_CELL)))
{
kal_uint8 *bdp = (kal_uint8*)Data;
FLASH_CELL Cell;
kal_uint8 *b = (kal_uint8*)&Cell;
#ifndef __PAGE_BUFFER_PROGRAM__
j = 0;
for(i = 0; i < Length/sizeof(FLASH_CELL); i++)
{
b[0] = bdp[j++];
b[1] = bdp[j++];
savedMask = SaveAndSetIRQMask();
bp[ADDR_UNLOCK_1] = CMD_UNLOCK_1;
bp[ADDR_UNLOCK_2] = CMD_UNLOCK_2;
bp[ADDR_UNLOCK_1] = CMD_PROG;
fp[i] = Cell;
#ifdef _LOW_COST_SINGLE_BANK_FLASH_
WaitReady_AMD((kal_uint32)&fp[i], (kal_uint16)Cell);
RestoreIRQMask(savedMask);
#else
RestoreIRQMask(savedMask);
WaitReady_AMD((kal_uint32)&fp[i], (kal_uint16)Cell);
#endif
}
#else
j = 0;
Words = (Length/sizeof(FLASH_CELL));
while(Words>0)
{
ProgramWords = Words > PAGE_BUFFER_SIZE ? PAGE_BUFFER_SIZE : Words ;
savedMask = SaveAndSetIRQMask();
bp[ADDR_UNLOCK_1] = CMD_UNLOCK_1;
bp[ADDR_UNLOCK_2] = CMD_UNLOCK_2;
fp[0] = CMD_WRITETOBUFFER;
fp[0] = ProgramWords -1;// set data count
for(i = 0; i < ProgramWords; i++)
{
b[0] = bdp[j++];
b[1] = bdp[j++];
fp[i] = Cell;
}
fp[0] = CMD_BUFFERTOFLASH;
#ifdef _LOW_COST_SINGLE_BANK_FLASH_
WaitReady_AMD((kal_uint32)&fp[ProgramWords -1], (kal_uint16)Cell);
RestoreIRQMask(savedMask);
#else
RestoreIRQMask(savedMask);
#ifdef __SPANSION_PL_N__
DelayAWhile_AMD();
#endif //__SPANSION_PL_N__
WaitReady_AMD((kal_uint32)&fp[ProgramWords -1], (kal_uint16)Cell);
#endif
Words -= ProgramWords;
fp += ProgramWords;
}
#endif
}
else
{
FLASH_CELL *dp = (FLASH_CELL*)Data;
#ifndef __PAGE_BUFFER_PROGRAM__
for(i = 0; i < Length/sizeof(FLASH_CELL); i++)
{
savedMask = SaveAndSetIRQMask();
bp[ADDR_UNLOCK_1] = CMD_UNLOCK_1;
bp[ADDR_UNLOCK_2] = CMD_UNLOCK_2;
bp[ADDR_UNLOCK_1] = CMD_PROG;
fp[i] = dp[i];
#ifdef _LOW_COST_SINGLE_BANK_FLASH_
WaitReady_AMD((kal_uint32)&fp[i], (kal_uint16)dp[i]);
RestoreIRQMask(savedMask);
#else
RestoreIRQMask(savedMask);
WaitReady_AMD((kal_uint32)&fp[i], (kal_uint16)dp[i]);
#endif
}
#else
Words = (Length/sizeof(FLASH_CELL));
while(Words>0)
{
ProgramWords = Words > PAGE_BUFFER_SIZE ? PAGE_BUFFER_SIZE : Words ;
savedMask = SaveAndSetIRQMask();
bp[ADDR_UNLOCK_1] = CMD_UNLOCK_1;
bp[ADDR_UNLOCK_2] = CMD_UNLOCK_2;
fp[0] = CMD_WRITETOBUFFER;
fp[0] = ProgramWords -1;// set data count
for(i = 0; i < ProgramWords; i++)
{
fp[i] = dp[i];
}
fp[0] = CMD_BUFFERTOFLASH;
#ifdef _LOW_COST_SINGLE_BANK_FLASH_
WaitReady_AMD((kal_uint32)&fp[ProgramWords -1], (kal_uint16)dp[ProgramWords -1]);
RestoreIRQMask(savedMask);
#else //_LOW_COST_SINGLE_BANK_FLASH_
RestoreIRQMask(savedMask);
#ifdef __SPANSION_PL_N__
DelayAWhile_AMD();
#endif //__SPANSION_PL_N__
WaitReady_AMD((kal_uint32)&fp[ProgramWords -1], (kal_uint16)dp[ProgramWords -1]);
#endif //_LOW_COST_SINGLE_BANK_FLASH_
Words -= ProgramWords;
fp += ProgramWords;
dp += ProgramWords;
}
#endif
}
}
break;
}
return FS_NO_ERROR;
}
#endif //__TOSHIBA_TV__
/*-----------------------------------*/
static int NonBlockEraseBlock_AMD(void * DriveData, kal_uint32 BlockIndex) /* Added by Eric */
{
NOR_Flash_MTD_Data * D = DriveData;
volatile FLASH_CELL *fp = (volatile FLASH_CELL *) D->CurrAddr;
#ifdef DEBUG
//EraseBlock: block not mapped
ASSERT(D->CurrAddr == BlockAddress(D, BlockIndex));
#endif
ASSERT((~D->Signature == (kal_uint32)D->RegionInfo));
EraseCommand_AMD(fp);
#ifdef __SPANSION_PL_N__
DelayAWhile_AMD();
#endif
return FS_NO_ERROR;
}
/*-----------------------------------*/
static int CheckDeviceReady_AMD(void * DriveData, kal_uint32 BlockIndex) /* Added by Eric */
{
NOR_Flash_MTD_Data * D = DriveData;
volatile FLASH_CELL *fp = (volatile FLASH_CELL *) D->CurrAddr;
FLASH_CELL s1, s2;
kal_uint32 data_cache_id;
#ifndef __PRODUCTION_RELEASE__
static kal_uint32 test_times=0;
#endif
data_cache_id = INT_DisableDataCache();
s1 = fp[1];
s2 = fp[1];
if (((s1 ^ s2) & TOGGLE_ERASE_SUSPEND))
{
if(!((s1 ^ s2) & TOGGLE_BUSY))
{
/* flash is erase suspended */
fp[0] = CMD_RESU_SEC_ERASE;
}
INT_RestoreDataCache(data_cache_id);
return FS_FLASH_ERASE_BUSY;
}
else
{
s1 = fp[1];
s2 = fp[1];
if(s2 == 0xffff)
{
INT_RestoreDataCache(data_cache_id);
#ifndef __PRODUCTION_RELEASE__
test_times = 0;
#endif
return FS_NO_ERROR;
}
else
{
/* the erase operation is reset abnormally */
if(!(s1 ^ s2))
{
#ifndef __PRODUCTION_RELEASE__
/* MAUI_00218339: S71PL129JB0BAW9U need another busy time before */
/* polling, modify to allow second erase command to solve this issue */
test_times++;
if (test_times > 1)
ASSERT(0);
#endif
EraseCommand_AMD(fp);
}
INT_RestoreDataCache(data_cache_id);
return FS_FLASH_ERASE_BUSY;
}
}
}
/*-----------------------------------*/
static int SuspendErase_AMD(void * DriveData, kal_uint32 BlockIndex) /* Added by Eric */
{
NOR_Flash_MTD_Data * D = DriveData;
volatile FLASH_CELL *fp = (volatile FLASH_CELL *) D->CurrAddr;
FLASH_CELL s;
kal_uint32 data_cache_id;
#ifdef _LOW_COST_SINGLE_BANK_FLASH_
kal_uint32 savedMask;
savedMask = SaveAndSetIRQMask();
#endif
data_cache_id = INT_DisableDataCache();
#ifdef DEBUG
#ifndef _LOW_COST_SINGLE_BANK_FLASH_
//SuspendErase: block not mapped
ASSERT(D->CurrAddr == BlockAddress(D, BlockIndex));
#endif
#endif
fp[0] = CMD_SUSP_SEC_ERASE;
s = fp[0];
while(!(s&POLL_BUSY))
s = fp[0];
INT_RestoreDataCache(data_cache_id);
#ifdef _LOW_COST_SINGLE_BANK_FLASH_
RestoreIRQMask(savedMask);
#endif
return FS_NO_ERROR;
}
/*-----------------------------------*/
static int ResumeErase_AMD(void * DriveData, kal_uint32 BlockIndex) /* Added by Eric */
{
NOR_Flash_MTD_Data * D = DriveData;
volatile FLASH_CELL *fp = (volatile FLASH_CELL *) D->CurrAddr;
#ifdef DEBUG
//ResumeErase: block not mapped
ASSERT(D->CurrAddr == BlockAddress(D, BlockIndex));
#endif
fp[0] = CMD_RESU_SEC_ERASE;
return FS_NO_ERROR;
}
#ifdef _LOW_COST_SINGLE_BANK_FLASH_
#ifdef __MTK_TARGET__
#pragma arm section code
#endif /* __MTK_TARGET__ */
#endif
/*-----------------------------------*/
NOR_MTD_Driver DriverName =
{
MountDevice_AMD,
ShutDown_AMD,
MapWindow,
EraseBlock_AMD,
#if (defined(__TOSHIBA_TV__) || defined(__TOSHIBA_TY__))
ProgramData_TOSHIBA,
#else
ProgramData_AMD,
#endif
NonBlockEraseBlock_AMD,
CheckDeviceReady_AMD,
SuspendErase_AMD,
ResumeErase_AMD
};
#endif //__AMD_SERIES_NOR__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -