a

Fork of FRDM_MMA8451Q by clemente di caprio

Committer:
rendek4
Date:
Sat Dec 17 21:22:50 2016 +0000
Revision:
12:37acb52ade50
Parent:
11:13e2af71e2cf
akcelerometer

Who changed what in which revision?

UserRevisionLine numberNew contents of line
emilmont 0:6149091f755d 1 #include "MMA8451Q.h"
emilmont 0:6149091f755d 2
clemente 10:fa532bf396fb 3 #define REG_STATUS 0x00
samux 1:d2630136d51e 4 #define REG_WHO_AM_I 0x0D
samux 1:d2630136d51e 5 #define REG_CTRL_REG_1 0x2A
clemente 8:7e6013f11b10 6 #define REG_CTRL_REG_2 0x2B
clemente 5:695063448f2a 7 #define REG_CTRL_REG_4 0x2D
clemente 5:695063448f2a 8 #define REG_CTRL_REG_5 0x2E
clemente 5:695063448f2a 9 #define REG_INT_SRC 0x0C
clemente 5:695063448f2a 10 #define REG_FF_MT_CFG 0x15
clemente 5:695063448f2a 11 #define REG_FF_MT_SRC 0x16
clemente 5:695063448f2a 12 #define REG_FF_MT_THS 0x17
clemente 5:695063448f2a 13 #define REG_FF_MT_CNT 0x18
clemente 6:c52175d13e0a 14 #define REG_DBCNTM 0x11
clemente 6:c52175d13e0a 15 #define REG_DBNCE 0x12
clemente 6:c52175d13e0a 16 #define REG_BKFR 0x13
clemente 6:c52175d13e0a 17 #define REG_P_L_THS 0x14
clemente 7:ba0016258d5d 18 #define REG_PL_STATUS 0x10
clemente 7:ba0016258d5d 19
emilmont 0:6149091f755d 20 #define REG_OUT_X_MSB 0x01
emilmont 0:6149091f755d 21 #define REG_OUT_Y_MSB 0x03
emilmont 0:6149091f755d 22 #define REG_OUT_Z_MSB 0x05
emilmont 0:6149091f755d 23
samux 1:d2630136d51e 24 #define UINT14_MAX 16383
emilmont 0:6149091f755d 25
clemente 10:fa532bf396fb 26 #define ZYXDR 0x08
clemente 10:fa532bf396fb 27 #define ZDR 0x04
clemente 10:fa532bf396fb 28 #define YDR 0x02
clemente 10:fa532bf396fb 29 #define XDR 0x01
clemente 10:fa532bf396fb 30
clemente 11:13e2af71e2cf 31 void (*MMA8451Q_usr2_fptr)(void); // Pointers to user function called after
clemente 11:13e2af71e2cf 32 void (*MMA8451Q_usr1_fptr)(void); // IRQ assertion.
clemente 5:695063448f2a 33
clemente 5:695063448f2a 34 //
clemente 8:7e6013f11b10 35 InterruptIn MMA8451Q_Int1( PTA14); // INT1
clemente 8:7e6013f11b10 36 InterruptIn MMA8451Q_Int2( PTA15); // INT2
clemente 5:695063448f2a 37
emilmont 0:6149091f755d 38 MMA8451Q::MMA8451Q(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr) {
clemente 8:7e6013f11b10 39
clemente 8:7e6013f11b10 40 MMA8451Q_Int1.fall( NULL);
clemente 8:7e6013f11b10 41 MMA8451Q_Int2.fall( NULL);
clemente 11:13e2af71e2cf 42 MMA8451Q_usr2_fptr = NULL;
clemente 11:13e2af71e2cf 43 MMA8451Q_usr1_fptr = NULL;
clemente 8:7e6013f11b10 44
clemente 8:7e6013f11b10 45 Reset();
clemente 8:7e6013f11b10 46 Active();
emilmont 0:6149091f755d 47 }
emilmont 0:6149091f755d 48
clemente 5:695063448f2a 49 MMA8451Q::~MMA8451Q()
clemente 5:695063448f2a 50 {
clemente 5:695063448f2a 51 MMA8451Q_Int1.fall( NULL);
clemente 5:695063448f2a 52 MMA8451Q_Int2.fall( NULL);
clemente 11:13e2af71e2cf 53 MMA8451Q_usr2_fptr = NULL;
clemente 11:13e2af71e2cf 54 MMA8451Q_usr1_fptr = NULL;
clemente 5:695063448f2a 55 }
clemente 5:695063448f2a 56
clemente 8:7e6013f11b10 57 void MMA8451Q::Reset( void)
clemente 5:695063448f2a 58 {
clemente 8:7e6013f11b10 59 // Soft reset
clemente 8:7e6013f11b10 60 uint8_t data[2] = {REG_CTRL_REG_2, 0x40};
clemente 8:7e6013f11b10 61 writeRegs(data, 2);
clemente 8:7e6013f11b10 62 wait( 0.1);
clemente 8:7e6013f11b10 63 }
clemente 8:7e6013f11b10 64
clemente 5:695063448f2a 65
clemente 5:695063448f2a 66 void MMA8451Q::MotionDetection( void(*fptr)(void))
clemente 5:695063448f2a 67 {
clemente 8:7e6013f11b10 68 Reset();
clemente 8:7e6013f11b10 69
rendek4 12:37acb52ade50 70 //data sheet MMA8451Q.pdf strana 45
clemente 5:695063448f2a 71 // 6.1 Example Steps for Configuring Motion Detection
clemente 5:695063448f2a 72 // X or Y > 3g using MFF Function 4g, 100 Hz ODR, Normal Mode
clemente 5:695063448f2a 73 // Step 1: Put the device into Standby Mode: Register 0x2A CTRL_REG1
clemente 5:695063448f2a 74 unsigned char data[2] = {REG_CTRL_REG_1, 0x18}; // Set the device in 100 Hz ODR, Standby
clemente 5:695063448f2a 75 writeRegs(data, 2);
clemente 5:695063448f2a 76
rendek4 12:37acb52ade50 77 //data sheet MMA8451Q.pdf strana 32
clemente 5:695063448f2a 78 // Step 2: Set Configuration Register for Motion Detection by setting the “OR” condition OAE = 1, enabling
clemente 5:695063448f2a 79 // X, Y, and the latch
clemente 5:695063448f2a 80 data[0] = REG_FF_MT_CFG;
clemente 5:695063448f2a 81 data[1] = 0xD8;
clemente 5:695063448f2a 82 writeRegs(data, 2);
clemente 5:695063448f2a 83
rendek4 12:37acb52ade50 84 //data sheet MMA8451Q.pdf strana 34
clemente 5:695063448f2a 85 // Step 3: Threshold Setting Value for the Motion detection of > 2g
clemente 5:695063448f2a 86 // Note: The step count is 0.063g/ count
clemente 8:7e6013f11b10 87 // • 1g/0.063g = 15.8; //Round up to 16
clemente 5:695063448f2a 88 data[0] = REG_FF_MT_THS;
rendek4 12:37acb52ade50 89 data[1] = 0x08;
clemente 5:695063448f2a 90 writeRegs(data, 2);
clemente 5:695063448f2a 91
rendek4 12:37acb52ade50 92 //data sheet MMA8451Q.pdf strana 32
clemente 5:695063448f2a 93 // Step 4: Set the debounce counter to eliminate false readings for 100 Hz sample rate with a requirement
clemente 5:695063448f2a 94 // of 100 ms timer.
clemente 5:695063448f2a 95 // Note: 100 ms/10 ms (steps) = 10 counts
clemente 5:695063448f2a 96 data[0] = REG_FF_MT_CNT;
clemente 5:695063448f2a 97 data[1] = 0x0A;
clemente 5:695063448f2a 98 writeRegs(data, 2);
clemente 5:695063448f2a 99
rendek4 12:37acb52ade50 100 //data sheet MMA8451Q.pdf strana 48
clemente 5:695063448f2a 101 // Step 5: Enable Motion/Freefall Interrupt Function in the System (CTRL_REG4)
clemente 5:695063448f2a 102 data[0] = REG_CTRL_REG_4;
clemente 5:695063448f2a 103 data[1] = 0x04;
clemente 5:695063448f2a 104 writeRegs(data, 2);
clemente 5:695063448f2a 105
rendek4 12:37acb52ade50 106 //data sheet MMA8451Q.pdf strana 48
clemente 7:ba0016258d5d 107 // Step 6: Route the Motion/Freefall Interrupt Function to INT2 hardware pin (CTRL_REG5)
clemente 5:695063448f2a 108 data[0] = REG_CTRL_REG_5;
clemente 7:ba0016258d5d 109 data[1] = 0x00;
clemente 5:695063448f2a 110 writeRegs(data, 2);
clemente 5:695063448f2a 111
rendek4 12:37acb52ade50 112
clemente 5:695063448f2a 113 // Step 7: Put the device in Active Mode
clemente 5:695063448f2a 114 data[0] = REG_CTRL_REG_1;
clemente 5:695063448f2a 115 data[1] = 0x19;
clemente 5:695063448f2a 116 writeRegs(data, 2);
clemente 5:695063448f2a 117
clemente 11:13e2af71e2cf 118 MMA8451Q_usr2_fptr = fptr;
clemente 7:ba0016258d5d 119 MMA8451Q_Int2.fall( this, &MMA8451Q::Motion_IRQ);
rendek4 12:37acb52ade50 120 }
clemente 5:695063448f2a 121
clemente 5:695063448f2a 122
clemente 5:695063448f2a 123 void MMA8451Q::Motion_IRQ( void)
clemente 5:695063448f2a 124 {
clemente 5:695063448f2a 125 unsigned char t;
clemente 5:695063448f2a 126
clemente 5:695063448f2a 127 readRegs( REG_INT_SRC, &t, 1);
clemente 5:695063448f2a 128 //
clemente 5:695063448f2a 129 if ( (t & 0x04) == 0x04) {
rendek4 12:37acb52ade50 130
clemente 5:695063448f2a 131 readRegs( REG_FF_MT_SRC, &t, 1);
rendek4 12:37acb52ade50 132
clemente 11:13e2af71e2cf 133 MMA8451Q_usr2_fptr();
clemente 5:695063448f2a 134 }
clemente 5:695063448f2a 135 }
clemente 5:695063448f2a 136
clemente 5:695063448f2a 137 void MMA8451Q::Active( void)
clemente 5:695063448f2a 138 {
clemente 5:695063448f2a 139 unsigned char t;
clemente 5:695063448f2a 140
clemente 5:695063448f2a 141 // Activate the peripheral
clemente 5:695063448f2a 142 readRegs(REG_CTRL_REG_1, &t, 1);
clemente 5:695063448f2a 143 unsigned char data[2] = {REG_CTRL_REG_1, t|0x01};
clemente 5:695063448f2a 144 writeRegs(data, 2);
clemente 5:695063448f2a 145 }
clemente 5:695063448f2a 146
clemente 5:695063448f2a 147 void MMA8451Q::Standby( void)
clemente 5:695063448f2a 148 {
clemente 5:695063448f2a 149 unsigned char t;
clemente 5:695063448f2a 150
clemente 5:695063448f2a 151 // Standby
clemente 5:695063448f2a 152 readRegs(REG_CTRL_REG_1, &t, 1);
clemente 5:695063448f2a 153 unsigned char data[2] = {REG_CTRL_REG_1, t&0xFE};
clemente 5:695063448f2a 154 writeRegs(data, 2);
clemente 5:695063448f2a 155 }
emilmont 0:6149091f755d 156
chris 3:db7126dbd63f 157 float MMA8451Q::getAccX() {
chris 3:db7126dbd63f 158 return (float(getAccAxis(REG_OUT_X_MSB))/4096.0);
emilmont 0:6149091f755d 159 }
emilmont 0:6149091f755d 160
chris 3:db7126dbd63f 161 float MMA8451Q::getAccY() {
chris 3:db7126dbd63f 162 return (float(getAccAxis(REG_OUT_Y_MSB))/4096.0);
emilmont 0:6149091f755d 163 }
emilmont 0:6149091f755d 164
chris 3:db7126dbd63f 165 float MMA8451Q::getAccZ() {
chris 3:db7126dbd63f 166 return (float(getAccAxis(REG_OUT_Z_MSB))/4096.0);
emilmont 0:6149091f755d 167 }
emilmont 0:6149091f755d 168
chris 3:db7126dbd63f 169 void MMA8451Q::getAccAllAxis(float * res) {
emilmont 0:6149091f755d 170 res[0] = getAccX();
emilmont 0:6149091f755d 171 res[1] = getAccY();
emilmont 0:6149091f755d 172 res[2] = getAccZ();
emilmont 0:6149091f755d 173 }
emilmont 0:6149091f755d 174
emilmont 0:6149091f755d 175 int16_t MMA8451Q::getAccAxis(uint8_t addr) {
emilmont 0:6149091f755d 176 int16_t acc;
emilmont 0:6149091f755d 177 uint8_t res[2];
samux 1:d2630136d51e 178 readRegs(addr, res, 2);
emilmont 0:6149091f755d 179
emilmont 0:6149091f755d 180 acc = (res[0] << 6) | (res[1] >> 2);
emilmont 0:6149091f755d 181 if (acc > UINT14_MAX/2)
emilmont 0:6149091f755d 182 acc -= UINT14_MAX;
emilmont 0:6149091f755d 183
emilmont 0:6149091f755d 184 return acc;
emilmont 0:6149091f755d 185 }
emilmont 0:6149091f755d 186
samux 1:d2630136d51e 187 void MMA8451Q::readRegs(int addr, uint8_t * data, int len) {
emilmont 0:6149091f755d 188 char t[1] = {addr};
emilmont 0:6149091f755d 189 m_i2c.write(m_addr, t, 1, true);
emilmont 0:6149091f755d 190 m_i2c.read(m_addr, (char *)data, len);
emilmont 0:6149091f755d 191 }
emilmont 0:6149091f755d 192
samux 1:d2630136d51e 193 void MMA8451Q::writeRegs(uint8_t * data, int len) {
emilmont 0:6149091f755d 194 m_i2c.write(m_addr, (char *)data, len);
emilmont 0:6149091f755d 195 }