Writing, Splitting, and Joining data - My first attempt
Jorge P
Posts: 385
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.