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

📄 dalddc.c

📁 此代码为WCE5.0下显示器的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    // this senario should not happen very offen unless there is no display
    // device connected before to the connector.  In this case, should
    // bDDCBlockAccess be called????
 
    EDID_BUFFER       sEDIDBuf;

    if (!bGetEdidData(lpHDE, lpDisplay, (LPEDID_BUFFER)&sEDIDBuf))
    {
      *lpulOutputSize = 0;
      return FALSE;
    }
  }

  switch (ulFunction)
  {
    case CWDDEDI_DISPLAY_DDCFN_READCLOCKLINE:
    {
      lpOutputBuf[0] = 0;
      if (pfnReadLine(lpDisplay->hGDO, DAL_DDC_I2C_LINE_SCL))
      {
        lpOutputBuf[0] = 1;
      }
      *lpulOutputSize = 1;
      break;
    }

    case CWDDEDI_DISPLAY_DDCFN_WRITECLOCKLINE:
    {
      if (lpInputBuf[0])
      {
        pfnWriteLine(lpDisplay->hGDO, 1, DAL_DDC_I2C_LINE_SCL);
      }
      else
      {
        pfnWriteLine(lpDisplay->hGDO, 0, DAL_DDC_I2C_LINE_SCL);
      }
      break;
    }

    case CWDDEDI_DISPLAY_DDCFN_READDATALINE:
    {
      lpOutputBuf[0] = 0;
      if (pfnReadLine(lpDisplay->hGDO, DAL_DDC_I2C_LINE_SDA))
      {
        lpOutputBuf[0] = 1;
      }
      *lpulOutputSize = 1;
      break;
    }

    case CWDDEDI_DISPLAY_DDCFN_WRITEDATALINE:
    {
      if (lpInputBuf[0])
      {
        pfnWriteLine(lpDisplay->hGDO, 1, DAL_DDC_I2C_LINE_SDA);
      }
      else
      {
        pfnWriteLine(lpDisplay->hGDO, 0, DAL_DDC_I2C_LINE_SDA);
      }
      break;
    }

    case CWDDEDI_DISPLAY_DDCFN_BLOCKACCESS:
    {
      if (CWDDEDI_DISPLAY_DDCOPT_SWITCHDDC2 & ulOption)
      {
        // This is a little fix that gets some older DDC monitors to respond
        // properly to DDC queries.  Set the clock line low, wait 15 ms then set
        // the clock line high.
        //
        pfnWriteLine(lpDisplay->hGDO, 0, DAL_DDC_I2C_LINE_SCL);
        DDC_DELAY_MILLISECONDS(15);
        pfnWriteLine(lpDisplay->hGDO, 1, DAL_DDC_I2C_LINE_SCL);

        // Initialize SDA and SCL lines to default state of released high (input).
        // Drive SCL low for 15ms to switch DDC2-capable monitor to DDC2 mode.
        //
        pfnWriteLine(lpDisplay->hGDO, 1, DAL_DDC_I2C_LINE_SDA);
        pfnWriteLine(lpDisplay->hGDO, 0, DAL_DDC_I2C_LINE_SCL);
        DDC_DELAY_MILLISECONDS(15);
        pfnWriteLine(lpDisplay->hGDO, 1, DAL_DDC_I2C_LINE_SCL);
  
        if (DDCWaitForClockLineHigh(lpDisplay) == FALSE)
        {
          DALDEBUG((DALDBG_DETAIL, "bDDCBlockAccess: Can't switch to DDC2"));
          return FALSE;
        }
      }

      // send start 
      // Try to start I2C bus a number of times. Should succeed every time,
      // otherwise fail. Really paranoid.
      bRet    = DDCStart(lpDisplay);
      ulCount = DDC_RETRIES;
      while ((bRet) && (ulCount > 0))
      {
        bRet = DDCStart(lpDisplay);
        ulCount--;
      }
      if (bRet == FALSE)
      {
        DDCStop(lpDisplay);
        return FALSE;
      }

      // send the body
      for (ulCount = 0; ulCount < ulInputSize; ulCount++)
      {
        if (FALSE == DDCWriteByte(lpDisplay, lpInputBuf[ulCount]))
        {
          DDCStop(lpDisplay);
          return FALSE;
        }

        DDC_I2C_DELAY();
        DDC_I2C_DELAY();
        DDC_I2C_DELAY();
        DDC_I2C_DELAY();
      }

      // check to see if we have to receive any data
      if (lpOutputBuf != NULL)
      {
        // read the data on I2C bus
        for (ulCount = 0; ulCount < *lpulOutputSize; ulCount++)
        {
          if (FALSE == (bRet = DDCReadByte(lpDisplay,
                                           lpOutputBuf + ulCount,
                                           ulCount < *lpulOutputSize - 1)))
          {
            break;
          }

          DDC_I2C_DELAY();
          DDC_I2C_DELAY();
          DDC_I2C_DELAY();
          DDC_I2C_DELAY();
        }
      }
      *lpulOutputSize = ulCount;

      // send stop
      DDCStop(lpDisplay);
      break;
    }

    default:
    {
      return FALSE;
    }
  }

  return TRUE;
}

/******************************Public*Routine******************************\
* BOOL bInformCVModChange
*
* This function allows caller to access the I2C bus.  It writes the input
* and read the data on the bus.  Since the dongle for Component video needs 
* set the I2C bus to outputs to HDTV/SDTV.
\**************************************************************************/
BOOL 
bInformCVModChange(
  LPHW_DAL_EXTENSION  lpHDE, 
  LPDEVGDO            lpDisplay,
  LPDEVMODE_INFO      lpMI
  )
{
  BOOL bRet ;
  
  UCHAR ucInput[DDC_NUM_BYTES];
  ULONG ulLength;
  UCHAR ucOutput;
  ULONG ulOutputSize =1;

  if (GDO_HOOK2_I2C_SUPPORT & lpDisplay->lpHWED->ulFunctionHooks2)
  {
    //ulLength is the actual Number of bytes for Get function.
    ulLength = (*lpDisplay->lpHWED->pfnGetSetI2CData)(lpDisplay->hGDO, &ucInput[0], DDC_NUM_BYTES, DAL_I2C_GET_DATA_FROM_GDO);
    if(0 ==ulLength)
     return FALSE;
  }
  else
    return FALSE; //Not support dongle.
  
  bRet = bDDCBlockAccess(lpHDE,
                         lpDisplay,
                         CWDDEDI_DISPLAY_DDCFN_BLOCKACCESS,
                         CWDDEDI_DISPLAY_DDCOPT_SWITCHDDC2,
                         ulLength,
                         &ucInput[0],
                         &ulOutputSize,
                         &ucOutput);


  return bRet;
}

/******************************Public*Routine******************************\
* BOOL FAR R6LCDGetEdidData(lpDisplayMaxModeInfo->ulPelsWidth,
*                           LPEDID_BUFFER lpEdidBuffer)
* This function is used to get emulated EDID data only for LCD.
*  
\**************************************************************************/

BOOL FAR bLCDGetFakeEdid(LPDEVGDO lpDisplay,
                         LPDEVMODE_INFO lpDisplayMaxModeInfo, 
                         LPEDID_BUFFER lpEDIDBuf)
{
  ULONG                  ulTemp,ulChecksum;
  LPEDID_STANDARD_TIMING lpStandardTiming;
  LPDEVMODE_INFO         lpMI;
  EDID_DETAILED_V1X      sDetailedTiming;
  BOOL                   bNeedAddDetailedTiming;
  LPEDID_DATA_V1X        lpEDID = (LPEDID_DATA_V1X)&lpEDIDBuf->aucEdidDataBuffer[0];
  ULONG                  i = 0;
  
  //MS supported Standard EDID mode
  DEVMODE_INFO aStandardModes[] =
  {
    {0,     640,  480, 0, 60},
    {0,     800,  600, 0, 60},
    {0,    1024,  768, 0, 60},
    {0,    1152,  864, 0, 60},
    {0,    1280, 1024, 0, 60},
    {0,    1600, 1200, 0, 60}
  };

  DALDEBUG((DALDBG_ENTRY_EXIT, "bLCDGetFakeEdid - Entry"));
  ZEROMEMORY((LPVOID)&lpEDIDBuf->aucEdidDataBuffer[0],sizeof(lpEDIDBuf->aucEdidDataBuffer));
  ZEROMEMORY((LPVOID)&sDetailedTiming, sizeof(EDID_DETAILED_V1X));

  bNeedAddDetailedTiming = TRUE;
  lpEDIDBuf->ulSize = sizeof(lpEDIDBuf->aucEdidDataBuffer);
  lpEDIDBuf->ulFormatId = EDID_VERSION_13;
 
  // Fill in EDID header.
  for (ulTemp = 1; ulTemp < 7; ulTemp++)
        lpEDID->aucHeader[ulTemp] = 0xFF;

  // Fill in necessary EDID fields.
  lpEDID->aucVendorID[0] = 0x36;       // MS_
  lpEDID->aucVendorID[1] = 0x7F;

  if(lpDisplayMaxModeInfo->ulDisplayFrequency == 60) //don't output standard timing if it is non_standard refresh rate panel.
  {
    switch (lpDisplayMaxModeInfo->ulPelsWidth)
    {
      case 1600:
        if (1200 == lpDisplayMaxModeInfo->ulPelsHeight)
        {
          lpEDID->aucVendorID[2] = 0x06;   // LCD 1600x1200
        }
        break;

      case 1280:
        if (1024 == lpDisplayMaxModeInfo->ulPelsHeight)
        {
          lpEDID->aucVendorID[2] = 0x05;   // LCD 1280x1024
        }
        break;

      case 1152:
        if(864 == lpDisplayMaxModeInfo->ulPelsHeight)
        {
          lpEDID->aucVendorID[2] = 0x04;   // LCD 1152x864
        }
        break;

      case 1024:
        if (768 == lpDisplayMaxModeInfo->ulPelsHeight)
        {
          lpEDID->aucVendorID[2] = 0x03;   // LCD 1024x768
        }
        break;

      case 800:
        if (600 == lpDisplayMaxModeInfo->ulPelsHeight)
        {
           lpEDID->aucVendorID[2] = 0x02;   // LCD 800x600
        }
        break;

      case 640:
        if (480 == lpDisplayMaxModeInfo->ulPelsHeight)
        {
           lpEDID->aucVendorID[2] = 0x01;   // LCD 640x480
        }
        break;

      default: //No entry in MS's.inf, but we still have support it!!
        break ;
    }
  }
  lpEDID->aucVersion[0] = 0x01;      //Version 1
  lpEDID->aucVersion[1] = 0x03;      //Revision 3
  
  lpEDID->aucBasicDisplayParameters [0] = 1;        // VideoInputDefinition - Digital
  lpEDID->aucBasicDisplayParameters [1] = 40;        // MaxHzImageSize in cm
  lpEDID->aucBasicDisplayParameters [2] = 30;        // MaxVtImageSize in cm
  lpEDID->aucBasicDisplayParameters [4] = 0xF0;      // FeatureSupport - DPMS and color display, 
                                                     
  if(lpDisplayMaxModeInfo->ulDisplayFrequency ==60)
  {
    // Fill in established timings.
    lpStandardTiming = (LPEDID_STANDARD_TIMING)&lpEDID->ausStandardTimings[0]; 
    lpMI = &aStandardModes[0];
  
    while((lpMI->ulPelsWidth <= lpDisplayMaxModeInfo->ulPelsWidth)&&
          (lpMI->ulPelsHeight <= lpDisplayMaxModeInfo->ulPelsHeight)&&
          (i < sizeof(aStandardModes)/sizeof(DEVMODE_INFO)))
    {
      lpStandardTiming ->ucHorizontalActive = (UCHAR)(lpMI->ulPelsWidth/8 -31);
      lpStandardTiming ->ucAspectAndRefreshRate = (UCHAR)(EDID_STANDARD_ASPECT_4_X_3 | 
                                               (lpDisplayMaxModeInfo->ulDisplayFrequency - 60));
      lpStandardTiming++;
      lpMI++;
      i++;
    }
    
    //Fill in established timings , here we assume LCD panel are all 60Hz!
  //if(lpDisplayMaxModeInfo->ulDisplayFrequency ==60)
  //{
    lpEDID->aucEstablishedTimings[0] |= EDID_ESTABLISHED_640_60;
    if(lpDisplayMaxModeInfo->ulPelsWidth >= 800)
    {
      lpEDID->aucEstablishedTimings[0] |= EDID_ESTABLISHED_800_60;
    }
    if(lpDisplayMaxModeInfo->ulPelsWidth >= 1024)
    {
      lpEDID->aucEstablishedTimings[1] |= EDID_ESTABLISHED_1024_60;
    }
  }
 
  //Fill in detailed timing for weired panel if Panel native mode is not supported by MS.

  for ( i = 0; i < sizeof(aStandardModes)/sizeof(DEVMODE_INFO); i++)
  {
      lpMI = &aStandardModes[i];
      
      if((lpDisplayMaxModeInfo ->ulPelsWidth == lpMI->ulPelsWidth)&&
         (lpDisplayMaxModeInfo ->ulPelsHeight== lpMI->ulPelsHeight)&&
         (lpDisplayMaxModeInfo->ulDisplayFrequency == lpMI->ulDisplayFrequency))
      {
        //Panel native mode is in the MS supported list, do noting. 
        bNeedAddDetailedTiming = FALSE;
        break;
      }
  }
  
  if(bNeedAddDetailedTiming)
  {
    DAL_CRTC_TIMING sTiming;
    ZEROMEMORY((LPDAL_CRTC_TIMING)&sTiming, sizeof(DAL_CRTC_TIMING));

    if(lpDisplay->lpHWED ->ulFunctionHooks2 & GDO_HOOK2_GETFIXEDDISPLAYMODETIMING)
    {
      if((*lpDisplay->lpHWED->pfnGetFixedDisplayModeTiming)(lpDisplay->hGDO, 
                                                            (LPDEVMODE_INFO)lpDisplayMaxModeInfo,
                                                            (LPDAL_CRTC_TIMING)&sTiming))
      {

        vDALTimingToDetailedTiming((LPDAL_CRTC_TIMING)&sTiming, (LPEDID_DETAILED_V1X)&sDetailedTiming);

        lpEDID->aucBasicDisplayParameters [4] |= 0x02; // perferred timing mode required for V1.3.
        //Only fill in the detailed timing when Panel mode is not MS supported 
        MOVEMEMORY((LPEDID_DETAILED_V1X) &lpEDID->EDIDDetailedTimings[0] ,(LPEDID_DETAILED_V1X)&sDetailedTiming, sizeof(EDID_DETAILED_V1X));
       
  
      }
    }
    
  }
  
  // Generate and fill in the checksum byte.
  for (ulTemp = 0, ulChecksum = 0; ulTemp < sizeof (EDID_DATA_V11); ulTemp++)
  {
     ulChecksum += lpEDIDBuf->aucEdidDataBuffer[ulTemp];
  }
  if (0x00 != (ulChecksum & 0xFF))
        lpEDIDBuf->aucEdidDataBuffer[--ulTemp] = (UCHAR)(0x100 - (ulChecksum & 0xFF));

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

  return TRUE;
}   // bLCDGetFakeEdid()
/******************************Public*Routine******************************\
* VOID    vDALTimingToDetailedTiming
* INPUT:  lpCrtcTiming
* OUTPUT: lpEdidDetailedTiming
* RETURN: NONE
\**************************************************************************/
VOID vDALTimingToDetailedTiming(LPDAL_CRTC_TIMING lpCrtcTiming, LPEDID_DETAILED_V1X lpEdidDetailedTiming)
{
  USHORT usHBlank;
  USHORT usVBlank;
  USHORT usHSyncOffset;
  USHORT usVSyncOffset;

  
  DALDEBUG((DALDBG_ENTRY_EXIT, "vDALTimingToDetailedTiming - Entry"));
  
  usHBlank = lpCrtcTiming->usHorizontalTotal -lpCrtcTiming->usHorizontalDisplay;
  usVBlank = lpCrtcTiming->usVerticalTotal -lpCrtcTiming->usVerticalDisplay;
  usHSyncOffset = lpCrtcTiming->usHorizontalSyncStart - lpCrtcTiming->usHorizontalDisplay;
  usVSyncOffset = lpCrtcTiming->usVerticalSyncStart - lpCrtcTiming->usVerticalDisplay;

  //Translate to Edid Detailed timing.
  lpEdidDetailedTiming ->usPixelClock       = lpCrtcTiming->usPixelClock;

  lpEdidDetailedTiming ->ucHActiveL8        = (UCHAR) (lpCrtcTiming->usHorizontalDisplay & 0x00FF); 
  lpEdidDetailedTiming ->ucHBlankingL8      = (UCHAR) (usHBlank & 0x00FF);
  lpEdidDetailedTiming ->ucHActive_HBlankU4 = (UCHAR) ((lpCrtcTiming->usHorizontalDisplay & 0x0F00)>>4|
                                                       (usHBlank & 0x0F00)>>8); 
  lpEdidDetailedTiming ->ucVActiveL8        = (UCHAR) (lpCrtcTiming->usVerticalDisplay & 0x00FF);
  lpEdidDetailedTiming ->ucVBlankingL8      = (UCHAR) (usVBlank  & 0x00FF);
  lpEdidDetailedTiming ->ucVActive_VBlankU4 = (UCHAR) ((lpCrtcTiming->usVerticalDisplay & 0x0F00)>>4|
                                                       (usVBlank  & 0x0F00)>>8); 

  lpEdidDetailedTiming ->ucHSyncOffsetL8    = (UCHAR) (usHSyncOffset & 0x00FF);
  lpEdidDetailedTiming ->ucHSyncWidthL8     = (UCHAR) (lpCrtcTiming->usHorizontalSyncWidth  & 0x00FF);  

  lpEdidDetailedTiming ->ucVSyncOffset_VSyncWidthL4 = (UCHAR)((usVSyncOffset & 0x0F00)>>4|
                                                              (lpCrtcTiming->usVerticalSyncWidth  & 0x0F00)>>8); 

  lpEdidDetailedTiming ->ucHSyncOffset_HSyncWidth_VSyncOffset_VSyncWidth  = (UCHAR)((usHSyncOffset & 0x0300) >>2|
                                                                             (lpCrtcTiming->usHorizontalSyncWidth  & 0x0300) >>4|
                                                                             (usVSyncOffset & 0x0300) >>6|
                                                                             (lpCrtcTiming->usVerticalSyncWidth  & 0x0300) >>8);
  lpEdidDetailedTiming ->ucHImageSize       = 0;
  lpEdidDetailedTiming ->ucVImageSize       = 0;
  lpEdidDetailedTiming ->ucHVImageSizeU4    = 0;

  lpEdidDetailedTiming ->ucHBorder          = (UCHAR)lpCrtcTiming->usHorizontalOverscanRight; //For overscan
  lpEdidDetailedTiming ->ucVBorder          = (UCHAR)lpCrtcTiming->usVerticalOverscanBottom;

  if(lpCrtcTiming->usFlags &USE_DEFAULT_POLARITY)
  {
    if(lpCrtcTiming->usFlags & CRTC_H_SYNC_POLARITY)
    {
      lpEdidDetailedTiming ->ucFlags |= EDID_DETAILED_V1x_FLAG_BIT1;
    }
    if(lpCrtcTiming->usFlags & CRTC_V_SYNC_POLARITY )
    {
      lpEdidDetailedTiming ->ucFlags |= EDID_DETAILED_V1x_FLAG_BIT1;
    }
  
    lpEdidDetailedTiming ->ucFlags |= EDID_DETAILED_V1x_FLAG_BIT3|EDID_DETAILED_V1x_FLAG_BIT4; //Digital seperated.

  }
  if(lpCrtcTiming->usFlags & CRTC_INTERLACED)  
  {
    lpEdidDetailedTiming ->ucFlags |= EDID_DETAILED_V1x_FLAG_INTERLACED;
  }
  
  DALDEBUG((DALDBG_ENTRY_EXIT, "vDALTimingToDetailedTiming - Entry"));
  return;

}

⌨️ 快捷键说明

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