⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dalddc.c

📁 此代码为WCE5.0下显示器的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
          && ulStdLen < ulLen)
      {
        ulLen = ulStdLen;
      }
    }
  }

    // Stop I2C bus no matter success or failure
    //
  if (FALSE == DDCStop(lpDisplay))
  {
    DALDEBUG((DALDBG_ENTRY_EXIT, "DDCRead- Exit"));
    return FALSE;
  }
  
  DALDEBUG((DALDBG_ENTRY_EXIT, "DDCRead- Exit"));
  return bRet;
} // DDCRead()

/******************************Private*Routine*****************************\
* BOOL DDCWrite(LPDEVGDO lpDisplay, LPUCHAR lpucBuf, ULONG ulLen)
*
* Write byte block of EDID data.
*
\**************************************************************************/

static BOOL
DDCWrite(
  LPDEVGDO  lpDisplay,  // Display structure
  LPUCHAR   lpucBuf,    // Buffer to write from
  ULONG     ulLen)      // Buffer length
{
  ULONG  ulCount;
  BOOL  bRet;

  DALDEBUG((DALDBG_ENTRY_EXIT, "DDCWrite- Entry"));
  DALASSERT(NULL != lpucBuf, "lpucBuf is NULL!");
  
  bRet  = DDCStart(lpDisplay);
  ulCount = DDC_RETRIES;
  while ((bRet) && (ulCount > 0))
  {
    bRet = DDCStart(lpDisplay);
    ulCount--;
  }
  
  if (bRet == FALSE)
  {
    DALDEBUG((DALDBG_ENTRY_EXIT, "DDCWrite- Exit"));
    return FALSE;
  }
  
  for (ulCount = 0; ulCount < ulLen; ulCount++)
  {
    if (FALSE == (bRet = DDCWriteByte(lpDisplay, lpucBuf[ulCount])))
      break;
  }
  
    // Stop I2C bus no matter success or failure
    //
  if (FALSE == DDCStop(lpDisplay))
  {
    DALDEBUG((DALDBG_ENTRY_EXIT, "DDCWrite- Exit"));
    return FALSE;
  }
  
  DALDEBUG((DALDBG_ENTRY_EXIT, "DDCWrite- Exit"));
  return bRet;
} // DDCWrite()

/******************************Private*Routine*****************************\
* BOOL DDCReadByte(LPDEVGDO lpDisplay, LPUCHAR lpucByte, BOOL bMore)
*
* Read one byte of EDID data.
*
\**************************************************************************/

