Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
MMA8452.h
00001 #pragma once 00002 00003 // Authors: Ashley Mills, Nicholas Herriot 00004 /* Copyright (c) 2013 Vodafone, MIT License 00005 * 00006 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00007 * and associated documentation files (the "Software"), to deal in the Software without restriction, 00008 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00009 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00010 * furnished to do so, subject to the following conditions: 00011 * 00012 * The above copyright notice and this permission notice shall be included in all copies or 00013 * substantial portions of the Software. 00014 * 00015 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00016 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00017 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00018 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00019 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00020 */ 00021 00022 // the SparkFun breakout board defaults to 1, set to 0 if SA0 jumper on the bottom of the board is set 00023 // see the Table 10. I2C Device Address Sequence in Freescale MMA8452Q pdf 00024 00025 #include "mbed.h" 00026 00027 #define MMA8452_DEBUG 1 00028 00029 // More info on MCU Master address can be found on section 5.10.1 of http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=MMA8452Q 00030 #define SA0 1 00031 #if SA0 00032 #define MMA8452_ADDRESS 0x3A // 0x1D<<1 // SA0 is high, 0x1C if low - 00033 #else 00034 #define MMA8452_ADDRESS 0x38 // 0x1C<<1 00035 #endif 00036 00037 // Register descriptions found in section 6 of pdf 00038 #define MMA8452_STATUS 0x00 // Type 'read' : Status of the data registers 00039 #define MMA8452_OUT_X_MSB 0x01 // Type 'read' : x axis - MSB of 2 byte sample 00040 #define MMA8452_OUT_X_LSB 0x02 // Type 'read' : x axis - LSB of 2 byte sample 00041 #define MMA8452_OUT_Y_MSB 0x03 // Type 'read' : y axis - MSB of 2 byte sample 00042 #define MMA8452_OUT_Y_LSB 0x04 // Type 'read' : y axis - LSB of 2 byte sample 00043 #define MMA8452_OUT_Z_MSB 0x05 // Type 'read' : z axis - MSB of 2 byte sample 00044 #define MMA8452_OUT_Z_LSB 0x06 // Type 'read' : z axis - LSB of 2 byte sample 00045 00046 // register definitions 00047 #define MMA8452_XYZ_DATA_CFG 0x0E 00048 00049 #define MMA8452_SYSMOD 0x0B // Type 'read' : This tells you if device is active, sleep or standy 0x00=STANDBY 0x01=WAKE 0x02=SLEEP 00050 #define MMA8452_WHO_AM_I 0x0D // Type 'read' : This should return the device id of 0x2A 00051 00052 #define MMA8452_PL_STATUS 0x10 // Type 'read' : This shows portrait landscape mode orientation 00053 #define MMA8452_PL_CFG 0x11 // Type 'read/write' : This allows portrait landscape configuration 00054 #define MMA8452_PL_COUNT 0x12 // Type 'read' : This is the portraint landscape debounce counter 00055 #define MMA8452_PL_BF_ZCOMP 0x13 // Type 'read' : 00056 #define MMA8452_PL_THS_REG 0x14 // Type 'read' : 00057 00058 #define MMA8452_FF_MT_CFG 0X15 // Type 'read/write' : Freefaul motion functional block configuration 00059 #define MMA8452_FF_MT_SRC 0X16 // Type 'read' : Freefaul motion event source register 00060 #define MMA8452_FF_MT_THS 0X17 // Type 'read' : Freefaul motion threshold register 00061 #define MMA8452_FF_COUNT 0X18 // Type 'read' : Freefaul motion debouce counter 00062 00063 #define MMA8452_ASLP_COUNT 0x29 // Type 'read/write' : Counter settings for auto sleep 00064 #define MMA8452_CTRL_REG_1 0x2A // Type 'read/write' : 00065 #define MMA8452_CTRL_REG_2 0x2B // Type 'read/write' : 00066 #define MMA8452_CTRL_REG_3 0x2C // Type 'read/write' : 00067 #define MMA8452_CTRL_REG_4 0x2D // Type 'read/write' : 00068 #define MMA8452_CTRL_REG_5 0x2E // Type 'read/write' : 00069 00070 // Defined in table 13 of the Freescale PDF 00071 /// xxx these all need to have better names 00072 #define STANDBY 0x00 // State value returned after a SYSMOD request, it can be in state STANDBY, WAKE or SLEEP 00073 #define WAKE 0x01 // State value returned after a SYSMOD request, it can be in state STANDBY, WAKE or SLEEP 00074 #define SLEEP 0x02 // State value returned after a SYSMOD request, it can be in state STANDBY, WAKE or SLEEP 00075 #define ACTIVE 0x01 // Stage value returned and set in Control Register 1, it can be STANDBY=00, or ACTIVE=01 00076 00077 #define TILT_STATUS 0x03 // Tilt Status (Read only) 00078 #define SRST_STATUS 0x04 // Sample Rate Status Register (Read only) 00079 #define SPCNT_STATUS 0x05 // Sleep Count Register (Read/Write) 00080 #define INTSU_STATUS 0x06 // Interrupt Setup Register 00081 #define MODE_STATUS 0x07 // Mode Register (Read/Write) 00082 #define SR_STATUS 0x08 // Auto-Wake and Active Mode Portrait/Landscape Samples per Seconds Register (Read/Write) 00083 #define PDET_STATUS 0x09 // Tap/Pulse Detection Register (Read/Write) 00084 #define PD_STATUS 0xA // Tap/Pulse Debounce Count Register (Read/Write) 00085 00086 // masks for enabling/disabling standby 00087 #define MMA8452_ACTIVE_MASK 0x01 00088 #define MMA8452_STANDBY_MASK 0xFE 00089 00090 // mask for dynamic range reading and writing 00091 #define MMA8452_DYNAMIC_RANGE_MASK 0xFC 00092 00093 // mask and shift for data rate reading and writing 00094 #define MMA8452_DATA_RATE_MASK 0xC7 00095 #define MMA8452_DATA_RATE_MASK_SHIFT 0x03 00096 00097 // mask and shift for general reading and writing 00098 #define MMA8452_WRITE_MASK 0xFE 00099 #define MMA8452_READ_MASK 0x01 00100 00101 // mask and shift for bit depth reading and writing 00102 #define MMA8452_BIT_DEPTH_MASK 0xFD 00103 #define MMA8452_BIT_DEPTH_MASK_SHIFT 0x01 00104 00105 // status masks and shifts 00106 #define MMA8452_STATUS_ZYXDR_MASK 0x08 00107 #define MMA8452_STATUS_ZDR_MASK 0x04 00108 #define MMA8452_STATUS_YDR_MASK 0x02 00109 #define MMA8452_STATUS_XDR_MASK 0x01 00110 00111 /** 00112 * Wrapper for the MMA8452 I2C driven accelerometer. 00113 */ 00114 class MMA8452 { 00115 00116 public: 00117 00118 enum DynamicRange { 00119 DYNAMIC_RANGE_2G=0x00, 00120 DYNAMIC_RANGE_4G, 00121 DYNAMIC_RANGE_8G, 00122 DYNAMIC_RANGE_UNKNOWN 00123 }; 00124 00125 enum BitDepth { 00126 BIT_DEPTH_12=0x00, 00127 BIT_DEPTH_8, // 1 sets fast read mode, hence the inversion 00128 BIT_DEPTH_UNKNOWN 00129 }; 00130 00131 enum DataRateHz { 00132 RATE_800=0x00, 00133 RATE_400, 00134 RATE_200, 00135 RATE_100, 00136 RATE_50, 00137 RATE_12_5, 00138 RATE_6_25, 00139 RATE_1_563, 00140 RATE_UNKNOWN 00141 }; 00142 00143 /** 00144 * Create an accelerometer object connected to the specified I2C pins. 00145 * 00146 * @param sda I2C data port 00147 * @param scl I2C clock port 00148 * @param frequency 00149 * 00150 */ 00151 MMA8452(PinName sda, PinName scl, int frequency); 00152 00153 /// Destructor 00154 ~MMA8452(); 00155 00156 /** 00157 * Puts the MMA8452 in active mode. 00158 * @return 0 on success, 1 on failure. 00159 */ 00160 int activate(); 00161 00162 /** 00163 * Puts the MMA8452 in standby. 00164 * @return 0 on success, 1 on failure. 00165 */ 00166 int standby(); 00167 00168 /** 00169 * Read the device ID from the accelerometer (should be 0x2a) 00170 * 00171 * @param dst pointer to store the ID 00172 * @return 0 on success, 1 on failure. 00173 */ 00174 int getDeviceID(char* dst); 00175 00176 /** 00177 * Read the MMA8452 status register. 00178 * 00179 * @param dst pointer to store the register value. 00180 * @ return 0 on success, 1 on failure. 00181 */ 00182 int getStatus(char* dst); 00183 00184 /** 00185 * Read the raw x, y, an z registers of the MMA8452 in one operation. 00186 * All three registers are read sequentially and stored in the provided buffer. 00187 * The stored values are signed 2's complement left-aligned 12 or 8 bit integers. 00188 * 00189 * @param dst The destination buffer. Note that this needs to be 3 bytes for 00190 * BIT_DEPTH_8 and 6 bytes for BIT_DEPTH_12. It is upto the caller to ensure this. 00191 * @return 0 for success, and 1 for failure 00192 * @sa setBitDepth 00193 */ 00194 int readXYZRaw(char *dst); 00195 00196 /// Read the raw x register into the provided buffer. @sa readXYZRaw 00197 int readXRaw(char *dst); 00198 /// Read the raw y register into the provided buffer. @sa readXYZRaw 00199 int readYRaw(char *dst); 00200 /// Read the raw z register into the provided buffer. @sa readXYZRaw 00201 int readZRaw(char *dst); 00202 00203 /** 00204 * Read the x, y, and z signed counts of the MMA8452 axes. 00205 * 00206 * Count resolution is either 8 bits or 12 bits, and the range is either +-2G, +-4G, or +-8G 00207 * depending on settings. The number of counts per G are 1024, 512, 256 for 2,4, and 8 G 00208 * respectively at 12 bit resolution and 64, 32, 16 for 2, 4, and 8 G respectively at 00209 * 8 bit resolution. 00210 * 00211 * This function queries the MMA8452 and returns the signed counts for each axes. 00212 * 00213 * @param x Pointer to integer to store x count 00214 * @param y Pointer to integer to store y count 00215 * @param z Pointer to integer to store z count 00216 * @return 0 on success, 1 on failure. 00217 */ 00218 int readXYZCounts(int *x, int *y, int *z); 00219 00220 /// Read the x axes signed count. @sa readXYZCounts 00221 int readXCount(int *x); 00222 /// Read the y axes signed count. @sa readXYZCounts 00223 int readYCount(int *y); 00224 /// Read the z axes signed count. @sa readXYZCounts 00225 int readZCount(int *z); 00226 00227 /** 00228 * Read the x, y, and z accelerations measured in G. 00229 * 00230 * The measurement resolution is controlled via setBitDepth which can 00231 * be 8 or 12, and by setDynamicRange, which can be +-2G, +-4G, or +-8G. 00232 * 00233 * @param x A pointer to the double to store the x acceleration in. 00234 * @param y A pointer to the double to store the y acceleration in. 00235 * @param z A pointer to the double to store the z acceleration in. 00236 * 00237 * @return 0 on success, 1 on failure. 00238 */ 00239 int readXYZGravity(double *x, double *y, double *z); 00240 00241 /// Read the x gravity in G into the provided double pointer. @sa readXYZGravity 00242 int readXGravity(double *x); 00243 /// Read the y gravity in G into the provided double pointer. @sa readXYZGravity 00244 int readYGravity(double *y); 00245 /// Read the z gravity in G into the provided double pointer. @sa readXYZGravity 00246 int readZGravity(double *z); 00247 00248 /// Returns 1 if data has been internally sampled (is available) for all axes since last read, 0 otherwise. 00249 int isXYZReady(); 00250 /// Returns 1 if data has been internally sampled (is available) for the x-axis since last read, 0 otherwise. 00251 int isXReady(); 00252 /// Returns 1 if data has been internally sampled (is available) for the y-axis since last read, 0 otherwise. 00253 int isYReady(); 00254 /// Returns 1 if data has been internally sampled (is available) for the z-axis since last read, 0 otherwise. 00255 int isZReady(); 00256 00257 /** 00258 * Reads a single byte from the specified MMA8452 register. 00259 * 00260 * @param addr The internal register address. 00261 * @param dst The destination buffer address. 00262 * @return 1 on success, 0 on failure. 00263 */ 00264 int readRegister(char addr, char *dst); 00265 00266 /** 00267 * Reads n bytes from the specified MMA8452 register. 00268 * 00269 * @param addr The internal register address. 00270 * @param dst The destination buffer address. 00271 * @param nbytes The number of bytes to read. 00272 * @return 1 on success, 0 on failure. 00273 */ 00274 int readRegister(char addr, char *dst, int nbytes); 00275 00276 /** 00277 * Write to the specified MMA8452 register. 00278 * 00279 * @param addr The internal register address 00280 * @param data Data byte to write 00281 */ 00282 int writeRegister(char addr, char data); 00283 00284 /** 00285 * Write a data buffer to the specified MMA8452 register. 00286 * 00287 * @param addr The internal register address 00288 * @param data Pointer to data buffer to write 00289 * @param nbytes The length of the data buffer to write 00290 */ 00291 int writeRegister(char addr, char *data, int nbytes); 00292 00293 int setDynamicRange(DynamicRange range, int toggleActivation=1); 00294 int setBitDepth(BitDepth depth, int toggleActivation=1); 00295 int setDataRate(DataRateHz dataRate, int toggleActivation=1); 00296 00297 DynamicRange getDynamicRange(); 00298 DataRateHz getDataRate(); 00299 BitDepth getBitDepth(); 00300 00301 #ifdef MMA8452_DEBUG 00302 void debugRegister(char reg); 00303 #endif 00304 00305 private: 00306 /** 00307 * Reads the specified register, applies the mask with logical AND, logical ORs the value 00308 * and writes back the result to the register. If toggleActivation is set to true then the 00309 * device is put in standby before the operation, and activated at the end. 00310 * Setting it to false is useful for setting options on a device that you want to keep in 00311 * standby. 00312 */ 00313 int maskAndApplyRegister(char reg, char mask, char value, int toggleActivation); 00314 00315 /// Reads the specified register, applies the mask with logical AND, and writes the result back. 00316 int logicalANDRegister(char addr, char mask); 00317 /// Reads the specified register, applies the mask with logical OR, and writes the result back. 00318 int logicalORRegister(char addr, char mask); 00319 /// Reads the specified register, applies the mask with logical XOR, and writes the result back. 00320 int logicalXORRegister(char addr, char mask); 00321 00322 /// Converts the 12-bit two's complement number in buf to a signed integer. Returns the integer. 00323 int twelveBitToSigned(char *buf); 00324 /// Converts the 8-bit two's complement number in buf to a signed integer. Returns the integer. 00325 int eightBitToSigned(char *buf); 00326 00327 /// Converts a count to a gravity using the supplied countsPerG. Returns the gravity. 00328 double convertCountToGravity(int count, int countsPerG); 00329 00330 /// Reads the register at addr, applies the mask with logical AND, and returns the result. 00331 char getMaskedRegister(int addr, char mask); 00332 00333 /// Get the counts per G for the current settings of bit depth and dynamic range. 00334 int getCountsPerG(); 00335 00336 I2C _i2c; 00337 int _frequency; 00338 int _readAddress; 00339 int _writeAddress; 00340 00341 BitDepth _bitDepth; 00342 DynamicRange _dynamicRange; 00343 };
Generated on Tue Jul 12 2022 11:35:54 by
1.7.2