📄 drvauto.c
字号:
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006-2007 MStar Semiconductor, Inc.
// All rights reserved.
//
// Unless otherwise stipulated in writing, any and all information contained
// herein regardless in any format shall remain the sole proprietary of
// MStar Semiconductor Inc. and be kept in strict confidence
// (¨MStar Confidential Information〃) by the recipient.
// Any unauthorized act including without limitation unauthorized disclosure,
// copying, use, reproduction, sale, distribution, modification, disassembling,
// reverse engineering and compiling of the contents of MStar Confidential
// Information is unlawful and strictly prohibited. MStar hereby reserves the
// rights to any and all damages, losses, costs and expenses resulting therefrom.
//
// Description: Auto-tune subroutines.
//
///////////////////////////////////////////////////////////////////////////////
#define DRV_AUTO_C
/******************************************************************************/
/* Header Files */
/* ****************************************************************************/
#include <stdlib.h>
#include "debug.h"
#include "drvtimer.h"
#include "drvScaler.h"
#include "drvADC.h"
#include "drvMode.h"
#include "drvAuto.h"
#define AUTOMSG(x) //x
#define AUTOHTMSG(x) //x // Htotal
#define AUTOPOSMSG(x) //x // Position
/********************************************************************************/
/* Local */
/* ******************************************************************************/
#define AUTO_MIN_R 0
#define AUTO_MIN_G 0x01
#define AUTO_MIN_B 0x02
#define AUTO_MAX_R 0x03
#define AUTO_MAX_G 0x04
#define AUTO_MAX_B 0x05
/********************************************************************************/
/* Local Function Prototypes */
/********************************************************************************/
/********************************************************************************/
/* Functions */
/********************************************************************************/
//*************************************************************************
//Function name: Mdrv_Auto_Geometry
//Passing parameter:
// EN_AUTO_TUNE_TYPE enAutoTuneType: Auto function select
// MS_PCADC_MODESETTING_TYPE *pstModesetting: Current PC mode setting
// MS_ADC_SETTING * pstADCSetting: ADC setting of Current PC mode
//Return parameter:
// BOOLEAN: Success status. (If faile, return FALSE.)
//Description: Auto-tune for PC mode
//*************************************************************************
BOOLEAN MDrv_Auto_Geometry(EN_AUTO_TUNE_TYPE enAutoTuneType, MS_PCADC_MODESETTING_TYPE *pstModesetting, MS_ADC_SETTING *pstADCSetting)
{
U8 u8Bank; // bank buffer
U8 u8VSyncTime; // VSync time
BOOLEAN bAutoResult = TRUE;
u8Bank = MDrv_ReadByte( BK_SELECT_00 );
MDrv_WriteByte( BK_SELECT_00, REG_BANK_IP1F2 );
MDrv_WriteByte(BK_SC_IP1F2_0E_L, 0x11); // enable auto gain function
printf("\r\nMDrv_Auto_Geometry(0x%bx)", enAutoTuneType);
u8VSyncTime = MDrv_Scaler_CalculateVSyncTime(g_wVerticalTotal, g_wHorizontalPeriod); // get VSync time
#if (!FAST_AUTO_TUNE)
// auto position valid data theshold
if(enAutoTuneType & AUTO_TUNE_VALID_DATA)
{
if(MDrv_Auto_SetValidData(u8VSyncTime) == FALSE)
{
AUTOMSG(printf("AutoValidData failed\n");)
bAutoResult = FALSE;
}
else // fixed valid data
{
MDrv_WriteByte(BK_SC_IP1F2_10_H, 0x40); // set valid data threshold
}
}
#else
MDrv_WriteByte(BK_SC_IP1F2_10_H, 0x40); // set valid data threshold
#endif
// auto horizontal total
if(enAutoTuneType & AUTO_TUNE_FREQ)
{
if(MDrv_Auto_TuneHTotal(u8VSyncTime, pstModesetting) == FALSE)
{
AUTOHTMSG(printf("AutoHtt failed\n");)
bAutoResult = FALSE;
}
}
// auto phase
if(enAutoTuneType & AUTO_TUNE_PHASE)
{
if(MDrv_Auto_TunePhase(u8VSyncTime, pstModesetting) == FALSE)
{
AUTOMSG(printf("AutoPhase failed\n");)
bAutoResult = FALSE;
}
}
// auto position
if(enAutoTuneType & AUTO_TUNE_POSITION)
{
if(MDrv_Auto_TunePosition(u8VSyncTime, pstModesetting) == FALSE)
{
AUTOMSG(printf("AutoPosition failed\n");)
bAutoResult = FALSE;
}
}
MDrv_WriteByte(BK_SC_IP1F2_0E_L, 0x11); // enable auto gain function
// auto RGB offset
if(enAutoTuneType & AUTO_TUNE_RGB_OFFSET)
{
if(MDrv_Auto_TuneOffset(u8VSyncTime, pstADCSetting) == FALSE)
{
AUTOMSG(printf("AutoOffset failed\n");)
bAutoResult = FALSE;
}
} // auto-tune ADC offset
// auto RGB gain
if(enAutoTuneType & AUTO_TUNE_RGB_GAIN)
{
if(MDrv_Auto_TuneGain(u8VSyncTime, pstADCSetting) == FALSE)
{
AUTOMSG(printf("AutoGain failed\n");)
bAutoResult = FALSE;
}
} // auto-tune ADC gain
if(enAutoTuneType & AUTO_TUNE_YUV_COLOR)
{
if(MDrv_Auto_ColorYUV(u8VSyncTime, pstADCSetting) == FALSE)
{
bAutoResult = FALSE;
}
} // auto-tune ADC gain
MDrv_WriteByte(BK_SC_IP1F2_0E_L, 0x00); // disable auto gain function
MDrv_WriteByte(BK_SC_IP1F2_10_H, 0x40); // set valid data threshold
MDrv_WriteByte( BK_SELECT_00, u8Bank );
AUTOMSG(printf("Offset R=0x%bx,G=0x%bx,B=0x%bx\n",
pstADCSetting->u8RedOffset,
pstADCSetting->u8GreenOffset,
pstADCSetting->u8BlueOffset);)
AUTOMSG(printf("Gain R=0x%bx,G=0x%bx,B=0x%bx\n",
pstADCSetting->u8RedGain,
pstADCSetting->u8GreenGain,
pstADCSetting->u8BlueGain);)
return bAutoResult;
}
//*************************************************************************
//Function name: MDrv_Auto_CheckSyncLoss
//Passing parameter: NO
//Return parameter:
// BOOLEAN: If PC mode change, return TRUE.
//Description: Check PC mode change when auto-tune executive.
//*************************************************************************
BOOLEAN MDrv_Auto_CheckSyncLoss(void)
{
U16 u16SyncCounter;
BOOLEAN bResult = FALSE;
if((MDrv_Scaler_GetInputSyncStatus() & MD_SYNC_LOSS) != 0)
{
bResult = TRUE;
}
// check H/VSync change
// HSync
u16SyncCounter = MDrv_Scaler_GetHorizontalPeriod();
if(abs(u16SyncCounter - g_wHorizontalPeriod) > MD_HPERIOD_TORLANCE)
{
bResult = TRUE;
}
// VSync
u16SyncCounter = MDrv_Scaler_GetVerticalTotal();
if(abs(u16SyncCounter - g_wVerticalTotal) > MD_VTOTAL_TORLANCE)
{
bResult = TRUE;
}
if(bResult)
{
g_u8CurrentSyncStatus |= MD_SYNC_LOSS;
g_bInputTimingChange = TRUE;
}
return bResult;
}
#if (!FAST_AUTO_TUNE)
//*************************************************************************
//Function name: MDrv_Auto_SetValidData
//Passing parameter:
// U8 u8VSyncTime : VSync time for delay
//Return parameter:
// BOOLEAN: If PC mode change, return FALSE.
//Description: Auto set valid data value.
//*************************************************************************
BOOLEAN MDrv_Auto_SetValidData(U8 u8VSyncTime)
{
U8 u8Bank;
U8 u8ValidData; // valide dataa value
U8 u8PhaseIndex; // phase index
U16 u16ComapreHPos; // compare horizontal position
u8Bank = MDrv_ReadByte( BK_SELECT_00 );
MDrv_WriteByte( BK_SELECT_00, REG_BANK_IP1F2 ); // select register bank scaler
for(u8ValidData = 0x04; u8ValidData != 0x10; u8ValidData++)
{
MDrv_WriteByteMask(BK_SC_IP1F2_10_H, u8ValidData << 4, 0xF0); // set valid data threshold
MDrv_ADC_SetADCPhase(0x00); // set phase
MDrv_Timer_Delayms(u8VSyncTime);
u16ComapreHPos = MDrv_Auto_GetPosition(BK_SC_IP1F2_13_L, u8VSyncTime); // horizontal position
for(u8PhaseIndex = 0x01; u8PhaseIndex != 0x10; u8PhaseIndex++)
{
MDrv_ADC_SetADCPhase(u8PhaseIndex * 4); // set phase
MDrv_Timer_Delayms(u8VSyncTime);
if(abs(u16ComapreHPos - MDrv_Auto_GetPosition(BK_SC_IP1F2_13_L, u8VSyncTime)) > 3) // check lose data
break;
if(MDrv_Auto_CheckSyncLoss()) // check Sync change
{
MDrv_WriteByte( BK_SELECT_00, u8Bank );
return FALSE;
}
} // for
if(u8PhaseIndex == 0x10)
break;
} // for
MDrv_WriteByte( BK_SELECT_00, u8Bank );
AUTOMSG(printf("Valid=0x%bx\n", u8ValidData << 4);)
return TRUE;
}
#endif
//*************************************************************************
//Function name: MDrv_Auto_WaitStatusReady
//Passing parameter:
// U8 u8RegIndex: Register index
// U8 u8RegMask: Status mask
//Return parameter: NO
//Description: Wait for status ready.
//*************************************************************************
void MDrv_Auto_WaitStatusReady(U16 u16RegIndex, U8 u8RegMask)
{
U16 u16Dummy = 1000; // loop dummy
while(!(MDrv_ReadByte(u16RegIndex) & u8RegMask) && (u16Dummy--)) ;
}
//*************************************************************************
//Function name: MDrv_Auto_GetPosition
//Passing parameter:
// U8 u8RegIndex: Register index
// U8 u8VSyncTime: VSync time
//Return parameter:
// U16: Position value.
//Description: Get position by register select
//*************************************************************************
U16 MDrv_Auto_GetPosition(U16 u16RegIndex, U8 u8VSyncTime)
{
U16 u16ComparePos=0,u16AutoPos; // position buffer
U8 u8Dummy = 20; // loop dummy
U8 u8Count = 0; // counter of compare alike
U8 u8Bank;
u8Bank = MDrv_ReadByte( BK_SELECT_00 );
MDrv_WriteByte( BK_SELECT_00, REG_BANK_IP1F2 );
while(u8Dummy--)
{
MDrv_Auto_WaitStatusReady(BK_SC_IP1F2_10_L, _BIT1); // auto position result ready
u16AutoPos = MDrv_Read2Byte(u16RegIndex) & 0xFFF; // get auto position
if(u16AutoPos == u16ComparePos) // match
u8Count++;
else // different
{
u8Count = 0; // reset counter
u16ComparePos = u16AutoPos; // reset position
}
if(u8Count == 3) // match counter ok
break;
#if ENABLE_INPUT_PIP2// kevin 071203
if(MDrv_Auto_CheckSyncLoss() && !IsVgaPipInUse()) // check no signal
{
MDrv_WriteByte( BK_SELECT_00, u8Bank );
AUTOPOSMSG(printf("\r\n NO signal"));
return -1; // return fail
}
#else
if(MDrv_Auto_CheckSyncLoss()) // check no signal
{
MDrv_WriteByte( BK_SELECT_00, u8Bank );
AUTOPOSMSG(printf("\r\n NO signal"));
return -1; // return fail
}
#endif
MDrv_Timer_Delayms(u8VSyncTime); // wait next frame
} // while
MDrv_WriteByte( BK_SELECT_00, u8Bank );
//AUTOPOSMSG(printf("\r\nRegIndex(%x)-> AutoVal(0x%x)", u16RegIndex, u16AutoPos));
return u16AutoPos;
}
//*************************************************************************
//Function name: MDrv_Auto_TunePosition
//Passing parameter:
// U8 u8VSyncTime : VSync time
// MS_PCADC_MODESETTING_TYPE *pstModesetting: Current PC mode setting
//Return parameter:
// BOOLEAN: Success status. (If faile, return FALSE.)
//Description: Auto-tune vertical and horizontal position for PC mode
//*************************************************************************
BOOLEAN MDrv_Auto_TunePosition(U8 u8VSyncTime, MS_PCADC_MODESETTING_TYPE *pstModesetting)
{
U16 u16PosBff; // position buffer
U8 u8Bank;
BOOLEAN bResult=TRUE;
u8Bank = MDrv_ReadByte( BK_SELECT_00 );
MDrv_WriteByte( BK_SELECT_00, REG_BANK_IP1F2 );
// horizotal position
u16PosBff = MDrv_Auto_GetPosition(BK_SC_IP1F2_13_L, u8VSyncTime); // auto horizontal start position detected result
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -