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:
8:7e6013f11b10
Parent:
7:ba0016258d5d
Child:
9:2aa9b1668d14
--- a/MMA8451Q.cpp	Tue May 28 10:33:50 2013 +0000
+++ b/MMA8451Q.cpp	Tue May 28 17:18:30 2013 +0000
@@ -20,6 +20,7 @@
 
 #define REG_WHO_AM_I      0x0D
 #define REG_CTRL_REG_1    0x2A
+#define REG_CTRL_REG_2    0x2B
 #define REG_CTRL_REG_4    0x2D
 #define REG_CTRL_REG_5    0x2E
 #define REG_INT_SRC       0x0C
@@ -41,31 +42,36 @@
 #define UINT14_MAX        16383
 
 /** 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);
+*
+* :: The FreeFall and Motion detection share the same IRQ2. 
+* 
+*   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);               // Pointers to user function called after
+void (*user1_fptr)(void);               // IRQ assertion.
 
 //
-InterruptIn MMA8451Q_Int1( PTA14);
-InterruptIn MMA8451Q_Int2( PTA15);
+InterruptIn MMA8451Q_Int1( PTA14);      // INT1
+InterruptIn MMA8451Q_Int2( PTA15);      // INT2
 
 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_Int1.fall( NULL);
+    MMA8451Q_Int2.fall( NULL);
+    user2_fptr = NULL;
+    user1_fptr = NULL;    
+
+    Reset();    
+    Active();    
 }
 
 MMA8451Q::~MMA8451Q() 
@@ -76,8 +82,19 @@
      user1_fptr = NULL;
 }
 
-void MMA8451Q::FreFallDetection( void(*fptr)(void))
+void MMA8451Q::Reset( void)
 {
+    // Soft reset
+    uint8_t data[2] = {REG_CTRL_REG_2, 0x40};
+    writeRegs(data, 2);
+    wait( 0.1);
+}
+
+void MMA8451Q::FreeFallDetection( void(*fptr)(void))
+{
+    // Soft Reset
+    Reset();
+    
     // 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
@@ -140,7 +157,9 @@
 
 void MMA8451Q::MotionDetection( void(*fptr)(void))
 {
-
+    // Soft Reset
+    Reset();
+    
     // 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
@@ -156,9 +175,9 @@
 
     // 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
+    // • 1g/0.063g = 15.8; //Round up to 16
     data[0] = REG_FF_MT_THS;
-    data[1] = 0x20;
+    data[1] = 0x10;
     writeRegs(data, 2);
     
     // Step 4: Set the debounce counter to eliminate false readings for 100 Hz sample rate with a requirement
@@ -211,6 +230,13 @@
 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;
+
+    // Soft Reset
+    Reset();
+        
+    // Reset orientation value.
+    OrientationState = 0;
+    OrientationStateUpdated = 0;
     
     // Step 1: Put the part into Standby Mode
     Standby();
@@ -320,11 +346,24 @@
     if ( (t & 0x10) == 0x10) {
         // Read the PL State from the Status Register, clear the interrupt
         readRegs( REG_PL_STATUS, &t, 1);
+        // Set the orientation state variable
+        OrientationState = t;
+        OrientationStateUpdated = 1;
         // Run the user supplied function
         user1_fptr();
     }
 }
 
+unsigned char MMA8451Q::GetOrientationState( void)
+{
+    if ( OrientationStateUpdated) {
+        OrientationStateUpdated = 0;
+        return OrientationState;
+    }
+    //
+    return 0;
+}
+
 void MMA8451Q::Active( void)
 {
     unsigned char t;