@@ -22,6 +22,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2222*/
2323
2424#include " sfeTkArdI2C.h"
25+ #include < cstddef>
26+ #include < cstdint>
2527
2628// ---------------------------------------------------------------------------------
2729// init()
@@ -87,7 +89,7 @@ sfeTkError_t sfeTkArdI2C::ping()
8789// ---------------------------------------------------------------------------------
8890// writeByte()
8991//
90- // Sends a single byte to the device.
92+ // Writes a single byte to the device, without indexing to a register .
9193//
9294// Returns true on success, false on failure
9395//
@@ -105,7 +107,7 @@ sfeTkError_t sfeTkArdI2C::writeByte(uint8_t dataToWrite)
105107// ---------------------------------------------------------------------------------
106108// writeWord()
107109//
108- // Sends a word to the device.
110+ // Writes a word to the device, without indexing to a register .
109111//
110112// Returns true on success, false on failure
111113//
@@ -120,13 +122,12 @@ sfeTkError_t sfeTkArdI2C::writeWord(uint16_t dataToWrite)
120122// ---------------------------------------------------------------------------------
121123// writeBlock()
122124//
123- // Sends an array of data to the device.
125+ // Writes a word to the device, without indexing to a register .
124126//
125127// Returns true on success, false on failure
126128//
127129sfeTkError_t sfeTkArdI2C::writeBlock (const uint8_t *data, size_t length)
128130{
129- int nData = 0 ;
130131 if (!_i2cPort)
131132 return kSTkErrBusNotInit ;
132133
@@ -218,6 +219,121 @@ sfeTkError_t sfeTkArdI2C::writeRegister16Region(uint16_t devReg, const uint8_t *
218219 return writeRegisterRegionAddress ((uint8_t *)&devReg, 2 , data, length);
219220}
220221
222+ // ---------------------------------------------------------------------------------
223+ // readByte()
224+ //
225+ // Reads a byte from the device, without indexing to a register.
226+ //
227+ // Returns true on success, false on failure
228+ //
229+ sfeTkError_t sfeTkArdI2C::readByte (uint8_t dataToWrite, uint8_t &dataToRead)
230+ {
231+ if (!_i2cPort)
232+ return kSTkErrBusNotInit ;
233+
234+ // Return value
235+ uint8_t result = 0 ;
236+
237+ int nData = 0 ;
238+
239+ _i2cPort->beginTransmission (address ());
240+ _i2cPort->write (dataToWrite);
241+ _i2cPort->endTransmission (stop ());
242+ _i2cPort->requestFrom (address (), (uint8_t )1 );
243+
244+ while (_i2cPort->available ()) // slave may send less than requested
245+ {
246+ result = _i2cPort->read (); // receive a byte as a proper uint8_t
247+ nData++;
248+ }
249+
250+ if (nData == sizeof (uint8_t )) // Only update outputPointer if a single byte was returned
251+ dataToRead = result;
252+
253+ return (nData == sizeof (uint8_t ) ? kSTkErrOk : kSTkErrFail );
254+ }
255+
256+
257+ // ---------------------------------------------------------------------------------
258+ // readWord()
259+ //
260+ // Reads a word from the device, without indexing to a register.
261+ //
262+ // Returns true on success, false on failure
263+ //
264+ sfeTkError_t sfeTkArdI2C::readWord (uint8_t dataToWrite, uint16_t &dataToRead)
265+ {
266+ if (!_i2cPort)
267+ return kSTkErrBusNotInit ;
268+
269+ size_t nRead;
270+ sfeTkError_t retval = readBlock (dataToWrite, (uint8_t *)&dataToRead, sizeof (uint16_t ), nRead);
271+
272+ return (retval == kSTkErrOk && nRead == sizeof (uint16_t ) ? kSTkErrOk : retval);
273+ }
274+
275+ // ---------------------------------------------------------------------------------
276+ // readBlock()
277+ //
278+ // Reads a block of data from the device, without indexing to a register.
279+ //
280+ // Returns the number of bytes written, < 0 is an error
281+ //
282+ sfeTkError_t sfeTkArdI2C::readBlock (uint8_t dataToWrite, uint8_t *data, size_t numBytes, size_t &readBytes)
283+ {
284+
285+ // got port
286+ if (!_i2cPort)
287+ return kSTkErrBusNotInit ;
288+
289+ // Buffer valid?
290+ if (!data)
291+ return kSTkErrBusNullBuffer ;
292+
293+ readBytes = 0 ;
294+
295+ uint16_t nOrig = numBytes; // original number of bytes.
296+ uint8_t nChunk;
297+ uint16_t nReturned;
298+ uint16_t i; // counter in loop
299+ bool bFirstInter = true ; // Flag for first iteration - used to send devRegister
300+
301+ while (numBytes > 0 )
302+ {
303+ if (bFirstInter)
304+ {
305+ _i2cPort->beginTransmission (address ());
306+ _i2cPort->write (dataToWrite);
307+ if (_i2cPort->endTransmission (stop ()) != 0 )
308+ return kSTkErrFail ; // error with the end transmission
309+
310+ bFirstInter = false ;
311+ }
312+
313+ // We're chunking in data - keeping the max chunk to kMaxI2CBufferLength
314+ nChunk = numBytes > _bufferChunkSize ? _bufferChunkSize : numBytes;
315+
316+ // Request the bytes. If this is the last chunk, always send a stop
317+ nReturned = _i2cPort->requestFrom ((int )address (), (int )nChunk, (int )(nChunk == numBytes ? true : stop ()));
318+
319+ // No data returned, no dice
320+ if (nReturned == 0 )
321+ return kSTkErrBusUnderRead ; // error
322+
323+ // Copy the retrieved data chunk to the current index in the data segment
324+ for (i = 0 ; i < nReturned; i++)
325+ *data++ = _i2cPort->read ();
326+
327+ // Decrement the amount of data received from the overall data request amount
328+ numBytes = numBytes - nReturned;
329+
330+ } // end while
331+
332+ readBytes = nOrig - numBytes; // Bytes read.
333+
334+ return (readBytes == nOrig) ? kSTkErrOk : kSTkErrBusUnderRead ; // Success
335+ }
336+
221337// ---------------------------------------------------------------------------------
222338
223339/* *
0 commit comments