I2C write problem

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

cross mob
Anonymous
Not applicable

Hi

I am trying to interface InvenSense MPU9150 motion detector sensor with Tag3 board. I found difficulty when i tried to write 0 on one of register of sensor in order to start sensor. I am very new in I2C programming. I posted function below kindly look into this. Thanks

UINT8 sensor_app_writeSensor(UINT8 register_address, UINT8 data)

{

    UINT8 read_status;

    UINT8 return_value = 0;

    UINT8 reg_data_bytes[2];

    reg_data_bytes[0]= register_address;

    reg_data_bytes[1] = data;

    read_status = i2cm_write(reg_data_bytes, sizeof(reg_data_bytes), MPU9150_I2C_ADDRESS);

    ble_trace1("read status=%d\n",MPU9150_PWR_MGMT_1);

    switch(read_status)

    {

        case I2CM_BUSY:

            // Transaction did not go through. ERROR. Handle this case.

        ble_trace0("\ndone4.\n");

            break;

        case I2CM_SUCCESS:

            // The read was successful.

        ble_trace0("\ndone5.\n");

            return_value = 1;

            break;

        case I2CM_OP_FAILED:

            // No slave device with this address exists on the I2C bus. ERROR. Handle this.

        ble_trace0("\ndone6.\n");

        default:

            break;

    }

    return return_value;

}

void  motion_sensor_read_and_print_motion_data(void)

{    UINT8 return_value = 0;

     INT8 motion_data;

     INT16 gcd;

     i2cm_init();

          /* the default speed is 100kHz, it's not required the speed config. */

          i2cm_setSpeed(I2CM_SPEED_400KHZ);

          i2cm_setTransactionSpeed();

              

          sensor_app_writeSensor(MPU9150_PWR_MGMT_1, 0);

          ble_trace0("\nStarting new measurement.\n");

   

    motion_data=sensor_app_readSensor(MPU9150_ACCEL_XOUT_L,MPU9150_ACCEL_XOUT_H);

         ble_trace1("motion_sensor_read_motion_data returned %d\n",motion_data);

   

}

0 Likes
1 Solution
Anonymous
Not applicable

Now I2C is working i just did shifting on my I2C address and it start working.

int MPU9150_I2C_ADDRESS = (0x68<< 1) ;

Thanks for help and support.

View solution in original post

0 Likes
16 Replies
JacobT_81
Employee
Employee
250 replies posted 100 replies posted 50 replies posted

msiddique

Unfortunately, none of the i2cm API functions work any more. In order to interface to i2c please use the cfa.h library.

Remove the setSpeed and setTransactionSpeed from your code, and replace your sensor_app_writeSensor function with something that resembles the code in i2c_temperature_sensor.c.

UINT8 sensor_app_writeSensor(UINT8 register_address, UINT8 data)

{

    CFA_BSC_STATUS read_status;

    UINT8 return_value = 0;

    UINT8 reg_data_bytes[2];

    reg_data_bytes[0]= register_address;

    reg_data_bytes[1] = data;

    read_status = cfa_bsc_OpExtended(reg_data_bytes, sizeof(reg_data_bytes), NULL,

                                             0, MPU9150_I2C_ADDRESS, I2C_SLAVE_OPERATION_WRITE);

    switch(read_status)

    {

        case CFA_BSC_STATUS_INCOMPLETE:

            break;

        case CFA_BSC_STATUS_SUCCESS:

            return_value = 1;

            break;

        case CFA_BSC_STATUS_NO_ACK:

        default:

            break;

    }

    return return_value;

}

Then call the function as you do already in the code.

*Import cfa.h. And define "I2C_SLAVE_OPERATION_READ" in your code as either a zero or a one. This can very from chip to chip, but generally is one.

Jacob

0 Likes
Anonymous
Not applicable

Hi Jacob

Thank you for your reply now write function is working fine. I have problem with read function i have sensor register address which is 12 bit long. I want to read from that register i made a function but it is not working.

UINT8 sensor_app_readSensor(UINT8 register_address_L, UINT8 register_address_H)

{

  CFA_BSC_STATUS read_status;

     UINT8 return_value = 0;

     UINT8 reg_bytes_to_read[1];

     // Do a combo write then read operation

     read_status = cfa_bsc_OpExtended(reg_bytes_to_read, sizeof(reg_bytes_to_read), &register_address_L,

                                                         sizeof(register_address_L), MPU9150_I2C_ADDRESS,

                                                         I2C_SLAVE_OPERATION_READ);

     int L = reg_bytes_to_read[0];

          // CFA_BSC_STATUS read_status;

         //UINT8 return_value = 0;

         //UINT8 reg_bytes_to_read[1];

         // Do a combo write then read operation

         read_status = cfa_bsc_OpExtended(reg_bytes_to_read, sizeof(reg_bytes_to_read), &register_address_H,

                                                             sizeof(register_address_H), MPU9150_I2C_ADDRESS,

                                                             I2C_SLAVE_OPERATION_READ);

        int H = reg_bytes_to_read[0];

    switch(read_status)

    {

        case CFA_BSC_STATUS_INCOMPLETE:

            // Transaction did not go through. ERROR. Handle this case.

            ble_trace0("\ndone1.\n");

            break;

        case CFA_BSC_STATUS_SUCCESS:

            // The read was successful.

        //*data = reg_bytes_to_read[0];

                   return_value = 1;

            ble_trace0("\ndone2.\n");

            break;

        case CFA_BSC_STATUS_NO_ACK:

            // No slave device with this address exists on the I2C bus. ERROR. Handle this.

            ble_trace0("\ndone3.\n");

        default:

            break;

    }

    return return_value;

}

void  motion_sensor_read_and_print_motion_data(void)

{    UINT8 return_value = 0;

     INT8 motion_data;

     INT16 gcd;

     UINT8 sen_data;

    // i2cm_init();

          /* the default speed is 100kHz, it's not required the speed config. */

          //i2cm_setSpeed(I2CM_SPEED_400KHZ);

          //i2cm_setTransactionSpeed();

          sensor_app_writeSensor(MPU9150_PWR_MGMT_1, 0);

          ble_trace0("\nStarting new measurement.\n");

    motion_data=sensor_app_readSensor(MPU9150_ACCEL_XOUT_L,MPU9150_ACCEL_XOUT_H);

         ble_trace1("motion_sensor_read_motion_data returned %d\n",motion_data);

}

0 Likes
JacobT_81
Employee
Employee
250 replies posted 100 replies posted 50 replies posted

msiddique

Sorry for the delay. In this case, I would suggest making a single 8-bit read function, and calling it twice back to back for the high and low registers, and finally parsing the data at the end. Again, we can see an example of the 8-bit read in the i2c_temperature_sensor.c:

UINT8 sensor_app_readSensor(UINT8 register_address, UINT8* data)

{

    CFA_BSC_STATUS read_status;

    UINT8 return_value = 0;

    UINT8 reg_bytes_to_read[1];

    // Do a combo write then read operation

    read_status = cfa_bsc_OpExtended(reg_bytes_to_read, sizeof(reg_bytes_to_read), &register_address,

                                                        sizeof(register_address), MPU9150_I2C_ADDRESS,

                                                        I2C_SLAVE_OPERATION_READ);

    switch(read_status)

    {

        case CFA_BSC_STATUS_INCOMPLETE:

            // Transaction did not go through. ERROR. Handle this case.

            break;

        case CFA_BSC_STATUS_SUCCESS:

            // The read was successful.

            *data = reg_bytes_to_read[0];

            return_value = 1;

            break;

        case CFA_BSC_STATUS_NO_ACK:

            // No slave device with this address exists on the I2C bus. ERROR. Handle this.

        default:

            break;

    }

    return return_value;

}

Your new call to these function will look something like this:

void  motion_sensor_read_and_print_motion_data(void)

{    UINT8 return_value = 0;  

     UINT8 motion_data_h;

     UINT8 motion_data_l;

     INT16 gcd;

     UINT8 sen_data;

     sensor_app_writeSensor(MPU9150_PWR_MGMT_1, 0);

     ble_trace0("\nStarting new measurement.\n");

     sensor_app_readSensor(MPU9150_ACCEL_XOUT_L, &motion_data_l);

     sensor_app_readSensor(MPU9150_ACCEL_XOUT_H, &motion_data_h);

     //parse your data here

}


Jacob


0 Likes
Anonymous
Not applicable

jacob.duijzer

Thanks for your reply. Still i am not able to read from register. It is always goes to CFA_BSC_STATUS_NO_ACK. When i tried to write it was successful i assign I2C_SLAVE_OPERATION_WRITE to 0. My code is similar to your code.

#define MPU9150_GYRO_XOUT_H        0x43   // R

#define MPU9150_GYRO_XOUT_L        0x44   // R

#define MPU9150_GYRO_YOUT_H        0x45   // R

#define MPU9150_GYRO_YOUT_L        0x46   // R

