Trenz Electronic GmbH Support Forum

Trenz Electronic Products => Trenz Electronic FPGA Modules => Topic started by: dave74321 on July 19, 2018, 05:27:26 PM

Title: TE0720 I2C-bus to RTC
Post by: dave74321 on July 19, 2018, 05:27:26 PM
I am using TE0720-03-1CFA modules.

The sda_in on the Zynq (CPLD_X5 to Zynq pin p22) is at logic '0' following boot of the Zynq (irrespective of boot from SD-Card or from JTAG). (The SDA line of the RTC is at logic '1').

This causes the software that I am using to hang (XIic_DynSend in xiix_l.c waits forever waiting for the bus to go busy).

Manually controlling the sda_out and scl_out I have found that if I toggle them both a few times the sda_in will go to logic '1' and from then on the software is able to use the I2C-Bus with the RTC fine.

The attached images show sda_out (yellow top trace), scl_out (blue middle trace) and sda_in (purple lower trace).

I would be interested to know what is in the CPLD if that is available?

Does the toggling of sda_out and scl_out sound like a okay solution or is there a better fix?

Thanks.
Title: Re: TE0720 I2C-bus to RTC
Post by: JH on July 20, 2018, 07:36:50 AM
Hi,
it's three wire I2C to two wire I2C and a I2C to GPIO expander:
   SCL <= X1;
   -- SDA tristate support mux
   SDA_in <= SDA;
   X5 <= SDA_in and gpio_sda_out;
   SDA <= '0' when X7 = '0' else 'Z';


How did you connect I2C on FPGA? We provide IP for this on our reference design (RTC is used in this linux example):br
John
Title: Re: TE0720 I2C-bus to RTC
Post by: monkeysewt on July 20, 2018, 10:07:08 PM
Hi John,

I'm a little confused about the System Controller.  The Block Design for the reference design that you linked shows the EXT_I2C interface of the System Controller is unconnected.  However, the VHDL source for the System Controller shows that the sda from the CPLD (PL_pin_P22) is logical ANDed with sda from the EXT_I2C (ext_sda_i):

        -- I2C bus merger
ext_sda_o <= sda_o;
ext_sda_t <= sda_t;
ext_scl_t <= scl_t;


-- SDA readback from SC to I2C core
sda_i <= PL_pin_P22 and ext_sda_i;
-- SDA/SCL pass through to SC
PL_pin_N22 <= sda;
PL_pin_L16 <= scl;
-- internal signals
sda <= sda_o or sda_t;
scl <= scl_o or scl_t;
-- SCL feedback to I2C core
scl_i <= scl;

So how can the processor read back from the RTC via the CPLD if that data gets logical ANDed with zero?

Thanks for any assistance!
Title: Re: TE0720 I2C-bus to RTC
Post by: dave74321 on July 23, 2018, 11:19:56 AM
Hi JH,
I'm using a Xilinx AXI IIC block, connected through some logic I copied from the Trenz example.

As a test I just tried connecting to the I2C-Bus sda_out and scl_out pins of the Zynq with GPIO controlled by the processor.  i.e. I just manual control these pins without any I2C-bus logic.

I need to toggle the sda_out and scl_out signals in order to get the sda_out to go high.

In the code you showed, what is "gpio_sda_out"? As perhaps this is holding X5 low?

Thanks
Dave

Hi monkeysewt,
ext_sda_i will be optimised out if not used or should be at '1' as this is its inactive state.
Dave
Title: Re: TE0720 I2C-bus to RTC
Post by: monkeysewt on July 23, 2018, 08:04:31 PM
Fascinating!  I feel confident that ISE would optimize all unconnected signals to logic '0.'  I see in post-synthesis schematic that Vivado has optimized ext_sda_i to logic '1.'  In post-implementation Device view, I see the signal goes directly from the IBUF to the PS, so ext_sda_i has indeed been optimized out, and sda goes to sda just as it should.

