mma8451q driver
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 |
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;