AnsweredAssumed Answered

Problem with MMA8451 accelerometer

Question asked by Iván Carello on Jun 2, 2020

Hello, this is my first post here, so sorry if there are any problems with my post.

 

I'm writing a program using the MMA8451 accelerometer on my KL46Z board, using MCUXpresso, and I'm running into some problems regarding the use and switching on and off of interruptions. My program begins with only the FF_MT interruptions enabled, and when it detects a free fall event, the reg4 is written to enable data ready interruptions. The FF_MT (Freefall) interruptions are received from a different pin than the DRDY (data ready) interruptions. INT2 for FF_MT and INT1 for DRDY.

 

The configuration works flawlessly if I don't rewrite the interruptions. Having one of them, or both, on or off, without changing them, the freefall event is detected correctly, and data is transmited.

 

However, the problem arises when I try to change the interruption status. I don't want the accelerometer to interrupt all the time, just when a free fall event is detected, so I wrote this function to change the interrupt status of each event:

 

void mma8451_INT(bool DRDY_INT, bool FF_MT_INT){
      bool estAct;
      CTRL_REG1_t ctrl_reg1;
      CTRL_REG4_t ctrl_reg4;

 

      ctrl_reg1.data=mma8451_read_reg(CTRL_REG1_ADDRESS);
      estAct=ctrl_reg1.ACTIVE;
      ctrl_reg1.ACTIVE=0;
      mma8451_write_reg(CTRL_REG1_ADDRESS, ctrl_reg1.data);

 

      ctrl_reg4.data=mma8451_read_reg(CTRL_REG4_ADDRESS);
      ctrl_reg4.INT_EN_DRDY=DRDY_INT;
      ctrl_reg4.INT_EN_FF_MT=FF_MT_INT;
      mma8451_write_reg(CTRL_REG4_ADDRESS, ctrl_reg4.data);

 

      ctrl_reg1.ACTIVE=estAct;
      mma8451_write_reg(CTRL_REG1_ADDRESS,ctrl_reg1.data);
}

 

Basically, it puts the accelerometer on standby and then enables or disables FF_MT and DRDY_INT according to the bool arguments recieved. Once that's done, it activates the accelerometer once again.

 

The problem is, it works fine for a few "cycles" of the program (I let the board fall, it detects the event, and when I press a switch it goes back to waiting for other free wall event).

 

But at some point, for some reason, the accelerometer gets stuck on standby mode (I checked it on the SYSMOD register), and is interrupting constantly from the FF_MT pin. That pin is configurable, it can be either INT1 or INT2, and changing it always makes the error come from the pin to wich FF_MT is connected.

 

If I read the INT_SOURCE register, which is suppoused to tell what triggered an interrupt, it's all 0, so supposedly no intteruption was triggered, but the hardware interrupt pin registered an interrupt and the handler was used. Debugging, I found that this;


PORT_ClearPinsInterruptFlags(INT2_PORT,1<<INT2_PIN);
int2=PORT_GetPinsInterruptFlags(INT2_PORT);

 

Does not clear the interrupt flags (I use the clear function, and then check reading the flags again), which makes me think that the accelerometer has it's interrupt signal always on logic 0 (My interruptions are configured like that).

 

I have no idea what the problem may be, the core clock is configured at 48 MHz.

 

I believe there may be an error writing a register, and the accelerometer gets stuck for some reason. I say this because it's constantly interrupting, even though its internal interruption flags are all 0, and the running mode is "standby" when the error happens, while it should be "wake" or "sleep".

 

Maybe I try writing the registers too son after I put it on standby, on the function listed above, and I should use some kind of delay, or some kind of problem with the I2C? If someone knows, I'd be really greatful if someone could help me!

Outcomes