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.

MSP430F1611 - I2C stop condition after slave NACK?

Other Parts Discussed in Thread: MSP430F1611

Hi,

The setup is an MSP430F1611 as single master with about 30 different slave devices. Some devices are sometimes off so  NACKS after addressing occurs regularly. The USART of the MSP430 does not send on default a stop condition after such a NACK. Unfortunately some slave devices cannot properly handle a repeated start, so the really need the stop condition before they can respond correctly to start conditions again.

To be more specific about the current situation as seen on a scope: athe SDA remains high and the SCL briefly goes low and is then released again (in less time than a regular clock pulse). The desired behavior is that once the SCL goes low, the SDA is pulled low after which SCL is released and the the SDA (the stop).

How can a stop condition be forced after a slave address NACK? Is there a way without bitbanging?

  • When you detect a NACKIFG (so the slave didn't answer), set I2CRM and I2CSTP manually. Then wait for !I2CBUSY  before you do the next start. Normally, the USART should handle a stop and following start properly, but apparently not.

    I must admit that I never used the 1x family USART for I2C. I found the I2C implementation too much overkill for the typical transfers I had to do (usually sending a register address and then doing a repeated start for readign the registers). So my I2C code for the 1611 was a plain software solution.

  • Jens-Michael Gross said:

    When you detect a NACKIFG (so the slave didn't answer), set I2CRM and I2CSTP manually.

    Unfortunately I could not get the stop condition after NACK to work. Below are the options tried. Option (1) is the basic one, option (2) is the suggested on setting I2CRM manually. Because the specsheet says that I2CRM can only be set when the module is disabled, also option 3 is tried. None of the cases a stop was generated. At a succesful transactions, stops are generated and look fine on the scope, so this is a NACK-only issue.

    (1) (2) (3)

    __interrupt void I2CISR(void) {

               switch(I2CIV) {
                    case I2CIV_NACK:
                    I2CTCTL |= I2CSTP;
                    break;
                     }
    }
     

    __interrupt void I2CISR(void) {

               switch(I2CIV) {
                    case I2CIV_NACK:
                    I2CTCTL |= I2CRM + I2CSTP;
                    break;
                     }
    }
     

    __interrupt void I2CISR(void) {

               switch(I2CIV) {
                    case I2CIV_NACK:
                    U0CTL &= ~I2CEN;
                    I2CTCTL |= I2CRM   
                    I2CTCTL |= I2CSTP;
                    U0CTL |= I2CEN;  
                    break;
                     }
    }
     

  • Jasper Bouwmeester said:
    Because the specsheet says that I2CRM can only be set when the module is disabled

    Yes, you're right. I only read the table of operating modes and didn'T notice this.

    Well, disabling the USART will reset it, so no stop will be generated.

    You may try setting I2CNDAT to 0 before setting I2CSTP, to force an premature end of the transmission.

    As I said, for my own projects, the USART was doing too much by itself in I2C mode, so I wrote a software one that exactly did what I wanted.

**Attention** This is a public forum