Skip to content

Commit e5fa8c1

Browse files
committed
add logic to detect system byte order at runtime; used this logic on the I2C bus to determine if uint16_t transfers need to swap bytes; note- Arduino SPI does this correctly
1 parent ec4aaad commit e5fa8c1

File tree

4 files changed

+44
-8
lines changed

4 files changed

+44
-8
lines changed

src/sfeTk/sfeTkIBus.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2727

2828
#pragma once
2929

30-
#include "sfeTkError.h"
30+
#include "sfeToolkit.h"
3131
#include <stddef.h>
3232

3333
/**

src/sfeTk/sfeToolkit.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,19 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3030
@brief Common include file for the core of the SparkFun Electronics Toolkit
3131
*/
3232
#include "sfeTkError.h"
33+
34+
/**
35+
@brief The byte order of the system
36+
*/
37+
typedef enum
38+
{
39+
SFETK_BIG_ENDIAN = 0x01,
40+
SFETK_LITTLE_ENDIAN = 0x00
41+
} sfeTKByteOrder_t;
42+
43+
// Runtime check for system byte order
44+
constexpr sfeTKByteOrder_t systemByteOrder(void)
45+
{
46+
uint16_t i = 1;
47+
return *((uint8_t *)&i) == 0 ? SFETK_BIG_ENDIAN : SFETK_LITTLE_ENDIAN;
48+
}

src/sfeTkArdI2C.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -222,12 +222,16 @@ sfeTkError_t sfeTkArdI2C::writeRegister16Region(uint16_t devReg, const uint8_t *
222222
//
223223
sfeTkError_t sfeTkArdI2C::writeRegister16Region16(uint16_t devReg, const uint16_t *data, size_t length)
224224
{
225-
devReg = ((devReg << 8) & 0xff00) | ((devReg >> 8) & 0x00ff);
225+
// if the system byte order is the same as the desired order, just send the buffer
226+
if (systemByteOrder() == _byteOrder)
227+
return writeRegisterRegionAddress((uint8_t *)&devReg, 2, (uint8_t *)data, length * 2);
226228

229+
// okay, we need to swap
230+
devReg = ((devReg << 8) & 0xff00) | ((devReg >> 8) & 0x00ff);
227231
uint16_t data16[length];
228-
// TODO determine local endianess and convert if needed
229232
for (size_t i = 0; i < length; i++)
230233
data16[i] = ((data[i] << 8) & 0xff00) | ((data[i] >> 8) & 0x00ff);
234+
231235
return writeRegisterRegionAddress((uint8_t *)&devReg, 2, (uint8_t *)data16, length * 2);
232236
}
233237

@@ -384,11 +388,14 @@ sfeTkError_t sfeTkArdI2C::readRegister16Region(uint16_t devReg, uint8_t *data, s
384388
//
385389
sfeTkError_t sfeTkArdI2C::readRegister16Region16(uint16_t devReg, uint16_t *data, size_t numBytes, size_t &readBytes)
386390
{
387-
devReg = ((devReg << 8) & 0xff00) | ((devReg >> 8) & 0x00ff);
391+
// if the system byte order is the same as the desired order, flip the address
392+
if (systemByteOrder() != _byteOrder)
393+
devReg = ((devReg << 8) & 0xff00) | ((devReg >> 8) & 0x00ff);
394+
388395
sfeTkError_t status = readRegisterRegionAnyAddress((uint8_t *)&devReg, 2, (uint8_t *)data, numBytes * 2, readBytes);
389396

390-
// TODO determine local endianess and convert if needed
391-
if (status == kSTkErrOk)
397+
// Do we need to flip the byte order?
398+
if (status == kSTkErrOk && systemByteOrder() != _byteOrder)
392399
{
393400
for (size_t i = 0; i < numBytes; i++)
394401
data[i] = ((data[i] << 8) & 0xff00) | ((data[i] >> 8) & 0x00ff);

src/sfeTkArdI2C.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@ class sfeTkArdI2C : public sfeTkII2C
4141
{
4242
public:
4343
/**
44-
@brief Constructor
44+
@brief Constructor
4545
*/
46-
sfeTkArdI2C(void) : _i2cPort(nullptr), _bufferChunkSize{kDefaultBufferChunk}
46+
47+
sfeTkArdI2C(void) : _i2cPort(nullptr), _bufferChunkSize{kDefaultBufferChunk}, _byteOrder{SFETK_LITTLE_ENDIAN}
4748
{
4849
}
4950
/**
@@ -291,6 +292,15 @@ class sfeTkArdI2C : public sfeTkII2C
291292
return _bufferChunkSize;
292293
}
293294

295+
/**
296+
* @brief Set the byte order for multi-byte data transfers
297+
*
298+
*/
299+
void setByteOrder(sfeTKByteOrder_t order)
300+
{
301+
_byteOrder = order;
302+
}
303+
294304
protected:
295305
// note: The wire port is protected, allowing access if a sub-class is
296306
// created to implement a special read/write routine
@@ -309,4 +319,7 @@ class sfeTkArdI2C : public sfeTkII2C
309319

310320
/** The I2C buffer chunker - chunk size*/
311321
size_t _bufferChunkSize;
322+
323+
/** flag to manage byte swapping */
324+
sfeTKByteOrder_t _byteOrder;
312325
};

0 commit comments

Comments
 (0)