Shop Learn
Smart-Pin DAC with Noise — Parallax Forums

Smart-Pin DAC with Noise

For several hours I have tried and failed (see code below) to get a Smart-Pin to produce what I think it should in the DAC_MODE = DAC Noise setting. Documentation doesn't include an example, and most of the Forum comments haven't helped. I assume I should see random voltages on my scope, but all I see is a short logic-0 pulse on the P20 output when the program starts. I'm revising the SMART PIN section of the v33 documentation, but it's difficult without an assembly-language program I can use as an example, test on my P2 board, and explain. I welcome a working example with comments. It will help others, too. Thanks. --Jon
CON            
    freq    = 160_000_000
dat
	org	0       
       dirl     #20			'Set DAC at Smart-Pin P20
       wrpin    DACconfig,    #20
	nop
       wxpin    DACperiod,    #20
       nop
       wypin    DACvolt,      #20
       dirh     #20

.myloop	nop
	jmp	#.myloop

DACconfig	long	%0000_0000_000_10100_00000000_01_00010_0     'Random dither
'DACconfig	long	%0000_0000_000_10100_00000000_01_00011_0     'PWM dither
DACperiod 	long 	$0000_0000_0000_0000     ' X15:X0, no period?                      
DACvolt 	long	$0000_0000_0000_FF00	 ' Bits Y15:Y0, voltage?  How set?

Comments

  • If you want random noise on the DAC, you'd need to use
    DACconfig	long	%0000_0000_000_10100_00000000_01_00001_0     'Random noise
    
    I think.
  • AribaAriba Posts: 2,470
    If you want to use the dithered DAC modes to output a random voltage, you need to write random values in a loop. Your code just outputs the same value forever. I think your code does not work because you can't have a period of 0, use min. 1 for noise dither or 256 for pwm dither.

    Here is an (untested) example for 16bit random output:
    dat
    	  org       
              dirl    #20			'Set DAC at Smart-Pin P20
              wrpin   DACconfig,  #20
              wxpin   DACperiod,  #20
              dirh    #20
           
    
    .myloop	  wypin   DACvolt,    #20       'write 16bit DAC value
              getrnd  DACvolt               'new random value
              and     DACvolt,    ##$FFFF   'mask lower 16 bits
    .waitper  testp   #20         wc        'wait for IN raise (period end)
       if_nc  jmp     #.waitper             'rate=clkfreq/256 ~ 78kHz
    	  jmp	  #.myloop
    
    DACconfig	long	%0000_0000_000_10100_00000000_01_00010_0     'Random dither
    'DACconfig	long	%0000_0000_000_10100_00000000_01_00011_0     'PWM dither
    DACperiod 	long 	256                   
    DACvolt 	long	$8000           'initial value (middle)
    
    Andy
  • Good insight. Thanks, I'll try it. I thought the random noise got taken care of automatically as part of the Smart-Pin circuit. --Jon
  • AribaAriba Posts: 2,470
    Yes, if you use the mode that Wuerfel_21 suggested. But then you need no DACvolt register, the DAC value is anyway automatically overwritten with a random 8 bit value.
  • That works! I appreciate your help. --Jon
  • Ariba and all - How would I write the code snippet to output just a single continuous (sine or square wave) frequency?
  • evanhevanh Posts: 10,929
    edited 2020-05-15 06:05
    Square wave can be done as a smartpin counter mode, eg:
    con
    	XTALFREQ	= 20_000_000				'PLL stage 0: crystal frequency
    	XDIV		= 1					'PLL stage 1: crystal divider (1..64)
    	XMUL		= 8					'PLL stage 2: crystal / div * mul (1..1024)
    	XDIVP		= 2					'PLL stage 3: crystal / div * mul / divp (1,2,4,6..30)
    
    ' Clock modes: %0000_000e_dddddd_mmmmmmmmmm_pppp_cc_ss
    	XOSC		= %10				' OSC    ' %00=OFF, %01=OSC, %10=15pF, %11=30pF
    	XSEL		= %11				' XI+PLL ' %00=rcfast(20+MHz), %01=rcslow(~20KHz), %10=XI(5ms), %11=XI+PLL(10ms)
    	XPPPP		= ((XDIVP>>1) + 15) & $F	' 1->15, 2->0, 4->1, 6->2...30->14
    	CLOCKFREQ	= round(float(XTALFREQ) / float(XDIV) * float(XMUL) / float(XDIVP))
    	CLK_MODE	= 1<<24 | (XDIV-1)<<18 | (XMUL-1)<<8 | XPPPP<<4 | XOSC<<2
    
    
    	SP_OUT		= (%1 << 6)			' enable digital output when DIR operates smartpin
    	SPM_NCO_FREQ	= %00110_0 |SP_OUT		' NCO frequency, X[15:0] = base period, Z += Y, OUT = Z[31]
    
    
    
    dat		org
    
    'Use accurate crystal oscillator and PLL instead of RCFAST
    		hubset	#$f0			'Safe RCFAST
    		hubset	##CLK_MODE		'Power up external 20 MHz crystal and PLL
    		waitx	##25_000_000/100	'10 ms pause for stablising
    		hubset	##CLK_MODE | XSEL	'switch over to PLL as system clock source
    
    'Set frequency output at Smart-Pin P20
    		dirl	#20
    		wrpin	##SPM_NCO_FREQ, #20
    		wxpin	FRQperiod, #20
    		wypin	FRQphase, #20
    		dirh    #20
    
    'Twiddle thumbs while smartpin does job
    		jmp	#$
    
    
    
    FRQphase 	long	$8000_0000		'32-bit fraction of oscillation
    FRQperiod 	long	1000			'Sysclocks per fraction
    
  • AribaAriba Posts: 2,470
    PropGuy2 wrote: »
    Ariba and all - How would I write the code snippet to output just a single continuous (sine or square wave) frequency?

    Here is a little Spin2 code, that outputs a sine wave with a 16bit DAC. It works with Fastspin and with PNUT.
      _clkfreq = 180_000_000
      smprate  = 44100
      sinfreq  = 1000
      dacpin   = 39
    
    pub sine_out() | smp, phs
      pinstart(dacpin, P_DAC_DITHER_RND | P_DAC_600R_2V | P_OE, clkfreq/smprate, 0)  'smartDAC
      repeat
         _,smp := polxy($7FFF, phs)      'cordic sine function
         wypin(dacpin, smp+$8000)        'write sine sample to dac
         phs += sinfreq FRAC smprate     'step angle for sine freq
         repeat until pinread(dacpin)    'wait for dac sample period
    
    Andy
  • cgraceycgracey Posts: 13,587
    To get high-bandwidth sine output, ir's best to use DDS mode in the streamer. It's hands-free that way and you can change the frequency whenever you want.
  • RaymanRayman Posts: 11,974

    If I'm seeing it right, DDS mode is 8-bit DAC output, whereas the smartpin mode above is 8-bit "real" plus 8-bit dither.
    I'd guess that at audio frequencies the smartpin mode would be a lot better...

  • cgraceycgracey Posts: 13,587

    @Rayman said:
    If I'm seeing it right, DDS mode is 8-bit DAC output, whereas the smartpin mode above is 8-bit "real" plus 8-bit dither.
    I'd guess that at audio frequencies the smartpin mode would be a lot better...

    I agree.

Sign In or Register to comment.