I am trying to write an embedded qt application that reads the specific i2c rtc device. Here is my code to init i2c:
int addr = 0x68; // The I2C address of the RTC
sprintf(filename,I2C_FILE_NAME);
if ((file = open(filename,O_RDWR)) < 0)
{
qDebug()<<"Failed to open the bus.";
return;
}
if (ioctl(file,I2C_SLAVE_FORCE,addr) < 0)
{
qDebug()<<"Failed to acquire bus access and/or talk to slave.\n";
return;
}
To read from device:
unsigned char addr = 0x68;
unsigned char reg = 0x00;
unsigned char inbuf[2], outbuf;
struct i2c_rdwr_ioctl_data packets;
struct i2c_msg messages[2];
/*
* In order to read a register, we first do a "dummy write" by writing
* 0 bytes to the register we want to read from. This is similar to
* the packet in set_i2c_register, except it's 1 byte rather than 2.
*/
outbuf = reg;
messages[0].addr = addr;
messages[0].flags = 0;
messages[0].len = sizeof(outbuf);
messages[0].buf = &outbuf;
/* The data will get returned in this structure */
messages[1].addr = addr;
messages[1].flags = I2C_M_RD/* | I2C_M_NOSTART*/;
messages[1].len = 2;
messages[1].buf = inbuf;
/* Send the request to the kernel and get the result back */
packets.msgs = messages;
packets.nmsgs = 2;
if(ioctl(file, I2C_RDWR, &packets) < 0)
{
qDebug()<<"Unable to send data";
return;
}
qDebug() << inbuf[0];
What I am trying to do is just read rtc device's register that holds the "seconds". What I get is some numbers but those numbers looks good at first but there is some weird incrementation. Like, 55,56,56,57
then it jumps to 64
? then it is going up to 89
then 0
? I don't know why this happens or what is wrong with my code?
The problem is that the register doesn't hold a simple count for the number of seconds. The upper bits hold tens of seconds and the lower bits hold unit seconds.
You can obtain tens of seconds with (inbuf[0] >> 4) & 0x7;
and unit seconds with inbuf[0] & 0xf
.
Instead of trying to print seconds with qDebug() << inbuf[0];
, use something like:
qDebug() << (10 * ((inbuf[0] >> 4) & 0x7) + (inbuf[0] & 0xf));