#include "flash.h"
#define LED1_MASK 0x20
#define LED2_MASK 0x40
#define LED3_MASK 0x80
#define GPCDAT_ADDR (*(volatile unsigned int *)0x56000024)
// NAND FLASH Controller Registers Addr.
#define NFCONF (*(volatile unsigned int *)0x4E000000)
#define NFCMD (*(volatile unsigned int *)0x4E000004)
#define NFADDR (*(volatile unsigned int *)0x4E000008)
#define NFDATA (*(volatile unsigned int *)0x4E00000C)
#define NFSTAT (*(volatile unsigned int *)0x4E000010)
#define NFECC (*(volatile unsigned int *)0x4E000014)
#define CLKCON (*(volatile unsigned long *) (0x4C00000C))
#define INTMSK (*(volatile unsigned long *) (0x4A000008))
#define GPACON (*(volatile unsigned long *) (0x56000000))
// Flash operator
void initFlash(void);
void readFlashID(void);
void flashRd(unsigned int addr,unsigned int size,unsigned char *buf);
void flashErase(unsigned int addr);
void flashWr(unsigned int addr,unsigned int size,unsigned char *buf);
unsigned int flashID=0;
unsigned char flashWhat[iDatN+16*16];
unsigned char flashRdDat[iDatN+16*6];
void Delay(int n)
{
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
}
}
}
int main()
{
int nLED=0;
int i,n=0;
// initialize NAND Controller
initFlash();
readFlashID();
// Erase Block 0:0~16KB
flashErase(0x0);
// Write flash.h
flashWr(0x0,iDatN,FlashDat);
flashRd(0,iDatN+16*16,flashWhat);
// Flash data,except 16B per 528
for(i=0;i<iDatN+16*16;i++)
{
n=i/528;
if((i>=n*528) && (i<n*528+512))
{
flashRdDat[i-n*16]=flashWhat[i];
}
}
// Above is Nand Flash operator
while(1)
{
nLED = 0;
nLED ^=(LED2_MASK | LED3_MASK); // LED1 light
GPCDAT_ADDR = nLED;
Delay(0x300);
nLED = 0;
nLED ^=(LED1_MASK | LED3_MASK); // LED2 light
GPCDAT_ADDR = nLED;
Delay(0x300);
nLED = 0;
nLED ^=(LED1_MASK | LED2_MASK); // LED3 light
GPCDAT_ADDR = nLED;
Delay(0x300);
}
}
// Init NAND Controller Reg
void initFlash()
{
INTMSK = 0xFFFFFFFF;
CLKCON = 0x0007FFF0; // bit 4
GPACON = 0xFFFFFFFF;
NFCONF = (1<<15)|(1<<12)|(0<<11)|(7<<8)|(7<<4)|(7<<0);
while(!(NFSTAT & 0x01));
NFCMD = 0xFF; // Reset NAND
while(!(NFSTAT & 0x01));
}
// Read flash ID
void readFlashID()
{
int i;
NFCMD = 0x90;
NFADDR = 0x0;
for(i=0;i<4;i++)
{
flashID=flashID | (NFDATA<<((3-i)*8));
while(!(NFSTAT & 0x01)); // Ready?
}
}
// Read flash contents
// Here, addr: start address; size: Data size(in byte); buf: data
void flashRd(unsigned int addr,unsigned int size,unsigned char *buf)
{
int i,n=1;
while(!(NFSTAT & 0x01));
NFCMD = 0x00 | ((addr>>8) & 0x01);
NFADDR = addr & 0xFF;
NFADDR = (addr>>9) & 0xFF;
NFADDR = (addr>>17) & 0xFF;
NFADDR = (addr>>25) & 0x01;
while(!(NFSTAT & 0x01));
for(i=0;i<size;i++,n++)
{
*buf++=NFDATA;
if((n%528)==0) // one page read over, wait
{
while(!(NFSTAT & 0x01));
}
}
while(i%528) // Read the entire page
{
NFDATA;
i++;
}
while(!(NFSTAT & 0x01));
}
// Erase Block,as 16KB per Block
// Use Addr25:14
void flashErase(unsigned int addr)
{
while(!(NFSTAT & 0x01)); // Ready?
NFCMD = 0x60;
NFADDR = (addr>>9) & 0xE0; // A25:14
NFADDR = (addr>>17) & 0xFF;
NFADDR = (addr>>25) & 0x01;
NFCMD = 0xD0;
while(!(NFSTAT & 0x01));
}
// Program flash
// Here, addr: start address; size: Data size(in byte);buf:data
// addr % 512 should be 0
void flashWr(unsigned int addr,unsigned int size,unsigned char *buf)
{
int i=0;
int k=0;
for(k=0;k<=size/512;k++)
{
while(!(NFSTAT & 0x01)); // Ready?
NFCMD = 0x80;
NFADDR = addr & 0xFF;
NFADDR = (addr>>9) & 0xFF;
NFADDR = (addr>>17) & 0xFF;
NFADDR = (addr>>25) & 0x01;
for(i=k*512;i<(k+1)*512;i++)
{
if(i>=size)
{
break;
}
NFDATA = *buf++;
}
NFCMD = 0x10;
while(!(NFSTAT & 0x01));
addr += 512;
}
while(!(NFSTAT & 0x01)); // Ready?
}