Problem with MMA8652FC 3-Axis, 12-bit Digital Accelerometer

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

Problem with MMA8652FC 3-Axis, 12-bit Digital Accelerometer

1,364 Views
l_diserio
Contributor I

Hello,

I'm currently working with a MMA8652FC 3-Axis, 12-bit Digital Accelerometer. My board comunicate with MMA8652FC via I2C.

I configured the device with two interrupt : one for the FIFO and one for trigger threshold 0.5g on y-axis.

The MMA8652FC's configuration is the following :

// Enter STANDBY mode

in CTRL_REG1 write 0x00

// Dynamic range

in XYZ_DATA_CFG write 0x02// Dynamic range = +-8g

// set MODS bits

in CTRL_REG2 write 0x01

//set F_SETUP_REG

in F_SETUP write 0xC8 // enable TRIGGER MODE and 8 Watermarks This allows data to be collected
both before and after the trigger event.

//TRIG_CFG_REG

in TRIG_CFG_REG write  0x04  //enable TRIG_FF_MT

//FF_MT_CFG

in FF_MT_CFG write 0x50 // enable OAE and YEFE

//FT_MT_THS_REG

in FT_MT_THS_REG write 0x08 //threshold 0.50 g

//CTRL_REG4

in CTRL_REG4 write (INT_EN_FIFO_MASK+INT_EN_FF_MT_MASK) // (0x40 +0x04)

//CTRL_REG5

in CTRL_REG5 write (~(INT_CFG_FIFO_MASK+INT_CFG_FF_MT_MASK)) // (~(0x40+0x04))

//CTRL_REG3

in CTRL_REG3 write 0x01

// Enter ACTIVE mode

in CTRL_REG1 write 0x01  // ACTIVE mode, data rate = 800 Hz

//Set HP_FILTER_CUTOFF

in HP_FILTER_CUTOFF write 0x30

In main loop in my apllication I executed the following procedure:

I read the register INT_SOURCE and if (INT_SOURCE [SRC_FF_MT_INTERRUPT] == 1) then I go to read the register FF_MT_SRC and if (FF_MT_SRC [YHE] == 1) I go to read the register INT_SOURCE_REG. I wait (INT_SOURCE_REG [SRC_FIFO_INTERRUPT] == 1) and as soon as SRC_FIFO_INTERRUPT occurs I go to read the OUT_X_MSB register to download 32 samples and print them.

The problem raised when there  are more tap togheter which generate more interrupt SRC_FF_MT_INTERRUPT .

In this case, when I go to read the FIFO F_STATUS register, F_CNTX [5:0] is always less than 32 samples and that value never reaches 32.

But when the there is one tap which generate only one interrupt SRC_FF_MT_INTERRUPT the previous procedure run correctly.

How I can solve this problem?

Thanks in advance for any replies.

Lucia.

Labels (1)
Tags (1)
0 Kudos
Reply
2 Replies

1,200 Views
AmitPurohit
NXP Employee
NXP Employee

Hello Lucia,

Thanks for posting your question on MMA8652. Please try following register configurations:

#define FIFO_WATERMARK (8) /* Must be between 1 - 32 */

/*! Configure the MMA865x to enable FIFO Mode and set Watermark. */
{MMA865x_F_SETUP, MMA865x_F_SETUP_F_MODE_STOP_MODE | FIFO_WATERMARK, MMA865x_F_SETUP_F_MODE_MASK | MMA865x_F_SETUP_F_WMRK_MASK},
/*! Configure the MMA865x to set FS Range as +/-8g. */
{MMA865x_XYZ_DATA_CFG, MMA865x_XYZ_DATA_CFG_FS_8G, MMA865x_XYZ_DATA_CFG_FS_MASK},
/*! Configure the MMA865x to set ODR to 800Hz. */
{MMA865x_CTRL_REG1, MMA865x_CTRL_REG1_DR_800HZ, MMA865x_CTRL_REG1_DR_MASK},
/*! Configure the MMA865x to set Low Noise Low Power mode. */
{MMA865x_CTRL_REG2, MMA865x_CTRL_REG2_MODS_LNLP, MMA865x_CTRL_REG2_MODS_MASK},
/*! Configure the MMA865x to set OAE Motion and Enable YEFE. */
{MMA865x_FF_MT_CFG, MMA865x_FF_MT_CFG_OAE_MOTION | MMA865x_FF_MT_CFG_YEFE_EN, MMA865x_FF_MT_CFG_OAE_MASK | MMA865x_FF_MT_CFG_YEFE_MASK},
/*! Configure the MMA865x to set FFMT THS to 0x08. */
{MMA865x_FF_MT_THS, MMA865x_FF_MT_THS_DBCNTM_INC_CLR|0x08, 0},
/*! Configure the MMA865x to Enable FIFO and FFMT Interrupts. */
{MMA865x_CTRL_REG4, MMA865x_CTRL_REG4_INT_EN_FIFO_EN | MMA865x_CTRL_REG4_INT_EN_FF_MT_EN, MMA865x_CTRL_REG4_INT_EN_FIFO_MASK | MMA865x_CTRL_REG4_INT_EN_FF_MT_MASK},
/*! Configure the MMA865x to Configure FIFO and FFMT Interrupts. */
{MMA865x_CTRL_REG5, MMA865x_CTRL_REG5_INT_CFG_FIFO_INT1 | MMA865x_CTRL_REG5_INT_CFG_FF_MT_INT1, MMA865x_CTRL_REG5_INT_CFG_FIFO_MASK | MMA865x_CTRL_REG5_INT_CFG_FF_MT_MASK}

In the execution loop, keep your logic as you described:

I read the register INT_SOURCE and if (INT_SOURCE [SRC_FF_MT_INTERRUPT] == 1) then I go to read the register FF_MT_SRC and if (FF_MT_SRC [YHE] == 1) I go to read the register INT_SOURCE_REG. I wait (INT_SOURCE_REG [SRC_FIFO_INTERRUPT] == 1) and as soon as SRC_FIFO_INTERRUPT occurs I go to read the OUT_X_MSB register and print watermark samples. Then just read-out the INT_SOURCE and FF_MT_SRC registers to clean out the interrupt flags and then the whole process repeats.

Try these suggested changes and share your observations.

Regards,

Amit Purohit.

0 Kudos
Reply

1,177 Views
l_diserio
Contributor I

Hi @AmitPurohit ,

 

Thanks for your reply.

our board communicates with MMA8652FC via I2C and we configure this device to use the following interrupts:

one for the FIFO in particular the TRIGGER_MODE mode to be able to analyze the samples before and after the trigger event
one for the 0.5g trigger threshold on the y axis.

the MMA8652FC device is configured with the following procedure and in particular we report all the registers involved in this phase:

 

// Enter STANDBY mode

in CTRL_REG1 write 0x00

// Dynamic range

in XYZ_DATA_CFG write 0x02// Dynamic range = +-8g

// set MODS bits

in CTRL_REG2 write 0x01

//set F_SETUP_REG

in F_SETUP write 0xD0 // enable TRIGGER MODE and 16 Watermarks. This allows data to be collected
both before and after the trigger event.

//TRIG_CFG_REG

in TRIG_CFG_REG write  0x04  //enable TRIG_FF_MT

//FF_MT_CFG

in FF_MT_CFG write 0x50 // enable OAE and YEFE

//FT_MT_THS_REG

in FT_MT_THS_REG write 0x08//threshold 0.50 g--> 0.50g/ 0.063g = 7.9 counts, round to 8 counts -->0x08

//CTRL_REG4

in CTRL_REG4 write (INT_EN_FIFO_MASK+INT_EN_FF_MT_MASK) // (0x40 +0x04)

//CTRL_REG5

in CTRL_REG5 write (~(INT_CFG_FIFO_MASK+INT_CFG_FF_MT_MASK)) // (~(0x40+0x04))

//CTRL_REG3

in CTRL_REG3 write 0x01

// Enter ACTIVE mode

in CTRL_REG1 write 0x01  // ACTIVE mode, data rate = 800 Hz

//Set HP_FILTER_CUTOFF

in HP_FILTER_CUTOFF write 0x30

we have implemented the following logic:

/*** Read FIFO STATUS register */

RegisterFlag.Byte = IIC_RegRead(F_STATUS);

/*** Control if FIFO event was detected; the FIFO has overflowed */

if(RegisterFlag.F_OVF_BIT==1)

{

/*** Go read the Interrupt Source Register */

RegisterFlag.Byte = IIC_RegRead(INT_SOURCE_REG);

/*** Control if The Freefall/Motion function interrupt is active */

if (RegisterFlag.SRC_FF_MT_BIT == 1)

{            

/*** Go read the Interrupt Source Register */

RegisterFlag.Byte = IIC_RegRead(FF_MT_SCR _REG);

/*** Control if Y motion has been detected */

               if (RegisterFlag. YHE_BIT == 1)

               {

                              /*** Read 12-bit XYZ results using a multi-read IIC access */

                              IIC_RegReadN(OUT_X_MSB_REG, 32*6, &value[0]);

}

}

}

Although we wait for the condition F_OVF = 1 which in F_MODE = 11 (it means that the FIFO cannot accept further samples) before reading the INT_SOURCE register the error reported previously occurs. Also below I report the debugging of the error, this phenomenon occurs as a result of multiple oscillations that trigger the trigger event. In addition, in debugging we also print the F_COUNT value to indicate the number of samples currently saved in the FIFO.

 

bits[F_OVF] : 1

bits[F_COUNT] : 31  

bits[SRC_FF_MT_INTERRUPT] : 1

bits_src[YHE] : 1

S:-131,-55,265

S:-153,-69,268

S:-214,-83,255

S:-240,-90,303

S:-283,-105,265

S:-324,-111,269

S:-347,-136,256

S:-374,-152,264

S:-392,-169,244

S:-429,-173,263

S:-431,-175,248

