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

📄 mode_detect.c

📁 液晶显示器程序代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	

    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 + -