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.

Waiting on UCBIT9IFG flag in I2C communications

Part Number: MSP432P401R

I think it is worth mentioning the active wait for UCBIT9IFG flag to be set in UCBxIFG register as a method for waiting the shift register to be flushed, for example by writing:

        // Wait until byte has not been successfully sent
        while(!I2C_getInterruptStatus(EUSCI_Bx_BASE, EUSCI_B_I2C_BIT9_POSITION_INTERRUPT))

At least, it works for me. It should be equivalent to the inline delay option, isn't it?

I do not need to use interrupts in my specific case, but I think the above flag should also make an ISR-managed solution possible.

  • On reading that thread, I suspect the real problem was that masterReceiveSingleByte issues a Start and Stop simultaneously. This case is not described in TRM (SLAU356H) Figure 26-12. Based on the OP's description, it is executed as a Stop followed by a Start, though intended as a Start followed by a Stop. Based on TRM section 26.3.4.2.1, I don't think any delay is needed.

    I suspect that Ms Thanigai's fix wasn't the delay, but the splitting of the Start and Stop (to assure the precedence). If masterReceiveSingleByte did that, maybe everything would act as expected.

    But that's just me.
  • The latest MSP432P4 SimpleLink SDK driverlib examples address the issue of reading 1  byte, then doing a repeated start to read 1 (or more) bytes. See the example: i2c_master_rw_repeated_start_single_byte-master_code here. There are also examples without interrupts. Neither uses built-in delays. 

    -Bob L.

  • Hi Bob,

    I actually read

    __delay_cycles(300000); // ~100ms pause between transmissions

    in that example at line 148.

  • Might be the case, but I think one should take into account the time serial data requires to be output by the shift register once the TXBUF is empty and TXIFG rises, anyway.
  • GioP,
    That's not the kind of delay we were talking about inside the ISR. It's only there so that the program will send periodic "bursts" of I2C transactions. (Also makes it much easier to distinguish on a logic analyzer.)

    I believe this answers your original question of how to send 1 byte, then restart and receive one byte from a slave.
    -Bob
  • Sorry Bob,
    I misinterpreted the listing as I was in a bit of a hurry.
    I actually need to do something similar to the routine shown in the example, and I am facing some troubles, so I am glad for the link: I will look carefully at it. Anyway, in spite of the example my initial doubt persists: Is it correct to wait on TXIFG before sending a restart, or not?

    I am asking this because according to user manual and the referenced post, TXIFG is set as soon as the shift register is loaded, so it makes sense to wait for the byte to be sent before issuing a restart condition (my MCLK is much faster than peripheral clock, also).

    I am polling on UCBIT9IFG but I don't see any example suggesting this method. It seems to work, even if my sensor stops sending data quite often, and the microcontroller then gets stuck waiting on RXIFG forever. I don't think my issue is related to the delay we are talking about anyway, and hopefully your example will help me solving it.

  • Giovanni,

     If you look at the i2c_master_repeated_start_singlebyte_master.c example, you'll see the kind of TXIFG sampling you mentioned above. One example is in line 129 of the latest SDK version.

    -Bob

  • Yeah, I noticed it.

    Anyway, I sorted-out my issues with the sensor I2C driver: I added some timeout condition handling and things went smoother :-)

    But I kept my approach though, so instead of doing:

            /* Now we need to initiate the read */
            /* Wait until 2nd Byte has been output to shift register */
            while(!(EUSCI_B0->IFG & EUSCI_B_IFG_TXIFG0));

    I keep doing:

            while(!I2C_getInterruptStatus(EUSCI_B3_BASE, EUSCI_B_I2C_BIT9_POSITION_INTERRUPT));

    before sending a restart. This is because I think it's more robust. From user manual we can notice that TXIFG is set before transmission happens:


    And this other flag rises at the end of transmission instead (weird it's not reported in the above diagram):



    Also consider that I have a 48 MHz MCLK and a 24 MHz SMCLK, while the example has both running at same speed (3 MHz).

**Attention** This is a public forum