Shop OBEX P1 Docs P2 Docs Learn Events
What's wrong with my code? — Parallax Forums

What's wrong with my code?

LegonigelLegonigel Posts: 12
edited 2011-08-03 18:27 in Propeller 1
I was messing around with multiple cogs and threw together this code. I can't seem to get multiple cogs running properly. Can someone please tell me what is wrong with my code?
{{Blink.spin

Blinks 16 LEDs in series controlled by 8 dip switches}}


CON
        _clkmode = xtal1 + pll16x       'Standard clock mode * crystal frequency = 80 MHz
        _xinfreq = 5_000_000

        LED_Pin = 0                     'LEDs on pins 0-15
        Dip_Pin = 16                    'Dip on pins 16-23
        
  
VAR

  long  stack1[128]              'Stack spaces for new cogs (Seperate stack for each cog
  long  stack2[128]
  long  stack3[128]
  long  stack4[128]  
  long  stack5[128]
  long  stack6[128]
  long  stack7[128]
 
  
PUB Main 'Runs the program

  Dira[LED_Pin..LED_Pin + 15]~~     'Set Pins for LEDs to Output
  Dira[Dip_Pin..Dip_Pin + 7]~       'Set Pins for Dips to Inputs
  Outa[LED_Pin..LED_Pin + 15]~~     'Flash all LEDs for 1 Second
  Waitcnt(clkfreq + cnt)
  Outa[LED_Pin..LED_Pin + 15]~

  cognew(SeriesUp(1, clkfreq), @stack1)     'Start a new cog with a series controlled by Dip 1 with a delay of 1 sec.
  cognew(SeriesUp(2, clkfreq/2), @stack2) 
  cognew(SeriesUp(3, clkfreq/3), @stack3) 
  cognew(SeriesUp(4, clkfreq/4), @stack4)
  cognew(SeriesUp(5, clkfreq/5), @stack5) 
  cognew(SeriesUp(6, clkfreq/10), @stack6) 
  cognew(SeriesUp(7, clkfreq/15), @stack7) 
  SeriesUp(8, clkfreq/20)                   'Have this cog run a series.

PUB SeriesUp(Dip, Delay) |LED_Count
   {Uses dip switch to control LEDs flashing in series with certain delay}
   
  repeat
    Repeat while Ina[Dip + Dip_Pin - 1]
      Outa[LED_Count]~~
      Waitcnt(Delay +cnt)
      Outa[LED_Count]~
      if LED_Count == 15
        LED_Count := 0
      else
        LED_Count++

Thanks,
Nigel

Comments

  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2011-08-03 13:23
    With a quick glance, it looks correct to run the cogs.
    What is incorrect is that LED_Count isn't set before it is called the first time.
    Also, each cog should fully control it's own set of IOs. So if you trying to set the DIRAs of the cogs' IOs with the blanket DIRAs in the Main method, it may not work as expected.

    Also, while 128 longs is plenty safe for a stack. Each of your cogs only needs 9 longs (though I'd do something like 20 to be safe). The math (as it was explained to me a while back) is this: each method requires 6 longs, then one long for each local variable and parameter. As soon as you start nesting methods it gets really difficult to calculate how much stack you need, so always err on the way-too-big side of things.
  • StefanL38StefanL38 Posts: 2,292
    edited 2011-08-03 13:33
    each cog has its own DIRA and OUTA-register.

    So the DIRA and OUTA-register has to be configured in that method that is running in the new cog.

    You should write an init-method that has parameters for the IO-pins you want to use.
    Then inside this init-method DIRA and OUTA are set.

    keep the questions coming
    best regards

    Stefan
  • LegonigelLegonigel Posts: 12
    edited 2011-08-03 13:39
    So, this would work
    {{Blink.spin
    
    Blinks 16 LEDs in series controlled by 8 dip switches}}
    
    
    CON
            _clkmode = xtal1 + pll16x       'Standard clock mode * crystal frequency = 80 MHz
            _xinfreq = 5_000_000
    
            LED_Pin = 0                     'LEDs on pins 0-15
            Dip_Pin = 16                    'Dip on pins 16-23
            
      
    VAR
    
      long  stack1[128]              'Stack spaces for new cogs (Seperate stack for each cog
      long  stack2[128]
      long  stack3[128]
      long  stack4[128]  
      long  stack5[128]
      long  stack6[128]
      long  stack7[128]
     
      
    PUB Main 'Runs the program
    
      Dira[LED_Pin..LED_Pin + 15]~~     'Set Pins for LEDs to Output
      Dira[Dip_Pin..Dip_Pin + 7]~       'Set Pins for Dips to Inputs
      Outa[LED_Pin..LED_Pin + 15]~~     'Flash all LEDs for 1 Second
      Waitcnt(clkfreq + cnt)
      Outa[LED_Pin..LED_Pin + 15]~
    
      cognew(SeriesUp(1, clkfreq), @stack1)     'Start a new cog with a series controlled by Dip 1 with a delay of 1 sec.
      cognew(SeriesUp(2, clkfreq/2), @stack2) 
      cognew(SeriesUp(3, clkfreq/3), @stack3) 
      cognew(SeriesUp(4, clkfreq/4), @stack4)
      cognew(SeriesUp(5, clkfreq/5), @stack5) 
      cognew(SeriesUp(6, clkfreq/10), @stack6) 
      cognew(SeriesUp(7, clkfreq/15), @stack7) 
      SeriesUp(8, clkfreq/20)                   'Have this cog run a series.
    
    PUB SeriesUp(Dip, Delay) |LED_Count
       {Uses dip switch to control LEDs flashing in series with certain delay}
    
      Dira[LED_Pin..LED_Pin + 15]~~
      Dira[Dip_Pin..Dip_Pin + 7]~ 
      repeat
        Repeat while Ina[Dip + Dip_Pin - 1]
          Outa[LED_Count]~~
          Waitcnt(Delay +cnt)
          Outa[LED_Count]~
          if LED_Count == 15
            LED_Count := 0
          else
            LED_Count++
    

    Thanks,
    Nigel
  • StefanL38StefanL38 Posts: 2,292
    edited 2011-08-03 13:56
    Hi Nigel,

    Yes should work. You are setting up all IO-pins in all cogs.
    The state of the DIRA and OUTA-register are "or"ed together.

    This means as soon as one cog sets a bit in OUTA to 1 the IO_pin goes high. regardless of the state of all other OUTA-registers in the other cogs
    You can read more about that in the Propeller-manual.

    It is better to have a method for initialisation with parameters for the PINS that this cog will work with.

    If you don't want to read - but like more to learn through practical tests - use a test-program with only to cogs and one or two IO-pins
    that it is easier to follow what is happening

    keep the questions coming
    best regards

    Stefan
  • LegonigelLegonigel Posts: 12
    edited 2011-08-03 14:25
    Thanks Stefan,

    I understand the concept, I just forgot that each cog has its own DIRA and OUTA register.
    Thanks for the help,

    Nigel
  • StefanL38StefanL38 Posts: 2,292
    edited 2011-08-03 14:35
    Hi Nigel,

    I forgot something important: the init-method should be called in the cognew-statement after the initialisation
    you can call other methods.
    All other called methods get executed in the new started cog.

    keep the questions coming
    best regards

    Stefan
  • LegonigelLegonigel Posts: 12
    edited 2011-08-03 18:27
    Thanks for the good idea. That makes sence, so that way the new cog will be initiated, and can then call on methods from other objects.

    Nigel
Sign In or Register to comment.