Thanks, Dave!
Title: Re: TE0720 I2C-bus to RTC
Post by: JH on July 23, 2018, 08:58:32 PM
Hi,

it's more IP setup, see attachment.

br
John
Title: Re: TE0720 I2C-bus to RTC
Post by: monkeysewt on July 23, 2018, 09:57:35 PM
That makes more sense.  Thanks for the details, John.  Still wading my way deeper into Vivado...
Title: Re: TE0720 I2C-bus to RTC
Post by: dave74321 on July 24, 2018, 09:32:07 AM
Hi JH,
Going back to the initial question of this post...i.e. the problem with the Zynq sda_in line being driven low by the CPLD.

Please refer to the attachment that shows what happens to the Zynq sda_in signal when the Zynq sda_out and scl_out are toggled.

Is this behaviour expected?
In the code you showed, what is "gpio_sda_out"?? Perhaps it is this that is causing the Zynq sda_in to go low? - how can I get the CPLD to set gpio_sda_out high?

Thanks
Dave
Title: Re: TE0720 I2C-bus to RTC
Post by: JH on August 06, 2018, 10:02:09 AM
Hi Dave,

can you try out one time the reference design and check if RTC works:

prebuilt boot.bin and image.ub are included.


Did you use our IP in Vivado?

If not how did you connect I2C?

gpio_sda_out is the output from an I2C slave. You can get access with I2C address 0x21:


--
-- Address 0x21
--
My_GPIO: I2C_to_GPIO port map (
sda_in => X7,
        sda_out => gpio_sda_out,
        sclk => X1,

        GPIO_input =>  GPIO_input,
        GPIO_output => GPIO_output
);




module I2C_to_GPIO (sda_in, sda_out, sclk,
GPIO_input,
GPIO_output
);

....
always@(negedge sclk)
    if (start_stop) begin
        if (~ack_flag) begin                             
            if ( add_is_matching  & ~write_flag) begin sda_out <= 1'b0;
            end else begin sda_out <= 1'b1;
            end
// Latch inputs
            if (read_oper & ~done) GPIO_input_reg <= GPIO_input_muxed;

        end else if (read_oper & data_or_address & ~done) begin
             if (ack_flag) begin
                 if (~GPIO_input_reg[7]) begin
                     sda_out <= 1'b0;
                 end else begin
                     sda_out <= 1'b1;
                 end
                 GPIO_input_reg <= GPIO_input_reg << 1;                   
             end
        end else begin
             sda_out <= 1'b1;
        end
    end
....

If you did not write to this I2C to GPIO expander, it's high.

br
John
Title: Re: TE0720 I2C-bus to RTC
Post by: dave74321 on August 08, 2018, 11:04:50 AM
Hi JH,
I interface the Xilinx AXI IIC blocks to some RTL that was based on the Trenz IP block (I removed the external I2C-bus).

To try the reference design: I added 3 test points (to take to oscilloscope) onto sda_out, scl_out and sda_in in te0720-test_board-vivado_2016.2-build_07_20161018124647, then built it, exported to SDK, created "Hello World" app in SDK and then programmed the Zynq with it.  This confirms that on power-up sda_in is at logic '0' (with sda_out and scl_out at logic '1' and also the sda from the RTC on resistor R48 at logic '1').

I could not see in your CPLD code where the sda_out (gpio_sda_out) default value is set before a sclk edge and start_stop has occurred?

It would seem that gpio_sda_out is holding the sda line low until there have been some transitions on the sda and scl lines from the Zynq to the CPLD (as shown in image attached).  Therefore unless the CPLD changes the best solution seems to be for me to put some sda and scl transitions on the I2C-bus after power-up before using it?
Title: Re: TE0720 I2C-bus to RTC
Post by: JH on August 08, 2018, 12:51:45 PM
Hi,

can you start the prebuilt Boot.bin and image.ub one time please.

On Linux you can check RTC:
Login and type: dmesg | grep rtc
This shows  rtc part of the boot log

This works on my place.

But I've check code again, it seems default value is not set, so it can be that sda is zero until first falling SCLK appears.

Why did you use AXI I2C and not I2C interface from PS?

So either PS I2C works a little bit different than AXI I2C or linux retry to get access to RTC and  onthe second attempt it works.

So some dummy access to I2C bus should solve this problems in your case.

br
John





Title: Re: TE0720 I2C-bus to RTC
Post by: monkeysewt on August 08, 2018, 03:05:16 PM
Dave -

I've successfully implemented my own RTL for the connecting the RTC IIC interface to AXI.  We are also running a bare-metal application, so we did it without any drivers (beyond what Xilinx hides in there).  I checked the signals on my scope (between the CPLD and the RTC), and they all look perfect.

Mind you, I didn't use the Xilinx IIC-to-AXI IP.  We already had an AXI status/control register architecture in place between the PS and the rest of the RTL.  So I have data into and out of my IIC RTL, along with control and status bits.  Did you OR together the SDA out to the CPLD with the SDA tri-state, as Trenz does in their System Controller IP?  In my RTL, I have:

SDA_out_to_CPLD <= SDA_out_from_RTL or SDA_t_from_RTL;
SCL_out_to_CPLD <= SCL_out_from_RTL;
SDA_in_to_RTL <= SDA_in_from_CPLD;

I'm not using the GPIO expander, and there's no accelerometer/magnetometer on the board, so the CPLD is only passing IIC through to the RTC.  Thus, I omitted the System Controller IP from my PL design.

The RTC datasheet could be a little more explicit about reading and writing the time/date registers.  All the information is there, but it's a little disjoint and leaves some points open to inference.

John and Dave - thanks for all the useful replies in this thread, which was a big help all around.
Title: Re: TE0720 I2C-bus to RTC
Post by: dave74321 on August 09, 2018, 11:13:09 AM
Hi monkeysewt,
Thanks for the news on getting it working.
The signals between the CPLD and RTC are fine for me too; it is the sda signal from the CPLD to the Zynq that has the start-up issue.
In a test case I just drove the pins to the CPLD with GPIO controlled by the processor, hence removing any concerns regarding I2C-bus tri-state interfaces.
Looks like the sda initially being logic '0' is an issue for me because I'm using the drivers for the Xilinx AXI-IIC IP blocks.


Hi JH,
Thanks for sharing some of the CPLD code.

I'm using a TE0720 module on my own hardware and not on a test board. I did just try booting from the prebuilt image.ub and Boot.bin from SD-Card but nothing appeared in my terminal window (Tera Term) connected to UART1 on MIO12 and MIO13 (pins C5 and A6).

I'm using the Xilinx AXI IIC blocks because at the start of development the design example I used on a Zedboard used them, and I have used them since.  I've not currently got time to swap to using the PS I2C but will do at some point.

Seems I probably would not have noticed the issue if my I2C read function skipped the first time but it got stuck in an infinite loop when the function XIic_DynRecv was called in xiix_l.c (in the BSP ps7_cortexa9_0/libsrc/iic_v3_4).  It gets stuck waiting for the bus to go busy.  A write function also gets stuck.

I now drive the I2C-Bus with GPIO as well as the AXI IIC, to allow me to toggle them after power-up.  From then on it works fine – as shown in attached image.

Thank you.

PS Ignore the signal labelled "SDA_RTC" in the attached image as the probe was not connected.
Title: Re: TE0720 I2C-bus to RTC
Post by: JH on August 09, 2018, 12:07:27 PM
Hi,

nice to hear the it works now.

We use default UART0 : MIO14..15
This is connected to the second FTDI port of our carrier (or XMOD FTDI in case of TE0706), so you can use uart over the same USB cable the JTAG.
br
John