flflash.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:14k
源码类别:

VxWorks

开发平台:

C/C++

  1. /*
  2.  * $Log:   P:/user/amir/lite/vcs/flflash.c_v  $
  3.  *
  4.  *    Rev 1.14   08 Aug 2000 11:22:00   chackney
  5.  * Changed second arameter for ISRAM_WRITE to &flashPtr[0]
  6.  *
  7.  *    Rev 1.13   03 Nov 1997 16:11:32   danig
  8.  * amdCmdRoutine receives FlashPTR
  9.  *
  10.  *    Rev 1.12   10 Sep 1997 16:28:48   danig
  11.  * Got rid of generic names
  12.  *
  13.  *    Rev 1.11   04 Sep 1997 18:36:24   danig
  14.  * Debug messages
  15.  *
  16.  *    Rev 1.10   18 Aug 1997 11:46:26   danig
  17.  * MTDidentifyRoutine already defined in header file
  18.  *
  19.  *    Rev 1.9   28 Jul 1997 14:43:30   danig
  20.  * setPowerOnCallback
  21.  *
  22.  *    Rev 1.8   24 Jul 1997 17:54:28   amirban
  23.  * FAR to FAR0
  24.  *
  25.  *    Rev 1.7   07 Jul 1997 15:21:38   amirban
  26.  * Ver 2.0
  27.  *
  28.  *    Rev 1.6   08 Jun 1997 17:03:28   amirban
  29.  * power on callback
  30.  *
  31.  *    Rev 1.5   20 May 1997 13:53:34   danig
  32.  * Defined write/read mode
  33.  *
  34.  *    Rev 1.4   18 Aug 1996 13:47:24   amirban
  35.  * Comments
  36.  *
  37.  *    Rev 1.3   31 Jul 1996 14:30:36   amirban
  38.  * New flash.erase definition
  39.  *
  40.  *    Rev 1.2   04 Jul 1996 18:20:02   amirban
  41.  * New flag field
  42.  *
  43.  *    Rev 1.1   16 Jun 1996 14:02:20   amirban
  44.  * Corrected reset method in intelIdentify
  45.  *
  46.  *    Rev 1.0   20 Mar 1996 13:33:08   amirban
  47.  * Initial revision.
  48.  */
  49. /************************************************************************/
  50. /*                                                                      */
  51. /* FAT-FTL Lite Software Development Kit */
  52. /* Copyright (C) M-Systems Ltd. 1995-1996 */
  53. /* */
  54. /************************************************************************/
  55. #include "flflash.h"
  56. #define READ_ID 0x90
  57. #define INTEL_READ_ARRAY        0xff
  58. #define AMD_READ_ARRAY 0xf0
  59. #if FALSE
  60. /* MTD registration information */
  61. extern int noOfMTDs;
  62. extern MTDidentifyRoutine mtdTable[];
  63. #endif /* FALSE */
  64. /*----------------------------------------------------------------------*/
  65. /*                   f l a s h M a p */
  66. /* */
  67. /* Default flash map method: Map through socket window. */
  68. /* This method is applicable for all NOR Flash */
  69. /* */
  70. /* Parameters:                                                          */
  71. /* vol : Pointer identifying drive */
  72. /*      address : Card address to map */
  73. /* length : Length to map (irrelevant here) */
  74. /*                                                                      */
  75. /* Returns:                                                             */
  76. /* Pointer to required card address */
  77. /*----------------------------------------------------------------------*/
  78. static void FAR0 *flashMap(FLFlash vol, CardAddress address, int length)
  79. {
  80.   return flMap(vol.socket,address);
  81. }
  82. /*----------------------------------------------------------------------*/
  83. /*                   f l a s h R e a d */
  84. /* */
  85. /* Default flash read method: Read by copying from mapped address */
  86. /* */
  87. /* Parameters:                                                          */
  88. /* vol : Pointer identifying drive */
  89. /*      address : Card address to read */
  90. /* buffer : Area to read into */
  91. /* length : Length to read */
  92. /*                                                                      */
  93. /*----------------------------------------------------------------------*/
  94. static FLStatus flashRead(FLFlash vol,
  95. CardAddress address,
  96. void FAR1 *buffer,
  97. int length,
  98. int mode)
  99. {
  100.   tffscpy(buffer,vol.map(&vol,address,length),length);
  101.   return flOK;
  102. }
  103. /*----------------------------------------------------------------------*/
  104. /*                f l a s h N o W r i t e */
  105. /* */
  106. /* Default flash write method: Write not allowed (read-only mode) */
  107. /* */
  108. /* Parameters:                                                          */
  109. /* vol : Pointer identifying drive */
  110. /*      address : Card address to write */
  111. /* buffer : Area to write from */
  112. /* length : Length to write */
  113. /*                                                                      */
  114. /* Returns:                                                             */
  115. /* Write-protect error */
  116. /*----------------------------------------------------------------------*/
  117. static FLStatus flashNoWrite(FLFlash vol,
  118.    CardAddress address,
  119.    const void FAR1 *from,
  120.    int length,
  121.    int mode)
  122. {
  123.   return flWriteProtect;
  124. }
  125. /*----------------------------------------------------------------------*/
  126. /*                f l a s h N o E r a s e */
  127. /* */
  128. /* Default flash erase method: Erase not allowed (read-only mode) */
  129. /* */
  130. /* Parameters:                                                          */
  131. /* vol : Pointer identifying drive */
  132. /*      firstBlock : No. of first erase block */
  133. /* noOfBlocks : No. of contiguous blocks to erase */
  134. /*                                                                      */
  135. /* Returns:                                                             */
  136. /* Write-protect error */
  137. /*----------------------------------------------------------------------*/
  138. static FLStatus flashNoErase(FLFlash vol,
  139.    int firstBlock,
  140.    int noOfBlocks)
  141. {
  142.   return flWriteProtect;
  143. }
  144. /*----------------------------------------------------------------------*/
  145. /*                s e t N o C a l l b a c k */
  146. /* */
  147. /* Register power on callback routine. Default: no routine is  */
  148. /* registered. */
  149. /* */
  150. /* Parameters:                                                          */
  151. /* vol : Pointer identifying drive */
  152. /*                                                                      */
  153. /*----------------------------------------------------------------------*/
  154. static void setNoCallback(FLFlash vol)
  155. {
  156.   flSetPowerOnCallback(vol.socket,NULL,NULL);
  157. }
  158. /*----------------------------------------------------------------------*/
  159. /*                f l I n t e l I d e n t i f y */
  160. /* */
  161. /* Identify the Flash type and interleaving for Intel-style Flash. */
  162. /* Sets the value of vol.type (JEDEC id) & vol.interleaving.         */
  163. /* */
  164. /* Parameters:                                                          */
  165. /* vol : Pointer identifying drive */
  166. /* amdCmdRoutine : Routine to read-id AMD/Fujitsu style at */
  167. /*   a specific location. If null, Intel procedure */
  168. /*   is used.                                      */
  169. /*      idOffset : Chip offset to use for identification */
  170. /*                                                                      */
  171. /* Returns:                                                             */
  172. /* FLStatus : 0 = OK, otherwise failed (invalid Flash array)*/
  173. /*----------------------------------------------------------------------*/
  174. void flIntelIdentify(FLFlash vol,
  175.      void (*amdCmdRoutine)(FLFlash vol, CardAddress,
  176.    unsigned char, FlashPTR),
  177.      CardAddress idOffset)
  178. {
  179.   int inlv;
  180.   FlashPTR flashPtr;
  181.   unsigned char vendorId = 0;
  182.   unsigned char firstByte = 0;
  183.   unsigned char resetCmd = amdCmdRoutine ? AMD_READ_ARRAY : INTEL_READ_ARRAY;
  184.   flNeedVpp (vol.socket); /* ADDED, first thing to do */
  185.   flashPtr = (FlashPTR) flMap(vol.socket,idOffset);
  186.   for (inlv = 0; inlv < 15; inlv++) { /* Increase interleaving until failure */
  187.     flashPtr[inlv] = resetCmd; /* Reset the chip */
  188.     flashPtr[inlv] = resetCmd; /* Once again for luck */
  189.     if (inlv == 0)
  190.       firstByte = flashPtr[0];  /* Remember byte on 1st chip */
  191.     if (amdCmdRoutine) /* AMD: use unlock sequence */
  192.       amdCmdRoutine(&vol,idOffset + inlv, READ_ID, flashPtr);
  193.     else
  194.       flashPtr[inlv] = READ_ID; /* Read chip id */
  195.     flDelayLoop(2);  /* HOOK for VME-177 */
  196.     if (inlv == 0)
  197.       vendorId = flashPtr[0]; /* Assume first chip responded */
  198.     else if (flashPtr[inlv] != vendorId || firstByte != flashPtr[0]) {
  199.       /* All chips should respond in the same way. We know interleaving = n */
  200.       /* when writing to chip n affects chip 0.     */
  201.       /* Get full JEDEC id signature */
  202.       vol.type = (FlashType) ((vendorId << 8) | flashPtr[inlv]);
  203.       flashPtr[inlv] = resetCmd;
  204.       break;
  205.     }
  206.     flashPtr[inlv] = resetCmd;
  207.   }
  208.   if (inlv & (inlv - 1))
  209.     vol.type = NOT_FLASH; /* not a power of 2, no way ! */
  210.   else
  211.     vol.interleaving = inlv;
  212.   flDontNeedVpp (vol.socket); /* ADDED, last thing to do */
  213. }
  214. /*----------------------------------------------------------------------*/
  215. /*                   i n t e l S i z e */
  216. /* */
  217. /* Identify the card size for Intel-style Flash. */
  218. /* Sets the value of vol.noOfChips. */
  219. /* */
  220. /* Parameters:                                                          */
  221. /* vol : Pointer identifying drive */
  222. /* amdCmdRoutine : Routine to read-id AMD/Fujitsu style at */
  223. /*   a specific location. If null, Intel procedure */
  224. /*   is used.                                      */
  225. /*      idOffset : Chip offset to use for identification */
  226. /*                                                                      */
  227. /* Returns:                                                             */
  228. /* FLStatus : 0 = OK, otherwise failed (invalid Flash array)*/
  229. /*----------------------------------------------------------------------*/
  230. FLStatus flIntelSize(FLFlash vol,
  231.      void (*amdCmdRoutine)(FLFlash vol, CardAddress,
  232.    unsigned char, FlashPTR),
  233.      CardAddress idOffset)
  234. {
  235.   unsigned char resetCmd = amdCmdRoutine ? AMD_READ_ARRAY : INTEL_READ_ARRAY;
  236.   FlashPTR flashPtr;
  237.   flNeedVpp (vol.socket); /* ADDED, first thing to do */
  238.   flashPtr = (FlashPTR) vol.map(&vol,idOffset,0);
  239.   if (amdCmdRoutine) /* AMD: use unlock sequence */
  240.     amdCmdRoutine(&vol,0,READ_ID, flashPtr);
  241.   else
  242.     flashPtr[0] = READ_ID;
  243.   /* We leave the first chip in Read ID mode, so that we can */
  244.   /* discover an address wraparound. */
  245.   for (vol.noOfChips = 0; /* Scan the chips */
  246.        vol.noOfChips < 2000;  /* Big enough ? */
  247.        vol.noOfChips += vol.interleaving) {
  248.     int i;
  249.     flashPtr = (FlashPTR) vol.map(&vol,vol.noOfChips * vol.chipSize + idOffset,0);
  250.     /* Check for address wraparound to the first chip */
  251.     if (vol.noOfChips > 0 &&
  252. (FlashType) ((flashPtr[0] << 8) | flashPtr[vol.interleaving]) == vol.type)
  253.       goto noMoreChips;    /* wraparound */
  254.     /* Check if chip displays the same JEDEC id and interleaving */
  255.     for (i = (vol.noOfChips ? 0 : 1); i < vol.interleaving; i++) {
  256.       if (amdCmdRoutine) /* AMD: use unlock sequence */
  257. amdCmdRoutine(&vol,vol.noOfChips * vol.chipSize + idOffset + i,
  258.       READ_ID, flashPtr);
  259.       else
  260. flashPtr[i] = READ_ID;
  261.       if ((FlashType) ((flashPtr[i] << 8) | flashPtr[i + vol.interleaving]) !=
  262.   vol.type)
  263. goto noMoreChips;  /* This "chip" doesn't respond correctly, so we're done */
  264.       flashPtr[i] = resetCmd;
  265.     }
  266.   }
  267. noMoreChips:
  268.   flashPtr = (FlashPTR) vol.map(&vol,idOffset,0);
  269.   flashPtr[0] = resetCmd; /* reset the original chip */
  270.   flDontNeedVpp (vol.socket); /* ADDED, last thing to do */
  271.   return (vol.noOfChips == 0) ? flUnknownMedia : flOK;
  272. }
  273. /*----------------------------------------------------------------------*/
  274. /*                        i s R A M */
  275. /* */
  276. /* Checks if the card memory behaves like RAM */
  277. /* */
  278. /* Parameters:                                                          */
  279. /* vol : Pointer identifying drive */
  280. /*                                                                      */
  281. /* Returns:                                                             */
  282. /* 0 = not RAM-like, other = memory is apparently RAM */
  283. /*----------------------------------------------------------------------*/
  284. static FLBoolean isRAM(FLFlash vol)
  285. {
  286.   volatile unsigned int FAR0 * flashIPtr;
  287.   unsigned int firstInt;
  288.   unsigned int writeInt;
  289.   flNeedVpp (vol.socket); /* ADDED, first thing to do */
  290.   flashIPtr = (volatile unsigned int FAR0 *) flMap(vol.socket,0);
  291.   firstInt = flashIPtr[0];
  292.   writeInt = (firstInt != 0x0) ? 0x0 : (unsigned int) -1;
  293.   ISRAM_WRITE(writeInt, &flashIPtr[0]); /* write something else safe */
  294.   flDelayLoop(2);  /* HOOK for VME-177 */
  295.   if (flashIPtr[0] == writeInt) { /* Was it written ? */
  296.     flashIPtr[0] = firstInt; /* must be RAM, undo the damage */
  297.     flDontNeedVpp (vol.socket); /* ADDED, last thing to do */
  298. #ifdef DEBUG_PRINT
  299.   DEBUG_PRINT("Debug: error, socket window looks like RAM.n");
  300. #endif
  301.     return TRUE;
  302.   }
  303.   flDontNeedVpp (vol.socket); /* ADDED, last thing to do */
  304.   return FALSE;
  305. }
  306. /*----------------------------------------------------------------------*/
  307. /*               f l I d e n t i f y F l a s h */
  308. /* */
  309. /* Identify the current Flash medium and select an MTD for it */
  310. /* */
  311. /* Parameters:                                                          */
  312. /* socket : Socket of flash */
  313. /* vol : New volume pointer */
  314. /*                                                                      */
  315. /* Returns:                                                             */
  316. /* FLStatus : 0 = Flash was identified */
  317. /*   other = identification failed                 */
  318. /*----------------------------------------------------------------------*/
  319. FLStatus flIdentifyFlash(FLSocket *socket, FLFlash vol)
  320. {
  321.   FLStatus status = flUnknownMedia;
  322.   int iMTD;
  323.   vol.socket = socket;
  324. #ifndef FIXED_MEDIA
  325.   /* Check that we have a media */
  326.   flResetCardChanged(vol.socket); /* we're mounting anyway */
  327.   checkStatus(flMediaCheck(vol.socket));
  328. #endif
  329.   if (isRAM(&vol))
  330.     return flUnknownMedia; /* if it looks like RAM, leave immediately */
  331.   /* Install default methods */
  332.   vol.type = NOT_FLASH;
  333.   vol.flags = 0;
  334.   vol.map = flashMap;
  335.   vol.read = flashRead;
  336.   vol.write = flashNoWrite;
  337.   vol.erase = flashNoErase;
  338.   vol.setPowerOnCallback = setNoCallback;
  339.   /* Attempt all MTD's */
  340.   for (iMTD = 0; iMTD < noOfMTDs && status != flOK; iMTD++)
  341.     status = mtdTable[iMTD](&vol);
  342.   if (status != flOK) { /* No MTD recognition */
  343.     /* Setup arbitrary parameters for read-only mount */
  344.     vol.chipSize = 0x100000L;
  345.     vol.erasableBlockSize = 0x1000;
  346.     vol.noOfChips = 1;
  347.     vol.interleaving = 1;
  348.   #ifdef DEBUG_PRINT
  349.     DEBUG_PRINT("Debug: did not identify flash media.n");
  350.   #endif
  351.     return flUnknownMedia;
  352.   }
  353.   return flOK;
  354. }