📄 mode_detect.c
字号:
return mode;
#else
mode = MODE_UNDEFINED0;
return 0;
#endif
}
/////////////////////////////////////////////////////////
//------------------ Detect VIDEO Mode ----------------//
/////////////////////////////////////////////////////////
void Detect_Video_Mode(void)
{
#if(VIDEO_CHIP != VDC_NONE)
I2CRead(ADDR_VIDEO, 0x1f, 0x01);
//------ Check Horizontal Lock & Frequency ------
if (0 == (Data[0] & 0x40))
{
if ((Data[0] & 0x20) && (0x01 != (ucAV_Mode & 0x0f)))
{
// Field rate changed to 60Hz
ucAV_Mode = 0x01;
ucMode_Found = MODE_NOSUPPORT;
ucMode_Times = 0;
Data[0] = 4;
Data[1] = ADDR_VIDEO;
Data[2] = 0x0e;
Data[3] = 0x08; // Start color search from NTSC-M
I2CWrite(Data);
}
else if ((0 == (Data[0] & 0x20)) && (0x02 != (ucAV_Mode & 0x02)))
{
// Field rate changed to 50Hz
ucAV_Mode = 0x02;
ucMode_Found = MODE_NOSUPPORT;
ucMode_Times = 0;
Data[0] = 4;
Data[1] = ADDR_VIDEO;
Data[2] = 0x0e;
Data[3] = 0x08; // Start color search from PAL-BDGHI
I2CWrite(Data);
}
else
{
//------ Check Lock Color ------
if (0x01 == (Data[0] & 0x01))
{
// Lock Color
if (ucAV_Mode & 0x01)
{
if (MODE_VIDEO60HZ == ucMode_Found)
{
ucMode_Times ++;
}
else
{
ucMode_Found = MODE_VIDEO60HZ;
ucMode_Times = 0;
}
}
else
{
if (MODE_VIDEO50HZ == ucMode_Found)
{
ucMode_Times ++;
}
else
{
ucMode_Found = MODE_VIDEO50HZ;
ucMode_Times = 0;
}
}
}
else
{
// Non Lock Color
if (MODE_NOSUPPORT != ucMode_Found)
{
ucMode_Found = MODE_NOSUPPORT;
ucMode_Times = 0;
}
Data[0] = 4;
Data[1] = ADDR_VIDEO;
Data[2] = 0x0e;
if (0x03 == (ucAV_Mode & 0x03))
{
// SECAM -> PAL-BDGHI(50Hz)
Data[3] = 0x08;
I2CWrite(Data);
ucAV_Mode = 0x02;
}
else
{
if (ucMode_Times & 0x01) // Every 2-times , change color
{
switch (ucAV_Mode & 0x70)
{
case 0x00:
Data[3] = 0x18; // NTSC-4.43(50Hz) // PAL-4.43(60Hz)
I2CWrite(Data);
ucAV_Mode = (ucAV_Mode & 0x0f) | 0x10;
break;
case 0x10:
Data[3] = 0x28; // PAL-N(50Hz) // NTSC-4.43(60Hz)
I2CWrite(Data);
ucAV_Mode = (ucAV_Mode & 0x0f) | 0x20;
break;
case 0x20:
Data[3] = 0x38; // NTSC-N(50Hz) // PAL-M(60Hz)
I2CWrite(Data);
ucAV_Mode = (ucAV_Mode & 0x0f) | 0x30;
break;
case 0x30:
if (ucAV_Mode & 0x02)
{
// NTSC-N -> SECAM (50Hz)
Data[3] = 0x5c;
I2CWrite(Data);
ucAV_Mode = 0x03;
}
else
{
// PAL-M -> NTSC_M (60Hz)
Data[3] = 0x08;
I2CWrite(Data);
ucAV_Mode = ucAV_Mode & 0x0f | 0x00;
}
default:
break;
}//end of "switch (ucAV_Mode & 0x70)"
}//end of "if (ucMode_Times & 0x01)"
}//end of "if (0x03 == (ucAV_Mode & 0x03)) else"
}//end of "Non Lock color
}//end of "Check Lock Color"
}//end of "if (0==(Data[0] & 0x40))"
else
{
// Non Horizontal Lock
ucAV_Mode = 0;
if (ucMode_Found != MODE_NOSUPPORT)
{
ucMode_Found = MODE_NOSUPPORT;
ucMode_Times = 0;
}
}
//-------------Check result--------------
if (MODE_NOSUPPORT != ucMode_Found)
{
if (VIDEO_SEARCH_TIMES < ucMode_Times)
{
bLIGHT_PWR = LIGHT_OFF; // Turn off BackLight for reset display
RTDSetByte(HOSTCTRL_02, 0x40); // Wake RTD up
RTDOSDW(OSD_Reset); // Clear OSD
if (SOURCE_YUV == (stGUD1.INPUT_SOURCE & 0x07))
ucMode_Curr = (ucAV_Mode & 0x02) ? MODE_YUV50HZ : MODE_YUV60HZ;
else
ucMode_Curr = ucMode_Found;
ucMode_Times = 0;
bStable = 0; // bStable must be cleared when mode changed
Display_Video_Set();
}
}
else
{
ucMode_Times ++;
if (ucAV_Mode)
{
// Force to display although we cannot lock color
if (VIDEO_SEARCH_TIMES < ucMode_Times
&& (NO_COLOR_TIMES < ucMode_Times || SOURCE_YUV == (stGUD1.INPUT_SOURCE & 0x07)))
{
bLIGHT_PWR = LIGHT_OFF; // Turn off BackLight for reset display
RTDSetByte(HOSTCTRL_02, 0x40); // Wake RTD up
RTDOSDW(OSD_Reset); // Clear OSD
ucAV_Mode = (ucAV_Mode & 0x02) ? 0x82 : 0x81;
if (SOURCE_YUV != (stGUD1.INPUT_SOURCE & 0x07))
ucMode_Curr = (ucAV_Mode & 0x02) ? MODE_VIDEO50HZ : MODE_VIDEO60HZ;
else
ucMode_Curr = (ucAV_Mode & 0x02) ? MODE_YUV50HZ : MODE_YUV60HZ;
ucMode_Times = 0;
bStable = 0; // bStable must be cleared when mode changed
Display_Video_Set();
}
}
else
{
if (NO_MODE_TIMES < ucMode_Times)
{
bStable = 1; // Set bStable to 1 when signal timing is stable.
ucMode_Times = NO_MODE_TIMES - 1;
}
}
}
#else
Display_Video_Set();
#endif
}
//------------------- Check AV Mode -------------------//
void Check_Video_Mode(void)
{
#if(VIDEO_CHIP != VDC_NONE)
I2CRead(ADDR_VIDEO, 0x1f, 0x01);
// Check color
if (0 == (ucAV_Mode & 0x80))
{
if (0 == (Data[0] & 0x01)) ucMode_Curr = MODE_NOSIGNAL; // Color standard changed
}
else
{
if (0 == (Data[0] & 0x01))
{
ucMode_Times = 0;
}
else
{
// When we cannot lock color, we set color standard to PAL-BDGHI if field rate is 50Hz,
// and to NTSC-M if it is 60Hz.
// If we find color is locked, we should update ucAV_Mode to indicate we now get color.
if (VIDEO_SEARCH_TIMES < ++ucMode_Times) ucAV_Mode = ucAV_Mode & 0x0f;
}
}
// Check field rate
if (Data[0] & 0x40)
{
ucMode_Curr = MODE_NOSIGNAL;
}
else
{
if (ucAV_Mode & 0x02) // 50Hz
{
if (0x00 != (Data[0] & 0x20)) ucMode_Curr = MODE_NOSIGNAL;
}
else // 60Hz
{
if (0x00 == (Data[0] & 0x20)) ucMode_Curr = MODE_NOSIGNAL;
}
}
// Check result
if (MODE_NOSIGNAL == ucMode_Curr)
Reset_Mode();
else
bStable = 1; // Set bStable to 1 when signal timing is stable.
#endif
}
void Calculate_IVS2DVS_Delay(unsigned char integer, unsigned char fraction, unsigned int DVStart)
{
if ((usIPV_ACT_STA + integer) < (DVStart >> 6))
{
// You should never get into this code ....
usIPV_ACT_STA = ( DVStart >> 6) - integer;
RTDSetByte(IPV_ACT_STA_0A, (unsigned char)usIPV_ACT_STA);
RTDSetByte(IPV_ACT_STA_0A + 1, (unsigned char)(usIPV_ACT_STA >> 8));
}
((unsigned int*)Data)[0] = ((usIPV_ACT_STA + integer) << 6) + ((unsigned int)fraction << 6)/10 - DVStart;
ucDV_Delay = (unsigned char)(((unsigned int*)Data)[0] >> 6);
Data[6] = ((unsigned int*)Data)[0] - (ucDV_Delay << 6);
Data[6] = (unsigned long)usADC_Clock * Data[6] / 1024;//512;
RTDSetByte(FS_FT_DELAY_1E, Data[6]);
}
void Set_Dclk(unsigned int DispLen)
{
if (Mode_Preset[ucMode_Curr][3])
{
// Use preset DCLK M/N code
Data[0] = 6;
Data[1] = Y_INC;
Data[2] = DPLL_CTRL_D0;
Data[3] = 0x11;
Data[4] = (unsigned char)(Mode_Preset[ucMode_Curr][3] >> 8);
Data[5] = (unsigned char)Mode_Preset[ucMode_Curr][3];
Data[6] = 0;
RTDWrite(Data);
}
else
{
// if (VGA_Mode[ucMode_Curr][4])
// {
// ((unsigned int *)Data)[0] = (unsigned long)8 * usDH_Total * USER_MODE_NCODE * usDispLen
// / ((unsigned long)usIPV_ACT_LEN * VGA_Mode[ucMode_Curr][4]);
// }
// else
// {
((unsigned int *)Data)[0] = (unsigned long)8 * usDH_Total * USER_MODE_NCODE * DispLen
/ ((unsigned long)usIPV_ACT_LEN * usHsync);
// }
//Original Formula : DPM/Ich = 17.6 must be constant
//Ich = DPM * 10 / 176
//2*Ich = DPM * 20 / 176 , set D0[0] to 0, then I = 2 * Ich
//I = 2 * Ich = 2.5u + D0[3]*2.5u + D0[4]*5u + D0[5]*10u + D0[6]*20u + D0[7]*30u(A)
//2I = 4 * Ich = 5u + D0[3]*5u + D0[4]*10u + D0[5]*20u + D0[6]*40u + D0[7]*60u(A)
Data[15] = ((unsigned int *)Data)[0] >> 2;
Data[5] = (unsigned int)Data[15] * 40 / 176 - 5; //Calculate the 4*Ich,
Data[6] = 0x00;
if(Data[5] > 60)
{
Data[5] -= 60;
Data[6] |= 0x80;
}
if(Data[5] > 40)
{
Data[5] -= 40;
Data[6] |= 0x40;
}
if(Data[5] > 20)
{
Data[5] -= 20;
Data[6] |= 0x20;
}
if(Data[5] > 10)
{
Data[5] -= 10;
Data[6] |= 0x10;
}
if(Data[5] > 5)
{
Data[5] -= 5;
Data[6] |= 0x08;
}
Data[0] = 7;
Data[1] = Y_INC;
Data[2] = DPLL_CTRL_D0;
Data[3] = Data[6];
Data[4] = Data[15] - 2;
Data[5] = 0x10 | (USER_MODE_NCODE - 2);//Offset Frequency Direction set to Downward
//Data[5] = (USER_MODE_NCODE - 2);//Offset Frequency Direction set to Downward
Data[6] = 0x04;
Data[7] = 0;
RTDWrite(Data);
// ucDebug_Value0 = Data[4];
// ucDebug_Value1 = Data[5];
//More precise Dclk in KHz
((unsigned long*)Data)[0] = (unsigned long)24576000 / usIPV_ACT_LEN * DispLen / usHsync * usDH_Total ;
//((unsigned long*)Data)[0] = (unsigned long)49152000 / usIPV_ACT_LEN * usDispLen / usHsync * usDH_Total ;
//set M/N code Dclk
((unsigned long*)Data)[1] = (unsigned long)12288000 * (Data[15] + 1) / USER_MODE_NCODE;
//((unsigned long*)Data)[1] = (unsigned long)24576000 * (Data[15] + 1) / USER_MODE_NCODE;
((unsigned long*)Data)[2] = ((unsigned long*)Data)[1] - ((unsigned long*)Data)[0]; //Dclk offset
((unsigned long*)Data)[3] = ((unsigned long*)Data)[1] >> 15; //Offset resolution equal to (Dclk / 2^15)
((unsigned long*)Data)[3] = ((((unsigned long*)Data)[2] << 1)/ ((unsigned long*)Data)[3]) & 0x00000fff; //Calculate the Dclk offset
//((unsigned long*)Data)[3] = (((unsigned long*)Data)[2] / ((unsigned long*)Data)[3]) & 0x00000fff; //Calculate the Dclk offset
RTDSetByte(DCLK_OFFSET_LSB_9A,(unsigned char)((unsigned long*)Data)[3]); //Set the Dclk offset
// ucDebug_Value0 = (unsigned char)(((unsigned long*)Data)[3]);
//RTDSetBit(DCLK_OFFSET_MSB_9B,0xf0,(unsigned char)(((unsigned long*)Data)[3] >> 8) | 0x20);
RTDSetBit(DCLK_OFFSET_MSB_9B,0xf0,(unsigned char)(((unsigned long*)Data)[3] >> 8) | 0x20);
// ucDebug_Value1 = (unsigned char)((((unsigned long*)Data)[3] >> 8) | 0x20);
RTDSetBit(FX_LST_LEN_H_5A,0xff,0x08); //Enable DDS Spread Spectrum Output Function
RTDSetBit(DPLL_N_D2,0xff,0x20); //DPLL Spread Spectrum Enable
RTDSetBit(DPLL_FILTER_D3,0x7f,0x00); //Enable DPll output
}
}
void Initial_Mode(void)
{
unsigned char ucOption;
unsigned int usDispLen;
// bit 7 of ucMode_Curr : partial-V display.
// bit 6 of ucMode_Curr : select 720x350 or 720x400 for VGA-50Hz and VGA-60Hz
ucOption = ucMode_Curr & 0xc0;
ucMode_Curr = ucMode_Curr & 0x3f;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -