Device driver for the Freescale MMA845x family of accelerometers.

Fork of MMA845x by Sam Grove

Committer:
1994timmeh
Date:
Thu Jan 05 06:41:39 2017 +0000
Revision:
1:37ddb4739f02
Parent:
0:9d1e3a344e4f
Child:
2:555f8ba0c959
asdfasdfadsf

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sam_grove 0:9d1e3a344e4f 1 /**
sam_grove 0:9d1e3a344e4f 2 * @file MMA845x.cpp
sam_grove 0:9d1e3a344e4f 3 * @brief Device driver - MMA845X 3-axis accelerometer IC
sam_grove 0:9d1e3a344e4f 4 * @author sam grove
sam_grove 0:9d1e3a344e4f 5 * @version 1.0
sam_grove 0:9d1e3a344e4f 6 * @see http://cache.freescale.com/files/sensors/doc/data_sheet/MMA8451Q.pdf
sam_grove 0:9d1e3a344e4f 7 * @see http://cache.freescale.com/files/sensors/doc/data_sheet/MMA8452Q.pdf
sam_grove 0:9d1e3a344e4f 8 * @see http://cache.freescale.com/files/sensors/doc/data_sheet/MMA8453Q.pdf
sam_grove 0:9d1e3a344e4f 9 *
sam_grove 0:9d1e3a344e4f 10 * Copyright (c) 2013
sam_grove 0:9d1e3a344e4f 11 *
sam_grove 0:9d1e3a344e4f 12 * Licensed under the Apache License, Version 2.0 (the "License");
sam_grove 0:9d1e3a344e4f 13 * you may not use this file except in compliance with the License.
sam_grove 0:9d1e3a344e4f 14 * You may obtain a copy of the License at
sam_grove 0:9d1e3a344e4f 15 *
sam_grove 0:9d1e3a344e4f 16 * http://www.apache.org/licenses/LICENSE-2.0
sam_grove 0:9d1e3a344e4f 17 *
sam_grove 0:9d1e3a344e4f 18 * Unless required by applicable law or agreed to in writing, software
sam_grove 0:9d1e3a344e4f 19 * distributed under the License is distributed on an "AS IS" BASIS,
sam_grove 0:9d1e3a344e4f 20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
sam_grove 0:9d1e3a344e4f 21 * See the License for the specific language governing permissions and
sam_grove 0:9d1e3a344e4f 22 * limitations under the License.
sam_grove 0:9d1e3a344e4f 23 */
sam_grove 0:9d1e3a344e4f 24
sam_grove 0:9d1e3a344e4f 25 #include "MMA845x.h"
sam_grove 0:9d1e3a344e4f 26
1994timmeh 1:37ddb4739f02 27 MMA845x::MMA845x(I2C &i2c, InterruptIn &int1, InterruptIn &int2) {
sam_grove 0:9d1e3a344e4f 28 _i2c = &i2c;
sam_grove 0:9d1e3a344e4f 29 _int1 = &int1;
sam_grove 0:9d1e3a344e4f 30 _int2 = &int2;
sam_grove 0:9d1e3a344e4f 31
1994timmeh 1:37ddb4739f02 32 _i2c_addr = (0x1c << 2) | (0 << 0x1);
sam_grove 0:9d1e3a344e4f 33
sam_grove 0:9d1e3a344e4f 34 return;
sam_grove 0:9d1e3a344e4f 35 }
sam_grove 0:9d1e3a344e4f 36
1994timmeh 1:37ddb4739f02 37 void MMA845x::init(void) const {
sam_grove 0:9d1e3a344e4f 38 uint8_t reg_val = 0;
sam_grove 0:9d1e3a344e4f 39
sam_grove 0:9d1e3a344e4f 40 _i2c->frequency(400000);
sam_grove 0:9d1e3a344e4f 41
sam_grove 0:9d1e3a344e4f 42 // Reset all registers to POR values
sam_grove 0:9d1e3a344e4f 43 MMA845x::writeRegister(CTRL_REG2, 0xFF); //REG 0x2B
sam_grove 0:9d1e3a344e4f 44 do{
sam_grove 0:9d1e3a344e4f 45 // wait for the reset bit to clear
sam_grove 0:9d1e3a344e4f 46 reg_val = MMA845x::readRegister(CTRL_REG2) & 0x40;
sam_grove 0:9d1e3a344e4f 47 }while(reg_val);
sam_grove 0:9d1e3a344e4f 48
sam_grove 0:9d1e3a344e4f 49 // setup the registers that are common among modes
sam_grove 0:9d1e3a344e4f 50 MMA845x::writeRegister(CTRL_REG1, 0xd8); //REG 0x2A
sam_grove 0:9d1e3a344e4f 51 MMA845x::writeRegister(CTRL_REG2, 0x00); //REG 0x2B
sam_grove 0:9d1e3a344e4f 52 MMA845x::writeRegister(CTRL_REG3, 0x00); //REG 0x2C
sam_grove 0:9d1e3a344e4f 53
sam_grove 0:9d1e3a344e4f 54 MMA845x::writeRegister(XYZ_DATA_CFG, 0x0); //REG 0xE HPF / scale +/-2,4,8g
sam_grove 0:9d1e3a344e4f 55 MMA845x::writeRegister(HP_FILTER_CUTOFF, 0x0); //REG 0xF HPF settings
sam_grove 0:9d1e3a344e4f 56
sam_grove 0:9d1e3a344e4f 57 return;
sam_grove 0:9d1e3a344e4f 58 }
sam_grove 0:9d1e3a344e4f 59
sam_grove 0:9d1e3a344e4f 60 void MMA845x::enableDataReadyMode(void) const
sam_grove 0:9d1e3a344e4f 61 {
sam_grove 0:9d1e3a344e4f 62 MMA845x::init();
sam_grove 0:9d1e3a344e4f 63 MMA845x::writeRegister(SYSMOD, 0x1); //REG 0x0B
sam_grove 0:9d1e3a344e4f 64 MMA845x::writeRegister(INT_SOURCE, 0x1); //REG 0x0C
sam_grove 0:9d1e3a344e4f 65 // need to finish up these config registers..... 3/8/13
sam_grove 0:9d1e3a344e4f 66
sam_grove 0:9d1e3a344e4f 67 }
sam_grove 0:9d1e3a344e4f 68
sam_grove 0:9d1e3a344e4f 69 void MMA845x::enableMotionMode(void) const{}
sam_grove 0:9d1e3a344e4f 70 void MMA845x::enablePulseMode(void) const{}
sam_grove 0:9d1e3a344e4f 71
sam_grove 0:9d1e3a344e4f 72 void MMA845x::enableOrientationMode(void) const
sam_grove 0:9d1e3a344e4f 73 {
sam_grove 0:9d1e3a344e4f 74 uint16_t who_am_i = MMA845x::readRegister(WHO_AM_I);
sam_grove 0:9d1e3a344e4f 75 if(who_am_i != MMA8451)
sam_grove 0:9d1e3a344e4f 76 {
sam_grove 0:9d1e3a344e4f 77 error("%s %d: Feature not compatible with the connected device.\n", __FILE__, __LINE__);
sam_grove 0:9d1e3a344e4f 78 }
sam_grove 0:9d1e3a344e4f 79
sam_grove 0:9d1e3a344e4f 80 return;
sam_grove 0:9d1e3a344e4f 81 }
sam_grove 0:9d1e3a344e4f 82
sam_grove 0:9d1e3a344e4f 83 void MMA845x::enableTransitMode(void) const{}
sam_grove 0:9d1e3a344e4f 84 void MMA845x::enableAutoSleepMode(void) const{}
sam_grove 0:9d1e3a344e4f 85
sam_grove 0:9d1e3a344e4f 86 void MMA845x::enableFIFOMode(void) const
sam_grove 0:9d1e3a344e4f 87 {
sam_grove 0:9d1e3a344e4f 88 uint16_t who_am_i = MMA845x::readRegister(WHO_AM_I);
sam_grove 0:9d1e3a344e4f 89 if(who_am_i != MMA8451)
sam_grove 0:9d1e3a344e4f 90 {
sam_grove 0:9d1e3a344e4f 91 error("%s %d: Feature not compatible with the connected device.\n", __FILE__, __LINE__);
sam_grove 0:9d1e3a344e4f 92 }
sam_grove 0:9d1e3a344e4f 93
sam_grove 0:9d1e3a344e4f 94 //MMA845x::writeRegister(
sam_grove 0:9d1e3a344e4f 95
sam_grove 0:9d1e3a344e4f 96 return;
sam_grove 0:9d1e3a344e4f 97 }
sam_grove 0:9d1e3a344e4f 98
sam_grove 0:9d1e3a344e4f 99 uint16_t MMA845x::getX(void) const
sam_grove 0:9d1e3a344e4f 100 {
sam_grove 0:9d1e3a344e4f 101 return _data._x;
sam_grove 0:9d1e3a344e4f 102 }
sam_grove 0:9d1e3a344e4f 103
sam_grove 0:9d1e3a344e4f 104 uint16_t MMA845x::getY(void) const
sam_grove 0:9d1e3a344e4f 105 {
sam_grove 0:9d1e3a344e4f 106 return _data._y;
sam_grove 0:9d1e3a344e4f 107 }
sam_grove 0:9d1e3a344e4f 108
sam_grove 0:9d1e3a344e4f 109 uint16_t MMA845x::getZ(void) const
sam_grove 0:9d1e3a344e4f 110 {
sam_grove 0:9d1e3a344e4f 111 return _data._z;
sam_grove 0:9d1e3a344e4f 112 }
sam_grove 0:9d1e3a344e4f 113
sam_grove 0:9d1e3a344e4f 114 MMA845x_DATA MMA845x::getXYZ(void) const
sam_grove 0:9d1e3a344e4f 115 {
sam_grove 0:9d1e3a344e4f 116 return _data;
sam_grove 0:9d1e3a344e4f 117 }
sam_grove 0:9d1e3a344e4f 118
sam_grove 0:9d1e3a344e4f 119 void MMA845x::writeRegister(uint8_t const reg, uint8_t const data) const
sam_grove 0:9d1e3a344e4f 120 {
sam_grove 0:9d1e3a344e4f 121 char buf[2] = {reg, data};
sam_grove 0:9d1e3a344e4f 122 uint8_t result = 0;
sam_grove 0:9d1e3a344e4f 123
sam_grove 0:9d1e3a344e4f 124 __disable_irq(); // Tickers and other timebase events can jack up the I2C bus for some deicse
sam_grove 0:9d1e3a344e4f 125 result = _i2c->write(_i2c_addr, buf, 2);
sam_grove 0:9d1e3a344e4f 126 __enable_irq(); // Just need to block during the transaction
sam_grove 0:9d1e3a344e4f 127
sam_grove 0:9d1e3a344e4f 128 if(0 != result)
sam_grove 0:9d1e3a344e4f 129 {
sam_grove 0:9d1e3a344e4f 130 error("%s %d: I2c write failed\n", __FILE__, __LINE__);
sam_grove 0:9d1e3a344e4f 131 }
sam_grove 0:9d1e3a344e4f 132
sam_grove 0:9d1e3a344e4f 133 return;
sam_grove 0:9d1e3a344e4f 134 }
sam_grove 0:9d1e3a344e4f 135
sam_grove 0:9d1e3a344e4f 136 uint8_t MMA845x::readRegister(uint8_t const reg) const
sam_grove 0:9d1e3a344e4f 137 {
sam_grove 0:9d1e3a344e4f 138 uint8_t result = 1, data = 0;
sam_grove 0:9d1e3a344e4f 139
sam_grove 0:9d1e3a344e4f 140 __disable_irq(); // Tickers and other timebase events can jack up the I2C bus
sam_grove 0:9d1e3a344e4f 141 _i2c->start();
sam_grove 0:9d1e3a344e4f 142 result &= _i2c->write(_i2c_addr);
sam_grove 0:9d1e3a344e4f 143 result &= _i2c->write(reg);
sam_grove 0:9d1e3a344e4f 144 // issue a repeated start...
sam_grove 0:9d1e3a344e4f 145 _i2c->start();
sam_grove 0:9d1e3a344e4f 146 result &= _i2c->write(_i2c_addr | 0x01);
sam_grove 0:9d1e3a344e4f 147 // read with nak
sam_grove 0:9d1e3a344e4f 148 data = _i2c->read(0);
sam_grove 0:9d1e3a344e4f 149 _i2c->stop();
sam_grove 0:9d1e3a344e4f 150 __enable_irq(); // Just need to block during the transaction
sam_grove 0:9d1e3a344e4f 151
sam_grove 0:9d1e3a344e4f 152 if(1 != result)
sam_grove 0:9d1e3a344e4f 153 {
sam_grove 0:9d1e3a344e4f 154 error("%s %d: I2C read failed\n", __FILE__, __LINE__);
sam_grove 0:9d1e3a344e4f 155 }
sam_grove 0:9d1e3a344e4f 156
sam_grove 0:9d1e3a344e4f 157 return data;
sam_grove 0:9d1e3a344e4f 158 }
sam_grove 0:9d1e3a344e4f 159
sam_grove 0:9d1e3a344e4f 160 void MMA845x::registerDump(void) const
sam_grove 0:9d1e3a344e4f 161 {
sam_grove 0:9d1e3a344e4f 162 uint8_t reg_val = 0;
sam_grove 0:9d1e3a344e4f 163
sam_grove 0:9d1e3a344e4f 164 for(int i=0; i<0x80; i++)
sam_grove 0:9d1e3a344e4f 165 {
sam_grove 0:9d1e3a344e4f 166 reg_val = MMA845x::readRegister(i);
sam_grove 0:9d1e3a344e4f 167 printf("Reg 0x%02x: 0x%02x \n", i, reg_val);
sam_grove 0:9d1e3a344e4f 168 }
sam_grove 0:9d1e3a344e4f 169
sam_grove 0:9d1e3a344e4f 170 return;
sam_grove 0:9d1e3a344e4f 171 }
sam_grove 0:9d1e3a344e4f 172