Skip to content

Commit 02bc0f1

Browse files
Merge pull request #31 from sparkfun/add_16bit_register_support
Add 16bit register support
2 parents ef8752b + 0adf922 commit 02bc0f1

File tree

5 files changed

+241
-48
lines changed

5 files changed

+241
-48
lines changed

src/sfeTk/sfeTkIBus.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ class sfeTkIBus
7878
*/
7979
virtual sfeTkError_t writeRegisterWord(uint8_t devReg, uint16_t data) = 0;
8080

81+
8182
/*--------------------------------------------------------------------------
8283
@brief Writes a number of bytes starting at the given register's address.
8384
@@ -90,6 +91,19 @@ class sfeTkIBus
9091
*/
9192
virtual sfeTkError_t writeRegisterRegion(uint8_t devReg, const uint8_t *data, size_t length) = 0;
9293

94+
/*--------------------------------------------------------------------------
95+
@brief Writes a number of bytes starting at the given register's 16-bit address.
96+
97+
@param devAddr The device's 16-bit address/pin
98+
param devReg The device's register's address.
99+
@param data Data to write.
100+
101+
@retval sfeTkError_t kSTkErrOk on successful execution
102+
103+
*/
104+
virtual sfeTkError_t writeRegister16Region(uint16_t devReg, uint8_t *data, size_t length) = 0;
105+
106+
93107
/*--------------------------------------------------------------------------
94108
@brief Read a single byte from the given register
95109
@@ -124,6 +138,20 @@ class sfeTkIBus
124138
125139
*/
126140
virtual sfeTkError_t readRegisterRegion(uint8_t reg, uint8_t *data, size_t numBytes, size_t &readBytes) = 0;
141+
142+
/*--------------------------------------------------------------------------
143+
@brief Reads a block of data from the given 16-bit register address.
144+
145+
@param reg The device's 16 bit register's address.
146+
@param data Data to write.
147+
@param numBytes - length of data
148+
@param[out] readBytes - number of bytes read
149+
150+
@retval int returns kSTkErrOk on success, or kSTkErrFail code
151+
152+
*/
153+
virtual sfeTkError_t readRegister16Region(uint16_t reg, uint8_t *data, size_t numBytes) = 0;
154+
127155
};
128156

129157
//};

src/sfeTkArdI2C.cpp

Lines changed: 102 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ sfeTkError_t sfeTkArdI2C::writeRegisterByte(uint8_t devReg, uint8_t dataToWrite)
124124
//---------------------------------------------------------------------------------
125125
// writeRegisterWord()
126126
//
127-
// Writes a world to a given register.
127+
// Writes a word to a given register.
128128
//
129129
// Returns true on success, false on failure
130130
//
@@ -137,83 +137,58 @@ sfeTkError_t sfeTkArdI2C::writeRegisterWord(uint8_t devReg, uint16_t dataToWrite
137137
}
138138

139139
//---------------------------------------------------------------------------------
140-
// writeRegisterRegion()
140+
// writeRegisterRegionAddress()
141141
//
142-
// Writes an array of bytes to a given register on the target address
142+
// Writes an array of bytes of specified length to a given register on the
143+
// target address
143144
//
144145
// Returns the number of bytes written, < 0 is an error
145146
//
146-
sfeTkError_t sfeTkArdI2C::writeRegisterRegion(uint8_t devReg, const uint8_t *data, size_t length)
147+
sfeTkError_t sfeTkArdI2C::writeRegisterRegionAddress(uint8_t *devReg, size_t regLength, const uint8_t *data, size_t length)
147148
{
148149
if (!_i2cPort)
149150
return kSTkErrBusNotInit;
150151

151152
_i2cPort->beginTransmission(address());
152-
_i2cPort->write(devReg);
153+
_i2cPort->write(devReg, regLength);
153154
_i2cPort->write(data, (int)length);
154155

155156
return _i2cPort->endTransmission() ? kSTkErrFail : kSTkErrOk;
156157
}
157158

