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

VxWorks

开发平台:

C/C++

  1. /* flashMem.c - Flash memory device driver */
  2. /* Copyright 1984-2000 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01o,15feb01,frf  merged latest contribution, added support for
  8.                  28F128J3A, 28F320J3A, 28F640J3A and 29LV040B.
  9. 01n,23mar00,zl   added support for 29LV160B/T. added sysSectorErase().
  10. 01m,01feb00,jpd  added support for 28F320. SPR 31293
  11. 01l,09sep98,jpd  added support for 28F016SV; minor doc fixes.
  12. 01k,20apr98,jpd  moved back into main source tree from local copy in BSPs.
  13. 01j,24mar98,jpd  added support for 29LV1024 and 29C040A.
  14. 01i,04jul97,jpd  added support for 28F008 device, made overlay buffer dynamic.
  15. 01h,25jun96,map  added documentation, and some clean up.
  16. 01g,02apr96,tam  cast FLASH_ADRS and FLASH_SIZE to UINT32 to get rid off
  17.                  a compiler warning.
  18. 01f,12feb96,kkk  made 1st param of sysFlashDataPoll() volatile to confirm
  19.                  to dzb's change.
  20. 01e,26jan96,dzb  added volatile to register pointers.
  21.            +jpb  changed delay parameters to be globals if not defined.
  22. 01d,24feb94,dzb  added sysFlashWrite{En,Dis}able(), sysFlashBoardDelay().
  23. 01c,15feb94,dzb  added SYS_FLASH_DELAY_SHIFT macro.
  24. 01b,07jan94,dzb  added support for 29F0X0 flash devices.
  25.                  cut ties to NVRAM macros.  added support for FLASH_WIDTH.
  26. 01a,05oct93,dzb  derived from version 1b of mem/iFlashMem.c.
  27. */
  28. /*
  29. DESCRIPTION
  30. This library contains routines to manipulate flash memory.  Read and write
  31. routines are included.
  32. The macro values FLASH_ADRS, FLASH_SIZE, and FLASH_WIDTH must be defined to
  33. indicate the address, size (in bytes), and the data-access width (in bytes) of
  34. the flash memory.
  35. If the flash memory needs to be overlaid, and the section of the memory that
  36. needs to be overlaid is less than FLASH_SIZE, then, for efficiency, define
  37. FLASH_SIZE_WRITABLE to the size (in bytes) of the overlay section.
  38. The routine sysFlashDelay() creates a delay for a specified number of
  39. microseconds.  The timing loop can be adjusted on a board-dependent basis by
  40. defining the function sysFlashBoardDelay and values for the following macros,
  41. .iP
  42. SYS_FLASH_DELAY_SHIFT
  43. .iP
  44. SYS_FLASH_DELAY_ADJ
  45. .iP
  46. SYS_FLASH_DELAY_INCR
  47. .LP
  48. To use the routine sysFlashBoardDelay(), the macro SYS_FLASH_BOARD_DELAY
  49. should be defined.
  50. The macro FLASH_NO_OVERLAY should be defined when calls to sysFlashSet()
  51. are expected to erase the flash and reprogram it with only the new data.
  52. The macro SYS_FLASH_TYPE should be defined for flash devices that cannot be
  53. auto-selected. This macro should be set to a flash device code defined in the
  54. header files, <drv/mem/flash28.h> and <drv/mem/flash29.h>
  55. To support flash devices that that need to turn on/off write protect features
  56. (special programming voltages or other write-enable features), the macro
  57. SYS_FLASH_WRITE, and the routines, sysFlashWriteEnable() and
  58. sysFlashFlashWriteDisable() should be defined.
  59. INTERNAL:
  60. The FLASH_SIZE_WRITABLE concept doesn't work very well.  It just limits the
  61. amount of flash that is writable, so why bother.  What it was really
  62. intended to address was flash that is only block writable, i.e. you
  63. can only write a complete block at a time.  To properly handle block
  64. memory, you must copy the old block of memory to a buffer, update the
  65. part of the buffer that is to be changed, and then write back the
  66. complete buffer in a single write operation.
  67. The accesses to non-volatile memory, and flash control registers needs
  68. to be abstracted.  Macros should be used for all actual i/o operations.
  69. */
  70. #include "drv/mem/flashDev.h"
  71. #include "drv/mem/flash28.h"
  72. #include "drv/mem/flash29.h"
  73. /* defines */
  74. /* Establish default values for DELAY parameters */
  75. #ifndef SYS_FLASH_DELAY_SHIFT
  76. #   define SYS_FLASH_DELAY_SHIFT 0
  77. #endif /*SYS_FLASH_DELAY_SHIFT*/
  78. #ifndef SYS_FLASH_DELAY_ADJ
  79. #   define SYS_FLASH_DELAY_ADJ 0
  80. #endif /* SYS_FLASH_DELAY_ADJ */
  81. #ifndef SYS_FLASH_DELAY_INCR
  82. #   define SYS_FLASH_DELAY_INCR 1
  83. #endif /* SYS_FLASH_DELAY_INCR */
  84. /* Names of routines, or null values */
  85. #ifdef SYS_FLASH_WRITE
  86. #   define SYS_FLASH_WRITE_ENABLE_RTN() sysFlashWriteEnable ()
  87. #   define SYS_FLASH_WRITE_DISABLE_RTN() sysFlashWriteDisable ()
  88. #else
  89. #   define SYS_FLASH_WRITE_ENABLE_RTN()
  90. #   define SYS_FLASH_WRITE_DISABLE_RTN()
  91. #endif /* SYS_FLASH_WRITE */
  92. #ifdef SYS_FLASH_BOARD_DELAY
  93. #   define SYS_FLASH_BOARD_DELAY_RTN() sysFlashBoardDelay ()
  94. #else
  95. #   define SYS_FLASH_BOARD_DELAY_RTN()
  96. #endif /* SYS_FLASH_BOARD_DELAY */
  97. #ifdef SYS_FLASH_TYPE
  98. #   define FLASH_MEM_TYPE SYS_FLASH_TYPE
  99. #else
  100. #   define FLASH_MEM_TYPE 0
  101. #endif /* SYS_FLASH_TYPE */
  102. #ifdef FLASH_SIZE_WRITEABLE
  103. #   define FLASH_MEM_SIZE FLASH_SIZE_WRITEABLE
  104. #else
  105. #   define FLASH_MEM_SIZE FLASH_SIZE
  106. #endif /* FLASH_SIZE_WRITEABLE */
  107. /* Operation status bits for Flash 29Fxxx devices */
  108. #define Q7(ix) ((ix & 0x80) >> 7) /* DQ7 bit */
  109. #define Q5(ix) ((ix & 0x20) >> 5) /* DQ5 bit */
  110. /* globals */
  111. IMPORT void sysFlashWriteEnable (void);
  112. IMPORT void sysFlashWriteDisable (void);
  113. IMPORT void sysFlashBoardDelay (void);
  114. int flashDelayShift = SYS_FLASH_DELAY_SHIFT;
  115. int flashDelayAdj = SYS_FLASH_DELAY_ADJ;
  116. int flashDelayIncr = SYS_FLASH_DELAY_INCR;
  117. static UINT8 flashType = FLASH_MEM_TYPE;
  118. /* forward declarations */
  119. void sysFlashDelay (int delayCount);
  120. STATUS sysFlashDataPoll (volatile FLASH_DEF * pFA, FLASH_DEF value);
  121. STATUS sysFlashWrite (FLASH_DEF * pFB, int size, int offset,
  122.                        UINT8 flashType, FLASH_DEF value);
  123. STATUS sysFlashUnlock ( FLASH_DEF * pFA,  UINT8 flashType);
  124. STATUS sysFlashLock(FLASH_DEF * pFA, UINT8 flashType);
  125. UINT8 sysFlashTypeGet (void);
  126. STATUS sysFlashNextBlock(UINT32 * flash_offset);
  127. /******************************************************************************
  128. *
  129. * sysFlashGet - get the contents of flash memory
  130. *
  131. * This routine copies the contents of flash memory into a specified
  132. * string.  The string is terminated with an EOS.
  133. *
  134. * RETURNS: OK, or ERROR if access is outside the flash memory range.
  135. *
  136. * SEE ALSO: sysFlashSet()
  137. *
  138. * INTERNAL
  139. * If multiple tasks are calling sysFlashSet() and sysFlashGet(),
  140. * they should use a semaphore to ensure mutually exclusive access.
  141. */
  142. STATUS sysFlashGet
  143.     (
  144.     char * string, /* where to copy flash memory      */
  145.     int strLen, /* maximum number of bytes to copy */
  146.     int offset /* byte offset into flash memory   */
  147.     )
  148.     {
  149.     if ((offset < 0) || (strLen < 0) || ((offset + strLen) > (FLASH_ADRS + FLASH_SIZE)))
  150.         return (ERROR);
  151.     bcopyBytes ((char *) (offset), string, strLen);
  152.     string [strLen] = EOS;
  153.     return (OK);
  154.     }
  155. /******************************************************************************
  156. *
  157. * sysFlashDelay - create a delay for a specified number of microseconds
  158. *
  159. * This routine implements a busy wait for a specified number of microseconds.
  160. * The timing loop can be adjusted on a board-dependent basis by
  161. * defining values for the following macros:
  162. * .iP
  163. * SYS_FLASH_DELAY_SHIFT
  164. * .iP
  165. * SYS_FLASH_DELAY_ADJ
  166. * .iP
  167. * SYS_FLASH_DELAY_INCR
  168. * .LP
  169. * The values SYS_FLASH_DELAY_SHIFT and SYS_FLASH_DELAY_ADJ
  170. * convert microseconds into a board-dependent tick-count.
  171. * This routine can call a user-defined hook, sysFlashBoardDelay(),
  172. * which creates a delay for a number of board-dependent ticks as
  173. * specified by SYS_FLASH_DELAY_INCR.  To use sysFlashBoardDelay(), define
  174. * SYS_FLASH_BOARD_DELAY in config.h.
  175. *
  176. * RETURNS: N/A
  177. *
  178. * SEE ALSO: sysFlashErase(), sysFlashWrite()
  179. */
  180. void sysFlashDelay
  181.     (
  182.     int delayCount /* number of uSec to delay */
  183.     )
  184.     {
  185.     int ix;
  186.     delayCount <<= flashDelayShift; /* board-dependent shift */
  187.     delayCount += flashDelayAdj; /* board-dependent addition */
  188.     for (ix = 0; ix < delayCount; ix += flashDelayIncr)
  189.         SYS_FLASH_BOARD_DELAY_RTN ();
  190.     }
  191. /******************************************************************************
  192. *
  193. * sysFlashDataPoll - wait for a flash device operation to complete
  194. *
  195. * This routine polls a specified address on a 29Ff2xxxf1 flash device
  196. * until the device operation at that location completes or times out.
  197. *
  198. * While a flash operation is in progress, a read on the device
  199. * returns on Q7 (data bit 7) the complement of the previous value of Q7.  Once
  200. * the flash operation has completed, the Q7 bit returns the true data
  201. * of the last write. Subsequent reads return the correct data in Q0-7.
  202. *
  203. * The Q5 bit implements a timeout functionality.  When a currently
  204. * executing flash operation exceeds specified limits, the Q5 bit is set (to 1).
  205. *
  206. * RETURNS: OK, or ERROR if the timeout (!Q5) occurs before the device operation
  207. * completes.
  208. *
  209. * SEE ALSO: sysFlashErase(), sysFlashWrite()
  210. */
  211. STATUS sysFlashDataPoll
  212.     (
  213.     volatile FLASH_DEF * pFA, /* programmed address to poll */
  214.     FLASH_DEF value /* data programmed to poll address */
  215.     )
  216.     {
  217.     STATUS retVal = OK;
  218.     volatile FLASH_POLL_DEF * pTest = (FLASH_POLL_DEF *) pFA;
  219.     volatile FLASH_POLL_DEF * pVal  = (FLASH_POLL_DEF *) &value;
  220.     int ix; /* byte counter */
  221.     int vBit; /* programmed value of DQ7 */
  222.     for (ix = (FLASH_WIDTH/FLASH_CHIP_WIDTH - 1); (ix >= 0 ) && (retVal == OK); 
  223.             ix--, pTest++, pVal++)
  224.         {
  225.         vBit = Q7(*pVal);
  226.         while (Q7(*pTest) != vBit)
  227.             if (Q5(*pTest) == 1) /* timeout ? */
  228.                 break;
  229.         if (Q7(*pTest) != vBit) /* check Q7 & Q5 race */
  230.             retVal = ERROR;
  231.         }
  232.     return (retVal);
  233.     }
  234. /******************************************************************************
  235. *
  236. * sysFlashErase - erase the contents of a sector
  237. *
  238. * This routine clears the contents of one sector in the flash memory.
  239. *
  240. * Flash 29Ff2xxxf1 devices are erased by writing the six-byte erase code
  241. * into specific address locations, which sets all byte locations to a high
  242. * value (0xFF).
  243. *
  244. * RETURNS: OK, or ERROR if the contents of sector cannot be erased.
  245. */
  246. STATUS sysFlashErase
  247.     (
  248.     FLASH_DEF * pFA, /* Sector start address */
  249.     UINT8 flashType /* type of flash memory on-board */
  250.     )
  251.     {
  252.     STATUS retVal = OK;
  253.     switch (flashType)
  254.         {
  255. case (FLASH_28F640J3A):
  256. case (FLASH_28F320J3A):
  257. case (FLASH_28F128J3A):
  258.     SYS_FLASH_WRITE_ENABLE_RTN (); /* raise Vpp */
  259.             *pFA = FLASH28_CMD_ERASE_SETUP; /* setup */
  260.             *pFA = FLASH28F008_CMD_ERASE; /* erase */
  261.     /* Check Write State Machine Status */
  262.     do
  263.       {
  264.       } while ((*pFA & FLASH28F008_STAT_WSMS) != FLASH28F008_STAT_WSMS);
  265.     /* Check Erase Error Status */
  266.            if (*pFA & (BIT(5) | BIT(4) | BIT(3) | BIT(1)))
  267. {
  268. *pFA = FLASH28F008_CMD_CLEAR_STATUS;
  269. retVal = ERROR;
  270. }
  271.             *pFA = FLASH28_CMD_RESET;
  272.     SYS_FLASH_WRITE_DISABLE_RTN (); /* lower Vpp */
  273.             break;
  274.         case (FLASH_29LV160T):
  275.         case (FLASH_29LV160B):
  276. case (FLASH_29LV040B):    
  277.     SYS_FLASH_WRITE_ENABLE_RTN (); /* enable write */
  278.             *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_FIRST;
  279.             *(FLASH_CAST FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;
  280.             *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_CHIP_ERASE;
  281.             *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_FOURTH;
  282.             *(FLASH_CAST FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_FIFTH;
  283.             *pFA       = FLASH29_CMD_SECTOR;
  284.             do {
  285.                 retVal = sysFlashDataPoll (pFA, (FLASH_DEF) 0xffffffff);
  286.                 } while ((*pFA != (FLASH_DEF) 0xffffffff) && (retVal == OK));
  287.     SYS_FLASH_WRITE_DISABLE_RTN (); /* disable write */
  288.     break;
  289.         default:
  290.             retVal = ERROR;
  291.         }
  292.     return (retVal);
  293.     }
  294. /******************************************************************************
  295. *
  296. * sysFlashWrite - write data to flash memory
  297. *
  298. * This routine copies specified data of a specified length, <size>, into a
  299. * specified offset, <offset>, in the flash memory.  Data is passed as a string,
  300. * <pFB>, if not NULL.  If NULL, data is taken as a repeated sequence of
  301. * <value>.
  302. * The parameter <flashType> should be set to the flash device code.
  303. * The parameter <offset> must be appropriately aligned for the width of
  304. * the Flash devices in use.
  305. *
  306. * Flash 28Ff2xxxf1 devices are programmed by a sequence of operations:
  307. * .iP
  308. * set up device to write
  309. * .iP
  310. * perform write
  311. * .iP
  312. * verify the write
  313. * .LP
  314. *
  315. * Flash 29Ff2xxxf1 devices are programmed by a sequence of operations:
  316. * .iP
  317. * set up device to write
  318. * .iP
  319. * perform write
  320. * .iP
  321. * wait for the write to complete
  322. * .LP
  323. *
  324. * RETURNS: OK, or ERROR if the write operation fails.
  325. *
  326. * SEE ALSO: sysFlashSet()
  327. */
  328. STATUS sysFlashWrite
  329.     (
  330.     FLASH_DEF * pFB, /* string to be copied; use <value> if NULL */
  331.     int size, /* size to program in bytes */
  332.     int offset, /* byte offset into flash memory */
  333.     UINT8 flashType, /* type of flash memory on-board */
  334.     FLASH_DEF value /* value to program */
  335.     )
  336.     {
  337.     volatile FLASH_DEF * pFA; /* flash address */
  338.     STATUS retVal = OK;
  339.     int ix;
  340.     int sectorSize = 128;
  341.     int twc = 2; /* time for write completion */
  342.     switch (flashType)
  343.         {
  344. case (FLASH_28F008):
  345. case (FLASH_28F016):
  346. case (FLASH_28F160):
  347. case (FLASH_28F320):
  348.     SYS_FLASH_WRITE_ENABLE_RTN (); /* raise Vpp */
  349.             for (pFA = FLASH_CAST (offset); (pFA < FLASH_CAST
  350.                 (size + offset)) && (retVal == OK); pFA++)
  351. {
  352. if (pFB != NULL)
  353.     value = *pFB++;
  354. *pFA = FLASH28_CMD_PROG_SETUP; /* write setup */
  355. *pFA = value; /* data to write */
  356. /* Check Write State Machine Status */
  357. do
  358.     {
  359.     *pFA = FLASH28F008_CMD_READ_STATUS;
  360.     }
  361. while ((*pFA & FLASH28F008_STAT_WSMS) != FLASH28F008_STAT_WSMS);
  362. /* Check Byte Write Error Status */
  363. if (*pFA & (BIT(5) | BIT(4) | BIT(3) | BIT(1)))
  364.     {
  365.     *pFA = FLASH28F008_CMD_CLEAR_STATUS;
  366.     retVal = ERROR;
  367.     }
  368. }
  369.             *pFA = FLASH28_CMD_RESET;
  370.     SYS_FLASH_WRITE_DISABLE_RTN (); /* lower Vpp */
  371.             break;
  372. case (FLASH_28F320J3A):     
  373. case (FLASH_28F640J3A):     
  374. case (FLASH_28F128J3A):
  375.      SYS_FLASH_WRITE_ENABLE_RTN (); /* raise Vpp */
  376.      for ( pFA = FLASH_CAST (offset);
  377.    (pFA <FLASH_CAST (size + offset)) &&
  378.        (retVal == OK);
  379.    pFA++)
  380.        {
  381.        if (pFB != NULL)
  382.  value = *pFB++;
  383.        *pFA = FLASH28_CMD_PROG_SETUP; /* write setup */
  384.        *pFA = value; /* data to write */
  385.        /* Check Write State Machine Status */
  386.        do
  387.  {
  388.  }
  389.        while ((*pFA & FLASH28F008_STAT_WSMS) != FLASH28F008_STAT_WSMS);
  390.        /* Check Byte Write Error Status */
  391.        
  392.            if (*pFA & (BIT(5) | BIT(4) | BIT(3) | BIT(1)))
  393.    {
  394.    *pFA = FLASH28F008_CMD_CLEAR_STATUS;
  395.    retVal = ERROR;
  396.     }
  397.        *pFA = FLASH28_CMD_RESET;
  398.        }
  399.      SYS_FLASH_WRITE_DISABLE_RTN (); /* lower Vpp */
  400.      break;
  401.         case (FLASH_28F256):
  402.         case (FLASH_28F512):
  403.         case (FLASH_28F010):
  404.         case (FLASH_28F020):
  405.             {
  406.     SYS_FLASH_WRITE_ENABLE_RTN (); /* raise Vpp */
  407.             for (pFA = FLASH_CAST (offset); (pFA < FLASH_CAST
  408.                 (size + offset)) && (retVal == OK); pFA++)
  409.         for (ix = 0; TRUE; ix++)
  410.             {
  411.     if (pFB != NULL)
  412. value = *pFB++;
  413.             *pFA = FLASH28_CMD_PROG_SETUP; /* write setup */
  414.             *pFA = value; /* data to write */
  415.             sysFlashDelay (10); /* wait for write */
  416.             *pFA = FLASH28_CMD_PROG_VERIFY; /* verify command */
  417.             sysFlashDelay (6); /* wait for verify */
  418.             if (*pFA == value) /* done? */
  419.         break;
  420.             if (ix == 25) /* error? */
  421. {
  422.                 retVal = ERROR;
  423. break;
  424. }
  425.             }
  426.             *pFA = FLASH28_CMD_RESET;
  427.             *pFA = FLASH28_CMD_READ_MEM;
  428.     sysFlashDelay (6);
  429.     SYS_FLASH_WRITE_DISABLE_RTN (); /* lower Vpp */
  430.             break;
  431.             }
  432.         case (FLASH_29F010):
  433.         case (FLASH_29LV160T):
  434.         case (FLASH_29LV160B):
  435. case (FLASH_29LV040B):
  436.             {
  437.     SYS_FLASH_WRITE_ENABLE_RTN (); /* enable write */
  438.             for (pFA = FLASH_CAST (offset); pFA < FLASH_CAST
  439.                 (size + offset) && (retVal == OK); pFA++)
  440.                 {
  441.                 *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_FIRST;
  442.                 *(FLASH_CAST FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;
  443.                 *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_PROGRAM;
  444. if (pFB != NULL)
  445.     value = *pFB++;
  446.                 *pFA = value;                     /* data to write */
  447.                 do {
  448.                     retVal = sysFlashDataPoll (pFA, (FLASH_DEF) value);
  449.                     } while ((*pFA != value) && (retVal == OK));
  450.                 }
  451.             *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_FIRST;
  452.             *(FLASH_CAST FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;
  453.             *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_READ_RESET;
  454.     SYS_FLASH_WRITE_DISABLE_RTN (); /* disable write */
  455.             break;
  456.             }
  457. case (FLASH_29C040A):
  458.     sectorSize = 256;
  459.     twc = 1;
  460.     /* FALL THROUGH */
  461.         case (FLASH_29LV1024):
  462.             {
  463.             for (pFA = FLASH_CAST (offset);
  464.  pFA < FLASH_CAST (size + offset); )
  465.                 {
  466. /* Enable sector write */
  467. *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_FIRST;
  468. *(FLASH_CAST FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;
  469. *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_PROGRAM;
  470. /*
  471.  * write the sector:
  472.  *    29LV1024: 128 half-word accesses = 256 bytes
  473.  *    29C040A 256 byte accesses
  474.  */
  475. for (ix = 0; ix < sectorSize; ix++)
  476.     {
  477.     if (pFB != NULL)
  478. value = *pFB++;
  479.     /* ensure entire sector written */
  480.     if (pFA >= FLASH_CAST (size + offset))
  481. value = (FLASH_DEF) 0xFFFFFFFF;
  482.     *pFA++ = value;                     /* data to write */
  483.     }
  484. /*
  485.  * Ensure write cycle completes. Atmel chip spec suggest
  486.  * waiting for a specified time rather than polling for
  487.  * completion.
  488.  *
  489.  * It seems that we cannot always safely use taskDelay()
  490.  */
  491. sysFlashDelay (10000 * twc);
  492.                 }
  493.             break;
  494.             }
  495.         default:
  496.             retVal = ERROR;
  497.         }
  498.     return (retVal);
  499.     }
  500. /******************************************************************************
  501. *
  502. * sysFlashTypeGet - determine the device type of on-board flash memory
  503. *
  504. * This routine uses the `autoselect' command to determine the device type of
  505. * on-board flash memory for flash 29Ff2xxxf1 devices.
  506. *
  507. * RETURNS: An integer indicating the device type of on-board flash memory.
  508. */
  509. UINT8 sysFlashTypeGet (void)
  510.     {
  511.     volatile FLASH_DEF * pFA = FLASH_CAST (FLASH_ADRS); /* flash address */
  512.     UINT8 retVal;
  513.     SYS_FLASH_WRITE_ENABLE_RTN (); /* enable writes */
  514.     *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_FIRST;
  515.     *(FLASH_CAST FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;
  516.     *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_AUTOSELECT;
  517.     /* 29LV1024 (at least) requires 20ms delay */
  518.     /* It seems we cannot always safely use taskDelay() */
  519.     sysFlashDelay (20000);
  520.     retVal = (UINT8) *++pFA;
  521.     *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_FIRST;
  522.     *(FLASH_CAST FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;
  523.     *(FLASH_CAST FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_READ_RESET;
  524.     sysFlashDelay (20000);
  525.     SYS_FLASH_WRITE_DISABLE_RTN (); /* disable writes */
  526.     return (retVal);
  527.     }
  528. /******************************************************************************
  529. *
  530. * sysFlashSet - write to flash memory
  531. *
  532. * This routine copies a specified string into flash memory after calling
  533. * sysFlashErase() and clearing flash memory.
  534. *
  535. * If FLASH_NO_OVERLAY is defined, the parameter <offset> must be
  536. * appropriately aligned for the Flash devices in use (device width,
  537. * sector size etc.).
  538. *
  539. * If the specified string must be overlaid on the contents of flash memory,
  540. * undefine FLASH_NO_OVERLAY.
  541. *
  542. * RETURNS: OK, or ERROR if the write fails or the input parameters are
  543. * out of range.
  544. *
  545. * SEE ALSO: sysFlashErase(), sysFlashGet(), sysFlashTypeGet(), sysFlashWrite()
  546. *
  547. * INTERNAL
  548. * If multiple tasks are calling sysFlashSet() and sysFlashGet(),
  549. * they should use a semaphore to ensure mutually exclusive access to flash
  550. * memory.
  551. */
  552. STATUS sysFlashSet
  553.     (
  554.     char * string, /* string to be copied into flash memory */
  555.     int strLen, /* maximum number of bytes to copy       */
  556.     int segment, /* segment base of flash*/
  557.     int offset /* byte offset into segment   */
  558.     )
  559.     {
  560.     char *tempBuffer;
  561.     if ((offset < 0) || (strLen < 0) || (segment < 0) || ((offset + strLen) > FLASH_SEGMENT_SIZE))
  562.         return (ERROR);
  563.     /* see if contents are actually changing */
  564.     if (bcmp ((char *) (segment + offset), string, strLen) == 0)
  565. return (OK);
  566.     /* first read existing data */
  567.     if (tempBuffer = malloc(FLASH_SEGMENT_SIZE), tempBuffer == 0)
  568. return (ERROR);
  569.     bcopyBytes ((char *) (segment), tempBuffer, FLASH_SEGMENT_SIZE);
  570.     bcopyBytes (string, (tempBuffer + offset), strLen);
  571.     if (flashType == 0)
  572. flashType = sysFlashTypeGet ();
  573.     switch (flashType)
  574.     {
  575.         case (FLASH_28F640J3A):
  576.         case (FLASH_28F320J3A):
  577. case (FLASH_28F128J3A):
  578.            /* unlock the sector*/
  579.            if (sysFlashUnlock(FLASH_CAST (segment), flashType) == ERROR)
  580.            {
  581. free (tempBuffer);
  582.                return (ERROR);
  583.            }
  584.    
  585.     /* erase the sector */
  586.     if (sysFlashErase (FLASH_CAST (segment), flashType) == ERROR)
  587. {
  588. free (tempBuffer);
  589. return (ERROR);
  590. }
  591.     break;
  592.     
  593. case FLASH_29C040A:
  594.         case FLASH_29LV1024:
  595.     /* do not erase these as not required */
  596.     break;
  597. case (FLASH_29LV160T):
  598. case (FLASH_29LV160B):
  599.         case (FLASH_29LV040B):
  600.     /* erase the sector */
  601.     if (sysFlashErase (FLASH_CAST (segment), flashType) == ERROR)
  602. {
  603. free (tempBuffer);
  604. return (ERROR);
  605. }
  606.     break;
  607. default:
  608. free (tempBuffer);
  609. return (ERROR);
  610.     break;
  611.     } /* endswitch */
  612.     if (sysFlashWrite (FLASH_CAST (tempBuffer), FLASH_SEGMENT_SIZE, segment, flashType, 0)
  613.     == ERROR)
  614.     {
  615. free (tempBuffer);
  616.        return (ERROR);
  617.     }
  618.     return OK;
  619. }
  620. /******************************************************************************
  621. *
  622. * sysSectorUnlock - unlock the flash memory
  623. *
  624. * This routine unlock the contents of flash memory.
  625. *
  626. *
  627. * RETURNS: OK, or ERROR if the contents of flash memory cannot be unlocked.
  628. */
  629. STATUS sysFlashUnlock
  630.     (
  631.     FLASH_DEF * pFA, /* Sector start address */
  632.     UINT8 flashType /* type of flash memory on-board */
  633.     )
  634.     {
  635.     STATUS retVal = OK;
  636.     switch (flashType)
  637.         {
  638. case (FLASH_28F640J3A):
  639. case (FLASH_28F320J3A):
  640. case (FLASH_28F128J3A):
  641.     SYS_FLASH_WRITE_ENABLE_RTN (); /* raise Vpp */
  642.     *pFA = FLASH28_CMD_LOCKSETUP; /* setup */
  643.     *pFA = FLASH28_CMD_UNLOCK; /* erase */
  644.     /* Check Write State Machine Status */
  645.     do
  646.       {
  647.       } while ((*pFA & FLASH28F008_STAT_WSMS) != FLASH28F008_STAT_WSMS);
  648.     /* Check Erase Error Status */
  649.            if (*pFA & (BIT(5) | BIT(4) | BIT(3) | BIT(1)))
  650. {
  651. *pFA = FLASH28F008_CMD_CLEAR_STATUS;
  652. retVal = ERROR;
  653. }
  654.             *pFA = FLASH28_CMD_RESET;
  655.     SYS_FLASH_WRITE_DISABLE_RTN (); /* lower Vpp */
  656.             break;
  657.         default:
  658.             retVal = ERROR;
  659.         }
  660.     return (retVal);
  661.     }
  662. /******************************************************************************
  663. *
  664. * sysFlashLock - lock the flash memory
  665. *
  666. * This routine lock the contents of flash memory.
  667. *
  668. *
  669. * RETURNS: OK, or ERROR if the contents of flash memory cannot be locked.
  670. */
  671. STATUS sysFlashLock
  672.     (
  673.     FLASH_DEF * pFA, /* Sector start address */
  674.     UINT8 flashType /* type of flash memory on-board */
  675.     )
  676.     {
  677.     STATUS retVal = OK;
  678.     switch (flashType)
  679.         {
  680. case (FLASH_28F640J3A):
  681. case (FLASH_28F320J3A):
  682. case (FLASH_28F128J3A):
  683.     SYS_FLASH_WRITE_ENABLE_RTN (); /* raise Vpp */
  684.     *pFA = FLASH28_CMD_LOCKSETUP; /* setup */
  685.     *pFA = FLASH28_CMD_LOCK; /* erase */
  686.     /* Check Write State Machine Status */
  687.     do
  688.       {
  689.       } while ((*pFA & FLASH28F008_STAT_WSMS) != FLASH28F008_STAT_WSMS);
  690.     /* Check Erase Error Status */
  691.            if (*pFA & (BIT(5) | BIT(4) | BIT(3) | BIT(1)))
  692. {
  693. *pFA = FLASH28F008_CMD_CLEAR_STATUS;
  694. retVal = ERROR;
  695. }
  696.             *pFA = FLASH28_CMD_RESET;
  697.     SYS_FLASH_WRITE_DISABLE_RTN (); /* lower Vpp */
  698.             break;
  699.         default:
  700.             retVal = ERROR;
  701.         }
  702.     return (retVal);
  703.     }
  704. /******************************************************************************
  705. *
  706. * flashNextBlock - Advance a pointer to the next flash block
  707. *
  708. * This routine advances a pointer to the start of the next flash block
  709. * for a multi-block device.
  710. * RETURNS: OK, or ERROR if the device type is unknown
  711. */
  712. STATUS sysFlashNextBlock
  713.     (
  714.     UINT32 *flash_offset      /* Offset into flash memory */
  715.     )
  716.     {
  717.     STATUS retVal = OK;
  718.     UINT32 blockSize;
  719.     UINT32 flashSize;
  720.     if (flashType == 0)
  721.         flashType = sysFlashTypeGet();
  722.     switch (flashType)
  723.         {
  724.         case (FLASH_28F128J3A):
  725.             flashSize = 16 * 1024*1024;
  726.             break;
  727.         default:
  728.             return ERROR;
  729.         }
  730.     switch (flashType)
  731.         {
  732.         case (FLASH_28F128J3A):
  733. blockSize = 128 * 1024;
  734.               *flash_offset = (*flash_offset + blockSize) & ~(blockSize-1);
  735.         default:
  736.               return ERROR;
  737.         }
  738.     return (retVal);
  739.     }
  740. /*******************************************************************************
  741. *
  742. * programFlash - Program the flash from a buffer
  743. *
  744. * This routine updates the flash with the contents of a buffer, optionally
  745. * skipping the block containing the NVRam value. It displays a status
  746. * update during the programming process.
  747. *
  748. * RETURNS: ERROR or OK
  749. */
  750. STATUS programFlash(UINT8* buf,
  751.                            UINT32 flashStart, UINT32 flashEnd,
  752.                            BOOL skipNVRam, BOOL skipFUtil)
  753.     {
  754.     UINT32 addr, next_addr;
  755.    if (flashType == 0)
  756. flashType = sysFlashTypeGet ();
  757.     printf("Progress:n");
  758.     for (addr = flashStart; addr < flashEnd; addr = next_addr)
  759.     {
  760.         printf("r%3d%%  ",(100 * (addr -flashStart) / (flashEnd - flashStart)));
  761.         next_addr = addr;
  762.         sysFlashNextBlock(&next_addr);
  763.  /* unlock the block */
  764.  if (OK != sysFlashUnlock(FLASH_CAST(addr), flashType))
  765.  {
  766.      printf("Error unlock flash block %xn", addr);
  767.  }
  768.  /*erase the block*/
  769.         if (OK != sysFlashErase(FLASH_CAST(addr), flashType))
  770.         {
  771.             printf("Error erasing flash block %Xn",addr);
  772.             return ERROR;
  773.         }
  774.  /*write the block*/
  775.         if (OK != sysFlashWrite(FLASH_CAST(buf + (addr - flashStart)),
  776.                              next_addr - addr,
  777.                              addr,
  778.                              flashType,
  779.                              0))
  780.         {
  781.             printf("Error writing flash block %Xn",addr);
  782.             return ERROR;
  783.         }
  784.  /*compare the block*/
  785.         if (0 != bcmp((char*)(buf + (addr - flashStart)), 
  786.                       (char*)(addr), 
  787.                       next_addr - addr))
  788.         {
  789.             printf("Error: data miscompares after write, block = %X.n",addr);
  790.             return ERROR;
  791.         }
  792.     } /* end for addr */
  793.     printf("r100%% ... donen");
  794.     return OK;
  795. }