Shop OBEX P1 Docs P2 Docs Learn Events
stopping/starting multiple cogs — Parallax Forums

stopping/starting multiple cogs

I'm having a problem with identifying cogs to be able to start and stop them. I've seen the examples in the pe kit and prop manual. I tried the example in the prop manual , but the compiler said I need a unique variable when I used cogid instead of cog1 (or 2). Also with the prop manual example i'm not sure how to control multiple cogs. The code will compile the way I have it below, but does not work.
var long servostack [150]
      long servo2stack [150]
      long cog1
      long cog2


pub go
halt:=1                                               'input changes state of halt and is intended to stop a cog
cog1:=cognew(servo2,@servo2stack)
cog2:=cognew(servo,@servostack) 

.....other unrelated code here.....

 repeat 

          
          phsa:= -thar
          tt+= tc
          waitcnt(tt)
        if halt==0
           cogstop( cog1)                                (cogstop for cog2 is the same as this group of code)

Comments

  • Clock LoopClock Loop Posts: 2,069
    edited 2018-04-09 07:04
    This post had bad code, so I removed it and posted the fix below.
  • Clock LoopClock Loop Posts: 2,069
    edited 2018-04-08 03:36
    BAD Spin UNattached. And i can't attache the corrected one because of this new forum software. so i must make another post to do that. Nor can i delete this post.

    Crappy forum software, killed fixing old posts, attachments, and kills old urls, and old youtube video urls.
    DAMN the torpedos, full steam ahead into lame forum software!
  • Clock LoopClock Loop Posts: 2,069
    edited 2018-04-09 07:05
    Corrected spin file attached.

    And then it was UNattached because it had issues, but this post remains, forever! HUZZZAH!
  • I can understand that a little easier, thanks clock loop.
  • JonnyMacJonnyMac Posts: 9,104
    edited 2018-04-08 15:53
    There is a tradition when starting cogs that goes like this
      cogX := cognew(@someLabel, @someVar) + 1
    
    This is for a PASM cog -- a Spin cog uses the method name as the first parameter.

    The reason for the + 1 is that cognew returns -1 if the cog didn't start, or 0 to 7 if it did. By adding one we promote the ID to a value that can be used in a true-false expression (i.e., you'll end up with a value between 1..8 if the cog started). Just remember to account for this when stopping said cog.
      if (cogX)
        cogstop(cogX - 1)
        cogX := 0
    

    And, FWIW, you're consuming WAY too much RAM (4K total) for stack space. With simple routines like that you could get away with far fewer longs. For example, here's an actual bit of code from the EFX-TEK HC-8+ controller. This embedded object runs in its own cog providing a 1ms clock, maitaining a Red/Green LED, and reading 16 inputs via two shift registers. Note the size of the stack = 32 longs.
    con
    
      { ----------------------------- }
      {  B A C K G R O U N D   C O G  }
      {  - global milliseconds        }
      {  - R/G LED                    }
      {  - TTL/DMX inputs scanning    }
      { ----------------------------- }
      
    
    var  
    
      long  bcog                                                    ' background cog #
      long  bcstack[32]                                             ' stack for background cog
                                                                     
      long  millis                                                  ' global milliseconds register
                                                                     
                                                                     
    pri background | t                                              ' launch with cognew()
                                                                     
      io.low(R_LED)                                                 ' setup R/G LED pins
      io.low(G_LED)                                                  
                                                                     
      io.high(LD_165)                                               ' setup x165 io pins
      io.low(CLK_165)                                                
      io.input(DO_165)                                               
                                                                     
      millis := 0                                                    
                                                                     
      t := cnt                                                      ' sync loop timer
      repeat                                                         
        waitcnt(t += MS_001)                                        ' run loop every millisecond
        ++millis                                                     
        refresh_rg_led                                              ' update the R/G LED
        scan_ttl_ins                                                ' re-scan TTL & DMX inputs
                                                                     
                                                                     
    var                                                              
                                                                     
      long  rgycolor[2]                                             ' led phase colors
      long  rgytime[2]                                              ' led phase timing (ms)
      long  rgphase                                                 ' current phase (red or green chip)
      long  phasetimer                                              ' time in phase
      long  rgtimer                                                 ' timer for rg process
                                                                     
                                                                     
    pri refresh_rg_led                                              ' call only from support()
                                                                     
      if (++phasetimer => rgytime[rgphase])                         ' done with this phase?
        phasetimer := 0                                             ' yes, reset timer
        rgphase := 1 - rgphase                                      '  and invert phase
                                                                     
      if (++rgtimer == 16)                                           
        rgtimer := 0                                                 
                                                                     
      case rgycolor[rgphase]                                        ' set led to color for phase
        OFF:                                                         
          outa[R_LED..G_LED] := %00                                  
                                                                     
        GRN:
          outa[R_LED..G_LED] := %01  
                                                                     
        RED:
          outa[R_LED..G_LED] := %10 
                                                                       
        YEL:
          if (rgtimer < 2)                                                                       
            outa[R_LED..G_LED] := %10                               ' 2 red                        
          else                                                                                   
            outa[R_LED..G_LED] := %01                               ' 14 green                  
                                                              
    
    var
    
      long  ttlpins
      long  dmxaddr                                                  
    
                                                                    
    pri scan_ttl_ins : tempin                                         
                                                                     
    '' Scan TTL and DMX address inputs                               
                                                                     
      outa[LD_165] := 0                                             ' blip Shift/Load line    
      outa[LD_165] := 1
    
      tempin := ina[DMX_A8]                                         ' bit16                                           
    
      ' unrolled for best speed
    
      tempin := (tempin << 1) | ina[DO_165]                         ' bit15
      outa[CLK_165] := 1                                            ' blip clock  
      outa[CLK_165] := 0                                                        
      tempin := (tempin << 1) | ina[DO_165]
      outa[CLK_165] := 1                   
      outa[CLK_165] := 0                   
      tempin := (tempin << 1) | ina[DO_165]
      outa[CLK_165] := 1                   
      outa[CLK_165] := 0                   
      tempin := (tempin << 1) | ina[DO_165]
      outa[CLK_165] := 1                   
      outa[CLK_165] := 0
      tempin := (tempin << 1) | ina[DO_165] 
      outa[CLK_165] := 1                    
      outa[CLK_165] := 0                    
      tempin := (tempin << 1) | ina[DO_165] 
      outa[CLK_165] := 1                    
      outa[CLK_165] := 0                    
      tempin := (tempin << 1) | ina[DO_165] 
      outa[CLK_165] := 1                    
      outa[CLK_165] := 0
      tempin := (tempin << 1) | ina[DO_165] 
      outa[CLK_165] := 1                    
      outa[CLK_165] := 0
      
      tempin := (tempin << 1) | ina[DO_165]                         ' bit7
      outa[CLK_165] := 1                    
      outa[CLK_165] := 0                    
      tempin := (tempin << 1) | ina[DO_165] 
      outa[CLK_165] := 1                    
      outa[CLK_165] := 0                    
      tempin := (tempin << 1) | ina[DO_165] 
      outa[CLK_165] := 1                    
      outa[CLK_165] := 0                    
      tempin := (tempin << 1) | ina[DO_165] 
      outa[CLK_165] := 1                    
      outa[CLK_165] := 0
      tempin := (tempin << 1) | ina[DO_165] 
      outa[CLK_165] := 1                    
      outa[CLK_165] := 0                    
      tempin := (tempin << 1) | ina[DO_165] 
      outa[CLK_165] := 1                    
      outa[CLK_165] := 0                    
      tempin := (tempin << 1) | ina[DO_165] 
      outa[CLK_165] := 1                    
      outa[CLK_165] := 0                                       
      tempin := (tempin << 1) | ina[DO_165]                         ' bit0                    
                                                             
      ttlpins := tempin.byte[0]                                     ' update global vars
      dmxaddr := tempin >> 8      
    
    I start that cog from my setup() method with this line of code
      bcog := cognew(background, @bcstack) + 1                      ' start background cog *
    


  • Thank Jon! I used your example and finished my project. Also thanks for the info about longs,
    I have not spend much time with fine tuning that yet. For the cog stop/start methods I was using example code posted earlier, but I think i'm doing something wrong. It will start the cog and i'm confident it's ending up at the halt method at the appropriate time, but it's not stopping the cogs. I'm all set now, but would like to know what I was doing wrong.
    
    pub go
        halt
        cogon[0] := (cogs[0] := cognew(servo, @pile[100]) > 0)     '1 cog used.
    
        cogon[1] := (cogs[1] := cognew(servo2, @pile[200]) > 0)     '1 cog used.
                
    
    
    pub halt
    
       
        if cogon[0]~                                          ' if object running, mark stopped
            cogstop(cogs[0])
            
        if cogon[1]~                                          ' if object running, mark stopped
            cogstop(cogs[1])     
    
  • That code is working very hard -- and unnecessarily so. There is no need for the cogon[] array when the cogs[] array will suffice. Keep things simple; it's usually best. The code as is could have a problem in that the go method doesn't keep the main cog running. This could causing a stack error and resetting everything. When I need to hold I do this
      repeat
        waitcnt(0)
    
    Since you don't have this at the end of the go method, you have a return-to-nowhere situation.

  • Clock LoopClock Loop Posts: 2,069
    edited 2018-04-09 03:25
    mikea wrote: »
    For the cog stop/start methods I was using example code posted earlier, but I think i'm doing something wrong. It will start the cog and i'm confident it's ending up at the halt method at the appropriate time, but it's not stopping the cogs. I'm all set now, but would like to know what I was doing wrong.

    I think thats the same problem I have with it, the stop function dosen't stop the cogs, but i never used it.. I just used the code to start cogs (and comment out ones i didn't want started)

    It seems Jon is saying the code is more complicated than it needs to be, perhaps so, I don't understand it myself, i should probably take it and put some debug code into it and see what the cog variables are doing...

    Thats interesting that Jon mentions keeping the main cog running... i stated that once in a thread but it was missed.. and my other bad points were focused on. meh...

    I also show I did this in the code above.
        Routine8      ' This keeps the main cog running.     'Last cog re-used in this Routine.
    

    I'll dig into the code i posted and figure it out soon. That will be my project tonight... :D

    JonnyMac wrote: »
      repeat
        waitcnt(0)
    

    I didn't know you could do that.. Since (from what i understand) there is a minimum limit to the waitcnt command.
  • Clock LoopClock Loop Posts: 2,069
    edited 2018-04-09 06:04
    It turns out the cogs are not stopping because they are all given the same ID of -1.

    I think that needs to be fixed so the cogs get a unique id.


    I am looking at the propeller manual and thats where the above code i originally attached, came from.

    Propeller manual bottom of page 83.
    This "UN-necessarily" complicated code is in the manual and im still looking it over to fully understand it, so i don't know why the manual uses "UN-necessarily" complicated code.

    But I see some differences... from what i posted... time to do more testing.
    VAR
    
        byte Cog 'Used to store ID of newly started cog
        
    PUB Start(Pos) : Pass
    
        'Start a new cog to run Update with Pos, 
        'return TRUE if successful 
        Pass := (Cog := cognew(@Update, Pos) + 1) > 0
    
    PUB Stop
    
        'Stop the cog we started earlier, if any. 
        if Cog 
            cogstop(Cog~ - 1) 
    
    
  • Clock LoopClock Loop Posts: 2,069
    edited 2018-04-09 15:18
    The example code in the manual on page 83 shows this code.

        Pass := (Cog := cognew(@Update, Pos) + 1) > 0
    


    The @ symbol in front of the Function is not correct, it should be in front of the variable stack.


    I think its a typo and meant to read
        Pass := (Cog := cognew(Update, @Pos) + 1) > 0
    



    So,.... After fixing a bug in the manual, I also fixed my bug, both fixed, due to understanding the manual's examples.


    My code was changed to match the manual, except for its own address symbol bug...

    '' =================================================================================================
    '   File......  CogManagement.spin       
    '   Purpose...  CogManagement
    '   Author....  Clock Loop @ parallax forums 
    '' =================================================================================================
    
    
    CON
    
        _clkmode = xtal1 + pll16x                'Standard clock mode * crystal frequency = 80 MHz
        _xinfreq = 5_000_000
    
    
    VAR
        long  cogon[8], cog[8], pile[1000]   ' cog management      
       
    OBJ
     
      
    PUB Start        'Remember this is the first cog.   1 cog used.
    
        Stop   'Make sure all cogs are OFF!
    
        cogon[0] := ((cog[0] := cognew(Routine1, @pile[100]) + 1) > 0)     '1 cog used.
    
        cogon[1] := ((cog[1] := cognew(Routine2, @pile[200]) + 1) > 0)     '1 cog used.
    
        cogon[2] := ((cog[2] := cognew(Routine3, @pile[300]) + 1) > 0)     '1 cog used.    
     
        cogon[3] := ((cog[3] := cognew(Routine4, @pile[400]) + 1) > 0)     '1 cog used.       
    
        cogon[4] := ((cog[4] := cognew(Routine5, @pile[500]) + 1) > 0)     '1 cog used.  
      
        cogon[5] := ((cog[5] := cognew(Routine6, @pile[600]) + 1) > 0)     '1 cog used.    
                                     
        cogon[6] := ((cog[6] := cognew(Routine7, @pile[700]) + 1) > 0)      '1 cog used.  
    
        'cogon[7] := ((cog[7] := cognew(Routine8, @pile[800]) + 1) > 0)     'If I launch this cog, won't it fail? since the cog launching this cog, is the last one, so you must run it below? Or will it just use the last cog and not run any code below this line?    
      
    
    
        Routine8      ' This keeps the main cog running.     'Last cog re-used in this Routine.
    
         
         
    PUB Routine1
        Repeat                 ' This keeps the cog running.    
            waitcnt(100_000 + cnt)     'cpu wait  
    
    PUB Routine2
        Repeat                 ' This keeps the cog running.    
            waitcnt(100_000 + cnt)     'cpu wait  
    
    PUB Routine3
        Repeat                 ' This keeps the cog running.    
            waitcnt(100_000 + cnt)     'cpu wait  
    
    PUB Routine4
        Repeat                 ' This keeps the cog running.    
            waitcnt(100_000 + cnt)     'cpu wait  
    
    PUB Routine5
        Repeat                 ' This keeps the cog running.    
            waitcnt(100_000 + cnt)     'cpu wait  
        
    PUB Routine6
        Repeat                 ' This keeps the cog running.    
            waitcnt(100_000 + cnt)     'cpu wait  
    
    PUB Routine7
        Repeat                 ' This keeps the cog running.    
            waitcnt(100_000 + cnt)     'cpu wait  
    
    PUB Routine8
        Repeat                 ' This keeps the cog running.    
            waitcnt(100_000 + cnt)     'cpu wait  
    
    
    
    PUB stop
    
    
        if cogon[0]                                          ' if object running, mark stopped
            cogstop(cog[0]~ - 1)    
    
        if cogon[1]                                          ' if object running, mark stopped
            cogstop(cog[1]~ - 1)
        
        if cogon[2]                                          ' if object running, mark stopped
            cogstop(cog[2]~ - 1)
    
        if cogon[3]                                          ' if object running, mark stopped
            cogstop(cog[3]~ - 1)
     
        if cogon[4]                                          ' if object running, mark stopped
            cogstop(cog[4]~ - 1)
    
        if cogon[5]                                          ' if object running, mark stopped
            cogstop(cog[5]~ - 1)
    
        if cogon[6]                                         ' if object running, mark stopped
            cogstop(cog[6]~ - 1)
    
        if cogon[7]                                          ' if object running, mark stopped
            cogstop(cog[7]~ - 1)
    
    
    Dat
    {{
    
      Terms of Use: MIT License
    
      Permission is hereby granted, free of charge, to any person obtaining a copy of this
      software and associated documentation files (the "Software"), to deal in the Software
      without restriction, including without limitation the rights to use, copy, modify,
      merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
      permit persons to whom the Software is furnished to do so, subject to the following
      conditions:
    
      The above copyright notice and this permission notice shall be included in all copies
      or substantial portions of the Software.
    
      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
      INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
      PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
      HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
      CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
      OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
    
    }}
    
  • Clock LoopClock Loop Posts: 2,069
    edited 2018-04-12 23:13
    If you want to see it in action.

    Get putty.

    Upload this code.

    And connect to your serial port with putty.
    The count will stop every 10 seconds and wait 10 seconds and start the count again. It strays a bit due to starting and stopping the cog without consideration for the timing; when its best to stop the cog, in relation to the variable update, and the display painting.

    But the start and stop cog code, works now.
    '' =================================================================================================
    '   File......  CogManagement.spin       
    '   Purpose...  CogManagement
    '   Author....  Clock Loop @ parallax forums 
    '' =================================================================================================
    
    
    CON
    
        _CLKMODE = XTAL1 + PLL16X
        _XINFREQ = 5_000_000
        '_XINFREQ = 6_250_000 ' I do my code testing on a propscope.
    
        Tx             = 30   'serial 
        Rx             = 31   'serial 
    
        'EepromScl      = 28  'eeprom. 
        'EepromSda      = 29  'eeprom.  
    
        
    VAR
    
        long    cogon[8], cog[8], pile[1000]   ' cog management      
    
        
    OBJ
    
        Term    :   "FullDuplexSerialPlus" 
      
    PUB Start        'Remember this is the first cog.   1 cog used.
    
        Stop
    
        Term.start(Rx, Tx, %0000, 115_200)                           '1cog start telnet terminal
    
        waitcnt(80_000_000 + cnt)  
        
    
        cogon[0] := ((cog[0] := cognew(Routine0, @pile[100]) + 1) > 0)     '1 cog used.
    
        cogon[1] := ((cog[1] := cognew(Routine1, @pile[200]) + 1) > 0)     '1 cog used.
    
        cogon[2] := ((cog[2] := cognew(Routine2, @pile[300]) + 1) > 0)     '1 cog used.    
     
        cogon[3] := ((cog[3] := cognew(Routine3, @pile[400]) + 1) > 0)     '1 cog used.       
    
        cogon[4] := ((cog[4] := cognew(Routine4, @pile[500]) + 1) > 0)     '1 cog used.  
      
        'cogon[5] := ((cog[5] := cognew(Routine5, @pile[600]) + 1) > 0)     '1 cog used.    'Can't use this the serial terminal uses a cog.
                                     
        'cogon[6] := ((cog[6] := cognew(Routine6, @pile[700]) + 1) > 0)      '1 cog used.  'Routine0 controls this cog for this test.
    
        'cogon[7] := ((cog[7] := cognew(Routine7, @pile[800]) + 1) > 0)     'If I launch this cog, won't it fail? since the cog launching this cog, is the last one, so you must run it below? Or will it just use the last cog and not run any code below this line?    
    
    
        Repeat
        
            Routine7      ' This keeps the main cog running.     'Last cog re-used in this Routine.
    
    
         
    PUB Routine0
    
        Repeat                 ' This keeps the cog running.    
    
            cogon[6] := ((cog[6] := cognew(Routine6, @pile[700]) + 1) > 0)      '1 cog used.
    
            Repeat 10
                waitcnt(80_000_000 + cnt)
    
            if cogon[6]                                         ' if object running, mark stopped
                cogstop(cog[6]~ -1)
    
            Repeat 10
                waitcnt(80_000_000 + cnt)
                  
    
    PUB Routine1
    
        Repeat                 ' This keeps the cog running.    
            waitcnt(100_000 + cnt)     'cpu wait  
    
    
    PUB Routine2
    
        Repeat                 ' This keeps the cog running.    
            waitcnt(100_000 + cnt)     'cpu wait  
    
    
    PUB Routine3
    
        Repeat                 ' This keeps the cog running.    
            waitcnt(100_000 + cnt)     'cpu wait  
    
    
    PUB Routine4
    
        Repeat                 ' This keeps the cog running.    
            waitcnt(100_000 + cnt)     'cpu wait  
    
     
    PUB Routine5
    
        Repeat                 ' This keeps the cog running.    
            waitcnt(100_000 + cnt)     'cpu wait  
    
            
    PUB Routine6
    
    
        Repeat
    
            ClockCount
                        
            
            
            
    PUB Routine7 | old 
    
       
            waitcnt(50_000 + cnt)
    
            If Secs <> old
            
                old := Secs
                
                PaintScreen
    
    
    Pub ClockCount   
     
    
            waitcnt(80_000_000 + cnt)     'wait 1 second      
         
            If Secs == 59
               
                Secs := 0
         
            Else
         
                Secs := Secs + 1
            
            
                  
    Pub  PaintScreen  
    
          
          If Secs == 0          
              term.str(string(27))  'Set command mode          
              term.str(string("[2J")) 'clear screen      
        
          term.str(string(27))  'Set command mode  
          term.str(string("[2;3f")) 'position
    
          term.str(string(27))   'Set command mode  
          term.str(string("[35m")) 'Purple color text
    
          term.str(string(27))   'Set command mode
          term.str(string("[1m")) 'Turn bold mode on 
    
          term.str(string(27))   'Set command mode 
          term.str(string("#3"))  'Double-height letters, top half 
          term.str(string("Cog Management! "))
    
          term.str(string(27))  'Set command mode  
          term.str(string("[3;3f")) 'position
    
          term.str(string(27))   'Set command mode 
          term.str(string("#4"))  'Double-height letters, bottom half 
          term.str(string("Cog Management! ")) 
    
          term.str(string(27))    'Set command mode 
          term.str(string("[1;1f"))  'Set Position
          
          term.str(string(27))    'Set command mode
          term.str(string("[0m")) 'Turn off character attributes
    
                                 
        '--------------AMBIENT------------------
            'term.str(string(27))  'Set command mode          
            'term.str(string("[2J")) 'clear screen
            
            'term.str(string(27))    'Set command mode
            'term.str(string("[0m")) 'Turn off character attributes        
            'term.str(string("[1m")) 'Turn bold mode on
            'term.str(string("[2m")) 'Turn low intensity mode on
            'term.str(string("[4m")) 'Turn underline mode on
            'term.str(string("[5m")) 'Turn blinking mode on
            'term.str(string("[7m")) 'Turn reverse video on    
            'term.str(string("[8m")) 'Turn invisible text mode on                  
            'term.str(string("#3"))   'Double-height letters, top half
            'term.str(string("#4"))   'Double-height letters, bottom half
            'term.str(string("#5"))   'Single width, single height letters
            'term.str(string("#6"))   'Double width, single height letters 
            'term.str(string("[30m")) 'Black color text
            'term.str(string("[31m")) 'Red color text
            'term.str(string("[32m")) 'Lime color text
            'term.str(string("[33m")) 'Yellow color text
            'term.str(string("[34m")) 'Blue color text  
            'term.str(string("[35m")) 'Purple color text
            'term.str(string("[36m")) 'SkyBlue color text  
            'term.str(string("[37m")) 'White color text
    
            term.str(string(27))   'Set command mode
            term.str(string("[1m")) 'Turn bold mode on 
    
            term.str(string(27))    'Set command mode 
            term.str(string("[5;5f"))  'Set Position
            
            term.str(string(27))    'Set command mode 
            term.str(string("[34m")) 'Blue color text
               
            term.str(string("Ticker   : "))
    
            term.str(string(27))    'Set command mode
            term.str(string("[33m")) 'Yellow color text
            term.dec(Secs)
    
            term.str(string(27))    'Set command mode 
            term.str(string("[1;1f"))  'Set Position
    
     
    PUB stop
    
        if cogon[0]                                          ' if object running, mark stopped
            cogstop(cog[0]~ - 1)    
    
        if cogon[1]                                          ' if object running, mark stopped
            cogstop(cog[1]~ - 1)
        
        if cogon[2]                                          ' if object running, mark stopped
            cogstop(cog[2]~ - 1)
    
        if cogon[3]                                          ' if object running, mark stopped
            cogstop(cog[3]~ - 1)
     
        if cogon[4]                                          ' if object running, mark stopped
            cogstop(cog[4]~ - 1)
    
        if cogon[5]                                          ' if object running, mark stopped
            cogstop(cog[5]~ - 1)
    
        if cogon[6]                                         ' if object running, mark stopped
            cogstop(cog[6]~ - 1)
    
        if cogon[7]                                          ' if object running, mark stopped
            cogstop(cog[7]~ - 1)
    
    
    
    DAT
             
        Secs                    LONG    0
    
    Dat
    {{
    
      Terms of Use: MIT License
    
      Permission is hereby granted, free of charge, to any person obtaining a copy of this
      software and associated documentation files (the "Software"), to deal in the Software
      without restriction, including without limitation the rights to use, copy, modify,
      merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
      permit persons to whom the Software is furnished to do so, subject to the following
      conditions:
    
      The above copyright notice and this permission notice shall be included in all copies
      or substantial portions of the Software.
    
      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
      INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
      PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
      HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
      CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
      OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
    
    }}
    
  • Cluso99Cluso99 Posts: 18,069
    edited 2018-04-09 07:51
    JonnyMac wrote: »
    That code is working very hard -- and unnecessarily so. There is no need for the cogon[] array when the cogs[] array will suffice. Keep things simple; it's usually best. The code as is could have a problem in that the go method doesn't keep the main cog running. This could causing a stack error and resetting everything. When I need to hold I do this
      repeat
        waitcnt(0)
    
    Since you don't have this at the end of the go method, you have a return-to-nowhere situation.
    You just need the repeat command.
    Waitcnt(0) is unnecessary.
            repeat     ' loops here indefinately
    

    However, the benefit of using waitcnt(0) is that it will put the cog to go into low power mode for ~54 seconds per loop of the 32 bit counter.
  • Clock Loop wrote: »
    The example code in the manual on page 83 shows this code.

        Pass := (Cog := cognew(@Update, Pos) + 1) > 0
    


    The @ symbol in front of the Function is not correct, it should be in front of the variable stack.

    The example is correct, it just doesn't have the correct reference. The cognew function has two syntax, one to start Spin functions and another to start PASM code, what you see in that example is the latter. Look at page 79-81 where both syntax are explained.

    Your code needs to start a Spin function so your fix is correct because in that case the second argument is the pointer to the Spin stack.
  • Clock LoopClock Loop Posts: 2,069
    edited 2018-04-09 07:59
    macca wrote: »

    Your code needs to start a Spin function so your fix is correct because in that case the second argument is the pointer to the Spin stack.

    The way I understood the manual...


    The prop assembly has a different section.
    Page 83 is for SPIN


    Page 286 is for pasm.

    But the cogstop for pasm says nothing about that, nor does the cogstop for spin mention how the example code is for pasm. (and why is the spin section using a pasm example) LOL
    :D

    From what I can tell actually pasm and spin syntax are all mixed up in the manual, and not seperate.
    THAT IS EXCELLENT, and not confusing at all.

    (and i must page back to an area for cognew, to find info on cogstop???)
    THAT IS EVEN MORE EXCELLENT!


    Im closing PropellerTool, and gonna watch a movie...

    Since chaos seems the theme for me tonight.. HardCore Henry should be an excellent movie right now.
  • Clock Loop wrote: »
    The prop assembly has a different section.
    Page 83 is for SPIN

    Page 286 is for pasm.

    Page 286 is to start cogs from PASM while page 83 is to start cogs from SPIN and from Spin you have two different syntax for cognew!

  • Clock LoopClock Loop Posts: 2,069
    edited 2018-04-09 08:05
    My page 83 has All CogStop spin info on it. (but has assembly too)

    And My page 286 has CogStop for pasm. (but probably not enough examples)

    What version of the manual are you using? 1.2 is the one on the parallax website; the one i have.

    https://www.parallax.com/downloads/propeller-manual
  • Clock LoopClock Loop Posts: 2,069
    edited 2018-04-09 08:14
    And another bug in the manual..

    Page 286 of PropellerManual version 1.2.
    Instruction:Start a cog by its ID.

    Should read
    Instruction:Stop a cog by its ID.


    again.... Im closing PropellerTool, and gonna watch a movie... Since chaos seems the theme for me tonight.. HardCore Henry should be an excellent movie right now.

    I suppose i could use my theme of the evening to find all the chaos around my world... but that sucks... im just gonna waste it by watching chaos.
  • JonnyMacJonnyMac Posts: 9,104
    edited 2018-04-09 19:48
    I didn't know you could do that.. Since (from what i understand) there is a minimum limit to the waitcnt command.
    The use of waitcnt(0) is to put that cog into low-power mode (waitcnt is waiting for a value; I'm arbitrarily setting that value to 0 since this loop is not for timing). As Ray pointed out, it's not required; an empty repeat loop will do the trick of holding the cog right there.

    By the way, you don't need to define separate method for each cog; the beauty of Spin cogs is that you can run the same cog in multiple interpreter cogs (this is why each needs its own stack). For example:
    pub blinker(pin, onms, offms) : t
    
      onms *= clkfreq / 1000                                        ' convert ms to ticks
      offms *= clkfreq / 1000
    
      dira[pin] := 1                                                ' make pin an output
    
      t := cnt                                                      ' sync timing
      repeat
        outa[pin] := 1
        waitcnt(t += onms)
        outa[pin] := 0
        waitcnt(t += offms)
    
    You could blink the LEDs on a PAB at different rates like this
      cog26 := cognew(blinker(26, 100, 900), @stack26) + 1
      cog27 := cognew(blinker(27, 333, 333), @stack27) + 1
    
Sign In or Register to comment.