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.

MSP430 Check for I2C Ack/Nack After Start Condition

Other Parts Discussed in Thread: MSP430F5438, MSP430G2553

I am having trouble checking for the ack/nack after the I2C start condition is sent using an MSP430F5438 as an I2C master. The user's guide states that after the slave device acknowledges that the UCTXSTT bit is cleared in UCBxCTL1, and if a nack is received the UCNACKIE bit is set in UCBxIFG. I'm not seeing either condition occur. And looking at the output on the logic analyzer it looks like the master is only clocking 8 bits, and it should be clocking 9, (7 address bits, r/w bit, plus ack bit). Here is my code (I'm using the latest version [v1.40.00.24] of the MSP430 Driver Library):

   USCI_B_I2C_masterSendStart(USCI_B0_BASE);    while((USCI_B_I2C_masterIsStartSent(USCI_B0_BASE) == USCI_B_I2C_SENDING_START) && (USCI_B_I2C_getInterruptStatus(USCI_B0_BASE, USCI_B_I2C_NAK_INTERRUPT) == 0)) ;

The code gets stuck in the while loop.

Please help.

  • In master transmitter mode, the master stops the clock on the ACK cycle until you write something to TXBUF. See the nice diagram in the users guide. As long as TXBUF is empty, UCTXSTT isn't reset and the slave ACK isn't checked.

  • My slave device requires the case where only the start condition and address are sent, and it requires I check on the ack/nack to determine if the master can continue communication. Is there any way to work around this? If the device were to ack would the loop fall through? In which case I can use to a timeout to check for nack. No offense to the author but that diagram is far from nice. After studying it my take away was what I explained in the previous post. Why not use a nice flow chart as is shown in this Wikipedia article: http://en.wikipedia.org/wiki/Flowchart.

  • Jens-Michael's answer helped me understand what was going on. I looked at my slave's spec one more time and saw that, even though the spec said to send the address, and then check for an ack, that there was a never a time where the address was sent but no data was sent afterwards, i.e. data is always sent after the start condition and address.

    So to workaround my issue I just always send the start condition and data byte(s) (always write to UCBxTXBUF after sending the start condition). Then I wait for the UCTXSTT (start condition) flag to clear. Then I check if the address was acknowledged. If the slave does not acknowledge the hardware is smart and does not attempt to send the data bytes, which was one of my concerns.

    The code looks something like:

    USCI_B_I2C_setMode(USCI_B0_BASE, USCI_B_I2C_TRANSMIT_MODE);
    USCI_B_I2C_masterMultiByteSendStart(USCI_B0_BASE, Byte);
    while(USCI_B_I2C_masterIsStartSent(USCI_B0_BASE) == USCI_B_I2C_SENDING_START) ;
    Acknowledged = !USCI_B_I2C_getInterruptStatus(USCI_B0_BASE, USCI_B_I2C_NAK_INTERRUPT);
    ...

    Thanks Jens-Michael for your support.

  • Samuel Hishmeh1 said:
    . If the slave does not acknowledge the hardware is smart and does not attempt to send the data bytes, which was one of my concerns.

    Right. If a NACK is detected, the USCI discards the data in TXBUF and sets NACKIFG instead. You then have the choice of either sending a stop or senting a repeated start.

    Please note that some slaves have a 'hold master' option if they are there but not yet ready. In this case, the slave holds SCL low until ready and the master waits with clocking the ACK bit in, until SCL is released by the slave. If the slave holds SCL down forever, the bus is locked. So a timeout is recommended. There's nothing the master can do (except resetting the slave, if this is somehow possible) to free the bus in this situation. All it can do is to flag an error and bail out.

  • Great thanks Jens. I think this is called clock stretching right? In my case the slave device's spec specifically says it doesn't clock stretch. 

  • Samuel Hishmeh1 said:
    I think this is called clock stretching right?

    The basic technique is indeed called clock stretching. But clock stretching can occur on every bit everytime.

    I was specifically referring to the ACK bit of the start byte. THis specific occurrence is called 'hold master' or similar. On some I2C slaves, you can decide with an I/O pin whether the slave shall NACK when no ready or holf the master in the ACK cycle of the start byte.
    For the USCI, it makes no difference where and when clock stretching occurs. However, for the high-level protocol (the master software), it might.

  • Now I understand. Didn't know there were devices that could be configured to NACK or or hold the master. Thanks so much for the information and your help.

  • In the MSP430 Library, there is a function called TI_USCI_I2C_slave_present 

    It issues a consecutive Start and Stop condition, avoiding the need to write to TXBUF. 

    __dint();

    UCB0CTL1 |= UCTR + UCTXSTT + UCTXSTP;

    while(UCB0CTL1 &UCTXSTP);

    return_value = !(UC0STAT &UCNACKIFG);

    __eint();

    yo can poll the UCNACKIFG bit right after the UCTXSTP is cleared. 

    I've done this, to check the presence (or readyness) of a slave previous to communication. 

  • So to workaround my issue I just always send the start condition and data byte(s) (always write to UCBxTXBUF after sending the start condition). Then I wait for the UCTXSTT (start condition) flag to clear. Then I check if the address was acknowledged. If the slave does not acknowledge the hardware is smart and does not attempt to send the data bytes, which was one of my concerns.

    How to check whether the address is acknowledged or not?   i.e. How to check the ack bit which will be received from the slave device?

  • If the slave did send a NACK (actually, if no slave did actively send an ACK on the start condition ACK cycle), the USCI will set UCNACKIFG. IT does so, no matter whether you did enable the interrupt with UCNACKIE. The next start condition you send will clear the UCNACKIFG bit again. It is also cleared if you manually clear it (not recommended) or if you have UCNACKIE set and did read the IV register on the interrupt. Reading the IV register will not present and clear interrupts which are not enabled with the corresponding IE bit.
  • Thanks for help.

    I came to know that wire library is already available for i2c communication.

    Just want another help

    Where can I get the register level function definitions of functions in wire.h library for msp430g2553?

    I want to know how the bits in various register are manipulated when we call any function from wire.h.

  • When you look at github.com/.../msp430, you can see that Wire.cpp (the code that belongs to Wire.h) includes twi.h. twi.c then includes various other header files (and therefore uses the associated code files) in this folder.
    Wire.h just has high-level functions that are not MSP specific. The 'magic' is done further down below the include chain.
    The downside of those libraries is that they are difficult to understand if you're not their developer. There's layer on layer on layer until you get to the low-level stuff. And all those nested function calls make the resulting code often very slow and inefficient. For large projects on desktop PCs, such an approach makes development much easier, simplifies debugging and allows workign for different platforms. However, on low-resource systems, it is a waste of program space and computing power. Quick results for small projects but IMHO a no-go for more complex projects. And besides this, you don't really know (unless you spend much time for studies of the code) what the code is doing - and where it interferes with the other parts of your project. At the end you pay twice.

**Attention** This is a public forum