Added code to manage Orientation, FreeFall and Motion Detection. Data is also available via IRQ.
Dependents: Test_FRDM_MMA8451Q AccelTest FRDM-KL46-Template KL25Z_Demo ... more
Fork of MMA8451Q by
Diff: MMA8451Q.cpp
- Revision:
- 7:ba0016258d5d
- Parent:
- 6:c52175d13e0a
- Child:
- 8:7e6013f11b10
--- a/MMA8451Q.cpp Tue May 28 07:29:58 2013 +0000 +++ b/MMA8451Q.cpp Tue May 28 10:33:50 2013 +0000 @@ -31,6 +31,8 @@ #define REG_DBNCE 0x12 #define REG_BKFR 0x13 #define REG_P_L_THS 0x14 +#define REG_PL_STATUS 0x10 + // #define REG_OUT_X_MSB 0x01 #define REG_OUT_Y_MSB 0x03 @@ -38,8 +40,23 @@ #define UINT14_MAX 16383 -void (*fall_fptr)(void); -void (*motion_fptr)(void); +/** Interrupt schema + * + * :: The FreeFall and Motion detection share the same IRQ. + * + * FreeFall --+ +-- Fall_IRQ -----+ + * \ / \ + * +-- MMA8451Q_Int2.fall ---+ +--- user2_fptr + * / \ / + * Motion ----+ +-- Motion_IRQ ---+ + * + * :: The Orientation Detect use the IRQ1 + * + * Orientation Detect -- MMA8451Q_Int1.fall --- Orientation_IRQ --- user1_fptr + * + */ +void (*user2_fptr)(void); +void (*user1_fptr)(void); // InterruptIn MMA8451Q_Int1( PTA14); @@ -55,8 +72,8 @@ { MMA8451Q_Int1.fall( NULL); MMA8451Q_Int2.fall( NULL); - fall_fptr = NULL; - motion_fptr = NULL; + user2_fptr = NULL; + user1_fptr = NULL; } void MMA8451Q::FreFallDetection( void(*fptr)(void)) @@ -102,7 +119,7 @@ data[1] = 0x21; writeRegs(data, 2); - fall_fptr = fptr; + user2_fptr = fptr; MMA8451Q_Int2.fall( this, &MMA8451Q::Fall_IRQ); } @@ -117,7 +134,7 @@ // Read the Motion/Freefall Function to clear the interrupt readRegs( REG_FF_MT_SRC, &t, 1); // Run the user supplied function - fall_fptr(); + user2_fptr(); } } @@ -156,9 +173,9 @@ data[1] = 0x04; writeRegs(data, 2); - // Step 6: Route the Motion/Freefall Interrupt Function to INT1 hardware pin (CTRL_REG5) + // Step 6: Route the Motion/Freefall Interrupt Function to INT2 hardware pin (CTRL_REG5) data[0] = REG_CTRL_REG_5; - data[1] = 0x04; + data[1] = 0x00; writeRegs(data, 2); // Step 7: Put the device in Active Mode @@ -166,8 +183,8 @@ data[1] = 0x19; writeRegs(data, 2); - motion_fptr = fptr; - MMA8451Q_Int1.fall( this, &MMA8451Q::Motion_IRQ); + user2_fptr = fptr; + MMA8451Q_Int2.fall( this, &MMA8451Q::Motion_IRQ); } @@ -182,16 +199,16 @@ // Read the Motion/Freefall Function to clear the interrupt readRegs( REG_FF_MT_SRC, &t, 1); // Run the user supplied function - motion_fptr(); + user2_fptr(); } } -void MMA8451Q::OrientationDetect( void) +void MMA8451Q::OrientationDetect( void(*fptr)(void)) { - OrientationDetect( Z_LOCKOUT_14, Z_BKFR_80, PL_THS_15, PL_HYS_0); + OrientationDetect( fptr, Z_LOCKOUT_14, Z_BKFR_80, PL_THS_15, PL_HYS_0); } -void MMA8451Q::OrientationDetect( unsigned int Z_LockOut, unsigned int Z_BkFr, unsigned int PL_Thsld, unsigned int PL_Hyst) +void MMA8451Q::OrientationDetect( void(*fptr)(void), unsigned int Z_LockOut, unsigned int Z_BkFr, unsigned int PL_Thsld, unsigned int PL_Hyst) { unsigned char t; @@ -274,7 +291,6 @@ readRegs( REG_CTRL_REG_5, &t, 1); data[0] = REG_CTRL_REG_5; data[1] = t | 0x10; // Set bit 4 to choose the interrupt to route to INT1 - data[1] = t & 0xEF; // Clear bit 4 to choose the interrupt to route to INT2 writeRegs(data, 2); // Step 10: Set the debounce counter in register 0x12 @@ -288,7 +304,25 @@ // Step 11: Put the device in Active Mode Active(); + + user1_fptr = fptr; + MMA8451Q_Int1.fall( this, &MMA8451Q::Orientation_IRQ); + +} + +void MMA8451Q::Orientation_IRQ( void) +{ + unsigned char t; + // Determine source of the interrupt by first reading the system interrupt + readRegs( REG_INT_SRC, &t, 1); + // + if ( (t & 0x10) == 0x10) { + // Read the PL State from the Status Register, clear the interrupt + readRegs( REG_PL_STATUS, &t, 1); + // Run the user supplied function + user1_fptr(); + } } void MMA8451Q::Active( void)