158159
//---------------------------------------------------------------------------------
159-
// readRegisterByte()
160+
// writeRegisterRegion()
160161
//
161-
// Reads a byte to a given register.
162+
// Writes an array of bytes to a given register on the target address
162163
//
163-
// Returns true on success, false on failure
164+
// Returns the number of bytes written, < 0 is an error
164165
//
165-
sfeTkError_t sfeTkArdI2C::readRegisterByte(uint8_t devReg, uint8_t &dataToRead)
166+
sfeTkError_t sfeTkArdI2C::writeRegisterRegion(uint8_t devReg, const uint8_t *data, size_t length)
166167
{
167-
if (!_i2cPort)
168-
return kSTkErrBusNotInit;
169-
170-
// Return value
171-
uint8_t result = 0;
172-
173-
int nData = 0;
174-
175-
_i2cPort->beginTransmission(address());
176-
_i2cPort->write(devReg);
177-
_i2cPort->endTransmission(stop());
178-
_i2cPort->requestFrom(address(), (uint8_t)1);
179-
180-
while (_i2cPort->available()) // slave may send less than requested
181-
{
182-
result = _i2cPort->read(); // receive a byte as a proper uint8_t
183-
nData++;
184-
}
185-
186-
if (nData == sizeof(uint8_t)) // Only update outputPointer if a single byte was returned
187-
dataToRead = result;
188-
189-
return (nData == sizeof(uint8_t) ? kSTkErrOk : kSTkErrFail);
168+
return writeRegisterRegionAddress(&devReg, 1, data, length);
190169
}
170+
191171
//---------------------------------------------------------------------------------
192-
// readRegisterWord()
172+
// write16BitRegisterRegion()
193173
//
194-
// Reads a world to a given register.
174+
// Writes an array of bytes to a given 16-bit register on the target address
195175
//
196-
// Returns true on success, false on failure
176+
// Returns the number of bytes written, < 0 is an error
197177
//
198-
sfeTkError_t sfeTkArdI2C::readRegisterWord(uint8_t devReg, uint16_t &dataToRead)
178+
sfeTkError_t sfeTkArdI2C::writeRegister16Region(uint16_t devReg, uint8_t *data, size_t length)
199179
{
200-
if (!_i2cPort)
201-
return kSTkErrBusNotInit;
202-
203-
size_t nRead;
204-
sfeTkError_t retval = readRegisterRegion(devReg, (uint8_t *)&dataToRead, sizeof(uint16_t), nRead);
205-
206-
return (retval == kSTkErrOk && nRead == sizeof(uint16_t) ? kSTkErrOk : retval);
180+
devReg = ((devReg << 8) & 0xff00) | ((devReg >> 8) & 0x00ff);
181+
return writeRegisterRegionAddress((uint8_t*)&devReg, 2, data, length);
207182
}
208183

