einride/can-go

Not understanding the SetBit operations for Big Endian

gadams999 opened this issue · 1 comments

Hi,

I'm looking to create a Frame with uint16 values converted to big endian, e.g., the value of 256 represented in the CAN data as (hex): 01 00.

I've looked at doing this via:

tx := socketcan.NewTransmitter(canCon)
a_uint16_var := 256
frame2.ID = 0xd0
frame2.Length = 2
frame2.Data.SetUnsignedBitsBigEndian(0, 16, uint64(a_uint16_var))
_ = tx.TransmitFrame(context.Background(), frame2)

Incorrect Result: vcan0 0D0 [2] 00 02

The documentation for Data looks like this is the correct format, and it's working when using SetUnsignedBitsLittleEndian (with byte order properly reversed).

However, the results I get passing the uint16 value come back with strange values in frame.Data.

Right now I can work around this by creating my own byte array, converting, then copying into frame.Data:

a_uint16_var := 256
tx := socketcan.NewTransmitter(canCon)
frame2.ID = 0xd0
frame2.Length = 2
buf := make([]byte, 2)
binary.BigEndian.PutUint16(buf, speed)
copy(frame2.Data[:], buf)
_ = tx.TransmitFrame(context.Background(), frame2)

Correct Result: vcan0 0D0 [2] 01 00

This works for some straight forward applications, but I saw all the error checking you've included in the Data type functions I'd to take advantage of. I looked for some more expanded examples, but didn't find anything to help me better understand the content of creating and sending frames from data in a big endian way.

Hi @gadams999!

The issue you're facing is due to the fact that the library uses consistent bit numbering. That means when using big endian byte order, the most significant bit in a byte will be bit 0 (the leftmost bit), and when using little endian byte order, the most significant bit will be bit 7 (the rightmost bit).

What you are trying to do only works when using inconsistent bit numbering. See https://github.com/ebroecker/canmatrix/wiki/signal-Byteorder for details on bit numbering.

I'm thinking about adding an option to set default bit numbering when using the library, because signals can be specified differently in different database formats.