This is a simple device driver for the 3 axis accelerometer MMA8452 that works with mbed.

Dependents:   MMA8452_test S05APP3_routeur

Revision:
3:ffb0b1650ca2
Parent:
2:66db0f91b215
Child:
4:27aa3cd43234
--- a/MMA8452.cpp	Tue Oct 08 16:13:14 2013 +0000
+++ b/MMA8452.cpp	Wed Oct 16 14:11:04 2013 +0000
@@ -21,8 +21,6 @@
 
 
 
-float TILT_XY[64] = {0, 2.69, 5.38, 8.08, 10.81, 13.55, 16.33, 19.16, 22.02, 24.95, 27.95, 31.04, 34.23, 37.54, 41.01, 44.68, 48.59, 52.83, 57.54, 62.95, 69.64, 79.86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -79.86, -69.64, -62.95, -57.54, -52.83, -48.59, -44.68, -41.01, -37.54, -34.23, -31.04, -27.95, -24.95, -22.02, -19.16, -16.33, -13.55, -10.81, -8.08, -5.38, -2.69}; 
-float TILT_Z[64] = {90.00, 87.31, 84.62, 81.92, 79.19, 76.45, 73.67, 70.84, 67.98, 65.05, 62.05, 58.96, 55.77, 52.46, 48.99, 45.32, 41.41, 37.17, 32.46, 27.05, 20.36, 10.14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10.14, -20.36, -27.05, -32.46, -37.17, -41.41, -45.32, -48.99, -52.46, -55.77, -58.96, -62.05, -65.05, -67.98, -70.84, -73.67, -76.45, -79.19, -81.92, -84.62};
 
 
 
@@ -45,8 +43,27 @@
     char mcu_address = (MMA8452_ADDRESS<<1);
     char init[2];
     init[0] = CTRL_REG_1;                 // control register 1
-    init[1] = 0x01;                       // set to active
-    //while(m_i2c.write(mcu_address,init,2));
+    init[1] = ACTIVE;                     // set to active
+    
+    if(m_i2c.write(mcu_address,init,2) == 0)
+    {
+         return 0;  // return 0 to indicate success
+    }
+    else
+    {
+        return 1;   // crumbs it failed!!!
+    }
+         
+}
+
+
+// Setting the control register bit 1 to true to activate the MMA8452
+int Accelerometer_MMA8452::standby()
+{
+    char mcu_address = (MMA8452_ADDRESS<<1);
+    char init[2];
+    init[0] = CTRL_REG_1;                 // control register 1
+    init[1] = STANDBY;                    // set to standby
     
     if(m_i2c.write(mcu_address,init,2) == 0)
     {
@@ -62,6 +79,7 @@
 }
 
 
+
 // Device initialization
 void Accelerometer_MMA8452::init()
 {
@@ -72,79 +90,230 @@
     
 }
 
+// Get real time status of device - it can be STANDBY, WAKE or SLEEP
+int Accelerometer_MMA8452::get_SystemMode(int& deviceSystemMode)
+{
+    char mcu_address = (MMA8452_ADDRESS<<1);
+    m_i2c.start();
+    if( m_i2c.write( mcu_address & 0xFE) == 0)          // just good practice to force bit 1 to a '0' by ANDing with 0xFE
+    {
+        return 1;                                       // we failed to write the mcu address on the bus to initiate dialogue 
+    }
+    if( m_i2c.write( SYSMOD) == 0) 
+    {
+        return 1;                                       // we failed to write 'status' to the chip
+    }
+    m_i2c.start();
+    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...
+    {
+        return 1;                                       // we failed to request a read from that mcu - this really is just writing the mcu vaule on the bus
+    }
+    deviceSystemMode  = m_i2c.read(0);
+    m_i2c.stop();
+    return 0;
+    
+
+}
+
+
+
+// Get real time status of device - it can be STANDBY, WAKE or SLEEP
+int Accelerometer_MMA8452::get_Status(int& deviceStatus)
+{
+    char mcu_address = (MMA8452_ADDRESS<<1);
+    m_i2c.start();
+    if( m_i2c.write( mcu_address & 0xFE) == 0)          // just good practice to force bit 1 to a '0' by ANDing with 0xFE
+    {
+        return 1;                                       // we failed to write the mcu address on the bus to initiate dialogue 
+    }
+    if( m_i2c.write( STATUS) == 0) 
+    {
+        return 1;                                       // we failed to write 'status' to the chip
+    }
+    m_i2c.start();
+    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...
+    {
+        return 1;                                       // we failed to request a read from that mcu - this really is just writing the mcu vaule on the bus
+    }
+    deviceStatus  = m_i2c.read(0);
+    m_i2c.stop();
+    return 0;
+    
+
+}
+
 
 // Get device ID 
 int Accelerometer_MMA8452::get_DeviceID(int& deviceID)
 {
     char mcu_address = (MMA8452_ADDRESS<<1);
-    int z = 0;
     m_i2c.start();
-    wait( 0.1);
-    if( m_i2c.write( mcu_address) == 0) 
+    if( m_i2c.write( mcu_address & 0xFE) == 0)          // just good practice to force bit 1 to a '0' by ANDing with 0xFE
     {
-        //printf( "GetDeviceId NAK on writing address");
-        return 1;
+        return 1;                                       // we failed to write the mcu address on the bus to initiate dialogue 
     }
-    wait( 0.1);
     if( m_i2c.write( WHO_AM_I) == 0) 
     {
-        //printf( "GetDeviceId NAK on writing register address");
-
-        return 1;
+        return 1;                                       // we failed to write 'who am i' to the chip
     }
-    wait( 0.1);
     m_i2c.start();
-    wait( 0.1);
-    if( m_i2c.write( mcu_address | 0x01) == 0)          // this is asking to read the slave address - even though it's a 'write' method!!! Crap API...
+    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...
     {
-        //printf( "GetDeviceId NAK on writing address");
-
-        return 1;
+        return 1;                                       // we failed to request a read from that mcu - this really is just writing the mcu vaule on the bus
     }
-    wait( 0.1);
     deviceID  = m_i2c.read(0);
-    z = m_i2c.read(0);
-    wait( 0.1);
     m_i2c.stop();
     return 0;
 
 }
 
 
-// Reads the tilt angle
-void Accelerometer_MMA8452::read_Tilt(float *x, float *y, float *z)
+/*
+// Reads x data
+int Accelerometer_MMA8452::read_x(int& xaxisLSB)
 {
+    char mcu_address = (MMA8452_ADDRESS<<1);
+    m_i2c.start();
+    if( m_i2c.write( mcu_address & 0xFE) == 0)          // just good practice to force bit 1 to a '0' by ANDing with 0xFE
+    {
+        return 1;                                       // we failed to write the mcu address on the bus to initiate dialogue 
+    }
+    if( m_i2c.write( OUT_X_MSB) == 0) 
+    {
+        return 1;                                       // we failed to write 'X axis LSB' to the chip
+    }
+    m_i2c.start();
+    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...
+    {
+        return 1;                                       // we failed to request a read from that mcu - this really is just writing the mcu vaule on the bus
+    }
+    xaxisLSB  = m_i2c.read(0);
+    m_i2c.stop();
+    return 0;
+}
+*/
 
-    const char Addr_X = OUT_X_MSB;
-    char buf[3] = {0,0,0};
+
+// Reads x data. This method reads two registers containing the x-axis values from the accelerometer. 
+// It takes a 2 byte char array and copies the register values into the buffer. If it fails the char array
+// is set to '0'. It returns '0' success '1' fail. This method does nothing to the registers - just returns
+// the raw data.
+//int Accelerometer_MMA8452::read_x(int& xaxisLSB)
+int Accelerometer_MMA8452::read_x_raw(char *xaxis)
+{
+    char mcu_address = (MMA8452_ADDRESS<<1);                // this is the slave address on the bus we want data from
+    char xaxis_buffer[2];                                   // this will contain data from that register
+    char xaxis_register[1];                     
+    xaxis_register[0] = OUT_X_MSB;                          // this is the register we want to get data from
+    //signed short s = 0;
     
-    m_i2c.write(MMA8452_ADDRESS, &Addr_X, 1);         // Pointer to the OUT_X_MSB register
-    m_i2c.read(MMA8452_ADDRESS, buf, 3);              // Read register content into buffer with 6bit
-    
-    // returns the x, y, z coordinates transformed into full degrees
-    *x = TILT_XY[(int)buf[0]];
-    *y = TILT_XY[(int)buf[1]];
-    *z = TILT_Z[(int)buf[2]];      
-  
+    if(m_i2c.write(mcu_address,xaxis_register,1) == 0)
+    {
+        if(m_i2c.read(mcu_address,xaxis_buffer,2) == 0)
+        {
+            //strcpy(xaxis, xaxis_buffer);
+            memcpy(xaxis, xaxis_buffer, 2);
+            //xaxis[0] = 0x00;                        // make sure the array is set to zero
+            //xaxis[1] = 0x00;
+            //s = *reinterpret_cast<short*>(&xaxis);
+            return 0;                               // great we got the two octets
+        }
+        else
+        {
+            xaxis[0] = 0x00;                        // make sure the array is set to zero
+            xaxis[1] = 0x00;
+            return 1;                               // failed to read the 12 bit x value
+        }
+    }
+    else
+    {
+        xaxis[0] = 0x00;                            // make sure the array is set to zero
+        xaxis[1] = 0x00;
+        return 1;                                   // failed to write and request the OUT_X_MSB bit
+    }    
 }
 
 
-// Reads x data
-int Accelerometer_MMA8452::read_x()
+// Reads y data. This method reads two registers containing the x-axis values from the accelerometer. 
+// It takes a 2 byte char array and copies the register values into the buffer. If it fails the char array
+// is set to '0'. It returns '0' success '1' fail. This method does nothing to the registers - just returns
+// the raw data.
+
+int Accelerometer_MMA8452::read_y_raw(char *yaxis)
 {
-    char mcu_address = (MMA8452_ADDRESS <<1);
+    char mcu_address = (MMA8452_ADDRESS<<1);                // this is the slave address on the bus we want data from
+    char yaxis_buffer[2];                                   // this will contain data from that register
+    char yaxis_register[1];                     
+    yaxis_register[0] = OUT_Y_MSB;                          // this is the register we want to get data from
+    //signed short s = 0;
+    
+    if(m_i2c.write(mcu_address,yaxis_register,1) == 0)
+    {
+        if(m_i2c.read(mcu_address,yaxis_buffer,2) == 0)
+        {
+            //strcpy(yaxis, yaxis_buffer);
+            memcpy(yaxis, yaxis_buffer, 2);
+            //yaxis[0] = 0x00;                        // make sure the array is set to zero
+            //yaxis[1] = 0x00;
+            //s = *reinterpret_cast<short*>(&xaxis);
+            return 0;                               // great we got the two octets
+        }
+        else
+        {
+            yaxis[0] = 0x00;                        // make sure the array is set to zero
+            yaxis[1] = 0x00;
+            return 1;                               // failed to read the 12 bit y value
+        }
+    }
+    else
+    {
+        yaxis[0] = 0x00;                            // make sure the array is set to zero
+        yaxis[1] = 0x00;
+        return 1;                                   // failed to write and request the OUT_Y_MSB bit
+    }    
+}
+
 
-    m_i2c.start();                      // Start
-    m_i2c.write(mcu_address);           // A write to devic
-    m_i2c.write(OUT_X_LSB);             // Register to read
-    m_i2c.start();                  
-    m_i2c.write(mcu_address);           // Read from device
-    int x = m_i2c.read(0);             // Read the data
-    m_i2c.stop();
+
+// Reads z data. This method reads two registers containing the x-axis values from the accelerometer. 
+// It takes a 2 byte char array and copies the register values into the buffer. If it fails the char array
+// is set to '0'. It returns '0' success '1' fail. This method does nothing to the registers - just returns
+// the raw data.
+
+int Accelerometer_MMA8452::read_z_raw(char *zaxis)
+{
+    char mcu_address = (MMA8452_ADDRESS<<1);                // this is the slave address on the bus we want data from
+    char zaxis_buffer[2];                                   // this will contain data from that register
+    char zaxis_register[1];                     
+    zaxis_register[0] = OUT_Z_MSB;                          // this is the register we want to get data from
+    //signed short s = 0;
     
-    return x;  
+    if(m_i2c.write(mcu_address,zaxis_register,1) == 0)
+    {
+        if(m_i2c.read(mcu_address,zaxis_buffer,2) == 0)
+        {
+            //strcpy(yaxis, yaxis_buffer);
+            memcpy(zaxis, zaxis_buffer, 2);
+            //yaxis[0] = 0x00;                        // make sure the array is set to zero
+            //yaxis[1] = 0x00;
+            //s = *reinterpret_cast<short*>(&xaxis);
+            return 0;                               // great we got the two octets
+        }
+        else
+        {
+            zaxis[0] = 0x00;                        // make sure the array is set to zero
+            zaxis[1] = 0x00;
+            return 1;                               // failed to read the 12 bit y value
+        }
+    }
+    else
+    {
+        zaxis[0] = 0x00;                            // make sure the array is set to zero
+        zaxis[1] = 0x00;
+        return 1;                                   // failed to write and request the OUT_Y_MSB bit
+    }    
+}
 
-}
 
 
 // Reads y data