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.

msp430g2553 i2c acknowledge polling

Expert 2260 points

Other Parts Discussed in Thread: TMP102, MSP430G2553

Hello,

I'm trying to get the msp430g2553 to acknowledge poll a 24lc256 flash rom and a tmp102 temperature sensor. I've modified the ti sample code somewhat and it is currently working, but not quite how it should. I would ideally like to send only the control byte, but I have tried various methods and I cannot seem to manage it. I have tried setting TxByteCtr to zero both directly and via my i2cTransmit function with no avail. I have also tried a very basic send a setupTX then send a start condition and then a stop more or less directly after which seems to be what is suggested in the data sheet. All of these generally end up with my program in one of the while(UCB0CTL1 & UCTXSTP); 's which suggests the chip cannot send the stop condition for some reason or the while 1 of the USCIAB0RX_ISR, which shouldn't happen.
I do know that my current method should cause no problems since both devices first bytes are for register addressing but I would like to try and make it as universal as possible. I also know that I could use a delay but I personally think that is a bit messy.
Any help would be appreciated.

 

#include "project2553i2c.h"

void Setup_TX(char address)
{
   _DINT();
   RX = 0;
   IE2 &= ~UCB0RXIE; 
   while (UCB0CTL1 & UCTXSTP);                          // Ensure stop condition got sent// Disable RX interrupt
   UCB0CTL1 |= UCSWRST;                                 // Enable SW reset
   UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;                // I2C Master, synchronous mode
   UCB0CTL1 = UCSSEL_2 + UCSWRST;                       // Use SMCLK, keep SW reset
   UCB0BR0 = 12;                                        // fSCL = SMCLK/12 = ~100kHz
   UCB0BR1 = 0;
   UCB0I2CSA = address;                                           
   UCB0CTL1 &= ~UCSWRST;                                // Clear SW reset, resume operation
   UCB0I2CIE |= UCNACKIE;
   IE2 |= UCB0TXIE;                                     // Enable TX interrupt
}

void Setup_RX(char address)
{
   _DINT();
   RX = 1;
   IE2 &= ~UCB0TXIE; 
   UCB0CTL1 |= UCSWRST;                                  // Enable SW reset
   UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;                 // I2C Master, synchronous mode
   UCB0CTL1 = UCSSEL_2 + UCSWRST;                        // Use SMCLK, keep SW reset
   UCB0BR0 = 12;                                         // fSCL = SMCLK/12 = ~100kHz
   UCB0BR1 = 0;
   UCB0I2CSA = address;                                           
   UCB0CTL1 &= ~UCSWRST;                                 // Clear SW reset, resume operation
   UCB0I2CIE |= UCNACKIE;
   IE2 |= UCB0RXIE;                                      // Enable RX interrupt
}

void i2cTransmit(char * data, int numberOfBytes)
{
    PTxData = data;                                      // TX array start address
    TXByteCtr = numberOfBytes;                           // Load TX byte counter
    while (UCB0CTL1 & UCTXSTP);                          // Ensure stop condition got sent
    UCB0CTL1 |= UCTR + UCTXSTT;                          // I2C TX, start condition
    __bis_SR_register(CPUOFF + GIE);                     // Enter LPM0 w/ interrupts
}

void i2cReceive(volatile char * data, int numberOfBytes)
{
    PRxData = (char *)data;                              // Start of RX buffer
    RXByteCtr = numberOfBytes;                           // Load RX byte counter
    while (UCB0CTL1 & UCTXSTP);                          // Ensure stop condition got sent
    UCB0CTL1 |= UCTXSTT;                                 // I2C start condition
    while (UCB0CTL1 & UCTXSTT);
    __bis_SR_register(CPUOFF + GIE);                     // Enter LPM0 w/ interrupts
}

void i2cFlashWrite(char * data, char i2cAddress, unsigned int internalAddress, int numberOfBytes)
{                                          
   while(numberOfBytes > 0)
   {   
      TxData[0] = (char)((internalAddress >> 8) & 0xff);               //Placing internal address into transmit data
      TxData[1] = (char)(internalAddress & 0xff);
   
      Setup_TX(i2cAddress);
      
      if(numberOfBytes > 64)                                 //Sends 64 bytes of data
      {   
         memcpy(&TxData[2], data, 64);         
         i2cTransmit(TxData,66);
         numberOfBytes -= 64;
         data+=64;
         internalAddress += 64;
         i2cPoll(i2cAddress);   
      }
      else
      {
         memcpy(&TxData[2], data, numberOfBytes);
         i2cTransmit(TxData, numberOfBytes + 2);
         i2cPoll(i2cAddress);
         break;
      }   
   }
}

void i2cRandomRead(volatile char * data, char i2cAddress,  unsigned int internalAddress, int numberOfBytes)
{
   char internalAddressArray[2];
   internalAddressArray[0] = (char)((internalAddress >> 8) & 0xFF);
   internalAddressArray[1] = (char)(internalAddress & 0xFF);
   Setup_TX(i2cAddress);
   i2cTransmit(&internalAddressArray[0], 2);
   i2cPoll(FLASH);
   while (UCB0CTL1 & UCTXSTP);
   Setup_RX(i2cAddress);
   i2cReceive(data, numberOfBytes);
   while (UCB0CTL1 & UCTXSTP);
}

void i2cPoll(char address)
{
   do                     //polling for write complete
   {
      polling = 1;
      Setup_TX(address);
      i2cTransmit(0,1);        //DEBUG   
   }   
   while(polling == 2);
   polling = 0;   
   
}

#pragma vector = USCIAB0RX_VECTOR
__interrupt void USCIAB0RX_ISR(void)
{   
   if ((UCB0STAT & UCNACKIFG) == UCNACKIFG && polling == 1)
   {
      nacks++;
      UCB0STAT &= ~UCNACKIFG;
      UCB0CTL1 |= UCTXSTP;
      while(UCB0CTL1 & UCTXSTP);
      polling = 2;
      __bic_SR_register_on_exit(CPUOFF);
   }
   else
   {
      UCB0CTL1 |= UCTXSTP;
      while(UCB0CTL1 & UCTXSTP);
      while(1);
   }
}



#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
    if(RX == 1)                                       // Master Recieve?
    {
       RXByteCtr--;                                   // Decrement RX byte counter
       if (RXByteCtr)
         {
           *PRxData++ = UCB0RXBUF;                    // Move RX data to address PRxData
        }
        else
        {
            if(RPT_Flag == 0)
            {
               UCB0CTL1 |= UCTXSTP;                    // No Repeated Start: stop condition
            }
             if(RPT_Flag == 1)                         // if Repeated Start: do nothing
             {
               RPT_Flag = 0;
             }
             *PRxData = UCB0RXBUF;                     // Move final RX data to PRxData
              IFG2 &= ~UCB0RXIFG;
             __bic_SR_register_on_exit(CPUOFF);        // Exit LPM0
        }
   }
    else
    {                                                  // Master Transmit
        if (TXByteCtr)                                 // Check TX byte counter
        {
          UCB0TXBUF = *PTxData++;                      // Load TX buffer
          TXByteCtr--;                                 // Decrement TX byte counter
        }
        else
        {
           if(RPT_Flag == 1)
           {
              RPT_Flag = 0;
              PTxData = &TxData[0];                    // TX array start address
              __bic_SR_register_on_exit(CPUOFF);
              }
          else
          {
               UCB0CTL1 |= UCTXSTP;                    // I2C stop condition
             IFG2 &= ~UCB0TXIFG;
             __bic_SR_register_on_exit(CPUOFF);        // Exit LPM0
            }
        }
    }
 
}

**Attention** This is a public forum