]> git.piffa.net Git - arduino/blob - sheets/gyro/Test program/Arduino/MPU6050/I2Cdev.cpp
first commit
[arduino] / sheets / gyro / Test program / Arduino / MPU6050 / I2Cdev.cpp
1 // I2Cdev library collection - Main I2C device class\r
2 // Abstracts bit and byte I2C R/W functions into a convenient class\r
3 // 11/1/2011 by Jeff Rowberg <jeff@rowberg.net>\r
4 //\r
5 // Changelog:\r
6 //     2011-11-01 - fix write*Bits mask calculation (thanks sasquatch @ Arduino forums)\r
7 //     2011-10-03 - added automatic Arduino version detection for ease of use\r
8 //     2011-10-02 - added Gene Knight's NBWire TwoWire class implementation with small modifications\r
9 //     2011-08-31 - added support for Arduino 1.0 Wire library (methods are different from 0.x)\r
10 //     2011-08-03 - added optional timeout parameter to read* methods to easily change from default\r
11 //     2011-08-02 - added support for 16-bit registers\r
12 //                - fixed incorrect Doxygen comments on some methods\r
13 //                - added timeout value for read operations (thanks mem @ Arduino forums)\r
14 //     2011-07-30 - changed read/write function structures to return success or byte counts\r
15 //                - made all methods static for multi-device memory savings\r
16 //     2011-07-28 - initial release\r
17 \r
18 /* ============================================\r
19 I2Cdev device library code is placed under the MIT license\r
20 Copyright (c) 2011 Jeff Rowberg\r
21 \r
22 Permission is hereby granted, free of charge, to any person obtaining a copy\r
23 of this software and associated documentation files (the "Software"), to deal\r
24 in the Software without restriction, including without limitation the rights\r
25 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
26 copies of the Software, and to permit persons to whom the Software is\r
27 furnished to do so, subject to the following conditions:\r
28 \r
29 The above copyright notice and this permission notice shall be included in\r
30 all copies or substantial portions of the Software.\r
31 \r
32 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
33 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
34 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
35 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
36 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
37 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
38 THE SOFTWARE.\r
39 ===============================================\r
40 */\r
41 \r
42 #include "I2Cdev.h"\r
43 \r
44 #if I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE\r
45     // NBWire implementation based heavily on code by Gene Knight <Gene@Telobot.com>\r
46     // Originally posted on the Arduino forum at http://arduino.cc/forum/index.php/topic,70705.0.html\r
47     // Originally offered to the i2cdevlib project at http://arduino.cc/forum/index.php/topic,68210.30.html\r
48     TwoWire Wire;\r
49 #endif\r
50 \r
51 /** Default constructor.\r
52  */\r
53 I2Cdev::I2Cdev() {\r
54 }\r
55 \r
56 /** Read a single bit from an 8-bit device register.\r
57  * @param devAddr I2C slave device address\r
58  * @param regAddr Register regAddr to read from\r
59  * @param bitNum Bit position to read (0-7)\r
60  * @param data Container for single bit value\r
61  * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)\r
62  * @return Status of read operation (true = success)\r
63  */\r
64 int8_t I2Cdev::readBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *data, uint16_t timeout) {\r
65     uint8_t b;\r
66     uint8_t count = readByte(devAddr, regAddr, &b, timeout);\r
67     *data = b & (1 << bitNum);\r
68     return count;\r
69 }\r
70 \r
71 /** Read a single bit from a 16-bit device register.\r
72  * @param devAddr I2C slave device address\r
73  * @param regAddr Register regAddr to read from\r
74  * @param bitNum Bit position to read (0-15)\r
75  * @param data Container for single bit value\r
76  * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)\r
77  * @return Status of read operation (true = success)\r
78  */\r
79 int8_t I2Cdev::readBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t *data, uint16_t timeout) {\r
80     uint16_t b;\r
81     uint8_t count = readWord(devAddr, regAddr, &b, timeout);\r
82     *data = b & (1 << bitNum);\r
83     return count;\r
84 }\r
85 \r
86 /** Read multiple bits from an 8-bit device register.\r
87  * @param devAddr I2C slave device address\r
88  * @param regAddr Register regAddr to read from\r
89  * @param bitStart First bit position to read (0-7)\r
90  * @param length Number of bits to read (not more than 8)\r
91  * @param data Container for right-aligned value (i.e. '101' read from any bitStart position will equal 0x05)\r
92  * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)\r
93  * @return Status of read operation (true = success)\r
94  */\r
95 int8_t I2Cdev::readBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data, uint16_t timeout) {\r
96     // 01101001 read byte\r
97     // 76543210 bit numbers\r
98     //    xxx   args: bitStart=4, length=3\r
99     //    010   masked\r
100     //   -> 010 shifted\r
101     uint8_t count, b;\r
102     if ((count = readByte(devAddr, regAddr, &b, timeout)) != 0) {\r
103         uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1);\r
104         b &= mask;\r
105         b >>= (bitStart - length + 1);\r
106         *data = b;\r
107     }\r
108     return count;\r
109 }\r
110 \r
111 /** Read multiple bits from a 16-bit device register.\r
112  * @param devAddr I2C slave device address\r
113  * @param regAddr Register regAddr to read from\r
114  * @param bitStart First bit position to read (0-15)\r
115  * @param length Number of bits to read (not more than 16)\r
116  * @param data Container for right-aligned value (i.e. '101' read from any bitStart position will equal 0x05)\r
117  * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)\r
118  * @return Status of read operation (1 = success, 0 = failure, -1 = timeout)\r
119  */\r
120 int8_t I2Cdev::readBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t *data, uint16_t timeout) {\r
121     // 1101011001101001 read byte\r
122     // fedcba9876543210 bit numbers\r
123     //    xxx           args: bitStart=12, length=3\r
124     //    010           masked\r
125     //           -> 010 shifted\r
126     uint8_t count;\r
127     uint16_t w;\r
128     if ((count = readWord(devAddr, regAddr, &w, timeout)) != 0) {\r
129         uint16_t mask = ((1 << length) - 1) << (bitStart - length + 1);\r
130         w &= mask;\r
131         w >>= (bitStart - length + 1);\r
132         *data = w;\r
133     }\r
134     return count;\r
135 }\r
136 \r
137 /** Read single byte from an 8-bit device register.\r
138  * @param devAddr I2C slave device address\r
139  * @param regAddr Register regAddr to read from\r
140  * @param data Container for byte value read from device\r
141  * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)\r
142  * @return Status of read operation (true = success)\r
143  */\r
144 int8_t I2Cdev::readByte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint16_t timeout) {\r
145     return readBytes(devAddr, regAddr, 1, data, timeout);\r
146 }\r
147 \r
148 /** Read single word from a 16-bit device register.\r
149  * @param devAddr I2C slave device address\r
150  * @param regAddr Register regAddr to read from\r
151  * @param data Container for word value read from device\r
152  * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)\r
153  * @return Status of read operation (true = success)\r
154  */\r
155 int8_t I2Cdev::readWord(uint8_t devAddr, uint8_t regAddr, uint16_t *data, uint16_t timeout) {\r
156     return readWords(devAddr, regAddr, 1, data, timeout);\r
157 }\r
158 \r
159 /** Read multiple bytes from an 8-bit device register.\r
160  * @param devAddr I2C slave device address\r
161  * @param regAddr First register regAddr to read from\r
162  * @param length Number of bytes to read\r
163  * @param data Buffer to store read data in\r
164  * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)\r
165  * @return Number of bytes read (0 indicates failure)\r
166  */\r
167 int8_t I2Cdev::readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout) {\r
168     #ifdef I2CDEV_SERIAL_DEBUG\r
169         Serial.print("I2C (0x");\r
170         Serial.print(devAddr, HEX);\r
171         Serial.print(") reading ");\r
172         Serial.print(length, DEC);\r
173         Serial.print(" bytes from 0x");\r
174         Serial.print(regAddr, HEX);\r
175         Serial.print("...");\r
176     #endif\r
177 \r
178     int8_t count = 0;\r
179 \r
180     Wire.beginTransmission(devAddr);\r
181     #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE)\r
182         Wire.send(regAddr);\r
183     #elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100)\r
184         Wire.write(regAddr);\r
185     #endif\r
186     Wire.endTransmission();\r
187 \r
188     Wire.beginTransmission(devAddr);\r
189     Wire.requestFrom(devAddr, length);\r
190 \r
191     uint32_t t1 = millis();\r
192     for (; Wire.available() && (timeout == 0 || millis() - t1 < timeout); count++) {\r
193         #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE)\r
194             data[count] = Wire.receive();\r
195         #elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100)\r
196             data[count] = Wire.read();\r
197         #endif\r
198         #ifdef I2CDEV_SERIAL_DEBUG\r
199             Serial.print(data[count], HEX);\r
200             if (count + 1 < length) Serial.print(" ");\r
201         #endif\r
202     }\r
203     if (timeout > 0 && millis() - t1 >= timeout && count < length) count = -1; // timeout\r
204 \r
205     Wire.endTransmission();\r
206 \r
207     #ifdef I2CDEV_SERIAL_DEBUG\r
208         Serial.print(". Done (");\r
209         Serial.print(count, DEC);\r
210         Serial.println(" read).");\r
211     #endif\r
212 \r
213     return count;\r
214 }\r
215 \r
216 /** Read multiple words from a 16-bit device register.\r
217  * @param devAddr I2C slave device address\r
218  * @param regAddr First register regAddr to read from\r
219  * @param length Number of words to read\r
220  * @param data Buffer to store read data in\r
221  * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)\r
222  * @return Number of words read (0 indicates failure)\r
223  */\r
224 int8_t I2Cdev::readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data, uint16_t timeout) {\r
225     #ifdef I2CDEV_SERIAL_DEBUG\r
226         Serial.print("I2C (0x");\r
227         Serial.print(devAddr, HEX);\r
228         Serial.print(") reading ");\r
229         Serial.print(length, DEC);\r
230         Serial.print(" words from 0x");\r
231         Serial.print(regAddr, HEX);\r
232         Serial.print("...");\r
233     #endif\r
234 \r
235     int8_t count = 0;\r
236 \r
237     Wire.beginTransmission(devAddr);\r
238     #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE)\r
239         Wire.send(regAddr);\r
240     #elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100)\r
241         Wire.write(regAddr);\r
242     #endif\r
243     Wire.endTransmission();\r
244 \r
245     Wire.beginTransmission(devAddr);\r
246     Wire.requestFrom(devAddr, (uint8_t)(length * 2)); // length=words, this wants bytes\r
247 \r
248     uint32_t t1 = millis();\r
249     bool msb = true; // starts with MSB, then LSB\r
250     for (; Wire.available() && count < length && (timeout == 0 || millis() - t1 < timeout);) {\r
251         if (msb) {\r
252             // first byte is bits 15-8 (MSb=15)\r
253             #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE)\r
254                 data[count] = Wire.receive() << 8;\r
255             #elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100)\r
256                 data[count] = Wire.read() << 8;\r
257             #endif\r
258         } else {\r
259             // second byte is bits 7-0 (LSb=0)\r
260             #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE)\r
261                 data[count] |= Wire.receive();\r
262             #elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100)\r
263                 data[count] |= Wire.read();\r
264             #endif\r
265             #ifdef I2CDEV_SERIAL_DEBUG\r
266                 Serial.print(data[count], HEX);\r
267                 if (count + 1 < length) Serial.print(" ");\r
268             #endif\r
269             count++;\r
270         }\r
271         msb = !msb;\r
272     }\r
273     if (timeout > 0 && millis() - t1 >= timeout && count < length) count = -1; // timeout\r
274 \r
275     Wire.endTransmission();\r
276 \r
277     #ifdef I2CDEV_SERIAL_DEBUG\r
278         Serial.print(". Done (");\r
279         Serial.print(count, DEC);\r
280         Serial.println(" read).");\r
281     #endif\r
282     \r
283     return count;\r
284 }\r
285 \r
286 /** write a single bit in an 8-bit device register.\r
287  * @param devAddr I2C slave device address\r
288  * @param regAddr Register regAddr to write to\r
289  * @param bitNum Bit position to write (0-7)\r
290  * @param value New bit value to write\r
291  * @return Status of operation (true = success)\r
292  */\r
293 bool I2Cdev::writeBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data) {\r
294     uint8_t b;\r
295     readByte(devAddr, regAddr, &b);\r
296     b = (data != 0) ? (b | (1 << bitNum)) : (b & ~(1 << bitNum));\r
297     return writeByte(devAddr, regAddr, b);\r
298 }\r
299 \r
300 /** write a single bit in a 16-bit device register.\r
301  * @param devAddr I2C slave device address\r
302  * @param regAddr Register regAddr to write to\r
303  * @param bitNum Bit position to write (0-15)\r
304  * @param value New bit value to write\r
305  * @return Status of operation (true = success)\r
306  */\r
307 bool I2Cdev::writeBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t data) {\r
308     uint16_t w;\r
309     readWord(devAddr, regAddr, &w);\r
310     w = (data != 0) ? (w | (1 << bitNum)) : (w & ~(1 << bitNum));\r
311     return writeWord(devAddr, regAddr, w);\r
312 }\r
313 \r
314 /** Write multiple bits in an 8-bit device register.\r
315  * @param devAddr I2C slave device address\r
316  * @param regAddr Register regAddr to write to\r
317  * @param bitStart First bit position to write (0-7)\r
318  * @param length Number of bits to write (not more than 8)\r
319  * @param data Right-aligned value to write\r
320  * @return Status of operation (true = success)\r
321  */\r
322 bool I2Cdev::writeBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t data) {\r
323     //      010 value to write\r
324     // 76543210 bit numbers\r
325     //    xxx   args: bitStart=4, length=3\r
326     // 00011100 mask byte\r
327     // 10101111 original value (sample)\r
328     // 10100011 original & ~mask\r
329     // 10101011 masked | value\r
330     uint8_t b;\r
331     if (readByte(devAddr, regAddr, &b) != 0) {\r
332         uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1);\r
333         data <<= (bitStart - length + 1); // shift data into correct position\r
334         data &= mask; // zero all non-important bits in data\r
335         b &= ~(mask); // zero all important bits in existing byte\r
336         b |= data; // combine data with existing byte\r
337         return writeByte(devAddr, regAddr, b);\r
338     } else {\r
339         return false;\r
340     }\r
341 }\r
342 \r
343 /** Write multiple bits in a 16-bit device register.\r
344  * @param devAddr I2C slave device address\r
345  * @param regAddr Register regAddr to write to\r
346  * @param bitStart First bit position to write (0-15)\r
347  * @param length Number of bits to write (not more than 16)\r
348  * @param data Right-aligned value to write\r
349  * @return Status of operation (true = success)\r
350  */\r
351 bool I2Cdev::writeBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t data) {\r
352     //              010 value to write\r
353     // fedcba9876543210 bit numbers\r
354     //    xxx           args: bitStart=12, length=3\r
355     // 0001110000000000 mask byte\r
356     // 1010111110010110 original value (sample)\r
357     // 1010001110010110 original & ~mask\r
358     // 1010101110010110 masked | value\r
359     uint16_t w;\r
360     if (readWord(devAddr, regAddr, &w) != 0) {\r
361         uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1);\r
362         data <<= (bitStart - length + 1); // shift data into correct position\r
363         data &= mask; // zero all non-important bits in data\r
364         w &= ~(mask); // zero all important bits in existing word\r
365         w |= data; // combine data with existing word\r
366         return writeWord(devAddr, regAddr, w);\r
367     } else {\r
368         return false;\r
369     }\r
370 }\r
371 \r
372 /** Write single byte to an 8-bit device register.\r
373  * @param devAddr I2C slave device address\r
374  * @param regAddr Register address to write to\r
375  * @param data New byte value to write\r
376  * @return Status of operation (true = success)\r
377  */\r
378 bool I2Cdev::writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data) {\r
379     return writeBytes(devAddr, regAddr, 1, &data);\r
380 }\r
381 \r
382 /** Write single word to a 16-bit device register.\r
383  * @param devAddr I2C slave device address\r
384  * @param regAddr Register address to write to\r
385  * @param data New word value to write\r
386  * @return Status of operation (true = success)\r
387  */\r
388 bool I2Cdev::writeWord(uint8_t devAddr, uint8_t regAddr, uint16_t data) {\r
389     return writeWords(devAddr, regAddr, 1, &data);\r
390 }\r
391 \r
392 /** Write multiple bytes to an 8-bit device register.\r
393  * @param devAddr I2C slave device address\r
394  * @param regAddr First register address to write to\r
395  * @param length Number of bytes to write\r
396  * @param data Buffer to copy new data from\r
397  * @return Status of operation (true = success)\r
398  */\r
399 bool I2Cdev::writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t* data) {\r
400     #ifdef I2CDEV_SERIAL_DEBUG\r
401         Serial.print("I2C (0x");\r
402         Serial.print(devAddr, HEX);\r
403         Serial.print(") writing ");\r
404         Serial.print(length, DEC);\r
405         Serial.print(" bytes to 0x");\r
406         Serial.print(regAddr, HEX);\r
407         Serial.print("...");\r
408     #endif\r
409     uint8_t status = 0;\r
410     #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE)\r
411         Wire.beginTransmission(devAddr);\r
412         Wire.send((uint8_t) regAddr); // send address\r
413     #elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100)\r
414         Wire.beginTransmission(devAddr);\r
415         Wire.write((uint8_t) regAddr); // send address\r
416     #endif\r
417     for (uint8_t i = 0; i < length; i++) {\r
418         #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE)\r
419             Wire.send((uint8_t) data[i]);\r
420         #elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100)\r
421             Wire.write((uint8_t) data[i]);\r
422         #endif\r
423         #ifdef I2CDEV_SERIAL_DEBUG\r
424             Serial.print(data[i], HEX);\r
425             if (i + 1 < length) Serial.print(" ");\r
426         #endif\r
427     }\r
428     #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE)\r
429         Wire.endTransmission();\r
430     #elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100)\r
431         status = Wire.endTransmission();\r
432     #endif\r
433     #ifdef I2CDEV_SERIAL_DEBUG\r
434         Serial.println(". Done.");\r
435     #endif\r
436     return status == 0;\r
437 }\r
438 \r
439 /** Write multiple words to a 16-bit device register.\r
440  * @param devAddr I2C slave device address\r
441  * @param regAddr First register address to write to\r
442  * @param length Number of words to write\r
443  * @param data Buffer to copy new data from\r
444  * @return Status of operation (true = success)\r
445  */\r
446 bool I2Cdev::writeWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t* data) {\r
447     #ifdef I2CDEV_SERIAL_DEBUG\r
448         Serial.print("I2C (0x");\r
449         Serial.print(devAddr, HEX);\r
450         Serial.print(") writing ");\r
451         Serial.print(length, DEC);\r
452         Serial.print(" words to 0x");\r
453         Serial.print(regAddr, HEX);\r
454         Serial.print("...");\r
455     #endif\r
456     uint8_t status = 0;\r
457     #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE)\r
458         Wire.beginTransmission(devAddr);\r
459         Wire.send(regAddr); // send address\r
460     #elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100)\r
461         Wire.beginTransmission(devAddr);\r
462         Wire.write(regAddr); // send address\r
463     #endif\r
464     for (uint8_t i = 0; i < length * 2; i++) {\r
465         #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE)\r
466             Wire.send((uint8_t)(data[i++] >> 8)); // send MSB\r
467             Wire.send((uint8_t)data[i]);          // send LSB\r
468         #elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100)\r
469             Wire.write((uint8_t)(data[i++] >> 8)); // send MSB\r
470             Wire.write((uint8_t)data[i]);          // send LSB\r
471         #endif\r
472         #ifdef I2CDEV_SERIAL_DEBUG\r
473             Serial.print(data[i], HEX);\r
474             if (i + 1 < length) Serial.print(" ");\r
475         #endif\r
476     }\r
477     #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE)\r
478         Wire.endTransmission();\r
479     #elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100)\r
480         status = Wire.endTransmission();\r
481     #endif\r
482     #ifdef I2CDEV_SERIAL_DEBUG\r
483         Serial.println(". Done.");\r
484     #endif\r
485     return status == 0;\r
486 }\r
487 \r
488 /** Default timeout value for read operations.\r
489  * Set this to 0 to disable timeout detection.\r
490  */\r
491 uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;\r
492 \r
493 #if I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE\r
494     /*\r
495     FastWire 0.1\r
496     This is a library to help faster programs to read I2C devices.\r
497     Copyright(C) 2011 Francesco Ferrara\r
498     occhiobello at gmail dot com\r
499     */\r
500 \r
501     boolean Fastwire::waitInt() {\r
502         int l = 250;\r
503         while (!(TWCR & (1 << TWINT)) && l-- > 0);\r
504         return l > 0;\r
505     }\r
506 \r
507     void Fastwire::setup(int khz, boolean pullup) {\r
508         TWCR = 0;\r
509         // TODO: add support for other MCUs, this is ATmega328+compatible only\r
510         if (pullup)\r
511             PORTC |= ((1 << 4) | (1 << 5));\r
512         else\r
513             PORTC &= ~((1 << 4) | (1 << 5));\r
514 \r
515         TWSR = 0; // no prescaler => prescaler = 1\r
516         TWBR = ((16000L / khz) - 16) / 2; // change the I2C clock rate\r
517         TWCR = 1 << TWEN; // enable twi module, no interrupt\r
518     }\r
519 \r
520     byte Fastwire::write(byte device, byte address, byte value) {\r
521         byte twst, retry;\r
522         retry = 2;\r
523         do {\r
524             TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO) | (1 << TWSTA);\r
525             if (!waitInt()) return 1;\r
526             twst = TWSR & 0xF8;\r
527             if (twst != TW_START && twst != TW_REP_START) return 2;\r
528 \r
529             TWDR = device & 0xFE; // send device address without read bit (1)\r
530             TWCR = (1 << TWINT) | (1 << TWEN);\r
531             if (!waitInt()) return 3;\r
532             twst = TWSR & 0xF8;\r
533         }\r
534         while (twst == TW_MT_SLA_NACK && retry-- > 0);\r
535         if (twst != TW_MT_SLA_ACK) return 4;\r
536 \r
537         TWDR = address; // send data to the previously addressed device\r
538         TWCR = (1 << TWINT) | (1 << TWEN);\r
539         if (!waitInt()) return 5;\r
540         twst = TWSR & 0xF8;\r
541         if (twst != TW_MT_DATA_ACK) return 6;\r
542     \r
543         TWDR = value; // send data to the previously addressed device\r
544         TWCR = (1 << TWINT) | (1 << TWEN);\r
545         if (!waitInt()) return 7;\r
546         twst = TWSR & 0xF8;\r
547         if (twst != TW_MT_DATA_ACK) return 8;\r
548     \r
549         return 0;\r
550     }\r
551     \r
552     byte Fastwire::readBuf(byte device, byte address, byte *data, byte num) {\r
553         byte twst, retry;\r
554 \r
555         retry = 2;\r
556         do {\r
557             TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO) | (1 << TWSTA);\r
558             if (!waitInt()) return 16;\r
559             twst = TWSR & 0xF8;\r
560             if (twst != TW_START && twst != TW_REP_START) return 17;\r
561 \r
562             TWDR = device & 0xFE; // send device address to write\r
563             TWCR = (1 << TWINT) | (1 << TWEN);\r
564             if (!waitInt()) return 18;\r
565             twst = TWSR & 0xF8;\r
566         }\r
567         while (twst == TW_MT_SLA_NACK && retry-- > 0);\r
568         if (twst != TW_MT_SLA_ACK) return 19;\r
569     \r
570         TWDR = address; // send data to the previously addressed device\r
571         TWCR = (1 << TWINT) | (1 << TWEN);\r
572         if (!waitInt()) return 20;\r
573         twst = TWSR & 0xF8;\r
574         if (twst != TW_MT_DATA_ACK) return 21;\r
575 \r
576         retry = 2;\r
577         do {\r
578             TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO) | (1 << TWSTA);\r
579             if (!waitInt()) return 22;\r
580             twst = TWSR & 0xF8;\r
581             if (twst != TW_START && twst != TW_REP_START) return 23;\r
582 \r
583             TWDR = device | 0x01; // send device address with the read bit (1)\r
584             TWCR = (1 << TWINT) | (1 << TWEN);\r
585             if (!waitInt()) return 24;\r
586             twst = TWSR & 0xF8;\r
587         }\r
588         while (twst == TW_MR_SLA_NACK && retry-- > 0);\r
589         if (twst != TW_MR_SLA_ACK) return 25;\r
590 \r
591         for (uint8_t i = 0; i < num; i++) {\r
592             if (i == num - 1)\r
593               TWCR = (1 << TWINT) | (1 << TWEN);\r
594             else\r
595               TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA);\r
596             if (!waitInt()) return 26;\r
597             twst = TWSR & 0xF8;\r
598             if (twst != TW_MR_DATA_ACK && twst != TW_MR_DATA_NACK) return twst;\r
599             data[i] = TWDR;\r
600         }\r
601 \r
602         return 0;\r
603     }\r
604 #endif\r
605 \r
606 #if I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE\r
607     // NBWire implementation based heavily on code by Gene Knight <Gene@Telobot.com>\r
608     // Originally posted on the Arduino forum at http://arduino.cc/forum/index.php/topic,70705.0.html\r
609     // Originally offered to the i2cdevlib project at http://arduino.cc/forum/index.php/topic,68210.30.html\r
610 \r
611     /*\r
612     call this version 1.0\r
613     \r
614     Offhand, the only funky part that I can think of is in nbrequestFrom, where the buffer\r
615     length and index are set *before* the data is actually read. The problem is that these\r
616     are variables local to the TwoWire object, and by the time we actually have read the\r
617     data, and know what the length actually is, we have no simple access to the object's \r
618     variables. The actual bytes read *is* given to the callback function, though.\r
619     \r
620     The ISR code for a slave receiver is commented out. I don't have that setup, and can't\r
621     verify it at this time. Save it for 2.0!\r
622     \r
623     The handling of the read and write processes here is much like in the demo sketch code: \r
624     the process is broken down into sequential functions, where each registers the next as a\r
625     callback, essentially.\r
626     \r
627     For example, for the Read process, twi_read00 just returns if TWI is not yet in a \r
628     ready state. When there's another interrupt, and the interface *is* ready, then it\r
629     sets up the read, starts it, and registers twi_read01 as the function to call after\r
630     the *next* interrupt. twi_read01, then, just returns if the interface is still in a\r
631     "reading" state. When the reading is done, it copies the information to the buffer,\r
632     cleans up, and calls the user-requested callback function with the actual number of \r
633     bytes read.\r
634     \r
635     The writing is similar.\r
636     \r
637     Questions, comments and problems can go to Gene@Telobot.com.\r
638     \r
639     Thumbs Up!\r
640     Gene Knight\r
641     \r
642     */\r
643     \r
644     uint8_t TwoWire::rxBuffer[NBWIRE_BUFFER_LENGTH];\r
645     uint8_t TwoWire::rxBufferIndex = 0;\r
646     uint8_t TwoWire::rxBufferLength = 0;\r
647     \r
648     uint8_t TwoWire::txAddress = 0;\r
649     uint8_t TwoWire::txBuffer[NBWIRE_BUFFER_LENGTH];\r
650     uint8_t TwoWire::txBufferIndex = 0;\r
651     uint8_t TwoWire::txBufferLength = 0;\r
652     \r
653     //uint8_t TwoWire::transmitting = 0;\r
654     void (*TwoWire::user_onRequest)(void);\r
655     void (*TwoWire::user_onReceive)(int);\r
656     \r
657     static volatile uint8_t twi_transmitting;\r
658     static volatile uint8_t twi_state;\r
659     static uint8_t twi_slarw;\r
660     static volatile uint8_t twi_error;\r
661     static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH];\r
662     static volatile uint8_t twi_masterBufferIndex;\r
663     static uint8_t twi_masterBufferLength;\r
664     static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH];\r
665     static volatile uint8_t twi_rxBufferIndex;\r
666     //static volatile uint8_t twi_Interrupt_Continue_Command;\r
667     static volatile uint8_t twi_Return_Value;\r
668     static volatile uint8_t twi_Done;\r
669     void (*twi_cbendTransmissionDone)(int);\r
670     void (*twi_cbreadFromDone)(int);\r
671     \r
672     void twi_init() {\r
673         // initialize state\r
674         twi_state = TWI_READY;\r
675 \r
676         // activate internal pull-ups for twi\r
677         // as per note from atmega8 manual pg167\r
678         sbi(PORTC, 4);\r
679         sbi(PORTC, 5);\r
680 \r
681         // initialize twi prescaler and bit rate\r
682         cbi(TWSR, TWPS0); // TWI Status Register - Prescaler bits\r
683         cbi(TWSR, TWPS1);\r
684 \r
685         /* twi bit rate formula from atmega128 manual pg 204\r
686         SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR))\r
687         note: TWBR should be 10 or higher for master mode\r
688         It is 72 for a 16mhz Wiring board with 100kHz TWI */\r
689 \r
690         TWBR = ((CPU_FREQ / TWI_FREQ) - 16) / 2; // bitrate register\r
691         // enable twi module, acks, and twi interrupt\r
692 \r
693         TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA);\r
694 \r
695         /* TWEN - TWI Enable Bit\r
696         TWIE - TWI Interrupt Enable\r
697         TWEA - TWI Enable Acknowledge Bit\r
698         TWINT - TWI Interrupt Flag\r
699         TWSTA - TWI Start Condition\r
700         */\r
701     }\r
702     \r
703     typedef struct {\r
704         uint8_t address;\r
705         uint8_t* data;\r
706         uint8_t length;\r
707         uint8_t wait;\r
708         uint8_t i;\r
709     } twi_Write_Vars;\r
710 \r
711     twi_Write_Vars *ptwv = 0;\r
712     static void (*fNextInterruptFunction)(void) = 0;\r
713     \r
714     void twi_Finish(byte bRetVal) {\r
715         if (ptwv) {\r
716             free(ptwv);\r
717             ptwv = 0;\r
718         }\r
719         twi_Done = 0xFF;\r
720         twi_Return_Value = bRetVal;\r
721         fNextInterruptFunction = 0;\r
722     }\r
723     \r
724     uint8_t twii_WaitForDone(uint16_t timeout) {\r
725         uint32_t endMillis = millis() + timeout;\r
726         while (!twi_Done && (timeout == 0 || millis() < endMillis)) continue;\r
727         return twi_Return_Value;\r
728     }\r
729     \r
730     void twii_SetState(uint8_t ucState) {\r
731         twi_state = ucState;\r
732     }\r
733 \r
734     void twii_SetError(uint8_t ucError) {\r
735         twi_error = ucError ;\r
736     }\r
737 \r
738     void twii_InitBuffer(uint8_t ucPos, uint8_t ucLength) {\r
739         twi_masterBufferIndex = 0;\r
740         twi_masterBufferLength = ucLength;\r
741     }\r
742 \r
743     void twii_CopyToBuf(uint8_t* pData, uint8_t ucLength) {\r
744         uint8_t i;\r
745         for (i = 0; i < ucLength; ++i) {\r
746             twi_masterBuffer[i] = pData[i];\r
747         }\r
748     }\r
749 \r
750     void twii_CopyFromBuf(uint8_t *pData, uint8_t ucLength) {\r
751         uint8_t i;\r
752         for (i = 0; i < ucLength; ++i) {\r
753             pData[i] = twi_masterBuffer[i];\r
754         }\r
755     }\r
756 \r
757     void twii_SetSlaRW(uint8_t ucSlaRW) {\r
758         twi_slarw = ucSlaRW;\r
759     }\r
760 \r
761     void twii_SetStart() {\r
762         TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);\r
763     }\r
764 \r
765     void twi_write01() {\r
766         if (TWI_MTX == twi_state) return; // blocking test\r
767         twi_transmitting = 0 ;\r
768         if (twi_error == 0xFF)\r
769             twi_Finish (0);    // success\r
770         else if (twi_error == TW_MT_SLA_NACK)\r
771             twi_Finish (2);    // error: address send, nack received\r
772         else if (twi_error == TW_MT_DATA_NACK)\r
773             twi_Finish (3);    // error: data send, nack received\r
774         else\r
775             twi_Finish (4);    // other twi error\r
776         if (twi_cbendTransmissionDone) return twi_cbendTransmissionDone(twi_Return_Value);\r
777         return;\r
778     }\r
779     \r
780     \r
781     void twi_write00() {\r
782         if (TWI_READY != twi_state) return; // blocking test\r
783         if (TWI_BUFFER_LENGTH < ptwv -> length) {\r
784             twi_Finish(1); // end write with error 1\r
785             return;\r
786         }\r
787         twi_Done = 0x00; // show as working\r
788         twii_SetState(TWI_MTX); // to transmitting\r
789         twii_SetError(0xFF); // to No Error\r
790         twii_InitBuffer(0, ptwv -> length); // pointer and length\r
791         twii_CopyToBuf(ptwv -> data, ptwv -> length); // get the data\r
792         twii_SetSlaRW((ptwv -> address << 1) | TW_WRITE); // write command\r
793         twii_SetStart(); // start the cycle\r
794         fNextInterruptFunction = twi_write01; // next routine\r
795         return twi_write01();\r
796     }\r
797     \r
798     void twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait) {\r
799         uint8_t i;\r
800         ptwv = (twi_Write_Vars *)malloc(sizeof(twi_Write_Vars));\r
801         ptwv -> address = address;\r
802         ptwv -> data = data;\r
803         ptwv -> length = length;\r
804         ptwv -> wait = wait;\r
805         fNextInterruptFunction = twi_write00;\r
806         return twi_write00();\r
807     }\r
808 \r
809     void twi_read01() {\r
810         if (TWI_MRX == twi_state) return; // blocking test\r
811         if (twi_masterBufferIndex < ptwv -> length) ptwv -> length = twi_masterBufferIndex;\r
812         twii_CopyFromBuf(ptwv -> data, ptwv -> length);\r
813         twi_Finish(ptwv -> length);\r
814         if (twi_cbreadFromDone) return twi_cbreadFromDone(twi_Return_Value);\r
815         return;\r
816     }\r
817     \r
818     void twi_read00() {\r
819         if (TWI_READY != twi_state) return; // blocking test\r
820         if (TWI_BUFFER_LENGTH < ptwv -> length) twi_Finish(0); // error return\r
821         twi_Done = 0x00; // show as working\r
822         twii_SetState(TWI_MRX); // reading\r
823         twii_SetError(0xFF); // reset error\r
824         twii_InitBuffer(0, ptwv -> length - 1); // init to one less than length\r
825         twii_SetSlaRW((ptwv -> address << 1) | TW_READ); // read command\r
826         twii_SetStart(); // start cycle\r
827         fNextInterruptFunction = twi_read01;\r
828         return twi_read01();\r
829     }\r
830 \r
831     void twi_readFrom(uint8_t address, uint8_t* data, uint8_t length) {\r
832         uint8_t i;\r
833 \r
834         ptwv = (twi_Write_Vars *)malloc(sizeof(twi_Write_Vars));\r
835         ptwv -> address = address;\r
836         ptwv -> data = data;\r
837         ptwv -> length = length;\r
838         fNextInterruptFunction = twi_read00;\r
839         return twi_read00();\r
840     }\r
841 \r
842     void twi_reply(uint8_t ack) {\r
843         // transmit master read ready signal, with or without ack\r
844         if (ack){\r
845             TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);\r
846         } else {\r
847             TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT);\r
848         }\r
849     }\r
850     \r
851     void twi_stop(void) {\r
852         // send stop condition\r
853         TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO);\r
854     \r
855         // wait for stop condition to be exectued on bus\r
856         // TWINT is not set after a stop condition!\r
857         while (TWCR & _BV(TWSTO)) {\r
858             continue;\r
859         }\r
860     \r
861         // update twi state\r
862         twi_state = TWI_READY;\r
863     }\r
864 \r
865     void twi_releaseBus(void) {\r
866         // release bus\r
867         TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT);\r
868     \r
869         // update twi state\r
870         twi_state = TWI_READY;\r
871     }\r
872     \r
873     SIGNAL(TWI_vect) {\r
874         switch (TW_STATUS) {\r
875             // All Master\r
876             case TW_START:     // sent start condition\r
877             case TW_REP_START: // sent repeated start condition\r
878                 // copy device address and r/w bit to output register and ack\r
879                 TWDR = twi_slarw;\r
880                 twi_reply(1);\r
881                 break;\r
882     \r
883             // Master Transmitter\r
884             case TW_MT_SLA_ACK:  // slave receiver acked address\r
885             case TW_MT_DATA_ACK: // slave receiver acked data\r
886                 // if there is data to send, send it, otherwise stop\r
887                 if (twi_masterBufferIndex < twi_masterBufferLength) {\r
888                     // copy data to output register and ack\r
889                     TWDR = twi_masterBuffer[twi_masterBufferIndex++];\r
890                     twi_reply(1);\r
891                 } else {\r
892                     twi_stop();\r
893                 }\r
894                 break;\r
895 \r
896             case TW_MT_SLA_NACK:  // address sent, nack received\r
897                 twi_error = TW_MT_SLA_NACK;\r
898                 twi_stop();\r
899                 break;\r
900 \r
901             case TW_MT_DATA_NACK: // data sent, nack received\r
902                 twi_error = TW_MT_DATA_NACK;\r
903                 twi_stop();\r
904                 break;\r
905 \r
906             case TW_MT_ARB_LOST: // lost bus arbitration\r
907                 twi_error = TW_MT_ARB_LOST;\r
908                 twi_releaseBus();\r
909                 break;\r
910     \r
911             // Master Receiver\r
912             case TW_MR_DATA_ACK: // data received, ack sent\r
913                 // put byte into buffer\r
914                 twi_masterBuffer[twi_masterBufferIndex++] = TWDR;\r
915 \r
916             case TW_MR_SLA_ACK:  // address sent, ack received\r
917                 // ack if more bytes are expected, otherwise nack\r
918                 if (twi_masterBufferIndex < twi_masterBufferLength) {\r
919                     twi_reply(1);\r
920                 } else {\r
921                     twi_reply(0);\r
922                 }\r
923                 break;\r
924 \r
925             case TW_MR_DATA_NACK: // data received, nack sent\r
926                 // put final byte into buffer\r
927                 twi_masterBuffer[twi_masterBufferIndex++] = TWDR;\r
928 \r
929             case TW_MR_SLA_NACK: // address sent, nack received\r
930                 twi_stop();\r
931                 break;\r
932 \r
933         // TW_MR_ARB_LOST handled by TW_MT_ARB_LOST case\r
934 \r
935         // Slave Receiver (NOT IMPLEMENTED YET)\r
936         /*\r
937             case TW_SR_SLA_ACK:   // addressed, returned ack\r
938             case TW_SR_GCALL_ACK: // addressed generally, returned ack\r
939             case TW_SR_ARB_LOST_SLA_ACK:   // lost arbitration, returned ack\r
940             case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack\r
941                 // enter slave receiver mode\r
942                 twi_state = TWI_SRX;\r
943 \r
944                 // indicate that rx buffer can be overwritten and ack\r
945                 twi_rxBufferIndex = 0;\r
946                 twi_reply(1);\r
947                 break;\r
948 \r
949             case TW_SR_DATA_ACK:       // data received, returned ack\r
950             case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack\r
951                 // if there is still room in the rx buffer\r
952                 if (twi_rxBufferIndex < TWI_BUFFER_LENGTH) {\r
953                     // put byte in buffer and ack\r
954                     twi_rxBuffer[twi_rxBufferIndex++] = TWDR;\r
955                     twi_reply(1);\r
956                 } else {\r
957                     // otherwise nack\r
958                     twi_reply(0);\r
959                 }\r
960                 break;\r
961 \r
962             case TW_SR_STOP: // stop or repeated start condition received\r
963                 // put a null char after data if there's room\r
964                 if (twi_rxBufferIndex < TWI_BUFFER_LENGTH) {\r
965                     twi_rxBuffer[twi_rxBufferIndex] = 0;\r
966                 }\r
967 \r
968                 // sends ack and stops interface for clock stretching\r
969                 twi_stop();\r
970 \r
971                 // callback to user defined callback\r
972                 twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex);\r
973 \r
974                 // since we submit rx buffer to "wire" library, we can reset it\r
975                 twi_rxBufferIndex = 0;\r
976 \r
977                 // ack future responses and leave slave receiver state\r
978                 twi_releaseBus();\r
979                 break;\r
980 \r
981             case TW_SR_DATA_NACK:       // data received, returned nack\r
982             case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack\r
983                 // nack back at master\r
984                 twi_reply(0);\r
985                 break;\r
986 \r
987             // Slave Transmitter\r
988             case TW_ST_SLA_ACK:          // addressed, returned ack\r
989             case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack\r
990                 // enter slave transmitter mode\r
991                 twi_state = TWI_STX;\r
992 \r
993                 // ready the tx buffer index for iteration\r
994                 twi_txBufferIndex = 0;\r
995 \r
996                 // set tx buffer length to be zero, to verify if user changes it\r
997                 twi_txBufferLength = 0;\r
998 \r
999                 // request for txBuffer to be filled and length to be set\r
1000                 // note: user must call twi_transmit(bytes, length) to do this\r
1001                 twi_onSlaveTransmit();\r
1002 \r
1003                 // if they didn't change buffer & length, initialize it\r
1004                 if (0 == twi_txBufferLength) {\r
1005                     twi_txBufferLength = 1;\r
1006                     twi_txBuffer[0] = 0x00;\r
1007                 }\r
1008                 \r
1009                 // transmit first byte from buffer, fall through\r
1010 \r
1011             case TW_ST_DATA_ACK: // byte sent, ack returned\r
1012                 // copy data to output register\r
1013                 TWDR = twi_txBuffer[twi_txBufferIndex++];\r
1014 \r
1015                 // if there is more to send, ack, otherwise nack\r
1016                 if (twi_txBufferIndex < twi_txBufferLength) {\r
1017                     twi_reply(1);\r
1018                 } else {\r
1019                     twi_reply(0);\r
1020                 }\r
1021                 break;\r
1022 \r
1023             case TW_ST_DATA_NACK: // received nack, we are done\r
1024             case TW_ST_LAST_DATA: // received ack, but we are done already!\r
1025                 // ack future responses\r
1026                 twi_reply(1);\r
1027                 // leave slave receiver state\r
1028                 twi_state = TWI_READY;\r
1029                 break;\r
1030             */\r
1031 \r
1032             // all\r
1033             case TW_NO_INFO:   // no state information\r
1034                 break;\r
1035 \r
1036             case TW_BUS_ERROR: // bus error, illegal stop/start\r
1037                 twi_error = TW_BUS_ERROR;\r
1038                 twi_stop();\r
1039                 break;\r
1040         }\r
1041 \r
1042         if (fNextInterruptFunction) return fNextInterruptFunction();\r
1043     }\r
1044 \r
1045     TwoWire::TwoWire() { }\r
1046     \r
1047     void TwoWire::begin(void) {\r
1048         rxBufferIndex = 0;\r
1049         rxBufferLength = 0;\r
1050     \r
1051         txBufferIndex = 0;\r
1052         txBufferLength = 0;\r
1053 \r
1054         twi_init();\r
1055     }\r
1056     \r
1057     void TwoWire::beginTransmission(uint8_t address) {\r
1058         //beginTransmission((uint8_t)address);\r
1059 \r
1060         // indicate that we are transmitting\r
1061         twi_transmitting = 1;\r
1062         \r
1063         // set address of targeted slave\r
1064         txAddress = address;\r
1065         \r
1066         // reset tx buffer iterator vars\r
1067         txBufferIndex = 0;\r
1068         txBufferLength = 0;\r
1069     }\r
1070     \r
1071     uint8_t TwoWire::endTransmission(uint16_t timeout) {\r
1072         // transmit buffer (blocking)\r
1073         //int8_t ret =\r
1074         twi_cbendTransmissionDone = NULL;\r
1075         twi_writeTo(txAddress, txBuffer, txBufferLength, 1);\r
1076         int8_t ret = twii_WaitForDone(timeout);\r
1077 \r
1078         // reset tx buffer iterator vars\r
1079         txBufferIndex = 0;\r
1080         txBufferLength = 0;\r
1081 \r
1082         // indicate that we are done transmitting\r
1083         // twi_transmitting = 0;\r
1084         return ret;\r
1085     }\r
1086 \r
1087     void TwoWire::nbendTransmission(void (*function)(int)) {\r
1088         twi_cbendTransmissionDone = function;\r
1089         twi_writeTo(txAddress, txBuffer, txBufferLength, 1);\r
1090         return;\r
1091     }\r
1092     \r
1093     void TwoWire::send(uint8_t data) {\r
1094         if (twi_transmitting) {\r
1095             // in master transmitter mode\r
1096             // don't bother if buffer is full\r
1097             if (txBufferLength >= NBWIRE_BUFFER_LENGTH) {\r
1098                 return;\r
1099             }\r
1100 \r
1101             // put byte in tx buffer\r
1102             txBuffer[txBufferIndex] = data;\r
1103             ++txBufferIndex;\r
1104 \r
1105             // update amount in buffer\r
1106             txBufferLength = txBufferIndex;\r
1107         } else {\r
1108             // in slave send mode\r
1109             // reply to master\r
1110             //twi_transmit(&data, 1);\r
1111         }\r
1112     }\r
1113     \r
1114     uint8_t TwoWire::receive(void) {\r
1115         // default to returning null char\r
1116         // for people using with char strings\r
1117         uint8_t value = 0;\r
1118       \r
1119         // get each successive byte on each call\r
1120         if (rxBufferIndex < rxBufferLength) {\r
1121             value = rxBuffer[rxBufferIndex];\r
1122             ++rxBufferIndex;\r
1123         }\r
1124     \r
1125         return value;\r
1126     }\r
1127     \r
1128     uint8_t TwoWire::requestFrom(uint8_t address, int quantity, uint16_t timeout) {\r
1129         // clamp to buffer length\r
1130         if (quantity > NBWIRE_BUFFER_LENGTH) {\r
1131             quantity = NBWIRE_BUFFER_LENGTH;\r
1132         }\r
1133 \r
1134         // perform blocking read into buffer\r
1135         twi_cbreadFromDone = NULL;\r
1136         twi_readFrom(address, rxBuffer, quantity);\r
1137         uint8_t read = twii_WaitForDone(timeout);\r
1138 \r
1139         // set rx buffer iterator vars\r
1140         rxBufferIndex = 0;\r
1141         rxBufferLength = read;\r
1142     \r
1143         return read;\r
1144     }\r
1145     \r
1146     void TwoWire::nbrequestFrom(uint8_t address, int quantity, void (*function)(int)) {\r
1147         // clamp to buffer length\r
1148         if (quantity > NBWIRE_BUFFER_LENGTH) {\r
1149             quantity = NBWIRE_BUFFER_LENGTH;\r
1150         }\r
1151 \r
1152         // perform blocking read into buffer\r
1153         twi_cbreadFromDone = function;\r
1154         twi_readFrom(address, rxBuffer, quantity);\r
1155         //uint8_t read = twii_WaitForDone();\r
1156 \r
1157         // set rx buffer iterator vars\r
1158         //rxBufferIndex = 0;\r
1159         //rxBufferLength = read;\r
1160 \r
1161         rxBufferIndex = 0;\r
1162         rxBufferLength = quantity; // this is a hack\r
1163 \r
1164         return; //read;\r
1165     }\r
1166 \r
1167     uint8_t TwoWire::available(void) {\r
1168         return rxBufferLength - rxBufferIndex;\r
1169     }\r
1170 \r
1171 #endif