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

📄 anx9021.c

📁 HDMI anx9021的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
    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 + -