Smart Pin DAC
John Abshier
Posts: 1,116
in Propeller 2
CON
oscmode = $010c3f04 'standard stuff
freq = 160_000_000
pub main | pMode, outVal, period, thePin
clkset(oscmode, freq)
thePin := 41
pMode := %0000_0000_000_10100_00000000_01_00010_0 'Random dither
' pMode := %0000_0000_000_10100_00000000_01_00011_0 'PWM dither
period := 32768
outVal := 16384
asm
dirl thePin
wrpin pMode, thePin
wxpin period, thePin
wypin outVal, thePin
dirh thePin
endasm
repeat
I have tried various values of period and outVal but my Propscope fails to trigger. If I turn the trigger off the Propscope measures -9 to 19 mVolts. I tried a simple program to toggle the pin at 1000 hz and the Propscope picked it up fine. I don't know what I am missing.
John Abshier

Comments
You need immediate values since period and outVal etc are global variables only. (I think)
This is a simple DAC function in TAQOZ.
So the first line is equivalent to WYPIN ##%101_000_0000000_01_00011,#thePin and also WXPIN ##1<<12,#thePin.
Setup:
To set pin to 1.850V
dirl #thePin wrpin ##pMode, #thePin wxpin ##period, #thePin wypin ##outVal, #thePin dirh #thePinNo, that's not it: pMode, period, outVal, and thePin are all variables, i.e. registers, so putting "#" in front of them will definitely not do what you want -- it'll cause the address of the variables to be used rather than their values.
I don't know off-hand what's wrong, and don't have my P2 handy, but the values for period and outVal look wrong to me. I think generally there should be something in the upper 16 bits, but the sample code above has 0 there.
I will be out of town the next 2 1/2 days and unable to test but will follow the forum.
John Abshier
CON oscmode = $010c3f04 'standard stuff freq = 160_000_000 pub main | pMode, outVal, period, thePin clkset(oscmode, freq) thePin := 41 ' AAAA BBBB FFF PPPPP PPPPPPPP TT MMMMM pMode := %0000_0000_000_10100_01000000_00_00000_0 asm dirl thePin wrpin pMode, thePin dirh thePin endasm repeat { dirb[thePin] := 1 ' code to test Propscope comment out the above assymbler code !outb[thePin] waitcnt(cnt + clkfreq / 1_000_000)}John Abshier
Read the section in the doco about these modes when using the DAC.
John Abshier
The ORGH should be ORGH $400.
registers and may give them alternate uses. Both dithered DAC modes are smartpin modes.
Raw DAC mode (not dithered) is not a smartpin mode so will require DIRH as I understand it. The MMMMM
bits have to be non-zero for smartpin operation.
I think that's right. Certainly my code using dither modes doesn't touch DIRx or OUTx
John Abshier
Mark might be correct when using %TT = 01. This basically forces DIRH for that pin. When in a DAC mode the OUT becomes an ADC enable.
Err, reading the docs, %TT = 01 in DAC mode means config for SETDACS operation:
And some additional info from the pad_io_modes
con pin = 56 freq = 160_000_000 mode = $010c3f04 delay = freq / 100000 prng = %0000_0000_000_10100_00000000_01_00001_0 dither = %0000_0000_000_10100_00000000_01_00010_0 ' remember to wypin dither_pwm = %0000_0000_000_10100_00000000_01_00011_0 ' remember to wypin dac = %0000_0000_000_10100_00000000_00_00000_0 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 mov val, #0 wrpin ##dither_pwm, #48 wxpin #0, #48 ' now loop forever blinking the pin rep @done, #0 drvnot #pin waitx ##delay add val, #1 and val, #$FF mov t, val xor t, #$E7 shl t, #8 wypin t, #48 done val long 0 t long 0An old test file, the loop is generating a somewhat random step function using add, xor I think, in pwm dither mode
(I think the wxpin is unnecessary)
mov val, #128 '#0 ****************** wrpin ##dither_pwm, #48 wxpin #0, #48 ' now loop forever blinking the pin rep @done, #0 drvnot #pin waitx ##delay ' add val, #1 ********************* ' and val, #$FF ********************* mov t, val ' xor t, #$E7 ********************* ' shl t, #8 ********************* wypin t, #48 doneJohn Abshier
For what you want, just set WRPIN to set the static DAC level. wypin isn't required and may be causing issues
in the code above 'j' is the static level 0 to 255
pinmode starts as
Note that if you output 128 you'll get around 1.65 or 1.0 volts depending on which dac you're using
Full working code we used for stepping through multiple dacs and every pin attached. The pulsevm sends a pulse to the multimeter to take a reading
John Abshier
Were you calling that pasm repeatedly on a tight loop? Or just once (just once should be fine)
Sounds like a worthy project, hope the remainder goes smoothly
I thought the looping/stepping nature was obvious and wouldn't cause confusion. John even correctly described it and identified a bug I had.
The way to make the OUT bit control the DAC level is to use what's called BIT_DAC mode. I'm guessing you may have accidentally done this already. There is mention of this in the main doc and here's the pad_io_modes write up continuing from earlier posting. Full write up - https://forums.parallax.com/discussion/comment/1452036/#Comment_1452036
An example would be: