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

  • 4 Comments sorted by Date Added Votes
  • evanhevanh Posts: 5,431
    For a single pin SETSEx/WAITSEx pair would be the way to go. Or TESTP is another option.

    "Are we alone in the universe?"
    "Yes," said the Oracle.
    "So there's no other life out there?"
    "There is. They're alone too."
  • evanhevanh Posts: 5,431
    edited June 2 Vote Up0Vote Down
    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
    
    "Are we alone in the universe?"
    "Yes," said the Oracle.
    "So there's no other life out there?"
    "There is. They're alone too."
  • evanhevanh Posts: 5,431
    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.

    "Are we alone in the universe?"
    "Yes," said the Oracle.
    "So there's no other life out there?"
    "There is. They're alone too."
  • 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.