This is a simple device driver for the 3 axis accelerometer MMA8452 that works with mbed.
Dependents: MMA8452_test S05APP3_routeur
MMA8452.cpp
00001 // Author: Nicholas Herriot 00002 /* Copyright (c) 2013 Vodafone, MIT License 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00005 * and associated documentation files (the "Software"), to deal in the Software without restriction, 00006 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00007 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00008 * furnished to do so, subject to the following conditions: 00009 * 00010 * The above copyright notice and this permission notice shall be included in all copies or 00011 * substantial portions of the Software. 00012 * 00013 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00014 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00015 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00016 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00017 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00018 */ 00019 00020 # include "MMA8452.h" 00021 00022 00023 00024 00025 00026 00027 // Connect module at I2C address using I2C port pins sda and scl 00028 Accelerometer_MMA8452::Accelerometer_MMA8452(PinName sda, PinName scl,int frequency) : m_i2c(sda, scl) , m_frequency(frequency) 00029 { 00030 //m_i2c.frequency(m_frequency); 00031 } 00032 00033 00034 // Destroys instance 00035 Accelerometer_MMA8452::~Accelerometer_MMA8452() 00036 { 00037 00038 } 00039 00040 // Setting the control register bit 1 to true to activate the MMA8452 00041 int Accelerometer_MMA8452::activate() 00042 { 00043 char mcu_address = (MMA8452_ADDRESS<<1); 00044 char init[2]; 00045 init[0] = CTRL_REG_1; // control register 1 00046 init[1] = ACTIVE; // set to active 00047 00048 if(m_i2c.write(mcu_address,init,2) == 0) 00049 { 00050 return 0; // return 0 to indicate success 00051 } 00052 else 00053 { 00054 return 1; // crumbs it failed!!! 00055 } 00056 00057 } 00058 00059 00060 // Get 'Fast Read Mode' called F_READ. If bit 1 is set '1' then F_READ is active. Fast read will skip LSB when reading xyz 00061 // resisters from 0x01 to 0x06. When F_READ is '0' then all 6 registers will be read. 00062 00063 int Accelerometer_MMA8452::get_CTRL_Reg1(int& CTRL_Reg) 00064 { 00065 { 00066 char mcu_address = (MMA8452_ADDRESS<<1); 00067 m_i2c.start(); 00068 if( m_i2c.write( mcu_address & 0xFE) == 0) // just good practice to force bit 1 to a '0' by ANDing with 0xFE 00069 { 00070 return 1; // we failed to write the mcu address on the bus to initiate dialogue 00071 } 00072 if( m_i2c.write( CTRL_REG_1) == 0) 00073 { 00074 return 1; // we failed to write 'status' to the chip 00075 } 00076 m_i2c.start(); 00077 if( m_i2c.write( mcu_address | 0x01) == 0) // this is asking to read the slave mcu address - even though it's a 'write' method!!! Crap API... 00078 { 00079 return 1; // we failed to request a read from that mcu - this really is just writing the mcu vaule on the bus 00080 } 00081 CTRL_Reg = m_i2c.read(0); 00082 m_i2c.stop(); 00083 return 0; 00084 00085 00086 } 00087 00088 00089 00090 00091 } 00092 00093 // Setting the control register bit 1 to true to activate the MMA8452 00094 int Accelerometer_MMA8452::standby() 00095 { 00096 char mcu_address = (MMA8452_ADDRESS<<1); 00097 char init[2]; 00098 init[0] = CTRL_REG_1; // control register 1 00099 init[1] = STANDBY; // set to standby 00100 00101 if(m_i2c.write(mcu_address,init,2) == 0) 00102 { 00103 // pc.printf("The initialisation worked"); 00104 return 0; // return 0 to indicate success 00105 } 00106 else 00107 { 00108 // pc.printf("The initialisation failed"); 00109 return 1; // crumbs it failed!!! 00110 } 00111 00112 } 00113 00114 00115 00116 // Device initialization 00117 void Accelerometer_MMA8452::init() 00118 { 00119 00120 write_reg(INTSU_STATUS, 0x10); // automatic interrupt after every measurement 00121 write_reg(SR_STATUS, 0x00); // 120 Samples/Second 00122 write_reg(MODE_STATUS, 0x01); // Active Mode 00123 00124 } 00125 00126 // Get real time status of device - it can be STANDBY, WAKE or SLEEP 00127 int Accelerometer_MMA8452::get_SystemMode(int& deviceSystemMode) 00128 { 00129 char mcu_address = (MMA8452_ADDRESS<<1); 00130 m_i2c.start(); 00131 if( m_i2c.write( mcu_address & 0xFE) == 0) // just good practice to force bit 1 to a '0' by ANDing with 0xFE 00132 { 00133 return 1; // we failed to write the mcu address on the bus to initiate dialogue 00134 } 00135 if( m_i2c.write( SYSMOD) == 0) 00136 { 00137 return 1; // we failed to write 'status' to the chip 00138 } 00139 m_i2c.start(); 00140 if( m_i2c.write( mcu_address | 0x01) == 0) // this is asking to read the slave mcu address - even though it's a 'write' method!!! Crap API... 00141 { 00142 return 1; // we failed to request a read from that mcu - this really is just writing the mcu vaule on the bus 00143 } 00144 deviceSystemMode = m_i2c.read(0); 00145 m_i2c.stop(); 00146 return 0; 00147 00148 00149 } 00150 00151 00152 00153 // Get real time status of device - it can be STANDBY, WAKE or SLEEP 00154 int Accelerometer_MMA8452::get_Status(int& deviceStatus) 00155 { 00156 char mcu_address = (MMA8452_ADDRESS<<1); 00157 m_i2c.start(); 00158 if( m_i2c.write( mcu_address & 0xFE) == 0) // just good practice to force bit 1 to a '0' by ANDing with 0xFE 00159 { 00160 return 1; // we failed to write the mcu address on the bus to initiate dialogue 00161 } 00162 if( m_i2c.write( STATUS) == 0) 00163 { 00164 return 1; // we failed to write 'status' to the chip 00165 } 00166 m_i2c.start(); 00167 if( m_i2c.write( mcu_address | 0x01) == 0) // this is asking to read the slave mcu address - even though it's a 'write' method!!! Crap API... 00168 { 00169 return 1; // we failed to request a read from that mcu - this really is just writing the mcu vaule on the bus 00170 } 00171 deviceStatus = m_i2c.read(0); 00172 m_i2c.stop(); 00173 return 0; 00174 00175 00176 } 00177 00178 00179 // Get device ID 00180 int Accelerometer_MMA8452::get_DeviceID(int& deviceID) 00181 { 00182 char mcu_address = (MMA8452_ADDRESS<<1); 00183 m_i2c.start(); 00184 if( m_i2c.write( mcu_address & 0xFE) == 0) // just good practice to force bit 1 to a '0' by ANDing with 0xFE 00185 { 00186 return 1; // we failed to write the mcu address on the bus to initiate dialogue 00187 } 00188 if( m_i2c.write( WHO_AM_I) == 0) 00189 { 00190 return 1; // we failed to write 'who am i' to the chip 00191 } 00192 m_i2c.start(); 00193 if( m_i2c.write( mcu_address | 0x01) == 0) // this is asking to read the slave mcu address - even though it's a 'write' method!!! Crap API... 00194 { 00195 return 1; // we failed to request a read from that mcu - this really is just writing the mcu vaule on the bus 00196 } 00197 deviceID = m_i2c.read(0); 00198 m_i2c.stop(); 00199 return 0; 00200 00201 } 00202 00203 00204 /* 00205 // Reads x data 00206 int Accelerometer_MMA8452::read_x(int& xaxisLSB) 00207 { 00208 char mcu_address = (MMA8452_ADDRESS<<1); 00209 m_i2c.start(); 00210 if( m_i2c.write( mcu_address & 0xFE) == 0) // just good practice to force bit 1 to a '0' by ANDing with 0xFE 00211 { 00212 return 1; // we failed to write the mcu address on the bus to initiate dialogue 00213 } 00214 if( m_i2c.write( OUT_X_MSB) == 0) 00215 { 00216 return 1; // we failed to write 'X axis LSB' to the chip 00217 } 00218 m_i2c.start(); 00219 if( m_i2c.write( mcu_address | 0x01) == 0) // this is asking to read the slave mcu address - even though it's a 'write' method!!! Crap API... 00220 { 00221 return 1; // we failed to request a read from that mcu - this really is just writing the mcu vaule on the bus 00222 } 00223 xaxisLSB = m_i2c.read(0); 00224 m_i2c.stop(); 00225 return 0; 00226 } 00227 */ 00228 00229 00230 // Reads x data. This method reads two registers containing the x-axis values from the accelerometer. 00231 // It takes a 2 byte char array and copies the register values into the buffer. If it fails the char array 00232 // is set to '0'. It returns '0' success '1' fail. This method does nothing to the registers - just returns 00233 // the raw data. 00234 //int Accelerometer_MMA8452::read_x(int& xaxisLSB) 00235 int Accelerometer_MMA8452::read_x_raw(char *xaxis) 00236 { 00237 char mcu_address = (MMA8452_ADDRESS<<1); // this is the slave address on the bus we want data from 00238 char xaxis_buffer[2]; // this will contain data from that register 00239 char xaxis_register[1]; 00240 xaxis_register[0] = OUT_X_MSB; // this is the register we want to get data from 00241 //signed short s = 0; 00242 00243 if(m_i2c.write(mcu_address,xaxis_register,1,true) == 0) 00244 { 00245 if(m_i2c.read(mcu_address,xaxis_buffer,2) == 0) 00246 { 00247 //strcpy(xaxis, xaxis_buffer); 00248 memcpy(xaxis, xaxis_buffer, 2); 00249 //xaxis[0] = 0x00; // make sure the array is set to zero 00250 //xaxis[1] = 0x00; 00251 //s = *reinterpret_cast<short*>(&xaxis); 00252 return 0; // great we got the two octets 00253 } 00254 else 00255 { 00256 xaxis[0] = 0x00; // make sure the array is set to zero 00257 xaxis[1] = 0x00; 00258 return 1; // failed to read the 12 bit x value 00259 } 00260 } 00261 else 00262 { 00263 xaxis[0] = 0x00; // make sure the array is set to zero 00264 xaxis[1] = 0x00; 00265 return 1; // failed to write and request the OUT_X_MSB bit 00266 } 00267 } 00268 00269 00270 // Reads y data. This method reads two registers containing the x-axis values from the accelerometer. 00271 // It takes a 2 byte char array and copies the register values into the buffer. If it fails the char array 00272 // is set to '0'. It returns '0' success '1' fail. This method does nothing to the registers - just returns 00273 // the raw data. 00274 00275 int Accelerometer_MMA8452::read_y_raw(char *yaxis) 00276 { 00277 char mcu_address = (MMA8452_ADDRESS<<1); // this is the slave address on the bus we want data from 00278 char yaxis_buffer[2]; // this will contain data from that register 00279 char yaxis_register[1]; 00280 yaxis_register[0] = OUT_Y_MSB; // this is the register we want to get data from 00281 //signed short s = 0; 00282 00283 if(m_i2c.write(mcu_address,yaxis_register,1,true) == 0) 00284 { 00285 if(m_i2c.read(mcu_address,yaxis_buffer,2) == 0) 00286 { 00287 //strcpy(yaxis, yaxis_buffer); 00288 memcpy(yaxis, yaxis_buffer, 2); 00289 //yaxis[0] = 0x00; // make sure the array is set to zero 00290 //yaxis[1] = 0x00; 00291 //s = *reinterpret_cast<short*>(&xaxis); 00292 return 0; // great we got the two octets 00293 } 00294 else 00295 { 00296 yaxis[0] = 0x00; // make sure the array is set to zero 00297 yaxis[1] = 0x00; 00298 return 1; // failed to read the 12 bit y value 00299 } 00300 } 00301 else 00302 { 00303 yaxis[0] = 0x00; // make sure the array is set to zero 00304 yaxis[1] = 0x00; 00305 return 1; // failed to write and request the OUT_Y_MSB bit 00306 } 00307 } 00308 00309 00310 00311 // Reads z data. This method reads two registers containing the x-axis values from the accelerometer. 00312 // It takes a 2 byte char array and copies the register values into the buffer. If it fails the char array 00313 // is set to '0'. It returns '0' success '1' fail. This method does nothing to the registers - just returns 00314 // the raw data. 00315 00316 int Accelerometer_MMA8452::read_z_raw(char *zaxis) 00317 { 00318 char mcu_address = (MMA8452_ADDRESS<<1); // this is the slave address on the bus we want data from 00319 char zaxis_buffer[2]; // this will contain data from that register 00320 char zaxis_register[1]; 00321 zaxis_register[0] = OUT_Z_MSB; // this is the register we want to get data from 00322 //signed short s = 0; 00323 00324 if(m_i2c.write(mcu_address,zaxis_register,1,true) == 0) 00325 { 00326 //if(m_i2c.read(mcu_address,zaxis_buffer,2) == 0) 00327 if(m_i2c.read(mcu_address,zaxis,2) == 0) 00328 { 00329 //strcpy(yaxis, yaxis_buffer); 00330 //memcpy(zaxis, zaxis_buffer, 2); 00331 //yaxis[0] = 0x00; // make sure the array is set to zero 00332 //yaxis[1] = 0x00; 00333 //s = *reinterpret_cast<short*>(&xaxis); 00334 return 0; // great we got the two octets 00335 } 00336 else 00337 { 00338 zaxis[0] = 0x00; // make sure the array is set to zero 00339 zaxis[1] = 0x00; 00340 return 1; // failed to read the 12 bit y value 00341 } 00342 } 00343 else 00344 { 00345 zaxis[0] = 0x00; // make sure the array is set to zero 00346 zaxis[1] = 0x00; 00347 return 1; // failed to write and request the OUT_Y_MSB bit 00348 } 00349 } 00350 00351 00352 00353 // Reads y data 00354 int Accelerometer_MMA8452::read_y() 00355 { 00356 char mcu_address = (MMA8452_ADDRESS <<1); 00357 00358 m_i2c.start(); // Start 00359 m_i2c.write(mcu_address); // A write to device 0x98 00360 m_i2c.write(OUT_Y_MSB); // Register to read 00361 m_i2c.start(); 00362 m_i2c.write(mcu_address); // Read from device 0x99 00363 int y = m_i2c.read(0); // Read the data 00364 m_i2c.stop(); 00365 00366 return y; 00367 00368 } 00369 00370 00371 // Reads z data 00372 int Accelerometer_MMA8452::read_z() 00373 { 00374 char mcu_address = (MMA8452_ADDRESS <<1); 00375 00376 m_i2c.start(); // Start 00377 m_i2c.write(mcu_address); // A write to device 0x98 00378 m_i2c.write(OUT_Z_MSB); // Register to read 00379 m_i2c.start(); 00380 m_i2c.write(mcu_address); // Read from device 0x99 00381 int z = m_i2c.read(0); // Read the data 00382 m_i2c.stop(); 00383 00384 return z; 00385 00386 } 00387 00388 00389 // Reads xyz 00390 int Accelerometer_MMA8452::read_xyz(char *x, char *y, char *z) 00391 { 00392 00393 00394 char mcu_address = (MMA8452_ADDRESS <<1); 00395 char register_buffer[6] ={0,0,0,0,0,0}; 00396 const char Addr_X = OUT_X_MSB; 00397 m_i2c.write(mcu_address); // A write to device 0x98 00398 m_i2c.write(MMA8452_ADDRESS, &Addr_X, 1); // Pointer to the OUT_X_MSB register 00399 00400 if(m_i2c.write(mcu_address,&Addr_X,1) == 0) 00401 { 00402 if(m_i2c.read(mcu_address,register_buffer,6) == 0) 00403 { 00404 *x = register_buffer[1]; 00405 *y = register_buffer[3]; 00406 *z = register_buffer[5]; 00407 return 0; // yahoooooo 00408 } 00409 else 00410 { 00411 return 1; // failed oh nooo! 00412 } 00413 } 00414 else 00415 { 00416 return 1; // failed oh nooo! 00417 } 00418 00419 } 00420 00421 // Write register (The device must be placed in Standby Mode to change the value of the registers) 00422 void Accelerometer_MMA8452::write_reg(char addr, char data) 00423 { 00424 00425 char cmd[2] = {0, 0}; 00426 00427 cmd[0] = MODE_STATUS; 00428 cmd[1] = 0x00; // Standby Mode on 00429 m_i2c.write(MMA8452_ADDRESS, cmd, 2); 00430 00431 cmd[0] = addr; 00432 cmd[1] = data; // New value of the register 00433 m_i2c.write(MMA8452_ADDRESS, cmd, 2); 00434 00435 cmd[0] = MODE_STATUS; 00436 cmd[1] = 0x01; // Active Mode on 00437 m_i2c.write(MMA8452_ADDRESS, cmd, 2); 00438 00439 } 00440 00441 00442 00443 // Read from specified MMA7660FC register 00444 char Accelerometer_MMA8452::read_reg(char addr) 00445 { 00446 00447 m_i2c.start(); // Start 00448 m_i2c.write(0x98); // A write to device 0x98 00449 m_i2c.write(addr); // Register to read 00450 m_i2c.start(); 00451 m_i2c.write(0x99); // Read from device 0x99 00452 char c = m_i2c.read(0); // Read the data 00453 m_i2c.stop(); 00454 00455 return c; 00456 00457 } 00458 00459 00460 00461 00462 00463
Generated on Fri Jul 15 2022 20:22:25 by
![doxygen](doxygen.png)