Adafruit_I2CDevice.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. #include "Adafruit_I2CDevice.h"
  2. // #define DEBUG_SERIAL Serial
  3. /*!
  4. * @brief Create an I2C device at a given address
  5. * @param addr The 7-bit I2C address for the device
  6. * @param theWire The I2C bus to use, defaults to &Wire
  7. */
  8. Adafruit_I2CDevice::Adafruit_I2CDevice(uint8_t addr, TwoWire *theWire) {
  9. _addr = addr;
  10. _wire = theWire;
  11. _begun = false;
  12. #ifdef ARDUINO_ARCH_SAMD
  13. _maxBufferSize = 250; // as defined in Wire.h's RingBuffer
  14. #elif defined(ESP32)
  15. _maxBufferSize = I2C_BUFFER_LENGTH;
  16. #else
  17. _maxBufferSize = 32;
  18. #endif
  19. }
  20. /*!
  21. * @brief Initializes and does basic address detection
  22. * @param addr_detect Whether we should attempt to detect the I2C address
  23. * with a scan. 99% of sensors/devices don't mind, but once in a while they
  24. * don't respond well to a scan!
  25. * @return True if I2C initialized and a device with the addr found
  26. */
  27. bool Adafruit_I2CDevice::begin(bool addr_detect) {
  28. _wire->begin();
  29. _begun = true;
  30. if (addr_detect) {
  31. return detected();
  32. }
  33. return true;
  34. }
  35. /*!
  36. * @brief De-initialize device, turn off the Wire interface
  37. */
  38. void Adafruit_I2CDevice::end(void) {
  39. // Not all port implement Wire::end(), such as
  40. // - ESP8266
  41. // - AVR core without WIRE_HAS_END
  42. // - ESP32: end() is implemented since 2.0.1 which is latest at the moment.
  43. // Temporarily disable for now to give time for user to update.
  44. #if !(defined(ESP8266) || \
  45. (defined(ARDUINO_ARCH_AVR) && !defined(WIRE_HAS_END)) || \
  46. defined(ARDUINO_ARCH_ESP32))
  47. _wire->end();
  48. _begun = false;
  49. #endif
  50. }
  51. /*!
  52. * @brief Scans I2C for the address - note will give a false-positive
  53. * if there's no pullups on I2C
  54. * @return True if I2C initialized and a device with the addr found
  55. */
  56. bool Adafruit_I2CDevice::detected(void) {
  57. // Init I2C if not done yet
  58. if (!_begun && !begin()) {
  59. return false;
  60. }
  61. // A basic scanner, see if it ACK's
  62. _wire->beginTransmission(_addr);
  63. #ifdef DEBUG_SERIAL
  64. DEBUG_SERIAL.print(F("Address 0x"));
  65. DEBUG_SERIAL.print(_addr, HEX);
  66. #endif
  67. #ifdef ARDUINO_ARCH_MBED
  68. _wire->write(0); // forces a write request instead of a read
  69. #endif
  70. if (_wire->endTransmission() == 0) {
  71. #ifdef DEBUG_SERIAL
  72. DEBUG_SERIAL.println(F(" Detected"));
  73. #endif
  74. return true;
  75. }
  76. #ifdef DEBUG_SERIAL
  77. DEBUG_SERIAL.println(F(" Not detected"));
  78. #endif
  79. return false;
  80. }
  81. /*!
  82. * @brief Write a buffer or two to the I2C device. Cannot be more than
  83. * maxBufferSize() bytes.
  84. * @param buffer Pointer to buffer of data to write. This is const to
  85. * ensure the content of this buffer doesn't change.
  86. * @param len Number of bytes from buffer to write
  87. * @param prefix_buffer Pointer to optional array of data to write before
  88. * buffer. Cannot be more than maxBufferSize() bytes. This is const to
  89. * ensure the content of this buffer doesn't change.
  90. * @param prefix_len Number of bytes from prefix buffer to write
  91. * @param stop Whether to send an I2C STOP signal on write
  92. * @return True if write was successful, otherwise false.
  93. */
  94. bool Adafruit_I2CDevice::write(const uint8_t *buffer, size_t len, bool stop,
  95. const uint8_t *prefix_buffer,
  96. size_t prefix_len) {
  97. if ((len + prefix_len) > maxBufferSize()) {
  98. // currently not guaranteed to work if more than 32 bytes!
  99. // we will need to find out if some platforms have larger
  100. // I2C buffer sizes :/
  101. #ifdef DEBUG_SERIAL
  102. DEBUG_SERIAL.println(F("\tI2CDevice could not write such a large buffer"));
  103. #endif
  104. return false;
  105. }
  106. _wire->beginTransmission(_addr);
  107. // Write the prefix data (usually an address)
  108. if ((prefix_len != 0) && (prefix_buffer != nullptr)) {
  109. if (_wire->write(prefix_buffer, prefix_len) != prefix_len) {
  110. #ifdef DEBUG_SERIAL
  111. DEBUG_SERIAL.println(F("\tI2CDevice failed to write"));
  112. #endif
  113. return false;
  114. }
  115. }
  116. // Write the data itself
  117. if (_wire->write(buffer, len) != len) {
  118. #ifdef DEBUG_SERIAL
  119. DEBUG_SERIAL.println(F("\tI2CDevice failed to write"));
  120. #endif
  121. return false;
  122. }
  123. #ifdef DEBUG_SERIAL
  124. DEBUG_SERIAL.print(F("\tI2CWRITE @ 0x"));
  125. DEBUG_SERIAL.print(_addr, HEX);
  126. DEBUG_SERIAL.print(F(" :: "));
  127. if ((prefix_len != 0) && (prefix_buffer != nullptr)) {
  128. for (uint16_t i = 0; i < prefix_len; i++) {
  129. DEBUG_SERIAL.print(F("0x"));
  130. DEBUG_SERIAL.print(prefix_buffer[i], HEX);
  131. DEBUG_SERIAL.print(F(", "));
  132. }
  133. }
  134. for (uint16_t i = 0; i < len; i++) {
  135. DEBUG_SERIAL.print(F("0x"));
  136. DEBUG_SERIAL.print(buffer[i], HEX);
  137. DEBUG_SERIAL.print(F(", "));
  138. if (i % 32 == 31) {
  139. DEBUG_SERIAL.println();
  140. }
  141. }
  142. if (stop) {
  143. DEBUG_SERIAL.print("\tSTOP");
  144. }
  145. #endif
  146. if (_wire->endTransmission(stop) == 0) {
  147. #ifdef DEBUG_SERIAL
  148. DEBUG_SERIAL.println();
  149. // DEBUG_SERIAL.println("Sent!");
  150. #endif
  151. return true;
  152. } else {
  153. #ifdef DEBUG_SERIAL
  154. DEBUG_SERIAL.println("\tFailed to send!");
  155. #endif
  156. return false;
  157. }
  158. }
  159. /*!
  160. * @brief Read from I2C into a buffer from the I2C device.
  161. * Cannot be more than maxBufferSize() bytes.
  162. * @param buffer Pointer to buffer of data to read into
  163. * @param len Number of bytes from buffer to read.
  164. * @param stop Whether to send an I2C STOP signal on read
  165. * @return True if read was successful, otherwise false.
  166. */
  167. bool Adafruit_I2CDevice::read(uint8_t *buffer, size_t len, bool stop) {
  168. size_t pos = 0;
  169. while (pos < len) {
  170. size_t read_len =
  171. ((len - pos) > maxBufferSize()) ? maxBufferSize() : (len - pos);
  172. bool read_stop = (pos < (len - read_len)) ? false : stop;
  173. if (!_read(buffer + pos, read_len, read_stop))
  174. return false;
  175. pos += read_len;
  176. }
  177. return true;
  178. }
  179. bool Adafruit_I2CDevice::_read(uint8_t *buffer, size_t len, bool stop) {
  180. #if defined(TinyWireM_h)
  181. size_t recv = _wire->requestFrom((uint8_t)_addr, (uint8_t)len);
  182. #elif defined(ARDUINO_ARCH_MEGAAVR)
  183. size_t recv = _wire->requestFrom(_addr, len, stop);
  184. #else
  185. size_t recv = _wire->requestFrom((uint8_t)_addr, (uint8_t)len, (uint8_t)stop);
  186. #endif
  187. if (recv != len) {
  188. // Not enough data available to fulfill our obligation!
  189. #ifdef DEBUG_SERIAL
  190. DEBUG_SERIAL.print(F("\tI2CDevice did not receive enough data: "));
  191. DEBUG_SERIAL.println(recv);
  192. #endif
  193. return false;
  194. }
  195. for (uint16_t i = 0; i < len; i++) {
  196. buffer[i] = _wire->read();
  197. }
  198. #ifdef DEBUG_SERIAL
  199. DEBUG_SERIAL.print(F("\tI2CREAD @ 0x"));
  200. DEBUG_SERIAL.print(_addr, HEX);
  201. DEBUG_SERIAL.print(F(" :: "));
  202. for (uint16_t i = 0; i < len; i++) {
  203. DEBUG_SERIAL.print(F("0x"));
  204. DEBUG_SERIAL.print(buffer[i], HEX);
  205. DEBUG_SERIAL.print(F(", "));
  206. if (len % 32 == 31) {
  207. DEBUG_SERIAL.println();
  208. }
  209. }
  210. DEBUG_SERIAL.println();
  211. #endif
  212. return true;
  213. }
  214. /*!
  215. * @brief Write some data, then read some data from I2C into another buffer.
  216. * Cannot be more than maxBufferSize() bytes. The buffers can point to
  217. * same/overlapping locations.
  218. * @param write_buffer Pointer to buffer of data to write from
  219. * @param write_len Number of bytes from buffer to write.
  220. * @param read_buffer Pointer to buffer of data to read into.
  221. * @param read_len Number of bytes from buffer to read.
  222. * @param stop Whether to send an I2C STOP signal between the write and read
  223. * @return True if write & read was successful, otherwise false.
  224. */
  225. bool Adafruit_I2CDevice::write_then_read(const uint8_t *write_buffer,
  226. size_t write_len, uint8_t *read_buffer,
  227. size_t read_len, bool stop) {
  228. if (!write(write_buffer, write_len, stop)) {
  229. return false;
  230. }
  231. return read(read_buffer, read_len);
  232. }
  233. /*!
  234. * @brief Returns the 7-bit address of this device
  235. * @return The 7-bit address of this device
  236. */
  237. uint8_t Adafruit_I2CDevice::address(void) { return _addr; }
  238. /*!
  239. * @brief Change the I2C clock speed to desired (relies on
  240. * underlying Wire support!
  241. * @param desiredclk The desired I2C SCL frequency
  242. * @return True if this platform supports changing I2C speed.
  243. * Not necessarily that the speed was achieved!
  244. */
  245. bool Adafruit_I2CDevice::setSpeed(uint32_t desiredclk) {
  246. #if defined(__AVR_ATmega328__) || \
  247. defined(__AVR_ATmega328P__) // fix arduino core set clock
  248. // calculate TWBR correctly
  249. if ((F_CPU / 18) < desiredclk) {
  250. #ifdef DEBUG_SERIAL
  251. Serial.println(F("I2C.setSpeed too high."));
  252. #endif
  253. return false;
  254. }
  255. uint32_t atwbr = ((F_CPU / desiredclk) - 16) / 2;
  256. if (atwbr > 16320) {
  257. #ifdef DEBUG_SERIAL
  258. Serial.println(F("I2C.setSpeed too low."));
  259. #endif
  260. return false;
  261. }
  262. if (atwbr <= 255) {
  263. atwbr /= 1;
  264. TWSR = 0x0;
  265. } else if (atwbr <= 1020) {
  266. atwbr /= 4;
  267. TWSR = 0x1;
  268. } else if (atwbr <= 4080) {
  269. atwbr /= 16;
  270. TWSR = 0x2;
  271. } else { // if (atwbr <= 16320)
  272. atwbr /= 64;
  273. TWSR = 0x3;
  274. }
  275. TWBR = atwbr;
  276. #ifdef DEBUG_SERIAL
  277. Serial.print(F("TWSR prescaler = "));
  278. Serial.println(pow(4, TWSR));
  279. Serial.print(F("TWBR = "));
  280. Serial.println(atwbr);
  281. #endif
  282. return true;
  283. #elif (ARDUINO >= 157) && !defined(ARDUINO_STM32_FEATHER) && \
  284. !defined(TinyWireM_h)
  285. _wire->setClock(desiredclk);
  286. return true;
  287. #else
  288. (void)desiredclk;
  289. return false;
  290. #endif
  291. }