📄 adccontrol.c
字号:
userSavedModeTable[index].PhaseSetting_R = alc_stat.ASMPhaseSetting;
EE_PUTVAR( UserMachine.UserSettings[index], userSavedModeTable[index] );
}
/****************************************************************************/
/* adc calibration procedure */
/* !!! NOTE: this calibration procedure assumes an ADC with 8-bit gain and */
/* offset control registers */
/****************************************************************************/
int08 adccontrol_Calibrate( void )
{
ALC_StatusStruct alc_stat;
int32 red_avg, green_avg, blue_avg, i;
ALC_RGB16Struct minlevel, maxlevel;
int16 calibrated_value;
float fcal_value;
BOOL rgb;
uint16 nominalOffset, nominalGain;
ADC_LimitStruct limits;
ALC_GetStatus(&alc_stat);
/* Determine if ALF is locked to RGB graphics or YUV video */
if ((alc_stat.ASMPreviousEvent == ALC_ASM_LOCKED) &&
(alc_stat.ASMStatus == ALC_ALG_STATUS_AUTOLOCKED) &&
(!alc_stat.ASMIsYUV) &&
(!alc_stat.ASMIsComponentVideo) &&
(!alc_stat.RawIsInterlaced) )
{
rgb = TRUE; /* Source is graphics */
}
else if ((alc_stat.ASMPreviousEvent == ALC_ASM_LOCKED) &&
(alc_stat.ASMStatus == ALC_ALG_STATUS_AUTOLOCKED) &&
(alc_stat.ASMIsYUV) &&
(alc_stat.ASMIsComponentVideo) &&
(alc_stat.RawIsInterlaced) )
{
rgb = FALSE; /* Source is video */
}
else
{
dbmsg_trace( DBM_DPATH, "Current source type must be RGB graphics or YUV video for calibration\r\n" );
return FAIL;
}
nominalOffset = 0x3f;
if( ADC_GetOffsetLimits( &limits ) == PASS )
{
nominalOffset = (limits.LowerLimit + limits.UpperLimit)/2;
}
nominalGain = 0x7f;
if( ADC_GetGainLimits( &limits ) == PASS )
{
nominalGain = (limits.LowerLimit + limits.UpperLimit)/2;
}
if( rgb ) /* RGB graphics */
{
/* turn off autolock so it is not adjusting gain and offset while monitoring */
ALC_AutoLockAlgorithmControl(ALC_ALG_CTL_STOP);
/* delay to be sure a vsync occurs to turn off autolock */
RTA_TaskDelay(TMR_ConvertMSToTicks(50));
/* set up the ADC to nominal defaults */
ALC_SetGain(nominalGain, nominalGain, nominalGain);
ALC_SetOffset(nominalOffset, nominalOffset, nominalOffset);
/* set up the window to gather black level (offset cal procedure) */
if (ALC_SetLevelDetectWindow(alc_stat.ASMActiveLeftPixel + gpCalStructure->BlackWindow[0],
alc_stat.ASMActiveLeftPixel + gpCalStructure->BlackWindow[1],
alc_stat.ASMActiveTopLine + gpCalStructure->BlackWindow[2],
alc_stat.ASMActiveTopLine + gpCalStructure->BlackWindow[3]) != PASS)
{
/* print out error message */
dbmsg_trace( DBM_ALWAYS, "Calibration: Bad definition for black window.\r\n" );
return FAIL;
}
/* let a couple frames go by with this new window and ADC settings */
RTA_TaskDelay(TMR_ConvertMSToTicks(40));
/* initialize accumulators */
red_avg = 0;
green_avg = 0;
blue_avg = 0;
/* get the levels 16 times so we can calculate an average */
for (i=0; i<16; i++)
{
ALC_GetRGBLevels(&minlevel, &maxlevel);
red_avg = red_avg + minlevel.Red + maxlevel.Red;
green_avg = green_avg + minlevel.Green + maxlevel.Green;
blue_avg = blue_avg + minlevel.Blue + maxlevel.Blue;
RTA_TaskDelay(TMR_ConvertMSToTicks(21));
}
/* find the actual average */
red_avg /= 32;
green_avg /= 32;
blue_avg /= 32;
calibrated_value = (16*4 - red_avg)/4 + nominalOffset;
/* print out the calibrated value */
dbmsg_ftrace( DBM_DPATH, "Calibration: Red average color value is 0x%X.\r\n" , red_avg );
dbmsg_ftrace( DBM_DPATH, "Calibration: Red calibrated offset value is 0x%X.\r\n", calibrated_value );
/* store the value if it is in range */
if ((calibrated_value >= (nominalOffset * 6/10)) && (calibrated_value < (nominalOffset * 14/10)))
{
EE_PUTVAR( UserMachine.Cal_Data.RedOffset, calibrated_value );
}
else
{
dbmsg_trace( DBM_ALWAYS, "Calibration: Red offset out of range!\r\n" );
}
calibrated_value = (16*4 - green_avg)/4 + nominalOffset;
/* print out the calibrated value */
dbmsg_ftrace( DBM_DPATH, "Calibration: Green average color value is 0x%X.\r\n" , green_avg );
dbmsg_ftrace( DBM_DPATH, "Calibration: Green calibrated offset value is 0x%X.\r\n", calibrated_value );
/* store the value if it is in range */
if ((calibrated_value >= (nominalOffset * 6/10)) && (calibrated_value < (nominalOffset * 14/10)))
{
EE_PUTVAR( UserMachine.Cal_Data.GreenOffset, calibrated_value );
}
else
{
dbmsg_trace( DBM_ALWAYS, "Calibration: Green offset out of range!\r\n" );
}
calibrated_value = (16*4 - blue_avg)/4 + nominalOffset;
/* print out the calibrated value */
dbmsg_ftrace( DBM_DPATH, "Calibration: Blue average color value is 0x%X.\r\n" , blue_avg );
dbmsg_ftrace( DBM_DPATH, "Calibration: Blue calibrated offset value is 0x%X.\r\n", calibrated_value );
/* store the valueif it is in range */
if ((calibrated_value >= (nominalOffset * 6/10)) && (calibrated_value < (nominalOffset * 14/10)))
{
EE_PUTVAR( UserMachine.Cal_Data.BlueOffset, calibrated_value );
}
else
{
dbmsg_trace( DBM_ALWAYS, "Calibration: Blue offset out of range!\r\n" );
}
/* set up window to gather white level (gain cal procedure) */
if (ALC_SetLevelDetectWindow(alc_stat.ASMActiveLeftPixel + gpCalStructure->WhiteWindow[0],
alc_stat.ASMActiveLeftPixel + gpCalStructure->WhiteWindow[1],
alc_stat.ASMActiveTopLine + gpCalStructure->WhiteWindow[2],
alc_stat.ASMActiveTopLine + gpCalStructure->WhiteWindow[3]) != PASS)
{
/* print out error message */
dbmsg_trace( DBM_ALWAYS, "Calibration: Bad definition for white window.\r\n" );
return FAIL;
}
/* let a couple frames go by with this new window and ADC settings */
RTA_TaskDelay(TMR_ConvertMSToTicks(40));
/* initialize accumulators */
red_avg = 0;
green_avg = 0;
blue_avg = 0;
/* get the levels 16 times so we can calculate an average */
for (i=0; i<16; i++)
{
ALC_GetRGBLevels(&minlevel, &maxlevel);
red_avg = red_avg + minlevel.Red + maxlevel.Red;
green_avg = green_avg + minlevel.Green + maxlevel.Green;
blue_avg = blue_avg + minlevel.Blue + maxlevel.Blue;
RTA_TaskDelay(TMR_ConvertMSToTicks(21));
}
/* find the actual average */
red_avg /= 32;
green_avg /= 32;
blue_avg /= 32;
fcal_value = (240*4/(float)red_avg) * nominalGain;
calibrated_value = (int16)fcal_value;
/* print out the calibrated value */
dbmsg_ftrace( DBM_DPATH, "Calibration: Red average color value is 0x%X.\r\n" , red_avg );
dbmsg_ftrace( DBM_DPATH, "Calibration: Red calibrated gain value is 0x%X.\r\n", calibrated_value );
/* store the value if it is in range */
if ((calibrated_value >= (nominalGain * 6/10)) && (calibrated_value < (nominalGain * 14/10)))
{
EE_PUTVAR( UserMachine.Cal_Data.RedGain, calibrated_value );
}
else
{
dbmsg_trace( DBM_ALWAYS, "Calibration: Red gain out of range!\r\n" );
}
fcal_value = (240*4/(float)green_avg) * nominalGain;
calibrated_value = (int16)fcal_value;
/* print out the calibrated value */
dbmsg_ftrace( DBM_DPATH, "Calibration: Green average color value is 0x%X.\r\n" , green_avg );
dbmsg_ftrace( DBM_DPATH, "Calibration: Green calibrated gain value is 0x%X.\r\n", calibrated_value );
/* store the value if it is in range */
if ((calibrated_value >= (nominalGain * 6/10)) && (calibrated_value < (nominalGain * 14/10)))
{
EE_PUTVAR( UserMachine.Cal_Data.GreenGain, calibrated_value );
}
else
{
dbmsg_trace( DBM_ALWAYS, "Calibration: Green gain out of range!\r\n" );
}
fcal_value = (240*4/(float)blue_avg) * nominalGain;
calibrated_value = (int16)fcal_value;
/* print out the calibrated value */
dbmsg_ftrace( DBM_DPATH, "Calibration: Blue average color value is 0x%X.\r\n" , blue_avg );
dbmsg_ftrace( DBM_DPATH, "Calibration: Blue calibrated gain value is 0x%X.\r\n", calibrated_value );
/* store the value if it is in range */
if ((calibrated_value >= (nominalGain * 6/10)) && (calibrated_value < (nominalGain * 14/10)))
{
EE_PUTVAR( UserMachine.Cal_Data.BlueGain, calibrated_value );
}
else
{
dbmsg_trace( DBM_ALWAYS, "Calibration: Blue gain out of range!\r\n" );
}
}
else /* YUV video calibration */
{
/* turn off autolock so it is not adjusting gain and offset while monitoring */
ALC_AutoLockAlgorithmControl(ALC_ALG_CTL_STOP);
/* delay to be sure a vsync occurs to turn off autolock */
RTA_TaskDelay(TMR_ConvertMSToTicks(50));
/* set up the ADC to nominal defaults */
ALC_SetGain(nominalGain, nominalGain, nominalGain);
ALC_SetOffset(nominalOffset, nominalOffset, nominalOffset);
/* set up window to gather white level (offset cal procedure) */
if (ALC_SetLevelDetectWindow(alc_stat.ASMActiveLeftPixel + gpCalStructure->WhiteVideoWindow[0],
alc_stat.ASMActiveLeftPixel + gpCalStructure->WhiteVideoWindow[1],
alc_stat.ASMActiveTopLine + gpCalStructure->WhiteVideoWindow[2],
alc_stat.ASMActiveTopLine + gpCalStructure->WhiteVideoWindow[3]) != PASS)
{
/* print out error message */
dbmsg_trace( DBM_ALWAYS, "Calibration: Bad definition for YUV white window.\r\n" );
return FAIL;
}
/* let a couple frames go by with this new window and ADC settings */
RTA_TaskDelay(TMR_ConvertMSToTicks(40));
/* initialize accumulators */
red_avg = 0;
green_avg = 0;
blue_avg = 0;
/* get the levels 16 times so we can calculate an average */
for (i=0; i<16; i++)
{
ALC_GetRGBLevels(&minlevel, &maxlevel);
red_avg = red_avg + minlevel.Red + maxlevel.Red;
green_avg = green_avg + minlevel.Green + maxlevel.Green;
blue_avg = blue_avg + minlevel.Blue + maxlevel.Blue;
RTA_TaskDelay(TMR_ConvertMSToTicks(21));
}
/* find the actual average */
red_avg /= 32;
green_avg /= 32;
blue_avg /= 32;
/* calculate the calibrated value for red */
calibrated_value = (128*4 - red_avg)/4 + nominalOffset;
/* print out the calibrated value */
dbmsg_ftrace( DBM_DPATH, "Calibration: Red average color value is 0x%X.\r\n" , red_avg );
dbmsg_ftrace( DBM_DPATH, "Calibration: Cr calibrated offset value is 0x%X.\r\n", calibrated_value );
/* store the value if it is in range */
if ((calibrated_value >= (nominalOffset * 6/10)) && (calibrated_value < (nominalOffset * 14/10)))
{
EE_PUTVAR( UserMachine.Cal_Data.RedMidLevelOffset, calibrated_value );
}
else
{
dbmsg_trace( DBM_ALWAYS, "Calibration: Cr offset out of range!\r\n" );
}
/* calculate the calibrated value for blue */
calibrated_value = (128*4 - blue_avg)/4 + nominalOffset;
/* print out the calibrated value */
dbmsg_ftrace( DBM_DPATH, "Calibration: Blue average color value is 0x%X.\r\n" , blue_avg );
dbmsg_ftrace( DBM_DPATH, "Calibration: Cb calibrated offset value is 0x%X.\r\n", calibrated_value );
/* store the value if it is in range */
if ((calibrated_value >= (nominalOffset * 6/10)) && (calibrated_value < (nominalOffset * 14/10)))
{
EE_PUTVAR( UserMachine.Cal_Data.BlueMidLevelOffset, calibrated_value );
}
else
{
dbmsg_trace( DBM_ALWAYS, "Calibration: Cb offset out of range!" );
}
}
return PASS;
}
#ifdef __ADC_MST3762MW
/****************************************************************************/
/* Sync separator callback for AutoLock */
/****************************************************************************/
ALC_SyncTypeEnum adccontrol_SyncSepCallback(void)
{
uint08 type;
int08 cc;
ALC_SyncTypeEnum sync_type = ALC_NO_SYNC_SIGNALS;
cc = SYNC_GetSyncType( &type );
switch ( type )
{
case 2:
sync_type = ALC_SYNC_ON_GREEN;
break;
case 1:
sync_type = ALC_VERT_AND_HORIZ_SYNC;
break;
case 0:
case 3:
default:
sync_type = ALC_NO_SYNC_SIGNALS;
break;
}
return sync_type;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -