📄 ddc.ccp
字号:
/* $Header: U:/archive/ce/mq200/driver/mq200drv/ext/ddc.ccv 1.2 May 15 1999 09:31:02 tzyywei $
*
* ========================================================================
* Copyright (c) 1999 by MediaQ, Incorporated.
* All Rights Reserved.
*
* Confidential and Proprietary to MediaQ, Incorporated.
* ========================================================================
*
* $Log: U:/archive/ce/mq200/driver/mq200drv/ext/ddc.ccv $
*
* Rev 1.2 May 15 1999 09:31:02 tzyywei
*change OutputDebugStringW to RETAILMSG
*
* Rev 1.1 Mar 30 1999 15:02:52 tzyywei
*update for JP demo.
*using GPIO to read HW switch for different mode setting.
*
* Rev 1.0 Feb 16 1999 14:39:40 yuhuan
*Initial revision.
*/
#ifdef MQ_CPP
///#include "mqcfg.h"
#include "..\mqhw2.h"
#else
#include <windows.h>
#endif
#include "ddc.h"
#define OLD_DEVICE 1
EDID_DATA EDID_Buffer;
#define ReportDDCcaps 0
#define ReadEDID 1
#define ReadVDIF 2
#define Fun_Read 0x00
#define Fun_No_Read 0x01
#define Fun_No_VerifyCheckSum 0x02
//#define Fun_VerifyCheckSum 0x03
///temp data
unsigned char *m_pMMIO;
//**************************************
// Local function prototype
//**************************************
void I2CNackWrite();
void I2CAckWrite();
BOOL I2CDataRequest(BYTE bStartAddr, BYTE *pBuffer, BYTE bLength, BYTE bAction);
BOOL I2CByteWrite(BYTE bData);
BOOL I2CBitWrite(BOOL BitData);
BYTE I2CByteRead();
BOOL I2CBitRead();
/// BOOL I2COemCheckSCLHigh();
/// BOOL I2COemInSDA();
/// void I2COemOut(ULONG SCL,ULONG SDA);
BOOL I2COut(ULONG SCL, ULONG SDA);
BOOL I2CStopService();
BOOL I2CStartService();
void I2CSetup();
BOOL ConfigChipReadVDIF(UINT iBlockNum, BYTE *pBuffer);
BOOL ConfigChipReadEDID(BYTE *pBuffer);
BOOL ConfigChipDDCCaps();
BOOL DDCCore(UINT ulFunction, UINT iBlockNum, BYTE *pBuffer);
void D2_DELAY();
void D1_DELAY();
void Wait_20_30ns();
UINT WAIT_COUNT=200;
UINT D1_TIME= 53;
UINT D2_TIME= 210;
#if 0
//****************************************************************************
// Test
//****************************************************************************
ULONG ulLoop = 100;
ULONG ulWait = 275;
BOOL DDCTest();
void DoDDCTest(ULONG ulFun)
{
BYTE bData;
BYTE pBuffer[128];
int i;
ULONG setvalue = 0;
int value=0;
switch(ulFun)
{
default:
break;
case 0:
//// DEBUGMSG(GPE_ZONE_INIT,(TEXT("DDCTest:\r\n")));
DDCTest();
break;
case 1:
//// DEBUGMSG(GPE_ZONE_INIT,(TEXT("SCL=0, SDA=1:\r\n")));
//I2COemOut(ULONG SCL,ULONG SDA)
pMQGC->I2COemOut(0L ,1L);
break;
case 2:
//// DEBUGMSG(GPE_ZONE_INIT,(TEXT("SCL=1, SDA=0:\r\n")));
//I2COemOut(ULONG SCL,ULONG SDA)
pMQGC->I2COemOut(1L ,0L);
break;
case 3:
//// DEBUGMSG(GPE_ZONE_INIT,(TEXT("SCL=1, SDA=1:\r\n")));
//I2COemOut(ULONG SCL,ULONG SDA)
pMQGC->I2COemOut(1L ,1L);
break;
case 4:
//// DEBUGMSG(GPE_ZONE_INIT,(TEXT("SCL=0, SDA=0:\r\n")));
//I2COemOut(ULONG SCL,ULONG SDA)
pMQGC->I2COemOut(0L ,0L);
break;
case 5:
//// DEBUGMSG(GPE_ZONE_INIT,(TEXT("Loop SCL=1, SDA=0,then SCL=1, SDA=1:\r\n")));
//I2COemOut(ULONG SCL,ULONG SDA)
for(i =0; i<(int)ulLoop; ++i)
{
pMQGC->I2COemOut(1L ,0L);
Wait_20_30ns();
// for(j=0; j<(int)ulWait; ++j)
// {}
pMQGC->I2COemOut(1L ,1L);
Wait_20_30ns();
// for(j=0; j<(int)ulWait; ++j)
// {}
}
break;
case 6:
DEBUGMSG(GPE_ZONE_INIT,(TEXT("Loop SCL=1, SDA=0,then SCL=1, SDA=1: cycle D1_TIME\r\n")));
for(i =0; i<(int)ulLoop; ++i)
{
pMQGC->I2COemOut(1L ,0L);
D1_DELAY();
pMQGC->I2COemOut(1L ,1L);
D1_DELAY();
}
DEBUGMSG(GPE_ZONE_INIT,(TEXT("Loop SCL=1, SDA=0,then SCL=1, SDA=1: cycle D2_TIME\r\n")));
for(i =0; i<(int)ulLoop; ++i)
{
pMQGC->I2COemOut(1L ,0L);
D2_DELAY();
pMQGC->I2COemOut(1L ,1L);
D2_DELAY();
}
break;
case 7:
RETAIL_MSG(1,(TEXT("Loop I2CStartServeice() function\r\n")));
for(i =0; i<(int)ulLoop; ++i)
{
I2CStartService();
}
break;
case 8:
DEBUGMSG(GPE_ZONE_INIT,(TEXT("Loop I2CStopService() function\r\n")));
for(i =0; i<(int)ulLoop; ++i)
{
I2CStopService();
}
break;
case 9:
DEBUGMSG(GPE_ZONE_INIT,(TEXT("I2CBitRead \r\n")));
I2CBitRead();
break;
case 10:
DEBUGMSG(GPE_ZONE_INIT,(TEXT("I2COemInSDA \r\n")));
pMQGC->I2COemInSDA();
break;
case 11:
I2CSetup(); // Ensure monitor is in DDC2 mode
break;
case 12:
I2CDataRequest(0x00, pBuffer, 0x00, Fun_No_Read); // setup address for display
break;
case 13:
I2CSetup(); // Ensure monitor is in DDC2 mode
I2CDataRequest(0x00, pBuffer, 0x00, Fun_No_Read); // setup address for display
bData = I2CByteRead();
I2CAckWrite(); // Send ACKnowledge
#if 0
if(bData)
{ // DDC Monitor Not Attached
I2CStopService();
return FALSE;
}
bData = I2CByteRead();
I2CNackWrite(); // Send Not Acknowledge
if(bData != 0xFF)
{ // DDC Monitor Not Attached
I2CStopService();
return FALSE;
}
I2CStopService();
#endif
break;
}
setvalue = (ulFun & 0xffff0000) >> 16;
value = (int)(ulFun & 0x0000ffff);
switch(setvalue)
{
default:
break;
case 1:
DEBUGMSG(GPE_ZONE_INIT,(TEXT("Set WAIT_COUNT:\r\n")));
WAIT_COUNT = value;
break;
case 2:
DEBUGMSG(GPE_ZONE_INIT,(TEXT("Set D1 WAIT COUNT:\r\n")));
D1_TIME = value;
break;
case 3:
DEBUGMSG(GPE_ZONE_INIT,(TEXT("Set D2 WAIT COUNT:\r\n")));
D1_TIME = value;
break;
}
}
void DumpHex(BYTE b)
{
DEBUGMSG(GPE_ZONE_INIT,(TEXT("0x%2x \r\n"),b));
}
#endif
BOOL DDCTest()
{
// DebugBreak();
//// DEBUGMSG(GPE_ZONE_INIT,(TEXT("Do ReportDDCcaps:\r\n")));
if(!DDCCore(ReportDDCcaps, 0 , NULL))
{
//Non DDC monitor
//// DEBUGMSG(GPE_ZONE_INIT,(TEXT("Fail ReportDDCcaps:\r\n")));
return FALSE;
}
//// DEBUGMSG(GPE_ZONE_INIT,(TEXT("Pass ReportDDCcaps:\r\n")));
//// DEBUGMSG(GPE_ZONE_INIT,(TEXT("Do ReadEDID:\r\n"));
if(!DDCCore(ReadEDID, 0, (BYTE *)&EDID_Buffer))
{
// Something wrong in the I2C
//// DEBUGMSG(GPE_ZONE_INIT,(TEXT("Fail ReadEDID:\r\n")));
return FALSE;
}
// Process EDID Data
//// DEBUGMSG(GPE_ZONE_INIT,(TEXT("Get ReadEDID:\r\n")));
#if 0
int i;
if(EDID_Buffer.Header[0] != 0x00 || EDID_Buffer.Header[7] != 0x00)
DEBUGMSG(GPE_ZONE_INIT,(TEXT("Bad Header:\r\n"));
else
DEBUGMSG(GPE_ZONE_INIT,(TEXT("Good Header:\r\n"));
for(i=1;i<7;++i)
{
if(EDID_Buffer.Header[i] != 0xff)
DEBUGMSG(GPE_ZONE_INIT,(TEXT("Bad Header:\r\n"));
else
DEBUGMSG(GPE_ZONE_INIT,(TEXT("Good Header:\r\n"));
}
BYTE *pByte = (BYTE *)(&EDID_Buffer);
for(i=0;i<128;++i,++pByte)
{
DumpHex(*pByte);
}
//return TRUE;
#endif
return TRUE;
}
//****************************************************************************
// DDCCore - VESA DDC core code, called by DDCHook from OEM tip
//****************************************************************************
BOOL DDCCore(UINT ulFunction, UINT iBlockNum, BYTE *pBuffer)
{
#ifdef MQ_CPP
if(!pMQGC)
pMQGC = (MQGC *)pGPE;
if(!pMQGC)
DebugBreak();
#endif
switch(ulFunction)
{
case ReportDDCcaps:
if(!ConfigChipDDCCaps())
return FALSE;
break;
case ReadEDID:
if(!ConfigChipReadEDID(pBuffer))
return FALSE;
break;
case ReadVDIF:
if(!ConfigChipReadVDIF(iBlockNum, pBuffer))
return FALSE;
break;
default:
break;
}
return TRUE;
}
//****************************************************************************
// ConfigChipDDCCaps - Determine capabilites of host and display.
//****************************************************************************
BOOL ConfigChipDDCCaps()
{
BYTE bData;
BYTE pBuffer[128];
I2CSetup(); // Ensure monitor is in DDC2 mode
I2CDataRequest(0x00, pBuffer, 0x00, Fun_No_Read); // setup address for display
bData = I2CByteRead();
I2CAckWrite(); // Send ACKnowledge
if(bData)
{ // DDC Monitor Not Attached
I2CStopService();
return FALSE;
}
bData = I2CByteRead();
I2CNackWrite(); // Send Not Acknowledge
if(bData != 0xFF)
{ // DDC Monitor Not Attached
I2CStopService();
return FALSE;
}
I2CStopService();
return TRUE;
}
//****************************************************************************
// ConfigChipReadEDID - Read the EDID block from monitor.
//****************************************************************************
BOOL ConfigChipReadEDID(BYTE *pBuffer)
{
I2CSetup();
I2CDataRequest(0x00, pBuffer, 128, Fun_Read); // Setup word address for display.
// Assume 1 EDID block
return TRUE;
}
//****************************************************************************
// ConfigChipReadVDIF - Read the VDIF block from the monitor.
//****************************************************************************
BOOL ConfigChipReadVDIF(UINT iBlockNum, BYTE *pBuffer)
{
BYTE bData;
I2CSetup();
I2CDataRequest(0x80, pBuffer, 00, Fun_No_Read); // Setup word address for display.
// Assume 1 EDID block
bData = I2CByteRead(); // Check for DDC2
if(bData != 0x56) // Check for "V"
{
I2CStopService();
return FALSE;
}
I2CAckWrite(); // Send Acknowledge
bData = I2CByteRead();
I2CAckWrite(); // Send Acknowledge
if(bData != 0x44) // Check for "D"
{
I2CStopService();
return FALSE;
}
I2CDataRequest(iBlockNum*64 + 0x80, pBuffer, 64, Fun_Read | Fun_No_VerifyCheckSum); // Setup word address for display.
return TRUE;
}
//****************************************************************************
// I2CSetup - Allow one very long low clock pulse so that the
// monitor has time to switch to DDC2 mode.
//
//****************************************************************************
void I2CSetup()
{
I2COut(0,1); // SCL = LOW, SDA = HIGH
Sleep(50);
//// WaitForDisplay();
//// WaitForDisplay();
I2COut(1,1); // SCL = HIGH, SDA = HIGH
Sleep(50);
//// WaitForDisplay();
//// WaitForDisplay();
}
//****************************************************************************
// I2CStartService - Provide start sequence for tallking to i2c bus.
//****************************************************************************
BOOL I2CStartService()
{
I2COut(0,1); // SCL = LOW, SDA = HIGH
I2COut(1,1); // SCL = HIGH, SDA = HIGH
I2COut(1,0); // SCL = HIGH, SDA = LOW
I2COut(0,0); // SCL = LOW, SDA = LOW
return TRUE;
}
//****************************************************************************
// I2CStopService - Provide stop sequence to i2c bus.
//****************************************************************************
BOOL I2CStopService()
{
I2COut(0,0); // SCL = LOW, SDA = LOW
I2COut(1,0); // SCL = HIGH, SDA = LOW
I2COut(1,1); // SCL = HIGH, SDA = HIGH
D1_DELAY();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -