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!

Reply

axi_iic driver issue

Accepted Solution Solved
Highlighted
Explorer
Posts: 187
Registered: ‎06-21-2013
Accepted Solution

axi_iic driver issue

Hi all,

 

I am using the linux-xlnx kernel version 4.0 via the meta-xilinx layer in yocto.  The hardware I am developing on has an axi_iic peripheral with a single slave microchip mcp23017 device on the I2C bus.  My associated device tree snippet is shown below.

 

axi_iic_0: axi_iic@70020000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "xlnx,xps-iic-2.00.a";
interrupt-parent = <&intc>;
interrupts = <0 31 4>;
reg = <0x70020000 0x4000>;
xlnx,family = "zynq";
xlnx,clk-freq = <100000000>;
xlnx,iic-freq = <100000>;
xlnx,scl-inertial-delay = <0x0>;
xlnx,sda-inertial-delay = <0x0>;
xlnx,ten-bit-adr = <0x0>;
};

 

&axi_iic_0 {
status = "okay";
gpio@20 {
compatible = "microchip,mcp23017";
gpio-controller;
#gpio-cells = <2>;
reg = <0x20>;
};
};

 

My associated kernel configuration for this device is

 

CONFIG_I2C_XILINX=y
CONFIG_I2C_DEBUG_BUS=y
CONFIG_I2C_SLAVE=y
CONFIG_I2C_SLAVE_EEPROM=y
CONFIG_I2C_DEBUG_CORE=y
CONFIG_GPIO_MCP23S08=y
CONFIG_DEBUG_GPIO=y

 

I have been following the example posted on http://www.wiki.xilinx.com/Linux+I2C+Driver and I am able to use the open and ioctl functions as per

 

int i2c_open (Xuint8 slaveAddress ) {
int Status;

if (pthread_mutex_init(&lock, NULL) != 0)
{
printf("\n mutex init failed\n");
return 1;
}
/*
* Open the device.
*/
Fdiic = open("/dev/i2c-1", O_RDWR);
if(Fdiic < 0)
{
printf("Cannot open the IIC device\n");

return 1;
}

if (ioctl(Fdiic, I2C_SLAVE, slaveAddress) < 0) {
/* ERROR HANDLING; you can check errno to see what went wrong */
return 1;
}

return 0;

}

 

The issue occurs when I try to use the close (), read () or write () functions.  What is strange is that these functions don't appear to be present in the associated <linux/i2c-dev.h> which may be the problem.  Eclipse gives me a warning that these are declared implicitly.  Which header file is used the define these functions?

 

The axi_iic appears as i2c-1 

 

Basic testing response below 

 

ls /dev/*i2c*
/dev/i2c-0 /dev/i2c-1

 

i2cdetect -l gives

i2c-0 i2c Cadence I2C at e0005000 I2C adapter
i2c-1 i2c xiic-i2c I2C adapter

And finally

i2cdetect -F 1
Functionalities implemented by /dev/i2c-1:
I2C yes
SMBus Quick Command yes
SMBus Send Byte yes
SMBus Receive Byte yes
SMBus Write Byte yes
SMBus Read Byte yes
SMBus Write Word yes
SMBus Read Word yes
SMBus Process Call yes
SMBus Block Write yes
SMBus Block Read no
SMBus Block Process Call no
SMBus PEC yes
I2C Block Write yes
I2C Block Read yes

 

I would be very grateful if anyone could provide me with some pointers regarding this issue.

 

Regards

 

 

Walter

 

 

 

 

 

 


Accepted Solutions
Explorer
Posts: 187
Registered: ‎06-21-2013

Re: axi_iic driver issue

[ Edited ]

Okay,

 

Found the problem.  The issue was down to a poky recipe picking an incorrect version of my fpga.bin file.  

 

So it looks like the meta-xilinx and petalinux agree.

 

I never got to find the write, read and close functions.  I suspect these are no longer used.   The i2c_smbus_read_i2c_block_data() and i2c_smbus_write_block_data() work fine.

 

Thanks for every ones help

 

Regards

 

Walter

View solution in original post


All Replies
Adventurer
Posts: 84
Registered: ‎12-03-2015

Re: axi_iic driver issue

There are two i2c-dev.h files. One is the kernel file and the other is from the i2c-tools module.

You have to include the i2c-tools module in the rootfs. This works for Petalinux v2015.4 and linux kernel 4.4.

Run: petalinux-config -c rootfs
Select: -> Filesystem Packages -> base -> i2c-tools

When you do petalinux-build, the I2C package will be downloaded and built into the rootfs. A new include file, i2c-dev-user.h, will be in the <proj-dir>/build/linux/rootfs/stage/usr/include/linux/ directory. This file  has all the i2c_smbus read and write functions in it.

The configuration parameters needed:
ROOTFS_PACKAGES_I2C_TOOLS_MISC
ROOTFS_PACKAGES_I2C_TOOLS_DEV 

The kernel documentation is worth a read also:

https://www.kernel.org/doc/Documentation/i2c/dev-interface

 

 

 

 

Explorer
Posts: 187
Registered: ‎06-21-2013

Re: axi_iic driver issue

[ Edited ]

Hi rgrossman

 

Thank you for your response.  I am using yocto and meta-xilinx to build the Linux distribution.  I was unaware that I needed to add in the i2c-tools to the rootfs so thank you for this pointer.  Setting the options in the linux-xlnx 4.0 kernel did supply several of the i2c-tools such as i2cdetect.

 

I have added the i2c-tools via the following bitbake directive in my machine.conf.   For the purposes of explanation  the company is abc and the machine is set to machine0

 

IMAGE_INSTALL_append_abc-machine0 += " i2c-tools"

 

I can see i2c-dev-user.h in my abc-machines user area

ie

root@abc-machine0:~# locate i2c-dev
/usr/include/linux/i2c-dev-user.h
/usr/include/linux/i2c-dev.h
/usr/src/debug/i2c-tools/3.1.2-r0/i2c-tools-3.1.2/include/linux/i2c-dev.h

 

it is missing from the user/src/debug/i2c-tools area so I need to dig a little deeper.  Eclipse on my cross compiler build host is also unable to locate the i2c-dev-user.h file.  This was after I rebuild the sdk and reinstalled it.  I think I have some more yocto recipe digging to do.

 

I will post my results once I have them

 

Regards

 

Walter

 

 

Explorer
Posts: 187
Registered: ‎06-21-2013

Re: axi_iic driver issue

I think finding the file i2c-dev-user.h was down to the includes search locations specified for the project in eclipse.

 

I added the the following in the path and symbols properties of eclipse

 

usr/local/oecore-x86_64/sysroots/armv7ahf-vfp-neon-oe-linux-gnueabi/usr/include

 

and now I can see 

<linux/i2c-dev-user.h>

 

However, it looks like I either have to use the i2c-dev-user.h or the i2c-dev.h, not both  as the i2c-dev-user.h has these C preprocessor directives at the top.

 

#ifndef _LINUX_I2C_DEV_H
#define _LINUX_I2C_DEV_H

 

The problem with only using  i2c-dev-user.h is that it only contains the smb bus functions ie

 

static inline __s32 i2c_smbus_write_byte(int file, __u8 value)

 

and does not have the necessary open ioctl, read and write functions.    Perhaps my kernel config needs rechecking to force it to use i2c only functions.  Don't appear to link to the library as well so perhaps a lib path needs setting up in eclipse.

 

All a bit confusing.

 

 

 

 

 

Explorer
Posts: 187
Registered: ‎06-21-2013

Re: axi_iic driver issue

Looks like open is in the i2c-dev-user. I2C_SLAVE is not defined.
Explorer
Posts: 187
Registered: ‎06-21-2013

Re: axi_iic driver issue

Hi all,

 

Okay got something sort of working but am having issues, will explain later.

 

It appears that the i2c-dev-user.h/c no longer support the read, write and close functions.  Therefore I am using the smbus equivalents.  

 

To write a byte I use

 

 bytesSent = i2c_smbus_write_byte_data(Fdiic,0x00,0xC0);

 

Another issue I had was with my device tree.  I had specified that the slave device on the bus was 

 

&axi_iic_0 {
status = "disabled";
gpio@20 {
compatible = "microchip,mcp23017";
gpio-controller;
#gpio-cells = <2>;
reg = <0x20>;
};

 

This is not a good idea as the Linux system tries to initialize this device on kernel startup via the i2c-1 device bus.  Unfortunately for reason yet to be determined this process hangs the i2c bus which can be observed on an oscilloscope.  Also the i2cdetect -r 0x20 0x20 crashes the bus after some initial activity.

 

I can run i2cset -t 1 0x20 0x00 0xC0 and the bus signals look good.  However, I get a timeout message now as per my dmesg output

 

[ 731.246721] i2c i2c-1: ioctl, cmd=0x720, arg=0xbefffba4
[ 731.246746] i2c i2c-1: master_xfer[0] W, addr=0x20, len=2
[ 731.246764] xiic-i2c 70020000.axi_iic: xiic_xfer entry SR: 0xc0
[ 731.246781] xiic-i2c 70020000.axi_iic: __xiic_start_xfer entry, msg: ee873e40, fifos space: 15
[ 731.246797] xiic-i2c 70020000.axi_iic: xiic_start_send entry, msg: ee873e40, len: 2
[ 731.246810] xiic-i2c 70020000.axi_iic: xiic_start_send entry, ISR: 0xd0, CR: 0x9
[ 731.246824] xiic-i2c 70020000.axi_iic: xiic_fill_tx_fifo entry, len: 2, fifo space: 15
[ 731.246836] xiic-i2c 70020000.axi_iic: xiic_fill_tx_fifo TX STOP
[ 732.240776] xiic-i2c 70020000.axi_iic: Controller timed out
[ 732.240776] xiic-i2c 70020000.axi_iic: Controller timed out

 

I set the timeout to 10mSec via

ioctl(Fdiic, I2C_TIMEOUT, 10)

but still no joy.  

 

The pull-up resistors are in circuit so more digging is required.

 

Regards

 

Walter

Adventurer
Posts: 84
Registered: ‎12-03-2015

Re: axi_iic driver issue

There is a problem with your device tree. My setup uses an NXP I2C multiplexer instead of a MCP but the setup should be the same.

This is the auto generated entry from zynq-7000.dtsi:

		i2c0: i2c@e0004000 {
			compatible = "cdns,i2c-r1p10";
			status = "disabled";
			clocks = <&clkc 38>;
			interrupt-parent = <&intc>;
			interrupts = <0 25 4>;
			reg = <0xe0004000 0x1000>;
			#address-cells = <1>;
			#size-cells = <0>;
		};

This is entry from the auto generated pcw.dtsi:

&i2c0 {
	clock-frequency = <400000>;
	status = "okay";
};

And finally the entry that I wrote for system-top.dts:

/* I2C Bus Devices */
&i2c0 {
    /* Run at 100 KHz until MBM is fixed */
	clock-frequency = <100000>;
    compatible = "cdns,i2c-r1p14";
    bus-id = <0x0>;

    /* I2C multiplexer */
    i2c_mux@74 {
    	compatible = "nxp,pca9548";
	    #address-cells = <0x1>;
		#size-cells = <0x0>;
		reg = <0x74>;
    
           /* some i2c devices in here */

    };
};

The i2c bus has to be defined first, then you add the devices to the bus. 

We have to add more variables to the setup because it isn't complicated enough! ;-)

 

Explorer
Posts: 187
Registered: ‎06-21-2013

Re: axi_iic driver issue

I am not 100% sure the device tree is at fault.  My reasoning is that the purpose of the user app access is to avoid having to write a driver.  I think when the compatible mcp device is put on the slave list the kernel tries to initialize it with a compatible driver.  This initialization unfortunately crashes the bus.   

 

If I leave the mcp20317 out of the device tree then I can write (See data on scope but still get the timeout issue) bytes using

 

i2cset -y 1 0x20 0x20 0xC0 b   // To write a byte 

or

i2cset -y 1 0x20 0x20 0xC0 0xAB....0xFF i // To write a block 

 

I think this issue may be in the xiic-i2c driver and how it interacts with the mcp20317 device which is not SMB.

 

What I seem to be unable to locate are the basic read, write and close functions in the i2c-dev-user.h.

 

Regards

 

Walter 

 

 

Adventurer
Posts: 61
Registered: ‎11-09-2015

Re: axi_iic driver issue

hi @wmaguire 

    Have you configure "CONFIG_GPIO_MCP23S08" in your kernel, xilinx_zynq_defconfig don't contain it. 

 

 

Explorer
Posts: 187
Registered: ‎06-21-2013

Re: axi_iic driver issue

[ Edited ]

I am beginning to think that the Xilinx driver is not very robust. I think the accuracy of the clocks on the hardware may also be causing the issue. The reason I think this is the case is sending a burst of zeros in the data crashes the bus. I am going to try running the I2C at 50kHz to see if there are any improvements

Thanks


Walter.