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

📄 dp_rx_drv.c

📁 display port接受芯片ANX9813的驱动代码。MCU使用LPC936FDH,内部包含AN9813寄存器设置
💻 C
📖 第 1 页 / 共 2 页
字号:
//  *******************************************

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

#include "DP_RX_DRV.h"
#include "i2c_intf.h"
#include "mcu.h"
#include "timer.h"

// globe variables
e_DP_Rx_FW_STATE DP_Rx_fw_state;
s_DP_Rx_CUR_STATE s_dp_rx;

BYTE timer_slot ;  
BYTE dp_rx_lanecount;
BYTE dp_rx_bandwidth;
BYTE dp_rx_lvds_format;
BYTE dp_rx_lvds_dual_single;
BYTE dp_rx_lvds_mapping[12];
WORD h_main,v_main;
WORD h_total_main,v_total_main;
WORD hsync_wid_main,vsync_wid_main;
WORD h_bp_main,v_bp_main;
WORD h_fp_main,v_fp_main;
bit fix;

void DP_RX_MainTask(void)
{
    DP_RX_Timer_Process();
//lllll,  
#if Disable_interrupt
       DP_RX_Interrupt_Process(); 
#endif
}

void DP_RX_Timer_Process(void)
{
    DP_RX_Timer_slot1();
    DP_RX_Timer_slot2();
}

// handler all interrupts
void DP_RX_Interrupt_Process(void)
{
    BYTE cv,int1,int2,int3,int4;

    if (DP_Rx_fw_state != STATE_WAIT_HPD) 
    {
        DP_RX_ReadI2C_RX0(INTR_4, &int4);
        DP_RX_WriteI2C_RX0(INTR_4, ~int4);
        if((int4 & 0x80) ||(int4 & 0x40))
        {
            B_puts("R0' available or HDCP link failed!");
            DP_RX_ReadI2C_RX1(IRQ_VECTOR, &cv);
            if(cv & 0x04)//if TX not clear this bit
            {
                DP_RX_HPD(0);
                delay_half_ms();//delay 0.5ms
                DP_RX_HPD(1);
            }
        }
        DP_RX_ReadI2C_RX0(INTR_3, &int3);
        DP_RX_WriteI2C_RX0(INTR_3, ~int3);
        if(int3 & 0x01)
            DP_RX_Data_RCV_Int();
        
        DP_RX_ReadI2C_RX0(INTR_1, &int1);
        DP_RX_WriteI2C_RX0(INTR_1, ~int1);

        DP_RX_ReadI2C_RX0(INTR_2, &int2);
        DP_RX_WriteI2C_RX0(INTR_2, ~int2);
        
        if(int2 & 0x01)
            DP_RX_Cable_Lost_Int();

        if(int1 & 0x04)
            DP_RX_Vid_Change_Int();

        if(int1 & 0x02)
            DP_RX_Link_Err_Int();

        DP_RX_Interrupt_Debug_Info(int1, 1);
        DP_RX_Interrupt_Debug_Info(int2, 2);
        DP_RX_Interrupt_Debug_Info(int3, 3);
        DP_RX_Interrupt_Debug_Info(int4, 4);
    }
}

// main state machine in firmware 
void DP_RX_Timer_slot1(void)
{

    if(DP_Rx_fw_state == STATE_WAIT_HPD)
        DP_RX_CHK_Cable();
    if(DP_Rx_fw_state == STATE_CHK_LINK)
        DP_RX_CHK_Link();
    if(DP_Rx_fw_state == STATE_WAIT_VIDEO)
        DP_RX_Wait_Video();
}

void DP_RX_Timer_slot2(void)
{
    if(DP_Rx_fw_state == STATE_PLAY_BACK)
        DP_RX_PlayBack(); 
    
}

