Shop OBEX P1 Docs P2 Docs Learn Events
Launching Cogs in Assembly Trouble — Parallax Forums

Launching Cogs in Assembly Trouble

pjvpjv Posts: 1,903
edited 2009-08-15 17:09 in Propeller 1
Hi All;

I'm trying to learn Propeller assembler, and am having difficulty in understanding what is going wrong when I launch a cog from an assembler routine.

A simple program to launch 3 "toggling" assembler cogs from spin works exactly as expected, but when I modify it (delete launching the second from spin) to launch one of them from one of the spin-launched assembler routines, the direction register seems to get messed up. Through current meassurement observations, I believe that·the·affected·cog IS actually being launched.

_clkmode = xtal1
_clkfreq = 5_000_000

PUB Launch                           'this should be cog0
     dira :=1
     outa := 1
     outa := 0
     coginit(1, @One,0)
     outa := 1
     coginit(2, @Two,0)              'disable this line when enabling the launch from cog2
     outa := 0
     coginit(3, @Three,0)
     outa := 1
 
 
DAT
              org                    'this should be cog1
One           mov       dira,#2
              xor       outa,#2
              xor       outa,#2
'              coginit   AssyLaunch  'assembly launch of cog2 disabled for now, enable when disabling spin launch of cog2
Loop1         xor       outa,#2
              jmp       #Loop1

 
AssyLaunch    long      @Two  <<4 | %0_010    'particulars for launching cog2

 
 
DAT
              org                    'this should be cog2
Two           mov       dira,#4
              xor       outa,#4
Loop2         xor       outa,#4
              jmp       #Loop2
 
DAT
              org                    'this should be cog3
Three         mov       dira,#8
              xor       outa,#8
Loop3         xor       outa,#8
              jmp       #Loop3
 


When spin launches cogs1, 2 and 3, I get toggling on all 3 cog lines, but when I comment-out the spin-launch of cog2, and enable the cog1 launch of cog2, I get no output on cog2's· "4"pin.... as if the cog2 direction register gets cleared. Replacing the three direction setting instructions "mov· dira,#num" with "or· dira,#num" does not fix the problem.

What am I doing wrong??

Cheers,

Peter (pjv)

Comments

  • TimmooreTimmoore Posts: 1,031
    edited 2009-08-14 23:16
    coginit needs the hub address, you are passing in the cog address. See page 10 of http://forums.parallax.com/forums/attach.aspx?a=17267
  • Mike GreenMike Green Posts: 23,101
    edited 2009-08-14 23:43
    The problem is in your use of "@Two" at AssyLaunch. Timmoore has the right idea. The problem is that the Spin compiler thinks it doesn't really know the address of Two when assembling AssyLaunch. Try the following:
    _clkmode = xtal1
    _clkfreq = 5_000_000
    
    PUB Launch                           'this should be cog0
         dira :=1
         outa := 1
         outa := 0
         coginit(1, @One,@Two)       ' This passes the run-time hub address of Two to the first routine in PAR
         outa := 1
         coginit(2, @Two,0)              'disable this line when enabling the launch from cog2
         outa := 0
         coginit(3, @Three,0)
         outa := 1
     
     
    DAT
                  org                    'this should be cog1
    One           mov       dira,#2
                  xor       outa,#2
                  xor       outa,#2
                  mov    AssyLaunch,PAR         ' get real address of Two
                  shl      AssyLaunch,#4           ' shift address into position
                  or       AssyLaunch,#%0_010 ' include cog# and COGINIT bit
    '              coginit   AssyLaunch  'assembly launch of cog2 disabled for now, enable when disabling spin launch of cog2
    Loop1         xor       outa,#2
                  jmp       #Loop1
     
    AssyLaunch    res      1
    
     
     
    DAT
                  org                    'this should be cog2
    Two           mov       dira,#4
                  xor       outa,#4
    Loop2         xor       outa,#4
                  jmp       #Loop2
     
    DAT
                  org                    'this should be cog3
    Three         mov       dira,#8
                  xor       outa,#8
    Loop3         xor       outa,#8
                  jmp       #Loop3
    
  • pjvpjv Posts: 1,903
    edited 2009-08-15 00:25
    Hi Tim, and Mike;

    I thought I had pre-loaded AssyLaunch with the correct hub address..... at least according to the HEX window of the listing, as well as hand-decoding the instructions. So I modified my code to read identical to Mike's suggestion (plus of course deleting the spin launch of cog2 and enabling the cog1 launch of cog2), and it still yields the same results; no toggling on cog2.

    @Tim: I'm still trying to wrap my head around this symbol's differing actions...... I spent a lot of time today counting and decoding instructions from the HEX listing window.

    What else might be wrong..... could there be a timing issue because spin is still getting cog3 loaded while cog1 is trying to load cog2?

    Cheers,

    Peter (pjv)
  • BradCBradC Posts: 2,601
    edited 2009-08-15 04:10
    pjv said...
    Hi Tim, and Mike;

    I thought I had pre-loaded AssyLaunch with the correct hub address..... at least according to the HEX window of the listing, as well as hand-decoding the instructions. So I modified my code to read identical to Mike's suggestion (plus of course deleting the spin launch of cog2 and enabling the cog1 launch of cog2), and it still yields the same results; no toggling on cog2.

    @Tim: I'm still trying to wrap my head around this symbol's differing actions...... I spent a lot of time today counting and decoding instructions from the HEX listing window.

    What else might be wrong..... could there be a timing issue because spin is still getting cog3 loaded while cog1 is trying to load cog2?

    Do you realise the address you need to put in [noparse][[/noparse] 17..4 ] is the top 14 bits of the address?

    Try
                  mov    AssyLaunch,PAR         ' get real address of Two
                  shl      AssyLaunch,#2           ' shift address into position
                  or       AssyLaunch,#%0_010 ' include cog# and COGINIT bit
    
    



    This will work as PAR automatically zeros the bottom 2 bits anyway. Ordinarily it's a good idea to mask it first. I use something like this in spin.

    PUB FRED
      Launcher := ((@@newcog >> 2) << 4) + %0_010
    
    DAT 
    
    go          org 0
                  coginit Launcher
    
    Launcher  long  0
    
    newcog  org 0
    
    



    This way you use the spin interpreter to fix the object offset for you and remove any guesswork. If you don't want to do that, and you are *sure* you are always going to be the top object then you could do :
    Launcher long  ((@newcog+$10) >> 2) << 4 + %0_010
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    lt's not particularly silly, is it?
  • BradCBradC Posts: 2,601
    edited 2009-08-15 04:14
    Here's a real example for you. RinksCustoms and I were using this to measure the launch time of a cog using a DSO

    CON
      _clkmode      = xtal1 + pll16x
      _xinfreq      = 5_000_000
    
    
    PUB Start
      cognew(@cog0,0)
    
    DAT
    cog0                    org
                  mov       dira, #1
                  mov       outa, #1
                  mov       da, cnt
                  add       da, dly
    :loop
                  waitcnt   da, dly
                  mov       outa, #1
                  coginit   newcog
                  mov       dc, #511
                  add       dc, cnt
                  waitcnt   dc, #0
                  mov       outa, #0
                  jmp       #:loop
    
    
    newcog  long  ((@cog1+$10) >> 2) << 4 + $8
    da      long  0
    dly     long  80_000_000/10
    dc      long  0
    
    cog1                    org
                  mov       dira, #2
                  mov       outa, #2
                  cogid     thiscog
                  cogstop   thiscog
    
    db            long      0
    thiscog       long      0
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    lt's not particularly silly, is it?
  • pjvpjv Posts: 1,903
    edited 2009-08-15 17:09
    Hi Brad;

    You're the man!

    I now see in my code I shifted 4 left when it should have been 2, because the address for the Parameter register is 14 bits long. Shifting in zeros then of course permits the new/old·cog·bit and chosen cog number just to be merged into the long. And of course the $10 starting offset has to be added..... I had earlier included that, but with the incorrect shifts the result was wrong.

    It·can really as simple as the following code:

    _clkmode = xtal1
    _clkfreq = 5_000_000
    
    PUB Launch
         dira :=1
         outa := 1
         outa := 0
         coginit(1, @One,0)
         outa := 1
     '    coginit(2, @Two,0)                   'delete this line when cog1 is to launch cog2
         outa := 0
         coginit(3, @Three,0)
         outa := 1
     
    DAT
                  org                          
    One           mov       dira,#2
                  xor       outa,#2
                  xor       outa,#2
                  coginit   AssyLaunch         'delete this line when PUB is to launch cog2
    Loop1         xor       outa,#2
                  jmp       #Loop1
    AssyLaunch    long      (@Two+$10) <<2 | %0_010
     
    DAT
                  org
    Two           mov       dira,#4
                  xor       outa,#4
    Loop2         xor       outa,#4
                  jmp       #Loop2
     
    DAT
                  org
    Three         mov       dira,#8
                  xor       outa,#8
    Loop3         xor       outa,#8
                  jmp       #Loop3
     
    


    Anyhow, up and running, so THANKS!

    Cheers,

    Peter (pjv)
Sign In or Register to comment.