Community
cancel
Showing results for 
Search instead for 
Did you mean: 
MCher6
Beginner
1,189 Views

SoC and i2c read/write transaction without stop in between.

I connect FXOS8700CQ to SoC with Intel FPGA Avalon I2C (Master) Core.

Add to *.dts:

i2c_accelerometer: i2c@0x000010300 { compatible = "altr,softip-i2c-v1.0"; reg = <0x00000000 0x00010300 0x00000040>; interrupt-parent = <&hps_0_arm_gic_0>; interrupts = <0 51 4>; clocks = <&clk_0>; clock-frequency = <100000>; #address-cells = <1>; #size-cells = <0>; fifo-size = <32>; }; //end i2c@0x000010300 (i2c_accelerometer)

Program:

#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/ioctl.h> #include <linux/i2c.h> #include <linux/i2c-dev.h>   #include <unistd.h>   #define I2C_ADAPTER "/dev/i2c-0"   void read_buffer(int fd, unsigned short addr) { struct i2c_rdwr_ioctl_data data; struct i2c_msg messages[2]; unsigned char write_buf[1] = {0x0D}, read_buf[1] = {0x00};   /* * .addr - Адрес устройства (датчика) * .flags - операция чтения или записи (0 - w, 1 - r) * .len - кол-во передаваемых/принимаемых сообщений * .buf - буфер на чтение или запись */ messages[0].addr = addr; messages[0].flags = 0; messages[0].len = 1; messages[0].buf = write_buf;   messages[1].addr = addr; messages[1].flags = 0x1; messages[1].len = 1; messages[1].buf = read_buf;   data.msgs = messages; data.nmsgs = 2;   ioctl(fd, I2C_TIMEOUT, 2); // set the timeout ioctl(fd, I2C_RETRIES, 4); // set the retries   if (ioctl(fd, I2C_RDWR, &data) < 0) { printf("Cant send data!\n"); } else { printf("ID = 0x%x\n", read_buf[0]); }   }   int main(int argc, char **argv) { int fd;   /* * Open I2C file descriptor. */ fd = open(I2C_ADAPTER, O_RDWR);   if (fd < 0) { printf("Unable to open i2c file\n"); return 0; }   while(1) { read_buffer(fd, 0x1E); sleep(1); }   return 0; }

I expect to see on i2c bus:

ST-ADDRESS-W-ACK-DATA-ACK-ST-ADDRESS-R-ACK-DATA-ACK-SP

But in reality, I see:

ST-ADDRESS-W-ACK-DATA-ACK-SP-ST-ADDRESS-R-ACK-DATA-ACK-SP

i2c.jpg

 

 

For this reason, reading does not work.

How I can set read/write transaction without stop in between?

 

0 Kudos
4 Replies
MCher6
Beginner
174 Views

Probably a problem in Linux driver i2c-altera.c

According to the documentation (Documentation/i2c/dev-interface):

ioctl (file, I2C_RDWR, struct i2c_rdwr_ioctl_data * msgset)

 Do combined read / write transaction without stop in between.

 Only valid if the adapter has I2C_FUNC_I2C. The argument is

 a pointer to a

 

 struct i2c_rdwr_ioctl_data {

   struct i2c_msg * msgs; / * ptr to array of simple messages * /

   int nmsgs; / * number of messages to exchange * /

 }

 

 The msgs [] themselves contain further pointers into data buffers.

 If you’re looking at what I2C_M_RD I’m flag on

 Overlaying the ivectl's

 

The i2c-altera.c driver has I2C_FUNC_I2C:

static u32 altr_i2c_func (struct i2c_adapter * adap)   {   return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;   }

 

 

The driver sets STOP when i2c_msg.len = 1 (last data byte):

static void altr_i2c_transfer (struct altr_i2c_dev * idev, u32 data)   {   / * On the last byte, send STOP * /   if (idev-> msg_len == 1)   data | = ALTR_I2C_TFR_CMD_STO;   if (idev-> msg_len> 0)   writel (data, idev-> base + ALTR_I2C_TFR_CMD);   }

 

 

Correctly put STOP after the last byte of the last message.

 

Any thoughts on how to fix this?

MCher6
Beginner
174 Views

I managed!

The changes are very rough and not entirely correct, but the driver works. I did not completely check, but maybe someone will fall into a similar situation.

 

KennyT_Intel
Moderator
174 Views

​Hi,

 

Do you mind to share with us which coding that you have make the changes for the driver to be working?

 

Thanks

MCher6
Beginner
174 Views

​Hi, KTan9.

 

Yes, a modified driver file has been attached to the previous message. Unfortunately, I am not an expert in creating drivers and my fixes are probably not optimal and need to be corrected. I wrote to the driver author (Thor Thayer from Intel), but I haven’t received a response yet.

 

Let me know any news on this issue.

 

Thanks.

Reply