Jump to content
Sign in to follow this  
Fabinhou

Problem receiving ACK on I2C communication [MSP430g2553]

Recommended Posts

Hello, I'm new here, and I'm trying to establish an I2C communication to my OLED Display , with the US2066 IC (http://www.buy-display.com/download/ic/US2066.pdf).

I've searched in this forum for some help on the I2C USCIB0 Communication and I used as a base the code from this topic: http://forum.43oh.com/topic/3216-need-help-with-i2c-using-msp430g2553/?hl=g2553#entry31766

 

This is my code right now:

#include "msp430g2553.h"

static int Num_bytes_tx = 0;
static int Byte_count;
static char BuffOutput[70];
static char Slv_add;
static int RPT_flag = 0;
static unsigned char TxByteCtr;

void I2CEndTx(unsigned char prescale){
  
  TxByteCtr = Num_bytes_tx;
  _DINT();
  while (UCB0CTL1 & UCTXSTP);
  UCB0CTL1 |= UCSWRST;                      // 1- USCI Enable, 0- Release state.
  P1SEL |= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0
  P1SEL2|= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0
  
  UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;     // Setting Master mode, synchronous mode
  UCB0CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset
  UCB0BR0 = prescale;                        // fSCL = SMCLK/12 = ~100kHz
  UCB0BR1 = 0;
  UCB0I2CSA = Slv_add;                    // Set slave address (write OLED)
  UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
  IE2 |= UCB0TXIE;                          // Enable TX interrupt
  
  while(UCB0CTL1 & UCTXSTP);

  UCB0CTL1 |= UCTR + UCTXSTT;
  
}

void I2CWrite(char info){
  BuffOutput[Num_bytes_tx]=info;
  Num_bytes_tx++;
}

void I2CBeginTx(char add){
  Slv_add = add;
  Num_bytes_tx =0;
  Byte_count=0;
  
}
void main(void)
{
   WDTCTL = WDTPW + WDTHOLD;             // Stop watchdog timer

   BCSCTL1 = CALBC1_8MHZ; 
   DCOCTL = CALDCO_8MHZ;
 
   
   P1DIR |= BIT4;                        //Reset PIN

   P1SEL &= ~BIT4;
   P1SEL2 &= ~BIT4;
   
   P1OUT |= BIT4;
  __delay_cycles(200);
   P1OUT &= ~BIT4;
  __delay_cycles(200);
  P1OUT |= BIT4;
  __delay_cycles(200);

 
  
  I2CBeginTx(0x78);//Slave adress+Write
  
  I2CWrite(0x80);
  I2CWrite(0x2A);
  
  I2CWrite(0x80);
  I2CWrite(0x71);
  
  I2CWrite(0xC0);
  I2CWrite(0x00);
  
  I2CWrite(0x80);
  I2CWrite(0x28);
  
  I2CWrite(0x80);
  I2CWrite(0x08);
  
  I2CWrite(0x80);
  I2CWrite(0x2A);
  
  I2CWrite(0x80);
  I2CWrite(0x79);
  
  I2CWrite(0x80);
  I2CWrite(0xD5);
  
  I2CWrite(0x80);
  I2CWrite(0x70);
  
  I2CWrite(0x80);
  I2CWrite(0x78);
  
  I2CWrite(0x80);
  I2CWrite(0x08);
  
  I2CWrite(0x80);
  I2CWrite(0x06);
  
  I2CWrite(0x80);
  I2CWrite(0x72);
  
  I2CWrite(0xC0);
  I2CWrite(0x01);
  
  I2CWrite(0x80);
  I2CWrite(0x2A);
  
  I2CWrite(0x80);
  I2CWrite(0x79);
  
  I2CWrite(0x80);
  I2CWrite(0xDA);
  
  I2CWrite(0x80);
  I2CWrite(0x10);
  
  I2CWrite(0x80);
  I2CWrite(0xDC);
  
  I2CWrite(0x80);
  I2CWrite(0x00);
  
  I2CWrite(0x80);
  I2CWrite(0x81);
  
  I2CWrite(0x80);
  I2CWrite(0x8F);
  
  I2CWrite(0x80);
  I2CWrite(0xD9);
  
  I2CWrite(0x80);
  I2CWrite(0xF1);
  
  I2CWrite(0x80);
  I2CWrite(0xDB);
  
  I2CWrite(0x80);
  I2CWrite(0x30);
  
  I2CWrite(0x80);
  I2CWrite(0x78);
  
  I2CWrite(0x80);
  I2CWrite(0x28);
  
  I2CWrite(0x80);
  I2CWrite(0x01);
  
  I2CWrite(0x80);
  I2CWrite(0x80);
  
 //__delay_cycles(1000);
 I2CWrite(0x80);
 I2CWrite(0x0C);
  
  
  I2CEndTx(0x28);    //manda o prescale e slv_add
  __bis_SR_register(CPUOFF + GIE); 
 
  while(1){}

}

#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
  if (UCB0STAT & UCNACKIFG)
	{            // send STOP if slave sends NACK
		UCB0CTL1 |= UCTXSTP;
		UCB0STAT &= ~UCNACKIFG;
	}
  else{
   if(TxByteCtr){
     UCB0TXBUF = BuffOutput[Byte_count];
     Byte_count++;
     TxByteCtr--;
  //   __bic_SR_register_on_exit(CPUOFF);
   }
   else
   {
     if(RPT_flag == 1)
     {
       RPT_flag = 0;
       TxByteCtr = Num_bytes_tx;
       __bic_SR_register_on_exit(CPUOFF);
     }
     UCB0CTL1 |= UCTXSTP;	// I2C stop condition
     IFG2 &= ~UCB0TXIFG;	// Clear USCI_B0 TX intterupt flag
     __bic_SR_register_on_exit(CPUOFF);	// Exit LPM0
    
  }
  }
    
}

I don't have an osciloscope or any type of Logic Analyzer. But I can see on the register that the NACK Flag is being setting, and only one byte is shifted to UCB0TXBUF. After it, the program just stops on my while(1) and never interrupts again.

 

On this code I'm just trying to initialize the Oled Display. I've cheked the hardware thousands times, and it seems ok. 

Can anybody give me an opinion on what to do? What could be wrong?

 

Thanks for the attention.

Share this post


Link to post
Share on other sites

Is this OLED have a schematic? Is it a pre-made board?

 

Just double checking, on the OLED the Bus Select pins BS0 and BS2 are tied low with BS1 tied high right? Otherwise it is not in i2c mode. And is the OLED 5v or 3.3/3.6v logic? The IC has options for both. Is CS#, R/W#, E and D7-D3 pulled low? This is required for i2c communication. Is D2 and D1 tied together? These two pins are the SDA line. D0 is the SCL line.

Do you have external pullups on the d2/d1/d0 lines?

 

If the SDAout pin (I think D2) isn't connected, you won't get any acks. Meaning it would be write only with no i2c acks, not standard, you would have to code around that. (See the pdf 5.1.4 (B) for info on that, it won't let me copy and paste the info)

 

The Slave address you use is 0x78. That's Binary 0b01111000. That indicated that the D/C# (SA0) line is tied low, is that correct?

That's an 8 bit address, including the write/read bit. The 7 bit address is 0x3C (0b0111100). I Think the USCI system requires a 7 bit address, not including the write/read bit, to be used. In that case, you are trying to write to the wrong address. Googling shows this to be correct. Try the 7 bit address, that might be the problem.

 

Make sure you have the i2c pins correct. P1.7 is SDA, P1.6 is SCL

Share this post


Link to post
Share on other sites

Is this OLED have a schematic? Is it a pre-made board?

 

Just double checking, on the OLED the 1)Bus Select pins BS0 and BS2 are tied low with BS1 tied high right? Otherwise it is not in i2c mode. 2)And is the OLED 5v or 3.3/3.6v logic? The IC has options for both. 3)Is CS#, R/W#, E and D7-D3 pulled low? This is required for i2c communication. 4)Is D2 and D1 tied together? These two pins are the SDA line. D0 is the SCL line.

5)Do you have external pullups on the d2/d1/d0 lines?

 

If the SDAout pin (I think D2) isn't connected, you won't get any acks. Meaning it would be write only with no i2c acks, not standard, you would have to code around that. (See the pdf 5.1.4 ( B) for info on that, it won't let me copy and paste the info)

 

The Slave address you use is 0x78. That's Binary 0b01111000. 6)That indicated that the D/C# (SA0) line is tied low, is that correct?

That's an 8 bit address, including the write/read bit. The 7 bit address is 0x3C (0b0111100). I Think the USCI system requires a 7 bit address, not including the write/read bit, to be used. In that case, you are trying to write to the wrong address. Googling shows this to be correct. 7)Try the 7 bit address, that might be the problem.

 

Make sure you have the i2c pins correct. P1.7 is SDA, P1.6 is SCL

Hello.

 

1)Yes, I noticed it yesterday. The first time I read the US2066 datasheet I thought that BS[2:0] automatically was set when I grounded the D[7:3] pins.But I saw yesterday that BS was little pins on the device's backside soldered with 0Ohms resistor smd. So I needed to solder in a way that BS[2:0] become '010'. After it, I tried the I2C communication and I Still didn't get the ACK signal.

 

2)Its 3.3V logic

 

3)All pulled low

 

4)D2 and D1 are tied toghether

 

5)Yeah, I pulled with 4.7kOhms resistors

 

6)SA0 is tied low.

 

7)There where you saved me. I was writing with 0x78. Today, before I come to work, I tried with the 0x3C adress and I think it worked!!!. Thank you so much, not getting an ACK signal for 2 weeks was driving me crazy.  But I still don't understand one thing: If it is a 7 bit slave adress, where do I set the Read or Write command, if someday I need to read? In this case, for example, if I need to read, my adress will be 0x3C again , or somehow it's gonna be 0x3D?

 

Thank you again.

Share this post


Link to post
Share on other sites

R/W bit is bit 0 of the address.  The 7 bit address is in the bits 7:1.  However, often I2C device datasheets specify addresses in right-aligned form, and they just specify only even addresses.  So, you have to read those datasheets twice.  Yes, read address would be 3D.

 

Actually, you probably need to read the datasheet three times.  If I had a dollar for every I2C device that did not quite meet the spec...  I2C is a pain to debug -- most logic analyzers introduce too much capacitance and you'll need to go to an oscilloscope.  I am not an expert of this part, but I know some parts that don't even send ACKs -- they just clock stretch.  So, you need to become an expert of the part.

Share this post


Link to post
Share on other sites

And if I let the SA0 pin on HIGH logic. What would be the Read and Write addresses?

Are you asking me to read the manual and then tell you? :smile:  SA0 is not part of I2C spec, it is part of the implementation of your OLED device.  I have no idea what it will do to the address, but it will probably change it.  If you only have one device on your I2C bus, then don't worry about it, keep it low.  Setting the read/write bit is something you do in software when you send the I2C address byte.  The device must accept odd and even LSBs, unless it doesn't support read or write.  Considering that it's a display, there might be no reason to have reading, but, again, RT[F]M.

Share this post


Link to post
Share on other sites

 

7)There where you saved me. I was writing with 0x78. Today, before I come to work, I tried with the 0x3C adress and I think it worked!!!. Thank you so much, not getting an ACK signal for 2 weeks was driving me crazy.  But I still don't understand one thing: If it is a 7 bit slave adress, where do I set the Read or Write command, if someday I need to read? In this case, for example, if I need to read, my adress will be 0x3C again , or somehow it's gonna be 0x3D?

 

Thank you again.

The USCI system is smart. It handles the read/write bit itself. You would still give the slave address of 0x3C for reads.

Share this post


Link to post
Share on other sites

And if I let the SA0 pin on HIGH logic. What would be the Read and Write addresses?

7 bit address 0111101 or 0x3D, 8 bit 01111010 write 0x7A 01111011 read 0x7B

Share this post


Link to post
Share on other sites

Are you asking me to read the manual and then tell you? :smile:  SA0 is not part of I2C spec, it is part of the implementation of your OLED device.  I have no idea what it will do to the address, but it will probably change it.  If you only have one device on your I2C bus, then don't worry about it, keep it low.  Setting the read/write bit is something you do in software when you send the I2C address byte.  The device must accept odd and even LSBs, unless it doesn't support read or write.  Considering that it's a display, there might be no reason to have reading, but, again, RT[F]M.

Yes, I know I won't read from the Oled display. I was just curious hehe.

 

The USCI system is smart. It handles the read/write bit itself. You would still give the slave address of 0x3C for reads.

That's tricky. I tried to use the slave adress 11110000 as a write adress one time, because I read on the Family User guide it was 7bit adress. But it was on the other way around.

 

7 bit address 0111101 or 0x3D, 8 bit 01111010 write 0x7A 01111011 read 0x7B

That anwser my question. Thank you so much. The oled display is working fine so far.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...