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

📄 adccontrol.c

📁 IT projecotr reference design.
💻 C
📖 第 1 页 / 共 3 页
字号:
    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 + -