📄 pa8204.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 + -