Shop OBEX P1 Docs P2 Docs Learn Events
Many words — Parallax Forums

Many words

Ken StraussKen Strauss Posts: 10
edited 2009-03-07 02:46 in General Discussion
I'm a newbie using SX/B 2.0 and wish that a manual were available.

I am working on a project that requires operations on the data from several sensors. Each sensor requires maintaining 6 values. Since each value is in the range of 0-30000 I need 12 bytes of storage per sensor. How can I store the data words using one bank for each sensor? I can find many examples of aliasing a named byte to an array element but nothing similar for word variables.

Comments

  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-02-28 19:08
    Use an array of 2 bytes
    aWord var byte(2)
    is an implied word.
    You can then access the both bytes of aWord as
    aWord_LSB and aWord_MSB.

    regards peter
  • JonnyMacJonnyMac Posts: 9,214
    edited 2009-02-28 19:53
    The attached demo illustrates just one method of solving your sensor storage problem, and doesn't rely on advanced features in SX/B 2.0.
  • Ken StraussKen Strauss Posts: 10
    edited 2009-02-28 20:10
    Is there any convenient way to use normal SX/B operators on the words stored as bytes in another bank? That is, it would be really nice to be able to write:

    INC aWord
    or
    bWord = aWord
    or
    cWord = aWord + bWord

    instead of having to explicitly work with aWord_MSB and aWord_LSB? I realize that this is what the compiler actually does but hiding things makes the source code much easier to follow and less prone to error.
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-02-28 20:14
    You use the implied words as you would use the normal variables·words.
    I mentioned the LSB and MSB parts as these are also generated for the
    normal words.

    regards peter
  • Ken StraussKen Strauss Posts: 10
    edited 2009-02-28 20:27
    So with something like:

    sensor0 VAR Byte(2) BANK
    speed0 VAR Byte(2)
    voltage0 VAR Byte(2)
    revs0 VAR Byte(2)
    thisCnt0 VAR Byte(2)

    sensor1 VAR Byte(2) BANK
    speed1 VAR Byte(2)
    voltage1 VAR Byte(2)
    revs1 VAR Byte(2)
    thisCnt1 VAR Byte(2)



    I could write:
    ASM
    BANK sensor1
    ENDASM
    revs0 = revs0 + thisCnt0

    and revs0 would actually operate on revs1? It would be nice to have one set of code for all sensors and just change the bank number to work with individual sensors.
  • JonnyMacJonnyMac Posts: 9,214
    edited 2009-02-28 20:33
    SX/B 2.x allows you to define words within an array using the @ modifier. Peter is better equipped to explain this, but the @ operator is really creating an offset within the presently-selected bank. In the attached program you'll see that the words are only defined within sensor1 but can be used within sensor2 as well. This allows you to have one set of code that works for any sensor -- you just switch to the sensor bank before calling the code. Note that some SX/B functions will set the FSR back to the default value so you need to watch for this within your routines.

    [noparse][[/noparse]Edit] I changed the PUT_WORD and GET_WORD routines so they can be used from any bank.

    [noparse][[/noparse]Edit] Fixed error found by Peter Verkaik in PUT_WORD -- upgraded to 2.00.13+ features to force promotion of bytes to words. See Peter's version (below) for even more features.

    Post Edited (JonnyMac) : 3/1/2009 6:38:51 PM GMT
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-02-28 21:25
    Jon is right about using the @ operator.

    sensordevice0 var byte (10) bank align
    sensordevice1 var byte (10) bank align
    sensordevice2 var byte (10) bank align
    sensordevice3 var byte (10) bank align
    sensor VAR word @sensordevice0(0)
    speed VAR word @sensordevice0(2)
    voltage VAR word @sensordevice0(4)
    revs VAR word @sensordevice0(6)
    thisCnt VAR word @sensordevice0(8)

    I used align to ensure the absolute offset of fields to start of banks is
    identical for all sensordevices, which they must.

    bank @sensordevice0
    revs = revs + thisCnt· 'this uses variables of sensordevice0
    bank __DEFAULT
    bank @sensordevice3
    revs = revs + thisCnt· 'this uses variables of sensordevice3
    bank __DEFAULT

    I would create subroutines that operate on sensorfields
    and pass the bank value as well

    SUB mySensor· 'let first parameter be the bank
    · fsr = __param1 'this accesses the correct bank
    · revs = revs + thisCnt
    · bank __DEFAULT· 'enable default bank upon return
    ENDSUB

    You call this sub like
    mySensor @sensordevice3,....

    Be careful when doing math on both sensorfields and other variables that are
    in different banks. Those 'outside' variables need either be copied to __paramX
    global ram or to temporary variables declared inside the sensordevice bank.
    I usually use the latter as __paramX is of course used by SXB.
    So I would add following sensorfields:
    sensorTempW1 VAR word @sensordevice0(10)
    sensorTempW2 VAR word @sensordevice0(12)
    You can copy 'outside' variables via __paramX to sensorTempX
    and then do the math.
    If you need to switch between banks, declare a local byte to hold
    the bank value.

    SUB mySensor· 'let first parameter be the bank
    · sbank var byte
    · sbank = __param1
    · __wparam34 = myOutsideVariable 'sxb retrieves an outside variable
    · fsr = sbank· 'this accesses the correct bank
    · sensorTempW1 = __wparam34 'save the variable locally
    · revs = revs + sensorTempW1
    · bank __DEFAULT· 'enable default bank upon return
    ENDSUB

    regards peter
  • Ken StraussKen Strauss Posts: 10
    edited 2009-02-28 21:36
    I didn't find a mention of "@" in the SX/B2.0 help file. I'm assuming that this is the syntax for a pointer to a variable. It appears that I only need PUT_WORD/GET_WORD to move data between banks. That is, I could write
    BANK @sensor1
    value1 = 2

    instead of
    PUT_WORD @sensor1,`,2

    The sample Words2 gets several compiler warnings such as "Line 282, Warning 48, Pass 2: File register not in current bank". Can these be ignored? What should be changed to make it compile without warnings?
  • Ken StraussKen Strauss Posts: 10
    edited 2009-02-28 21:40
    Thanks for the additional clarification! Where can I read about ALIGN and all of the other magic words?
  • JonnyMacJonnyMac Posts: 9,214
    edited 2009-02-28 22:01
    All the SX/B 2.x information is in the "What's New" document:
    -- http://forums.parallax.com/attachment.php?attachmentid=0

    Post Edited (JonnyMac) : 2/28/2009 10:09:21 PM GMT
  • JonnyMacJonnyMac Posts: 9,214
    edited 2009-02-28 22:04
    Ken Strauss said...
    I didn't find a mention of "@" in the SX/B2.0 help file. I'm assuming that this is the syntax for a pointer to a variable. It appears that I only need PUT_WORD/GET_WORD to move data between banks. That is, I could write
    BANK @sensor1
    value1 = 2

    instead of
    PUT_WORD @sensor1,`,2

    The sample Words2 gets several compiler warnings such as "Line 282, Warning 48, Pass 2: File register not in current bank". Can these be ignored? What should be changed to make it compile without warnings?

    Exactly: PUT_WORD and GET_WORD are for bank-to-bank transfers. When you're inside a sensor bank you can freely manipulate its contents. I don't know how to suppress that compiler warning and wouldn't want to as it could be a real problem in some cases (though not in this one).
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-03-01 00:23
    You can suppress the warnings by using
    fsr = @sensor1 instead of bank @sensor1.
    (but note that·fsr =··destroys W).

    regards peter
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-03-01 13:14
    Jon,
    There is a problem in PUT_WORD

    SUB PUT_WORD
      ASM
        MOV   __PARAM5, FSR    ' save current bank
        MOV   W, __PARAM1    ' start of array
        CLC
        RL    __PARAM2    ' index *= 2
        ADD   W, __PARAM2
        MOV   FSR, W    ' FSR = array(index)
        MOV   IND, __PARAM3
        INC   FSR     ' FSR = array(index+1)
        SB    __PARAMCNT.2    ' skip next if word
         CLR  __PARAM4    '  else clear MSB if byte
        MOV   IND, __PARAM4
        MOV   FSR, __PARAM5    ' restore bank
      ENDASM
      ENDSUB 
    

    You save fsr in __param5, but later on you test __paramcnt.
    Since __paramcnt is aliased to __param5 this will not work.
    Better to change PUT_WORD to always use word values (or extend bytevalues to wordvalues)
    PUT_WORD·SUB·4, 4, byte, byte, word
    __paramcnt is not used then.

    regards peter
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-03-01 15:01
    Here is an extended version of Jon's file.
    I added subs/funcs for named variables that use the variables address rather than·the array index.
    Disadvantage of using an index is that if you ever change the order of fields
    you must change indexes throughout your program. Using named variables
    that should not be neccessary.
    I also added subs/funcs for byte values (index and named variables).
    Finally, I also added two macros for named variables that either call a
    word function or byte function based on the variable names.
    The idea is that if the type of the variable changes, you don't need
    to change calls throughout your program as the macros take care of that.

    regards peter
  • JonnyMacJonnyMac Posts: 9,214
    edited 2009-03-01 18:37
    Thanks for the catch, Peter. I fixed the listing by using 2.00.13 features in SUB/FUNC calls. Am studying your version now. Thanks.
  • David BaylissDavid Bayliss Posts: 58
    edited 2009-03-02 00:05
    Peter,

    First - I love reading your code - you produce excellent solutions -

    Couple of questions:

    For the 'index word' variants you use:

    ··· MOV·· W, __PARAM1····' start of array
    ··· CLC
    ··· RL··· __PARAM2····' index *= 2
    ··· ADD·· W, __PARAM2

    to compute the index; would there be a downside to using:

    ··· MOV·· W, __PARAM1····' start of array
    ··· ADD·· W, __PARAM2

    ··· ADD·· W, __PARAM2

    I -think- it saves a byte and a cycle ...

    Secondly - the GetName/PutName variants are clearly rather larger - but obviously I understand the reason not to want to use hard-code numbers for the index vars ...

    I wonder however, could you not equate the 'field labels' as index offset constants·and then use the regular index routines?

    David
    Peter Verkaik said...
    Here is an extended version of Jon's file.
    I added subs/funcs for named variables that use the variables address rather than·the array index.
    Disadvantage of using an index is that if you ever change the order of fields
    you must change indexes throughout your program. Using named variables
    that should not be neccessary.
    I also added subs/funcs for byte values (index and named variables).
    Finally, I also added two macros for named variables that either call a
    word function or byte function based on the variable names.
    The idea is that if the type of the variable changes, you don't need
    to change calls throughout your program as the macros take care of that.

    regards peter

  • JonnyMacJonnyMac Posts: 9,214
    edited 2009-03-02 00:39
    David,

    That code is my fault and as Assembly is still not my first choice I'm not always particularly efficient with it. I appreciate that you provide alternative approaches -- has been very educational.
  • David BaylissDavid Bayliss Posts: 58
    edited 2009-03-02 03:01
    You tackled the problem perfectly; it is always easier to spot optimizations in working code....

    I really would like to try to find a way to produce a code library for the SX - you and Peter and others produce dozens of examples of great code - but there is no 'easy use' repository of it all ...
  • JonnyMacJonnyMac Posts: 9,214
    edited 2009-03-02 04:17
    Peter has done a much better job than me with the "library" stuff because that suits his style -- it really doesn't fit mine. Still, SX/B 2.0 has improved library support and I find myself taking advantage of it for code that I end to use over and over.
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-03-02 05:25
    Hi David,
    You said...I wonder however, could you not equate the 'field labels' as index offset constants·and then use the regular index routines?
    Yes and so I did.
    I have abandoned the index and named routines all together
    so now I have only 4 byteindexed routines and 2 macros.
    The byteindexed routines do not double the index so they
    can be used even if an array supports wordfields and bytefields.
    The 'problem' with fieldaddresses is that they are absolute and
    not relative to the arraybegin. To support multiple instances
    of identical objects (like sensor1 and sensor2 in·the demo)
    not only the address of the instance but also the address of
    the object definition must be given.
    I have resolved that using two macros GET_VAR and PUT_VAR
    that you call like this:

    \GET_VAR resultName,objectName,objectField,objectInstance
    \GET_VAR objectName,objectField,objectInstance
    \GET_VAR resultName,varName
    \GET_VAR varName

    \PUT_VAR objectName,objectField,objectInstance,value
    \PUT_VAR objectName,objectField,objectInstance
    \PUT_VAR varName,value
    \PUT_VAR varName

    Check out the generated code in the list view.
    The subroutines do not yet suppoert spanned banks on the sx18/20/28.

    regards peter
  • BeanBean Posts: 8,129
    edited 2009-03-02 12:35
    Ken Strauss said...
    The sample Words2 gets several compiler warnings such as "Line 282, Warning 48, Pass 2: File register not in current bank". Can these be ignored? What should be changed to make it compile without warnings?
    Ken,
    · By putting the line "\LIST Q=48" (without the quotes) right after the DEVICE line with prevent the "File register not in current bank" warning.

    Bean.


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    There is a fine line between arrogance and confidence. Make sure you don't cross it...

    ·
  • David BaylissDavid Bayliss Posts: 58
    edited 2009-03-02 12:38
    Cool - and yes that is probably the correct 'clean' way to do it ... being an old school hacker I had been thinking of a rather more primitive:



    value1 CON 0 
    value2 CON 2 
    value3 CON 4
    

    but I think I prefer your solution - because you are using macros and constant folding the extra subtract is not really costing you anything ...



    David
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-03-06 17:08
    I finally got around to put it all in a library file.
    Also added functions for reading ROM.

    regards peter
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-03-07 02:46
    Bugfix. I had forgotten to make address calculations
    compliant with spanned arrays. All fixed now.
    Just replace the INC file with the one attached.

    regards peter
Sign In or Register to comment.