Testing pins for shorts using Smartpins and pullups/pulldowns

Cluso99Cluso99 Posts: 16,909
edited 2020-11-22 - 03:13:08 in Propeller 2
Changed the title to better reflect this thread

See a few posts down for working code :sunglasses:
Latest code attached to this post. Compiles with flexspin.

@ManAtWork also posted some test code here
forums.parallax.com/discussion/comment/1510159/#Comment_1510159


I am trying to test out my boards and need to set pullups and pulldowns but it's not working because I don't understand exactly how to configure them.
I think the problem is that I am not initialising the smart pins correctly. Also, not sure the best way to read the pins either as I get different results with rdpin vs pinread.

This is what I have (using jonnymacs serial driver)
CON
  _clkfreq      = 200_000_000           ' clock frequency
  _BAUD         = 115_200               ' serial speed

  rx_pin	      =	63		                'pin serial receiver
  tx_pin	      =	62		                'pin serial transmitter

  LOPIN         = 0                     ' lowest  io pin to be tested
  HIPIN         = 15 '57                ' highest io pin to be tested                                

OBJ
  term : "jm_fullduplexserial"                                  ' serial terminal    

PUB main()                                                         
  term.start(rx_pin, tx_pin, %0000, _baud)                      ' start serial
  waitms(5000)                                                  ' 5s delay for PST     
  term.fstr0(string("Testing io pins...\r\n"))

  setup_pins(LOPIN, HIPIN, P_HIGH_15K)                          ' set pins with 15K pullups
  setup_pins(LOPIN, HIPIN, P_LOW_15K)                           ' set pins with 15K pulldowns
                                                         
  repeat                                                        ' <---- loop indefinitely

PUB setup_pins(lowest, highest, mode) | pin, v, p
  repeat pin from lowest to highest
'    pinstart(pin, mode, 0, 0)                                   ' clear and setup pin(s)
    pinclear(pin)                                               ' clear pin
    wrpin(pin, mode)                                            ' set smart mode

    waitms(2)                                                   ' ?? just in case
    v := rdpin(pin)                                             ' read back pin
    p := pinread(pin)                                           ' read back pin

    term.fstr3(string("%2d %8x %8x\r\n"), pin, v, p)

