1 2 Previous Next 16 Replies Latest reply on Aug 17, 2015 10:06 PM by fishc_1849816

    I2C write problem

      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);

         

      }

        • 1. Re: I2C write problem
          JacobT_81

          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

          • 2. Re: I2C write problem

            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);

             

             

            }

            • 3. Re: I2C write problem
              JacobT_81

              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


              • 4. Re: I2C write problem

                userc_12593

                 

                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);

                 

                 

                 

                 

                }

                • 5. Re: I2C write problem
                  JacobT_81

                  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

                  • 6. Re: I2C write problem

                    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);

                    • 7. Re: I2C write problem

                      Hi JacobT_81

                       

                      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

                      • 8. Re: I2C write problem

                        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 =)

                        • 9. Re: I2C write problem

                          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...

                          • 10. Re: I2C write problem

                            fishc_1849816 msiddique

                             

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

                             

                            -Kevin

                            • 11. Re: I2C write problem

                              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

                              • 12. Re: I2C write problem

                                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.

                                • 13. Re: I2C write problem

                                  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.

                                  • 14. Re: I2C write problem
                                    MichaelF_56

                                    fishc_1849816

                                     

                                    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."

                                    1 2 Previous Next