I2C "STOP signal" not send when receive a NAK

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

I2C "STOP signal" not send when receive a NAK

ソリューションへジャンプ
1,989件の閲覧回数
tapiepierre
Contributor III

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 :

 

41304_41304.pngI2C_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  ?

ラベル(1)
1 解決策
1,483件の閲覧回数
Jorge_Gonzalez
NXP Employee
NXP Employee

Hello PE TAPIE:

That is a bug with KSDK v1.0.0, which is fixed in the latest versions. Attached you can find the relevant I2C driver and HAL from KSDK v1.2 so you can compare the differences, but I highly recommend you to migrate to KDS v3.0.0 and KSDK v1.2.0.


Regards!,
Jorge Gonzalez

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

元の投稿で解決策を見る

2 返答(返信)
1,484件の閲覧回数
Jorge_Gonzalez
NXP Employee
NXP Employee

Hello PE TAPIE:

That is a bug with KSDK v1.0.0, which is fixed in the latest versions. Attached you can find the relevant I2C driver and HAL from KSDK v1.2 so you can compare the differences, but I highly recommend you to migrate to KDS v3.0.0 and KSDK v1.2.0.


Regards!,
Jorge Gonzalez

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

1,483件の閲覧回数
tapiepierre
Contributor III

Hello Jorge Gonzalez,

Thanks for you answer,

I looked at the differences beetween the two drivers and effectively the new works as expected

thanks,

0 件の賞賛
返信