Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
I2Cdev.cpp
00001 // ported from arduino library: https://github.com/jrowberg/i2cdevlib 00002 // written by szymon gaertig (email: szymon@gaertig.com.pl, website: szymongaertig.pl) 00003 // Changelog: 00004 // 2013-01-08 - first release 00005 00006 #include "I2Cdev.h" 00007 00008 00009 I2Cdev::I2Cdev(I2C &interface) : i2c(interface) 00010 { 00011 00012 } 00013 00014 /** Read a single bit from an 8-bit device register. 00015 * @param devAddr I2C slave device address 00016 * @param regAddr Register regAddr to read from 00017 * @param bitNum Bit position to read (0-7) 00018 * @param data Container for single bit value 00019 * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) 00020 * @return Status of read operation (true = success) 00021 */ 00022 int8_t I2Cdev::readBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *data, uint16_t timeout) { 00023 uint8_t b; 00024 uint8_t count = readByte(devAddr, regAddr, &b, timeout); 00025 *data = b & (1 << bitNum); 00026 return count; 00027 } 00028 00029 /** Read a single bit from a 16-bit device register. 00030 * @param devAddr I2C slave device address 00031 * @param regAddr Register regAddr to read from 00032 * @param bitNum Bit position to read (0-15) 00033 * @param data Container for single bit value 00034 * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) 00035 * @return Status of read operation (true = success) 00036 */ 00037 int8_t I2Cdev::readBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t *data, uint16_t timeout) { 00038 uint16_t b; 00039 uint8_t count = readWord(devAddr, regAddr, &b, timeout); 00040 *data = b & (1 << bitNum); 00041 return count; 00042 } 00043 00044 /** Read multiple bits from an 8-bit device register. 00045 * @param devAddr I2C slave device address 00046 * @param regAddr Register regAddr to read from 00047 * @param bitStart First bit position to read (0-7) 00048 * @param length Number of bits to read (not more than 8) 00049 * @param data Container for right-aligned value (i.e. '101' read from any bitStart position will equal 0x05) 00050 * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) 00051 * @return Status of read operation (true = success) 00052 */ 00053 int8_t I2Cdev::readBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data, uint16_t timeout) { 00054 // 01101001 read byte 00055 // 76543210 bit numbers 00056 // xxx args: bitStart=4, length=3 00057 // 010 masked 00058 // -> 010 shifted 00059 uint8_t count, b; 00060 if ((count = readByte(devAddr, regAddr, &b, timeout)) != 0) { 00061 uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1); 00062 b &= mask; 00063 b >>= (bitStart - length + 1); 00064 *data = b; 00065 } 00066 return count; 00067 } 00068 00069 /** Read multiple bits from a 16-bit device register. 00070 * @param devAddr I2C slave device address 00071 * @param regAddr Register regAddr to read from 00072 * @param bitStart First bit position to read (0-15) 00073 * @param length Number of bits to read (not more than 16) 00074 * @param data Container for right-aligned value (i.e. '101' read from any bitStart position will equal 0x05) 00075 * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) 00076 * @return Status of read operation (1 = success, 0 = failure, -1 = timeout) 00077 */ 00078 int8_t I2Cdev::readBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t *data, uint16_t timeout) { 00079 // 1101011001101001 read byte 00080 // fedcba9876543210 bit numbers 00081 // xxx args: bitStart=12, length=3 00082 // 010 masked 00083 // -> 010 shifted 00084 uint8_t count; 00085 uint16_t w; 00086 if ((count = readWord(devAddr, regAddr, &w, timeout)) != 0) { 00087 uint16_t mask = ((1 << length) - 1) << (bitStart - length + 1); 00088 w &= mask; 00089 w >>= (bitStart - length + 1); 00090 *data = w; 00091 } 00092 return count; 00093 } 00094 /** Read single byte from an 8-bit device register. 00095 * @param devAddr I2C slave device address 00096 * @param regAddr Register regAddr to read from 00097 * @param data Container for byte value read from device 00098 * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) 00099 * @return Status of read operation (true = success) 00100 */ 00101 int8_t I2Cdev::readByte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint16_t timeout) { 00102 return readBytes(devAddr, regAddr, 1, data, timeout); 00103 } 00104 00105 /** Read single word from a 16-bit device register. 00106 * @param devAddr I2C slave device address 00107 * @param regAddr Register regAddr to read from 00108 * @param data Container for word value read from device 00109 * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) 00110 * @return Status of read operation (true = success) 00111 */ 00112 int8_t I2Cdev::readWord(uint8_t devAddr, uint8_t regAddr, uint16_t *data, uint16_t timeout) { 00113 return readWords(devAddr, regAddr, 1, data, timeout); 00114 } 00115 00116 /** Read multiple bytes from an 8-bit device register. 00117 * @param devAddr I2C slave device address 00118 * @param regAddr First register regAddr to read from 00119 * @param length Number of bytes to read 00120 * @param data Buffer to store read data in 00121 * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) 00122 * @return Number of bytes read (-1 indicates failure) 00123 */ 00124 int8_t I2Cdev::readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout) 00125 { 00126 char command[1]; 00127 command[0] = regAddr; 00128 char *redData = (char*)malloc(length); 00129 i2c.write(devAddr<<1, command, 1, true); 00130 i2c.read(devAddr<<1, redData, length); 00131 for(int i =0; i < length; i++) { 00132 data[i] = redData[i]; 00133 } 00134 free (redData); 00135 return length; 00136 } 00137 00138 int8_t I2Cdev::readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data, uint16_t timeout) 00139 { 00140 return 0; 00141 } 00142 00143 /** write a single bit in an 8-bit device register. 00144 * @param devAddr I2C slave device address 00145 * @param regAddr Register regAddr to write to 00146 * @param bitNum Bit position to write (0-7) 00147 * @param value New bit value to write 00148 * @return Status of operation (true = success) 00149 */ 00150 bool I2Cdev::writeBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data) { 00151 uint8_t b; 00152 readByte(devAddr, regAddr, &b); 00153 b = (data != 0) ? (b | (1 << bitNum)) : (b & ~(1 << bitNum)); 00154 return writeByte(devAddr, regAddr, b); 00155 } 00156 00157 /** write a single bit in a 16-bit device register. 00158 * @param devAddr I2C slave device address 00159 * @param regAddr Register regAddr to write to 00160 * @param bitNum Bit position to write (0-15) 00161 * @param value New bit value to write 00162 * @return Status of operation (true = success) 00163 */ 00164 bool I2Cdev::writeBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t data) { 00165 uint16_t w; 00166 readWord(devAddr, regAddr, &w); 00167 w = (data != 0) ? (w | (1 << bitNum)) : (w & ~(1 << bitNum)); 00168 return writeWord(devAddr, regAddr, w); 00169 } 00170 00171 /** Write multiple bits in an 8-bit device register. 00172 * @param devAddr I2C slave device address 00173 * @param regAddr Register regAddr to write to 00174 * @param bitStart First bit position to write (0-7) 00175 * @param length Number of bits to write (not more than 8) 00176 * @param data Right-aligned value to write 00177 * @return Status of operation (true = success) 00178 */ 00179 bool I2Cdev::writeBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t data) { 00180 // 010 value to write 00181 // 76543210 bit numbers 00182 // xxx args: bitStart=4, length=3 00183 // 00011100 mask byte 00184 // 10101111 original value (sample) 00185 // 10100011 original & ~mask 00186 // 10101011 masked | value 00187 uint8_t b; 00188 if (readByte(devAddr, regAddr, &b) != 0) { 00189 uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1); 00190 data <<= (bitStart - length + 1); // shift data into correct position 00191 data &= mask; // zero all non-important bits in data 00192 b &= ~(mask); // zero all important bits in existing byte 00193 b |= data; // combine data with existing byte 00194 return writeByte(devAddr, regAddr, b); 00195 } else { 00196 return false; 00197 } 00198 } 00199 00200 /** Write multiple bits in a 16-bit device register. 00201 * @param devAddr I2C slave device address 00202 * @param regAddr Register regAddr to write to 00203 * @param bitStart First bit position to write (0-15) 00204 * @param length Number of bits to write (not more than 16) 00205 * @param data Right-aligned value to write 00206 * @return Status of operation (true = success) 00207 */ 00208 bool I2Cdev::writeBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t data) { 00209 // 010 value to write 00210 // fedcba9876543210 bit numbers 00211 // xxx args: bitStart=12, length=3 00212 // 0001110000000000 mask byte 00213 // 1010111110010110 original value (sample) 00214 // 1010001110010110 original & ~mask 00215 // 1010101110010110 masked | value 00216 uint16_t w; 00217 if (readWord(devAddr, regAddr, &w) != 0) { 00218 uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1); 00219 data <<= (bitStart - length + 1); // shift data into correct position 00220 data &= mask; // zero all non-important bits in data 00221 w &= ~(mask); // zero all important bits in existing word 00222 w |= data; // combine data with existing word 00223 return writeWord(devAddr, regAddr, w); 00224 } else { 00225 return false; 00226 } 00227 } 00228 00229 /** Write single byte to an 8-bit device register. 00230 * @param devAddr I2C slave device address 00231 * @param regAddr Register address to write to 00232 * @param data New byte value to write 00233 * @return Status of operation (true = success) 00234 */ 00235 bool I2Cdev::writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data) { 00236 return writeBytes(devAddr, regAddr, 1, &data); 00237 } 00238 00239 /** Write single word to a 16-bit device register. 00240 * @param devAddr I2C slave device address 00241 * @param regAddr Register address to write to 00242 * @param data New word value to write 00243 * @return Status of operation (true = success) 00244 */ 00245 bool I2Cdev::writeWord(uint8_t devAddr, uint8_t regAddr, uint16_t data) { 00246 return writeWords(devAddr, regAddr, 1, &data); 00247 } 00248 00249 bool I2Cdev::writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data) 00250 { 00251 int len = length + 1; 00252 char *buf = (char*)malloc(len); 00253 buf[0] = regAddr; 00254 for (int i = 0; i < length; i++) { 00255 buf[i + 1] = data[i]; 00256 } 00257 i2c.write(devAddr << 1 , buf, len); 00258 00259 free (buf); 00260 return true; 00261 } 00262 00263 bool I2Cdev::writeWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data) 00264 { 00265 int len = length * 2 + 1; 00266 char *buf = (char*)malloc(len); 00267 buf[0] = regAddr; 00268 for (int i = 0; i < length; i++) { 00269 uint16_t word = data[i]; 00270 buf[2*i + 1] = word >> 8; 00271 buf[2*i + 2] = word & 0xFF; 00272 } 00273 i2c.write(devAddr << 1 , buf, len); 00274 00275 free (buf); 00276 return true; 00277 } 00278 00279 uint16_t I2Cdev::readTimeout(void) 00280 { 00281 return 0; 00282 }
Generated on Wed Jul 13 2022 20:00:27 by
