Shop OBEX P1 Docs P2 Docs Learn Events
Writing, Splitting, and Joining data - My first attempt — Parallax Forums

Writing, Splitting, and Joining data - My first attempt

Jorge PJorge P Posts: 385
edited 2011-11-23 23:09 in Propeller 1
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:
{{
/////////////////////////////////////////////////////////////////////////
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  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

  • MagIO2MagIO2 Posts: 2,243
    edited 2011-11-23 03:32
    About your tipp doing copy&paste ... you can also use BST instead of the propeller tool .... it is very similar and produces the same compile-result if you want ... but you can also let it optimize, which means remove all functions not used automatically.

    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.
  • JonnyMacJonnyMac Posts: 9,198
    edited 2011-11-23 09:11
    Another tip: you can make your methods atomic by passing destination pointers instead of relying on predefined variables. For example, you might do this:
    pub long2words(value, whipntr, wlopntr)
    
      word[whipntr] := value >> 16
      word[wlopntr] := value & $FFFF
    


    Now you can copy-and-paste this method to any program and use it with any set of variables:
    long2words(somevalue, @word1, @word2)
    
  • Jorge PJorge P Posts: 385
    edited 2011-11-23 23:09
    PS: Hope you don't find this demotivating!

    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.
Sign In or Register to comment.