Confusing little issue
Hey all!
I have isolated a bug in my code, and I have stripped it down to the extreme basics. I know that it does not, but I would like to know exactly why this code sample does not work. For bare simplicity, I brought it down to toggling a pin, and it just won't fire up. Here is the top file.
And here is the child object:
In my mind, I would expect it to still blink the pin. whatever cog does the actual processing. But the it stays idle. I have done some experimenting and found the pin number is passed correctly, but it just will not toggle. I know the hardware is good becuase when I do it with a single cog, single file, single method:
it does exaclty the right thing. Can anyone explain this to me?
I have isolated a bug in my code, and I have stripped it down to the extreme basics. I know that it does not, but I would like to know exactly why this code sample does not work. For bare simplicity, I brought it down to toggling a pin, and it just won't fire up. Here is the top file.
CON
'' Clock settings
_CLKMODE = XTAL1 +PLL16X
_XINFREQ = 5_000_000
Power = 26 ' GPIO to use in this demonstration
OBJ
BLINK : "BlinkyPins.spin"
PUB Start
'' Init the system
BLINK.Startcog(Power) ' Start the cog up with the code from the other object
run ' Go to the next method.
PUB Run
'' this loop is to toggle the pin's output status
repeat
BLINK.PinOn ' Turn the pin on
waitcnt(clkfreq + cnt) ' Wait for approx 1 second
BLINK.PinOff ' Turn the pin back off
waitcnt(clkfreq + cnt) ' Wait for approx 1 second
And here is the child object:
VAR
byte cog ' Cog ID variable
byte Power ' Var for holding the pin number to run
long stack[10] ' STack space for the new cog.
PUB Startcog(PowerPin) : ok
'' Start the cog up.
ok := cog := cognew(INIT(PowerPin), @stack[0]) + 1
PUB init(Power_)
Power := Power_
dira[Power] := 1
repeat
waitcnt(clkfreq + cnt) ' Normally this area would be filled with other code.
waitcnt(clkfreq + cnt) ' I just wanted to keep the cog alive
PUB PinOn
'' Turn the pin on
outa[Power] := 1
PUB PinOff
'' Turn the pin off
outa[Power] := 0
In my mind, I would expect it to still blink the pin. whatever cog does the actual processing. But the it stays idle. I have done some experimenting and found the pin number is passed correctly, but it just will not toggle. I know the hardware is good becuase when I do it with a single cog, single file, single method:
dira[Power] := 1
repeat
outa[Power] := 1
waitcnt(clkfreq + cnt)
outa[Power] := 0
waitcnt(clkfreq + cnt)
it does exaclty the right thing. Can anyone explain this to me?

Comments
PUB Startcog(PowerPin) : ok '' Start the cog up. ok := cog := cognew(INIT(PowerPin), @stack[0]) + 1 PUB init(Power_) Power := Power_ dira[Power] := 1 repeat waitcnt(clkfreq + cnt) ' Normally this area would be filled with other code. waitcnt(clkfreq + cnt) ' I just wanted to keep the cog aliveThe main cog has no concept of the "byte Power" member of BlinkyPins as the IO is ORed together..
UB Run '' this loop is to toggle the pin's output status repeat BLINK.PinOn ' Turn the pin on waitcnt(clkfreq + cnt) ' Wait for approx 1 second BLINK.PinOff ' Turn the pin back off waitcnt(clkfreq + cnt) ' Wait for approx 1 secondGenerally, you'll have a COG running is a loop looking for a command to execute - Producer/Consumer model.
See the Propeller Education kit. It has a great tutorial covering this topic.
Thanks Mike.
0 = no command
1 = light LED
2 = turn off
I did not test this code - and it is not the greatest - but it should provide an example.
VAR byte cog ' Cog ID variable byte Power ' Var for holding the pin number to run long command long stack[10] ' STack space for the new cog. PUB Startcog(PowerPin, cmd) : ok '' Start the cog up. command := cmd ok := cog := cognew(INIT(PowerPin), @stack[0]) + 1 PUB init(Power_) | cmd Power := Power_ dira[Power] := 1 repeat cmd := byte[command] if(cmd == 1) PinOn if(cmd == 2) PinOff PUB PinOn '' Turn the pin on outa[Power] := 1 PUB PinOff '' Turn the pin off outa[Power] := 0You set DIRA in the second cog, while you execute the BLINK.PinOn/PinOff with the first cog. So just set dira at begin of the RUN methode instead of the INIT methode.
Andy
If more than one cog has a 1 for the same pin in DIRA, then the pin's output is the logical OR of the OUTA registers in those cogs with a 1 in the DIRA.
Well I'll be.... it is working. but is it taking the pin information from the variable in the child, or the constant in the parent file? I know it does not matter, but curiosity on this is bugging me.
And by default, they are set to 0. Hrmmm...
and to answear my own question, I got rid of the constant (and passing from parent to child) and just init'd the variable in the child object to be 26 and it gave up the ghost again. I guess that proves that even though it is pulling the method from the child, it is running in the first, and hence has access to the constants and variables of the first cog.
Boy.. I am learning a boatload today. thanks guys. I know it is just a stupid little program here, but it has taught me a LOT about the inner workings of this beast.