Writing, Splitting, and Joining data - My first attempt
First off I would like to state that I am just starting to learn more spin so my code is fairly bloated and may look messy, but it works for my purposes so I am releasing it here. Advanced spin users will most likely have much better code so please post on how to do anything in the following code in a cleaner fashion if you feel like it.
The intent of this code to just copy the function needed into another application, not to be included as an object. I hope, as a beginner, it is a fair attempt at getting things to function the way I wanted them to....
Here it is:
The intent of this code to just copy the function needed into another application, not to be included as an object. I hope, as a beginner, it is a fair attempt at getting things to function the way I wanted them to....
Here it is:
{{
/////////////////////////////////////////////////////////////////////////
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
FileName: DataSplitterV1_0_Test.spin
Purpose: Splits/Joins data up to 32 bits
Copyright: Copyright (c) 2011 Jorge Joaquin Pareja ( http://WhatsAvailable.org )
ThanksTo: MagIO2 for helping me write bits using less code.
WARNING: This code is written by a fairly new user of spin, Some or all of
the code may be written in a better fashion using much less code.
This is my first attempt at doing all this so it may be a bit
messy and bloated.
I am releasing this source code, License Free, as Public Domain, use it as
you wish. You claim all responsibility for using this code.
I did all this so I can understand how to move bits of memory/data without
corrupting it and without asking for help with this in any form aside from
the Propeller Manual. By doing this I am learning how to alter bits that
will eventualy go to an external device over i2c/seirial or other protocol.
This was all sparked from my "Using the full PPDB" project on the forums,
and the desire to read the 4x4 matrix keypad using a PCA9555 bus extender
over i2c while updating the 16 segment display at the same time.
I will keep this file with that project for future referance.
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
/////////////////////////////////////////////////////////////////////////
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
This spin program is basicaly a playground for putting bits where I
want them, it is not intended to be included as an object. Instead
the functions needed should be copied to your programs main object.
All functions/methods have Documentation comments stating what is
required for them to work individualy, feel free to alter the names
to have more meaning for your specific application.
I have left 3 split functions up to you to toy with by examining
the other split functions and how they work with shifting. The
functions I left blank are as follows:
* SplitLongToBits
* SplitWordToBits
* SplitByteToBits
All you need to do is examine the code apply some spin and add the
required variables to store each bit. All values are in Binary
throughout my code, however you can use Base Ten or Base Sixteen if
you wish.
PUB Main uses constants starting with the word Beginning_ solely for
testing each function/method, feel free to alter the value of the
constants as it will not affect anything other than data to work
with and test.
Use Parallax Serial Terminal to view the results.
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
}}
CON
' Start running at 80Mhz
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
' The baudrate of the serial terminal
myBaud = 115200 ' only required for DEBUG
' Data Used for testing
' The following constants can be removed if your done with testing
Beginning_Long = %11111100_00000101__10000000_00000001
Beginning_Word = %11111100_00000101
Beginning_Byte = %0011_0101 '%11111100
Beginning_Nibble = %0110
' Data used for writing each bit, likewise all these can be
' removed after testing
Beginning_bit0 = %1
Beginning_bit1 = %0
Beginning_bit2 = %0
Beginning_bit3 = %0
Beginning_bit4 = %0
Beginning_bit5 = %0
Beginning_bit6 = %0
Beginning_bit7 = %0
Beginning_bit8 = %0
Beginning_bit9 = %0
Beginning_bit10 = %0
Beginning_bit11 = %0
Beginning_bit12 = %0
Beginning_bit13 = %0
Beginning_bit14 = %0
Beginning_bit15 = %1
Beginning_bit16 = %1
Beginning_bit17 = %0
Beginning_bit18 = %1
Beginning_bit19 = %0
Beginning_bit20 = %0
Beginning_bit21 = %0
Beginning_bit22 = %0
Beginning_bit23 = %0
Beginning_bit24 = %0
Beginning_bit25 = %0
Beginning_bit26 = %1
Beginning_bit27 = %1
Beginning_bit28 = %1
Beginning_bit29 = %1
Beginning_bit30 = %1
Beginning_bit31 = %1
VAR
' The following are required for this all to work. You can remove anything you are
' not going to use with the exception of what is required by the methods you use
' from this object. Read the Documentation for each method used to determine what
' you need.
'
LONG LongOut
WORD WordOut1, WordOut0
BYTE ByteOut3, ByteOut2, ByteOut1, ByteOut0
BYTE NibbleOut7, NibbleOut6, NibbleOut5, NibbleOut4, {
} NibbleOut3, NibbleOut2, NibbleOut1, NibbleOut0
BYTE BitOut31, BitOut30, BitOut29, BitOut28, BitOut27, BitOut26, BitOut25, BitOut24, {
} BitOut23, BitOut22, BitOut21, BitOut20, BitOut19, BitOut18, BitOut17, BitOut16, {
} BitOut15, BitOut14, BitOut13, BitOut12, BitOut11, BitOut10, BitOut9, BitOut8, {
} BitOut7, BitOut6, BitOut5, BitOut4, BitOut3, BitOut2, BitOut1, BitOut0, {
} BitOut
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' WARNING: the following Variables are required by most functions, don't remove
' unless you know what you are doing. They are here to ensure the bits of
' larger datatypes are not carried over to smaller datatypes when the
' smaller datatype is shifted right and/or shifted left again (Overflow?).
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
LONG tmpLong0, tmpLong1
' for the byte datatypes
BYTE tmpByte0, tmpByte1, tmpByte2, tmpByte3
' for the word datatypes
WORD tmpWord0, tmpWord1
' for the nibble datatypes
BYTE tmpNibble0, tmpNibble1, tmpNibble2, tmpNibble3, tmpNibble4, tmpNibble5, tmpNibble6, tmpNibble7
' for the bit datatypes
BYTE tmpBit0, tmpBit1, tmpBit2, tmpBit3, tmpBit4, tmpBit5, tmpBit6, tmpBit7, {
} tmpBit8, tmpBit9, tmpBit10, tmpBit11, tmpBit12, tmpBit13, tmpBit14, tmpBit15, {
} tmpBit16, tmpBit17, tmpBit18, tmpBit19, tmpBit20, tmpBit21, tmpBit22, tmpBit23, {
} tmpBit24, tmpBit25, tmpBit26, tmpBit27, tmpBit28, tmpBit29, tmpBit30, tmpBit31
OBJ
DEBUG : "Parallax Serial Terminal"
PUB Main | x
'' this main method just tests all the other methods. For the most part
'' you can remove all the DEBUG.* stuff and it will still work, you just
'' wont be able to see the work being done.
''
'' If you use this object in your own code, you can completely remove
'' this PUB Main.
''
DEBUG.Start(myBaud)
DEBUG.Str(String("Beginning Long data is "))
DEBUG.Bin(Beginning_Long, 32)
DEBUG.NewLine
DEBUG.Str(String("Running SplitLong to split a long into 2 words"))
DEBUG.NewLine
SplitLong(Beginning_Long)
DEBUG.Bin(WordOut0, 16)
DEBUG.NewLine
DEBUG.Bin(WordOut1, 16)
DEBUG.NewLine
DEBUG.NewLine
DEBUG.Str(String("Running SplitLong_ex to split a long into 4 bytes"))
DEBUG.NewLine
SplitLong_ex(Beginning_Long)
DEBUG.Bin(ByteOut0, 8)
DEBUG.NewLine
DEBUG.Bin(ByteOut1, 8)
DEBUG.NewLine
DEBUG.Bin(ByteOut2, 8)
DEBUG.NewLine
DEBUG.Bin(ByteOut3, 8)
DEBUG.NewLine
DEBUG.NewLine
DEBUG.Str(String("Beginning Word data is "))
DEBUG.Bin(Beginning_Word, 16)
DEBUG.NewLine
DEBUG.Str(String("Running SplitWord to split a word into 2 bytes"))
DEBUG.NewLine
SplitWord(Beginning_Word)
DEBUG.Bin(ByteOut0, 8)
DEBUG.NewLine
DEBUG.Bin(ByteOut1, 8)
DEBUG.NewLine
DEBUG.NewLine
DEBUG.Str(String("Beginning Byte data is "))
DEBUG.Bin(Beginning_Byte, 8)
DEBUG.NewLine
DEBUG.Str(String("Running SplitByte to split a byte into 2 nibbles"))
DEBUG.NewLine
SplitByte(Beginning_Byte)
DEBUG.Bin(NibbleOut0, 4)
DEBUG.NewLine
DEBUG.Bin(NibbleOut1, 4)
DEBUG.NewLine
DEBUG.NewLine
DEBUG.Str(String("Testing Join Methods"))
DEBUG.NewLine
DEBUG.Str(String("Running Join32 to join two words into a long"))
DEBUG.NewLine
Join32(Beginning_Word, Beginning_Word)
DEBUG.Bin(LongOut, 32)
DEBUG.NewLine
DEBUG.NewLine
DEBUG.Str(String("Running Join16 to join two bytes into a word"))
DEBUG.NewLine
Join16(Beginning_Word, Beginning_Word)
DEBUG.Bin(WordOut0, 16)
DEBUG.NewLine
DEBUG.NewLine
DEBUG.Str(String("Running Join8 to join two nibbles into a byte"))
DEBUG.NewLine
Join8(Beginning_Nibble, Beginning_Nibble)
DEBUG.Bin(ByteOut0, 8)
DEBUG.NewLine
DEBUG.NewLine
DEBUG.Str(String("Testing Bit Reading Methods"))
DEBUG.NewLine
DEBUG.Str(String("Running BitFromLong to get each bit of long data"))
DEBUG.NewLine
DEBUG.Str(String("Beginning Long data is "))
DEBUG.Bin(Beginning_Long, 32)
DEBUG.NewLine
REPEAT x from 0 to 31
DEBUG.Str(String("Reading bit "))
DEBUG.Dec(x)
DEBUG.Str(String(" is = "))
DEBUG.Bin(BitFromLong(Beginning_Long, x), 1)
DEBUG.NewLine
DEBUG.NewLine
DEBUG.NewLine
DEBUG.Str(String("Running BitFromWord to get each bit of word data"))
DEBUG.NewLine
DEBUG.Str(String("Beginning Word data is "))
DEBUG.Bin(Beginning_Word, 16)
DEBUG.NewLine
REPEAT x from 0 to 15
DEBUG.Str(String("Reading bit "))
DEBUG.Dec(x)
DEBUG.Str(String(" is = "))
DEBUG.Bin(BitFromWord(Beginning_Word, x), 1)
DEBUG.NewLine
DEBUG.NewLine
DEBUG.NewLine
DEBUG.Str(String("Running BitFromByte to get each bit of byte data"))
DEBUG.NewLine
DEBUG.Str(String("Beginning Byte data is "))
DEBUG.Bin(Beginning_Byte, 8)
DEBUG.NewLine
REPEAT x from 0 to 7
DEBUG.Str(String("Reading bit "))
DEBUG.Dec(x)
DEBUG.Str(String(" is = "))
DEBUG.Bin(BitFromByte(Beginning_Byte, x), 1)
DEBUG.NewLine
DEBUG.NewLine
DEBUG.NewLine
DEBUG.Str(String("Running BitFromNibble to get each bit of nibble data"))
DEBUG.NewLine
DEBUG.Str(String("Beginning nibble data is "))
DEBUG.Bin(Beginning_Nibble, 4)
DEBUG.NewLine
REPEAT x from 0 to 3
DEBUG.Str(String("Reading bit "))
DEBUG.Dec(x)
DEBUG.Str(String(" is = "))
DEBUG.Bin(BitFromNibble(Beginning_Nibble, x), 1)
DEBUG.NewLine
DEBUG.NewLine
DEBUG.Str(String("Testing Bit writing functions!!!"))
DEBUG.NewLine
DEBUG.NewLine
DEBUG.Str(String("Beginning Byte to alter is "))
DEBUG.Bin(Beginning_Byte, 8)
DEBUG.NewLine
DEBUG.Str(String("Set individual bits to 0 "))
DEBUG.NewLine
repeat x from 0 to 7
DEBUG.Bin(BitToByte(Beginning_Byte,x,0),8)
DEBUG.NewLine
DEBUG.Str(String("Set individual bits to 1 "))
DEBUG.NewLine
repeat x from 0 to 7
DEBUG.Bin(BitToByte(Beginning_Byte,x,1),8)
DEBUG.NewLine
DEBUG.NewLine
{ DEBUG.NewLine
DEBUG.Str(String("Beginning Nibble to alter is "))
DEBUG.Bin(Beginning_Nibble, 8)
DEBUG.NewLine
DEBUG.Str(String("Set individual bits to 0 "))
DEBUG.NewLine
repeat x from 0 to 3
DEBUG.Bin(BitToNibble(Beginning_Nibble,x,0),8)
DEBUG.NewLine
DEBUG.Str(String("Set individual bits to 1 "))
DEBUG.NewLine
repeat x from 0 to 3
DEBUG.Bin(BitToNibble(Beginning_Nibble,x,1),8)
DEBUG.NewLine
}
''
''
''
''
''/////////////////////////////////////////////////////////////////////////
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''|| Splitting Functions
'',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
''\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
PUB SplitLong(longDataIn)
'' Splits a long into 2 words and stores them respectivly in WordOut0
'' and WordOut1
''
'' Variables Required
'' * WordOut0 - must be atleast word sized datatype
'' * WordOut1 - must be atleast word sized datatype
'' * tmpWord0 - must be a WORD
'' * tmpWord1 - must be a WORD
''
'' Methods Required
'' * ClearVars
' make sure our output variables are 0 to start with
ClearVars
' WARNING:
' you may think the following two lines seem pointless but I discovered
' that storing a larger datatype into a smaller datatype retains the
' bits from the larger datatype when the smaller datatype is shifted
' right or left. Doing it this way eliminates that.
'
tmpWord0 := longDataIn ' store the low word of a long into a tmp WORD datatype
WordOut0 := tmpWord0 ' store the tmp WORD into the actual WORD to drop the unwanted bits from the origional long
tmpWord1 := longDataIn >> 16 ' do the same for the high word incase we later shift left
WordOut1 := tmpWord1 ' store the tmp WORD into the actual word we will use.
PUB SplitLong_ex(longDataIn)
'' Splits a long into 4 bytes and stores them respectivly in ByteOut0,
'' ByteOut1, ByteOut2, and ByteOut3
''
'' Variables Required
'' * ByteOut0
'' * ByteOut1
'' * ByteOut2
'' * ByteOut3
'' * tmpByte0
'' * tmpByte1
'' * tmpByte2
'' * tmpByte3
''
'' Methods Required
'' * ClearVars
' make sure our output variables are 0 to start with
ClearVars
tmpByte0 := longDataIn
ByteOut0 := tmpByte0
tmpByte1 := longDataIn >> 8
ByteOut1 := tmpByte1
tmpByte2 := longDataIn >> 16
ByteOut2 := tmpByte2
tmpByte3 := longDataIn >> 24
ByteOut3 := tmpByte3
PUB SplitWord(wordDataIn)
'' Splits a word into 2 bytes and stores the respectivly in ByteOut0
'' and ByteOut1
''
'' Variables Required
'' * ByteOut0
'' * ByteOut1
'' * tmpByte0
'' * tmpByte1
''
'' Methods Required
'' * ClearVars
' make sure our output variables are 0 to start with
ClearVars
tmpByte0 := wordDataIn
ByteOut0 := tmpByte0
tmpByte1 := wordDataIn >> 8
ByteOut1 := tmpByte1
PUB SplitByte(byteDataIn)
'' Splits a byte into 2 nibbles and stores the respectively in
'' NibbleOut0 and NibbleOut1
''
'' Variables Required
'' * NibbleOut0
'' * NibbleOut1
'' * tmpNibble0
'' * tmpNibble1
''
'' Methods Required
'' * ClearVars
' make sure our output variables are 0 to start with
ClearVars
'tmp1 := byteDataIn << 4 ' I kept this code here as a reminder of where
'tmp2 := tmp1 >> 4 ' I learned about bits being retained that I
'NibbleOut0 := tmp2 ' didnt want to retain.
'NibbleOut1 := byteDataIn >> 4
tmpNibble0 := byteDataIn << 4 ' start to drop off the high nibble of the byte
tmpNibble2 := tmpNibble0 >> 4 ' this drops the high nibble of the Byte
NibbleOut0 := tmpNibble2 ' now store the low nibble back into a byte since there is no nibble datatype
tmpNibble1 := byteDataIn >> 4
tmpNibble3 := tmpNibble1
NibbleOut1 := tmpNibble3
PUB SplitLongToBits(longDataIn)
'' this method is as a placeholder for splitting a long into bits
'' using variables BitOut0 through BitOut31
''
''
PUB SplitWordToBits(wordDataIn)
'' this method is as a placeholder for splitting a word into bits
'' using variables BitOut0 through BitOut15
''
''
PUB SplitByteToBits(wordDataIn)
'' this method is as a placeholder for splitting a byte into bits
'' using variables BitOut0 through BitOut7
''
''
''
''
''
''/////////////////////////////////////////////////////////////////////////
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''|| Joining Functions
'',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
''\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
PUB Join32(word1, word0)
'' Joins word0 and word1 to form a long
''
'' Variables Required
'' * LongOut
''
'' Methods Required
'' * ClearVars
' make sure our output variables are 0 to start with
ClearVars
LongOut := word1 << 16
LongOut := LongOut | word0
PUB Join16(byte1, byte0)
'' Joins byte0 and byte1 to form a word
''
'' Variables Required
'' * WordOut0
''
'' Methods Required
'' * ClearVars
' make sure our output variables are 0 to start with
ClearVars
WordOut0 := byte1 << 8
WordOut0 := WordOut0 | byte0
PUB Join8(nibble1, nibble0)
'' Joins nibble 0 and 1 to form a byte. Since there are no
'' nibble datatypes in spin we will use bytes to store both
'' high and low nibbles both as low nibbles of a byte
''
'' Variables Required
'' * ByteOut0
''
'' Methods Required
'' * ClearVars
' make sure our output variables are 0 to start with
ClearVars
ByteOut0 := nibble1 << 4
ByteOut0 := byteOut0 | nibble0
''
''
''
''/////////////////////////////////////////////////////////////////////////
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''|| Bit Reading Functions
'',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
''\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
PUB BitFromLong(yourLong, position0to31)
'' Returns a byte with the least significant bit being the value
'' of position0to31 from yourLong
''
'' Variables Required
'' * BitOut
'' * tmpLong0
'' * tmpLong1
''
'' Methods Required
'' * ClearVars
' make sure our output and tmp variables are 0 to start with
ClearVars
case position0to31
0:
tmpLong0 := yourLong << 31
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
1:
'tmp1 := yourLong >> position0to31
'bit1 := tmp1
'return bit1
tmpLong0 := yourLong << 30
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
2:
tmpLong0 := yourLong << 29
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
3:
tmpLong0 := yourLong << 28
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
4:
tmpLong0 := yourLong << 27
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
5:
tmpLong0 := yourLong << 26
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
6:
tmpLong0 := yourLong << 25
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
7:
tmpLong0 := yourLong << 24
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
8:
tmpLong0 := yourLong << 23
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
9:
tmpLong0 := yourLong << 22
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
10:
tmpLong0 := yourLong << 21
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
11:
tmpLong0 := yourLong << 20
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
12:
tmpLong0 := yourLong << 19
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
13:
tmpLong0 := yourLong << 18
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
14:
tmpLong0 := yourLong << 17
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
15:
tmpLong0 := yourLong << 16
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
16:
tmpLong0 := yourLong << 15
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
17:
tmpLong0 := yourLong << 14
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
18:
tmpLong0 := yourLong << 13
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
19:
tmpLong0 := yourLong << 12
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
20:
tmpLong0 := yourLong << 11
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
21:
tmpLong0 := yourLong << 10
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
22:
tmpLong0 := yourLong << 9
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
23:
tmpLong0 := yourLong << 8
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
24:
tmpLong0 := yourLong << 7
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
25:
tmpLong0 := yourLong << 6
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
26:
tmpLong0 := yourLong << 5
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
27:
tmpLong0 := yourLong << 4
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
28:
tmpLong0 := yourLong << 3
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
29:
tmpLong0 := yourLong << 2
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
30:
tmpLong0 := yourLong << 1
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
31:
tmpLong0 := yourLong << 0
tmpLong1 := tmpLong0 >> 31
BitOut := tmpLong1
return BitOut
OTHER:
DEBUG.NewLine
DEBUG.Str(String("ERROR: Bit Position Invalid!!!"))
DEBUG.NewLine
DEBUG.Beep ' :( the beeper does not beep :( just prints a 0 :(
PUB BitFromWord(yourWord, position0to15)
'' Returns a byte with the least significant bit being the value
'' of position0to15 from yourWord
''
'' Variables Required
'' * BitOut
'' * tmpWord0
'' * tmpWord1
''
'' Methods Required
'' * ClearVars
' make sure our output variables are 0 to start with
ClearVars
case position0to15
0:
tmpWord0 := yourWord << 15
tmpWord1 := tmpWord0 >> 15
BitOut := tmpWord1
return BitOut
1:
tmpWord0 := yourWord << 14
tmpWord1 := tmpWord0 >> 15
BitOut := tmpWord1
return BitOut
2:
tmpWord0 := yourWord << 13
tmpWord1 := tmpWord0 >> 15
BitOut := tmpWord1
return BitOut
3:
tmpWord0 := yourWord << 12
tmpWord1 := tmpWord0 >> 15
BitOut := tmpWord1
return BitOut
4:
tmpWord0 := yourWord << 11
tmpWord1 := tmpWord0 >> 15
BitOut := tmpWord1
return BitOut
5:
tmpWord0 := yourWord << 10
tmpWord1 := tmpWord0 >> 15
BitOut := tmpWord1
return BitOut
6:
tmpWord0 := yourWord << 9
tmpWord1 := tmpWord0 >> 15
BitOut := tmpWord1
return BitOut
7:
tmpWord0 := yourWord << 8
tmpWord1 := tmpWord0 >> 15
BitOut := tmpWord1
return BitOut
8:
tmpWord0 := yourWord << 7
tmpWord1 := tmpWord0 >> 15
BitOut := tmpWord1
return BitOut
9:
tmpWord0 := yourWord << 6
tmpWord1 := tmpWord0 >> 15
BitOut := tmpWord1
return BitOut
10:
tmpWord0 := yourWord << 5
tmpWord1 := tmpWord0 >> 15
BitOut := tmpWord1
return BitOut
11:
tmpWord0 := yourWord << 4
tmpWord1 := tmpWord0 >> 15
BitOut := tmpWord1
return BitOut
12:
tmpWord0 := yourWord << 3
tmpWord1 := tmpWord0 >> 15
BitOut := tmpWord1
return BitOut
13:
tmpWord0 := yourWord << 2
tmpWord1 := tmpWord0 >> 15
BitOut := tmpWord1
return BitOut
14:
tmpWord0 := yourWord << 1
tmpWord1 := tmpWord0 >> 15
BitOut := tmpWord1
return BitOut
15:
tmpWord0 := yourWord << 0
tmpWord1 := tmpWord0 >> 15
BitOut := tmpWord1
return BitOut
OTHER:
DEBUG.NewLine
DEBUG.Str(String("ERROR: Bit Position Invalid!!!"))
DEBUG.NewLine
DEBUG.Beep ' :( the beeper does not beep :( just prints a 0 :(
PUB BitFromByte(yourByte, position0to7)
'' Returns a byte with the least significant bit being the value
'' of position0to7 from yourByte
''
'' Variables Required
'' * BitOut
'' * tmpByte0
'' * tmpByte1
''
'' Methods Required
'' * ClearVars
' make sure our output variables are 0 to start with
ClearVars
case position0to7
0:
tmpByte0 := yourByte << 7
tmpByte1 := tmpByte0 >> 7
BitOut := tmpByte1
return BitOut
1:
tmpByte0 := yourByte << 6
tmpByte1 := tmpByte0 >> 7
BitOut := tmpByte1
return BitOut
2:
tmpByte0 := yourByte << 5
tmpByte1 := tmpByte0 >> 7
BitOut := tmpByte1
return BitOut
3:
tmpByte0 := yourByte << 4
tmpByte1 := tmpByte0 >> 7
BitOut := tmpByte1
return BitOut
4:
tmpByte0 := yourByte << 3
tmpByte1 := tmpByte0 >> 7
BitOut := tmpByte1
return BitOut
5:
tmpByte0 := yourByte << 2
tmpByte1 := tmpByte0 >> 7
BitOut := tmpByte1
return BitOut
6:
tmpByte0 := yourByte << 1
tmpByte1 := tmpByte0 >> 7
BitOut := tmpByte1
return BitOut
7:
tmpByte0 := yourByte << 0
tmpByte1 := tmpByte0 >> 7
BitOut := tmpByte1
return BitOut
OTHER:
DEBUG.NewLine
DEBUG.Str(String("ERROR: Bit Position Invalid!!!"))
DEBUG.NewLine
DEBUG.Beep ' :( the beeper does not beep :( just prints a 0 :(
PUB BitFromNibble(yourNibble, position0to3)
'' Returns a byte with the least significant bit being the value
'' of position0to4 from yourNibble
''
'' Variables Required
'' * BitOut
'' * tmpLong0
'' * tmpLong1
''
'' Methods Required
'' * ClearVars
' make sure our output variables are 0 to start with
ClearVars
case position0to3
0:
tmpNibble0 := yourNibble << 4
tmpNibble1 := tmpNibble0 >> 4
BitOut := tmpNibble1
return BitOut
1:
tmpNibble0 := yourNibble << 3
tmpNibble1 := tmpNibble0 >> 4
BitOut := tmpNibble1
return BitOut
2:
tmpNibble0 := yourNibble << 2
tmpNibble1 := tmpNibble0 >> 4
BitOut := tmpNibble1
return BitOut
3:
tmpNibble0 := yourNibble << 1
tmpNibble1 := tmpNibble0 >> 4
BitOut := tmpNibble1
return BitOut
OTHER:
DEBUG.NewLine
DEBUG.Str(String("ERROR: Bit Position Invalid!!!"))
DEBUG.NewLine
DEBUG.Beep ' :( the beeper does not beep :( just prints a 0 :(
''
''
''
''/////////////////////////////////////////////////////////////////////////
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''|| Bit Writinging Functions
'',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
''\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
PUB BitToLong(yourLong, position0to31, value)
'' sets the bit value at position0to31 in yourLong
''
'' This PUB is left blank so you can look at BitToByte and
'' try to program it for yourself. Read up on Operators in
'' the Propeller Manual
PUB BitToWord(yourWord, position0to15, value)
'' sets the bit value at position0to15 in yourWord
''
'' This PUB is left blank so you can look at BitToByte and
'' try to program it for yourself. Read up on Operators in
'' the Propeller Manual
PUB BitToByte(yourByte, position0to7, value)
'' sets the bit value at position0to7 in yourByte
''
'' Variables Required
'' * ByteOut0
''
'' Methods Required
'' * ClearVars
''
'' Thanks to MagIO2 for showing me how to do it this way
ClearVars
byteOut0:=yourByte
if value
byteOut0:=byteOut0 | |<position0to7
else
byteOut0:=byteOut0 & !|<position0to7
return byteOut0
{ this is how I origionaly did it but MagIO2 on the forums showed me
a better way (above). I will leave this here as a reminder.
PUB BitToByte(yourByte, position0to7, value)
'' sets the bit value at position0to7 in yourByte
''
'' the tmpBits are actualy byte datatypes since there is no bit datatype
ClearVars
tmpBit8 := yourByte << 7
tmpBit0 := tmpBit8 >> 7
tmpBit9 := yourByte << 6
tmpBit1 := tmpBit9 >> 7
tmpBit10 := yourByte << 5
tmpBit2 := tmpBit10 >> 7
tmpBit11 := yourByte << 4
tmpBit3 := tmpBit11 >> 7
tmpBit12 := yourByte << 3
tmpBit4 := tmpBit12 >> 7
tmpBit13 := yourByte << 2
tmpBit5 := tmpBit13 >> 7
tmpBit14 := yourByte << 1
tmpBit6 := tmpBit14 >> 7
tmpBit15 := yourByte << 0
tmpBit7 := tmpBit15 >> 7
'
case position0to7
0:
tmpBit0 := value
1:
tmpBit1 := value
2:
tmpBit2 := value
3:
tmpBit3 := value
4:
tmpBit4 := value
5:
tmpBit5 := value
6:
tmpBit6 := value
7:
tmpBit7 := value
OTHER:
' TODO: return something indicating invalid position
byteOut0 := tmpBit7 << 7
byteOut0 := byteOut0 | (tmpBit6 << 6)
byteOut0 := byteOut0 | (tmpBit5 << 5)
byteOut0 := byteOut0 | (tmpBit4 << 4)
byteOut0 := byteOut0 | (tmpBit3 << 3)
byteOut0 := byteOut0 | (tmpBit2 << 2)
byteOut0 := byteOut0 | (tmpBit1 << 1)
byteOut0 := byteOut0 | (tmpBit0 << 0)
return byteOut0
PUB BitToNibble(yourNibble, position0to3, value)
'' sets the bit value at position0to3 in yourNibble
''
'' value is either one or zero!
'' the tmpBits are actualy byte datatypes, since there is no bit datatype, in the VAR section
''
ClearVars
tmpBit8 := yourNibble << 3
tmpBit0 := tmpBit8 >> 3
tmpBit9 := yourNibble << 2
tmpBit1 := tmpBit9 >> 3
tmpBit10 := yourNibble << 1
tmpBit2 := tmpBit10 >> 3
tmpBit11 := yourNibble << 0
tmpBit3 := tmpBit11 >> 3
'
case position0to3
0:
tmpBit0 := value
1:
tmpBit1 := value
2:
tmpBit2 := value
3:
tmpBit3 := value
OTHER:
' TODO: return something indicating invalid position
NibbleOut0 := tmpBit3 << 3
NibbleOut0 := NibbleOut0 | (tmpBit2 << 2)
NibbleOut0 := NibbleOut0 | (tmpBit1 << 1)
NibbleOut0 := NibbleOut0 | (tmpBit0 << 0)
return NibbleOut0
}
''
''
''
''/////////////////////////////////////////////////////////////////////////
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''|| Private Functions
'',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
''\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
PUB ClearVars
'' Clears all used Variables in one shot as opposed to clearing them
'' within each method above. This saved me some program space.
''
tmpBit0 := 0
tmpBit1 := 0
tmpBit2 := 0
tmpBit3 := 0
tmpBit4 := 0
tmpBit4 := 0
tmpBit5 := 0
tmpBit6 := 0
tmpBit7 := 0
tmpBit8 := 0
tmpBit9 := 0
tmpBit10 := 0
tmpBit11 := 0
tmpBit12 := 0
tmpBit13 := 0
tmpBit15 := 0
tmpBit16 := 0
tmpBit17 := 0
tmpBit18 := 0
tmpBit19 := 0
tmpBit20 := 0
tmpBit21 := 0
tmpBit22 := 0
tmpBit23 := 0
tmpBit24 := 0
tmpBit25 := 0
tmpBit26 := 0
tmpBit27 := 0
tmpBit28 := 0
tmpBit29 := 0
tmpBit30 := 0
tmpBit31 := 0
tmpLong0 := 0
tmpLong1 := 0
BitOut := 0
BitOut0 := 0
BitOut1 := 0
BitOut2 := 0
BitOut3 := 0
BitOut4 := 0
BitOut5 := 0
BitOut6 := 0
BitOut7 := 0
BitOut8 := 0
BitOut9 := 0
BitOut10 := 0
BitOut11 := 0
BitOut12 := 0
BitOut13 := 0
BitOut14 := 0
BitOut15 := 0
BitOut16 := 0
BitOut17 := 0
BitOut18 := 0
BitOut19 := 0
BitOut20 := 0
BitOut21 := 0
BitOut22 := 0
BitOut23 := 0
BitOut24 := 0
BitOut25 := 0
BitOut26 := 0
BitOut27 := 0
BitOut28 := 0
BitOut29 := 0
BitOut30 := 0
BitOut31 := 0
NibbleOut7 := 0
NibbleOut6 := 0
NibbleOut5 := 0
NibbleOut4 := 0
NibbleOut3 := 0
NibbleOut2 := 0
NibbleOut1 := 0
NibbleOut0 := 0
LongOut := 0
WordOut1 := 0
WordOut0 := 0
ByteOut3 := 0
ByteOut2 := 0
ByteOut1 := 0
ByteOut0 := 0

Comments
In SPIN there is no real need to split a long into pieces! You can simply access it like that:
word[@theLongVar][0]
word[@theLongVar][1]
byte[@theLongVar][0]
...
byte[@theLongVar][3]
which would at least make your split functions smaller, faster and ... sorry ... unnecessary ;o)
I really doubt that the function split to bits is very usefull. Using a long for storing 32 bits is much more effective than having at least a byte array of 32 bytes to just hold the same amount of information. It is much more usefull to have functions that allow to alter, read, write single bits - and only if you are not familiar with the bitwise operators available in SPIN.
Wow ... the huge case statement can be resolved in something easier. Why don't you simply calculate the value for the left-shift?
tmpLong := yourLong << (31-position0To31)
BitFromLong in a one line version:
return (yourLong & |<position0to31) >> position0to31
BitFromWord ... why do you need it at all? You can simply use BitFromLong! Parameters are always passed as long and in case you call the function using a word variable, you can simply restrict the bit-range by yourself.
Same is true for BitTo-functions ... return values are always 32 bit. The assignment to a byte variable will take care of trunkating.
PS: Hope you don't find this demotivating! That's not my intention! You have my full respect for posting code here even if you are a beginner. That's how learning works. In the end you solved your problem even if you did it with bigger efford. Now turn it in a bigger learning experience by investigating what each optimization step brings in terms of memory usage and runtime.
Now you can copy-and-paste this method to any program and use it with any set of variables:
Not at all, it's much appreciated. If there was a meetup group close to me I would go just to learn a bit more, its always nice to have someone to ask if this or that is right and make some improvements while learning also. The forums are the only place I can do that right now, although responses come a little slower they still achieve the same goal.