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

VxWorks

开发平台:

C/C++

  1. /*
  2.  * $Log:   P:/user/amir/lite/vcs/i28f016.c_v  $
  3.  * 
  4.  *    Rev 1.10   06 Oct 1997  9:45:48   danig
  5.  * VPP functions under #ifdef
  6.  * 
  7.  *    Rev 1.9   10 Sep 1997 16:48:24   danig
  8.  * Debug messages & got rid of generic names
  9.  * 
  10.  *    Rev 1.8   31 Aug 1997 15:09:20   danig
  11.  * Registration routine return status
  12.  * 
  13.  *    Rev 1.7   24 Jul 1997 17:52:58   amirban
  14.  * FAR to FAR0
  15.  * 
  16.  *    Rev 1.6   20 Jul 1997 17:17:06   amirban
  17.  * No watchDogTimer
  18.  * 
  19.  *    Rev 1.5   07 Jul 1997 15:22:08   amirban
  20.  * Ver 2.0
  21.  * 
  22.  *    Rev 1.4   04 Mar 1997 16:44:22   amirban
  23.  * Page buffer bug fix
  24.  * 
  25.  *    Rev 1.3   18 Aug 1996 13:48:24   amirban
  26.  * Comments
  27.  * 
  28.  *    Rev 1.2   12 Aug 1996 15:49:04   amirban
  29.  * Added suspend/resume
  30.  * 
  31.  *    Rev 1.1   31 Jul 1996 14:30:50   amirban
  32.  * Background stuff
  33.  * 
  34.  *    Rev 1.0   18 Jun 1996 16:34:30   amirban
  35.  * Initial revision.
  36.  */
  37. /************************************************************************/
  38. /*                                                                      */
  39. /* FAT-FTL Lite Software Development Kit */
  40. /* Copyright (C) M-Systems Ltd. 1995-1996 */
  41. /* */
  42. /************************************************************************/
  43. /*----------------------------------------------------------------------*/
  44. /*                                                                      */
  45. /* This MTD supports the following Flash technologies:                  */
  46. /*                                                                      */
  47. /* - Intel 28F016SA/28016SV/Cobra 16-mbit devices */
  48. /* */
  49. /* And (among else), the following Flash media and cards: */
  50. /*                                                                      */
  51. /* - Intel Series-2+ PCMCIA cards                                       */
  52. /* */
  53. /*----------------------------------------------------------------------*/
  54. #include "flflash.h"
  55. #include "backgrnd.h"
  56. /* JEDEC ids for this MTD */
  57. #define I28F016_FLASH 0x89a0
  58. #define SETUP_ERASE 0x2020
  59. #define SETUP_WRITE 0x4040
  60. #define CLEAR_STATUS 0x5050
  61. #define READ_STATUS 0x7070
  62. #define READ_ID  0x9090
  63. #define SUSPEND_ERASE 0xb0b0
  64. #define CONFIRM_ERASE 0xd0d0
  65. #define RESUME_ERASE 0xd0d0
  66. #define READ_ARRAY 0xffff
  67. #define LOAD_PAGE_BUFFER 0xe0e0
  68. #define WRITE_PAGE_BUFFER 0x0c0c
  69. #define READ_EXTENDED_REGS 0x7171
  70. #define WSM_VPP_ERROR 0x08
  71. #define WSM_ERROR 0x38
  72. #define WSM_SUSPENDED 0x40
  73. #define WSM_READY 0x80
  74. #define GSR_ERROR 0x20
  75. #define both(word) (vol.interleaving == 1 ? (word) : (word) & ((word) >> 8))
  76. #define any(word) ((word) | ((word) >> 8))
  77. /*----------------------------------------------------------------------*/
  78. /*                    i 2 8 f 0 1 6 W o r d S i z e */
  79. /* */
  80. /* Identify the card size for an Intel 28F016 word-mode Flash array. */
  81. /* Sets the value of vol.noOfChips. */
  82. /* */
  83. /* Parameters:                                                          */
  84. /* vol : Pointer identifying drive */
  85. /*                                                                      */
  86. /* Returns:                                                             */
  87. /* FLStatus : 0 = OK, otherwise failed (invalid Flash array)*/
  88. /*----------------------------------------------------------------------*/
  89. static FLStatus i28f016WordSize(FLFlash vol)
  90. {
  91.   FlashWPTR flashPtr = (FlashWPTR) flMap(vol.socket,0);
  92.   flashPtr[0] = CLEAR_STATUS;
  93.   flashPtr[0] = READ_ID;
  94.   /* We leave the first chip in Read ID mode, so that we can */
  95.   /* discover an address wraparound. */
  96.   for (vol.noOfChips = 1; /* Scan the chips */
  97.        vol.noOfChips < 2000;  /* Big enough ? */
  98.        vol.noOfChips++) {
  99.     flashPtr = (FlashWPTR) flMap(vol.socket,vol.noOfChips * vol.chipSize);
  100.     if (flashPtr[0] == 0x0089 && flashPtr[1] == 0x66a0)
  101.       break;   /* We've wrapped around to the first chip ! */
  102.     flashPtr[0] = READ_ID;
  103.     if (!(flashPtr[0] == 0x0089 && flashPtr[1] == 0x66a0))
  104.       break;
  105.     flashPtr[0] = CLEAR_STATUS;
  106.     flashPtr[0] = READ_ARRAY;
  107.   }
  108.   flashPtr = (FlashWPTR) flMap(vol.socket,0);
  109.   flashPtr[0] = READ_ARRAY;
  110.   return flOK;
  111. }
  112. /*----------------------------------------------------------------------*/
  113. /*                      i 2 8 f 0 1 6 W r i t e */
  114. /* */
  115. /* Write a block of bytes to Flash */
  116. /* */
  117. /* This routine will be registered as the MTD flash.write routine */
  118. /* */
  119. /* Parameters:                                                          */
  120. /* vol : Pointer identifying drive */
  121. /*      address : Card address to write to */
  122. /*      buffer : Address of data to write */
  123. /* length : Number of bytes to write */
  124. /* overwrite : TRUE if overwriting old Flash contents */
  125. /*   FALSE if old contents are known to be erased */
  126. /*                                                                      */
  127. /* Returns:                                                             */
  128. /* FLStatus : 0 on success, failed otherwise */
  129. /*----------------------------------------------------------------------*/
  130. static FLStatus i28f016Write(FLFlash vol,
  131.    CardAddress address,
  132.    const void FAR1 *buffer,
  133.    int length,
  134.    FLBoolean overwrite)
  135. {
  136.   /* Set timeout ot 5 seconds from now */
  137.   unsigned long writeTimeout = flMsecCounter + 5000;
  138.   FLStatus status = flOK;
  139.   FlashWPTR flashPtr;
  140.   int maxLength, i, from;
  141.   if (flWriteProtected(vol.socket))
  142.     return flWriteProtect;
  143.   if ((length & 1) || (address & 1)) /* Only write words on word-boundary */
  144.     return flBadParameter;
  145. #ifdef SOCKET_12_VOLTS
  146.   checkStatus(flNeedVpp(vol.socket));
  147. #endif
  148.   maxLength = 256 * vol.interleaving;
  149.   for (from = 0; from < length && status == flOK; from += maxLength) {
  150.     FlashWPTR currPtr;
  151.     unsigned lengthWord;
  152.     int tailBytes;
  153.     int thisLength = length - from;
  154.     if (thisLength > maxLength)
  155.       thisLength = maxLength;
  156.     lengthWord = (thisLength + vol.interleaving - 1) /
  157.  (vol.interleaving == 1 ? 2 : vol.interleaving) - 1;
  158.     if (vol.interleaving != 1)
  159.       lengthWord |= (lengthWord << 8);
  160.     flashPtr = (FlashWPTR) flMap(vol.socket,address + from);
  161.     tailBytes = ((thisLength - 1) & (vol.interleaving - 1)) + 1;
  162.     for (i = 0, currPtr = flashPtr;
  163.  i < vol.interleaving && i < thisLength;
  164.  i += 2, currPtr++) {
  165.       *currPtr = LOAD_PAGE_BUFFER;
  166.       *currPtr = i < tailBytes ? lengthWord : lengthWord - 1;
  167.       *currPtr = 0;
  168.     }
  169.     tffscpyWords((unsigned long FAR0 *) flashPtr,
  170.     (const char FAR1 *) buffer + from,
  171.     thisLength);
  172.     for (i = 0, currPtr = flashPtr;
  173.  i < vol.interleaving && i < thisLength;
  174.  i += 2, currPtr++) {
  175.       *currPtr = WRITE_PAGE_BUFFER;
  176.       if (!((address + from + i) & vol.interleaving)) {
  177. /* Even address */
  178. *currPtr = lengthWord;
  179. *currPtr = 0;
  180.       }
  181.       else {
  182. /* Odd address */
  183. *currPtr = 0;
  184. *currPtr = lengthWord;
  185.       }
  186.     }
  187.     /* map to the GSR & BSR */
  188.     flashPtr = (FlashWPTR) flMap(vol.socket,
  189.        ((address + from) & -vol.erasableBlockSize) +
  190.        4 * vol.interleaving);
  191.     for (i = 0, currPtr = flashPtr;
  192.  i < vol.interleaving && i < thisLength;
  193.  i += 2, currPtr++) {
  194.       *currPtr = READ_EXTENDED_REGS;
  195.       while (!(both(*currPtr) & WSM_READY) && flMsecCounter < writeTimeout)
  196. ;
  197.       if ((any(*currPtr) & GSR_ERROR) || !(both(*currPtr) & WSM_READY)) {
  198.       #ifdef DEBUG_PRINT
  199. DEBUG_PRINT("Debug: write failed for 16-bit Intel media.n");
  200.       #endif
  201. status = flWriteFault;
  202. *currPtr = CLEAR_STATUS;
  203.       }
  204.       *currPtr = READ_ARRAY;
  205.     }
  206.   }
  207. #ifdef SOCKET_12_VOLTS
  208.   flDontNeedVpp(vol.socket);
  209. #endif
  210.   flashPtr = (FlashWPTR) flMap(vol.socket, address);
  211.   /* verify the data */
  212.   if (status == flOK && tffscmpWords((void FAR0 *) flashPtr, (void FAR1 *) buffer,length)) {
  213.   #ifdef DEBUG_PRINT
  214.     DEBUG_PRINT("Debug: write failed for 16-bit Intel media in verification.n");
  215.   #endif
  216.     status = flWriteFault;
  217.   }
  218.   return status;
  219. }
  220. /*----------------------------------------------------------------------*/
  221. /*                      i 2 8 f 0 1 6 E r a s e */
  222. /* */
  223. /* Erase one or more contiguous Flash erasable blocks */
  224. /* */
  225. /* This routine will be registered as the MTD vol.erase routine */
  226. /* */
  227. /* Parameters:                                                          */
  228. /* vol : Pointer identifying drive */
  229. /*      firstErasableBlock : Number of first block to erase */
  230. /* numOfErasableBlocks: Number of blocks to erase */
  231. /*                                                                      */
  232. /* Returns:                                                             */
  233. /* FLStatus : 0 on success, failed otherwise */
  234. /*----------------------------------------------------------------------*/
  235. static FLStatus i28f016Erase(FLFlash vol,
  236.    int firstErasableBlock,
  237.    int numOfErasableBlocks)
  238. {
  239.   FLStatus status = flOK; /* unless proven otherwise */
  240.   int iBlock;
  241.   if (flWriteProtected(vol.socket))
  242.     return flWriteProtect;
  243. #ifdef SOCKET_12_VOLTS
  244.   checkStatus(flNeedVpp(vol.socket));
  245. #endif
  246.   for (iBlock = 0; iBlock < numOfErasableBlocks && status == flOK; iBlock++) {
  247.     FlashWPTR currPtr;
  248.     int i;
  249.     FLBoolean finished;
  250.     FlashWPTR flashPtr = (FlashWPTR)
  251.    flMap(vol.socket,(firstErasableBlock + iBlock) * vol.erasableBlockSize);
  252.     for (i = 0, currPtr = flashPtr;
  253.  i < vol.interleaving;
  254.  i += 2, currPtr++) {
  255.       *currPtr = SETUP_ERASE;
  256.       *currPtr = CONFIRM_ERASE;
  257.     }
  258.     do {
  259. #ifdef BACKGROUND
  260.       while (flForeground(1) == BG_SUSPEND) { /* suspend */
  261. for (i = 0, currPtr = flashPtr;
  262.      i < vol.interleaving;
  263.      i += 2, currPtr++) {
  264.   *currPtr = READ_STATUS;
  265.   if (!(both(*currPtr) & WSM_READY)) {
  266.     *currPtr = SUSPEND_ERASE;
  267.     *currPtr = READ_STATUS;
  268.     while (!(both(*currPtr) & WSM_READY))
  269.       ;
  270.   }
  271.   *currPtr = READ_ARRAY;
  272. }
  273.       }
  274. #endif
  275.       finished = TRUE;
  276.       for (i = 0, currPtr = flashPtr;
  277.    i < vol.interleaving;
  278.    i += 2, currPtr++) {
  279. *currPtr = READ_STATUS;
  280. if (any(*currPtr) & WSM_SUSPENDED) {
  281.   *currPtr = RESUME_ERASE;
  282.   finished = FALSE;
  283. }
  284. else if (!(both(*currPtr) & WSM_READY))
  285.   finished = FALSE;
  286. else {
  287.   if (any(*currPtr) & WSM_ERROR) {
  288.   #ifdef DEBUG_PRINT
  289.     DEBUG_PRINT("Debug: erase failed for 16-bit Intel media.n");
  290.   #endif
  291.     status = (any(*currPtr) & WSM_VPP_ERROR) ? flVppFailure : flWriteFault;
  292.     *currPtr = CLEAR_STATUS;
  293.   }
  294.   *currPtr = READ_ARRAY;
  295. }
  296.       }
  297.     } while (!finished);
  298.   }
  299. #ifdef SOCKET_12_VOLTS
  300.   flDontNeedVpp(vol.socket);
  301. #endif
  302.   return status;
  303. }
  304. /*----------------------------------------------------------------------*/
  305. /*                     i 2 8 f 0 1 6 I d e n t i f y */
  306. /* */
  307. /* Identifies media based on Intel 28F016 and registers as an MTD for */
  308. /* such. */
  309. /* */
  310. /* This routine will be placed on the MTD list in custom.h. It must be */
  311. /* an extern routine. */
  312. /* */
  313. /* On successful identification, the Flash structure is filled out and */
  314. /* the write and erase routines registered. */
  315. /* */
  316. /* Parameters:                                                          */
  317. /* vol : Pointer identifying drive */
  318. /*                                                                      */
  319. /* Returns:                                                             */
  320. /* FLStatus : 0 on positive identificaion, failed otherwise */
  321. /*----------------------------------------------------------------------*/
  322. FLStatus i28f016Identify(FLFlash vol)
  323. {
  324.   FlashWPTR flashPtr;
  325. #ifdef DEBUG_PRINT
  326.   DEBUG_PRINT("Debug: entering 16-bit Intel media identification routine.n");
  327. #endif
  328.   flSetWindowBusWidth(vol.socket,16);/* use 16-bits */
  329.   flSetWindowSpeed(vol.socket,120);  /* 120 nsec. */
  330.   flSetWindowSize(vol.socket,2); /* 8 KBytes */
  331.   flashPtr = (FlashWPTR) flMap(vol.socket,0);
  332.   vol.noOfChips = 0;
  333.   flashPtr[0] = READ_ID;
  334.   if (flashPtr[0] == 0x0089 && flashPtr[1] == 0x66a0) {
  335.     /* Word mode */
  336.     vol.type = I28F016_FLASH;
  337.     vol.interleaving = 1;
  338.     flashPtr[0] = READ_ARRAY;
  339.   }
  340.   else {
  341.     /* Use standard identification routine to detect byte-mode */
  342.     flIntelIdentify(&vol, NULL,0);
  343.     if (vol.interleaving == 1)
  344.       vol.type = NOT_FLASH; /* We cannot handle byte-mode interleaving-1 */
  345.   }
  346.   if (vol.type == I28F016_FLASH) {
  347.     vol.chipSize = 0x200000L;
  348.     vol.erasableBlockSize = 0x10000L * vol.interleaving;
  349.     checkStatus(vol.interleaving == 1 ?
  350. i28f016WordSize(&vol) :
  351. flIntelSize(&vol, NULL,0));
  352.     /* Register our flash handlers */
  353.     vol.write = i28f016Write;
  354.     vol.erase = i28f016Erase;
  355.   #ifdef DEBUG_PRINT
  356.     DEBUG_PRINT("Debug: identified 16-bit Intel media.n");
  357.   #endif
  358.     return flOK;
  359.   }
  360.   else {
  361.   #ifdef DEBUG_PRINT
  362.     DEBUG_PRINT("Debug: failed to identify 16-bit Intel media.n");
  363.   #endif
  364.     return flUnknownMedia;  /* not ours */
  365.   }
  366. }
  367. #if FALSE
  368. /*----------------------------------------------------------------------*/
  369. /*                   f l R e g i s t e r I 2 8 F 0 1 6 */
  370. /* */
  371. /* Registers this MTD for use */
  372. /* */
  373. /* Parameters:                                                          */
  374. /* None */
  375. /*                                                                      */
  376. /* Returns: */
  377. /* FLStatus : 0 on success, otherwise failure */
  378. /*----------------------------------------------------------------------*/
  379. FLStatus flRegisterI28F016(void)
  380. {
  381.   if (noOfMTDs >= MTDS)
  382.     return flTooManyComponents;
  383.   mtdTable[noOfMTDs++] = i28f016Identify;
  384.   return flOK;
  385. }
  386. #endif /* FALSE */