mbed os with nrf51 internal bandgap enabled to read battery level

Dependents:   BLE_file_test BLE_Blink ExternalEncoder

Committer:
elessair
Date:
Sun Oct 23 15:10:02 2016 +0000
Revision:
0:f269e3021894
Initial commit

Who changed what in which revision?

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