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.

CCS/TM4C123GH6PM: Polling NAK until ACK is received for TivaWare I2C API

Part Number: TM4C123GH6PM

Tool/software: Code Composer Studio

Hello,

I have a demo board setup with TM4C123G micro connected to SI7006-A20-IM1 Temperature/Humidity sensor and trying to read data from the registers but getting wrong values. The read method of "No Hold Master Mode" requires polling an NACK until the ACK is received from the sensor so the correct data can be received. I wanted to know how this can be done using the TivaWare 2.1.4.178 version I2C API calls in the documentation or if another method is required to accomplish this. I am using CCS9.

Thks!

Mark

  • Hi Mark,

      Here is a SI7006-A20-IM1 I2C transaction sequence for the No Hold Master Mode. In this case, the device will NACK the slave address byte until the data is complete. You can call the TivaWare I2CMsterErr() and poll for I2C_MASTER_ERR_ADDR_ACK and wait until the flag is cleared by which time you can re-issue the slave address byte again. This is a polling method. Another method is to use interrupt. When NACK is received by the I2C master, it can cause an interrupt to the processor. The processor can re-issue the slave address byte based on the interrupt request. 

  • Greetings Charles,

    Your guidance appears proper in enabling poster's success w/his (chosen) method.

    That said - does not poster's (chosen) method "No Hold Master Mode" demand (much) monkey motion?     (i.e. repeated I2C transmissions which end (only) - if & when - ACK finally (if ever) arrives.)     

    You've identified what appears to be a 'clever' (i.e. reduced & eased) method to recognize, "when ACK arrives."    (i.e. calls to I2CMasterErr() function.)    However - can that command succeed 'by itself' (i.e. alone) & 'Without burdening the I2C bus w/repeated Slave Address transactions?'    My fear is that the, 'return from the call to I2CMasterErr() will remain (latched/locked) until the Slave Address is sent again - thus (limiting) the value of this 'I2CMasterErr()' function.   (Staff & I see 'No means' for the MCU to recognize the eventual, 'Arrival of ACK' - w/out repeated Slave Address transmissions!)     Might you be good enough to advise regarding this point?      We do not believe that 'I2CMasterErr()' can extract 'Slave's eventual ACK' minus the, 'Repeat transmission of the Slave Address!     Our review of the source code reveals that, 'I2CMasterErr()' does NOT generate a fresh 'Slave Addressing Sequence' - thus it is (essentially) a, "One & Done" function!    (Repeated calls (by themselves) serve no purpose...)

    My group proposes instead - poster's switch to "Hold Master Mode" - which substitutes 'clock-stretching' in place of 'repeated polling.'     This method seems to be far less demanding - almost 'automatic' - as the requirement for polling is eliminated.    Presented below is a, 'Contrast of each method' - our vote goes to this 'Hold Master Mode!'    (which BTW - enables the acquisition of Temperature just after Humidity measurement.)

  • Hi cb1,

       What I'm not sure is whether the ADRACK (address acknowledge) bit is sticky. Once it is set, it may remain set until another address byte is issued and get cleared by a valid ACK. If this is the case, keep polling the ADRACK AND re-issuing the address byte in a loop until the ADRACK bit is cleared. Interrupt method will work better in my opinion. I agree with you that the Hold Master Mode will be easier to handle. However, you still need to wait until the bus is not busy before you can read the data bytes. The I2CMasterBusy() is another form of polling while the NACK is active. 

  • Hi Charles,

    Thank you - appreciated.   

    Gurlz & I have the opinion that, "ONLY by issuing ANOTHER Slave Address" - can a 'FRESH ACK or NAK' be obtained!    Our logic is that there exists 'NO METHOD' for the Slave to 'magically' present its (NEW) ACK - until (another) Slave Address Transaction has arrived.   

    To use 'your words' - it must be that (both) the ADRACK & DATAACK Bits - obtained via call to, 'I2CMasterErr()'  (must) STICK until a new Slave Address Transaction is launched.    (think of it - how possibly can the Master (MCU) detect the Slave's 'CHANGED' ACK/NAK Bit .. without Resending the Slave Address Sequence?)    (which only then enables the Slave Device to respond...)

    Charles Tsai said:
     I agree with you that the Hold Master Mode will be easier to handle. However, you still need to wait until the bus is not busy before you can read the data bytes.

    May we respectfully disagree?     Is not the intent of the 'clock-stretching' to, "Eliminate that waiting for the Slave to complete its processing?"     You  may note that the diagram we presented removes the asterisk and related 'Note' (which directed the repeated polling requirement) - when the "Hold Master Mode" is selected...    It is for that 'simplicity' - bordering upon automation - that we've recommended "Hold Master Mode" as superior...

    This may rise to the level of improved explanation w/in the (pardon) 'Teased/Pending' API Updates...   (i.e. "I2CMasterErr()" is (only) a, 'One & Done' function - thus cannot be (productively) called repeatedly (by itself, alone.)    Existing API nowhere provides this (necessary) level of detail...)

  • Hi cb1,

      What I meant is that the CPU still needs to call I2CMasterBusy() before proceeding to I2CmasterDataGet(). The CPU does not know if the SCL is stretched or not. 

        MAP_I2CMasterSlaveAddrSet(I2C3_BASE, SHT21_I2C_ADDRESS, true);
        //
        MAP_I2CMasterControl(I2C3_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);
        //
        while(MAP_I2CMasterBusy(I2C3_BASE))
        {
        }
        //
        pui32DataRx[0] = MAP_I2CMasterDataGet(I2C3_BASE);
    

  • Hello,

    Thks for your quick responses. I will try the polling method first as described in the first answer and then look at the following. I have read some data using the MASTER_MODE and can see the clock stretching on the logic analyzer so that is working but the readings are bouncing a little. I need to have both options available and that is why I am testing the NO_HOLD_MASTER_MODE.I will provide some feedback shortly after testing and appreciate your support.

    Mark

  • "Bouncing (a little) Greetings,"

    Some thoughts - possibly warranting consideration:

    • using another's ARM Cortex M4 (168MHz w/DAC) and a different (yet similar) sensor my small group has found:
      • polling adds to the (elapsed) time before the (similar - ours is a 'mil grade') sensor can complete its processing
      • while polling - your MCU is (most likely) 'either blind to other tasks' or 'stopped in its tracks' by a higher priority interrupt - neither good!
    • as a "counter" to (both) conditions you may consider inserting a, "Timer-based & interrupting delay" - which enables (other) operations while awaiting your sensor's becoming ready
    • program this "Timer-based delay" so that it is (somewhat) excessive (initially).   Do note if this reduces the "bouncing readings" - which we have found to be impacted by the sensor's polling - no longer required!    (Later - the delay may be 'fine-tuned' - mission (always) comes before 'optimization.')

    Unstated is, "Why you need to have both options available" - especially as we (and our client) have found such 'polling' (at least in our application) to degrade sensor response time AND accuracy...

  • Hello,

    I tried the polling for the ACK from the slave but the code seems to hang as it never arrives. The Tivaware I2C API does not seem to be to flexible as I have not experienced these problems with other micros reading humidity and other sensors. The unstable temperature reading is most likely from some noise or bad circuitry on the board. Working on debugging that and going to test another sensor and board.

    Thks!

    Mark

  • Hi Mark,

      

    Mark Chin said:
    I tried the polling for the ACK from the slave but the code seems to hang as it never arrives.

      Did you mean master or the slave? The MCU is the master, not the slave. Perhaps you meant polling the ADACK for the master and the flag never indicated it receive NACK. Is that what you meant?

      Can you try the interrupt mode? If the NACK was ever detected it will interrupt the processor. 

    Mark Chin said:
    The unstable temperature reading is most likely from some noise or bad circuitry on the board. Working on debugging that and going to test another sensor and board

      I'm a bit unclear here. If you were hanging polling the ADACK then how would you be able to read the data? You seem to suggest you were reading some data. Whether the data is good or bad is one thing, but you at least pass the address byte in order to read data bytes, isn't?

  • Hello Charles,

    Charles Tsai said:
    I'm a bit unclear here. If you were hanging polling the ADACK then how would you be able to read the data? You seem to suggest you were reading some data.

    Young staff believe they can "aid/assist" here.    Poster's response (13 Jan, 22:28 (10:28pm) read, "I have read some data using the MASTER_MODE and can see the clock stretching on the logic analyzer so that is working but the readings are bouncing a little."

    Thus - staff's suggestion of "Clock Stretching" (via the "Hold Master Mode") is what enabled the, "Data Capture from poster's sensor."    Polling - as repeatedly reported - always failed!

    Staff wrote (days ago) " Is not the intent of the 'clock-stretching' to, "Eliminate that waiting for the Slave to complete its processing?"     You  may note that the diagram we presented removes the asterisk and related 'Note' (which directed the repeated polling requirement) - when the "Hold Master Mode" is selected...   Staff has employed, "Just this clock-stretch method w/other/similar sensors" - and enjoyed success!

    One final point (prior to this 'dead horse' decaying (even) further.)    "I2CMasterErr()" is (only) a, 'One & Done' function - thus cannot be (productively) called repeatedly (by itself, alone.)     Staff experimented w/2 other (different) sensors - and confirmed that the "Sensor has NO MEANS to convey its 'Changed State' - only another Addressing Sequence enables that, "Shift from NAK to ACK!"     (unfortunately gravely reducing the value (i.e re-usability) of "I2CMasterErr()."   It CANNOT be called repeatedly - and (somehow - minus another address sequence) 'divine' - the sensor's changed state!)

  • Hi cb1,

      Agreed with your assessment. You brought up two critical points - that is "I2CMasterErr()" is (only) a, 'One & Done' function and only another Addressing Sequence enables that, "Shift from NAK to ACK!". This means when the slave asserts the NACK the first time, it should have been captured by the master at least once. In theory, polling the ADACK should reveal the status as such. It appears to me that the master is not seeing the NACK at all in NO HOLD MASTER MODE according to Mark. 

  • Hi Charles,

    Good analysis - staff appreciates your 'approval' ... (eye-rolls) are the best that I can 'hope for.'    (their 'crewing' upon SScb1 this summer is in (some) jeopardy)

    Beyond ANY DOUBT - a proper, "Capture of Data Events - sufficient to reveal 'any/all' ACKs/NAKs" - throughout the entire data sequence - is required!

  • Hello,

    There are two modes which can be used to obtain the temperature and humidity which are "Hold Master Mode" and" No Hold Master Mode". The Hold Master Mode involves Clock Stretching which I have tested and was able to read some data. The No Hold Master Mode involves the Master (TM4C123G) to NACK the slave (Si7006) until the conversion is complete. This method is what I am trying to get working with the Tivaware API. Not sure how to implement that with the API. I have gone through the documentation but do not see how to do that.

    Thks.

    Mark

  • Hello back,

    Mark Chin said:
    The Hold Master Mode involves Clock Stretching which I have tested and was able to read some data.

    Might you (better) explain?     Why were you not able to successfully read "ALL Data?"   

    Earlier you noted your desire to, "employ both Hold & No Hold Modes."     That was never explained/justified - why cannot the (proven) clock-stretching method answer "ALL of your requirements?"    (Note that "IT ALONE" appears to be succeeding...)

  • Hi Mark,

      Are you making progress here? Earlier I asked if you can try the interrupt mode. Did you have a chance to try that. If a NACK is received by the I2C master it should generate an interrupt. This way, at least you know if the NACK ever happened from the eye of the master. I don't know why polling mode does not work. How are you polling the ADRACK bit of the I2CMCS register? Can you show your code?