I2C Read and write

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

cross mob
CaDu_3933941
Level 4
Level 4
50 replies posted 25 replies posted 10 replies posted

Hi all,

I am trying to read data from an accelerometer with the following read protocol:

pastedImage_0.png

I tried the following code for it:

uint8 i2c_accelerometer_single_byte_read(uint8 reg)

{  

    uint8 write_stat = 0u;

       

    I2C_MasterSendStart(ACCELEROMETER_ADDR, 0);

      

    while(I2C_MasterStatus() == I2C_MSTAT_XFER_INP){};

   

    write_stat = I2C_MasterWriteByte(reg);

   

    while(I2C_MasterStatus() != I2C_MSTAT_WR_CMPLT){};

   

    I2C_MasterSendRestart(ACCELEROMETER_ADDR, 1);

   

    if(write_stat == I2C_MSTR_ERR_LB_NAK)  /* Return false if the communication attempt was Nacked */

        return FALSE;

       

    return I2C_MasterReadByte(I2C_NAK_DATA);     

}

The problem is, the program keeps getting held up at  the I2C_MasterWriteByte() fct. Does anyone know a better way I could read using the following protocol?

P.S This is the accelerometer I am using:

https://www.nxp.com/docs/en/data-sheet/MMA8452Q.pdf

0 Likes
1 Solution
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

In my sample project MCU Tester

Re: MCU Tester, a Swiss Army Knife for PSoC (CY8CKIT-059 version)

I wrote i2c_read_reg() as below. (i2c_read_reg() in i2c_utils.c)

As I wanted to check the I2C status, the value is retuned in the argument list.

========================

int i2c_read_reg(uint8_t reg_address, uint8_t *value)

{

    uint8 errStatus = I2C_MSTR_NO_ERROR ;

    errStatus = I2C_MasterSendStart(i2c_slave_address, 0) ; /* write access */

    if (errStatus == I2C_MSTR_NO_ERROR) {

        CyDelay(i2c_delay) ;

        errStatus = I2C_MasterWriteByte(reg_address) ;

    } else {

        print("I2C Send Start Failed!\n\r") ;

    }

    if (errStatus == I2C_MSTR_NO_ERROR) {

        CyDelay(i2c_delay) ;

        errStatus = I2C_MasterSendRestart(i2c_slave_address, 1) ; /* read access */

    } else {

        print("I2C Write Reg Address Failed\n\r") ;

    }

    if (errStatus == I2C_MSTR_NO_ERROR) {

        CyDelay(i2c_delay) ;

        *value = I2C_MasterReadByte(I2C_NAK_DATA) ;

    }

    if (errStatus != I2C_MSTR_NO_ERROR) {

        print("I2C Read Reg Data Failed!\n\r") ;

    }

    errStatus = I2C_MasterSendStop() ; 

    return( errStatus ) ;

}

========================

moto

View solution in original post

0 Likes
1 Reply
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

In my sample project MCU Tester

Re: MCU Tester, a Swiss Army Knife for PSoC (CY8CKIT-059 version)

I wrote i2c_read_reg() as below. (i2c_read_reg() in i2c_utils.c)

As I wanted to check the I2C status, the value is retuned in the argument list.

========================

int i2c_read_reg(uint8_t reg_address, uint8_t *value)

{

    uint8 errStatus = I2C_MSTR_NO_ERROR ;

    errStatus = I2C_MasterSendStart(i2c_slave_address, 0) ; /* write access */

    if (errStatus == I2C_MSTR_NO_ERROR) {

        CyDelay(i2c_delay) ;

        errStatus = I2C_MasterWriteByte(reg_address) ;

    } else {

        print("I2C Send Start Failed!\n\r") ;

    }

    if (errStatus == I2C_MSTR_NO_ERROR) {

        CyDelay(i2c_delay) ;

        errStatus = I2C_MasterSendRestart(i2c_slave_address, 1) ; /* read access */

    } else {

        print("I2C Write Reg Address Failed\n\r") ;

    }

    if (errStatus == I2C_MSTR_NO_ERROR) {

        CyDelay(i2c_delay) ;

        *value = I2C_MasterReadByte(I2C_NAK_DATA) ;

    }

    if (errStatus != I2C_MSTR_NO_ERROR) {

        print("I2C Read Reg Data Failed!\n\r") ;

    }

    errStatus = I2C_MasterSendStop() ; 

    return( errStatus ) ;

}

========================

moto

0 Likes