[Solved] WAITPEQ problem - waits forever despite pin toggling at sensible speed
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
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:
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.
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 ...