Shop OBEX P1 Docs P2 Docs Learn Events
How to wait on a pin state? — Parallax Forums

How to wait on a pin state?

I was updating my P1Spin bytecode interpreter this morning, and I'm trying to figure out how to handle the WAITPEQ and WAITPNE bytecodes. When I did this a few years ago I use SETPAE, SETPBA, SETPAN or SETPBN followed by a WAITPAT. However, those SETXXX instructions no longer exists. It seems now I must do a MODCZ, DECOD, SETPAT and then WAITPAT. Is that the way best way to wait on a pin where the pin number is specified in a register, or is there an easier way to do it that requires fewer instructions?

Comments

  • evanhevanh Posts: 15,170
    For a single pin SETSEx/WAITSEx pair would be the way to go. Or TESTP is another option.

  • evanhevanh Posts: 15,170
    edited 2018-06-02 18:48
    Now you mention it I did have a fiddle with your old serial code that I've been using. You'll see I've used jnse1 instead of waitse1 to maintain the non-IRQ-blocking arrangement you already had:
    '*******************************************************************************
    '  COG Code
    '*******************************************************************************
    
    'smartpin version
    getch
    		testp   #rx_pin         wz
    if_nz		jmp     #getch                'wait while Smartpin is idle
    		rdpin   char, #rx_pin
    _ret_		shr     char, #32-8           'shift the data to bottom of register
    
    
    putch
    		rqpin   temp1, #tx_pin  wc    'transmiting
    		testp   #tx_pin         wz    'buffer free
    if_nz_and_c	jmp     #putch                'wait while Smartpin is both full (nz) and transmitting (c)
    _ret_		wypin   char, #tx_pin
    
    
    'non-smartpin version
    'getch
    '		setse1  #%100_000000|rx_pin   'reset selectable event #1 (SE1) - needs an instruction time to take effect
    '		mov     char, #0
    '.getc0		jnse1   #.getc0               'wait while rx_pin is idle (HIGH) using SE1
    '		getct   temp2                 '"Start the clock!"
    '		add     temp2, bitcentre      'first interval aligns bit centred sampling on bit0, skipping the start bit
    '		mov     temp1, #8             '8 bits to read in
    '.getc1
    '		addct1  temp2, bitcycles
    '.getc2		jnct1   #.getc2               'wait a bit interval
    '		testp   #rx_pin     wc        'sample the data bit (single sampling only)
    '		rcr     char, #1              'log it
    '		djnz    temp1, #.getc1
    '
    '_ret_		shr     char, #32-8           'shift the data to bottom of register
    
    
    'bitcycles	long    (clock_freq + baud_rate/2) / baud_rate   'rounded to nearest
    'bitcentre	long    clock_freq / baud_rate / 2 - 20          'an estimated 20 clocks for combined event and instruction lags present in the start-bit trigger event
    
    
    'putch
    '		or      char, #$100
    '		shl     char, #1
    '		mov     temp1, #10
    '		getct   temp2
    '.putc0
    '		shr     char, #1   wc
    '		drvc    #tx_pin
    '		addct1  temp2, bitcycles
    '.putc1		jnct1   #.putc1
    '		djnz    temp1, #.putc0
    '		ret
    
    parm		long    0
    char		long    0
    temp1		long    0
    temp2		long    0
    
  • evanhevanh Posts: 15,170
    And the reason I used branch on non-event instruction is because it can loop on itself, making for a tighter loop than testp + branch can achieve.

  • After looking at is some more I found that I needed to use MODZ along with SETPAT. The C flag is set by another instruction, and I didn't need DECOD since WAITPXX uses a mask for multiple bits. It turned out to be the same number of instructions as I had been using before.
Sign In or Register to comment.