关于支持多个片选的大容量NANDFLASH简记

很多处理器,都支持大容量的NAND,拿三星6410处理器来讲,从资料上看,支持大容量8G NANDFLASH,也说明了需要加片选来控制,这次做的是2GNAND的支持,需要2个片选。OK ~~~~~~~硬件上,NANDFLASH上增加一路片选信号,增加一路R/B控制。

我这个是由2个8G08构成的2GNAND

      软件上调整:

      1, 让系统判断出NAND的容量大小:在初始化NAND的时候,读2个片选对应的NANDID,读出两个NAND的相关信息,然后把这些信息告诉系统

   

    

[c-sharp]  view plain copy
  1. static DWORD ReadFlashID(void)  
  2. {  
  3.     BYTE Mfg, Dev;  
  4.     int i;  
  5.   
  6.     NF_nFCE_L();                // Deselect the flash chip.  
  7.     NF_CMD(CMD_READID);        // Send flash ID read command.  
  8.   
  9.     NF_ADDR(0);  
  10.   
  11.     for (i=0; i<10; i++)  
  12.     {  
  13.         Mfg    = NF_RDDATA_BYTE();  
  14.         if (Mfg == 0xEC || Mfg == 0x98) break;  
  15.     }  
  16.   
  17.     Dev    = NF_RDDATA_BYTE();  
  18.   
  19.     NF_nFCE_H();  
  20.   
  21.     return ((DWORD)(Mfg<<8)+Dev);  
  22. }  
  23.   
  24. //增加一个读片选2的函数  
  25. static DWORD ReadFlashID2(void)  
  26. {  
  27.     BYTE Mfg, Dev;  
  28.     int i;  
  29.   
  30.     NF_nFCE_L1();                // Deselect the flash chip.  
  31.     NF_CMD(CMD_READID);        // Send flash ID read command.  
  32.   
  33.     NF_ADDR(0);  
  34.   
  35.     for (i=0; i<10; i++)  
  36.     {  
  37.         Mfg    = NF_RDDATA_BYTE();  
  38.         if (Mfg == 0xEC || Mfg == 0x98) break;  
  39.     }  
  40.   
  41.     Dev    = NF_RDDATA_BYTE();  
  42.   
  43.     NF_nFCE_H1();  
  44.   
  45.     return ((DWORD)(Mfg<<8)+Dev);  
  46. }  

NF_nFCE_L1()为增加的那个片选的控制。

 

2, 把第1步中得到的2GNAND的信息,重新赋给全局变量,即告诉系统新的NAND信息。

在NAND初始化函数中 添加对第2快NAND的初始化

 

[c-sharp]  view plain copy
  1. //********************************初始化第2片NAND******************************************  
  2.     RETAILMSG(1, (TEXT("init the secend nand/n")));  
  3.     nMID = (UINT8)(nNandID2 >> 8);  
  4.     nDID = (UINT8)(nNandID2 & 0xff);  
  5.   
  6.     RETAILMSG(1, (TEXT("[FMD:INF] FMD_Init() : Read ID = 0x%08x/n"), nNandID2));  
  7.   
  8.     for (nCnt = 0; astNandSpec[nCnt].nMID != 0; nCnt++)  
  9.     {  
  10.         if (nDID == astNandSpec[nCnt].nDID)  
  11.         {  
  12.             bNandExt = TRUE;  
  13.             break;  
  14.         }  
  15.     }  
  16.   
  17.     if (!bNandExt)  
  18.     {  
  19.         RETAILMSG(1, (TEXT("[FMD:ERR] FMD_Init() : Unknown ID = 0x%08x/n"), nNandID));  
  20.         return NULL;  
  21.     }  
  22.   
  23.     int NUM_OF_BLOCKS2 = astNandSpec[nCnt].nNumOfBlks;  
  24.     int PAGES_PER_BLOCK2 = astNandSpec[nCnt].nPgsPerBlk;  
  25.     int SECTORS_PER_PAGE2 = astNandSpec[nCnt].nSctsPerPg;  
  26.   
  27.     RETAILMSG(1, (TEXT("[FMD] FMD_Init() : NUM_OF_BLOCKS2 = %d/n"), NUM_OF_BLOCKS2));  
  28.     RETAILMSG(1, (TEXT("[FMD] FMD_Init() : PAGES_PER_BLOCK2 = %d/n"), PAGES_PER_BLOCK2));  
  29.     RETAILMSG(1, (TEXT("[FMD] FMD_Init() : SECTORS_PER_PAGE2 = %d/n"), SECTORS_PER_PAGE2));  
  30.   
  31.     RETAILMSG(1, (TEXT("[FMD] --FMD_Init()2/n")));  
  32.   
  33. //相加  
  34.     NUM_OF_BLOCKS = NUM_OF_BLOCKS1+NUM_OF_BLOCKS1;   
  35.     PAGES_PER_BLOCK = astNandSpec[nCnt].nPgsPerBlk;  
  36.     SECTORS_PER_PAGE = astNandSpec[nCnt].nSctsPerPg;  
  37.   
  38.     RETAILMSG(1, (TEXT("[FMD] FMD_Init() : NUM_OF_BLOCKS = %d/n"), NUM_OF_BLOCKS));  
  39.     RETAILMSG(1, (TEXT("[FMD] FMD_Init() : PAGES_PER_BLOCK = %d/n"), PAGES_PER_BLOCK));  
  40.     RETAILMSG(1, (TEXT("[FMD] FMD_Init() : SECTORS_PER_PAGE = %d/n"), SECTORS_PER_PAGE));  
  41.   
  42.   
  43.     return((PVOID)g_pNFConReg);  
  44. }  

 

