EEPROM.cs
上传用户:huajielb
上传日期:2022-07-29
资源大小:626k
文件大小:17k
源码类别:

驱动编程

开发平台:

Visual C++

  1. using System;
  2. using Jungo.wdapi_dotnet;
  3. using wdc_err = Jungo.wdapi_dotnet.WD_ERROR_CODES;
  4. using wdc_lib_decl = Jungo.wdapi_dotnet.wdc_lib_decl;
  5. using DWORD = System.UInt32;
  6. using WORD = System.UInt16;
  7. using WDC_DEVICE_HANDLE = System.IntPtr;   
  8. using HANDLE = System.IntPtr;
  9. namespace Jungo.plx_lib
  10. {
  11.     abstract public class EEPROM
  12.     {
  13.         internal WDC_DEVICE_HANDLE m_devHandle;
  14.         internal DWORD m_dwCNTRL;
  15.         internal EEPROM(WDC_DEVICE_HANDLE hDev, DWORD dwCntrlReg)
  16.         {
  17.             m_devHandle = hDev;
  18.             m_dwCNTRL = dwCntrlReg;                        
  19.         }
  20.         public bool IsVPD()
  21.         {
  22.             return this.GetType() == typeof(EEPROM_VPD);
  23.         }
  24.         static public bool EEPROMIsPresent(WDC_DEVICE_HANDLE hDev, 
  25.             DWORD dwCntrlReg)
  26.         {
  27.             uint u32CNTRL = 0;
  28.             wdc_lib_decl.WDC_ReadAddr32(hDev, (DWORD)PLX_ADDR.PLX_ADDR_REG,
  29.                 dwCntrlReg, ref u32CNTRL);
  30.             return (u32CNTRL & (DWORD)BITS.BIT28) == (DWORD)BITS.BIT28;
  31.         }
  32.         /* VPD EEPROM access */
  33.         static public bool VPD_Validate(WDC_DEVICE_HANDLE devHandle, 
  34.             DWORD dwDevCntrlReg)
  35.         {
  36.             byte bData = 0;
  37.             if (devHandle == IntPtr.Zero)
  38.             {
  39.                 Log.ErrLog("EEPROM.VPD_Validate: device's handle is null");
  40.                 return false;
  41.             }
  42.             /* Verify that a blank or programmed serial EEPROM is present */
  43.             if (!EEPROMIsPresent(devHandle, dwDevCntrlReg))
  44.             {
  45.                 Log.ErrLog("EEPROM.VPD_Validate: Error - serial EEPROM " +
  46.                     "was not found on board");
  47.                 return false;
  48.             }
  49.             /* Check the next capability pointers */
  50.             wdc_lib_decl.WDC_PciReadCfg8(devHandle, (DWORD)PCI_CFG_REG.PCI_CAP,
  51.                 ref bData);
  52.             if (bData != (byte)PLX_CFG_REGS.PLX_PMCAPID)
  53.             {
  54.                 Log.TraceLog("EEPROM.VPD_Validate: PMCAP register validation failed");
  55.                 return false;
  56.             }
  57.             wdc_lib_decl.WDC_PciReadCfg8(devHandle, 
  58.                 (DWORD)PLX_CFG_REGS.PLX_PMNEXT, ref bData);
  59.             if (bData != (byte)PLX_CFG_REGS.PLX_HS_CAPID)
  60.             {
  61.                 Log.TraceLog("EEPROM.VPD_Validate: PMNEXT register validation failed");
  62.                 return false;
  63.             }
  64.             wdc_lib_decl.WDC_PciReadCfg8(devHandle, 
  65.                 (DWORD)PLX_CFG_REGS.PLX_HS_NEXT, ref bData);
  66.             if (bData != (byte)PLX_CFG_REGS.PLX_VPD_CAPID)
  67.             {
  68.                 Log.TraceLog("EEPROM.VPD_Validate: HS_NEXT register validation failed");
  69.                 return false;
  70.             }
  71.             wdc_lib_decl.WDC_PciReadCfg8(devHandle, 
  72.                 (DWORD)PLX_CFG_REGS.PLX_VPD_NEXT, ref bData);
  73.             if (bData != 0)
  74.             {
  75.                 Log.TraceLog("EEPROM.VPD_Validate: VPD_NEXT register validation failed");
  76.                 return false;
  77.             }
  78.             return true;
  79.         }
  80.         abstract public DWORD EEPROM_Write(DWORD dwOffset, uint u32Data);
  81.         abstract public DWORD EEPROM_Read(DWORD dwOffset,ref uint u32Data);
  82.     };
  83.     public class EEPROM_VPD: EEPROM
  84.     {
  85.         private DWORD m_devProtAreaReg;
  86.         internal protected EEPROM_VPD(WDC_DEVICE_HANDLE hDev, DWORD dwCntrlReg,
  87.             DWORD dwDevProtAreaReg) :base(hDev, dwCntrlReg)
  88.         {
  89.             m_devProtAreaReg = dwDevProtAreaReg;
  90.         }
  91.         private DWORD EEPROM_Delay()
  92.         {
  93.             return wdc_lib_decl.WDC_Sleep(30000, 
  94.                 WDC_SLEEP_OPTIONS.WDC_SLEEP_BUSY); 
  95.         }
  96.         override public DWORD EEPROM_Read(DWORD dwOffset, ref uint u32Data)
  97.         {
  98.             DWORD i;
  99.             uint u32EnableAccess = 0;
  100.             WORD wAddr, wData = 0;
  101.             if (m_devHandle == IntPtr.Zero)
  102.                 return (DWORD)wdc_err.WD_INVALID_PARAMETER;
  103.             if (dwOffset % 4 != 0)
  104.             {
  105.                 Log.ErrLog("EEPROM_Read: Error - offset (0x" + 
  106.                     dwOffset.ToString("X") + ") is not a multiple of 4 ");
  107.                 return (DWORD)wdc_err.WD_INVALID_PARAMETER;
  108.             }
  109.             /* Clear EEDO Input Enable */
  110.             EEPROM_EnableAccess(ref u32EnableAccess);
  111.             /* Write a destination serial EEPROM address and flag of operation,
  112.              * value of 0 */
  113.             wAddr = (WORD)(dwOffset & ~(DWORD)BITS.BIT15);
  114.             wdc_lib_decl.WDC_PciWriteCfg16(m_devHandle, 
  115.                 (DWORD)PLX_CFG_REGS.PLX_VPD_ADDR, wAddr);
  116.             /* Probe a flag of operation until it changes to a 1 to ensure the
  117.              * Read data is available */
  118.             for (i = 0; i < 10; i++)
  119.             {
  120.                 EEPROM_Delay();
  121.                 wdc_lib_decl.WDC_PciReadCfg16(m_devHandle, 
  122.                     (DWORD)PLX_CFG_REGS.PLX_VPD_ADDR, ref wData);
  123.                 if ((wData & (DWORD)BITS.BIT15) != 0)
  124.                     break;
  125.             }
  126.             if (i == 10)
  127.             {
  128.                 Log.ErrLog("PLX_EEPROM_VPD_Read32: Error - Acknowledge " +
  129.                     "to EEPROM read was not received");
  130.                 return (DWORD)wdc_err.WD_OPERATION_FAILED;
  131.             }
  132.             /* Read back the requested data from PVPDATA register */
  133.             wdc_lib_decl.WDC_PciReadCfg32(m_devHandle, 
  134.                 (DWORD)PLX_CFG_REGS.PLX_VPD_DATA, ref u32Data);
  135.             /* Restore EEDO Input Enable */
  136.             EEPROM_RestoreAccess(u32EnableAccess);
  137.             return (DWORD)wdc_err.WD_STATUS_SUCCESS;
  138.         }
  139.         override public DWORD EEPROM_Write(DWORD dwOffset, uint u32Data)
  140.         {
  141.             DWORD i;
  142.             uint u32ReadBack = 0, u32EnableAccess = 0;
  143.             WORD wAddr, wData = 0;
  144.             byte bEnableOffset = 0;
  145.             if (m_devHandle == IntPtr.Zero)
  146.                 return (DWORD)wdc_err.WD_INVALID_PARAMETER;
  147.             if (dwOffset % 4 != 0)
  148.             {
  149.                 Log.ErrLog("EEPROM_Write: Error - offset (0x" +
  150.                     dwOffset.ToString("X") + " is not a multiple of 4");
  151.                 return (DWORD)wdc_err.WD_INVALID_PARAMETER;
  152.             }
  153.             /* Clear EEDO Input Enable */
  154.             EEPROM_EnableAccess(ref u32EnableAccess);
  155.             wAddr = (WORD)dwOffset;
  156.             EEPROM_RemoveWriteProtection(wAddr, ref bEnableOffset);
  157.             EEPROM_Delay();
  158.             /* Write desired data to PVPDATA register */
  159.             wdc_lib_decl.WDC_PciWriteCfg32(m_devHandle,
  160.                 (DWORD)PLX_CFG_REGS.PLX_VPD_DATA, u32Data);
  161.             /* Write a destination serial EEPROM address and flag of operation,
  162.              * value of 1 */
  163.             wAddr = (WORD)(wAddr | (WORD)BITS.BIT15);
  164.             wdc_lib_decl.WDC_PciWriteCfg16(m_devHandle, 
  165.                 (DWORD)PLX_CFG_REGS.PLX_VPD_ADDR, wAddr);
  166.             /* Probe a flag of operation until it changes to a 0 to ensure the
  167.              * write completes */
  168.             for (i = 0; i < 10; i++)
  169.             {
  170.                 EEPROM_Delay();
  171.                 wdc_lib_decl.WDC_PciReadCfg16(m_devHandle,
  172.                     (DWORD)PLX_CFG_REGS.PLX_VPD_ADDR, ref wData);
  173.                 if ((wData & (WORD)BITS.BIT15) != 0)
  174.                     break;
  175.             }
  176.             EEPROM_RestoreWriteProtection(bEnableOffset);
  177.             /* Restore EEDO Input Enable */
  178.             EEPROM_RestoreAccess(u32EnableAccess);
  179.             EEPROM_Read(dwOffset, ref u32ReadBack);
  180.             if (u32ReadBack != u32Data)
  181.             {
  182.                 Log.ErrLog(string.Format("EEPROM_Write: Error - Wrote " +
  183.                     "0x{0,8}, read back 0x{1,8}", u32Data.ToString("X"),
  184.                     u32ReadBack.ToString("X"))); 
  185.                 return (DWORD)wdc_err.WD_OPERATION_FAILED;
  186.             }
  187.             return (DWORD)wdc_err.WD_STATUS_SUCCESS;
  188.         }
  189.         /* Enable EEPROM access via VPD mechanism - disable EEDO Input 
  190.          * (CNTRL[31]=0, default). This bit is specific to PLX 9656 and PLX 
  191.          * 9056 chips (it is reserved on other boards) */
  192.         private DWORD EEPROM_EnableAccess(ref uint u32DataOld)
  193.         {
  194.             wdc_lib_decl.WDC_ReadAddr32(m_devHandle, 
  195.                 (DWORD)PLX_ADDR.PLX_ADDR_REG, m_dwCNTRL, ref u32DataOld);
  196.             return wdc_lib_decl.WDC_WriteAddr32(m_devHandle,
  197.                 (DWORD)PLX_ADDR.PLX_ADDR_REG, m_dwCNTRL, 
  198.                 u32DataOld & ~(DWORD)BITS.BIT31);
  199.         }
  200.         /* Restore EEDO Input Enable */
  201.         private DWORD EEPROM_RestoreAccess(uint u32Data)
  202.         {
  203.             return wdc_lib_decl.WDC_WriteAddr32(m_devHandle, 
  204.                 (DWORD)PLX_ADDR.PLX_ADDR_REG, m_dwCNTRL, u32Data);
  205.         }
  206.         private DWORD EEPROM_RemoveWriteProtection(WORD wAddr, 
  207.             ref byte bDataOld)
  208.         {
  209.             wdc_lib_decl.WDC_ReadAddr8(m_devHandle, 
  210.                 (DWORD)PLX_ADDR.PLX_ADDR_REG, m_devProtAreaReg, ref bDataOld);
  211.             wAddr /= 4;
  212.             wAddr &= 0x7F;
  213.             wdc_lib_decl.WDC_WriteAddr8(m_devHandle, 
  214.                 (DWORD)PLX_ADDR.PLX_ADDR_REG, m_devProtAreaReg, (byte)wAddr);
  215.             bDataOld *= 4; /* Expand from DWORD to BYTE count */
  216.             return (DWORD)wdc_err.WD_STATUS_SUCCESS;
  217.         }
  218.         private DWORD EEPROM_RestoreWriteProtection(WORD wAddr)
  219.         {    
  220.             return wdc_lib_decl.WDC_WriteAddr8(m_devHandle, 
  221.                 (DWORD)PLX_ADDR.PLX_ADDR_REG, m_devProtAreaReg, (byte)wAddr);
  222.         }
  223.     };
  224.     public class EEPROM_RT: EEPROM
  225.     {
  226.         private DWORD m_EEPROMmsb;
  227.         internal protected EEPROM_RT(WDC_DEVICE_HANDLE hDev, DWORD dwCntrlReg,
  228.             DWORD EEPROMmsb) :base(hDev, dwCntrlReg)
  229.         {
  230.             m_EEPROMmsb = EEPROMmsb;
  231.         }
  232.         private DWORD EEPROM_Delay()
  233.         {
  234.             return wdc_lib_decl.WDC_Sleep(700, 
  235.                 WDC_SLEEP_OPTIONS.WDC_SLEEP_BUSY);
  236.         }
  237.         /* To use the Read16/Write16 methods, you can cast a "base" EEPROM
  238.          * object to EEPROM_RT, and that will give the access to those methods */
  239.         public DWORD EEPROM_Read16(DWORD dwOffset, ref WORD wData)
  240.         {
  241.             WORD i;
  242.             DWORD dwAddr = dwOffset >> 1;
  243.             bool bit = false;
  244.             if (m_devHandle == IntPtr.Zero)
  245.                 return (DWORD)wdc_err.WD_INVALID_HANDLE;
  246.             wData = 0;
  247.             EEPROM_ChipSelect(true);
  248.             EEPROM_WriteBit(true);
  249.             EEPROM_WriteBit(true);
  250.             EEPROM_WriteBit(false);
  251.             /* CS06, CS46 EEPROM - send 6bit address
  252.              * CS56, CS66 EEPROM - send 8bit address */
  253.             for (i = (WORD)m_EEPROMmsb; i!=0 ; i >>= 1)
  254.                 EEPROM_WriteBit((dwAddr & i) == i);
  255.             for (i = (WORD)BITS.BIT15; i != 0; i >>= 1)
  256.             {
  257.                 EEPROM_ReadBit(ref bit);
  258.                 wData |= (bit) ? i : (WORD)0;
  259.             }
  260.             EEPROM_ChipSelect(false);
  261.             return (DWORD)wdc_err.WD_STATUS_SUCCESS;
  262.         }
  263.         public DWORD EEPROM_Write16(DWORD dwOffset, WORD wData)
  264.         {
  265.             WORD i;
  266.             DWORD dwAddr = dwOffset >> 1;
  267.             WORD wReadBack = 0;
  268.             if (m_devHandle == IntPtr.Zero)
  269.                 return (DWORD)wdc_err.WD_INVALID_PARAMETER;
  270.             EEPROM_WriteEnableDisable(true);
  271.             EEPROM_ChipSelect(true);
  272.             /* Send a PRWRITE instruction */
  273.             EEPROM_WriteBit(true);
  274.             EEPROM_WriteBit(false);
  275.             EEPROM_WriteBit(true);
  276.             /* CS06, CS46 EEPROM - send 6bit address
  277.              * CS56, CS66 EEPROM - send 8bit address */
  278.             for (i = (WORD)m_EEPROMmsb; i != 0; i >>= 1)
  279.                 EEPROM_WriteBit((dwAddr & i) == i);
  280.             for (i = (WORD)BITS.BIT15; i != 0; i >>= 1)
  281.                 EEPROM_WriteBit((wData & i) == i);
  282.             EEPROM_ChipSelect(false);
  283.             EEPROM_WriteEnableDisable(true);
  284.             EEPROM_Read16(dwOffset, ref wReadBack);
  285.             if (wData != wReadBack)
  286.             {
  287.                 Log.ErrLog(string.Format("EEPROM_Write16: Error - Wrote " +
  288.                     "0x{0,4}, read back 0x{1,4}", wData.ToString("X"),
  289.                     wReadBack.ToString("X")));
  290.                 return (DWORD)wdc_err.WD_OPERATION_FAILED;
  291.             }
  292.             return (DWORD)wdc_err.WD_STATUS_SUCCESS;
  293.         }
  294.         override public DWORD EEPROM_Read(DWORD dwOffset,ref uint u32Data)
  295.         {
  296.             WORD wData1 =0 , wData2 = 0;
  297.             if (m_devHandle == IntPtr.Zero)
  298.                 return (DWORD)wdc_err.WD_INVALID_PARAMETER;
  299.             if ((dwOffset % 4) != 0)
  300.             {
  301.                 Log.ErrLog("EEPROM_Read: Error - offset 0x" +
  302.                     dwOffset.ToString("X") + "is not a multiple of 4");
  303.                 return (DWORD)wdc_err.WD_INVALID_PARAMETER;
  304.             }
  305.             EEPROM_Read16(dwOffset, ref wData1);
  306.             EEPROM_Read16(dwOffset + 2, ref wData2);
  307.             u32Data = (uint)((wData1 << 16) + wData2);
  308.             return (DWORD)wdc_err.WD_STATUS_SUCCESS;
  309.         }
  310.         override public DWORD EEPROM_Write(DWORD dwOffset, uint u32Data)
  311.         {
  312.             WORD wData1, wData2;
  313.             if (m_devHandle == IntPtr.Zero)
  314.                 return (DWORD)wdc_err.WD_INVALID_PARAMETER;
  315.             if ((dwOffset % 4) != 0)
  316.             {
  317.                 Log.ErrLog("EEPROM_Write: Error - offset 0x" + 
  318.                     dwOffset.ToString("X") + "is not a multiple of 4");
  319.                 return (DWORD)wdc_err.WD_INVALID_PARAMETER;
  320.             }
  321.             wData1 = (WORD)(u32Data >> 16);
  322.             wData2 = (WORD)(u32Data & 0xFFFF);
  323.             EEPROM_Write16(dwOffset, wData1);
  324.             EEPROM_Write16(dwOffset + 2, wData2);
  325.             return (DWORD)wdc_err.WD_STATUS_SUCCESS;
  326.         }
  327.         private void EEPROM_ChipSelect(bool fSelect)
  328.         {
  329.             uint u32CNTRL = 0;
  330.             wdc_lib_decl.WDC_ReadAddr32(m_devHandle,
  331.                 (DWORD)PLX_ADDR.PLX_ADDR_REG, m_dwCNTRL, ref u32CNTRL);
  332.             wdc_lib_decl.WDC_WriteAddr32(m_devHandle,
  333.                 (DWORD)PLX_ADDR.PLX_ADDR_REG, m_dwCNTRL, fSelect ?
  334.                 (u32CNTRL | (uint)BITS.BIT25) : (u32CNTRL & ~(uint)BITS.BIT25));
  335.             EEPROM_Delay();
  336.         }
  337.         private void EEPROM_ReadBit(ref bool bit)
  338.         {
  339.             uint u32CNTRL = 0;
  340.             wdc_lib_decl.WDC_ReadAddr32(m_devHandle, 
  341.                 (DWORD)PLX_ADDR.PLX_ADDR_REG, m_dwCNTRL, ref u32CNTRL);
  342.             /* clock */
  343.             wdc_lib_decl.WDC_WriteAddr32(m_devHandle, 
  344.                 (DWORD)PLX_ADDR.PLX_ADDR_REG, m_dwCNTRL,
  345.                 u32CNTRL & ~(uint)BITS.BIT24);
  346.             EEPROM_Delay();
  347.             wdc_lib_decl.WDC_WriteAddr32(m_devHandle,
  348.                 (DWORD)PLX_ADDR.PLX_ADDR_REG, m_dwCNTRL, 
  349.                 u32CNTRL | (uint)BITS.BIT24);
  350.             EEPROM_Delay();
  351.             wdc_lib_decl.WDC_WriteAddr32(m_devHandle,
  352.                 (DWORD)PLX_ADDR.PLX_ADDR_REG, m_dwCNTRL, 
  353.                 u32CNTRL & ~(uint)BITS.BIT24);
  354.             EEPROM_Delay();
  355.             /* data */
  356.             wdc_lib_decl.WDC_ReadAddr32(m_devHandle, 
  357.                 (DWORD)PLX_ADDR.PLX_ADDR_REG, m_dwCNTRL, ref u32CNTRL);
  358.             bit = (u32CNTRL & (uint)BITS.BIT27) == (uint)BITS.BIT27;
  359.         }
  360.         private void EEPROM_WriteBit(bool bit)
  361.         {
  362.             uint u32CNTRL = 0;
  363.             wdc_lib_decl.WDC_ReadAddr32(m_devHandle, 
  364.                 (DWORD)PLX_ADDR.PLX_ADDR_REG, m_dwCNTRL, ref u32CNTRL);
  365.             if (bit) /* data */
  366.                 u32CNTRL |= (uint)BITS.BIT26;
  367.             else
  368.                 u32CNTRL &= (uint)~BITS.BIT26;
  369.             /* clock */
  370.             wdc_lib_decl.WDC_WriteAddr32(m_devHandle, 
  371.                 (DWORD)PLX_ADDR.PLX_ADDR_REG, m_dwCNTRL, 
  372.                 u32CNTRL & ~(uint)BITS.BIT24);
  373.             EEPROM_Delay();
  374.             wdc_lib_decl.WDC_WriteAddr32(m_devHandle, 
  375.                 (DWORD)PLX_ADDR.PLX_ADDR_REG, m_dwCNTRL,
  376.                 u32CNTRL | (uint)BITS.BIT24);
  377.             EEPROM_Delay();
  378.             wdc_lib_decl.WDC_WriteAddr32(m_devHandle, 
  379.                 (DWORD)PLX_ADDR.PLX_ADDR_REG, m_dwCNTRL, 
  380.                 u32CNTRL & ~(uint)BITS.BIT24);
  381.             EEPROM_Delay();
  382.         }
  383.         private void EEPROM_WriteEnableDisable(bool fEnable)
  384.         {
  385.             EEPROM_ChipSelect(true);
  386.             /* Send a WEN instruction */
  387.             EEPROM_WriteBit(true);
  388.             EEPROM_WriteBit(false);
  389.             EEPROM_WriteBit(false);
  390.             EEPROM_WriteBit(fEnable ? true : false);
  391.             EEPROM_WriteBit(fEnable ? true : false);
  392.             EEPROM_WriteBit(false);
  393.             EEPROM_WriteBit(false);
  394.             EEPROM_WriteBit(false);
  395.             EEPROM_WriteBit(false);
  396.             EEPROM_ChipSelect(false);
  397.         }
  398.     };
  399. }