MCher6
New Contributor
8 years agoSoC 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
For this reason, reading does not work.
How I can set read/write transaction without stop in between?