I2C_HAL_ReadByteBlocking and I2C_HAL_WriteByteBlocking hang

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

I2C_HAL_ReadByteBlocking and I2C_HAL_WriteByteBlocking hang

792 Views
intractablesubt
Contributor III

This is for KDS 3.0 and KSDK 1.2. The The I2C_HAL_ReadByteBlocking and I2C_HAL_WriteByteBlocking functions in fsl_i2c_hal.c will hang if the byte transfer does not complete. Both routines have a while loop that cannot terminate with an error and instead will loop forever waiting on the byte transfer to complete.

Labels (1)
0 Kudos
3 Replies

551 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, William,

Regarding your question, I have checked the IIC driver, I found out that the I2C_HAL_ReadByteBlocking() and I2C_HAL_WriteByteBlocking() functions in fsl_i2c_hal.c are called only in I2C_HAL_MasterReceiveDataPolling() and I2C_HAL_MasterSendDataPolling(), in other words, the I2C_HAL_ReadByteBlocking() and I2C_HAL_WriteByteBlocking() functions are used in the polling mode instead of interrupt mode.

If you want to transfer data in polling mode, it is okay to call the  I2C_DRV_MasterReceiveDataPolling() or  I2C_DRV_MasterSendDataPolling(), it is unnecessary to call the I2C_HAL_ReadByteBlocking() and I2C_HAL_WriteByteBlocking() directly by application code.

Hope it can help you.

BR

XiangJun Rong

0 Kudos

551 Views
intractablesubt
Contributor III

I am using I2C_DRV_MasterReceiveDataPolling() and I2C_DRV_MasterSendDataPolling() in my application code. These, in turn, call the HAL routines and hang because of the bug.

0 Kudos

551 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, William,

For the api function:

i2c_status_t I2C_HAL_MasterReceiveDataPolling(I2C_Type * base,

                                              uint16_t slaveAddr,

                                              const uint8_t * cmdBuff,

                                              uint32_t cmdSize,

                                              uint8_t * rxBuff,

                                              uint32_t rxSize)

{

..............................

/* Receive data */

    for(i=rxSize-1; i>=0; i--)

    {

        switch :smileyinfo:

        {

            case 0x0U:

                /* Generate STOP signal. */

                I2C_HAL_SendStop(base);

                break;

            case 0x1U:

                /* For the byte before last, we need to set NAK */

                I2C_HAL_SendNak(base);

                break;

            default :

                I2C_HAL_SendAck(base);

                break;

        }

        /* Read recently received byte into buffer and update buffer index */

        if (i==0)

        {

            *rxBuff++ = I2C_HAL_ReadByte(base);

        }

        else

        {

            *rxBuff++ = I2C_HAL_ReadByteBlocking(base);

        }

    }

    return kStatus_I2C_Success;

}

Regarding above code, I2C_HAL_ReadByte(base); is a macro, it does not wait, just read the IIC_Data register. But the I2C_HAL_ReadByteBlocking(base); api function waits for the IICIF bit, when it is NOT the last Byte received.

For your application, I suppose you have to know the accurate NUMBER of the received data from the slave if you want to call the function I2C_HAL_MasterReceiveDataPolling. If the data number you specified in the rxSize is greater that what you get actually from slave, the code will hang at the I2C_HAL_ReadByteBlocking(), because it think there is data to raed, so it waits for the data from slave.

In conclusion, the rxSize must be less than or equal to the actual number the master receive, otherwise, the calling will hang.

Hope it can help you

BR

XiangJun Rong

0 Kudos