Shop OBEX P1 Docs P2 Docs Learn Events
Monitoring the state of an output pin using ASM and multiple cogs — Parallax Forums

Monitoring the state of an output pin using ASM and multiple cogs

Vega256Vega256 Posts: 197
edited 2015-12-29 04:01 in Propeller 1
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.
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

  • JonnyMacJonnyMac Posts: 9,105
    edited 2015-12-28 23:47
    Here's an idea to consider -- I've used this in Spin and PASM for detecting a rising edge without blocking code.
    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_PIN
    
    Keep in mind that you'll want all the cogs waiting on the signal to be loaded and running before you give that signal.
  • ElectrodudeElectrodude Posts: 1,657
    edited 2015-12-29 01:56
    After the test fails, your code runs into do_something_else anyway. Do you want a "jmp #start_monitor" to prevent that?

    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    0
    

    EDIT: made code more complete
  • Vega256Vega256 Posts: 197
    edited 2015-12-29 03:46
    After the test fails, your code runs into do_something_else anyway. Do you want a "jmp #start_monitor" to prevent that?

    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    0
    

    EDIT: 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?
  • yes they do.

    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
  • Vega256,

    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
  • As usual @Phil is right to mention that. You need to use ina not outa, but you can do that from any cog, reflecting the actual state.

    Mike
Sign In or Register to comment.