209184
//---------------------------------------------------------------------------------
210-
// readRegisterRegion()
185+
// readRegisterRegionAnyAddress()
211186
//
212-
// Reads an array of bytes to a given register on the target address
187+
// Reads an array of bytes to a register on the target address
213188
//
214-
// Returns the number of bytes read, < 0 is an error
189+
// Returns the number of bytes written, < 0 is an error
215190
//
216-
sfeTkError_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes, size_t &readBytes)
191+
sfeTkError_t sfeTkArdI2C::readRegisterRegionAnyAddress(uint8_t *devReg, size_t regLength, uint8_t *data, size_t numBytes, size_t &readBytes)
217192
{
218193

219194
// got port
@@ -238,7 +213,7 @@ sfeTkError_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size
238213
{
239214
_i2cPort->beginTransmission(address());
240215

241-
_i2cPort->write(devReg);
216+
_i2cPort->write(devReg, regLength);
242217

243218
if (_i2cPort->endTransmission(stop()) != 0)
244219
return kSTkErrFail; // error with the end transmission
@@ -269,3 +244,82 @@ sfeTkError_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size
269244

270245
return (readBytes == nOrig) ? kSTkErrOk : kSTkErrBusUnderRead; // Success
271246
}
247+
248+
249+
//---------------------------------------------------------------------------------
250+
// readRegisterByte()
251+
//
252+
// Reads a byte to a given register.
253+
//
254+
// Returns true on success, false on failure
255+
//
256+
sfeTkError_t sfeTkArdI2C::readRegisterByte(uint8_t devReg, uint8_t &dataToRead)
257+
{
258+
if (!_i2cPort)
259+
return kSTkErrBusNotInit;
260+
261+
// Return value
262+
uint8_t result = 0;
263+
264+
int nData = 0;
265+
266+
_i2cPort->beginTransmission(address());
267+
_i2cPort->write(devReg);
268+
_i2cPort->endTransmission(stop());
269+
_i2cPort->requestFrom(address(), (uint8_t)1);
270+
271+
while (_i2cPort->available()) // slave may send less than requested
272+
{
273+
result = _i2cPort->read(); // receive a byte as a proper uint8_t
274+
nData++;
275+
}
276+
277+
if (nData == sizeof(uint8_t)) // Only update outputPointer if a single byte was returned
278+
dataToRead = result;
279+
280+
return (nData == sizeof(uint8_t) ? kSTkErrOk : kSTkErrFail);
281+
}
282+
283+
//---------------------------------------------------------------------------------
284+
// readRegisterWord()
285+
//
286+
// Reads a word to a given register.
287+
//
288+
// Returns true on success, false on failure
289+
//
290+
sfeTkError_t sfeTkArdI2C::readRegisterWord(uint8_t devReg, uint16_t &dataToRead)
291+
{
292+
if (!_i2cPort)
293+
return kSTkErrBusNotInit;
294+
295+
size_t nRead;
296+
sfeTkError_t retval = readRegisterRegion(devReg, (uint8_t *)&dataToRead, sizeof(uint16_t), nRead);
297+
298+
return (retval == kSTkErrOk && nRead == sizeof(uint16_t) ? kSTkErrOk : retval);
299+
}
300+
301+
//---------------------------------------------------------------------------------
302+
// readRegisterRegion()
303+
//
304+
// Reads an array of bytes to a given register on the target address
305+
//
306+
// Returns the number of bytes read, < 0 is an error
307+
//
308+
sfeTkError_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes, size_t &readBytes)
309+
{
310+
return readRegisterRegionAnyAddress(&devReg, 1, data, numBytes, readBytes);
311+
}
312+
313+
//---------------------------------------------------------------------------------
314+
// read16BitRegisterRegion()
315+
//
316+
// Reads an array of bytes to a given 16-bit register on the target address
317+
//
318+
// Returns the number of bytes read, < 0 is an error
319+
//
320+
sfeTkError_t sfeTkArdI2C::readRegister16Region(uint16_t devReg, uint8_t *data, size_t numBytes)
321+
{
322+
size_t readBytes = 0;
323+
devReg = ((devReg << 8) & 0xff00) | ((devReg >> 8) & 0x00ff);
324+
return readRegisterRegionAnyAddress((uint8_t*)&devReg, 2, data, numBytes, readBytes);
325+
}

src/sfeTkArdI2C.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,19 @@ class sfeTkArdI2C : public sfeTkII2C
137137
*/
138138
virtual sfeTkError_t writeRegisterRegion(uint8_t devReg, const uint8_t *data, size_t length);
139139

140+
/*--------------------------------------------------------------------------
141+
@brief Writes a number of bytes starting at the given register's 16-bit address.
142+
143+
@param devAddr The device's 16-bit address/pin
144+
param devReg The device's register's address.
145+
@param data Data to write.
146+
147+
@retval sfeTkError_t kSTkErrOk on successful execution
148+
149+
*/
150+
sfeTkError_t writeRegister16Region(uint16_t devReg, uint8_t *data, size_t length);
151+
152+
140153
/*--------------------------------------------------------------------------
141154
@brief Reads a byte of data from the given register.
142155
@@ -177,6 +190,19 @@ class sfeTkArdI2C : public sfeTkII2C
177190
*/
178191
sfeTkError_t readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes, size_t &readBytes);
179192

