a
Fork of FRDM_MMA8451Q by
Diff: MMA8451Q.cpp
- Revision:
- 5:695063448f2a
- Parent:
- 3:db7126dbd63f
- Child:
- 6:c52175d13e0a
diff -r c4d879a39775 -r 695063448f2a MMA8451Q.cpp --- a/MMA8451Q.cpp Fri Oct 12 11:35:07 2012 +0000 +++ b/MMA8451Q.cpp Tue May 28 04:39:42 2013 +0000 @@ -20,19 +20,187 @@ #define REG_WHO_AM_I 0x0D #define REG_CTRL_REG_1 0x2A +#define REG_CTRL_REG_4 0x2D +#define REG_CTRL_REG_5 0x2E +#define REG_INT_SRC 0x0C +#define REG_FF_MT_CFG 0x15 +#define REG_FF_MT_SRC 0x16 +#define REG_FF_MT_THS 0x17 +#define REG_FF_MT_CNT 0x18 +// #define REG_OUT_X_MSB 0x01 #define REG_OUT_Y_MSB 0x03 #define REG_OUT_Z_MSB 0x05 #define UINT14_MAX 16383 +void (*fall_fptr)(void); +void (*motion_fptr)(void); + +// +InterruptIn MMA8451Q_Int1( PTA14); +InterruptIn MMA8451Q_Int2( PTA15); + MMA8451Q::MMA8451Q(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr) { // activate the peripheral uint8_t data[2] = {REG_CTRL_REG_1, 0x01}; writeRegs(data, 2); } -MMA8451Q::~MMA8451Q() { } +MMA8451Q::~MMA8451Q() +{ + MMA8451Q_Int1.fall( NULL); + MMA8451Q_Int2.fall( NULL); + fall_fptr = NULL; + motion_fptr = NULL; +} + +void MMA8451Q::FreFallDetection( void(*fptr)(void)) +{ + // Example Steps for Configuring Linear Freefall Detection + // X AND Y AND Z < 0.2g using MFF Function, 50 Hz ODR + // Step 1: Put the device in Standby Mode: Register 0x2A CTRL_REG1 + unsigned char data[2] = {REG_CTRL_REG_1, 0x20}; + writeRegs(data, 2); + + // Step 2: Configuration Register set for Freefall Detection enabling “AND” condition, OAE = 0, Enabling X, + // Y, Z and the Latch + data[0] = REG_FF_MT_CFG; + data[1] = 0x01; + writeRegs(data, 2); + + // Step 3: Threshold Setting Value for the resulting acceleration < 0.2g + // Note: The step count is 0.063g/count + // • 0.2g/0.063g = 3.17 counts //Round to 3 counts + data[0] = REG_FF_MT_THS; + data[1] = 0x03; + writeRegs(data, 2); + + // Step 4: Set the debounce counter to eliminate false positive readings for 50Hz sample rate with a + // requirement of 120 ms timer, assuming Normal Mode. + // Note: 120 ms/20 ms (steps) = 6 counts + data[0] = REG_FF_MT_CNT; + data[1] = 0x06; + writeRegs(data, 2); + + // Step 5: Enable Motion/Freefall Interrupt Function in the System (CTRL_REG4) + data[0] = REG_CTRL_REG_4; + data[1] = 0x04; + writeRegs(data, 2); + + // Step 6: Route the Motion/Freefall Interrupt Function to INT2 hardware pin (CTRL_REG5) + data[0] = REG_CTRL_REG_5; + data[1] = 0x00; + writeRegs(data, 2); + + // Step 7: Put the device in Active Mode, 50 Hz + data[0] = REG_CTRL_REG_1; + data[1] = 0x21; + writeRegs(data, 2); + + fall_fptr = fptr; + MMA8451Q_Int2.fall( this, &MMA8451Q::Fall_IRQ); +} + +void MMA8451Q::Fall_IRQ( void) +{ + unsigned char t; + + // Determine source of the interrupt by first reading the system interrupt + readRegs( REG_INT_SRC, &t, 1); + // + if ( (t & 0x04) == 0x04) { + // Read the Motion/Freefall Function to clear the interrupt + readRegs( REG_FF_MT_SRC, &t, 1); + // Run the user supplied function + fall_fptr(); + } +} + +void MMA8451Q::MotionDetection( void(*fptr)(void)) +{ + + // 6.1 Example Steps for Configuring Motion Detection + // X or Y > 3g using MFF Function 4g, 100 Hz ODR, Normal Mode + // Step 1: Put the device into Standby Mode: Register 0x2A CTRL_REG1 + unsigned char data[2] = {REG_CTRL_REG_1, 0x18}; // Set the device in 100 Hz ODR, Standby + writeRegs(data, 2); + + + // Step 2: Set Configuration Register for Motion Detection by setting the “OR” condition OAE = 1, enabling + // X, Y, and the latch + data[0] = REG_FF_MT_CFG; + data[1] = 0xD8; + writeRegs(data, 2); + + // Step 3: Threshold Setting Value for the Motion detection of > 2g + // Note: The step count is 0.063g/ count + // • 2g/0.063g = 31.7; //Round up to 32 + data[0] = REG_FF_MT_THS; + data[1] = 0x20; + writeRegs(data, 2); + + // Step 4: Set the debounce counter to eliminate false readings for 100 Hz sample rate with a requirement + // of 100 ms timer. + // Note: 100 ms/10 ms (steps) = 10 counts + data[0] = REG_FF_MT_CNT; + data[1] = 0x0A; + writeRegs(data, 2); + + // Step 5: Enable Motion/Freefall Interrupt Function in the System (CTRL_REG4) + data[0] = REG_CTRL_REG_4; + data[1] = 0x04; + writeRegs(data, 2); + + // Step 6: Route the Motion/Freefall Interrupt Function to INT1 hardware pin (CTRL_REG5) + data[0] = REG_CTRL_REG_5; + data[1] = 0x04; + writeRegs(data, 2); + + // Step 7: Put the device in Active Mode + data[0] = REG_CTRL_REG_1; + data[1] = 0x19; + writeRegs(data, 2); + + motion_fptr = fptr; + MMA8451Q_Int1.fall( this, &MMA8451Q::Motion_IRQ); + +} + +void MMA8451Q::Motion_IRQ( void) +{ + unsigned char t; + + // Determine source of the interrupt by first reading the system interrupt + readRegs( REG_INT_SRC, &t, 1); + // + if ( (t & 0x04) == 0x04) { + // Read the Motion/Freefall Function to clear the interrupt + readRegs( REG_FF_MT_SRC, &t, 1); + // Run the user supplied function + motion_fptr(); + } +} + +void MMA8451Q::Active( void) +{ + unsigned char t; + + // Activate the peripheral + readRegs(REG_CTRL_REG_1, &t, 1); + unsigned char data[2] = {REG_CTRL_REG_1, t|0x01}; + writeRegs(data, 2); +} + +void MMA8451Q::Standby( void) +{ + unsigned char t; + + // Standby + readRegs(REG_CTRL_REG_1, &t, 1); + unsigned char data[2] = {REG_CTRL_REG_1, t&0xFE}; + writeRegs(data, 2); +} uint8_t MMA8451Q::getWhoAmI() { uint8_t who_am_i = 0;