Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: nRF51822_DataLogger_PowerImpulseCounter scpi_sx127x NAMote72_Utility scpi_sx127x_firstTest
Revision 2:4bc96749141e, committed 2015-09-01
- 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 | 
--- 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;
 }
--- 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;