Shop OBEX P1 Docs P2 Docs Learn Events
asm coginit — Parallax Forums

asm coginit

DelusDelus Posts: 79
edited 2008-12-22 04:07 in Propeller 1
I'm some what new to prop asm and am trying to convert a spin program a wrote to asm.· Everything is working when i start all the cogs in spin but i can't seem to figure out how to get a cog to start in asm.· If anyone has an example of this it would be greatly apreciated.· I am starting each cog with a given id so i don't need to get the id of the started cog back.

Thanks in advance.

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2008-11-23 20:18
    First of all, it's bad programming practice most of the time to use specific cogs (with the COGINIT instruction). There are some situations where that's necessary, but most of the time you'll make a mistake and use the wrong cog and it will take a lot of time and effort to find the error. Use COGNEW and save the id of the cog if you want to stop it later.

    If you're starting an assembly cog from Spin, use the COGNEW statement. There's an example on page 191 of the Propeller Manual.

    If you're starting an assembly cog from assembly, use the COGINIT instruction with the NEW bit set in the operand (page 366).
  • DelusDelus Posts: 79
    edited 2008-11-27 16:23
    I'm trying to do everything in asm with the exeption of the first coginit call i use in spin. I'm doing this mostly to farmiliarize myself with prop asm so i'd like to get both ways working. the reson i have decided to start by starting specific cogs is to inshure i do not accidentally restart a cog i've already started later though this could also be done by getting the cog id back as you suggested. in either case what i'm not sure about is how i'm supposed to setup the destination register for calling coginit in asm. currently i chop off the last two bits of the parameter which points to a global variable then shift it left 16 bits before oring it with the register i'm using as the destination of coginit which was previosly initialized to zero. i then do the same thing with the address of the asm i whant to load into a new cog(this could be my problem as i'm not quite sure what to use here) shifting it 4 instead of 16 then or the cog id and call coginit.

    sorry if this is a bit long winded and/or confusing I will post my code once I get back and clean it up a bit.

    (changed to shifting by 14 and 2 bits but still no luck)

    Post Edited (Delus) : 11/27/2008 6:47:14 PM GMT
  • AribaAriba Posts: 2,687
    edited 2008-11-27 17:25
    Here is a short part of the PASD assembly code which restarts the debugged cog:
    resetcog                cogstop cognr
                            mov     t1,cogpar               'restart cog
                            shl     t1,#14
                            or      t1,cogaddr
                            shl     t1,#2
                            or      t1,cognr
                            coginit t1
    
    


    cognr, cogaddr and cogpar are registers which saves the id, the startaddress and the parameter value to pass to the new cog.
    cogaddr and cogpar must have the lower 2 bits cleared (long aligned addresses).

    Andy
  • DelusDelus Posts: 79
    edited 2008-11-27 18:22
    ok that's almost exactly what i have exept i clear the lower two bits as part of the init process. written an extreemly simple program to figure this out which seems to work and then quit's randomly.

    here's the code:

    var
    long waitTime

    pub main
    waitTime := 5_000_000
    coginit(0, @mainEntry, @waittime)
    'blinkTest

    pri blinkTest
    dira[noparse][[/noparse]12] := 1
    repeat
    if outa[noparse][[/noparse]12] == 0
    outa[noparse][[/noparse]12] := 1
    else
    outa[noparse][[/noparse]12] := 0
    waitcnt(5_000_000+cnt)

    dat
    org
    mainEntry
    mov parameter, par
    mov cID, #1

    mov cInitDest, #0
    and parameter, Mask14Bit
    shl Parameter, #14
    or cInitDest, parameter
    and BlinkEnt, Mask14Bit
    shl BlinkEnt, #2
    or cInitDest, BlinkEnt
    or cInitDest, cID
    coginit cInitDest

    cInitDest res 1
    parameter res 1
    cID res 1
    BlinkEnt long @blinkTestEntry
    Mask14Bit long $00_00_FF_FC

    org
    blinkTestEntry
    mov outpin, #1
    shl outpin, #12
    mov dira, outpin
    rdlong delta, par
    mov wait, cnt
    add wait, delta
    blinkLoop xor outa, outpin
    waitcnt wait, delta
    jmp #blinkLoop
    outpin res 1
    delta res 1
    wait res 1

    this seems to work for a few minutes then the led attached to pin 16 stops blinking and stays lit all the time.(actually after running it a few times it just stops blinking lit or unlit seems random)
    ps how do you post code in a box as above?

    Post Edited (Delus) : 11/27/2008 7:10:33 PM GMT
  • Mike GreenMike Green Posts: 23,101
    edited 2008-11-27 19:02
    For posting code, use "[noparse][[/noparse] code ]" at the beginning of the block and "[noparse][[/noparse] /code ]" at the end of the block. Note that I've added spaces before and after the tags so the tag parser won't interpret them. Leave the extra spaces out.
  • AribaAriba Posts: 2,687
    edited 2008-11-27 22:13
    I think your problem is this variable definition in DAT:

    BlinkEnt long @blinkTestEntry

    this is solved at compile time and gives not the right address for blinkTestEntry (only an object relativ offset)
    You can add this to the Spin main routine, before the coginit:

    BlinkEnt := @blinkTestEntry

    then you have the right address in the BlinkEnt var when the cog is started.

    Andy
  • Mike GreenMike Green Posts: 23,101
    edited 2008-11-27 22:17
    Also, you need to have RES items as the last in the cog

    Instead of
    cInitDest res 1
    parameter res 1 
    cID res 1 
    BlinkEnt long @blinkTestEntry
    Mask14Bit long $00_00_FF_FC
    


    use
    BlinkEnt long @blinkTestEntry
    Mask14Bit long $00_00_FF_FC
    cInitDest res 1
    parameter res 1 
    cID res 1
    
  • DelusDelus Posts: 79
    edited 2008-11-27 22:44
    Mike I've done that with no luck, Ariba i get an error when i try your suggestion...about ready to give up.

    here's my current code
    [noparse][[/noparse]code]
    var
    long waitTime
    pub main
    · waitTime := 5_000_000
    · coginit(0, @mainEntry, @waittime)
    · 'blinkTest

    dat
    ······· org
    mainEntry
    ······················· mov······ parameter, par
    ······················· mov······ cID, #1
    ······················· cogstop cID
    ······················· mov···· t1, #0
    ······················· mov···· t1,parameter·············· 'restart cog
    ······················· shl···· t1,#14
    ······················· or····· t1,BlinkEnt
    ······················· shl···· t1,#2
    ······················· or····· t1,cID
    ······················· coginit t1

    ······················· mov······ cID, #0
    ······················· cogstop·· cID
    ·············
    ············· mov······ cInitDest, #0
    ············· 'and······ parameter, Mask14Bit
    ············· shl······ Parameter, #14
    ············· or······· cInitDest, parameter
    ············· 'and······ BlinkEnt, Mask14Bit
    ············· shl······ BlinkEnt, #2
    ············· or······· cInitDest, BlinkEnt
    ············· or······· cInitDest, cID
    ············· coginit·· cInitDest
    ············· mov······ cID, #0
    ············· cogstop·· cID
    ····················
    BlinkEnt····· long····· @blinkTestEntry
    Mask14Bit···· long····· $00_00_FF_FC
    t1··········· res 1···········
    cInitDest···· res 1
    parameter···· res 1···················
    cID·········· res 1····································
    ············· org
    blinkTestEntry
    ············· mov······ outpin, #1
    ············· shl······ outpin, #12
    ············· mov······ dira, outpin
    ············· mov······ wait, cnt
    ············· add······ wait, delta
    blinkLoop···· xor······ outa, outpin
    ············· waitcnt·· wait, delta
    ············· jmp······ #blinkLoop
    ·············
    delta········ long····· 5_000_000
    outpin······· res 1·············
    wait········· res 1
    [noparse][[/noparse]/code]


    Post Edited (Delus) : 11/27/2008 10:52:09 PM GMT
  • DelusDelus Posts: 79
    edited 2008-11-27 23:06
    ok using the toggle method from the manual and the code from abriba ive come up with this which still does not work...

    and i can't get the code box to work on this form arg!

    CON
    _clkmode = xtal1 + pll16x
    _xinfreq = 5_000_000
    PUB Main
    {Launch cog to toggle P16 endlessly}
    cognew(@mainEntry, 0) 'Launch new cog
    DAT
    {Toggle P16}
    ORG 0 'Begin at Cog RAM addr 0
    Toggle                  mov dira, Pin 'Set Pin to output
                            mov Time, cnt 'Calculate delay time
                            add Time, #9 'Set minimum delay here
    :loop                   waitcnt Time, Delay 'Wait
                            xor outa, Pin 'Toggle Pin
                            jmp #:loop 'Loop endlessly
    Pin           long      |< 12 'Pin number
    Delay         long      30_000_000 'Clock cycles to delay
    Time          res 1     'System Counter Workspace
    
    
    ORG 0
    mainEntry               cogstop cognr
                            mov     t1,cogpar               'restart cog
                            shl     t1,#14
                            or      t1,cogaddr
                            shl     t1,#2
                            or      t1,cognr
                            coginit t1
    
    cogpar        long      0
    cogaddr       long      @Toggle
    cognr         long      1
    t1            res 1
    
    
  • kuronekokuroneko Posts: 3,623
    edited 2008-11-28 03:29
    Four points:

    1. Remove the cogstop instruction. As you stop #1 you're usually stopping yourself (spin starts on #0, so cognew will most likely run mainEntry in #1).
    2. The current compiler miscalculates function addresses, use @Toggle + $10 instead.
    3. If you want to toggle pin 16 use |< 16 not |< 12
    4. Get used to not using absolute cog IDs [noparse]:)[/noparse]
  • AribaAriba Posts: 2,687
    edited 2008-11-28 18:07
    Delus, this code works on my Propeller Protoboard with a LED on Pin 16:
    CON
    _clkmode = xtal1 + pll16x
    _xinfreq = 5_000_000
    PUB Main
    {Launch cog to toggle P16 endlessly}
    cogaddr := @Toggle
    cognew(@mainEntry, 0) 'Launch new cog
    DAT
    {Toggle P16}
    ORG 0 'Begin at Cog RAM addr 0
    Toggle                  mov dira, Pin 'Set Pin to output
                            mov Time, cnt 'Calculate delay time
                            add Time, Delay
    :loop                   waitcnt Time, Delay 'Wait
                            xor outa, Pin 'Toggle Pin
                            jmp #:loop 'Loop endlessly
    Pin           long      |< 16 'Pin number
    Delay         long      30_000_000 'Clock cycles to delay
    Time          res 1     'System Counter Workspace
    
    
    ORG 0
    mainEntry               mov     t1,cogpar               'restart cog
                            shl     t1,#14
                            or      t1,cogaddr
                            shl     t1,#2
                            or      t1,cognr
                            coginit t1
                                                                                                                                                            
    cogpar        long      0
    cogaddr       long      0-0
    cognr         long      1
    t1            res 1
    
    



    Andy
  • DelusDelus Posts: 79
    edited 2008-12-21 06:49
    ok can any one tell me why this
    CON
    _clkmode = xtal1 + pll16x
    _xinfreq = 5_000_000
    PUB Main
    {Launch cogs to toggle P16 and 17 endlessly}
    cogaddr := @Toggle
    cogaddr2 := @Toggle2
    coginit(2,@mainEntry,0) 'Launch new cog
    DAT
    {Toggle P16}
    ORG 0 'Begin at Cog RAM addr 0
    Toggle                  mov dira, Pin 'Set Pin to output
                            mov Time, cnt 'Calculate delay time
                            add Time, Delay
    :loop                   waitcnt Time, Delay 'Wait
                            xor outa, Pin 'Toggle Pin
                            jmp #:loop 'Loop endlessly
    Pin           long      |< 16 'Pin number
    Delay         long      30_000_000 'Clock cycles to delay
    Time          res 1     'System Counter Workspace
    
    {Toggle P17}
    ORG 0
    Toggle2                 mov dira, Pin2 'Set Pin to output
                            mov Time2, cnt 'Calculate delay time
                            add Time2, Delay2
    :loop2                   waitcnt Time2, Delay2 'Wait
                            xor outa, Pin2 'Toggle Pin
                            jmp #:loop2 'Loop endlessly
    Pin2           long      |< 17 'Pin number
    Delay2         long      15_000_000 'Clock cycles to delay
    Time2          res 1     'System Counter Workspace
    
    
    ORG 0
    mainEntry               mov     t1,cogpar               'restart cog
                            shl     t1,#14
                            or      t1,cogaddr
                            shl     t1,#2
                            or      t1,cognr
                            coginit t1
    
                            mov     t1,cogpar2               'restart cog
                            shl     t1,#14
                            or      t1,cogaddr2
                            shl     t1,#2
                            or      t1,cognr2
                            coginit t1
                                                                                                                                                            
    cogpar        long      0
    cogaddr       long      0-0
    cognr         long      2
    cogpar2       long      0
    cogaddr2      long      0-0
    cognr2         long      3
    t1            res 1
    
    


    only works for
    coginit(2,@mainEntry,0) 'Launch new cog
    and
    coginit(3,@mainEntry,0) 'Launch new cog
    i understand that 2 will restart the cog which launches the other cogs and thus only blinks one led but why do 0, 1, and 3-7 not work?
    yes i know it's best practice to let the prop choose which cog to start but this is a curious outcome

    Post Edited (Delus) : 12/21/2008 6:54:31 AM GMT
  • DelusDelus Posts: 79
    edited 2008-12-21 06:59
    Using cognr = %1000 in the last post works for all values 0-7 in the spin coginit function
  • StefanL38StefanL38 Posts: 2,292
    edited 2008-12-21 19:20
    Hello Delus,

    Why are you so keen about using cogINIT instead of cogNEW ?

    all eight cogs are EXACTLY the same. So it does't matter which cog you use for what.

    As Mike already mentioned it's more buggy to use coginit than cognew

    best regards

    Stefan
  • kuronekokuroneko Posts: 3,623
    edited 2008-12-22 04:07
    Delus said...
    Using cognr = %1000 in the last post works for all values 0-7 in the spin coginit function

    Well, bit 3 (%1000) makes all the difference. If set coginit becomes cognew (see prop manual p.366).
Sign In or Register to comment.