From bb33ff71187570f2bd146100425d9a8d54364e29 Mon Sep 17 00:00:00 2001 From: ladyada Date: Fri, 17 May 2019 23:36:14 -0400 Subject: [PATCH] initial SPI bus device --- Adafruit_BusIO_Register.cpp | 43 +++++++++++------- Adafruit_BusIO_Register.h | 20 +++++---- Adafruit_SPIDevice.cpp | 56 ++++++++++++++++++++++++ Adafruit_SPIDevice.h | 26 +++++++++++ examples/spi_readwrite/i2c_readwrite.ino | 41 +++++++++++++++++ 5 files changed, 161 insertions(+), 25 deletions(-) create mode 100644 Adafruit_SPIDevice.cpp create mode 100644 Adafruit_SPIDevice.h create mode 100644 examples/spi_readwrite/i2c_readwrite.ino diff --git a/Adafruit_BusIO_Register.cpp b/Adafruit_BusIO_Register.cpp index 37bfe7c..0be1387 100644 --- a/Adafruit_BusIO_Register.cpp +++ b/Adafruit_BusIO_Register.cpp @@ -1,23 +1,34 @@ -#include +#include -Adafruit_I2CRegister::Adafruit_I2CRegister(Adafruit_I2CDevice *device, uint16_t reg_addr, uint8_t width, uint8_t bitorder, uint8_t address_width) { - _device = device; +Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice, uint16_t reg_addr, uint8_t width, uint8_t bitorder, uint8_t address_width) { + _i2cdevice = i2cdevice; + _spidevice = NULL; _addrwidth = address_width; _address = reg_addr; _bitorder = bitorder; _width = width; } +/* +Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_SPIDevice *spidevice, uint16_t reg_addr, uint8_t width, uint8_t bitorder, uint8_t address_width) { + _spidevice = spidevice; + _i2cdevice = NULL; + _addrwidth = address_width; + _address = reg_addr; + _bitorder = bitorder; + _width = width; +} +*/ -bool Adafruit_I2CRegister::write(uint8_t *buffer, uint8_t len) { +bool Adafruit_BusIO_Register::write(uint8_t *buffer, uint8_t len) { uint8_t addrbuffer[2] = {(uint8_t)(_address & 0xFF), (uint8_t)(_address>>8)}; - if (! _device->write(buffer, len, true, addrbuffer, _addrwidth)) { + if (_i2cdevice && ! _i2cdevice->write(buffer, len, true, addrbuffer, _addrwidth)) { return false; } return true; } -bool Adafruit_I2CRegister::write(uint32_t value, uint8_t numbytes) { +bool Adafruit_BusIO_Register::write(uint32_t value, uint8_t numbytes) { if (numbytes == 0) { numbytes = _width; } @@ -37,7 +48,7 @@ bool Adafruit_I2CRegister::write(uint32_t value, uint8_t numbytes) { } // This does not do any error checking! returns 0xFFFFFFFF on failure -uint32_t Adafruit_I2CRegister::read(void) { +uint32_t Adafruit_BusIO_Register::read(void) { if (! read(_buffer, _width)) { return -1; } @@ -57,15 +68,15 @@ uint32_t Adafruit_I2CRegister::read(void) { } -bool Adafruit_I2CRegister::read(uint8_t *buffer, uint8_t len) { +bool Adafruit_BusIO_Register::read(uint8_t *buffer, uint8_t len) { _buffer[0] = _address; - if (! _device->write_then_read(_buffer, 1, buffer, len)) { + if (_i2cdevice && ! _i2cdevice->write_then_read(_buffer, 1, buffer, len)) { return false; } return true; } -bool Adafruit_I2CRegister::read(uint16_t *value) { +bool Adafruit_BusIO_Register::read(uint16_t *value) { if (! read(_buffer, 2)) { return false; } @@ -82,7 +93,7 @@ bool Adafruit_I2CRegister::read(uint16_t *value) { return true; } -bool Adafruit_I2CRegister::read(uint8_t *value) { +bool Adafruit_BusIO_Register::read(uint8_t *value) { if (! read(_buffer, 1)) { return false; } @@ -91,30 +102,30 @@ bool Adafruit_I2CRegister::read(uint8_t *value) { return true; } -void Adafruit_I2CRegister::print(Stream *s) { +void Adafruit_BusIO_Register::print(Stream *s) { uint32_t val = read(); s->print("0x"); s->print(val, HEX); } -void Adafruit_I2CRegister::println(Stream *s) { +void Adafruit_BusIO_Register::println(Stream *s) { print(s); s->println(); } -Adafruit_I2CRegisterBits::Adafruit_I2CRegisterBits(Adafruit_I2CRegister *reg, uint8_t bits, uint8_t shift) { +Adafruit_BusIO_RegisterBits::Adafruit_BusIO_RegisterBits(Adafruit_BusIO_Register *reg, uint8_t bits, uint8_t shift) { _register = reg; _bits = bits; _shift = shift; } -uint32_t Adafruit_I2CRegisterBits::read(void) { +uint32_t Adafruit_BusIO_RegisterBits::read(void) { uint32_t val = _register->read(); val >>= _shift; return val & ((1 << (_bits+1)) - 1); } -void Adafruit_I2CRegisterBits::write(uint32_t data) { +void Adafruit_BusIO_RegisterBits::write(uint32_t data) { uint32_t val = _register->read(); // mask off the data before writing diff --git a/Adafruit_BusIO_Register.h b/Adafruit_BusIO_Register.h index 2ee3033..84e2d5b 100644 --- a/Adafruit_BusIO_Register.h +++ b/Adafruit_BusIO_Register.h @@ -1,14 +1,15 @@ #include +#include #include -#ifndef Adafruit_I2CRegister_h -#define Adafruit_I2CRegister_h +#ifndef Adafruit_BusIO_Register_h +#define Adafruit_BusIO_Register_h -class Adafruit_I2CRegister { +class Adafruit_BusIO_Register { public: - Adafruit_I2CRegister(Adafruit_I2CDevice *device, uint16_t reg_addr, + Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice, uint16_t reg_addr, uint8_t width=1, uint8_t bitorder=LSBFIRST, uint8_t address_width=1); @@ -26,21 +27,22 @@ class Adafruit_I2CRegister { void println(Stream *s=&Serial); private: - Adafruit_I2CDevice *_device; + Adafruit_I2CDevice *_i2cdevice; + Adafruit_SPIDevice *_spidevice; uint16_t _address; uint8_t _width, _addrwidth, _bitorder; uint8_t _buffer[4]; // we wont support anything larger than uint32 for non-buffered read }; -class Adafruit_I2CRegisterBits { +class Adafruit_BusIO_RegisterBits { public: - Adafruit_I2CRegisterBits(Adafruit_I2CRegister *reg, uint8_t bits, uint8_t shift); + Adafruit_BusIO_RegisterBits(Adafruit_BusIO_Register *reg, uint8_t bits, uint8_t shift); void write(uint32_t value); uint32_t read(void); private: - Adafruit_I2CRegister *_register; + Adafruit_BusIO_Register *_register; uint8_t _bits, _shift; }; -#endif //I2CRegister_h +#endif //BusIO_Register_h diff --git a/Adafruit_SPIDevice.cpp b/Adafruit_SPIDevice.cpp new file mode 100644 index 0000000..fc4819e --- /dev/null +++ b/Adafruit_SPIDevice.cpp @@ -0,0 +1,56 @@ +#include +#include + +//#define DEBUG_SERIAL Serial + +Adafruit_SPIDevice::Adafruit_SPIDevice(int8_t cspin, uint32_t freq, BitOrder dataOrder, uint8_t dataMode, SPIClass *theSPI) { + _cs = cspin; + _spi = theSPI; + _begun = false; + _spiSetting = new SPISettings(freq, dataOrder, dataMode); +} + +bool Adafruit_SPIDevice::begin(void) { + _spi->begin(); + pinMode(_cs, OUTPUT); + digitalWrite(_cs, HIGH); + _begun = true; + return true; +} + +bool Adafruit_SPIDevice::write(uint8_t *buffer, size_t len, uint8_t *prefix_buffer, size_t prefix_len) { + + + + return true; +} + +bool Adafruit_SPIDevice::read(uint8_t *buffer, size_t len, uint8_t sendvalue) { + memset(buffer, sendvalue, len); // clear out existing buffer + _spi->beginTransaction(*_spiSetting); + digitalWrite(_cs, LOW); + _spi->transfer(buffer, len); + digitalWrite(_cs, HIGH); + _spi->endTransaction(); + + return true; +} + + + +bool Adafruit_SPIDevice::write_then_read(uint8_t *write_buffer, size_t write_len, uint8_t *read_buffer, size_t read_len, uint8_t sendvalue) { + _spi->beginTransaction(*_spiSetting); + digitalWrite(_cs, LOW); + // do the writing + for (int i=0; itransfer(write_buffer[i]); + } + // do the reading + for (int i=0; itransfer(sendvalue); + } + digitalWrite(_cs, HIGH); + _spi->endTransaction(); + + return true; +} diff --git a/Adafruit_SPIDevice.h b/Adafruit_SPIDevice.h new file mode 100644 index 0000000..ac93686 --- /dev/null +++ b/Adafruit_SPIDevice.h @@ -0,0 +1,26 @@ +#include + +#ifndef Adafruit_SPIDevice_h +#define Adafruit_SPIDevice_h + + +class Adafruit_SPIDevice { + public: + Adafruit_SPIDevice(int8_t cspin, + uint32_t freq=1000000, + BitOrder dataOrder=MSBFIRST, + uint8_t dataMode=SPI_MODE0, + SPIClass *theSPI=&SPI); + bool begin(void); + bool read(uint8_t *buffer, size_t len, uint8_t sendvalue=0xFF); + bool write(uint8_t *buffer, size_t len, 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, uint8_t sendvalue=0xFF); + + private: + SPIClass *_spi; + SPISettings *_spiSetting; + int8_t _cs; + bool _begun; +}; + +#endif // Adafruit_SPIDevice_h diff --git a/examples/spi_readwrite/i2c_readwrite.ino b/examples/spi_readwrite/i2c_readwrite.ino new file mode 100644 index 0000000..909cf31 --- /dev/null +++ b/examples/spi_readwrite/i2c_readwrite.ino @@ -0,0 +1,41 @@ +#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 read and write 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); + + uint8_t buffer[32]; + // Try to read 32 bytes + i2c_dev.read(buffer, 32); + Serial.print("Read: "); + for (uint8_t i=0; i<32; i++) { + Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", "); + } + Serial.println(); + + // read a register by writing first, then reading + buffer[0] = 0x0C; // we'll reuse the same buffer + i2c_dev.write_then_read(buffer, 1, buffer, 2, false); + Serial.print("Write then Read: "); + for (uint8_t i=0; i<2; i++) { + Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", "); + } + Serial.println(); +} + +void loop() { + +}