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

📄 mode_detect.c

📁 Realtek 公司的RTD2523A芯片原厂source code,没有被修改过的。
💻 C
📖 第 1 页 / 共 5 页
字号:

    PowerDown_ADC();

    // Set user's ADC gain and offset settings
    SetADC_GainOffset();

    Set_Gamma();
    Set_Dithering();
    Set_Bright_Contrast();

    // Read mode default settings from EEPROM
    Load_MUD(ucMode_Curr);

	// Read auto result from EEPROM
    I2CRead(ADDR_EROM2, (ucMode_Curr - 1) << 2, 0x03);

    // Check auto result range
    ucAUTO_HPOS = (128 + 100) < Data[0] ? 128 : (128 - 100) > Data[0] ? 128 : Data[0];
    ucAUTO_VPOS = (128 + 32) < Data[1] ? 128 : (128 - 32) > Data[1] ? 128 : Data[1];
    ucAUTO_SCLK = (128 + 100) < Data[2] ? 128 : (128 - 100) > Data[2] ? 128 : Data[2];

    // Check Clock within adjustable range
    if (28 > stMUD.CLOCK || 228 < stMUD.CLOCK)
        stMUD.CLOCK = 128;

    if (ucAUTO_SCLK > ((unsigned int)stMUD.CLOCK + 50) || ((unsigned int)ucAUTO_SCLK + 50) < stMUD.CLOCK)
        stMUD.CLOCK = ucAUTO_SCLK;
    
    // For jitter adjust
    ucPE_Level      = 0;
    ucI_Code        = 0;

    // Set Clock 
    Set_Clock();
    
    // Calculate the P correction and I correction according to the CE value
    Delay_Xms(6);
	
    if (0 == ucCE_Value)
    {
        RTDRead(I_CODE_MB_CA, 1, N_INC);
        RTDSetByte(I_CODE_MB_CA, 0x0d);
        Delay_Xms(4);
        RTDRead(PLL_CALIBRATION_CE, 1, N_INC);
       
        // Prevent the read back data equal to 0
        if (0 == Data[0])   Data[0] = 38;

        ucP_Corr    = (unsigned char)((unsigned int)(Data[0] * 200) >> (29 - P_Code_Value));
        ucCE_Value  = Data[0];  //CE value  
    }

	Adjust_I_Code();
    
    // Set clock again after adjust I code
    Set_Clock();

    // Setup margin for adjusting H position
    usIPH_ACT_STA   -= 100;
    ucH_Max_Margin  = 128 + 100;
    ucH_Min_Margin  = 128 - 100;

    // Check H-Position
    if (28 > stMUD.H_POSITION || 228 < stMUD.H_POSITION)
        stMUD.H_POSITION    = 128;
    
    if (((unsigned int)ucAUTO_HPOS + 50) < stMUD.H_POSITION || ucAUTO_HPOS > ((unsigned int)stMUD.H_POSITION + 50))
        stMUD.H_POSITION    = ucAUTO_HPOS;

    // Update H-Position
    Set_H_Position();

    // Check Phase
    stMUD.PHASE &= 0x7c;    // Phase 0~31

    // Update Phase
    Set_Phase(stMUD.PHASE);

    // Start auto-tracking function once
    RTDSetByte(AUTO_ADJ_CTRL_7F, 0x01);
    Delay_Xms(40);

    // Force to stop auto-tracking function
    RTDSetByte(AUTO_ADJ_CTRL_7F, 0x00);
    Delay_Xms(40);

    // Measure actual number of scan line in each frame
    RTDCodeW(MEASURE_IVS);

    Wait_Time_Cnt  = 50;    // Tracking timeout 50ms
    do
    {   
        Delay_Xms(1);
        RTDRead(AUTO_ADJ_CTRL_7F, 0x01, N_INC);
    }
    while ((Data[0] & 0x01) && (--Wait_Time_Cnt));

    RTDSetByte(AUTO_ADJ_CTRL_7F, 0x00);
    
    if (Wait_Time_Cnt)
    {
        RTDRead(VER_START_80, 0x04, Y_INC);
        Data[0] = Data[3] & 0x0f;
        Data[1] = Data[2];

        usVer_End   = usVsync < ((unsigned int *)Data)[0] ? ((unsigned int *)Data)[0] : usVsync;
    }
    else
    {
        usVer_End   = usVsync;
    }

    // Update to reasonable usIPV_ACT_STA for user mode
    if (MODE_USER720x400 <= ucMode_Curr)
    {
        ((unsigned int *)Data)[0]   = usVer_End - VGA_Mode[ucMode_Curr][2];

        if ((254 - 8) < ((unsigned int *)Data)[0] + ucDV_Delay)   ((unsigned int *)Data)[0]   = (254 - 8) - ucDV_Delay;

        usIPV_ACT_STA   += ((unsigned int *)Data)[0];
        ucDV_Delay      += ((unsigned int *)Data)[0];
    }

    // Set the ucV_Min_Margin/ucV_Max_Margin
    ucV_Min_Margin  = (128 < usIPV_ACT_STA) ? 0 : 128 - usIPV_ACT_STA + 1;

    if ((128 - 50) > ucV_Min_Margin)    ucV_Min_Margin  = 128 - 50;

    ((unsigned int *)Data)[0]   = (usVer_End + 128 - PROGRAM_VDELAY) - (usIPV_ACT_STA + usIPV_ACT_LEN);

    ucV_Max_Margin  = (((unsigned int *)Data)[0] > 0x00ff) ? 0xff : ((unsigned int *)Data)[0];

    // Check ucV_Min_Margin/ucV_Max_Margin :
    // ucDV_Delay can only range from 0 to 254
    // Original Formula :
    // 128 - ucV_Min_Margin >= ucDV_Delay
    // ucV_Max_Margin - 128 >= 254 - ucDV_Delay

    if ((unsigned int)128 > ((unsigned int)ucV_Min_Margin + ucDV_Delay))    ucV_Min_Margin  = 128 - ucDV_Delay;
    if ((unsigned int)382 < ((unsigned int)ucV_Max_Margin + ucDV_Delay))    ucV_Max_Margin  = 382 - ucDV_Delay;

    if ((128 + 50) < ucV_Max_Margin)    ucV_Max_Margin  = 128 + 50;

    // Check auto result for V position
    if ((ucV_Min_Margin + 1) > ucAUTO_VPOS)
        ucAUTO_VPOS    = 128;
    else if (ucV_Max_Margin < ucAUTO_VPOS)
        ucAUTO_VPOS    = 128;

    // Check V-Position
    if (ucV_Min_Margin > stMUD.V_POSITION)
        stMUD.V_POSITION    = ucV_Min_Margin;
    
    if (stMUD.V_POSITION > ((unsigned int)ucAUTO_VPOS << 1) - ucV_Min_Margin)
        stMUD.V_POSITION = ((unsigned int)ucAUTO_VPOS << 1) - ucV_Min_Margin;

    // Update V-Position
    Set_V_Position();

    // Re-calculate actual refresh rate
    ((unsigned long *)Data)[0]  = (unsigned long)usHsync * usVer_End;

    ucRefresh   = ((unsigned long)RTD_XTAL * 1000 * 2) / ((unsigned long *)Data)[0];
    ucRefresh   = (ucRefresh & 0x01) ? ((ucRefresh + 1) >> 1) : (ucRefresh >> 1);

    if (V_OVERSPEC_FREQ < ucRefresh || H_OVERSPEC_FREQ < (unsigned int)RTD_XTAL / usHsync)      bOverSpec = _TRUE;
    
    Data[0] = Frame_Sync();
    
    if (1 == Data[0])
    {
        // Fail and retry once
       Delay_Xms(10);
       Data[0] = Frame_Sync();	   	  
    }

#if (FORCE_DISP)
    bFrameSync  = Data[0] ? 0 : 1;              // 0 : fail, 1 : pass
#else
    bFrameSync  = 1;
#endif

    RTDSetBit(VDIS_CTRL_20, 0x7f, 0x20 | DHS_MASK); // Background display

    RTDSetByte(STATUS0_01, 0x00);       // Clear Status
    RTDSetByte(STATUS1_1F, 0x00);       // Clear Status
}

void Display_DVI_Set(void)
{
#if (TMDS_ENABLE)
    unsigned char   Wait_Time_Cnt;

    Initial_Mode();

    // Set the ucV_Min_Margin/ucV_Max_Margin
    ucV_Min_Margin  = (128 < usIPV_ACT_STA) ? 0 : 128 - usIPV_ACT_STA + 1;

    // Use Data[8],Data[9] as a temporary 16-bit variable.
    ((unsigned int *)Data)[4]   = (usVsync + 128 - 2) - (usIPV_ACT_STA + usIPV_ACT_LEN);

    ucV_Max_Margin  = (0x00ff <  ((unsigned int *)Data)[4]) ? 0xff :  ((unsigned int *)Data)[4];

    // Check ucV_Min_Margin/ucV_Max_Margin :
    // ucDV_Delay can only range from 0 to 254
    // Original Formula :
    // 128 - ucV_Min_Margin <= ucDV_Delay
    // ucV_Max_Margin - 128 <= 254 - ucDV_Delay

    if ((unsigned int)128 > ((unsigned int)ucV_Min_Margin + ucDV_Delay))    ucV_Min_Margin  = 128 - ucDV_Delay;
    if ((unsigned int)382 < ((unsigned int)ucV_Max_Margin + ucDV_Delay))    ucV_Max_Margin  = 382 - ucDV_Delay;

    // Read mode default settings from 24C04
    Load_MUD(ucMode_Curr);

    Set_Gamma();
    Set_Dithering();
    Set_Bright_Contrast();
    Sharpness();

    // Issac :
    // RTD controller can support both digital mode and analog mode to capture input image data.
    // In digital mode, input image data is captured according to input data enable (IDEN) signal;
    // In analog mode, input image data is captured according to capture window settings;
    // Although can support both of them, I always use analog mode to capture input image in this F/W.
    // Because RTD controller can measure the position and size of IDEN signal, we can just set our
    // capture window to be the same size and position as IDEN.

    Data[0]     = 14;
    Data[1]     = Y_INC;
    Data[2]     = H_BND_STA_L_75;
    Data[3]     = 0x02;
    Data[4]     = usADC_Clock - 2;
    Data[5]     = (usADC_Clock - 2) >> 8;
    Data[6]     = 0x02;
    Data[7]     = usVsync - 2;
    Data[8]     = (usVsync - 2) >> 8;
    Data[9]     = 0;
    Data[10]    = 0;
    Data[11]    = 0;
    Data[12]    = 0;
    Data[13]    = 0x81;     // Measure IDEN position
    Data[14]    = 0;
    RTDWrite(Data);

    Wait_Time_Cnt  = 60;    // Tracking timeout 60ms        
    do
    {   
        Delay_Xms(1);
        RTDRead(AUTO_ADJ_CTRL_7F, 0x01, N_INC);
    }
    while ((Data[0] & 0x01) && (--Wait_Time_Cnt));
    
    if (0 == Wait_Time_Cnt)
    {
        RTDSetByte(AUTO_ADJ_CTRL_7F, 0x00);
        Reset_Mode();
    }
    else
    {
        // Read IDEN position information
        RTDRead(VER_START_80, 0x08, Y_INC);
        
        // IDEN horizontal Start
        usIPH_ACT_STA   = (unsigned int)Data[4] + ((unsigned int)Data[5] << 8) - 2;

        // IDEN vertical Start
        ((unsigned int *)Data)[0]   = (unsigned int)Data[0] + ((unsigned int)Data[1] << 8) - 1;

        if (((unsigned int *)Data)[0] > (usIPV_ACT_STA + ucV_Max_Margin - 0x80))
        {
            /*
            ((unsigned int *)Data)[1]   = (usVsync + 128 - 2) - (usIPV_ACT_STA + usIPV_ACT_LEN);    // Actual V max. Margin

            ucDV_Delay      = (unsigned char)((unsigned int)ucDV_Delay + ucV_Max_Margin - 0x80);
            usIPV_ACT_STA   = usIPV_ACT_STA + ucV_Max_Margin - 0x80;

            if (ucV_Max_Margin < ((unsigned int *)Data)[1])
            {
                // We have to increase IVS delay to fix ucV_Max_Margin
                if ((((unsigned int *)Data)[1] - ucV_Max_Margin) >= (((unsigned int *)Data)[0] - usIPV_ACT_STA))
                    ((unsigned int *)Data)[1]   = ((unsigned int *)Data)[0] - usIPV_ACT_STA + PROGRAM_VDELAY;
                else
                    ((unsigned int *)Data)[1]   = usIPV_ACT_STA + ((unsigned int *)Data)[1] - ucV_Max_Margin + PROGRAM_VDELAY;

                if (126 < ((unsigned int *)Data)[1])    ((unsigned int *)Data)[1]  = 126;

                RTDSetByte(IVS_DELAY_8C, 0x80 | ((unsigned int *)Data)[1]);
            }
            */

            ucDV_Delay      = (unsigned char)((unsigned int)ucDV_Delay + ucV_Max_Margin - 0x80);
            usIPV_ACT_STA   = usIPV_ACT_STA + ucV_Max_Margin - 0x80;

            RTDSetByte(IVS_DELAY_8C, ((unsigned int *)Data)[0] - usIPV_ACT_STA + PROGRAM_VDELAY);
        }
        else if (((unsigned int *)Data)[0] < (usIPV_ACT_STA + ucV_Min_Margin - 0x80))
        {
            /*
            ucDV_Delay      = (unsigned char)((unsigned int)ucDV_Delay + ucV_Min_Margin - 0x80);
            usIPV_ACT_STA   = usIPV_ACT_STA + ucV_Min_Margin - 0x80;

            ((unsigned int *)Data)[1]   = usIPV_ACT_STA - ((unsigned int *)Data)[0];

            // We have to decrease IVS delay to fix ucV_Min_Margin
            if (PROGRAM_VDELAY <= ((unsigned int *)Data)[1])
                RTDSetByte(IVS_DELAY_8C, 0x00);
            else
                RTDSetByte(IVS_DELAY_8C, 0x80 | (PROGRAM_VDELAY - ((unsigned int *)Data)[1]));
            */

            ucDV_Delay      = (unsigned char)((unsigned int)ucDV_Delay + ucV_Min_Margin - 0x80);
            usIPV_ACT_STA   = usIPV_ACT_STA + ucV_Min_Margin - 0x80;

            ((unsigned int *)Data)[1]   = usIPV_ACT_STA - ((unsigned int *)Data)[0];

            if (PROGRAM_VDELAY <= ((unsigned int *)Data)[1])
                RTDSetByte(IVS_DELAY_8C, 0x00);
            else
                RTDSetByte(IVS_DELAY_8C, PROGRAM_VDELAY - ((unsigned int *)Data)[1]);
        }
        else
        {
            ucDV_Delay      = ((unsigned int *)Data)[0] + ucDV_Delay - usIPV_ACT_STA ;
            usIPV_ACT_STA   = ((unsigned int *)Data)[0];
        }

        //if TMDS error correction enable, then compensate the IPH_ACT_STA offset.
		RTDRead(TMDS_CORRECTION_FF, 0x01, N_INC);
		if (Data[0] & 0x03)     usIPH_ACT_STA -= 14;

        Data[0]     = 5;
        Data[1]     = Y_INC;
        Data[2]     = IPH_ACT_STA_06;
        Data[3]     = (unsigned char)(usIPH_ACT_STA & 0x00ff);
        Data[4]     = (unsigned char)((usIPH_ACT_STA >> 8) & 0x00ff);
        Data[5]     = 5;
        Data[6]     = Y_INC;
        Data[7]     = IPV_ACT_STA_0A;
        Data[8]     = (unsigned char)(usIPV_ACT_STA & 0x00ff);
        Data[9]     = (unsigned char)((usIPV_ACT_STA >> 8) & 0x00ff);
        Data[10]    = 4;
        Data[11]    = N_INC;
        Data[12]    = IV_DV_LINES_38;
        Data[13]    = ucDV_Delay;
        Data[14]    = 0;
        RTDWrite(Data);

        Wait_For_Event(EVENT_DVS);

        Data[0] = Frame_Sync();
        
        if (1 == Data[0])
        {
            Data[0] = Frame_Sync();     // Fail. Try again
        }

#if (FORCE_DISP)
        bFrameSync  = Data[0] ? 0 : 1;  // 0 : fail, 1 : pass
#else
        bFrameSync  = 1;
#endif
		RTDSetBit(VDIS_CTRL_20, 0x7f, 0x20 | DHS_MASK); // Background display
    }
#endif

    RTDSetByte(STATUS0_01, 0x00);       // Clear Status
    RTDSetByte(STATUS1_1F, 0x00);       // Clear Status
}


#if (VIDEO_CHIP != VDC_NONE)

/////////////////////////////////////////////////////////
//----------------- Display VIDEO Mode ----------------//
/////////////////////////////////////////////////////////

void Set_Video_Mode(void)
{
#if (VIDEO_CHIP == VDC_SAA7114 || VIDEO_CHIP == VDC_SAA7115 || VIDEO_CHIP == VDC_SAA7118)
    I2CWrite(V_DISABLE);
    I2CWrite(VIDEO_ALL);
    I2CWrite((ucAV_Mode & 0x02) ? VIDEO_50 : VIDEO_60);
#endif

    RTDCodeW((ucAV_Mode & 0x02) ? RTD_VIDEO_50 : RTD_VIDEO_60);

//    if (PANEL_OFF == MCU_ReadPanelPower())
    if (_OFF == bPanel_Status)
    {

        RTDSetByte(VDIS_SIGINV_21, 0x00 | DISP_EO_SWAP | DISP_RB_SWAP | DISP_ML_SWAP);       // DHS, DVS, DEN, DCLK MUST NOT be inverted.

        RTDSetBit(VDIS_CTRL_20, 0xfd, 0x01);    // DHS, DVS, DEN, DCLK and data

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -