Adafruit_I2CDevice.cpp (7193B)
1 #include <Adafruit_I2CDevice.h> 2 #include <Arduino.h> 3 4 //#define DEBUG_SERIAL Serial 5 6 /*! 7 * @brief Create an I2C device at a given address 8 * @param addr The 7-bit I2C address for the device 9 * @param theWire The I2C bus to use, defaults to &Wire 10 */ 11 Adafruit_I2CDevice::Adafruit_I2CDevice(uint8_t addr, TwoWire *theWire) { 12 _addr = addr; 13 _wire = theWire; 14 _begun = false; 15 #ifdef ARDUINO_ARCH_SAMD 16 _maxBufferSize = 250; // as defined in Wire.h's RingBuffer 17 #else 18 _maxBufferSize = 32; 19 #endif 20 } 21 22 /*! 23 * @brief Initializes and does basic address detection 24 * @param addr_detect Whether we should attempt to detect the I2C address 25 * with a scan. 99% of sensors/devices don't mind but once in a while, they spaz 26 * on a scan! 27 * @return True if I2C initialized and a device with the addr found 28 */ 29 bool Adafruit_I2CDevice::begin(bool addr_detect) { 30 _wire->begin(); 31 _begun = true; 32 33 if (addr_detect) { 34 return detected(); 35 } 36 return true; 37 } 38 39 /*! 40 * @brief Scans I2C for the address - note will give a false-positive 41 * if there's no pullups on I2C 42 * @return True if I2C initialized and a device with the addr found 43 */ 44 bool Adafruit_I2CDevice::detected(void) { 45 // Init I2C if not done yet 46 if (!_begun && !begin()) { 47 return false; 48 } 49 50 // A basic scanner, see if it ACK's 51 _wire->beginTransmission(_addr); 52 if (_wire->endTransmission() == 0) { 53 return true; 54 } 55 return false; 56 } 57 58 /*! 59 * @brief Write a buffer or two to the I2C device. Cannot be more than 60 * maxBufferSize() bytes. 61 * @param buffer Pointer to buffer of data to write. This is const to 62 * ensure the content of this buffer doesn't change. 63 * @param len Number of bytes from buffer to write 64 * @param prefix_buffer Pointer to optional array of data to write before 65 * buffer. Cannot be more than maxBufferSize() bytes. This is const to 66 * ensure the content of this buffer doesn't change. 67 * @param prefix_len Number of bytes from prefix buffer to write 68 * @param stop Whether to send an I2C STOP signal on write 69 * @return True if write was successful, otherwise false. 70 */ 71 bool Adafruit_I2CDevice::write(const uint8_t *buffer, size_t len, bool stop, 72 const uint8_t *prefix_buffer, 73 size_t prefix_len) { 74 if ((len + prefix_len) > maxBufferSize()) { 75 // currently not guaranteed to work if more than 32 bytes! 76 // we will need to find out if some platforms have larger 77 // I2C buffer sizes :/ 78 #ifdef DEBUG_SERIAL 79 DEBUG_SERIAL.println(F("\tI2CDevice could not write such a large buffer")); 80 #endif 81 return false; 82 } 83 84 _wire->beginTransmission(_addr); 85 86 // Write the prefix data (usually an address) 87 if ((prefix_len != 0) && (prefix_buffer != NULL)) { 88 if (_wire->write(prefix_buffer, prefix_len) != prefix_len) { 89 #ifdef DEBUG_SERIAL 90 DEBUG_SERIAL.println(F("\tI2CDevice failed to write")); 91 #endif 92 return false; 93 } 94 } 95 96 // Write the data itself 97 if (_wire->write(buffer, len) != len) { 98 #ifdef DEBUG_SERIAL 99 DEBUG_SERIAL.println(F("\tI2CDevice failed to write")); 100 #endif 101 return false; 102 } 103 104 #ifdef DEBUG_SERIAL 105 106 DEBUG_SERIAL.print(F("\tI2CWRITE @ 0x")); 107 DEBUG_SERIAL.print(_addr, HEX); 108 DEBUG_SERIAL.print(F(" :: ")); 109 if ((prefix_len != 0) && (prefix_buffer != NULL)) { 110 for (uint16_t i = 0; i < prefix_len; i++) { 111 DEBUG_SERIAL.print(F("0x")); 112 DEBUG_SERIAL.print(prefix_buffer[i], HEX); 113 DEBUG_SERIAL.print(F(", ")); 114 } 115 } 116 for (uint16_t i = 0; i < len; i++) { 117 DEBUG_SERIAL.print(F("0x")); 118 DEBUG_SERIAL.print(buffer[i], HEX); 119 DEBUG_SERIAL.print(F(", ")); 120 if (i % 32 == 31) { 121 DEBUG_SERIAL.println(); 122 } 123 } 124 DEBUG_SERIAL.println(); 125 #endif 126 127 #ifdef DEBUG_SERIAL 128 // DEBUG_SERIAL.print("Stop: "); DEBUG_SERIAL.println(stop); 129 #endif 130 131 if (_wire->endTransmission(stop) == 0) { 132 #ifdef DEBUG_SERIAL 133 // DEBUG_SERIAL.println("Sent!"); 134 #endif 135 return true; 136 } else { 137 #ifdef DEBUG_SERIAL 138 DEBUG_SERIAL.println("Failed to send!"); 139 #endif 140 return false; 141 } 142 } 143 144 /*! 145 * @brief Read from I2C into a buffer from the I2C device. 146 * Cannot be more than maxBufferSize() bytes. 147 * @param buffer Pointer to buffer of data to read into 148 * @param len Number of bytes from buffer to read. 149 * @param stop Whether to send an I2C STOP signal on read 150 * @return True if read was successful, otherwise false. 151 */ 152 bool Adafruit_I2CDevice::read(uint8_t *buffer, size_t len, bool stop) { 153 if (len > maxBufferSize()) { 154 // currently not guaranteed to work if more than 32 bytes! 155 // we will need to find out if some platforms have larger 156 // I2C buffer sizes :/ 157 #ifdef DEBUG_SERIAL 158 DEBUG_SERIAL.println(F("\tI2CDevice could not read such a large buffer")); 159 #endif 160 return false; 161 } 162 163 size_t recv = _wire->requestFrom((uint8_t)_addr, (uint8_t)len, (uint8_t)stop); 164 if (recv != len) { 165 // Not enough data available to fulfill our obligation! 166 #ifdef DEBUG_SERIAL 167 DEBUG_SERIAL.print(F("\tI2CDevice did not receive enough data: ")); 168 DEBUG_SERIAL.println(recv); 169 #endif 170 return false; 171 } 172 173 for (uint16_t i = 0; i < len; i++) { 174 buffer[i] = _wire->read(); 175 } 176 177 #ifdef DEBUG_SERIAL 178 DEBUG_SERIAL.print(F("\tI2CREAD @ 0x")); 179 DEBUG_SERIAL.print(_addr, HEX); 180 DEBUG_SERIAL.print(F(" :: ")); 181 for (uint16_t i = 0; i < len; i++) { 182 DEBUG_SERIAL.print(F("0x")); 183 DEBUG_SERIAL.print(buffer[i], HEX); 184 DEBUG_SERIAL.print(F(", ")); 185 if (len % 32 == 31) { 186 DEBUG_SERIAL.println(); 187 } 188 } 189 DEBUG_SERIAL.println(); 190 #endif 191 192 return true; 193 } 194 195 /*! 196 * @brief Write some data, then read some data from I2C into another buffer. 197 * Cannot be more than maxBufferSize() bytes. The buffers can point to 198 * same/overlapping locations. 199 * @param write_buffer Pointer to buffer of data to write from 200 * @param write_len Number of bytes from buffer to write. 201 * @param read_buffer Pointer to buffer of data to read into. 202 * @param read_len Number of bytes from buffer to read. 203 * @param stop Whether to send an I2C STOP signal between the write and read 204 * @return True if write & read was successful, otherwise false. 205 */ 206 bool Adafruit_I2CDevice::write_then_read(const uint8_t *write_buffer, 207 size_t write_len, uint8_t *read_buffer, 208 size_t read_len, bool stop) { 209 if (!write(write_buffer, write_len, stop)) { 210 return false; 211 } 212 213 return read(read_buffer, read_len); 214 } 215 216 /*! 217 * @brief Returns the 7-bit address of this device 218 * @return The 7-bit address of this device 219 */ 220 uint8_t Adafruit_I2CDevice::address(void) { return _addr; } 221 222 /*! 223 * @brief Change the I2C clock speed to desired (relies on 224 * underlying Wire support! 225 * @param desiredclk The desired I2C SCL frequency 226 * @return True if this platform supports changing I2C speed. 227 * Not necessarily that the speed was achieved! 228 */ 229 bool Adafruit_I2CDevice::setSpeed(uint32_t desiredclk) { 230 #if (ARDUINO >= 157) && !defined(ARDUINO_STM32_FEATHER) 231 _wire->setClock(desiredclk); 232 return true; 233 #else 234 return false; 235 #endif 236 }