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.

CC3220SF: I2C bus clear

Part Number: CC3220SF


Hi all,

does SDK for CC3220SF(MODA) contains function for performing I2C bus clear operation?
Is there also possible detection of the need of this operation?

Alternatively: if I will implement my own function, I would like to better understand delay defined by function UtilsDelay(..).
If its delay is "constant length delay", what is the duration? How to calculate it (rather than measure)?

Thanks for help!

Jiří

  • Hi Michael,

    thank you for your reply. I have checked both links and there is no information I am looking for.

    I have understood: I have to implement my own "bus clear" function. Currently I am calling this function from init, before my FreeRTOS starts
    and before TI SDK takes I2C pins under control. So I have no issue with driving pins. But I do have problem with timing. See my question above regarding UtilsDelay(..).

    static void busClear(void)
    {
    	uint8_t u8L_sclPulses = 8+1; /* 8 pulses on SCL line to clear I2C bus, the ninth one is stop condition */
    
    	gpio_set(BOARD_PIN_I2C_SCL, 1);
    	gpio_set(BOARD_PIN_I2C_SDA, 1);
    
    	UtilsDelay(I2C_BUS_HALF_PERIOD_US);
    
    	/* Toggle SCL */
    	do
    	{
    		gpio_set(BOARD_PIN_I2C_SCL, 1);
    		UtilsDelay(I2C_BUS_HALF_PERIOD_US);
    
    		gpio_set(BOARD_PIN_I2C_SCL, 0);
    		UtilsDelay(I2C_BUS_HALF_PERIOD_US);
    
    		u8L_sclPulses--;
    	} while (u8L_sclPulses > 0);
    
    	/* Generate STOP condition */
    	gpio_set(BOARD_PIN_I2C_SDA, 0);
    	UtilsDelay(I2C_BUS_HALF_PERIOD_US);
    
    	gpio_set(BOARD_PIN_I2C_SCL, 1);
    	UtilsDelay(I2C_BUS_HALF_PERIOD_US);
    
    	gpio_set(BOARD_PIN_I2C_SDA, 1);
    	UtilsDelay(I2C_BUS_HALF_PERIOD_US);
    }

    It would be also good to have some detection of stuck SDA line, but I am not sure how to do that.

    Regards
    Jiří 

    PS:
    Off-topic: section 3.1.16 in the I2C specification ( UM10204 I2C-bus specification and user manual) is not very clear.
    There is no information about timing constrains and there is also nothing about the need to have STOP condition
    part of 9 pulses (actually the ninth pulse). But my colleague gave me some links where people are using this.
    Very confusing. :-(

  • Hi Jiří,

    Your code to clear the I2C looks fine.

    I am not the most familiar with third-party I2C documentation so I cannot comment on that unfortunately.

    Regards,

    Michael

  • Michael,

    thank you regarding I2C bus clear procedure.

    Will you advice regarding UtilsDelay(..) function? What is the time duration for UtilsDelay(1)?
    I expect that input clock related to this function is 80MHz for CC3220MODASF.

    Jiří

  • Hi Jiří,

    Yes, the delay length of the UtilsDelay() function is linked MCU clock of 80MHz.

    Specifically, UtilsDelay() takes 3 clock cycles to complete. As each clock cycle of the ARM Cortex M4 takes (1s/80MHz) = 0.0125us, UtilsDelay(1) should result in a delay of 0.0375us.

    What is the delay you are measuring?

    Regards,

    Michael

  • Hi Michael,

    thank you for info, I will use GPIO_setConfig() based on advice in the link above to get more precise results.
    I will come back with my results as soon as I will switch back to relevant task in my project.

    Jiří

  • I have measured timing of UtilsDelay().

    UtilsDelay(0) never returns. I understand that it is not possible to check 0 in runtime inside of this function, this is ok.

    UtilsDelay(1) used in code above gave about 8us.

    UtilsDelay(3) used in code above gave about 8us.

    UtilsDelay(30): used in code above gave about 10us.

    For info: gpio_set() in code above calls directly GPIO_write(). I haven't used GPIO_setConfig() as in my case is I2C not yet configured/activated.

    I have tried to disable interrupts using pair HwiP_disable() / HwiP_restore() around the whole function with similar results.

    Next measurements:

    UtilsDelay(300)   >> cca 53us
    UtilsDelay(3000) >> cca 457us

    -------------------

    When calling GPIOPinWrite() directly instead of GPIO_write()

    UtilsDelay(3) used in code above gave about 2.25us

    When ASSERT(GPIOBaseValid(ulPort)); is disabled in GPIOPinWrite() ( running on DEBUG )

    UtilsDelay(1) used in code above gave about 1.00us

    UtilsDelay(3) used in code above gave about 1.29us     // UtilsDelay(1) ~ 0.43us

    UtilsDelay(30) used in code above gave about 3.2us     // UtilsDelay(1) ~ 0.11us

    UtilsDelay(300) used in code above gave about 46us    // UtilsDelay(1) ~ 0.15us

    UtilsDelay(3000) used in code above gave about 451us // UtilsDelay(1) ~ 0.15us

    UtilsDelay(30000) used in code above gave about 4.5m// UtilsDelay(1~ 0.15us

    UtilsDelay(300000) used in code above gave about 22.5m/UtilsDelay(1) ~ 75ns

    The measurements above (which eliminated overheads) are giving 150ns / 75ns which looks to be similar to issue reported here:

    https://e2e.ti.com/support/wireless-connectivity/wi-fi-group/wifi/f/wi-fi-forum/1003724/cc3200mod-utilsdelay-is-not-giving-precise-delay-in-cc3200-cc3220sf

    For my needs I have something that I can use - UtilsDelay(5) (I want to generate I2C "bus clear" with similar clock speed as regularly used cca 386kHz - should be actually 400kHz, some feature/bug of CC3220MODASF?).

  • I believe the timing is correct and the 75ns (which is double of expected) is caused just be measurement. As for pin toggling I need at least 1 instruction. ;-)