diff --git a/Adafruit_I2CDevice.cpp b/Adafruit_I2CDevice.cpp index fee01ec..c3804d3 100644 --- a/Adafruit_I2CDevice.cpp +++ b/Adafruit_I2CDevice.cpp @@ -1,7 +1,7 @@ #include #include -//#define DEBUG_SERIAL Serial +#define DEBUG_SERIAL Serial Adafruit_I2CDevice::Adafruit_I2CDevice(uint8_t addr, TwoWire *theWire) { _addr = addr; @@ -30,8 +30,8 @@ bool Adafruit_I2CDevice::detected(void) { return false; } -bool Adafruit_I2CDevice::write(uint8_t *buffer, size_t len, bool stop) { - if (len > 32) { +bool Adafruit_I2CDevice::write(uint8_t *buffer, size_t len, bool stop, uint8_t *prefix_buffer, size_t prefix_len) { + if ((len+prefix_len) > 32) { // currently not guaranteed to work if more than 32 bytes! // we will need to find out if some platforms have larger // I2C buffer sizes :/ @@ -43,6 +43,17 @@ bool Adafruit_I2CDevice::write(uint8_t *buffer, size_t len, bool stop) { _wire->beginTransmission(_addr); + // Write the prefix data (usually an address) + if ((prefix_len != 0) && (prefix_buffer != NULL)) { + if (_wire->write(prefix_buffer, prefix_len) != prefix_len) { +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.println(F("\tI2CDevice failed to write")); +#endif + return false; + } + } + + // Write the data itself if (_wire->write(buffer, len) != len) { #ifdef DEBUG_SERIAL DEBUG_SERIAL.println(F("\tI2CDevice failed to write")); @@ -52,6 +63,13 @@ bool Adafruit_I2CDevice::write(uint8_t *buffer, size_t len, bool stop) { #ifdef DEBUG_SERIAL DEBUG_SERIAL.print(F("\tI2CDevice Wrote: ")); + if ((prefix_len != 0) && (prefix_buffer != NULL)) { + for (int i=0; i +#ifndef Adafruit_I2CDevice_h +#define Adafruit_I2CDevice_h + + class Adafruit_I2CDevice { - -private: - uint8_t _addr; - TwoWire *_wire; - bool _begun; - -public: + public: Adafruit_I2CDevice(uint8_t addr, TwoWire *theWire=&Wire); uint8_t address(void); bool begin(void); bool detected(void); bool read(uint8_t *buffer, size_t len, bool stop=true); - bool write(uint8_t *buffer, size_t len, bool stop=true); + bool write(uint8_t *buffer, size_t len, bool stop=true, uint8_t *prefix_buffer=NULL, size_t prefix_len=0); bool write_then_read(uint8_t *write_buffer, size_t write_len, uint8_t *read_buffer, size_t read_len, bool stop=false); + + + private: + uint8_t _addr; + TwoWire *_wire; + bool _begun; + }; + +#endif // Adafruit_I2CDevice_h diff --git a/Adafruit_I2CRegister.cpp b/Adafruit_I2CRegister.cpp new file mode 100644 index 0000000..04d987a --- /dev/null +++ b/Adafruit_I2CRegister.cpp @@ -0,0 +1,71 @@ +#include + +Adafruit_I2CRegister::Adafruit_I2CRegister(Adafruit_I2CDevice *device, uint16_t reg_addr, uint8_t width, uint8_t bitorder, uint8_t address_width) { + _device = device; + _addrwidth = address_width; + _address = reg_addr; + _bitorder = bitorder; + _width = width; +} + + +bool Adafruit_I2CRegister::write(uint8_t *buffer, uint8_t len) { + uint8_t addrbuffer[2] = {_address & 0xFF, _address >> 8}; + if (! _device->write(buffer, len, true, addrbuffer, _addrwidth)) { + return false; + } + return true; +} + +bool Adafruit_I2CRegister::write(uint32_t value, uint8_t numbytes=0) { + if (numbytes == 0) { + numbytes = _width; + } + if (numbytes > 4) { + return false; + } + + for (int i=0; i>= 8; + } + return write(_buffer, numbytes); +} + +bool Adafruit_I2CRegister::read(uint8_t *buffer, uint8_t len) { + _buffer[0] = _address; + if (! _device->write_then_read(_buffer, 1, buffer, len)) { + return false; + } + return true; +} + +bool Adafruit_I2CRegister::read(uint16_t *value) { + if (! read(_buffer, 2)) { + return false; + } + + if (_bitorder == LSBFIRST) { + *value = _buffer[1]; + *value <<= 8; + *value |= _buffer[0]; + } else { + *value = _buffer[0]; + *value <<= 8; + *value |= _buffer[1]; + } + return true; +} + +bool Adafruit_I2CRegister::read(uint8_t *value) { + if (! read(_buffer, 1)) { + return false; + } + + *value = _buffer[0]; + return true; +} diff --git a/Adafruit_I2CRegister.h b/Adafruit_I2CRegister.h new file mode 100644 index 0000000..6f51a27 --- /dev/null +++ b/Adafruit_I2CRegister.h @@ -0,0 +1,30 @@ +#include +#include + + +#ifndef Adafruit_I2CRegister_h +#define Adafruit_I2CRegister_h + + +class Adafruit_I2CRegister { + public: + Adafruit_I2CRegister(Adafruit_I2CDevice *device, uint16_t reg_addr, + uint8_t width=1, uint8_t bitorder=LSBFIRST, + uint8_t address_width=1); + + bool read(uint8_t *buffer, uint8_t len); + bool read(uint8_t *value); + bool read(uint16_t *value); + bool read(uint32_t *value); + bool write(uint8_t *buffer, uint8_t len); + bool write(uint32_t value, uint8_t numbytes=0); + + private: + Adafruit_I2CDevice *_device; + uint16_t _address; + uint8_t _width, _addrwidth, _bitorder; + uint8_t _buffer[4]; // we wont support anything larger than uint32 for non-buffered read +}; + + +#endif //I2CRegister_h diff --git a/examples/i2c_registers/i2c_registers.ino b/examples/i2c_registers/i2c_registers.ino new file mode 100644 index 0000000..a1b1bfd --- /dev/null +++ b/examples/i2c_registers/i2c_registers.ino @@ -0,0 +1,39 @@ +#include +#include + +#define I2C_ADDRESS 0x60 +Adafruit_I2CDevice i2c_dev = Adafruit_I2CDevice(I2C_ADDRESS); + + +void setup() { + while (!Serial) { delay(10); } + Serial.begin(115200); + Serial.println("I2C device register test"); + + if (!i2c_dev.begin()) { + Serial.print("Did not find device at 0x"); + Serial.println(i2c_dev.address(), HEX); + while (1); + } + Serial.print("Device found on address 0x"); + Serial.println(i2c_dev.address(), HEX); + + Adafruit_I2CRegister id_reg = Adafruit_I2CRegister(&i2c_dev, 0x0C, 2, LSBFIRST); + uint16_t id; + id_reg.read(&id); + Serial.print("ID register = 0x"); Serial.println(id, HEX); + + Adafruit_I2CRegister thresh_reg = Adafruit_I2CRegister(&i2c_dev, 0x01, 2, LSBFIRST); + uint16_t thresh; + thresh_reg.read(&thresh); + Serial.print("Initial threshold register = 0x"); Serial.println(thresh, HEX); + + thresh_reg.write(~thresh); + + thresh_reg.read(&thresh); + Serial.print("Post threshold register = 0x"); Serial.println(thresh, HEX); +} + +void loop() { + +}