static BOOL
DDCReadByte(
  LPDEVGDO  lpDisplay,  // Display structure
  LPUCHAR   lpucByte,   // Byte to read
  BOOL      bMore)      // More reads needed?
{
  LONG  lShift;
  LONG  lClockWait;
  BOOL  bAck;
  PFNDDCREADLINE    pfnReadLine = lpDisplay->lpHWED->pfnDDC_I2C_ReadLine;
  PFNDDCWRITELINE   pfnWriteLine = lpDisplay->lpHWED->pfnDDC_I2C_WriteLine;
  HGDO  hGDO = lpDisplay->hGDO;
  
  DALDEBUG((DALDBG_ENTRY_EXIT, "DDCReadByte- Entry"));

  *lpucByte = 0;
  
  //
  // The data bits are read from MSB to LSB. A data bit is read while the SCL is high.
  //
  
  for (lShift = 7; lShift >= 0; lShift--)
  {
    // Set SCL high
    //
    pfnWriteLine(hGDO, 1, DAL_DDC_I2C_LINE_SCL);
    DDC_I2C_DELAY();
    
    bAck     = DDCWaitForClockLineHigh(lpDisplay);
    lClockWait = DDC_RETRIES;
    
    // Some monitors take awhile to respond to the fact that
    // the clock has been set high.  For these monitors we 
    // simply ask them a few times if think they might be
    // ready to talk to us nicely.
    //
    while ( (!bAck) && (lClockWait > 0))
    {
      bAck = DDCWaitForClockLineHigh(lpDisplay);
      lClockWait--;
      DDC_I2C_DELAY();
    }
    
    if(bAck == FALSE)
    {
      DALDEBUG((DALDBG_DETAIL, "DDCReadByte: SCL didn't take"));
	  DALDEBUG((DALDBG_ENTRY_EXIT, "DDCReadByte- Exit"));
      return FALSE;
    }
    
    // Read SDA
    //
    *lpucByte |= pfnReadLine(hGDO, 
      DAL_DDC_I2C_LINE_SDA) << lShift;
    
    // Set SCL low
    //
    pfnWriteLine(hGDO, 0, DAL_DDC_I2C_LINE_SCL);
    DDC_I2C_DELAY();
  }
  
  //
  // Send the acknowledge bit. SDA low = ACK, SDA high = NAK.
  //
  
  if (TRUE == bMore)
  {   // Set SDA low - ACK
    
    pfnWriteLine(hGDO, 0, DAL_DDC_I2C_LINE_SDA);
  }
  else
  {   // Set SDA high - NAK
    
    pfnWriteLine(hGDO, 1, DAL_DDC_I2C_LINE_SDA);
  }
  DDC_I2C_DELAY();
  
  //
  // Send a SCL high->low pulse, then release the SDA by setting it high.
  //
  
  // Set SCL high
  //
  pfnWriteLine(hGDO, 1, DAL_DDC_I2C_LINE_SCL);
  DDC_I2C_DELAY();
  if (DDCWaitForClockLineHigh(lpDisplay) == FALSE)
  {
    DALDEBUG((DALDBG_DETAIL, "DDCReadByte: SCL didn't take - ACK failed"));
	DALDEBUG((DALDBG_ENTRY_EXIT, "DDCReadByte- Exit"));
    return FALSE;
  }
  
  // Set SCL low
  //
  pfnWriteLine(hGDO, 0, DAL_DDC_I2C_LINE_SCL);
  DDC_I2C_DELAY();
  
  // Set SDA high
  //
  pfnWriteLine(hGDO, 1, DAL_DDC_I2C_LINE_SDA);
  DDC_I2C_DELAY();

  DALDEBUG((DALDBG_ENTRY_EXIT, "DDCReadByte- Exit"));
  return TRUE;
} // DDCReadByte()

/******************************Private*Routine*****************************\
* BOOL DDCWriteByte(LPDEVGDO lpDisplay, UCHAR ucByte)
*
* Write one byte of EDID data.
*
\**************************************************************************/
  
static BOOL
DDCWriteByte(
  LPDEVGDO  lpDisplay,  // Display structure
  UCHAR     ucByte)     // Byte to write
{
  LONG  lShift;
  LONG  lClockWait;
  BOOL  bAck;
  PFNDDCREADLINE    pfnReadLine = lpDisplay->lpHWED->pfnDDC_I2C_ReadLine;
  PFNDDCWRITELINE   pfnWriteLine = lpDisplay->lpHWED->pfnDDC_I2C_WriteLine;
  HGDO  hGDO = lpDisplay->hGDO;
  
  DALDEBUG((DALDBG_ENTRY_EXIT, "DDCWriteByte- Entry"));

  //
  // Bits are transmitted serially starting with the MSB.
  //
  
  for (lShift = 7; lShift >= 0; lShift--)
  {
    //
    // Transmitt data bit.
    //
    
    // Set SDA
    //
    pfnWriteLine(hGDO, (UCHAR)((ucByte >> lShift) & 0x01), DAL_DDC_I2C_LINE_SDA);
    DDC_I2C_DELAY();
    
    //
    // After each data bit we must send high->low SCL pulse.
    //
    
    // Set SCL high
    //
    pfnWriteLine(hGDO, 1, DAL_DDC_I2C_LINE_SCL);
    DDC_I2C_DELAY();
    
    bAck = DDCWaitForClockLineHigh(lpDisplay);
    lClockWait = DDC_RETRIES;
    
    // Some monitors take awhile to respond to the fact that
    // the clock has been set high.  For these monitors we 
    // simply ask them a few times if think they might be
    // ready to talk to us nicely.
    //
    while ( (!bAck) && (lClockWait > 0))
    {
      bAck = DDCWaitForClockLineHigh(lpDisplay);
      lClockWait--;
      DDC_I2C_DELAY();
    }
    
    if(bAck == FALSE)
    {
      DALDEBUG((DALDBG_DETAIL, "DDCWriteByte: SCL didn't take"));
	  DALDEBUG((DALDBG_ENTRY_EXIT, "DDCWriteByte- Exit"));
      return FALSE;
    }
    
    // Set SCL low
    //
    pfnWriteLine(hGDO, 0, DAL_DDC_I2C_LINE_SCL);
    DDC_I2C_DELAY();
  }
  
  //
  // The monitor sends ACK by preventing the SDA from going high after the clock pulse we use
  // to send our last data bit. If the SDA goes high after this bit, it is a NAK from the monitor.
  //
  
  // Set SDA high
  //
  pfnWriteLine(hGDO, 1, DAL_DDC_I2C_LINE_SDA);
  DDC_I2C_DELAY();
  
  // Set SCL high
  //
  pfnWriteLine(hGDO, 1, DAL_DDC_I2C_LINE_SCL);
  DDC_I2C_DELAY();
  if (DDCWaitForClockLineHigh(lpDisplay) == FALSE)
  {
    DALDEBUG((DALDBG_DETAIL, "DDCWriteByte: SCL didn't take - ACK failed"));
	DALDEBUG((DALDBG_ENTRY_EXIT, "DDCWriteByte- Exit"));
    return FALSE;
  }
  
  // Read ACK bit
  //
  DDC_I2C_DELAY();
  bAck = pfnReadLine(hGDO, DAL_DDC_I2C_LINE_SDA);
  
  // Set SCL low
  //
  pfnWriteLine(hGDO, 0, DAL_DDC_I2C_LINE_SCL);
  DDC_I2C_DELAY();
  
  if (TRUE == bAck)
  {   // NAK from the monitor
   
    DALDEBUG((DALDBG_DETAIL, "DDCWriteByte: NAK received"));
	DALDEBUG((DALDBG_ENTRY_EXIT, "DDCWriteByte- Exit"));
    return FALSE;
  }
  
  DALDEBUG((DALDBG_ENTRY_EXIT, "DDCWriteByte- Exit"));
  return TRUE;
} // DDCWriteByte()
  