void DP_RX_SL_CR_AL_State_Checking(void)
{
    BYTE cLane_cnt,cstat1,cstat2;
    
    //for align status
    DP_RX_ReadI2C_RX0(SYSTEM_STATUS_2, &cstat2);
    if((cstat2 & 0x20) != 0x20)
    {
        B_puts("align loss");
        DP_RX_HPD_Update_Status();
    }
    else
    {
        //for symbol and clock loss
        DP_RX_ReadI2C_RX1(LANE_COUNT_SET, &cLane_cnt);
        if((cLane_cnt & 0x0f) == 0x04)//4lane used
        {
            DP_RX_ReadI2C_RX0(SYSTEM_STATUS_1, &cstat1);
            DP_RX_ReadI2C_RX0(SYSTEM_STATUS_2, &cstat2);

            if(((cstat1&0x03)!=0x03)||((cstat2&0xc0)!=0xc0))
            {
                B_puts("sl and cr loss");
                DP_RX_HPD_Update_Status();
            }
        }
        else if(((cLane_cnt & 0x0f) == 0x02)||((cLane_cnt & 0x0f) == 0x01))
        {
            DP_RX_ReadI2C_RX0(SYSTEM_STATUS_2, &cstat1);
            if((cLane_cnt & 0x0f) == 0x02)////2lane used 
            {
                if((cstat2 &0xc0)!=0xc0)
                {
                    B_puts("sl and cr loss");
                    DP_RX_HPD_Update_Status();
                }
            }
            else//1lane used
            {
                if((cstat2 & 0x40)!=0x40)
                {
                    B_puts("sl and cr loss");
                    DP_RX_HPD_Update_Status();
                }
            }
        }
    }
}

void DP_RX_HPD_Update_Status(void)
{
    BYTE c;
    EX1 = 0;

    DP_RX_Set_FW_State(STATE_WAIT_VIDEO);
    DP_RX_WriteI2C_RX0(INTR_MASK_3, 0xfd);
    DP_RX_ReadI2C_RX1(TRAINING_PATTERN_SET, &c);
    DP_RX_WriteI2C_RX1(TRAINING_PATTERN_SET, c |0x02);
    //IRQ HPD
    DP_RX_HPD(0);
    delay_half_ms();//delay 0.5ms
    DP_RX_HPD(1);
    DP_RX_WriteI2C_RX0(INTR_MASK_3, 0xf9);

}

void DP_RX_Set_Lane_Count(BYTE lanecount)
{
    BYTE c;
    DP_RX_ReadI2C_RX1(MAX_LINE_COUNT, &c);
    DP_RX_WriteI2C_RX1(MAX_LINE_COUNT, c & 0xf0 |lanecount);
    DP_RX_WriteI2C_RX1(LANE_COUNT_SET, lanecount);
}

void DP_RX_Set_BandWidth(BYTE bandwidth)
{
    DP_RX_WriteI2C_RX1(MAX_LINE_RATE, bandwidth);
    DP_RX_WriteI2C_RX1(LINK_BW_SET, bandwidth);
}

void DP_RX_Set_LVDS_Format(BYTE format)
{
    BYTE c;
    DP_RX_ReadI2C_RX0(LVDS_CTRL_3, &c);
    DP_RX_WriteI2C_RX0(LVDS_CTRL_3, (c & 0xf3) | format);   
}

void DP_RX_Set_LVDS_Dual_Single(BYTE dual_signal)
{
    BYTE c;
    DP_RX_ReadI2C_RX0(VID_CTRL_1, &c);
    DP_RX_WriteI2C_RX0(VID_CTRL_1, (c & 0xef) | dual_signal);
}

void DP_RX_CHK_Link(void)
{
    BYTE c;
    DP_RX_ReadI2C_RX0(SYSTEM_STATUS_2,&c);
    if(c & 0x03)
    {
        DP_RX_WriteI2C_RX0(PWD_REG, 0x00); 
        DP_RX_WriteI2C_RX0(INTR_MASK_3, 0xf9);
        B_puts("AUX CMD found");
        DP_RX_Set_FW_State(STATE_WAIT_VIDEO);
        DP_RX_WriteI2C_RX0(INTR_MASK_1, 0xf9);
        DP_RX_WriteI2C_RX0(SYSTEM_STATUS_2,c);
    }
}

