nand.c
上传用户:qiulin1960
上传日期:2013-10-16
资源大小:2844k
文件大小:6k
源码类别:

Windows CE

开发平台:

Windows_Unix

  1. //
  2. // Copyright (c) Microsoft Corporation.  All rights reserved.
  3. //
  4. //
  5. // Use of this source code is subject to the terms of the Microsoft end-user
  6. // license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
  7. // If you did not accept the terms of the EULA, you are not authorized to use
  8. // this source code. For a copy of the EULA, please see the LICENSE.RTF on your
  9. // install media.
  10. //
  11. /*++
  12. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  13. ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  14. THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  15. PARTICULAR PURPOSE.
  16. --*/
  17. #include <string.h>
  18. #include "def.h"
  19. #include "option.h"
  20. #include "2440addr.h"
  21. #include "2440lib.h"
  22. #include "nand.h"
  23. void __RdPage512(UCHAR *bufPt); 
  24. void __RdPage256(UCHAR *bufPt); 
  25. //  Status bit pattern
  26. #define STATUS_READY                0x40          
  27. #define STATUS_ERROR                0x01
  28. #define NF_CMD(cmd)     {rNFCMD  = (cmd); }
  29. #define NF_ADDR(addr) {rNFADDR = (addr); }
  30. #define NF_nFCE_L()     {rNFCONT &= ~(1<<1); }
  31. #define NF_nFCE_H()     {rNFCONT |= (1<<1); }
  32. #define NF_RSTECC()     {rNFCONT |= (1<<4); }
  33. #define NF_RDDATA()  (rNFDATA)
  34. #define NF_WRDATA(data) {rNFDATA = (data); }
  35. #define NF_WAITRB()     {while(!(rNFSTAT&(1<<0)));} 
  36. #define NF_CLEAR_RB() {rNFSTAT |= (1<<2); }
  37. #define NF_DETECT_RB() {while(!(rNFSTAT&(1<<2)));}
  38. #define NF_MECC_UnLock() {rNFCONT &= ~(1<<5);}
  39. #define NF_MECC_Lock() {rNFCONT |= (1<<5);}
  40. #define     pNFCONF     rNFCONF 
  41. #define     pNFCMD      rNFCMD  
  42. #define     pNFADDR     rNFADDR 
  43. #define     pNFDATA     rNFDATA 
  44. #define     pNFSTAT     rNFSTAT 
  45. #define     pNFECC      rNFECC0  
  46. #define NF_CE_L()     NF_nFCE_L()
  47. #define NF_CE_H()     NF_nFCE_H()
  48. #define NF_DATA_R()   rNFDATA
  49. #define NF_ECC()      rNFECC0
  50. typedef union _ECCRegVal
  51. {
  52. DWORD dwECCVal;
  53. BYTE bECCBuf[4];
  54. } ECCRegVal;
  55. //
  56. //  Reset the chip
  57. //
  58. void NF_Reset()
  59. {                       
  60.     NF_CE_L();
  61. NF_CLEAR_RB();
  62.     NF_CMD(CMD_RESET);  
  63.     NF_CE_H();          
  64. }
  65. // HCLK=133Mhz
  66. #define TACLS 0
  67. #define TWRPH0 6
  68. #define TWRPH1 0
  69. void NF_Init(void)
  70. {
  71.     rNFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);
  72.     rNFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(0<<6)|(0<<5)|(1<<4)|(1<<1)|(1<<0);
  73.     rNFSTAT = 0;
  74. }
  75. #ifdef NF_READID
  76. void NF_ReadID()
  77. {
  78.     USHORT  wData1, wData2;
  79.     //  First we enable chip select
  80.     NF_CE_L();
  81. NF_CLEAR_RB();
  82.     //  Issue commands to the controller
  83.     NF_CMD(CMD_READID);
  84.     NF_ADDR(0x00);
  85.     NF_DETECT_RB();
  86.     wData1 = (BYTE)NF_DATA_R();
  87.     wData2 = (BYTE)NF_DATA_R();
  88.     NF_CE_H();
  89.     Uart_SendString("Nand Mfg: ");
  90.     Uart_SendDWORD((DWORD)wData1, TRUE);
  91.     Uart_SendString("Nand Dev: ");
  92.     Uart_SendDWORD((DWORD)wData2, TRUE);
  93. }
  94. #endif
  95. #ifdef READ_SECTOR_INFO
  96. /* 
  97.  *  NAND_ReadSectorInfo
  98.  *
  99.  *  Read SectorInfo out of the spare area. The current implementation only handles
  100.  *  one sector at a time.
  101.  */
  102. void 
  103. NAND_ReadSectorInfo(
  104.     SECTOR_ADDR sectorAddr, 
  105.     PSectorInfo pInfo
  106.     )
  107. {
  108.     //  Chip enable
  109.     NF_CE_L();
  110. NF_CLEAR_RB();
  111.     //  Write the command
  112.     NF_CMD(CMD_READ2);
  113.     //  Write the address
  114.     NF_ADDR(0x00);
  115.     NF_ADDR(sectorAddr & 0xff);
  116.     NF_ADDR((sectorAddr >> 8) & 0xff);
  117.     
  118.     if (NEED_EXT_ADDR) {
  119.         NF_ADDR((sectorAddr >> 16) & 0xff);
  120.     }
  121.     //  Wait for the Ready bit
  122.     NF_DETECT_RB();
  123.     //  Read the SectorInfo data (we only need to read first 8 bytes) 
  124.     pInfo->dwReserved1  = (DWORD) ((BYTE) NF_DATA_R()) << 24;
  125.     pInfo->dwReserved1 |= (DWORD) ((BYTE) NF_DATA_R()) << 16;
  126.     pInfo->dwReserved1 |= (DWORD) ((BYTE) NF_DATA_R()) << 8;
  127.     pInfo->dwReserved1 |= (DWORD) ((BYTE) NF_DATA_R());
  128.     //  OEM byte
  129.     pInfo->bOEMReserved = (BYTE) NF_DATA_R();
  130.     //  Read the bad block mark
  131.     pInfo->bBadBlock = (BYTE) NF_DATA_R();
  132.     
  133.     //  Second reserved field (WORD)
  134.     pInfo->wReserved2 = ((BYTE) NF_DATA_R() << 8);
  135.     pInfo->wReserved2 |= ((BYTE) NF_DATA_R());
  136.     NF_CE_H();
  137. }
  138. #endif
  139. //  FMD_ReadSector
  140. //
  141. //  Read the content of the sector.
  142. //
  143. //  startSectorAddr: Starting page address
  144. //  pSectorBuff  : Buffer for the data portion
  145. //  pSectorInfoBuff: Buffer for Sector Info structure
  146. //  dwNumSectors : Number of sectors
  147. //
  148. BOOL 
  149. FMD_ReadSector(
  150.     SECTOR_ADDR startSectorAddr, 
  151.     LPBYTE pSectorBuff,
  152.     PSectorInfo pSectorInfoBuff, 
  153.     DWORD dwNumSectors
  154.     )
  155. {
  156.     DWORD   i, r = 0;
  157.     BYTE   ecc0,ecc1,ecc2;
  158.     BOOL   rc = TRUE;
  159.     ECCRegVal eccRegVal;
  160.     //  BUGBUGBUG: I need to come back to support dwNumSectors > 1
  161.     //
  162.     //  Sanity check
  163.     if (!pSectorBuff && !pSectorInfoBuff || dwNumSectors > 1 || !pSectorBuff) {
  164. //        Uart_SendString("ERROR_INVALID_PARAMETERn");
  165.         return FALSE;
  166.     }
  167. //    Uart_SendString("R: ");
  168. //    Uart_SendDWORD(startSectorAddr, TRUE);
  169. _retry:
  170.     //  Initialize ECC register
  171.     NF_RSTECC();
  172. NF_MECC_UnLock();
  173.     //  Enable the chip
  174.     NF_nFCE_L();   
  175. NF_CLEAR_RB();
  176.     // Issue Read command
  177.     NF_CMD(CMD_READ);
  178.     //  Set up address
  179.     NF_ADDR(0x00);
  180.     NF_ADDR((startSectorAddr) & 0xff);
  181.     NF_ADDR((startSectorAddr >> 8) & 0xff);
  182.     if (NEED_EXT_ADDR) {
  183.         NF_ADDR((startSectorAddr >> 16) & 0xff);
  184.     }
  185.     for (i = 0; i < 5; i++);   // wait tWB(100ns)
  186.     NF_DETECT_RB();        // wait tR(max 12us)
  187.     // read the data
  188.     __RdPage512(pSectorBuff);
  189. //    __RdPage256(pSectorBuff);
  190. NF_MECC_Lock();
  191. // for ( i = 0; i < 512; i++ )
  192. // Uart_SendByte(*(pSectorBuff+i));
  193. // Read the ECC from ECC Register
  194. eccRegVal.dwECCVal = NF_ECC();
  195. // Skip first 8 bytes
  196. for(i=0; i<8; i++){
  197. ecc0 = (BYTE)NF_DATA_R();
  198. }
  199. ecc0 = (BYTE)NF_DATA_R();
  200. ecc1 = (BYTE)NF_DATA_R();
  201. ecc2 = (BYTE)NF_DATA_R();
  202.     NF_nFCE_H();
  203.     if ( !rc && r++ < 3 ) {
  204.         Uart_SendString("FMD_ReadSector: ");
  205.         Uart_SendDWORD(startSectorAddr, TRUE);
  206.         NF_Reset();
  207.         
  208.         for (i = 0; i < 5; i++);   // delay
  209.         rc = TRUE;
  210.         
  211.         goto _retry;
  212.     }
  213.     
  214.     if ( startSectorAddr < 0x120 ) // NO ECC Check about EBOOT
  215.     {
  216.      rc = TRUE;
  217.     }
  218.     else
  219.     {
  220. if( ecc0 != eccRegVal.bECCBuf[0] ||
  221. ecc0 != eccRegVal.bECCBuf[0] ||
  222. ecc0 != eccRegVal.bECCBuf[0] )  {
  223. // Uart_SendString("ECC mismatch for Sector: ");
  224. // Uart_SendDWORD(startSectorAddr, TRUE);
  225. rc = FALSE;
  226. }
  227.     }
  228.     return rc;
  229. }