diff --git a/Adafruit_GenericDevice.cpp b/Adafruit_GenericDevice.cpp index 2fab4f0..7fe5a10 100644 --- a/Adafruit_GenericDevice.cpp +++ b/Adafruit_GenericDevice.cpp @@ -6,16 +6,19 @@ #include "Adafruit_GenericDevice.h" -/*! @brief Create a Generic device with the provided read/write functions - @param read_func Function pointer for reading raw data - @param write_func Function pointer for writing raw data - @param readreg_func Function pointer for reading registers (optional) - @param writereg_func Function pointer for writing registers (optional) */ +/*! + * @brief Create a Generic device with the provided read/write functions + * @param obj Pointer to object instance + * @param read_func Function pointer for reading raw data + * @param write_func Function pointer for writing raw data + * @param readreg_func Function pointer for reading registers (optional) + * @param writereg_func Function pointer for writing registers (optional) */ Adafruit_GenericDevice::Adafruit_GenericDevice( - busio_genericdevice_read_t read_func, + void *obj, busio_genericdevice_read_t read_func, busio_genericdevice_write_t write_func, busio_genericdevice_readreg_t readreg_func, busio_genericdevice_writereg_t writereg_func) { + _obj = obj; _read_func = read_func; _write_func = write_func; _readreg_func = readreg_func; @@ -23,56 +26,57 @@ Adafruit_GenericDevice::Adafruit_GenericDevice( _begun = false; } -/*! @brief Initializes the device - @return true if initialization was successful, otherwise false */ +/*! @brief Simple begin function (doesn't do much at this time) + @return true always +*/ bool Adafruit_GenericDevice::begin(void) { _begun = true; return true; } /*! @brief Write a buffer of data - @param buffer Pointer to buffer of data to write - @param len Number of bytes to write - @return true if write was successful, otherwise false */ + @param buffer Pointer to buffer of data to write + @param len Number of bytes to write + @return true if write was successful, otherwise false */ bool Adafruit_GenericDevice::write(const uint8_t *buffer, size_t len) { if (!_begun) return false; - return _write_func(buffer, len); + return _write_func(_obj, buffer, len); } /*! @brief Read data into a buffer - @param buffer Pointer to buffer to read data into - @param len Number of bytes to read - @return true if read was successful, otherwise false */ + @param buffer Pointer to buffer to read data into + @param len Number of bytes to read + @return true if read was successful, otherwise false */ bool Adafruit_GenericDevice::read(uint8_t *buffer, size_t len) { if (!_begun) return false; - return _read_func(buffer, len); + return _read_func(_obj, buffer, len); } /*! @brief Read from a register location - @param addr_buf Buffer containing register address - @param addrsiz Size of register address in bytes - @param buf Buffer to store read data - @param bufsiz Size of data to read in bytes - @return true if read was successful, otherwise false */ + @param addr_buf Buffer containing register address + @param addrsiz Size of register address in bytes + @param buf Buffer to store read data + @param bufsiz Size of data to read in bytes + @return true if read was successful, otherwise false */ 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); + return _readreg_func(_obj, addr_buf, addrsiz, buf, bufsiz); } /*! @brief Write to a register location - @param addr_buf Buffer containing register address - @param addrsiz Size of register address in bytes - @param buf Buffer containing data to write - @param bufsiz Size of data to write in bytes - @return true if write was successful, otherwise false */ + @param addr_buf Buffer containing register address + @param addrsiz Size of register address in bytes + @param buf Buffer containing data to write + @param bufsiz Size of data to write in bytes + @return true if write was successful, otherwise false */ 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); + return _writereg_func(_obj, addr_buf, addrsiz, buf, bufsiz); } diff --git a/Adafruit_GenericDevice.h b/Adafruit_GenericDevice.h index 7dd032f..14bb8ae 100644 --- a/Adafruit_GenericDevice.h +++ b/Adafruit_GenericDevice.h @@ -3,15 +3,17 @@ #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, +typedef bool (*busio_genericdevice_read_t)(void *obj, uint8_t *buffer, + size_t len); +typedef bool (*busio_genericdevice_write_t)(void *obj, const uint8_t *buffer, + size_t len); +typedef bool (*busio_genericdevice_readreg_t)(void *obj, uint8_t *addr_buf, + uint8_t addrsiz, uint8_t *data, + uint16_t datalen); +typedef bool (*busio_genericdevice_writereg_t)(void *obj, uint8_t *addr_buf, uint8_t addrsiz, - const uint8_t *buf, - uint16_t bufsiz); + const uint8_t *data, + uint16_t datalen); /*! * @brief Class for communicating with a device via generic read/write functions @@ -19,7 +21,7 @@ typedef bool (*busio_genericdevice_writereg_t)(uint8_t *addr_buf, class Adafruit_GenericDevice { public: Adafruit_GenericDevice( - busio_genericdevice_read_t read_func, + void *obj, 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); @@ -45,6 +47,9 @@ class Adafruit_GenericDevice { bool _begun; ///< whether we have initialized yet (in case the function needs ///< to do something) + +private: + void *_obj; ///< Pointer to object instance }; #endif // ADAFRUIT_GENERICDEVICE_H diff --git a/examples/genericdevice_uartregtest/genericdevice_uartregtest.ino b/examples/genericdevice_uartregtest/genericdevice_uartregtest.ino index d9f3fab..59af308 100644 --- a/examples/genericdevice_uartregtest/genericdevice_uartregtest.ino +++ b/examples/genericdevice_uartregtest/genericdevice_uartregtest.ino @@ -1,17 +1,17 @@ /* - Advanced example of using bstracted transport for reading and writing + Advanced example of using bstracted transport for reading and writing register data from a UART-based device such as a TMC2209 - Written with help by Claude! https://claude.ai/chat/335f50b1-3dd8-435e-9139-57ec7ca26a3c - (at this time chats are not shareable :( + Written with help by Claude! + https://claude.ai/chat/335f50b1-3dd8-435e-9139-57ec7ca26a3c (at this time + chats are not shareable :( */ - #include "Adafruit_BusIO_Register.h" #include "Adafruit_GenericDevice.h" // Debugging macros -//#define DEBUG_SERIAL Serial +#define DEBUG_SERIAL Serial #ifdef DEBUG_SERIAL #define DEBUG_PRINT(x) DEBUG_SERIAL.print(x) @@ -29,36 +29,17 @@ #define DEBUG_PRINT_HEX(x) #endif -// Add IOIN register definition #define TMC2209_IOIN 0x06 class TMC2209_UART { private: - static TMC2209_UART *_instance; Stream *_uart_stream; uint8_t _addr; - static bool uart_read_impl(uint8_t *buffer, size_t len) { - return _instance->uart_read_fn(buffer, len); - } - - static bool uart_write_impl(const uint8_t *buffer, size_t len) { - return _instance->uart_write_fn(buffer, len); - } - - static bool uart_readreg_impl(uint8_t *addr_buf, uint8_t addrsiz, - uint8_t *data, uint16_t datalen) { - return _instance->uart_readreg_fn(addr_buf, addrsiz, data, datalen); - } - - static bool uart_writereg_impl(uint8_t *addr_buf, uint8_t addrsiz, - const uint8_t *data, uint16_t datalen) { - return _instance->uart_writereg_fn(addr_buf, addrsiz, data, datalen); - } - - bool uart_read_fn(uint8_t *buffer, size_t len) { + static bool uart_read(void *thiz, uint8_t *buffer, size_t len) { + TMC2209_UART *dev = (TMC2209_UART *)thiz; uint16_t timeout = 100; - while (_uart_stream->available() < len && timeout--) { + while (dev->_uart_stream->available() < len && timeout--) { delay(1); } if (timeout == 0) { @@ -68,7 +49,7 @@ private: DEBUG_PRINT("Reading: "); for (size_t i = 0; i < len; i++) { - buffer[i] = _uart_stream->read(); + buffer[i] = dev->_uart_stream->read(); DEBUG_PRINT_HEX(buffer[i]); } DEBUG_PRINTLN(""); @@ -76,31 +57,33 @@ private: return true; } - bool uart_write_fn(const uint8_t *buffer, size_t len) { + static bool uart_write(void *thiz, const uint8_t *buffer, size_t len) { + TMC2209_UART *dev = (TMC2209_UART *)thiz; DEBUG_PRINT("Writing: "); for (size_t i = 0; i < len; i++) { DEBUG_PRINT_HEX(buffer[i]); } DEBUG_PRINTLN(""); - _uart_stream->write(buffer, len); + dev->_uart_stream->write(buffer, len); return true; } - bool uart_readreg_fn(uint8_t *addr_buf, uint8_t addrsiz, uint8_t *data, - uint16_t datalen) { - while (_uart_stream->available()) - _uart_stream->read(); + static bool uart_readreg(void *thiz, uint8_t *addr_buf, uint8_t addrsiz, + uint8_t *data, uint16_t datalen) { + TMC2209_UART *dev = (TMC2209_UART *)thiz; + while (dev->_uart_stream->available()) + dev->_uart_stream->read(); - uint8_t packet[4] = {0x05, uint8_t(_addr << 1), addr_buf[0], 0x00}; + uint8_t packet[4] = {0x05, uint8_t(dev->_addr << 1), addr_buf[0], 0x00}; packet[3] = calcCRC(packet, 3); - if (!uart_write_impl(packet, 4)) + if (!uart_write(thiz, packet, 4)) return false; // Read back echo uint8_t echo[4]; - if (!uart_read_impl(echo, 4)) + if (!uart_read(thiz, echo, 4)) return false; // Verify echo @@ -112,7 +95,7 @@ private: } uint8_t response[8]; // sync + 0xFF + reg + 4 data bytes + CRC - if (!uart_read_impl(response, 8)) + if (!uart_read(thiz, response, 8)) return false; // Verify response @@ -121,38 +104,34 @@ private: return false; } - // Verify 0xFF address byte if (response[1] != 0xFF) { DEBUG_PRINTLN("Invalid reply address"); return false; } - // Verify register address matches our request if (response[2] != addr_buf[0]) { DEBUG_PRINTLN("Register mismatch"); return false; } - // Verify CRC - uint8_t crc = calcCRC(response, 7); // Calculate CRC of all but last byte + uint8_t crc = calcCRC(response, 7); if (crc != response[7]) { DEBUG_PRINTLN("CRC mismatch"); return false; } - // Copy the data bytes memcpy(data, &response[3], 4); - return true; } - bool uart_writereg_fn(uint8_t *addr_buf, uint8_t addrsiz, const uint8_t *data, - uint16_t datalen) { - while (_uart_stream->available()) - _uart_stream->read(); + static bool uart_writereg(void *thiz, uint8_t *addr_buf, uint8_t addrsiz, + const uint8_t *data, uint16_t datalen) { + TMC2209_UART *dev = (TMC2209_UART *)thiz; + while (dev->_uart_stream->available()) + dev->_uart_stream->read(); uint8_t packet[8] = {0x05, - uint8_t(_addr << 1), + uint8_t(dev->_addr << 1), uint8_t(addr_buf[0] | 0x80), data[0], data[1], @@ -161,15 +140,13 @@ private: 0x00}; packet[7] = calcCRC(packet, 7); - if (!uart_write_impl(packet, 8)) + if (!uart_write(thiz, packet, 8)) return false; - // Read and verify echo uint8_t echo[8]; - if (!uart_read_impl(echo, 8)) + if (!uart_read(thiz, echo, 8)) return false; - // Verify echo matches what we sent for (uint8_t i = 0; i < 8; i++) { if (echo[i] != packet[i]) { DEBUG_PRINTLN("Write echo mismatch"); @@ -198,18 +175,14 @@ private: public: TMC2209_UART(Stream *serial, uint8_t addr) - : _uart_stream(serial), _addr(addr) { - _instance = this; - } + : _uart_stream(serial), _addr(addr) {} Adafruit_GenericDevice *createDevice() { - return new Adafruit_GenericDevice(uart_read_impl, uart_write_impl, - uart_readreg_impl, uart_writereg_impl); + return new Adafruit_GenericDevice(this, uart_read, uart_write, uart_readreg, + uart_writereg); } }; -TMC2209_UART *TMC2209_UART::_instance = nullptr; - void setup() { Serial.begin(115200); while (!Serial) @@ -232,7 +205,7 @@ void setup() { Serial.print("IOIN = 0x"); Serial.println(ioin_reg.read(), HEX); - // Create RegisterBits for VERSION field (bits 28:24) + // Create RegisterBits for VERSION field (bits 31:24) Adafruit_BusIO_RegisterBits version_bits( &ioin_reg, 8, 24); // 8 bits wide, starting at bit 24 @@ -243,4 +216,4 @@ void setup() { Serial.println(version, HEX); } -void loop() { delay(1000); } +void loop() { delay(1000); } \ No newline at end of file diff --git a/examples/genericdevice_uarttest/genericdevice_uarttest.ino b/examples/genericdevice_uarttest/genericdevice_uarttest.ino index bc4175c..6a11dbf 100644 --- a/examples/genericdevice_uarttest/genericdevice_uarttest.ino +++ b/examples/genericdevice_uarttest/genericdevice_uarttest.ino @@ -1,39 +1,57 @@ -/* - Abstracted transport for reading and writing data from a UART-based +/* + Abstracted transport for reading and writing data from a UART-based device such as a TMC2209 - Written with help by Claude! https://claude.ai/chat/335f50b1-3dd8-435e-9139-57ec7ca26a3c - (at this time chats are not shareable :( + Written with help by Claude! + https://claude.ai/chat/335f50b1-3dd8-435e-9139-57ec7ca26a3c (at this time + chats are not shareable :( */ #include "Adafruit_GenericDevice.h" -Stream *uart_stream; // Will hold the pointer to our Stream object - -Adafruit_GenericDevice *create_uart_device(Stream *serial_port) { - uart_stream = serial_port; // Store the Stream pointer - - auto uart_write = [](const uint8_t *buffer, size_t len) -> bool { - uart_stream->write(buffer, len); +/** + * Basic UART device class that demonstrates using GenericDevice with a Stream + * interface. This example shows how to wrap a Stream (like HardwareSerial or + * SoftwareSerial) with read/write callbacks that can be used by BusIO's + * register functions. + */ +class UARTDevice { +public: + UARTDevice(Stream *serial) : _serial(serial) {} + + // Static callback for writing data to UART + // Called by GenericDevice when data needs to be sent + static bool uart_write(void *thiz, const uint8_t *buffer, size_t len) { + UARTDevice *dev = (UARTDevice *)thiz; + dev->_serial->write(buffer, len); return true; - }; + } - auto uart_read = [](uint8_t *buffer, size_t len) -> bool { + // Static callback for reading data from UART + // Includes timeout and will return false if not enough data available + static bool uart_read(void *thiz, uint8_t *buffer, size_t len) { + UARTDevice *dev = (UARTDevice *)thiz; uint16_t timeout = 100; - while (uart_stream->available() < len && timeout--) { + while (dev->_serial->available() < len && timeout--) { delay(1); } if (timeout == 0) { return false; } for (size_t i = 0; i < len; i++) { - buffer[i] = uart_stream->read(); + buffer[i] = dev->_serial->read(); } return true; - }; + } - return new Adafruit_GenericDevice(uart_read, uart_write); -} + // Create a GenericDevice instance using our callbacks + Adafruit_GenericDevice *createDevice() { + return new Adafruit_GenericDevice(this, uart_read, uart_write); + } + +private: + Stream *_serial; // Underlying Stream instance (HardwareSerial, etc) +}; void setup() { Serial.begin(115200); @@ -43,11 +61,15 @@ void setup() { Serial.println("Generic Device test!"); + // Initialize UART for device communication Serial1.begin(115200); - Adafruit_GenericDevice *device = create_uart_device(&Serial1); + // Create UART wrapper and BusIO device + UARTDevice uart(&Serial1); + Adafruit_GenericDevice *device = uart.createDevice(); device->begin(); + // Test write/read cycle uint8_t write_buf[4] = {0x5, 0x0, 0x0, 0x48}; uint8_t read_buf[8]; @@ -63,6 +85,7 @@ void setup() { return; } + // Print response bytes Serial.print("Got response: "); for (int i = 0; i < 8; i++) { Serial.print("0x"); @@ -72,4 +95,4 @@ void setup() { Serial.println(); } -void loop() { delay(1000); } +void loop() { delay(1000); } \ No newline at end of file diff --git a/examples/i2c_address_detect/i2c_address_detect.ino b/examples/i2c_address_detect/i2c_address_detect.ino index b150525..f2e6ba7 100644 --- a/examples/i2c_address_detect/i2c_address_detect.ino +++ b/examples/i2c_address_detect/i2c_address_detect.ino @@ -3,19 +3,20 @@ Adafruit_I2CDevice i2c_dev = Adafruit_I2CDevice(0x10); void setup() { - while (!Serial) { delay(10); } + while (!Serial) { + delay(10); + } Serial.begin(115200); Serial.println("I2C address detection test"); if (!i2c_dev.begin()) { Serial.print("Did not find device at 0x"); Serial.println(i2c_dev.address(), HEX); - while (1); + while (1) + ; } Serial.print("Device found on address 0x"); Serial.println(i2c_dev.address(), HEX); } -void loop() { - -} +void loop() {} diff --git a/examples/i2c_readwrite/i2c_readwrite.ino b/examples/i2c_readwrite/i2c_readwrite.ino index 909cf31..4ac2626 100644 --- a/examples/i2c_readwrite/i2c_readwrite.ino +++ b/examples/i2c_readwrite/i2c_readwrite.ino @@ -3,16 +3,18 @@ #define I2C_ADDRESS 0x60 Adafruit_I2CDevice i2c_dev = Adafruit_I2CDevice(I2C_ADDRESS); - void setup() { - while (!Serial) { delay(10); } + 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); + while (1) + ; } Serial.print("Device found on address 0x"); Serial.println(i2c_dev.address(), HEX); @@ -21,21 +23,23 @@ void setup() { // 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(", "); + 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 + 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(", "); + for (uint8_t i = 0; i < 2; i++) { + Serial.print("0x"); + Serial.print(buffer[i], HEX); + Serial.print(", "); } Serial.println(); } -void loop() { - -} +void loop() {} diff --git a/examples/i2c_registers/i2c_registers.ino b/examples/i2c_registers/i2c_registers.ino index 41a3043..2d44c83 100644 --- a/examples/i2c_registers/i2c_registers.ino +++ b/examples/i2c_registers/i2c_registers.ino @@ -1,38 +1,43 @@ -#include #include +#include #define I2C_ADDRESS 0x60 Adafruit_I2CDevice i2c_dev = Adafruit_I2CDevice(I2C_ADDRESS); - void setup() { - while (!Serial) { delay(10); } + 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); + while (1) + ; } Serial.print("Device found on address 0x"); Serial.println(i2c_dev.address(), HEX); - Adafruit_BusIO_Register id_reg = Adafruit_BusIO_Register(&i2c_dev, 0x0C, 2, LSBFIRST); + Adafruit_BusIO_Register id_reg = + Adafruit_BusIO_Register(&i2c_dev, 0x0C, 2, LSBFIRST); uint16_t id; id_reg.read(&id); - Serial.print("ID register = 0x"); Serial.println(id, HEX); + Serial.print("ID register = 0x"); + Serial.println(id, HEX); - Adafruit_BusIO_Register thresh_reg = Adafruit_BusIO_Register(&i2c_dev, 0x01, 2, LSBFIRST); + Adafruit_BusIO_Register thresh_reg = + Adafruit_BusIO_Register(&i2c_dev, 0x01, 2, LSBFIRST); uint16_t thresh; thresh_reg.read(&thresh); - Serial.print("Initial threshold register = 0x"); Serial.println(thresh, HEX); + Serial.print("Initial threshold register = 0x"); + Serial.println(thresh, HEX); thresh_reg.write(~thresh); - Serial.print("Post threshold register = 0x"); Serial.println(thresh_reg.read(), HEX); + Serial.print("Post threshold register = 0x"); + Serial.println(thresh_reg.read(), HEX); } -void loop() { - -} \ No newline at end of file +void loop() {} \ No newline at end of file diff --git a/examples/i2corspi_register/i2corspi_register.ino b/examples/i2corspi_register/i2corspi_register.ino index 992a2e0..be04606 100644 --- a/examples/i2corspi_register/i2corspi_register.ino +++ b/examples/i2corspi_register/i2corspi_register.ino @@ -9,7 +9,9 @@ Adafruit_SPIDevice *spi_dev = NULL; // new Adafruit_SPIDevice(SPIDEVICE_CS); Adafruit_I2CDevice *i2c_dev = new Adafruit_I2CDevice(I2C_ADDRESS); void setup() { - while (!Serial) { delay(10); } + while (!Serial) { + delay(10); + } Serial.begin(115200); Serial.println("I2C or SPI device register test"); @@ -27,12 +29,12 @@ void setup() { } } - Adafruit_BusIO_Register id_reg = Adafruit_BusIO_Register(i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, 0x0F); - uint8_t id=0; + Adafruit_BusIO_Register id_reg = + Adafruit_BusIO_Register(i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, 0x0F); + uint8_t id = 0; id_reg.read(&id); - Serial.print("ID register = 0x"); Serial.println(id, HEX); + Serial.print("ID register = 0x"); + Serial.println(id, HEX); } -void loop() { - -} +void loop() {} diff --git a/examples/spi_modetest/spi_modetest.ino b/examples/spi_modetest/spi_modetest.ino index 10168c5..ebf14f9 100644 --- a/examples/spi_modetest/spi_modetest.ino +++ b/examples/spi_modetest/spi_modetest.ino @@ -1,28 +1,34 @@ #include #define SPIDEVICE_CS 10 -Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS, 100000, SPI_BITORDER_MSBFIRST, SPI_MODE1); -//Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS, 13, 12, 11, 100000, SPI_BITORDER_MSBFIRST, SPI_MODE1); - +Adafruit_SPIDevice spi_dev = + Adafruit_SPIDevice(SPIDEVICE_CS, 100000, SPI_BITORDER_MSBFIRST, SPI_MODE1); +// Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS, 13, 12, 11, +// 100000, SPI_BITORDER_MSBFIRST, SPI_MODE1); void setup() { - while (!Serial) { delay(10); } + while (!Serial) { + delay(10); + } Serial.begin(115200); Serial.println("SPI device mode test"); if (!spi_dev.begin()) { Serial.println("Could not initialize SPI device"); - while (1); + while (1) + ; } } void loop() { Serial.println("\n\nTransfer test"); - for (uint16_t x=0; x<=0xFF; x++) { - uint8_t i = x; - Serial.print("0x"); Serial.print(i, HEX); + for (uint16_t x = 0; x <= 0xFF; x++) { + uint8_t i = x; + Serial.print("0x"); + Serial.print(i, HEX); spi_dev.read(&i, 1, i); - Serial.print("/"); Serial.print(i, HEX); + Serial.print("/"); + Serial.print(i, HEX); Serial.print(", "); delay(25); } diff --git a/examples/spi_readwrite/spi_readwrite.ino b/examples/spi_readwrite/spi_readwrite.ino index 6f2c063..4b9ecf1 100644 --- a/examples/spi_readwrite/spi_readwrite.ino +++ b/examples/spi_readwrite/spi_readwrite.ino @@ -3,15 +3,17 @@ #define SPIDEVICE_CS 10 Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS); - void setup() { - while (!Serial) { delay(10); } + while (!Serial) { + delay(10); + } Serial.begin(115200); Serial.println("SPI device read and write test"); if (!spi_dev.begin()) { Serial.println("Could not initialize SPI device"); - while (1); + while (1) + ; } uint8_t buffer[32]; @@ -19,21 +21,23 @@ void setup() { // Try to read 32 bytes spi_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(", "); + 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] = 0x8F; // we'll reuse the same buffer + buffer[0] = 0x8F; // we'll reuse the same buffer spi_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(", "); + for (uint8_t i = 0; i < 2; i++) { + Serial.print("0x"); + Serial.print(buffer[i], HEX); + Serial.print(", "); } Serial.println(); } -void loop() { - -} +void loop() {} diff --git a/examples/spi_register_bits/spi_register_bits.ino b/examples/spi_register_bits/spi_register_bits.ino index e70a17b..d11b440 100644 --- a/examples/spi_register_bits/spi_register_bits.ino +++ b/examples/spi_register_bits/spi_register_bits.ino @@ -1,163 +1,233 @@ -/*************************************************** +/*************************************************** - This is an example for how to use Adafruit_BusIO_RegisterBits from Adafruit_BusIO library. + This is an example for how to use Adafruit_BusIO_RegisterBits from + Adafruit_BusIO library. Designed specifically to work with the Adafruit RTD Sensor ----> https://www.adafruit.com/products/3328 uisng a MAX31865 RTD-to-Digital Converter ----> https://datasheets.maximintegrated.com/en/ds/MAX31865.pdf - This sensor uses SPI to communicate, 4 pins are required to + This sensor uses SPI to communicate, 4 pins are required to interface. A fifth pin helps to detect when a new conversion is ready. - Adafruit invests time and resources providing this open source code, - please support Adafruit and open-source hardware by purchasing + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing products from Adafruit! - Example written (2020/3) by Andreas Hardtung/AnHard. + Example written (2020/3) by Andreas Hardtung/AnHard. BSD license, all text above must be included in any redistribution ****************************************************/ #include #include -#define MAX31865_SPI_SPEED (5000000) +#define MAX31865_SPI_SPEED (5000000) #define MAX31865_SPI_BITORDER (SPI_BITORDER_MSBFIRST) -#define MAX31865_SPI_MODE (SPI_MODE1) - -#define MAX31865_SPI_CS (10) -#define MAX31865_READY_PIN (2) - - -Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice( MAX31865_SPI_CS, MAX31865_SPI_SPEED, MAX31865_SPI_BITORDER, MAX31865_SPI_MODE, &SPI); // Hardware SPI -// Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice( MAX31865_SPI_CS, 13, 12, 11, MAX31865_SPI_SPEED, MAX31865_SPI_BITORDER, MAX31865_SPI_MODE); // Software SPI - -// MAX31865 chip related ********************************************************************************************* -Adafruit_BusIO_Register config_reg = Adafruit_BusIO_Register(&spi_dev, 0x00, ADDRBIT8_HIGH_TOWRITE, 1, MSBFIRST); -Adafruit_BusIO_RegisterBits bias_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 7); -Adafruit_BusIO_RegisterBits auto_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 6); -Adafruit_BusIO_RegisterBits oneS_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 5); -Adafruit_BusIO_RegisterBits wire_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 4); -Adafruit_BusIO_RegisterBits faultT_bits = Adafruit_BusIO_RegisterBits(&config_reg, 2, 2); -Adafruit_BusIO_RegisterBits faultR_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 1); -Adafruit_BusIO_RegisterBits fi50hz_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 0); - -Adafruit_BusIO_Register rRatio_reg = Adafruit_BusIO_Register(&spi_dev, 0x01, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST); -Adafruit_BusIO_RegisterBits rRatio_bits = Adafruit_BusIO_RegisterBits(&rRatio_reg, 15, 1); -Adafruit_BusIO_RegisterBits fault_bit = Adafruit_BusIO_RegisterBits(&rRatio_reg, 1, 0); - -Adafruit_BusIO_Register maxRratio_reg = Adafruit_BusIO_Register(&spi_dev, 0x03, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST); -Adafruit_BusIO_RegisterBits maxRratio_bits = Adafruit_BusIO_RegisterBits(&maxRratio_reg, 15, 1); - -Adafruit_BusIO_Register minRratio_reg = Adafruit_BusIO_Register(&spi_dev, 0x05, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST); -Adafruit_BusIO_RegisterBits minRratio_bits = Adafruit_BusIO_RegisterBits(&minRratio_reg, 15, 1); - -Adafruit_BusIO_Register fault_reg = Adafruit_BusIO_Register(&spi_dev, 0x07, ADDRBIT8_HIGH_TOWRITE, 1, MSBFIRST); -Adafruit_BusIO_RegisterBits range_high_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 7); -Adafruit_BusIO_RegisterBits range_low_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 6); -Adafruit_BusIO_RegisterBits refin_high_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 5); -Adafruit_BusIO_RegisterBits refin_low_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 4); -Adafruit_BusIO_RegisterBits rtdin_low_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 3); -Adafruit_BusIO_RegisterBits voltage_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 2); +#define MAX31865_SPI_MODE (SPI_MODE1) + +#define MAX31865_SPI_CS (10) +#define MAX31865_READY_PIN (2) + +Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice( + MAX31865_SPI_CS, MAX31865_SPI_SPEED, MAX31865_SPI_BITORDER, + MAX31865_SPI_MODE, &SPI); // Hardware SPI +// Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice( MAX31865_SPI_CS, 13, 12, 11, +// MAX31865_SPI_SPEED, MAX31865_SPI_BITORDER, MAX31865_SPI_MODE); // Software +// SPI + +// MAX31865 chip related +// ********************************************************************************************* +Adafruit_BusIO_Register config_reg = + Adafruit_BusIO_Register(&spi_dev, 0x00, ADDRBIT8_HIGH_TOWRITE, 1, MSBFIRST); +Adafruit_BusIO_RegisterBits bias_bit = + Adafruit_BusIO_RegisterBits(&config_reg, 1, 7); +Adafruit_BusIO_RegisterBits auto_bit = + Adafruit_BusIO_RegisterBits(&config_reg, 1, 6); +Adafruit_BusIO_RegisterBits oneS_bit = + Adafruit_BusIO_RegisterBits(&config_reg, 1, 5); +Adafruit_BusIO_RegisterBits wire_bit = + Adafruit_BusIO_RegisterBits(&config_reg, 1, 4); +Adafruit_BusIO_RegisterBits faultT_bits = + Adafruit_BusIO_RegisterBits(&config_reg, 2, 2); +Adafruit_BusIO_RegisterBits faultR_bit = + Adafruit_BusIO_RegisterBits(&config_reg, 1, 1); +Adafruit_BusIO_RegisterBits fi50hz_bit = + Adafruit_BusIO_RegisterBits(&config_reg, 1, 0); + +Adafruit_BusIO_Register rRatio_reg = + Adafruit_BusIO_Register(&spi_dev, 0x01, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST); +Adafruit_BusIO_RegisterBits rRatio_bits = + Adafruit_BusIO_RegisterBits(&rRatio_reg, 15, 1); +Adafruit_BusIO_RegisterBits fault_bit = + Adafruit_BusIO_RegisterBits(&rRatio_reg, 1, 0); + +Adafruit_BusIO_Register maxRratio_reg = + Adafruit_BusIO_Register(&spi_dev, 0x03, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST); +Adafruit_BusIO_RegisterBits maxRratio_bits = + Adafruit_BusIO_RegisterBits(&maxRratio_reg, 15, 1); + +Adafruit_BusIO_Register minRratio_reg = + Adafruit_BusIO_Register(&spi_dev, 0x05, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST); +Adafruit_BusIO_RegisterBits minRratio_bits = + Adafruit_BusIO_RegisterBits(&minRratio_reg, 15, 1); + +Adafruit_BusIO_Register fault_reg = + Adafruit_BusIO_Register(&spi_dev, 0x07, ADDRBIT8_HIGH_TOWRITE, 1, MSBFIRST); +Adafruit_BusIO_RegisterBits range_high_fault_bit = + Adafruit_BusIO_RegisterBits(&fault_reg, 1, 7); +Adafruit_BusIO_RegisterBits range_low_fault_bit = + Adafruit_BusIO_RegisterBits(&fault_reg, 1, 6); +Adafruit_BusIO_RegisterBits refin_high_fault_bit = + Adafruit_BusIO_RegisterBits(&fault_reg, 1, 5); +Adafruit_BusIO_RegisterBits refin_low_fault_bit = + Adafruit_BusIO_RegisterBits(&fault_reg, 1, 4); +Adafruit_BusIO_RegisterBits rtdin_low_fault_bit = + Adafruit_BusIO_RegisterBits(&fault_reg, 1, 3); +Adafruit_BusIO_RegisterBits voltage_fault_bit = + Adafruit_BusIO_RegisterBits(&fault_reg, 1, 2); // Print the details of the configuration register. -void printConfig( void ) { - Serial.print("BIAS: "); if (bias_bit.read() ) Serial.print("ON"); else Serial.print("OFF"); - Serial.print(", AUTO: "); if (auto_bit.read() ) Serial.print("ON"); else Serial.print("OFF"); - Serial.print(", ONES: "); if (oneS_bit.read() ) Serial.print("ON"); else Serial.print("OFF"); - Serial.print(", WIRE: "); if (wire_bit.read() ) Serial.print("3"); else Serial.print("2/4"); - Serial.print(", FAULTCLEAR: "); if (faultR_bit.read() ) Serial.print("ON"); else Serial.print("OFF"); - Serial.print(", "); if (fi50hz_bit.read() ) Serial.print("50HZ"); else Serial.print("60HZ"); +void printConfig(void) { + Serial.print("BIAS: "); + if (bias_bit.read()) + Serial.print("ON"); + else + Serial.print("OFF"); + Serial.print(", AUTO: "); + if (auto_bit.read()) + Serial.print("ON"); + else + Serial.print("OFF"); + Serial.print(", ONES: "); + if (oneS_bit.read()) + Serial.print("ON"); + else + Serial.print("OFF"); + Serial.print(", WIRE: "); + if (wire_bit.read()) + Serial.print("3"); + else + Serial.print("2/4"); + Serial.print(", FAULTCLEAR: "); + if (faultR_bit.read()) + Serial.print("ON"); + else + Serial.print("OFF"); + Serial.print(", "); + if (fi50hz_bit.read()) + Serial.print("50HZ"); + else + Serial.print("60HZ"); Serial.println(); } // Check and print faults. Then clear them. -void checkFaults( void ) { +void checkFaults(void) { if (fault_bit.read()) { - Serial.print("MAX: "); Serial.println(maxRratio_bits.read()); - Serial.print("VAL: "); Serial.println( rRatio_bits.read()); - Serial.print("MIN: "); Serial.println(minRratio_bits.read()); - - if (range_high_fault_bit.read() ) Serial.println("Range high fault"); - if ( range_low_fault_bit.read() ) Serial.println("Range low fault"); - if (refin_high_fault_bit.read() ) Serial.println("REFIN high fault"); - if ( refin_low_fault_bit.read() ) Serial.println("REFIN low fault"); - if ( rtdin_low_fault_bit.read() ) Serial.println("RTDIN low fault"); - if ( voltage_fault_bit.read() ) Serial.println("Voltage fault"); + Serial.print("MAX: "); + Serial.println(maxRratio_bits.read()); + Serial.print("VAL: "); + Serial.println(rRatio_bits.read()); + Serial.print("MIN: "); + Serial.println(minRratio_bits.read()); + + if (range_high_fault_bit.read()) + Serial.println("Range high fault"); + if (range_low_fault_bit.read()) + Serial.println("Range low fault"); + if (refin_high_fault_bit.read()) + Serial.println("REFIN high fault"); + if (refin_low_fault_bit.read()) + Serial.println("REFIN low fault"); + if (rtdin_low_fault_bit.read()) + Serial.println("RTDIN low fault"); + if (voltage_fault_bit.read()) + Serial.println("Voltage fault"); faultR_bit.write(1); // clear fault } } void setup() { - #if (MAX31865_1_READY_PIN != -1) - pinMode(MAX31865_READY_PIN ,INPUT_PULLUP); - #endif +#if (MAX31865_1_READY_PIN != -1) + pinMode(MAX31865_READY_PIN, INPUT_PULLUP); +#endif - while (!Serial) { delay(10); } + while (!Serial) { + delay(10); + } Serial.begin(115200); Serial.println("SPI Adafruit_BusIO_RegisterBits test on MAX31865"); if (!spi_dev.begin()) { Serial.println("Could not initialize SPI device"); - while (1); + while (1) + ; } - // Set up for automode 50Hz. We don't care about selfheating. We want the highest possible sampling rate. + // Set up for automode 50Hz. We don't care about selfheating. We want the + // highest possible sampling rate. auto_bit.write(0); // Don't switch filtermode while auto_mode is on. fi50hz_bit.write(1); // Set filter to 50Hz mode. faultR_bit.write(1); // Clear faults. - bias_bit.write(1); // In automode we want to have the bias current always on. - delay(5); // Wait until bias current settles down. - // 10.5 time constants of the input RC network is required. - // 10ms worst case for 10kω reference resistor and a 0.1µF capacitor across the RTD inputs. - // Adafruit Module has 0.1µF and only 430/4300ω So here 0.43/4.3ms - auto_bit.write(1); // Now we can set automode. Automatically starting first conversion. - - // Test the READY_PIN - #if (defined( MAX31865_READY_PIN ) && (MAX31865_READY_PIN != -1)) - int i = 0; - while (digitalRead(MAX31865_READY_PIN) && i++ <= 100) { delay(1); } - if (i >= 100) { - Serial.print("ERROR: Max31865 Pin detection does not work. PIN:"); - Serial.println(MAX31865_READY_PIN); - } - #else - delay(100); - #endif + bias_bit.write(1); // In automode we want to have the bias current always on. + delay(5); // Wait until bias current settles down. + // 10.5 time constants of the input RC network is required. + // 10ms worst case for 10kω reference resistor and a 0.1µF capacitor + // across the RTD inputs. Adafruit Module has 0.1µF and only + // 430/4300ω So here 0.43/4.3ms + auto_bit.write( + 1); // Now we can set automode. Automatically starting first conversion. + +// Test the READY_PIN +#if (defined(MAX31865_READY_PIN) && (MAX31865_READY_PIN != -1)) + int i = 0; + while (digitalRead(MAX31865_READY_PIN) && i++ <= 100) { + delay(1); + } + if (i >= 100) { + Serial.print("ERROR: Max31865 Pin detection does not work. PIN:"); + Serial.println(MAX31865_READY_PIN); + } +#else + delay(100); +#endif // Set ratio range. - // Setting the temperatures would need some more calculation - not related to Adafruit_BusIO_RegisterBits. + // Setting the temperatures would need some more calculation - not related to + // Adafruit_BusIO_RegisterBits. uint16_t ratio = rRatio_bits.read(); - maxRratio_bits.write( (ratio < 0x8fffu-1000u) ? ratio + 1000u : 0x8fffu ); - minRratio_bits.write( (ratio > 1000u) ? ratio - 1000u : 0u ); + maxRratio_bits.write((ratio < 0x8fffu - 1000u) ? ratio + 1000u : 0x8fffu); + minRratio_bits.write((ratio > 1000u) ? ratio - 1000u : 0u); printConfig(); checkFaults(); } void loop() { - #if (defined( MAX31865_READY_PIN ) && (MAX31865_1_READY_PIN != -1)) - // Is conversion ready? - if (!digitalRead(MAX31865_READY_PIN)) - #else - // Warant conversion is ready. - delay(21); // 21ms for 50Hz-mode. 19ms in 60Hz-mode. - #endif - { - // Read ratio, calculate temperature, scale, filter and print. - Serial.println( rRatio2C( rRatio_bits.read() ) * 100.0f, 0); // Temperature scaled by 100 - // Check, print, clear faults. - checkFaults(); - } +#if (defined(MAX31865_READY_PIN) && (MAX31865_1_READY_PIN != -1)) + // Is conversion ready? + if (!digitalRead(MAX31865_READY_PIN)) +#else + // Warant conversion is ready. + delay(21); // 21ms for 50Hz-mode. 19ms in 60Hz-mode. +#endif + { + // Read ratio, calculate temperature, scale, filter and print. + Serial.println(rRatio2C(rRatio_bits.read()) * 100.0f, + 0); // Temperature scaled by 100 + // Check, print, clear faults. + checkFaults(); + } // Do something else. - //delay(15000); + // delay(15000); } - -// Module/Sensor related. Here Adafruit PT100 module with a 2_Wire PT100 Class C ***************************** +// Module/Sensor related. Here Adafruit PT100 module with a 2_Wire PT100 Class C +// ***************************** float rRatio2C(uint16_t ratio) { // A simple linear conversion. const float R0 = 100.0f; @@ -165,28 +235,34 @@ float rRatio2C(uint16_t ratio) { const float alphaPT = 0.003850f; const float ADCmax = (1u << 15) - 1.0f; const float rscale = Rref / ADCmax; - // Measured temperature in boiling water 101.08°C with factor a = 1 and b = 0. Rref and MAX at about 22±2°C. - // Measured temperature in ice/water bath 0.76°C with factor a = 1 and b = 0. Rref and MAX at about 22±2°C. - //const float a = 1.0f / (alphaPT * R0); - const float a = (100.0f/101.08f) / (alphaPT * R0); - //const float b = 0.0f; // 101.08 - const float b = -0.76f; // 100.32 > 101.08 - - return filterRing( ((ratio * rscale) - R0) * a + b ); + // Measured temperature in boiling water 101.08°C with factor a = 1 and b = 0. + // Rref and MAX at about 22±2°C. Measured temperature in ice/water bath 0.76°C + // with factor a = 1 and b = 0. Rref and MAX at about 22±2°C. + // const float a = 1.0f / (alphaPT * R0); + const float a = (100.0f / 101.08f) / (alphaPT * R0); + // const float b = 0.0f; // 101.08 + const float b = -0.76f; // 100.32 > 101.08 + + return filterRing(((ratio * rscale) - R0) * a + b); } -// General purpose ********************************************************************************************* +// General purpose +// ********************************************************************************************* #define RINGLENGTH 250 -float filterRing( float newVal ) { - static float ring[RINGLENGTH] = { 0.0 }; +float filterRing(float newVal) { + static float ring[RINGLENGTH] = {0.0}; static uint8_t ringIndex = 0; static bool ringFull = false; - if ( ringIndex == RINGLENGTH ) { ringFull = true; ringIndex = 0; } + if (ringIndex == RINGLENGTH) { + ringFull = true; + ringIndex = 0; + } ring[ringIndex] = newVal; uint8_t loopEnd = (ringFull) ? RINGLENGTH : ringIndex + 1; float ringSum = 0.0f; - for (uint8_t i = 0; i < loopEnd; i++) ringSum += ring[i]; + for (uint8_t i = 0; i < loopEnd; i++) + ringSum += ring[i]; ringIndex++; return ringSum / loopEnd; } diff --git a/examples/spi_registers/spi_registers.ino b/examples/spi_registers/spi_registers.ino index 091a353..af6069b 100644 --- a/examples/spi_registers/spi_registers.ino +++ b/examples/spi_registers/spi_registers.ino @@ -5,30 +5,36 @@ Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS); void setup() { - while (!Serial) { delay(10); } + while (!Serial) { + delay(10); + } Serial.begin(115200); Serial.println("SPI device register test"); if (!spi_dev.begin()) { Serial.println("Could not initialize SPI device"); - while (1); + while (1) + ; } - Adafruit_BusIO_Register id_reg = Adafruit_BusIO_Register(&spi_dev, 0x0F, ADDRBIT8_HIGH_TOREAD); + Adafruit_BusIO_Register id_reg = + Adafruit_BusIO_Register(&spi_dev, 0x0F, ADDRBIT8_HIGH_TOREAD); uint8_t id = 0; id_reg.read(&id); - Serial.print("ID register = 0x"); Serial.println(id, HEX); + Serial.print("ID register = 0x"); + Serial.println(id, HEX); - Adafruit_BusIO_Register thresh_reg = Adafruit_BusIO_Register(&spi_dev, 0x0C, ADDRBIT8_HIGH_TOREAD, 2, LSBFIRST); + Adafruit_BusIO_Register thresh_reg = Adafruit_BusIO_Register( + &spi_dev, 0x0C, ADDRBIT8_HIGH_TOREAD, 2, LSBFIRST); uint16_t thresh = 0; thresh_reg.read(&thresh); - Serial.print("Initial threshold register = 0x"); Serial.println(thresh, HEX); + Serial.print("Initial threshold register = 0x"); + Serial.println(thresh, HEX); thresh_reg.write(~thresh); - Serial.print("Post threshold register = 0x"); Serial.println(thresh_reg.read(), HEX); + Serial.print("Post threshold register = 0x"); + Serial.println(thresh_reg.read(), HEX); } -void loop() { - -} +void loop() {}