0
\$\begingroup\$

I ran into an issue with my project. I use Renesas RL78 microcontroller and on one I2C bus I have two sensors: digital compass and accelerometer. Accelerometer type is MMA8453 by Freescale.

Datasheet: http://cache.freescale.com/files/sensors/doc/data_sheet/MMA8453Q.pdf

I have no problem with reading data from compass. Accelerometer, however, is a different story. I can't read anything from it - at least I guess I'm not getting anything. Unfortunately I don't have scope or logic analyzer to check out. I get an ACK, but no data.

Here is the function I use for reading register of I2C device:

uint8_t Read_I2C_Sensor_Reg(uint8_t DevAddr, uint8_t RegAddr, uint8_t *Data, uint8_t Numbytes, uint8_t wait)
{
    uint16_t status = 0;
    uint16_t timeout = 1000; //approx 32uSec
    DevAddr <<= 1;      //Shifting left by one bit to make room for Read/Write bit

    IICA0_Err = 0;
    IICA0_Tx_Done |= 1;
    status = IICA0_Master_Send(DevAddr, &RegAddr, 1,  wait);
    while(IICA0_Tx_Done)
    {
        while(timeout--);
        iica0_master_check_status();    //<SCH> checking the transation status, in case if this fails, report andre initiate transaction.
        if(IICA0_Err)
        {
            status = IICA0_Err ; break;
        }
    }
    if (IICA0_Tx_Done == 0)
    {
        IICA0_StopCondition();
        while (SPD0 == 0);

        IICA0_Rx_Done |= 1;
        status = IICA0_Master_Receive(DevAddr, Data, Numbytes,  wait);
        while(IICA0_Rx_Done)
        {
            while(timeout--);
            iica0_master_check_status();
            if(IICA0_Err)
            {
                status = IICA0_Err ; break;
            }
        }

        if (IICA0_Tx_Done == 0)
        {
            IICA0_StopCondition();
            while (SPD0 == 0);
        }
    }

    if (status == MD_OK)
      return 0;
    else
      return 1;
}

Did anyone come across this kind of issue? I can post more details later, if needed.

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

Based on the fact that you able to communicate with one i2c sensor but not another, I would start investing the following:

Focus on reading the WHO_AM_I register because it is a simple test for reads and the answer 0x3A is fixed.

  • Check that the slave's I2C address matches the hardware, i.e. is the pin SA0 pulled high or low? Are you using the slave address 0x1C or 0x1D?
  • Check that you are terminating your reads with NACK. A master's read sequence must end in a NACK according to I2C, but not all vendors care too much. IIRC Freescale does.
  • Check the I2C bus length and pullups, i.e. if you have more than a few cm of cable, your pullups should be for example 1k rather than 10k. This will depend on the timing etc characteristics of the device.

I've written a blog post about I2C a while ago where I've also outlined common I2C problems and given more details: http://chipscoop.blogspot.fi/2012/08/understanding-ic-and-some-typical-uses.html

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.