AnsweredAssumed Answered

I2C "STOP signal" not send when receive a NAK

Question asked by PE TAPIE on Jun 23, 2015
Latest reply on Jun 29, 2015 by PE TAPIE

Hello Freescale community,

 

I use Kinetis Design studio 2.0.0, MQX KSDK 1.0.0 with Processor expert, (uc MK64F),

 

I realized I2C communication using I2C0 as Master.

 

I talk with a eeprom in a Task every 50ms, when I want to talk with the Eeprom, if it is not present on the bus, I receive a NAK but the signal STOP is not send and the driver return :  I2C_Fail

 

You can see the behavior in the following screenshot :

 

I2C_not_good.png

 

I use the function :  i2c_status_t    I2C_DRV_MasterReceiveDataBlocking

 

To solve the problem I add this condition (indicate in RED) in the function I2C_DRV_MasterReceiveDataBlocking :

 

************************************************************************************************************************************************************************************************************

/*FUNCTION**********************************************************************

*

* Function Name : I2C_DRV_MasterReceiveDataBlocking

* Description   : Performs a blocking receive transaction on the I2C bus.

*

*END**************************************************************************/

i2c_status_t I2C_DRV_MasterReceiveDataBlocking(uint32_t instance,

                                       const i2c_device_t * device,

                                       uint8_t * cmdBuff,

                                       uint32_t cmdSize,

                                       uint8_t * rxBuff,

                                       uint32_t rxSize,

                                       uint32_t timeout_ms)

{

    assert(instance < HW_I2C_INSTANCE_COUNT);

 

    uint32_t baseAddr = g_i2cBaseAddr[instance];

    uint32_t i = 0;

    /* Get current runtime structure. */

    i2c_master_state_t * master = (i2c_master_state_t *)g_i2cStatePtr[instance];

 

    /* Return if there is already a trasction */

    if (!master->i2cIdle)

    {

        return master->status = kStatus_I2C_Busy;

    }

 

    master->rxBuff = rxBuff;

    master->rxSize = rxSize;

    master->txBuff = NULL;

    master->txSize = 0;

    master->status = kStatus_I2C_Success;

 

    I2C_DRV_MasterSetBaudRate(instance, device);

 

    /* Set direction to send for sending of address. */

    I2C_HAL_SetDirMode(baseAddr, kI2CSend);

 

    /* Enable i2c interrupt.*/

    I2C_HAL_ClearInt(baseAddr);

    I2C_HAL_SetIntCmd(baseAddr, true);

 

    /* Generate start signal. */

    I2C_HAL_SendStart(baseAddr);

 

    /* Send out slave address. */

    I2C_DRV_SendAddress(instance, device, cmdBuff, cmdSize, kI2CReceive, timeout_ms);

 

    /* Start to receive data. */

    if (master->status == kStatus_I2C_Success)

    {

        /* Change direction to receive. */

        I2C_HAL_SetDirMode(baseAddr, kI2CReceive);

 

        /* Send NAK if only one byte to read. */

        if (rxSize == 0x1U)

        {

            I2C_HAL_SendNak(baseAddr);

        }

        else

        {

            I2C_HAL_SendAck(baseAddr);

        }

 

        /* Dummy read to trigger receive of next byte in interrupt. */

        I2C_HAL_ReadByte(baseAddr);

 

        /* Wait for the transfer to finish.*/

        I2C_DRV_MasterWait(instance, timeout_ms);

    }

 

    if(master->status == kStatus_I2C_ReceivedNak)

          I2C_HAL_SendStop(baseAddr);

 

    /* The stop signal is send inside irq before reading the last byte. */

    /* Disable interrupt. */

    I2C_HAL_SetIntCmd(baseAddr, false);

 

    /* Indicate I2C bus is idle. */

    master->i2cIdle = true;

 

    /* Wait for the STOP signal finish. */

    while(I2C_HAL_GetStatusFlag(baseAddr, kI2CBusBusy))

    {

        if(++i == 2)

        {

            /* Something is wrong becuase the bus is still busy. */

            master->status = kStatus_I2C_Fail;

            break;

        }

        else

        {

            OSA_TimeDelay(1U);

        }

    }   

 

    return master->status;

}

 

************************************************************************************************************************************************************************

 

It is normal to have to add this condition  ?

Outcomes