MMA7455L test for I2C interface. 10-bit 8g mode.

Dependencies:   mbed

Revision:
0:17e709908189
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Aug 21 10:44:59 2011 +0000
@@ -0,0 +1,243 @@
+#include "mbed.h"
+
+/*
+*************************************************************************************************
+MMA7455. Simple test for I2C interface and 10-bit 8g mode . 2g, 4g, 8g, digital triple axis accelerometer
+with I2C/SPI interface.
+
+In Level Detection Mode and pulse detection mode, dynamic range is set automatically to 8g.
+Read or Write Low Byte first.
+
+Wiring:
+pin 2, pin 3, pin 5, IADDR0(pin 4), pin 10 and pin 11 tied to ground.
+DVdd(pin 1),AVdd(pin 6) and CS(pin 7) tied to 3.3V.
+INT1(p8) to mBed's p15(INT1 is not used in this program). INT2(p9) to mBed's p16.
+
+Author: Lluis Nadal. August 2011.
+*************************************************************************************************
+*/
+
+I2C i2c(p9, p10); // SDA(p13), SCL(p14). 4.7k pull-up resistors.
+
+//pin 4 (IADDR0) tied to ground.
+const int addr_R = 0x3B; // Address to read:  111011
+const int addr_W = 0x3A; // Address to write: 111010
+
+Serial pc(USBTX, USBRX);
+
+DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4);
+InterruptIn int1(p15); //
+InterruptIn int2(p16); //
+
+int offset[3];
+int v[6];
+int a;
+char msb, lsb;
+
+
+
+
+void read_8(int n) { // Read 8-bit register
+    i2c.start();
+    v[0]=i2c.write(addr_W);
+    v[1]=i2c.write(n);
+    i2c.start();
+    v[2] = i2c.write(addr_R);
+    v[3]=i2c.read(0);
+    i2c.stop();
+//ACK = v[0]= v[1]= v[2]= 1; NACK = 0. v[3] = value.
+    pc.printf(" (v[0],v[1],v[2],v[3]) = (%d, %d, %d, %d)\r\n\r\n", v[0],v[1],v[2],v[3]);
+}
+
+
+void read(int n) { // Read 10-bit registers n and n+1
+    i2c.start();
+    i2c.write(addr_W);
+    i2c.write(n); // Starting register(L)
+    i2c.start();
+    i2c.write(addr_R);
+    lsb = i2c.read(0);
+    i2c.stop();
+
+    i2c.start();
+    i2c.write(addr_W);
+    i2c.write(n+1); // Next register(H)
+    i2c.start();
+    i2c.write(addr_R);
+    msb = i2c.read(0);
+    i2c.stop();
+    pc.printf(" (msb, lsb): (%d, %d)\r\n", msb, lsb);
+    pc.printf("\r\n");
+    a = (int)msb;
+    a = (a << 8) | lsb;
+    if ((msb >> 1) == 1) a = a -1024; // If negative
+    pc.printf(" a = %d\r\n\r\n", a);
+}
+
+
+void write_8(int reg, int data) { // Write 8-bit data to register
+    i2c.start();
+    v[0]=i2c.write(addr_W);
+    v[1]=i2c.write(reg);
+    v[2] = i2c.write(data);
+    i2c.stop();
+//ACK = v[0]= v[1]= v[2] = 1; NACK = 0.
+    // pc.printf(" (v[0],v[1],v[2]) = (%d, %d, %d)\r\n", v[0],v[1],v[2]);
+    // pc.printf("\r\n");
+}
+
+void write_offset(int reg, int data) { // Write 11-bit data to offset registers L and H
+    char H, L;
+    i2c.start();
+    i2c.write(addr_W);
+    i2c.write(reg); // Starting register(L)
+    if (data < 0) data = 2048 + data ; // If negative
+    pc.printf(" data = %d\r\n", data);
+    H = (char) ((data & 0xFF00) >> 8);
+    L = (char) (data & 0x00FF);
+    i2c.write(L);
+    i2c.stop();
+    i2c.start();
+    i2c.write(addr_W);
+    i2c.write(reg+1); // Next register(H)
+    i2c.write(H);
+    i2c.stop();
+    pc.printf(" (H, L) = (%d, %d )\r\n\r\n", H, L);
+}
+
+
+
+
+void clr_int() {   // Clear interrupt latch
+    write_8(0x17, 0x03);
+    write_8(0x17, 0x00); // Default option
+}
+
+void flash() {
+    led4 = 0;
+    pc.printf("Pulse detected!\r\n");
+    led4 = 1;
+    wait(1);
+    led4 = 0;
+    clr_int(); // Clear interrupt latch
+}
+
+
+
+
+int main() {
+
+    i2c.frequency(100000);
+
+    led1 = 0, led2 = 0, led3 = 0, led4 = 0;
+    wait(2);
+
+// Read some 8-bit registers
+    pc.printf(" Read some registers: \r\n\r\n");
+
+
+    pc.printf(" WHOAMI register: ");
+    read_8(0x0F); // WHOAMI
+
+    pc.printf(" I2C ADDRESS: ");
+    read_8(0x0D); // I2C ADDRESS
+
+    pc.printf(" MODE CONTROL register: ");
+    read_8(0x16); // Mode control register
+
+
+    // 0x16: Mode[1:0] Control Register:
+    // 00: Standby Mode
+    // 01: Measurement Mode
+    // 10: Level Detection Mode
+    // 11: Pulse Detection Mode
+
+    // 0x16: GLV[1:0] Control Register:
+    // 00: 8g
+    // 10: 4g
+    // 01: 2g
+
+    pc.printf( "Write to MODE CONTROL register 0x16\r\n\r\n");
+    // Write: DRPD = 1, GLVL = 00(8g), MODE: 01(Measurement).
+    write_8(0x16, 0x41);
+    clr_int(); // Clear interrupt latch
+
+    pc.printf(" MODE CONTROL register updated: ");
+    read_8(0x16); // MODE CONTROL register is updated
+
+    pc.printf(" Interrupt latch register: ");
+    read_8(0x17); // Interrupt latch register
+
+    pc.printf(" Status: ");
+    read_8(0x09); // Status
+
+// Clear offset registers: 11-bit
+    pc.printf(" Clear offset registers\r\n\r\n");
+    write_offset(0x10, 0); // Offset x
+    write_offset(0x12, 0); // Offset y
+    write_offset(0x14, 0); // Offset z
+    wait(0.1);
+
+    // Start autocalibration. Lay device down horizontal and do not move
+    // Average 4 readings
+    // Offsets must be multiplied by 2
+    pc.printf(" Autocalibration: lay device down horizontal and do not move\r\n\r\n");
+    led1 = 1; // Start autocalibration in 4 seconds
+    wait(4);
+    offset[0] = 0, offset[1] = 0, offset[2] = 0;
+
+    for (int i = 0; i < 4; i++) {
+
+        pc.printf(" x: \r\n");
+        read(0x00);
+        offset[0] = offset[0]-a;
+
+        pc.printf( "y: \r\n");
+        read(0x02);
+        offset[1] = offset[1]-a ;
+
+        pc.printf(" z: \r\n");
+        read(0x04);
+        offset[2] = offset[2]-a;
+        wait(0.2);
+    }
+
+    led2 = 1; // End autocalibration
+
+    // Offsets must be multiplied by 2 and divided by 4 to calculate the average
+    offset[0] = offset[0]/2;
+    offset[1] = offset[1]/2;
+    offset[2] = offset[2]/2 + 2*64; //Z axis output for 1g must be 64 in 10-bit mode
+
+
+    // Write offset registers (11-bit). Offset registers are volatile and are cleared on  power off.
+    pc.printf(" Write offset registers\r\n\r\n");
+    write_offset(0x10, offset[0]); // Offset x
+    write_offset(0x12, offset[1]); // Offset y
+    write_offset(0x14, offset[2]); // Offset z
+    wait(0.1);
+
+
+// Read x, y, z with offset correction
+    pc.printf(" Read x, y, z with offset correction\r\n\r\n");
+    pc.printf(" x corrected: \r\n");
+    read(0x00);
+    pc.printf( "y corrected: \r\n");
+    read(0x02);
+    pc.printf(" z corrected: \r\n");
+    read(0x04);
+    wait(0.1);
+
+// Single pulse detection
+    write_8(0x16, 0x43); // DRPD = 1; GLV = 00(8g), MODE: 11(pulse detection).
+    write_8(0x19, 0x00);
+    write_8(0x18, 0x00); // Int2 for pulse detection
+    write_8(0x1B, 0x20); // Unsigned 7-bit Pulse Treshold set to 2g.
+    write_8(0x1C, 0x10); // Pulse duration set to 8 ms
+    int2.rise(&flash); // Attach flash function to int2
+    pc.printf(" Start pulse detection\r\n\r\n");
+    led3 = 1; // Start pulse detection
+
+    while (1) {
+    }
+}
\ No newline at end of file