i28f008.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:14k
源码类别:

VxWorks

开发平台:

C/C++

  1. /*
  2.  * $Log:   V:/i28f008.c_v  $
  3.  *
  4.  *    Rev 1.16   06 Oct 1997 18:37:30   ANDRY
  5.  * no COBUX
  6.  *
  7.  *    Rev 1.15   05 Oct 1997 15:32:40   ANDRY
  8.  * COBUX (16-bit Motorola M68360 board)
  9.  *
  10.  *    Rev 1.14   05 Oct 1997 14:35:36   ANDRY
  11.  * flNeedVpp() and flDontNeedVpp() are under #ifdef SOCKET_12_VOLTS
  12.  *
  13.  *    Rev 1.13   10 Sep 1997 16:18:10   danig
  14.  * Got rid of generic names
  15.  *
  16.  *    Rev 1.12   04 Sep 1997 18:47:20   danig
  17.  * Debug messages
  18.  *
  19.  *    Rev 1.11   31 Aug 1997 15:06:40   danig
  20.  * Registration routine return status
  21.  *
  22.  *    Rev 1.10   24 Jul 1997 17:52:30   amirban
  23.  * FAR to FAR0
  24.  *
  25.  *    Rev 1.9   21 Jul 1997 14:44:06   danig
  26.  * No parallelLimit
  27.  *
  28.  *    Rev 1.8   20 Jul 1997 17:17:00   amirban
  29.  * No watchDogTimer
  30.  *
  31.  *    Rev 1.7   07 Jul 1997 15:22:06   amirban
  32.  * Ver 2.0
  33.  *
  34.  *    Rev 1.6   15 Apr 1997 19:16:40   danig
  35.  * Pointer conversions.
  36.  *
  37.  *    Rev 1.5   29 Aug 1996 14:17:48   amirban
  38.  * Warnings
  39.  *
  40.  *    Rev 1.4   18 Aug 1996 13:48:44   amirban
  41.  * Comments
  42.  *
  43.  *    Rev 1.3   31 Jul 1996 14:31:10   amirban
  44.  * Background stuff
  45.  *
  46.  *    Rev 1.2   04 Jul 1996 18:20:06   amirban
  47.  * New flag field
  48.  *
  49.  *    Rev 1.1   03 Jun 1996 16:28:58   amirban
  50.  * Cobra additions
  51.  *
  52.  *    Rev 1.0   20 Mar 1996 13:33:06   amirban
  53.  * Initial revision.
  54.  */
  55. /************************************************************************/
  56. /*                                                                      */
  57. /* FAT-FTL Lite Software Development Kit */
  58. /* Copyright (C) M-Systems Ltd. 1995-1996 */
  59. /* */
  60. /************************************************************************/
  61. /*----------------------------------------------------------------------*/
  62. /*                                                                      */
  63. /* This MTD supports the following Flash technologies:                  */
  64. /*                                                                      */
  65. /* - Intel 28F008/Cobra 8-mbit devices */
  66. /* - Intel 28F016SA/28016SV/Cobra 16-mbit devices (byte-mode operation) */
  67. /* */
  68. /* And (among else), the following Flash media and cards: */
  69. /*                                                                      */
  70. /* - Intel Series-2 PCMCIA cards                                        */
  71. /* - Intel Series-2+ PCMCIA cards                                       */
  72. /* - M-Systems ISA/Tiny/PC-104 Flash Disks                              */
  73. /* - M-Systems NOR PCMCIA cards                                         */
  74. /* - Intel Value-100 cards                                              */
  75. /* */
  76. /*----------------------------------------------------------------------*/
  77. #include "flflash.h"
  78. #include "backgrnd.h"
  79. #define flash (*pFlash)
  80. #define SETUP_ERASE 0x20
  81. #define SETUP_WRITE 0x40
  82. #define CLEAR_STATUS 0x50
  83. #define READ_STATUS 0x70
  84. #define READ_ID  0x90
  85. #define SUSPEND_ERASE 0xb0
  86. #define CONFIRM_ERASE 0xd0
  87. #define RESUME_ERASE 0xd0
  88. #define READ_ARRAY 0xff
  89. #define WSM_ERROR 0x38
  90. #define WSM_VPP_ERROR 0x08
  91. #define WSM_SUSPENDED 0x40
  92. #define WSM_READY 0x80
  93. /* JEDEC ids for this MTD */
  94. #define I28F008_FLASH   0x89a2
  95. #define I28F016_FLASH 0x89a0
  96. #define COBRA004_FLASH 0x89a7
  97. #define COBRA008_FLASH 0x89a6
  98. #define COBRA016_FLASH 0x89aa
  99. #define MOBILE_MAX_INLV_4 0x8989
  100. #define LDP_1MB_IN_16BIT_MODE 0x89ff
  101. /* Definition of MTD specific vol.flags bits: */
  102. #define NO_12VOLTS 0x100 /* Card does not need 12 Volts Vpp */
  103. /*----------------------------------------------------------------------*/
  104. /*                      i 2 8 f 0 0 8 W r i t e */
  105. /* */
  106. /* Write a block of bytes to Flash */
  107. /* */
  108. /* This routine will be registered as the MTD vol.write routine */
  109. /* */
  110. /* Parameters:                                                          */
  111. /* vol : Pointer identifying drive */
  112. /*      address : Card address to write to */
  113. /*      buffer : Address of data to write */
  114. /* length : Number of bytes to write */
  115. /* overwrite : TRUE if overwriting old Flash contents */
  116. /*   FALSE if old contents are known to be erased */
  117. /*                                                                      */
  118. /* Returns:                                                             */
  119. /* FLStatus : 0 on success, failed otherwise */
  120. /*----------------------------------------------------------------------*/
  121. static FLStatus i28f008Write(FLFlash vol,
  122.    CardAddress address,
  123.    const void FAR1 *buffer,
  124.    int length,
  125.    FLBoolean overwrite)
  126. {
  127.   /* Set timeout ot 5 seconds from now */
  128.   unsigned long writeTimeout = flMsecCounter + 5000;
  129.   FLStatus status;
  130.   int i, cLength;
  131.   FlashPTR flashPtr;
  132.   if (flWriteProtected(vol.socket))
  133.     return flWriteProtect;
  134. #ifdef SOCKET_12_VOLTS
  135.   if (!(vol.flags & NO_12VOLTS))
  136.     checkStatus(flNeedVpp(vol.socket));
  137. #endif
  138.   flashPtr = (FlashPTR) vol.map(&vol, address,length);
  139.   cLength = length;
  140.   if (vol.interleaving == 1) {
  141. lastByte:
  142. #ifdef __cplusplus
  143.     #define bFlashPtr  flashPtr
  144.     #define bBuffer ((const unsigned char FAR1 * &) buffer)
  145. #else
  146.     #define bFlashPtr  flashPtr
  147.     #define bBuffer ((const unsigned char FAR1 *) buffer)
  148. #endif
  149.     while (cLength >= 1) {
  150.       *bFlashPtr = SETUP_WRITE;
  151.       *bFlashPtr = *bBuffer;
  152.       cLength--;
  153.       buffer = (const unsigned char FAR1 *) buffer + 1; /* bBuffer++; */
  154.       bFlashPtr++;
  155.       while (!(bFlashPtr[-1] & WSM_READY) && flMsecCounter < writeTimeout)
  156. ;
  157.     }
  158.   }
  159.   else if (vol.interleaving == 2) {
  160. lastWord:
  161. #ifdef __cplusplus
  162.     #define wFlashPtr ((FlashWPTR &) flashPtr)
  163.     #define wBuffer ((const unsigned short FAR1 * &) buffer)
  164. #else
  165.     #define wFlashPtr ((FlashWPTR) flashPtr)
  166.     #define wBuffer ((const unsigned short FAR1 *) buffer)
  167. #endif
  168.     while (cLength >= 2) {
  169.       *wFlashPtr = SETUP_WRITE * 0x101;        flDelayLoop(2);  /* HOOK for VME-177 */
  170.       *wFlashPtr = *wBuffer;                   flDelayLoop(2);  /* HOOK for VME-177 */
  171.       cLength -= 2;
  172.       /* used to be wBuffer++; */
  173.       buffer = (const unsigned char FAR1 *)buffer + sizeof(short);
  174.       /* used to be wFlashPtr++; */
  175.       flashPtr = (unsigned char *)flashPtr + sizeof(short);
  176.       while ((~wFlashPtr[-1] & (WSM_READY * 0x101)) && flMsecCounter < writeTimeout)
  177. ;
  178.     }
  179.     if (cLength > 0)
  180.       goto lastByte;
  181.   }
  182.   else /* if (vol.interleaving >= 4) */ {
  183. #ifdef __cplusplus
  184.     #define dFlashPtr ((FlashDPTR &) flashPtr)
  185.     #define dBuffer ((const unsigned long FAR1 * &) buffer)
  186. #else
  187.     #define dFlashPtr ((FlashDPTR) flashPtr)
  188.     #define dBuffer ((const unsigned long FAR1 *) buffer)
  189. #endif
  190.     while (cLength >= 4) {
  191.       *dFlashPtr = SETUP_WRITE * 0x1010101l;    flDelayLoop(2);  /* HOOK for VME-177 */
  192.       *dFlashPtr = *dBuffer;                    flDelayLoop(2);  /* HOOK for VME-177 */
  193.       cLength -= 4;
  194.       /* used to be dBuffer++; */
  195.       buffer = (unsigned char *)buffer + sizeof(unsigned long);
  196.       /* used to be dFlashPtr++; */
  197.       flashPtr = (unsigned char *)flashPtr + sizeof(unsigned long);
  198.       while ((~dFlashPtr[-1] & (WSM_READY * 0x1010101lu)) && flMsecCounter < writeTimeout)
  199. ;
  200.     }
  201.     if (cLength > 0)
  202.       goto lastWord;
  203.   }
  204.   flashPtr -= length;
  205.   buffer = (unsigned char *)buffer - length; /* bBuffer -= length */
  206.   status = flOK;
  207.   for (i = 0; i < vol.interleaving && i < length; i++) {
  208.     if (flashPtr[i] & WSM_ERROR) {
  209.     #ifdef DEBUG_PRINT
  210.       DEBUG_PRINT("Debug: write failed for 8-bit Intel media.n");
  211.     #endif
  212.       status = (flashPtr[i] & WSM_VPP_ERROR) ? flVppFailure : flWriteFault;
  213.       flashPtr[i] = CLEAR_STATUS;
  214.     }
  215.     flashPtr[i] = READ_ARRAY;
  216.   }
  217. #ifdef SOCKET_12_VOLTS
  218.   if (!(vol.flags & NO_12VOLTS))
  219.     flDontNeedVpp(vol.socket);
  220. #endif
  221.   /* we need this to switch to the read window */
  222.   flashPtr = (FlashPTR) vol.map(&vol, address,length); /* ADDED */
  223.   /* verify the data */
  224.   if (status == flOK && tffscmp((void FAR0 *) flashPtr,buffer,length)) {
  225.   #ifdef DEBUG_PRINT
  226.     DEBUG_PRINT("Debug: write failed for 8-bit Intel media in verification.n");
  227.   #endif
  228.     status = flWriteFault;
  229.   }
  230.   return status;
  231. }
  232. /*----------------------------------------------------------------------*/
  233. /*                      i 2 8 f 0 0 8 E r a s e */
  234. /* */
  235. /* Erase one or more contiguous Flash erasable blocks */
  236. /* */
  237. /* This routine will be registered as the MTD vol.erase routine */
  238. /* */
  239. /* Parameters:                                                          */
  240. /* vol : Pointer identifying drive */
  241. /*      firstErasableBlock : Number of first block to erase */
  242. /* numOfErasableBlocks: Number of blocks to erase */
  243. /*                                                                      */
  244. /* Returns:                                                             */
  245. /* FLStatus : 0 on success, failed otherwise */
  246. /*----------------------------------------------------------------------*/
  247. static FLStatus i28f008Erase(FLFlash vol,
  248.    int firstErasableBlock,
  249.    int numOfErasableBlocks)
  250. {
  251.   int iBlock;
  252.   FLStatus status = flOK; /* unless proven otherwise */
  253.   if (flWriteProtected(vol.socket))
  254.     return flWriteProtect;
  255. #ifdef SOCKET_12_VOLTS
  256.   if (!(vol.flags & NO_12VOLTS))
  257.     checkStatus(flNeedVpp(vol.socket));
  258. #endif
  259.   for (iBlock = 0; iBlock < numOfErasableBlocks && status == flOK; iBlock++) {
  260.     int j;
  261.     FLBoolean finished;
  262.     FlashPTR flashPtr = (FlashPTR)
  263.   vol.map(&vol,
  264.     (firstErasableBlock + iBlock) * vol.erasableBlockSize,
  265.     vol.interleaving);
  266.     for (j = 0; j < vol.interleaving; j++) {
  267.       flashPtr[j] = SETUP_ERASE; flDelayLoop (2);
  268.       flashPtr[j] = CONFIRM_ERASE; flDelayLoop (2);
  269.     }
  270.     do {
  271. #ifdef BACKGROUND
  272.       while (flForeground(1) == BG_SUSPEND) { /* suspend */
  273. for (j = 0; j < vol.interleaving; j++) {
  274.   flashPtr[j] = READ_STATUS;
  275.   if (!(flashPtr[j] & WSM_READY)) {
  276.     flashPtr[j] = SUSPEND_ERASE;
  277.     flashPtr[j] = READ_STATUS;
  278.     while (!(flashPtr[j] & WSM_READY))
  279.       ;
  280.   }
  281.   flashPtr[j] = READ_ARRAY;
  282. }
  283.       }
  284. #endif
  285.       finished = TRUE;
  286.       for (j = 0; j < vol.interleaving; j++) {
  287. flashPtr[j] = READ_STATUS;
  288. if (flashPtr[j] & WSM_SUSPENDED) {
  289.   flashPtr[j] = RESUME_ERASE;
  290.   finished = FALSE;
  291. }
  292. else if (!(flashPtr[j] & WSM_READY))
  293.   finished = FALSE;
  294. else {
  295.   if (flashPtr[j] & WSM_ERROR) {
  296.   #ifdef DEBUG_PRINT
  297.     DEBUG_PRINT("Debug: erase failed for 8-bit Intel media.n");
  298.   #endif
  299.     status = (flashPtr[j] & WSM_VPP_ERROR) ? flVppFailure : flWriteFault;
  300.   #ifdef DEBUG_PRINT
  301.     DEBUG_PRINT("Debug: flash status = 0x%xn", flashPtr[j]);
  302.   #endif
  303.     flashPtr[j] = CLEAR_STATUS;
  304.   #ifdef DEBUG_PRINT
  305.     DEBUG_PRINT("Debug: erase failed status = 0x%xn", status);
  306.   #endif
  307.   }
  308.   flashPtr[j] = READ_ARRAY;
  309. }
  310.       }
  311.     } while (!finished);
  312.   } /* block loop */
  313. #ifdef SOCKET_12_VOLTS
  314.   if (!(vol.flags & NO_12VOLTS))
  315.     flDontNeedVpp(vol.socket);
  316. #endif
  317.   return status;
  318. }
  319. /*----------------------------------------------------------------------*/
  320. /*                     i 2 8 f 0 0 8 I d e n t i f y */
  321. /* */
  322. /* Identifies media based on Intel 28F008 and Intel 28F016 and */
  323. /* registers as an MTD for such                                         */
  324. /* */
  325. /* This routine will be placed on the MTD list in custom.h. It must be */
  326. /* an extern routine. */
  327. /* */
  328. /* On successful identification, the Flash structure is filled out and */
  329. /* the write and erase routines registered. */
  330. /* */
  331. /* Parameters:                                                          */
  332. /* vol : Pointer identifying drive */
  333. /*                                                                      */
  334. /* Returns:                                                             */
  335. /* FLStatus : 0 on positive identificaion, failed otherwise */
  336. /*----------------------------------------------------------------------*/
  337. FLStatus i28f008Identify(FLFlash vol)
  338. {
  339.   int iChip;
  340.   CardAddress idOffset = 0;
  341. #ifdef DEBUG_PRINT
  342.   DEBUG_PRINT("Debug: entering 8-bit Intel media identification routine.n");
  343. #endif
  344.   flSetWindowBusWidth(vol.socket, 16);/* use 16-bits */
  345.   flSetWindowSpeed(vol.socket, 120);  /* 120 nsec. */
  346.   flSetWindowSize(vol.socket, 2); /* 8 KBytes */
  347.   flIntelIdentify(&vol, NULL,0);
  348.   if (vol.type == NOT_FLASH) {
  349.     /* The flash may be write-protected at offset 0. Try another offset */
  350.     idOffset = 0x80000l;
  351.     flIntelIdentify(&vol, NULL,idOffset);
  352.   }
  353.    if (vol.type == LDP_1MB_IN_16BIT_MODE) {
  354.     flSetWindowBusWidth(vol.socket, 8); /* use 8-bits */
  355.     flIntelIdentify(&vol, NULL,idOffset); /* and try to get a valid id */
  356.   }
  357.   switch (vol.type) {
  358.     case COBRA004_FLASH:
  359.       vol.chipSize = 0x80000l;
  360.       vol.flags |= SUSPEND_FOR_WRITE | NO_12VOLTS;
  361.       break;
  362.     case COBRA008_FLASH:
  363.       vol.flags |= SUSPEND_FOR_WRITE | NO_12VOLTS;
  364.       /* no break */
  365.     case MOBILE_MAX_INLV_4:
  366.     case I28F008_FLASH:
  367.       vol.chipSize = 0x100000l;
  368.       vol.chipSize = flFitInSocketWindow (vol.chipSize, vol.interleaving, vol.socket->window.size);
  369.       break;
  370.     case COBRA016_FLASH:
  371.       vol.flags |= SUSPEND_FOR_WRITE | NO_12VOLTS;
  372.       /* no break */
  373.     case I28F016_FLASH:
  374.       vol.chipSize = 0x200000l;
  375.       break;
  376.     default:
  377.     #ifdef DEBUG_PRINT
  378.       DEBUG_PRINT("Debug: failed to identify 8-bit Intel media.n");
  379.     #endif
  380.       return flUnknownMedia; /* not ours */
  381.   }
  382.   vol.erasableBlockSize = 0x10000l * vol.interleaving;
  383.   checkStatus(flIntelSize(&vol, NULL,idOffset));
  384.   if (vol.type == MOBILE_MAX_INLV_4)
  385.     vol.type = I28F008_FLASH;
  386.   for (iChip = 0; iChip < vol.noOfChips; iChip += vol.interleaving) {
  387.     int i;
  388.     FlashPTR flashPtr;
  389.     flNeedVpp(vol.socket);        /* ADDED, first thing to do */
  390.     flashPtr = (FlashPTR)
  391.             vol.map(&vol,iChip * vol.chipSize,vol.interleaving);
  392.     for (i = 0; i < vol.interleaving; i++)
  393.       flashPtr[i] = CLEAR_STATUS;
  394.     
  395.     flDontNeedVpp(vol.socket);   /* ADDED, last thing to do */
  396.   }
  397.   /* Register our flash handlers */
  398.   vol.write = i28f008Write;
  399.   vol.erase = i28f008Erase;
  400. #ifdef DEBUG_PRINT
  401.   DEBUG_PRINT("Debug: identified 8-bit Intel media.n");
  402. #endif
  403.   return flOK;
  404. }
  405. #if FALSE
  406. /*----------------------------------------------------------------------*/
  407. /*                   f l R e g i s t e r I 2 8 F 0 0 8 */
  408. /* */
  409. /* Registers this MTD for use */
  410. /* */
  411. /* Parameters:                                                          */
  412. /* None */
  413. /*                                                                      */
  414. /* Returns: */
  415. /* FLStatus : 0 on success, otherwise failure */
  416. /*----------------------------------------------------------------------*/
  417. FLStatus flRegisterI28F008(void)
  418. {
  419.   if (noOfMTDs >= MTDS)
  420.     return flTooManyComponents;
  421.   mtdTable[noOfMTDs++] = i28f008Identify;
  422.   return flOK;
  423. }
  424. #endif /* FALSE */