// power up chip, init the registers
void DP_RX_InitSys(void)
{
    BYTE c;
    
    DP_RX_WriteI2C_RX0(PWD_REG, 0x6f);
    DP_RX_WriteI2C_RX0(SFT_RST_REG, 0x40);

    DP_RX_WriteI2C_RX0(SFT_RST_AUTO_REG, 0x38);
    
    DP_RX_WriteI2C_RX0(GPIO_CTRL, 0x42);

    DP_RX_WriteI2C_RX0(TM_LOOP_CTRL_1, 0x05);
    
    DP_RX_WriteI2C_RX0(EQ_TAIN_CTRL1, 0x9a);

    //enable AVC
    DP_RX_ReadI2C_RX0(SYSTEM_CTRL_3,&c);
    DP_RX_WriteI2C_RX0(SYSTEM_CTRL_3, (c | 0x08));


        //config HDCP
        DP_RX_WriteI2C_RX1(SINK_COUNT, 0x40);
        //DP_RX_WriteI2C_RX1(BCAPS, 0x01);
        DP_RX_WriteI2C_RX1(MAX_LINE_COUNT, 0x84);
        DP_RX_WriteI2C_RX0(SYSTEM_CTRL_1, 0x00);
        DP_RX_WriteI2C_RX0(SYSTEM_CTRL_2, 0x08);

    //scramble select
  //      DP_RX_WriteI2C_RX1(MAIN_LINK_CHANNEL_CODING, 0x09);
        DP_RX_WriteI2C_RX1(MAIN_LINK_CHANNEL_CODING, 0x0f);

        DP_RX_Mute_Vid();

    DP_RX_WriteI2C_RX0(INTR_MASK_1, 0xff);
    DP_RX_WriteI2C_RX0(INTR_MASK_2, 0xfe);
    DP_RX_WriteI2C_RX0(INTR_MASK_3, 0xf8);
    DP_RX_WriteI2C_RX0(INTR_MASK_4, 0x3f);

    //set int. output type
    DP_RX_WriteI2C_RX0(INTR_CTRL, 0x01);

    DP_RX_Set_Lane_Count(dp_rx_lanecount);
    DP_RX_Set_BandWidth(dp_rx_bandwidth);
    DP_RX_Set_LVDS_Format(dp_rx_lvds_format);
    DP_RX_Set_LVDS_Dual_Single(dp_rx_lvds_dual_single);
   for(c = 0; c < 12; c++)
        DP_RX_LVDS_Output_Mapping(c, dp_rx_lvds_mapping[c]);
        //power on LVDS
    DP_RX_WriteI2C_RX0(LVDS_PD_1, 0x00);
    DP_RX_WriteI2C_RX0(LVDS_PD_2, 0x00);
      //lllll, ?????? 
 //       DP_RX_WriteI2C_RX0(0x1f,0x01);
        DP_RX_WriteI2C_RX0(0x1f,0x00);

}

// cable plug 
void DP_RX_CHK_Cable(void)
{
    BYTE cv;
    EX1 = 0;
    DP_RX_ReadI2C_RX0(SYSTEM_STATUS_1, &cv);
    if(cv & 0x80)
    {
        delay_ms(20);
        DP_RX_ReadI2C_RX0(SYSTEM_STATUS_1, &cv);
        if(cv & 0x80)
        {
            DP_RX_InitSys();

			if(1)       // test without EDID reading, lllll
			{
				DP_RX_WriteI2C_RX0(PWD_REG, 0x00); 
		        DP_RX_WriteI2C_RX0(INTR_MASK_3, 0xf9);
		        B_puts("Testing with equiment without EDID reading");
		        DP_RX_Set_FW_State(STATE_WAIT_VIDEO);
		        DP_RX_WriteI2C_RX0(INTR_MASK_1, 0xf9);	
			}
			else
                 	   DP_RX_Set_FW_State(STATE_CHK_LINK);

            DP_RX_HPD(1);
            EX_EN = 1;

        }
    }

 
}


