Shop OBEX P1 Docs P2 Docs Learn Events
Using Multiple Cogs in PASM — Parallax Forums

Using Multiple Cogs in PASM

tholbertontholberton Posts: 41
edited 2012-05-26 11:18 in Propeller 1
I want to start using multiple cogs in assembly, but i'm not quite sure how to go about that. I've seen a lot of things about using stacks but I'm not really sure what those are used for. Here's what's not working:
CON
_clkmode = xtal1
_xinfreq = 5_000_000

PUB Main
cognew(@test_code, 0)
cognew(@test_code_two,1)

DAT
org 0
test_code
{stuff here}
fit


org 0
test_code_two
{stuff here}
fit

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2012-05-24 01:57
    tholberton wrote: »
    Here's what's not working:
    I am assuming that {stuff here} is some useful/valid code. How do you know it's not working? That said, the cognew part is perfectly valid (with the exception that the second parameter has to be a 4n value).
  • tholbertontholberton Posts: 41
    edited 2012-05-24 02:04
    well i just removed the code, and did a simple debug with leds... it's working now. but what you do mean 4n value?
  • kuronekokuroneko Posts: 3,623
    edited 2012-05-24 02:07
    4n: multiple of four

    The second parameter to cognew will end up in the par(ameter) register ($1F0). The way coginit/cognew works means that only 14 bits of this parameter can be transferred to the cog. In order to cover the 16bit address range only bits 15..2 are used. Anything else will be cut off (your 1 for the second cog will appear as 0).
  • tholbertontholberton Posts: 41
    edited 2012-05-24 02:07
    I take that back... it's not working.
    here's the code:

    CON
    _clkmode = xtal1
    _xinfreq = 5_000_000

    PUB Main
    cognew(@test_code, 0)
    cognew(@test_code, 1)

    DAT
    org 0
    test_code
    mov dira,#256 {pin 8}
    mov outa,#256
    fit
    org 0
    test_code_two
    add dira,pin9
    add outa,pin9
    pin9 long 512 {pin 9}
    fit
  • tholbertontholberton Posts: 41
    edited 2012-05-24 02:10
    oh, I thought that was the cog id... then what does the parameter do? or what's it used for?
  • kuronekokuroneko Posts: 3,623
    edited 2012-05-24 02:13
    When you post code it helps (us) when you embed it in [noparse]
    
    [/noparse] tags.

    As for the code, excution doesn't stop unless you tell it to. IOW after setting the relevant pin to high the cog keeps executing whatever is in memory which may have unwanted side effects (remember that a cog memory is always loaded full size regardless of actual program size). To stop execution simply add a loop or other wait command, e.g.
    jmp     #$     ' # optional
    
    waitpeq $, #0
    
  • Heater.Heater. Posts: 21,230
    edited 2012-05-24 02:18
    So what do you expect it to do and what does it actually do?
    I note you are not using test_code_two.
    Also be aware that cognew loads 512 longs into your cog no matter how long you think your program is.
    So when you cognew test_code_one it also loads the following test_code_two longs. Of course the first cog then runs both codes and then runs whatever junk follows in memory.
    Probably not what you want.
    Put a jmp to self at the end of your test codes or have each jmp back to their start locations at the end.
  • kuronekokuroneko Posts: 3,623
    edited 2012-05-24 02:18
    tholberton wrote: »
    oh, I thought that was the cog id... then what does the parameter do? or what's it used for?
    Whatever you want it to do (provided 14bit are enough). People around here usually use it to communicate between different cogs and/or languages.
  • tholbertontholberton Posts: 41
    edited 2012-05-24 02:26
    okay, i added the waitpeq, but it's still not turning on pin 9. and i'm still unclear about the parameter part. i'm reading the manual right now
    CON
      _clkmode = xtal1 
      _xinfreq = 5_000_000  
    PUB Main
      coginit(0,@test_code,0)
      coginit(1,@test_code_two,0)
    DAT
    org 0
    test_code
    add dira,#256        {pin 8}
    xor outa,#256
    waitpeq $,#0
    fit
    
    
    org 0
    test_code_two
    add dira,pin9
    add outa,pin9
    waitpeq $,#0
    pin9 long 512            {pin 9}
    
    
    fit
    
  • tholbertontholberton Posts: 41
    edited 2012-05-24 02:28
    oh okay, thanks Heater. and kuroneko that makes sense
  • kuronekokuroneko Posts: 3,623
    edited 2012-05-24 02:28
    tholberton wrote: »
    okay, i added the waitpeq, but it's still not turning on pin 9.
    May I suggest you stick with cognew for now? By re-starting cog 0 you basically kill the SPIN interpreter (after re/boot usually cog 0 is used) and therefore your second cog is never started. Using cognew will attempt to start the next available cog (e.g. 1 and 2).
  • tholbertontholberton Posts: 41
    edited 2012-05-24 02:31
    kuroneko wrote: »
    May I suggest you stick with cognew for now? By re-starting cog 0 you basically kill the SPIN interpreter (after re/boot cog 0 is used) and therefore your second cog is never started.

    okay, that pretty much made it work. it's written like this now:
    CON
      _clkmode = xtal1 
      _xinfreq = 5_000_000  
    PUB Main
      cognew(@test_code,0)
      cognew(@test_code_two,0)
    DAT
    org 0
    test_code
    add dira,#256        {pin 8}
    xor outa,#256
    waitpeq $,#0
    fit
    
    
    org 0
    test_code_two
    add dira,pin9
    add outa,pin9
    waitpeq $,#0
    pin9 long 512            {pin 9}
    
    
    fit
    
  • PliersPliers Posts: 280
    edited 2012-05-26 05:10
    I hope this is not considered hijacking a thread, but I am having the same problem. Two cogs running.
    Here is my code and I can not get the intended results. All eight LEDs should be on.
    pub main
    cognew(@IOtest1,0)
    cognew(@IOtest2,0)                        
    dat
                   org 0
     IOtest1     mov dira, pin        
     loop1           
                 mov outa,out1
                 jmp #loop1
                   
     IOtest2     mov dira, pin        
     loop2           
                mov outa,out2
                jmp #loop2
               
     pin  long  000000_11111111_00000000_00000000 
     out1 long  000000_11000011_00000000_00000000 
     out2 long  000000_00111100_00000000_00000000 
    FIT
    
  • kuronekokuroneko Posts: 3,623
    edited 2012-05-26 05:26
    In short, each cog image should start with an org 0 and should have its own set of variables.
    pub main
    cognew(@IOtest1,0)
    cognew(@IOtest2,0)                        
    
    DAT             org     0
    
    IOtest1         mov     dira, :pin
    :loop1           
                    mov     outa, :out1
                    jmp     #:loop1
    
    :pin            long    %00000000_11111111_00000000_00000000
    :out1           long    %00000000_11000011_00000000_00000000
    
                    fit
    
    DAT             org     0               
    
    IOtest2         mov     dira, :pin
    :loop2           
                    mov     outa, :out2
                    jmp     #:loop2
               
    :pin            long    %00000000_11111111_00000000_00000000
    :out2           long    %00000000_00111100_00000000_00000000
    
                    fit
    
    In your example IOtest2 is assembled for cog location 3 but loaded at 0 which more often than not goes wrong.
  • turbosupraturbosupra Posts: 1,088
    edited 2012-05-26 07:20
    Why not make each cog an object? So you can reuse the code in other projects?
  • PliersPliers Posts: 280
    edited 2012-05-26 11:18
    Thanks kuroneko for the solution.
    I very much appreciate your help.


    Turbosupra, I have been away from the prop for a while and I'm re-learning the program.
    I agree that objects are a great way to build a program.

    Thanks again for your help.
    Best regards.

Sign In or Register to comment.