Method behaves differently when launched in new cog
Mag748
Posts: 269
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:
This does 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:
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
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.
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:
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!!
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.
You're very welcome.
This is often the culprit when code will work in one cog and not another.