Shop OBEX P1 Docs P2 Docs Learn Events
WAITPEQ returns unexpectedly — Parallax Forums

WAITPEQ returns unexpectedly

trevormstrevorms Posts: 7
edited 2010-08-10 21:50 in Propeller 1
I have an application which instantiates a state machine (SPIN code) into two different COGs. At one point the following line of code is called in COG 1:

waitpeq(0, |< awake_in[unit_instance], 0)

In this case unit_instance=0, awake_in[unit_instance] = 9.

This function returns unexpectedly when COG 2 executes this code:

outa[relay[unit_instance]]~~
outa[ign[unit_instance]]~

In this case unit_instance= 1, relay[unit_instance] = 5 and ign[unit_instance] = 7.

The awake_in input is pulled high with a 10k resistor and I confirmed with an oscilloscope that it does not change state either.

To work around this problem I call this code after the WAITPEQ function:

waitpeq(0, |< awake_in[unit_instance], 0)
delay(1) ' Wait 1 second
awake_state := ina[awake_in[unit_instance]]


if awake_state == 0
unit_state[unit_instance] := STATE_WAIT_TIMEOUT


In this case awake_state is 1.

It seems that WAITPEQ when waiting on one COG can return if another COG writes to its output pin registers.

Has anyone else experienced this problem or is there something wrong that I am doing?

I have attached the full spin code for my application. It depends on VGA_Text which can be found in the object exchange.

Cheers,
T.

Comments

  • T ChapT Chap Posts: 4,223
    edited 2010-08-10 21:15
    Hello Trevor.

    Is this as you intended it to be, seems either your comment is wrong or the use of ~~ should be ~?

    dira[relay[unit_instance]]~~ 'Set relay pin to output
    outa[relay[unit_instance]]~ 'Make relay output low

    dira[ign[unit_instance]]~~ 'Set ignition pin to output
    outa[ign[unit_instance]]~~ '<<<<<Make ignition output low
  • Mike GreenMike Green Posts: 23,101
    edited 2010-08-10 21:18
    Indeed, it is possible for output pin changes in one cog's register to affect a WAITPEQ active in another cog. This reason this happens is that there's only one set of I/O pins and the input I/O circuitry reads the actual state of the I/O pins. If an I/O pin is set to output mode, the state of the output is what's read. If this satisfies a WAITPEQ condition, then the WAITPEQ instruction terminates.
  • trevormstrevorms Posts: 7
    edited 2010-08-10 21:19
    Sorry, my comments are not accurate and may be the result of copy-paste errors. The SPIN code does what I want.

    The relay outputs are active high while the ign outputs are active low.
  • kuronekokuroneko Posts: 3,623
    edited 2010-08-10 21:19
    trevorms wrote: »
    It seems that WAITPEQ when waiting on one COG can return if another COG writes to its output pin registers.

    waitpxx is very sensitive, a single clock pulse is enough to trigger it (e.g. 12.5ns @80MHz). How is the signal on this input pin generated?
  • trevormstrevorms Posts: 7
    edited 2010-08-10 21:21
    kuroneko wrote: »
    waitpxx is very sensitive, a single clock pulse is enough to trigger it (e.g. 12.5ns @80MHz). How is the signal on this input pin generated?
    The pin is pulled high with a resistor. An open drain transistor pulls the line low. In my test the input remained high with no glitches.
  • trevormstrevorms Posts: 7
    edited 2010-08-10 21:25
    Mike Green wrote: »
    Indeed, it is possible for output pin changes in one cog's register to affect a WAITPEQ active in another cog. This reason this happens is that there's only one set of I/O pins and the input I/O circuitry reads the actual state of the I/O pins. If an I/O pin is set to output mode, the state of the output is what's read. If this satisfies a WAITPEQ condition, then the WAITPEQ instruction terminates.
    My code is writing to different pins than the input pins, with the OUTA call, so I am confused as to why WAITPEQ should return.
  • trevormstrevorms Posts: 7
    edited 2010-08-10 21:26
    trevorms wrote: »
    My code is writing to different pins than the input pins, with the OUTA call, so I am confused as to why WAITPEQ should return.
    Also once the pin directions are set in my code, they are not changed.
  • kuronekokuroneko Posts: 3,623
    edited 2010-08-10 21:27
    trevorms wrote: »
    In my test the input remained high with no glitches.

    For the sake of it, can you connect an edge counter to the pin in question and monitor phsx just before and after the offending code sequence?
  • trevormstrevorms Posts: 7
    edited 2010-08-10 21:29
    Sure I could do that with an oscilloscope. Given the time I may simplify the spin code to reproduce this specific problem and wait on a pin that is tied high. When I do this I will post the results.
  • kuronekokuroneko Posts: 3,623
    edited 2010-08-10 21:33
    trevorms wrote: »
    Sure I could do that with an oscilloscope. Given the time I may simplify the spin code to reproduce this specific problem and wait on a pin that is tied high. When I do this I will post the results.

    Please use a cog internal counter, it sees what waitpxx sees.
  • trevormstrevorms Posts: 7
    edited 2010-08-10 21:38
    kuroneko wrote: »
    Please use a cog internal counter, it sees what waitpxx sees.
    Please excuse my ignorance but could you post example code to read the internal COG counter as I am not sure what you mean.
  • kuronekokuroneko Posts: 3,623
    edited 2010-08-10 21:50
    if unit_instance == 1
        ctra[30..26] := %01000      ' POS EDGE detector
        ctra[$5..$0] := awake_in[0] ' monitored pin
        frqa := 1
    
      if unit_instance == 1
        phsa := 0                   ' before
         
      outa[relay[unit_instance]]~~  ' offending code which seems
      outa[ign[unit_instance]]~     ' to trigger waitpeq()
    
      if unit_instance == 1
        temp := phsa                ' after
    
    Place this somewhere around the code which you think triggers the waitpeq. It is guarded so it's only active for unit 1 (but monitors the pin from unit 0). What I'm after is whether temp stays 0 or not.

    Hope this makes sense.
Sign In or Register to comment.