📄 nand.c
字号:
#include "Typedef.h"
#include "Nand.h"
void SetCommand(UINT8 Command)
{
volatile UINT8 delay;
NAND_CLE_HIGH();
for(delay = 8; delay > 0; delay--)
delay--;
CMD_PORT = Command;
for(delay = 8; delay > 0; delay--)
delay--;
NAND_CLE_LOW();
for(delay = 8; delay > 0; delay--)
delay--;
}
void SetAddress32(UINT32 Address)
{
volatile UINT8 delay;
NAND_ALE_HIGH();
for(delay = 8; delay > 0; delay--)
delay--;
ADDR_PORT = (Address & 0xFF);
ADDR_PORT = ((Address >> 8) & 0xFF);
ADDR_PORT = ((Address >> 16) & 0xFF);
ADDR_PORT = ((Address >> 24) & 0xFF);
for(delay = 8; delay > 0; delay--)
delay--;
NAND_ALE_LOW();
for(delay = 8; delay > 0; delay--)
delay--;
}
void SetAddress24(UINT32 Address)
{
volatile UINT8 delay;
NAND_ALE_HIGH();
for(delay = 8; delay > 0; delay--)
delay--;
ADDR_PORT = (Address & 0xFF);
ADDR_PORT = ((Address >> 8) & 0xFF);
ADDR_PORT = ((Address >> 16) & 0xFF);
for(delay = 8; delay > 0; delay--)
delay--;
NAND_ALE_LOW();
for(delay = 8; delay > 0; delay--)
delay--;
}
void SetAddress16(UINT32 Address)
{
volatile UINT8 delay;
NAND_ALE_HIGH();
for(delay = 8; delay > 0; delay--)
delay--;
ADDR_PORT = (Address & 0xFF);
ADDR_PORT = ((Address >> 8) & 0xFF);
for(delay = 8; delay > 0; delay--)
delay--;
NAND_ALE_LOW();
for(delay = 8; delay > 0; delay--)
delay--;
}
void SetAddress8(UINT32 Address)
{
volatile UINT8 delay;
NAND_ALE_HIGH();
for(delay = 8; delay > 0; delay--)
delay--;
ADDR_PORT = (Address & 0xFF);
for(delay = 8; delay > 0; delay--)
delay--;
NAND_ALE_LOW();
for(delay = 8; delay > 0; delay--)
delay--;
}
void NandReset()
{
NAND_CE_LOW();
SetCommand(CMD_RESET);
WAIT_NAND_READY();
NAND_CE_HIGH();
}
UINT32 NandInit()
{
volatile UINT32 *SYS_CFG = (UINT32 *)0x01C00000;
volatile UINT32 *NCACHBE0 = (UINT32 *)0x01C00004;
volatile UINT32 *PCONC = (UINT32 *)0x01D20010;
volatile UINT32 *PCONE = (UINT32 *)0x01D20028;
volatile UINT32 *PDATC = (UINT32 *)0x01D20014;
*(SYS_CFG) = 0x6; //8K Cache
*(NCACHBE0) = (((0x02000000 + 4096)/4096) << 16 | ((0x02000000)/4096));
//*(PCONC) = ((1<<6)|(1<<4)|(1<<2)|0);
*(PCONC) = (1<<22);
*(PCONE) |= (0x1);
*(PDATC) |= (1<<11);
NandReset();
return 1;
}
UINT32 IsBadBlock(UINT32 BlockID)
{
UINT32 PageID = BlockID << 5;
UINT32 Address;
BYTE state;
Address = ((((PageID >> 16) & 0xFF) << 24) |(((PageID >> 8) & 0xFF) << 16) |
((PageID & 0xFF) << 8) | (VALIDADDR));
NAND_CE_LOW();
SetCommand(CMD_READ2);
SetAddress32(Address);
WAIT_NAND_READY();
state = NAND_IO;
NAND_CE_HIGH();
if(state != 0xFF)
return 1; /* Bad Block */
return 0; /* Block is OK */
}
UINT32 EraseBlock(UINT32 BlockID)
{
UINT32 PageID = BlockID << 5;
BYTE state;
NAND_CE_LOW();
SetCommand(CMD_ERASE);
SetAddress24(PageID);
SetCommand(CMD_ERASE2);
WAIT_NAND_READY();
SetCommand(CMD_STATUS);
state = NAND_IO;
NAND_CE_HIGH();
if(state & 0x1)
return 0; /* Error in erase */
return 1; /* Success */
}
BYTE ReadDeviceID()
{
volatile BYTE DeviceID;
NAND_CE_LOW();
SetCommand(CMD_READID);
SetAddress8(0x0);
DeviceID = NAND_IO; /* TOSHIBA is shit */
DeviceID = NAND_IO;
NAND_CE_HIGH();
return DeviceID;
}
UINT32 ReadPage(UINT32 BlockID,UINT32 PageID,BYTE *pData)
{
UINT32 Address = ((BlockID << 5) | PageID) << 8;
volatile int i;
NAND_CE_LOW();
SetCommand(CMD_READ);
SetAddress32(Address);
for(i=0;i<10;i++);
WAIT_NAND_READY();
for(i=0;i<512;i++) /* Read one page */
{
*pData++ = NAND_IO;
}
NAND_CE_HIGH();
return 512; /* return the byte count */
}
UINT32 WritePage(UINT32 BlockID,UINT32 PageID,BYTE *pData)
{
UINT32 Address = ((BlockID << 5) | PageID) << 8;
volatile int i;
BYTE state;
NAND_CE_LOW();
SetCommand(CMD_READ); /* Set the internal pointer to the first half */
SetCommand(CMD_WRITE);
SetAddress32(Address);
for(i=0;i<10;i++);
for(i=0;i<512;i++) /* Read one page */
{
NAND_IO = *pData++;
}
for(i=0;i<10;i++);
SetCommand(CMD_WRITE2);
for(i=0;i<10;i++);
WAIT_NAND_READY();
SetCommand(CMD_STATUS);
for(i=0;i<10;i++);
state = NAND_IO;
NAND_CE_HIGH();
if(state & 0x1)
return 0;
return 512;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -