I2C Framework Device read problem

Hi all.

I am trying to read a log a register of I2C device (AIS3624DQ).
The open/reset functions do not give an error, instead writing / reading returns the SSP_ERR_TRANSFER_ABORTED error. I have seen from the examples that to read a register you must first write and then read. This is the offending code. The signs seem ok, and the address too.

    uint8_t value;
    uint8_t reg = 0xF;
    g_sf_i2c_acceleretor.p_api->lock(g_sf_i2c_acceleretor.p_ctrl);

    ssp_err_t status;
    status = g_sf_i2c_acceleretor.p_api->write(g_sf_i2c_acceleretor.p_ctrl, &reg, 1, false, TX_WAIT_FOREVER);

    if (status != SSP_SUCCESS) {
#ifndef NDEBUG
        __BKPT(0);
#endif
    }

    status = g_sf_i2c_acceleretor.p_api->read(g_sf_i2c_acceleretor.p_ctrl, &value, 1, false, TX_WAIT_FOREVER);
    g_sf_i2c_acceleretor.p_api->unlock(g_sf_i2c_acceleretor.p_ctrl);

    if (status != SSP_SUCCESS) {
#ifndef NDEBUG
        __BKPT(0);
#endif
    }

Where am I doing wrong?

Paolo

  • What is the I2C slave device address, and what is configured in the I2C framework? Open and reset don't actually do any communication on the I2C bus with the slave device. Open just sets up the I2C peripheral ready to do a transfer, reset will abort any outstanding communication in progress.
  • In reply to Jeremy:

    Hi Jeremy.
    Slave address is 0x19 (SA0 is high). I2C framework is configured with channel 2, fast mode.
    If I connect to another type of device it works, but with that and another device it doesn't.
    If I interpreted the datasheet well by reading the register 0xF I should receive a value.
    Is the reading correct? I don't understand why to read a register first I have to use the write function (all the examples do so). Why doesn't the read function take a parameter which register should I read for?

    Best regards
    Paolo
  • In reply to Paolo Miatto:

    The format of communication for a single read from the AIS3624 is :-

    The red box is an I2C write with a Repeated start condition, the green box is an I2C read with a stop condition at the end. The I2C framework API map to the I2C bus cycles they produce, if you want a single function call to read from a register in the AIS3624, you will need to create a function that calls the I2C framework API in the correct sequence to achieve that.

    If the I2C framework API return SSP_ERR_TRANSFER_ABORTED, one possiblilty is that the slave device has not ACK'd on the bus. Have you looked at a trace of the SDA and SCL signals to see what is actually happening on the I2C bus?

    The write API call you are using will not generate a repeated start condition :-

    g_sf_i2c_acceleretor.p_api->write(g_sf_i2c_acceleretor.p_ctrl, &reg, 1, false, TX_WAIT_FOREVER);

    to generate a repeated start, the 4th parameter should be true.

  • In reply to Jeremy:

    Hi Jeremy.
    In the code I posted the autorepeat was false, but before it was true.
    The sensors, apart from one, do not respond (seen with the oscilloscope). We are trying to understand the reason (the signs seem nice).

    Thanks for your help.

    Paolo
  • In reply to Jeremy:

    This is the command I send (I also lowered the speed in standard mode). The submission seems correct (address 0x19), but I have a NAK.

     

    Paolo

  • In reply to Paolo Miatto:

    Paolo,

     

    The correct sequence would be:

     

      uint8_t value;
        uint8_t reg = 0xF;
        g_sf_i2c_acceleretor.p_api->lock(g_sf_i2c_acceleretor.p_ctrl);

        ssp_err_t status;
        status = g_sf_i2c_acceleretor.p_api->write(g_sf_i2c_acceleretor.p_ctrl, &reg, 1, true, TX_WAIT_FOREVER);    // don't send stop and leave comm open

        if (status != SSP_SUCCESS) {
    #ifndef NDEBUG
            __BKPT(0);
    #endif
        }

        status = g_sf_i2c_acceleretor.p_api->read(g_sf_i2c_acceleretor.p_ctrl, &value, 1, false, TX_WAIT_FOREVER);   // read and send stop to close comm
        g_sf_i2c_acceleretor.p_api->unlock(g_sf_i2c_acceleretor.p_ctrl);

        if (status != SSP_SUCCESS) {
    #ifndef NDEBUG
            __BKPT(0);
    #endif
        }

  • In reply to Michael Quirk:

    Hi Michael.
    Thanks for the reply, but unfortunately it was the first thing I tried. As can be seen from the oscilloscope image I have a NAK after sending the slave address.
    I tried to change the pin settings in CMOS/OPEN DRAIN but I don't solve anything.
    Now I will try to communicate with other I2C devices and to lower the values of the pull-up resistors.

    Paolo
  • In reply to Paolo Miatto:

    Is the CS line of the AIS3624 tied high to enable I2C mode :-

     

  • In reply to Jeremy:

    Hi Jeremy.
    The other sensor (MPRLS0025PA00001A) I wasn't reading was broken, replacing it now works.
    Instead, I can't read this device (the CS signal is high). I have tried connecting it to the Raspberry Pi and see it (command i2cdetect). Now I will write a mini program on the raspberry that sends the same commands and I will compare the signals with those of my pcb. I have no other ideas.

    Paolo
  • In reply to Paolo Miatto:

    Hi all.
    I solved it. By putting the 1.5K pull-ups it read both sensors (previously they were 4.7K).

    Thank you all
    Paolo