/******************************Private*Routine*****************************\
* BOOL DDCWaitForClockLineHigh(LPDEVGDO lpDisplay)
*
* Wait for clock line to become high.
*
\**************************************************************************/

static BOOL
DDCWaitForClockLineHigh(
  LPDEVGDO  lpDisplay)    // Display structure
{
  ULONG ulCount;
  PFNDDCREADLINE    pfnReadLine = lpDisplay->lpHWED->pfnDDC_I2C_ReadLine;
  
  DALDEBUG((DALDBG_ENTRY_EXIT, "DDCWaitForClockLineHigh- Entry"));
  
  for (ulCount = 0; ulCount < DDC_I2C_SCL_READ_RETRIES; ulCount++)
  {
    if (pfnReadLine(lpDisplay->hGDO, DAL_DDC_I2C_LINE_SCL) == TRUE)
	{
	  DALDEBUG((DALDBG_ENTRY_EXIT, "DDCWaitForClockLineHigh- Exit"));
      return TRUE;
	}
    
    DDC_I2C_DELAY();
  }
  DALDEBUG((DALDBG_ENTRY_EXIT, "DDCWaitForClockLineHigh- Exit"));
  return FALSE;
} // DDCWaitForClockLineHigh()

/******************************Public*Routine******************************\
* BOOL bFakeTvEdidData(LPHW_DAL_EXTENSION lpHDE, LPDEVGDO lpDisplay,
*                   LPEDID_BUFFER lpEDIDBuf)
*
* Fake TV EDID data.
*
\**************************************************************************/

