I don't understand smart pin pull-down.

I am using the Parallax Control board. I have a program that loops and reads status of the button on P20. If I set the pull-down outside the loop it doesn't work. If I call the SetPulldown method immediately before reading the button it doesn't work the first time thru the loop. If I add a delay after the call to SetPulldown it works. I guess I should be happy that I have something that works, but I don't understand what is happening.

Here is the code with results of different test cases in comments.
    oscmode = $010c3f04               'standard stuff
    freq    = 160_000_000
    baud = 230400                     'must configure RUN command to match this
    thepin = 20

    ser: "PrintfSerial"     'access to Propellor output (output only)
pub main | pinInput
    clkset(oscmode, freq)
    ser.start(baud)                  'start up serial terminal
'    SetPulldown(thepin)             ' if here 8 to 10 lows then highs with no button push
    waitcnt(freq * 2 + cnt)          ' wait to enable terminal
    ser.str(string("Pullup Pulldown Input test"))
        SetPulldown(thepin)           ' without delay below 2 highs then lows and highs with pin pushed
        waitcnt(freq / 8_000_000 + cnt)  ' works with this delay. freq / 8_000_000 has one high then lows and highs with pin pushed
        pinInput := In(thepin)
        waitcnt(freq / 10 + cnt)

PUB SetPulldown(pin)
           wrpin   ##( %0_011_000010010 << 8 ), pin 
           drvl    pin
PUB In(pin) : state
      dirl      pin
      testp     pin            WC
if_c  addx      state, #0 


  • I'm not sure I have it 100% either...

    But, I think this is a smartpin mode, so you need to set dir high on this pin after the wrpin and leave it high.
    Then, hopefully, you've picked the smartpin mode where IN gives you the state of the pin.
  • evanhevanh Posts: 10,229
    edited 2019-02-21 - 23:05:45
    I think everyone has struggled with the I/O in their own ways. I've certainly spent many hour on them and am still learning new details.

    Right, what is happening here ... is:
    1: SetPullDown() drives low with 15kR pulldown. This takes time, and not only because it's a weak drive but also because there is a number of stages involved in both controlling the pins and reading them back in again.

    2: Then DIRL stops the driving. This also takes time so the immediate TESTP still works, but any further tests will show no pulldown. ("Direction", DIR, is somewhat misnamed. It's less of a direction control and more just an output drive control, it would have been more correctly named Drive or Out-Enable.)

  • A general detail:
    The time factor involved is not unique to I/O operations. There is many operations in all hardware that take longer than one instruction to come to fruition. How that is managed varies:

    RDFAST instruction, for example, has two ways to manage its FIFO pre-filling requirements. One is to stall execution until the pre-filling is complete and only then is the next instruction allowed to continue. The other way is it can be told to initiate the pre-filling but allow execution to continue even though the FIFO is not yet ready to be used.

    The first method doesn't require any precautions from the developer. But it costs execution time.

    The second method requires the developer to understand that the FIFO still needs time to be ready before use. But it has the advantage of no-stalls in execution.
  • I thought that even when pulled down low, the IN could still be high...
  • evanhevanh Posts: 10,229
    edited 2019-02-22 - 00:28:16
    Yep. Driven with a pull-down is a weak drive. A push button will pull it high again against the driven pull-down. The pin may not go low at all.

    The pins can switch between weakly driving high and low just on OUT change. That's why there is HHH and LLL separately in the config bits. They can be resistances or constant currents or mixed with open collector or logic drive.
    		%HHH/LLL = digital out drive strength
    			000: Fast
    			001: 1k5R
    			010: 15kR
    			011: 150kR
    			100: 1mA
    			101: 100uA
    			110: 10uA
    			111: Float
    If HHH and LLL are both %111==Float then DIR and OUT no longer has any effect on the output.
Sign In or Register to comment.