This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2650: I2C_transfer not working

Part Number: CC2650

Hi, 

I´m trying to connect to the LSM6DS33 device via I2C and it has been giving me some problems. My inttention is to do a bluetooth beacon and broadcast a type of interpretation of the values the device gives to me.

The problem is that when I try to read the values with a Periodic Task the LSM6DS33 configuration values dissapear and sometimes the sensor values are zero and sometimes are the correct ones. 

static void SimpleBLEBroadcaster_init(void)
{
// ******************************************************************
// N0 STACK API CALLS CAN OCCUR BEFORE THIS CALL TO ICall_registerApp
// ******************************************************************
// Register the current thread as an ICall dispatcher application
// so that the application can send and receive messages.
ICall_registerApp(&selfEntity, &sem);

//The I2C driver initialization
I2C_init();
I2C_Params_init(&params);

I2C_Transaction i2cTrans;
uint8_t txBuf[32] = {0}; //Transmit buffer
uint8_t rxBuf[32] = {0}; //Read buffer 
handle = I2C_open(Board_I2C, &params);
if(!handle) {
//Error
}
////////////////////////////////LSM6DS33//////////////////

// Configuraciones de gyro y acelerometro

//Acel
// Adress= 0x10 ctrl1
// // 0x80
txBuf[0] = 0x10;
txBuf[1] = 0x80;
i2cTrans.writeCount = 2;
i2cTrans.writeBuf = txBuf;
i2cTrans.readCount = 0;
i2cTrans.readBuf = NULL;
i2cTrans.slaveAddress = 0x6B;

.

.

.

.

}

static void SimpleBLEPeripheral_performPeriodicTask(void)
{


#if 1
//*********************I2C CODE***************************************
struct acel
{
uint16_t x;
uint16_t y;
uint16_t z;
};

struct gyro
{

uint16_t x;
uint16_t y;
uint16_t z;


};

I2C_Transaction i2cTrans;
uint8_t rxBuf[32] = {0}; //Receive buffer
uint8_t txBuf[32] = {0}; //Transmit buffer

struct acel a;

struct gyro g;

handle = I2C_open(Board_I2C, &params);
if(!handle) {
//Error
}
////////////////////////////////LSM6DS33//////////////////

//Read Gyroscope
//Address = 0x22
txBuf[0] = 0x22;
i2cTrans.writeCount = 1;
i2cTrans.writeBuf = txBuf;
i2cTrans.readCount = 6;
i2cTrans.readBuf = rxBuf;
i2cTrans.slaveAddress = 0x6B;

I2C_transfer(handle, &i2cTrans);

g.x= (rxBuf[1]<<8 | rxBuf[0] );
g.y= (rxBuf[3]<<8 | rxBuf[2] );
g.z= (rxBuf[5]<<8 | rxBuf[4] );

.

.

.

 I think that the main problem is with the  I2C_transfer function. When I debug it step by step it blocks completely, but I´m not sure at all. 

  • When you cal I2C_tranfer, do you see clock signal on CLK pin?
  • Yes I do, and I have signal in the SDA too. When I run the periodic task sometimes it reads the values of the sensors, but when it arrives to the periodic task the configuration values disappear.
  • Hi alex22,
    You should call I2C_open only once in the init. Then you can use I2C_transfer with handle of i2c to transfer.
  • I´ve been checking the SDA channel with osciloscope and I´ve seen that the ACK bit is 1. It is supposed to be 0 if a correct transfer has been done
    cdn.sparkfun.com/.../51ae0000ce395f645d000000.png
  • alex22 said:

    static void SimpleBLEPeripheral_performPeriodicTask(void)
    {


    #if 1
    //*********************I2C CODE***************************************
    struct acel
    {
    uint16_t x;
    uint16_t y;
    uint16_t z;
    };

    struct gyro
    {

    uint16_t x;
    uint16_t y;
    uint16_t z;


    };

    I2C_Transaction i2cTrans;
    uint8_t rxBuf[32] = {0}; //Receive buffer
    uint8_t txBuf[32] = {0}; //Transmit buffer

    struct acel a;

    struct gyro g;

    handle = I2C_open(Board_I2C, &params);
    if(!handle) {
    //Error
    }
    ////////////////////////////////LSM6DS33//////////////////

    //Read Gyroscope
    //Address = 0x22
    txBuf[0] = 0x22;
    i2cTrans.writeCount = 1;
    i2cTrans.writeBuf = txBuf;
    i2cTrans.readCount = 6;
    i2cTrans.readBuf = rxBuf;
    i2cTrans.slaveAddress = 0x6B;

    I2C_transfer(handle, &i2cTrans);

    g.x= (rxBuf[1]<<8 | rxBuf[0] );
    g.y= (rxBuf[3]<<8 | rxBuf[2] );
    g.z= (rxBuf[5]<<8 | rxBuf[4] );


    Hi Alex22,
    Try to remove "handle = I2C_open(Board_I2C, &params); " in SimpleBLEPeripheral_performPeriodicTask.

  • It doesn´t work. I don´t know what it´s happening. At first it could read the values of the sensors without problems, but each day it works worse. With the same programme now, it is not able to read configuration values neither.
    I2C_init();
    I2C_Params_init(&params);

    I2C_Transaction i2cTrans;
    uint8_t txBuf[32] = {0}; //Transmit buffer
    uint8_t rxBuf[32] = {0}; //Read buffer No hace falta ponerlo rn la inicializacion porque solo escribimos
    handle = I2C_open(Board_I2C, &params);
    if(!handle) {
    //Error
    }
    ////////////////////////////////LSM6DS33//////////////////

    // Configuraciones de gyro y acelerometro



    //Acel
    // Adress= 0x10 ctrl1
    // // 0x80
    txBuf[0] = 0x10;
    txBuf[1] = 0x80;
    i2cTrans.writeCount = 2;
    i2cTrans.writeBuf = txBuf;
    i2cTrans.readCount = 0;
    i2cTrans.readBuf = NULL;
    i2cTrans.slaveAddress = 0x6B;

    I2C_transfer(handle, &i2cTrans);



    // Gyro
    // Address = 0x11 Ctrl2_G
    // 0x80 = 0b10000000
    // ODR = 1000 (1.66 kHz (high performance)); FS_XL = 00 (245 dps)
    txBuf[0] = 0x11;
    txBuf[1] = 0x80;
    i2cTrans.writeCount = 2;
    i2cTrans.writeBuf = txBuf;
    i2cTrans.readCount = 0;
    i2cTrans.readBuf = NULL;
    i2cTrans.slaveAddress = 0x6B;

    I2C_transfer(handle, &i2cTrans);



    //Control 3

    txBuf[0] = 0x12;
    txBuf[1] = 0x04 ; // 0b00000100
    i2cTrans.writeCount = 2;
    i2cTrans.writeBuf = txBuf;
    i2cTrans.readCount = 0;
    i2cTrans.readBuf = NULL;
    i2cTrans.slaveAddress = 0x6B;

    I2C_transfer(handle, &i2cTrans);

    // Here I try to read what I´ve written , at first it worked but now it doesn´t


    txBuf[0] = 0x10;
    i2cTrans.writeCount = 1;
    i2cTrans.writeBuf = txBuf;
    i2cTrans.readCount = 1;
    i2cTrans.readBuf = rxBuf;
    i2cTrans.slaveAddress = 0x6B;

    I2C_transfer(handle, &i2cTrans);






    I2C_close(handle);
  • Hi alex22,
    I dont find any problem in your code. You have to try to check
    1/ Check your schematic and PCB such as pull-up resister of I2C, power pin....
    2/ Change other sensor to check to make sure your sensor that dont have any problem.
    3/ Capture the signal on i2c bus to analyze the wave to make sure its wave that work correctly
  • It works but it need time to do it. After some debug and executing the app programme, it reads the values correctly, but I don´t know why it can´t do from the beggining.
  • I´ve been checking the transfer´s returning values and sometimes it is zero, what means that something is going wrong. I´m adding do while sentences with transfer function inside them but it could interfere the correct performance of the application
  • There are also some transfer that never return anything and the programme is always waiting for something.
  • Hi alex22,
    Device can read your sensor, but sometime it never return. That mean is your i2c bus is suspended becuase the pulses of i2c may be missed. You have to reset your device or try to send the pulse to fix the missed pulses.
    This issue of i2c bus sometime appear. You can research how to fix it on forum.
    However, you should check your code again carefully.
  • Actually I achieved to make it work. I put the transfer sentences inside do{}while conditions ,and there was missing a I2C close sentence after the configurations also.
  • Nice :)