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.

RTOS/LAUNCHXL-CC2650: ADXL345 - Some problem with I2C transaction

Part Number: LAUNCHXL-CC2650
Other Parts Discussed in Thread: CC2650

Tool/software: TI-RTOS

Hello everyone,

I'm having a very similar issue like in this post (https://e2e.ti.com/support/embedded/tirtos/f/355/t/538836) except that I'm using CC2650 connects with ADXL345 via I2C interface. My first read/write transaction always fails and I have to send a dummy transaction as a work-around. After my first transaction, my other transactions that write/read to registers works properly. Unfortunately, that post is pretty old, so I don't know if the OP finds out the solution for this or not. Does anyone experience with the same issue or know what cause this?

I ran a couple tests to make sure that my CC2650 and ADXL345 can communicate properly, including a 'read' transaction to get the device id, and it returns the value of 0xE5 (correct as stated in the data sheet).

At this moment, I'm trying to find the solution as I mentioned above and also implement a function to read raw input data of 3 axis x, y ,z and converts it to g,

void ADXL345_GetGxyz(float* x,
             float* y,
             float* z)
{
    System_printf("\t%s IS CALLED\n", __FUNCTION__); System_flush();
    unsigned short xData = 0;  // X-axis's output data.
    unsigned short yData = 0;  // Y-axis's output data.
    unsigned short zData = 0;  // Z-axis's output data.

    ADXL345_GetXyz(&xData, &yData, &zData);
    *x = (float)(fullResolutionSet ? (xData * ADXL345_SCALE_FACTOR) :
            (xData * ADXL345_SCALE_FACTOR * (selectedRange >> 1)));
    *y = (float)(fullResolutionSet ? (yData * ADXL345_SCALE_FACTOR) :
            (yData * ADXL345_SCALE_FACTOR * (selectedRange >> 1)));
    *z = (float)(fullResolutionSet ? (zData * ADXL345_SCALE_FACTOR) :
            (zData * ADXL345_SCALE_FACTOR * (selectedRange >> 1)));
}

void ADXL345_GetXyz(unsigned short* x,
            unsigned short* y,
            unsigned short* z)
{
    System_printf("\t%s IS CALLED\n", __FUNCTION__); System_flush();
    *x = ADXL345_GetRegisterValue(ADXL345_DATAX1) << 8;
    *x += ADXL345_GetRegisterValue(ADXL345_DATAX0);
    *y = ADXL345_GetRegisterValue(ADXL345_DATAY1) << 8;
    *y += ADXL345_GetRegisterValue(ADXL345_DATAY0);
    *z = ADXL345_GetRegisterValue(ADXL345_DATAZ1) << 8;
    *z += ADXL345_GetRegisterValue(ADXL345_DATAZ0);
}

uint32_t ADXL345_GetRegisterValue(uint32_t registerAddress)
{
    System_printf("\t%s IS CALLED\n", __FUNCTION__); System_flush();
    uint32_t readData[2] = {0};
    uint32_t writeData[2] = {0};
    uint32_t registerValue = 0;

    I2C_Transaction i2cTransaction;
    // set up transaction
    writeData[0] = registerAddress;
    i2cTransaction.slaveAddress = ADXL345_ADDRESS;
    i2cTransaction.writeBuf = writeData;
    i2cTransaction.writeCount = 1;
    i2cTransaction.readBuf = readData;
    i2cTransaction.readCount = 1;

    if (I2C_transfer(i2c, &i2cTransaction)){
        registerValue = readData[0];
        System_printf("We received this 1 byte from ACC: %04x\n", registerValue); System_flush();
        System_printf("Read Work \n"); System_flush();
    } else {
        System_printf("I2C Bus fault .... Read Register Function \n");
        System_flush();
    }
    return registerValue;

}

But calling ADXL_GetGxyz only give me the same value of X Y Z: c083 9d8b 1759 although I tried to move the accelerometer with different positions? What did I possibly do wrong?

Any help would be greatly appreciated. Thanks,

Henry

  • I have read a post that said, to read a register, it needs to be done by two I2C transfers. 1st transfer is "write" to specify the register address. 2nd is read from the register.

    Would the following transaction handles 2 transfer?

    I2C_Transaction i2cTransaction;
        
    // set up transaction
    writeData[0] = registerAddress;
    i2cTransaction.slaveAddress = ADXL345_ADDRESS;
    i2cTransaction.writeBuf = writeData;
    i2cTransaction.writeCount = 1;
    i2cTransaction.readBuf = readData;
    i2cTransaction.readCount = 1;
        
    I2C_transfer(i2c, &i2cTransaction)

    Thanks,

    Henry

  • Hi,

    See, the I2C testing code in this post below. It is set to read the Device Identification Register of I2C LIS3DH Accelerometer.

    e2e.ti.com/.../586492

    - kel
  • Hello Markel,

    Thanks for sharing, but your code is pretty much similar to mine if not the same.

    I'm able to send a read transaction and get the device id register of I2C adxl345 accelerometer, but for some reason, the first transaction in my program ALWAYS false.
    More importantly, I'm trying to figure out how to read the accelerometer adxl345 correctly, and it seems my ADXL345_Getxyz is not getting correct results.

    Thanks,
    Henry
  • For further testing, I figure out that while I can successfully do the read transaction, my write transaction does not change the register value.

    I'm trying to set the power control mode to measure (0x1) instead of standby (0x0), but the value of POWER_CTL register remains 0x0 before and after the write transaction. Does anyone know how to solve this problem?

    Thanks,
    Henry
  • The first transfer problem might be related to this issue e2e.ti.com/.../564068