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

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
lnadal
Date:
Sun Aug 21 10:44:59 2011 +0000
Commit message:

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 17e709908189 main.cpp
--- /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
diff -r 000000000000 -r 17e709908189 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sun Aug 21 10:44:59 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/63bcd7ba4912