Comments

  • TubularTubular Posts: 4,154
    edited 2020-11-21 - 02:11:45
    you can just configure the pullup/downs using Wrpin (the P_HIGH_15K and P_LOW_15K set the right CIO bits ready to go). Then just output a High . What appears at the pin is in effect a high with 15k series resistor. Then output a low, what appears at the pin is a low with 15k series resistor. This isn't smart pin stuff (so no wxpin wypin rdpin needed)

    If you also want to read back the ADC node voltage you can do this using TT bits and a couple of smartpin commands. I'll post a MicroPython demo in a moment that does this (its in MP but the constant names are same as Spin2)
  • Tubular wrote: »
    you can just configure the pullup/downs using Wrpin (the P_HIGH_15K and P_LOW_15K set the right CIO bits ready to go). Then just output a High . What appears at the pin is in effect a high with 15k series resistor. Then output a low, what appears at the pin is a low with 15k series resistor. This isn't smart pin stuff (so no wxpin wypin rdpin needed)

    If you also want to read back the ADC node voltage you can do this using TT bits and a couple of smartpin commands. I'll post a MicroPython demo in a moment that does this (its in MP but the constant names are same as Spin2)
    Maybe I was overcomplicating it. I thought that enabling the pullup would not require outputting a high too as I would have supposed that would drive the pin high. I'll give it a try now and report back.
  • RaymanRayman Posts: 11,482
    edited 2020-11-21 - 02:29:46
    The pull-ups and pull downs are strange as they are between the pin and VDD/GND instead of in parallel...

    So, you have to drive pin high for pull
    up to work and drive pin low for pull down to work...
  • Yeah thats the slightly counterintuitive leap needed say to read a pushbutton (without external passives)

  • This seems to work. Is this what you're looking to do, Ray?
    pub main() | t, x, y, p
    
      setup()
    
      wait_for_terminal(true)
    
      repeat p from 24 to 31 
        term.fstr1(string("Testing pin %d\r"), p)
        
        set_pullup(p)
        term.fstr0(string("-- high: "))
        if (pinread(p) == 1)
          term.fstr0(string("PASS\r"))
        else
          term.fstr0(string("FAIL\r"))
    
        set_pulldown(p)           
        term.fstr0(string("--  low: "))
        if (pinread(p) == 0)
          term.fstr0(string("PASS\r"))
        else
          term.fstr0(string("FAIL\r"))
        term.tx(13)
        waitms(100)
        pinclear(p)
    
      repeat
        waitct(0) 
    
    
    pub set_pullup(pin)
    
      pinclear(pin)
      wrpin(pin, P_HIGH_15K)  
      pinhigh(pin)
                
    
    pub set_pulldown(pin)
    
      pinclear(pin)
      wrpin(pin, P_LOW_15K)  
      pinlow(pin)
    
  • Interesting that there is a reasonable delay before the pins report back correctly. A waitx(25) minimum is required !!!
    PUB main()                                                         
      term.start(rx_pin, tx_pin, %0000, _baud)                      ' start serial
      waitms(5000)                                                  ' 5s delay for PST     
      term.fstr0(string("Testing io pins...\r\n"))
    
      setup_pins(LOPIN, HIPIN, P_HIGH_15K)                          ' set pins with 15K pullups
      setup_pins(LOPIN, HIPIN, P_LOW_15K)                           ' set pins with 15K pulldowns
      setup_pins(LOPIN, HIPIN, P_HIGH_15K)                          ' set pins with 15K pullups
      setup_pins(LOPIN, HIPIN, P_LOW_15K)                           ' set pins with 15K pulldowns
                                                             
      repeat                                                        ' <---- loop indefinitely
    
    PUB setup_pins(lowest, highest, mode) | pin, v, p
      repeat pin from lowest to highest
    '    pinclear(pin)                                               ' clear pin (may not be reqd)
        wrpin(pin, mode)                                            ' set smart mode
        if mode == P_HIGH_15K
          pinhigh(pin)
        else
          pinlow(pin)
    
        waitx(30)                                                   ' tiny delay >=25
        v := pinread(pin)                                           ' read back pin
    
        term.fstr2(string("%2d %8x\r\n"), pin, v)
    
  • Yep, it's done by setting drive strengths of the pin logic output. So, even FAST (20 ohm) strength counts here.

    The apparent delay will partly be rise time. About 8 ticks is for I/O stages but the rest is a charge curve timer of the 15 kR vs the pin/board capacitance. If you use higher sysclock frequency then you'll also need a bigger WAITX.

  • TubularTubular Posts: 4,154
    edited 2020-11-21 - 03:19:38
    yes, what evanh said, although 25 clocks is around 1uSec and thats a lot more than I would have guessed. Implies 10s of picofarads of capacitive loading

    Is it still 8 clocks turnaround at RCFast evanh? Wouldn't it be fewer?
  • Cluso99Cluso99 Posts: 16,909
    edited 2020-11-21 - 03:47:38
    It's a lot more than I expected it to be.

    Presuming spin translates to using waitx, at 200MHz it's 25*5ns = 125ns plus the spin decoding over head.

    Cannot recall how many clocks it takes to clock out, then back in. but there is spin overhead here too.
  • Oh you're at 200 MHz. In that case its about right, 15k * 7pF gives a time constant of 105ns, add a few clocks for going out and coming again
  • I'm confused, Ray. I can't find the waitx() instruction in Spin2 using v35 PNut or Propeller Tool. Are you compiling using FlexSpin? If that's the case, then the waitx() instruction should compile directly a native PASM2 instruction -- no Spin overhead.
  • JonnyMac wrote: »
    I'm confused, Ray. I can't find the waitx() instruction in Spin2 using v35 PNut or Propeller Tool. Are you compiling using FlexSpin? If that's the case, then the waitx() instruction should compile directly a native PASM2 instruction -- no Spin overhead.
    Yes, I'm now using flexspin. Started with pnut but its a chore to switch over to PST when I can use a bat file to compile/load/run+terminal in flexspin.
    Then I added to the program and just typed waitx(n) without thinking.

    BTW love your term.fstrn with parameters for decimal, hex etc!

    Might be worthwhile adding a sample pullup method to your jmtosp_demos.spin2 program :)
  • Cluso99Cluso99 Posts: 16,909
    edited 2020-11-21 - 05:27:39
    Interesting that the pins connected to the VGA connector (RGB only, not HS or VS) require the waitx delay to be increased to 35.

    Here is the code
    '' RR20201121 RBTest01.spin2  testing P2 I/O pins on "RBTest01.spin2"
    
    CON
      _clkfreq      = 200_000_000           ' clock frequency
      _BAUD         = 115_200               ' serial speed
    
      rx_pin	      =	63		                'pin serial receiver
      tx_pin	      =	62		                'pin serial transmitter
    
      LOPIN         = 0                     ' lowest  io pin to be tested
      HIPIN         = 57 '61                ' highest io pin to be tested                                
    
      DLAY          = 50                    ' delay after setting pullups/pulldowns (>=25/35)
    
    OBJ
      term : "jm_fullduplexserial"                                  ' serial terminal    
    
    PUB main()                                                         
      term.start(rx_pin, tx_pin, %0000, _baud)                      ' start serial
      waitms(5000)                                                  ' 5s delay for PST     
      
      term.fstr0(string("Test pins 0....V....1....V....2....V....3....V....4....V....5....V....6...\r\n"))
    
      set_pullups(LOPIN, HIPIN, P_HIGH_15K)                         ' set pins with 15K pullups
      test_pulldowns(LOPIN, HIPIN, P_LOW_15K, P_HIGH_15K)           ' test all pins read back correctly
    
      set_pulldowns(LOPIN, HIPIN, P_LOW_15K)                        ' set pins with 15K pulldowns
      test_pullups(LOPIN, HIPIN, P_LOW_15K, P_HIGH_15K)             ' test all pins read back correctly
    
      term.fstr0(string("Done      0....V....1....V....2....V....3....V....4....V....5....V....6...\r\n"))
      repeat                                                        ' <---- loop indefinitely
    
    PUB set_pullups(lowest, highest, mode) | pin, v, err
      term.fstr0(string("Init Hi   "))
      err~
    
      repeat pin from lowest to highest
        wrpin(pin, mode)                                            ' set smart mode
        pinhigh(pin)
        waitx(DLAY)                                                 ' tiny delay
        v := pinread(pin)                                           ' read back pin
        if v == 0
          err++
        term.tx(v | "0")
    
      if err > 0
        term.fstr1(string(" <<< %2d error(s)"), err)
      term.fstr0(string("\r\n"))
    
    PUB set_pulldowns(lowest, highest, mode) | pin, v, err
      term.fstr0(string("Init Lo   "))
      err~
    
      repeat pin from lowest to highest
        wrpin(pin, mode)                                            ' set smart mode
        pinlow(pin)
        waitx(DLAY)                                                 ' tiny delay
        v := pinread(pin)                                           ' read back pin
        if v == 1
          err++
        term.tx(v | "0")
    
      if err > 0
        term.fstr1(string(" <<< %2d error(s)"), err)
      term.fstr0(string("\r\n"))
    
    PUB test_pulldowns(lowest, highest,lomode, himode) | pin, v, err  ' test all pins read back correctly
      term.fstr0(string("Test Lo   "))
      err~
    
      repeat pin from lowest to highest
        wrpin(pin, lomode)                                          ' make low
        pinlow(pin)
        waitx(DLAY)                                                 ' tiny delay
        v := pinread(pin)                                           ' read back pin
        if v == 1
          err++
        term.tx(v | "0")
        wrpin(pin, himode)                                          ' make high again
        pinhigh(pin)
        waitx(DLAY)                                                 ' tiny delay
    
      if err > 0
        term.fstr1(string(" <<< %2d error(s)"), err)
      term.fstr0(string("\r\n"))
    
    PUB test_pullups(lowest, highest, lomode, himode) | pin, v, err   ' test all pins read back correctly
      term.fstr0(string("Test Hi   "))
      err~
    
      repeat pin from lowest to highest
        wrpin(pin, himode)                                          ' make high
        pinhigh(pin)
        waitx(DLAY)                                                 ' tiny delay
        v := pinread(pin)                                           ' read back pin
        if v == 0
          err++
        term.tx(v | "0")
        wrpin(pin, lomode)                                          ' make low again
        pinlow(pin)
        waitx(DLAY)                                                 ' tiny delay
    
      if err > 0
        term.fstr1(string(" <<< %2d error(s)"), err)
      term.fstr0(string("\r\n"))
    
    And the program output
    C:\P2\_RetroBlade2\RetroBlade2_testing>l500 RBTest01.binary -b115200 -t -SINGLE
    ( Entering terminal mode.  Press Ctrl-] to exit. )
    Test pins 0....V....1....V....2....V....3....V....4....V....5....V....6...
    Init Hi   1111111111111111111111111111111111111111111111111111111111
    Test Lo   0000000000000000000000000000000000000000000000000000000000
    Init Lo   0000000000000000000000000000000000000000000000000000000000
    Test Hi   1111111111111111111111111111111111111111111111111111111111
    Done      0....V....1....V....2....V....3....V....4....V....5....V....6...
    
    And with forced errors (delay=30)
    C:\P2\_RetroBlade2\RetroBlade2_testing>l500 RBTest01.binary -b115200 -t -SINGLE
    ( Entering terminal mode.  Press Ctrl-] to exit. )
    Test pins 0....V....1....V....2....V....3....V....4....V....5....V....6...
    Init Hi   1111111111111111111111111111111111111111111111111111111111
    Test Lo   0000000000000000000000000000011100000000000000000000000000 <<<  3 error(s)
    Init Lo   0000000000000000000000000000011000000000000000000000000000 <<<  2 error(s)
    Test Hi   1111111111111111111111111111111111111111111111111111111111
    Done      0....V....1....V....2....V....3....V....4....V....5....V....6...
    

    OT: Don't you just hate the way editing programs put in tabs even when you have spaces switched on! I'm using VSC with spaces: 2.
  • Might be worthwhile adding a sample pullup method to your jmtosp_demos.spin2 program :)
    I have a simple object called jm_ez_button.spin2 that uses allows one to configure the pin as active-high or active-low with the built-in resistors.
  • JonnyMac wrote: »
    Might be worthwhile adding a sample pullup method to your jmtosp_demos.spin2 program :)
    I have a simple object called jm_ez_button.spin2 that uses allows one to configure the pin as active-high or active-low with the built-in resistors.
    Of course you have :smiley:

    Love all these little snippets you do! Such a help for anyone trying something new.
  • So are RGB on the top pins of your right angle VGA connector? Above a plane of grounds on pins 6~10 (excl 9) . Those signals will have bit more capacitance than VS/HS that have less distance to travel, but not by much

    You could also hook on an unconnected VGA cable, if its proper coax its going to load R/G/B around 35pF per foot

  • The above program works with 1K between adjacent pins, or to 3V3 or GND.
Sign In or Register to comment.