#define MPU9150_GYRO_ZOUT_H        0x47   // R

#define MPU9150_GYRO_ZOUT_L        0x48   // R

#define MPU9150_PWR_MGMT_1         0x6B

// I2C address 0x69 could be 0x68 depends on your wiring.

int MPU9150_I2C_ADDRESS = 0x68;

// Read operation to the lower level driver is 1.

#define I2C_SLAVE_OPERATION_READD                    (1)

// Write operation to the lower level driver is 0.

#define I2C_SLAVE_OPERATION_WRITEE                   (0)

UINT8 sensor_app_readSensor(UINT8 register_address, UINT8* data)

{

  CFA_BSC_STATUS read_status;

     UINT8 return_value = 0;

     UINT8 reg_bytes_to_read[1];

     // Do a combo write then read operation

     read_status = cfa_bsc_OpExtended(reg_bytes_to_read, sizeof(reg_bytes_to_read), &register_address,

                                                         sizeof(register_address), MPU9150_I2C_ADDRESS,

                                                         I2C_SLAVE_OPERATION_READD);

    switch(read_status)

    {

        case CFA_BSC_STATUS_INCOMPLETE:

            // Transaction did not go through. ERROR. Handle this case.

            ble_trace0("done1.\n");

            break;

        case CFA_BSC_STATUS_SUCCESS:

            *data = reg_bytes_to_read[0];

            return_value = 1;

            ble_trace0("done2.\n");

            break;

        case CFA_BSC_STATUS_NO_ACK:

            // No slave device with this address exists on the I2C bus. ERROR. Handle this.

          //  ble_trace0("done3.\n");

        default:

            break;

    }

    return return_value;

}

////////////////////////////////call////////////////////////////////////////////////

void  motion_sensor_read_and_print_motion_data(void)

{    UINT8 return_value = 0;

     UINT8 motion_data_h;

     UINT8 motion_data_l;

     INT16 gcd;

     INT16 sen_data;

     sensor_app_writeSensor(MPU9150_PWR_MGMT_1, 0x00);

     ble_trace0("Starting new measurement.\n");

     sensor_app_readSensor(MPU9150_GYRO_XOUT_L, &motion_data_l);

     sensor_app_readSensor(MPU9150_GYRO_XOUT_H, &motion_data_h);

     sen_data = (motion_data_h << 8 | motion_data_l);

     ble_trace1("motion_sensor_read_motion_data returned %d\n",sen_data);

     sensor_app_readSensor(MPU9150_GYRO_YOUT_L, &motion_data_l);

     sensor_app_readSensor(MPU9150_GYRO_YOUT_H, &motion_data_h);

     sen_data = (motion_data_h << 8 | motion_data_l);

     ble_trace1("motion_sensor_read_motion_data returned %d\n",sen_data);

     sensor_app_readSensor(MPU9150_GYRO_ZOUT_L, &motion_data_l);

     sensor_app_readSensor(MPU9150_GYRO_ZOUT_H, &motion_data_h);

     sen_data = (motion_data_h << 8 | motion_data_l);

     ble_trace1("motion_sensor_read_motion_data returned %d\n",sen_data);

}

0 Likes
JacobT_81
Employee
Employee
250 replies posted 100 replies posted 50 replies posted

msiddique

I've got one last piece of code for you to try here:

UINT8 sensor_app_readSensor(UINT8 Reg, UINT8* Data){

       CFA_BSC_STATUS read_status;

       UINT8 return_value = 0;

       read_status = cfa_bsc_OpExtended(Data, sizeof(u8_t), &Reg, sizeof(u8_t),        LSM9DS1_ACC_GYRO_I2C_ADDRESS , I2C_SLAVE_OPERATION_READ);

       switch(read_status)

       {

         case CFA_BSC_STATUS_INCOMPLETE:

               return;

               break;

          case CFA_BSC_STATUS_SUCCESS:

               return_value = 1;

               return;

               break;

         case CFA_BSC_STATUS_NO_ACK:

         default:

               break;

       }

     return;

}

Every i2c sensor is a little different and won't necessarily respond to the API in the same way as another sensor. This may require some trial and error work.

-Be sure you're reading from the correct address (as shifted by your SA0 pin).

-Be sure power is applied to the sensor

-Be sure your pull up resistors are configured correctly. (Have you used this i2c line with other sensors?)

Jacob

0 Likes
Anonymous
Not applicable

I am having the same problem. Write operation (0 in my case) returns CFA_BSC_STATUS_SUCCESS, but the exact same code with read operation(1) to the same register with the same parameters returns CFA_BSC_STATUS_NO_ACK.

This is the write code that is working for me:

    UINT8 writeData[2];

    writeData[0] = register_address;

    writeData[1] = register_value;

    CFA_BSC_STATUS writeStatus = cfa_bsc_OpExtended(writeData, sizeof(writeData),

                                                    NULL, 0,

                                                    I2C_SLAVE_ADDRESS, I2C_SLAVE_OPERATION_WRITE);

This is the read code that is not working:

    UINT8 readData[2];

    readData[0]= register_address;

    readData[1] = register_value;

    CFA_BSC_STATUS readStatus = cfa_bsc_OpExtended(readData, sizeof(readData),

                                                   NULL, 0,

                                                   I2C_SLAVE_ADDRESS, I2C_SLAVE_OPERATION_READ);

I also tried this, with no luck:

    UINT8 registerAddress[1];

    registerAddress[0] = register_address;

    UINT8 readData[1];

    readData[0] = register_value[0];

    CFA_BSC_STATUS readStatus = cfa_bsc_OpExtended(readData, sizeof(readData),

                                                   registerAddress, sizeof(registerAddress),

                                                   I2C_SLAVE_ADDRESS, I2C_SLAVE_OPERATION_READ);

0 Likes
Anonymous
Not applicable

Hi jakewtorres

No luck with this new code. I have checked I am using correct SAO pin. I have also applied voltage to sensor. I have checked sensor with Arduino it's working fine with it. I did not use I2C with any other sensor actually I don't have any other one. I have one doubt that when i built my code I have errors on 'cfa' commands. All cfa commands give same errors that compiler does not resolve 'CFA_BSC_STATUS read_status'. Filipps do you have same error. Kindly see image below of these error. I already asked question about that on forum they replied me its Eclipse error and nothing else just ignore it, Is it right?

bugs.jpg

0 Likes
Anonymous
Not applicable

I am getting the highlight in Eclipse, but I ignore it because the error doesn't show up when I compile. CFA_BSC_STATUS is defined in "cfa.h", not sure why Eclipse is not picking it up. In either case, I am more interested in making the board work with the I2C sensor 😃

0 Likes
Anonymous
Not applicable

Hmm, write returns CFA_BSC_STATUS_SUCCESS whether or not the device is connected, so I guess none of that is really working for me...

0 Likes
Anonymous
Not applicable

filipps msiddique

We are looking into this problem and will get back to you guys as soon as possible.

-Kevin

0 Likes
Anonymous
Not applicable

Are you addressing anything close to 0xA0? If you are then you will get a response.

Can you put a scope on the I2C?

-Kevin

0 Likes
Anonymous
Not applicable

Kevin, sorry if this is a dumb question, but what do you mean by "close to 0xA0"? The sensor's address I am trying to reach is 0x6B. The register address in the sensor is 0x0A, though it has tons of registers.

0 Likes

filipps

I2C Slave Address.

Per the WICED™ Smart Hardware Interfaces

"Restrictions

When using the I2C-compatible master, the following restrictions apply to use of the NV storage device:

1. If the SPI serial flash is used for NV storage, then the I2C master device will be unavailable for application use.

2. If the I2C EEPROM is used as the NV storage device, then the SPIFFY1 SPI interface will be unavailable (see the Serial Peripheral Interface section in the document).

3. If the I2C EEPROM is used, then the 7-bit control word/slave address for the EEPROM device must be 0x50.Thus, the slave address generated for read/write for the EEPROM will always be 0xA1/0xA0 on the I2C bus."

0 Likes
Anonymous
Not applicable

Yeah, reading from 0xA0 is working for me. My guess is that I miscalculated the slave address then. Thank you for the help!

Anonymous
Not applicable

I also got it working. The two things I did were:

1. Shift the address left by 1 bit

2. Use I2C_SLAVE_OPERATION_READ for read commands. The constant is defined as 0 in cfa.h, and because my sensor uses 1 for read I thought that's what I needed to pass into cfa_bsc_OpExtended. Turns out I the function actually sends 1 for read commands, so this is working just fine for me:

cfa_bsc_OpExtended(read_data, 1, register_address_data, 1, device_address, I2C_SLAVE_OPERATION_READ);

0 Likes
Anonymous
Not applicable

Now I2C is working i just did shifting on my I2C address and it start working.

int MPU9150_I2C_ADDRESS = (0x68<< 1) ;

Thanks for help and support.

0 Likes