193+
/*--------------------------------------------------------------------------
194+
@brief Reads a block of data from the given 16-bit register address.
195+
196+
@param reg The device's 16 bit register's address.
197+
@param data Data to write.
198+
@param numBytes - length of data
199+
@param[out] readBytes - number of bytes read
200+
201+
@retval int returns kSTkErrOk on success, or kSTkErrFail code
202+
203+
*/
204+
sfeTkError_t readRegister16Region(uint16_t reg, uint8_t *data, size_t numBytes);
205+
180206
// Buffer size chunk getter/setter
181207
/*--------------------------------------------------------------------------
182208
@brief set the buffer chunk size
@@ -211,6 +237,10 @@ class sfeTkArdI2C : public sfeTkII2C
211237
TwoWire *_i2cPort;
212238

213239
private:
240+
sfeTkError_t writeRegisterRegionAddress(uint8_t *devReg, size_t regLength, const uint8_t *data, size_t length);
241+
242+
sfeTkError_t readRegisterRegionAnyAddress(uint8_t *devReg, size_t regLength, uint8_t *data, size_t numBytes, size_t &readBytes);
243+
214244
static constexpr size_t kDefaultBufferChunk = 32;
215245

216246
// the I2C buffer chunker size

src/sfeTkArdSPI.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,29 @@ sfeTkError_t sfeTkArdSPI::writeRegisterRegion(uint8_t devReg, const uint8_t *dat
176176
return kSTkErrOk;
177177
}
178178

179+
// 16 bit address version ...
180+
sfeTkError_t sfeTkArdSPI::writeRegister16Region(uint16_t devReg, const uint8_t *data, size_t length)
181+
{
182+
if (!_spiPort)
183+
return kSTkErrBusNotInit;
184+
185+
// Apply settings before work
186+
_spiPort->beginTransaction(_sfeSPISettings);
187+
188+
// Signal communication start
189+
digitalWrite(cs(), LOW);
190+
_spiPort->transfer16(devReg);
191+
192+
for (size_t i = 0; i < length; i++)
193+
_spiPort->transfer(*data++);
194+
195+
// End communication
196+
digitalWrite(cs(), HIGH);
197+
_spiPort->endTransaction();
198+
199+
return kSTkErrOk;
200+
}
201+
179202
sfeTkError_t sfeTkArdSPI::readRegisterByte(uint8_t devReg, uint8_t &data)
180203
{
181204
size_t nRead;
@@ -223,3 +246,36 @@ sfeTkError_t sfeTkArdSPI::readRegisterRegion(uint8_t devReg, uint8_t *data, size
223246

224247
return kSTkErrOk;
225248
}
249+
250+
//---------------------------------------------------------------------------------
251+
// readRegister16Region()
252+
//
253+
// Reads an array of bytes to a given a 16 bit register on the target address
254+
//
255+
// Returns kSTkErrOk on success
256+
//
257+
sfeTkError_t sfeTkArdSPI::readRegister16Region(uint16_t devReg, uint8_t *data, size_t numBytes, size_t &readBytes)
258+
{
259+
if (!_spiPort)
260+
return kSTkErrBusNotInit;
261+
262+
// Apply settings
263+
_spiPort->beginTransaction(_sfeSPISettings);
264+
265+
// Signal communication start
266+
digitalWrite(cs(), LOW);
267+
268+
// A leading "1" must be added to transfer with devRegister to indicate a "read"
269+
_spiPort->transfer16(devReg | kSPIReadBit);
270+
271+
for (size_t i = 0; i < numBytes; i++)
272+
*data++ = _spiPort->transfer(0x00);
273+
274+
// End transaction
275+
digitalWrite(cs(), HIGH);
276+
_spiPort->endTransaction();
277+
278+
readBytes = numBytes;
279+
280+
return kSTkErrOk;
281+
}

0 commit comments

Comments
 (0)