mma8451q driver

Dependents:   nRF51822_DataLogger_PowerImpulseCounter scpi_sx127x NAMote72_Utility scpi_sx127x_firstTest

Files at this revision

API Documentation at this revision

Comitter:
dudmuck
Date:
Tue Sep 01 00:27:13 2015 +0000
Parent:
1:778b685c3ad0
Commit message:
added orientation detection mode

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
diff -r 778b685c3ad0 -r 4bc96749141e mma8451q.cpp
--- a/mma8451q.cpp	Fri May 08 01:31:18 2015 +0000
+++ b/mma8451q.cpp	Tue Sep 01 00:27:13 2015 +0000
@@ -94,6 +94,71 @@
         return false;
 }
 
+void MMA8451Q::orient_detect()
+{
+    uint8_t v;
+    
+    ctrl_reg1.octet = read_single(MMA8451_CTRL_REG1);
+    /* AN4068 Sensors Freescale Semiconductor, Inc.    
+     * 4.1 Example Steps for Implementing the Embedded Orientation Detection */
+     
+     /* Step 1: Put the part into Standby Mode */
+    ctrl_reg1.bits.ACTIVE = 0;
+    write(MMA8451_CTRL_REG1, ctrl_reg1.octet);     
+     
+    /* Step 2: Set the data rate to 50 Hz (for example, but can choose any sample rate). */
+    ctrl_reg1.bits.DR = 4;
+    write(MMA8451_CTRL_REG1, ctrl_reg1.octet);
+    
+    /* Step 3: Set the PL_EN bit in Register 0x11 PL_CFG. This will enable the orientation detection. */
+    v = read_single(MMA8451_PL_CFG);
+    v |= 0x40;
+    write(MMA8451_PL_CFG, v);
+    
+    /* Step 4: Set the Back/Front Angle trip points in register 0x13 following the table in the data sheet. */
+    v = read_single(MMA8451_PL_BF_ZCOMP);
+    /*v &= 0x3f;
+    v |= 0xX0;
+    write(MMA8451_PL_BF_ZCOMP, v);*/
+    
+    /* Step 5: Set the Z-Lockout angle trip point in register 0x13 following the table in the data sheet. */
+    /* v &= 0xf8;
+    v |= 0x0X;
+    */
+    
+    /* Step 6: Set the Trip Threshold Angle */
+    v = read_single(MMA8451_PL_THS_REG);
+    /*v &= 0x07;
+    v |= 0x0X << 3;
+    write(MMA8451_PL_THS_REG. v);*/
+    
+    /* Step 7: Set the Hysteresis Angle */
+    v = read_single(MMA8451_PL_THS_REG);
+    /*v &= 0xf8;
+    v |= 0x0X;
+    write(MMA8451_PL_THS_REG. v);*/    
+    
+    /* Step 8: Register 0x2D, Control Register 4 configures all embedded features for interrupt */
+    ctrl_reg4.octet = 0;
+    ctrl_reg4.bits.INT_EN_LNDPRT = 1;
+    write(MMA8451_CTRL_REG4, ctrl_reg4.octet);
+    
+    /* Step 9: Register 0x2E is Control Register 5 which gives the option of routing the interrupt to either INT1 or INT2 */
+    ctrl_reg5.octet = 0;
+    ctrl_reg5.bits.INT_CFG_LNDPRT = 1;
+    write(MMA8451_CTRL_REG5, ctrl_reg5.octet);
+        
+    /* Step 10: Set the debounce counter in register 0x12 */
+    write(MMA8451_PL_COUNT, 5); // 5: debounce to 100ms at 50hz
+    
+    /* Step 11: Put the device in Active Mode */
+    ctrl_reg1.octet = read_single(MMA8451_CTRL_REG1);
+    ctrl_reg1.bits.ACTIVE = 1;
+    write(MMA8451_CTRL_REG1, ctrl_reg1.octet);
+        
+    /* Step 12: in service() function */
+}
+
 
 void MMA8451Q::transient_detect()
 {
@@ -144,11 +209,11 @@
      * System Interrupt Status and the Transient Status */
 }
 
-void MMA8451Q::service()
+uint8_t MMA8451Q::service()
 {
     mma_int_source_t int_src;
     if (m_int_pin)
-        return; // no interrupt
+        return 0; // no interrupt
         
     int_src.octet = read_single(MMA8451_INT_SOURCE);
     
@@ -162,23 +227,51 @@
         read_single(MMA8451_PULSE_SRC);
     }
     if (int_src.bits.SRC_LNDPRT) {
-        read_single(MMA8451_PL_STATUS);
-    }                        
+        mma_pl_status_t pl_status;
+        /*AN4068 Step 12: Write a Service Routine to Service the Interrupt */
+        pl_status.octet = read_single(MMA8451_PL_STATUS);
+        if (verbose) {
+            printf("PL_STATUS: ");
+            if (pl_status.bits.NEWLP) {
+                if (pl_status.bits.LO)
+                    printf("Z-tilt-LO ");
+                    
+                if (pl_status.bits.LAPO == 0)
+                    printf("up ");
+                else if (pl_status.bits.LAPO == 1)
+                    printf("down ");
+                else if (pl_status.bits.LAPO == 2)
+                    printf("left ");
+                else if (pl_status.bits.LAPO == 3)
+                    printf("right ");
+                
+                if (pl_status.bits.BAFRO)
+                    printf("back ");
+                else
+                    printf("front ");
+            }
+            printf("\r\n");
+        }
+    } // ...int_src.bits.SRC_LNDPRT
+                         
     if (int_src.bits.SRC_TRANS) {
         transient_src_t t_src;
         t_src.octet = read_single(MMA8451_TRANSIENT_SRC);
-        printf("transient src:%x ", t_src.octet);
-        if (t_src.bits.XTRANSE)
-            printf("X_Pol:%d ", t_src.bits.X_Trans_Pol);
-        if (t_src.bits.YTRANSE)
-            printf("Y_Pol:%d ", t_src.bits.Y_Trans_Pol);
-        if (t_src.bits.ZTRANSE)
-            printf("Z_Pol:%d ", t_src.bits.Z_Trans_Pol);
-        printf("\n");        
-    }
+        if (verbose) {
+            printf("transient src:%x ", t_src.octet);
+            if (t_src.bits.XTRANSE)
+                printf("X_Pol:%d ", t_src.bits.X_Trans_Pol);
+            if (t_src.bits.YTRANSE)
+                printf("Y_Pol:%d ", t_src.bits.Y_Trans_Pol);
+            if (t_src.bits.ZTRANSE)
+                printf("Z_Pol:%d ", t_src.bits.Z_Trans_Pol);
+            printf("\r\n");        
+        }
+    } // ...int_src.bits.SRC_TRANS
     
     if (int_src.bits.SRC_ASLP) {
         read_single(MMA8451_SYSMOD);
     }
     
+    return int_src.octet;
 }
diff -r 778b685c3ad0 -r 4bc96749141e mma8451q.h
--- a/mma8451q.h	Fri May 08 01:31:18 2015 +0000
+++ b/mma8451q.h	Tue Sep 01 00:27:13 2015 +0000
@@ -11,6 +11,10 @@
 #define MMA8451_INT_SOURCE                 0x0c // 
 #define MMA8451_ID                         0x0d
 #define MMA8451_PL_STATUS                  0x10
+#define MMA8451_PL_CFG                     0x11
+#define MMA8451_PL_COUNT                   0x12 // orientation debounce
+#define MMA8451_PL_BF_ZCOMP                0x13
+#define MMA8451_PL_THS_REG                 0x14
 #define MMA8451_FF_MT_SRC                  0x16
 #define MMA8451_TRANSIENT_CFG              0x1d // transient enable
 #define MMA8451_TRANSIENT_SRC              0x1e // transient read/clear interrupt
@@ -46,6 +50,17 @@
     uint8_t octet;
 } mma_int_source_t;
 
+typedef union { 
+    struct {    // at 0x10
+        uint8_t BAFRO  : 1;    // 0     0=front, 1=back
+        uint8_t LAPO   : 2;    // 1,2   up, down, right, left
+        uint8_t res    : 3;    // 3,4,5
+        uint8_t LO     : 1;    // 6    Z-tilt lockout
+        uint8_t NEWLP  : 1;    // 7    1 = BAFRO or LO has changed
+    } bits;
+    uint8_t octet;
+} mma_pl_status_t;
+
 typedef union {
     struct {    // at 0x1d
         uint8_t HPF_BYP : 1;    // 0
@@ -123,8 +138,10 @@
         void read(uint8_t addr, uint8_t *dst_buf, int length);
         void write(uint8_t addr, uint8_t data);
         void transient_detect(void);
-        void service(void);
+        void orient_detect(void);
+        uint8_t service(void); // returns 0 if no interrupt occurred
 
+        bool verbose;   // print interrupt event
         mma_out_t out;
         transient_cfg_t transient_cfg;
         ctrl_reg1_t ctrl_reg1;