When a CAN mapping is configured in bit mode and the data on the bus is formatted Least Significant Bit the swap_uint_length function does an endian (byte level) swap when in fact it needs to be doing a Most Significant Bit to Least Significant Bit conversion.
Lets use the decimal number 4099 as an example. 4099 encoded in binary is:
1000000000011 (13 bits Most Significant Bit)
"On the wire" it will be:
1100000000001 (13 bits Least Significant Bit)
Entering the canmapping_extract_value function that Least Significant Bit value will be embedded in that 64bit uint somewhere (as indicated by length/offset), carved out by a bitmask to a uint_32 native to the host processor.
What I believe is happening is the swap_uint_length is treating that 13 bit value as a 16 bit short and doing a byte swap so swap_unit_length is basically doing the following
00011000 00000001 (0-padded to 16 bit value from above)
00000001 00011000 (byte swapped)
which equals 280 not 4099
What I believe needs to happen is that the whole uint_16 needs to be shifted left to a byte boundary (in this case 3 bits) and the order of the BITS in each byte reversed. Then the bytes themselves need to be swapped.
Demonstrated:
00011000 00000001 (0-padded to 16 bit value from above)
11000000 00001000 (whole uint_16 value shifted left by 3 bits to)
00000011 00010000 (both upper and lower bytes BITS rotated)
00010000 00000011 (byte swapped)
|
raw_value = swap_uint_length(raw_value, length); |