Shop OBEX P1 Docs P2 Docs Learn Events
How to retrieve global variable values from VAR block inside DAT block. — Parallax Forums

How to retrieve global variable values from VAR block inside DAT block.

NicopowersNicopowers Posts: 12
edited 2017-01-24 00:22 in Propeller 1
Greetings Parallax Forum,
I am trying to constantly use a new and updated global variable inside the DAT block; however, when I try to reference that global variable, I get an error that says "Expected a constant, unary operator, or "("" below, I have the code that gives me the error:
CON
  _CLKMODE = xtal1 + pll16x                       ' System clock --> 80 MHz
  _XINFREQ = 5_000_000

  MY_LED_PIN = 17                                  'this variable is used for the designation of the PIN to be toggled

  

VAR

        long          Divider, Frequenz

OBJ

  pst : "Parallax Serial Terminal"


PUB main 
  
  Frequenz := 4000000
  cognew(@blink, 0)                                     'Start a Cog with our assembly routine, no stack
                                                        'is required since PASM requires we explicitly
                                                        'assign and use memory locations within the Cog/Hub
'  Divider = 0

'  repeat 10
'      Divider ++
                        
              
DAT

                                                        'Step 1 of 3: -->  This is the Assembly Code
        org             0
blink   mov             dira,     Pin                   'Set our Pin to an output
        'rdlong          Delay,    #0                   'Prime the Delay variable with memory location 0
 '       shr             Delay,    #2                         'important --> Divide by value indicated after "#"
                                                        'this is where the Propeller stores the CLKFREQ variable
                                                        'which is the number of clock ticks per second
        mov             Time,     cnt                  'Prime our timer with the current value of the system counter
        add             Time,     #9                    'Add a minimum delay (more on this below)
:loop   waitcnt         Time,     Delay                 'Start waiting
        xor             outa,     Pin                   'Toggle our output pin with "xor"
        jmp             #:loop                          'Jump back to the beginning of our loop

                                                        ' Step 2 of 3: --> Initialization of Symbolic Data
                                                

Pin     long            |< MY_LED_PIN                   'Encode MY_LED_PIN to a bit mask -->  Other alternative Pin      long         $0000_0010    Answer: Use I/O pin 4($10 or %1_0000)

'Pin     long            $0000_0000                     '--> not used          

Delay   long   Frequenz                                  'clock cycles to delay
              



Delay                   res        1                    'Step 3 of 3: --> Reserved symbolic memory
Time                    res        1
        fit


As you can see, I am trying to use the global variable "Frequenz" that I initialize in PUB main, and then passing that value to "Delay" to then be used inside my loop that resides inside the DAT block. I have experience programming in SPIN Language, but I am not familiar with the Assembly environment. Is there a way to possibly read the data from the global variable via. it's memory address? Is there a semantic/syntactical solution to this? Any help will be much appreciated, thank you so much!

Comments

  • Duane DegnDuane Degn Posts: 10,588
    edited 2017-01-24 08:08
    Edit: Sorry, I didn't read the original question carefully. Go with Andy's suggestion.

    There are a couple ways to do this.

    You could make "Frequenz" a constant:
    CON
      FREQUENZ = 4000000
    

    The then use this constant to define delay.
    Delay                   long        FREQUENZ
    

    You could also just define Delay as 4000000.
    Delay                   long        4000000
    

    Of before launching the cog, you could define Delay.
    PUB main 
      
      Frequenz := 4000000
      Delay := Frequenz
      cognew(@blink, 0)
    

    To do this, you'd need to define Delay as a long.
    Delay                   long        0 ' changed by main method
    

    If you're going to hard code the value of Delay you might as well do it this way:
    Delay                   long        4000000
    
  • AribaAriba Posts: 2,690
    edited 2017-01-24 02:16
    Nicopowers wrote: »
    ...
    Is there a way to possibly read the data from the global variable via. it's memory address? Is there a semantic/syntactical solution to this? Any help will be much appreciated, thank you so much!

    Yes, you can pass the address of the Frequenz variable as a parameter on cog start:
    cognew(@blink, @Frequenz)
    
    Then in the Assembly code loop, you read the current value of the variable with:
         ...
         rdlong  Delay,par
         ...
    
    par holds the address you passed in cognew's second argument. Be aware that this must be a long aligned address.

    Andy
  • Andy's approach only works for that instance of the object through which main was activated.

    If there are multiple instances of this object, there is no real solution to your problem.

    If there's only a single instance then there's no reason to use the var declarations, move them to dat and it's all suddenly simple.
Sign In or Register to comment.