• 0
kadionik

I2C PMOD access under Linux

Question

Hi all,

I've built with the Nexyx4 DDR board a system running Linux. In my running HW design, I've added the onboard temperature sensor of the board and the PMOD A connector to connect a I2C TMP3 temperature sensor.

The HW interface for the onboard temperature sensor is the AXI IIC interface.

For the TMP3 sensor with the Digilent's vivado library (as explained in: https://reference.digilentinc.com/learn/programmable-logic/tutorials/pmod-ips/start), it's the AXI LITE IIC interface.

With the Linux I2C tools, I see the onboard sensor:

nexys4ddr:/# uname -r
4.14.0-00493-gb68293ad2c93-dirty  
nexys4ddr:/# i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- 4b -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

And I can read temperature with the Linux I2C API:

nexys4ddr:/# tsttemp
TEMP=29.2 oC
nexys4ddr:/#

But I don't see the I2C TMP3 sensor.

My questions are:

- The vivado TMP3 instance has a I2C interface (AXI LITE IIC). Can I use the Linux I2C API? If yes, on the PMOD ja port, what are the pins of the connector corresponding to SCL, SDA (easy for ground and 3V3 ;-)? I didn't find this information in the Digilent's vivado library.

- If I I can't use the Linux I2C API, I must generate by hand and by software the SCL and SDA signals and what is the role of AXI LITE IIC interface? In this case, would it better to use directly the IIC AXI interface as with the onboard sensor and precise after in a XDC file connexions  between to the PMOD A port and TMP3 sensor?

Thank you for your help.

Pat.

Sans titre.jpg

Share this post


Link to post
Share on other sites

6 answers to this question

Recommended Posts

  • 0

All the information regarding TMP3 is here including pin layout and a link to the IC manufacturer datasheet (for the register space configuration). As far as I can tell the IP is just a wrapper of a AXI IIC IP so I'm guessing that if you instantiated it in the DTS using the xilinx I2C driver you should be fine.

If that doesn't work you can always try to just simply replace the TMP3 IP with a AXI IIC IP and then respecting the IC datasheet you should get it going.

- Ciprian

Share this post


Link to post
Share on other sites
  • 0

Hi Ciprian,

Thank you for your response. I agree with you.

In the first case, with the TMP3 IP with the Digilent's vivado_library, what is the connection between the PMOD A pins from the Nexyx4 DDR board and the TMP3 pins? The TMP3 doesn't respect the PMOD connector. To be clearer, which pins between JA1, JA2, JA3, JA4, JA7, JA8, JA9, JA10 from the PMOD A connector must I use to connect to SCL and SDA pins of the TMP3 sensor?

I'm trying meanwhile the second solution.

 

Cheers.

Pat.

Share this post


Link to post
Share on other sites
  • 0

Eureka! It works with the second solution: instanciate a IIC AXI IP, route SCL and SDA signals to 2 pins from the PMOD JA connector and connect with wires to the TMP3 sensor.

I was confused with the onboard sensor that worked directly and driven by the Xilinx's I2C Linux driver (file drivers/i2c/busses/i2c-xiic.c). I guessed that the AXI IIC IP worked as a I2C passthrough device but with help of PG090 AXI IIC Bus Interface manual (https://www.xilinx.com/products/intellectual-property/axi_iic.html), I saw It's just a gateway and you have to drive many registers. That's what does the i2c-xiic.c Linux driver. With the driver that drives the registers  of the AXI IIC IP, it's easy to use the Linux API (open(), close(), read(), write(), ioctl()). 

For the first I2C sensor, we must use the /dev/i2c/0 character driver file (Major=89 minor=0).

I've enabled I2C debugging in the Linux kernel and found that a second I2C interface was detected for my second AXI IIC IP. So I have created a second character driver file /dev/i2c/1 (Major=89, minor=1) and I have now:

nexys4ddr:/# i2cdetect -y 0                                                     
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f                             
00:          -- -- -- -- -- -- -- -- -- -- -- -- --                             
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                             
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                             
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                             
40: -- -- -- -- -- -- -- -- -- -- -- 4b -- -- -- --                             
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                             
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                             
70: -- -- -- -- -- -- -- --                                                     
nexys4ddr:/# i2cdetect -y 1                                                     
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f                             
00:          -- -- -- -- -- -- -- -- -- -- -- -- --                             
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                             
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                             
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                             
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --                             
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                             
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                             
70: -- -- -- -- -- -- -- --                                                     
nexys4ddr:/# 

I2C Id=0x4b:  ADT7420 temperature onboard sensor of the Nexys4 DDR board.

I2C Id=0x48: TCN75A PMOD TMP3 temperature sensor.

With 2 Linux programs, I can read now temperature:

nexys4ddr:/# adt7420                                                            
TEMP=31.2 oC                                                                    
nexys4ddr:/# tcn75a                                                             
TEMP=25.00 oC                                                                   
nexys4ddr:/# 

Everything is ok now. I'll write a howto in a future post. I'll analyze my first design with the PMOD TMP3 IP from Digilent's vivado_library too.

Cheers.

Pat.

Share this post


Link to post
Share on other sites
  • 0

OK.

With my first design based on the PMOD TMP3 IP from Digilent's vivado_library, I have in my Device Tree:

                PmodTMP3_0: PmodTMP3@40900000 {
                        compatible = "xlnx,PmodTMP3-1.0";
                        interrupt-names = "I2C_Interrupt";
                        interrupt-parent = <&microblaze_0_axi_intc>;
                        interrupts = <4 2>;
                        reg = <0x40900000 0x1000>;

And I have in my IO Vivado report file:

| C14        | temp_sensor_scl_io   | High Range | IO_L1N_T0_AD0N_15            | BIDIR       | LVCMOS33       |      15 |         12 | SLOW |                     |            FP_VTT_50 |         | FIXED      |           |          |          | NONE             |              |                   |              |
| C15        | temp_sensor_sda_io   | High Range | IO_L12N_T1_MRCC_15           | BIDIR       | LVCMOS33       |      15 |         12 | SLOW |                     |            FP_VTT_50 |         | FIXED      |           |          |          | NONE             |              |                   |              |
| C17        | ja_pin1_io           | High Range | IO_L20N_T3_A19_15            | BIDIR       | LVCMOS33       |      15 |         12 | SLOW |                     |            FP_VTT_50 |         | FIXED      |           |          |          | NONE             |              |                   |              |
| D17        | ja_pin7_io           | High Range | IO_L16N_T2_A27_15            | BIDIR       | LVCMOS33       |      15 |         12 | SLOW |                     |            FP_VTT_50 |         | FIXED      |           |          |          | NONE             |              |                   |              |
| D18        | ja_pin2_io           | High Range | IO_L21N_T3_DQS_A18_15        | BIDIR       | LVCMOS33       |      15 |         12 | SLOW |                     |            FP_VTT_50 |         | FIXED      |           |          |          | NONE             |              |                   |              |
| E17        | ja_pin8_io           | High Range | IO_L16P_T2_A28_15            | BIDIR       | LVCMOS33       |      15 |         12 | SLOW |                     |            FP_VTT_50 |         | FIXED      |           |          |          | NONE             |              |                   |              |
| E18        | ja_pin3_io           | High Range | IO_L21P_T3_DQS_15            | BIDIR       | LVCMOS33       |      15 |         12 | SLOW |                     |            FP_VTT_50 |         | FIXED      |           |          |          | NONE             |              |                   |              |
| F18        | ja_pin9_io           | High Range | IO_L22N_T3_A16_15            | BIDIR       | LVCMOS33       |      15 |         12 | SLOW |                     |            FP_VTT_50 |         | FIXED      |           |          |          | NONE             |              |                   |              |
| G17        | ja_pin4_io           | High Range | IO_L18N_T2_A23_15            | BIDIR       | LVCMOS33       |      15 |         12 | SLOW |                     |            FP_VTT_50 |         | FIXED      |           |          |          | NONE             |              |                   |              |
| G18        | ja_pin10_io          | High Range | IO_L22P_T3_A17_15            | BIDIR       | LVCMOS33       |      15 |         12 | SLOW |                     |            FP_VTT_50 |         | FIXED      |           |          |          | NONE             |              |                   |              |

Pins are considered as GPIO pins and no as SCL and SDA signals. In this case, using MOD TMP3 IP from Digilent's vivado_library is well sweeted to bare-metal programming and not to Linux programming.We can see that for the onboard sensor, we have temp_sensor_scl_io temp_sensor_sda_io signals corresponding to I2C SCL and SDA signals. What's what I want!

With, the second design based on the AXI IIC IP, the Device Tree is now:

                axi_iic_1: i2c@40810000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        clock-frequency = <100000000>;
                        clocks = <&clk_bus_0>;
                        compatible = "xlnx,xps-iic-2.00.a";
                        interrupt-names = "iic2intc_irpt";
                        interrupt-parent = <&microblaze_0_axi_intc>;
                        interrupts = <4 2>;
                        reg = <0x40810000 0x10000>;
                };

The second design with the AXI IIC IP is the solution for Linux. The Linux driver used existing one and is i2c-xiic.c. You have just to add XDC file for manual ouput SCL and SDA signal routing from AXII IIC outputs to PMOD connector of your board.

I'll make a tutorial.

Pat.

Edited by kadionik

Share this post


Link to post
Share on other sites
  • 0

My first suggestion was just basically replacing

	PmodTMP3_0: PmodTMP3@40900000 {
                        compatible = "xlnx,PmodTMP3-1.0";
                        interrupt-names = "I2C_Interrupt";
                        interrupt-parent = <&microblaze_0_axi_intc>;
                        interrupts = <4 2>;
                        reg = <0x40900000 0x1000>;

with

	PmodTMP3_0: PmodTMP3@40900000 {
    			clock-frequency = <100000000>;
                        compatible = "xlnx,xps-iic-2.00.a";
                        interrupt-names = "I2C_Interrupt";
                        interrupt-parent = <&microblaze_0_axi_intc>;
                        interrupts = <4 2>;
                        reg = <0x40900000 0x1000>;

and it should work... In theory.

 

Either way, I'm glad you got it going and thank you for your tutorial.

- Ciprian 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now