Interfacing MMA8653FCR1

cancel
Showing results for 
Search instead for 
Did you mean: 

Interfacing MMA8653FCR1

1,591 Views
shalinchikhalka
Contributor I

Hello,

I am trying to interface the MMA8653FCR1 via I2C. I have to configure the MMA to detect motion interrupts and give out a pulse on INT1. The pseudo code for the same is as follows

1) CTRL_REG1 = 0x00    // Put MMA in standby mode

2) INT_SOURCE = 0x04  // Activate Motion Interrupt

3) XYZ_DATA_CFG = 0x00 // 2g Mode

4) FF_MT_CFG = 0xf8    // Motion on all three axis

5) FF_MT_THS = 0x1f     //Motion Threshold

6) CTRL_REG3 = 0x0a   // Active High and Motion can Wake-up Controller

7) CTRL_REG4 = 0x04   //Enable Motion Interrupts

8) CTRL_REG5 = 0x02  // Interrupts on INT1

9) CTRL_REG1 = 0x01  // MMA Active.

I have tried the above code, the I2C library for my controller is working perfectly fine. The MMA however is unresponsive.

Could someone provide me with a link or sample code which can help.

Thanks,

Shalin

Labels (1)
0 Kudos
7 Replies

562 Views
shalinchikhalka
Contributor I

Hello Anthony,

Thanks a lot for the above help.

I am facing some issues though.

I am unable to read the WHO_AM_I register, it gives a value of 0x00.

When initially configured, the MMA8653 gives an interrupt by default(without motion). Below is the code for the same.

void MMA8653_init(void)

{

uint8 buffer_i2c2[2] = {0};

uint8 value = 0;

CyDelay(3);

int i , j;

    buffer_i2c2[0]= M_WHO_AM_I;

    I2C_I2CMasterWriteBuf(MMA_ADDR, buffer_i2c2, 1, I2C_I2C_MODE_COMPLETE_XFER );

    while (0u == (I2C_I2CMasterStatus() & I2C_I2C_MSTAT_WR_CMPLT))

    {}

     (void) I2C_I2CMasterReadBuf(MMA_ADDR,&value, 1, \

                  I2C_I2C_MODE_COMPLETE_XFER);

            while (0u == (I2C_I2CMasterStatus() & I2C_I2C_MSTAT_RD_CMPLT));

    value = value;  //Value shown here displays 0x00

    buffer_i2c2[0]=M_CTRL_REG1;

    buffer_i2c2[1] = 0x00;  

    I2C_I2CMasterWriteBuf(MMA_ADDR, buffer_i2c2, 2, I2C_I2C_MODE_COMPLETE_XFER );

    while (0u == (I2C_I2CMasterStatus() & I2C_I2C_MSTAT_WR_CMPLT))

    {}

   

    buffer_i2c2[0]=M_CTRL_REG2;

    buffer_i2c2[1] = 0x07;  

    I2C_I2CMasterWriteBuf(MMA_ADDR, buffer_i2c2, 2, I2C_I2C_MODE_REPEAT_START );

    while (0u == (I2C_I2CMasterStatus() & I2C_I2C_MSTAT_WR_CMPLT))

    {}

   

    buffer_i2c2[0]=M_CTRL_REG3;

    buffer_i2c2[1] = 0x08;   

    I2C_I2CMasterWriteBuf(MMA_ADDR, buffer_i2c2, 2, I2C_I2C_MODE_REPEAT_START );

    while (0u == (I2C_I2CMasterStatus() & I2C_I2C_MSTAT_WR_CMPLT))

    {}

  

    buffer_i2c2[0]=M_CTRL_REG4;

    buffer_i2c2[1] = 0x04;   

    I2C_I2CMasterWriteBuf(MMA_ADDR, buffer_i2c2, 2, I2C_I2C_MODE_REPEAT_START );

    while (0u == (I2C_I2CMasterStatus() & I2C_I2C_MSTAT_WR_CMPLT))

    {}

  

   

    buffer_i2c2[0]=M_CTRL_REG5;

    buffer_i2c2[1] = 0x04;   

    I2C_I2CMasterWriteBuf(MMA_ADDR, buffer_i2c2, 2, I2C_I2C_MODE_REPEAT_START );

    while (0u == (I2C_I2CMasterStatus() & I2C_I2C_MSTAT_WR_CMPLT))

    {}

   

    buffer_i2c2[0]=M_FF_MT_CFG;

    buffer_i2c2[1] = 0x71;  

    I2C_I2CMasterWriteBuf(MMA_ADDR, buffer_i2c2, 2, I2C_I2C_MODE_REPEAT_START );

    while (0u == (I2C_I2CMasterStatus() & I2C_I2C_MSTAT_WR_CMPLT))

    {}

  

    buffer_i2c2[0]=M_FF_MT_THS;  

    buffer_i2c2[1] = 0x12;  

    I2C_I2CMasterWriteBuf(MMA_ADDR, buffer_i2c2, 2, I2C_I2C_MODE_REPEAT_START );

    while (0u == (I2C_I2CMasterStatus() & I2C_I2C_MSTAT_WR_CMPLT))

    {}

   

   

    buffer_i2c2[0]=M_FF_MT_COUNT;

    buffer_i2c2[1] = 0x00;  

    I2C_I2CMasterWriteBuf(MMA_ADDR, buffer_i2c2, 2, I2C_I2C_MODE_REPEAT_START );

    while (0u == (I2C_I2CMasterStatus() & I2C_I2C_MSTAT_WR_CMPLT))

    {}

 

    buffer_i2c2[0] = M_FF_MT_SRC;

    I2C_I2CMasterWriteBuf(MMA_ADDR, buffer_data, 1, I2C_I2C_MODE_REPEAT_START );

    while (0u == (I2C_I2CMasterStatus() & I2C_I2C_MSTAT_WR_CMPLT));

    (void) I2C_I2CMasterReadBuf(MMA_ADDR, buffer_data, 1, \

                       I2C_I2C_MODE_COMPLETE_XFER);

    while (0u == (I2C_I2CMasterStatus() & I2C_I2C_MSTAT_RD_CMPLT));

   

    buffer_i2c2[0]=M_CTRL_REG1; 

    buffer_i2c2[1] = 0x21; 

    I2C_I2CMasterWriteBuf(MMA_ADDR, buffer_i2c2, 2, I2C_I2C_MODE_REPEAT_START );

    while (0u == (I2C_I2CMasterStatus() & I2C_I2C_MSTAT_WR_CMPLT))

    {}

 

}

I am also clearing the interrupt in main,

if(MMA_intr == 1)

        {

            buffer_data[0] = M_FF_MT_SRC;

            I2C_I2CMasterWriteBuf(MMA_ADDR, buffer_data, 1, I2C_I2C_MODE_COMPLETE_XFER);

            while (0u == (I2C_I2CMasterStatus() & I2C_I2C_MSTAT_WR_CMPLT));

            (void) I2C_I2CMasterReadBuf(MMA_ADDR, buffer_data, 1, \

                         I2C_I2C_MODE_COMPLETE_XFER);

            while (0u == (I2C_I2CMasterStatus() & I2C_I2C_MSTAT_RD_CMPLT));

            adxl_intr = 0;

            LED_YELLOW_Write(0u);

        }

Please help.

Shalin

0 Kudos

562 Views
anthonyduhamel
NXP Employee
NXP Employee

Shalin,

If you can't read WHO_AM_I value stop trying to configure the sensor. You have to read this value to be sure the MMA works well. Maybe you have hardware issues.... And perhaps your I²C communication does not work...

Can you share with us your schematic & check if I²C is working well?

By the way, I suggest you to write an I2C_Read and an I2C_Write function, your code will be more legible ans easier to debug...

void MMA8653_SingleWrite(uint8_t register,uint8_t value )

{

  uint8 buffer_i2c2[] = {register,value};

  I2C_I2CMasterWriteBuf(MMA_ADDR, buffer_i2c2, 2, I2C_I2C_MODE_COMPLETE_XFER );

    while (0u == (I2C_I2CMasterStatus() & I2C_I2C_MSTAT_WR_CMPLT));

}

uint8_t MMA8653_SingleRead(uint8_t register)

{

  uint8_t value;

  // Write register address

  I2C_I2CMasterWriteBuf(MMA_ADDR, &register, 1, I2C_I2C_MODE_COMPLETE_XFER );

    while (0u == (I2C_I2CMasterStatus() & I2C_I2C_MSTAT_WR_CMPLT));

  // Read returned value

  I2C_I2CMasterReadBuf(MMA_ADDR, &value, 1,      I2C_I2C_MODE_COMPLETE_XFER);

    while (0u == (I2C_I2CMasterStatus() & I2C_I2C_MSTAT_RD_CMPLT));

  return value;

}

Thanks,

Anthony

0 Kudos

562 Views
anthonyduhamel
NXP Employee
NXP Employee

Shalin,

Your problem should be your read function.

As written in the FXOS8700 datasheet I²C communication has to follow these rules:

i2c2.PNG

Unfortunalty,you're using the I2C_MODE_COMPLETE_XFER which adds a stop condition at the end of the write operation...

i2c.PNG

You probably need to use I2C_MODE_NO_STOP for the first transfert (read operation). Should be a thing like that:

uint8_t MMA8653_SingleRead(uint8_t register) 

  uint8_t value; 

 

 

  // Write register address 

  I2C_I2CMasterWriteBuf(MMA_ADDR, &register, 1, I2C_MODE_NO_STOP); 

    while (0u == (I2C_I2CMasterStatus() & I2C_I2C_MSTAT_WR_CMPLT)); 

  // Read returned value 

  I2C_I2CMasterReadBuf(MMA_ADDR, &value, 1,      I2C_I2C_MODE_COMPLETE_XFER); 

    while (0u == (I2C_I2CMasterStatus() & I2C_I2C_MSTAT_RD_CMPLT)); 

 

 

  return value; 

But, it's your job, MCU side I think.

Make the Read function working correctly and come back to me if you still have problems with motion detection/configuration.

Anthony

0 Kudos

562 Views
shalinchikhalka
Contributor I

Hello Anthony,

Thanks for the prompt reply.

I had the wiring wrong, I am able to communicate with the MMA8653 now.

Could you please guide me as to how can I set up motion interrupts for the same. I read the datasheet and understood the working of the registers, is there a specific order with which I should address the MMA(Standby mode-->Set Threshold --> Set Interrupt source...etc).

Thanks,

Shalin

0 Kudos

562 Views
anthonyduhamel
NXP Employee
NXP Employee

Hi Shalin,

I have prepared for you some code samples for MMA565x motion detection configuration.

////////////////////////////////////////////////////////////////////////////////

//!                                 Define

////////////////////////////////////////////////////////////////////////////////

#define MMA8653FC_CTRL_REG1         0x2A

#define MMA8653FC_CTRL_REG2         0x2B

#define MMA8653FC_CTRL_REG3         0x2C

#define MMA8653FC_CTRL_REG4         0x2D

#define MMA8653FC_CTRL_REG5         0x2E

#define MMA8653FC_FF_MT_CFG     0x15

#define MMA8653FC_FF_MT_SRC     0x16

#define MMA8653FC_FF_MT_THS     0x17

#define MMA8653FC_FF_MT_COUNT   0x18

#define MMA8653FC_WHO_AM_I       0x0D

#define MMA8653FC_WHO_AM_I_VAL   0x5A

////////////////////////////////////////////////////////////////////////////////

//!                                 Public methods

////////////////////////////////////////////////////////////////////////////////

bool MMA8653FC::init()

{

  bool __b_result = false;

  uint8_t __u8_temp;

    if(bRead(MMA8653FC_WHO_AM_I,&__u8_temp,1))     //Check presence of the sensor

    if(__u8_temp == MMA8653FC_WHO_AM_I_VAL)        //Check Sensor ID answer

    if(bWrite(MMA8653FC_CTRL_REG1       ,0x00   )) //Standby Mode 

    if(bWrite(MMA8653FC_CTRL_REG2       ,0x07   )) //Autosleep enabled / Low Power

    if(bWrite(MMA8653FC_CTRL_REG3       ,0x08   )) //Wake from Motion interrupt / Active Low / PushPull

    if(bWrite(MMA8653FC_CTRL_REG4       ,0x04   )) //Enable Motion interrupt

    if(bWrite(MMA8653FC_CTRL_REG5       ,0x04   )) //Interrupt on INT1

    if(bWrite(MMA8653FC_FF_MT_CFG       ,0x71   )) //Event not latched/Motion/ Enable X/Y/Z detection on INT1

    if(bWrite(MMA8653FC_FF_MT_THS       ,0x12   )) //Set threshold value to 1.134g

    if(bWrite(MMA8653FC_FF_MT_COUNT     ,0x00   )) //Set number of debounce

    if(bWrite(MMA8653FC_CTRL_REG1       ,0x21   )) //Set ODR to 200Hz & active mode

   {                           

        __b_result= true;

    }

    return __b_result ;

}

bool MMA8653FC::clearINTflag()

{

  uint8_t __u8_result;

  return bRead(MMA8652FC_FF_MT_SRC,&__u8_result,1);

}

Here the motion threshold is 1.134g on 3axis. You can change this value, but be carefull: gravity of earth is 1g! If you want more sensitivity, you probably need to disable an axis (MR_CFG register) or use the MMA8652 with Transient&HighPassFilter features.

When you catch a motion with your interrupt function, be sure to call "clearINTflag()" function to clear the INT flag.

For example:

void OnMotionDetected()

{

   _t_led2 = 0;

   printf("Motion detected!\n");

   wait(0.1);

    _t_accelerometer.clearINTflag();

    _t_led2 = 1;

   

}

int main()

{

    _t_pc.baud(115200);

    _t_it.fall(&OnMotionDetected);

    _t_pc.printf("Hello ");

    _t_it.enable_irq();

    if(_t_accelerometer.init())

    {

        while(true)

        { 

        sleep();

        }

    }

    else

{

        while(true)

        {

            wait(0.05);

            _t_led = !_t_led;

            wait(0.05);

            _t_led = !_t_led;

             wait(0.05);

            _t_led = !_t_led;

            wait(1);

            _t_led = !_t_led;    

        } 

    }

}

I hope it will help you!

Anthony

0 Kudos

562 Views
anthonyduhamel
NXP Employee
NXP Employee

Shalin,

There is no specific order to configure the device. You have just to begin by putting the MMA in Standymode first, then configure all your registers and finish by switching it in Active Mode. In fact, register changes are saved and effective when the MMA moves from Standby mode to Active mode.

Capture.PNG

StepNoteRegValue to write
1MMA8653FCR1 in standby modeCTRL_REG1 (0x2A) 0bXXXXXXX0
2Configure the device ....
3MMA8653FCR1 in active modeCTRL_REG1 (0x2A)0bXXXXXXX1

For motion interrupts on MMA8653, I have to check. I'm used to work with the MMA8652: motion detection can be easly enabled by using Transient Detection with High-Pass filter feature. Unfortunalty, MMA8653 doesn't get this fonction, so I will see if it's possible.

differences.PNG

I will take a look at Motion Interrupt MMA8653 feature. If you progress on your side, keep me informed.

Thanks,

Anthony

0 Kudos

562 Views
anthonyduhamel
NXP Employee
NXP Employee

Hi Shalin,

You have to make sure the I²C communication is working well. I suggest you to read the WHO_AM_I register (0x0D) which contains the Device ID (0x5A). If you don't read 0x5A, maybe you have a problem with I²C com (can be missed pull-up resistor, invalid frequency) or with the MMA . If you read the right value, it could be a configuration problem.

Let-me know if you're able to communicate with the MMA reading the Device ID. After ensuring that, next step is to check your motion detection configuration.

Anthony

0 Kudos