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.

SPI issues with ADXL345

Other Parts Discussed in Thread: MSP430F5638, MSP430F2274

Everyone,

I have a MSP430F5638 that is interfacing with an ADXL345 accelerometer over SPI. I am attempting to write the values of X, Y, and Z into a buffer. Note that each axis is one word long and requires concatenation of the first byte sent (LSB) and the second byte sent (MSB). The X axis is read first followed by Y then Z for a total of 6 registers read on the accelerometer. 

My problem is in recovering the proper values of X, Y, and Z during a multi-register read. When stepping through the code below in debug, I get the proper values. I am also able to view any register on the ADXL, so the SPI communication is not an issue. However, when I set a break point at "SPI_OFF" the X-axis value is stored in the Y slot in the buffer and Y-axis value is stored in the Z slot in the buffer. The Z data is lost completely. Visually:

X -> Y

Y->Z

Z->0x00

Where the variable on the left is the axis being observed and the right variable is the position in the buffer. I have attempted to correct the issue by disabling interrupts, but that did not work. I then tried adding delays after the write, that too did not work. It seems like this is a timing issue, but I do not see in the datasheet for the ADXL345 any timing issues that would be a problem. I realize this is a TI MSP forum, but I am not sure where to get help. Any suggestions are appreciated!

//Poll Accelerometer
  SPI_ON;                           //Unlatch SPI
  while (!(UCB1IFG & UCTXIFG));
  UCB1TXBUF = 0xF2;                 //BITs 7 and 6 are added for multi write and read
  
  for(int j=0;j<6;j++)
  {
    while (!(UCB1IFG&UCTXIFG));
    UCB1TXBUF = 0x00;
    
    if(j%2)
    { //Starts second
      byteVar = byteVar | (UCB1RXBUF << 8);
      outBuf[bufCt] = byteVar;
      bufCt++;
      outBuf[bufCt] = 0x20;
      bufCt++;
    }else //Starts 1st
      {
        byteVar = UCB1RXBUF;
      }
  }
  while(UCB1STAT&UCBUSY);
  SPI_OFF;
Note that the SPI clock is at 500 kHz
-David
  • UPDATE:

    I got my hands on a logic analyzer and found out that the ADXL is transmitting the data correctly, it is the MSP430 that is not receiving the data correctly. So there is something wrong with my code.

  • Hello David,

    You have mentioned that you get correct results when you step through, but wrong values when you run to a break point. This sounds like a timing issue.

    This is how I interfaced the ADXL345  with the MSP430F2274.

    May be it can help..

    http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/p/221110/782579.aspx#782579

    Satbir

  • Hi David,

    You should wait for the transfer to complete before reading the RXBUF.  Otherwise, you'll end up two bytes ahead in the RX data stream.

      SPI_ON;                           //Unlatch SPI
      while (!(UCB1IFG & UCTXIFG));
      UCB1TXBUF = 0xF2;                 //BITs 7 and 6 are added for multi write and read
      
      for(int j=0;j<6;j++)
      {
        while (!(UCB1IFG&UCTXIFG));
        UCB1TXBUF = 0x00;
        while(UCB1STAT&UCBUSY);  // wait for transfer to complete
        if(j%2)
        { //Starts second
          byteVar = byteVar | (UCB1RXBUF << 8);
          outBuf[bufCt] = byteVar;
          bufCt++;
          outBuf[bufCt] = 0x20;
          bufCt++;
        }else //Starts 1st
          {
            byteVar = UCB1RXBUF;
          }
      }
      // while(UCB1STAT&UCBUSY);
      SPI_OFF;

    Once you make sense of this, you might look into taking advantage of double buffering to speed up the transaction.

    Jeff

  • Satbir and Jeff,

    Thank you both for responding, I have it working now. 

    Jeff - Thanks for pointing out my error, I can't believe I missed that!

**Attention** This is a public forum