Shop Learn
PINSTART(PinField, Mode, Xval, Yval) Syntax question — Parallax Forums

PINSTART(PinField, Mode, Xval, Yval) Syntax question

PINSTART performs :
DIR=0, then WRPIN=Mode, WXPIN=Xval, WYPIN=Yval, then DIR=1
if you run the following instead of PINSTART:
What will set DIR = 1 . The following code seems to work, but where is DIR = 1 set? or does it not matter?
Regards and Thanks
Bob (WRD)

  long  ap                                                      ' analog pin
  long  urlo                                                    ' user output range, low
  long  urhi                                                    ' user output range, high
  long  aout                                                    ' analog out value (in user range)
  long  setup                                                  ' true when pin setup
  long codetest                                              ' mode loaded
  _clkfreq = 200_000_000                             ' set system clock
  delay    = _clkfreq / 1_000
  pinfield = 25                                                  'only pin25 set analogout
  mode     = P_DAC_DITHER_PWM | P_DAC_990R_3V | P_OE             '3.3v analog out
  xval     = 256                                                 '256 max unsigned 16 bit $FFFF
  yval     =  0                                                    ' 0  min unsigned 
  analogOutPinP25 = 25  { 0 } 'P25 20k Load Resistor
  analogOutP25_LO =   0    'Lo range analog out                  ' scaled range for pot
  analogOutP25_HI = 3300   'Hi range analog out                  '16 bit dac ou 0-256
  long  analogOutValueP25

PUB main() |t , ReturnHexValueP25
      start(analogOutPinP25,analogOutP25_LO, analogOutP25_HI)  'call analog.start(Pin,lo,Hi)
         repeat analogOutValueP25 from 0 to 3300
             ReturnHexValueP25 := write(analogOutValueP25)     

pub start(pin, lo, hi)
'' Setup pin for analog output
'' -- lo and hi define user range (e.g. 0 and 3300 for millivolts)
  pin &= $3F                                                    ' limit to one pin
  wrpin(pinfield,mode)                                        'anlaog out enabled
  wxpin(pinfield,xval)                                          'max val 256
  wypin(pinfield,yval)                                          'min val 0
  codetest :=   P_DAC_DITHER_PWM | P_DAC_990R_3V | P_OE 
  longmove(@ap, @pin, 3)                                        ' save setup
  setup := true

pub stop()
 '' Disable analog smart pin if previously configured
   if (setup)
     pinclear(ap)                                                 ' disable smart pin
     longfill(@ap, 0, 5)                                         ' mark disabled

pub write(value) : result
 '' Convert value to 16-bit level and write to DAC
'' -- value is in user-defined lo..hi range
   aout := urlo #> value <# urhi                                 ' constrain to user range
   result := (aout - urlo) * $FFFF / (urhi - urlo) + urlo        ' convert to 16-bit dac value
   wypin(ap, result)

pub level() : result
'' Return last user level written to analog output
  return aout


  • evanhevanh Posts: 12,043

    pinl(pinfield) would do it. Another option is inlined assembly.

  • The code I don't believe sets DIR = 1 , but it still outputs the correct analogue out signal as measured by my fluke meter.
    Doesn't really matter but something I noticed.
    Regards and Thanks
    Bob (WRD)

  • roglohrogloh Posts: 3,666
    edited 2021-11-25 03:35

    The P2 documentation snippet below for the DAC PWM smart pin mode mentions that Y[15:0] is still captured even with DIR=0. Presumably this is why it appears to be working even without setting DIR=1 after you initialize this mode. Although the IN pin data bit is not functional in this state, so synchronous updates would not work, only async updates would work when you write the data, which could affect the quality of your dithered DAC output.

    DAC 16-Bit With PWM dither (%00011 and DAC_MODE)

    • Overrides MP[7:0] to feed the pin's 8-bit DAC with PWM-dithered data on every clock. M[12:10] must be set to %101 to configure the low-level pin for DAC output.
    • X[15:0] establishes the sample period in clock cycles. The sample period must be a multiple of 256 (X[7:0]=0), so that an integral number of 256 steps are afforded the PWM, which dithers the DAC between adjacent 8-bit levels.
    • Y[15:0] establishes the DAC output value which gets captured at each sample period and used for its duration.
    • On completion of each sample period, Y[15:0] is captured for the next output value and IN is raised. Therefore, you would coordinate updating Y[15:0] with IN going high.
    • PWM dithering will give better dynamic range than pseudo-random dithering, since a maximum of only two transitions occur for every 256 clocks. This means, though, that a frequency of Fclock/256 will be present in the output at -48dB.
    • If OUT is high, the ADC will be enabled and RDPIN / RQPIN can be used to retrieve the 16-bit ADC accumulation from the last sample period. This can be used to measure loading on the DAC pin.
    • During reset (DIR=0), IN is low and Y[15:0] is captured.
  • evanhevanh Posts: 12,043

    Oh, I misunderstood the question ... The DAC is driven because of P_OE. The smartpin most likely isn't dithering without DIR set. It'll just be outputting the upper 8 bits to the DAC bus.

  • JonnyMacJonnyMac Posts: 7,823
    edited 2021-11-25 04:21

    From the interpreter source:

    ' PINSTART(pins,mode,xval,yval)         (8 longs)
    pins_           setq    #4-1            'pop parameters, including new top of stack
                    rdlong  a,--ptra        'a=top of stack, b=pins, c=mode, d=xval, x=yval
                    fltl    b               'reset smart pin(s)
                    wrpin   c,b             'set smart pin(s) mode
                    wxpin   d,b             'set smart pin(s) x
                    wypin   x,b             'set smart pin(s) y
                    drvl    b               'enable smart pin(s)
            _ret_   mov     x,a             'set top of stack

    As you can see, the pin/pin-group is driven low (output state) which enables the smart pin configured by the pinstart() functions.

    What will set DIR = 1 . The following code seems to work, but where is DIR = 1 set? or does it not matter?

    You can use pinhigh() or pinlow() -- either sets the dection bit(s) to 1. The smart pin(s) will not be enabled until that happens.

Sign In or Register to comment.