Shop Learn
[Solved] WAITPEQ problem - waits forever despite pin toggling at sensible speed — Parallax Forums

[Solved] WAITPEQ problem - waits forever despite pin toggling at sensible speed

CabbageCabbage Posts: 32
edited 2021-06-23 20:16 in Propeller 1

Can anyone deduce why the waitpeq instruction never responds to the RX_LATCH_PIN (P8, physical pin 13 on the 40-pin DIP)?

Both my oscilloscope and my logic analyser agree that this pin is indeed toggling. 3 microseconds HIGH, then 123 microseconds LOW. The signal is solid as a rock, no noise at all, no aliasing. The signal is actually generated by another pin driven from a different cog (cog 0 which is working perfectly according to the same scope and logic analyser).

The signal source is Cog 0: Pin 11 (output), and is physically hard wired to Cog 1 (the code below) Pin P8 (input). The wiring throughout the circuit is solid and free from intermittent faults.

As far as I can tell waitpeq never responds to the toggling pin. There are no short circuits happening (current usage is also perfectly stable and noiseless).

Here's the funny thing though, if I change the waitpeq into a waitpne, then the instruction NEVER waits, and always returns instantly and allows the serial port code to proceed and the loop runs without stalling.

Why is this waitpeq not responding to the toggling pin state?

              org       0
C1_ENTRY
              or        dira, RS232_TX_PIN 'output
              or        outa, RS232_TX_PIN 'idle high

              or        dira, DEBUG 

:c1_loop
              CALL      #Fast_RX
              mov       rs232_byte, fast_rx_byte

              mov       rs232_byte, #$55

              CALL      #RS232_TX

              or        outa, DEBUG              
              andn      outa, DEBUG              
              jmp       #:c1_loop



'receives a byte and stores it in fast_rx_byte              
Fast_RX
              waitpeq   ALL_ONES, RX_LATCH_PIN 'wait for the pin to go HIGH
              mov       fast_rx_byte, ina      'then read the inputs
              and       fast_rx_byte, RX_PINS  'and keep the LSByte               
Fast_RX_ret   ret      



'expects rs232_byte to contain the byte to send (gets clobbered)
RS232_TX
              or        rs232_byte, #$100 'insert stop bit
              shl       rs232_byte, #1    'insert start bit
              mov       rs232_count, #10 '10 bits because of start and stop bits

              mov       rs232_time, CNT
              add       rs232_time, RS232_BIT_TIME

:rs232_loop
              rcr       rs232_byte, #1 WC
              muxc      outa, RS232_TX_PIN
              waitcnt   rs232_time, RS232_BIT_TIME
              djnz      rs232_count, #:rs232_loop

              waitcnt   rs232_time, RS232_BIT_TIME
              waitcnt   rs232_time, RS232_BIT_TIME
              waitcnt   rs232_time, RS232_BIT_TIME
              waitcnt   rs232_time, RS232_BIT_TIME
              waitcnt   rs232_time, RS232_BIT_TIME
              waitcnt   rs232_time, RS232_BIT_TIME

RS232_TX_ret  ret

'########################################

RS232_TX_PIN  long      |< 30
RS232_BIT_TIME long     _xinfreq / 115200

RX_PINS       long      $000000ff  '8 input pins in a block
RX_LATCH_PIN  long      |< 8 'input

ALL_ZEROES    long      $00000000
ALL_ONES      long      $ffffffff

DEBUG         long      |< 16

rs232_byte    res       1
rs232_time    res       1
rs232_count   res       1

fast_rx_byte  res       1

              fit

This is driving me mad.

Comments

  • avsa242avsa242 Posts: 281
    edited 2021-06-23 20:42

    I've only ever used it waitpeq/pne spin, but in PASM I think the equivalent to how I would normally use it would be:

    waitpeq RX_LATCH_PIN, RX_LATCH_PIN
    

    I think having ALL_ONES in the source field waits for every single I/O pin to be high.

    In the code below, I've tried to reproduce the issue in spin. In the loop that runs in the secondary cog, if I wait for the state field to be ALL_ONES, the condition is never met, so sits there, as you've found. If I wait for the same as the mask field, however, it works, and the LED on pin 26 flashes.

    CON
    
        _clkmode    = xtal1 + pll16x
        _xinfreq    = 5_000_000
    
    VAR
    
        long stack[50]                              ' stack space for 2nd cog
    
    PUB Main
    
        outa[8] := 0                                ' pin 8 low, and output
        dira[8] := 1
        cognew(waitpin, @stack)                     ' start waitpin() in a new cog
    
        waitcnt(cnt + (clkfreq*2))                  ' wait 2sec
        outa[8] := 1                                ' now bring pin 8 high
    
    PUB waitpin
    
        repeat
            ' wait for pin 8's state (INA) to be high
            waitpeq(ALL_ONES, RX_LATCH_PIN, 0)      ' doesn't work
    '        waitpeq(RX_LATCH_PIN, RX_LATCH_PIN, 0) ' works
    
            dira[26] := 1
            repeat
                !outa[26]                           ' flash LED on pin 26
                waitcnt(cnt + (100*(clkfreq/1000))) ' wait 100ms
    
    CON
    
        ALL_ONES = $ffff_ffff
        RX_LATCH_PIN = |< 8                         ' = (1 << 8)
    
    

    EDIT: Resolved already, but updating code example with comments for potential passersby benefits.

  • Yes, you're right. Thank you.
    Thanks also to Wuerfel_21 for the same sage advice on discord.

    I had mistakenly thought that the AND with the mask happened to both parameters, which is not the case of course.

    This community is so awesome.

    Working now :) ...

Sign In or Register to comment.