initial SPI bus device

This commit is contained in:
ladyada 2019-05-17 23:36:14 -04:00
parent 8bc19f41cf
commit bb33ff7118
5 changed files with 161 additions and 25 deletions

View File

@ -1,23 +1,34 @@
#include <Adafruit_I2CRegister.h> #include <Adafruit_BusIO_Register.h>
Adafruit_I2CRegister::Adafruit_I2CRegister(Adafruit_I2CDevice *device, uint16_t reg_addr, uint8_t width, uint8_t bitorder, uint8_t address_width) { Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice, uint16_t reg_addr, uint8_t width, uint8_t bitorder, uint8_t address_width) {
_device = device; _i2cdevice = i2cdevice;
_spidevice = NULL;
_addrwidth = address_width; _addrwidth = address_width;
_address = reg_addr; _address = reg_addr;
_bitorder = bitorder; _bitorder = bitorder;
_width = width; _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)}; 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 false;
} }
return true; 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) { if (numbytes == 0) {
numbytes = _width; 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 // 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)) { if (! read(_buffer, _width)) {
return -1; 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; _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 false;
} }
return true; return true;
} }
bool Adafruit_I2CRegister::read(uint16_t *value) { bool Adafruit_BusIO_Register::read(uint16_t *value) {
if (! read(_buffer, 2)) { if (! read(_buffer, 2)) {
return false; return false;
} }
@ -82,7 +93,7 @@ bool Adafruit_I2CRegister::read(uint16_t *value) {
return true; return true;
} }
bool Adafruit_I2CRegister::read(uint8_t *value) { bool Adafruit_BusIO_Register::read(uint8_t *value) {
if (! read(_buffer, 1)) { if (! read(_buffer, 1)) {
return false; return false;
} }
@ -91,30 +102,30 @@ bool Adafruit_I2CRegister::read(uint8_t *value) {
return true; return true;
} }
void Adafruit_I2CRegister::print(Stream *s) { void Adafruit_BusIO_Register::print(Stream *s) {
uint32_t val = read(); uint32_t val = read();
s->print("0x"); s->print(val, HEX); s->print("0x"); s->print(val, HEX);
} }
void Adafruit_I2CRegister::println(Stream *s) { void Adafruit_BusIO_Register::println(Stream *s) {
print(s); print(s);
s->println(); 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; _register = reg;
_bits = bits; _bits = bits;
_shift = shift; _shift = shift;
} }
uint32_t Adafruit_I2CRegisterBits::read(void) { uint32_t Adafruit_BusIO_RegisterBits::read(void) {
uint32_t val = _register->read(); uint32_t val = _register->read();
val >>= _shift; val >>= _shift;
return val & ((1 << (_bits+1)) - 1); 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(); uint32_t val = _register->read();
// mask off the data before writing // mask off the data before writing

View File

@ -1,14 +1,15 @@
#include <Adafruit_I2CDevice.h> #include <Adafruit_I2CDevice.h>
#include <Adafruit_SPIDevice.h>
#include <Arduino.h> #include <Arduino.h>
#ifndef Adafruit_I2CRegister_h #ifndef Adafruit_BusIO_Register_h
#define Adafruit_I2CRegister_h #define Adafruit_BusIO_Register_h
class Adafruit_I2CRegister { class Adafruit_BusIO_Register {
public: 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 width=1, uint8_t bitorder=LSBFIRST,
uint8_t address_width=1); uint8_t address_width=1);
@ -26,21 +27,22 @@ class Adafruit_I2CRegister {
void println(Stream *s=&Serial); void println(Stream *s=&Serial);
private: private:
Adafruit_I2CDevice *_device; Adafruit_I2CDevice *_i2cdevice;
Adafruit_SPIDevice *_spidevice;
uint16_t _address; uint16_t _address;
uint8_t _width, _addrwidth, _bitorder; uint8_t _width, _addrwidth, _bitorder;
uint8_t _buffer[4]; // we wont support anything larger than uint32 for non-buffered read uint8_t _buffer[4]; // we wont support anything larger than uint32 for non-buffered read
}; };
class Adafruit_I2CRegisterBits { class Adafruit_BusIO_RegisterBits {
public: 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); void write(uint32_t value);
uint32_t read(void); uint32_t read(void);
private: private:
Adafruit_I2CRegister *_register; Adafruit_BusIO_Register *_register;
uint8_t _bits, _shift; uint8_t _bits, _shift;
}; };
#endif //I2CRegister_h #endif //BusIO_Register_h

56
Adafruit_SPIDevice.cpp Normal file
View File

@ -0,0 +1,56 @@
#include <Adafruit_SPIDevice.h>
#include <Arduino.h>
//#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; i<write_len; i++) {
_spi->transfer(write_buffer[i]);
}
// do the reading
for (int i=0; i<read_len; i++) {
read_buffer[i] = _spi->transfer(sendvalue);
}
digitalWrite(_cs, HIGH);
_spi->endTransaction();
return true;
}

26
Adafruit_SPIDevice.h Normal file
View File

@ -0,0 +1,26 @@
#include <SPI.h>
#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

View File

@ -0,0 +1,41 @@
#include <Adafruit_I2CDevice.h>
#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() {
}