bug in i2c driver for kinetis?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

bug in i2c driver for kinetis?

1,164 Views
mastupristi
Senior Contributor I

I'm refering to KSDK 2.2 for Kinetis K64

I you try to do an empty transfer the stop condition is never issued.

the case is:

    i2c_master_transfer_t masterXfer;

    masterXfer.slaveAddress = I2C_EEPROM_ADDRESS;
    masterXfer.direction = kI2C_Write;
    masterXfer.subaddress = 0;
    masterXfer.subaddressSize = 0;
    masterXfer.data = NULL;
    masterXfer.dataSize = 0;
    masterXfer.flags = kI2C_TransferDefaultFlag;

    I2C_MasterTransferBlocking(I2C0, &masterXfer);

this is useful to detect busy status of 24cXX i2c memories.

at the end of I2C_MasterTransferBlocking() funtion there is:

    /* Transmit data. */
    if ((xfer->direction == kI2C_Write) && (xfer->dataSize > 0))
    {
        /* Send Data. */
        result = I2C_MasterWriteBlocking(base, xfer->data, xfer->dataSize, xfer->flags);
    }

    /* Receive Data. */
    if ((xfer->direction == kI2C_Read) && (xfer->dataSize > 0))
    {
        result = I2C_MasterReadBlocking(base, xfer->data, xfer->dataSize, xfer->flags);
    }

    return result;
}

in case xfer->dataSize is zero there is no explicit or implicit call to I2C_MasterStop(), so I have solved adding this:

    /* Transmit data. */
    if ((xfer->direction == kI2C_Write) && (xfer->dataSize > 0))
    {
        /* Send Data. */
        result = I2C_MasterWriteBlocking(base, xfer->data, xfer->dataSize, xfer->flags);
    }

    /* Receive Data. */
    if ((xfer->direction == kI2C_Read) && (xfer->dataSize > 0))
    {
        result = I2C_MasterReadBlocking(base, xfer->data, xfer->dataSize, xfer->flags);
    }

    /* In case no data has to be transfer we have to send stop condition */
    if( 0 == xfer->dataSize )
    {
        result = I2C_MasterStop(base);
    }

    return result;
}

Can this patch be considered to be merge in the official source tree?

best regards

Labels (1)
0 Kudos
1 Reply

622 Views
IvanRuiz
NXP Employee
NXP Employee

Hello, thank you for noticing this.

After a start condition has been sent and to prevent the bus to be left busy, there is a function which checks whether an arbitration lost has occurred and also checks for NAK:

/* Check if there's transfer error. */
result = I2C_CheckAndClearError(base, base->S);

 

If a NAK flag is detected, it will send the stop condition:

/* Return if error. */
if (result)
{
if (result == kStatus_I2C_Nak)
{
result = kStatus_I2C_Addr_Nak;

I2C_MasterStop(base);
}

So if no data has to be transferred, it will send a stop condition and the bus will no longer be busy.

Best regards,

Ivan Ruiz.

0 Kudos