Little Endian to Big Endian
bboy8012
Posts: 153
How would I convert bytes being recieved from little endian to big endian? Or just get MSB first instead of LSB? I have been trying to use the shift operators, but no avail. Thanks
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Comments
http://forums.parallax.com/showthread.php?p=616821
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
To learn about programming, you might start with the various tutorials you can access via the "Propeller: Getting Started and Key Thread Index" sticky thread. The Propeller Education Kit tutorials also help introduce you to Spin programming.
There really isn't a tutorial on "bit restructuring" since it's really about binary arithmetic including bit shifts. You should be able to find this sort of stuff in any introductory programming course, especially one dealing with embedded systems or hardware design as well. A number of universities now have free lectures on-line including some introductory programming courses. The Apple iTunes Store has some of these and some you can find through the various Universities' sites. Try places like MIT and Carnegie-Mellon for a start.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
First you use the REV to convert the whole 32 bits. This will of course change the order of the bytes inside the long. But then you can use the BYTE[noparse][[/noparse]@var_adr] to restore the order of the bytes again.
var_32 := var_32 >< 32
byte_buffer:=byte[noparse][[/noparse] @var_32 ]
byte[noparse][[/noparse] @var_32 ]:=byte[noparse][[/noparse] @var_32+3 ]
byte[noparse][[/noparse] @var_32+3 ]:=byte_buffer
byte_buffer:=byte[noparse][[/noparse] @var_32+1 ]
byte[noparse][[/noparse] @var_32+1 ]:=byte[noparse][[/noparse] @var_32+2 ]
byte[noparse][[/noparse] @var_32+2 ]:=byte_buffer
(Didn't try that cause my prop is at home and I'm at work)
Post Edited (MagIO2) : 4/8/2009 2:23:39 PM GMT
In SPIN, to swap the WORDs from Little Endian to Big Endian within a single LONG:
In SPIN, to swap the BYTEs from Little Endian to Big Endian within a single LONG:
In SPIN, to swap the NIBBLE's from Little Endian to Big Endian within a single LONG:
Note: Define both 'Dest' and 'Source' as longs ; temp1 and temp2 are also defined as longs
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.
To explain a little, if you look at the top example I gave you'll see five lines of code doing the swap. The first line swaps every pair of adjacent bits, the second every pair of two adjacent bits, the third every pair of 4 adjacent bits and so on. By picking your combination of lines you can achieve just about any conceivable swapping arrangement.
The nice thing about these methods is that they translate to very tight assembler needing no loops.
Nevertheless, the code given in the last post is not converted to assembler at all, it's converted to bytecode. Each assignment and each boolean operation is converted in bytecode which has to be interpreted and you need constants that need to be stored as well. The pure conversion will at least result in 6 bytecode commands. So we have 12 commands all in all.
Using the .byte[noparse][[/noparse]0]-.byte to access the longs bytes seems to be more effective for me for both, memory and speed. A loop as given in Beaus example will at least optimize memory usage. I'm not sure about speed, because there we have the loop against not needed assignments to the byte_buffer.
My original example is switching the bits keeping the byte-order. But if you remove the line with ><, it is switching the byte-order keeping the bits.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
to stay in your example
an incomming string stored in a bytearray
defined as
VAR
Byte arrayBuf[noparse][[/noparse]8]
and this byte-array contains "1ABC3EFG"
this means
arrayBuf[noparse][[/noparse] 0] contains the "1"
arrayBuf[noparse][[/noparse] 1] contains the "A"
arrayBuf[noparse][[/noparse] 2] contains the "B"
arrayBuf[noparse][[/noparse] 3] contains the "C"
arrayBuf[noparse][[/noparse] 4] contains the "3"
arrayBuf[noparse][[/noparse] 5] contains the "E"
arrayBuf[noparse][[/noparse] 6] contains the "F"
arrayBuf[noparse][[/noparse] 7] contains the "G"
so after this explanation. Could you please post a more specific question what your problem is ?
best regards
Stefan
Post Edited (StefanL38) : 4/9/2009 6:26:14 AM GMT
arrayBuff[noparse]/noparse = "10003000"
temp1 := @arrayBuff[noparse][[/noparse]4]
temp2 := @arrayBuff?? I want to only have the arrayBuff[noparse][[/noparse]0] to arrayBuff[noparse][[/noparse]3]
print.Str(temp1) displays "3000"
print.Str(temp2) should display only "1000" not "10003000"
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Why send CR then and not 0? Because you could attach your propeller with any terminal program and feed it with numbers. No need to write a program for that until everything is tested.
If you don't want to send CR, and you are sure you only have 4 digit numbers, you can of course add the string terminator to the bytestream in the receiving function:
if bytecount==3
arrayBuff[noparse][[/noparse] bytecount++ ]:=0
Using string on the other hand means the number of bytes is variable. 4 up to 12 bytes have to be transferred (including the CR). If you want to do more than only display the numbers, you have to convert the strings back to words. So, if speed is an issue you should go back think about the words to be transferred binary. Your propeller would be the first one that is not able to switch a word from MSB to LSB endian numbers ;o)
You see, there are a lot of ways to solve problems. Some only work, some are optimized to the needs (for example speed or codesize).
Let's go back to the endian problem:
You receive 2 words which is 4 bytes and store it in a receive buffer.
byte rec_buf[noparse][[/noparse] 4 ]
word word1, word2
The sender sends the numbers $03E8 and $0BB8 in the following order (edit: read your post again .. it's send in·little endian and prop is using·big endian, right?):
$03, $E8, $0B, $B8
$E8, $03, $B8, $0B
So, that's now the content of your rec_buf. To convert it to LSB you simply do (edit: but that does not change anything here for words):
word1.byte[noparse][[/noparse] 0 ] := rec_buf[noparse][[/noparse] 1 ]
word1.byte[noparse][[/noparse] 1 ] := rec_buf[noparse][[/noparse] 0 ]
word2.byte[noparse][[/noparse] 0 ] := rec_buf[noparse][[/noparse] 3 ]
word2.byte[noparse][[/noparse] 1 ] := rec_buf[noparse][[/noparse] 2 ]
Post Edited (MagIO2) : 4/9/2009 6:20:18 AM GMT
MagIO did already mention i
strings are TERMINATED by a zero.
This why you get the reuslt
arrayBuff[noparse]/noparse = "10003000"
temp1 := @arrayBuff
temp2 := @arrayBuff?? I want to only have the arrayBuff[noparse][[/noparse]0] to arrayBuff
print.Str(temp1) displays "3000"
print.Str(temp2) should display only "1000" not "10003000"
print.Str(temp2) runs though until it finds the first zero-VALUE $00 and then it stops
and this is after the third "0" of "3000" "10003000"
This means you have to add a zero at the end of EVERY bytesequence that should be treadted as a str using a .str-method
best regards
Stefan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