I2C code doesn't work after component update

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
user_1669321
Level 5
Level 5
100 replies posted 50 replies posted 25 replies posted

Hi,

I was using the component SCB_P4 3.20 as an I2C component. I updated the component to 4.0, added the timeout value to the functions, as described in the datasheet, but my code doesn't work anymore. I've compared the generated files before and after the change, but there is too much for me to pinpoint the issue. Here is my code :

#define I2C_TIMEOUT_MS          (100)

int I2C_read(unsigned char *buf, int bufferSize) {

    // Read must be passed the following format with expected start, restart,

    // stop to be inserted

    // buf[0]: ADDRESS + W

    // buf[1]: REG ADDRESS

    // buf[2]: ADDRESS + R

    int cnt,

        status = bufferSize;

    uint32_t devAddr,

             rdVal,

             err;

    // Extracting

    devAddr = (uint32_t)((buf[0] >> 1) & 0x7F);

   

    // Sending Start and address + w followed by the register address

    if ( I2C_I2CMasterSendStart(devAddr, 0, I2C_TIMEOUT_MS) != I2C_I2C_MSTR_NO_ERROR ) { return -1; }

    if ( I2C_I2CMasterWriteByte(buf[1], I2C_TIMEOUT_MS) != I2C_I2C_MSTR_NO_ERROR ) { return -1; }

   

    // Sending Restart and reading data

    I2C_I2CMasterReadBuf(devAddr, buf, bufferSize, I2C_I2C_MODE_COMPLETE_XFER | I2C_I2C_MODE_REPEAT_START);

   

    while( !((err = I2C_I2CMasterStatus()) & (I2C_I2C_MSTAT_RD_CMPLT | I2C_I2C_MSTAT_ERR_XFER)) ) {

        CySysPmSleep();

    }

   

    I2C_I2CMasterClearReadBuf();

   

    return status;

}

int I2C_write(unsigned char *buf, int bufferSize) {

   

    // Write must be passed the following format with expected start and

    // stop to be inserted

    // buf[0]: ADDRESS + W

    // buf[1]: REG ADDRESS

    // buf[2 to 2+bufferSize]: value

    int cnt;

    uint32_t devAddr, err;

   

    // Extracting

    devAddr = (uint32_t)((buf[0] >> 1) & 0x7F);

   

    // Sending Start and address + w followed by the register address and then values

    if ( I2C_I2CMasterSendStart(devAddr, 0, I2C_TIMEOUT_MS) != I2C_I2C_MSTR_NO_ERROR ) { return -1; }

    for ( cnt = 1; cnt < bufferSize + 2; cnt++ ) {

        if ( I2C_I2CMasterWriteByte(buf[cnt], I2C_TIMEOUT_MS) != I2C_I2C_MSTR_NO_ERROR ) { return -1; }

    }

    // Stop

    if ( I2C_I2CMasterSendStop(I2C_TIMEOUT_MS) != I2C_I2C_MSTR_NO_ERROR ) { return -1; }

   

    return bufferSize;

}

0 Likes
1 Solution

Hi Fred,

No problem, I also gave up somewhat and re-wrote my code to use the lower level APIs (with the 4.0 component) eg. read is now:

MasterSendStart

MasterWriteByte

MasterSendRestart

MasterReadByte (repeat as needed with last byte being NAK'd)

MasterSendStop

Vs

MasterSendStart

MasterWriteByte

MasterReadBuf (which seems to be where the problem lies)

Seems to work reliably now, and the timeouts added to the 4.0 component may prove to make the whole thing a little more robust

Cheers

Anthony

View solution in original post

0 Likes
5 Replies
JobinT_31
Employee
Employee
50 solutions authored 25 solutions authored 10 solutions authored

Hi,

Can you try changing this :
#define I2C_TIMEOUT_MS          (100) to

#define I2C_TIMEOUT_MS          (0)

This will make the function waits forever for the action to complete. This will make your code aligned with previous version. May be the timeout is not enough for any of the call.

Please try debugging the code and find which particular step the code is returning error.

Thanks

Jobin GT

0 Likes

Hi Jobin,

I already tried that, but it didn't work either. In debug, the code was stuck in the while loop.

I had a similar problem before making this specific code work where the transaction was done too fast by the time the code was evaluating the while, so the while was always true (see discussion thread here: Is it possible to sleep during I2C transactions? ). I previously fixed that by reducing the I2C clock from 1M to 400k.

0 Likes

Hi Frederic,

I'm experiencing the same problem with very similar code, it seems like I2C_I2CMasterReadBuf() is not working the way it did pre 4.0, have you had any luck finding a solution?

Cheers

Anthony

0 Likes

Hi Anthony,

Unfortunately, I didn't have the time to investigate this problem more, so I kept the component's old version.

Good luck,

Fred

0 Likes

Hi Fred,

No problem, I also gave up somewhat and re-wrote my code to use the lower level APIs (with the 4.0 component) eg. read is now:

MasterSendStart

MasterWriteByte

MasterSendRestart

MasterReadByte (repeat as needed with last byte being NAK'd)

MasterSendStop

Vs

MasterSendStart

MasterWriteByte

MasterReadBuf (which seems to be where the problem lies)

Seems to work reliably now, and the timeouts added to the 4.0 component may prove to make the whole thing a little more robust

Cheers

Anthony

0 Likes