?? nand.c
字號:
NF_CMD(Controller, 0x05);
NF_ADDR(Controller, (512*2)&0xFF);
NF_ADDR(Controller, ((512*2)>>8)&0xFF);
NF_CMD(Controller, 0xE0);
#if NAND_TRANSFER_MODE == POLLING_TRANSFER
#if 0
for(i=0 ; i<NAND_MLC_TRANS_SIZE ; i++) // MLC ECC Size : 512bytes
{
*pBuffer++ = NF_RDDATA8(Controller); // Read one page
}
#else
for(i=0 ; i<NAND_MLC_TRANS_SIZE/4 ; i++)
{
*pBufferW++ = NF_RDDATA(Controller); // Read one page
}
#endif
#elif NAND_TRANSFER_MODE == DMA_TRANSFER
Nand_DmaDone = 0;
DMACH_Setup(DMA_A, 0x0, (u32)(&(NAND(Controller)->rNFDATA)), 1, (u32)pBufferW, 0, WORD, NAND_MLC_TRANS_SIZE/4, DEMAND, DMA1_NAND_TX, MEM, BURST128, &g_oNandDmac1);
DMACH_Start(&g_oNandDmac1);
while(!Nand_DmaDone);
pBufferW += NAND_MLC_TRANS_SIZE/4;
#endif
NF_CMD(Controller, 0x05);
NF_ADDR(Controller, (uPageSize+15)&0xFF);
NF_ADDR(Controller, ((uPageSize+15)>>8)&0xFF);
NF_CMD(Controller, 0xE0);
for(i=15;i<22;i++)
{
aNand_Spare_Data[i] = NF_RDDATA8(Controller);
if(NAND_Inform[Controller].uPerformanceCheck == 0)
*pSpareBuffer++ = aNand_Spare_Data[i];
}
while(g_Nand_4bitEccDecDone == 0);
eError = NAND_CheckECCError(Controller);
if(eError != eNAND_NoError)
{
NF_MECC_Lock(Controller);
NF_nFCE_H(Controller);
uTemp = NAND_ReadNFCONRegister(Controller);
uTemp &= ~(1<<12); // 4bit ECC decoding Interrupt enable
Outp32(&(NAND(Controller)->rNFCONT), uTemp);
NAND_Inform[Controller].uMLCECCPageReadSector = 2; //1024 ~ 1535 Bytes
return eError;
}
//////////////////////////
// Read 1536 ~ 2047
//////////////////////////
g_Nand_4bitEccDecDone = 0;
NF_RSTECC(Controller); // Initialize ECC
#if (NAND_REG_BUG == TRUE)
uTemp = NAND_ReadNFCONRegister(Controller);
uTemp |= (1<<12)|(1<<13); // 4bit ECC decoding/encoding Interrupt enable...because error
Outp32(&(NAND(Controller)->rNFCONT), uTemp);
#endif
NF_CMD(Controller, 0x05);
NF_ADDR(Controller, (512*3)&0xFF);
NF_ADDR(Controller, ((512*3)>>8)&0xFF);
NF_CMD(Controller, 0xE0);
#if NAND_TRANSFER_MODE == POLLING_TRANSFER
#if 0
for(i=0 ; i<NAND_MLC_TRANS_SIZE ; i++) // MLC ECC Size : 512bytes
{
*pBuffer++ = NF_RDDATA8(Controller); // Read one page
}
#else
for(i=0 ; i<NAND_MLC_TRANS_SIZE/4 ; i++)
{
*pBufferW++ = NF_RDDATA(Controller); // Read one page
}
#endif
#elif NAND_TRANSFER_MODE == DMA_TRANSFER
Nand_DmaDone = 0;
DMACH_Setup(DMA_A, 0x0, (u32)(&(NAND(Controller)->rNFDATA)), 1, (u32)pBufferW, 0, WORD, NAND_MLC_TRANS_SIZE/4, DEMAND, DMA1_NAND_TX, MEM, BURST128, &g_oNandDmac1);
DMACH_Start(&g_oNandDmac1);
while(!Nand_DmaDone);
pBufferW += NAND_MLC_TRANS_SIZE/4;
#endif
NF_CMD(Controller, 0x05);
NF_ADDR(Controller, (uPageSize+22)&0xFF);
NF_ADDR(Controller, ((uPageSize+22)>>8)&0xFF);
NF_CMD(Controller, 0xE0);
//for(i=22;i<29;i++)
for(i=22;i<36;i++)
{
aNand_Spare_Data[i] = NF_RDDATA8(Controller);
if(NAND_Inform[Controller].uPerformanceCheck == 0)
*pSpareBuffer++ = aNand_Spare_Data[i];
}
while(g_Nand_4bitEccDecDone == 0);
eError = NAND_CheckECCError(Controller);
if(eError != eNAND_NoError)
{
NF_MECC_Lock(Controller);
NF_nFCE_H(Controller);
uTemp = NAND_ReadNFCONRegister(Controller);
uTemp &= ~(1<<12); // 4bit ECC decoding Interrupt enable
Outp32(&(NAND(Controller)->rNFCONT), uTemp);
NAND_Inform[Controller].uMLCECCPageReadSector = 3; // 1536 ~ 2047 Bytes
return eError;
}
NF_nFCE_H(Controller);
NF_MECC_Lock(Controller);
uTemp = NAND_ReadNFCONRegister(Controller);
uTemp &= ~((1<<12)|(1<<13)); // 4bit ECC decoding/encoding Interrupt disable
Outp32(&(NAND(Controller)->rNFCONT), uTemp);
INTC_Disable(NUM_NFC);
return eNAND_NoError;
}
//////////
// Function Name : NAND_ReadPage
// Function Description : This function read the 1 page data of external NAND device
// Input : Controller - Nand Controller Port Number
// uBlock - Read Block
// uPage - Read Page
// pBuffer - Read data buffer
// Output : Nand Error Type
NAND_eERROR NAND_ReadPage(u32 Controller, u32 uBlock, u32 uPage, u8 *pBuffer, u8 *pSpareBuffer)
{
NAND_eERROR eError;
if( (NAND_Inform[Controller].uNandType == NAND_Normal8bit) || (NAND_Inform[Controller].uNandType == NAND_Advanced8bit) )
eError = NAND_ReadPageSLC(Controller, uBlock, uPage, pBuffer, pSpareBuffer);
else //if(NAND_Inform[Controller].uNandType == NAND_MLC8bit)
eError = NAND_ReadPageMLC(Controller, uBlock, uPage, pBuffer, pSpareBuffer);
return eError;
}
//////////
// Function Name : NAND_ReadMultiPage
// Function Description : This function read the multi page data of external NAND device
// Input : Controller - Nand Controller Port Number
// uBlock - Read Block
// uPage - Read Page
// pBuffer - Read data buffer
// Output : Nand Error Type
NAND_eERROR NAND_ReadMultiPage(u32 Controller, u32 uStartBlock, u32 uStartPage, u8 *pBuffer, u32 uSize)
{
u8 aSpareBuffer[NAND_SPARE_MAX];
u32 i, uPageCnt, uBlock, uPage;
NAND_eERROR eError;
uPageCnt = uSize/NAND_Inform[Controller].uPageSize;
uBlock = uStartBlock;
uPage = uStartPage;
for(i=0 ; i<uPageCnt ; i++)
{
if( (NAND_Inform[Controller].uNandType == NAND_Normal8bit) || (NAND_Inform[Controller].uNandType == NAND_Advanced8bit) )
eError = NAND_ReadPageSLC(Controller, uBlock, uPage, pBuffer, aSpareBuffer);
else
eError = NAND_ReadPageMLC(Controller, uBlock, uPage, pBuffer, aSpareBuffer);
if(eError != eNAND_NoError)
return eError;
pBuffer += NAND_Inform[Controller].uPageSize;
uPage++;
if(uPage == NAND_Inform[Controller].uPageNum)
{
uBlock++;
uPage = 0;
}
}
return eError;
}
//////////
// Function Name : NAND_WritePageSLC
// Function Description : This function write the 1 page data of external SLC Type NAND device
// Input : Controller - Nand Controller Port Number
// uBlock - Write Block
// uPage - Write Page
// pBuffer - Write data buffer
// aSpareBuffer - Memory to store the spare data
// Output : ECC Error Type
NAND_eERROR NAND_WritePageSLC(u32 Controller, u32 uBlock, u32 uPage, u8 *pBuffer, u8 *aSpareBuffer)
{
u32 i, uBlockPage, uPageSize, uSpareSize, uTemp;
u32 uMecc, uSecc, uStatus;
NAND_eERROR eError;
u32 *pBufferW;
pBufferW = (u32 *)pBuffer;
g_Nand_RnBTransition = 0;
uTemp = NAND_ReadNFCONRegister(Controller);
uTemp &= ~((1<<13)|(1<<12)); // 4bit ECC encoding/decoding completion Interrupt disable
uTemp |= (1<<10) | (1<<9); // Illegal Access & RnB Transition Interrupt enable
Outp32(&(NAND(Controller)->rNFCONT), uTemp);
Outp32(&(NAND(Controller)->rNFSTAT), (1<<5)|(1<<4)); // Illegal Access & RnB Interrupt Pending bit clear
INTC_Enable(NUM_NFC);
if(NAND_Inform[Controller].uNandType == NAND_Normal8bit)
{
uBlockPage=(uBlock<<5) + uPage;
uPageSize = NAND_Inform[Controller].uPageSize;
uSpareSize = NAND_Inform[Controller].uSpareSize;
}
else //if(NAND_Inform[Controller].uNandType == NAND_Advanced8bit)
{
uBlockPage=(uBlock<<6) + uPage;
uPageSize = NAND_Inform[Controller].uPageSize;
uSpareSize = NAND_Inform[Controller].uSpareSize;
}
NF_RSTECC(Controller); // Initialize ECC
NF_MECC_UnLock(Controller);
NF_nFCE_L(Controller);
NF_CLEAR_RnB(Controller);
NF_CMD(Controller, 0x80); // Program command
NF_ADDR(Controller, 0);
//if(NAND_Inform[Controller].uNandType == NAND_Advanced8bit)
if(NAND_Inform[Controller].uAddrCycle == 5)
NF_ADDR(Controller, 0);
NF_ADDR(Controller, uBlockPage&0xff); //
NF_ADDR(Controller, (uBlockPage>>8)&0xff); // Block & Page num.
NF_ADDR(Controller, (uBlockPage>>16)&0xff); //
#if NAND_TRANSFER_MODE == POLLING_TRANSFER
#if 0
for(i=0 ; i<uPageSize ; i++)
{
NF_WRDATA8(Controller, *pBuffer++); // Write one page
}
#else
for(i=0 ; i<uPageSize/4 ; i++)
{
NF_WRDATA(Controller, *pBufferW++); // Read one page
}
#endif
#elif NAND_TRANSFER_MODE == DMA_TRANSFER
Nand_DmaDone = 0;
DMACH_Setup(DMA_A, 0x0, (u32)pBufferW, 0, (u32)(&(NAND(Controller)->rNFDATA)), 1, WORD, uPageSize/4, DEMAND, MEM, DMA1_NAND_RX, BURST128, &g_oNandDmac1);
DMACH_Start(&g_oNandDmac1);
while(!Nand_DmaDone);
#endif
NF_MECC_Lock(Controller);
g_Nand_IllegalAccError = 0;
if(NAND_Inform[Controller].uNandType == NAND_Normal8bit)
{
// Main Area ECC
uMecc = Inp32(&NAND(Controller)->rNFMECC0);
aNand_Spare_Data[0] = (u8)(uMecc&0xFF);
aNand_Spare_Data[1] = (u8)((uMecc&0xFF00)>>8);
aNand_Spare_Data[2] = (u8)((uMecc&0xFF0000)>>16);
aNand_Spare_Data[3] = (u8)((uMecc&0xFF000000)>>24);
aNand_Spare_Data[5] = (u8)0xFF; //Marking Valid Block
NF_SECC_UnLock(Controller);
for(i=0;i<4;i++)
{
NF_WRDATA8(Controller, aNand_Spare_Data[i]); // Write spare array(Main ECC)
//NF8_Spare_Data[i]=aNand_Spare_Data[i];
}
NF_SECC_Lock(Controller);
// Spare Area ECC
uSecc = Inp32(&NAND(Controller)->rNFSECC) & 0xFFFF;
aNand_Spare_Data[8] = (u8)(uSecc&0xFF);
aNand_Spare_Data[9] = (u8)((uSecc&0xFF00)>>8);
for(i=4 ; i<uSpareSize; i++)
{
NF_WRDATA8(Controller, aNand_Spare_Data[i]); // Write spare array(Spare ECC and Mark)
//NF8_Spare_Data[i]=aNand_Spare_Data[i];
}
NF_CLEAR_RnB(Controller);
NF_CMD(Controller, 0x10); // Write 2nd command
}
else if(NAND_Inform[Controller].uNandType == NAND_Advanced8bit)
{
// Main Area ECC
uMecc = Inp32(&NAND(Controller)->rNFMECC0);
aNand_Spare_Data[0] = (u8)0xFF; //Marking Valid Block
aNand_Spare_Data[1] = (u8)(uMecc&0xFF);
aNand_Spare_Data[2] = (u8)((uMecc&0xFF00)>>8);
aNand_Spare_Data[3] = (u8)((uMecc&0xFF0000)>>16);
aNand_Spare_Data[4] = (u8)((uMecc&0xFF000000)>>24);
NF_WRDATA8(Controller, aNand_Spare_Data[0]); //Write Marking Valid Block
NF_SECC_UnLock(Controller);
for(i=1;i<5;i++)
{
NF_WRDATA8(Controller, aNand_Spare_Data[i]); // Write spare array(Main ECC)
//NF8_Spare_Data[i]=aNand_Spare_Data[i];
}
NF_SECC_Lock(Controller);
// Spare Area ECC
uSecc = Inp32(&NAND(Controller)->rNFSECC) & 0xFFFF;
aNand_Spare_Data[8] = (u8)(uSecc&0xFF);
aNand_Spare_Data[9] = (u8)((uSecc&0xFF00)>>8);
for(i=5 ; i<uSpareSize; i++)
{
NF_WRDATA8(Controller, aNand_Spare_Data[i]); // Write spare array(Spare ECC and Mark)
//NF8_Spare_Data[i]=aNand_Spare_Data[i];
}
NF_CLEAR_RnB(Controller);
NF_CMD(Controller, 0x10); // Write 2nd command
}
while(!g_Nand_RnBTransition)
{
if(g_Nand_IllegalAccError == 1)
{
NAND_Reset(Controller);
g_Nand_IllegalAccError = 0;
return eNAND_ProgramError;
}
}
//Read Program Status
NF_CMD(Controller, 0x70);
while(!((uStatus = NF_RDDATA8(Controller)) & (1<<6)));
if(uStatus & 0x01)
eError = eNAND_ProgramError; // Error in Program
else
eError = eNAND_NoError;
// if(NF_RDDATA8(Controller) & 0x01)
// eError = eNAND_ProgramError; // Error in Program
// else
// eError = eNAND_NoError;
NF_nFCE_H(Controller);
uTemp = NAND_ReadNFCONRegister(Controller);
uTemp &= ~((1<<10) | (1<<9)); // Illegal Access & RnB Transition Interrupt disable
Outp32(&(NAND(Controller)->rNFCONT), uTemp);
if(NAND_Inform[Controller].uECCtest == 1)
{
for(i=0 ; i<uSpareSize ; i++)
aNand_Spare_Data_Temp[i] = aNand_Spare_Data[i];
}
for(i=0 ; i<uSpareSize ; i++)
{
*aSpareBuffer++ = aNand_Spare_Data[i];
}
INTC_Disable(NUM_NFC);
return eError;
}
//////////
// Function Name : NAND_WritePageMLC
// Function Description : This function write the 1 page data of external NAND device
// Input : Controller - Nand Controller Port Number
// uBlock - Write Block
// uPage - Write Page
// pBuffer - Write data buffer
// Output : Nand Error Type
NAND_eERROR NAND_WritePageMLC(u32 Controller, u32 uBlock, u32 uPage, u8 *pBuffer, u8 *aSpareBuffer)
{
u32 i, uBlockPage, uSpareSize, uTemp;
u32 uMecc0, uMecc1, uStatus;
//u32 uSecc;
NAND_eERROR eError;
u32 *pBufferW;
pBufferW = (u32 *)pBuffer;
g_Nand_4bitEccEncDone = 0;
g_Nand_RnBTransition = 0;
g_Nand_IllegalAccError = 0;
uTemp = NAND_ReadNFCONRegister(Controller);
#if (NAND_REG_BUG == TRUE)
uTemp |= (1<<18)|(1<<13)|(1<<12)|(1<<10)|(1<<9); // 4bit ECC encoding& decoding & Illegal Access & RnB Transition Interrupt enable..because error
#else
uTemp |= (1<<18)|(1<<13)|(1<<10)|(1<<9); // 4bit ECC encoding & Illegal Access & RnB Transition Interrupt enable
#endif
Outp32(&(NAND(Controller)->rNFCONT), uTemp);
Outp32(&(NAND(Controller)->rNFSTAT), (1<<7)); // 4bit ECC encoding finish bit clear
INTC_Enable(NUM_NFC);
uBlockPage=(uBlock<<7) + uPage;
uSpareSize = NAND_Inform[Controller].uSpareSize;
//////////////////////////
// Write 0 ~ 511
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -