UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Observer sberner66
Observer
966 Views
Registered: ‎10-06-2018

ZCU104 -- Use HDMI connectors for general purpose data link between two boards ?

Jump to solution

I want to use the HDMI connectors to connect two ZCU104 boards and transfer data packets between them. I connected an aurora_64b66 module to one of the HDMI lanes, ref clk is HDMI_RX_CLK = 125 MHz. As a start, I tried a loopback, HDMI TX connector connected to HDMI RX connector of the same board.

I have an unstable loopback link at 0.6 Gbit/sec with a LONG cable, means channel_up of aurora module high may be 80% of the time. All other configurations, higher or lower rate, shorter cable, don't work.

I suspect the problem are the signal conditioning chips, SN65DP159RGZ and TMDS181IRGZT, which most likely depend on the HDMI protocol.

Questions:

1) Is this idea feasible ?

2) When using the signal conditioning chips SN65DP159RGZ and TMDS181IRGZT in redriver mode, is there still any depency on the HDMI protocol or do they work for any high speed serial data ?

3) Is there any sample code for reprogramming those chips vis I2C ?

4) Do I have to reprogram those chips ? I read in the data sheet that redriver mode is automatically selected if the rate is low.

 

0 Kudos
1 Solution

Accepted Solutions
Observer sberner66
Observer
783 Views
Registered: ‎10-06-2018

Re: ZCU104 -- Use HDMI connectors for general purpose data link between two boards ?

Jump to solution

SUMMARY:

To get the link working the following steps are necessary.

1) Instantiate an aurora8b10b module, connect the lane(s) to the HDMI pair(s), choose ref clk 0 in the aurora GUI which connects the clk from the 8T49N241 PLL chip. aurora64b66b may work to, but haven't retried.

2) Program the 8T49N241 as a synthesizer generating 148.5 MHz as shown above. Adjust the rate of the aurora module in the GUI such that 148.5MHz is a legal reference clk frequency, select this ref clk frequency. For example, the lowest possible rate it 4*148.5 MHz

3) Program the driver chip and receiver chip for redriver mode as shown above because in retiming mode the operation of these chips relies on a valid HDMI signal

 

0 Kudos
5 Replies
Observer sberner66
Observer
920 Views
Registered: ‎10-06-2018

Re: ZCU104 -- Use HDMI connectors for general purpose data link between two boards ?

Jump to solution

One obvious mistake was to use the aurora-64b66b module. HDMI relies on 8b10b coding and using the aurora-8b10b module makes more sense.

After replacing the 64b66b module by the 8b10b module, it works much better, but there are still problems.

Having an HDMI loopback, 5 feet cable, rate = 1.25 Gbps, ref clk = 125 MHz, the channel goes down randomly every few msec for a duration of a few usec.

A loopback with rate = 0.5 Gbps, ref_clk = 125 MHz works better, but still not error free.

 

0 Kudos
Highlighted
Observer sberner66
Observer
836 Views
Registered: ‎10-06-2018

Re: ZCU104 -- Use HDMI connectors for general purpose data link between two boards ?

Jump to solution

As suspected earlier, forcing the signal conditioning chips DP159 and TMDS181 into redriver mode by I2C commands solves the problem of the loopback errors mentioned in previous reply

Steps to do:

1) Instantiate an AXI IIC Bus Interface

2) reprogram the signal conditioning chips

//set redriver mode
*((u32 *) (AXI_I2C_BASEADDR + TX_FIFO)) = 0xbc; //dev addr
*((u32 *) (AXI_I2C_BASEADDR + TX_FIFO)) = 0x0a; //subaddr
*((u32 *) (AXI_I2C_BASEADDR + TX_FIFO)) = 0x00; //data

*((u32 *) (AXI_I2C_BASEADDR + CR)) = 0x0d; //master, tx, en
while(!(*((u32 *) (AXI_I2C_BASEADDR + SR)) & 0x80));
//*((u32 *) (AXI_I2C_BASEADDR + SR)) = 0x40;
xil_printf("DP159 redriver mode set\n\r");

usleep(10000);
*((u32 *) (AXI_I2C_BASEADDR + CR)) = 0x0;

//power down chip
*((u32 *) (AXI_I2C_BASEADDR + TX_FIFO)) = 0xbc; //dev addr
*((u32 *) (AXI_I2C_BASEADDR + TX_FIFO)) = 0x09; //subaddr
*((u32 *) (AXI_I2C_BASEADDR + TX_FIFO)) = 0x08; //data

*((u32 *) (AXI_I2C_BASEADDR + CR)) = 0x0d; //master, tx, en
while(!(*((u32 *) (AXI_I2C_BASEADDR + SR)) & 0x80));
//*((u32 *) (AXI_I2C_BASEADDR + ISR)) = 0x40;
xil_printf("DP159 powered down\n\r");

usleep(10000);
*((u32 *) (AXI_I2C_BASEADDR + CR)) = 0x0;


//power up chip
*((u32 *) (AXI_I2C_BASEADDR + TX_FIFO)) = 0xbc; //dev addr
*((u32 *) (AXI_I2C_BASEADDR + TX_FIFO)) = 0x09; //subaddr
*((u32 *) (AXI_I2C_BASEADDR + TX_FIFO)) = 0;//0x08; //data

*((u32 *) (AXI_I2C_BASEADDR + CR)) = 0x0d; //master, tx, en
while(!(*((u32 *) (AXI_I2C_BASEADDR + ISR)) & 0x40));
*((u32 *) (AXI_I2C_BASEADDR + ISR)) = 0x40;
xil_printf("DP159 powered up\n\r");

usleep(10000);
*((u32 *) (AXI_I2C_BASEADDR + CR)) = 0x0;

 

////////////////////////

//set redriver mode
*((u32 *) (AXI_I2C_BASEADDR + TX_FIFO)) = 0xb8; //dev addr
*((u32 *) (AXI_I2C_BASEADDR + TX_FIFO)) = 0x0a; //subaddr
*((u32 *) (AXI_I2C_BASEADDR + TX_FIFO)) = 0x00; //data

*((u32 *) (AXI_I2C_BASEADDR + CR)) = 0x0d; //master, tx, en
while(!(*((u32 *) (AXI_I2C_BASEADDR + ISR)) & 0x40));
*((u32 *) (AXI_I2C_BASEADDR + ISR)) = 0x40;
xil_printf("TMDS181 redriver mode set\n\r");

usleep(10000);
*((u32 *) (AXI_I2C_BASEADDR + CR)) = 0x0;


//power down chip
*((u32 *) (AXI_I2C_BASEADDR + TX_FIFO)) = 0xb8; //dev addr
*((u32 *) (AXI_I2C_BASEADDR + TX_FIFO)) = 0x09; //subaddr
*((u32 *) (AXI_I2C_BASEADDR + TX_FIFO)) = 0x08; //data

*((u32 *) (AXI_I2C_BASEADDR + CR)) = 0x0d; //master, tx, en
while(!(*((u32 *) (AXI_I2C_BASEADDR + ISR)) & 0x40));
*((u32 *) (AXI_I2C_BASEADDR + ISR)) = 0x40;
xil_printf("TMDS181 powered down\n\r");

usleep(10000);
*((u32 *) (AXI_I2C_BASEADDR + CR)) = 0x0;

 

//power up chip
*((u32 *) (AXI_I2C_BASEADDR + TX_FIFO)) = 0xb8; //dev addr
*((u32 *) (AXI_I2C_BASEADDR + TX_FIFO)) = 0x09; //subaddr
*((u32 *) (AXI_I2C_BASEADDR + TX_FIFO)) = 0;//0x08; //data

*((u32 *) (AXI_I2C_BASEADDR + CR)) = 0x0d; //master, tx, en
while(!(*((u32 *) (AXI_I2C_BASEADDR + ISR)) & 0x40));
xil_printf("TMDS181 powered up\n\r");

usleep(10000);
*((u32 *) (AXI_I2C_BASEADDR + CR)) = 0x0;

 

