The most elegant MSB LSB swap?
Erlend
Posts: 612
in Propeller 1
Is there a more elegant/efficient/legible way to do a swap of MSB and LSB. In this case I need it to communicate with a chip that reads and writes in the "reverse" order. (please do not start an 'endian war in this thread).
Erlend
value.BYTE[0]<< 8 + value>> 8
Erlend
Comments
... or not. Dunno.
-Phil
-Phil
Erlend
-Phil
serial.Nstring(@wordValue,2)
That would point to the low byte and send it first.
x and y are bytes, ^ is the bitwise XOR operator.
x := x ^ y
y := y ^ x
x := x ^ y
now the bytes are swapped.
No mystery intended. I was just curious to learn if there were a simpler way. The 'chip' is the IR sensor MLX90614. My curiousity was with regards to Spin and swapping byte order in general - interfacing to this chip just triggered me to ask the question.
appears to be the best answer.
Erlend
ReadPage(SCL, devSel, addrReg, @data, 2) . ' to read a word
WritePage(SCL, devSel, addrReg, @data, 2) . ' to write a word
Isn't that what you want, no byte swap required?
That said, the order of bytes presented by different i2c devices is all over the place. Many do send most significant first, or have data like time strings in an order opposite of what you'd like. I posit that the order should be handled as an option within any full-featured i2c object, a choice of most or least significant byte first. I'd write it to interpret a negative byte count as an endedness swap.
p.s. I'm not trying to start an endedness war -- we have to work with it however it is.
Thanks for that info. As Tracy mentioned that chip send its words in the same order as the Propeller handles it in memory so there isn't any need for byte swapping in this and most cases, although not all cases.
More legible: compiles to the same amount of bytes as your code
More efficient: Is 2 bytes shorter
Elegance is a matter of taste, so no proposal for that...
Andy
I like this one. Elegant, compact, and efficient.
Erlend
(this is just for my curiosity and learning, I can easily do a &FF first to clean it)
Erlend
It's probably not necessary, but it ensures the order of operations.
As for making sure that the upper-word bits are set / not set, it depends on how the values are used. Ultimately some code somewhere is sending bits out to a device. If that code only deals with the lower 16 bits then no, you don't need to worry.
-Phil
Yes, the result only needs the 16 bits, but when I tested in my particular code, as I feared, the 'value' variable had 'trash' in it's upper word bits, so I had to do a & $FF on it, so that that trash did not get shifted into the lower word - which I guess is only good coding practise anyway.
Erlend
Transmitting LittleEndian serial data is a simple case of transmitting from the lsb and shifting right, then repeat until the word is all shifted out. As opposed to BigEndian where you transmit the msb and shift left instead.
To receive, input bits at the opposite end to transmitting: LE receives at msb and shifts right, while BE receives at lsb and shifts left.
If not doing the above then you'll be up for bit swapping the whole word, but that's still not a byte swap.
I got "85" and "170"
The situation is pretty simple; I have a (library) method that puts out MSB first, then LSB. The receiver wants LSB first, then MSB. How to fix this? Either write a new method that does LSB-MSB - or - swap the bytes before transmitting. I chose the latter, and I have asked for advice on how to do that in the best way. I did not expect to get so much good answers, and I still think is the best answer. A valuable side effect is all the stuff I learn from this thread.
Erlend