Shop OBEX P1 Docs P2 Docs Learn Events
new cogs will not launch — Parallax Forums

new cogs will not launch

sciguysciguy Posts: 48
edited 2008-05-16 13:17 in Propeller 1
Hey there, I'm brand new to the propeller chip, and I have read through all of the documentation. I can't seem to get my chip to launch anything in a new cog.

Here is an except from my code:

VAR
long stack [noparse][[/noparse]30]

PUB main
  DIRA[noparse][[/noparse]0..5]~
  DIRA[noparse][[/noparse]16..21]~~
  
  cognew( act(1,16), @stack)

PUB act(distance, outputPIN) | delay
  delay := ((clkfreq / 1_000)*distance) 

 repeat                                                 'inifinte loop
   waitcnt(delay + cnt)                                                                            
   !OUTA [noparse][[/noparse]outputPIN]




When I do that, the act method does not run.

But if i simply use
act(1,16)

, it works fine.

Any suggestions.

Comments

  • hippyhippy Posts: 1,981
    edited 2008-05-13 14:40
    When you are setting DIRA you need to do that in the Cog which is going to alter the output. The DIRA in
    PUB Main set P16 to P21 as outputs for that Cog, but the Cog invoked ( PUB Act ) will have its DIRA still
    as all inputs.
  • Mike GreenMike Green Posts: 23,101
    edited 2008-05-13 14:41
    You're launching the 2nd cog, but you can't see what it's doing. Each cog has its own copy of DIRA and OUTA. You're enabling I/O pin #1 in one cog and using it in the 2nd cog where it's still configured as an input. At the beginning of "act", put a "DIRA[noparse][[/noparse] outputPIN ]~~" and, in your "main" method, don't initialize DIRA for the pin # you pass to "act".

    There is a section of the Propeller manual that shows how all the DIRA and OUTA registers are connected together to control the actual I/O circuitry.
  • sciguysciguy Posts: 48
    edited 2008-05-13 15:17
    ok, thanks alot. that will fix it.
  • sciguysciguy Posts: 48
    edited 2008-05-13 18:13
    Ok, now I've got a new question:

    I'm trying to light up 5 different LEDs blinking at once, by using multiple cogs (I know I can do this serially, but I'm trying to learn). Only the first (green) LED is blinking, and the other's stay off.

    MAIN FILE
    
    CON
    
    {{Output PINS}}
    {{Output Pins must be consecutive}}
    greenOUT        =16                                     'Output PIN for Green Button
    redOUT          =17                                     'Output PIN for Red Button
    yellowOUT       =18                                     'Output PIN for Yellow Button
    blueOUT         =19                                     'Output PIN for Blue Button
    orangeOUT       =20                                     'Output PIN for Orange Button
    
    DAT
    green byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    red byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    yellow byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    blue byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    orange byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
     
    VAR
    
    long stack [noparse][[/noparse]20]                                          'Stack space for new cogs
      
    
    
    OBJ
    
    output : "check"
    
    PUB main
    
      
    coginit(1, output[noparse][[/noparse]0].act(1, greenOUT, green), @stack)
    coginit(2, output.act(1, redOUT, red), @stack)
    coginit(3, output.act(1, yellowOUT, yellow), @stack)
    coginit(4, output.act(1, blueOUT, blue), @stack)
    coginit(5, output.act(1, orangeOUT, orange), @stack)
    
    



    check
    CON
    
    {{Output PINS}}
    {{Output Pins must be consecutive}}
    greenOUT        =16                                     'Output PIN for Green Button
    redOUT          =17                                     'Output PIN for Red Button
    yellowOUT       =18                                     'Output PIN for Yellow Button
    blueOUT         =19                                     'Output PIN for Blue Button
    orangeOUT       =20                                     'Output PIN for Orange Button
    
    
    
    PUB act(distance, outputPIN, color) | delay
    delay := ((clkfreq / 1_000)*distance) 
    
      DIRA[noparse][[/noparse]greenOUT..orangeOUT]~~
    
        repeat
          waitcnt(delay + cnt)
          color[noparse][[/noparse]0]++
          if color[noparse][[/noparse]0]==800
            color [noparse][[/noparse]0] := 0
            !OUTA [noparse][[/noparse]outputPIN]
    
    
  • Mike GreenMike Green Posts: 23,101
    edited 2008-05-13 18:17
    1) You have to put a space after the opening subscript bracket or the forum software may "gobble" the index ("i" or a digit).

    2) You cannot use the same stack for two cogs running at the same time. You have to have a stack space for each one.

    3) Don't use "DIRA[noparse][[/noparse]greenOUT..orangeOUT]~~", use "DIRA[noparse][[/noparse]outputPIN]~~" as I suggested. In your case, the former will work, but it won't work as a general case. Only set the direction bits to output mode (1) for those I/O pins that you want to control from that specific cog.

    Post Edited (Mike Green) : 5/13/2008 6:24:08 PM GMT
  • sciguysciguy Posts: 48
    edited 2008-05-13 18:39
    I made the changes you suggested, but only the first LED is still blinking:
    (Thanks, by the way, you've been very helpful)

    MAIN FILE
    
    CON
    
    {{Output PINS}}
    {{Output Pins must be consecutive}}
    greenOUT        =16                                     'Output PIN for Green Button
    redOUT          =17                                     'Output PIN for Red Button
    yellowOUT       =18                                     'Output PIN for Yellow Button
    blueOUT         =19                                     'Output PIN for Blue Button
    orangeOUT       =20                                     'Output PIN for Orange Button
    
    DAT
    green byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    red byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    yellow byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    blue byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    orange byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
     
    VAR
    
    long stack1 [noparse][[/noparse] 20]                                          'Stack space for cog1
    long stack2 [noparse][[/noparse] 20]                                          'Stack space for cog2
    long stack3 [noparse][[/noparse] 20]                                          'Stack space for cog3
    long stack4 [noparse][[/noparse] 20]                                          'Stack space for cog4
    long stack5 [noparse][[/noparse] 20]                                          'Stack space for cog5
    long stack6 [noparse][[/noparse] 20]                                          'Stack space for cog6
    long stack7 [noparse][[/noparse] 20]                                          'Stack space for cog7
      
    
    
    OBJ
    
    output[noparse][[/noparse] 5] : "check"
    
    PUB main
    
      
    coginit(1, output[noparse][[/noparse] 0].act(1, greenOUT, green), @stack1)
    coginit(2, output[noparse][[/noparse] 1].act(1, redOUT, red), @stack2)
    coginit(3, output[noparse][[/noparse] 2].act(1, yellowOUT, yellow), @stack3)
    coginit(4, output[noparse][[/noparse] 3].act(1, blueOUT, blue), @stack4)
    coginit(5, output[noparse][[/noparse] 4].act(1, orangeOUT, orange), @stack5)
    
    



    check
    CON
    
    {{Output PINS}}
    {{Output Pins must be consecutive}}
    greenOUT        =16                                     'Output PIN for Green Button
    redOUT          =17                                     'Output PIN for Red Button
    yellowOUT       =18                                     'Output PIN for Yellow Button
    blueOUT         =19                                     'Output PIN for Blue Button
    orangeOUT       =20                                     'Output PIN for Orange Button
    
    
    
    PUB act(distance, outputPIN, color) | delay
    delay := ((clkfreq / 1_000)*distance) 
    
      DIRA[noparse][[/noparse] outputPIN]~~
    
        repeat
          waitcnt(delay + cnt)
          color[noparse][[/noparse] 0]++
          if color[noparse][[/noparse] 0]==800
            color [noparse][[/noparse] 0] := 0
            !OUTA [noparse][[/noparse] outputPIN]
    
    
  • sciguysciguy Posts: 48
    edited 2008-05-14 13:55
    Anybody have any ideas?
  • Mike GreenMike Green Posts: 23,101
    edited 2008-05-14 15:37
    1) I didn't notice originally that you're calling COGINIT from your main object, but giving the initial routine as a method in another object. Unfortunately this doesn't work and the compiler doesn't catch it. Convention is that the start routine is part of the object containing the actual routines that run in the other cog(s).

    2) It's not a good idea to use COGINIT to start a new cog. You never know whether some other object is also using the same cog, even by mistake (because of a COGNEW). It's better to use COGNEW except where you absolutely know the cog number that you want to use.

    3) Try something like:
    OBJ output[noparse][[/noparse]6] : "check"
    PUB main
       repeat i from 0 to 5
          output[noparse][[/noparse] i ].start(firstPin+i,firstColor+i,1)
    ----------------
    VAR long cog, stack[noparse][[/noparse]20]
    PUB start(pin,color,distance)
       cog := cognew(act(pin,color,distance),@stack) + 1 ' save cog# + 1 or zero if can't start
       return cog > 0 ' return true if successful, false if fails
    PUB stop
       if cog > 0 ' stop the associated cog if it was started
          cogstop(cog~ - 1) ' clear cog # to zero if it was non-zero
    
    PRI act(pin,color,distance)
    ...
    
  • hippyhippy Posts: 1,981
    edited 2008-05-14 15:37
    sciguy said...
    I made the changes you suggested, but only the first LED is still blinking

    You've gone well beyond making just the changes suggested. You've jumped from a single Cog
    invoked from the main program to multiple Cogs invoked in sub-objects.

    coginit(5, output[noparse][[/noparse] 4].act(1, orangeOUT, orange), @stack5)
    
    



    If I recall right, it's not possible to launch a method in a new Cog that way, where the method
    to run is in a sub-object.

    You need to move the coginit into the object itself, so your coginits in the main program
    would become something like ...

    output[noparse][[/noparse] 4].DoCogInit(5,1, orangeOUT, orange, @stack5)
    
    



    And you'd need to add the DoCogInit mrthod to the object, something like ...

    PUB DoCogInit( cogNum, distance, outputPIN, color, stackPtr )
      coginit( cogNum, act(distance, outputPIN, color), stackPtr )
    
    



    You would be better off using cognew rather than coginit and you'd probably
    also benefit from moving the stack array into the object.
  • sciguysciguy Posts: 48
    edited 2008-05-14 16:32
    Thank you, it works now!
  • sciguysciguy Posts: 48
    edited 2008-05-15 19:22
    More questions now...

    So I am trying to get things working with a circular buffer. Basically, I want information about when the lights should flash to be stored in an array, and pulled up a little while later, and be used to light an LED (basically just a delay). The lights seem to flash at intervals, but not as a result of my inputs.

    CON
    {INPUT PINS}
    greenIN =0 'Input PIN for Green PhotoDiode
    redIN =1 'Input PIN for Red PhotoDiode
    yellowIN =2 'Input PIN for Yellow PhotoDiode
    blueIN =3 'Input PIN for Blue PhotoDiode
    orangeIN =4 'Input PIN for Orange PhotoDiode

    {Output PINS}
    greenOUT =16 'Output PIN for Green Button
    redOUT =17 'Output PIN for Red Button
    yellowOUT =18 'Output PIN for Yellow Button
    blueOUT =19 'Output PIN for Blue Button
    orangeOUT =20 'Output PIN for Orange Button
    strumOUT =21 'Output PIN for Strum Bar

    VAR
    {THESE LENGTHS MUST EQUAL THE VALUE OF BUFFERLENGTH BELOW}
    long green ]
    long red[noparse][[/noparse] 55]
    long yellow[noparse][[/noparse] 55]
    long blue[noparse][[/noparse] 55]
    long orange[noparse][[/noparse] 55]
    long default[noparse][[/noparse] 55]

    PUB DoCogInit (cogNum, distance, inputPIN, outputPIN, stackPtr)

    __coginit(cogNum, act(distance, inputPIN, outputPIN), stackPtr)

    PUB act(distance, inputPIN, outputPIN) | delay, i, j, bufferLength, checkBack, color

    {IMPORTANT}
    bufferLength := (distance/10)+5

    delay := (clkfreq / 100) 'sets the delay in clock cycles

    checkBack:= distance/10 'sets checkBack location for color array

    DIRA[noparse][[/noparse] inputPIN]~ 'Sets inputPIN to input mode
    DIRA[noparse][[/noparse] outputPIN]~~ 'Sets outputPIN to output mode
    color:=default
    if inputPIN == greenIN
    __color:=green
    if inputPIN == redIN
    __color:=red
    if inputPIN == yellowIN
    __color:=yellow
    if inputPIN == blueIN
    __color:=blue
    if inputPIN == orangeIN
    __color:=orange


    i:=0 'Initializes i to 0 for repeat loop
    j:=0 'Initializes j to 0 for repeat loop



    repeat while i<bufferLength 'Repeat for the circular buffer
    __if INA[noparse][[/noparse] inputPIN] == 1 'if the pin is active...
    ____color[noparse][[/noparse] i] := 1 'set value to 1 in array
    __else
    _____color[noparse][[/noparse] i ] := 0
    __if (i - checkBack) < 0 'if distance back loops...
    _____j:=(i - checkBack) + (bufferLength - 1) 'loop the value to find j
    __else 'else...
    _____j:=i-checkBack 'otherwise, set j normally
    __if color[noparse][[/noparse] j] == 1 'if j was on...
    _____OUTA[noparse][[/noparse] outputPIN]~~ 'press the button
    __color[noparse][[/noparse] j] := 0
    __i++ 'increment i
    __if i==bufferLength 'if end of circular buffer is reached...
    _____i:=0 'reset i to initial array value
    __waitcnt(cnt+delay) 'waits necessary time
    __OUTA[noparse][[/noparse] outputPIN]~ 'releases button

    Post Edited (sciguy) : 5/15/2008 7:27:24 PM GMT
  • Mike GreenMike Green Posts: 23,101
    edited 2008-05-15 20:09
    This is getting too long and too complicated to deal with as a conversation in a forum. Please
    1) Simplify this to a single cog and a single pin as best you can so it still illustrates the problem
    2) Document better what you're trying to do, preferably with comments in the source.
    3) Attach the source file to your message or use the [noparse][[/noparse] code ] [noparse][[/noparse] /code ] tags to maintain formatting.
    Keep in mind that some subscripts like some single letters and digits are gobbled by the forum software.
    4) Your main method just initiates the second cog without doing anything further. In that case, you
    don't really need to have a separate cog since the first cog terminates itself.
  • sciguysciguy Posts: 48
    edited 2008-05-16 13:17
    ok thanks for the suggestions. Sorry...I'm new to this.
Sign In or Register to comment.