很多处理器,都支持大容量的NAND,拿三星6410处理器来讲,从资料上看,支持大容量8G NANDFLASH,也说明了需要加片选来控制,这次做的是2GNAND的支持,需要2个片选。OK ~~~~~~~硬件上,NANDFLASH上增加一路片选信号,增加一路R/B控制。
我这个是由2个8G08构成的2GNAND
软件上调整:
1, 让系统判断出NAND的容量大小:在初始化NAND的时候,读2个片选对应的NAND的ID,读出两个NAND的相关信息,然后把这些信息告诉系统
- static DWORD ReadFlashID(void)
- {
- BYTE Mfg, Dev;
- int i;
- NF_nFCE_L(); // Deselect the flash chip.
- NF_CMD(CMD_READID); // Send flash ID read command.
- NF_ADDR(0);
- for (i=0; i<10; i++)
- {
- Mfg = NF_RDDATA_BYTE();
- if (Mfg == 0xEC || Mfg == 0x98) break;
- }
- Dev = NF_RDDATA_BYTE();
- NF_nFCE_H();
- return ((DWORD)(Mfg<<8)+Dev);
- }
- //增加一个读片选2的函数
- static DWORD ReadFlashID2(void)
- {
- BYTE Mfg, Dev;
- int i;
- NF_nFCE_L1(); // Deselect the flash chip.
- NF_CMD(CMD_READID); // Send flash ID read command.
- NF_ADDR(0);
- for (i=0; i<10; i++)
- {
- Mfg = NF_RDDATA_BYTE();
- if (Mfg == 0xEC || Mfg == 0x98) break;
- }
- Dev = NF_RDDATA_BYTE();
- NF_nFCE_H1();
- return ((DWORD)(Mfg<<8)+Dev);
- }
NF_nFCE_L1()为增加的那个片选的控制。
2, 把第1步中得到的2GNAND的信息,重新赋给全局变量,即告诉系统新的NAND信息。
在NAND初始化函数中 添加对第2快NAND的初始化
- //********************************初始化第2片NAND******************************************
- RETAILMSG(1, (TEXT("init the secend nand/n")));
- nMID = (UINT8)(nNandID2 >> 8);
- nDID = (UINT8)(nNandID2 & 0xff);
- RETAILMSG(1, (TEXT("[FMD:INF] FMD_Init() : Read ID = 0x%08x/n"), nNandID2));
- for (nCnt = 0; astNandSpec[nCnt].nMID != 0; nCnt++)
- {
- if (nDID == astNandSpec[nCnt].nDID)
- {
- bNandExt = TRUE;
- break;
- }
- }
- if (!bNandExt)
- {
- RETAILMSG(1, (TEXT("[FMD:ERR] FMD_Init() : Unknown ID = 0x%08x/n"), nNandID));
- return NULL;
- }
- int NUM_OF_BLOCKS2 = astNandSpec[nCnt].nNumOfBlks;
- int PAGES_PER_BLOCK2 = astNandSpec[nCnt].nPgsPerBlk;
- int SECTORS_PER_PAGE2 = astNandSpec[nCnt].nSctsPerPg;
- RETAILMSG(1, (TEXT("[FMD] FMD_Init() : NUM_OF_BLOCKS2 = %d/n"), NUM_OF_BLOCKS2));
- RETAILMSG(1, (TEXT("[FMD] FMD_Init() : PAGES_PER_BLOCK2 = %d/n"), PAGES_PER_BLOCK2));
- RETAILMSG(1, (TEXT("[FMD] FMD_Init() : SECTORS_PER_PAGE2 = %d/n"), SECTORS_PER_PAGE2));
- RETAILMSG(1, (TEXT("[FMD] --FMD_Init()2/n")));
- //相加
- NUM_OF_BLOCKS = NUM_OF_BLOCKS1+NUM_OF_BLOCKS1;
- PAGES_PER_BLOCK = astNandSpec[nCnt].nPgsPerBlk;
- SECTORS_PER_PAGE = astNandSpec[nCnt].nSctsPerPg;
- RETAILMSG(1, (TEXT("[FMD] FMD_Init() : NUM_OF_BLOCKS = %d/n"), NUM_OF_BLOCKS));
- RETAILMSG(1, (TEXT("[FMD] FMD_Init() : PAGES_PER_BLOCK = %d/n"), PAGES_PER_BLOCK));
- RETAILMSG(1, (TEXT("[FMD] FMD_Init() : SECTORS_PER_PAGE = %d/n"), SECTORS_PER_PAGE));
- return((PVOID)g_pNFConReg);
- }
3,增加读写操作中的地址转换:
例如现在第1个NAND的大小是8192个BLOCK,那么当我们想去读/写第16000个BLOCK进行操作的时候,我们要做个判断,让系统去操作第2片 NAND的第(16000-8192)个BLOCK。
接下来就是细心的完全驱动相关函数的修改;
由于NAND的驱动相关函数很多,我这个就不全贴出,思路是一样的,注意这个地址转换就可以了(加个判断就OK了),仅列举读NAND函数
- BOOL FMD_ReadSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)
- {
- BOOL bRet;
- //RETAILMSG(1, (TEXT("[R:0x%08x] /n"), startSectorAddr));
- #if (NAND_DEBUG)
- RETAILMSG(1, (TEXT("[FMD] ++FMD_ReadSector(0x%08x) /n"), startSectorAddr));
- #endif
- #ifdef SYNC_OP
- EnterCriticalSection(&g_csNandFlash);
- #endif
- if ( IS_LB )
- {
- if(8192*64<=startSectorAddr)
- {
- startSectorAddr=(startSectorAddr-8192*64);//转换为第2块NAND的地址,调用第2块NAND的函数
- bRet = FMD_LB_ReadSector2(startSectorAddr, pSectorBuff, pSectorInfoBuff, dwNumSectors, USE_NFCE);//!!!!
- }
- else
- bRet = FMD_LB_ReadSector(startSectorAddr, pSectorBuff, pSectorInfoBuff, dwNumSectors, USE_NFCE);
- }
- else
- {
- if(8192*64<=startSectorAddr)
- {
- startSectorAddr=(startSectorAddr-8192*64);//转换为第2块NAND的地址,调用第2块NAND的函数
- bRet = FMD_SB_ReadSector2(startSectorAddr, pSectorBuff, pSectorInfoBuff, dwNumSectors, USE_NFCE);//!!!!
- }
- else
- bRet = FMD_SB_ReadSector(startSectorAddr, pSectorBuff, pSectorInfoBuff, dwNumSectors, USE_NFCE);
- }
- #ifdef SYNC_OP
- LeaveCriticalSection(&g_csNandFlash);
- #endif
- #if (NAND_DEBUG)
- RETAILMSG(1, (TEXT("[FMD] --FMD_ReadSector()/n")));
- #endif
- return bRet;
- }
这样编译后,重启,擦出/低格/高格信息:
- Enter your selection: a
- All block(16384) Erase...
- LB######## Error Erasing block 1462!
- LB######## Error Erasing block 2011!
- LB######## Error Erasing block 5027!
- LB######## Error Erasing block 5687!
- LB######## Error Erasing block 8048!
- 2LB######## Error Erasing block 1005!//转换后的第2块NAND
- 2LB######## Error Erasing block 1366!
- 2LB######## Error Erasing block 3396!
- 2LB######## Error Erasing block 5239!
- 2LB######## Error Erasing block 7557!
- //低格
- Reserving Blocks [0x0 - 0x5] ...
- ...reserve complete.
- Low-level format Blocks [0x6 - 0x3fff] ...
- LB######## Error Erasing block 1462!
- LB######## Error Erasing block 2011!
- LB######## Error Erasing block 5027!
- LB######## Error Erasing block 5687!
- LB######## Error Erasing block 8048!
- 2LB######## Error Erasing block 1005!
- 2LB######## Error Erasing block 1366!
- 2LB######## Error Erasing block 3396!
- 2LB######## Error Erasing block 5239!
- 2LB######## Error Erasing block 7557!
- ...erase complete.
- //高格
- Enter LowLevelFormat [0x6, 0x3fff].
- Erasing flash block(s) [0x6, 0x3fff] (please wait): EraseBlocks: found a bad block (0x5b6) - skipping...
- EraseBlocks: found a bad block (0x7db) - skipping...
- EraseBlocks: found a bad block (0x13a3) - skipping...
- EraseBlocks: found a bad block (0x1637) - skipping...
- EraseBlocks: found a bad block (0x1f70) - skipping...
- EraseBlocks: found a bad block (0x23ed) - skipping...
- EraseBlocks: found a bad block (0x2556) - skipping...
- EraseBlocks: found a bad block (0x2d44) - skipping...
- EraseBlocks: found a bad block (0x3477) - skipping...
- EraseBlocks: found a bad block (0x3d85) - skipping...
- Done.
- WriteMBR: MBR block = 0x6.
- Done.
这样就可以了,做的时间久了 ,可以有些细节会忘记了,但是思路就是这样,很简单。其他4G/8G如果需要片选,则也可以用这个思路做,只不过驱动可能代码又长了很多~呵呵