This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

ti-rtos i2c fast mode plus with TIVA

Hi.

(I asked this question in a different thread, but didn't get an answer)

I have a TIVA device, which supports 1 Mbps rate on I2C bus, but TI-RTOS I2C driver only supports 400 Kbps.

Is it possible to use the driver with FM+ mode? If so, how is it done?

And another question (also asked in a different thread):

I have 2 tasks with same priority, each using different I2C channel in blocking mode.

Task #1 calls  I2C_Transfer and blocks.

What happens when task #2 calls I2C_Transfer immediately after task #1 ? Does it wait for task #1 to complete the transfer, or these two calls are run simultaneously, because 2 different I2C channels are used?

Thanks.

  • Hi Michael,

    I've files a bug ID to track this enhancement (SDOCM00118015).

    The TI-RTOS I2C does not directly support FM+, though it shouldn't be too hard to add it. The driver depends on TivaWare to set the I2C controller's 1MHz bitrate. Looking at the driverlib APIs, there is a remark in I2CMasterInitExpClk to configure it.

    //*****************************************************************************
    //
    //! Initializes the I2C Master block.
    //!
    //! \param ui32Base is the base address of the I2C module.
    //! \param ui32I2CClk is the rate of the clock supplied to the I2C module.
    //! \param bFast set up for fast data transfers.
    //!
    //! This function initializes operation of the I2C Master block by configuring
    //! the bus speed for the master and enabling the I2C Master block.
    //!
    //! If the parameter \e bFast is \b true, then the master block is set up to
    //! transfer data at 400 Kbps; otherwise, it is set up to transfer data at
    //! 100 Kbps.  If Fast Mode Plus (1 Mbps) is desired, software should manually
    //! write the I2CMTPR after calling this function.  For High Speed (3.4 Mbps)
    //! mode, a specific command is used to switch to the faster clocks after the
    //! initial communication with the slave is done at either 100 Kbps or
    //! 400 Kbps.
    //!
    //! The peripheral clock is the same as the processor clock.  This value is
    //! returned by SysCtlClockGet(), or it can be explicitly hard coded if it is
    //! constant and known (to save the code/execution overhead of a call to
    //! SysCtlClockGet()).
    //!
    //! \return None.
    //
    //*****************************************************************************
    void
    I2CMasterInitExpClk(uint32_t ui32Base, uint32_t ui32I2CClk,
                        bool bFast)
    {

    I referred to the datasheet to find out what I2CMTPR to use and want able to get the I2C driver to operate at 833MHz (faster than fast mode). I just opened the I2C driver at I2C_400kHz and then immediately set I2CMTPR. I was able to get the i2crf430cl330_load example to run with the code shown below.

    #include <xdc/runtime/Types.h>
    #include <inc/hw_types.h>
    #include <inc/hw_i2c.h>
    #include <ti/drivers/i2c/I2CTiva.h>
    extern const I2CTiva_HWAttrs i2cTivaHWAttrs[];
    
    /*
     *  ======== taskFxn ========
     *  Task for this function is created statically. See the project's .cfg file.
     */
    Void nfcLoadTask(UArg arg0, UArg arg1)
    {
        I2C_Handle          i2c;
        I2C_Params          i2cParams;
        Types_FreqHz        freq;
    
        /* Create I2C for usage */
        I2C_Params_init(&i2cParams);
        i2cParams.bitRate = I2C_400kHz;
        i2c = I2C_open(Board_I2C_NFC, &i2cParams);
        if (i2c == NULL) {
            System_abort("Error Initializing I2C\n");
        }
        else {
            System_printf("I2C Initialized!\n");
        }
    
        /* Change bitrate */
        BIOS_getCpuFreq(&freq);
        if (freq.lo == 120000000) {
        	System_printf("Setting MTPR\n");
        	HWREG(i2cTivaHWAttrs[Board_I2C_NFC].baseAddr + I2C_O_MTPR) = 0x05; //From the datasheet
        }
        else {
        	System_printf("Need to find the proper dividers for %d Hz\n", freq.lo);
        }
    
        System_flush();

    Michael Vinokur said:

    And another question (also asked in a different thread):

    I have 2 tasks with same priority, each using different I2C channel in blocking mode.

    Task #1 calls  I2C_Transfer and blocks.

    What happens when task #2 calls I2C_Transfer immediately after task #1 ? Does it wait for task #1 to complete the transfer, or these two calls are run simultaneously, because 2 different I2C channels are used?

    Each I2C controller "channel" has its own internal semaphore mutex for thread-safety, so in your case, Task 2 will not block on the 2nd I2C controller.