From f0a91e48871507296ceb4a14db138e5214b4dba2 Mon Sep 17 00:00:00 2001 From: Kirk Benell Date: Tue, 30 Apr 2024 06:21:46 -0600 Subject: [PATCH 01/13] Tweaks on syntax - for doxygen gen'd docs --- docs/ar_ibus.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/ar_ibus.md b/docs/ar_ibus.md index 560b567..187f3cf 100644 --- a/docs/ar_ibus.md +++ b/docs/ar_ibus.md @@ -131,7 +131,7 @@ The general pattern for a device driver implementation that uses the SparkFun To The first step is to implement a core, platform independent version of the driver that communicates to the target device using the methods of a ```sfeTkIBus``` interface. By limiting use to the IBus interface, the core implementation can use any bus type or platform that implements the sfeTkIBus interface. ->[!IMPORTANT] +> [!IMPORTANT] > At this level, the driver is only using a ```sfeTkIBus``` interface, not any specific bus implementation. This driver has the following unique functionality: @@ -141,12 +141,12 @@ This driver has the following unique functionality: #### Simple Example of an Independent Driver Implementation ->[!NOTE] +> [!NOTE] > This code is **pseudo-code**, used to demonstrate the key concepts of the implementation pattern. This implementation would take the following form: -```c++ +```cpp class myDriverClass { @@ -205,7 +205,7 @@ The following is an example of an I2C class in Arduino based on the previous pla > [!NOTE] > If your device supports repeated starts, make sure to include ```_theI2CBus.setStop(false)``` in your begin function. Otherwise this can cause issues with your device. -```c++ +```cpp class myArduinoDriverI2C : public myDriverClass { @@ -246,7 +246,7 @@ The following is a SPI version of the driver implemented in Arduino. While simil > [!NOTE] > This class implements a ```isConnected()``` method that just calls the superclasses ```checkDeviceID()``` method to determine if the device is available on the bus. -```c++ +```cpp class myArduinoDriveSPI : public myDriverClass { From e5533ad85e9d59727c1e5766c5f4fb76962cc5c2 Mon Sep 17 00:00:00 2001 From: Kirk Benell Date: Wed, 1 May 2024 14:05:46 -0600 Subject: [PATCH 02/13] Fix typos and mistakes in comments / docs --- src/sfeTk/sfeTkError.h | 2 +- src/sfeTk/sfeTkIBus.h | 19 +++++++++---------- src/sfeTkArdI2C.h | 20 ++++++++++++-------- src/sfeTkArdSPI.h | 33 ++++++++++++++++++++++----------- 4 files changed, 44 insertions(+), 30 deletions(-) diff --git a/src/sfeTk/sfeTkError.h b/src/sfeTk/sfeTkError.h index 8d79240..3f00841 100644 --- a/src/sfeTk/sfeTkError.h +++ b/src/sfeTk/sfeTkError.h @@ -32,7 +32,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * General Concept * A SparkFun Toolkit error system. The goal is to keep this simple. * - * This mimics a vareity of systems, using an int type for error codes, + * This mimics a variety of systems, using an int type for error codes, * where: * 0 = okay * -1 = general failure diff --git a/src/sfeTk/sfeTkIBus.h b/src/sfeTk/sfeTkIBus.h index 6b13758..003a914 100644 --- a/src/sfeTk/sfeTkIBus.h +++ b/src/sfeTk/sfeTkIBus.h @@ -88,7 +88,7 @@ class sfeTkIBus public: /**-------------------------------------------------------------------------- * @brief Write a single byte to the device* - * @param data Data to write.* + * @param data Data to write. * * @retval sfeTkError_t - kSTkErrOk on successful execution. * @@ -120,9 +120,9 @@ class sfeTkIBus /**-------------------------------------------------------------------------- * @brief Writes a number of bytes starting at the given register's address. * - * @param devAddr The device's address/pin - * param devReg The device's register's address. - * @param data Data to write. + * @param devReg The device's register's address. + * @param data Data to write. + * @param length - length of data * * @retval sfeTkError_t kSTkErrOk on successful execution * @@ -132,9 +132,9 @@ class sfeTkIBus /**-------------------------------------------------------------------------- * @brief Writes a number of bytes starting at the given register's 16-bit address. * - * @param devAddr The device's 16-bit address/pin - * param devReg The device's register's address. - * @param data Data to write. + * @param devReg The device's register's address. + * @param data Data to write. + * @param length - length of data * * @retval sfeTkError_t kSTkErrOk on successful execution * @@ -145,7 +145,7 @@ class sfeTkIBus * @brief Read a single byte from the given register * * @param devReg The device's register's address. - * @param data Data to read. + * @param data Data to read. * * @retval sfeTkError_t - kSTkErrOk on successful execution. * @@ -165,8 +165,7 @@ class sfeTkIBus /**-------------------------------------------------------------------------- * @brief Reads a block of data from the given register. * - * @param devAddr The device's I2C address. - * @param devReg The device's register's address. + * @param reg The device's register's address. * @param data Data to write. * @param numBytes - length of data * @param[out] readBytes - number of bytes read diff --git a/src/sfeTkArdI2C.h b/src/sfeTkArdI2C.h index 1a843f2..f42837d 100644 --- a/src/sfeTkArdI2C.h +++ b/src/sfeTkArdI2C.h @@ -84,6 +84,8 @@ class sfeTkArdI2C : public sfeTkII2C /** @brief - address version of the init method + + @param addr The address of the device */ sfeTkError_t init(uint8_t addr); @@ -91,6 +93,7 @@ class sfeTkArdI2C : public sfeTkII2C @brief Method sets up the required I2C settings. @param wirePort Port for I2C communication. + @param addr The address of the device @param bInit This flag tracks whether the bus has been initialized. @retval kSTkErrOk on successful execution. @@ -145,6 +148,7 @@ class sfeTkArdI2C : public sfeTkII2C @param devReg The device's register's address. @param data Data to write. + @param length - length of data @retval kStkErrOk on success */ @@ -153,9 +157,9 @@ class sfeTkArdI2C : public sfeTkII2C /** @brief Writes a number of bytes starting at the given register's 16-bit address. - @param devAddr The device's 16-bit address/pin - param devReg The device's register's address. + @param devReg The device's register's address - 16 bit. @param data Data to write. + @param length - length of data @retval sfeTkError_t kSTkErrOk on successful execution @@ -168,7 +172,7 @@ class sfeTkArdI2C : public sfeTkII2C @note sfeTkIBus interface method @param devReg The device's register's address. - @param data Data to read. + @param[out] data Data to read. @retval kStkErrOk on success */ @@ -180,7 +184,7 @@ class sfeTkArdI2C : public sfeTkII2C @note sfeTkIBus interface method @param devReg The device's register's address. - @param data Data to read. + @param[out] data Data to read. @retval kSTkErrOk on success */ @@ -193,8 +197,8 @@ class sfeTkArdI2C : public sfeTkII2C @note This method is virtual to allow it to be overridden to support a device that requires a unique impl @param devReg The device's register's address. - @param data Data being read. - @param numBytes Number of bytes to read. + @param[out] data Data buffer to read into + @param numBytes Number of bytes to read/length of data buffer @param[out] readBytes - Number of bytes read @@ -206,8 +210,8 @@ class sfeTkArdI2C : public sfeTkII2C @brief Reads a block of data from the given 16-bit register address. @param reg The device's 16 bit register's address. - @param data Data to write. - @param numBytes - length of data + @param data Data buffer to read into + @param numBytes - Number of bytes to read/length of data buffer @param[out] readBytes - number of bytes read @retval int returns kSTkErrOk on success, or kSTkErrFail code diff --git a/src/sfeTkArdSPI.h b/src/sfeTkArdSPI.h index 3e48178..cfab0e3 100644 --- a/src/sfeTkArdSPI.h +++ b/src/sfeTkArdSPI.h @@ -54,8 +54,7 @@ class sfeTkArdSPI : public sfeTkISPI /** @brief Copy constructor for Arduino SPI bus object of the toolkit - @param spiPort Port for SPI communication. - @param busSPISettings Settings for speed, endianness, and spi mode of the SPI bus. + @param rhs source of the copy operation */ sfeTkArdSPI(sfeTkArdSPI const &rhs) : sfeTkISPI(), _spiPort{rhs._spiPort}, _sfeSPISettings{rhs._sfeSPISettings} { @@ -78,12 +77,21 @@ class sfeTkArdSPI : public sfeTkISPI @brief Method sets up the required SPI settings. @note This function provides a default SPI Port. - @param bInit This flag tracks whether the bus has been initialized. + @param bInit Init the device - default is false. @retval sfeTkError_t - kSTkErrOk on success */ sfeTkError_t init(bool bInit = false); + /** + @brief Method sets up the required SPI settings. + @note This function provides a default SPI Port. + + @param csPin The CS Pin for the device + @param bInit Init the device - default is false. + + @retval sfeTkError_t - kSTkErrOk on success + */ sfeTkError_t init(uint8_t csPin, bool bInit = false); /** @@ -91,6 +99,7 @@ class sfeTkArdSPI : public sfeTkISPI @param spiPort Port for SPI communication. @param busSPISettings Settings for speed, endianness, and spi mode of the SPI bus. + @param csPin The CS Pin for the device @param bInit This flag tracks whether the bus has been initialized. @retval sfeTkError_t - kSTkErrOk on success @@ -132,6 +141,7 @@ class sfeTkArdSPI : public sfeTkISPI @param devReg The device's register's address. @param data Data to write. + @param length - length of data @retval sfeTkError_t - kSTkErrOk on success */ @@ -143,6 +153,7 @@ class sfeTkArdSPI : public sfeTkISPI @param devReg The device's register's address. @param data Data to write. + @param length - length of data @retval sfeTkError_t - kSTkErrOk on success */ @@ -152,7 +163,7 @@ class sfeTkArdSPI : public sfeTkISPI @brief Read a single byte from the given register @param devReg The device's register's address. - @param data Data to read. + @param[out] data Data to read. @retval sfeTkError_t - kSTkErrOk on success */ @@ -162,7 +173,7 @@ class sfeTkArdSPI : public sfeTkISPI @brief read a single word to the given register @param devReg The device's register's address. - @param data Data to write. + @param[out] data Data to write. @retval sfeTkError_t - true on success */ @@ -172,9 +183,9 @@ class sfeTkArdSPI : public sfeTkISPI @brief Reads a block of data from the given register. @note This method is virtual to allow it to be overridden to support a device that requires a unique impl - @param devReg The device's register's address. - @param data Data to write. - @param numBytes - length of data + @param reg The device's register's address. + @param[out] data Data buffer to read into + @param numBytes - length of data/size of data buffer @param[out] readBytes - Number of bytes read @retval sfeTkError_t - true on success @@ -185,9 +196,9 @@ class sfeTkArdSPI : public sfeTkISPI @brief Reads a block of data from the given register. @note This method is virtual to allow it to be overridden to support a device that requires a unique impl - @param devReg The device's register's 16 bit address. - @param data Data to write. - @param numBytes - length of data + @param reg The device's register's 16 bit address. + @param[out] data Data buffer to read into + @param numBytes - Length of data to read/size of data buffer @param[out] readBytes - Number of bytes read @retval sfeTkError_t - true on success From 8422de8ba0ad7cf542b5e77857a7228f03d45d07 Mon Sep 17 00:00:00 2001 From: Kirk Benell Date: Mon, 6 May 2024 13:55:47 -0600 Subject: [PATCH 03/13] fixed a doc typo --- src/sfeTkArdSPI.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sfeTkArdSPI.h b/src/sfeTkArdSPI.h index cfab0e3..457a809 100644 --- a/src/sfeTkArdSPI.h +++ b/src/sfeTkArdSPI.h @@ -63,7 +63,7 @@ class sfeTkArdSPI : public sfeTkISPI /** @brief Assignment copy operator for Arduino SPI bus object of the toolkit - @param rsh The right hand side of the assignment. + @param rhs The right hand side of the assignment. @return sfeTkArdSPI& - The left hand side of the assignment. */ sfeTkArdSPI &operator=(const sfeTkArdSPI &rhs) From c499f29c399faaf6e1eb98f56a886a7e52f0a4d4 Mon Sep 17 00:00:00 2001 From: santised Date: Thu, 30 May 2024 06:20:01 -0600 Subject: [PATCH 04/13] Adds two functions for sending data to a device that doesn't indexing to a given register * Still needs test --- src/sfeTkArdI2C.cpp | 38 +++++++++++++++++++++++++++++++++++++- src/sfeTkArdI2C.h | 22 +++++++++++++++++++++- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/sfeTkArdI2C.cpp b/src/sfeTkArdI2C.cpp index 076807b..ea340b8 100644 --- a/src/sfeTkArdI2C.cpp +++ b/src/sfeTkArdI2C.cpp @@ -22,6 +22,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "sfeTkArdI2C.h" +#include //--------------------------------------------------------------------------------- // init() @@ -87,7 +88,7 @@ sfeTkError_t sfeTkArdI2C::ping() //--------------------------------------------------------------------------------- // writeByte() // -// Writes a single byte to the device. +// Sends a single byte to the device. // // Returns true on success, false on failure // @@ -102,6 +103,41 @@ sfeTkError_t sfeTkArdI2C::writeByte(uint8_t dataToWrite) return _i2cPort->endTransmission() == 0 ? kSTkErrOk : kSTkErrFail; } +//--------------------------------------------------------------------------------- +// writeWord() +// +// Sends a word to the device. +// +// Returns true on success, false on failure +// +sfeTkError_t sfeTkArdI2C::writeWord(uint16_t dataToWrite) +{ + if (!_i2cPort) + return kSTkErrBusNotInit; + + return writeBlock((uint8_t *)&dataToWrite, sizeof(uint16_t)); +} + +//--------------------------------------------------------------------------------- +// writeBlock() +// +// Sends an array of data to the device. +// +// Returns true on success, false on failure +// +sfeTkError_t sfeTkArdI2C::writeBlock(const uint8_t *dataToWrite, size_t length) +{ + int nData = 0; + if (!_i2cPort) + return kSTkErrBusNotInit; + + // do the Arduino I2C work + _i2cPort->beginTransmission(address()); + _i2cPort->write(data, (int)length); + + return _i2cPort->endTransmission() == 0 ? kSTkErrOk : kSTkErrFail; +} + //--------------------------------------------------------------------------------- // writeRegisterByte() // diff --git a/src/sfeTkArdI2C.h b/src/sfeTkArdI2C.h index f42837d..344ef17 100644 --- a/src/sfeTkArdI2C.h +++ b/src/sfeTkArdI2C.h @@ -109,7 +109,7 @@ class sfeTkArdI2C : public sfeTkII2C sfeTkError_t ping(); /** - @brief Write a single byte to the device + @brief Sends a single byte to the device @note sfeTkIBus interface method @param data Data to write. @@ -118,6 +118,26 @@ class sfeTkArdI2C : public sfeTkII2C */ sfeTkError_t writeByte(uint8_t data); + /** + @brief Sends a word to the device. + @note sfeTkIBus interface method + + @param data Data to write. + + @retval returns kStkErrOk on success + */ + sfeTkError_t writeWord(uint16_t data); + + /** + @brief Sends a block of data to the device. + @note sfeTkIBus interface method + + @param data Data to write. + + @retval returns kStkErrOk on success + */ + sfeTkError_t writeBlock(const uint8_t *data); + /** @brief Write a single byte to the given register @note sfeTkIBus interface method From 5b234746055b9a5288f05f2b997066352b4c98e9 Mon Sep 17 00:00:00 2001 From: santised Date: Thu, 30 May 2024 11:05:41 -0600 Subject: [PATCH 05/13] Adds new virtual functions to highest order bus class * Updates descriptions to indicate that these functions to not index to a given register. --- src/sfeTk/sfeTkIBus.h | 20 +++++++++++++++++++- src/sfeTkArdI2C.cpp | 2 +- src/sfeTkArdI2C.h | 2 +- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/sfeTk/sfeTkIBus.h b/src/sfeTk/sfeTkIBus.h index 003a914..c6b2c65 100644 --- a/src/sfeTk/sfeTkIBus.h +++ b/src/sfeTk/sfeTkIBus.h @@ -87,7 +87,7 @@ class sfeTkIBus { public: /**-------------------------------------------------------------------------- - * @brief Write a single byte to the device* + * @brief Send a single byte to the device* * @param data Data to write. * * @retval sfeTkError_t - kSTkErrOk on successful execution. @@ -95,6 +95,24 @@ class sfeTkIBus */ virtual sfeTkError_t writeByte(uint8_t data) = 0; + /**-------------------------------------------------------------------------- + * @brief Send a word to the device. + * @param data Data to write. + * + * @retval sfeTkError_t - kSTkErrOk on successful execution. + * + */ + virtual sfeTkError_t writeWord(uint16_t data) = 0; + + /**-------------------------------------------------------------------------- + * @brief Send an array of data to the device. + * @param data Data to write. + * + * @retval sfeTkError_t - kSTkErrOk on successful execution. + * + */ + virtual sfeTkError_t writeBlock(const uint8_t *data, size_t length) = 0; + /**-------------------------------------------------------------------------- * @brief Write a single byte to the given register * diff --git a/src/sfeTkArdI2C.cpp b/src/sfeTkArdI2C.cpp index ea340b8..6f94e5b 100644 --- a/src/sfeTkArdI2C.cpp +++ b/src/sfeTkArdI2C.cpp @@ -125,7 +125,7 @@ sfeTkError_t sfeTkArdI2C::writeWord(uint16_t dataToWrite) // // Returns true on success, false on failure // -sfeTkError_t sfeTkArdI2C::writeBlock(const uint8_t *dataToWrite, size_t length) +sfeTkError_t sfeTkArdI2C::writeBlock(const uint8_t *data, size_t length) { int nData = 0; if (!_i2cPort) diff --git a/src/sfeTkArdI2C.h b/src/sfeTkArdI2C.h index 344ef17..851f827 100644 --- a/src/sfeTkArdI2C.h +++ b/src/sfeTkArdI2C.h @@ -136,7 +136,7 @@ class sfeTkArdI2C : public sfeTkII2C @retval returns kStkErrOk on success */ - sfeTkError_t writeBlock(const uint8_t *data); + sfeTkError_t writeBlock(const uint8_t *data, size_t length); /** @brief Write a single byte to the given register From 79a7992da4ab3a3008a980a3f7fb16e1fe780747 Mon Sep 17 00:00:00 2001 From: santised Date: Thu, 30 May 2024 11:18:26 -0600 Subject: [PATCH 06/13] Removes accidental include --- src/sfeTkArdI2C.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sfeTkArdI2C.cpp b/src/sfeTkArdI2C.cpp index 6f94e5b..6798d0d 100644 --- a/src/sfeTkArdI2C.cpp +++ b/src/sfeTkArdI2C.cpp @@ -22,7 +22,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "sfeTkArdI2C.h" -#include //--------------------------------------------------------------------------------- // init() From 5333ef3642aab7b92ef04e9c5f69cf4f9c6904af Mon Sep 17 00:00:00 2001 From: santised Date: Thu, 6 Jun 2024 15:36:32 -0600 Subject: [PATCH 07/13] Adds read methods to compliment the previously committed write methods --- src/sfeTk/sfeTkIBus.h | 39 +++++++++++++ src/sfeTkArdI2C.cpp | 124 ++++++++++++++++++++++++++++++++++++++++-- src/sfeTkArdI2C.h | 39 +++++++++++++ 3 files changed, 198 insertions(+), 4 deletions(-) diff --git a/src/sfeTk/sfeTkIBus.h b/src/sfeTk/sfeTkIBus.h index c6b2c65..daa1c06 100644 --- a/src/sfeTk/sfeTkIBus.h +++ b/src/sfeTk/sfeTkIBus.h @@ -124,6 +124,45 @@ class sfeTkIBus */ virtual sfeTkError_t writeRegisterByte(uint8_t devReg, uint8_t data) = 0; + /** + @brief Reads a byte of data from the device. + + @note sfeTkIBus interface method + + @param dataToWrite The data to write to the device. + @param[out] data Data to read. + + @retval kStkErrOk on success + */ + virtual sfeTkError_t readByte(uint8_t dataToWrite, uint8_t &data) = 0; + + /** + @brief Reads a word of data from the device. + + @note sfeTkIBus interface method + + @param dataToWrite The data to write to the device. + @param[out] data Data to read. + + @retval kSTkErrOk on success + */ + virtual sfeTkError_t readWord(uint8_t dataToWrite, uint16_t &data) = 0; + + /** + @brief Reads a block of data from the device. + + @note sfeTkIBus interface method + + @param dataToWrite The data to write to the device. + @param[out] data Data buffer to read into + @param numBytes Number of bytes to read/length of data buffer + @param[out] readBytes - Number of bytes read + + + @retval kSTkErrOk on success + */ + virtual sfeTkError_t readBlock(uint8_t dataToWrite, uint8_t *data, size_t numBytes, size_t &readBytes) = 0; + /**-------------------------------------------------------------------------- * @brief Write a single word (16 bit) to the given register * diff --git a/src/sfeTkArdI2C.cpp b/src/sfeTkArdI2C.cpp index 6798d0d..12b3102 100644 --- a/src/sfeTkArdI2C.cpp +++ b/src/sfeTkArdI2C.cpp @@ -22,6 +22,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "sfeTkArdI2C.h" +#include +#include //--------------------------------------------------------------------------------- // init() @@ -87,7 +89,7 @@ sfeTkError_t sfeTkArdI2C::ping() //--------------------------------------------------------------------------------- // writeByte() // -// Sends a single byte to the device. +// Writes a single byte to the device, without indexing to a register. // // Returns true on success, false on failure // @@ -105,7 +107,7 @@ sfeTkError_t sfeTkArdI2C::writeByte(uint8_t dataToWrite) //--------------------------------------------------------------------------------- // writeWord() // -// Sends a word to the device. +// Writes a word to the device, without indexing to a register. // // Returns true on success, false on failure // @@ -120,13 +122,12 @@ sfeTkError_t sfeTkArdI2C::writeWord(uint16_t dataToWrite) //--------------------------------------------------------------------------------- // writeBlock() // -// Sends an array of data to the device. +// Writes a word to the device, without indexing to a register. // // Returns true on success, false on failure // sfeTkError_t sfeTkArdI2C::writeBlock(const uint8_t *data, size_t length) { - int nData = 0; if (!_i2cPort) return kSTkErrBusNotInit; @@ -218,6 +219,121 @@ sfeTkError_t sfeTkArdI2C::writeRegister16Region(uint16_t devReg, const uint8_t * return writeRegisterRegionAddress((uint8_t *)&devReg, 2, data, length); } +//--------------------------------------------------------------------------------- +// readByte() +// +// Reads a byte from the device, without indexing to a register. +// +// Returns true on success, false on failure +// +sfeTkError_t sfeTkArdI2C::readByte(uint8_t dataToWrite, uint8_t &dataToRead) +{ + if (!_i2cPort) + return kSTkErrBusNotInit; + + // Return value + uint8_t result = 0; + + int nData = 0; + + _i2cPort->beginTransmission(address()); + _i2cPort->write(dataToWrite); + _i2cPort->endTransmission(stop()); + _i2cPort->requestFrom(address(), (uint8_t)1); + + while (_i2cPort->available()) // slave may send less than requested + { + result = _i2cPort->read(); // receive a byte as a proper uint8_t + nData++; + } + + if (nData == sizeof(uint8_t)) // Only update outputPointer if a single byte was returned + dataToRead = result; + + return (nData == sizeof(uint8_t) ? kSTkErrOk : kSTkErrFail); +} + + +//--------------------------------------------------------------------------------- +// readWord() +// +// Reads a word from the device, without indexing to a register. +// +// Returns true on success, false on failure +// +sfeTkError_t sfeTkArdI2C::readWord(uint8_t dataToWrite, uint16_t &dataToRead) +{ + if (!_i2cPort) + return kSTkErrBusNotInit; + + size_t nRead; + sfeTkError_t retval = readBlock(dataToWrite, (uint8_t *)&dataToRead, sizeof(uint16_t), nRead); + + return (retval == kSTkErrOk && nRead == sizeof(uint16_t) ? kSTkErrOk : retval); +} + +//--------------------------------------------------------------------------------- +// readBlock() +// +// Reads a block of data from the device, without indexing to a register. +// +// Returns the number of bytes written, < 0 is an error +// +sfeTkError_t sfeTkArdI2C::readBlock(uint8_t dataToWrite, uint8_t *data, size_t numBytes, size_t &readBytes) +{ + + // got port + if (!_i2cPort) + return kSTkErrBusNotInit; + + // Buffer valid? + if (!data) + return kSTkErrBusNullBuffer; + + readBytes = 0; + + uint16_t nOrig = numBytes; // original number of bytes. + uint8_t nChunk; + uint16_t nReturned; + uint16_t i; // counter in loop + bool bFirstInter = true; // Flag for first iteration - used to send devRegister + + while (numBytes > 0) + { + if (bFirstInter) + { + _i2cPort->beginTransmission(address()); + _i2cPort->write(dataToWrite); + if (_i2cPort->endTransmission(stop()) != 0) + return kSTkErrFail; // error with the end transmission + + bFirstInter = false; + } + + // We're chunking in data - keeping the max chunk to kMaxI2CBufferLength + nChunk = numBytes > _bufferChunkSize ? _bufferChunkSize : numBytes; + + // Request the bytes. If this is the last chunk, always send a stop + nReturned = _i2cPort->requestFrom((int)address(), (int)nChunk, (int)(nChunk == numBytes ? true : stop())); + + // No data returned, no dice + if (nReturned == 0) + return kSTkErrBusUnderRead; // error + + // Copy the retrieved data chunk to the current index in the data segment + for (i = 0; i < nReturned; i++) + *data++ = _i2cPort->read(); + + // Decrement the amount of data received from the overall data request amount + numBytes = numBytes - nReturned; + + } // end while + + readBytes = nOrig - numBytes; // Bytes read. + + return (readBytes == nOrig) ? kSTkErrOk : kSTkErrBusUnderRead; // Success +} + //--------------------------------------------------------------------------------- /** diff --git a/src/sfeTkArdI2C.h b/src/sfeTkArdI2C.h index 851f827..583b369 100644 --- a/src/sfeTkArdI2C.h +++ b/src/sfeTkArdI2C.h @@ -186,6 +186,45 @@ class sfeTkArdI2C : public sfeTkII2C */ sfeTkError_t writeRegister16Region(uint16_t devReg, const uint8_t *data, size_t length); + /** + @brief Reads a byte of data from the device. + + @note sfeTkIBus interface method + + @param dataToWrite The data to write to the device. + @param[out] data Data to read. + + @retval kStkErrOk on success + */ + sfeTkError_t readByte(uint8_t dataToWrite, uint8_t &data); + + /** + @brief Reads a word of data from the device. + + @note sfeTkIBus interface method + + @param dataToWrite The data to write to the device. + @param[out] data Data to read. + + @retval kSTkErrOk on success + */ + sfeTkError_t readWord(uint8_t dataToWrite, uint16_t &data); + + /** + @brief Reads a block of data from the device. + + @note sfeTkIBus interface method + + @param dataToWrite The data to write to the device. + @param[out] data Data buffer to read into + @param numBytes Number of bytes to read/length of data buffer + @param[out] readBytes - Number of bytes read + + + @retval kSTkErrOk on success + */ + sfeTkError_t readBlock(uint8_t dataToWrite, uint8_t *data, size_t numBytes, size_t &readBytes); + /** @brief Reads a byte of data from the given register. From ae3e1ca5de92a267b2226a98c17359ca5b01bb5e Mon Sep 17 00:00:00 2001 From: Elias Santistevan Date: Tue, 18 Jun 2024 10:29:35 -0600 Subject: [PATCH 08/13] Removes redundant read methods * Changes the name of `writeBlock()` to `writeRegion()` * `writeRegion()` now calls `writeRegisterRegionAddress()` function * `writeRegisterRegionAddress()` now has a nullptr check before indexing to an address on write --- src/sfeTk/sfeTkIBus.h | 41 +------------ src/sfeTkArdI2C.cpp | 132 +++--------------------------------------- src/sfeTkArdI2C.h | 41 +------------ 3 files changed, 10 insertions(+), 204 deletions(-) diff --git a/src/sfeTk/sfeTkIBus.h b/src/sfeTk/sfeTkIBus.h index daa1c06..603218f 100644 --- a/src/sfeTk/sfeTkIBus.h +++ b/src/sfeTk/sfeTkIBus.h @@ -111,7 +111,7 @@ class sfeTkIBus * @retval sfeTkError_t - kSTkErrOk on successful execution. * */ - virtual sfeTkError_t writeBlock(const uint8_t *data, size_t length) = 0; + virtual sfeTkError_t writeRegion(const uint8_t *data, size_t length) = 0; /**-------------------------------------------------------------------------- * @brief Write a single byte to the given register @@ -124,45 +124,6 @@ class sfeTkIBus */ virtual sfeTkError_t writeRegisterByte(uint8_t devReg, uint8_t data) = 0; - /** - @brief Reads a byte of data from the device. - - @note sfeTkIBus interface method - - @param dataToWrite The data to write to the device. - @param[out] data Data to read. - - @retval kStkErrOk on success - */ - virtual sfeTkError_t readByte(uint8_t dataToWrite, uint8_t &data) = 0; - - /** - @brief Reads a word of data from the device. - - @note sfeTkIBus interface method - - @param dataToWrite The data to write to the device. - @param[out] data Data to read. - - @retval kSTkErrOk on success - */ - virtual sfeTkError_t readWord(uint8_t dataToWrite, uint16_t &data) = 0; - - /** - @brief Reads a block of data from the device. - - @note sfeTkIBus interface method - - @param dataToWrite The data to write to the device. - @param[out] data Data buffer to read into - @param numBytes Number of bytes to read/length of data buffer - @param[out] readBytes - Number of bytes read - - - @retval kSTkErrOk on success - */ - virtual sfeTkError_t readBlock(uint8_t dataToWrite, uint8_t *data, size_t numBytes, size_t &readBytes) = 0; - /**-------------------------------------------------------------------------- * @brief Write a single word (16 bit) to the given register * diff --git a/src/sfeTkArdI2C.cpp b/src/sfeTkArdI2C.cpp index 12b3102..6f3b339 100644 --- a/src/sfeTkArdI2C.cpp +++ b/src/sfeTkArdI2C.cpp @@ -116,26 +116,22 @@ sfeTkError_t sfeTkArdI2C::writeWord(uint16_t dataToWrite) if (!_i2cPort) return kSTkErrBusNotInit; - return writeBlock((uint8_t *)&dataToWrite, sizeof(uint16_t)); + return writeRegion((uint8_t *)&dataToWrite, sizeof(uint16_t)); } //--------------------------------------------------------------------------------- -// writeBlock() +// writeRegion() // // Writes a word to the device, without indexing to a register. // // Returns true on success, false on failure // -sfeTkError_t sfeTkArdI2C::writeBlock(const uint8_t *data, size_t length) +sfeTkError_t sfeTkArdI2C::writeRegion(const uint8_t *data, size_t length) { if (!_i2cPort) return kSTkErrBusNotInit; - // do the Arduino I2C work - _i2cPort->beginTransmission(address()); - _i2cPort->write(data, (int)length); - - return _i2cPort->endTransmission() == 0 ? kSTkErrOk : kSTkErrFail; + return writeRegisterRegionAddress(nullptr, 0, data, length) == 0 ? kSTkErrOk : kSTkErrFail; } //--------------------------------------------------------------------------------- @@ -188,7 +184,10 @@ sfeTkError_t sfeTkArdI2C::writeRegisterRegionAddress(uint8_t *devReg, size_t reg return kSTkErrBusNotInit; _i2cPort->beginTransmission(address()); - _i2cPort->write(devReg, regLength); + + if(devReg != nullptr && regLength > 0) + _i2cPort->write(devReg, regLength); + _i2cPort->write(data, (int)length); return _i2cPort->endTransmission() ? kSTkErrFail : kSTkErrOk; @@ -219,122 +218,7 @@ sfeTkError_t sfeTkArdI2C::writeRegister16Region(uint16_t devReg, const uint8_t * return writeRegisterRegionAddress((uint8_t *)&devReg, 2, data, length); } -//--------------------------------------------------------------------------------- -// readByte() -// -// Reads a byte from the device, without indexing to a register. -// -// Returns true on success, false on failure -// -sfeTkError_t sfeTkArdI2C::readByte(uint8_t dataToWrite, uint8_t &dataToRead) -{ - if (!_i2cPort) - return kSTkErrBusNotInit; - - // Return value - uint8_t result = 0; - - int nData = 0; - - _i2cPort->beginTransmission(address()); - _i2cPort->write(dataToWrite); - _i2cPort->endTransmission(stop()); - _i2cPort->requestFrom(address(), (uint8_t)1); - - while (_i2cPort->available()) // slave may send less than requested - { - result = _i2cPort->read(); // receive a byte as a proper uint8_t - nData++; - } - - if (nData == sizeof(uint8_t)) // Only update outputPointer if a single byte was returned - dataToRead = result; - - return (nData == sizeof(uint8_t) ? kSTkErrOk : kSTkErrFail); -} - - -//--------------------------------------------------------------------------------- -// readWord() -// -// Reads a word from the device, without indexing to a register. -// -// Returns true on success, false on failure -// -sfeTkError_t sfeTkArdI2C::readWord(uint8_t dataToWrite, uint16_t &dataToRead) -{ - if (!_i2cPort) - return kSTkErrBusNotInit; - - size_t nRead; - sfeTkError_t retval = readBlock(dataToWrite, (uint8_t *)&dataToRead, sizeof(uint16_t), nRead); - - return (retval == kSTkErrOk && nRead == sizeof(uint16_t) ? kSTkErrOk : retval); -} -//--------------------------------------------------------------------------------- -// readBlock() -// -// Reads a block of data from the device, without indexing to a register. -// -// Returns the number of bytes written, < 0 is an error -// -sfeTkError_t sfeTkArdI2C::readBlock(uint8_t dataToWrite, uint8_t *data, size_t numBytes, size_t &readBytes) -{ - - // got port - if (!_i2cPort) - return kSTkErrBusNotInit; - - // Buffer valid? - if (!data) - return kSTkErrBusNullBuffer; - - readBytes = 0; - - uint16_t nOrig = numBytes; // original number of bytes. - uint8_t nChunk; - uint16_t nReturned; - uint16_t i; // counter in loop - bool bFirstInter = true; // Flag for first iteration - used to send devRegister - - while (numBytes > 0) - { - if (bFirstInter) - { - _i2cPort->beginTransmission(address()); - _i2cPort->write(dataToWrite); - if (_i2cPort->endTransmission(stop()) != 0) - return kSTkErrFail; // error with the end transmission - - bFirstInter = false; - } - - // We're chunking in data - keeping the max chunk to kMaxI2CBufferLength - nChunk = numBytes > _bufferChunkSize ? _bufferChunkSize : numBytes; - - // Request the bytes. If this is the last chunk, always send a stop - nReturned = _i2cPort->requestFrom((int)address(), (int)nChunk, (int)(nChunk == numBytes ? true : stop())); - - // No data returned, no dice - if (nReturned == 0) - return kSTkErrBusUnderRead; // error - - // Copy the retrieved data chunk to the current index in the data segment - for (i = 0; i < nReturned; i++) - *data++ = _i2cPort->read(); - - // Decrement the amount of data received from the overall data request amount - numBytes = numBytes - nReturned; - - } // end while - - readBytes = nOrig - numBytes; // Bytes read. - - return (readBytes == nOrig) ? kSTkErrOk : kSTkErrBusUnderRead; // Success -} - -//--------------------------------------------------------------------------------- /** * @brief Reads an array of bytes to a register on the target address. Supports any address size diff --git a/src/sfeTkArdI2C.h b/src/sfeTkArdI2C.h index 583b369..dd5f834 100644 --- a/src/sfeTkArdI2C.h +++ b/src/sfeTkArdI2C.h @@ -136,7 +136,7 @@ class sfeTkArdI2C : public sfeTkII2C @retval returns kStkErrOk on success */ - sfeTkError_t writeBlock(const uint8_t *data, size_t length); + sfeTkError_t writeRegion(const uint8_t *data, size_t length); /** @brief Write a single byte to the given register @@ -186,45 +186,6 @@ class sfeTkArdI2C : public sfeTkII2C */ sfeTkError_t writeRegister16Region(uint16_t devReg, const uint8_t *data, size_t length); - /** - @brief Reads a byte of data from the device. - - @note sfeTkIBus interface method - - @param dataToWrite The data to write to the device. - @param[out] data Data to read. - - @retval kStkErrOk on success - */ - sfeTkError_t readByte(uint8_t dataToWrite, uint8_t &data); - - /** - @brief Reads a word of data from the device. - - @note sfeTkIBus interface method - - @param dataToWrite The data to write to the device. - @param[out] data Data to read. - - @retval kSTkErrOk on success - */ - sfeTkError_t readWord(uint8_t dataToWrite, uint16_t &data); - - /** - @brief Reads a block of data from the device. - - @note sfeTkIBus interface method - - @param dataToWrite The data to write to the device. - @param[out] data Data buffer to read into - @param numBytes Number of bytes to read/length of data buffer - @param[out] readBytes - Number of bytes read - - - @retval kSTkErrOk on success - */ - sfeTkError_t readBlock(uint8_t dataToWrite, uint8_t *data, size_t numBytes, size_t &readBytes); - /** @brief Reads a byte of data from the given register. From bf2deb8537faf9ff9206e0959b1abe1cea2d6b92 Mon Sep 17 00:00:00 2001 From: Elias Santistevan Date: Tue, 18 Jun 2024 12:19:51 -0600 Subject: [PATCH 09/13] Adds SPI implementation *Adds `writeWord()` and `writeRegion()` --- src/sfeTkArdSPI.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++-- src/sfeTkArdSPI.h | 19 +++++++++++++++++++ 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/sfeTkArdSPI.cpp b/src/sfeTkArdSPI.cpp index 15fcd60..276e3eb 100644 --- a/src/sfeTkArdSPI.cpp +++ b/src/sfeTkArdSPI.cpp @@ -82,7 +82,7 @@ sfeTkError_t sfeTkArdSPI::init(bool bInit) } //--------------------------------------------------------------------------------- -// writeRegisterByte() +// writeByte() // // Writes a single byte to the device. // @@ -108,6 +108,46 @@ sfeTkError_t sfeTkArdSPI::writeByte(uint8_t dataToWrite) return kSTkErrOk; } +//--------------------------------------------------------------------------------- +// writeWord() +// +// Writes a word to the device without indexing to a register. +// +// Returns kSTkErrOk on success +// +sfeTkError_t sfeTkArdSPI::writeWord(uint16_t dataToWrite) +{ + return writeRegion((uint8_t *)&dataToWrite, sizeof(uint8_t)) > 0; +} + + +//--------------------------------------------------------------------------------- +// writeRegion() +// +// Writes an array of data to the device without indexing to a register. +// +// Returns kSTkErrOk on success +// +sfeTkError_t sfeTkArdSPI::writeRegion(const uint8_t *dataToWrite, size_t length) +{ + + if (!_spiPort) + return kSTkErrBusNotInit; + + _spiPort->beginTransaction(_sfeSPISettings); + // Signal communication start + digitalWrite(cs(), LOW); + + for (size_t i = 0; i < length; i++) + _spiPort->transfer(*dataToWrite++); + + // End communication + digitalWrite(cs(), HIGH); + _spiPort->endTransaction(); + + return kSTkErrOk; +} + //--------------------------------------------------------------------------------- // writeRegisterByte() // @@ -164,6 +204,7 @@ sfeTkError_t sfeTkArdSPI::writeRegisterRegion(uint8_t devReg, const uint8_t *dat // Signal communication start digitalWrite(cs(), LOW); + _spiPort->transfer(devReg); for (size_t i = 0; i < length; i++) @@ -278,4 +319,4 @@ sfeTkError_t sfeTkArdSPI::readRegister16Region(uint16_t devReg, uint8_t *data, s readBytes = numBytes; return kSTkErrOk; -} \ No newline at end of file +} diff --git a/src/sfeTkArdSPI.h b/src/sfeTkArdSPI.h index 457a809..113853e 100644 --- a/src/sfeTkArdSPI.h +++ b/src/sfeTkArdSPI.h @@ -115,6 +115,25 @@ class sfeTkArdSPI : public sfeTkISPI */ sfeTkError_t writeByte(uint8_t data); + /** + @brief Write a word to the device without indexing to a register. + + @param data Data to write. + + @retval sfeTkError_t - kSTkErrOk on success + */ + sfeTkError_t writeWord(uint16_t data); + + /** + @brief Write an array of data to the device without indexing to a register. + + @param data Data to write + @param length Length of Data + + @retval sfeTkError_t - kSTkErrOk on success + */ + sfeTkError_t writeRegion(const uint8_t *data, size_t length); + /** @brief Write a single byte to the given register From 0cdd5316da1af87e6e79fb1d1549f3ee36885cb2 Mon Sep 17 00:00:00 2001 From: Elias Santistevan Date: Tue, 18 Jun 2024 12:20:49 -0600 Subject: [PATCH 10/13] Removes unnecessary in `writeRegion()` --- src/sfeTkArdI2C.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/sfeTkArdI2C.cpp b/src/sfeTkArdI2C.cpp index 6f3b339..9fb5d23 100644 --- a/src/sfeTkArdI2C.cpp +++ b/src/sfeTkArdI2C.cpp @@ -128,9 +128,6 @@ sfeTkError_t sfeTkArdI2C::writeWord(uint16_t dataToWrite) // sfeTkError_t sfeTkArdI2C::writeRegion(const uint8_t *data, size_t length) { - if (!_i2cPort) - return kSTkErrBusNotInit; - // do the Arduino I2C work return writeRegisterRegionAddress(nullptr, 0, data, length) == 0 ? kSTkErrOk : kSTkErrFail; } From b35f9a9d57a20a79a0741dd169735507713bd811 Mon Sep 17 00:00:00 2001 From: Elias Santistevan Date: Tue, 18 Jun 2024 13:10:06 -0600 Subject: [PATCH 11/13] Removes erroneous include causing issues with Atmega --- src/sfeTkArdI2C.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sfeTkArdI2C.cpp b/src/sfeTkArdI2C.cpp index 9fb5d23..03bd760 100644 --- a/src/sfeTkArdI2C.cpp +++ b/src/sfeTkArdI2C.cpp @@ -22,7 +22,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "sfeTkArdI2C.h" -#include #include //--------------------------------------------------------------------------------- From 3ac4a2c8bf415dcc198f2975f7beb11745daaee1 Mon Sep 17 00:00:00 2001 From: Elias Santistevan Date: Tue, 18 Jun 2024 13:14:12 -0600 Subject: [PATCH 12/13] Rolls version --- library.properties | 2 +- src/sfeTkArdI2C.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/library.properties b/library.properties index 3269264..5201f0f 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=SparkFun Toolkit -version=0.9.1 +version=0.9.2 author=SparkFun Electronics maintainer=SparkFun Electronics sentence=A utility library that other SparkFun libraries can take advantage of. diff --git a/src/sfeTkArdI2C.cpp b/src/sfeTkArdI2C.cpp index 03bd760..ab7b20a 100644 --- a/src/sfeTkArdI2C.cpp +++ b/src/sfeTkArdI2C.cpp @@ -22,7 +22,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "sfeTkArdI2C.h" -#include //--------------------------------------------------------------------------------- // init() From 97a2ab150fb8b829f2e3ef939ac56ac8c0c99d73 Mon Sep 17 00:00:00 2001 From: santised Date: Wed, 19 Jun 2024 11:17:45 -0600 Subject: [PATCH 13/13] Adds description of length parameter for `writeRegion()` in both header locations where it was missing. --- src/sfeTk/sfeTkIBus.h | 1 + src/sfeTkArdI2C.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/sfeTk/sfeTkIBus.h b/src/sfeTk/sfeTkIBus.h index 603218f..c6ca7ab 100644 --- a/src/sfeTk/sfeTkIBus.h +++ b/src/sfeTk/sfeTkIBus.h @@ -107,6 +107,7 @@ class sfeTkIBus /**-------------------------------------------------------------------------- * @brief Send an array of data to the device. * @param data Data to write. + * @param length - length of data. * * @retval sfeTkError_t - kSTkErrOk on successful execution. * diff --git a/src/sfeTkArdI2C.h b/src/sfeTkArdI2C.h index dd5f834..dc73432 100644 --- a/src/sfeTkArdI2C.h +++ b/src/sfeTkArdI2C.h @@ -133,6 +133,7 @@ class sfeTkArdI2C : public sfeTkII2C @note sfeTkIBus interface method @param data Data to write. + @param length - length of data @retval returns kStkErrOk on success */