uint8_t FlashInit(void)
{
uint8_t buff[5]; // buff for CMD_READ_ID response
MLCRefreshRow = 0xffffffff;
TotalPhySec = 0;
FlashPendCmd.Valid = 0;
FlashReadStatusCmd = CMD_READ_STATUS;
FMWAIT = 0x1081;
FLCTL = FL_RST;
for (i=0; i< MAX_FLASH_NUM i++)
{
FlashSpec[i].Cmd = 0x180E8200 + (i<<9);
FlashSpec[i].Addr = 0x180E204 + (i<<9);
FlashSpec[i].Data = 0x180E208 + (i<<9);
FlashCs(i);
*FlashSpec[i].Cmd = CMD_RESET; //write cmd to flash chip
Delay100cyc(2):
FlashWaitBusy(0);
*FlashSpec[i].Cmd = CMD_READ_ID; //write cmd to flash chip
*FlashSpec[i].Addr = 0x00;
// read 5 bytes of CMD_READ_ID response
for (j=0; j<5; j++)
buff[j] = *FlashSpec[i].Data;
FlashDeCs();
for (j=0; j<sizeof(ManufactureIDTbl); j++)
{
// store Manufacturer index
if (ManufactureIDTbl[j] == buff[0])
FlashSpec[i].Vendor = j;
}
for (j=0; j<sizeof(DeviceCode); j++)
{
// look for matching device code
// and store total phys sectors
if (DeviceCode[j] == buff[1])
{
FlashSpec[i].TotPhySec = DeviceInfo[j];
break;
}
}
FlashSpec[i].MLC = 0;
//FlashSpec[i].Large = 0;
if (j > 2)
FlashSpec[i].Large = 1;
else
FlashSpec[i].Large = 0;
FlashSpec[i].Five = 1;
FlashSpec[i].MulPlane = 1;
FlashSpec[i].Interleave = 0;
FlashSpec[i].CacheProg = buff[2] & 0x80;
// store flash access time (ns)
switch (buff[3] & 0x88)
case 0:
FlashSpec[i].AccessTime = 50;
break;
case 0x80:
FlashSpec[i].AccessTime = 25;
break;
case 0x08:
FlashSpec[i].AccessTime = 20;
break;
default:
FlashSpec[i].AccessTime = 60;
// how many bits holds single flash cell
FlashSpec[i].MLC = (buff[3] >> 2) &0x03;
FlashSpec[i].SecPerPageRaw=2; // 1KB~8KB
for (j=0; j<(buff[3] & 0x03); j++) // page size
{
FlashSpec[i].SecPerPageRaw <<= 1;
}
FlashSpec[i].SecPerBlockRaw = 128; //64KB~512KB
for (j=0; j<((buff[3]>>4) & 0x03); j++) // block size
{
FlashSpec[i].SecPerBlockRaw<<=1;
}
// number of simultanously programmed pages
FlashSpec[i].MulPlane = 1<<((buff[2]>>4)&0x03 - 1);
FlashSpec[i].Interleave = (buff[2]>>6)&0x01;
FlashSpec[i].PagePerBlockRaw = FlashSpec[i].SectorPerBlockRaw/FlashSpec[i].SectorPerPageRaw;
FlashSpec[i].PagePerBlock = FlashSpec[i].PagePerBlockRaw * FlashSpec[i].MulPlane;
FlashSpec[i].SectorPerBlock = FlashSpec[i].SectorPerBlockRaw * FlashSpec[i].MulPlane;
FlashSpec[i].SectorPerPage = FlashSpec[i].SectorPerPageRaw * FlashSpec[i].MulPlane;
FlashSpec[i].TotBlks = FlashSpec[i].TotPhySec / FlashSpec[i].SectorPerBlock;
}
// read ID block and propagate SysDiskCapacity and SysResBlocks
}