Help to getting started with MMA8652 and MSP430G2553

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Help to getting started with MMA8652 and MSP430G2553

Jump to solution
4,258 Views
petrus6432
Contributor II

In my first trial with accelerometers, I just want to get a "Hello World" from an MMA8652 via I2C mastered from a MSP430G2553 which is into the ti launchpad (not Arduino). I've searched for information in the web and tried lots of examples but never got a response from the accelerometer.

In particular I took the examples for I2C communication that come with the Code Composer Studio, changing the slave address to the WHO_AM_I address (UCB0I2CSA = 0x0d) and I've also tried to read several other adresses.

Many blogs mention i2c.h library, but I couldn find it specifically for G2553 microprocessor, the examples into CCS don't use it. I've also read about wire.h, but I understand it is for Arduino board.

I've tried Mr. Kerry Wong examples, etc, etc, etc ... 

I used two accelerometers in two different boards and nothing, I don't actually know if they are alive.

Please I'm asking for a very basic working code example which gets a response from the accelerometer.

You can see into the image how I've connected the accelerometer to the launchpad (it is ok VCC=3.56V ?)

8652 to 2553.JPG.jpg

On the other hand I know that MSP430G2553 is working ok because I succesfully communicated it via i2c with other MSP430G2553.

Thanks.

Pedro

Labels (1)
Tags (2)
1 Solution
1,800 Views
TomasVaverka
NXP TechSupport
NXP TechSupport

Hi Pedro,

Do you have a logic analyzer or an oscilloscope to see what is going on on the I2C bus?

A single byte read from the WHO_AM_I register 0x0D looks like this:

Who_Am_I register read.JPG.jpg

A common problem with the read operation is sending a stop condition (a low to high transition of SDA while SCL is high) after the second byte (in this case 0x0D). The correct way is to release the SDA line (so that it transitiones to high) before the SCL line goes high.


And here is an example of a single byte write operation which writes the value 0x3D to the CTRL_REG1 register 0x2A:

CTRL_REG1 register write.JPG.jpg

You might also find useful my sample code here.

I hope it helps.

Regards,

Tomas

PS: If my answer helps to solve your question, please mark it as "Correct" or “Helpful”. Thank you.

View solution in original post

0 Kudos
6 Replies
1,801 Views
TomasVaverka
NXP TechSupport
NXP TechSupport

Hi Pedro,

Do you have a logic analyzer or an oscilloscope to see what is going on on the I2C bus?

A single byte read from the WHO_AM_I register 0x0D looks like this:

Who_Am_I register read.JPG.jpg

A common problem with the read operation is sending a stop condition (a low to high transition of SDA while SCL is high) after the second byte (in this case 0x0D). The correct way is to release the SDA line (so that it transitiones to high) before the SCL line goes high.


And here is an example of a single byte write operation which writes the value 0x3D to the CTRL_REG1 register 0x2A:

CTRL_REG1 register write.JPG.jpg

You might also find useful my sample code here.

I hope it helps.

Regards,

Tomas

PS: If my answer helps to solve your question, please mark it as "Correct" or “Helpful”. Thank you.

0 Kudos
1,800 Views
petrus6432
Contributor II

Hi Tomas,

I'm still fighting with this. I remind you I have a MMA8652, a MSP430G2553 MCU and I use Code Composer Studio.

Today I know that the hardware is ok, because it worked fine with a Energia code example.

But it has been imposible to me to find, adapt  or write a native code for a MSP430G2553. I know you are not TI technical representative, but  would ask you if you have a basic example (read who_am_i) for this microprocessor.

I case you don't, I'll ask you please to send me the example for whatever MCU you use, and I'll try to translate it.

I've been taking a look to the "Bare metal example project", but i prefer to start with an ultra basic example if possible.

_________________________________________________________________________________________________

This is a trial,  I've adapted it from a code example in the web. It executes until the end apparently ok, but the reading result "PRxData" is always 0x00. I tried different variations over this code but nothing. I feel it is quite close, but something is still wrong. Do I need to initialize ctrl_reg1 before reading WHO_AM_I register?

#include <msp430g2553.h>

int ctrl_reg1 = 0x2A;

int lcount = 0;

int TXByteCtr;

unsigned char palout;

unsigned char PRxData;

int Rx = 0;

char WHO_AM_I = 0x0D; //WHO_AM_I register address

char itgAddress = 0x1D;

void init_I2C(void);

void Transmit(void);

void Receive(void);

int main(void)

{

  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT

  P1SEL |= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0

  P1SEL2|= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0

  init_I2C();

//  while(1){

      //Transmit process

      Rx = 0;

      TXByteCtr = 1;

      palout= ctrl_reg1;

      Transmit();

      _delay_cycles(100);

      //Transmit process

      Rx = 0;

      TXByteCtr = 1;

   palout= 0x01;

      Transmit();

      _delay_cycles(100);

      //Transmit process

      Rx = 0;

      TXByteCtr = 1;

      palout= WHO_AM_I;

      Transmit();

      _delay_cycles(100);

      //Receive process

      Rx = 1;

      Receive();

      lcount++;

     while(1);

//}

}

//-------------------------------------------------------------------------------

// The USCI_B0 data ISR is used to move received data from the I2C slave

// to the MSP430 memory. It is structured such that it can be used to receive

//-------------------------------------------------------------------------------

#pragma vector = USCIAB0TX_VECTOR

__interrupt void USCIAB0TX_ISR(void)

{

  if(Rx == 1){                              // Master Recieve?

      PRxData = UCB0RXBUF;                       // Get RX data

      lcount++;

      __bic_SR_register_on_exit(CPUOFF);        // Exit LPM0

  }

  else{                                     // Master Transmit

      if (TXByteCtr)                            // Check TX byte counter

        {

          UCB0TXBUF = palout;                     // Load TX buffer

          TXByteCtr--;                            // Decrement TX byte counter

        }

        else

        {

          UCB0CTL1 |= UCTXSTP;                    // I2C stop condition

          IFG2 &= ~UCB0TXIFG;                     // Clear USCI_B0 TX int flag

          __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0

        }

}

}

void init_I2C(void) {

      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 = itgAddress;                         // Slave Address is 069h

      UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation

      IE2 |= UCB0RXIE + UCB0TXIE;               //Enable RX and TX interrupt

}

void Transmit(void){

    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 Receive(void){

        while (UCB0CTL1 & UCTXSTP);             // Ensure stop condition got sent

        UCB0CTL1 &= ~UCTR ;                     // Clear UCTR

        UCB0CTL1 |= UCTXSTT;                    // I2C start condition

        while (UCB0CTL1 & UCTXSTT);             // Start condition sent?

        UCB0CTL1 |= UCTXSTP;                    // I2C stop condition

        __bis_SR_register(CPUOFF + GIE);        // Enter LPM0 w/ interrupts

}

0 Kudos
1,800 Views
TomasVaverka
NXP TechSupport
NXP TechSupport

Hi Pedro,

Are you seeing any traffic on the I2C bus? If yes, could you please post here scope shots illustrating both read and write operations?

Unfortunately I do not have any I2C examples for the TI MSP430G2553, but you might find useful my example code for the Kinetis KL25Z and MMA8652FC. If you donwload the source code, you can find the I2C routines in the I2C.c file within the Sources folder.

The MMA8652FC uses a well known I2C combined format that looks as follows:

Reading from the MMA8652FC:

1. Send a start sequence

2. Send 0x3A    // slave address with the R/W bit low or 0x1D << 1

3. Send internal address of the register you want to read from

4. Send a repeated start

5. Send 0x3B    // slave address with the R/W bit high or (0x1D << 1 ) | 0x01

6. Read data byte from MMA8652FC

7. [Optionally, read any further data bytes]

8. Send NAK and a stop sequence.

Writing to the MMA8652FC:

1. Send a start sequence

2. Send 0x3A    // slave address with the R/W bit low or 0x1D << 1

3. Send the internal register number you want to write to

4. Send the data byte

5. [Optionally, send any further data bytes]

6. Send a stop sequence.

I hope that helps.

Regards,

Tomas

0 Kudos
1,800 Views
petrus6432
Contributor II

Hi Tomas,

I solved my problem, it was hardware trouble. Your examples were very useful to the trials.

Thanks.

Pedro

0 Kudos
1,799 Views
TomasVaverka
NXP TechSupport
NXP TechSupport

Hi Pedro,


Glad to hear you found out where the problem was and that you found my examples useful.


Have a good day.


Regards,

Tomas



0 Kudos
1,800 Views
petrus6432
Contributor II

Hi Tomas, thank you for the answer.

Yes I have connected an oscilloscope to the SCL and SDA lines, expecting to see some pulses but... nothing happens, SCL remains low and SDA remains high.

Please confirm if launchpad's VCC=3.56 is ok for MMA8652, I know the limit is 3.6V.

I will try now with you example and I will mount a third MMA8652 in another board.

I'll tell you later.

Thanks.

Pedro

0 Kudos