sysMtd.c
上传用户:dqzhongke1
上传日期:2022-06-26
资源大小:667k
文件大小:9k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* sysMtd.c - MTD driver for flash(s) on wrSbc8548 */
  2. /*
  3.  * Copyright (c) 2007 Wind River Systems, Inc.
  4.  *
  5.  * The right to copy, distribute, modify, or otherwise make use
  6.  * of this software may be licensed only pursuant to the terms
  7.  * of an applicable Wind River license agreement.
  8.  */
  9. /*
  10. modification history
  11. --------------------
  12. 01a,30mar07,b_m  written.
  13. */
  14. /*
  15. DESCRIPTION
  16. This file provides the TFFS MTD driver for the 4 banks of 8-bit Intel V28F128J3
  17. flash on the wrSbc8548 board. The driver handles the low level operations like
  18. erase and program of the flash. It also provides an identify routine to check if
  19. it is compatible with the devices.
  20. The macros DEBUG_PRINT must be defined as 'printf' to provide informative debug
  21. messages if necessary.
  22. The driver is only compatible and tested with wrSbc8548 board. DO NOT use this
  23. driver on any other boards unless the flashes are absolutely the same.
  24. INCLUDE FILES:
  25. SEE ALSO:
  26. */
  27. #include <stdio.h>
  28. #include "tffs/flflash.h"
  29. #include "tffs/backgrnd.h"
  30. /* defines */
  31. #undef  DEBUG_PRINT
  32. #define INTEL_VENDOR_ID         0x89
  33. #define FLASH_4M_DEV_ID         0x16
  34. #define FLASH_8M_DEV_ID         0x17
  35. #define FLASH_16M_DEV_ID        0x18
  36. #define FLASH_32M_DEV_ID        0x1D
  37. #define VENDOR_ID_INTERLEAVED   0x89898989
  38. #define DEVICE_ID_INTERLEAVED   0x18181818
  39. #define V28F128J3_VENDOR_OFFSET 0
  40. #define V28F128J3_DEVICE_OFFSET 2
  41. #define V28F128J3_FLASH_ID      ((INTEL_VENDOR_ID << 8) | FLASH_16M_DEV_ID)
  42. #define V28F128J3_FLASH_SIZE    0x01000000
  43. #define V28F128J3_FLASH_NUM     4
  44. #define V28F128J3_SECTOR_SIZE   0x20000
  45. #define V28F128J3_CMD_RESET             0xFFFFFFFF
  46. #define V28F128J3_CMD_READ_STATUS       0x70707070
  47. #define V28F128J3_CMD_CLEAR_STATUS      0x50505050
  48. #define V28F128J3_CMD_ERASE_BLOCK       0x20202020
  49. #define V28F128J3_CMD_ERASE_CONFIRM     0xD0D0D0D0
  50. #define V28F128J3_CMD_PROGRAM           0x10101010
  51. #define V28F128J3_CMD_READ_ID           0x90909090
  52. #define V28F128J3_STATUS_READY          0x80808080
  53. #define V28F128J3_STATUS_READY_MASK     0x80808080
  54. #define V28F128J3_STATUS_ERA_ERR_MASK   0x20202020
  55. #define V28F128J3_STATUS_PRG_ERR_MASK   0x10101010
  56. #define V28F128J3_STATUS_ERR_MASK       (V28F128J3_STATUS_ERA_ERR_MASK | V28F128J3_STATUS_PRG_ERR_MASK)
  57. #define V28F128J3_OP_TIMEOUT            5000
  58. #define V28F128J3_RESET(addr)   
  59.     do  
  60.     {   
  61.         *addr = V28F128J3_CMD_RESET;    
  62.     } while(0);
  63. #define V28F128J3_READ_STATUS(addr) 
  64.     do  
  65.     {   
  66.         *addr = V28F128J3_CMD_READ_STATUS;  
  67.     } while(0);
  68. #define V28F128J3_CLEAR_STATUS(addr)    
  69.     do  
  70.     {   
  71.         *addr = V28F128J3_CMD_CLEAR_STATUS;   
  72.     } while(0);
  73. #define V28F128J3_ERASE_BLOCK(addr) 
  74.     do  
  75.     {   
  76.         *addr = V28F128J3_CMD_ERASE_BLOCK;  
  77.     } while(0);
  78. #define V28F128J3_ERASE_CONFIRM(addr)   
  79.     do  
  80.     {   
  81.         *addr = V28F128J3_CMD_ERASE_CONFIRM;    
  82.     } while(0);
  83. #define V28F128J3_PROGRAM(addr, value)  
  84.     do  
  85.     {   
  86.         *addr = V28F128J3_CMD_PROGRAM;    
  87.         *addr = value;  
  88.     } while(0);
  89. #define V28F128J3_READ_ID(addr) 
  90.     do  
  91.     {   
  92.         *addr = V28F128J3_CMD_READ_ID;  
  93.     } while(0);
  94. /*******************************************************************************
  95. *
  96. * v28F128J3Program - low level byte programming routine
  97. *
  98. */
  99. LOCAL FLStatus v28F128J3Program
  100.     (
  101.     UINT32 *    addr,
  102.     UINT32      value
  103.     )
  104.     {
  105.     UINT32  status = V28F128J3_STATUS_READY;
  106.     UINT32  timeout = 0;
  107.     /* set timeout = 5s */
  108.     timeout = flMsecCounter + V28F128J3_OP_TIMEOUT;
  109.     V28F128J3_READ_STATUS(addr);
  110.     do
  111.     {
  112.         status = *addr;
  113.         if (flMsecCounter >= timeout)
  114.             break;
  115.     } while ((status & V28F128J3_STATUS_READY_MASK) != V28F128J3_STATUS_READY);
  116.     if ((status & V28F128J3_STATUS_ERR_MASK) != 0)
  117.         V28F128J3_CLEAR_STATUS(addr);
  118.     V28F128J3_PROGRAM(addr, value);
  119.     /* set timeout = 5s */
  120.     timeout = flMsecCounter + V28F128J3_OP_TIMEOUT;
  121.     do
  122.     {
  123.         status = *addr;
  124.         if (flMsecCounter >= timeout)
  125.         {
  126.             V28F128J3_RESET(addr);
  127.             return flTimedOut;
  128.         }
  129.     } while ((status & V28F128J3_STATUS_READY_MASK) != V28F128J3_STATUS_READY);
  130.     /* check program error bit */
  131.     if (status & V28F128J3_STATUS_PRG_ERR_MASK)
  132.     {
  133.         V28F128J3_RESET(addr);
  134.         return flWriteFault;
  135.     }
  136.     V28F128J3_RESET(addr);
  137.     return flOK;
  138.     }
  139. /*******************************************************************************
  140. *
  141. * v28F128J3Write - write routine for v28F128J3 flash
  142. *
  143. */
  144. LOCAL FLStatus v28F128J3Write
  145.     (
  146.     FLFlash         vol,
  147.     CardAddress     address,
  148.     const void FAR1 *buffer,
  149.     int             length,
  150.     int             overwrite
  151.     )
  152.     {
  153.     UINT8  *unaligned;
  154.     UINT8  *buf = (UINT8 *)buffer;
  155.     UINT32  left = length;
  156.     UINT32 *aligned;
  157.     UINT32  data, num;
  158.     int     i;
  159.     if (flWriteProtected(vol.socket))
  160.     return flWriteProtect;
  161.     /* calculate the program addr, make sure it's 32-bit aligned */
  162.     unaligned = (UINT8 *)vol.map (&vol, address, 0);
  163.     num = (UINT32)unaligned & 0x3;
  164.     aligned = (UINT32 *)((UINT32)unaligned - num);
  165.     if (num != 0)
  166.     {
  167.         data = *aligned;
  168.         for (i = num ; i < 4; i++)
  169.         {
  170.             data &= ~(0xFF << ((3 - i) * 8));
  171.             data |= ((*(buf + i - num)) << ((3 - i) * 8));
  172.         }
  173.         if (v28F128J3Program(aligned, data) != flOK)
  174.             return flWriteFault;
  175.         buf  += (4 - num);
  176.         left -= (4 - num);
  177.         aligned++;
  178.     }
  179.     while (left >= 4)
  180.     {
  181.         data = *(UINT32 *)buf;
  182.         if (v28F128J3Program (aligned, data) != flOK)
  183.             return flWriteFault;
  184.         buf  += 4;
  185.         left -= 4;
  186.         aligned++;
  187.     }
  188.     if (left > 0)
  189.     {
  190.         data = *aligned;
  191.         for (i = 0 ; i < left; i++)
  192.         {
  193.             data &= ~(0xFF << ((3 - i) * 8));
  194.             data |= ((*(buf + i)) << ((3 - i) * 8));
  195.         }
  196.         if (v28F128J3Program (aligned, data) != flOK)
  197.             return flWriteFault;
  198.     }
  199.     if (tffscmp((void FAR0 *)unaligned, buffer, length))
  200.     {
  201. #ifdef DEBUG_PRINT
  202.         DEBUG_PRINT("[v28F128J3Write]: data double check error @ 0x%08x ...n", unaligned);
  203. #endif
  204.         return flWriteFault;
  205.     }
  206.     return flOK;
  207.     }
  208. /*******************************************************************************
  209. *
  210. * v28F128J3Erase - erase routine for v28F128J3 flash
  211. *
  212. */
  213. LOCAL FLStatus v28F128J3Erase
  214.     (
  215.     FLFlash vol,
  216.     int     firstErasableBlock,
  217.     int     numOfErasableBlocks
  218.     )
  219.     {
  220.     UINT32 * block = NULL;
  221.     UINT32 status = V28F128J3_STATUS_READY;
  222.     UINT32 timeout = 0;
  223.     int i;
  224.     if (flWriteProtected(vol.socket))
  225.     return flWriteProtect;
  226.     for (i = firstErasableBlock; i < firstErasableBlock + numOfErasableBlocks; i++)
  227. {
  228.     block = (UINT32 *)vol.map(&vol, i * vol.erasableBlockSize, 0);
  229. #ifdef DEBUG_PRINT
  230.         DEBUG_PRINT("Erasing block#%03d @ 0x%08x ...r", i, block);
  231. #endif
  232.      /* set timeout = 5s */
  233.      timeout = flMsecCounter + V28F128J3_OP_TIMEOUT;
  234.         V28F128J3_READ_STATUS(block);
  235.         do
  236.         {
  237.             status = *block;
  238.             if (flMsecCounter >= timeout)
  239.                 break;
  240.         } while ((status & V28F128J3_STATUS_READY_MASK) != V28F128J3_STATUS_READY);
  241.         if ((status & V28F128J3_STATUS_ERR_MASK) != 0)
  242.             V28F128J3_CLEAR_STATUS(block);
  243.         V28F128J3_ERASE_BLOCK(block);
  244.         V28F128J3_ERASE_CONFIRM(block);
  245.      /* set timeout = 5s */
  246.      timeout = flMsecCounter + V28F128J3_OP_TIMEOUT;
  247.         do
  248.         {
  249.             status = *block;
  250.             if (flMsecCounter >= timeout)
  251.             {
  252.                 V28F128J3_RESET(block);
  253.                 return flTimedOut;
  254.             }
  255.         } while ((status & V28F128J3_STATUS_READY_MASK) != V28F128J3_STATUS_READY);
  256.         /* check erase error bit */
  257.      if (status & V28F128J3_STATUS_ERA_ERR_MASK)
  258.         {
  259.             V28F128J3_RESET(block);
  260.      return flWriteFault;
  261.         }
  262. }
  263.     V28F128J3_RESET(block);
  264.     return flOK;
  265.     }
  266. /*******************************************************************************
  267. *
  268. * v28F128J3Identify - identify routine for v28F128J3 flash
  269. *
  270. */
  271. FLStatus v28F128J3Identify
  272.     (
  273.     FLFlash vol
  274.     )
  275.     {
  276.     UINT32 * base = (UINT32 *)vol.map(&vol, 0, 0);
  277.     UINT32   vendor, device;
  278. #ifdef DEBUG_PRINT
  279.     DEBUG_PRINT("Entering v28F128J3Identify routine @ base address 0x%08x ...n", (UINT32)base);
  280. #endif
  281.     /* check the flash id */
  282.     V28F128J3_READ_ID(base);
  283.     vendor = *(base + V28F128J3_VENDOR_OFFSET);
  284.     device = *(base + V28F128J3_DEVICE_OFFSET);
  285.     if ((vendor == VENDOR_ID_INTERLEAVED) && (device == DEVICE_ID_INTERLEAVED))
  286.         vol.type = V28F128J3_FLASH_ID;
  287.     else
  288.     {
  289.         V28F128J3_RESET(base);
  290.         return flUnknownMedia;
  291.     }
  292.     vol.chipSize = V28F128J3_FLASH_SIZE;
  293.     vol.noOfChips = V28F128J3_FLASH_NUM;
  294.     vol.interleaving = V28F128J3_FLASH_NUM;
  295.     vol.erasableBlockSize = V28F128J3_SECTOR_SIZE * vol.interleaving;
  296.     vol.write = v28F128J3Write;
  297.     vol.erase = v28F128J3Erase;
  298.     V28F128J3_RESET(base);
  299.     return flOK;
  300.     }