软件:xilinx vivado 2016.3
还是最近在一直调试的adv7511和adv7611,碰到蛮多乱七八糟的问题,但最后还是驱动起来了。数据流就是主机数据经过adv7611后通过FPGA转接到adv7511再驱动另一块显示器。在FPGA中暂时就只是转接一下,之后的计划是在FPGA中做一些数据处理后再通过7511发送出去。
记录一下过程中碰到的坑。。。
//********************************************************************************
/*
* The video input format of the ADV7511 is set to YCbCr, 16-bit, 4:2:2,
* ID 1 (separate syncs), Style 1. The video output format is set to
* YCbCr, 16-bit, 4:2:2, HDMI mode.
*/
adv7511_I2C_CONFIG adv7511_hdmi_config[16] =
{
{0x41, 0x10}, // Power Down Control
// R0x41[ 6] = PowerDown = 0 (power-up)
{0xD6, 0xC0}, // HPD Control
// R0xD6[7:6] = HPD Control = 11 (always high)
{0x15, 0x01}, // Input YCbCr 4:2:2 with separate syncs
{0x16, 0xB9}, // Output format 4:2:2, Input Color Depth = 8
// R0x16[ 7] = Output Video Format = 1 (4:2:2)
// R0x16[5:4] = Input Video Color Depth = 11 (8 bits/color)
// R0x16[3:2] = Input Video Style = 10 (style 1) ;= 01(style 2)
// R0x16[ 1] = DDR Input Edge = 0 (falling edge)
// R0x16[ 0] = Output Color Space = 1 (YCbCr)
{0x48, 0x08}, // Video Input Justification
// R0x48[4:3] = Video Input Justification = 01 (right justified)
{0x55, 0x20}, // Set RGB in AVinfo Frame
// R0x55[6:5] = Output Format = 01 (YCbCr)
{0x56, 0x28}, // Aspect Ratio
// R0x56[5:4] = Picture Aspect Ratio = 10 (16:9)
// R0x56[3:0] = Active Format Aspect Ratio = 1000 (Same as Aspect Ratio)
{0x98, 0x03}, // ADI Recommended Write
{0x9A, 0xE0}, // ADI Recommended Write
{0x9C, 0x30}, // PLL Filter R1 Value
{0x9D, 0x61}, // Set clock divide
{0xA2, 0xA4}, // ADI Recommended Write
{0xA3, 0xA4}, // ADI Recommended Write
{0xAF, 0x06}, // HDMI/DVI Modes
// R0xAF[ 7] = HDCP Enable = 0 (HDCP disabled)
// R0xAF[ 4] = Frame Encryption = 0 (Current frame NOT HDCP encrypted)
// R0xAF[3:2] = 01 (fixed)
// R0xAF[ 1] = HDMI/DVI Mode Select = 2 (HDMI Mode)
{0xE0, 0xD0}, // Must be set to 0xD0 for proper operation
{0xF9, 0x00} // Fixed I2C Address (This should be set to a non-conflicting I2C address)
};
//********************************************************************************
// 读取adv7511的版本号,测试IIC通信
u32 read_version_7511()
{
u32 temp;
temp = iic_read_data(XPAR_IIC_DRIVER_0_S00_AXI_BASEADDR,adv7511_device_addr,0x00);
return temp;
}
//********************************************************************************
// 初始化7511
void init_adv7511()
{
u32 i;
for(i=0;i<16;i++)
{
iic_write_data(XPAR_IIC_DRIVER_0_S00_AXI_BASEADDR,adv7511_device_addr,adv7511_hdmi_config[i].reg_addr,adv7511_hdmi_config[i].init_data);
}
}
//********************************************************************************
// 配置7611
unsigned char script[] = {
0x98, 0xFF, 0x80, // I2C reset
0x98, 0xF4, 0x80, // CEC SLAVE ADDRESS
0x98, 0xF5, 0x7C, // INFOFRAME SLAVE ADDRESS
0x98, 0xF8, 0x4C, // DPLL SLAVE ADDRESS
0x98, 0xF9, 0x64, // KSV SLAVE ADDRESS
0x98, 0xFA, 0x6C, // EDID SLAVE ADDRESS
0x98, 0xFB, 0x68, // HDMI SLAVE ADDRESS
0x98, 0xFD, 0x44, // CP SLAVE ADDRESS
0x98, 0x00,0x1e, //input video,output 1920*1080
0x98, 0x01, 0x05, // vertical frequency = 60Hz,Prim_Mode =101b HDMI-Comp
0x98, 0x02, 0xF5, // Auto CSC, no YPbPr colorspace conversion,
// set the output range of the digital data = limited range (16 to 235), YCrCb out
0x98, 0x03, 0x80, // 0x80 = 16-bit ITU-656 SDR mode; 0x20 = 8-bit 4:2:2 DDR mode (ITU-656 mode)
0x98, 0x04,0xa2, // OP_CH_SEL[2:0] = 011b(最高3位) - (P[15:8] Y, P[7:0] CrCb), 101(P[7:0] Y ,P[15:8]CrCb ) XTAL_FREQ[1:0] = 01b (28.63636 MHz)
0x98, 0x05, 0x28, // DE output on the FIELD/DE pin ; AV Codes Off
0x98, 0x0B, 0x44, // Powers up CP and digital sections of HDMI block; Powers up XTAL buffer to the digital core
0x98, 0x0C, 0x42, // Chip is operational,Disables power save mode,Powers up the clock to the CP core,Powers up the pads of the digital output pins
0x98, 0x14, 0x7F, // High drive strength of data output drivers;output pixel clock out signal on the LLC pin,
// synchronization pins, HS, VS/FIELD, FIELD/DE;audio output interface pins (AP0, AP1/I2S_TDM, AP2 ... AP5).
0x98, 0x15, 0x80, // Disable Tristate of Pins
0x98, 0x19, 0x83, // LLC DLL phase
0x98, 0x33, 0x40, // LLC DLL enable
0x44, 0xBA, 0x01, // Set HDMI FreeRun when the TMDS clock is not detected on the selected HDMI port
0x64, 0x40, 0x81, // Disable HDCP 1.1 features
0x68, 0x9B, 0x03, // ADI recommended setting
0x68, 0xC1, 0x01, // ADI recommended setting
0x68, 0xC2, 0x01, // ADI recommended setting
0x68, 0xC3, 0x01, // ADI recommended setting
0x68, 0xC4, 0x01, // ADI recommended setting
0x68, 0xC5, 0x01, // ADI recommended setting
0x68, 0xC6, 0x01, // ADI recommended setting
0x68, 0xC7, 0x01, // ADI recommended setting
0x68, 0xC8, 0x01, // ADI recommended setting
0x68, 0xC9, 0x01, // ADI recommended setting
0x68, 0xCA, 0x01, // ADI recommended setting
0x68, 0xCB, 0x01, // ADI recommended setting
0x68, 0xCC, 0x01, // ADI recommended setting
0x68, 0x00, 0x00, // Set HDMI Input Port A
0x68, 0x83, 0xFE, // Enable clock terminator for port A
0x68, 0x6F, 0x0C, // ADI recommended setting
0x68, 0x85, 0x1F, // ADI recommended setting
0x68, 0x87, 0x70, // ADI recommended setting
0x68, 0x8D, 0x04, // LF gain equalizer settings for dynamic mode range 1
0x68, 0x8E, 0x1E, // HF gain equalizer settings for dynamic mode range 1
0x68, 0x1A, 0x8A, // unmute audio
0x68, 0x57, 0xDA, // ADI recommended setting
0x68, 0x58, 0x01, // ADI recommended setting
0x68, 0x03, 0x98, // DIS_I2C_ZERO_COMPR
0x68, 0x75, 0x10, // DDC drive strength
0xFF };
void I2C_write_tab_new_7611( unsigned char *script )
{
do {
iic_write_data(XPAR_IIC_DRIVER_1_S00_AXI_BASEADDR,*script, *(script+1), *(script+2));
{
script += 3;
}
} while (*script != 0xFF) ;
}
unsigned char hdmi_edid[256]=
{
0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x4C,0x2D,0x4E,0x0C,0x46,0x53,0x4D,0x30,
0x22,0x1A,0x01,0x03,0x80,0x3D,0x23,0x78,0x2A,0x5F,0xB1,0xA2,0x57,0x4F,0xA2,0x28,
0x0F,0x50,0x54,0xBF,0xEF,0x80,0x71,0x4F,0x81,0x00,0x81,0xC0,0x81,0x80,0x95,0x00,
0xA9,0xC0,0xB3,0x00,0x01,0x01,0x04,0x74,0x00,0x30,0xF2,0x70,0x5A,0x80,0xB0,0x58,
0x8A,0x00,0x60,0x59,0x21,0x00,0x00,0x1E,0x00,0x00,0x00,0xFD,0x00,0x18,0x4B,0x1E,
0x5A,0x1E,0x00,0x0A,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0xFC,0x00,0x55,
0x32,0x38,0x45,0x35,0x39,0x30,0x0A,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0xFF,
0x00,0x48,0x54,0x50,0x48,0x38,0x30,0x32,0x30,0x36,0x36,0x0A,0x20,0x20,0x01,0xF8
};
void i2c_program_edid_7611(unsigned char *data, int length)
{
u32 i;
iic_write_data(XPAR_IIC_DRIVER_1_S00_AXI_BASEADDR,0x64, 0x77, 0x00);
iic_write_data(XPAR_IIC_DRIVER_1_S00_AXI_BASEADDR,0x64, 0x74, 0x00);
for (i=0; i0x6C, i, data[i]);
for (i=0; i<800000; i++); // delay for HPA
iic_write_data(XPAR_IIC_DRIVER_1_S00_AXI_BASEADDR,0x64, 0x77, 0x00);
iic_write_data(XPAR_IIC_DRIVER_1_S00_AXI_BASEADDR,0x64, 0x52, 0x20);
iic_write_data(XPAR_IIC_DRIVER_1_S00_AXI_BASEADDR,0x64, 0x53, 0x00);
iic_write_data(XPAR_IIC_DRIVER_1_S00_AXI_BASEADDR,0x64, 0x70, 0x9E);
iic_write_data(XPAR_IIC_DRIVER_1_S00_AXI_BASEADDR,0x64, 0x74, 0x03);
}
void init_adv7611()
{
u32 i;
iic_write_data(XPAR_IIC_DRIVER_1_S00_AXI_BASEADDR,0x98, 0xFF, 0x80); // RESET part and wait (no ACK after reset)
for (i=0; i<800000; i++);
I2C_write_tab_new_7611(script); // program the part
i2c_program_edid_7611(hdmi_edid, 256);
}