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 Emilio Monti

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)