Monitoring the state of an output pin using ASM and multiple cogs
Hey guys,
I need one cog to set a pin to an output (in order to set up a high duty cycle signal). Then, I need another cog to do something else, but only on the positive-going edge of the aforementioned signal.
Before I write the definite code for this, I wrote some test code. This code is supposed to have one cog set a pin high while another cog running ASM makes a decision based on the output of the same pin.
When I run this, the cog running asm jumps straight to do_something_else, so the check on outa read a low for the pin outputting a high. What's going on? Is there some weird caveat with outa or something basic that I'm missing here?
I need one cog to set a pin to an output (in order to set up a high duty cycle signal). Then, I need another cog to do something else, but only on the positive-going edge of the aforementioned signal.
Before I write the definite code for this, I wrote some test code. This code is supposed to have one cog set a pin high while another cog running ASM makes a decision based on the output of the same pin.
con
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
SIGNAL_PIN = 3
var
long stack1 [32]
pub start
cognew (start_waveform (SIGNAL_PIN), @stack1)
cognew (@start_monitor, 0)
pub start_waveform (pin)
dira [pin] := 1
outa [pin] := 1
repeat
dat
org
start_monitor
or dira, output_pins
mov r1, outa
and r1, signal_mask
cmp r1, signal_mask wz
if_ne jmp #do_something_else
mov r1, #3
do_something_else
dat
output_pins long 1 << SIGNAL_PIN
signal_mask long 1 << SIGNAL_PIN
r1 res
When I run this, the cog running asm jumps straight to do_something_else, so the check on outa read a low for the pin outputting a high. What's going on? Is there some weird caveat with outa or something basic that I'm missing here?

Comments
dat org 0 monitor shl scan, #1 ' prep for new input and scan, #%11 ' truncate to two bits test pinmask, ina wc ' scan the pin muxc scan, #1 ' add to scan variable cmp scan, #%01 wc, wz ' edge detected? if_ne jmp #monitor edge_detected ' do something jmp #monitor scan long 0 pinmask long 1 << SIGNAL_PINKeep in mind that you'll want all the cogs waiting on the signal to be loaded and running before you give that signal.If that is what you want, and there won't be anything else in that loop (i.e. you want to wait until the pins don't equal a value), you can use the waitpne instruction:
DAT org 0 start_monitor or dira, output_pins wait waitpeq zero, signal_mask ' wait until not positive waitpne zero, signal_mask ' wait for positive edge jmp #do_something_else do_something_else jmp #wait output_pins long 1 << SIGNAL_PIN signal_mask long 1 << SIGNAL_PIN zero long 0EDIT: made code more complete
Does waitpeq/waitpne work for monitoring output pins as well?
Also, how do you guys get the clean code block section in posts?
in the editor is a symbol looking like a C
just click it and type your text between them tags.
or type the tags by yourself.
Enjoy!
Mike
Just an FYI: one cog cannot monitor the outa state of another cog, since each cog has its own outa register. Every cog has access to the physical pin states of all the pins, regardless of which cog is controlling them. This is done by monitoring ina, either directly or via the waitpxx commands.
-Phil
Mike