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:
6:c52175d13e0a
Parent:
5:695063448f2a
Child:
7:ba0016258d5d
--- a/MMA8451Q.cpp	Tue May 28 04:39:42 2013 +0000
+++ b/MMA8451Q.cpp	Tue May 28 07:29:58 2013 +0000
@@ -27,6 +27,10 @@
 #define REG_FF_MT_SRC     0x16
 #define REG_FF_MT_THS     0x17
 #define REG_FF_MT_CNT     0x18
+#define REG_DBCNTM        0x11
+#define REG_DBNCE         0x12
+#define REG_BKFR          0x13
+#define REG_P_L_THS       0x14
 //
 #define REG_OUT_X_MSB     0x01
 #define REG_OUT_Y_MSB     0x03
@@ -182,6 +186,111 @@
     }
 }
 
+void MMA8451Q::OrientationDetect( void)
+{
+    OrientationDetect( 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)
+{
+    unsigned char t;
+    
+    // Step 1: Put the part into Standby Mode
+    Standby();
+    
+    // Step 2: Set the data rate to 50 Hz (for example, but can choose any sample rate).
+    readRegs( REG_CTRL_REG_1, &t, 1);       // Note: Can combine this step with above
+    t &= 0xC7;                             // Clear the sample rate bits
+    t |= 0x20;                             // Set the sample rate bits to 50 Hz
+    unsigned char data[2] = {REG_CTRL_REG_1, t};
+    writeRegs(data, 2);                     // Write updated value into the register.   
+    
+    
+    // Step 3: Set the PL_EN bit in Register 0x11 PL_CFG. This will enable the orientation detection.
+    readRegs( REG_DBCNTM, &t, 1);
+    data[0] = REG_DBCNTM;
+    data[1] = t | 0x40;
+    writeRegs(data, 2);
+    
+    // Step 4: Set the Back/Front Angle trip points in register 0x13 following the table in the data sheet.
+    // NOTE: This register is readable in all versions of MMA845xQ but it is only modifiable in the
+    // MMA8451Q.
+    readRegs( REG_BKFR, &t, 1);
+    t &= 0x3F;                      // Clear bit 7 and 6    
+    data[0] = REG_BKFR;
+    data[1] = t | Z_BkFr;
+    writeRegs(data, 2);             // Write in the updated Back/Front Angle
+
+    // Step 5: Set the Z-Lockout angle trip point in register 0x13 following the table in the data sheet.
+    // NOTE: This register is readable in all versions of MMA845xQ but it is only modifiable in the
+    // MMA8451Q.
+    readRegs( REG_BKFR, &t, 1);
+    t &= 0xF8;                      // Clear the last three bits of the register
+    data[0] = REG_BKFR;
+    data[1] = t | Z_LockOut;
+    writeRegs(data, 2);             // Write in the updated Z-lockout angle
+    
+    // Step 6: Set the Trip Threshold Angle
+    // NOTE: This register is readable in all versions of MMA845xQ but it is only modifiable in the
+    // MMA8451Q.
+    // Select the angle desired in the table, and,
+    // Enter in the values given in the table for the corresponding angle.
+    // Refer to Figure 7 for the reference frame of the trip angles.
+    readRegs( REG_P_L_THS, &t, 1);
+    t &= 0x07;                      // Clear the Threshold values
+    data[0] = REG_P_L_THS;
+    data[1] = t | (PL_Thsld<<3);
+    writeRegs(data, 2);             
+    
+    // Step 7: Set the Hysteresis Angle
+    // NOTE: This register is readable in all versions of MMA845xQ but it is only modifiable in the
+    // MMA8451Q.
+    // Select the hysteresis value based on the desired final trip points (threshold + hysteresis)
+    // Enter in the values given in the table for that corresponding angle.
+    // Note: Care must be taken. Review the final resulting angles. Make sure there isn’t a resulting trip value
+    // greater than 90 or less than 0.
+    // The following are the options for setting the hysteresis.
+    readRegs( REG_P_L_THS, &t, 1);
+    t &= 0xF8;                      // Clear the Hysteresis values
+    data[0] = REG_P_L_THS;
+    data[1] = t | PL_Hyst;
+    writeRegs(data, 2);             
+    
+    // Step 8: Register 0x2D, Control Register 4 configures all embedded features for interrupt
+    // detection.
+    // To set this device up to run an interrupt service routine:
+    // Program the Orientation Detection bit in Control Register 4.
+    // Set bit 4 to enable the orientation detection “INT_EN_LNDPRT”.
+    readRegs( REG_CTRL_REG_4, &t, 1);
+    data[0] = REG_CTRL_REG_4;
+    data[1] = t | 0x10;                 // Set bit 4
+    writeRegs(data, 2);             
+    
+    // Step 9: Register 0x2E is Control Register 5 which gives the option of routing the interrupt to
+    // either INT1 or INT2
+    // Depending on which interrupt pin is enabled and configured to the processor:
+    // Set bit 4 “INT_CFG_LNDPRT” to configure INT1, or,
+    // Leave the bit clear to configure INT2.
+    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
+    // This value will scale depending on the application-specific required ODR.
+    // If the device is set to go to sleep, reset the debounce counter before the device goes to sleep. This setting
+    // helps avoid long delays since the debounce will always scale with the current sample rate. The debounce
+    // can be set between 50 ms - 100 ms to avoid long delays.
+    data[0] = REG_DBNCE;
+    data[1] = 0x05;                     // This sets the debounce counter to 100 ms at 50 Hz
+    writeRegs(data, 2);             
+    
+    // Step 11: Put the device in Active Mode
+    Active();
+    
+}
+
 void MMA8451Q::Active( void)
 {
     unsigned char t;