MatrixMiniR4 1.1.5
Matrix Mini R4 Arduino Library API Documentation
Loading...
Searching...
No Matches
MiniR4_I2CDevice.cpp
Go to the documentation of this file.
1
6/*
7The MIT License (MIT)
8
9Copyright (c) 2017 Adafruit Industries
10
11Permission is hereby granted, free of charge, to any person obtaining a copy
12of this software and associated documentation files (the "Software"), to deal
13in the Software without restriction, including without limitation the rights
14to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15copies of the Software, and to permit persons to whom the Software is
16furnished to do so, subject to the following conditions:
17
18The above copyright notice and this permission notice shall be included in all
19copies or substantial portions of the Software.
20
21THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27SOFTWARE.
28*/
29
30#include "MiniR4_I2CDevice.h"
31
32//#define DEBUG_SERIAL Serial
33
39Adafruit_I2CDevice::Adafruit_I2CDevice(uint8_t addr, TwoWire *theWire) {
40 _addr = addr;
41 _wire = theWire;
42 _begun = false;
43#ifdef ARDUINO_ARCH_SAMD
44 _maxBufferSize = 250; // as defined in Wire.h's RingBuffer
45#elif defined(ESP32)
46 _maxBufferSize = I2C_BUFFER_LENGTH;
47#else
48 _maxBufferSize = 32;
49#endif
50}
51
59bool Adafruit_I2CDevice::begin(bool addr_detect) {
60 _wire->begin();
61 _begun = true;
62
63 if (addr_detect) {
64 return detected();
65 }
66 return true;
67}
68
73 // Not all port implement Wire::end(), such as
74 // - ESP8266
75 // - AVR core without WIRE_HAS_END
76 // - ESP32: end() is implemented since 2.0.1 which is latest at the moment.
77 // Temporarily disable for now to give time for user to update.
78#if !(defined(ESP8266) || \
79 (defined(ARDUINO_ARCH_AVR) && !defined(WIRE_HAS_END)) || \
80 defined(ARDUINO_ARCH_ESP32))
81 _wire->end();
82 _begun = false;
83#endif
84}
85
92 // Init I2C if not done yet
93 if (!_begun && !begin()) {
94 return false;
95 }
96
97 // A basic scanner, see if it ACK's
98 _wire->beginTransmission(_addr);
99#ifdef DEBUG_SERIAL
100 DEBUG_SERIAL.print(F("Address 0x"));
101 DEBUG_SERIAL.print(_addr);
102#endif
103 if (_wire->endTransmission() == 0) {
104#ifdef DEBUG_SERIAL
105 DEBUG_SERIAL.println(F(" Detected"));
106#endif
107 return true;
108 }
109#ifdef DEBUG_SERIAL
110 DEBUG_SERIAL.println(F(" Not detected"));
111#endif
112 return false;
113}
114
128bool Adafruit_I2CDevice::write(const uint8_t *buffer, size_t len, bool stop,
129 const uint8_t *prefix_buffer,
130 size_t prefix_len) {
131 if ((len + prefix_len) > maxBufferSize()) {
132 // currently not guaranteed to work if more than 32 bytes!
133 // we will need to find out if some platforms have larger
134 // I2C buffer sizes :/
135#ifdef DEBUG_SERIAL
136 DEBUG_SERIAL.println(F("\tI2CDevice could not write such a large buffer"));
137#endif
138 return false;
139 }
140
141 _wire->beginTransmission(_addr);
142
143 // Write the prefix data (usually an address)
144 if ((prefix_len != 0) && (prefix_buffer != nullptr)) {
145 if (_wire->write(prefix_buffer, prefix_len) != prefix_len) {
146#ifdef DEBUG_SERIAL
147 DEBUG_SERIAL.println(F("\tI2CDevice failed to write"));
148#endif
149 return false;
150 }
151 }
152
153 // Write the data itself
154 if (_wire->write(buffer, len) != len) {
155#ifdef DEBUG_SERIAL
156 DEBUG_SERIAL.println(F("\tI2CDevice failed to write"));
157#endif
158 return false;
159 }
160
161#ifdef DEBUG_SERIAL
162
163 DEBUG_SERIAL.print(F("\tI2CWRITE @ 0x"));
164 DEBUG_SERIAL.print(_addr, HEX);
165 DEBUG_SERIAL.print(F(" :: "));
166 if ((prefix_len != 0) && (prefix_buffer != nullptr)) {
167 for (uint16_t i = 0; i < prefix_len; i++) {
168 DEBUG_SERIAL.print(F("0x"));
169 DEBUG_SERIAL.print(prefix_buffer[i], HEX);
170 DEBUG_SERIAL.print(F(", "));
171 }
172 }
173 for (uint16_t i = 0; i < len; i++) {
174 DEBUG_SERIAL.print(F("0x"));
175 DEBUG_SERIAL.print(buffer[i], HEX);
176 DEBUG_SERIAL.print(F(", "));
177 if (i % 32 == 31) {
178 DEBUG_SERIAL.println();
179 }
180 }
181
182 if (stop) {
183 DEBUG_SERIAL.print("\tSTOP");
184 }
185#endif
186
187 if (_wire->endTransmission(stop) == 0) {
188#ifdef DEBUG_SERIAL
189 DEBUG_SERIAL.println();
190 // DEBUG_SERIAL.println("Sent!");
191#endif
192 return true;
193 } else {
194#ifdef DEBUG_SERIAL
195 DEBUG_SERIAL.println("\tFailed to send!");
196#endif
197 return false;
198 }
199}
200
209bool Adafruit_I2CDevice::read(uint8_t *buffer, size_t len, bool stop) {
210 size_t pos = 0;
211 while (pos < len) {
212 size_t read_len =
213 ((len - pos) > maxBufferSize()) ? maxBufferSize() : (len - pos);
214 bool read_stop = (pos < (len - read_len)) ? false : stop;
215 if (!_read(buffer + pos, read_len, read_stop))
216 return false;
217 pos += read_len;
218 }
219 return true;
220}
221
222bool Adafruit_I2CDevice::_read(uint8_t *buffer, size_t len, bool stop) {
223#if defined(TinyWireM_h)
224 size_t recv = _wire->requestFrom((uint8_t)_addr, (uint8_t)len);
225#elif defined(ARDUINO_ARCH_MEGAAVR)
226 size_t recv = _wire->requestFrom(_addr, len, stop);
227#else
228 size_t recv = _wire->requestFrom((uint8_t)_addr, (uint8_t)len, (uint8_t)stop);
229#endif
230
231 if (recv != len) {
232 // Not enough data available to fulfill our obligation!
233#ifdef DEBUG_SERIAL
234 DEBUG_SERIAL.print(F("\tI2CDevice did not receive enough data: "));
235 DEBUG_SERIAL.println(recv);
236#endif
237 return false;
238 }
239
240 for (uint16_t i = 0; i < len; i++) {
241 buffer[i] = _wire->read();
242 }
243
244#ifdef DEBUG_SERIAL
245 DEBUG_SERIAL.print(F("\tI2CREAD @ 0x"));
246 DEBUG_SERIAL.print(_addr, HEX);
247 DEBUG_SERIAL.print(F(" :: "));
248 for (uint16_t i = 0; i < len; i++) {
249 DEBUG_SERIAL.print(F("0x"));
250 DEBUG_SERIAL.print(buffer[i], HEX);
251 DEBUG_SERIAL.print(F(", "));
252 if (len % 32 == 31) {
253 DEBUG_SERIAL.println();
254 }
255 }
256 DEBUG_SERIAL.println();
257#endif
258
259 return true;
260}
261
273bool Adafruit_I2CDevice::write_then_read(const uint8_t *write_buffer,
274 size_t write_len, uint8_t *read_buffer,
275 size_t read_len, bool stop) {
276 if (!write(write_buffer, write_len, stop)) {
277 return false;
278 }
279
280 return read(read_buffer, read_len);
281}
282
287uint8_t Adafruit_I2CDevice::address(void) { return _addr; }
288
296bool Adafruit_I2CDevice::setSpeed(uint32_t desiredclk) {
297#if defined(__AVR_ATmega328__) || \
298 defined(__AVR_ATmega328P__) // fix arduino core set clock
299 // calculate TWBR correctly
300
301 if ((F_CPU / 18) < desiredclk) {
302#ifdef DEBUG_SERIAL
303 Serial.println(F("I2C.setSpeed too high."));
304#endif
305 return false;
306 }
307 uint32_t atwbr = ((F_CPU / desiredclk) - 16) / 2;
308 if (atwbr > 16320) {
309#ifdef DEBUG_SERIAL
310 Serial.println(F("I2C.setSpeed too low."));
311#endif
312 return false;
313 }
314
315 if (atwbr <= 255) {
316 atwbr /= 1;
317 TWSR = 0x0;
318 } else if (atwbr <= 1020) {
319 atwbr /= 4;
320 TWSR = 0x1;
321 } else if (atwbr <= 4080) {
322 atwbr /= 16;
323 TWSR = 0x2;
324 } else { // if (atwbr <= 16320)
325 atwbr /= 64;
326 TWSR = 0x3;
327 }
328 TWBR = atwbr;
329
330#ifdef DEBUG_SERIAL
331 Serial.print(F("TWSR prescaler = "));
332 Serial.println(pow(4, TWSR));
333 Serial.print(F("TWBR = "));
334 Serial.println(atwbr);
335#endif
336 return true;
337#elif (ARDUINO >= 157) && !defined(ARDUINO_STM32_FEATHER) && \
338 !defined(TinyWireM_h)
339 _wire->setClock(desiredclk);
340 return true;
341
342#else
343 (void)desiredclk;
344 return false;
345#endif
346}
Adafruit SSD1306 dependency code for I2C.
size_t maxBufferSize()
How many bytes we can read in a transaction.
bool setSpeed(uint32_t desiredclk)
Change the I2C clock speed to desired (relies on underlying Wire support!
bool write(const uint8_t *buffer, size_t len, bool stop=true, const uint8_t *prefix_buffer=nullptr, size_t prefix_len=0)
Write a buffer or two to the I2C device. Cannot be more than maxBufferSize() bytes.
bool detected(void)
Scans I2C for the address - note will give a false-positive if there's no pullups on I2C.
bool begin(bool addr_detect=true)
Initializes and does basic address detection.
uint8_t address(void)
Returns the 7-bit address of this device.
bool write_then_read(const uint8_t *write_buffer, size_t write_len, uint8_t *read_buffer, size_t read_len, bool stop=false)
Write some data, then read some data from I2C into another buffer. Cannot be more than maxBufferSize(...
void end(void)
De-initialize device, turn off the Wire interface.
Adafruit_I2CDevice(uint8_t addr, TwoWire *theWire=&Wire)
Create an I2C device at a given address.
bool read(uint8_t *buffer, size_t len, bool stop=true)
Read from I2C into a buffer from the I2C device. Cannot be more than maxBufferSize() bytes.