Judah Okeleye / Mbed 2 deprecated SLVM

Dependencies:   mbed-rtos mbed

Committer:
jerziboi732
Date:
Wed Dec 03 22:33:03 2014 +0000
Revision:
0:354a8831107d
Initial commit

Who changed what in which revision?

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