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