Adventurer
Adventurer
794 Views
Registered: ‎02-14-2009

Re: ZCU104 -- Use HDMI connectors for general purpose data link between two boards ?

Jump to solution

Thanks for sharing!

0 Kudos
Observer sberner66
Observer
784 Views
Registered: ‎10-06-2018

Re: ZCU104 -- Use HDMI connectors for general purpose data link between two boards ?

Jump to solution

I also had to program the 8T49N241 PLL chip working as a synthesiser to have a local reference clock for the aurora module. I took the configuration of the chip from
https://github.com/Xilinx/embeddedsw/blob/master/XilinxProcessorIPLib/drivers/v_hdmirxss/examples/xhdmi_example/idt_8t49n24x.h

which programs the chip to generate an output clk frequency of 148.5 MHz.

static const u8 IDT_8T49N24x_Config_Syn[] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xEF, 0x00, 0x03, 0x00, 0x31, 0x00,
0x04, 0x89, 0x00, 0x00, 0x01, 0x00, 0x63, 0xC6, 0x07, 0x00, 0x00, 0x77,
0x6D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
0x3F, 0x00, 0x28, 0x00, 0x1A, 0xCC, 0xCD, 0x00, 0x01, 0x00, 0x00, 0xD0,
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00,
0x00, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B,
0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x0A, 0x2B, 0x20,
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

*((u32 *) (AXI_I2C_BASEADDR + CR)) = 0x05;
*((u32 *) (AXI_I2C_BASEADDR + TX_FIFO)) = 0x100|T49N241_BASE_ADDR;
*((u32 *) (AXI_I2C_BASEADDR + TX_FIFO)) = 0; //offset MSB
*((u32 *) (AXI_I2C_BASEADDR + TX_FIFO)) = 0; //offset LSB
u32 i;


for(i=0; i<sizeof(IDT_8T49N24x_Config_Syn)-1; i++)
{
while(*((u32 *) (AXI_I2C_BASEADDR + SR)) & 0x10); //while tx fifo full
//*((u32 *) (AXI_I2C_BASEADDR + TX_FIFO)) = IDT_8T49N24x_Config_JA[i];
*((u32 *) (AXI_I2C_BASEADDR + TX_FIFO)) = IDT_8T49N24x_Config_Syn[i];
}
while(*((u32 *) (AXI_I2C_BASEADDR + SR)) & 0x10); //while tx fifo full
//*((u32 *) (AXI_I2C_BASEADDR + TX_FIFO)) = 0x200|IDT_8T49N24x_Config_JA[sizeof(IDT_8T49N24x_Config_JA)-1];
*((u32 *) (AXI_I2C_BASEADDR + TX_FIFO)) = 0x200|IDT_8T49N24x_Config_Syn[sizeof(IDT_8T49N24x_Config_JA)-1];

xil_printf("8T49N241 full config\n\r");

NOTE:

For an unknown reason before being able to program the chip I have to do some other i2c ops. In my case I am running a loop scanning for i2c slaves. Otherwise the  8T49N241 is unresponsive. Why ????

 

 

 

 

0 Kudos
Observer sberner66
Observer
784 Views
Registered: ‎10-06-2018

Re: ZCU104 -- Use HDMI connectors for general purpose data link between two boards ?

Jump to solution

SUMMARY:

To get the link working the following steps are necessary.

1) Instantiate an aurora8b10b module, connect the lane(s) to the HDMI pair(s), choose ref clk 0 in the aurora GUI which connects the clk from the 8T49N241 PLL chip. aurora64b66b may work to, but haven't retried.

2) Program the 8T49N241 as a synthesizer generating 148.5 MHz as shown above. Adjust the rate of the aurora module in the GUI such that 148.5MHz is a legal reference clk frequency, select this ref clk frequency. For example, the lowest possible rate it 4*148.5 MHz

3) Program the driver chip and receiver chip for redriver mode as shown above because in retiming mode the operation of these chips relies on a valid HDMI signal

 

0 Kudos