Skip to content

Commit 39a44e1

Browse files
authored
Merge pull request #29 from sparkfun/readregion_api_change
Readregion api change
2 parents 702fec6 + 3a30596 commit 39a44e1

10 files changed

+65
-28
lines changed

.gitattributes

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Auto detect text files and perform LF normalization
2+
* text=auto

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# VSCode directories
2+
.vscode
3+

docs/ar_ibus.md

+7
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,9 @@ The following is an example of an I2C class in Arduino based on the previous pla
202202
> [!NOTE]
203203
> 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.
204204
205+
> [!NOTE]
206+
> 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.
207+
205208
```c++
206209
207210
class myArduinoDriverI2C : public myDriverClass
@@ -214,6 +217,10 @@ class myArduinoDriverI2C : public myDriverClass
214217
{
215218
if (_theI2CBus.init(MY_DEVICE_ADDRESS) != kSTkErrOk)
216219
return false;
220+
221+
// OPTIONAL: If your device supports repeat starts.
222+
_theI2CBus.setStop(false);
223+
217224
setCommunicationBus(&_theI2CBus);
218225
219226
return myDriverClass::begin();

library.properties

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
name=SparkFun Toolkit
2-
version=0.8.0
2+
version=0.9.0
33
author=SparkFun Electronics
44
maintainer=SparkFun Electronics
55
sentence=A utility library that other SparkFun libraries can take advantage of.
66
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.
77
category=Other
88
url=https://github.com/sparkfun/SparkFun_Toolkit
99
architectures=*
10+
includes=SparkFun_Toolkit.h

src/sfeTk/sfeTkIBus.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,13 @@ class sfeTkIBus
117117
@param devAddr The device's I2C address.
118118
@param devReg The device's register's address.
119119
@param data Data to write.
120+
@param numBytes - length of data
121+
@param[out] readBytes - number of bytes read
120122
121123
@retval int returns kSTkErrOk on success, or kSTkErrFail code
122124
123125
*/
124-
virtual sfeTkError_t readRegisterRegion(uint8_t reg, uint8_t *data, size_t numBytes) = 0;
126+
virtual sfeTkError_t readRegisterRegion(uint8_t reg, uint8_t *data, size_t numBytes, size_t &readBytes) = 0;
125127
};
126128

127129
//};

src/sfeTk/sfeTkII2C.h

+8-9
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3131
class sfeTkII2C : public sfeTkIBus
3232
{
3333
public:
34-
// set the address to No address and stop bit to the default value of 1
35-
sfeTkII2C() : _address{kNoAddress}, _stop{kDefaultStopBit}
34+
// set the address to No address and stop flag to true
35+
sfeTkII2C() : _address{kNoAddress}, _stop{true}
3636
{
3737
}
3838
sfeTkII2C(uint8_t addr) : _address{addr}
@@ -70,31 +70,30 @@ class sfeTkII2C : public sfeTkIBus
7070
}
7171

7272
/*--------------------------------------------------------------------------
73-
@brief setter for I2C stops (vs restarts)
73+
@brief setter for I2C stop message (vs restarts)
7474
7575
*/
76-
virtual void setStop(uint8_t stop)
76+
virtual void setStop(bool stop)
7777
{
7878
_stop = stop;
7979
}
8080

8181
/*--------------------------------------------------------------------------
82-
@brief getter for I2C stops (vs restarts)
82+
@brief getter for I2C stops message (vs restarts)
8383
84-
@retval uint8_t returns the value of "send stop"
84+
@retval bool returns the value of "send stop"
8585
8686
*/
87-
virtual uint8_t getStop(void)
87+
virtual bool stop(void)
8888
{
8989
return _stop;
9090
}
9191

9292
static constexpr uint8_t kNoAddress = 0;
93-
static constexpr uint8_t kDefaultStopBit = 1;
9493

9594
private:
9695
uint8_t _address;
97-
uint8_t _stop;
96+
bool _stop;
9897
};
9998

10099
//};

src/sfeTkArdI2C.cpp

+20-10
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ sfeTkError_t sfeTkArdI2C::readRegisterByte(uint8_t devReg, uint8_t &dataToRead)
174174

175175
_i2cPort->beginTransmission(address());
176176
_i2cPort->write(devReg);
177-
_i2cPort->endTransmission((int)getStop());
177+
_i2cPort->endTransmission(stop());
178178
_i2cPort->requestFrom(address(), (uint8_t)1);
179179

180180
while (_i2cPort->available()) // slave may send less than requested
@@ -183,10 +183,10 @@ sfeTkError_t sfeTkArdI2C::readRegisterByte(uint8_t devReg, uint8_t &dataToRead)
183183
nData++;
184184
}
185185

186-
if (nData == 1) // Only update outputPointer if a single byte was returned
186+
if (nData == sizeof(uint8_t)) // Only update outputPointer if a single byte was returned
187187
dataToRead = result;
188188

189-
return (nData == 1 ? kSTkErrOk : kSTkErrFail);
189+
return (nData == sizeof(uint8_t) ? kSTkErrOk : kSTkErrFail);
190190
}
191191
//---------------------------------------------------------------------------------
192192
// readRegisterWord()
@@ -200,9 +200,10 @@ sfeTkError_t sfeTkArdI2C::readRegisterWord(uint8_t devReg, uint16_t &dataToRead)
200200
if (!_i2cPort)
201201
return kSTkErrBusNotInit;
202202

203-
uint32_t nRead = readRegisterRegion(devReg, (uint8_t *)&dataToRead, sizeof(uint16_t));
203+
size_t nRead;
204+
sfeTkError_t retval = readRegisterRegion(devReg, (uint8_t *)&dataToRead, sizeof(uint16_t), nRead);
204205

205-
return (nRead == 2 ? kSTkErrOk : kSTkErrFail);
206+
return (retval == kSTkErrOk && nRead == sizeof(uint16_t) ? kSTkErrOk : retval);
206207
}
207208

208209
//---------------------------------------------------------------------------------
@@ -212,12 +213,19 @@ sfeTkError_t sfeTkArdI2C::readRegisterWord(uint8_t devReg, uint16_t &dataToRead)
212213
//
213214
// Returns the number of bytes read, < 0 is an error
214215
//
215-
int32_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes)
216+
sfeTkError_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes, size_t &readBytes)
216217
{
218+
217219
// got port
218220
if (!_i2cPort)
219221
return kSTkErrBusNotInit;
220222

223+
// Buffer valid?
224+
if (!data)
225+
return kSTkErrBusNullBuffer;
226+
227+
readBytes = 0;
228+
221229
uint16_t nOrig = numBytes; // original number of bytes.
222230
uint8_t nChunk;
223231
uint16_t nReturned;
@@ -232,7 +240,7 @@ int32_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t nu
232240

233241
_i2cPort->write(devReg);
234242

235-
if (_i2cPort->endTransmission(getStop()) != 0)
243+
if (_i2cPort->endTransmission(stop()) != 0)
236244
return kSTkErrFail; // error with the end transmission
237245

238246
bFirstInter = false;
@@ -242,11 +250,11 @@ int32_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t nu
242250
nChunk = numBytes > _bufferChunkSize ? _bufferChunkSize : numBytes;
243251

244252
// Request the bytes. If this is the last chunk, always send a stop
245-
nReturned = _i2cPort->requestFrom((int)address(), (int)nChunk, (int)(nChunk == numBytes ? true : getStop()));
253+
nReturned = _i2cPort->requestFrom((int)address(), (int)nChunk, (int)(nChunk == numBytes ? true : stop()));
246254

247255
// No data returned, no dice
248256
if (nReturned == 0)
249-
return -1; // error
257+
return kSTkErrBusUnderRead; // error
250258

251259
// Copy the retrieved data chunk to the current index in the data segment
252260
for (i = 0; i < nReturned; i++)
@@ -257,5 +265,7 @@ int32_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t nu
257265

258266
} // end while
259267

260-
return nOrig - numBytes; // Success
268+
readBytes = nOrig - numBytes; // Bytes read.
269+
270+
return (readBytes == nOrig) ? kSTkErrOk : kSTkErrBusUnderRead; // Success
261271
}

src/sfeTkArdI2C.h

+6-3
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,14 @@ class sfeTkArdI2C : public sfeTkII2C
168168
@note This method is virtual to allow it to be overridden to support a device that requires a unique impl
169169
170170
@param devReg The device's register's address.
171-
@param data Data to write.
171+
@param data Data being read.
172+
@param numBytes Number of bytes to read.
173+
@param[out] readBytes - Number of bytes read
172174
173-
@retval kStkErrOk on success
175+
176+
@retval kSTkErrOk on success
174177
*/
175-
sfeTkError_t readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes);
178+
sfeTkError_t readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes, size_t &readBytes);
176179

177180
// Buffer size chunk getter/setter
178181
/*--------------------------------------------------------------------------

src/sfeTkArdSPI.cpp

+11-3
Original file line numberDiff line numberDiff line change
@@ -178,12 +178,18 @@ sfeTkError_t sfeTkArdSPI::writeRegisterRegion(uint8_t devReg, const uint8_t *dat
178178

179179
sfeTkError_t sfeTkArdSPI::readRegisterByte(uint8_t devReg, uint8_t &data)
180180
{
181-
return readRegisterRegion(devReg, &data, sizeof(data)) == 1;
181+
size_t nRead;
182+
sfeTkError_t retval = readRegisterRegion(devReg, (uint8_t *)&data, sizeof(uint8_t), nRead);
183+
184+
return (retval == kSTkErrOk && nRead == sizeof(uint8_t) ? kSTkErrOk : retval);
182185
}
183186

184187
sfeTkError_t sfeTkArdSPI::readRegisterWord(uint8_t devReg, uint16_t &data)
185188
{
186-
return readRegisterRegion(devReg, (uint8_t *)&data, sizeof(data)) == 2;
189+
size_t nRead;
190+
sfeTkError_t retval = readRegisterRegion(devReg, (uint8_t *)&data, sizeof(uint16_t), nRead);
191+
192+
return (retval == kSTkErrOk && nRead == sizeof(uint16_t) ? kSTkErrOk : retval);
187193
}
188194
//---------------------------------------------------------------------------------
189195
// readRegisterRegion()
@@ -192,7 +198,7 @@ sfeTkError_t sfeTkArdSPI::readRegisterWord(uint8_t devReg, uint16_t &data)
192198
//
193199
// Returns kSTkErrOk on success
194200
//
195-
sfeTkError_t sfeTkArdSPI::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes)
201+
sfeTkError_t sfeTkArdSPI::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes, size_t &readBytes)
196202
{
197203
if (!_spiPort)
198204
return kSTkErrBusNotInit;
@@ -213,5 +219,7 @@ sfeTkError_t sfeTkArdSPI::readRegisterRegion(uint8_t devReg, uint8_t *data, size
213219
digitalWrite(cs(), HIGH);
214220
_spiPort->endTransaction();
215221

222+
readBytes = numBytes;
223+
216224
return kSTkErrOk;
217225
}

src/sfeTkArdSPI.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,12 @@ class sfeTkArdSPI : public sfeTkISPI
148148
149149
@param devReg The device's register's address.
150150
@param data Data to write.
151+
@param numBytes - length of data
152+
@param[out] readBytes - Number of bytes read
151153
152154
@retval sfeTkError_t - true on success
153155
*/
154-
virtual sfeTkError_t readRegisterRegion(uint8_t reg, uint8_t *data, size_t numBytes);
156+
virtual sfeTkError_t readRegisterRegion(uint8_t reg, uint8_t *data, size_t numBytes, size_t &readBytes);
155157

156158
protected:
157159
// note: The instance data is protected, allowing access if a sub-class is

0 commit comments

Comments
 (0)