📄 nandflash.c
字号:
GpioDataRegs.GPACLEAR.bit.GPIO22 = 1; //I/O set low FLASH_CE=0;
GpioDataRegs.GPACLEAR.bit.GPIO2 = 1; //I/O set low FLASH_ALE=0;
GpioDataRegs.GPASET.bit.GPIO21= 1; //I/O set high FLASH_RE=1;
NF_WriteByte(0x70); //写读状态积存器控制命令
delay_loop_us(1); //延时时间要确定, 2 us
utemp = NF_ReadByte(); //读状态积存器
GpioDataRegs.GPACLEAR.bit.GPIO0 = 1; //I/O set low FLASH_CLE=0;
return utemp;
}
void NF_WriteBuffer(unsigned char addr0, unsigned char addr1,unsigned char addr2,unsigned char *pBuf,short bufLen) // write buffer to pointer address ,烧写NANDFLASH
{
short i;
GpioDataRegs.GPASET.bit.GPIO0= 1; //I/O set high FLASH_CLE=1;
GpioDataRegs.GPACLEAR.bit.GPIO22 = 1; //I/O set low FLASH_CE=0;
GpioDataRegs.GPASET.bit.GPIO21= 1; //I/O set high FLASH_RE=1;
GpioDataRegs.GPACLEAR.bit.GPIO2 = 1; //I/O set low FLASH_ALE=0;
NF_WriteByte(0x80); //写控制命令1
delay_loop_ms(255); //延时时间要确定
GpioDataRegs.GPACLEAR.bit.GPIO0 = 1; //I/O set low FLASH_CLE=0;
GpioDataRegs.GPASET.bit.GPIO2= 1; //I/O set high FLASH_ALE=1;
NF_WriteByte(addr0); //写列地址A0-A7
delay_loop_ms(255); //延时时间要确定
NF_WriteByte(addr1); //写页地址A9-A16
delay_loop_ms(255); //延时时间要确定
NF_WriteByte(addr2); //写页地址A17-A23
delay_loop_ms(255); //延时时间要确定
GpioDataRegs.GPACLEAR.bit.GPIO2 = 1; //I/O set low FLASH_ALE=0;
for(i =0 ;i<bufLen;i++)
{
NF_WriteByte(pBuf[i]); //烧写数据
delay_loop_ms(255); //延时时间要确定
}
GpioDataRegs.GPASET.bit.GPIO0= 1; //I/O set high FLASH_CLE=1;
NF_WriteByte(0x10); //写控制命令2
NF_WaitRb(); //忙等待
delay_loop_ms(255); //延时时间要确定,delay(5);
NF_ReadStatue(); //读状态寄存器
}
void NF_ReadBuffer(unsigned char addr0, unsigned char addr1,unsigned char addr2,unsigned char *pBuf,short bufLen) //读NANDFLASH,如果读取到一个页的结尾,一定要将CE &RE写高
{
unsigned char *p = pBuf;
short i;
GpioDataRegs.GPASET.bit.GPIO0= 1; //I/O set high FLASH_CLE=1;
GpioDataRegs.GPACLEAR.bit.GPIO22 = 1; //I/O set low FLASH_CE=0;
GpioDataRegs.GPACLEAR.bit.GPIO2 = 1; //I/O set low FLASH_ALE=0;
GpioDataRegs.GPASET.bit.GPIO21= 1; //I/O set high FLASH_RE=1;
NF_WriteByte(0x00); //first half
delay_loop_ms(255); //延时时间要确定
GpioDataRegs.GPACLEAR.bit.GPIO0 = 1; //I/O set low FLASH_CLE=0;
GpioDataRegs.GPASET.bit.GPIO2= 1; //I/O set high FLASH_ALE=1;
NF_WriteByte(addr0); //写列地址A0-A7
delay_loop_ms(255); //延时时间要确定
NF_WriteByte(addr1); //写页地址A9-A16
delay_loop_ms(255); //延时时间要确定
NF_WriteByte(addr2); //写页地址A17-A23
delay_loop_ms(255); //延时时间要确定
GpioDataRegs.GPACLEAR.bit.GPIO2 = 1; //I/O set low FLASH_ALE=0;
NF_WaitRb(); //忙等待
for(i =0 ;i<bufLen;i++)
{
*p = NF_ReadByte(); //读数据
p++; //连续读
}
GpioDataRegs.GPASET.bit.GPIO22= 1; //I/O set high FLASH_CE=1;
}
void NF_EraseBlock(unsigned char addr1,unsigned char addr2) //擦NANDFLASH块
{
GpioDataRegs.GPASET.bit.GPIO0= 1; //I/O set high FLASH_CLE=1;
GpioDataRegs.GPACLEAR.bit.GPIO22 = 1; //I/O set low FLASH_CE=0;
GpioDataRegs.GPACLEAR.bit.GPIO2 = 1; //I/O set low FLASH_ALE=0;
GpioDataRegs.GPASET.bit.GPIO21= 1; //I/O set high FLASH_RE=1;
NF_WriteByte(0x60); //擦控制命令1
delay_loop_us(50); //延时时间要确定, 50 us
GpioDataRegs.GPASET.bit.GPIO2= 1; //I/O set high FLASH_ALE=1;
GpioDataRegs.GPACLEAR.bit.GPIO0 = 1; //I/O set low FLASH_CLE=0;
NF_WriteByte(addr1); //块地址A9-A16
delay_loop_us(50); //延时时间要确定, 50 us
NF_WriteByte(addr2); //块地址A17-A23
delay_loop_us(50); //延时时间要确定, 50 us
GpioDataRegs.GPACLEAR.bit.GPIO2 = 1; //I/O set low FLASH_ALE=0;
GpioDataRegs.GPASET.bit.GPIO0= 1; //I/O set high FLASH_CLE=1;
delay_loop_us(50); //延时时间要确定, 50 us
NF_WriteByte(0xd0); //擦控制命令2
delay_loop_us(1); //延时时间要确定, 50 us
NF_WaitRb() ; //忙等待
GpioDataRegs.GPACLEAR.bit.GPIO0 = 1; //I/O set low FLASH_CLE=0;
NF_ReadStatue(); //读状态寄存器
delay_loop_us(1); //延时时间要确定, 50 us
}
void NF_Reset() //NANDFLASH复位
{
GpioDataRegs.GPACLEAR.bit.GPIO22 = 1; //I/O set low FLASH_CE=0;
//NF_CLEAR_RB(); //R/B 低
NF_WriteByte(0xff); //写NANDFLASH复位控制命令
delay_loop_us(1); //延时时间要确定, 1 us
NF_WaitRb() ; //忙等待
NF_ReadStatue(); //读状态寄存器
}
void NF_ReadID() //读NANDFLASH的设备ID
{
#if 1
GpioDataRegs.GPACLEAR.bit.GPIO22 = 1; //I/O set low FLASH_CE=0;
GpioDataRegs.GPASET.bit.GPIO0= 1; //I/O set high FLASH_CLE=1;
GpioDataRegs.GPACLEAR.bit.GPIO2 = 1; //I/O set low FLASH_ALE=0;
GpioDataRegs.GPASET.bit.GPIO21= 1; //I/O set high FLASH_RE=1;
NF_WriteByte(0x90); //写读ID控制命令
// delay_loop_us(1); //delay(5);
GpioDataRegs.GPACLEAR.bit.GPIO0 = 1; //I/O set low FLASH_CLE=0;
GpioDataRegs.GPASET.bit.GPIO2= 1; //I/O set high FLASH_ALE=1;
NF_WriteByte(0x00); //写地址0x00,
// delay_loop_us(1); //delay(5);
GpioDataRegs.GPACLEAR.bit.GPIO2 = 1; //I/O set low FLASH_ALE=0;
NF_WaitRb(); //忙等待
// delay_loop_ms(5); //延时时间要确定
GpioDataRegs.GPACLEAR.bit.GPIO21 = 1; //I/O set low FLASH_RE=0;
delay_loop_ms(50); //延时时间要确定
wData1 = NF_ReadByte(); //读取数据,制造商的ID
delay_loop_ms(50); //延时时间要确定
wData2 = NF_ReadByte(); //读取数据,设备类型ID
delay_loop_ms(50); //延时时间要确定
GpioDataRegs.GPASET.bit.GPIO22= 1; //I/O set high FLASH_CE=1;
delay_loop_ms(1); //延时时间要确定
#endif
}
unsigned char NF_ReadBadBlock(unsigned char addr0, unsigned char addr1,unsigned char addr2) //读NANDFLASH坏块标记
{
unsigned char pBuf;
GpioDataRegs.GPASET.bit.GPIO0= 1; //I/O set high FLASH_CLE=1;
GpioDataRegs.GPACLEAR.bit.GPIO22 = 1; //I/O set low FLASH_CE=0;
GpioDataRegs.GPACLEAR.bit.GPIO2 = 1; //I/O set low FLASH_ALE=0;
GpioDataRegs.GPASET.bit.GPIO21= 1; //I/O set high FLASH_RE=1;
NF_WriteByte(0x50); //first half
delay_loop_ms(255); //延时时间要确定
GpioDataRegs.GPACLEAR.bit.GPIO0 = 1; //I/O set low FLASH_CLE=0;
GpioDataRegs.GPASET.bit.GPIO2= 1; //I/O set high FLASH_ALE=1;
NF_WriteByte(addr0); //写列地址A0-A7
delay_loop_ms(255); //延时时间要确定
NF_WriteByte(addr1); //写页地址A9-A16
delay_loop_ms(255); //延时时间要确定
NF_WriteByte(addr2); //写页地址A17-A23
delay_loop_ms(255); //延时时间要确定
GpioDataRegs.GPACLEAR.bit.GPIO2 = 1; //I/O set low FLASH_ALE=0;
NF_WaitRb(); //忙等待
pBuf= NF_ReadByte(); //读坏块标志
GpioDataRegs.GPASET.bit.GPIO22= 1; //I/O set high FLASH_CE=1;
return pBuf;
}
void NF_MarkBadBlock() //扫描坏块
{
Uint16 i;
for(i=0;i<1024;i++)
{
if((NF_ReadBadBlock(0x05,(0x20*i)%256,(0x20*i)/256)&0xff)!=0xff) //第一页是否有坏块标记
{
badblock[badblocknum++]=i; //记录坏块号
continue; //第一页有坏块标记就直接扫描下一块,不再扫描第二页
}
if((NF_ReadBadBlock(0x05,(0x01+0x20*i)%256,(0x01+0x20*i)/256)&0xff)!=0xff) //第二页是否有坏块标记
badblock[badblocknum++]=i; //记录坏块号
}
}
void main(void)
{
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP280x_SysCtrl.c file.
InitSysCtrl();
// Step 2. Initalize GPIO:
// This example function is found in the DSP280x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio(); // Skipped for this example
// For this example, configure CAN pins using GPIO regs here
// This function is found in DSP280x_ECan.c
NF_Gpio_Init();
NF_Init();
// Initialize PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the DSP280x_PieCtrl.c file.
InitPieCtrl();
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in DSP280x_DefaultIsr.c.
// This function is found in DSP280x_PieVect.c.
InitPieVectTable();
// Step 4. Initialize all the Device Peripherals:
// This function is found in DSP280x_InitPeripherals.c
// InitPeripherals(); // Not required for this example
NF_ReadID();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -