📄 ddcci.c
字号:
/*
$Workfile: ddcci.c $
$Revision: 1.27 $
$Date: May 17 2006 01:34:42 $
*/
//******************************************************************
//
// Copyright (C) 2002. GENESIS MICROCHIP INC.
// All rights reserved. No part of this program may be reproduced
//
// Genesis Microchip Corp., 2150 Gold Street
// Alviso, CA 95002 USA
// Genesis Microchip Inc., 165 Commerce Valley Dr. West
// Thornhill, Ontario, Canada, L3T 7V8
//
//================================================================
//
// MODULE: ddcci.c
//
//******************************************************************
#include "..\inc\all.h"
#include "mem.h"
#include "ddcci.h"
#define DEBUG_DDC2BI_VCP 0
//Note. Please pay attention to the way you use "msg" to debug DDCCI.
//Since Serial handler may share the same command buffer with DDC2Bi handler,
//your "msg" to GProbe may overwrite ddc2bi packet before you actually process
//a command. Use "msg" after ddc2bi command is processed or if it is saved in
//another buffer and before reply is send back i.e. before
//gm_DDC2Bi_SendMessage() function call.
#if DEBUG_DDC2BI_VCP & DEBUG_MSG
#define msg(a,b) gm_Print(a,b)
#else
#define msg(a,b)
#endif
#define rxBuffer (gDDCCI.buff)
#define txBuffer (gDDCCI.buff)
VCPFeaturePktType VCPFeature;
BYTE VCPPage;
BYTE CpStrID; // current capability string ID
WORD CpStrOffset; // current capability string offset
CommBufferType gDDCCI;
#define SWAP_BYTES(a) ((a >> 8) | (a << 8))
static BYTE _near DDC2Bi_VCP_ParseCommand(BYTE);
static void _near DDC2Bi_GetCapabilitiesRequest(void);
static void _near DDC2Bi_GetTimingReport(void);
static void _near DDC2Bi_EEPROMCmdHandler(void);
#if USE_ACC_ACM
static void _near windowControl(BYTE cmd, BYTE opcode);
#endif
//To make MCCS 2.0 Compliant - 14June04
//Definitions related to VCP response
#define DispFirmwareLevel 0x0201 //V1.2 REL
#define DispControllerType 0x02 //2 for Genesis
#define ApplnEnableKey 0xFFFF //define a key value here
#define OSD_Enable 0x02 //2 for enable OSD
#define OSD_Disable 0x01 //2 for disable OSD
#define VCP_Version 0x0002 //version 2, Revision 0
#define DispTechnologyType 0x03 //3 for TFT
#define NewControlVal 0x02 //2 for a new control value has been saved
#define NoNewControlVal 0x01 //1 for a NO new control value
//Supported Input source
#define AnalogVideo_1 0x01 //1 for Analog video(R/G/B) 1
#define AnalogVideo_2 0x02 //2 for Analog video(R/G/B) 2
#define DigitalVideo_1 0x03 //3 for Digital video(TMDS) 1
#define DigitalVideo_2 0x04 //4 for Digital video(TMDS) 2
#define CompositeVideo_1 0x05 //5 for Composite video 1
#define CompositeVideo_2 0x06 //6 for Composite video 2
#define SVideo_1 0x07 //7 for S video 1
#define SVideo_2 0x08 //8 for S video 2
#define Tuner_1 0x09 //9 for Tuner 1
#define Tuner_2 0x0A //10 for Tuner 2
#define Tuner_3 0x0B //11 for Tuner 3
#define ComponentVideo_1 0x0C //12 for Component video(YPrPb/YCrCb) 1
#define ComponentVideo_2 0x0D //13 for Component video(YPrPb/YCrCb) 2
#define ComponentVideo_3 0x0E //14 for Component video(YPrPb/YCrCb) 3
bit B_DDCCINewControlVal;
#if THEFT_DETERRENCE_SUPPORT
typedef struct TheftDeterrenceVCPCMDStruct
{
BYTE ACMode;
BYTE ACTimeout;
WORD ACPINLow;
WORD ACPINHigh;
}TheftDeterrenceVCPCMDType;
TheftDeterrenceVCPCMDType AC_VCPCommnd;
BYTE TD_TimerStart;
WORD ACPinLowByte;
WORD ACPinHighByte;
BYTE TD_State;
#endif
/*****************************************************************************\
FUNCTION: DDCCI_Handler
USAGE: Parses the received message, checks for syntax and executes the
command.
DESCRIPTION: Parses the received string, decodes the command and message
length, performs a syntax sanity check, and if gmd_OK executes the
command.
INPUT: -
OUTPUT: -
\*****************************************************************************/
void DDCCI_Handler (void)
{
BYTE readExpected = 1;
if(gm_DDC2Bi_GetStatus() != UNKNOWN_MSG_CMD) return;
gm_DDC2Bi_GetMessage((BYTE*)&gDDCCI);
switch(rxBuffer[COMMAND])
{
case DDC2B_CMD_DEBUG:
{
//check whether they are really GProbe Debug command,
//if yes, do nothing here so that other handler can process them;
//otherise, handle them separately
if(rxBuffer[COMMAND+1]==0x00 && rxBuffer[COMMAND+2]==0x00)
{
return;
}
else
{
//put code here to handle non-GProbe debug command if needed
}
break;
}
case DDC2B_CMD_GetVCPFeature:
{
//select Page0
VCPPage = 0;
VCPFeature.value = 0x0000;
VCPFeature.max = 0xFFFF;
VCPFeature.vcp_opcode = gDDCCI.DDC2BiGetVCPFeatureCmd.vcp_opcode;
gDDCCI.DDC2BiGetVCPFeature_ReplyCmd.result = DDC2Bi_VCP_ParseCommand(GET_VCP);
gDDCCI.DDC2BiGetVCPFeature_ReplyCmd.a_VCPFeature = VCPFeature;
//set command and length
gDDCCI.DDC2BiGetVCPFeature_ReplyCmd.length = 0x88;
gDDCCI.DDC2BiGetVCPFeature_ReplyCmd.command = DDC2B_CMD_GetVCPFeature_Reply;
msg("GetVCP opcode: %x",VCPFeature.vcp_opcode);
msg("GetVCP result: %x",gDDCCI.DDC2BiGetVCPFeature_ReplyCmd.result);
break;
}
case DDC2B_CMD_SetVCPFeature:
{
readExpected = 0; //no message back
//select Page0
VCPPage = 0;
VCPFeature.vcp_opcode = gDDCCI.DDC2BiSetVCPFeatureCmd.vcp_opcode;
VCPFeature.value = SWAP_BYTES(gDDCCI.DDC2BiSetVCPFeatureCmd.val);
DDC2Bi_VCP_ParseCommand(SET_VCP);
msg("SetVCP opcode: %x",VCPFeature.vcp_opcode);
msg("SetVCP val: %x",VCPFeature.value);
break;
}
case DDC2B_CMD_SaveCurrentSettings:
{
readExpected = 0; //no message back
//save current settings
// SaveUserPrefs();
SaveModeIndependentSettings();
UpdateModeDependentSettings();
SaveModeDependentSettings();
break;
}
case DDC2B_CMD_CapabilitiesRequest:
{
DDC2Bi_GetCapabilitiesRequest();
break;
}
case DDC2B_CMD_GetTimingReport:
{
DDC2Bi_GetTimingReport();
break;
}
case DDC2B_CMD_CUSTM_EEPROM:
{
DDC2Bi_EEPROMCmdHandler();
break;
}
case DDC2B_CMD_CUSTM_GetVCPPage:
{
gDDCCI.DDC2BiGetVCPPage_ReplyCmd.vcp_page = VCPPage;
gDDCCI.DDC2BiGetVCPPage_ReplyCmd.vcp_maxpage = 2;
//set command and length
txBuffer[LENGTH] = 0x83;
txBuffer[COMMAND] = DDC2B_CMD_CUSTM_GetVCPPage_Reply;
msg("GetVCPPage",0);
break;
}
//CUSTM custom commands
case DDC2B_CMD_CUSTM_GetPagedVCP:
{
VCPPage = gDDCCI.DDC2BiGetPagedVCPCmd.vcp_page;
VCPFeature.value = 0x0000;
VCPFeature.max = 0xFFFF;
VCPFeature.vcp_opcode = gDDCCI.DDC2BiGetPagedVCPCmd.vcp_opcode;
gDDCCI.DDC2BiGetPagedVCP_ReplyCmd.result = DDC2Bi_VCP_ParseCommand(GET_VCP);
gDDCCI.DDC2BiGetPagedVCP_ReplyCmd.vcp_page = VCPPage;
gDDCCI.DDC2BiGetPagedVCP_ReplyCmd.b_VCPFeature = VCPFeature;
//set command and length
txBuffer[LENGTH] = 0x89;
txBuffer[COMMAND] = DDC2B_CMD_CUSTM_GetPagedVCP_Reply;
msg("GetPagedVCP",0);
break;
}
case DDC2B_CMD_CUSTM_SetPagedVCP:
{
VCPPage = gDDCCI.DDC2BiSetPagedVCPCmd.vcp_page;
VCPFeature.vcp_opcode = gDDCCI.DDC2BiSetPagedVCPCmd.vcp_opcode;
VCPFeature.value = SWAP_BYTES(gDDCCI.DDC2BiSetPagedVCPCmd.value);
gDDCCI.DDC2BiGetPagedVCP_ReplyCmd.result = DDC2Bi_VCP_ParseCommand(SET_VCP);
gDDCCI.DDC2BiGetPagedVCP_ReplyCmd.vcp_page = VCPPage;
gDDCCI.DDC2BiGetPagedVCP_ReplyCmd.b_VCPFeature = VCPFeature;
//set command and length
txBuffer[LENGTH] = 0x89;
txBuffer[COMMAND] = DDC2B_CMD_CUSTM_SetPagedVCP_Reply;
msg("SetPagedVCP",0);
break;
}
default :
{
//error condition - unsupported ddc2bi command
readExpected = 0;
}
}
//if read expected create ddc2bi reply packet
if(!readExpected)
txBuffer[LENGTH] = 0x80; //respond with NULL packet
gm_DDC2Bi_SendMessage((BYTE*)&gDDCCI);
}
//Note 1. The VCP code uses data generated by the Workbench utility such as
//osd adjuster offsets. For example ADJV_Brightness.
//If you start your new osd project from the scratch and your project
//does not have all the adjuster supported by VCP code or you name it differently
//you'll be noticed by the compile errors. To fix it, please remove support for
//undefined in Workbench project adjuster or rename them either in the following code
//or Workbench project file. Search for all appearences of symbolic name with "ADJV_"
//prefix.
//
//Note 2. If you need to add or remove support of any adjusters of Page0 VCP commands,
//update VCPAdjOffset array and VCP_ADJ_NUM defined below.
VCPAdjOffsetType ROM VCPAdjOffset[] =
{
{ DDC2B_CMD_VCP_Clock, ADJV_HTotal },
{ DDC2B_CMD_VCP_Brightness,ADJV_Brightness },
{ DDC2B_CMD_VCP_Contrast, ADJV_Contrast },
{ DDC2B_CMD_VCP_HPosition, ADJV_HStart },
{ DDC2B_CMD_VCP_VPosition, ADJV_VStart },
{ DDC2B_CMD_VCP_ClockPhase,ADJV_HSyncPhase },
#if (USE_ACM_3D && defined( ADJUSTER_SIXAXISREDCOLOR_DECLARED ))
{ DDC2B_CMD_VCP_RED, ADJV_SixAxisRedColor },
{ DDC2B_CMD_VCP_GREEN, ADJV_SixAxisGreenColor },
{ DDC2B_CMD_VCP_BLUE, ADJV_SixAxisBlueColor },
{ DDC2B_CMD_VCP_CYAN, ADJV_SixAxisCyanColor},
{ DDC2B_CMD_VCP_MAGENDA, ADJV_SixAxisMagentaColor},
{ DDC2B_CMD_VCP_YELLOW, ADJV_SixAxisYellowColor },
#else
{ DDC2B_CMD_VCP_RED, ADJV_RedColor },
{ DDC2B_CMD_VCP_GREEN, ADJV_GreenColor },
{ DDC2B_CMD_VCP_BLUE, ADJV_BlueColor },
#endif
{ DDC2B_CMD_VCP_RedGain, ADJV_RedColor }, //To make MCCS 2.0 Compliant - 14June04
{ DDC2B_CMD_VCP_GreenGain, ADJV_GreenColor }, //To make MCCS 2.0 Compliant - 14June04
{ DDC2B_CMD_VCP_BlueGain, ADJV_BlueColor }, //To make MCCS 2.0 Compliant - 14June04
// for black level (MicroSoft Vista)
#ifdef UserPrefRBlacklevel
{ Red_Video_Black_Level, ADJV_RBlacklevel },
{ Green_Video_Black_Level, ADJV_GBlacklevel },
{ Blue_Video_Black_Level, ADJV_BBlacklevel }
#endif
};
#define VCP_ADJ_NUM (sizeof(VCPAdjOffset)/sizeof(VCPAdjOffsetType))
/*****************************************************************************\
FUNCTION: GetVCPAdjOffset
USAGE: Parses VCPAdjOffset array, finds the adjuster for a recieved
VCP opcode.
DESCRIPTION: Parses VCPAdjOffset array, finds the adjuster for a recieved
VCP opcode. It return the adjuster offset.
INPUT: - BYTE vcp opcode;
OUTPUT: - WORD adjuster offset
\*****************************************************************************/
static WORD _near GetVCPAdjOffset(BYTE vcp_opcode)
{
BYTE i;
for( i = 0; i < VCP_ADJ_NUM; i++ )
if (VCPAdjOffset[i].vcp_opcode == vcp_opcode)
return (VCPAdjOffset[i].adj_offset);
return 0xFFFF;
}
static BYTE _near dummy_hook(void)
{
return 1; //unsupported command
}
/*****************************************************************************\
FUNCTION: ProcessSetGetVCPAdjuster
USAGE: Process Get/Set VCPFeature and Get/Set Paged VCP requests
DESCRIPTION: Process Get/Set VCPFeature and Get/Set Paged VCP requests.
This routine is also responsible for filling common part of the
response packet body of VESA GetVCPFeature and CUSTM Get/SetPagedVCP
ddc2bi commands.
INPUT: - BYTE cmd : SET_VCP or GET_VCP
OUTPUT: - WORD adjuster offset
\*****************************************************************************/
static void _near ProcessSetGetVCPAdjuster(BYTE cmd, WORD offset)
{
WORD maxvalue;
VCPFeature.vcp_type = 0;
maxvalue = (WORD)(GetAdjusterMax(offset) - GetAdjusterMin(offset));
if(VCPFeature.value > maxvalue)
VCPFeature.value = maxvalue;
if(cmd == SET_VCP)
{
SetAdjusterValue(offset, (WORD)(VCPFeature.value + GetAdjusterMin(offset)));
}
VCPFeature.value = (WORD)(gm_GetAdjusterValue(offset) - GetAdjusterMin(offset));
VCPFeature.value = SWAP_BYTES(VCPFeature.value);
VCPFeature.max = SWAP_BYTES(maxvalue);
}
/*****************************************************************************\
FUNCTION: DDC2Bi_VCP_ParseCommand
USAGE: Parses the received VCP message, checks for syntax and executes the
command.
DESCRIPTION: Parses the received string, decodes the command and message
length, performs a syntax sanity check, and if gmd_OK executes the
command.
INPUT: - BYTE cmd : SET_VCP or GET_VCP
OUTPUT: - BYTE result code. 0 - no error, 1 unsupported command
\*****************************************************************************/
static BYTE _near DDC2Bi_VCP_ParseCommand(BYTE cmd)
{
BYTE ret = 0;
WORD offset;
#if THEFT_DETERRENCE_SUPPORT
BYTE retVal = 0;
#endif
VCPFeature.vcp_type = 1; //Momentary
if(VCPPage == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -