0

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?

embedded.kyle
  • 10,976
  • 5
  • 37
  • 56
thehilmisu
  • 342
  • 1
  • 5
  • 13

1 Answers1

2

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));
D Krueger
  • 2,446
  • 15
  • 12
  • How do you know this without knowing the device? – László Papp Jan 11 '14 at 05:14
  • @MartinJames: the OP did not actually publish the device, so I am not sure what manual you would read then... Perhaps the OP and Krueger had a previous discussion, so the context was known, but for new people like me, it is not. That is why asking for clarification... – László Papp Jan 12 '14 at 19:10
  • the device is a RTC, ds1337. here it's datasheet datasheets.maximintegrated.com/en/ds/DS1337-DS1337C.pdf – thehilmisu Jan 13 '14 at 07:51
  • it works but i dont understand how can you understand without knowing the device ? Are all RTC Devices have the same standards ? – thehilmisu Jan 13 '14 at 07:59
  • 1
    Using binary-coded decimal for clock values isn't a standard, but it's also not unusual. If you convert the example counts in the question to hexadecimal representations, the pattern is easy to see. – D Krueger Jan 13 '14 at 17:11