hadif azli
/
TEST123
BLYNK TEST
I2Cdev.cpp@2:6cd3b0947188, 2016-06-15 (annotated)
- Committer:
- lixianyu
- Date:
- Wed Jun 15 03:08:40 2016 +0000
- Revision:
- 2:6cd3b0947188
- Child:
- 3:4cd9171ba989
PM2.5????????5V??????????
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
lixianyu | 2:6cd3b0947188 | 1 | #include "I2Cdev.h" |
lixianyu | 2:6cd3b0947188 | 2 | |
lixianyu | 2:6cd3b0947188 | 3 | extern DigitalOut myled; |
lixianyu | 2:6cd3b0947188 | 4 | static uint8_t buffer[24]; |
lixianyu | 2:6cd3b0947188 | 5 | //I2C g_i2c1(P0_11, P0_10); |
lixianyu | 2:6cd3b0947188 | 6 | extern I2C g_i2c; |
lixianyu | 2:6cd3b0947188 | 7 | |
lixianyu | 2:6cd3b0947188 | 8 | uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT; |
lixianyu | 2:6cd3b0947188 | 9 | |
lixianyu | 2:6cd3b0947188 | 10 | void I2Cdev::init() |
lixianyu | 2:6cd3b0947188 | 11 | { |
lixianyu | 2:6cd3b0947188 | 12 | g_i2c.frequency(267000); |
lixianyu | 2:6cd3b0947188 | 13 | } |
lixianyu | 2:6cd3b0947188 | 14 | |
lixianyu | 2:6cd3b0947188 | 15 | /** Default constructor. |
lixianyu | 2:6cd3b0947188 | 16 | */ |
lixianyu | 2:6cd3b0947188 | 17 | I2Cdev::I2Cdev() |
lixianyu | 2:6cd3b0947188 | 18 | { |
lixianyu | 2:6cd3b0947188 | 19 | g_i2c.frequency(400000); |
lixianyu | 2:6cd3b0947188 | 20 | //myled = 1; |
lixianyu | 2:6cd3b0947188 | 21 | } |
lixianyu | 2:6cd3b0947188 | 22 | |
lixianyu | 2:6cd3b0947188 | 23 | /** Read a single bit from an 8-bit device register. |
lixianyu | 2:6cd3b0947188 | 24 | * @param devAddr I2C slave device address |
lixianyu | 2:6cd3b0947188 | 25 | * @param regAddr Register regAddr to read from |
lixianyu | 2:6cd3b0947188 | 26 | * @param bitNum Bit position to read (0-7) |
lixianyu | 2:6cd3b0947188 | 27 | * @param data Container for single bit value |
lixianyu | 2:6cd3b0947188 | 28 | * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) |
lixianyu | 2:6cd3b0947188 | 29 | * @return Status of read operation (true = success) |
lixianyu | 2:6cd3b0947188 | 30 | */ |
lixianyu | 2:6cd3b0947188 | 31 | int8_t I2Cdev::readBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *data, uint16_t timeout) |
lixianyu | 2:6cd3b0947188 | 32 | { |
lixianyu | 2:6cd3b0947188 | 33 | uint8_t b; |
lixianyu | 2:6cd3b0947188 | 34 | uint8_t count = readByte(devAddr, regAddr, &b, timeout); |
lixianyu | 2:6cd3b0947188 | 35 | *data = b & (1 << bitNum); |
lixianyu | 2:6cd3b0947188 | 36 | return count; |
lixianyu | 2:6cd3b0947188 | 37 | } |
lixianyu | 2:6cd3b0947188 | 38 | |
lixianyu | 2:6cd3b0947188 | 39 | /** Read a single bit from a 16-bit device register. |
lixianyu | 2:6cd3b0947188 | 40 | * @param devAddr I2C slave device address |
lixianyu | 2:6cd3b0947188 | 41 | * @param regAddr Register regAddr to read from |
lixianyu | 2:6cd3b0947188 | 42 | * @param bitNum Bit position to read (0-15) |
lixianyu | 2:6cd3b0947188 | 43 | * @param data Container for single bit value |
lixianyu | 2:6cd3b0947188 | 44 | * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) |
lixianyu | 2:6cd3b0947188 | 45 | * @return Status of read operation (true = success) |
lixianyu | 2:6cd3b0947188 | 46 | */ |
lixianyu | 2:6cd3b0947188 | 47 | int8_t I2Cdev::readBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t *data, uint16_t timeout) |
lixianyu | 2:6cd3b0947188 | 48 | { |
lixianyu | 2:6cd3b0947188 | 49 | uint16_t b; |
lixianyu | 2:6cd3b0947188 | 50 | uint8_t count = readWord(devAddr, regAddr, &b, timeout); |
lixianyu | 2:6cd3b0947188 | 51 | *data = b & (1 << bitNum); |
lixianyu | 2:6cd3b0947188 | 52 | return count; |
lixianyu | 2:6cd3b0947188 | 53 | } |
lixianyu | 2:6cd3b0947188 | 54 | |
lixianyu | 2:6cd3b0947188 | 55 | /** Read multiple bits from an 8-bit device register. |
lixianyu | 2:6cd3b0947188 | 56 | * @param devAddr I2C slave device address |
lixianyu | 2:6cd3b0947188 | 57 | * @param regAddr Register regAddr to read from |
lixianyu | 2:6cd3b0947188 | 58 | * @param bitStart First bit position to read (0-7) |
lixianyu | 2:6cd3b0947188 | 59 | * @param length Number of bits to read (not more than 8) |
lixianyu | 2:6cd3b0947188 | 60 | * @param data Container for right-aligned value (i.e. '101' read from any bitStart position will equal 0x05) |
lixianyu | 2:6cd3b0947188 | 61 | * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) |
lixianyu | 2:6cd3b0947188 | 62 | * @return Status of read operation (true = success) |
lixianyu | 2:6cd3b0947188 | 63 | */ |
lixianyu | 2:6cd3b0947188 | 64 | int8_t I2Cdev::readBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data, uint16_t timeout) |
lixianyu | 2:6cd3b0947188 | 65 | { |
lixianyu | 2:6cd3b0947188 | 66 | // 01101001 read byte |
lixianyu | 2:6cd3b0947188 | 67 | // 76543210 bit numbers |
lixianyu | 2:6cd3b0947188 | 68 | // xxx args: bitStart=4, length=3 |
lixianyu | 2:6cd3b0947188 | 69 | // 010 masked |
lixianyu | 2:6cd3b0947188 | 70 | // -> 010 shifted |
lixianyu | 2:6cd3b0947188 | 71 | uint8_t count, b; |
lixianyu | 2:6cd3b0947188 | 72 | if ((count = readByte(devAddr, regAddr, &b, timeout)) != 0) { |
lixianyu | 2:6cd3b0947188 | 73 | uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1); |
lixianyu | 2:6cd3b0947188 | 74 | b &= mask; |
lixianyu | 2:6cd3b0947188 | 75 | b >>= (bitStart - length + 1); |
lixianyu | 2:6cd3b0947188 | 76 | *data = b; |
lixianyu | 2:6cd3b0947188 | 77 | } |
lixianyu | 2:6cd3b0947188 | 78 | return count; |
lixianyu | 2:6cd3b0947188 | 79 | } |
lixianyu | 2:6cd3b0947188 | 80 | |
lixianyu | 2:6cd3b0947188 | 81 | /** Read multiple bits from a 16-bit device register. |
lixianyu | 2:6cd3b0947188 | 82 | * @param devAddr I2C slave device address |
lixianyu | 2:6cd3b0947188 | 83 | * @param regAddr Register regAddr to read from |
lixianyu | 2:6cd3b0947188 | 84 | * @param bitStart First bit position to read (0-15) |
lixianyu | 2:6cd3b0947188 | 85 | * @param length Number of bits to read (not more than 16) |
lixianyu | 2:6cd3b0947188 | 86 | * @param data Container for right-aligned value (i.e. '101' read from any bitStart position will equal 0x05) |
lixianyu | 2:6cd3b0947188 | 87 | * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) |
lixianyu | 2:6cd3b0947188 | 88 | * @return Status of read operation (1 = success, 0 = failure, -1 = timeout) |
lixianyu | 2:6cd3b0947188 | 89 | */ |
lixianyu | 2:6cd3b0947188 | 90 | int8_t I2Cdev::readBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t *data, uint16_t timeout) |
lixianyu | 2:6cd3b0947188 | 91 | { |
lixianyu | 2:6cd3b0947188 | 92 | // 1101011001101001 read byte |
lixianyu | 2:6cd3b0947188 | 93 | // fedcba9876543210 bit numbers |
lixianyu | 2:6cd3b0947188 | 94 | // xxx args: bitStart=12, length=3 |
lixianyu | 2:6cd3b0947188 | 95 | // 010 masked |
lixianyu | 2:6cd3b0947188 | 96 | // -> 010 shifted |
lixianyu | 2:6cd3b0947188 | 97 | uint8_t count; |
lixianyu | 2:6cd3b0947188 | 98 | uint16_t w; |
lixianyu | 2:6cd3b0947188 | 99 | if ((count = readWord(devAddr, regAddr, &w, timeout)) != 0) { |
lixianyu | 2:6cd3b0947188 | 100 | uint16_t mask = ((1 << length) - 1) << (bitStart - length + 1); |
lixianyu | 2:6cd3b0947188 | 101 | w &= mask; |
lixianyu | 2:6cd3b0947188 | 102 | w >>= (bitStart - length + 1); |
lixianyu | 2:6cd3b0947188 | 103 | *data = w; |
lixianyu | 2:6cd3b0947188 | 104 | } |
lixianyu | 2:6cd3b0947188 | 105 | return count; |
lixianyu | 2:6cd3b0947188 | 106 | } |
lixianyu | 2:6cd3b0947188 | 107 | |
lixianyu | 2:6cd3b0947188 | 108 | /** Read single byte from an 8-bit device register. |
lixianyu | 2:6cd3b0947188 | 109 | * @param devAddr I2C slave device address |
lixianyu | 2:6cd3b0947188 | 110 | * @param regAddr Register regAddr to read from |
lixianyu | 2:6cd3b0947188 | 111 | * @param data Container for byte value read from device |
lixianyu | 2:6cd3b0947188 | 112 | * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) |
lixianyu | 2:6cd3b0947188 | 113 | * @return Status of read operation (true = success) |
lixianyu | 2:6cd3b0947188 | 114 | */ |
lixianyu | 2:6cd3b0947188 | 115 | int8_t I2Cdev::readByte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint16_t timeout) |
lixianyu | 2:6cd3b0947188 | 116 | { |
lixianyu | 2:6cd3b0947188 | 117 | return readBytes(devAddr, regAddr, 1, data, timeout); |
lixianyu | 2:6cd3b0947188 | 118 | } |
lixianyu | 2:6cd3b0947188 | 119 | |
lixianyu | 2:6cd3b0947188 | 120 | /** Read single word from a 16-bit device register. |
lixianyu | 2:6cd3b0947188 | 121 | * @param devAddr I2C slave device address |
lixianyu | 2:6cd3b0947188 | 122 | * @param regAddr Register regAddr to read from |
lixianyu | 2:6cd3b0947188 | 123 | * @param data Container for word value read from device |
lixianyu | 2:6cd3b0947188 | 124 | * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) |
lixianyu | 2:6cd3b0947188 | 125 | * @return Status of read operation (true = success) |
lixianyu | 2:6cd3b0947188 | 126 | */ |
lixianyu | 2:6cd3b0947188 | 127 | int8_t I2Cdev::readWord(uint8_t devAddr, uint8_t regAddr, uint16_t *data, uint16_t timeout) |
lixianyu | 2:6cd3b0947188 | 128 | { |
lixianyu | 2:6cd3b0947188 | 129 | return readWords(devAddr, regAddr, 1, data, timeout); |
lixianyu | 2:6cd3b0947188 | 130 | } |
lixianyu | 2:6cd3b0947188 | 131 | |
lixianyu | 2:6cd3b0947188 | 132 | /** Read multiple bytes from an 8-bit device register. |
lixianyu | 2:6cd3b0947188 | 133 | * @param devAddr I2C slave device address |
lixianyu | 2:6cd3b0947188 | 134 | * @param regAddr First register regAddr to read from |
lixianyu | 2:6cd3b0947188 | 135 | * @param length Number of bytes to read |
lixianyu | 2:6cd3b0947188 | 136 | * @param data Buffer to store read data in |
lixianyu | 2:6cd3b0947188 | 137 | * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) |
lixianyu | 2:6cd3b0947188 | 138 | * @return Number of bytes read (-1 indicates failure) |
lixianyu | 2:6cd3b0947188 | 139 | */ |
lixianyu | 2:6cd3b0947188 | 140 | int8_t I2Cdev::readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout) |
lixianyu | 2:6cd3b0947188 | 141 | { |
lixianyu | 2:6cd3b0947188 | 142 | g_i2c.write(devAddr << 1, (char*)®Addr, 1, false); |
lixianyu | 2:6cd3b0947188 | 143 | uint8_t realReadAddr = (devAddr << 1) | 0x01; |
lixianyu | 2:6cd3b0947188 | 144 | int retRead = g_i2c.read(realReadAddr, (char*)data, length); |
lixianyu | 2:6cd3b0947188 | 145 | if (retRead == 0) { |
lixianyu | 2:6cd3b0947188 | 146 | return length; |
lixianyu | 2:6cd3b0947188 | 147 | } |
lixianyu | 2:6cd3b0947188 | 148 | return -1; |
lixianyu | 2:6cd3b0947188 | 149 | } |
lixianyu | 2:6cd3b0947188 | 150 | |
lixianyu | 2:6cd3b0947188 | 151 | int8_t I2Cdev::readBytesOnly(uint8_t devAddr, uint8_t length, uint8_t *data, uint16_t timeout) |
lixianyu | 2:6cd3b0947188 | 152 | { |
lixianyu | 2:6cd3b0947188 | 153 | uint8_t realReadAddr = (devAddr << 1) | 0x01; |
lixianyu | 2:6cd3b0947188 | 154 | int retRead = g_i2c.read(realReadAddr, (char*)data, length); |
lixianyu | 2:6cd3b0947188 | 155 | if (retRead == 0) { |
lixianyu | 2:6cd3b0947188 | 156 | return length; |
lixianyu | 2:6cd3b0947188 | 157 | } |
lixianyu | 2:6cd3b0947188 | 158 | return -1; |
lixianyu | 2:6cd3b0947188 | 159 | } |
lixianyu | 2:6cd3b0947188 | 160 | |
lixianyu | 2:6cd3b0947188 | 161 | /** Read multiple words from a 16-bit device register. |
lixianyu | 2:6cd3b0947188 | 162 | * @param devAddr I2C slave device address |
lixianyu | 2:6cd3b0947188 | 163 | * @param regAddr First register regAddr to read from |
lixianyu | 2:6cd3b0947188 | 164 | * @param length Number of words to read |
lixianyu | 2:6cd3b0947188 | 165 | * @param data Buffer to store read data in |
lixianyu | 2:6cd3b0947188 | 166 | * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) |
lixianyu | 2:6cd3b0947188 | 167 | * @return Number of words read (0 indicates failure) |
lixianyu | 2:6cd3b0947188 | 168 | */ |
lixianyu | 2:6cd3b0947188 | 169 | int8_t I2Cdev::readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data, uint16_t timeout) |
lixianyu | 2:6cd3b0947188 | 170 | { |
lixianyu | 2:6cd3b0947188 | 171 | g_i2c.write(devAddr << 1, (char*)®Addr, 1, false); |
lixianyu | 2:6cd3b0947188 | 172 | uint8_t realReadAddr = (devAddr << 1) | 0x01; |
lixianyu | 2:6cd3b0947188 | 173 | int retRead = g_i2c.read(realReadAddr, (char*)data, length*2); |
lixianyu | 2:6cd3b0947188 | 174 | if (retRead == 0) { |
lixianyu | 2:6cd3b0947188 | 175 | return length; |
lixianyu | 2:6cd3b0947188 | 176 | } |
lixianyu | 2:6cd3b0947188 | 177 | return 0; |
lixianyu | 2:6cd3b0947188 | 178 | } |
lixianyu | 2:6cd3b0947188 | 179 | |
lixianyu | 2:6cd3b0947188 | 180 | /** write a single bit in an 8-bit device register. |
lixianyu | 2:6cd3b0947188 | 181 | * @param devAddr I2C slave device address |
lixianyu | 2:6cd3b0947188 | 182 | * @param regAddr Register regAddr to write to |
lixianyu | 2:6cd3b0947188 | 183 | * @param bitNum Bit position to write (0-7) |
lixianyu | 2:6cd3b0947188 | 184 | * @param value New bit value to write |
lixianyu | 2:6cd3b0947188 | 185 | * @return Status of operation (true = success) |
lixianyu | 2:6cd3b0947188 | 186 | */ |
lixianyu | 2:6cd3b0947188 | 187 | bool I2Cdev::writeBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data) |
lixianyu | 2:6cd3b0947188 | 188 | { |
lixianyu | 2:6cd3b0947188 | 189 | uint8_t b; |
lixianyu | 2:6cd3b0947188 | 190 | readByte(devAddr, regAddr, &b); |
lixianyu | 2:6cd3b0947188 | 191 | b = (data != 0) ? (b | (1 << bitNum)) : (b & ~(1 << bitNum)); |
lixianyu | 2:6cd3b0947188 | 192 | return writeByte(devAddr, regAddr, b); |
lixianyu | 2:6cd3b0947188 | 193 | } |
lixianyu | 2:6cd3b0947188 | 194 | |
lixianyu | 2:6cd3b0947188 | 195 | /** write a single bit in a 16-bit device register. |
lixianyu | 2:6cd3b0947188 | 196 | * @param devAddr I2C slave device address |
lixianyu | 2:6cd3b0947188 | 197 | * @param regAddr Register regAddr to write to |
lixianyu | 2:6cd3b0947188 | 198 | * @param bitNum Bit position to write (0-15) |
lixianyu | 2:6cd3b0947188 | 199 | * @param value New bit value to write |
lixianyu | 2:6cd3b0947188 | 200 | * @return Status of operation (true = success) |
lixianyu | 2:6cd3b0947188 | 201 | */ |
lixianyu | 2:6cd3b0947188 | 202 | bool I2Cdev::writeBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t data) |
lixianyu | 2:6cd3b0947188 | 203 | { |
lixianyu | 2:6cd3b0947188 | 204 | uint16_t w; |
lixianyu | 2:6cd3b0947188 | 205 | readWord(devAddr, regAddr, &w); |
lixianyu | 2:6cd3b0947188 | 206 | w = (data != 0) ? (w | (1 << bitNum)) : (w & ~(1 << bitNum)); |
lixianyu | 2:6cd3b0947188 | 207 | return writeWord(devAddr, regAddr, w); |
lixianyu | 2:6cd3b0947188 | 208 | } |
lixianyu | 2:6cd3b0947188 | 209 | |
lixianyu | 2:6cd3b0947188 | 210 | /** Write multiple bits in an 8-bit device register. |
lixianyu | 2:6cd3b0947188 | 211 | * @param devAddr I2C slave device address |
lixianyu | 2:6cd3b0947188 | 212 | * @param regAddr Register regAddr to write to |
lixianyu | 2:6cd3b0947188 | 213 | * @param bitStart First bit position to write (0-7) |
lixianyu | 2:6cd3b0947188 | 214 | * @param length Number of bits to write (not more than 8) |
lixianyu | 2:6cd3b0947188 | 215 | * @param data Right-aligned value to write |
lixianyu | 2:6cd3b0947188 | 216 | * @return Status of operation (true = success) |
lixianyu | 2:6cd3b0947188 | 217 | */ |
lixianyu | 2:6cd3b0947188 | 218 | bool I2Cdev::writeBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t data) |
lixianyu | 2:6cd3b0947188 | 219 | { |
lixianyu | 2:6cd3b0947188 | 220 | // 010 value to write |
lixianyu | 2:6cd3b0947188 | 221 | // 76543210 bit numbers |
lixianyu | 2:6cd3b0947188 | 222 | // xxx args: bitStart=4, length=3 |
lixianyu | 2:6cd3b0947188 | 223 | // 00011100 mask byte |
lixianyu | 2:6cd3b0947188 | 224 | // 10101111 original value (sample) |
lixianyu | 2:6cd3b0947188 | 225 | // 10100011 original & ~mask |
lixianyu | 2:6cd3b0947188 | 226 | // 10101011 masked | value |
lixianyu | 2:6cd3b0947188 | 227 | uint8_t b; |
lixianyu | 2:6cd3b0947188 | 228 | if (readByte(devAddr, regAddr, &b) != 0) { |
lixianyu | 2:6cd3b0947188 | 229 | uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1); |
lixianyu | 2:6cd3b0947188 | 230 | data <<= (bitStart - length + 1); // shift data into correct position |
lixianyu | 2:6cd3b0947188 | 231 | data &= mask; // zero all non-important bits in data |
lixianyu | 2:6cd3b0947188 | 232 | b &= ~(mask); // zero all important bits in existing byte |
lixianyu | 2:6cd3b0947188 | 233 | b |= data; // combine data with existing byte |
lixianyu | 2:6cd3b0947188 | 234 | return writeByte(devAddr, regAddr, b); |
lixianyu | 2:6cd3b0947188 | 235 | } else { |
lixianyu | 2:6cd3b0947188 | 236 | return false; |
lixianyu | 2:6cd3b0947188 | 237 | } |
lixianyu | 2:6cd3b0947188 | 238 | } |
lixianyu | 2:6cd3b0947188 | 239 | |
lixianyu | 2:6cd3b0947188 | 240 | /** Write multiple bits in a 16-bit device register. |
lixianyu | 2:6cd3b0947188 | 241 | * @param devAddr I2C slave device address |
lixianyu | 2:6cd3b0947188 | 242 | * @param regAddr Register regAddr to write to |
lixianyu | 2:6cd3b0947188 | 243 | * @param bitStart First bit position to write (0-15) |
lixianyu | 2:6cd3b0947188 | 244 | * @param length Number of bits to write (not more than 16) |
lixianyu | 2:6cd3b0947188 | 245 | * @param data Right-aligned value to write |
lixianyu | 2:6cd3b0947188 | 246 | * @return Status of operation (true = success) |
lixianyu | 2:6cd3b0947188 | 247 | */ |
lixianyu | 2:6cd3b0947188 | 248 | bool I2Cdev::writeBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t data) |
lixianyu | 2:6cd3b0947188 | 249 | { |
lixianyu | 2:6cd3b0947188 | 250 | // 010 value to write |
lixianyu | 2:6cd3b0947188 | 251 | // fedcba9876543210 bit numbers |
lixianyu | 2:6cd3b0947188 | 252 | // xxx args: bitStart=12, length=3 |
lixianyu | 2:6cd3b0947188 | 253 | // 0001110000000000 mask byte |
lixianyu | 2:6cd3b0947188 | 254 | // 1010111110010110 original value (sample) |
lixianyu | 2:6cd3b0947188 | 255 | // 1010001110010110 original & ~mask |
lixianyu | 2:6cd3b0947188 | 256 | // 1010101110010110 masked | value |
lixianyu | 2:6cd3b0947188 | 257 | uint16_t w; |
lixianyu | 2:6cd3b0947188 | 258 | if (readWord(devAddr, regAddr, &w) != 0) { |
lixianyu | 2:6cd3b0947188 | 259 | uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1); |
lixianyu | 2:6cd3b0947188 | 260 | data <<= (bitStart - length + 1); // shift data into correct position |
lixianyu | 2:6cd3b0947188 | 261 | data &= mask; // zero all non-important bits in data |
lixianyu | 2:6cd3b0947188 | 262 | w &= ~(mask); // zero all important bits in existing word |
lixianyu | 2:6cd3b0947188 | 263 | w |= data; // combine data with existing word |
lixianyu | 2:6cd3b0947188 | 264 | return writeWord(devAddr, regAddr, w); |
lixianyu | 2:6cd3b0947188 | 265 | } else { |
lixianyu | 2:6cd3b0947188 | 266 | return false; |
lixianyu | 2:6cd3b0947188 | 267 | } |
lixianyu | 2:6cd3b0947188 | 268 | } |
lixianyu | 2:6cd3b0947188 | 269 | |
lixianyu | 2:6cd3b0947188 | 270 | /** Write single byte to an 8-bit device register. |
lixianyu | 2:6cd3b0947188 | 271 | * @param devAddr I2C slave device address |
lixianyu | 2:6cd3b0947188 | 272 | * @param regAddr Register address to write to |
lixianyu | 2:6cd3b0947188 | 273 | * @param data New byte value to write |
lixianyu | 2:6cd3b0947188 | 274 | * @return Status of operation (true = success) |
lixianyu | 2:6cd3b0947188 | 275 | */ |
lixianyu | 2:6cd3b0947188 | 276 | bool I2Cdev::writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data) |
lixianyu | 2:6cd3b0947188 | 277 | { |
lixianyu | 2:6cd3b0947188 | 278 | return writeBytes(devAddr, regAddr, 1, &data); |
lixianyu | 2:6cd3b0947188 | 279 | } |
lixianyu | 2:6cd3b0947188 | 280 | |
lixianyu | 2:6cd3b0947188 | 281 | /** Write single word to a 16-bit device register. |
lixianyu | 2:6cd3b0947188 | 282 | * @param devAddr I2C slave device address |
lixianyu | 2:6cd3b0947188 | 283 | * @param regAddr Register address to write to |
lixianyu | 2:6cd3b0947188 | 284 | * @param data New word value to write |
lixianyu | 2:6cd3b0947188 | 285 | * @return Status of operation (true = success) |
lixianyu | 2:6cd3b0947188 | 286 | */ |
lixianyu | 2:6cd3b0947188 | 287 | bool I2Cdev::writeWord(uint8_t devAddr, uint8_t regAddr, uint16_t data) |
lixianyu | 2:6cd3b0947188 | 288 | { |
lixianyu | 2:6cd3b0947188 | 289 | return writeWords(devAddr, regAddr, 1, &data); |
lixianyu | 2:6cd3b0947188 | 290 | } |
lixianyu | 2:6cd3b0947188 | 291 | |
lixianyu | 2:6cd3b0947188 | 292 | /** Write multiple bytes to an 8-bit device register. |
lixianyu | 2:6cd3b0947188 | 293 | * @param devAddr I2C slave device address |
lixianyu | 2:6cd3b0947188 | 294 | * @param regAddr First register address to write to |
lixianyu | 2:6cd3b0947188 | 295 | * @param length Number of bytes to write |
lixianyu | 2:6cd3b0947188 | 296 | * @param data Buffer to copy new data from |
lixianyu | 2:6cd3b0947188 | 297 | * @return Status of operation (true = success) |
lixianyu | 2:6cd3b0947188 | 298 | */ |
lixianyu | 2:6cd3b0947188 | 299 | bool I2Cdev::writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t* data) |
lixianyu | 2:6cd3b0947188 | 300 | { |
lixianyu | 2:6cd3b0947188 | 301 | uint8_t i; |
lixianyu | 2:6cd3b0947188 | 302 | uint8_t *p = buffer; |
lixianyu | 2:6cd3b0947188 | 303 | |
lixianyu | 2:6cd3b0947188 | 304 | /* Copy address and data to local buffer for burst write */ |
lixianyu | 2:6cd3b0947188 | 305 | *p++ = regAddr; |
lixianyu | 2:6cd3b0947188 | 306 | for (i = 0; i < length; i++) { |
lixianyu | 2:6cd3b0947188 | 307 | *p++ = *data++; |
lixianyu | 2:6cd3b0947188 | 308 | } |
lixianyu | 2:6cd3b0947188 | 309 | length++; |
lixianyu | 2:6cd3b0947188 | 310 | /* Send address and data */ |
lixianyu | 2:6cd3b0947188 | 311 | int status = g_i2c.write(devAddr << 1, (char*)buffer, length, false); |
lixianyu | 2:6cd3b0947188 | 312 | return status == 0; |
lixianyu | 2:6cd3b0947188 | 313 | } |
lixianyu | 2:6cd3b0947188 | 314 | |
lixianyu | 2:6cd3b0947188 | 315 | /** Write multiple words to a 16-bit device register. |
lixianyu | 2:6cd3b0947188 | 316 | * @param devAddr I2C slave device address |
lixianyu | 2:6cd3b0947188 | 317 | * @param regAddr First register address to write to |
lixianyu | 2:6cd3b0947188 | 318 | * @param length Number of words to write |
lixianyu | 2:6cd3b0947188 | 319 | * @param data Buffer to copy new data from |
lixianyu | 2:6cd3b0947188 | 320 | * @return Status of operation (true = success) |
lixianyu | 2:6cd3b0947188 | 321 | */ |
lixianyu | 2:6cd3b0947188 | 322 | bool I2Cdev::writeWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t* data) |
lixianyu | 2:6cd3b0947188 | 323 | { |
lixianyu | 2:6cd3b0947188 | 324 | uint16_t i; |
lixianyu | 2:6cd3b0947188 | 325 | uint8_t *p = buffer; |
lixianyu | 2:6cd3b0947188 | 326 | uint16_t realLen = length * 2; |
lixianyu | 2:6cd3b0947188 | 327 | |
lixianyu | 2:6cd3b0947188 | 328 | /* Copy address and data to local buffer for burst write */ |
lixianyu | 2:6cd3b0947188 | 329 | *p++ = regAddr; |
lixianyu | 2:6cd3b0947188 | 330 | for (i = 0; i < realLen; i++) { |
lixianyu | 2:6cd3b0947188 | 331 | *p++ = *data++; |
lixianyu | 2:6cd3b0947188 | 332 | } |
lixianyu | 2:6cd3b0947188 | 333 | realLen++; |
lixianyu | 2:6cd3b0947188 | 334 | /* Send address and data */ |
lixianyu | 2:6cd3b0947188 | 335 | int status = g_i2c.write(devAddr << 1, (char*)buffer, realLen, false); |
lixianyu | 2:6cd3b0947188 | 336 | return status == 0; |
lixianyu | 2:6cd3b0947188 | 337 | } |