I2C - Read & Write

22 Aug 2012

I read 7 bytes of info from an IC into an 8 byte array. The first byte returned is the number of bytes to be read to the mbed. That seems right if I output the results to terminal and do the maths.

I then copy all info from the "read" array into a "write" array (with the the offset address of the register I want to write to in position [0]). This to ensure that all info I am not manipulating is "as read" from the IC. I then manipulate the bits I want to change. I then write the register to the IC and read all the contents back a second time and display to terminal.

What I see after reading it a second time after writing is that the contents have shifted down by 1 from the first time I read.

Example: First read array[6] = 8 array[5] = 255 array[4] = 255 array[3] = 246 array[2] = 223 array[1] = 224

Second read array[6] = 8 array[5] = 8 array[4] = 255 array[3] = 255 array[2] = 246 array[1] = 223

I am using a I2C address of 0x20 to address the IC. I am not changing it for read and write. I am not too familiar with I2C. Comments

I am also using the same register offset address for read and write. Is this correct?

Any suggestions?

22 Aug 2012

I guess you refer to the forum thread that you started here. The device you used there is the SM72445. I mentioned in my previous comment that this device sends a dummy length byte (value 7) when reading data. It also expects a dummy length byte value (7) when writing data (See datasheet Fig 12). You dont seem to send that length byte, this probably explains the shift in your results.

So in very step-by-step mode your code should be something like this:

#include "mbed.h"

I2C i2c(p9, p10);        // sda, scl
Serial pc(USBTX, USBRX); // tx, rx

const int addr = 0x00 ... 0x07; // define the correct I2C Address    

int main() 
{
    char regaddr[1];
    char readdata[8]; // room for length and 7 databytes
    char writedata[9]; // room for reg address, length and 7 databytes
    while (1) 
    {
        // read the data
        regaddr[0] = 0xE0;
        i2c.write(addr, regaddr, 1, true);  // select the register, no I2C Stop
        i2c.read(addr, readdata, 8);        // read the length byte and the 7 databytes
        
        wait (1);

        // print the data to the screen
        pc.printf("Register 0x%x = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\r\n",
                  regaddr[0],
                  readdata[1], readdata[2], readdata[3], readdata[4],
                  readdata[5], readdata[6], readdata[7] );
        wait(1);

        // copy the data, starting with register address
        writedata[0] = regaddr[0];  // register address
        writedata[1] = readdata[0]; // length, should be 7
        writedata[2] = readdata[1]; // byte 1
        writedata[3] = readdata[2];
        writedata[4] = readdata[3];
        writedata[5] = readdata[4];
        writedata[6] = readdata[5];
        writedata[7] = readdata[6];
        writedata[8] = readdata[7]; // byte 7

        // write the data
        i2c.write(addr, writedata, 9); // select the register, 
                                       // write the length, write 7 databytes      
        wait(1);

    }
}

20 Apr 2018

Hello really interesting, thanks

I'm Just starting with C code for micros. Is there any guide or step by step commented guide of how to read/write parameters or registers in C code? I mean, really for dummies and explaining it from the C point of view. Ir real examples much better. If that examples does come with real AD converters, DACs orTemp sensors from Maxim, even better.

Thanks in advance !