📄 anx9021.c
字号:
BYTE c;
ANX9021_ReadI2C_RX0(INTR1_MASK_REG, &c);
if (c == 0) { g_Restart_System = 1; }
if(g_Restart_System)
{
g_Restart_System = 0;
ANX9021_Chip_Located();
}
}
void ANX9021_Timer_Process(void)
{
if(g_Timer_Slot >= 3)
g_Timer_Slot = 0;
else
g_Timer_Slot ++;
if(g_Timer_Slot == 0)
ANX9021_Video_Timer_Slot();
else if(g_Timer_Slot == 1)
ANX9021_Audio_Timer_Slot();
else if(g_Timer_Slot == 2)
ANX9021_Timer_Slot2();
}
void ANX9021_Chip_Located(void)
{
BYTE c,c1;
BYTE i;
for (i=0;i<20;i++)
{
HDMIRX_reset_pin = 0;
delay_ms(10);
HDMIRX_reset_pin = 1;
delay_ms(10);
ANX9021_WriteI2C_RX1(HDMI_MUTE_REG, 0x3);
c = ANX9021_ReadI2C_RX0(DEV_IDL_REG, &c1);
if ((c == 0) && (c1 == 0x21))
{
c = ANX9021_ReadI2C_RX0(DEV_IDH_REG, &c1);
if ((c == 0) && (c1 == 0x90))
break;
}
}
if(i<20)
debug_puts("ANX9021 found");
else
debug_puts("\n Can not read registers from 9021, something wrong with I2C or chip.");
ANX9021_Initialize();
}
void ANX9021_Init_var(void)
{
ANX9021_Set_Sys_State(MONITOR_CKDT);
g_Cur_H_Res = 0;
g_Cur_V_Res = 0;
g_Cur_Pix_Clk = 0;
g_Video_Muted = 1;
g_Audio_Muted = 1;
g_Video_Stable_Cntr = 0;
g_Audio_Stable_Cntr = 0;
g_Sync_Expire_Cntr = 0;
g_Restart_System = 0;
g_HDCP_Err_Cnt = 0;
g_Auth_Start = 0;
g_Sync_Change = 0;
g_HDMI_DVI_Status = DVI_MODE;
g_CTS_Got = 0;
g_Audio_Got = 0;
}
void ANX9021_Set_Sys_State(BYTE ss)
{
if(g_Sys_State != ss)
{
debug_puts("");
g_Sys_State = ss;
switch (ss)
{
case MONITOR_CKDT:
debug_puts("ANX9021: MONITOR_CKDT");
break;
case WAIT_SCDT:
debug_puts("ANX9021: WAIT_SCDT");
break;
case WAIT_VIDEO:
debug_puts("ANX9021: WAIT_VIDEO");
//ANX9021_ReadI2C_RX0(IP_CTRL_REG, &c);
//ANX9021_WriteI2C_RX0(IP_CTRL_REG, c | 0x01);
break;
case WAIT_AUDIO:
debug_puts("ANX9021: WAIT_AUDIO");
ANX9021_Restart_Audio_Chk();
break;
case PLAYBACK:
debug_puts("ANX9021: PLAYBACK");
break;
default:
break;
}
}
}
void ANX9021_Restart_Audio_Chk(void)
{
//BYTE c;
if (g_Sys_State == WAIT_AUDIO)
{
debug_puts("WAIT_AUDIO: ANX9021_Restart_Audio_Chk.");
g_CTS_Got = 0;
g_Audio_Got = 0;
}
}
void ANX9021_Mute_Video(void)
{
BYTE c;
debug_puts("Mute Video.");
ANX9021_ReadI2C_RX1(HDMI_MUTE_REG, &c);
ANX9021_WriteI2C_RX1(HDMI_MUTE_REG, c | 0x01);
g_Video_Muted = 1;
}
void ANX9021_Unmute_Video(void)
{
BYTE c;
debug_puts("Unmute Video.");
ANX9021_ReadI2C_RX1(HDMI_MUTE_REG, &c);
ANX9021_WriteI2C_RX1(HDMI_MUTE_REG, c & 0xfe);
g_Video_Muted =0;
}
void ANX9021_Mute_Audio(void)
{
BYTE c;
debug_puts("Mute Audio.");
ANX9021_ReadI2C_RX1(HDMI_MUTE_REG, &c);
ANX9021_WriteI2C_RX1(HDMI_MUTE_REG, c | 0x02);
g_Audio_Muted = 1;
}
void ANX9021_Unmute_Audio(void)
{
BYTE c;
debug_puts("Unmute Audio.");
ANX9021_ReadI2C_RX1(HDMI_MUTE_REG, &c);
ANX9021_WriteI2C_RX1(HDMI_MUTE_REG, c & 0xfd);
g_Audio_Muted = 0;
}
char ANX9021_Is_Video_Change(void)
{
BYTE ch, cl;
xdata unsigned long n; //WORD n;
ANX9021_ReadI2C_RX0(H_RESL_REG, &cl);
ANX9021_ReadI2C_RX0(H_RESH_REG, &ch);
n = ch;
n = (n << 8) + cl;
if ((g_Cur_H_Res < (n-10)) || (g_Cur_H_Res > (n+10)))
{
return 1;
}
ANX9021_ReadI2C_RX0(V_RESL_REG, &cl);
ANX9021_ReadI2C_RX0(V_RESH_REG, &ch);
n = ch;
n = (n << 8) + cl;
if ((g_Cur_V_Res < (n-10)) || (g_Cur_V_Res > (n+10)))
{
return 1;
}
ANX9021_ReadI2C_RX0(SHD_BSTAT2_REG, &cl);
cl &= ANX9021_HDMI_MODE;
cl = cl >> 4;
if(g_HDMI_DVI_Status != cl)
{
debug_puts("DVI to HDMI or HDMI to DVI Change.");
return 1;
}
return 0;
}
void ANX9021_Get_Video_Info(void)
{
BYTE ch, cl;
unsigned int n;
ANX9021_ReadI2C_RX0(H_RESL_REG, &cl);
ANX9021_ReadI2C_RX0(H_RESH_REG, &ch);
n = ch;
n = (n << 8) + cl;
g_Cur_H_Res = n;
ANX9021_ReadI2C_RX0(V_RESL_REG, &cl);
ANX9021_ReadI2C_RX0(V_RESH_REG, &ch);
n = ch;
n = (n << 8) + cl;
g_Cur_V_Res = n;
ANX9021_ReadI2C_RX0(VID_XPCNT_REG, &cl);
g_Cur_Pix_Clk = cl;
ANX9021_ReadI2C_RX0(SHD_BSTAT2_REG, &cl);
g_HDMI_DVI_Status = ((cl & ANX9021_HDMI_MODE) == ANX9021_HDMI_MODE);
}
void ANX9021_Sync_Det_Int(void)
{
BYTE c,c1;
debug_puts("*ANX9021 Interrupt: Sync Detect.");
g_Sync_Change = 1; // record sync change
ANX9021_ReadI2C_RX0(STATE_REG, &c);
if (c & ANX9021_SYNC_DECT) // sync existed
{
if (g_Sys_State == WAIT_SCDT)
{
debug_puts("Sync found.");
ANX9021_ReadI2C_RX0(AEC_CTRL_REG, &c);
ANX9021_WriteI2C_RX0(AEC_CTRL_REG, c | 0x04);
ANX9021_Set_Sys_State(WAIT_VIDEO);
g_Video_Stable_Cntr = 0;
}
else if(g_Sys_State == WAIT_VIDEO)
{;}
// check the PLL range in WAIT_AUDIO and PLAYBACK
else if((g_Sys_State==WAIT_AUDIO) || (g_Sys_State==PLAYBACK))
{
ANX9021_ReadI2C_RX0(TMDS_PLL_RNG_STATUS_REG, &c);
ANX9021_ReadI2C_RX0(TMDS_PLL_RNG_CTRL_REG, &c1);
if((c & 0x40) != (c1 & 0x40)) //check PLL range
{
debug_puts("++++++Wrong PLL range. ++++++");
ANX9021_Mute_Audio();
ANX9021_Mute_Video();
ANX9021_Set_Sys_State(MONITOR_CKDT);
}
}
ANX9021_Get_Video_Info();// save first video info
}
else // sync lost
{
debug_puts("Sync lost.");
g_Auth_Start = 0;
ANX9021_Mute_Audio();
ANX9021_Mute_Video();
if(c & 0x02) //check if the clock lost
{
ANX9021_Set_Sys_State(WAIT_SCDT);
}
else
{
ANX9021_Set_Sys_State(MONITOR_CKDT);
}
}// end of sync lost
}
void ANX9021_Aac_Done_Int(void)
{
BYTE c;
debug_puts("*ANX9021 Interrupt: AEC AAC Done.");
ANX9021_ReadI2C_RX1(HDMI_MUTE_REG, &c);
if (c & ANX9021_AUD_MUTE)
{
g_Audio_Muted = 1;
if (g_Sys_State == PLAYBACK)
{
ANX9021_ReadI2C_RX0(SHD_BSTAT2_REG, &c);
if (c & ANX9021_HDMI_MODE)
{
ANX9021_Set_Sys_State(WAIT_AUDIO);
}
}
}
}
void ANX9021_Auth_Start_Int(BYTE s1)
{
BYTE c;
debug_puts("*ANX9021 Interrupt: Authentication Start.");
g_Auth_Start = 1;
if (s1 & 0x01) // auth done
{
debug_puts("*ANX9021 Interrupt: Authentication Done 0.") ;
}
else // no auth done at first time
{
delay_ms(10);
ANX9021_ReadI2C_RX0(INTR1_REG, &c); // delay 10 ms, read auth done again
ANX9021_WriteI2C_RX0(INTR1_REG, c& 0x01); // clear auth DONE int
if (c & 0x01)
{
debug_puts("*ANX9021 Interrupt: Authentication Done 1.") ;
}
else
{
debug_puts("++++++ auth is wrong ++++++") ;
ANX9021_ReadI2C_RX0(SRST_REG, &c);
ANX9021_WriteI2C_RX0(SRST_REG, c | 0x08); // Manual reset HDCP
ANX9021_WriteI2C_RX0(SRST_REG, c);
g_Auth_Start = 0;
}
}
}
void ANX9021_HDMI_DVI_Int(void)
{
BYTE c;
debug_puts("*ANX9021 Interrupt: HDMI-DVI Mode Change.");
ANX9021_ReadI2C_RX0(SHD_BSTAT2_REG, &c);
ANX9021_Get_Video_Info();
if ((c & ANX9021_HDMI_MODE) == ANX9021_HDMI_MODE)
{
debug_puts("ANX9021_HDMI_DVI_Int: HDMI MODE.");
if ( g_Sys_State==PLAYBACK )
{
ANX9021_Set_Sys_State(WAIT_AUDIO);
}
}
else
{
ANX9021_Unmute_Audio();
}
}
void ANX9021_Cts_Rcv_Int(void)
{
// BYTE c;
g_CTS_Got = 1;
// ANX9021_ReadI2C_RX0(INTR2_MASK_REG, &c);
// ANX9021_WriteI2C_RX0(INTR2_MASK_REG, c & 0xfb);
}
void ANX9021_Audio_Rcv_Int(void)
{
// BYTE c;
g_Audio_Got = 1;
// ANX9021_ReadI2C_RX0(INTR2_MASK_REG, &c);
// ANX9021_WriteI2C_RX0(INTR2_MASK_REG, c & 0xfd);
}
void ANX9021_HDCP_Error_Int(void)
{
BYTE c;
g_Audio_Got = 0;
g_CTS_Got = 0;
if(g_HDCP_Err_Cnt >= 40 )
{
g_HDCP_Err_Cnt = 0;
debug_puts("Lots of hdcp error occured ...");
ANX9021_Mute_Audio();
ANX9021_Mute_Video();
ANX9021_Set_Sys_State(MONITOR_CKDT);
//issue hotplug
ANX9021_ReadI2C_RX0(PORT_SEL_REG, &c);
if( c&0x01 ) //port 0
{
ANX9021_HPD_Port0(300);
debug_puts("++++++++++Debug information: HDCP error interrupt: port 0 HPD issued.");
}
else
{
ANX9021_HPD_Port1(300);
debug_puts("++++++++++Debug information: HDCP error interrupt: port 1 HPD issued.");
}
}
else if((g_Sys_State==MONITOR_CKDT) || (g_Sys_State == WAIT_SCDT))
{
g_HDCP_Err_Cnt = 0;
}
else
{
g_HDCP_Err_Cnt ++;
}
}
void ANX9021_New_AVI_Int(void)
{
BYTE c;
debug_puts("*ANX9021 Interrupt: New AVI Packet.");
ANX9021_ReadI2C_RX1(0x40, &c);
debug_printf("AVI Infoframe:\n");
debug_printf("0x%.2x ",(WORD)c);
ANX9021_ReadI2C_RX1(0x41, &c);
debug_printf("0x%.2x ",(WORD)c);
ANX9021_ReadI2C_RX1(0x42, &c);
debug_printf("0x%.2x ",(WORD)c);
ANX9021_ReadI2C_RX1(0x43, &c);
debug_printf(" Check Sum = 0x%.2x \n",(WORD)c);
ANX9021_ReadI2C_RX1(0x44, &c);
debug_printf("0x%.2x ",(WORD)c);
ANX9021_ReadI2C_RX1(0x45, &c);
debug_printf("0x%.2x ",(WORD)c);
ANX9021_ReadI2C_RX1(0x46, &c);
debug_printf("0x%.2x ",(WORD)c);
ANX9021_ReadI2C_RX1(0x47, &c);
debug_printf("0x%.2x ",(WORD)c);
ANX9021_ReadI2C_RX1(0x48, &c);
debug_printf("0x%.2x ",(WORD)c);
ANX9021_ReadI2C_RX1(0x49, &c);
debug_printf("0x%.2x ",(WORD)c);
ANX9021_ReadI2C_RX1(0x50, &c);
debug_printf("0x%.2x ",(WORD)c);
ANX9021_ReadI2C_RX1(0x51, &c);
debug_printf("0x%.2x ",(WORD)c);
ANX9021_ReadI2C_RX1(0x52, &c);
debug_printf("0x%.2x ",(WORD)c);
ANX9021_ReadI2C_RX1(0x53, &c);
debug_printf("0x%.2x \n",(WORD)c);
}
BYTE ANX9021_Initialize(void)
{
BYTE c;
BYTE Vid_Output_Format;
ANX9021_Init_var();
// Mute audio and video output
ANX9021_WriteI2C_RX1(HDMI_MUTE_REG, 0x03);
ANX9021_WriteI2C_RX0(BCAPS_SET_REG, 0x81);
// Adjust TMDS params
ANX9021_ReadI2C_RX0(TMDS_DEBUG_REG, &c);
ANX9021_WriteI2C_RX0(TMDS_DEBUG_REG, c | 0x40);
// Set clock detect source
// Enable pll_lock, digital clock detect, disable analog clock detect
ANX9021_WriteI2C_RX0(CHIP_CTRL_REG, 0xe5);
// Init Interrupt
ANX9021_WriteI2C_RX0(INT_CTRL_REG, 0x02);
ANX9021_WriteI2C_RX0(INTR1_MASK_REG, 0xff); // HDCP interrupt is disable for some DVD not use that
ANX9021_WriteI2C_RX0(INTR2_MASK_REG, 0xbe); // 0xbf,HDMI_DVI, CKDT_CHANGE, SCDT_CHANGE, CTS_RCV
ANX9021_WriteI2C_RX0(INTR3_MASK_REG, 0x1f); // NEW_AVI
ANX9021_WriteI2C_RX0(INTR4_MASK_REG, 0xef); // HDCP_ERR
ANX9021_WriteI2C_RX0(INTR5_MASK_REG, 0xef); // AAC_DONE
ANX9021_WriteI2C_RX0(INTR6_MASK_REG, 0xff);
ANX9021_WriteI2C_RX0(AEC_EN0_REG, 0xe7); // disable CP mute set, disable video clock change
ANX9021_WriteI2C_RX0(AEC_EN1_REG, 0x17);
ANX9021_WriteI2C_RX0(AEC_EN2_REG, 0x00); // disable V resolution change
ANX9021_WriteI2C_RX0(AFIFO_CTRL_REG, 0xcc);// add AFIFO control
// Init CTS threshold
ANX9021_WriteI2C_RX1(ACR_CTRL3_REG, 0x07);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -