@@ -155,6 +155,27 @@ sfeTkError_t sfeTkArdI2C::writeRegisterRegion(uint8_t devReg, const uint8_t *dat
155155 return _i2cPort->endTransmission () ? kSTkErrFail : kSTkErrOk ;
156156}
157157
158+ // ---------------------------------------------------------------------------------
159+ // write16BitRegisterRegion()
160+ //
161+ // Writes an array of bytes to a given 16-bit register on the target address
162+ //
163+ // Returns the number of bytes written, < 0 is an error
164+ //
165+ sfeTkError_t sfeTkArdI2C::write16BitRegisterRegion (uint16_t devReg, const uint8_t *data, size_t length)
166+ {
167+ if (!_i2cPort)
168+ return kSTkErrBusNotInit ;
169+
170+ _i2cPort->beginTransmission (address ());
171+ _i2cPort->write ((devReg >> 8 ) & 0xff );
172+ _i2cPort->write (devReg & 0xff );
173+ _i2cPort->write (data, (int )length);
174+
175+ return _i2cPort->endTransmission () ? kSTkErrFail : kSTkErrOk ;
176+ }
177+
178+
158179// ---------------------------------------------------------------------------------
159180// readRegisterByte()
160181//
@@ -269,3 +290,71 @@ sfeTkError_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size
269290
270291 return (readBytes == nOrig) ? kSTkErrOk : kSTkErrBusUnderRead ; // Success
271292}
293+
294+
295+
296+
297+ // ---------------------------------------------------------------------------------
298+ // read16BitRegisterRegion()
299+ //
300+ // Reads an array of bytes to a given 16-bit register on the target address
301+ //
302+ // Returns the number of bytes read, < 0 is an error
303+ //
304+ sfeTkError_t sfeTkArdI2C::read16BitRegisterRegion (uint16_t devReg, uint8_t *data, size_t numBytes, size_t &readBytes)
305+ {
306+
307+ // got port
308+ if (!_i2cPort)
309+ return kSTkErrBusNotInit ;
310+
311+ // Buffer valid?
312+ if (!data)
313+ return kSTkErrBusNullBuffer ;
314+
315+ readBytes = 0 ;
316+
317+ uint16_t nOrig = numBytes; // original number of bytes.
318+ uint8_t nChunk;
319+ uint16_t nReturned;
320+ uint16_t i; // counter in loop
321+ bool bFirstInter = true ; // Flag for first iteration - used to send devRegister
322+
323+ while (numBytes > 0 )
324+ {
325+ if (bFirstInter)
326+ {
327+ _i2cPort->beginTransmission (address ());
328+
329+ _i2cPort->write ((devReg >> 8 ) & 0xff );
330+ _i2cPort->write (devReg & 0xff );
331+
332+ if (_i2cPort->endTransmission (stop ()) != 0 )
333+ return kSTkErrFail ; // error with the end transmission
334+
335+ bFirstInter = false ;
336+ }
337+
338+ // We're chunking in data - keeping the max chunk to kMaxI2CBufferLength
339+ nChunk = numBytes > _bufferChunkSize ? _bufferChunkSize : numBytes;
340+
341+ // Request the bytes. If this is the last chunk, always send a stop
342+ nReturned = _i2cPort->requestFrom ((int )address (), (int )nChunk, (int )(nChunk == numBytes ? true : stop ()));
343+
344+ // No data returned, no dice
345+ if (nReturned == 0 )
346+ return kSTkErrBusUnderRead ; // error
347+
348+ // Copy the retrieved data chunk to the current index in the data segment
349+ for (i = 0 ; i < nReturned; i++)
350+ *data++ = _i2cPort->read ();
351+
352+ // Decrement the amount of data received from the overall data request amount
353+ numBytes = numBytes - nReturned;
354+
355+ } // end while
356+
357+ readBytes = nOrig - numBytes; // Bytes read.
358+
359+ return (readBytes == nOrig) ? kSTkErrOk : kSTkErrBusUnderRead ; // Success
360+ }
0 commit comments