// check the main stream attribute
void DP_RX_Wait_Video(void)
{
    BOOL pass = 1;
    BYTE cv;

    if(DP_RX_Link_Stable() == 0)
    {
        pass = 0;
        B_puts("DP_RX: link is unstable.");
        return;
    } 

    if (DP_RX_Stream_Attr_Stable() == 0)
    {     
        pass = 0;
        B_puts("DP_RX: Main stream attribute error.");
        return;
    }

    // is video active 
  //  debug_printf("DP_RX: Check video active:  ");
    DP_RX_ReadI2C_RX0(SYSTEM_STATUS_2, &cv);
    if(cv & 0x08)    
    {
        B_puts("Link is stable.");
        pass = 1;
    } 
    else 
    { 
        pass = 0;
        B_puts("Link is not stable.");
        return;
    }

    if(pass)
    {
        DP_RX_UnMute_Vid();
        EX1 = 0;
        if(DP_Rx_fw_state == STATE_WAIT_VIDEO)
            DP_RX_Set_FW_State(STATE_PLAY_BACK);

        DP_RX_Show_Vid_Info(); 
    }

}

// Link maintenance
void DP_RX_PlayBack(void)
{
    DP_RX_SL_CR_AL_State_Checking();
}


 // check if the link is ok
BOOL DP_RX_Link_Stable(void)
{
    BYTE c,cv;
    BOOL lane3_en,lane2_en,lane1_en,lane0_en;

    lane3_en = 0;
    lane2_en = 0;
    lane1_en = 0;
    lane0_en = 0;

    DP_RX_ReadI2C_RX1(LANE_COUNT_SET, &c);
    c = c & 0x0f;
    if(c == 0x04)
    {
        lane3_en = 1;
        lane2_en = 1;
        lane1_en = 1;
        lane0_en = 1;
    }
    else if(c == 0x02)
    {
        lane1_en = 1;
        lane0_en = 1;
    }
    else if(c == 0x01)
        lane0_en = 1;
    
    DP_RX_ReadI2C_RX0(SYSTEM_STATUS_1, &cv);

    // check HPD, crystal clk and Serdes Pll lock
    if( (cv & 0x04) != 0x04) 
    {
        B_puts("PLL not lock.");
        return 0;
    }

    // check lane 3 and lane 2 sync status
   
    if(lane3_en) 
    {
        if( (cv & 0x02) != 0x02) 
        {
            B_puts("No sync in Lane3.");
            return 0;
        }
    }
    if(lane2_en) 
    {
        if( (cv & 0x01) != 0x01) 
        {
            B_puts("No sync in Lane2.");
            return 0;
        }
    }
   
    // check sync status of lane 1 and lane 0 
    DP_RX_ReadI2C_RX0(SYSTEM_STATUS_2, &cv);
    if(lane1_en) 
    {
        if( (cv & 0x80) != 0x80) 
       {
            B_puts("No sync in Lane1.");
            return 0;
        }
    }
    if(lane0_en) 
    {
        if( (cv & 0x40) != 0x40) 
        {
            B_puts("No sync in Lane0.");
            return 0;
        }
    }

    // check Align status
    if((cv & 0x20) == 0x20)
    {
        B_puts("Channel align stable!");
        return 1;
    }
    else
    {        
        return 0;
    }
    
}

// check if the main stream attributes is ok
BOOL DP_RX_Stream_Attr_Stable(void)
{
    BYTE cv;
    
    DP_RX_ReadI2C_RX0(SYSTEM_STATUS_2, &cv);
    if((cv & 0x04) == 0x04 )
    {
        return 1;
    }
    else
    {
        return 0;
    }
        
}

BOOL DP_RX_Chip_Located(void)
{
    BYTE c,c0,i;

    for(i = 0; i < 10; i++)
    {
        DP_RX_HW_Reset();
        DP_RX_ReadI2C_RX0(VENDOR_ID_L, &c);
        DP_RX_ReadI2C_RX0(VENDOR_ID_H, &c0);
        if((c == 0x85) && (c0 == 0x14))
            break;
    }
    if(i < 10)
        return 1;
    else
    {
        B_puts("\n Can not read registers from DP RX, something wrong with I2C or chip.");
        enable_debug_output = 0;
        return 0;
    }
}

// init globe variables
void DP_RX_Init_Var(void)
{
    BYTE i;
    s_dp_rx.cur_h_res = 0;
    s_dp_rx.cur_v_res = 0;
    dp_rx_lanecount = 4;
    dp_rx_bandwidth = 0x0a;
    dp_rx_lvds_format = 0x00;

⌨️ 快捷键说明

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