📄 onenand.c
字号:
{
return eOND_NOERROR;
}
#endif
#if 0
ONENAND_WriteCmd(Controller, uEndBlkAddr, 0, 0x00);
ONENAND_ReadCmd(Controller, uEndBlkAddr, 0, &uData);
// Wait Erase Completion
while(uData)
{
ONENAND_ReadCmd(Controller, uEndBlkAddr, &uData);
}
return eOND_ERSCMP;
#endif
if(OneNandT_oIntFlag.ErsCmpInt == 1)
return eOND_NOERROR;
else
return eOND_ERSFAIL;
}
#else
OneNAND_eINTERROR ONENAND_EraseBlock(u32 Controller, u32 uStartBlkAddr, u32 uEndBlkAddr)
{
u32 i, j, uBlockSize, uQuotient, uRemainder;
u32 uBlock;
if(uEndBlkAddr < uStartBlkAddr)
return eOND_NOERROR;
OneNandT_oIntFlag.IntActInt = 0;
OneNandT_oIntFlag.ErsFailInt = 0;
OneNandT_oIntFlag.LockedBlkInt = 0;
OneNandT_oIntFlag.ErsCmpInt = 0;
if(uStartBlkAddr == uEndBlkAddr)
{
ONENAND_WriteCmd(Controller, uEndBlkAddr, 0, 0x03);
while(!OneNandT_oIntFlag.IntActInt);
OneNandT_oIntFlag.IntActInt = 0;
ONENAND_WriteCmd(Controller, uEndBlkAddr, 0, 0x15);
while(!OneNandT_oIntFlag.IntActInt);
if(OneNandT_oIntFlag.ErsFailInt == 1)
{
OneNandT_oIntFlag.ErsFailInt = 0;
if(OneNandT_oIntFlag.LockedBlkInt == 1)
return (OneNAND_eINTERROR)(eOND_ERSFAIL | eOND_LOCKEDBLK);
return eOND_ERSFAIL;
}
}
else
{
uBlockSize = uEndBlkAddr - uStartBlkAddr + 1;
uQuotient = uBlockSize/OND_MULTIERASE_SIZE;
uRemainder = uBlockSize%OND_MULTIERASE_SIZE;
uBlock = uStartBlkAddr;
for(i=0 ; i<uQuotient ; i++)
{
for(j=uBlock ; j<(uBlock+OND_MULTIERASE_SIZE-1) ; j++)
{
OneNandT_oIntFlag.IntActInt = 0;
ONENAND_WriteCmd(Controller, j, 0, 0x01);
while(!OneNandT_oIntFlag.IntActInt);
}
ONENAND_WriteCmd(Controller, uBlock+OND_MULTIERASE_SIZE-1, 0, 0x03);
while(!OneNandT_oIntFlag.IntActInt);
// Verify Erase block
for(j=uBlock ; j<=(uBlock+OND_MULTIERASE_SIZE-1) ; j++)
{
OneNandT_oIntFlag.IntActInt = 0;
ONENAND_WriteCmd(Controller, j, 0, 0x15);
while(!OneNandT_oIntFlag.IntActInt);
if(OneNandT_oIntFlag.ErsFailInt == 1)
{
OneNandT_oIntFlag.ErsFailInt = 0;
if(OneNandT_oIntFlag.LockedBlkInt == 1)
return (OneNAND_eINTERROR)(eOND_ERSFAIL | eOND_LOCKEDBLK);
return eOND_ERSFAIL;
}
}
uBlock += OND_MULTIERASE_SIZE;
}
if(uRemainder > 0)
{
for(i=uBlock ; i<(uBlock+uRemainder-1) ; i++)
{
OneNandT_oIntFlag.IntActInt = 0;
ONENAND_WriteCmd(Controller, i, 0, 0x01);
while(!OneNandT_oIntFlag.IntActInt);
}
ONENAND_WriteCmd(Controller, uBlock+uRemainder-1, 0, 0x03);
while(!OneNandT_oIntFlag.IntActInt);
// Verify Erase block
for(i=uBlock ; i<=(uBlock+uRemainder-1) ; i++)
{
OneNandT_oIntFlag.IntActInt = 0;
ONENAND_WriteCmd(Controller, i, 0, 0x15);
while(!OneNandT_oIntFlag.IntActInt);
if(OneNandT_oIntFlag.ErsFailInt == 1)
{
OneNandT_oIntFlag.ErsFailInt = 0;
if(OneNandT_oIntFlag.LockedBlkInt == 1)
return (OneNAND_eINTERROR)(eOND_ERSFAIL | eOND_LOCKEDBLK);
return eOND_ERSFAIL;
}
}
}
}
if(OneNandT_oIntFlag.ErsCmpInt == 1)
return eOND_NOERROR;
else
return eOND_ERSFAIL;
}
#endif
//////////
// Function Name : ONENAND_EraseVerify
// Function Description : Verify Memory Block Erase
// Input : Controller - OneNand Controller Port Number
// uBlkAddr - Block Number
// Version : v0.1
OneNAND_eINTERROR ONENAND_EraseVerify(u32 Controller, u32 uBlkAddr)
{
bool uError;
OneNandT_oIntFlag.IntActInt = 0;
ONENAND_WriteCmd(Controller, uBlkAddr, 0, 0x15);
//Interrupt肺 背眉
//while(!(ONENAND(Controller)->rIntErrStat & (1<<10)));
//Outp32(&ONENAND(Controller)->rIntErrAck, (1<<10));
while(!OneNandT_oIntFlag.IntActInt);
uError = Inp32(&ONENAND(Controller)->rIntErrStat);
if (uError & (1<<3))
{
//Erase fail
Outp32(&ONENAND(Controller)->rIntErrAck, (1<<3));
return eOND_ERSFAIL;
}
return eOND_NOERROR;
}
//////////
// Function Name : ONENAND_CopyBack
// Function Description : Copy-back operation
// Input : Controller - OneNand Controller Port Number
// uSourceBlkAddr - Source Block number
// uSourcePageAddr - Source Page number
// uDestinationBlkAddr - Destination Block number
// uDestinationPageAddr - Destination Page number
// uPageSize - Page size to be copied
// Version : v0.1
bool ONENAND_CopyBack(u32 Controller, u32 uSourceBlkAddr, u8 uSourcePageAddr, u32 uDestinationBlkAddr, u8 uDestinationPageAddr, u32 uPageSize)
{
OneNandT_oIntFlag.IntActInt = 0;
OneNandT_oIntFlag.BlkRwCmpInt = 0;
OneNandT_oIntFlag.PgmCmpInt = 0;
ONENAND_WriteCmd(Controller, uSourceBlkAddr, uSourcePageAddr, 0x1000);
ONENAND_WriteCmd(Controller, uDestinationBlkAddr, uDestinationPageAddr, (0x2000|(uPageSize&0xFF)));
//Interrupt肺 背眉
//while(!(ONENAND(Controller)->rIntErrStat & (1<<10)));
//Outp32(&ONENAND(Controller)->rIntErrAck, (1<<10));
while(!OneNandT_oIntFlag.IntActInt);
//Interrupt肺 背眉
//while(!(ONENAND(Controller)->rIntErrStat & (1<<7)));
//Outp32(&ONENAND(Controller)->rIntErrAck, (1<<7));
while(!OneNandT_oIntFlag.BlkRwCmpInt);
//Interrupt肺 背眉
//while(!(ONENAND(Controller)->rIntErrStat & (1<<5)));
//Outp32(&ONENAND(Controller)->rIntErrAck, (1<<5));
while(!OneNandT_oIntFlag.PgmCmpInt);
return TRUE;
}
//////////
// Function Name : ONENAND_WritePage
// Function Description : Write 1 Page
// Input : Controller - OneNand Controller Port Number
// uBlkAddr - Block Number to write
// uPageAddr - Page number to write
// aData - Start Address of the data array
// Version : v0.1
bool ONENAND_WritePage(u32 Controller, u32 uBlkAddr, u8 uPageAddr, u32* aData)
{
OneNandT_oIntFlag.IntActInt = 0;
OneNandT_oIntFlag.BlkRwCmpInt = 0;
OneNandT_oIntFlag.PgmCmpInt = 0;
#if (OND_TRANS_MODE == OND_POLLING)
{
u32 i;
for(i=0; i<ONENAND_PAGESIZE/4; i++)
{
ONENAND_WriteIntoFlash(Controller, uBlkAddr, uPageAddr, *aData);
aData++;
}
}
#elif (OND_TRANS_MODE == OND_DMA)
{
u32 uDstAddr;
OneNand_DmaDone = 0;
uDstAddr = OneNAND_ARRAY_BASE[Controller] + ((FbaMask[Controller] & uBlkAddr)<<FbaShift[Controller]) +((FpaMask[Controller] & uPageAddr)<<FpaShift[Controller]);
#if (ONENAND_VERSION == ONENAND_EVT0)
DMACH_Setup(DMA_A, 0x0, (u32)aData, 0, (u32)uDstAddr, 1, WORD, ONENAND_PAGESIZE/4, DEMAND, MEM, MEM, BURST128, &g_oONDDmac0);
#elif (ONENAND_VERSION == ONENAND_EVT1)
DMACH_Setup(DMA_D, 0, (u32)aData, 0, (u32)uDstAddr, 0, WORD, ONENAND_PAGESIZE/4, DEMAND, MEM, DMA0_OND_RX, BURST4, &g_oONDDmac0);
//DMACH_Setup(DMA_A, 0x0, (u32)aData, 0, (u32)uDstAddr, 1, WORD, ONENAND_PAGESIZE/4, DEMAND, MEM, MEM, BURST128, &g_oONDDmac0);
#endif
DMACH_Start(&g_oONDDmac0);
while(!OneNand_DmaDone);
}
#else
{
u32 uDstAddr, uContBaseAddr;
if(Controller == 0)
uContBaseAddr = ONENAND0_BASE;
else
uContBaseAddr = ONENAND1_BASE;
uDstAddr = OneNAND_ARRAY_BASE[Controller] + ((FbaMask[Controller] & uBlkAddr)<<FbaShift[Controller]) +((FpaMask[Controller] & uPageAddr)<<FpaShift[Controller]);
OneNandPageWrite(uContBaseAddr, (u32)aData, uDstAddr);
}
#endif
while(!OneNandT_oIntFlag.IntActInt);
while(!OneNandT_oIntFlag.BlkRwCmpInt);
while(!OneNandT_oIntFlag.PgmCmpInt);
return TRUE;
}
//////////
// Function Name : ONENAND_ReadPage
// Function Description : Read 1 Page
// Input : Controller - OneNand Controller Port Number
// uBlkAddr - Block Number to read
// uPageAddr - Page number to read
// aData - Start Address of the data array
// Version : v0.1
extern void TCM_DMA_ReadTransfer(u32 uSrcAddr, u32 uDstAddr);
bool ONENAND_ReadPage(u32 Controller, u32 uBlkAddr, u8 uPageAddr, u32* aData)
{
OneNandT_oIntFlag.IntActInt = 0;
OneNandT_oIntFlag.BlkRwCmpInt = 0;
OneNandT_oIntFlag.LoadCmpInt = 0;
#if (OND_TRANS_MODE == OND_POLLING)
{
u32 i;
for(i=0; i<ONENAND_PAGESIZE/4; i++)
{
ONENAND_ReadOutFlash(Controller, uBlkAddr, uPageAddr, aData);
aData++;
}
}
#elif (OND_TRANS_MODE == OND_DMA)
{
#if 0 //TCM DMA
u32 uSrcAddr;
uSrcAddr = OneNAND_ARRAY_BASE[Controller] + ((FbaMask[Controller] & uBlkAddr)<<FbaShift[Controller]) +((FpaMask[Controller] & uPageAddr)<<FpaShift[Controller]);
TCM_DMA_ReadTransfer(uSrcAddr, (u32)aData);
#else
u32 uSrcAddr;
OneNand_DmaDone = 0;
uSrcAddr = OneNAND_ARRAY_BASE[Controller] + ((FbaMask[Controller] & uBlkAddr)<<FbaShift[Controller]) +((FpaMask[Controller] & uPageAddr)<<FpaShift[Controller]);
#if (ONENAND_VERSION == ONENAND_EVT0)
//ONENAND_SetLLI(uSrcAddr, (u32)aData);
//DMACH_Setup(DMA_A, ONENAND_LLI_BASE+0x20, (u32)uSrcAddr, 0, (u32)aData, 0, WORD, 4, DEMAND, MEM, MEM, BURST4, &g_oONDDmac0);
DMACH_Setup(DMA_A, 0, (u32)uSrcAddr, 1, (u32)aData, 0, WORD, ONENAND_PAGESIZE/4, DEMAND, MEM, MEM, BURST128, &g_oONDDmac0);
#elif (ONENAND_VERSION == ONENAND_EVT1)
DMACH_Setup(DMA_D, 0, (u32)uSrcAddr, 0, (u32)aData, 0, WORD, ONENAND_PAGESIZE/4, DEMAND, DMA0_OND_TX, MEM, BURST4, &g_oONDDmac0);
//DMACH_Setup(DMA_A, 0, (u32)uSrcAddr, 1, (u32)aData, 0, WORD, ONENAND_PAGESIZE/4, DEMAND, MEM, MEM, BURST128, &g_oONDDmac0);
#endif
DMACH_Start(&g_oONDDmac0);
while(!OneNand_DmaDone);
#endif
}
#else // using the "LDM" instruction
{
u32 uSrcAddr, uContBaseAddr;
if(Controller == 0)
uContBaseAddr = ONENAND0_BASE;
else
uContBaseAddr = ONENAND1_BASE;
uSrcAddr = OneNAND_ARRAY_BASE[Controller] + ((FbaMask[Controller] & uBlkAddr)<<FbaShift[Controller]) +((FpaMask[Controller] & uPageAddr)<<FpaShift[Controller]);
OneNandPageRead(uContBaseAddr, uSrcAddr, (u32)aData);
}
#endif
while(!OneNandT_oIntFlag.IntActInt);
while(!OneNandT_oIntFlag.BlkRwCmpInt);
while(!OneNandT_oIntFlag.LoadCmpInt);
OneNandT_oIntFlag.IntActInt = 0;
OneNandT_oIntFlag.BlkRwCmpInt = 0;
OneNandT_oIntFlag.LoadCmpInt = 0;
return TRUE;
}
bool ONENAND_ReadPageForCacheRead(u32 Controller, u32 uBlkAddr, u8 uPageAddr, u32* aData, u32 uPageSize)
{
OneNandT_oIntFlag.IntActInt = 0;
OneNandT_oIntFlag.BlkRwCmpInt = 0;
OneNandT_oIntFlag.LoadCmpInt = 0;
#if (OND_TRANS_MODE == OND_POLLING)
{
u32 i;
for(i=0; i<ONENAND_PAGESIZE/4; i++)
{
ONENAND_ReadOutFlash(Controller, uBlkAddr, uPageAddr, aData);
aData++;
}
}
#elif (OND_TRANS_MODE == OND_DMA)
{
u32 uSrcAddr;
OneNand_DmaDone = 0;
uSrcAddr = OneNAND_ARRAY_BASE[Controller] + ((FbaMask[Controller] & uBlkAddr)<<FbaShift[Controller]) +((FpaMask[Controller] & uPageAddr)<<FpaShift[Controller]);
#if (ONENAND_VERSION == ONENAND_EVT0)
//ONENAND_SetLLI(uSrcAddr, (u32)aData);
//DMACH_Setup(DMA_A, ONENAND_LLI_BASE+0x20, (u32)uSrcAddr, 0, (u32)aData, 0, WORD, 4, DEMAND, MEM, MEM, BURST4, &g_oONDDmac0);
DMACH_Setup(DMA_A, 0, (u32)uSrcAddr, 1, (u32)aData, 0, WORD, ONENAND_PAGESIZE/4, DEMAND, MEM, MEM, BURST128, &g_oONDDmac0);
#elif (ONENAND_VERSION == ONENAND_EVT1)
DMACH_Setup(DMA_D, 0, (u32)uSrcAddr, 0, (u32)aData, 0, WORD, ONENAND_PAGESIZE/4, DEMAND, DMA0_OND_TX, MEM, BURST4, &g_oONDDmac0);
//DMACH_Setup(DMA_A, 0, (u32)uSrcAddr, 1, (u32)aData, 0, WORD, ONENAND_PAGESIZE/4, DEMAND, MEM, MEM, BURST128, &g_oONDDmac0);
#endif
DMACH_Start(&g_oONDDmac0);
while(!OneNand_DmaDone);
}
#else
{
u32 uSrcAddr, uContBaseAddr;
if(Controller == 0)
uContBaseAddr = ONENAND0_BASE;
else
uContBaseAddr = ONENAND1_BASE;
uSrcAddr = OneNAND_ARRAY_BASE[Controller] + ((FbaMask[Controller] & uBlkAddr)<<FbaShift[Controller]) +((FpaMask[Controller] & uPageAddr)<<FpaShift[Controller]);
OneNandPageRead(uContBaseAddr, uSrcAddr, (u32)aData);
}
#endif
#if 0
// rb1004...When HCLK is low(~50MHz), Interrupt loss is occured.
if(OneNandT_oIntFlag.IntActInt_Count != uPageSize)
{
while(!OneNandT_oIntFlag.IntActInt);
while(!OneNandT_oIntFlag.BlkRwCmpInt);
while(!OneNandT_oIntFlag.LoadCmpInt);
}
#endif
return TRUE;
}
//////////
// Function Name : ONENAND_ReadPageWithSpare
// Function Description : Read 1 Page with Spare area data
// Input : Controller - OneNand Controller Port Number
// uBlkAddr - Block Number to read
// uPageAddr - Page number to read
// aData - Start Address of the data array
// Version : v0.1
bool ONENAND_ReadPageWithSpare(u32 Controller, u32 uBlkAddr, u8 uPageAddr, u32* aData, u32 *aSpare)
{
u32 i;
OneNandT_oIntFlag.IntActInt = 0;
OneNandT_oIntFlag.BlkRwCmpInt = 0;
OneNandT_oIntFlag.LoadCmpInt = 0;
for(i=0; i<ONENAND_PAGESIZE/4; i++)
{
ONENAND_ReadOutFlash(Controller, uBlkAddr, uPageAddr, aData);
aData++;
}
for(i=0; i<ONENAND_SPARESIZE/4; i++)
{
ONENAND_ReadOutFlash(Controller, uBlkAddr, uPageAddr, aSpare);
aSpare++;
}
//Interrupt肺 背眉
//while(!(ONENAND(Controller)->rIntErrStat & (1<<10)));
//Outp32(&ONENAND(Controller)->rIntErrAck, (1<<10));
while(!OneNandT_oIntFlag.IntActInt);
//Interrupt肺 背眉
//while(!(ONENAND(Controller)->rIntErrStat & (1<<7)));
//Outp32(&ONENAND(Controller)->rIntErrAck, (1<<7));
while(!OneNandT_oIntFlag.BlkRwCmpInt);
//Interrupt肺 背眉
//while(!(ONENAND(Controller)->rIntErrStat & (1<<4)));
//Outp32(&ONENAND(Controller)->rIntErrAck, (1<<4));
while(!OneNandT_oIntFlag.LoadCmpInt);
return TRUE;
}
//////////
// Function Name : ONENAND_LoadToXIPBuffer
// Function Description : Load the page specified by the FBA,FPA,FSA to the map00 XIP buffer
// Input : Controller - OneNand Controller Port Number
// uBlkAddr - Block Number to load
// uPageAddr - Page number to load
// Version : v0.1
void ONENAND_LoadToXIPBuffer(u32 Controller, u32 uBlkAddr, u8 uPageAddr)
{
OneNandT_oIntFlag.IntActInt = 0;
OneNandT_oIntFlag.BlkRwCmpInt = 0;
OneNandT_oIntFlag.LoadCmpInt = 0;
ONENAND_WriteCmd(Controller, uBlkAddr, uPageAddr, 0x10);
#if 0
while(!OneNandT_oIntFlag.IntActInt); //Waiting Interrupt
while(!OneNandT_oIntFlag.BlkRwCmpInt); //Waiting Interrupt
while(!OneNandT_oIntFlag.LoadCmpInt); //Waiting Interrupt
#else
//Interrupt肺 背眉
//while(!(ONENAND(Controller)->rIntErrStat & (1<<10)));
//Outp32(&ONENAND(Controller)->rIntErrAck, (1<<10));
while(!OneNandT_oIntFlag.IntActInt);
//Interrupt肺 背眉
//while(!(ONENAND(Controller)->rIntErrStat & (1<<7)));
//Outp32(&ONENAND(Controller)->rIntErrAck, (1<<7));
while(!OneNandT_oIntFlag.BlkRwCmpInt);
//Interrupt肺 背眉
//while(!(ONENAND(Controller)->rIntErrStat & (1<<4)));
//Outp32(&ONENAND(Controller)->rIntErrAck, (1<<4));
while(!OneNandT_oIntFlag.LoadCmpInt);
#endif
}
//////////
// Function Name : ONENAND_WriteFromXIPBuffer
// Function Description : Write the data int the map00 XIP buffer to the page specified by the FBA,FPA, and FSA
// Input : Controller - OneNand Controller Port Number
// uBlkAddr - Block Number to write
// uPageAddr - Page number to write
// Version : v0.1
void ONENAND_WriteFromXIPBuffer(u32 Controller, u32 uBlkAddr, u8 uPageAddr)
{
OneNandT_oIntFlag.IntActInt = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -