MMA8451Q Interrupt based reading of accelerometer using FRDM-KL25Z

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

MMA8451Q Interrupt based reading of accelerometer using FRDM-KL25Z

Jump to solution
1,430 Views
Raghahanuma
Contributor I
I'm getting a fault at these lines, I don't know what is wrong with it. have I coded the interrupt part wrong ?
NVIC_EnableIRQ(PORTA_IRQn);
NVIC_SetPendingIRQ(PORTA_IRQn);
 
Below is my complete code,
 
#include <stdio.h>
#include "board.h"
#include "peripherals.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "MKL25Z4.h"
#include "fsl_debug_console.h"
#include "pin_mux.h"
#include "fsl_gpio.h"
#include "fsl_port.h"
 
/* TODO: insert other include files here. */
 
/* TODO: insert other definitions and declarations here. */
 
#define MMA8451_SA 0x1D
 
/* MMA8451 Registers */
#define MMA8451_REG_WHOAMI 0x0D
 
 
/*
* u/brief Application entry point.
*/
int main(void) {
 
 
/* Enable clock for PORTE */
SIM->SCGC5 = (1 << SIM_SCGC5_PORTE_SHIFT);
 
/* Enable clock for I2C0 */
SIM->SCGC4 = (1 << SIM_SCGC4_I2C0_SHIFT);
 
BOARD_I2C_ReleaseBus();
 
/* PORTE24 pin as I2C0_SCL */
PORTE->PCR[24] = (5 << PORT_PCR_MUX_SHIFT) | (1 << PORT_PCR_PS_SHIFT) | (1<<PORT_PCR_PE_SHIFT) | (1<<PORT_PCR_SRE_SHIFT);
 
/* PORTE25 pin as I2C0_SDA */
PORTE->PCR[25] = (5 << PORT_PCR_MUX_SHIFT) | (1 << PORT_PCR_PS_SHIFT) | (1<<PORT_PCR_PE_SHIFT) | (1<<PORT_PCR_SRE_SHIFT);
/* clear interrupt flag and set pins of port A as gpio*/
PORTA->PCR[14]= (0 | PORT_PCR_ISF_MASK) | (1 << PORT_PCR_MUX_SHIFT) | PORT_PCR_IRQC(0xA);
//NVIC_REG->iser[0] = (1 << 16);
// NVIC_REG->icpr[0] = (1 << 16);
NVIC_EnableIRQ(PORTA_IRQn);
NVIC_SetPendingIRQ(PORTA_IRQn);
/* I2C0 Frequency Divider */
I2C0->F = 0x0F;
 
/* I2C0 Enable, Master Mode */
I2C0->C1 = (1 << I2C_C1_IICEN_SHIFT) | (1 << I2C_C1_IICIE_SHIFT);
 
I2C0->S |= (1 << I2C_S_IICIF_SHIFT);
 
/* I2C0 Check for Bus Busy */
while(I2C0->S & (1 << I2C_S_BUSY_SHIFT));
 
data = i2c_read(MMA8451_SA, MMA8451_REG_WHOAMI);
while(I2C0->S & (1 << I2C_S_BUSY_SHIFT));
 
data = i2c_read(MMA8451_SA, MMA8451_REG_WHOAMI);
 
data = i2c_read(MMA8451_SA, MMA8451_REG_WHOAMI);
 
i2c_write(MMA8451_SA, 0x2A, 0x01);
 
data = i2c_read(MMA8451_SA, 0x2A);
i2c_write(MMA8451_SA, CTRL_REG4, 0x01); // Enable DRDY interrupt
 
i2c_write(MMA8451_SA, CTRL_REG5, 0x01); // DRDY interrupt routed to INT1
 
while(1) {
//if(dataready){
//dataready=0;
/* X Offset LSB */
 
}
return 0;
}
void PORTA_IRQHandler()
{
//PORTA->PCR[14]=(0<< PORT_PCR_ISF_SHIFT); // Clear the interrupt flag
//dataready = 1;
/* X Offset LSB */
data = i2c_read(MMA8451_SA, 0x02);
xoff = data;
 
/* X Offset MSB */
data = i2c_read(MMA8451_SA, 0x03);
xoff |= (data << 8);
 
/* Y Offset LSB */
data = i2c_read(MMA8451_SA, 0x04);
yoff = data;
 
/* Y Offset MSB */
data = i2c_read(MMA8451_SA, 0x05);
yoff |= (data << 8);
 
/* Z Offset LSB */
data = i2c_read(MMA8451_SA, 0x06);
zoff = data;
 
/* Z Offset MSB */
data = i2c_read(MMA8451_SA, 0x07);
zoff |= (data << 8);
 
printf("XOFF: 0x%04x YOFF: 0x%04x ZOFF: 0x%04x\n", xoff, yoff, zoff);
PORT_ClearPinsInterruptFlags(PORTA, (1 << 12));
 
}
 
 
 
0 Kudos
1 Solution
1,417 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

Hi Raghahanuma,

This fault is not caused by NVIC_EnableIRQ(PORTA_IRQn);,

This is because the clock gate for PORTA is not enabled, but you accessed PORTA->PCR[14].

Please enable the clock gate of PORTA.

Best Regards,
Robin
-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

View solution in original post

0 Kudos
7 Replies
1,376 Views
JackITB
NXP Employee
NXP Employee
Hi Raghahanuma,
 
Be aware that control registers settings are updated only if the sensor is in standby mode.
So I suggest you change your sequence as per below:
 
i2c_write(MMA8451_SA, 0x2A, 0x00); // Put sensor in Standby mode (this will be already the case after POR or Reset)
 
 
 
i2c_write(MMA8451_SA, CTRL_REG4, 0x01); // Enable DRDY interrupt
 
i2c_write(MMA8451_SA, CTRL_REG5, 0x01); // DRDY interrupt routed to INT1
 
i2c_write(MMA8451_SA, 0x2A, 0x01);
data = i2c_read(MMA8451_SA, 0x2A); // optional verification
 
Hope this will help.
0 Kudos
1,409 Views
bobpaddock
Senior Contributor III

NVIC_SetPendingIRQ(PORTA_IRQn);


After the clock issue is addressed,
why is that being used?

That will force the PORTA IRQ to fire and I2C is not yet configured.

 

The Accel itself will generate an IRQ when it is ready, after everything is correctly configured.

0 Kudos
1,392 Views
Raghahanuma
Contributor I

Tried everything still not getting the output!

0 Kudos
1,385 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

No output from INT1 or I2C?

0 Kudos
1,372 Views
Raghahanuma
Contributor I

NVM! The problem was that I didn't route the interrupt back to port A 14 so it didn't throw up any output now its working fine. thanks for your contribution. 

0 Kudos
1,418 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

Hi Raghahanuma,

This fault is not caused by NVIC_EnableIRQ(PORTA_IRQn);,

This is because the clock gate for PORTA is not enabled, but you accessed PORTA->PCR[14].

Please enable the clock gate of PORTA.

Best Regards,
Robin
-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
1,395 Views
Raghahanuma
Contributor I

Thanks well that solved the fault but still not getting the output. will work on it and update

0 Kudos