Class Module for MMA845x I2C Accelerometer.
Dependents: mDotEVBM2X MTDOT-EVBDemo-DRH MTDOT-BOX-EVB-Factory-Firmware-LIB-108 MTDOT-UDKDemo_Senet ... more
Fork of MMA845x by
MMA845x.cpp
00001 /** 00002 * @file MMA845x.cpp 00003 * @brief Device driver - MMA845X 3-axis accelerometer IC W/RTOS support 00004 * @author Tim Barr 00005 * @version 1.0 00006 * @see http://cache.freescale.com/files/sensors/doc/data_sheet/MMA8451Q.pdf 00007 * @see http://cache.freescale.com/files/sensors/doc/data_sheet/MMA8452Q.pdf 00008 * @see http://cache.freescale.com/files/sensors/doc/data_sheet/MMA8453Q.pdf 00009 * 00010 * Copyright (c) 2015 00011 * 00012 * Licensed under the Apache License, Version 2.0 (the "License"); 00013 * you may not use this file except in compliance with the License. 00014 * You may obtain a copy of the License at 00015 * 00016 * http://www.apache.org/licenses/LICENSE-2.0 00017 * 00018 * Unless required by applicable law or agreed to in writing, software 00019 * distributed under the License is distributed on an "AS IS" BASIS, 00020 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00021 * See the License for the specific language governing permissions and 00022 * limitations under the License. 00023 * 00024 * 5/5/2015 Forked from https://developer.mbed.org/users/sam_grove/code/MMA845x/ 00025 * 00026 * 6/20/2015 TAB Added setup functions and polling data capability. Also added RTOS calls 00027 * TODO Still need to add interrupt support for other Accelerometer mode support 00028 */ 00029 00030 #include "MMA845x.h" 00031 #include "mbed_debug.h" 00032 #include "rtos.h" 00033 00034 MMA845x::MMA845x(I2C &i2c, SA0 const i2c_addr, InterruptIn* int1, InterruptIn* int2) 00035 { 00036 _i2c = &i2c; 00037 _int1 = int1; 00038 _int2 = int2; 00039 00040 _i2c_addr = (0x1c | i2c_addr) << 1; 00041 00042 MMA845x::init(); 00043 00044 return; 00045 } 00046 00047 uint8_t MMA845x::init(void) 00048 { 00049 uint8_t result = 0; 00050 uint8_t i = 0; 00051 char reg_val[1]; 00052 00053 _who_am_i = 0x00; 00054 00055 // Reset all registers to POR values 00056 result = MMA845x::writeRegister(CTRL_REG2, 0xFF); //REG 0x2B 00057 if (result == 0) { 00058 00059 do { 00060 // wait for the reset bit to clear. readRegister may error out so we re-try 10 times 00061 osDelay(200); 00062 reg_val[0] = 0x40; 00063 result = MMA845x::readRegister(CTRL_REG2,1,reg_val); 00064 reg_val[0] = reg_val[0] & 0x40; 00065 i++; 00066 } while(((reg_val[0] != 0)||( result != 0)) && (i<=10)); 00067 } 00068 00069 if (result == 0) { 00070 result = MMA845x::readRegister(WHO_AM_I,1,reg_val); 00071 } 00072 00073 switch (reg_val[0]) { 00074 case MMA8451 : 00075 case MMA8452 : 00076 case MMA8453 : 00077 _who_am_i= reg_val[0]; 00078 if ((_int1 == NULL) && (_int2 == NULL)) 00079 _polling_mode = true; 00080 else _polling_mode = false; 00081 break; 00082 default: 00083 debug ("Device not supported by this library!\n\r"); 00084 result = 1; 00085 } 00086 00087 if(result != 0) { 00088 debug("MMA845x:init failed\n\r"); 00089 } 00090 00091 00092 return result; 00093 } 00094 00095 uint8_t MMA845x::setCommonParameters(RANGE range, RESOLUTION resolution, LOW_NOISE lo_noise, 00096 DATA_RATE data_rate, OVERSAMPLE_MODE os_mode, HPF_MODE hpf_mode) const 00097 { 00098 uint8_t result = 0; 00099 char datain[1]; 00100 uint8_t dataout = 0; 00101 00102 result |= MMA845x::readRegister(SYSMOD,1,datain); // Make sure MMA845x is in Stand-By mode 00103 if ((datain[0] & 0x03) != 0 ) { 00104 debug ("MMA845x not in STAND BY mode\n\f"); 00105 debug("MMA845x:setCommonParameters failed\n\r"); 00106 result = 1; 00107 return result; 00108 } 00109 00110 result |= MMA845x::readRegister(CTRL_REG1, 1, datain); 00111 dataout = (datain[0] & 0xB1) | resolution | lo_noise | data_rate; 00112 result |= MMA845x::writeRegister(CTRL_REG1, dataout); // Set resolution, Low Noise mode, and data rate 00113 00114 result |= MMA845x::readRegister(CTRL_REG2,1, datain); 00115 dataout = (datain[0] & 0xFB) | os_mode; 00116 result |= MMA845x::writeRegister(CTRL_REG2, dataout); // Set Oversample mode 00117 00118 result |= MMA845x::readRegister(XYZ_DATA_CFG,1, datain); 00119 dataout = range | hpf_mode; 00120 result |= MMA845x::writeRegister(XYZ_DATA_CFG, dataout); //Set HPF mode and range 00121 00122 // result |= MMA845x::readRegister(HP_FILTER_CUTOFF,1, datain); 00123 // result |= MMA845x::writeRegister(HP_FILTER_CUTOFF, dataout); //REG 0xF HPF settings 00124 00125 if(result != 0) { 00126 debug("MMA845x:setParameters failed\n\r"); 00127 } 00128 00129 return result; 00130 00131 } 00132 00133 uint8_t MMA845x::enableMotionDetect(void) const 00134 { 00135 uint8_t result = 0; 00136 return result; 00137 } 00138 00139 uint8_t MMA845x::enablePulseDetect(void) const 00140 { 00141 uint8_t result = 0; 00142 return result; 00143 } 00144 00145 uint8_t MMA845x::enableOrientationDetect(void) const 00146 { 00147 uint8_t result = 0; 00148 00149 if(_who_am_i != MMA8451 ) { 00150 debug("%s %d: Feature not compatible with the connected device.\n", __FILE__, __LINE__); 00151 result = 1; 00152 } 00153 00154 return result; 00155 } 00156 00157 uint8_t MMA845x::enableTransientDetect(void) const 00158 { 00159 uint8_t result = 0; 00160 return result; 00161 } 00162 00163 uint8_t MMA845x::enableAutoSleep(void) const 00164 { 00165 uint8_t result = 0; 00166 return result; 00167 } 00168 00169 uint8_t MMA845x::enableFIFO(void) const 00170 { 00171 uint8_t result = 0; 00172 00173 if(_who_am_i != MMA8451 ) { 00174 debug("%s %d: Feature not compatible with the connected device.\n", __FILE__, __LINE__); 00175 result = 1; 00176 } 00177 00178 return result; 00179 } 00180 00181 uint8_t MMA845x::activeMode(void) const 00182 { 00183 uint8_t result = 0; 00184 char datain[1]; 00185 uint8_t dataout; 00186 00187 result |= MMA845x::readRegister(CTRL_REG1,1, datain); 00188 dataout = (datain[0] & 0xFE) | 0x01 ; 00189 result |= MMA845x::writeRegister(CTRL_REG1, dataout); // Set to active mode 00190 00191 return result; 00192 } 00193 uint8_t MMA845x::standbyMode(void) const 00194 { 00195 uint8_t result = 0; 00196 char datain[1]; 00197 uint8_t dataout; 00198 00199 result |= MMA845x::readRegister(CTRL_REG1,1, datain); 00200 dataout = (datain[0] & 0xFE); 00201 result |= MMA845x::writeRegister(CTRL_REG1, dataout); // Set to standby mode 00202 00203 return result; 00204 } 00205 00206 uint8_t MMA845x::getStatus(void) const 00207 { 00208 uint8_t result = 0; 00209 char datain[1]; 00210 uint8_t dataout; 00211 00212 result = MMA845x::readRegister(STATUS,1, datain); 00213 00214 if (result != 0) 00215 dataout = result; 00216 else 00217 dataout = datain[0]; 00218 00219 return dataout; 00220 } 00221 00222 int16_t MMA845x::getX(void) 00223 { 00224 char datain[2]; 00225 00226 if (_polling_mode) { 00227 MMA845x::readRegister(OUT_X_MSB,2, datain); 00228 _data._x = ((datain[0] << 8) | datain[1]); /* data is 14 bit signed with 2 LSB = 0 */ 00229 _data._x /= 4; /* need to shift first to preserve sign then /4 to remove LSBs */ 00230 } 00231 return _data._x ; 00232 00233 } 00234 00235 int16_t MMA845x::getY(void) 00236 { 00237 char datain[2]; 00238 00239 if (_polling_mode) { 00240 MMA845x::readRegister(OUT_Y_MSB,2, datain); 00241 _data._y = ((datain[0] << 8) | datain[1]); /* data is 14 bit signed with 2 LSB = 0 */ 00242 _data._y /= 4; /* need to shift first to preserve sign then /4 to remove LSBs */ 00243 } 00244 return _data._y ; 00245 } 00246 00247 int16_t MMA845x::getZ(void) 00248 { 00249 char datain[2]; 00250 00251 if (_polling_mode) { 00252 MMA845x::readRegister(OUT_Z_MSB,2, datain); 00253 _data._z = ((datain[0] << 8) | datain[1]); /* data is 14 bit signed with 2 LSB = 0 */ 00254 _data._z /= 4; /* need to shift first to preserve sign then /4 to remove LSBs */ 00255 } 00256 00257 return _data._z ; 00258 } 00259 00260 MMA845x_DATA MMA845x::getXYZ(void) 00261 { 00262 char datain[6]; 00263 00264 if (_polling_mode) { 00265 MMA845x::readRegister(OUT_X_MSB,6, datain); /* data is 14 bit signed with 2 LSB = 0 */ 00266 _data._x = ((datain[0] << 8) | datain[1]); /* need to shift first to preserve sign */ 00267 _data._x /= 4; /* then /4 to remove LSBs */ 00268 _data._y = ((datain[2] << 8) | datain[3]); 00269 _data._y /= 4; 00270 _data._z = ((datain[4] << 8) | datain[5]); 00271 _data._z /= 4; 00272 } 00273 00274 return _data; 00275 } 00276 00277 char MMA845x::getWhoAmI(void) const 00278 { 00279 return _who_am_i; 00280 } 00281 00282 uint8_t MMA845x::writeRegister(uint8_t const reg, uint8_t const data) const 00283 { 00284 char buf[2] = {reg, data}; 00285 uint8_t result = 0; 00286 00287 buf[0] = reg; 00288 buf[1] = data; 00289 00290 result |= _i2c->write(_i2c_addr, buf, 2); 00291 00292 if (result != 0) { 00293 debug("MMA845x::writeRegister failed r-%d\n\r",result); 00294 } 00295 00296 return result; 00297 } 00298 00299 uint8_t MMA845x::readRegister(uint8_t const reg, uint8_t count, char* data) const 00300 { 00301 uint8_t result = 0; 00302 char reg_out[1]; 00303 00304 reg_out[0] = reg; 00305 _i2c->lock(); 00306 00307 // MMA8451Q expects a repeated start from the master 00308 result |= _i2c->write(_i2c_addr,reg_out,1,true); 00309 00310 if (result != 0) { 00311 debug("MMA845x::readRegister failed write r- %d\n\r", result); 00312 goto exit; 00313 } 00314 00315 result |= _i2c->read(_i2c_addr,data,count,false); 00316 00317 if (result != 0) { 00318 debug("MMA845x::readRegister failed read r-%d\n\r",result); 00319 } 00320 00321 exit: 00322 _i2c->unlock(); 00323 return result; 00324 }
Generated on Thu Jul 14 2022 17:24:22 by 1.7.2