S:-466,-198,220

S:-452,-198,271

S:-460,-195,230

S:-468,-194,263

S:-510,-190,272

S:-519,-181,250

S:-528,-166,247

S:-586,-154,249

S:-605,-158,273

S:-632,-160,262

S:-641,-159,267

S:-668,-146,243

S:-682,-142,250

S:-685,-153,260

S:-724,-137,256

S:-718,-129,248

S:-722,-108,244

S:-715,-92,270

S:-638,-65,297

S:-485,-44,351

S:-2040,-2040,-2040

Furthermore we have also tested the following logic by inserting after verifying that F_OVF = 1 we have placed the accelerometer in STANDBY going to write in the CTRL_REG1 register and at the end of the operation we write again in the CTRL_REG1 register to bring it back to ACTIVE condition, this in order to avoid the FIFO accept further samples.

/*** Read FIFO STATUS register */

RegisterFlag.Byte = IIC_RegRead(F_STATUS);

/*** Control if FIFO event was detected; the FIFO has overflowed */

if(RegisterFlag.F_OVF_BIT==1)

{

/*** Go to Standby Mode */

MMA865xFC_Standby();

/*** Go read the Interrupt Source Register */

RegisterFlag.Byte = IIC_RegRead(INT_SOURCE_REG);

/*** Control if The Freefall/Motion function interrupt is active */

if (RegisterFlag.SRC_FF_MT_BIT == 1)

{            

/*** Go read the Interrupt Source Register */

RegisterFlag.Byte = IIC_RegRead(FF_MT_SCR _REG);

/*** Control if Y motion has been detected */

               if (RegisterFlag. YHE_BIT == 1)

               {

                              /*** Read 12-bit XYZ results using a multi-read IIC access */

                              IIC_RegReadN(OUT_X_MSB_REG, 32*6, &value[0]);

}

}

/*** Go to Active Mode */

MMA865xFC_Active();

}

Despite this further test, the error reported above still occurs. In addition, below I report the debugging of the error in this case there are two close trigger events. This phenomenon occurs as a result of multiple oscillations that trigger the trigger event. In addition, in debugging we also print the F_COUNT value to indicate the number of samples currently saved in the FIFO.

bits[F_OVF] : 0

bits[F_OVF] : 1

bits[F_COUNT] : 32

bits[SRC_FF_MT_INTERRUPT] : 1

bits[SRC_FIFO_INTERRUPT] : 1

bits_src[YHE] : 1

S:-98,17,489

S:-189,-81,707

S:-139,-86,-58

S:4,21,511

S:-200,-83,192

S:-143,-82,-19

S:-161,-112,507

S:-214,-216,461

S:-57,-53,498

S:-393,17,611

S:-356,-30,413

S:-240,-119,721

S:-288,-115,542

S:-354,-39,116

S:-317,-135,-130

S:-413,8,592

S:-556,-26,552

S:-349,-143,52

S:-313,-157,-46

S:-445,-151,213

S:-357,-216,602

S:-470,-192,519

S:-497,-80,527

S:-550,-55,175

S:-561,-44,204

S:-538,-164,165

S:-574,-114,227

S:-572,-165,324

S:-607,-122,239

S:-617,-101,329

S:-634,-54,322

S:-647,-42,158

bits[F_OVF] : 0

bits[F_OVF] : 0

bits[F_OVF] : 0

bits[F_OVF] : 0

bits[F_OVF] : 0

bits[F_OVF] : 0

bits[F_OVF] : 0

bits[F_OVF] : 0

bits[F_OVF] : 0

bits[F_OVF] : 1

bits[F_COUNT] : 26

bits[SRC_FF_MT_INTERRUPT] : 1

bits[SRC_FIFO_INTERRUPT] : 1

bits_src[YHE] : 1

S:-121,-36,-574

S:-134,152,-63

S:-150,13,285

S:53,-35,437

S:66,-178,43

S:96,-103,375

S:90,28,-208

S:-14,-224,481

S:111,66,235

S:-509,53,112

S:-272,-49,983

S:-142,-29,28

S:-71,-83,544

S:-166,-172,1158

S:-19,-191,791

S:-288,-55,24

S:-128,-183,988

S:-267,-135,654

S:-173,-76,181

S:-387,12,239

S:-296,-112,512

S:-524,60,-144

S:-307,-22,599

S:-474,-116,503

S:-312,-200,475

S:-319,-323,287

S:-2040,-2040,-2040

S:-2040,-2040,-2040

S:-2040,-2040,-2040

S:-2040,-2040,-2040

S:-2040,-2040,-2040

S:-2040,-2040,-2040

bits[F_OVF] : 0

 

How can we implement proper logic to avoid such an error?

We have already looked at the AN4073 and in particular at paragraph 5.2 as a starting point for the configuration of the device, however we do not use the physical pins to detect the trigger event as we do not have the possibility to connect them on our board .

And raising the trigger threshold for example to 1g we encounter the same problem described above.

Best Regards

0 Kudos
Reply