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.

MSP430FR5994: Rx interrupt and STPIFG Issue

Part Number: MSP430FR5994


Hello,

I have been trying to interface the ADXL345 accelerometer  through  I2c . all the methods that i tried  has led me to the dead end. whatever i am trying to transmit works fine but at last there is no STOP interrupt flag assertion or  no ack from the sensor. since there is no ack i couldn't able to receive any values from the sensor. I have shared my whole code. go through it and let me know your suggestions. Thanks in advance.


#include <msp430.h>
#include <stdio.h>
#include <stdint.h>
#define NUM_BYTES_TX 2
#define NUM_BYTES_RX 2
#define ADXL_345     0x53
int RXByteCtr, x1,y1,z1, RX_Data;       // enables repeated start when 1
volatile unsigned char RxBuffer[6];         // Allocate 6 byte of RAM
unsigned char *PRxData;                     // Pointer to RX data
unsigned char TXByteCtr, RX = 0;
unsigned char MSData[2];
uint8_t BW_RATE[2] ={0x2C,0x0D};
uint8_t POWER_CTL[2] ={0x2D,0x08};
uint8_t Data_Format[2] ={0x31,0x03};
unsigned int i,j;
void Setup_TX(unsigned char);
void Setup_RX(unsigned char);
void Transmit(unsigned char,unsigned char);
void TransmitOne(unsigned char);
void Receive(void);
void getX();
void getY();
void getZ();
void GPIO_Setup()
{
    // Ports
    P7SEL1 &= ~BIT0;
    P7SEL0 |= BIT0;
    P7SEL1 &= ~BIT1;
    P7SEL0 |= BIT1;
//    P7REN |= BIT0 | BIT1;                    // Enable Internal pullup resistor on P7.0 & P7.1
    PM5CTL0 &= ~LOCKLPM5;
}
int main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  printf("Started Initialize\n");
  //Transmit process
  Setup_TX(ADXL_345);
  TransmitOne(BW_RATE[0]);
  while (UCB2CTL1 & UCTXSTP);
  printf("0x2C\n");
  Setup_TX(ADXL_345);
  TransmitOne(BW_RATE[1]);
  while (UCB2CTL1 & UCTXSTP);             // Ensure stop condition got sent
  printf("0x0D\n");
  Setup_TX(ADXL_345);
  TransmitOne(POWER_CTL[0]);
  while (UCB2CTL1 & UCTXSTP);             // Ensure stop condition got sent
  printf("0x2D\n");
  Setup_TX(ADXL_345);
  TransmitOne(POWER_CTL[1]);
  while (UCB2CTL1 & UCTXSTP);             // Ensure stop condition got sent
  printf("0x08\n");
  Setup_TX(ADXL_345);
  TransmitOne(Data_Format[0]);
  while (UCB2CTL1 & UCTXSTP);             // Ensure stop condition got sent
  printf("0x31\n");
  Setup_TX(ADXL_345);
  TransmitOne(Data_Format[1]);
  while (UCB2CTL1 & UCTXSTP);             // Ensure stop condition got sent
  printf("0x03\n");
  while(1)
  {
    getX();
//    getY();
//    getZ();
//    printf("x1 = %d, y1 = %d, z1 = %d\n",x1,y1,z1);
  }
}
void getX()
{
    //Transmit process
    Setup_TX(ADXL_345);
    TransmitOne(0x32);  // 0x32                    // Request Data from ADXL345 in 2g Range 10Bit resolution
    printf("Transmitted\n");
    while (UCB2CTL1 & UCTXSTP);             // Ensure stop condition got sent
    //Receive process
    UCB2IFG &= ~UCSTPIFG;
    Setup_RX(ADXL_345);
    Receive();
}
void getY()
{
    //Transmit process
    Setup_TX(ADXL_345);
    TransmitOne(0x34);                      // Request Data from ADXL345 in 2g Range 10Bit resolution
    printf("Transmitted\n");
    while (UCB2CTL1 & UCTXSTP);             // Ensure stop condition got sent
    //Receive process
    Setup_RX(ADXL_345);
    Receive();
}
void getZ()
{
    //Transmit process
    Setup_TX(ADXL_345);
    TransmitOne(0x36);                      // Request Data from ADXL345 in 2g Range 10Bit resolution
    printf("Transmitted\n");
    while (UCB2CTL1 & UCTXSTP);             // Ensure stop condition got sent
    //Receive process
    Setup_RX(ADXL_345);
    Receive();
}
void Setup_TX(unsigned char Dev_ID){
  RX = 0;
  printf("Inside TX\n");
  UCB2CTLW0 |= UCSWRST;               // Enable SW reset
  UCB1CTLW0 |= UCCKPL;
  UCB2CTLW0 |= UCSSEL__SMCLK;              // Use SMCLK, keep SW reset
  UCB2BRW = 10;                      // fSCL = SMCLK/12 = ~100kHz
  UCB2CTLW0 |= UCMODE_3;              // I2C Master, synchronous mode
  UCB2CTLW0 |= UCMST;
  UCB2CTLW0 |= UCTR;
  UCB2I2CSA = Dev_ID;                  // Slave Address is 053h
  UCB2CTLW1 = UCASTP_2;               // automatic STOP assertion
  GPIO_Setup();
  UCB2CTLW0 &= ~UCSWRST;             // Clear SW reset, resume operation
  UCB2IE |= UCTXIE0;
  __enable_interrupt();
//  __bis_SR_register(LPM0_bits + GIE);
}
void Setup_RX(unsigned char Dev_ID)
{
  printf("Inside RX\n");
  RX = 1;
  UCB2CTLW0 |= UCSWRST;               // Enable SW reset
  UCB1CTLW0 |= UCCKPL;
  UCB2CTLW0 |= UCSSEL__SMCLK;              // Use SMCLK, keep SW reset
  UCB2BRW = 10;                      // fSCL = SMCLK/12 = ~100kHz
  UCB2CTLW0 |= UCMODE_3;              // I2C Master, synchronous mode
  UCB2CTLW0 |= UCMST;
  UCB2CTLW0 &=~UCTR;
  UCB2I2CSA = Dev_ID;                  // Slave Address is 053h
  UCB2CTLW1 = UCASTP_2;               // automatic STOP assertion
  UCB2TBCNT = 1;
  GPIO_Setup();
  UCB2CTLW0 &= ~UCSWRST;             // Clear SW reset, resume operation
  UCB2IE |= UCRXIE0;
  __enable_interrupt();
  printf("RX Completed\n");
}
void Transmit(unsigned char Reg_ADD,unsigned char Reg_DAT)
{
    __disable_interrupt();
    printf("Inside Transmit Function\n");
    MSData[1]= Reg_ADD;
    MSData[0]= Reg_DAT;
    UCB2TBCNT = NUM_BYTES_TX;         // TX 2 bytes of data
    TXByteCtr = NUM_BYTES_TX;         // Load TX byte counter
    while (UCB2CTL1 & UCTXSTP);
    UCB2CTLW0 |= UCTXSTT;             // I2C TX, start condition
    __delay_cycles(2000);
    __enable_interrupt();
}
void TransmitOne(unsigned char Reg_ADD)
{
    printf("Inside TransmitOne Function\n");
    TXByteCtr = 1;
    UCB2TBCNT = 1;
    MSData[0]= Reg_ADD;
    UCB2CTLW0 |=UCTR;
    UCB2CTLW0 |= UCTXSTT;             // I2C TX, start condition
    __delay_cycles(2000);
    __enable_interrupt();
}
void Receive(void)
{
    printf("Receive\n");
    PRxData = (unsigned char *)RxBuffer;    // Start of RX buffer
    RXByteCtr = 1;
    while (UCB2CTL1 & UCTXSTP);
    UCB2CTLW0 |= UCTXSTT;                    // I2C start condition
    __delay_cycles(2000);
    __enable_interrupt();
}
//-------------------------------------------------------------------
// ISR Vector
//-------------------------------------------------------------------
#pragma vector = EUSCI_B2_VECTOR
__interrupt void I2C_B2_ISR(void)
{
    printf("Interrupt Routine\n");
    switch(UCB2IV)
      {
        case USCI_NONE:          break;         // Vector 0: No interrupts
        case USCI_I2C_UCALIFG:   break;         // Vector 2: ALIFG
        case USCI_I2C_UCNACKIFG:                // Vector 4: NACKIFG
            printf("inside NACK\n");
            UCB2CTL1 |= UCTXSTT;                //re-send start if NACK
          break;
        case USCI_I2C_UCSTTIFG:  break;         // Vector 6: STTIFG
        case USCI_I2C_UCSTPIFG:  break;         // Vector 8: STPIFG
        case USCI_I2C_UCRXIFG3:  break;         // Vector 10: RXIFG3
        case USCI_I2C_UCTXIFG3:  break;         // Vector 12: TXIFG3
        case USCI_I2C_UCRXIFG2:  break;         // Vector 14: RXIFG2
        case USCI_I2C_UCTXIFG2:  break;         // Vector 16: TXIFG2
        case USCI_I2C_UCRXIFG1:  break;         // Vector 18: RXIFG1
        case USCI_I2C_UCTXIFG1:  break;         // Vector 20: TXIFG1
        case USCI_I2C_UCRXIFG0:                 // Vector 22: RXIFG0
            if(RX == 1)
            {                                   // Master Receive?
              RXByteCtr--;                      // Decrement RX byte counter
              if (RXByteCtr)
                {
                  *PRxData++ = UCB2RXBUF;       // Move RX data to address PRxData
                  printf("Received = %d", *PRxData);
                }
              else
                {
                  UCB2CTL1 |= UCTXSTP;          // No Repeated Start: stop condition
                  *PRxData++ = UCB2RXBUF;       // Move final RX data to PRxData
                  printf("Else Received = %d", *PRxData);
                  __disable_interrupt();        // Exit LPM0
                }
            }
            else
            {
                printf("RX = 0\n");
            }
          break;
        case USCI_I2C_UCTXIFG0:                 // Vector 24: TXIFG0
            printf("ISR Transmitted\n");
            UCB2TXBUF = MSData[0];
            break;
        case USCI_I2C_UCBCNTIFG: break;         // Vector 26: BCNTIFG
        case USCI_I2C_UCCLTOIFG: break;         // Vector 28: clock low timeout
        case USCI_I2C_UCBIT9IFG: break;         // Vector 30: 9th bit
        default: break;
      }
}

  • 1) Setting a register value requires (at least) 2 bytes in a single transaction -- the first is interpreted as the register number, and the second as the value. [Ref ADXL345 data sheet (RevE) Fig 41] This code splits this into two transactions. I suggest you add a TransmitTwo() function. 

    2) TBCNT can only be set while the I2C unit is in reset (UCSWRST=1) [Ref User Guide (SLAU367P) Table 32-8]. One way to do this is to pass a length value into Setup_TX().

    3) Checking for UCTXSTP=0 is not a reliable mechanism for waiting for a transaction to complete, since it's only on for a short part of the transaction. I suggest you employ a software-based "busy" variable.

  • Sorry pal.This didn't solve my issue.The problem is here the TXIFG wasn't set after the Transmission.Please help me out.

  • OK, I read "whatever i am trying to transmit works fine", so I was looking elsewhere. 

    What ADXL345 board are you using? ADI's ADXL345EB doesn't provide the bus pullups, nor does the Launchpad. Missing pullups are consistent with a no-TXIFG symptom.

  • We're Using Adafruit ADXL345 Devlopment board and We have also connected the 4.7K pullup resistors but still i stuck in the TXIFG

  • Which TXIFG wasn't set? The one after the STT? Which transaction?

    You may want to try power-cycling the accelerometer. After some of the transactions this code will generate it may have been left holding the bus.

  • Hey Bruce,

    Thanks for your quick reply.

    1.The TXIFG0 (while(!(UCB2IFG & UCTXIFG));) after the transaction is not set. Yes, after STT.

    2.We're also trying to communicate with two MSP430fr5994 as a slave and master using the example code from TI's own SDK. That's also not giving the desired results. The example says slave transmits 5 bytes to the master. We also enabled the UCTR in Slave. Cleared in Master. In Master, the execution stuck in this line while (UCB2CTL1 & UCTXSTP);.

    Please help us,

    Thank you

**Attention** This is a public forum