mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-09-12 01:24:04 +00:00
[Cleanup] Fix missing paths on #include statements + update I2Cdev lib
This commit is contained in:
+229
-201
@@ -3,6 +3,9 @@
|
||||
// 2013-06-05 by Jeff Rowberg <jeff@rowberg.net>
|
||||
//
|
||||
// Changelog:
|
||||
// 2021-09-28 - allow custom Wire object as transaction function argument
|
||||
// 2020-01-20 - hardija : complete support for Teensy 3.x
|
||||
// 2015-10-30 - simondlevy : support i2c_t3 for Teensy3.1
|
||||
// 2013-05-06 - add Francesco Ferrara's Fastwire v0.24 implementation with small modifications
|
||||
// 2013-05-05 - fix issue with writing bit values to words (Sasquatch/Farzanegan)
|
||||
// 2012-06-09 - fix major issue with reading > 32 bytes at a time with Arduino Wire
|
||||
@@ -44,11 +47,8 @@ THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "I2Cdev.h"
|
||||
#if defined(ESP32)
|
||||
#define BUFFER_LENGTH 32
|
||||
#endif
|
||||
|
||||
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
|
||||
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_SBWIRE
|
||||
|
||||
#ifdef I2CDEV_IMPLEMENTATION_WARNINGS
|
||||
#if ARDUINO < 100
|
||||
@@ -103,9 +103,9 @@ I2Cdev::I2Cdev() {
|
||||
* @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
|
||||
* @return Status of read operation (true = success)
|
||||
*/
|
||||
int8_t I2Cdev::readBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *data, uint16_t timeout) {
|
||||
int8_t I2Cdev::readBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *data, uint16_t timeout, void *wireObj) {
|
||||
uint8_t b;
|
||||
uint8_t count = readByte(devAddr, regAddr, &b, timeout);
|
||||
uint8_t count = readByte(devAddr, regAddr, &b, timeout, wireObj);
|
||||
*data = b & (1 << bitNum);
|
||||
return count;
|
||||
}
|
||||
@@ -118,9 +118,9 @@ int8_t I2Cdev::readBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t
|
||||
* @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
|
||||
* @return Status of read operation (true = success)
|
||||
*/
|
||||
int8_t I2Cdev::readBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t *data, uint16_t timeout) {
|
||||
int8_t I2Cdev::readBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t *data, uint16_t timeout, void *wireObj) {
|
||||
uint16_t b;
|
||||
uint8_t count = readWord(devAddr, regAddr, &b, timeout);
|
||||
uint8_t count = readWord(devAddr, regAddr, &b, timeout, wireObj);
|
||||
*data = b & (1 << bitNum);
|
||||
return count;
|
||||
}
|
||||
@@ -134,14 +134,14 @@ int8_t I2Cdev::readBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16
|
||||
* @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
|
||||
* @return Status of read operation (true = success)
|
||||
*/
|
||||
int8_t I2Cdev::readBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data, uint16_t timeout) {
|
||||
int8_t I2Cdev::readBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data, uint16_t timeout, void *wireObj) {
|
||||
// 01101001 read byte
|
||||
// 76543210 bit numbers
|
||||
// xxx args: bitStart=4, length=3
|
||||
// 010 masked
|
||||
// -> 010 shifted
|
||||
uint8_t count, b;
|
||||
if ((count = readByte(devAddr, regAddr, &b, timeout)) != 0) {
|
||||
if ((count = readByte(devAddr, regAddr, &b, timeout, wireObj)) != 0) {
|
||||
uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1);
|
||||
b &= mask;
|
||||
b >>= (bitStart - length + 1);
|
||||
@@ -159,7 +159,7 @@ int8_t I2Cdev::readBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint
|
||||
* @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
|
||||
* @return Status of read operation (1 = success, 0 = failure, -1 = timeout)
|
||||
*/
|
||||
int8_t I2Cdev::readBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t *data, uint16_t timeout) {
|
||||
int8_t I2Cdev::readBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t *data, uint16_t timeout, void *wireObj) {
|
||||
// 1101011001101001 read byte
|
||||
// fedcba9876543210 bit numbers
|
||||
// xxx args: bitStart=12, length=3
|
||||
@@ -167,7 +167,7 @@ int8_t I2Cdev::readBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uin
|
||||
// -> 010 shifted
|
||||
uint8_t count;
|
||||
uint16_t w;
|
||||
if ((count = readWord(devAddr, regAddr, &w, timeout)) != 0) {
|
||||
if ((count = readWord(devAddr, regAddr, &w, timeout, wireObj)) != 0) {
|
||||
uint16_t mask = ((1 << length) - 1) << (bitStart - length + 1);
|
||||
w &= mask;
|
||||
w >>= (bitStart - length + 1);
|
||||
@@ -183,8 +183,8 @@ int8_t I2Cdev::readBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uin
|
||||
* @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
|
||||
* @return Status of read operation (true = success)
|
||||
*/
|
||||
int8_t I2Cdev::readByte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint16_t timeout) {
|
||||
return readBytes(devAddr, regAddr, 1, data, timeout);
|
||||
int8_t I2Cdev::readByte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint16_t timeout, void *wireObj) {
|
||||
return readBytes(devAddr, regAddr, 1, data, timeout, wireObj);
|
||||
}
|
||||
|
||||
/** Read single word from a 16-bit device register.
|
||||
@@ -194,8 +194,8 @@ int8_t I2Cdev::readByte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint16_
|
||||
* @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
|
||||
* @return Status of read operation (true = success)
|
||||
*/
|
||||
int8_t I2Cdev::readWord(uint8_t devAddr, uint8_t regAddr, uint16_t *data, uint16_t timeout) {
|
||||
return readWords(devAddr, regAddr, 1, data, timeout);
|
||||
int8_t I2Cdev::readWord(uint8_t devAddr, uint8_t regAddr, uint16_t *data, uint16_t timeout, void *wireObj) {
|
||||
return readWords(devAddr, regAddr, 1, data, timeout, wireObj);
|
||||
}
|
||||
|
||||
/** Read multiple bytes from an 8-bit device register.
|
||||
@@ -206,7 +206,7 @@ int8_t I2Cdev::readWord(uint8_t devAddr, uint8_t regAddr, uint16_t *data, uint16
|
||||
* @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
|
||||
* @return Number of bytes read (-1 indicates failure)
|
||||
*/
|
||||
int8_t I2Cdev::readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout) {
|
||||
int8_t I2Cdev::readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout, void *wireObj) {
|
||||
#ifdef I2CDEV_SERIAL_DEBUG
|
||||
Serial.print("I2C (0x");
|
||||
Serial.print(devAddr, HEX);
|
||||
@@ -220,71 +220,73 @@ int8_t I2Cdev::readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8
|
||||
int8_t count = 0;
|
||||
uint32_t t1 = millis();
|
||||
|
||||
#if (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE)
|
||||
#if (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_SBWIRE || I2CDEV_IMPLEMENTATION == I2CDEV_TEENSY_3X_WIRE)
|
||||
TwoWire *useWire = &Wire;
|
||||
if (wireObj) useWire = (TwoWire *)wireObj;
|
||||
|
||||
#if (ARDUINO < 100)
|
||||
// Arduino v00xx (before v1.0), Wire library
|
||||
|
||||
// I2C/TWI subsystem uses internal buffer that breaks with large data requests
|
||||
// so if user requests more than BUFFER_LENGTH bytes, we have to do it in
|
||||
// so if user requests more than I2CDEVLIB_WIRE_BUFFER_LENGTH bytes, we have to do it in
|
||||
// smaller chunks instead of all at once
|
||||
for (uint8_t k = 0; k < length; k += _min(length, BUFFER_LENGTH)) {
|
||||
Wire.beginTransmission(devAddr);
|
||||
Wire.send(regAddr);
|
||||
Wire.endTransmission();
|
||||
Wire.beginTransmission(devAddr);
|
||||
Wire.requestFrom(devAddr, (uint8_t)_min(length - k, BUFFER_LENGTH));
|
||||
for (int k = 0; k < length; k += min((int)length, I2CDEVLIB_WIRE_BUFFER_LENGTH)) {
|
||||
useWire->beginTransmission(devAddr);
|
||||
useWire->send(regAddr);
|
||||
useWire->endTransmission();
|
||||
useWire->beginTransmission(devAddr);
|
||||
useWire->requestFrom((uint8_t)devAddr, (uint8_t)min((int)length - k, I2CDEVLIB_WIRE_BUFFER_LENGTH));
|
||||
|
||||
for (; Wire.available() && (timeout == 0 || millis() - t1 < timeout); count++) {
|
||||
data[count] = Wire.receive();
|
||||
for (; useWire->available() && (timeout == 0 || millis() - t1 < timeout); count++) {
|
||||
data[count] = useWire->receive();
|
||||
#ifdef I2CDEV_SERIAL_DEBUG
|
||||
Serial.print(data[count], HEX);
|
||||
if (count + 1 < length) Serial.print(" ");
|
||||
#endif
|
||||
}
|
||||
|
||||
Wire.endTransmission();
|
||||
useWire->endTransmission();
|
||||
}
|
||||
#elif (ARDUINO == 100)
|
||||
// Arduino v1.0.0, Wire library
|
||||
// Adds standardized write() and read() stream methods instead of send() and receive()
|
||||
|
||||
// I2C/TWI subsystem uses internal buffer that breaks with large data requests
|
||||
// so if user requests more than BUFFER_LENGTH bytes, we have to do it in
|
||||
// so if user requests more than I2CDEVLIB_WIRE_BUFFER_LENGTH bytes, we have to do it in
|
||||
// smaller chunks instead of all at once
|
||||
for (uint8_t k = 0; k < length; k += _min(length, BUFFER_LENGTH)) {
|
||||
Wire.beginTransmission(devAddr);
|
||||
Wire.write(regAddr);
|
||||
Wire.endTransmission();
|
||||
Wire.beginTransmission(devAddr);
|
||||
Wire.requestFrom(devAddr, (uint8_t)_min(length - k, BUFFER_LENGTH));
|
||||
|
||||
for (; Wire.available() && (timeout == 0 || millis() - t1 < timeout); count++) {
|
||||
data[count] = Wire.read();
|
||||
for (int k = 0; k < length; k += min((int)length, I2CDEVLIB_WIRE_BUFFER_LENGTH)) {
|
||||
useWire->beginTransmission(devAddr);
|
||||
useWire->write(regAddr);
|
||||
useWire->endTransmission();
|
||||
useWire->beginTransmission(devAddr);
|
||||
useWire->requestFrom((uint8_t)devAddr, (uint8_t)min((int)length - k, I2CDEVLIB_WIRE_BUFFER_LENGTH));
|
||||
|
||||
for (; useWire->available() && (timeout == 0 || millis() - t1 < timeout); count++) {
|
||||
data[count] = useWire->read();
|
||||
#ifdef I2CDEV_SERIAL_DEBUG
|
||||
Serial.print(data[count], HEX);
|
||||
if (count + 1 < length) Serial.print(" ");
|
||||
#endif
|
||||
}
|
||||
|
||||
Wire.endTransmission();
|
||||
|
||||
useWire->endTransmission();
|
||||
}
|
||||
#elif (ARDUINO > 100)
|
||||
// Arduino v1.0.1+, Wire library
|
||||
// Adds official support for repeated start condition, yay!
|
||||
|
||||
// I2C/TWI subsystem uses internal buffer that breaks with large data requests
|
||||
// so if user requests more than BUFFER_LENGTH bytes, we have to do it in
|
||||
// so if user requests more than I2CDEVLIB_WIRE_BUFFER_LENGTH bytes, we have to do it in
|
||||
// smaller chunks instead of all at once
|
||||
for (uint8_t k = 0; k < length; k += _min(length, BUFFER_LENGTH)) {
|
||||
Wire.beginTransmission(devAddr);
|
||||
Wire.write(regAddr);
|
||||
Wire.endTransmission();
|
||||
Wire.beginTransmission(devAddr);
|
||||
Wire.requestFrom(devAddr, (uint8_t)_min(length - k, BUFFER_LENGTH));
|
||||
|
||||
for (; Wire.available() && (timeout == 0 || millis() - t1 < timeout); count++) {
|
||||
data[count] = Wire.read();
|
||||
for (int k = 0; k < length; k += min((int)length, I2CDEVLIB_WIRE_BUFFER_LENGTH)) {
|
||||
useWire->beginTransmission(devAddr);
|
||||
useWire->write(regAddr);
|
||||
useWire->endTransmission();
|
||||
useWire->beginTransmission(devAddr);
|
||||
useWire->requestFrom((uint8_t)devAddr, (uint8_t)min((int)length - k, I2CDEVLIB_WIRE_BUFFER_LENGTH));
|
||||
|
||||
for (; useWire->available() && (timeout == 0 || millis() - t1 < timeout); count++) {
|
||||
data[count] = useWire->read();
|
||||
#ifdef I2CDEV_SERIAL_DEBUG
|
||||
Serial.print(data[count], HEX);
|
||||
if (count + 1 < length) Serial.print(" ");
|
||||
@@ -326,7 +328,7 @@ int8_t I2Cdev::readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8
|
||||
* @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
|
||||
* @return Number of words read (-1 indicates failure)
|
||||
*/
|
||||
int8_t I2Cdev::readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data, uint16_t timeout) {
|
||||
int8_t I2Cdev::readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data, uint16_t timeout, void *wireObj) {
|
||||
#ifdef I2CDEV_SERIAL_DEBUG
|
||||
Serial.print("I2C (0x");
|
||||
Serial.print(devAddr, HEX);
|
||||
@@ -340,29 +342,31 @@ int8_t I2Cdev::readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint1
|
||||
int8_t count = 0;
|
||||
uint32_t t1 = millis();
|
||||
|
||||
#if (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE)
|
||||
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_SBWIRE || I2CDEV_IMPLEMENTATION == I2CDEV_TEENSY_3X_WIRE
|
||||
TwoWire *useWire = &Wire;
|
||||
if (wireObj) useWire = (TwoWire *)wireObj;
|
||||
|
||||
#if (ARDUINO < 100)
|
||||
// Arduino v00xx (before v1.0), Wire library
|
||||
|
||||
// I2C/TWI subsystem uses internal buffer that breaks with large data requests
|
||||
// so if user requests more than BUFFER_LENGTH bytes, we have to do it in
|
||||
// so if user requests more than I2CDEVLIB_WIRE_BUFFER_LENGTH bytes, we have to do it in
|
||||
// smaller chunks instead of all at once
|
||||
for (uint8_t k = 0; k < length * 2; k += _min(length * 2, BUFFER_LENGTH)) {
|
||||
Wire.beginTransmission(devAddr);
|
||||
Wire.send(regAddr);
|
||||
Wire.endTransmission();
|
||||
Wire.beginTransmission(devAddr);
|
||||
Wire.requestFrom(devAddr, (uint8_t)(length * 2)); // length=words, this wants bytes
|
||||
|
||||
for (uint8_t k = 0; k < length * 2; k += min(length * 2, I2CDEVLIB_WIRE_BUFFER_LENGTH)) {
|
||||
useWire->beginTransmission(devAddr);
|
||||
useWire->send(regAddr);
|
||||
useWire->endTransmission();
|
||||
useWire->beginTransmission(devAddr);
|
||||
useWire->requestFrom(devAddr, (uint8_t)(length * 2)); // length=words, this wants bytes
|
||||
|
||||
bool msb = true; // starts with MSB, then LSB
|
||||
for (; Wire.available() && count < length && (timeout == 0 || millis() - t1 < timeout);) {
|
||||
for (; useWire->available() && count < length && (timeout == 0 || millis() - t1 < timeout);) {
|
||||
if (msb) {
|
||||
// first byte is bits 15-8 (MSb=15)
|
||||
data[count] = Wire.receive() << 8;
|
||||
data[count] = useWire->receive() << 8;
|
||||
} else {
|
||||
// second byte is bits 7-0 (LSb=0)
|
||||
data[count] |= Wire.receive();
|
||||
data[count] |= useWire->receive();
|
||||
#ifdef I2CDEV_SERIAL_DEBUG
|
||||
Serial.print(data[count], HEX);
|
||||
if (count + 1 < length) Serial.print(" ");
|
||||
@@ -372,30 +376,30 @@ int8_t I2Cdev::readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint1
|
||||
msb = !msb;
|
||||
}
|
||||
|
||||
Wire.endTransmission();
|
||||
useWire->endTransmission();
|
||||
}
|
||||
#elif (ARDUINO == 100)
|
||||
// Arduino v1.0.0, Wire library
|
||||
// Adds standardized write() and read() stream methods instead of send() and receive()
|
||||
|
||||
|
||||
// I2C/TWI subsystem uses internal buffer that breaks with large data requests
|
||||
// so if user requests more than BUFFER_LENGTH bytes, we have to do it in
|
||||
// so if user requests more than I2CDEVLIB_WIRE_BUFFER_LENGTH bytes, we have to do it in
|
||||
// smaller chunks instead of all at once
|
||||
for (uint8_t k = 0; k < length * 2; k += _min(length * 2, BUFFER_LENGTH)) {
|
||||
Wire.beginTransmission(devAddr);
|
||||
Wire.write(regAddr);
|
||||
Wire.endTransmission();
|
||||
Wire.beginTransmission(devAddr);
|
||||
Wire.requestFrom(devAddr, (uint8_t)(length * 2)); // length=words, this wants bytes
|
||||
|
||||
for (uint8_t k = 0; k < length * 2; k += min(length * 2, I2CDEVLIB_WIRE_BUFFER_LENGTH)) {
|
||||
useWire->beginTransmission(devAddr);
|
||||
useWire->write(regAddr);
|
||||
useWire->endTransmission();
|
||||
useWire->beginTransmission(devAddr);
|
||||
useWire->requestFrom(devAddr, (uint8_t)(length * 2)); // length=words, this wants bytes
|
||||
|
||||
bool msb = true; // starts with MSB, then LSB
|
||||
for (; Wire.available() && count < length && (timeout == 0 || millis() - t1 < timeout);) {
|
||||
for (; useWire->available() && count < length && (timeout == 0 || millis() - t1 < timeout);) {
|
||||
if (msb) {
|
||||
// first byte is bits 15-8 (MSb=15)
|
||||
data[count] = Wire.read() << 8;
|
||||
data[count] = useWire->read() << 8;
|
||||
} else {
|
||||
// second byte is bits 7-0 (LSb=0)
|
||||
data[count] |= Wire.read();
|
||||
data[count] |= useWire->read();
|
||||
#ifdef I2CDEV_SERIAL_DEBUG
|
||||
Serial.print(data[count], HEX);
|
||||
if (count + 1 < length) Serial.print(" ");
|
||||
@@ -404,31 +408,31 @@ int8_t I2Cdev::readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint1
|
||||
}
|
||||
msb = !msb;
|
||||
}
|
||||
|
||||
Wire.endTransmission();
|
||||
|
||||
useWire->endTransmission();
|
||||
}
|
||||
#elif (ARDUINO > 100)
|
||||
// Arduino v1.0.1+, Wire library
|
||||
// Adds official support for repeated start condition, yay!
|
||||
|
||||
// I2C/TWI subsystem uses internal buffer that breaks with large data requests
|
||||
// so if user requests more than BUFFER_LENGTH bytes, we have to do it in
|
||||
// so if user requests more than I2CDEVLIB_WIRE_BUFFER_LENGTH bytes, we have to do it in
|
||||
// smaller chunks instead of all at once
|
||||
for (uint8_t k = 0; k < length * 2; k += _min(length * 2, BUFFER_LENGTH)) {
|
||||
Wire.beginTransmission(devAddr);
|
||||
Wire.write(regAddr);
|
||||
Wire.endTransmission();
|
||||
Wire.beginTransmission(devAddr);
|
||||
Wire.requestFrom(devAddr, (uint8_t)(length * 2)); // length=words, this wants bytes
|
||||
|
||||
for (uint8_t k = 0; k < length * 2; k += min(length * 2, I2CDEVLIB_WIRE_BUFFER_LENGTH)) {
|
||||
useWire->beginTransmission(devAddr);
|
||||
useWire->write(regAddr);
|
||||
useWire->endTransmission();
|
||||
useWire->beginTransmission(devAddr);
|
||||
useWire->requestFrom(devAddr, (uint8_t)(length * 2)); // length=words, this wants bytes
|
||||
|
||||
bool msb = true; // starts with MSB, then LSB
|
||||
for (; Wire.available() && count < length && (timeout == 0 || millis() - t1 < timeout);) {
|
||||
for (; useWire->available() && count < length && (timeout == 0 || millis() - t1 < timeout);) {
|
||||
if (msb) {
|
||||
// first byte is bits 15-8 (MSb=15)
|
||||
data[count] = Wire.read() << 8;
|
||||
data[count] = useWire->read() << 8;
|
||||
} else {
|
||||
// second byte is bits 7-0 (LSb=0)
|
||||
data[count] |= Wire.read();
|
||||
data[count] |= useWire->read();
|
||||
#ifdef I2CDEV_SERIAL_DEBUG
|
||||
Serial.print(data[count], HEX);
|
||||
if (count + 1 < length) Serial.print(" ");
|
||||
@@ -437,8 +441,8 @@ int8_t I2Cdev::readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint1
|
||||
}
|
||||
msb = !msb;
|
||||
}
|
||||
|
||||
Wire.endTransmission();
|
||||
|
||||
useWire->endTransmission();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -446,8 +450,8 @@ int8_t I2Cdev::readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint1
|
||||
|
||||
// Fastwire library
|
||||
// no loop required for fastwire
|
||||
uint16_t intermediate[(uint8_t)length];
|
||||
uint8_t status = Fastwire::readBuf(devAddr << 1, regAddr, (uint8_t *)intermediate, (uint8_t)(length * 2));
|
||||
uint8_t intermediate[(uint8_t)length*2];
|
||||
uint8_t status = Fastwire::readBuf(devAddr << 1, regAddr, intermediate, (uint8_t)(length * 2));
|
||||
if (status == 0) {
|
||||
count = length; // success
|
||||
for (uint8_t i = 0; i < length; i++) {
|
||||
@@ -466,7 +470,7 @@ int8_t I2Cdev::readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint1
|
||||
Serial.print(count, DEC);
|
||||
Serial.println(" read).");
|
||||
#endif
|
||||
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -477,11 +481,11 @@ int8_t I2Cdev::readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint1
|
||||
* @param value New bit value to write
|
||||
* @return Status of operation (true = success)
|
||||
*/
|
||||
bool I2Cdev::writeBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data) {
|
||||
bool I2Cdev::writeBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data, void *wireObj) {
|
||||
uint8_t b;
|
||||
readByte(devAddr, regAddr, &b);
|
||||
readByte(devAddr, regAddr, &b, I2Cdev::readTimeout, wireObj);
|
||||
b = (data != 0) ? (b | (1 << bitNum)) : (b & ~(1 << bitNum));
|
||||
return writeByte(devAddr, regAddr, b);
|
||||
return writeByte(devAddr, regAddr, b, wireObj);
|
||||
}
|
||||
|
||||
/** write a single bit in a 16-bit device register.
|
||||
@@ -491,11 +495,11 @@ bool I2Cdev::writeBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t
|
||||
* @param value New bit value to write
|
||||
* @return Status of operation (true = success)
|
||||
*/
|
||||
bool I2Cdev::writeBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t data) {
|
||||
bool I2Cdev::writeBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t data, void *wireObj) {
|
||||
uint16_t w;
|
||||
readWord(devAddr, regAddr, &w);
|
||||
readWord(devAddr, regAddr, &w, I2Cdev::readTimeout, wireObj);
|
||||
w = (data != 0) ? (w | (1 << bitNum)) : (w & ~(1 << bitNum));
|
||||
return writeWord(devAddr, regAddr, w);
|
||||
return writeWord(devAddr, regAddr, w, wireObj);
|
||||
}
|
||||
|
||||
/** Write multiple bits in an 8-bit device register.
|
||||
@@ -506,7 +510,7 @@ bool I2Cdev::writeBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_
|
||||
* @param data Right-aligned value to write
|
||||
* @return Status of operation (true = success)
|
||||
*/
|
||||
bool I2Cdev::writeBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t data) {
|
||||
bool I2Cdev::writeBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t data, void *wireObj) {
|
||||
// 010 value to write
|
||||
// 76543210 bit numbers
|
||||
// xxx args: bitStart=4, length=3
|
||||
@@ -515,13 +519,13 @@ bool I2Cdev::writeBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8
|
||||
// 10100011 original & ~mask
|
||||
// 10101011 masked | value
|
||||
uint8_t b;
|
||||
if (readByte(devAddr, regAddr, &b) != 0) {
|
||||
if (readByte(devAddr, regAddr, &b, I2Cdev::readTimeout, wireObj) != 0) {
|
||||
uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1);
|
||||
data <<= (bitStart - length + 1); // shift data into correct position
|
||||
data &= mask; // zero all non-important bits in data
|
||||
b &= ~(mask); // zero all important bits in existing byte
|
||||
b |= data; // combine data with existing byte
|
||||
return writeByte(devAddr, regAddr, b);
|
||||
return writeByte(devAddr, regAddr, b, wireObj);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -535,7 +539,7 @@ bool I2Cdev::writeBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8
|
||||
* @param data Right-aligned value to write
|
||||
* @return Status of operation (true = success)
|
||||
*/
|
||||
bool I2Cdev::writeBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t data) {
|
||||
bool I2Cdev::writeBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t data, void *wireObj) {
|
||||
// 010 value to write
|
||||
// fedcba9876543210 bit numbers
|
||||
// xxx args: bitStart=12, length=3
|
||||
@@ -544,13 +548,13 @@ bool I2Cdev::writeBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint
|
||||
// 1010001110010110 original & ~mask
|
||||
// 1010101110010110 masked | value
|
||||
uint16_t w;
|
||||
if (readWord(devAddr, regAddr, &w) != 0) {
|
||||
if (readWord(devAddr, regAddr, &w, I2Cdev::readTimeout, wireObj) != 0) {
|
||||
uint16_t mask = ((1 << length) - 1) << (bitStart - length + 1);
|
||||
data <<= (bitStart - length + 1); // shift data into correct position
|
||||
data &= mask; // zero all non-important bits in data
|
||||
w &= ~(mask); // zero all important bits in existing word
|
||||
w |= data; // combine data with existing word
|
||||
return writeWord(devAddr, regAddr, w);
|
||||
return writeWord(devAddr, regAddr, w, wireObj);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -562,8 +566,8 @@ bool I2Cdev::writeBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint
|
||||
* @param data New byte value to write
|
||||
* @return Status of operation (true = success)
|
||||
*/
|
||||
bool I2Cdev::writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data) {
|
||||
return writeBytes(devAddr, regAddr, 1, &data);
|
||||
bool I2Cdev::writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data, void *wireObj) {
|
||||
return writeBytes(devAddr, regAddr, 1, &data, wireObj);
|
||||
}
|
||||
|
||||
/** Write single word to a 16-bit device register.
|
||||
@@ -572,8 +576,8 @@ bool I2Cdev::writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data) {
|
||||
* @param data New word value to write
|
||||
* @return Status of operation (true = success)
|
||||
*/
|
||||
bool I2Cdev::writeWord(uint8_t devAddr, uint8_t regAddr, uint16_t data) {
|
||||
return writeWords(devAddr, regAddr, 1, &data);
|
||||
bool I2Cdev::writeWord(uint8_t devAddr, uint8_t regAddr, uint16_t data, void *wireObj) {
|
||||
return writeWords(devAddr, regAddr, 1, &data, wireObj);
|
||||
}
|
||||
|
||||
/** Write multiple bytes to an 8-bit device register.
|
||||
@@ -583,7 +587,7 @@ bool I2Cdev::writeWord(uint8_t devAddr, uint8_t regAddr, uint16_t data) {
|
||||
* @param data Buffer to copy new data from
|
||||
* @return Status of operation (true = success)
|
||||
*/
|
||||
bool I2Cdev::writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t* data) {
|
||||
bool I2Cdev::writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t* data, void *wireObj) {
|
||||
#ifdef I2CDEV_SERIAL_DEBUG
|
||||
Serial.print("I2C (0x");
|
||||
Serial.print(devAddr, HEX);
|
||||
@@ -594,12 +598,20 @@ bool I2Cdev::writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_
|
||||
Serial.print("...");
|
||||
#endif
|
||||
uint8_t status = 0;
|
||||
|
||||
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_SBWIRE || I2CDEV_IMPLEMENTATION == I2CDEV_TEENSY_3X_WIRE
|
||||
TwoWire *useWire = &Wire;
|
||||
if (wireObj) useWire = (TwoWire *)wireObj;
|
||||
#endif
|
||||
|
||||
#if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE)
|
||||
Wire.beginTransmission(devAddr);
|
||||
Wire.send((uint8_t) regAddr); // send address
|
||||
#elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100)
|
||||
Wire.beginTransmission(devAddr);
|
||||
Wire.write((uint8_t) regAddr); // send address
|
||||
useWire->beginTransmission(devAddr);
|
||||
useWire->send((uint8_t) regAddr); // send address
|
||||
#elif ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100) \
|
||||
|| (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_SBWIRE && ARDUINO >= 100) \
|
||||
|| I2CDEV_IMPLEMENTATION == I2CDEV_TEENSY_3X_WIRE)
|
||||
useWire->beginTransmission(devAddr);
|
||||
useWire->write((uint8_t) regAddr); // send address
|
||||
#elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE)
|
||||
Fastwire::beginTransmission(devAddr);
|
||||
Fastwire::write(regAddr);
|
||||
@@ -610,17 +622,21 @@ bool I2Cdev::writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_
|
||||
if (i + 1 < length) Serial.print(" ");
|
||||
#endif
|
||||
#if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE)
|
||||
Wire.send((uint8_t) data[i]);
|
||||
#elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100)
|
||||
Wire.write((uint8_t) data[i]);
|
||||
useWire->send((uint8_t) data[i]);
|
||||
#elif ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100) \
|
||||
|| (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_SBWIRE && ARDUINO >= 100) \
|
||||
|| I2CDEV_IMPLEMENTATION == I2CDEV_TEENSY_3X_WIRE)
|
||||
useWire->write((uint8_t) data[i]);
|
||||
#elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE)
|
||||
Fastwire::write((uint8_t) data[i]);
|
||||
#endif
|
||||
}
|
||||
#if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE)
|
||||
Wire.endTransmission();
|
||||
#elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100)
|
||||
status = Wire.endTransmission();
|
||||
useWire->endTransmission();
|
||||
#elif ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100) \
|
||||
|| (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_SBWIRE && ARDUINO >= 100) \
|
||||
|| I2CDEV_IMPLEMENTATION == I2CDEV_TEENSY_3X_WIRE)
|
||||
status = useWire->endTransmission();
|
||||
#elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE)
|
||||
Fastwire::stop();
|
||||
//status = Fastwire::endTransmission();
|
||||
@@ -638,7 +654,7 @@ bool I2Cdev::writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_
|
||||
* @param data Buffer to copy new data from
|
||||
* @return Status of operation (true = success)
|
||||
*/
|
||||
bool I2Cdev::writeWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t* data) {
|
||||
bool I2Cdev::writeWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t* data, void *wireObj) {
|
||||
#ifdef I2CDEV_SERIAL_DEBUG
|
||||
Serial.print("I2C (0x");
|
||||
Serial.print(devAddr, HEX);
|
||||
@@ -649,37 +665,49 @@ bool I2Cdev::writeWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16
|
||||
Serial.print("...");
|
||||
#endif
|
||||
uint8_t status = 0;
|
||||
|
||||
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_SBWIRE || I2CDEV_IMPLEMENTATION == I2CDEV_TEENSY_3X_WIRE
|
||||
TwoWire *useWire = &Wire;
|
||||
if (wireObj) useWire = (TwoWire *)wireObj;
|
||||
#endif
|
||||
|
||||
#if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE)
|
||||
Wire.beginTransmission(devAddr);
|
||||
Wire.send(regAddr); // send address
|
||||
#elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100)
|
||||
Wire.beginTransmission(devAddr);
|
||||
Wire.write(regAddr); // send address
|
||||
useWire->beginTransmission(devAddr);
|
||||
useWire->send(regAddr); // send address
|
||||
#elif ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100) \
|
||||
|| (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_SBWIRE && ARDUINO >= 100) \
|
||||
|| I2CDEV_IMPLEMENTATION == I2CDEV_TEENSY_3X_WIRE)
|
||||
useWire->beginTransmission(devAddr);
|
||||
useWire->write(regAddr); // send address
|
||||
#elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE)
|
||||
Fastwire::beginTransmission(devAddr);
|
||||
Fastwire::write(regAddr);
|
||||
#endif
|
||||
for (uint8_t i = 0; i < length * 2; i++) {
|
||||
for (uint8_t i = 0; i < length; i++) {
|
||||
#ifdef I2CDEV_SERIAL_DEBUG
|
||||
Serial.print(data[i], HEX);
|
||||
if (i + 1 < length) Serial.print(" ");
|
||||
#endif
|
||||
#if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE)
|
||||
Wire.send((uint8_t)(data[i] >> 8)); // send MSB
|
||||
Wire.send((uint8_t)data[i++]); // send LSB
|
||||
#elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100)
|
||||
Wire.write((uint8_t)(data[i] >> 8)); // send MSB
|
||||
Wire.write((uint8_t)data[i++]); // send LSB
|
||||
useWire->send((uint8_t)(data[i] >> 8)); // send MSB
|
||||
useWire->send((uint8_t)data[i]); // send LSB
|
||||
#elif ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100) \
|
||||
|| (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_SBWIRE && ARDUINO >= 100) \
|
||||
|| I2CDEV_IMPLEMENTATION == I2CDEV_TEENSY_3X_WIRE)
|
||||
useWire->write((uint8_t)(data[i] >> 8)); // send MSB
|
||||
useWire->write((uint8_t)data[i]); // send LSB
|
||||
#elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE)
|
||||
Fastwire::write((uint8_t)(data[i] >> 8)); // send MSB
|
||||
status = Fastwire::write((uint8_t)data[i++]); // send LSB
|
||||
status = Fastwire::write((uint8_t)data[i]); // send LSB
|
||||
if (status != 0) break;
|
||||
#endif
|
||||
}
|
||||
#if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE)
|
||||
Wire.endTransmission();
|
||||
#elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100)
|
||||
status = Wire.endTransmission();
|
||||
useWire->endTransmission();
|
||||
#elif ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100) \
|
||||
|| (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_SBWIRE && ARDUINO >= 100) \
|
||||
|| I2CDEV_IMPLEMENTATION == I2CDEV_TEENSY_3X_WIRE)
|
||||
status = useWire->endTransmission();
|
||||
#elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE)
|
||||
Fastwire::stop();
|
||||
//status = Fastwire::endTransmission();
|
||||
@@ -739,15 +767,15 @@ uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;
|
||||
#endif
|
||||
|
||||
TWSR = 0; // no prescaler => prescaler = 1
|
||||
TWBR = ((16000L / khz) - 16) / 2; // change the I2C clock rate
|
||||
TWBR = F_CPU / 2000 / khz - 8; // change the I2C clock rate
|
||||
TWCR = 1 << TWEN; // enable twi module, no interrupt
|
||||
}
|
||||
|
||||
// added by Jeff Rowberg 2013-05-07:
|
||||
// Arduino Wire-style "beginTransmission" function
|
||||
// (takes 7-bit device address like the Wire method, NOT 8-bit: 0x68, not 0xD0/0xD1)
|
||||
uint8_t Fastwire::beginTransmission(uint8_t device) {
|
||||
uint8_t twst, retry;
|
||||
byte Fastwire::beginTransmission(byte device) {
|
||||
byte twst, retry;
|
||||
retry = 2;
|
||||
do {
|
||||
TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO) | (1 << TWSTA);
|
||||
@@ -766,8 +794,8 @@ uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t Fastwire::writeBuf(uint8_t device, uint8_t address, uint8_t *data, uint8_t num) {
|
||||
uint8_t twst, retry;
|
||||
byte Fastwire::writeBuf(byte device, byte address, byte *data, byte num) {
|
||||
byte twst, retry;
|
||||
|
||||
retry = 2;
|
||||
do {
|
||||
@@ -793,7 +821,7 @@ uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;
|
||||
twst = TWSR & 0xF8;
|
||||
if (twst != TW_MT_DATA_ACK) return 6;
|
||||
|
||||
for (uint8_t i = 0; i < num; i++) {
|
||||
for (byte i = 0; i < num; i++) {
|
||||
//Serial.print(data[i], HEX);
|
||||
//Serial.print(" ");
|
||||
TWDR = data[i]; // send data to the previously addressed device
|
||||
@@ -807,8 +835,8 @@ uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t Fastwire::write(uint8_t value) {
|
||||
uint8_t twst;
|
||||
byte Fastwire::write(byte value) {
|
||||
byte twst;
|
||||
//Serial.println(value, HEX);
|
||||
TWDR = value; // send data
|
||||
TWCR = (1 << TWINT) | (1 << TWEN);
|
||||
@@ -818,8 +846,8 @@ uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t Fastwire::readBuf(uint8_t device, uint8_t address, uint8_t *data, uint8_t num) {
|
||||
uint8_t twst, retry;
|
||||
byte Fastwire::readBuf(byte device, byte address, byte *data, byte num) {
|
||||
byte twst, retry;
|
||||
|
||||
retry = 2;
|
||||
do {
|
||||
@@ -885,7 +913,7 @@ uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;
|
||||
TWCR = 0;
|
||||
}
|
||||
|
||||
uint8_t Fastwire::stop() {
|
||||
byte Fastwire::stop() {
|
||||
TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
|
||||
if (!waitInt()) return 1;
|
||||
return 0;
|
||||
@@ -899,50 +927,50 @@ uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;
|
||||
|
||||
/*
|
||||
call this version 1.0
|
||||
|
||||
|
||||
Offhand, the only funky part that I can think of is in nbrequestFrom, where the buffer
|
||||
length and index are set *before* the data is actually read. The problem is that these
|
||||
are variables local to the TwoWire object, and by the time we actually have read the
|
||||
data, and know what the length actually is, we have no simple access to the object's
|
||||
data, and know what the length actually is, we have no simple access to the object's
|
||||
variables. The actual bytes read *is* given to the callback function, though.
|
||||
|
||||
|
||||
The ISR code for a slave receiver is commented out. I don't have that setup, and can't
|
||||
verify it at this time. Save it for 2.0!
|
||||
|
||||
The handling of the read and write processes here is much like in the demo sketch code:
|
||||
|
||||
The handling of the read and write processes here is much like in the demo sketch code:
|
||||
the process is broken down into sequential functions, where each registers the next as a
|
||||
callback, essentially.
|
||||
|
||||
For example, for the Read process, twi_read00 just returns if TWI is not yet in a
|
||||
|
||||
For example, for the Read process, twi_read00 just returns if TWI is not yet in a
|
||||
ready state. When there's another interrupt, and the interface *is* ready, then it
|
||||
sets up the read, starts it, and registers twi_read01 as the function to call after
|
||||
the *next* interrupt. twi_read01, then, just returns if the interface is still in a
|
||||
"reading" state. When the reading is done, it copies the information to the buffer,
|
||||
cleans up, and calls the user-requested callback function with the actual number of
|
||||
cleans up, and calls the user-requested callback function with the actual number of
|
||||
bytes read.
|
||||
|
||||
|
||||
The writing is similar.
|
||||
|
||||
|
||||
Questions, comments and problems can go to Gene@Telobot.com.
|
||||
|
||||
|
||||
Thumbs Up!
|
||||
Gene Knight
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
uint8_t TwoWire::rxBuffer[NBWIRE_BUFFER_LENGTH];
|
||||
uint8_t TwoWire::rxBufferIndex = 0;
|
||||
uint8_t TwoWire::rxBufferLength = 0;
|
||||
|
||||
|
||||
uint8_t TwoWire::txAddress = 0;
|
||||
uint8_t TwoWire::txBuffer[NBWIRE_BUFFER_LENGTH];
|
||||
uint8_t TwoWire::txBufferIndex = 0;
|
||||
uint8_t TwoWire::txBufferLength = 0;
|
||||
|
||||
|
||||
//uint8_t TwoWire::transmitting = 0;
|
||||
void (*TwoWire::user_onRequest)(void);
|
||||
void (*TwoWire::user_onReceive)(int);
|
||||
|
||||
|
||||
static volatile uint8_t twi_transmitting;
|
||||
static volatile uint8_t twi_state;
|
||||
static uint8_t twi_slarw;
|
||||
@@ -957,7 +985,7 @@ uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;
|
||||
static volatile uint8_t twi_Done;
|
||||
void (*twi_cbendTransmissionDone)(int);
|
||||
void (*twi_cbreadFromDone)(int);
|
||||
|
||||
|
||||
void twi_init() {
|
||||
// initialize state
|
||||
twi_state = TWI_READY;
|
||||
@@ -979,7 +1007,7 @@ uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;
|
||||
TWBR = ((CPU_FREQ / TWI_FREQ) - 16) / 2; // bitrate register
|
||||
// enable twi module, acks, and twi interrupt
|
||||
|
||||
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA);
|
||||
TWCR = (1 << TWEN) | (1 << TWIE) | (1 << TWEA);
|
||||
|
||||
/* TWEN - TWI Enable Bit
|
||||
TWIE - TWI Interrupt Enable
|
||||
@@ -988,7 +1016,7 @@ uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;
|
||||
TWSTA - TWI Start Condition
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t address;
|
||||
uint8_t* data;
|
||||
@@ -1000,7 +1028,7 @@ uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;
|
||||
twi_Write_Vars *ptwv = 0;
|
||||
static void (*fNextInterruptFunction)(void) = 0;
|
||||
|
||||
void twi_Finish(uint8_t bRetVal) {
|
||||
void twi_Finish(byte bRetVal) {
|
||||
if (ptwv) {
|
||||
free(ptwv);
|
||||
ptwv = 0;
|
||||
@@ -1009,13 +1037,13 @@ uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;
|
||||
twi_Return_Value = bRetVal;
|
||||
fNextInterruptFunction = 0;
|
||||
}
|
||||
|
||||
|
||||
uint8_t twii_WaitForDone(uint16_t timeout) {
|
||||
uint32_t endMillis = millis() + timeout;
|
||||
while (!twi_Done && (timeout == 0 || millis() < endMillis)) continue;
|
||||
return twi_Return_Value;
|
||||
}
|
||||
|
||||
|
||||
void twii_SetState(uint8_t ucState) {
|
||||
twi_state = ucState;
|
||||
}
|
||||
@@ -1048,7 +1076,7 @@ uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;
|
||||
}
|
||||
|
||||
void twii_SetStart() {
|
||||
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
|
||||
TWCR = (1 << TWEN) | (1 << TWIE) | (1 << TWEA) | (1 << TWINT) | (1 << TWSTA);
|
||||
}
|
||||
|
||||
void twi_write01() {
|
||||
@@ -1065,8 +1093,8 @@ uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;
|
||||
if (twi_cbendTransmissionDone) return twi_cbendTransmissionDone(twi_Return_Value);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void twi_write00() {
|
||||
if (TWI_READY != twi_state) return; // blocking test
|
||||
if (TWI_BUFFER_LENGTH < ptwv -> length) {
|
||||
@@ -1083,7 +1111,7 @@ uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;
|
||||
fNextInterruptFunction = twi_write01; // next routine
|
||||
return twi_write01();
|
||||
}
|
||||
|
||||
|
||||
void twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait) {
|
||||
uint8_t i;
|
||||
ptwv = (twi_Write_Vars *)malloc(sizeof(twi_Write_Vars));
|
||||
@@ -1103,7 +1131,7 @@ uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;
|
||||
if (twi_cbreadFromDone) return twi_cbreadFromDone(twi_Return_Value);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void twi_read00() {
|
||||
if (TWI_READY != twi_state) return; // blocking test
|
||||
if (TWI_BUFFER_LENGTH < ptwv -> length) twi_Finish(0); // error return
|
||||
@@ -1131,34 +1159,34 @@ uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;
|
||||
void twi_reply(uint8_t ack) {
|
||||
// transmit master read ready signal, with or without ack
|
||||
if (ack){
|
||||
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);
|
||||
TWCR = (1 << TWEN) | (1 << TWIE) | (1 << TWINT) | (1 << TWEA);
|
||||
} else {
|
||||
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT);
|
||||
TWCR = (1 << TWEN) | (1 << TWIE) | (1 << TWINT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void twi_stop(void) {
|
||||
// send stop condition
|
||||
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO);
|
||||
|
||||
TWCR = (1 << TWEN) | (1 << TWIE) | (1 << TWEA) | (1 << TWINT) | (1 << TWSTO);
|
||||
|
||||
// wait for stop condition to be exectued on bus
|
||||
// TWINT is not set after a stop condition!
|
||||
while (TWCR & _BV(TWSTO)) {
|
||||
while (TWCR & (1 << TWSTO)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// update twi state
|
||||
twi_state = TWI_READY;
|
||||
}
|
||||
|
||||
void twi_releaseBus(void) {
|
||||
// release bus
|
||||
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT);
|
||||
|
||||
TWCR = (1 << TWEN) | (1 << TWIE) | (1 << TWEA) | (1 << TWINT);
|
||||
|
||||
// update twi state
|
||||
twi_state = TWI_READY;
|
||||
}
|
||||
|
||||
|
||||
SIGNAL(TWI_vect) {
|
||||
switch (TW_STATUS) {
|
||||
// All Master
|
||||
@@ -1168,7 +1196,7 @@ uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;
|
||||
TWDR = twi_slarw;
|
||||
twi_reply(1);
|
||||
break;
|
||||
|
||||
|
||||
// Master Transmitter
|
||||
case TW_MT_SLA_ACK: // slave receiver acked address
|
||||
case TW_MT_DATA_ACK: // slave receiver acked data
|
||||
@@ -1196,7 +1224,7 @@ uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;
|
||||
twi_error = TW_MT_ARB_LOST;
|
||||
twi_releaseBus();
|
||||
break;
|
||||
|
||||
|
||||
// Master Receiver
|
||||
case TW_MR_DATA_ACK: // data received, ack sent
|
||||
// put byte into buffer
|
||||
@@ -1294,7 +1322,7 @@ uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;
|
||||
twi_txBufferLength = 1;
|
||||
twi_txBuffer[0] = 0x00;
|
||||
}
|
||||
|
||||
|
||||
// transmit first byte from buffer, fall through
|
||||
|
||||
case TW_ST_DATA_ACK: // byte sent, ack returned
|
||||
@@ -1332,26 +1360,26 @@ uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;
|
||||
}
|
||||
|
||||
TwoWire::TwoWire() { }
|
||||
|
||||
|
||||
void TwoWire::begin(void) {
|
||||
rxBufferIndex = 0;
|
||||
rxBufferLength = 0;
|
||||
|
||||
|
||||
txBufferIndex = 0;
|
||||
txBufferLength = 0;
|
||||
|
||||
twi_init();
|
||||
}
|
||||
|
||||
|
||||
void TwoWire::beginTransmission(uint8_t address) {
|
||||
//beginTransmission((uint8_t)address);
|
||||
|
||||
// indicate that we are transmitting
|
||||
twi_transmitting = 1;
|
||||
|
||||
|
||||
// set address of targeted slave
|
||||
txAddress = address;
|
||||
|
||||
|
||||
// reset tx buffer iterator vars
|
||||
txBufferIndex = 0;
|
||||
txBufferLength = 0;
|
||||
@@ -1378,7 +1406,7 @@ uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;
|
||||
twi_writeTo(txAddress, txBuffer, txBufferLength, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void TwoWire::send(uint8_t data) {
|
||||
if (twi_transmitting) {
|
||||
// in master transmitter mode
|
||||
@@ -1399,21 +1427,21 @@ uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;
|
||||
//twi_transmit(&data, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t TwoWire::receive(void) {
|
||||
// default to returning null char
|
||||
// for people using with char strings
|
||||
uint8_t value = 0;
|
||||
|
||||
|
||||
// get each successive byte on each call
|
||||
if (rxBufferIndex < rxBufferLength) {
|
||||
value = rxBuffer[rxBufferIndex];
|
||||
++rxBufferIndex;
|
||||
}
|
||||
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
uint8_t TwoWire::requestFrom(uint8_t address, int quantity, uint16_t timeout) {
|
||||
// clamp to buffer length
|
||||
if (quantity > NBWIRE_BUFFER_LENGTH) {
|
||||
@@ -1428,10 +1456,10 @@ uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;
|
||||
// set rx buffer iterator vars
|
||||
rxBufferIndex = 0;
|
||||
rxBufferLength = read;
|
||||
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
|
||||
void TwoWire::nbrequestFrom(uint8_t address, int quantity, void (*function)(int)) {
|
||||
// clamp to buffer length
|
||||
if (quantity > NBWIRE_BUFFER_LENGTH) {
|
||||
|
||||
Reference in New Issue
Block a user