📄 dp_rx_drv.c
字号:
// *******************************************
// *******************************************
#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 + -