Shop OBEX P1 Docs P2 Docs Learn Events
variable name generating with macro — Parallax Forums

variable name generating with macro

Peter VerkaikPeter Verkaik Posts: 3,956
edited 2005-04-29 20:34 in General Discussion
Hi,
I want to generate variables using a macro.
The macro argument is the variable name prefix

myMacro··macro·name
??\1_count·ds·1··;count value
When I have
myMacro lowpass

then I want the macro to create
lowpass_count ds 1 ;count value

Is that at all possible?
The macro above generates
\1_count ds 1 ;count value

regards peter
·

Comments

  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2005-04-25 15:40
    Solved it.

    Had to use

    myMacro··macro·prefix
    prefix??_??count·ds·1··;count value

    Thanks to

    http://www.piclist.com/techref/new/letter/news0403.htm

    regards peter
  • James NewtonJames Newton Posts: 329
    edited 2005-04-25 16:47
    Darn! I was going to answer this one... <GRIN> Glad you found the answer yourself.

    That URL should probably be
    http://www.sxlist.com/techref/new/letter/news0403.htm·
    although it is possible to use SASM to write code for PIC 16C5x chips, I really doubt anyone is...

    Really happy to see someone actually using macros, and I hope we see more of it.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ---
    James Newton, Host of SXList.com
    james@sxlist.com 1-619-652-0593 fax:1-208-279-8767
    SX FAQ / Code / Tutorials / Documentation:
    http://www.sxlist.com Pick faster!



  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2005-04-25 19:59
    James,

    Perhaps you can now.

    I am trying to conserve a macro argument to use it in another macro.

    myMacro··macro·prefix
    myMacro_prefix = prefix

    prefix??_??count·ds·1··;count value
    endm

    myMacro_code

    ·· inc myMacro_prefix??_??count

    endm



    Somewhere in my code I place

    ifdef myMacro_prefix

    myMacro_code

    endif



    But this does not work.

    I get

    · inc myMacro_prefix_count

    The idea is to let the code operate on defined variables

    so I can create a library of code that is only included if

    certain variables are defined.



    regards peter
  • James NewtonJames Newton Posts: 329
    edited 2005-04-25 21:47
    Could you add what you expected the output to be? I afraid I'm very confused about what you are trying to accomplish.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ---
    James Newton, Host of SXList.com
    james@sxlist.com 1-619-652-0593 fax:1-208-279-8767
    SX FAQ / Code / Tutorials / Documentation:
    http://www.sxlist.com Pick faster!



  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2005-04-25 22:44
    Ok, here is the total setup:

    uart···macro·prefix
    prefix??_??bank··equ·$
    prefix??_??count·ds·1··;number of bits
    prefix??_??divide·ds·1··;timing counter
    prefix??_??low··ds·1··;shift register
    prefix??_??high·ds·1··;value
    prefix??_??format·ds·1
    · prefix??_??bits_0·equ·prefix??_??format.0·;bits 1 and 0 specify number of total bits
    · prefix??_??bits_1·equ·prefix??_??format.1·;01 -> 9bits, 10 -> 10bits, 11 -> 11bits (start+data+parity+stop)
    · prefix??_??7bits·equ·prefix??_??format.2·;set for 7 databits (0 = 8 databits)
    · prefix??_??even·equ·prefix??_??format.3·;set for even parity
    · prefix??_??odd·equ·prefix??_??format.4·;set for odd parity
    · prefix??_??data·equ·prefix??_??format.5·;set if valid value, cleared after value grabbed
    · prefix??_??enable·equ·prefix??_??format.6·;set to enable uart
    · prefix??_??parity·equ·prefix??_??format.7·;parity bit placeholder
    prefix??_??baud·ds·1··;baudrate
    prefix??_??datapin·ds·1··;high nib = port (5 to 9), low nib = pin (0 to 7)
    · prefix??_??error·equ·prefix??_??datapin.3·;set if parity error
    prefix??_??hspin·ds·1··;high nib = port (5 to 9), low nib = pin (0 to 7)
    endm

    rxuart_data··macro·prefix
    rxprefix··=·?\1?
    uart prefix
    endm
    txuart_data··macro·prefix
    txprefix··=·?\1?
    uart prefix
    endm

    ;rxuart_code··macro·prefix
    uart_receive
    ···mov·fsr,vp_bank··;select target uart rambank
    ···jnb·prefix??_??enable,:rxdone
    ···mov·w,<>prefix??_??datapin··;port (ra to re) in lownib
    ···and·w,#$0F
    ···mov·fsr,w···;ports ra to re
    ···mov·w,indf···;read all pins
    ···mov·isr_temp,w··;save pin states
    ···mov·fsr,vp_bank
    ···mov·w,prefix??_??datapin··;pin number 0 to 7 in lownib
    ···call·pinmask···;get mask for pin
    ···and·isr_temp,w··;extract bit for pin
    ···test·prefix??_??count··;currently receiving byte?
    ···sz····;no
    ···jmp·:rx1···;yes, jump ahead
    ···mov·w,--prefix??_??format··;ready bits for start
    ···and·w,#$03···;number of bits 1, 2 or 3
    ···or·w,#$08···;9, 10 or 11
    ···test·isr_temp··;start bit?
    ···snz····;no
    ···mov·prefix??_??count,w··;yes, renew bit count
    ···mov·w,>>prefix??_??baud··;half bittime delay
    ···add·w,prefix??_??baud··;plus bittime delay -> start delay
    ···mov·prefix??_??divide,w
    :rx1
    ···clc
    ···test·isr_temp
    ···sz
    ···stc
    ···decsz·prefix??_??divide··;middle of next bit?
    ········· ··jmp·:rxdone···;no
    ···dec·prefix??_??count··;last bit?
    ···jz·:rx2···;yes
    ···rr·prefix??_??low···;no, rotate in new bit
    ···movb·prefix??_??parity,C··;save b0
    ···jmp·:rx3···;renew delay time
    :rx2
    ···mov·w,prefix??_??low··;save byte to allow receive another byte
    ···mov·prefix??_??high,w
    ···setb·prefix??_??data···;mark byte received
    :rx3
    ···mov·w,prefix??_??baud··;renew delay time
    ···mov·prefix??_??divide,w
    :rxdone
    ···retp
    ; RAM Bank Register VP definitions
    ;
    ·; userram0
    ·;
    ···org·userram0_org
    rxuart_data rx
    txuart_data tx
    ·; userram1
    ·;
    ···org·userram1_org
    rxuart_data rx1
    txuart_data tx1

    So I have multiple uart records, but only a single uart receive subroutine.
    (the uart data is at equal offsets in different banks, vp_bank sets the
    correct bank before probing the pins)

    in my code I have

    ifdef rxprefix
    rxuart_code txprefix
    endif

    I need that prefix to access the earlier defined variables.

    Hope this clarifies what I try to accomplish.

    regards peter
    ·
  • James NewtonJames Newton Posts: 329
    edited 2005-04-27 22:56
    Ok, I've been stareing at this for a while and I just don't see how that code and what you are describing goes together.

    I can understand "So I have multiple uart records, but only a single uart receive subroutine." that makes sense because you are using FSR / bank to switch between the variables but it doesn't make sense be cause you can't use macros to switch between the data pins for example. The macro could be used to compile a SEPERATE bit of code for each uart from the same source code where a parameter would used to change the code compiled to match the data pin for that usart.

    Are you thinking that the macro will cause ONE bit of code to be generated that will allow the data pin to be changed with the variables? It doesn't work that way.

    You found some information on that page at

    http://www.sxlist.com/techref/new/letter/news0403.htm· but did you actually read that entire article? It does a pretty good job of explaining what macros are.

    "Macros are code that is executed by the compiler rather than by the processor. E.g. by SASM rather than by the SX. Macros are programs that generate code for the processor just like you generate code for the processor. You write the MACRO program so that it will write code for you instead of you haveing to write the code each time yourself. Macros are like a "mini-me" that I have taught how to write code. The programming language that you write macros in, are the compiler directives like IFDEF, REPT, EQU, and so on."

    Since macro code is executed by the compiler (SASM) it is all done executing by the time it gets into the SX; it can not have any effect on the code at "run time" inside the SX.

    Or is this just something that I'm still not understanding? Are you planning on invoking the rxuart_code macro once for each uart?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ---
    James Newton, Host of SXList.com
    james@sxlist.com 1-619-652-0593 fax:1-208-279-8767
    SX FAQ / Code / Tutorials / Documentation:
    http://www.sxlist.com Pick faster!



  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2005-04-28 10:11
    James,

    the attachement may clarify it better.

    The idea is to let macros DECLARE variables and include the code that operates on these variables.

    The rxuart macro·for example, DECLARES 8 byte variables with a specified prefix (different prefix

    for different receive uarts) but also DEFINES the same variables with a fixed name. These

    defined variables gets redefined for each rxuart macro call.

    The fsr is set to the propr rambank before calling uart_receive (which is only included once).

    The used datapin is specified in variable lib_rx_datapin and is different for each uart.

    All recieve uarts must be declared at the same rambank offset but different rambanks,

    otherwise it doesn't work.

    This way I hope to create a library of code I can use by simply calling a macro after setting

    the ram address.

    · org·bank0_org
    data···=·$
    defvp 1,rxuart,rx
    defvp 2,txuart,tx

    · org·bank1_org
    data···=·$
    defvp 3,rxuart,rx1
    defvp 4,txuart,tx1

    egards peter
  • James NewtonJames Newton Posts: 329
    edited 2005-04-29 17:58
    Ok, so you would be invoking the rxuart_code macro more than once. Each of your examples has changed in large ways, so I still don't know that I have a handle on everything you are trying to do, but starting with the first example, which is the simplest. There are several problems with it. First, there is no "macro" keyword after "myMacro_code" I assume that is to be a seperate macro I don't understand why, but anyway... myMacro_code has no way to know the value of prefix. You could add a "prefix" parameter, but I think I understand that you want to avoid this. The only way to "preserve a macro argument to use it in another macro" is to define a global value in the first macro.

    This code works:
        DEVICE SX28
        FREQ 4000
        IRC_CAL IRC_SLOW
    
    
    myMacro  macro prefix
    myMacro??_??prefix??_??count ds 1  ;count value
    
        endm
    
    myMacro_A_code macro
        inc myMacro_A_count
        endm
    
     
        org $10
    myMacro A
    
    ifdef myMacro_A_count
        myMacro_A_code
        endif
    
    



    Does that help? Or am I missing something else... If this gets your first example working, I can move on to the more complex ones.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ---
    James Newton, Host of SXList.com
    james@sxlist.com 1-619-652-0593 fax:1-208-279-8767
    SX FAQ / Code / Tutorials / Documentation:
    http://www.sxlist.com Pick faster!



  • James NewtonJames Newton Posts: 329
    edited 2005-04-29 18:29
    I was just looking at vplib.src. Wow... I love the way you are including the vp code only once and only when needed. The trick is the order so that the VP code is placed before the main code and so you don't have to jump around each one.


    Why do you take up a file register for "vp_bank"? You could just mov fsr, #vp??nr??_bank after vp??nr??_isr thereby saving a register and a cycle. Or am I missing something there?

    I will have to spend quite some time to understand all of the features you have in this... but I appears it will be worth it. With some include files to seperate things out, that could be a very nice template. Will you publish the result when you are satisfied with it?

    Thanks!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ---
    James Newton, Host of SXList.com
    james@sxlist.com 1-619-652-0593 fax:1-208-279-8767
    SX FAQ / Code / Tutorials / Documentation:
    http://www.sxlist.com Pick faster!



  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2005-04-29 20:34
    James,

    I use vp_bank if and only if executing inside the isr. The main level code

    does not touch vp_bank. Notice that I have a single isr subroutine for

    multiple uart records (each in their own·rambank) so vp_bank gets

    loaded prior to executing that isr subroutine. (Perhaps I should rename it

    to isr_bank). Inside that isr, fsr is changed because of dynamic pin access,

    and so fsr is reloaded from vp_bank to access the correct rambank afterwards.



    In general, a VP macro

    consists of isr code (labelled vp??nr??_isr),

    main code (labelled vp??nr??_main),

    and additional routines called by either isr code or main code.

    I have completed the vplib.src with an i2c_slave macro.

    This particular macro requires two isr_flags (one to notify when

    a byte is received, and another one to notify when a byte is needed).

    I am still struggling with the·format for the defvp macro.

    For now, I use nr+1 as the 2nd isr flag for that macro.

    The end goal, is to move·all constants and macros to an include file,

    so in the project file only an include is visable.

    regards peter
Sign In or Register to comment.