@@ -22,6 +22,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
22
*/
23
23
24
24
#include " sfeTkArdI2C.h"
25
+ #include < cstddef>
26
+ #include < cstdint>
25
27
26
28
// ---------------------------------------------------------------------------------
27
29
// init()
@@ -87,7 +89,7 @@ sfeTkError_t sfeTkArdI2C::ping()
87
89
// ---------------------------------------------------------------------------------
88
90
// writeByte()
89
91
//
90
- // Sends a single byte to the device.
92
+ // Writes a single byte to the device, without indexing to a register .
91
93
//
92
94
// Returns true on success, false on failure
93
95
//
@@ -105,7 +107,7 @@ sfeTkError_t sfeTkArdI2C::writeByte(uint8_t dataToWrite)
105
107
// ---------------------------------------------------------------------------------
106
108
// writeWord()
107
109
//
108
- // Sends a word to the device.
110
+ // Writes a word to the device, without indexing to a register .
109
111
//
110
112
// Returns true on success, false on failure
111
113
//
@@ -120,13 +122,12 @@ sfeTkError_t sfeTkArdI2C::writeWord(uint16_t dataToWrite)
120
122
// ---------------------------------------------------------------------------------
121
123
// writeBlock()
122
124
//
123
- // Sends an array of data to the device.
125
+ // Writes a word to the device, without indexing to a register .
124
126
//
125
127
// Returns true on success, false on failure
126
128
//
127
129
sfeTkError_t sfeTkArdI2C::writeBlock (const uint8_t *data, size_t length)
128
130
{
129
- int nData = 0 ;
130
131
if (!_i2cPort)
131
132
return kSTkErrBusNotInit ;
132
133
@@ -218,6 +219,121 @@ sfeTkError_t sfeTkArdI2C::writeRegister16Region(uint16_t devReg, const uint8_t *
218
219
return writeRegisterRegionAddress ((uint8_t *)&devReg, 2 , data, length);
219
220
}
220
221
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
+
221
337
// ---------------------------------------------------------------------------------
222
338
223
339
/* *
0 commit comments