modified from jppang's MMA8451Q for MMA8491Q on sensor evaluation board with the FRDM-KL25Z

Dependencies:   mbed

Fork of MMA8491Q by JP PANG

Committer:
DiyGuy
Date:
Fri Nov 29 23:14:21 2013 +0000
Revision:
3:3f5c717835c3
Parent:
2:b79d19bdfe10
Added main() example and exercises sensor EN input to trigger new readings

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jppang 0:41db55eef564 1 /* Copyright (c) 2010-2011 mbed.org, MIT License
jppang 0:41db55eef564 2 *
jppang 0:41db55eef564 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
jppang 0:41db55eef564 4 * and associated documentation files (the "Software"), to deal in the Software without
jppang 0:41db55eef564 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
jppang 0:41db55eef564 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
jppang 0:41db55eef564 7 * Software is furnished to do so, subject to the following conditions:
jppang 0:41db55eef564 8 *
jppang 0:41db55eef564 9 * The above copyright notice and this permission notice shall be included in all copies or
jppang 0:41db55eef564 10 * substantial portions of the Software.
jppang 0:41db55eef564 11 *
jppang 0:41db55eef564 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
jppang 0:41db55eef564 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
jppang 0:41db55eef564 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
jppang 0:41db55eef564 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
jppang 0:41db55eef564 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
jppang 0:41db55eef564 17 */
jppang 0:41db55eef564 18
jppang 0:41db55eef564 19 #include "MMA8491Q.h"
jppang 0:41db55eef564 20
DiyGuy 2:b79d19bdfe10 21 #define REG_STATUS 0x00
jppang 0:41db55eef564 22 #define REG_OUT_X_MSB 0x01
jppang 0:41db55eef564 23 #define REG_OUT_Y_MSB 0x03
jppang 0:41db55eef564 24 #define REG_OUT_Z_MSB 0x05
jppang 0:41db55eef564 25
DiyGuy 2:b79d19bdfe10 26 #define XDR 0x01 //X data ready flag position
DiyGuy 2:b79d19bdfe10 27 #define YDR 0x02 //Y data ready flag position
DiyGuy 2:b79d19bdfe10 28 #define ZDR 0x04 //Z data ready flag position
DiyGuy 2:b79d19bdfe10 29 #define ZYXDR 0x08 //X, Y, Z data ready flag position
jppang 0:41db55eef564 30
DiyGuy 2:b79d19bdfe10 31 #define UINT14_MAX 16383 //maximum count for unsigned 14-bit integer
jppang 0:41db55eef564 32
DiyGuy 2:b79d19bdfe10 33 MMA8491Q::MMA8491Q(PinName sda, PinName scl, int addr, PinName en) : m_i2c(sda, scl), m_addr(addr), m_en(en) {
DiyGuy 2:b79d19bdfe10 34
jppang 0:41db55eef564 35 }
jppang 0:41db55eef564 36
DiyGuy 2:b79d19bdfe10 37 MMA8491Q::MMA8491Q(PinName sda, PinName scl, int addr, PinName en, PinName Xout, PinName Yout, PinName Zout)
DiyGuy 2:b79d19bdfe10 38 : m_i2c(sda, scl), m_addr(addr), m_en(en), m_xout(Xout), m_yout(Yout), m_zout(Zout) {
DiyGuy 2:b79d19bdfe10 39
jppang 0:41db55eef564 40 }
jppang 0:41db55eef564 41
jppang 0:41db55eef564 42
DiyGuy 2:b79d19bdfe10 43 MMA8491Q::~MMA8491Q() { }
jppang 0:41db55eef564 44
DiyGuy 2:b79d19bdfe10 45 float MMA8491Q::getAccX() {
DiyGuy 2:b79d19bdfe10 46 uint8_t res[2];
DiyGuy 2:b79d19bdfe10 47 uint8_t status;
DiyGuy 2:b79d19bdfe10 48 float acc = 0;
jppang 0:41db55eef564 49
DiyGuy 2:b79d19bdfe10 50 toggleEN();
jppang 0:41db55eef564 51
DiyGuy 2:b79d19bdfe10 52 status = isDataAvailable(XDR);
DiyGuy 2:b79d19bdfe10 53 if(status){
DiyGuy 2:b79d19bdfe10 54 readRegs(REG_OUT_X_MSB, res, 2); //get X readings
DiyGuy 2:b79d19bdfe10 55 acc = intAccToFloat(res);
DiyGuy 2:b79d19bdfe10 56
DiyGuy 2:b79d19bdfe10 57 }
DiyGuy 2:b79d19bdfe10 58 return acc;
DiyGuy 2:b79d19bdfe10 59 }
DiyGuy 2:b79d19bdfe10 60
DiyGuy 2:b79d19bdfe10 61
DiyGuy 2:b79d19bdfe10 62 float MMA8491Q::getAccY() {
DiyGuy 2:b79d19bdfe10 63 uint8_t res[2];
DiyGuy 2:b79d19bdfe10 64 uint8_t status;
DiyGuy 2:b79d19bdfe10 65 float acc = 0;
jppang 0:41db55eef564 66
DiyGuy 2:b79d19bdfe10 67 toggleEN();
DiyGuy 2:b79d19bdfe10 68
DiyGuy 2:b79d19bdfe10 69 status = isDataAvailable(YDR);
DiyGuy 2:b79d19bdfe10 70 if(status){
DiyGuy 2:b79d19bdfe10 71 readRegs(REG_OUT_Y_MSB, res, 2); //get Y readings
DiyGuy 2:b79d19bdfe10 72 acc = intAccToFloat(res);
DiyGuy 2:b79d19bdfe10 73
DiyGuy 2:b79d19bdfe10 74 }
DiyGuy 2:b79d19bdfe10 75 return acc;
jppang 0:41db55eef564 76 }
jppang 0:41db55eef564 77
jppang 0:41db55eef564 78
DiyGuy 2:b79d19bdfe10 79 float MMA8491Q::getAccZ() {
DiyGuy 2:b79d19bdfe10 80 uint8_t res[2];
DiyGuy 2:b79d19bdfe10 81 uint8_t status;
DiyGuy 2:b79d19bdfe10 82 float acc = 0;
DiyGuy 2:b79d19bdfe10 83
DiyGuy 2:b79d19bdfe10 84 toggleEN();
DiyGuy 2:b79d19bdfe10 85
DiyGuy 2:b79d19bdfe10 86 status = isDataAvailable(ZDR);
DiyGuy 2:b79d19bdfe10 87 if(status){
DiyGuy 2:b79d19bdfe10 88 readRegs(REG_OUT_Z_MSB, res, 2); //get Z readings
DiyGuy 2:b79d19bdfe10 89 acc = intAccToFloat(res);
DiyGuy 2:b79d19bdfe10 90
DiyGuy 2:b79d19bdfe10 91 }
DiyGuy 2:b79d19bdfe10 92 return acc;
DiyGuy 2:b79d19bdfe10 93 }
DiyGuy 2:b79d19bdfe10 94
DiyGuy 2:b79d19bdfe10 95
DiyGuy 2:b79d19bdfe10 96 uint8_t MMA8491Q::getAccAllAxis(float * acc) {
DiyGuy 2:b79d19bdfe10 97 uint8_t res[6];
DiyGuy 2:b79d19bdfe10 98 uint8_t status;
DiyGuy 2:b79d19bdfe10 99
DiyGuy 2:b79d19bdfe10 100 toggleEN();
DiyGuy 2:b79d19bdfe10 101
DiyGuy 2:b79d19bdfe10 102 status = isDataAvailable(ZYXDR);
DiyGuy 2:b79d19bdfe10 103 if(status){
DiyGuy 2:b79d19bdfe10 104 readRegs(REG_OUT_X_MSB, res, 6); //get X,Y,Z readings
DiyGuy 2:b79d19bdfe10 105 for(int8_t i=0; i<3; i++){
DiyGuy 2:b79d19bdfe10 106 acc[i] = intAccToFloat(&res[(i*2)]);
DiyGuy 2:b79d19bdfe10 107 }
DiyGuy 2:b79d19bdfe10 108 }
DiyGuy 2:b79d19bdfe10 109 return status;
DiyGuy 2:b79d19bdfe10 110 }
DiyGuy 2:b79d19bdfe10 111
DiyGuy 2:b79d19bdfe10 112
DiyGuy 2:b79d19bdfe10 113 uint8_t MMA8491Q::isDataAvailable( uint8_t mask){
DiyGuy 2:b79d19bdfe10 114 unsigned char status;
DiyGuy 2:b79d19bdfe10 115 readRegs( REG_STATUS, &status, 1);
DiyGuy 2:b79d19bdfe10 116 status &= mask; //check for requested Data Ready flag
DiyGuy 2:b79d19bdfe10 117 return status;
DiyGuy 2:b79d19bdfe10 118 }
DiyGuy 2:b79d19bdfe10 119
DiyGuy 2:b79d19bdfe10 120
DiyGuy 2:b79d19bdfe10 121 //convert 14-bit 2's compliment (mg) number from sensor to float scaled to 1g
DiyGuy 2:b79d19bdfe10 122 float MMA8491Q::intAccToFloat(uint8_t * data) {
DiyGuy 2:b79d19bdfe10 123 int16_t acc = 0;
DiyGuy 2:b79d19bdfe10 124
DiyGuy 2:b79d19bdfe10 125 acc = (data[0] << 6) | (data[1] >> 2);
DiyGuy 2:b79d19bdfe10 126 if (acc > UINT14_MAX/2) //MSB of 14-bit value is 1 or negative
DiyGuy 2:b79d19bdfe10 127 acc -= UINT14_MAX; //extend sign to 16 bits
DiyGuy 2:b79d19bdfe10 128
DiyGuy 2:b79d19bdfe10 129 return acc/1000.0;
DiyGuy 2:b79d19bdfe10 130 }
DiyGuy 2:b79d19bdfe10 131
DiyGuy 2:b79d19bdfe10 132
DiyGuy 2:b79d19bdfe10 133 void MMA8491Q::toggleEN(void){
DiyGuy 2:b79d19bdfe10 134 m_en = 0; //cycle cycle enable low-high
DiyGuy 2:b79d19bdfe10 135 wait(0.001);
DiyGuy 2:b79d19bdfe10 136 m_en = 1; //start MMA8491Q reading
DiyGuy 2:b79d19bdfe10 137 wait(0.001); //wait 1 ms for reading
DiyGuy 2:b79d19bdfe10 138
DiyGuy 2:b79d19bdfe10 139 }
DiyGuy 2:b79d19bdfe10 140
DiyGuy 2:b79d19bdfe10 141
jppang 0:41db55eef564 142 void MMA8491Q::readRegs(int addr, uint8_t * data, int len) {
jppang 0:41db55eef564 143 char t[1] = {addr};
jppang 0:41db55eef564 144 m_i2c.write(m_addr, t, 1, true);
jppang 0:41db55eef564 145 m_i2c.read(m_addr, (char *)data, len);
jppang 0:41db55eef564 146 }
jppang 0:41db55eef564 147
jppang 0:41db55eef564 148
jppang 0:41db55eef564 149 void MMA8491Q::writeRegs(uint8_t * data, int len) {
jppang 0:41db55eef564 150 m_i2c.write(m_addr, (char *)data, len);
jppang 0:41db55eef564 151 }