📄 onenand.c
字号:
uEnableECC &= ~(0x1<<8);
Outp32(&ONENAND(Controller)->rMemCfg, uEnableECC);
}
}
else if(uEnable == ONENAND_WITHOUT_CORRECT)
{
if(!(uEnableECC&(1<<8)))
{
uEnableECC |= (0x1<<8);
Outp32(&ONENAND(Controller)->rMemCfg, uEnableECC);
}
}
#endif
}
//////////
// Function Name : ONENAND_EnableSpareTransfer
// Function Description : If enabled, The main data area for the page will be transferred first and then the spare area
// Input : Controller - OneNand Controller Port Number
// bEnable - IOBE Enable/Disable
// Version : v0.1
void ONENAND_EnableSpareTransfer(u32 Controller, bool bEnable)
{
Outp32(&ONENAND(Controller)->rTransSpare, (u32)bEnable);
}
//////////
// Function Name : ONENAND_GetDevInformation
// Function Description : Get the OneNand Device Infomation
// Input : Controller - OneNand Controller Port Number
// Version : v0.1
void ONENAND_GetDevInformation(u32 Controller)
{
OneNand_Inform[Controller].uManufID = Inp32(&ONENAND(Controller)->rManufactID);
OneNand_Inform[Controller].uDeviceID = Inp32(&ONENAND(Controller)->rDeviceID);
OneNand_Inform[Controller].uDataBufSize = Inp32(&ONENAND(Controller)->rDataBufSize);
OneNand_Inform[Controller].uBootBufSize = Inp32(&ONENAND(Controller)->rBootBufSize);
OneNand_Inform[Controller].uAmountOfBuf = Inp32(&ONENAND(Controller)->rBufAmount);
OneNand_Inform[Controller].uTechnology = Inp32(&ONENAND(Controller)->rTech);
OneNand_Inform[Controller].uFlashVerID = Inp32(&ONENAND(Controller)->rFlashVerID);
}
//////////
// Function Name : ONENAND_GetMemCfg
// Function Description : Get the OneNand MEM_CFG register value
// Input : Controller - OneNand Controller Port Number
// Version : v0.1
u32 ONENAND_GetMemCfg(u32 Controller)
{
return (Inp32(&ONENAND(Controller)->rMemCfg));
}
//////////
// Function Name : ONENAND_GetBurstLength
// Function Description : Get the OneNand BURST_LEN register value
// Input : Controller - OneNand Controller Port Number
// Version : v0.1
u32 ONENAND_GetBurstLength(u32 Controller)
{
return (Inp32(&ONENAND(Controller)->rBurstLength));
}
//////////
// Function Name : ONENAND_GetInterruptStatus
// Function Description : Get the OneNand Interrupt Error Status Register Infomation
// Input : Controller - OneNand Controller Port Number
// Version : v0.1
u32 ONENAND_GetInterruptStatus(u32 uController)
{
u32 uIntStatus;
uIntStatus = Inp32(&ONENAND(uController)->rIntErrStat) & 0x3FFF;
return uIntStatus;
}
//////////
// Function Name : ONENAND_GetInterruptMask
// Function Description : Get the OneNand Interrupt Error Mask Register Infomation
// Input : Controller - OneNand Controller Port Number
// Version : v0.1
u32 ONENAND_GetInterruptMask(u32 uController)
{
u32 uIntMask;
uIntMask = Inp32(&ONENAND(uController)->rIntErrMask) & 0x3FFF;
return uIntMask;
}
//////////
// Function Name : ONENAND_SetMemSpace
// Function Description : Set the OneNand Device Infomation to Controller Register & Set variable about the MEM_ADDR field Information
// Input : Controller - OneNand Controller Port Number
// Version : v0.1
void ONENAND_SetMemSpace(u32 Controller)
{
u32 uDeviceDensity, uDeviceDDP;
uDeviceDensity = (Inp32(&ONENAND(Controller)->rDeviceID) & 0xF0)>>4;
uDeviceDDP = (Inp32(&ONENAND(Controller)->rDeviceID) & 0x8)>>3;
switch(uDeviceDensity)
{
case 0 : Outp32(&ONENAND(Controller)->rFbaWidth, 8);
Outp32(&ONENAND(Controller)->rFpaWidth, 6);
Outp32(&ONENAND(Controller)->rFsaWidth, 1);
Outp32(&ONENAND(Controller)->rDbsDfsWidth, 0);
FbaShift[Controller] = 9;
FpaShift[Controller] = 3;
//FsaShift[Controller] = 2;
FbaMask[Controller] = 0xFF;
FpaMask[Controller] = 0x3F;
//FsaMask[Controller] = 0x01;
OneNand_Inform[Controller].uNumOfBlock = 256;
OneNand_Inform[Controller].uCacheReadSupport = 0;
break;
case 1 : Outp32(&ONENAND(Controller)->rFbaWidth, 9);
Outp32(&ONENAND(Controller)->rFpaWidth, 6);
Outp32(&ONENAND(Controller)->rFsaWidth, 1);
Outp32(&ONENAND(Controller)->rDbsDfsWidth, 0);
FbaShift[Controller] = 9;
FpaShift[Controller] = 3;
//FsaShift[Controller] = 2;
FbaMask[Controller] = 0x1FF;
FpaMask[Controller] = 0x3F;
//FsaMask[Controller] = 0x01;
OneNand_Inform[Controller].uNumOfBlock = 512;
OneNand_Inform[Controller].uCacheReadSupport = 0;
break;
case 2 : Outp32(&ONENAND(Controller)->rFbaWidth, 9);
Outp32(&ONENAND(Controller)->rFpaWidth, 6);
Outp32(&ONENAND(Controller)->rFsaWidth, 2);
Outp32(&ONENAND(Controller)->rDbsDfsWidth, 0);
FbaShift[Controller] = 10;
FpaShift[Controller] = 4;
//FsaShift[Controller] = 2;
FbaMask[Controller] = 0x1FF;
FpaMask[Controller] = 0x3F;
//FsaMask[Controller] = 0x03;
OneNand_Inform[Controller].uNumOfBlock = 512;
OneNand_Inform[Controller].uCacheReadSupport = 0;
break;
case 3 : Outp32(&ONENAND(Controller)->rFpaWidth, 6);
Outp32(&ONENAND(Controller)->rFsaWidth, 2);
if(uDeviceDDP)
{
Outp32(&ONENAND(Controller)->rFbaWidth, 9);
Outp32(&ONENAND(Controller)->rDbsDfsWidth, 1);
//added by rb1004....2007.04.23
OneNand_Inform[Controller].uDbsDfs = 1;
OneNand_Inform[Controller].uCacheReadSupport = 0;
}
else
{
Outp32(&ONENAND(Controller)->rFbaWidth, 10);
Outp32(&ONENAND(Controller)->rDbsDfsWidth, 0);
//added by rb1004....2007.04.23
OneNand_Inform[Controller].uDbsDfs = 0;
OneNand_Inform[Controller].uCacheReadSupport = 0;
}
FbaShift[Controller] = 10;
FpaShift[Controller] = 4;
//FsaShift[Controller] = 2;
FbaMask[Controller] = 0x3FF;
FpaMask[Controller] = 0x3F;
//FsaMask[Controller] = 0x03;
OneNand_Inform[Controller].uNumOfBlock = 1024;
break;
case 4 : Outp32(&ONENAND(Controller)->rFpaWidth, 6);
Outp32(&ONENAND(Controller)->rFsaWidth, 2);
if(uDeviceDDP)
{
Outp32(&ONENAND(Controller)->rFbaWidth, 10);
Outp32(&ONENAND(Controller)->rDbsDfsWidth, 1);
//added by rb1004....2007.04.23
OneNand_Inform[Controller].uDbsDfs = 1;
OneNand_Inform[Controller].uCacheReadSupport = 0;
}
else
{
Outp32(&ONENAND(Controller)->rFbaWidth, 11);
Outp32(&ONENAND(Controller)->rDbsDfsWidth, 0);
//added by rb1004....2007.04.23
OneNand_Inform[Controller].uDbsDfs = 0;
OneNand_Inform[Controller].uCacheReadSupport = 1;
}
FbaShift[Controller] = 10;
FpaShift[Controller] = 4;
//FsaShift[Controller] = 2;
FbaMask[Controller] = 0x7FF;
FpaMask[Controller] = 0x3F;
//FsaMask[Controller] = 0x03;
OneNand_Inform[Controller].uNumOfBlock = 2048;
break;
case 5 : Outp32(&ONENAND(Controller)->rFpaWidth, 6);
Outp32(&ONENAND(Controller)->rFsaWidth, 2);
if(uDeviceDDP)
{
Outp32(&ONENAND(Controller)->rFbaWidth, 11);
Outp32(&ONENAND(Controller)->rDbsDfsWidth, 1);
//added by rb1004....2007.04.23
OneNand_Inform[Controller].uDbsDfs = 1;
OneNand_Inform[Controller].uCacheReadSupport = 1;
}
else
{
Outp32(&ONENAND(Controller)->rFbaWidth, 12);
Outp32(&ONENAND(Controller)->rDbsDfsWidth, 0);
//added by rb1004....2007.04.23
OneNand_Inform[Controller].uDbsDfs = 0;
OneNand_Inform[Controller].uCacheReadSupport = 1;
}
FbaShift[Controller] = 10;
FpaShift[Controller] = 4;
//FsaShift[Controller] = 2;
FbaMask[Controller] = 0xFFF;
FpaMask[Controller] = 0x3F;
//FsaMask[Controller] = 0x03;
OneNand_Inform[Controller].uNumOfBlock = 4096;
break;
default : break;
}
//OneNAND_BUFFER_BASE[Controller] = (volatile u32)ONENAND_pBase[Controller] + BUFFER;
//OneNAND_ARRAY_BASE[Controller] = (volatile u32)ONENAND_pBase[Controller] + ARRAY_RW;
//OneNAND_CMD_BASE[Controller] = (volatile u32)ONENAND_pBase[Controller] + COMMANDS;
//OneNAND_DIRECT_BASE[Controller] = (volatile u32)ONENAND_pBase[Controller] + DIRECT_ACCESS;
if(Controller == 0)
{
OneNAND_BUFFER_BASE[Controller] = (ONENAND0_MEM_BASE + BUFFER);
OneNAND_ARRAY_BASE[Controller] = (ONENAND0_MEM_BASE + ARRAY_RW);
OneNAND_CMD_BASE[Controller] = (ONENAND0_MEM_BASE + COMMANDS);
OneNAND_DIRECT_BASE[Controller] = (ONENAND0_MEM_BASE + DIRECT_ACCESS);
}
else if(Controller == 1)
{
OneNAND_BUFFER_BASE[Controller] = (ONENAND1_MEM_BASE + BUFFER);
OneNAND_ARRAY_BASE[Controller] = (ONENAND1_MEM_BASE + ARRAY_RW);
OneNAND_CMD_BASE[Controller] = (ONENAND1_MEM_BASE + COMMANDS);
OneNAND_DIRECT_BASE[Controller] = (ONENAND1_MEM_BASE + DIRECT_ACCESS);
}
OneNand_Inform[Controller].uNumOfPage = Pow(2, Inp32(&ONENAND(Controller)->rFpaWidth));
}
//////////
// Function Name : ONENAND_UnlockBlock
// Function Description : Unlock Memory Block
// Input : Controller - OneNand Controller Port Number
// uStartBlkAddr - Start block for the unlock
// uEndBlkAddr - End block for the unlock
// Version : v0.1
bool ONENAND_UnlockBlock(u32 Controller, u32 uStartBlkAddr, u32 uEndBlkAddr)
{
//u32 uData;
OneNandT_oIntFlag.IntActInt = 0;
if(uStartBlkAddr == uEndBlkAddr)
{
ONENAND_WriteCmd(Controller, uEndBlkAddr, 0, 0x09);
}
else
{
ONENAND_WriteCmd(Controller, uStartBlkAddr, 0, 0x08);
ONENAND_WriteCmd(Controller, uEndBlkAddr, 0, 0x09);
}
//Interrupt肺 背眉
//while(!(ONENAND(Controller)->rIntErrStat & (1<<10)));
//Outp32(&ONENAND(Controller)->rIntErrAck, (1<<10));
while(!OneNandT_oIntFlag.IntActInt);
#if 0
ONENAND_DirectRead(Controller, OND_WPROT_STATUS, &uData);
if ((uData&0xFFFF) != 0x4)
{
//UART_Printf(" Failed unlock block, locked status (0x%x)\n", uData);
return TRUE;
}
#endif
return FALSE;
}
//////////
// Function Name : ONENAND_UnlockAllBlock
// Function Description : Unlock Memory All Block
// Input : Controller - OneNand Controller Port Number
// Version : v0.1
OneNAND_eINTERROR ONENAND_UnlockAllBlock(u32 Controller)
{
//u32 uError;
OneNandT_oIntFlag.IntActInt = 0;
OneNandT_oIntFlag.UnsupCmdInt = 0;
ONENAND_WriteCmd(Controller, 0, 0, 0x0E);
//Interrupt肺 背眉
//while(!(ONENAND(Controller)->rIntErrStat & (1<<10)));
//Outp32(&ONENAND(Controller)->rIntErrAck, (1<<10));
while(!OneNandT_oIntFlag.IntActInt);
#if 0
uError = Inp32(&ONENAND(Controller)->rIntErrStat);
if (uError & (1<<9))
{
//Unsupported Command
Outp32(&ONENAND(Controller)->rIntErrAck, (1<<9));
return eOND_UNSUPCMD;
}
#else
if(OneNandT_oIntFlag.UnsupCmdInt == 1)
return eOND_UNSUPCMD;
#endif
return eOND_NOERROR;
}
//////////
// Function Name : ONENAND_LockBlock
// Function Description : Lock Memory Block
// Input : Controller - OneNand Controller Port Number
// uStartBlkAddr - Start block for the lock
// uEndBlkAddr - End block for the lock
// Version : v0.1
bool ONENAND_LockBlock(u32 Controller, u32 uStartBlkAddr, u32 uEndBlkAddr)
{
//u32 uData;
OneNandT_oIntFlag.IntActInt = 0;
if(uStartBlkAddr == uEndBlkAddr)
{
ONENAND_WriteCmd(Controller, uEndBlkAddr, 0, 0x0B);
}
else
{
ONENAND_WriteCmd(Controller, uStartBlkAddr, 0, 0x0A);
ONENAND_WriteCmd(Controller, uEndBlkAddr, 0, 0x0B);
}
//Interrupt肺 背眉
//while(!(ONENAND(Controller)->rIntErrStat & (1<<10)));
//Outp32(&ONENAND(Controller)->rIntErrAck, (1<<10));
while(!OneNandT_oIntFlag.IntActInt);
#if 0
ONENAND_DirectRead(Controller, OND_WPROT_STATUS, &uData);
if ((uData&0xFFFF) != 0x2)
{
//UART_Printf(" Failed lock block, locked status (0x%x)\n", uData);
return TRUE;
}
#endif
return FALSE;
}
//////////
// Function Name : ONENAND_LockTightBlock
// Function Description : Lock-tight Memory Block
// Input : Controller - OneNand Controller Port Number
// uStartBlkAddr - Start block for the lock-tight
// uEndBlkAddr - End block for the lock-tight
// Version : v0.1
bool ONENAND_LockTightBlock(u32 Controller, u32 uStartBlkAddr, u32 uEndBlkAddr)
{
//u32 uData;
OneNandT_oIntFlag.IntActInt = 0;
if(uStartBlkAddr == uEndBlkAddr)
{
ONENAND_WriteCmd(Controller, uEndBlkAddr, 0, 0x0D);
}
else
{
ONENAND_WriteCmd(Controller, uStartBlkAddr, 0, 0x0C);
ONENAND_WriteCmd(Controller, uEndBlkAddr, 0, 0x0D);
}
//Interrupt肺 背眉
//while(!(ONENAND(Controller)->rIntErrStat & (1<<10)));
//Outp32(&ONENAND(Controller)->rIntErrAck, (1<<10));
while(!OneNandT_oIntFlag.IntActInt);
#if 0
ONENAND_DirectRead(Controller, OND_WPROT_STATUS, &uData);
if ((uData&0xFFFF) != 0x1)
{
//UART_Printf(" Failed lock block, locked status (0x%x)\n", uData);
return TRUE;
}
#endif
return FALSE;
}
//////////
// Function Name : ONENAND_EraseBlock
// Function Description : Erase Memory Block
// Input : Controller - OneNand Controller Port Number
// uStartBlkAddr - Start block for the erase
// uEndBlkAddr - End block for the erase
// Version : v0.1
#if 0
OneNAND_eINTERROR ONENAND_EraseBlock(u32 Controller, u32 uStartBlkAddr, u32 uEndBlkAddr)
{
u32 i;
//u32 uError;
u32 uStatus;
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);
}
else
{
#if 1
for(i=uStartBlkAddr ; i<uEndBlkAddr ; i++)
{
ONENAND_WriteCmd(Controller, i, 0, 0x01);
}
ONENAND_WriteCmd(Controller, uEndBlkAddr, 0, 0x03);
while(!OneNandT_oIntFlag.IntActInt);
#else
for(i=uStartBlkAddr ; i<=uEndBlkAddr ; i++)
{
ONENAND_WriteCmd(Controller, i, 0, 0x03);
while(!OneNandT_oIntFlag.IntActInt);
}
#endif
// Verify Erase block
for(i=uStartBlkAddr ; i<=uEndBlkAddr ; 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;
}
#if 0
uError = Inp32(&ONENAND(Controller)->rIntErrStat);
if (uError & (1<<3))
{
//The erase operation was unsuccessful
Outp32(&ONENAND(Controller)->rIntErrAck, (1<<3));
if(uError & (1<<8))
{
Outp32(&ONENAND(Controller)->rIntErrAck, (1<<8));
return (eOND_ERSFAIL | eOND_LOCKEDBLK);
}
return eOND_ERSFAIL;
}
#elif 0
if(OneNandT_oIntFlag.ErsFailInt == 1)
{
if(OneNandT_oIntFlag.LockedBlkInt == 1)
return (OneNAND_eINTERROR)(eOND_ERSFAIL | eOND_LOCKEDBLK);
return eOND_ERSFAIL;
}
else if(OneNandT_oIntFlag.BlkRwCmpInt == 1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -