Allows for reading accelerometer, gyroscope, and magnetometer data from an LSM9DS0 IMU device

Dependencies:   mbed

Dependents:   uVGA_4180 uLCD_4180_mini ECE4781_Project

Committer:
randrews33
Date:
Sun Jan 11 14:44:43 2015 +0000
Revision:
5:e6a15dcba942
Parent:
0:1b975a6ae539
Gave credit where credit was due

Who changed what in which revision?

UserRevisionLine numberNew contents of line
randrews33 0:1b975a6ae539 1 // ported from arduino library: https://github.com/jrowberg/i2cdevlib
randrews33 0:1b975a6ae539 2 // written by szymon gaertig (email: szymon@gaertig.com.pl, website: szymongaertig.pl)
randrews33 0:1b975a6ae539 3 // Changelog:
randrews33 0:1b975a6ae539 4 // 2013-01-08 - first release
randrews33 0:1b975a6ae539 5
randrews33 0:1b975a6ae539 6 #include "I2Cdev.h"
randrews33 0:1b975a6ae539 7
randrews33 0:1b975a6ae539 8 #define useDebugSerial
randrews33 0:1b975a6ae539 9
randrews33 0:1b975a6ae539 10 I2Cdev::I2Cdev(): i2c(I2C_SDA,I2C_SCL), debugSerial(USBTX, USBRX)
randrews33 0:1b975a6ae539 11 {
randrews33 0:1b975a6ae539 12
randrews33 0:1b975a6ae539 13 }
randrews33 0:1b975a6ae539 14
randrews33 0:1b975a6ae539 15 I2Cdev::I2Cdev(PinName i2cSda, PinName i2cScl): i2c(i2cSda,i2cScl), debugSerial(USBTX, USBRX)
randrews33 0:1b975a6ae539 16 {
randrews33 0:1b975a6ae539 17 i2c.frequency(100000);
randrews33 0:1b975a6ae539 18 }
randrews33 0:1b975a6ae539 19
randrews33 0:1b975a6ae539 20 /** Read a single bit from an 8-bit device register.
randrews33 0:1b975a6ae539 21 * @param devAddr I2C slave device address
randrews33 0:1b975a6ae539 22 * @param regAddr Register regAddr to read from
randrews33 0:1b975a6ae539 23 * @param bitNum Bit position to read (0-7)
randrews33 0:1b975a6ae539 24 * @param data Container for single bit value
randrews33 0:1b975a6ae539 25 * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
randrews33 0:1b975a6ae539 26 * @return Status of read operation (true = success)
randrews33 0:1b975a6ae539 27 */
randrews33 0:1b975a6ae539 28 int8_t I2Cdev::readBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *data, uint16_t timeout) {
randrews33 0:1b975a6ae539 29 uint8_t b;
randrews33 0:1b975a6ae539 30 uint8_t count = readByte(devAddr, regAddr, &b, timeout);
randrews33 0:1b975a6ae539 31 *data = b & (1 << bitNum);
randrews33 0:1b975a6ae539 32 return count;
randrews33 0:1b975a6ae539 33 }
randrews33 0:1b975a6ae539 34
randrews33 0:1b975a6ae539 35 /** Read a single bit from a 16-bit device register.
randrews33 0:1b975a6ae539 36 * @param devAddr I2C slave device address
randrews33 0:1b975a6ae539 37 * @param regAddr Register regAddr to read from
randrews33 0:1b975a6ae539 38 * @param bitNum Bit position to read (0-15)
randrews33 0:1b975a6ae539 39 * @param data Container for single bit value
randrews33 0:1b975a6ae539 40 * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
randrews33 0:1b975a6ae539 41 * @return Status of read operation (true = success)
randrews33 0:1b975a6ae539 42 */
randrews33 0:1b975a6ae539 43 int8_t I2Cdev::readBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t *data, uint16_t timeout) {
randrews33 0:1b975a6ae539 44 uint16_t b;
randrews33 0:1b975a6ae539 45 uint8_t count = readWord(devAddr, regAddr, &b, timeout);
randrews33 0:1b975a6ae539 46 *data = b & (1 << bitNum);
randrews33 0:1b975a6ae539 47 return count;
randrews33 0:1b975a6ae539 48 }
randrews33 0:1b975a6ae539 49
randrews33 0:1b975a6ae539 50 /** Read multiple bits from an 8-bit device register.
randrews33 0:1b975a6ae539 51 * @param devAddr I2C slave device address
randrews33 0:1b975a6ae539 52 * @param regAddr Register regAddr to read from
randrews33 0:1b975a6ae539 53 * @param bitStart First bit position to read (0-7)
randrews33 0:1b975a6ae539 54 * @param length Number of bits to read (not more than 8)
randrews33 0:1b975a6ae539 55 * @param data Container for right-aligned value (i.e. '101' read from any bitStart position will equal 0x05)
randrews33 0:1b975a6ae539 56 * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
randrews33 0:1b975a6ae539 57 * @return Status of read operation (true = success)
randrews33 0:1b975a6ae539 58 */
randrews33 0:1b975a6ae539 59 int8_t I2Cdev::readBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data, uint16_t timeout) {
randrews33 0:1b975a6ae539 60 // 01101001 read byte
randrews33 0:1b975a6ae539 61 // 76543210 bit numbers
randrews33 0:1b975a6ae539 62 // xxx args: bitStart=4, length=3
randrews33 0:1b975a6ae539 63 // 010 masked
randrews33 0:1b975a6ae539 64 // -> 010 shifted
randrews33 0:1b975a6ae539 65 uint8_t count, b;
randrews33 0:1b975a6ae539 66 if ((count = readByte(devAddr, regAddr, &b, timeout)) != 0) {
randrews33 0:1b975a6ae539 67 uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1);
randrews33 0:1b975a6ae539 68 b &= mask;
randrews33 0:1b975a6ae539 69 b >>= (bitStart - length + 1);
randrews33 0:1b975a6ae539 70 *data = b;
randrews33 0:1b975a6ae539 71 }
randrews33 0:1b975a6ae539 72 return count;
randrews33 0:1b975a6ae539 73 }
randrews33 0:1b975a6ae539 74
randrews33 0:1b975a6ae539 75 /** Read multiple bits from a 16-bit device register.
randrews33 0:1b975a6ae539 76 * @param devAddr I2C slave device address
randrews33 0:1b975a6ae539 77 * @param regAddr Register regAddr to read from
randrews33 0:1b975a6ae539 78 * @param bitStart First bit position to read (0-15)
randrews33 0:1b975a6ae539 79 * @param length Number of bits to read (not more than 16)
randrews33 0:1b975a6ae539 80 * @param data Container for right-aligned value (i.e. '101' read from any bitStart position will equal 0x05)
randrews33 0:1b975a6ae539 81 * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
randrews33 0:1b975a6ae539 82 * @return Status of read operation (1 = success, 0 = failure, -1 = timeout)
randrews33 0:1b975a6ae539 83 */
randrews33 0:1b975a6ae539 84 int8_t I2Cdev::readBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t *data, uint16_t timeout) {
randrews33 0:1b975a6ae539 85 // 1101011001101001 read byte
randrews33 0:1b975a6ae539 86 // fedcba9876543210 bit numbers
randrews33 0:1b975a6ae539 87 // xxx args: bitStart=12, length=3
randrews33 0:1b975a6ae539 88 // 010 masked
randrews33 0:1b975a6ae539 89 // -> 010 shifted
randrews33 0:1b975a6ae539 90 uint8_t count;
randrews33 0:1b975a6ae539 91 uint16_t w;
randrews33 0:1b975a6ae539 92 if ((count = readWord(devAddr, regAddr, &w, timeout)) != 0) {
randrews33 0:1b975a6ae539 93 uint16_t mask = ((1 << length) - 1) << (bitStart - length + 1);
randrews33 0:1b975a6ae539 94 w &= mask;
randrews33 0:1b975a6ae539 95 w >>= (bitStart - length + 1);
randrews33 0:1b975a6ae539 96 *data = w;
randrews33 0:1b975a6ae539 97 }
randrews33 0:1b975a6ae539 98 return count;
randrews33 0:1b975a6ae539 99 }
randrews33 0:1b975a6ae539 100 /** Read single byte from an 8-bit device register.
randrews33 0:1b975a6ae539 101 * @param devAddr I2C slave device address
randrews33 0:1b975a6ae539 102 * @param regAddr Register regAddr to read from
randrews33 0:1b975a6ae539 103 * @param data Container for byte value read from device
randrews33 0:1b975a6ae539 104 * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
randrews33 0:1b975a6ae539 105 * @return Status of read operation (true = success)
randrews33 0:1b975a6ae539 106 */
randrews33 0:1b975a6ae539 107 int8_t I2Cdev::readByte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint16_t timeout) {
randrews33 0:1b975a6ae539 108
randrews33 0:1b975a6ae539 109 return readBytes(devAddr, regAddr, 1, data, timeout);
randrews33 0:1b975a6ae539 110 }
randrews33 0:1b975a6ae539 111
randrews33 0:1b975a6ae539 112 /** Read single word from a 16-bit device register.
randrews33 0:1b975a6ae539 113 * @param devAddr I2C slave device address
randrews33 0:1b975a6ae539 114 * @param regAddr Register regAddr to read from
randrews33 0:1b975a6ae539 115 * @param data Container for word value read from device
randrews33 0:1b975a6ae539 116 * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
randrews33 0:1b975a6ae539 117 * @return Status of read operation (true = success)
randrews33 0:1b975a6ae539 118 */
randrews33 0:1b975a6ae539 119 int8_t I2Cdev::readWord(uint8_t devAddr, uint8_t regAddr, uint16_t *data, uint16_t timeout) {
randrews33 0:1b975a6ae539 120 return readWords(devAddr, regAddr, 1, data, timeout);
randrews33 0:1b975a6ae539 121 }
randrews33 0:1b975a6ae539 122
randrews33 0:1b975a6ae539 123 /** Read multiple bytes from an 8-bit device register.
randrews33 0:1b975a6ae539 124 * @param devAddr I2C slave device address
randrews33 0:1b975a6ae539 125 * @param regAddr First register regAddr to read from
randrews33 0:1b975a6ae539 126 * @param length Number of bytes to read
randrews33 0:1b975a6ae539 127 * @param data Buffer to store read data in
randrews33 0:1b975a6ae539 128 * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
randrews33 0:1b975a6ae539 129 * @return Number of bytes read (-1 indicates failure)
randrews33 0:1b975a6ae539 130 */
randrews33 0:1b975a6ae539 131 int8_t I2Cdev::readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout)
randrews33 0:1b975a6ae539 132 {
randrews33 0:1b975a6ae539 133 char command[1];
randrews33 0:1b975a6ae539 134 command[0] = regAddr;
randrews33 0:1b975a6ae539 135 char *redData = (char*)malloc(length);
randrews33 0:1b975a6ae539 136 i2c.write(devAddr<<1, command, 1, true);
randrews33 0:1b975a6ae539 137 i2c.read(devAddr<<1, redData, length);
randrews33 0:1b975a6ae539 138 for(int i =0; i < length; i++) {
randrews33 0:1b975a6ae539 139 data[i] = redData[i];
randrews33 0:1b975a6ae539 140 //debugSerial.printf("We read %x\n" , redData[i]);
randrews33 0:1b975a6ae539 141
randrews33 0:1b975a6ae539 142 }
randrews33 0:1b975a6ae539 143 free (redData);
randrews33 0:1b975a6ae539 144 return length;
randrews33 0:1b975a6ae539 145 }
randrews33 0:1b975a6ae539 146
randrews33 0:1b975a6ae539 147 int8_t I2Cdev::readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data, uint16_t timeout)
randrews33 0:1b975a6ae539 148 {
randrews33 0:1b975a6ae539 149 return 0;
randrews33 0:1b975a6ae539 150 }
randrews33 0:1b975a6ae539 151
randrews33 0:1b975a6ae539 152 /** write a single bit in an 8-bit device register.
randrews33 0:1b975a6ae539 153 * @param devAddr I2C slave device address
randrews33 0:1b975a6ae539 154 * @param regAddr Register regAddr to write to
randrews33 0:1b975a6ae539 155 * @param bitNum Bit position to write (0-7)
randrews33 0:1b975a6ae539 156 * @param value New bit value to write
randrews33 0:1b975a6ae539 157 * @return Status of operation (true = success)
randrews33 0:1b975a6ae539 158 */
randrews33 0:1b975a6ae539 159 bool I2Cdev::writeBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data) {
randrews33 0:1b975a6ae539 160 uint8_t b;
randrews33 0:1b975a6ae539 161 readByte(devAddr, regAddr, &b);
randrews33 0:1b975a6ae539 162 b = (data != 0) ? (b | (1 << bitNum)) : (b & ~(1 << bitNum));
randrews33 0:1b975a6ae539 163 return writeByte(devAddr, regAddr, b);
randrews33 0:1b975a6ae539 164 }
randrews33 0:1b975a6ae539 165
randrews33 0:1b975a6ae539 166 /** write a single bit in a 16-bit device register.
randrews33 0:1b975a6ae539 167 * @param devAddr I2C slave device address
randrews33 0:1b975a6ae539 168 * @param regAddr Register regAddr to write to
randrews33 0:1b975a6ae539 169 * @param bitNum Bit position to write (0-15)
randrews33 0:1b975a6ae539 170 * @param value New bit value to write
randrews33 0:1b975a6ae539 171 * @return Status of operation (true = success)
randrews33 0:1b975a6ae539 172 */
randrews33 0:1b975a6ae539 173 bool I2Cdev::writeBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t data) {
randrews33 0:1b975a6ae539 174 uint16_t w;
randrews33 0:1b975a6ae539 175 readWord(devAddr, regAddr, &w);
randrews33 0:1b975a6ae539 176 w = (data != 0) ? (w | (1 << bitNum)) : (w & ~(1 << bitNum));
randrews33 0:1b975a6ae539 177 return writeWord(devAddr, regAddr, w);
randrews33 0:1b975a6ae539 178 }
randrews33 0:1b975a6ae539 179
randrews33 0:1b975a6ae539 180 /** Write multiple bits in an 8-bit device register.
randrews33 0:1b975a6ae539 181 * @param devAddr I2C slave device address
randrews33 0:1b975a6ae539 182 * @param regAddr Register regAddr to write to
randrews33 0:1b975a6ae539 183 * @param bitStart First bit position to write (0-7)
randrews33 0:1b975a6ae539 184 * @param length Number of bits to write (not more than 8)
randrews33 0:1b975a6ae539 185 * @param data Right-aligned value to write
randrews33 0:1b975a6ae539 186 * @return Status of operation (true = success)
randrews33 0:1b975a6ae539 187 */
randrews33 0:1b975a6ae539 188 bool I2Cdev::writeBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t data) {
randrews33 0:1b975a6ae539 189 // 010 value to write
randrews33 0:1b975a6ae539 190 // 76543210 bit numbers
randrews33 0:1b975a6ae539 191 // xxx args: bitStart=4, length=3
randrews33 0:1b975a6ae539 192 // 00011100 mask byte
randrews33 0:1b975a6ae539 193 // 10101111 original value (sample)
randrews33 0:1b975a6ae539 194 // 10100011 original & ~mask
randrews33 0:1b975a6ae539 195 // 10101011 masked | value
randrews33 0:1b975a6ae539 196 uint8_t b;
randrews33 0:1b975a6ae539 197 if (readByte(devAddr, regAddr, &b) != 0) {
randrews33 0:1b975a6ae539 198 uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1);
randrews33 0:1b975a6ae539 199 data <<= (bitStart - length + 1); // shift data into correct position
randrews33 0:1b975a6ae539 200 data &= mask; // zero all non-important bits in data
randrews33 0:1b975a6ae539 201 b &= ~(mask); // zero all important bits in existing byte
randrews33 0:1b975a6ae539 202 b |= data; // combine data with existing byte
randrews33 0:1b975a6ae539 203 return writeByte(devAddr, regAddr, b);
randrews33 0:1b975a6ae539 204 } else {
randrews33 0:1b975a6ae539 205 return false;
randrews33 0:1b975a6ae539 206 }
randrews33 0:1b975a6ae539 207 }
randrews33 0:1b975a6ae539 208
randrews33 0:1b975a6ae539 209 /** Write multiple bits in a 16-bit device register.
randrews33 0:1b975a6ae539 210 * @param devAddr I2C slave device address
randrews33 0:1b975a6ae539 211 * @param regAddr Register regAddr to write to
randrews33 0:1b975a6ae539 212 * @param bitStart First bit position to write (0-15)
randrews33 0:1b975a6ae539 213 * @param length Number of bits to write (not more than 16)
randrews33 0:1b975a6ae539 214 * @param data Right-aligned value to write
randrews33 0:1b975a6ae539 215 * @return Status of operation (true = success)
randrews33 0:1b975a6ae539 216 */
randrews33 0:1b975a6ae539 217 bool I2Cdev::writeBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t data) {
randrews33 0:1b975a6ae539 218 // 010 value to write
randrews33 0:1b975a6ae539 219 // fedcba9876543210 bit numbers
randrews33 0:1b975a6ae539 220 // xxx args: bitStart=12, length=3
randrews33 0:1b975a6ae539 221 // 0001110000000000 mask byte
randrews33 0:1b975a6ae539 222 // 1010111110010110 original value (sample)
randrews33 0:1b975a6ae539 223 // 1010001110010110 original & ~mask
randrews33 0:1b975a6ae539 224 // 1010101110010110 masked | value
randrews33 0:1b975a6ae539 225 uint16_t w;
randrews33 0:1b975a6ae539 226 if (readWord(devAddr, regAddr, &w) != 0) {
randrews33 0:1b975a6ae539 227 uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1);
randrews33 0:1b975a6ae539 228 data <<= (bitStart - length + 1); // shift data into correct position
randrews33 0:1b975a6ae539 229 data &= mask; // zero all non-important bits in data
randrews33 0:1b975a6ae539 230 w &= ~(mask); // zero all important bits in existing word
randrews33 0:1b975a6ae539 231 w |= data; // combine data with existing word
randrews33 0:1b975a6ae539 232 return writeWord(devAddr, regAddr, w);
randrews33 0:1b975a6ae539 233 } else {
randrews33 0:1b975a6ae539 234 return false;
randrews33 0:1b975a6ae539 235 }
randrews33 0:1b975a6ae539 236 }
randrews33 0:1b975a6ae539 237
randrews33 0:1b975a6ae539 238 /** Write single byte to an 8-bit device register.
randrews33 0:1b975a6ae539 239 * @param devAddr I2C slave device address
randrews33 0:1b975a6ae539 240 * @param regAddr Register address to write to
randrews33 0:1b975a6ae539 241 * @param data New byte value to write
randrews33 0:1b975a6ae539 242 * @return Status of operation (true = success)
randrews33 0:1b975a6ae539 243 */
randrews33 0:1b975a6ae539 244 bool I2Cdev::writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data) {
randrews33 0:1b975a6ae539 245 return writeBytes(devAddr, regAddr, 1, &data);
randrews33 0:1b975a6ae539 246 }
randrews33 0:1b975a6ae539 247
randrews33 0:1b975a6ae539 248 /** Write single word to a 16-bit device register.
randrews33 0:1b975a6ae539 249 * @param devAddr I2C slave device address
randrews33 0:1b975a6ae539 250 * @param regAddr Register address to write to
randrews33 0:1b975a6ae539 251 * @param data New word value to write
randrews33 0:1b975a6ae539 252 * @return Status of operation (true = success)
randrews33 0:1b975a6ae539 253 */
randrews33 0:1b975a6ae539 254 bool I2Cdev::writeWord(uint8_t devAddr, uint8_t regAddr, uint16_t data) {
randrews33 0:1b975a6ae539 255 return writeWords(devAddr, regAddr, 1, &data);
randrews33 0:1b975a6ae539 256 }
randrews33 0:1b975a6ae539 257
randrews33 0:1b975a6ae539 258 bool I2Cdev::writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data)
randrews33 0:1b975a6ae539 259 {
randrews33 0:1b975a6ae539 260 i2c.start();
randrews33 0:1b975a6ae539 261 i2c.write(devAddr<<1);
randrews33 0:1b975a6ae539 262 i2c.write(regAddr);
randrews33 0:1b975a6ae539 263 for(int i = 0; i < length; i++) {
randrews33 0:1b975a6ae539 264 i2c.write(data[i]);
randrews33 0:1b975a6ae539 265 }
randrews33 0:1b975a6ae539 266 i2c.stop();
randrews33 0:1b975a6ae539 267 return true;
randrews33 0:1b975a6ae539 268 }
randrews33 0:1b975a6ae539 269
randrews33 0:1b975a6ae539 270 bool I2Cdev::writeWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data)
randrews33 0:1b975a6ae539 271 {
randrews33 0:1b975a6ae539 272 return true;
randrews33 0:1b975a6ae539 273 }
randrews33 0:1b975a6ae539 274
randrews33 0:1b975a6ae539 275 uint16_t I2Cdev::readTimeout(void)
randrews33 0:1b975a6ae539 276 {
randrews33 0:1b975a6ae539 277 return 0;
randrews33 0:1b975a6ae539 278 }