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

Files at this revision

API Documentation at this revision

Comitter:
clemente
Date:
Tue May 28 07:29:58 2013 +0000
Parent:
5:695063448f2a
Child:
7:ba0016258d5d
Commit message:
Added Orientation. To be completed and tested.

Changed in this revision

MMA8451Q.cpp Show annotated file Show diff for this revision Revisions of this file
MMA8451Q.h Show annotated file Show diff for this revision Revisions of this file
--- 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;
--- a/MMA8451Q.h	Tue May 28 04:39:42 2013 +0000
+++ b/MMA8451Q.h	Tue May 28 07:29:58 2013 +0000
@@ -46,6 +46,42 @@
 * }
 * @endcode
 */
+
+// Z-Lock Threshold Angles
+#define Z_LOCKOUT_14    0       // Angle to 14°
+#define Z_LOCKOUT_18    1       // Angle to 18°
+#define Z_LOCKOUT_21    2       // Angle to 21°
+#define Z_LOCKOUT_25    3       // Angle to 25°
+#define Z_LOCKOUT_29    4       // Angle to 29°
+#define Z_LOCKOUT_33    5       // Angle to 33°
+#define Z_LOCKOUT_37    6       // Angle to 37°
+#define Z_LOCKOUT_42    7       // Angle to 42°
+// Back/Front Orientation Definition
+#define Z_BKFR_80       0       // Back and Front trip angle
+#define Z_BKFR_75       1       // Back and Front trip angle
+#define Z_BKFR_70       2       // Back and Front trip angle
+#define Z_BKFR_65       3       // Back and Front trip angle
+// Threshold Angle Thresholds Lookup Table
+#define PL_THS_15       0x07    // Set Threshold to 15°
+#define PL_THS_20       0x09    // Set Threshold to 20°
+#define PL_THS_30       0x0C    // Set Threshold to 30°
+#define PL_THS_35       0x0D    // Set Threshold to 35°
+#define PL_THS_40       0x0F    // Set Threshold to 40°
+#define PL_THS_45       0x10    // Set Threshold to 45°
+#define PL_THS_55       0x13    // Set Threshold to 55°
+#define PL_THS_60       0x14    // Set Threshold to 60°
+#define PL_THS_70       0x17    // Set Threshold to 70°
+#define PL_THS_75       0x19    // Set Threshold to 75°
+// Trip Angles with Hysteresis for 45° Angle
+#define PL_HYS_0        0x00    // Set Hysteresis to ±0°    
+#define PL_HYS_4        0x01    // Set Hysteresis to ±4°    
+#define PL_HYS_7        0x02    // Set Hysteresis to ±7°
+#define PL_HYS_11       0x03    // Set Hysteresis to ±11°
+#define PL_HYS_14       0x04    // Set Hysteresis to ±14°
+#define PL_HYS_17       0x05    // Set Hysteresis to ±17°
+#define PL_HYS_21       0x06    // Set Hysteresis to ±21°
+#define PL_HYS_24       0x07    // Set Hysteresis to ±24°
+
 class MMA8451Q
 {
 public:
@@ -100,6 +136,8 @@
 
     void FreFallDetection( void(*fptr)(void));
     void MotionDetection( void(*fptr)(void));
+    void OrientationDetect( unsigned int Z_LockOut, unsigned int Z_BkFr, unsigned int PL_Thsld, unsigned int PL_Hyst);
+    void OrientationDetect( void);
     
 private:
     I2C m_i2c;