copy for backup

Fork of MMA8451Q by Antonio Quevedo

Revision:
1:204a460446d7
Parent:
0:7c9ab58f6af3
--- a/MMA8451Q.cpp	Wed Jun 04 19:16:47 2014 +0000
+++ b/MMA8451Q.cpp	Wed Oct 19 10:26:07 2016 +0000
@@ -1,5 +1,4 @@
 /* Copyright (c) 2010-2011 mbed.org, MIT License
-* Copyright (c) 2014 Antonio Quevedo, UNICAMP
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
 * and associated documentation files (the "Software"), to deal in the Software without
@@ -19,57 +18,138 @@
 
 #include "MMA8451Q.h"
 
-#define ACCEL_I2C_ADDRESS 0x1D<<1
-#define REG_STATUS        0x00
-#define REG_XYZ_DATA_CFG  0x0E
+#define INT_SOURCE        0x0C 
 #define REG_WHO_AM_I      0x0D
-#define REG_CTRL_REG1     0x2A
-#define REG_CTRL_REG2     0x2B
-#define REG_CTRL_REG3     0x2C
-#define REG_CTRL_REG4     0x2D
-#define REG_CTRL_REG5     0x2E
+#define HP_FILTER_CUTOFF  0x0F 
+#define PULSE_CFG         0x21 
+#define PULSE_SRC         0x22 
+#define PULSE_THSX        0x23 
+#define PULSE_THSY        0x24 
+#define PULSE_THSZ        0x25 
+#define PULSE_TMLT        0x26 
+#define PULSE_LTCY        0x27 
+#define PULSE_WIND        0x28 
+#define REG_CTRL_REG_1    0x2A 
+#define CTRL_REG2         0x2B
+#define CTRL_REG4         0x2D 
+#define CTRL_REG5         0x2E 
 #define REG_OUT_X_MSB     0x01
 #define REG_OUT_Y_MSB     0x03
 #define REG_OUT_Z_MSB     0x05
 
-MMA8451Q::MMA8451Q(PinName sda, PinName scl) : m_i2c(sda, scl) {
-    uint8_t data[2] = {REG_CTRL_REG1, 0x00}; // Puts acc in standby for configuring
-    writeRegs(data, 2);
-    data[0] = REG_XYZ_DATA_CFG; // Writing 00 turns off high-pass filter and sets full scale range to 2g
-    // data[1] = 0x01; for 4g
-    // data[1] = 0x02; for 8g
-    writeRegs(data, 2);
-    data[0] = REG_CTRL_REG2;
-    data[1] = 0x00; // Disable self-test, software reset and auto-sleep; operates in normal mode
-    writeRegs(data, 2);
-    data[0] = REG_CTRL_REG3; // Interrupt polarity low, push-pull output
-    writeRegs(data, 2);
-    data[0] = REG_CTRL_REG4;
-    data[1] = 0x01; // Enables interrupt for data Ready
-    writeRegs(data, 2);
-    data[0] = REG_CTRL_REG5;
-    writeRegs(data, 2); // Routes Data Ready interrupt to INT1
-    data[0] = REG_CTRL_REG1; 
-    data[1] = 0x09; // Data rate is 800Hz
+#define UINT14_MAX        16383
+
+MMA8451Q::MMA8451Q(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr) {
+    // activate the peripheral
+    uint8_t data[2] = {REG_CTRL_REG_1, 0x01};
     writeRegs(data, 2);
 }
 
 MMA8451Q::~MMA8451Q() { }
 
-void MMA8451Q::getAccAllAxis(int16_t * res) {
-    uint8_t temp[6];
-    readRegs(REG_OUT_X_MSB, temp, 6);
-    res[0] = (temp[0] * 256) + temp[1];
-    res[1] = (temp[2] * 256) + temp[3];
-    res[2] = (temp[4] * 256) + temp[5];
+uint8_t MMA8451Q::getWhoAmI() {
+    uint8_t who_am_i = 0;
+    readRegs(REG_WHO_AM_I, &who_am_i, 1);
+    return who_am_i;
+}
+
+float MMA8451Q::getAccX() {
+//divide by 4096 b/c MMA output is 4096 counts per g so this f outputs accelorometer value formatted to g (gravity)
+    return (float(getAccAxis(REG_OUT_X_MSB))/4096.0);
+}
+
+float MMA8451Q::getAccY() {
+    return (float(getAccAxis(REG_OUT_Y_MSB))/4096.0);
+}
+
+float MMA8451Q::getAccZ() {
+    return (float(getAccAxis(REG_OUT_Z_MSB))/4096.0);
+}
+
+void MMA8451Q::getAccAllAxis(float * res) {
+    res[0] = getAccX();
+    res[1] = getAccY();
+    res[2] = getAccZ();
+}
+
+int16_t MMA8451Q::getAccAxis(uint8_t addr) {
+    int16_t acc;
+    uint8_t res[2];
+    readRegs(addr, res, 2);
+
+    acc = (res[0] << 6) | (res[1] >> 2);
+    if (acc > UINT14_MAX/2)
+        acc -= UINT14_MAX;
+
+    return acc;
 }
 
+void MMA8451Q::setDoubleTap(void){
+//Implemented directly from Freescale's AN4072 
+//Added to MMA8451Q lib
+
+    uint8_t CTRL_REG1_Data;
+//    int adds;
+   uint8_t data[2] = {REG_CTRL_REG_1, 0x08};
+    
+    //400 Hz, Standby Mode
+    writeRegs(data,2);
+    
+    //Enable X, Y and Z Double Pulse with DPA = 0 no double pulse abort    
+    data[0]=PULSE_CFG;data[1]=0x2A;
+    writeRegs(data,2);
+    
+    //SetThreshold 3g on X and Y and 5g on Z
+    //Note: Every step is 0.063g
+    //3 g/0.063g = 48 counts
+    //5g/0.063g = 79 counts
+    data[0]=PULSE_THSX;data[1]=0x30;
+    writeRegs(data,2);//Set X Threshold to 3g 
+    data[0]=PULSE_THSY;data[1]=0x30;
+    writeRegs(data,2);//Set Y Threshold to 3g 
+    data[0]=PULSE_THSZ;data[1]=0x4F;
+    writeRegs(data,2);//Set Z Threshold to 5g
+
+    //Set Time Limit for Tap Detection to 60 ms LP Mode
+    //Note: 400 Hz ODR, Time step is 1.25 ms per step
+    //60 ms/1.25 ms = 48 counts 
+    data[0]=PULSE_TMLT;data[1]=0x30;
+    writeRegs(data,2);//60 ms
+    
+    //Set Latency Time to 200 ms
+    //Note: 400 Hz ODR LPMode, Time step is 2.5 ms per step 00 ms/2.5 ms = 80 counts
+    data[0]=PULSE_LTCY;data[1]=0x50;
+    writeRegs(data,2);//200 ms
+    
+    //Set Time Window for second tap to 300 ms
+    //Note: 400 Hz ODR LP Mode, Time step is 2.5 ms per step
+    //300 ms/2.5 ms = 120 counts
+    data[0]=PULSE_WIND;data[1]=0x78;
+    writeRegs(data,2);//300 ms
+    
+    //Route INT1 to System Interrupt
+    data[0]=CTRL_REG4;data[1]=0x08;
+    writeRegs(data,2);//Enable Pulse Interrupt in System CTRL_REG4
+    data[0]=CTRL_REG5;data[1]=0x08; 
+    writeRegs(data,2);//Route Pulse Interrupt to INT1 hardware Pin CTRL_REG5
+
+    //Set the device to Active Mode
+    readRegs(0x2A,&CTRL_REG1_Data,1);//Read out the contents of the register 
+    CTRL_REG1_Data |= 0x01; //Change the value in the register to Active Mode.
+    data[0]=REG_CTRL_REG_1; 
+    data[1]=CTRL_REG1_Data;
+    writeRegs(data,2);//Write in the updated value to put the device in Active Mode
+}
+
+
 void MMA8451Q::readRegs(int addr, uint8_t * data, int len) {
     char t[1] = {addr};
-    m_i2c.write(ACCEL_I2C_ADDRESS, t, 1, true);
-    m_i2c.read(ACCEL_I2C_ADDRESS, (char *)data, len);
+    m_i2c.write(m_addr, t, 1, true);
+    m_i2c.read(m_addr, (char *)data, len);
 }
 
+
+
 void MMA8451Q::writeRegs(uint8_t * data, int len) {
-    m_i2c.write(ACCEL_I2C_ADDRESS, (char *)data, len);
-}
\ No newline at end of file
+    m_i2c.write(m_addr, (char *)data, len);
+}