3,增加读写操作中的地址转换:

例如现在第1NAND的大小是8192BLOCK,那么当我们想去读/写第16000BLOCK进行操作的时候,我们要做个判断,让系统去操作第2  NAND的第(16000-8192)BLOCK

接下来就是细心的完全驱动相关函数的修改;

由于NAND的驱动相关函数很多,我这个就不全贴出,思路是一样的,注意这个地址转换就可以了(加个判断就OK了),仅列举读NAND函数

[c-sharp]  view plain copy
  1. BOOL FMD_ReadSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)  
  2. {  
  3.     BOOL bRet;  
  4.   
  5.     //RETAILMSG(1, (TEXT("[R:0x%08x] /n"), startSectorAddr));  
  6. #if (NAND_DEBUG)  
  7.     RETAILMSG(1, (TEXT("[FMD] ++FMD_ReadSector(0x%08x) /n"), startSectorAddr));  
  8. #endif  
  9.  
  10. #ifdef    SYNC_OP  
  11.     EnterCriticalSection(&g_csNandFlash);  
  12. #endif  
  13.   
  14.     if ( IS_LB )  
  15.     {   
  16.         if(8192*64<=startSectorAddr)  
  17.         {  
  18.             startSectorAddr=(startSectorAddr-8192*64);//转换为第2块NAND的地址,调用第2块NAND的函数  
  19.             bRet = FMD_LB_ReadSector2(startSectorAddr, pSectorBuff, pSectorInfoBuff, dwNumSectors, USE_NFCE);//!!!!  
  20.               
  21.         }  
  22.         else   
  23.         bRet = FMD_LB_ReadSector(startSectorAddr, pSectorBuff, pSectorInfoBuff, dwNumSectors, USE_NFCE);  
  24.     }  
  25.     else  
  26.     {  
  27.         if(8192*64<=startSectorAddr)  
  28.         {  
  29.             startSectorAddr=(startSectorAddr-8192*64);//转换为第2块NAND的地址,调用第2块NAND的函数  
  30.             bRet = FMD_SB_ReadSector2(startSectorAddr, pSectorBuff, pSectorInfoBuff, dwNumSectors, USE_NFCE);//!!!!  
  31.         }  
  32.         else  
  33.         bRet = FMD_SB_ReadSector(startSectorAddr, pSectorBuff, pSectorInfoBuff, dwNumSectors, USE_NFCE);  
  34.     }  
  35.  
  36. #ifdef    SYNC_OP  
  37.     LeaveCriticalSection(&g_csNandFlash);  
  38. #endif  
  39.  
  40. #if (NAND_DEBUG)  
  41.     RETAILMSG(1, (TEXT("[FMD] --FMD_ReadSector()/n")));  
  42. #endif  
  43.   
  44.     return bRet;  
  45. }  

这样编译后,重启,擦出/低格/高格信息:

[c-sharp]  view plain copy
  1. Enter your selection: a  
  2. All block(16384) Erase...  
  3. LB######## Error Erasing block 1462!  
  4. LB######## Error Erasing block 2011!  
  5. LB######## Error Erasing block 5027!  
  6. LB######## Error Erasing block 5687!  
  7. LB######## Error Erasing block 8048!  
  8. 2LB######## Error Erasing block 1005!//转换后的第2块NAND  
  9. 2LB######## Error Erasing block 1366!  
  10. 2LB######## Error Erasing block 3396!  
  11. 2LB######## Error Erasing block 5239!  
  12. 2LB######## Error Erasing block 7557!  
  13. //低格  
  14.   
  15. Reserving Blocks [0x0 - 0x5] ...  
  16. ...reserve complete.  
  17. Low-level format Blocks [0x6 - 0x3fff] ...  
  18. LB######## Error Erasing block 1462!  
  19. LB######## Error Erasing block 2011!  
  20. LB######## Error Erasing block 5027!  
  21. LB######## Error Erasing block 5687!  
  22. LB######## Error Erasing block 8048!  
  23. 2LB######## Error Erasing block 1005!  
  24. 2LB######## Error Erasing block 1366!  
  25. 2LB######## Error Erasing block 3396!  
  26. 2LB######## Error Erasing block 5239!  
  27. 2LB######## Error Erasing block 7557!  
  28. ...erase complete.  
  29. //高格  
  30.   
  31. Enter LowLevelFormat [0x6, 0x3fff].  
  32. Erasing flash block(s) [0x6, 0x3fff] (please wait): EraseBlocks: found a bad block (0x5b6) - skipping...  
  33. EraseBlocks: found a bad block (0x7db) - skipping...  
  34. EraseBlocks: found a bad block (0x13a3) - skipping...  
  35. EraseBlocks: found a bad block (0x1637) - skipping...  
  36. EraseBlocks: found a bad block (0x1f70) - skipping...  
  37. EraseBlocks: found a bad block (0x23ed) - skipping...  
  38. EraseBlocks: found a bad block (0x2556) - skipping...  
  39. EraseBlocks: found a bad block (0x2d44) - skipping...  
  40. EraseBlocks: found a bad block (0x3477) - skipping...  
  41. EraseBlocks: found a bad block (0x3d85) - skipping...  
  42. Done.  
  43. WriteMBR: MBR block = 0x6.  
  44. Done.  

这样就可以了,做的时间久了 ,可以有些细节会忘记了,但是思路就是这样,很简单。其他4G/8G如果需要片选,则也可以用这个思路做,只不过驱动可能代码又长了很多~呵呵

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值