BOOL 
bFakeTvEdidData(
  LPDEVGDO lpDisplay,
  LPDEVMODE_INFO lpDisplayMaxModeInfo,  // Display structure
  LPEDID_BUFFER       lpEDIDBuf)  // Uninitialized EDID buffer structure
{

  static EDID_DATA_V1X sTvEdidDataV1X =
  {
      // Header (8): EDID ver 1 header
    {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
      // Vendor / Product Identification (10)
    { 0x41, 0xD0,  // ID Manufacturer Name: PNP (0 10000 01110 10000)
      0xFE, 0x09,  // ID Product Code: TV (?)
      0x00, 0x00, 0x00, 0x00,  // ID Serial Number
      0x00,   // Week of Manufacture
      0x00    // Year of Manufacture: 1990
    },
      // EDID structure Version / Revision (2)
    {0x01, 0x03}, // What revision to use? v1.3
      // Basic Display Parameters / Features (5)
    { 0x00, // Vudeo Input Definition
      0x00, // Max Horizontal Image Size
      0x00, // Max Vertical Image SIze
      0x00, // Display Transfer characteristic (Gamma * 100 - 100)
      0xF0  // Feature Support (DPMS)
    },
      // Color Characteristics (10)
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      // Established Timings (3)
    { 0x21, // 640 x 480 @ 60Hz, 800 x 600 @ 60Hz
      0x00, // 0x08 = 1024 x 768 @ 60Hz, if supported
      0x00
    },
      // Standard Timing Identification (16)
    { 0, 0, 0, 0, 0, 0, 0, 0},
      // Detailed timing (18 x 4)
    { {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
      {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
      {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
      {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
    },
      // Extension Flag (1)
    0x00,
      // Check Sum (1)
    0x00
  };

  ULONG ulTemp;
  ULONG ulChecksum;
//  DEVMODE_INFO HighResMode;

  DALDEBUG((DALDBG_ENTRY_EXIT, "bFakeTvEdidData - Entry"));

  DALASSERT(EDID_VER_1_STDLEN == sizeof(sTvEdidDataV1X), 
    "EDID_DATA_V11 structure size mismatch - mispacked??");
  DALASSERT(EDID_VER_1_STDLEN <= sizeof(lpEDIDBuf->aucEdidDataBuffer), 
    "Supplied EDID buffer too small");
  
    // Copy fake EDID structure
    //
  lpEDIDBuf->ulSize     = EDID_VER_1_STDLEN;
  lpEDIDBuf->ulFormatId = EDID_VER_13;
  MOVEMEMORY(lpEDIDBuf->aucEdidDataBuffer, &sTvEdidDataV1X, EDID_VER_1_STDLEN);

    // Check if high resolution supported
    //
  if((lpDisplayMaxModeInfo->ulPelsWidth >= 1024) &&
     (lpDisplayMaxModeInfo->ulPelsHeight >= 768)) //Never assume existing code working .
  {
    LPEDID_DATA_V1X pEdidV1x = ((LPEDID_DATA_V1X)lpEDIDBuf->aucEdidDataBuffer);
    pEdidV1x->aucEstablishedTimings[1] = 0x08;
  }

    // Generate and fill in the checksum byte.
    //
  for (ulTemp = 0, ulChecksum = 0; ulTemp < EDID_VER_1_STDLEN; ulTemp++)
  {
    ulChecksum += lpEDIDBuf->aucEdidDataBuffer[ulTemp];
  }

  if (0x00 != (ulChecksum & 0xFF))
  {
    lpEDIDBuf->aucEdidDataBuffer[EDID_VER_1_STDLEN - 1] 
        = (UCHAR)(0x100 - (ulChecksum & 0xFF));
  }

  DALDEBUG((DALDBG_ENTRY_EXIT, "bFakeTvEdidData - Exit"));

  return TRUE;
} // bFakeTvEdidData()

/******************************Public*Routine******************************\
* BOOL bDDCBlockAccess
*
* This function allows caller to access the I2C bus.  It writes the input
* and read the data on the bus.  The size of data to be read is inputed by
* caller. 
\**************************************************************************/
BOOL 
bDDCBlockAccess(
  LPHW_DAL_EXTENSION  lpHDE, 
  LPDEVGDO            lpDisplay,
  ULONG               ulFunction,
  ULONG               ulOption,
  ULONG               ulInputSize,
  LPUCHAR             lpInputBuf,
  LPULONG             lpulOutputSize,
  LPUCHAR             lpOutputBuf    )
{
  BOOL            bRet;
  ULONG           ulCount;
  PFNDDCREADLINE  pfnReadLine  = lpDisplay->lpHWED->pfnDDC_I2C_ReadLine;
  PFNDDCWRITELINE pfnWriteLine = lpDisplay->lpHWED->pfnDDC_I2C_WriteLine;

  // in order to support DDC2Ci, GDO must support DDC primitive functions
  if (!bUseDalBasedDdc(lpDisplay))
  {
    *lpulOutputSize = 0;
    return FALSE;
  }

  // We need the establish the correct I2C bus.  If it does not, call bGetEdidData
  // function to have it established.
  if (!(lpDisplay->ulFlags & GDO_CONNECTOR_ESTABLISHED))
  {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -