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

📄 pa8204.c

📁 一个LCD TV的源程序, 用的是realtek的IC
💻 C
字号:
/*********************************************************************

      COPYRIGHT  (C)  Himax Technologies, Inc.

      File name     : HX8824.c

      Description   : Implement HX8824 control function

      Author        : Nice

      Create date   : 2004/10/01

      Modifications :

*********************************************************************/

#define _HX8824_C

/********************** Include Section *****************************/

#include "hx8824.h"
#include "remote.h"
#include "rs232.h"
#include "osd.h"
#include "ModeTbl.h"

/**************** Function Implement Section ************************/

/* ================================================================
    Name    : Init_HX8824
    Purpose : Initial HX8824 Device
    Passed  : None
    Notes   : None
   ================================================================ */

void Init_HX8824(void)
{
    // Delcare Variable for Display Test Pattern
    Byte TestPattern;

    // Read HX8824 ID
    //I2CReadByte(HX8824_ADDR, HX8824_ID, &TestPattern);

    // Dump to RS232
    Puts_UART("HX8824 ID="),HexTobyStr((Byte)TestPattern),Puts_UART(byStr),Puts_UART("\r\n");

    // Select Input Mux, For VIDEO Input Timing
	I2CWriteByte(HX8824_ADDR, HX8824_MAIN_INP_CTRL1, 0xE4);

    // Select Video
    I2CWriteByte(HX8824_ADDR, HX8824_MAIN_INP_FORMAT, 0xA1);

    // Setup Input Detect
    I2CWriteByte(HX8824_ADDR, HX8824_MAIN_INP_DETECT, 0x60);

    // Setup Input Timing VGA_60 Horizontal & Vertical
    I2CWrtCNByte(HX8824_ADDR, &HX8824_Video_Input[0][0], HX8824_MAIN_INP_HSTART, 4);
    I2CWrtCNByte(HX8824_ADDR, &HX8824_Video_Input[0][4], HX8824_MAIN_INP_VSTART, 4);

    // Mode Detect Threshold Setup, For Auto Function
    I2CWriteByte(HX8824_ADDR, HX8824_MAIN_REGMODETH, 0xA3);

    // TCON Setup
    I2CWriteByte(HX8824_ADDR, HX8824_TCONCONTROL, 0x00);

    // GateDriver Setup
    I2CWrtCNByte(HX8824_ADDR, &HX8824_Line[0], HX8824_LINEAUTODETECT, 8);

    // Source Driver Control
    I2CWrtCNByte(HX8824_ADDR, &HX8824_SourceDriver[0], HX8824_SOURCEDRIVER, 6);

    // Gate Driver Control
    I2CWrtCNByte(HX8824_ADDR, &HX8824A_GateDriver[0], HX8824_GATEDRIVER, 12);

    // V-Sync Detect Mode
    I2CWrite2Byte(HX8824_ADDR, HX8824_VSYNCDETECTTH, 0x1F, 0x02);

    // Output Timing Selection
    I2CWrtCNByte(HX8824_ADDR, &HX8824_Table_OutPut[0][0], HX8824_DSP_HTOT, 8);
    I2CWrtCNByte(HX8824_ADDR, &HX8824_Table_OutPut[0][8], HX8824_DSP_VTOT, 8);

    // Prescaling Ratio Setup
    I2CWrite2Byte(HX8824_ADDR, HX8824_PreSCALE_HRat, 0x00, 0x10);
    // Prescaling Size
    I2CWrite2Byte(HX8824_ADDR, HX8824_HSIZE, 0x80, 0x02);

    // Output Reset 0xA0 ~ 0xA3
    I2CWrtCNByte(HX8824_ADDR, &HX8824_Table_OutPut[0][16], HX8824_DSP_RESET, 3);

    // Output Port Control
    I2CWrite2Byte(HX8824_ADDR, HX8824_OUTPORT, 0x63,0x04);

    // Format Selection
    I2CWriteByte(HX8824_ADDR, HX8824_SWAP_CONTROL, 0x00);

    // Clock Selection
    I2CWriteByte(HX8824_ADDR, HX8824_CLOCK_SELECT, 0x0F);

    // Dithering 10 - 6 bit
    I2CWriteByte(HX8824_ADDR, HX8824_DITHER, 0x40);

    // Scaler: H, V Ratio & Size
    I2CWrtCNByte(HX8824_ADDR, &HX8824_Video_Input[0][8], HX8824_SCALE_RATIO, 4);
    I2CWrtCNByte(HX8824_ADDR, &HX8824_Video_Input[0][12], HX8824_SCALE_RATIO, 4);

    // Scaling Control
    I2CWriteByte(HX8824_ADDR, HX8824_SCCTRL, 0x01);

    /*
    // Output Timing Setup 108MHz
    Unlock_Clock2();
    Clock2_Write(20,7);
    Clock2_Write(0,3);
    Clock2_Write(80,7);
    Clock2_Write(0,4);
    Clock2_Write(2,3);
    Stop_Clock2();
    */

	// Output Timing = 108MHz, SXGA_60Hz
	I2CWrite3Byte(HX8824_ADDR, HX8824_DSP_PLL, 0xD2, 0x1A, 0x10);

    // Start Position Setup
    I2CWrtCNByte(HX8824_ADDR, &HX8824_Video_Input[0][16], HX8824_MAIN_INP_HSTART, 2);
    I2CWrtCNByte(HX8824_ADDR, &HX8824_Video_Input[0][18], HX8824_MAIN_INP_VSTART, 2);

    Puts_UART("Initial OK \r\n");
}


void Init_HX6204A(void)
{
	// Output Timing = 108MHz, SXGA_60Hz
	I2CWrite3Byte(HX8824_ADDR, HX8824_DSP_PLL, 0xD2, 0x1A, 0x10);
    // Free Run
    I2CWrite3Byte(HX8824_ADDR, HX8824_DSP_RESET, 0xFF, 0xFF, 0xFF);
    // Test Pattern On
    I2CWriteByte(HX8824_ADDR, HX8824_TEST_PATTERN, 0x77);
}


void Select_Inp_HX8824(Byte InpType)
{
    switch(InpType)
    {
        case _VGA_IN:
            // Input Clock Select
            I2CWriteByte(HX8824_ADDR, HX8824_MAIN_INP_CLK, 0xE8);
            // Input Format Select --> Deinterlace, Video Input
            I2CWriteByte(HX8824_ADDR, HX8824_MAIN_INP_FORMAT, 0x11);
            break;
    }
}


/* ================================================================
    Name    : Select_Video_Input
    Purpose : According Pass Variable to change Input Mux Path
    Passed  : None
    Notes   : None
   ================================================================ */

void Select_Video_Input(Byte VideoSrc)
{
    switch(VideoSrc)
    {
        // From VPC3230
        case _AV:
        case _YC:
        	I2CWrtCNByte(HX8824_ADDR, &HX8824_Input_Format[2][0], HX8824_MAIN_INP_CLK, 2);
            break;

        // From ADC YUV, ADC Component
        case _Component:
        case _VGA_IN:
             I2CWrtCNByte(HX8824_ADDR, &HX8824_Input_Format[1][0], HX8824_MAIN_INP_CLK, 2);
             break;

		// DVI Input
		case  _DVI:
             I2CWrtCNByte(HX8824_ADDR, &HX8824_Input_Format[0][0], HX8824_MAIN_INP_CLK, 2);
             break;
    }
}

/* ================================================================
    Name    : Set_Video_Timing
    Purpose : Setup HX8824 FRC/Memeory/Output Clock according
              different input timing
    Passed  : None
    Notes   : None
   ================================================================ */

void Set_Video_Timing(Byte byMode)
{
    // Enable interrupt ALL
    EA 						    = 	0;

    //Select Video Source to Setup FRC,Memory,Clock etc..
    switch (byMode)
    {
        // NTSC Video --> 3230
        case _NTSC:
            // Switch to Video 3230 Path
            I2CWrtCNByte(HX8824_ADDR, &HX8824_Input_Format[1][0], HX8824_MAIN_INP_FORMAT, 6);
            break;

        // PAL/SECAM Video --> 3230
        case _PAL:
            // Switch to Video 3230 Path, ODD is different with NTSC
            I2CWrtCNByte(HX8824_ADDR, &HX8824_Input_Format[7][0], HX8824_MAIN_INP_FORMAT, 6);
            break;

        // VGA --> AD9883
        case _VGA:
            I2CWrtCNByte(HX8824_ADDR, &HX8824_Input_Format[0][0], HX8824_MAIN_INP_FORMAT, 6);
            break;

        // 480i --> AD9883
        case _480i:
            // Main Channel + Sub Select
            // Choice HX8824_Input_Format[7] & HX8824_Input_Format[8] Reason:
            // Solving Continued INT-Request from G3
            I2CWrtCNByte(HX8824_ADDR, &HX8824_Input_Format[7][0], HX8824_MAIN_INP_FORMAT, 6);
            break;

        // 1080i --> AD9883
        // 480p --> AD9883
        case _1080i:
        case _480p:
            // Main Channel + Sub Select
            I2CWrtCNByte(HX8824_ADDR, &HX8824_Input_Format[4][0], HX8824_MAIN_INP_FORMAT, 6);
            break;
    }

   	// Setup Output/Memory
	// I2CWrtCNByte(HX8824_ADDR, &HX8824_Video_Input[byMode][0], HX8824_DSP_PLL, 3);
	I2CWrite3Byte(HX8824_ADDR,HX8824_DSP_PLL,0x41,0x9B,0x10);

    // Setup Input Timing: Horizontal Vertical
	I2CWrtCNByte(HX8824_ADDR, &HX8824_Video_Input[byMode][3], HX8824_MAIN_INP_HSTART, 4);
	I2CWrtCNByte(HX8824_ADDR, &HX8824_Video_Input[byMode][7],HX8824_MAIN_INP_VSTART, 4);

    // Horizontal Ratio
    I2CWrtCNByte(HX8824_ADDR, &HX8824_Video_Input[byMode][15],HX8824_SCALE_RATIO, 2);			// Set H-Scaling Ratio	// FF , 1F
	I2CWriteByte(HX8824_ADDR, HX8824_SCALE_RATIO + 2,0xFF);
	I2CWriteByte(HX8824_ADDR, HX8824_SCALE_RATIO + 3,0x1F);

    // Vertical Ratio
	I2CWrtCNByte(HX8824_ADDR, &HX8824_Video_Input[byMode][17],HX8824_SCALE_RATIO, 2);			// Set V-Scaling Ratio
	I2CWriteByte(HX8824_ADDR, HX8824_SCALE_RATIO + 2,0xFF);
	I2CWriteByte(HX8824_ADDR, HX8824_SCALE_RATIO + 3,0x0F);

    // Output Reset
	I2CWrtCNByte(HX8824_ADDR, &HX8824_Video_Input[byMode][19],HX8824_DSP_RESET, 3);

    // PreScaling Process
    switch (byMode)
    {
		case _NTSC:
        case _PAL:
        case _VGA:
        case _480i:
        case _480p:
            // Prescaling Setup
	        I2CWriteByte(HX8824_ADDR, HX8824_PreSCALE_HRat,	0x00);
            I2CWriteByte(HX8824_ADDR, HX8824_PreSCALE_HRat+1,0x10);
            break;

        case _1080i:
            // Prescaling Setup
	        I2CWriteByte(HX8824_ADDR, HX8824_PreSCALE_HRat,	0x00);
            I2CWriteByte(HX8824_ADDR, HX8824_PreSCALE_HRat+1,0x18);
            // Horizontal Ratio Reset
            I2CWrite2Byte(HX8824_ADDR, HX8824_SCALE_RATIO, 0xFD,0x0E);
            I2CWrite2Byte(HX8824_ADDR, HX8824_SCALE_RATIO+2,0xFF,0x1F);
            break;
    }

    // Enable interrupt ALL
    EA 						    = 	1;
}


/* ================================================================
    Name    : InitAutoFunction
    Purpose : Setup Default Gain/Offset to AD9883 VGA
              different input timing
    Passed  : None
    Notes   : None
   ================================================================ */

void InitAutoFunction(void)
{
  	Byte  RGB[6] = {  DEFAULT_AA_GAIN,DEFAULT_AA_GAIN,DEFAULT_AA_GAIN,
                      DEFAULT_AA_OFF, DEFAULT_AA_OFF, DEFAULT_AA_OFF };

	Set_ADC_VGA_GainOff(RGB);
}


/* ================================================================
    Name    : SetAutoClock
    Purpose : Tuning AD9883's PLL equal [Input Horizontal total]
    Passed  : None
    Notes   : None
   ================================================================ */

void SetAutoClock(Byte byIdx)
{
	Word                  temp0;
	Word                  wH_Total;
	ENUM_AutoClockState   byIncDecState=INITIAL;

  	wH_Total = (Word)((ADC_VGA_Tbl[0][0]<<8) |(ADC_VGA_Tbl[0][1]));
	wInpHSize=HX8824_Video_Input[3][5] + (HX8824_Video_Input[3][6])*256;

  	I2CWriteByte(AD9883_ADR_VGA, 1, HIBYTE(wH_Total));
  	I2CWriteByte(AD9883_ADR_VGA, 2, LOBYTE(wH_Total));
  	temp0 = (wH_Total / 0x10) + 1;
    Puts_UART("AD9883 temp0="),HexTobyStr((Byte)temp0),Puts_UART(byStr),Puts_UART("\r\n");

  	// Read back H-active area size
  	StartAutoBlock(byIdx, AUTO_POS);
  	temp0 = GetAutoPos(byIdx, H_SIZE);

    Puts_UART("Before Auto temp0="),HexTobyStr((Byte)temp0),Puts_UART(byStr),Puts_UART("\r\n");

  	// Check if the deviation is within reasonable range?
  	if ( ( temp0 < (wInpHSize+16) ) && ( temp0 > (wInpHSize-16) ) )
  	{
    	while ( ( temp0 != wInpHSize ) && ( (byIncDecState&BOTH) != BOTH ) )
    	{
      		if(temp0>wInpHSize)
      		{
      			wH_Total -= 0x20;
      			if (byIncDecState&INC) // Inc before?
      			{
      				byIncDecState|=BOTH;
      			}
      			else
      			{
      				byIncDecState|=DEC;
      			}
      		}
      		if(temp0<wInpHSize)
      		{
      			wH_Total += 0x20;
      			if (byIncDecState&DEC) // Dec before?
      			{
      				byIncDecState|=BOTH;
      			}
      			else
      			{
      				byIncDecState|=INC;
      			}
      		}

      		// Set new PLL_divider
      		I2CWriteByte(AD9883_ADR_VGA, 1, HIBYTE(wH_Total));
	    	I2CWriteByte(AD9883_ADR_VGA, 2, LOBYTE(wH_Total));
  	  		temp0 = (wH_Total / 0x10) + 1;

      		// Read back H-active area size
      		StartAutoBlock(byIdx, AUTO_POS);
      		temp0 = GetAutoPos(byIdx, H_SIZE);
    	}
  	}
  	else
  	{
	       Puts_UART("H-Size is out of range.  Use default value.\r\n");
  	}
  	temp0 = (wH_Total / 0x10) + 1;
    Puts_UART("After Auto temp0="),HexTobyStr((Byte)temp0),Puts_UART(byStr),Puts_UART("\r\n");

}

/* ================================================================
    Name    : StartAutoBlock
    Purpose : 

⌨️ 快捷键说明

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