Adafruit_I2CDevice.cpp 7.0 KB

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