diff --git a/Adafruit_BusIO_Register.cpp b/Adafruit_BusIO_Register.cpp index a28193f..6099431 100644 --- a/Adafruit_BusIO_Register.cpp +++ b/Adafruit_BusIO_Register.cpp @@ -88,6 +88,29 @@ Adafruit_BusIO_Register::Adafruit_BusIO_Register( _width = width; } +/*! +* @brief Create a register we access over a GenericDevice +* @param genericdevice Generic device to use +* @param reg_addr Register address we will read/write +* @param width Width of the register in bytes (1-4) +* @param byteorder Byte order of register data (LSBFIRST or MSBFIRST) +* @param address_width Width of the register address in bytes (1 or 2) +*/ +Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_GenericDevice *genericdevice, + uint16_t reg_addr, + uint8_t width, + uint8_t byteorder, + uint8_t address_width) { + _i2cdevice = nullptr; + _spidevice = nullptr; + _genericdevice = genericdevice; + _addrwidth = address_width; + _address = reg_addr; + _byteorder = byteorder; + _width = width; +} + + /*! * @brief Write a buffer of data to the register location * @param buffer Pointer to data to write @@ -96,17 +119,14 @@ Adafruit_BusIO_Register::Adafruit_BusIO_Register( * uncheckable) */ bool Adafruit_BusIO_Register::write(uint8_t *buffer, uint8_t len) { - uint8_t addrbuffer[2] = {(uint8_t)(_address & 0xFF), (uint8_t)(_address >> 8)}; - if (_i2cdevice) { return _i2cdevice->write(buffer, len, true, addrbuffer, _addrwidth); } if (_spidevice) { if (_spiregtype == ADDRESSED_OPCODE_BIT0_LOW_TO_WRITE) { // very special case! - // pass the special opcode address which we set as the high byte of the // regaddr addrbuffer[0] = @@ -116,7 +136,6 @@ bool Adafruit_BusIO_Register::write(uint8_t *buffer, uint8_t len) { // the address appears to be a byte longer return _spidevice->write(buffer, len, addrbuffer, _addrwidth + 1); } - if (_spiregtype == ADDRBIT8_HIGH_TOREAD) { addrbuffer[0] &= ~0x80; } @@ -129,6 +148,9 @@ bool Adafruit_BusIO_Register::write(uint8_t *buffer, uint8_t len) { } return _spidevice->write(buffer, len, addrbuffer, _addrwidth); } + if (_genericdevice) { + return _genericdevice->writeRegister(addrbuffer, _addrwidth, buffer, len); + } return false; } @@ -191,48 +213,43 @@ uint32_t Adafruit_BusIO_Register::read(void) { */ uint32_t Adafruit_BusIO_Register::readCached(void) { return _cached; } -/*! - * @brief Read a buffer of data from the register location - * @param buffer Pointer to data to read into - * @param len Number of bytes to read - * @return True on successful write (only really useful for I2C as SPI is - * uncheckable) - */ bool Adafruit_BusIO_Register::read(uint8_t *buffer, uint8_t len) { - uint8_t addrbuffer[2] = {(uint8_t)(_address & 0xFF), - (uint8_t)(_address >> 8)}; - - if (_i2cdevice) { - return _i2cdevice->write_then_read(addrbuffer, _addrwidth, buffer, len); - } - if (_spidevice) { - if (_spiregtype == ADDRESSED_OPCODE_BIT0_LOW_TO_WRITE) { - // very special case! - - // pass the special opcode address which we set as the high byte of the - // regaddr - addrbuffer[0] = - (uint8_t)(_address >> 8) | 0x01; // set bottom bit high to read - // the 'actual' reg addr is the second byte then - addrbuffer[1] = (uint8_t)(_address & 0xFF); - // the address appears to be a byte longer - return _spidevice->write_then_read(addrbuffer, _addrwidth + 1, buffer, - len); - } - if (_spiregtype == ADDRBIT8_HIGH_TOREAD) { - addrbuffer[0] |= 0x80; - } - if (_spiregtype == ADDRBIT8_HIGH_TOWRITE) { - addrbuffer[0] &= ~0x80; - } - if (_spiregtype == AD8_HIGH_TOREAD_AD7_HIGH_TOINC) { - addrbuffer[0] |= 0x80 | 0x40; - } - return _spidevice->write_then_read(addrbuffer, _addrwidth, buffer, len); - } - return false; + uint8_t addrbuffer[2] = {(uint8_t)(_address & 0xFF), + (uint8_t)(_address >> 8)}; + if (_i2cdevice) { + return _i2cdevice->write_then_read(addrbuffer, _addrwidth, buffer, len); + } + if (_spidevice) { + if (_spiregtype == ADDRESSED_OPCODE_BIT0_LOW_TO_WRITE) { + // very special case! + // pass the special opcode address which we set as the high byte of the + // regaddr + addrbuffer[0] = + (uint8_t)(_address >> 8) | 0x01; // set bottom bit high to read + // the 'actual' reg addr is the second byte then + addrbuffer[1] = (uint8_t)(_address & 0xFF); + // the address appears to be a byte longer + return _spidevice->write_then_read(addrbuffer, _addrwidth + 1, buffer, + len); + } + if (_spiregtype == ADDRBIT8_HIGH_TOREAD) { + addrbuffer[0] |= 0x80; + } + if (_spiregtype == ADDRBIT8_HIGH_TOWRITE) { + addrbuffer[0] &= ~0x80; + } + if (_spiregtype == AD8_HIGH_TOREAD_AD7_HIGH_TOINC) { + addrbuffer[0] |= 0x80 | 0x40; + } + return _spidevice->write_then_read(addrbuffer, _addrwidth, buffer, len); + } + if (_genericdevice) { + return _genericdevice->readRegister(addrbuffer, _addrwidth, buffer, len); + } + return false; } + /*! * @brief Read 2 bytes of data from the register location * @param value Pointer to uint16_t variable to read into diff --git a/Adafruit_BusIO_Register.h b/Adafruit_BusIO_Register.h index c6d58de..cd7f18a 100644 --- a/Adafruit_BusIO_Register.h +++ b/Adafruit_BusIO_Register.h @@ -8,6 +8,7 @@ #include #include +#include typedef enum _Adafruit_BusIO_SPIRegType { ADDRBIT8_HIGH_TOREAD = 0, @@ -57,6 +58,10 @@ public: uint8_t width = 1, uint8_t byteorder = LSBFIRST, uint8_t address_width = 1); + Adafruit_BusIO_Register(Adafruit_GenericDevice *genericdevice, uint16_t reg_addr, + uint8_t width = 1, uint8_t byteorder = LSBFIRST, + uint8_t address_width = 1); + bool read(uint8_t *buffer, uint8_t len); bool read(uint8_t *value); bool read(uint16_t *value); @@ -77,6 +82,7 @@ public: private: Adafruit_I2CDevice *_i2cdevice; Adafruit_SPIDevice *_spidevice; + Adafruit_GenericDevice *_genericdevice; Adafruit_BusIO_SPIRegType _spiregtype; uint16_t _address; uint8_t _width, _addrwidth, _byteorder; diff --git a/Adafruit_GenericDevice.cpp b/Adafruit_GenericDevice.cpp new file mode 100644 index 0000000..d41ec88 --- /dev/null +++ b/Adafruit_GenericDevice.cpp @@ -0,0 +1,45 @@ +#include "Adafruit_GenericDevice.h" + +Adafruit_GenericDevice::Adafruit_GenericDevice(busio_genericdevice_read_t read_func, + busio_genericdevice_write_t write_func, + busio_genericdevice_readreg_t readreg_func, + busio_genericdevice_writereg_t writereg_func) { + _read_func = read_func; + _write_func = write_func; + _readreg_func = readreg_func; + _writereg_func = writereg_func; + _begun = false; +} + +bool Adafruit_GenericDevice::begin(void) { + _begun = true; + return true; +} + +bool Adafruit_GenericDevice::write(const uint8_t *buffer, size_t len) { + if (!_begun) + return false; + + return _write_func(buffer, len); +} + +bool Adafruit_GenericDevice::read(uint8_t *buffer, size_t len) { + if (!_begun) + return false; + + return _read_func(buffer, len); +} + +bool Adafruit_GenericDevice::readRegister(uint8_t *addr_buf, uint8_t addrsiz, uint8_t *buf, uint16_t bufsiz) { + if (!_begun || !_readreg_func) + return false; + + return _readreg_func(addr_buf, addrsiz, buf, bufsiz); +} + +bool Adafruit_GenericDevice::writeRegister(uint8_t *addr_buf, uint8_t addrsiz, const uint8_t *buf, uint16_t bufsiz) { + if (!_begun || !_writereg_func) + return false; + + return _writereg_func(addr_buf, addrsiz, buf, bufsiz); +} diff --git a/Adafruit_GenericDevice.h b/Adafruit_GenericDevice.h new file mode 100644 index 0000000..ef84110 --- /dev/null +++ b/Adafruit_GenericDevice.h @@ -0,0 +1,37 @@ +#ifndef ADAFRUIT_GENERICDEVICE_H +#define ADAFRUIT_GENERICDEVICE_H + +#include + +typedef bool (*busio_genericdevice_read_t)(uint8_t *buffer, size_t len); +typedef bool (*busio_genericdevice_write_t)(const uint8_t *buffer, size_t len); +typedef bool (*busio_genericdevice_readreg_t)(uint8_t *addr_buf, uint8_t addrsiz, uint8_t *buf, uint16_t bufsiz); +typedef bool (*busio_genericdevice_writereg_t)(uint8_t *addr_buf, uint8_t addrsiz, const uint8_t *buf, uint16_t bufsiz); + +/*! + * @brief Class for communicating with a device via generic read/write functions + */ +class Adafruit_GenericDevice { +public: + Adafruit_GenericDevice(busio_genericdevice_read_t read_func, + busio_genericdevice_write_t write_func, + busio_genericdevice_readreg_t readreg_func = nullptr, + busio_genericdevice_writereg_t writereg_func = nullptr); + + bool begin(void); + + bool read(uint8_t *buffer, size_t len); + bool write(const uint8_t *buffer, size_t len); + bool readRegister(uint8_t *addr_buf, uint8_t addrsiz, uint8_t *buf, uint16_t bufsiz); + bool writeRegister(uint8_t *addr_buf, uint8_t addrsiz, const uint8_t *buf, uint16_t bufsiz); + +protected: + busio_genericdevice_read_t _read_func; + busio_genericdevice_write_t _write_func; + busio_genericdevice_readreg_t _readreg_func; + busio_genericdevice_writereg_t _writereg_func; + + bool _begun; +}; + +#endif // ADAFRUIT_GENERICDEVICE_H