AnsweredAssumed Answered

What is the best way to access I2C in a MQX project?

Question asked by matt johnson on Mar 16, 2015
Latest reply on Mar 18, 2015 by David E Seymour

uPC: MK21FN1M0A

IDE: KDS 2.0.0

SDK: KSDK1.1.0_K21FA_1.0.0

 

Hello

 

I have a project that uses MQX OS with several tasks that access two I2C ports. Currently, I am using the SDK I2C component from Processor Expert for all I2C operations. I seem to run across some issues with this I2C driver when multiple tasks are trying to access the I2C ports, specifically an assert statement will fail in the driver code. In order to make sure the I2C is thread safe, I use a mutex for accessing each I2C resource. Also, the driver code seemed sensitive when preempted by another task, so I disable preemption whenever the I2C is accessed.

 

Considering these issues, I am wondering if this is the best method of accessing I2C in a MQX OS environment? Are there better methods of accessing the I2C than what I am doing currently?

 

Thanks

 

Matt

 

Here are some snippets of relevant code:

 

assert statement that fails: fsl_i2c_hal.c

i2c_status_t I2C_HAL_SendStop(uint32_t baseAddr)
{
    assert(BR_I2C_C1_MST(baseAddr) == 1);
    uint32_t i = 0;


    /* Start the STOP signal */
    HW_I2C_C1_CLR(baseAddr, BM_I2C_C1_MST | BM_I2C_C1_TX);


    /* Wait for the STOP signal finish. */
    while(I2C_HAL_GetStatusFlag(baseAddr, kI2CBusBusy))
    {
        if (++i == 0x400U)
        {
            /* Something is wrong because the bus is still busy. */
            return kStatus_I2C_StopSignalFail;
        }
        else
        {
            __asm("nop");
        }
    }


    return kStatus_I2C_Success;
}

 

Current function that accesses I2C through the I2C SDK component driver:

i2c_status_t i2c_stat;

if (instance == FSL_I2CCOM0){if (lockMutex(&i2c0_mutex) != MQX_OK){return kStatus_I2C_Fail;}}
else if (instance == FSL_I2CCOM2){if (lockMutex(&i2c2_mutex) != MQX_OK){return kStatus_I2C_Fail;}}
  else {return kStatus_I2C_Fail;}

_task_stop_preemption();
i2c_stat = I2C_DRV_MasterSendDataBlocking(instance, device, cmdBuff, cmdSize, txBuff, txSize, timeout_ms);
_task_start_preemption();

if (instance == FSL_I2CCOM0){if (unlockMutex(&i2c0_mutex) != MQX_OK){return kStatus_I2C_Fail;}}
else if (instance == FSL_I2CCOM2){if (unlockMutex(&i2c2_mutex) != MQX_OK){return kStatus_I2C_Fail;}}

return i2c_stat;

Outcomes