Shop OBEX P1 Docs P2 Docs Learn Events
Method behaves differently when launched in new cog — Parallax Forums

Method behaves differently when launched in new cog

Mag748Mag748 Posts: 269
edited 2012-06-02 08:50 in Propeller 1
Hello,

I am running the below code. The "run" method behaves correctly when run within the main Cog. But if I try an run it in a new cog, it does not work as expected.

I have an led driver connected and the shift-out commands are used to change the status of the LEDs. The LEDs change as expected when run in the main cog, but do not change at all when run in a new cog. The only code I am changing is the following:

This works fine:
  'cognew(run, @Stack)    ' <- uncomment this and... 
  run                     ' ...comment this and it WILL NOT WORK

This does not work:
  cognew(run, @Stack)    ' <- uncomment this and... 
  'run                     ' ...comment this and it WILL NOT WORK

I do not understand what would be different depending on how the code is launched. Any ideas?

Thanks,
Marcus


This is the full program:
{Object_Title_and_Purpose}


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

        SDI         = 20
        CLK         = 21
        LE          = 22

        'Modes:
        PTXmode = 1
        PRXmode = 2
        PTXwithRX = 3
        PRXwithAddr = 4

        PTXledMask  = |< 16
        PRXledMask  = |< 32
        
VAR
  long  currLEDbuffer
  long  nextLEDbuffer

  long ModeUpdateTimer
  long ModeLEDtimer
  byte ModuleMode
  long Stack[500]
   
OBJ
  SPI      : "SPI_asm"
  Debug    : "FullDuplexSerial"
  
PUB public_method_name

  'Debug.start(31, 30, 0, 57600)
  
  currLEDbuffer := %0
  outa[LE]~
  dira[LE]~~
  SPI.start(1, 0) ' Start the SPI driver for the LED Display

  'cognew(run, @Stack)    ' <- uncomment this and... 
  run                     ' ...comment this and it WILL NOT WORK

    
  
PUB run
  
  ModeUpdateTimer := cnt
  ModeLEDtimer := cnt
  'Debug.str(String(" Running! "))
  nextLEDbuffer := currLEDbuffer :=  %00000000000000010000000000000001
  repeat
    updateLEDbuffer
    'waitcnt(clkfreq + cnt)
    updateModeLeds
    

PUB updateLEDbuffer
 
  if nextLEDbuffer <> currLEDbuffer
    SPI.SHIFTOUT(SDI, CLK, 4, 32,  currLEDbuffer)       
    waitcnt(clkfreq/10000 + cnt)
    outa[LE]~~
    outa[LE]~
      'Debug.str(String(" currLEDbuffer: "))
      'Debug.bin(currLEDbuffer, 32)
      'Debug.str(String(" nextLEDbuffer: "))
      'Debug.bin(nextLEDbuffer, 32)
      'Debug.tx(13)
    currLEDbuffer := nextLEDbuffer
  

PUB updateModeLEDs

  if cnt => ModeUpdateTimer
    ModuleMode := 1
    ModeUpdateTimer := clkfreq + cnt
    
  if ModuleMode == PTXwithRX
    nextLEDbuffer |= PTXledMask   'Turn on PTX LED
    nextLEDbuffer &= !PRXledMask  'Turn off PRX LED
  elseif ModuleMode == PTXmode
    nextLEDbuffer |= PTXledMask   'Turn on PTX LED
    if cnt => ModeLEDtimer        'Toggle PRX Led
      nextLEDbuffer ^= PRXledMask
      ModeLEDtimer := clkfreq/2 + cnt
  elseif ModuleMode == PRXwithAddr
    nextLEDbuffer &= !PTXledMask   'Turn off PTX LED
    nextLEDbuffer |= PRXledMask  'Turn on PRX LED
  elseif ModuleMode == PRXmode
    nextLEDbuffer |= PRXledMask  'Turn on PRX LED
    if cnt => ModeLEDtimer       ' Toggle PTX LED
      nextLEDbuffer ^= PTXledMask
      ModeLEDtimer := clkfreq/2 + cnt 

Comments

  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-06-02 08:28
    Mag748 wrote: »
    Any ideas?

    When you launch your new cog, you allow the first cog to stop since there isn't any code after your newcog statement. I don't know if this is causing your problem but it's not really good programming practice (I can hear people asking "what was wrong with the cog you were just using to make you want to jump cogs?").

    The other issue, which is the one I think is likely causing the trouble, is two different cogs are setting pin I/O states. I have much better luck if I just have a single cog changing the I/O states of the pins. Wait to set dira and outa registers until the cog using those pins has been launched and set the states with the same cog that will use the pins.

    If one cog sets a pin as an output the pin will stay an output if a different cog attempts to change it to an input. The pin states are ORed together.

    I see you set some pin states in the first cog which is allowed to die (and not with a cogstop). I'm not sure what those pin states will be with a cog that stops currently but if you had used a cogstop, the pin would change to an input (I think).

    I suggest, not letting a cog die the way you have it now and to set the I/O states of pins from the cogs that will be using those pins.
  • Dave HeinDave Hein Posts: 6,347
    edited 2012-06-02 08:35
    Try calling SPI.start from the run method.
  • Mag748Mag748 Posts: 269
    edited 2012-06-02 08:40
    Earlier I had a single "repeat" command at the bottom of that method in order to keep it running. I guess I had gotten rid of it at some point cause it wasn't making any difference.

    The reason I am launching this code into a new cog as opposed to just using the main cog is because I want the LEDs to be updated constantly, while the main cog can run code that will change variables that the LED code will read and update its LED buffer accordingly.

    OMG!
    You are right about the two different cogs setting the I/O pins.
    I move this:
      outa[LE]~
      dira[LE]~~
    

    from the "public_method_name" to the "run" method, and it works now!

    I had no idea that the states of the I/O pins would be affected like that.

    Thanks so much!!
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-06-02 08:42
    Dave Hein wrote: »
    Try calling SPI.start from the run method.

    I think it's a good idea to start an object from the cog that will be using the object, but I don't think it matters in this case.

    SPI_Asm.spin only sets pin states from the cog running the PASM code so it shouldn't matter which cog calls the start method.

    Using SPI_Spin.spin from two different cogs would cause problems.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-06-02 08:50
    Mag748 wrote: »
    I had no idea that the states of the I/O pins would be affected like that.

    Thanks so much!!

    You're very welcome.

    This is often the culprit when code will work in one cog and not another.
Sign In or Register to comment.