Reputation: 1213
I am trying to read in an i2c value like you would with i2cget, but it is returning the wrong value in one of the cases.
i2cget -y 0 0x57 0x40
returns 0x57
i2cget -y 0 0x3b 0x09
returns 0x86
When I run my program with #define I2C_ADDR 0x57
and buffer[0] = 0x40
my program returns 0x57
.
But when I run my program with #define I2C_ADDR 0x3b
and buffer[0] = 0x09
my program returns 0x00
.
Here is my code:
// #define I2C_ADDR 0x57
#define I2C_ADDR 0x3b
// #define I2C_REG 0x40
#define I2C_REG 0x09
int main(int argc, char **argv) {
char buffer[1];
buffer[0] = I2C_REG;
int fd;
// Get i2c File Descriptor
if((fd = open("/dev/i2c-0", O_RDWR)) >= 0){
// Set i2c Block Address
if((ioctl(fd, I2C_SLAVE, I2C_ADDR)) >= 0) {
// Set i2c Register Address
write(fd, buffer, 1);
// Read data at Register into buffer
read(fd, buffer, 1);
// Close fd
close(fd);
// Print Result
printf("0x%02x\n", buffer[0]);
} else {
// ioctl error
printf("ioctl error: %s\n", strerror(errno));
}
} else {
// file error
printf("Error opening file: %s\n", strerror(errno));
}
return 0;
}
I ran an strace
on i2cget -y 0x3b 0x09
and my program. Here is a piece of output that shows how the 2 reads differ.
i2cget:
open("/dev/i2c-0", O_RDWR|O_LARGEFILE) = 3
ioctl(3, 0x705, 0xbeae5bf8) = 0
ioctl(3, 0x703, 0x3b) = 0
ioctl(3, 0x720, 0xbeae5b4c) = 0
close(3) = 0
my program:
open("/dev/i2c-0", O_RDWR|O_LARGEFILE) = 3
ioctl(3, 0x703, 0x3b) = 0
write(3, "\t", 1) = 1
read(3, "\0", 1) = 1
close(3)
Upvotes: 2
Views: 2680
Reputation: 1213
From the strace
of i2cget
I researched 0x720 and found out it is the value of I2C_SMBUS. I then found the source code for the i2cget
in buildroot
.
There was no use of this in the C code, but there was use of a function i2c_smbus_read_byte_data
. I added this to my code and ran it, it wouldn't run due to the function being undefined. I copied the i2c-dev.h
file from buildroot to my folder and changed the #include
to include the local file and it ran, and output the right data.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <errno.h>
#include "i2c-dev.h"
#define I2C_ADDR 0x3b
#define I2C_REG 0x09
// Prints Value of /dev/i2c-0 at Block 0x3b Register 0x09
int main(int argc, char **argv) {
int fd, res;
if ((fd = open("/dev/i2c-0", O_RDWR)) >= 0) {
ioctl(fd, I2C_SLAVE, I2C_ADDR);
res = i2c_smbus_read_byte_data(fd, I2C_REG);
close(fd);
printf("Value - 0x%02x\n", res);
} else {
printf("Error opening file: %s\n", strerror(errno));
}
return 0;
}
Upvotes: 1