2
\$\begingroup\$

I'm trying to get an I2C communication with an MSP430 (MSP430G2231) working. This is the first time I'm using a MSP430 for I2C and not sure if I'm doing everything correctly.

I have a Slave connected to SDA/SCL line of the Microcontroller with the Address: 0xE0 (the last Bit of the address is the Write Bit which needs to be set to 0). When monitoring the I2C bus with a logic analyzer I don't get any response from the slave to the send address - attached a picture of the bus communication. Are there any obvious errors in my code? Thanks a lot!

I2C Bus receiving Slave Address NACK

#include <msp430g2231.h>
#include <stdio.h>
#include <stdint.h>

    
void main(void) {
    WDTCTL = WDTPW + WDTHOLD;                                                   //disable watchdog timer
    

    
    //I2C init
    USICTL0 |= USIPE7 + USIPE6 + USIMST + USIOE + USISWRST;                     
    USICTL1 = USII2C;                                                           
    USICKCTL = USIDIV_7 + USISSEL_2 + USICKPL;                                 

    USICNT |= USIIFGCC;                                                         
    USICTL0 &= ~USISWRST;                                                      
    USICTL1 &= ~USIIFG;                                                                   
    
    while(1)
    {
        //Start Condition
        USISRL = 0x00;                                                              
        USICTL0 |= USIGE + USIOE;                                                   
        USICTL0 &= ~USIGE;
        
        //Send Data
        USISRL = 0xE0;                                                         
        USICTL0 |= USIOE;                                                           
        USICNT = 0x08;
        while((USICTL1 & USIIFG) != 0x01);                                          
        
        //Read Ack Bit
        USICTL0 &= ~USIOE;       
        USICNT |= 0x01;          
        USICTL0 |= USIOE;        
        
        //Stop
        USICTL0 |= USIOE;
        USISRL = 0x00;                                                              
        USICNT = 1;
        while((USICTL1 & USIIFG) != 0x01);                                          
      
        USISRL = 0xFF;                                                             
        USICTL0 |= USIGE;
        USICTL0 &= ~(USIGE+USIOE);
        
        for(delay=0; delay<100; delay++);
    }
}

.-.- Update:

I have changed the section for the ACK Reading to the following code and getting now still no ACK from the slave (see attatched second image):

//Read Ack Bit
USICTL0 &= ~USIOE;       
USICNT = 0x01;
USICTL0 |= USIOE;          
while((USICTL1 & USIIFG) != 0x01);
ack_flag = USISRL;

Second updated I2C communication

\$\endgroup\$
4
  • 1
    \$\begingroup\$ The protocol has a problem. There is a stop condition happening during ACK/NAK bit transfer. Either MCU sends it or the logic analyzer settings are incorrect and in reality that does not happen. An oscilloscope would be bettet at this point. \$\endgroup\$
    – Justme
    Jun 18, 2023 at 12:33
  • \$\begingroup\$ @Justme I thought the same thing, I explained to myself that the MCU is waiting for the Slave to take control of the Bus but since the slave doesn't do anything then the code actually uses the commands to introduce a stop condition. The logic analyzer images shown here are with the I2C protocol, if I remove them I get the exact same signals on the bus. Don't think it is the logic analyzer... \$\endgroup\$
    – ulix
    Jun 18, 2023 at 12:36
  • 1
    \$\begingroup\$ You already got a likely correct answer, but if the logic analyzer has a too low sampling rate it can see valid bus transitions as invalid. You never said the sampling rate. \$\endgroup\$
    – Justme
    Jun 18, 2023 at 12:49
  • \$\begingroup\$ I'm using 24MHz smapling rate. But you are right this is a valid point and I need to remeber that! \$\endgroup\$
    – ulix
    Jun 18, 2023 at 13:15

1 Answer 1

3
\$\begingroup\$
USICNT |= 0x01;

The previous value of this register is 8. This results in a value of 9. To read one bit, just set the register to 1.

Section 14.2.4.3 of the User's Guide says:

To receive the I2C acknowledgment bit, the USIOE bit is cleared with software and USICNTx is loaded with 1. This clears USIIFG and one bit is received into USISRL. When USIIFG becomes set again, the LSB of USISRL is the received acknowledge bit and can be tested in software.

Your "Read Ack Bit" code does not wait for USIIFG.

\$\endgroup\$
3
  • \$\begingroup\$ Sadly it didn't help... I have updated my code to reflect your comment (should have read the manual more carefully). But still not getting ACK from the slave? Is anything else suspicious? \$\endgroup\$
    – ulix
    Jun 18, 2023 at 13:36
  • 1
    \$\begingroup\$ This is not a forum but a Q&A site; please do not change the question after it has been answered. Your code and the waveform looks correct; this is likely to be a problem with the slave address or the slave device. Ask a new question, and include the schematic and do not keep the slave device a secret. (And the code is no longer needed.) \$\endgroup\$
    – CL.
    Jun 18, 2023 at 13:58
  • \$\begingroup\$ sorry for that. Thanks a lot for your input! Will try to find the schematic... \$\endgroup\$
    – ulix
    Jun 18, 2023 at 14:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.