Shop OBEX P1 Docs P2 Docs Learn Events
Smart pins as level shifter? — Parallax Forums

Smart pins as level shifter?

I am hoping to use the smart pins as a digitally controlled level shifter, but reading through the documentation I am kind of lost. The behavior I am looking for is to define an input pin and an output pin with set voltage levels, but then in software have them behave as normal pins where I can read and write to them without worrying about the analog side. Is this possible?

For the output I would want to setup the dac to a voltage initially, but then have the Out command tell the pin whether to drive or not.
for input I want to set the comparator value, then have the in command read high if it is above that value or low if it is below that value.

Confirmation that it is designed to do this would be good enough and I will keep chugging along with the documentation. If someone already has an example they can point me to that would be perfect!

Comments

  • evanhevanh Posts: 15,916
    edited 2019-11-17 06:51
    The pins are always bound to VIO as a hard upper limit. Normally 3.3 Volts but indications are that VIO supply of 4.0 Volts wouldn't be damaging.

    That said, yep, there is a pin mode that allows the DAC to be switched between two voltages just by toggling that pin's OUT bit. And there is a pin mode that uses the DAC internally to set the comparator threshold. I've not tried to work out if such arrangements are as fast as simple digital I/O though.

    As you've already discovered, these are not clearly documented yet ... I did a translation a while back that should help, BIT_DAC and COMP_DAC are the modes you're after - https://forums.parallax.com/discussion/comment/1452036/#Comment_1452036

    EDIT: Err, the BIT_DAC mode write-up there is out of date. That one applies to the revA silicon only.
    EDIT2: Updated now. Easier than expected.
  • evanhevanh Posts: 15,916
    edited 2019-11-19 04:10
    Here's a config line from yesterday's testing where I used the BIT_DAC mode for a hyperRAM clock source. The purpose was to use the DAC's weaker driver strength to make the output slewing slower and therefore phase shift the clock wrt the data.

    And it did that, I got working results at low clock rates. However, the higher resistance also increased attenuation so high clock rates still didn't work.
    		wrpin	##SPM_STEPS | PM_DAC124 | ($f0<<8), #ram_ck	'HR clock pin, registered, 124 Ohm BIT_DAC (high=15, low=0)
    

    Elsewhere, I have the constants defined as
    	PM_DAC		= (%101 << 18)		' turn on custom pin DAC output (with optional ADC input)
    	PM_DAC990	= PM_DAC
    	PM_DAC600	= PM_DAC |(%01 << 16)
    	PM_DAC124	= PM_DAC |(%10 << 16)
    	PM_DAC75	= PM_DAC |(%11 << 16)
    	SP_OUT		= (%1 << 6)		' force on pin output when DIR operates smartpin
    
    	SPM_STEPS	= %00101_0 |SP_OUT		' transition output
    
  • Thanks for the info! I was able to get the bit_dac output working. It is strange having the two 4 bit drive values which lets you have the '0' output be higher than the '1'. I'll work on the comp dac later in the week.


    56 has normal 0 1 behavior while 57 is inverted:
    wrpin ##%10110_11110000_10_00000_0,#56
    wrpin ##%10110_00001111_10_00000_0,#57

  • Ok, I got both sides working now and I setup a little self test to evaluate them. Starting from the pasm blink example from the flexgui tool I added 3 more pins. The dac out, the comparator, then a result pin connected to an LED. I shorted the dac pin and the comparator together so that the comparator reads the result from the dac. The code drives the dac high, waits some time and then checks the comparator input pin. If the comparator reads the correct value it turns on the results LED. with this setup I verify that the two modes are working. Setting a comparator value greater than the output dac causes it to consistently fail. I have tried this for several ranges of dac and comparator so I think it is working well.

    Evaluating the speed is interesting too. The key code is outh to waitx to testp. I checked for the minimum waitx value to still allow for blinking. the comparator was set to less than 50% to allow it to observe higher speeds.

    digital out to digital in waitx=3
    dac out digital in waitx=4
    digital out comparator in waitx=6
    dac out comparator in waitx=7

    Then I set the Dac to minimum voltage swing and the comparator to half that and I got a minimum waitx of 9. This mode has 16 voltage levels so that is a swing of 0.22V.

    I'm not sure what that really means in terms of speed. there need to be at least 2-4 cycles added to each number for the instructions running. I don't know whether there are additional clock cycles added between the process or and the pins in these modes.



    con
      solid_pin = 56
      DAC_pin = 44
      Comp_pin = 42
      result_pin = 57
      freq = 160_000_000
      mode = $010007f8
      delay_big = freq / 2
      delay_small = 10
    dat
        org
    	
        ' set up clock
        hubset #0
        hubset ##mode  ' initialize oscillator
        waitx ##20_000_000/100 ' wait for it to settle down
        hubset ##mode + %11   ' enable it
        dirh #solid_pin
        dirh #result_pin
        dirh #DAC_pin
    
    	'dac
        wrpin   ##%10110_11110000_10_00000_0,#solid_pin
        wrpin   ##%10110_11110000_10_00000_0,#result_pin
        wrpin   ##%10110_00010000_10_00000_0,#DAC_pin
       
    	'bit compare
        wrpin   ##%1100_000001000_10_00000_0,#Comp_pin
    
        ' now loop forever blinking the pin
        rep @done, #0
    
    
        'drive high
        outh #solid_pin
        outh #DAC_pin
        waitx ##delay_small
        testp #Comp_pin wc
        if_c outh #result_pin
        
        waitx ##delay_big
        
        'Drive low
        outl #solid_pin
        outl #DAC_pin
        waitx ##delay_small
        testp #Comp_pin  wc
        if_nc outl #result_pin
    
        waitx ##delay_big
    
    
    done
    
    
  • evanhevanh Posts: 15,916
    edited 2019-11-21 05:46
    Yeah, it's about 4 sys-clocks each way for I/O. Chip had to keep adding more stages to keep the fast clocking - as he added more features I think. Each new processing unit needs another mux which in turn burdens the propagation times.

    It has quite an impact on external data read overheads, like SPI devices. To get top data rates, you have to lead by a number of clocks before the read data comes back at you.


    PS: And the DAC clocking dynamically adds another stage.

  • evanhevanh Posts: 15,916
    Here's an example snippet of low level bit-bashed SPI clock and data for both writing to and reading from the device. No comments were needed for the send routine but for the read routine I've gone to some trouble to explain to myself why it is like that.
    '------------------------------------------------
    send_byte2
    		shl	pa, #32-7	wc
    		rep	@.loop,#8
    		outc	#spi_di
    		outh	#spi_clk
    		shl	pa, #1		wc
    		outl	#spi_clk
    .loop		
    		ret
    
    '------------------------------------------------
    read_byte4
    		outh	#spi_clk		'OUT takes 4 sysclocks to present to the pin
    		nop
    		outl	#spi_clk		'tells SPI chip to clock the second bit out
    
    		rep	@.loop, #31		'one bit per 8 sysclocks, plenty of leeway to accommodate poor slewing
    		outh	#spi_clk
    		testp	#spi_do		wc	'IN takes another 4 or 5 sysclock to present from the pin
    		outl	#spi_clk		'SPI chip clocks out data on falling edge
    		rcl	pa, #1
    .loop
    		nop
    		testp	#spi_do		wc	'picks up data from OUTL seven instructions prior (14 sysclocks)
    	_ret_	rcl	pa, #1			'  the last OUTL is for first bit of next word, if any
    '------------------------------------------------
    
Sign In or Register to comment.