Shop OBEX P1 Docs P2 Docs Learn Events
How am I supposed to use COGINIT in SPIN2 to control multiple cogs in parallel? — Parallax Forums

How am I supposed to use COGINIT in SPIN2 to control multiple cogs in parallel?

************Hello,
I am new to Spin2 and am having enormous difficulty. I am trying to use COGINIT **to turn on different LEDs in each cog, but I can't seem to get it to work. If anyone has the answer to my question, it would be a huge help.
Currently, my code looks like this:
**CON

_clkfreq = 200_000_000

****VAR****
long stack[8*32]
long cogida[8]

PUB main() | i
repeat i from 0 to 7
cogida[i] := coginit(i, @blink, @stack[i*32])
waitms(200)
repeat i from 0 to 7
if cogida[i] < 0
debug("coginit failed for cog", i, " : ", cogida[i], "\n")
repeat
waitms(1000)

PUB blink(pAddr) | mypin
mypin := 56 + cogid() 'LEDs 56 à 63
dirb[mypin] := 1
repeat
pintoggle(mypin)
waitms(300)

ooh and i work on P2X8C4M

Comments

  • Please format code inside ``` codeblocks so we can easily see indentation.

    You have a couple of problems. main runs in cog 0, but the first thing it does is restart itself with your blink function, so nothing else in main runs. Perhaps make main only start cogs 1-7 and then call blink itself.

    Do you need to allocate cog numbers yourself when you can make coginit just use the next free one? Sorry, I'm on my phone and forget the constant you need to pass coginit to make it do this, but it's in the documentation.

    You're going to have a bad time trying to flash LEDs on pins 56-63, since they're already used for programming. The biggest symptom you'll probably see is that it interferes with debug output.

  • For launching Spin2 cogs, you should be using cogspin (infact, I don't think @blink with blink being a PUB/PRI function is even valid syntax??). coginit is for launching ASM code only (this changed from Spin1!)

  • JonnyMacJonnyMac Posts: 9,474
    edited 2025-10-13 22:57

    I am new to Spin2 and am having enormous difficulty.

    Then why are you starting with something so obtuse? Learn the basics first, and if you want to prove to yourself that you can run the same code in multiple cogs, do it with two cogs to start with, and do make your code obvious. I copied your code from the forums and it doesn't run -- and it's not worth taking the time to fix. My version of a multi-cog blinker is easier to understand and more flexible than what you're attempting.

    When in doubt, keep it simple.

    var { globals }
    
      long  cid0                                                    ' cog for first blinker
      long  stack0[32]                                              ' stack for first blinker
    
      long  cid1                                                    ' cog for second blinker
      long  stack1[32]                                              ' stack for second blinker
    
    
    pub main() | i, byte cogsused
    
      cid0 := cogspin(newcog, blinker(LED1 , 50,  50), @stack0)     ' fast blink on P56
      cid1 := cogspin(newcog, blinker(LED2, 700, 300), @stack1)     ' slow blink on P57
    
      repeat i from 0 to 7                                          ' scan all cogs
        cogsused.[i] := cogchk(i)                                   '  mark if in use
    
      debug("Blinkers using cogs ", udec_(cid0), " and ", udec_(cid1))
      debug("Cogs in use: ", ubin_byte_(cogsused))
    
      repeat
      ' forever
    
    
    pri blinker(pin, mson, msoff)                                   ' launch with cogspin
    
      repeat
        pinhigh(pin)
        waitms(mson)
        pinlow(pin)
        waitms(msoff)
    
    
  • JonnyMacJonnyMac Posts: 9,474
    edited 2025-10-14 01:02

    Before deleting the file I looked one more time

    • You need to use cogspin to launch Spin methods into their own cog (new interpreter); coginit is for PASM cogs
    • Better to use newcog instead of attempting to crowbar code into a specific cog (unless it's a deliberate replacement issue)
    • Your code wants to trample on cog0 which is loading everything else
    • Your code wants to use P62 and P63 which are used by the DEBUG serial routines

    This works

    PUB main() | i
    
      repeat i from 1 to 5
        cogida[i] := cogspin(i, blink(), @stack[i*32])
        if cogida[i] < 0
          debug("cogspin failed for cog", i, " : ", cogida[i], "\n")
        waitms(200)
    
      repeat
        waitms(1000)
    
    PUB blink() | mypin
    
      mypin := 56 + cogid() 'LEDs 57 à 61
      repeat
        pintoggle(mypin)
        waitms(300)
    

    Note that pintoggle sets the direction bit for the pin so you don't need to do it manually. With Spin2's pin control commands there is almost no reason to deal with the direction bits directly.

  • For fun a quad version that uses cogspin and coginit.

Sign In or Register to comment.