Yet another Global vs Local variables question across COGs
JackBak
Posts: 45
Ok, lets keep this simple - no objects just one spin file. First COG is spin MAIN to fire off COG2 which is pure PASM.
Code is below. Note this is stub code so after the muxnc line nothing is going to work, I'm using the PASD tool to see
what is going on.
From what I can see q_pin through q_rpt are available in Main RAM to the COG1 spin code and when I fire off COG2
local versions of q_pin through q_rpt are instantiated. So in COG2 I get the global value of q_rpt by going thru an offset
from the par register. But if I simplify that idle loop by referencing q_rpt directly COG2 PASM code thinks it is the local
copy of q_rpt.
Notice that I can change q_rpt to a value of 2 by pressing a button on the Prop Professional Dev. Board (PPDB). When
I do that the main RAM version of q_rpt changes to 2 but unless I do the indexed par code below COG2 won't see
that new value of q_rpt.
Thanks,
Jack
Code is below. Note this is stub code so after the muxnc line nothing is going to work, I'm using the PASD tool to see
what is going on.
From what I can see q_pin through q_rpt are available in Main RAM to the COG1 spin code and when I fire off COG2
local versions of q_pin through q_rpt are instantiated. So in COG2 I get the global value of q_rpt by going thru an offset
from the par register. But if I simplify that idle loop by referencing q_rpt directly COG2 PASM code thinks it is the local
copy of q_rpt.
Notice that I can change q_rpt to a value of 2 by pressing a button on the Prop Professional Dev. Board (PPDB). When
I do that the main RAM version of q_rpt changes to 2 but unless I do the indexed par code below COG2 won't see
that new value of q_rpt.
{{ [b]test[/b] code }} [b]CON[/b] [b]_clkmode[/b] = [b]xtal1[/b] + [b]pll16x[/b] [b]_xinfreq[/b] = 5_000_000 '***************************************************************************** ' Global Definitions '***************************************************************************** _OUTPUT = 1 'Sets pin to output in DIRA register _INPUT = 0 'Sets pin to input in DIRA register _HIGH = 1 'High=ON=1=3.3v DC _ON = 1 _LOW = 0 'Low=OFF=0=0v DC _OFF = 0 _ENABLE = [b]true[/b] 'Enable (turn on) function/mode _DISABLE = [b]false[/b] 'Disable (turn off) function/mode '********************** L O C A L C O N S T A N T S ************************* BP = 4 'Button pin [b]OBJ[/b] dbg : "PasDebug" [b]VAR[/b] [b]long[/b] Cog [b]PUB[/b] Main | Time [b]dira[/b][noparse][[/noparse]*BP]~ 'Input q_rpt := 0 dbg.start(31, 30, @entry) Cog := [b]cognew[/b](@entry, @q_pin) + 1 [b]repeat[/b] [b]if[/b] [b]ina[/b][noparse][[/noparse]*BP] == _LOW 'on button push light LED q_rpt := 2 [b]dira[/b][noparse][[/noparse]*16]~~ [b]outa[/b][noparse][[/noparse]*16] := _HIGH [b]waitcnt[/b]([b]cnt[/b] + (clkfreq / 1_000) * 3_000) ' 3 seconds ON [b]outa[/b][noparse][[/noparse]*16] := _LOW 'LED off [b]DAT[/b] [b]org[/b] 0 entry ' --------- Debugger Kernel add this at Entry (Addr 0) --------- [b]long[/b] $34FC1202,$6CE81201,$83C120B,$8BC0E0A,$E87C0E03,$8BC0E0A [b]long[/b] $EC7C0E05,$A0BC1207,$5C7C0003,$5C7C0003,$7FFC,$7FF8 ' -------------------------------------------------------------- [b]movd[/b] :loop, #repeat_cnt [b]mov[/b] tmp, [b]par[/b] [b]add[/b] tmp, #16 :loop [b]rdlong[/b] 0-0, tmp [b]test[/b] repeat_cnt, #$FF [b]wz[/b] [b]if_z[/b] [b]jmp[/b] #:loop 'we will wait for something to do [b]movd[/b] parmld, #pin 'fall thru as we apparently have work to do [b]mov[/b] p, [b]par[/b] [b]mov[/b] j, #05 parmld [b]rdlong[/b] 0-0, p [b]add[/b] parmld, dlsb [b]add[/b] p, #4 [b]djnz[/b] j, #parmld 'loop until we finish loading the parameters [b]mov[/b] pmask, #1 [b]shl[/b] pmask, q_pin [b]muxnc[/b] [b]dira[/b], pmask dlsb [b]long[/b] 1 << 9 q_pin [b]long[/b] $0A q_pat [b]long[/b] $A5 'data pattern q_win [b]long[/b] $12 'window for pattern q_dly [b]long[/b] $34 'delay until next repeat of pattern q_rpt [b]long[/b] $FF 'repeat count - if 0 driver loops waiting for non-zero ' ' Unitialized data ' p [b]res[/b] 1 'parameter pointer j [b]res[/b] 1 'counter pmask [b]res[/b] 1 'pin mask tmp [b]res[/b] 1 pin [b]res[/b] 1 pattern [b]res[/b] 1 window [b]res[/b] 1 delay [b]res[/b] 1 repeat_cnt [b]res[/b] 1
Thanks,
Jack
Comments
If the COGs are to work together, they've got to pull the shared memory into their space to operate on it, or operate on the HUB value directly.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Propeller Wiki: Share the coolness!
Chat in real time with other Propellerheads on IRC #propeller @ freenode.net
Safety Tip: Life is as good as YOU think it is!
having to go thru the PAR register and adding an index. Is this not possible to do except as I have shown? And yes,
I know what you are referring to by letting the Main COG update a COG2 method - seems a bit much and too time expensive.
Thanks,
Jack
So, in your startup code, you might have something like the following:
mov index, PAR
rdlong value1, index
mov value1_pointer, index
add index, #4
rdlong value2, index
mov value1_pointer, index
that way you capture your pointers when the cog gets up and running.
In your DAT, you then have:
value1 long 0
value1_pointer long 0
...
To update the cog, you do rdlong value1, value1_pointer
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Propeller Wiki: Share the coolness!
Chat in real time with other Propellerheads on IRC #propeller @ freenode.net
Safety Tip: Life is as good as YOU think it is!
Post Edited (potatohead) : 10/15/2009 9:51:13 PM GMT
I think I'm starting to read between the lines here. Probably do it this way and be done with it.
Best regards,
Jack.
Andy
Still kinda irritating that I have to do it with an index to PAR because it ties down the structure of the variables.
I have to know the offset to hard code it into the ADD instruction. Linkers were made to keep track of things like
this.
Regards,
Jack
Andy
So, my understanding is, that you want to run the PASM code straight away, as the q_-variables are already initialized in the code. If you don't use the RES variables in PASM, but the q_-variable-copies in COG-RAM, you don't waste 5 longs and you can start straight away without copying the values in the first place, because cognew already did that for you.
I suppose after you repeated your code q_rpt-times, you go back to wait for q_rpt to be set again. But you have to clear it in HUB-RAM, otherwise your PASM might pick q_rpt from HUB-RAM before SPIN had a chance to set it to·0. Please remember: PASM is much faster than SPIN.
Hope that helped.
Post Edited (MagIO2) : 10/16/2009 6:38:32 AM GMT
The main reason you have to use rd/wr/long/word/byte is because you have 16 bit addressing so you have to use indirect addressing (i.e. a pointer). Cog memory is limited to 9 bit addressing.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBlade,·RamBlade, RetroBlade,·TwinBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: Micros eg Altair, and Terminals eg VT100 (Index) ZiCog (Z80) , MoCog (6809)
· Search the Propeller forums·(uses advanced Google search)
My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
I'm positive impressed ! Very good and detailed formatted source-code !
best regards
Stefan
@Andy:
Yes it's all coming back to me (my assembler tricks that is)... let the compiler do the math #@q_rpt-@q_pin
@MagIO2:
Very nice, yes as I alluded to above I had not optimized anything and this was just stub code that I threw together
to test concepts. I did think of putting q_rpt as the first variable in the block thus no index offset needed in the top idle loop.
The reason I did not and in fact put it last was as a mental crutch to remind me that in any code I used to modify these
hub variables I must change q_rpt to a non-zero last else the PASM driver would start executing on old data.
My mental calculus was that since PASM code was plenty fast enough for this project I could tolerate the extra ADD offset.
@Cluso99:
Huh, why is zero illegal? Yes I had already thought about the sequence of setting variable see my comment above to MagIO2.
[noparse][[/noparse]Edit] or did you mean illegal in the sense that that value in q_rpt would cause the driver to idle endlessly.
Again really good stuff everyone thank you.
Best regards,
Jack
Post Edited (JackBak) : 10/16/2009 1:59:24 PM GMT