From 5da9146558db50d46b8c34a51149464e51115111 Mon Sep 17 00:00:00 2001 From: Alex Brudner <101155592+SFE-Brudnerd@users.noreply.github.com> Date: Tue, 5 Dec 2023 13:31:44 -0700 Subject: [PATCH 01/15] Add git files. --- .gitattributes | 2 ++ .gitignore | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..eba1110 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..737bcf8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# VSCode directories +.vscode + From c17b3a045aeb584557d1747fc3db232f40a14968 Mon Sep 17 00:00:00 2001 From: Kirk Benell Date: Fri, 8 Dec 2023 13:21:20 -0700 Subject: [PATCH 02/15] lates - ready for publish --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 6f971ef..45a0a30 100644 --- a/library.properties +++ b/library.properties @@ -3,7 +3,7 @@ version=0.8.0 author=SparkFun Electronics maintainer=SparkFun Electronics sentence=A utility library that other SparkFun libraries can take advantage of. -paragraph= +paragraph=The SparkFun Toolkit provides a common set of core functionality for use across the SparkFun Arduino Driver library. Instead of each device driver library implementing a communication layers, error types and interface, the SparkFun Toolkit library is used. category=Other url=https://github.com/sparkfun/SparkFun_Toolkit architectures=* From 23d7d9a32f02987d01bef72ee3dfec7812a58ed1 Mon Sep 17 00:00:00 2001 From: Paul Date: Tue, 12 Dec 2023 10:11:49 +0000 Subject: [PATCH 03/15] See description: Add writeByte for both I2C and SPI - needed by the ADS1219 on I2C Add support for I2C restart vs. stop (many devices require a restart between set-register-address and read-register-value). This is I2C-specific and may be needed on non-Arduino platforms too. Added setStop and getStop. Corrected readRegisterRegion: the beginTransmission and endTransmission should be inside the if(bFirstInter). --- src/sfeTk/sfeTkIBus.h | 10 ++++++++++ src/sfeTk/sfeTkII2C.h | 23 ++++++++++++++++++++++- src/sfeTkArdI2C.cpp | 35 ++++++++++++++++++++++++++++------- src/sfeTkArdI2C.h | 10 ++++++++++ src/sfeTkArdSPI.cpp | 28 ++++++++++++++++++++++++++++ src/sfeTkArdSPI.h | 9 +++++++++ 6 files changed, 107 insertions(+), 8 deletions(-) diff --git a/src/sfeTk/sfeTkIBus.h b/src/sfeTk/sfeTkIBus.h index a63fe07..5499f37 100644 --- a/src/sfeTk/sfeTkIBus.h +++ b/src/sfeTk/sfeTkIBus.h @@ -46,6 +46,16 @@ const sfeTkError_t kSTkErrBusNotEnabled = kSTkErrBaseBus + 8; class sfeTkIBus { public: + /*-------------------------------------------------------------------------- + @brief Write a single byte to the device + + @param data Data to write. + + @retval sfeTkError_t - kSTkErrOk on successful execution. + + */ + virtual sfeTkError_t writeByte(uint8_t data) = 0; + /*-------------------------------------------------------------------------- @brief Write a single byte to the given register diff --git a/src/sfeTk/sfeTkII2C.h b/src/sfeTk/sfeTkII2C.h index 8ff4d14..81a5604 100644 --- a/src/sfeTk/sfeTkII2C.h +++ b/src/sfeTk/sfeTkII2C.h @@ -34,7 +34,7 @@ class sfeTkII2C : public sfeTkIBus sfeTkII2C() : _address{kNoAddress} { } - sfeTkII2C(uint8_t addr) : _address{addr} + sfeTkII2C(uint8_t addr) : _address{addr}, _stop{true} { } @@ -68,10 +68,31 @@ class sfeTkII2C : public sfeTkIBus return _address; } + /*-------------------------------------------------------------------------- + @brief setter for I2C stops (vs restarts) + + */ + virtual void setStop(uint8_t stop) + { + _stop = stop; + } + + /*-------------------------------------------------------------------------- + @brief getter for I2C stops (vs restarts) + + @retval uint8_t returns the value of "send stop" + + */ + virtual uint8_t getStop(void) + { + return _stop; + } + static constexpr uint8_t kNoAddress = 0; private: uint8_t _address; + uint8_t _stop; }; //}; diff --git a/src/sfeTkArdI2C.cpp b/src/sfeTkArdI2C.cpp index d29f8f8..dc553e1 100644 --- a/src/sfeTkArdI2C.cpp +++ b/src/sfeTkArdI2C.cpp @@ -84,6 +84,24 @@ sfeTkError_t sfeTkArdI2C::ping() return _i2cPort->endTransmission() == 0 ? kSTkErrOk : kSTkErrFail; } +//--------------------------------------------------------------------------------- +// writeByte() +// +// Writes a single byte to the device. +// +// Returns true on success, false on failure +// +sfeTkError_t sfeTkArdI2C::writeByte(uint8_t dataToWrite) +{ + if (!_i2cPort) + return kSTkErrBusNotInit; + + // do the Arduino I2C work + _i2cPort->beginTransmission(address()); + _i2cPort->write(dataToWrite); + return _i2cPort->endTransmission() == 0 ? kSTkErrOk : kSTkErrFail; +} + //--------------------------------------------------------------------------------- // writeRegisterByte() // @@ -102,6 +120,7 @@ sfeTkError_t sfeTkArdI2C::writeRegisterByte(uint8_t devReg, uint8_t dataToWrite) _i2cPort->write(dataToWrite); return _i2cPort->endTransmission() == 0 ? kSTkErrOk : kSTkErrFail; } + //--------------------------------------------------------------------------------- // writeRegisterWord() // @@ -155,7 +174,7 @@ sfeTkError_t sfeTkArdI2C::readRegisterByte(uint8_t devReg, uint8_t &dataToRead) _i2cPort->beginTransmission(address()); _i2cPort->write(devReg); - _i2cPort->endTransmission(); + _i2cPort->endTransmission((int)getStop()); _i2cPort->requestFrom(address(), (uint8_t)1); while (_i2cPort->available()) // slave may send less than requested @@ -207,21 +226,23 @@ int32_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t nu while (numBytes > 0) { - _i2cPort->beginTransmission(address()); - if (bFirstInter) { + _i2cPort->beginTransmission(address()); + _i2cPort->write(devReg); + + if (_i2cPort->endTransmission(getStop()) != 0) + return kSTkErrFail; // error with the end transmission + bFirstInter = false; } - if (_i2cPort->endTransmission() != 0) - return kSTkErrFail; // error with the end transmission - // We're chunking in data - keeping the max chunk to kMaxI2CBufferLength nChunk = numBytes > _bufferChunkSize ? _bufferChunkSize : numBytes; - nReturned = _i2cPort->requestFrom((int)address(), (int)nChunk, (int)true); + // Request the bytes. If this is the last chunk, always send a stop + nReturned = _i2cPort->requestFrom((int)address(), (int)nChunk, (int)(nChunk == numBytes ? true : getStop())); // No data returned, no dice if (nReturned == 0) diff --git a/src/sfeTkArdI2C.h b/src/sfeTkArdI2C.h index 2a9e0e0..34f3327 100644 --- a/src/sfeTkArdI2C.h +++ b/src/sfeTkArdI2C.h @@ -92,6 +92,16 @@ class sfeTkArdI2C : public sfeTkII2C */ sfeTkError_t ping(); + /*-------------------------------------------------------------------------- + @brief Write a single byte to the device + @note sfeTkIBus interface method + + @param data Data to write. + + @retval returns kStkErrOk on success + */ + sfeTkError_t writeByte(uint8_t data); + /*-------------------------------------------------------------------------- @brief Write a single byte to the given register @note sfeTkIBus interface method diff --git a/src/sfeTkArdSPI.cpp b/src/sfeTkArdSPI.cpp index 2c5fa58..c933ed3 100644 --- a/src/sfeTkArdSPI.cpp +++ b/src/sfeTkArdSPI.cpp @@ -81,6 +81,33 @@ sfeTkError_t sfeTkArdSPI::init(bool bInit) return init(cs(), bInit); } +//--------------------------------------------------------------------------------- +// writeRegisterByte() +// +// Writes a single byte to the device. +// +// Returns kSTkErrOk on success +// +sfeTkError_t sfeTkArdSPI::writeByte(uint8_t dataToWrite) +{ + + if (!_spiPort) + return kSTkErrBusNotInit; + + // Apply settings + _spiPort->beginTransaction(_sfeSPISettings); + // Signal communication start + digitalWrite(cs(), LOW); + + _spiPort->transfer(dataToWrite); + + // End communication + digitalWrite(cs(), HIGH); + _spiPort->endTransaction(); + + return kSTkErrOk; +} + //--------------------------------------------------------------------------------- // writeRegisterByte() // @@ -108,6 +135,7 @@ sfeTkError_t sfeTkArdSPI::writeRegisterByte(uint8_t devReg, uint8_t dataToWrite) return kSTkErrOk; } + //--------------------------------------------------------------------------------- // writeRegisterWord() // diff --git a/src/sfeTkArdSPI.h b/src/sfeTkArdSPI.h index 0dfe73a..d8ff00b 100644 --- a/src/sfeTkArdSPI.h +++ b/src/sfeTkArdSPI.h @@ -82,6 +82,15 @@ class sfeTkArdSPI : public sfeTkISPI */ sfeTkError_t init(SPIClass &spiPort, SPISettings &busSPISettings, uint8_t csPin, bool bInit = false); + /*-------------------------------------------------------------------------- + @brief Write a single byte to the device + + @param data Data to write. + + @retval sfeTkError_t - kSTkErrOk on success + */ + sfeTkError_t writeByte(uint8_t data); + /*-------------------------------------------------------------------------- @brief Write a single byte to the given register From 702fec6abd3fc8b1d7ecfff2ffefd125601a6f8d Mon Sep 17 00:00:00 2001 From: Kirk Benell Date: Tue, 12 Dec 2023 12:19:16 -0700 Subject: [PATCH 04/15] move stop bit init to default constructor; added constexpr for default stop bit value --- src/sfeTk/sfeTkII2C.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sfeTk/sfeTkII2C.h b/src/sfeTk/sfeTkII2C.h index 81a5604..e35d7d0 100644 --- a/src/sfeTk/sfeTkII2C.h +++ b/src/sfeTk/sfeTkII2C.h @@ -31,10 +31,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. class sfeTkII2C : public sfeTkIBus { public: - sfeTkII2C() : _address{kNoAddress} + // set the address to No address and stop bit to the default value of 1 + sfeTkII2C() : _address{kNoAddress}, _stop{kDefaultStopBit} { } - sfeTkII2C(uint8_t addr) : _address{addr}, _stop{true} + sfeTkII2C(uint8_t addr) : _address{addr} { } @@ -89,6 +90,7 @@ class sfeTkII2C : public sfeTkIBus } static constexpr uint8_t kNoAddress = 0; + static constexpr uint8_t kDefaultStopBit = 1; private: uint8_t _address; From 9b7a93aad87c95b695a08d31ece767e58b89e435 Mon Sep 17 00:00:00 2001 From: Alex Brudner <101155592+SFE-Brudnerd@users.noreply.github.com> Date: Tue, 12 Dec 2023 13:09:18 -0700 Subject: [PATCH 05/15] Update readRegisterRegion. Returns a proper error code now. ReadBytes returns number of bytes read. --- src/sfeTk/sfeTkIBus.h | 2 +- src/sfeTkArdI2C.cpp | 16 ++++++++++++---- src/sfeTkArdI2C.h | 8 +++++--- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/sfeTk/sfeTkIBus.h b/src/sfeTk/sfeTkIBus.h index 5499f37..cc8f1da 100644 --- a/src/sfeTk/sfeTkIBus.h +++ b/src/sfeTk/sfeTkIBus.h @@ -121,7 +121,7 @@ class sfeTkIBus @retval int returns kSTkErrOk on success, or kSTkErrFail code */ - virtual sfeTkError_t readRegisterRegion(uint8_t reg, uint8_t *data, size_t numBytes) = 0; + virtual sfeTkError_t readRegisterRegion(uint8_t reg, uint8_t *data, size_t numBytes, size_t *readBytes) = 0; }; //}; diff --git a/src/sfeTkArdI2C.cpp b/src/sfeTkArdI2C.cpp index dc553e1..e5bf936 100644 --- a/src/sfeTkArdI2C.cpp +++ b/src/sfeTkArdI2C.cpp @@ -200,9 +200,11 @@ sfeTkError_t sfeTkArdI2C::readRegisterWord(uint8_t devReg, uint16_t &dataToRead) if (!_i2cPort) return kSTkErrBusNotInit; - uint32_t nRead = readRegisterRegion(devReg, (uint8_t *)&dataToRead, sizeof(uint16_t)); + uint16_t nRead = 0; - return (nRead == 2 ? kSTkErrOk : kSTkErrFail); + sfeTkError_t result = readRegisterRegion(devReg, (uint8_t *)&dataToRead, sizeof(uint16_t), &nRead); + + return nRead == 2 ? kSTkErrOk : result; } //--------------------------------------------------------------------------------- @@ -212,12 +214,16 @@ sfeTkError_t sfeTkArdI2C::readRegisterWord(uint8_t devReg, uint16_t &dataToRead) // // Returns the number of bytes read, < 0 is an error // -int32_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes) +int32_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes, size_t *readBytes) { // got port if (!_i2cPort) return kSTkErrBusNotInit; + // Are buffers valid? + if (!data || !readBytes) + return kSTkErrBusNullBuffer; + uint16_t nOrig = numBytes; // original number of bytes. uint8_t nChunk; uint16_t nReturned; @@ -257,5 +263,7 @@ int32_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t nu } // end while - return nOrig - numBytes; // Success + *readBytes = nOrig - numBytes; // Bytes read. + + return (*readBytes == nOrig) ? kSTkErrOk : kSTkErrBusUnderRead; // Success } diff --git a/src/sfeTkArdI2C.h b/src/sfeTkArdI2C.h index 34f3327..94ab558 100644 --- a/src/sfeTkArdI2C.h +++ b/src/sfeTkArdI2C.h @@ -168,11 +168,13 @@ 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 to write. + @param data Data being read. + @param numBytes Number of bytes to read. + @param readBytes Number of bytes read. - @retval kStkErrOk on success + @retval kSTkErrOk on success */ - sfeTkError_t readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes); + sfeTkError_t readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes, size_t *readBytes); // Buffer size chunk getter/setter /*-------------------------------------------------------------------------- From bf890f68b1a74da21168d03f0509d2b6aa1fd608 Mon Sep 17 00:00:00 2001 From: Kirk Benell Date: Tue, 12 Dec 2023 13:18:42 -0700 Subject: [PATCH 06/15] rework on reg region and stop --- src/sfeTk/sfeTkIBus.h | 4 +++- src/sfeTk/sfeTkII2C.h | 17 ++++++++--------- src/sfeTkArdI2C.cpp | 22 ++++++++++++++-------- src/sfeTkArdI2C.h | 4 +++- src/sfeTkArdSPI.cpp | 14 +++++++++++--- src/sfeTkArdSPI.h | 4 +++- 6 files changed, 42 insertions(+), 23 deletions(-) diff --git a/src/sfeTk/sfeTkIBus.h b/src/sfeTk/sfeTkIBus.h index 5499f37..858f023 100644 --- a/src/sfeTk/sfeTkIBus.h +++ b/src/sfeTk/sfeTkIBus.h @@ -117,11 +117,13 @@ class sfeTkIBus @param devAddr The device's I2C address. @param devReg The device's register's address. @param data Data to write. + @param numBytes - length of data + @param[out] readBytes - number of bytes read @retval int returns kSTkErrOk on success, or kSTkErrFail code */ - virtual sfeTkError_t readRegisterRegion(uint8_t reg, uint8_t *data, size_t numBytes) = 0; + virtual sfeTkError_t readRegisterRegion(uint8_t reg, uint8_t *data, size_t numBytes, size_t &readBytes) = 0; }; //}; diff --git a/src/sfeTk/sfeTkII2C.h b/src/sfeTk/sfeTkII2C.h index e35d7d0..676866c 100644 --- a/src/sfeTk/sfeTkII2C.h +++ b/src/sfeTk/sfeTkII2C.h @@ -31,8 +31,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. class sfeTkII2C : public sfeTkIBus { public: - // set the address to No address and stop bit to the default value of 1 - sfeTkII2C() : _address{kNoAddress}, _stop{kDefaultStopBit} + // set the address to No address and stop flag to true + sfeTkII2C() : _address{kNoAddress}, _stop{true} { } sfeTkII2C(uint8_t addr) : _address{addr} @@ -70,31 +70,30 @@ class sfeTkII2C : public sfeTkIBus } /*-------------------------------------------------------------------------- - @brief setter for I2C stops (vs restarts) + @brief setter for I2C stop message (vs restarts) */ - virtual void setStop(uint8_t stop) + virtual void setStop(bool stop) { _stop = stop; } /*-------------------------------------------------------------------------- - @brief getter for I2C stops (vs restarts) + @brief getter for I2C stops message (vs restarts) - @retval uint8_t returns the value of "send stop" + @retval bool returns the value of "send stop" */ - virtual uint8_t getStop(void) + virtual bool stop(void) { return _stop; } static constexpr uint8_t kNoAddress = 0; - static constexpr uint8_t kDefaultStopBit = 1; private: uint8_t _address; - uint8_t _stop; + bool _stop; }; //}; diff --git a/src/sfeTkArdI2C.cpp b/src/sfeTkArdI2C.cpp index dc553e1..34127c1 100644 --- a/src/sfeTkArdI2C.cpp +++ b/src/sfeTkArdI2C.cpp @@ -174,7 +174,7 @@ sfeTkError_t sfeTkArdI2C::readRegisterByte(uint8_t devReg, uint8_t &dataToRead) _i2cPort->beginTransmission(address()); _i2cPort->write(devReg); - _i2cPort->endTransmission((int)getStop()); + _i2cPort->endTransmission(stop()); _i2cPort->requestFrom(address(), (uint8_t)1); while (_i2cPort->available()) // slave may send less than requested @@ -200,9 +200,10 @@ sfeTkError_t sfeTkArdI2C::readRegisterWord(uint8_t devReg, uint16_t &dataToRead) if (!_i2cPort) return kSTkErrBusNotInit; - uint32_t nRead = readRegisterRegion(devReg, (uint8_t *)&dataToRead, sizeof(uint16_t)); + size_t nRead; + sfeTkError_t retval = readRegisterRegion(devReg, (uint8_t *)&dataToRead, sizeof(uint16_t), nRead); - return (nRead == 2 ? kSTkErrOk : kSTkErrFail); + return (retval == kSTkErrOk && nRead == 2 ? kSTkErrOk : retval); } //--------------------------------------------------------------------------------- @@ -212,12 +213,15 @@ sfeTkError_t sfeTkArdI2C::readRegisterWord(uint8_t devReg, uint16_t &dataToRead) // // Returns the number of bytes read, < 0 is an error // -int32_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes) +sfeTkError_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes, size_t &readBytes) { + // got port if (!_i2cPort) return kSTkErrBusNotInit; + readBytes = 0; + uint16_t nOrig = numBytes; // original number of bytes. uint8_t nChunk; uint16_t nReturned; @@ -232,7 +236,7 @@ int32_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t nu _i2cPort->write(devReg); - if (_i2cPort->endTransmission(getStop()) != 0) + if (_i2cPort->endTransmission(stop())) return kSTkErrFail; // error with the end transmission bFirstInter = false; @@ -242,11 +246,11 @@ int32_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t nu 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 : getStop())); + nReturned = _i2cPort->requestFrom((int)address(), (int)nChunk, (int)(nChunk == numBytes ? true : stop())); // No data returned, no dice if (nReturned == 0) - return -1; // error + return kSTkErrBusUnderRead; // error // Copy the retrieved data chunk to the current index in the data segment for (i = 0; i < nReturned; i++) @@ -257,5 +261,7 @@ int32_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t nu } // end while - return nOrig - numBytes; // Success + readBytes = nOrig - numBytes; + + return kSTkErrOk; } diff --git a/src/sfeTkArdI2C.h b/src/sfeTkArdI2C.h index 34f3327..85a74da 100644 --- a/src/sfeTkArdI2C.h +++ b/src/sfeTkArdI2C.h @@ -169,10 +169,12 @@ class sfeTkArdI2C : public sfeTkII2C @param devReg The device's register's address. @param data Data to write. + @param numBytes - length of data + @param[out] readBytes - Number of bytes read @retval kStkErrOk on success */ - sfeTkError_t readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes); + sfeTkError_t readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes, size_t &readBytes); // Buffer size chunk getter/setter /*-------------------------------------------------------------------------- diff --git a/src/sfeTkArdSPI.cpp b/src/sfeTkArdSPI.cpp index c933ed3..e14a283 100644 --- a/src/sfeTkArdSPI.cpp +++ b/src/sfeTkArdSPI.cpp @@ -178,12 +178,18 @@ sfeTkError_t sfeTkArdSPI::writeRegisterRegion(uint8_t devReg, const uint8_t *dat sfeTkError_t sfeTkArdSPI::readRegisterByte(uint8_t devReg, uint8_t &data) { - return readRegisterRegion(devReg, &data, sizeof(data)) == 1; + size_t nRead; + sfeTkError_t retval = readRegisterRegion(devReg, (uint8_t *)&data, sizeof(data), nRead); + + return (retval == kSTkErrOk && nRead == sizeof(data) ? kSTkErrOk : retval); } sfeTkError_t sfeTkArdSPI::readRegisterWord(uint8_t devReg, uint16_t &data) { - return readRegisterRegion(devReg, (uint8_t *)&data, sizeof(data)) == 2; + size_t nRead; + sfeTkError_t retval = readRegisterRegion(devReg, (uint8_t *)&data, sizeof(data), nRead); + + return (retval == kSTkErrOk && nRead == sizeof(data) ? kSTkErrOk : retval); } //--------------------------------------------------------------------------------- // readRegisterRegion() @@ -192,7 +198,7 @@ sfeTkError_t sfeTkArdSPI::readRegisterWord(uint8_t devReg, uint16_t &data) // // Returns kSTkErrOk on success // -sfeTkError_t sfeTkArdSPI::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes) +sfeTkError_t sfeTkArdSPI::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes, size_t &readBytes) { if (!_spiPort) return kSTkErrBusNotInit; @@ -213,5 +219,7 @@ sfeTkError_t sfeTkArdSPI::readRegisterRegion(uint8_t devReg, uint8_t *data, size digitalWrite(cs(), HIGH); _spiPort->endTransaction(); + readBytes = numBytes; + return kSTkErrOk; } diff --git a/src/sfeTkArdSPI.h b/src/sfeTkArdSPI.h index d8ff00b..f386cc2 100644 --- a/src/sfeTkArdSPI.h +++ b/src/sfeTkArdSPI.h @@ -148,10 +148,12 @@ class sfeTkArdSPI : public sfeTkISPI @param devReg The device's register's address. @param data Data to write. + @param numBytes - length of data + @param[out] readBytes - Number of bytes read @retval sfeTkError_t - true on success */ - virtual sfeTkError_t readRegisterRegion(uint8_t reg, uint8_t *data, size_t numBytes); + virtual sfeTkError_t readRegisterRegion(uint8_t reg, uint8_t *data, size_t numBytes, size_t &readBytes); protected: // note: The instance data is protected, allowing access if a sub-class is From 39a5116973c91a6bf1bb3d8f194e1aeda4aeb989 Mon Sep 17 00:00:00 2001 From: Alex Brudner <101155592+SFE-Brudnerd@users.noreply.github.com> Date: Tue, 12 Dec 2023 13:21:12 -0700 Subject: [PATCH 07/15] Made ref instead of ptr. --- src/sfeTk/sfeTkIBus.h | 2 +- src/sfeTkArdI2C.cpp | 10 +++++----- src/sfeTkArdI2C.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sfeTk/sfeTkIBus.h b/src/sfeTk/sfeTkIBus.h index cc8f1da..7889d38 100644 --- a/src/sfeTk/sfeTkIBus.h +++ b/src/sfeTk/sfeTkIBus.h @@ -121,7 +121,7 @@ class sfeTkIBus @retval int returns kSTkErrOk on success, or kSTkErrFail code */ - virtual sfeTkError_t readRegisterRegion(uint8_t reg, uint8_t *data, size_t numBytes, size_t *readBytes) = 0; + virtual sfeTkError_t readRegisterRegion(uint8_t reg, uint8_t *data, size_t numBytes, size_t &readBytes) = 0; }; //}; diff --git a/src/sfeTkArdI2C.cpp b/src/sfeTkArdI2C.cpp index e5bf936..4fd1c8c 100644 --- a/src/sfeTkArdI2C.cpp +++ b/src/sfeTkArdI2C.cpp @@ -214,14 +214,14 @@ sfeTkError_t sfeTkArdI2C::readRegisterWord(uint8_t devReg, uint16_t &dataToRead) // // Returns the number of bytes read, < 0 is an error // -int32_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes, size_t *readBytes) +int32_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes, size_t &readBytes) { // got port if (!_i2cPort) return kSTkErrBusNotInit; - // Are buffers valid? - if (!data || !readBytes) + // Buffer valid? + if (!data) return kSTkErrBusNullBuffer; uint16_t nOrig = numBytes; // original number of bytes. @@ -263,7 +263,7 @@ int32_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t nu } // end while - *readBytes = nOrig - numBytes; // Bytes read. + readBytes = nOrig - numBytes; // Bytes read. - return (*readBytes == nOrig) ? kSTkErrOk : kSTkErrBusUnderRead; // Success + return (readBytes == nOrig) ? kSTkErrOk : kSTkErrBusUnderRead; // Success } diff --git a/src/sfeTkArdI2C.h b/src/sfeTkArdI2C.h index 94ab558..a95e701 100644 --- a/src/sfeTkArdI2C.h +++ b/src/sfeTkArdI2C.h @@ -174,7 +174,7 @@ class sfeTkArdI2C : public sfeTkII2C @retval kSTkErrOk on success */ - sfeTkError_t readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes, size_t *readBytes); + sfeTkError_t readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes, size_t &readBytes); // Buffer size chunk getter/setter /*-------------------------------------------------------------------------- From aba6692c25e88a89d06d04acff9ff5495bc8ab02 Mon Sep 17 00:00:00 2001 From: Alex Brudner <101155592+SFE-Brudnerd@users.noreply.github.com> Date: Tue, 12 Dec 2023 13:24:16 -0700 Subject: [PATCH 08/15] retype readRegisterRegion --- src/sfeTkArdI2C.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sfeTkArdI2C.cpp b/src/sfeTkArdI2C.cpp index 4fd1c8c..6402c68 100644 --- a/src/sfeTkArdI2C.cpp +++ b/src/sfeTkArdI2C.cpp @@ -214,7 +214,7 @@ sfeTkError_t sfeTkArdI2C::readRegisterWord(uint8_t devReg, uint16_t &dataToRead) // // Returns the number of bytes read, < 0 is an error // -int32_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes, size_t &readBytes) +sfeTkError_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes, size_t &readBytes) { // got port if (!_i2cPort) From 90ab6e02ed8ffbc229fbb548be083ae47741ba06 Mon Sep 17 00:00:00 2001 From: Alex Brudner <101155592+SFE-Brudnerd@users.noreply.github.com> Date: Wed, 13 Dec 2023 15:55:44 -0700 Subject: [PATCH 09/15] Invert default stop logic. --- src/sfeTk/sfeTkII2C.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sfeTk/sfeTkII2C.h b/src/sfeTk/sfeTkII2C.h index 676866c..f2b7d40 100644 --- a/src/sfeTk/sfeTkII2C.h +++ b/src/sfeTk/sfeTkII2C.h @@ -32,7 +32,7 @@ class sfeTkII2C : public sfeTkIBus { public: // set the address to No address and stop flag to true - sfeTkII2C() : _address{kNoAddress}, _stop{true} + sfeTkII2C() : _address{kNoAddress}, _stop{false} { } sfeTkII2C(uint8_t addr) : _address{addr} From 21e5587b6218856fb2a2e9af951cf74254e3c7b5 Mon Sep 17 00:00:00 2001 From: Alex Brudner <101155592+SFE-Brudnerd@users.noreply.github.com> Date: Wed, 13 Dec 2023 15:57:37 -0700 Subject: [PATCH 10/15] Fix comment. --- src/sfeTk/sfeTkII2C.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sfeTk/sfeTkII2C.h b/src/sfeTk/sfeTkII2C.h index f2b7d40..b9f284f 100644 --- a/src/sfeTk/sfeTkII2C.h +++ b/src/sfeTk/sfeTkII2C.h @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. class sfeTkII2C : public sfeTkIBus { public: - // set the address to No address and stop flag to true + // set the address to No address and stop flag to false sfeTkII2C() : _address{kNoAddress}, _stop{false} { } From a95c8d50b9b48ba178c5e5b1a89e079f46cf193d Mon Sep 17 00:00:00 2001 From: Alex Brudner <101155592+SFE-Brudnerd@users.noreply.github.com> Date: Wed, 13 Dec 2023 15:59:13 -0700 Subject: [PATCH 11/15] Rev library. --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 45a0a30..34cffae 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=SparkFun Toolkit -version=0.8.0 +version=0.9.0 author=SparkFun Electronics maintainer=SparkFun Electronics sentence=A utility library that other SparkFun libraries can take advantage of. From 17009ec0129f44d2507ef905010ceb04196deb1e Mon Sep 17 00:00:00 2001 From: Alex Brudner <101155592+SFE-Brudnerd@users.noreply.github.com> Date: Wed, 13 Dec 2023 17:25:38 -0700 Subject: [PATCH 12/15] Update library.properties Add include directive. --- library.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/library.properties b/library.properties index 34cffae..9ffc27b 100644 --- a/library.properties +++ b/library.properties @@ -7,3 +7,4 @@ paragraph=The SparkFun Toolkit provides a common set of core functionality for u category=Other url=https://github.com/sparkfun/SparkFun_Toolkit architectures=* +includes=SparkFun_Toolkit.h From 7a93c00f67fac71af35ec64fed6bea25f0957c45 Mon Sep 17 00:00:00 2001 From: Alex Brudner <101155592+SFE-Brudnerd@users.noreply.github.com> Date: Thu, 14 Dec 2023 08:03:10 -0700 Subject: [PATCH 13/15] Fix changes requested. Add to docs for pointing out enabling repeat start. --- docs/ar_ibus.md | 7 +++++++ src/sfeTk/sfeTkII2C.h | 4 ++-- src/sfeTkArdI2C.cpp | 6 +++--- src/sfeTkArdSPI.cpp | 8 ++++---- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/docs/ar_ibus.md b/docs/ar_ibus.md index 91a3933..85b972d 100644 --- a/docs/ar_ibus.md +++ b/docs/ar_ibus.md @@ -202,6 +202,9 @@ The following is an example of an I2C class in Arduino based on the previous pla > [!NOTE] > This class implements a ```isConnected()``` method that calls the ```ping()``` method of the I2C bus class being used, and if this passes, then calls the ```checkDeviceID()``` method of the superclass. +> [!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++ class myArduinoDriverI2C : public myDriverClass @@ -214,6 +217,10 @@ class myArduinoDriverI2C : public myDriverClass { if (_theI2CBus.init(MY_DEVICE_ADDRESS) != kSTkErrOk) return false; + + // OPTIONAL: If your device supports repeat starts. + _theI2CBus.setStop(false); + setCommunicationBus(&_theI2CBus); return myDriverClass::begin(); diff --git a/src/sfeTk/sfeTkII2C.h b/src/sfeTk/sfeTkII2C.h index b9f284f..676866c 100644 --- a/src/sfeTk/sfeTkII2C.h +++ b/src/sfeTk/sfeTkII2C.h @@ -31,8 +31,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. class sfeTkII2C : public sfeTkIBus { public: - // set the address to No address and stop flag to false - sfeTkII2C() : _address{kNoAddress}, _stop{false} + // set the address to No address and stop flag to true + sfeTkII2C() : _address{kNoAddress}, _stop{true} { } sfeTkII2C(uint8_t addr) : _address{addr} diff --git a/src/sfeTkArdI2C.cpp b/src/sfeTkArdI2C.cpp index 880afb4..11aeea5 100644 --- a/src/sfeTkArdI2C.cpp +++ b/src/sfeTkArdI2C.cpp @@ -183,10 +183,10 @@ sfeTkError_t sfeTkArdI2C::readRegisterByte(uint8_t devReg, uint8_t &dataToRead) nData++; } - if (nData == 1) // Only update outputPointer if a single byte was returned + if (nData == sizeof(uint8_t)) // Only update outputPointer if a single byte was returned dataToRead = result; - return (nData == 1 ? kSTkErrOk : kSTkErrFail); + return (nData == sizeof(uint8_t) ? kSTkErrOk : kSTkErrFail); } //--------------------------------------------------------------------------------- // readRegisterWord() @@ -203,7 +203,7 @@ sfeTkError_t sfeTkArdI2C::readRegisterWord(uint8_t devReg, uint16_t &dataToRead) size_t nRead; sfeTkError_t retval = readRegisterRegion(devReg, (uint8_t *)&dataToRead, sizeof(uint16_t), nRead); - return (retval == kSTkErrOk && nRead == 2 ? kSTkErrOk : retval); + return (retval == kSTkErrOk && nRead == sizeof(uint16_t) ? kSTkErrOk : retval); } //--------------------------------------------------------------------------------- diff --git a/src/sfeTkArdSPI.cpp b/src/sfeTkArdSPI.cpp index e14a283..62f91c8 100644 --- a/src/sfeTkArdSPI.cpp +++ b/src/sfeTkArdSPI.cpp @@ -179,17 +179,17 @@ sfeTkError_t sfeTkArdSPI::writeRegisterRegion(uint8_t devReg, const uint8_t *dat sfeTkError_t sfeTkArdSPI::readRegisterByte(uint8_t devReg, uint8_t &data) { size_t nRead; - sfeTkError_t retval = readRegisterRegion(devReg, (uint8_t *)&data, sizeof(data), nRead); + sfeTkError_t retval = readRegisterRegion(devReg, (uint8_t *)&data, sizeof(uint8_t), nRead); - return (retval == kSTkErrOk && nRead == sizeof(data) ? kSTkErrOk : retval); + return (retval == kSTkErrOk && nRead == sizeof(uint8_t) ? kSTkErrOk : retval); } sfeTkError_t sfeTkArdSPI::readRegisterWord(uint8_t devReg, uint16_t &data) { size_t nRead; - sfeTkError_t retval = readRegisterRegion(devReg, (uint8_t *)&data, sizeof(data), nRead); + sfeTkError_t retval = readRegisterRegion(devReg, (uint8_t *)&data, sizeof(uint16_t), nRead); - return (retval == kSTkErrOk && nRead == sizeof(data) ? kSTkErrOk : retval); + return (retval == kSTkErrOk && nRead == sizeof(uint16_t) ? kSTkErrOk : retval); } //--------------------------------------------------------------------------------- // readRegisterRegion() From d361f4ba4a959ce6677ddf9b693704e85fcb376a Mon Sep 17 00:00:00 2001 From: Alex Brudner <101155592+SFE-Brudnerd@users.noreply.github.com> Date: Thu, 14 Dec 2023 08:06:22 -0700 Subject: [PATCH 14/15] Add forgotten != 0 --- src/sfeTkArdI2C.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sfeTkArdI2C.cpp b/src/sfeTkArdI2C.cpp index 11aeea5..608b612 100644 --- a/src/sfeTkArdI2C.cpp +++ b/src/sfeTkArdI2C.cpp @@ -240,7 +240,7 @@ sfeTkError_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size _i2cPort->write(devReg); - if (_i2cPort->endTransmission(stop())) + if (_i2cPort->endTransmission(stop() != 0)) return kSTkErrFail; // error with the end transmission bFirstInter = false; From 3a30596c7676e773cecbe997555227f8e8ae63cb Mon Sep 17 00:00:00 2001 From: Alex Brudner <101155592+SFE-Brudnerd@users.noreply.github.com> Date: Thu, 14 Dec 2023 08:07:37 -0700 Subject: [PATCH 15/15] fix --- src/sfeTkArdI2C.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sfeTkArdI2C.cpp b/src/sfeTkArdI2C.cpp index 608b612..0f994be 100644 --- a/src/sfeTkArdI2C.cpp +++ b/src/sfeTkArdI2C.cpp @@ -240,7 +240,7 @@ sfeTkError_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size _i2cPort->write(devReg); - if (_i2cPort->endTransmission(stop() != 0)) + if (_i2cPort->endTransmission(stop()) != 0) return kSTkErrFail; // error with the end transmission bFirstInter = false;