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

VxWorks

开发平台:

C/C++

  1. /* m8260Flash.c - Flash memory device driver for 28F016 flash devices */
  2. /* Copyright 1984-1999 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01d,15jul99,ms_  make compliant with our coding standards
  8. 01c,05jun99,cn   added sysFlashUpdate, updated documentation, removed 
  9.  unnecessary code.
  10. 01b,28may99,ms_  get flash28.h locally, not from the driver include location
  11. 01a,05may99,cn   derived from version 01k of mem/flashMem.c.
  12. */
  13. /*
  14. DESCRIPTION
  15. This library contains routines to manipulate the 28F016 flash memory.  Read 
  16. and write routines are included.
  17. The macro values FLASH_ADRS, FLASH_SIZE, and FLASH_WIDTH must be defined to
  18. indicate the address, size (in bytes), and the data-access width (in bytes) of
  19. the flash memory. Besides, the macro FLASH_SIZE_WRITEABLE should be defined
  20. to a reasonable amount of flash-memory that needs to be modified. In fact, 
  21. the user is not likely to need to change the entire contents of the device.
  22. */
  23. #include "drv/mem/flash28.h"
  24. /* defines */
  25. #define FLASH_DEF       UINT32
  26. #define FLASH_CAST      (UINT32 *)
  27. #define FLASH_BLK_SZ 0x10000
  28. #define FLASH_ALIGN_SZ (FLASH_BLK_SZ * FLASH_WIDTH)
  29. #ifdef FLASH_SIZE_WRITEABLE
  30. #   define FLASH_MEM_SIZE FLASH_SIZE_WRITEABLE
  31. #else
  32. #   define FLASH_MEM_SIZE FLASH_SIZE
  33. #endif /* FLASH_SIZE_WRITEABLE */
  34. /* globals */
  35. /* forward declarations */
  36. STATUS sysFlashErase (UINT32 offset);
  37. STATUS sysFlashWrite (FLASH_DEF * pFB, UINT32 size, UINT32 offset,
  38.                        FLASH_DEF value);
  39. STATUS sysFlashGet (UCHAR * string, UINT32 strLen, UINT32 offset);
  40. UINT8 sysFlashTypeGet (void);
  41. STATUS sysFlashUpdate (UCHAR * filename);
  42. /******************************************************************************
  43. *
  44. * sysFlashGet - get the contents of flash memory
  45. *
  46. * This routine copies the contents of flash memory into a specified
  47. * string.  The string is terminated with an EOS.
  48. *
  49. * RETURNS: OK, or ERROR if access is outside the flash memory range.
  50. *
  51. * SEE ALSO: sysFlashSet()
  52. *
  53. * INTERNAL
  54. * If multiple tasks are calling sysFlashSet() and sysFlashGet(),
  55. * they should use a semaphore to ensure mutually exclusive access.
  56. */
  57. STATUS sysFlashGet
  58.     (
  59.     UCHAR * string, /* where to copy flash memory      */
  60.     UINT32   strLen, /* maximum number of bytes to copy */
  61.     UINT32   offset /* byte offset into flash memory   */
  62.     )
  63.     {
  64.     if ((offset < 0) || (strLen < 0) || ((offset + strLen) > FLASH_MEM_SIZE))
  65.         return (ERROR);
  66.     bcopyBytes ((char *) (FLASH_ADRS + offset), string, strLen);
  67.     string [strLen] = EOS;
  68.     return (OK);
  69.     }
  70. /******************************************************************************
  71. *
  72. * sysFlashErase - erase the contents of flash memory
  73. *
  74. * This routine clears the contents of flash memory from the specified
  75. * <offset> up to the top.
  76. *
  77. * Flash 28F016 devices support block erase mode. This means each of the 32
  78. * 64-KByte blocks is erased by writing a flash erase command to
  79. * the device at any address within the target block, and verifying that 
  80. * the operation completed successfully.
  81. *
  82. * RETURNS: OK, or ERROR if the contents of flash memory cannot be erased.
  83. */
  84. STATUS sysFlashErase
  85.     (
  86.     UINT32 offset /* offset from flash base address */
  87.     )
  88.     {
  89.     volatile FLASH_DEF * pFA = FLASH_CAST (offset + FLASH_ADRS);
  90.     STATUS retVal = OK;
  91.     *pFA = FLASH28_CMD_RESET;
  92.     for (; (pFA <= FLASH_CAST (FLASH_ADRS + ((UINT32) FLASH_MEM_SIZE - 1)))
  93.  && (retVal == OK); pFA += FLASH_BLK_SZ)
  94. {
  95. *pFA = FLASH28_CMD_ERASE_SETUP;             /* setup */
  96. *pFA = FLASH28F008_CMD_ERASE;               /* erase */
  97.  
  98. /* Check Write State Machine Status */
  99.  
  100. do
  101.     *pFA = FLASH28F008_CMD_READ_STATUS;
  102. while ((*pFA & FLASH28F008_STAT_WSMS) != FLASH28F008_STAT_WSMS);
  103.  
  104. /* Check Erase Error Status */
  105.      
  106. if ((*pFA & FLASH28F008_STAT_EWS) != 0)
  107.     {
  108.     *pFA = FLASH28F008_CMD_CLEAR_STATUS;
  109.     retVal = ERROR;
  110.     }
  111. /* check we are at the last block */
  112. if (pFA >= FLASH_CAST (FLASH_ADRS + (FLASH_MEM_SIZE - FLASH_ALIGN_SZ)))
  113.     break;
  114. }
  115.     pFA = FLASH_CAST (FLASH_ADRS);
  116.     *pFA = FLASH28_CMD_RESET;
  117.     return (retVal);
  118.     }
  119. /******************************************************************************
  120. *
  121. * sysFlashWrite - write data to flash memory
  122. *
  123. * This routine copies specified data of a specified length, <size>, into a
  124. * specified offset, <offset>, in the flash memory.  Data is passed as a string,
  125. * <pFB>, if not NULL.  If NULL, data is taken as a repeated sequence of
  126. * <value>.
  127. * The parameter <offset> must be appropriately aligned for the width of
  128. * the Flash devices in use.
  129. *
  130. * Flash 28F016 devices are programmed by a sequence of operations:
  131. * .iP
  132. * set up device to write
  133. * .iP
  134. * perform write
  135. * .iP
  136. * verify the write
  137. * .LP
  138. *
  139. * RETURNS: OK, or ERROR if the write operation fails.
  140. *
  141. * SEE ALSO: sysFlashSet()
  142. */
  143. STATUS sysFlashWrite
  144.     (
  145.     FLASH_DEF * pFB, /* string to be copied; use <value> if NULL */
  146.     UINT32 size, /* size to program in bytes */
  147.     UINT32 offset, /* byte offset into flash memory */
  148.     FLASH_DEF value /* value to program */
  149.     )
  150.     {
  151.     volatile FLASH_DEF * pFA = FLASH_CAST (FLASH_ADRS); /* flash address */
  152.     STATUS retVal = OK;
  153.     *pFA = FLASH28_CMD_RESET;
  154.     for (pFA = FLASH_CAST (FLASH_ADRS + offset); (pFA < FLASH_CAST
  155. (FLASH_ADRS + size + offset)) && (retVal == OK); pFA++)
  156. {
  157. if (pFB != NULL)
  158.     value = *pFB++;
  159. *pFA = FLASH28_CMD_PROG_SETUP; /* write setup */
  160. *pFA = value; /* data to write */
  161. /* Check Write State Machine Status */
  162. do
  163.     {
  164.     *pFA = FLASH28F008_CMD_READ_STATUS;
  165.     }
  166. while ((*pFA & FLASH28F008_STAT_WSMS) != FLASH28F008_STAT_WSMS);
  167. /* Check Byte Write Error Status */
  168. if ((*pFA & FLASH28F008_STAT_BWS) != 0)
  169.     {
  170.     *pFA = FLASH28F008_CMD_CLEAR_STATUS;
  171.     retVal = ERROR;
  172.     }
  173. }
  174.     pFA = FLASH_CAST (FLASH_ADRS);
  175.     *pFA = FLASH28_CMD_RESET;
  176.     return (retVal);
  177.     }
  178. /******************************************************************************
  179. *
  180. * sysFlashTypeGet - determine the device type of on-board flash memory
  181. *
  182. * This routine uses the `read identifier code' command to determine the 
  183. * device type of * on-board flash memory. The returned value should be 
  184. * the one in drv/mem/flash28.h
  185. *
  186. * RETURNS: An integer indicating the device type of on-board flash memory.
  187. */
  188. UINT8 sysFlashTypeGet (void)
  189.     {
  190.     volatile FLASH_DEF * pFA = FLASH_CAST (FLASH_ADRS); /* flash address */
  191.     UINT8 retVal;
  192.     UINT32 temp;
  193.     *pFA = FLASH28_CMD_RESET;
  194.     *pFA = FLASH28_CMD_READ_ID;
  195.     temp = (UINT32) *++pFA;
  196.     retVal = (UINT8) temp;
  197.     *pFA = FLASH28_CMD_RESET;
  198.     return (retVal);
  199.     }
  200. /******************************************************************************
  201. *
  202. * sysFlashUpdate - update the contents of the flash device
  203. *
  204. * This code allows the user to overwrite the flash device with data from
  205. * a file. It will copy data from "filename" to the flash device.  It first
  206. * erase the device, and it attempts to write data to the flash device 
  207. * via sysFlashWrite ().
  208. *
  209. * The user should pass a binary bootrom file, for example
  210. * to update the bootrom with a VxWorks BSP bootrom image:
  211. * .CS
  212. *       % make bootrom
  213. *         make: `bootrom' is up to date.
  214. *       % elfToBin < bootrom > bootrom.bin
  215. *
  216. * -> sysUpdateFlash ("hostname:/tmp/bootrom.bin")
  217. * The flash has been updated without error.
  218. * .CE
  219. *
  220. * RETURNS: OK, or ERROR: if the file was not accessable, the
  221. * file was too large to fit into the flash, the buffers cannot
  222. * be allocated, sysFlashErase () or sysFlashWrite () returned error.
  223. *
  224. * SEE ALSO: sysFlashErase(), sysFlashGet(), sysFlashTypeGet(), sysFlashWrite()
  225. *
  226. * INTERNAL
  227. * If multiple tasks are calling sysFlashSet() and sysFlashGet(),
  228. * they should use a semaphore to ensure mutually exclusive access to flash
  229. * memory.
  230. */
  231. STATUS sysFlashUpdate
  232.     (
  233.     UCHAR * filename /* file to be copied into flash memory */
  234.     )
  235.     {
  236.     UCHAR * pMemBuf; /* holds the flash data */
  237.     int fd;                  /* the bootrom image fd */
  238.     int statReturn;             /* return values    */
  239.     /* first step is to open the file */
  240.     if ((fd = open (filename, O_RDONLY, 0444)) == ERROR)
  241.         return (ERROR);
  242.     /* now we read it */
  243.     pMemBuf = calloc (FLASH_MEM_SIZE, 1);
  244.  
  245.     if (pMemBuf == NULL)
  246.         {
  247.         printErr ("sysFlashUpdate: ");
  248.         printErr ("Could not allocate 0x%x bytes.n", (long) FLASH_MEM_SIZE);
  249.         close (fd);
  250.         return (ERROR);
  251.         }
  252.  
  253.     statReturn = read (fd, pMemBuf, FLASH_MEM_SIZE);
  254.  
  255.     if ((statReturn > FLASH_MEM_SIZE) || (statReturn <= 0)) 
  256.         {
  257.         printErr ("Failed to read from file n");
  258.         close (fd);
  259. free (pMemBuf);
  260.         return (ERROR);
  261. }
  262.     /* see if contents are actually changing */
  263.     if (bcmp ((char *) (FLASH_ADRS), pMemBuf, FLASH_MEM_SIZE) == 0)
  264. return (OK);
  265.     /* now we can erase the device */
  266.     if (sysFlashErase (0) == ERROR)
  267.         return (ERROR);
  268.     /* write to the device */
  269.     if (sysFlashWrite ((FLASH_DEF *) pMemBuf, statReturn, 0, 0) == ERROR)
  270. {
  271.         printErr ("Failed to write to the device n");
  272.         close (fd);
  273. free (pMemBuf);
  274.         return (ERROR);
  275. }
  276.     return (OK);
  277.     }