b

Fork of MMA7660 by Erik -

Committer:
co657_kk351
Date:
Thu Oct 29 17:38:25 2015 +0000
Revision:
5:fd9787a2959d
Parent:
4:36a163511e34
kk351_a3

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sissors 0:7bc29a9ea016 1 #include "MMA7660.h"
Sissors 0:7bc29a9ea016 2
co657_kk351 5:fd9787a2959d 3
Sissors 2:a8e20db7901e 4 MMA7660::MMA7660(PinName sda, PinName scl, bool active) : _i2c(sda, scl)
Sissors 0:7bc29a9ea016 5 {
Sissors 2:a8e20db7901e 6 setActive(active);
Sissors 1:8997a1b348dd 7 samplerate = 64;
Sissors 0:7bc29a9ea016 8 }
Sissors 0:7bc29a9ea016 9
Sissors 0:7bc29a9ea016 10 //Since the MMA lacks a WHO_AM_I register, we can only check if there is a device that answers to the I2C address
Sissors 0:7bc29a9ea016 11 bool MMA7660::testConnection( void )
Sissors 0:7bc29a9ea016 12 {
Sissors 0:7bc29a9ea016 13 if (_i2c.write(MMA7660_ADDRESS, NULL, 0) == 0 )
Sissors 0:7bc29a9ea016 14 return true;
Sissors 0:7bc29a9ea016 15 else
Sissors 0:7bc29a9ea016 16 return false;
Sissors 0:7bc29a9ea016 17 }
Sissors 0:7bc29a9ea016 18
Sissors 0:7bc29a9ea016 19 void MMA7660::setActive(bool state)
Sissors 0:7bc29a9ea016 20 {
Sissors 3:89cb08cc663b 21 active = state;
Sissors 0:7bc29a9ea016 22 char modereg = read(MMA7660_MODE_R);
Sissors 0:7bc29a9ea016 23 modereg &= ~(1<<0);
Sissors 0:7bc29a9ea016 24
Sissors 0:7bc29a9ea016 25 //If it somehow was in testmode, disable that
Sissors 0:7bc29a9ea016 26 if (modereg && (1<<2)) {
Sissors 0:7bc29a9ea016 27 modereg &= ~(1<<2);
Sissors 0:7bc29a9ea016 28 write(MMA7660_MODE_R, modereg);
Sissors 0:7bc29a9ea016 29 }
Sissors 0:7bc29a9ea016 30
Sissors 0:7bc29a9ea016 31 modereg += state;
Sissors 0:7bc29a9ea016 32 write(MMA7660_MODE_R, modereg);
Sissors 0:7bc29a9ea016 33 }
Sissors 0:7bc29a9ea016 34
Sissors 0:7bc29a9ea016 35 void MMA7660::readData(int *data)
Sissors 0:7bc29a9ea016 36 {
Sissors 3:89cb08cc663b 37 bool active_old = active;
Sissors 0:7bc29a9ea016 38 if (!active) {
Sissors 0:7bc29a9ea016 39 setActive(true);
Sissors 1:8997a1b348dd 40 wait(0.012 + 1/samplerate); //Wait until new sample is ready, my experience is that 1/samplerate isnt needed, but datasheet says so
Sissors 0:7bc29a9ea016 41 }
Sissors 0:7bc29a9ea016 42
Sissors 0:7bc29a9ea016 43 char temp[3];
Sissors 0:7bc29a9ea016 44 bool alert;
Sissors 0:7bc29a9ea016 45
Sissors 0:7bc29a9ea016 46 do {
Sissors 0:7bc29a9ea016 47 alert = false;
Sissors 0:7bc29a9ea016 48 read(MMA7660_XOUT_R, temp, 3);
Sissors 0:7bc29a9ea016 49 for (int i = 0; i<3; i++) {
Sissors 0:7bc29a9ea016 50 if (temp[i] > 63)
Sissors 0:7bc29a9ea016 51 alert = true;
Sissors 0:7bc29a9ea016 52 if (temp[i] > 31)
Sissors 0:7bc29a9ea016 53 temp[i] += 128+64;
Sissors 0:7bc29a9ea016 54 data[i] = (signed char)temp[i];
Sissors 0:7bc29a9ea016 55 }
Sissors 0:7bc29a9ea016 56 } while (alert);
Sissors 2:a8e20db7901e 57
Sissors 3:89cb08cc663b 58 if (!active_old)
Sissors 2:a8e20db7901e 59 setActive(false);
Sissors 0:7bc29a9ea016 60 }
Sissors 0:7bc29a9ea016 61
Sissors 1:8997a1b348dd 62
Sissors 0:7bc29a9ea016 63 void MMA7660::readData(float *data)
Sissors 0:7bc29a9ea016 64 {
Sissors 0:7bc29a9ea016 65 int intdata[3];
Sissors 0:7bc29a9ea016 66 readData(intdata);
Sissors 0:7bc29a9ea016 67 for (int i = 0; i<3; i++)
Sissors 0:7bc29a9ea016 68 data[i] = intdata[i]/MMA7660_SENSITIVITY;
Sissors 0:7bc29a9ea016 69 }
Sissors 0:7bc29a9ea016 70
Sissors 2:a8e20db7901e 71 float MMA7660::x( void )
Sissors 1:8997a1b348dd 72 {
Sissors 0:7bc29a9ea016 73 return getSingle(0);
Sissors 1:8997a1b348dd 74 }
Sissors 1:8997a1b348dd 75
Sissors 2:a8e20db7901e 76 float MMA7660::y( void )
Sissors 1:8997a1b348dd 77 {
Sissors 1:8997a1b348dd 78 return getSingle(1);
Sissors 1:8997a1b348dd 79 }
Sissors 1:8997a1b348dd 80
Sissors 2:a8e20db7901e 81 float MMA7660::z( void )
Sissors 1:8997a1b348dd 82 {
Sissors 1:8997a1b348dd 83 return getSingle(2);
Sissors 1:8997a1b348dd 84 }
Sissors 1:8997a1b348dd 85
Sissors 1:8997a1b348dd 86
Sissors 1:8997a1b348dd 87 void MMA7660::setSampleRate(int samplerate)
Sissors 1:8997a1b348dd 88 {
Sissors 3:89cb08cc663b 89 bool active_old = active;
Sissors 1:8997a1b348dd 90 setActive(false); //Not allowed to be active to change anything
Sissors 1:8997a1b348dd 91 int rates[] = {120, 64, 32, 16, 8, 4, 2, 1}; //Alowed samplerates (and their number in array is also number required for MMA)
Sissors 1:8997a1b348dd 92 int sampleLoc = 0, sampleError = 10000, temp;
Sissors 1:8997a1b348dd 93 for (int i = 0; i<8; i++) {
Sissors 1:8997a1b348dd 94 temp = abs( rates[i] - samplerate );
Sissors 1:8997a1b348dd 95 if (temp<sampleError) {
Sissors 1:8997a1b348dd 96 sampleLoc = i;
Sissors 1:8997a1b348dd 97 sampleError=temp;
Sissors 1:8997a1b348dd 98 }
Sissors 0:7bc29a9ea016 99 }
Sissors 0:7bc29a9ea016 100
Sissors 1:8997a1b348dd 101 //Update the samplerate reg
Sissors 1:8997a1b348dd 102 temp = read(MMA7660_SR_R);
Sissors 2:a8e20db7901e 103 temp &= ~0x07; //Awake sample rate are lowest 3 bit
Sissors 1:8997a1b348dd 104 temp |= sampleLoc;
Sissors 1:8997a1b348dd 105 write(MMA7660_SR_R, temp);
Sissors 1:8997a1b348dd 106 this->samplerate = rates[sampleLoc];
Sissors 3:89cb08cc663b 107 setActive(active_old); //Restore previous active state
Sissors 1:8997a1b348dd 108 }
Sissors 1:8997a1b348dd 109
Sissors 1:8997a1b348dd 110
Sissors 1:8997a1b348dd 111 MMA7660::Orientation MMA7660::getSide( void )
Sissors 1:8997a1b348dd 112 {
Sissors 1:8997a1b348dd 113 char tiltreg = read(MMA7660_TILT_R);
Sissors 1:8997a1b348dd 114 //We care about 2 LSBs
Sissors 1:8997a1b348dd 115 tiltreg &= 0x03;
Sissors 1:8997a1b348dd 116 if (tiltreg == 0x01)
Sissors 1:8997a1b348dd 117 return MMA7660::Front;
Sissors 1:8997a1b348dd 118 if (tiltreg == 0x02)
Sissors 1:8997a1b348dd 119 return MMA7660::Back;
Sissors 1:8997a1b348dd 120 return MMA7660::Unknown;
Sissors 1:8997a1b348dd 121 }
Sissors 1:8997a1b348dd 122
Sissors 1:8997a1b348dd 123 MMA7660::Orientation MMA7660::getOrientation( void )
Sissors 1:8997a1b348dd 124 {
Sissors 1:8997a1b348dd 125 char tiltreg = read(MMA7660_TILT_R);
Sissors 1:8997a1b348dd 126
Sissors 1:8997a1b348dd 127 //We care about bit 2, 3 and 4 (counting from zero)
Sissors 1:8997a1b348dd 128 tiltreg &= 0x07<<2;
Sissors 1:8997a1b348dd 129 tiltreg >>= 2;
Sissors 1:8997a1b348dd 130 if (tiltreg == 0x01)
Sissors 1:8997a1b348dd 131 return MMA7660::Left;
Sissors 1:8997a1b348dd 132 if (tiltreg == 0x02)
Sissors 1:8997a1b348dd 133 return MMA7660::Right;
Sissors 1:8997a1b348dd 134 if (tiltreg == 0x05)
Sissors 1:8997a1b348dd 135 return MMA7660::Down;
Sissors 1:8997a1b348dd 136 if (tiltreg == 0x06)
Sissors 1:8997a1b348dd 137 return MMA7660::Up;
Sissors 1:8997a1b348dd 138 return MMA7660::Unknown;
Sissors 1:8997a1b348dd 139 }
Sissors 1:8997a1b348dd 140
Sissors 2:a8e20db7901e 141
Sissors 1:8997a1b348dd 142
Sissors 1:8997a1b348dd 143 //////////////////////////////////////////////
Sissors 1:8997a1b348dd 144 ///////////////PRIVATE////////////////////////
Sissors 1:8997a1b348dd 145 //////////////////////////////////////////////
Sissors 1:8997a1b348dd 146
Sissors 0:7bc29a9ea016 147
Sissors 0:7bc29a9ea016 148 void MMA7660::write(char address, char data)
Sissors 0:7bc29a9ea016 149 {
Sissors 0:7bc29a9ea016 150 char temp[2];
Sissors 0:7bc29a9ea016 151 temp[0]=address;
Sissors 0:7bc29a9ea016 152 temp[1]=data;
Sissors 0:7bc29a9ea016 153
Sissors 0:7bc29a9ea016 154 _i2c.write(MMA7660_ADDRESS, temp, 2);
Sissors 0:7bc29a9ea016 155 }
Sissors 0:7bc29a9ea016 156
Sissors 0:7bc29a9ea016 157 char MMA7660::read(char address)
Sissors 0:7bc29a9ea016 158 {
Sissors 0:7bc29a9ea016 159 char retval;
Sissors 0:7bc29a9ea016 160 _i2c.write(MMA7660_ADDRESS, &address, 1, true);
Sissors 0:7bc29a9ea016 161 _i2c.read(MMA7660_ADDRESS, &retval, 1);
Sissors 0:7bc29a9ea016 162 return retval;
Sissors 0:7bc29a9ea016 163 }
Sissors 0:7bc29a9ea016 164
Sissors 0:7bc29a9ea016 165 void MMA7660::read(char address, char *data, int length)
Sissors 0:7bc29a9ea016 166 {
Sissors 0:7bc29a9ea016 167 _i2c.write(MMA7660_ADDRESS, &address, 1, true);
Sissors 0:7bc29a9ea016 168 _i2c.read(MMA7660_ADDRESS, data, length);
Sissors 0:7bc29a9ea016 169 }
Sissors 0:7bc29a9ea016 170
Sissors 0:7bc29a9ea016 171 float MMA7660::getSingle( int number )
Sissors 0:7bc29a9ea016 172 {
Sissors 3:89cb08cc663b 173 bool active_old = active;
Sissors 0:7bc29a9ea016 174 if (!active) {
Sissors 0:7bc29a9ea016 175 setActive(true);
co657_kk351 5:fd9787a2959d 176 wait(0.012 + 1/samplerate); //Wait until new sample is ready
Sissors 0:7bc29a9ea016 177 }
Sissors 0:7bc29a9ea016 178
Sissors 0:7bc29a9ea016 179 signed char temp;
Sissors 0:7bc29a9ea016 180 bool alert;
Sissors 0:7bc29a9ea016 181
Sissors 0:7bc29a9ea016 182 do {
Sissors 0:7bc29a9ea016 183 alert = false;
Sissors 0:7bc29a9ea016 184 temp = read(MMA7660_XOUT_R + number);
Sissors 0:7bc29a9ea016 185 if (temp > 63)
Sissors 0:7bc29a9ea016 186 alert = true;
Sissors 0:7bc29a9ea016 187 if (temp > 31)
Sissors 0:7bc29a9ea016 188 temp += 128+64;
Sissors 2:a8e20db7901e 189 } while (alert);
Sissors 0:7bc29a9ea016 190
Sissors 3:89cb08cc663b 191 if (!active_old)
Sissors 2:a8e20db7901e 192 setActive(false);
Sissors 0:7bc29a9ea016 193
Sissors 0:7bc29a9ea016 194 return temp / MMA7660_SENSITIVITY;
co657_kk351 5:fd9787a2959d 195 }
co657_kk351 5:fd9787a2959d 196