Shop OBEX P1 Docs P2 Docs Learn Events
DAC — Parallax Forums

DAC

Robert  HumistonRobert Humiston Posts: 8
edited 2006-12-05 05:00 in Propeller 1
I have tried to dicpher how the DAC should work but cannot glean any understanding of how to use the cog counters.
I was hoping to use the propeller as a basic function genrate and Frequency counter. This serves two goals. One to learn more about frequency synthesis and how to use the propeller to do this and to create a fairly afforfdable bench tool.
I have seen dom axamples on the forum but they neither explain the use of the cog counters nor the DAC functionaliy. I small code examples would be nice, as i am trying to learn both the propeller and frequency synthesis.

Thank you in advance for support

Comments

  • Paul BakerPaul Baker Posts: 6,351
    edited 2006-11-16 22:45
    Like this thread: http://forums.parallax.com/showthread.php?p=615257·?

    The documentation for the Propeller Counters will be released shortly (it's complete, we are testing and verifying the posting system for Propeller Application Notes). It includes examples of a frequency counter, ADC, Sawtooth waveform generation (any waveform can be generated by setting the values according to the function), and other applications.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.
  • AndreLAndreL Posts: 1,004
    edited 2006-11-16 22:49
    The new HYDRA book also has a very extensive coverage of the counters used for PWM D/A use for sound and general sound synthesis with examples. We wrote an entire ADSR engine with 9-11 channels with mixing, which is basically a bunch of software DACs using PWM and 1-bit output to generate the final output. Both PWM theory and the props counters are described to do the PWM D/A in a couple different methods.

    Andre'
  • Robert  HumistonRobert Humiston Posts: 8
    edited 2006-11-17 01:39
    Yes Paul I had reviewed the thread and several of the ideas were interesting. I am aware of PWM but without being familiar with assembly it seems that spin would limit the usable frequency range. Plus I would really like to explore the limits of the propeller.
  • Paul BakerPaul Baker Posts: 6,351
    edited 2006-11-17 02:22
    The code within the ApNote is assembly, I can post the program tomorrow. There are pros and cons of using Duty Cycle and PWM, PWM has a massive fundamental frequency which isn't eliminated with a single pole filter while Duty Cycle produces quantization noise. If you're going for audio, PWM with the fundamental beyond 20kHz is the way to go, otherwise Duty Cycle should be used.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.

    Post Edited (Paul Baker (Parallax)) : 11/17/2006 2:26:59 AM GMT
  • Paul BakerPaul Baker Posts: 6,351
    edited 2006-11-17 21:16
    Here is the program which demonstrates duty cycle as I promised. It outputs a sawtooth wave, but this can be changed to any function.


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.
  • Robert  HumistonRobert Humiston Posts: 8
    edited 2006-11-19 00:15
    Thanks for the asisstance. PWM and Duty Cycle I understand and after reviewing the code for scaling duty I think I have a better grasp. Knowing that pin A is the bit 31 of the PHSA brought some clarity. FreqA is added every cycle to make bit 31 turn on at the desired frequency. So if FREQA is A would go high once cycle per 2^32 cycles is this a correct assesment? Atleat in NCO mode
  • Paul BakerPaul Baker Posts: 6,351
    edited 2006-11-19 00:40
    For NCO/PWM, the PHSA[noparse][[/noparse]31] is the output to APIN, to generate PWM, you set FRQA to 1 and set PHSA to -duty using "neg phsa, duty" where duty is the fractional part of the period in which the signal is high. Since you have set PHSA to be 2^32-duty, it will transition from 1 to 0 exactly duty cycles later, you establish the period by doing a waitcnt "period cycles long" and reset the PHSA.

    For Duty Cycle, the carry output of PHSA is the ouput to APIN. This is like a memoryless PHS[noparse][[/noparse]32], or what that bit would contain if it existed, and then was reset back to zero the next clock cycle. To use it, you simply set FRQA equal to the fractional amount you want or 3.3V x duty/2^32. This is a set it and forget it type operation, once you establish the duty cycle, the couter will continue to output the correct amount of pulses to generate the analog voltage without any program intervention nessesary.

    Also Duty cycle provides twice as many levels of output than PWM can, and several orders of magnitude in practice, this is because to obtain the full precision possible for PWM the period must be ~54 seconds long, this is way too low of a fundamental frequency to be smoothed out by a single pole low pass filter and still have a rapid response to changes in ouput. Duty cycle takes the same total of high to low pulses as output by PWM but does a "shuffle the deck" way of outputting the pulses so high pulses are intermixed with low pulses. With PWM all the high pulses are stacked on one side of the period and all the low pulses are stacked on the other side of the period.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.

    Post Edited (Paul Baker (Parallax)) : 11/19/2006 12:44:32 AM GMT
  • Robert  HumistonRobert Humiston Posts: 8
    edited 2006-11-21 17:48
    Looking at your ScalingDuty(DAC).spin a CTR mode 00111 is Duty cycle diferential but comment is NCO/PWM. I assume the differential portion means that "shuffle the deck" way of outputting the pulses so high pulses are intermixed with low pulse. I understand that and the voltage output is determined by FRQA = 3.3V x duty/2^32. So is Duty 0 to 100 as an integer or is it 0 to 1.00 as floating or something else? My ultimate goal is to generate a Sine wave. The primary use for this would be Audio but I would like to see how high a frequency I can generate. I appreciate you guidance and wisdom so far.
  • Robert  HumistonRobert Humiston Posts: 8
    edited 2006-11-23 08:11
    I have gotten this far. My questions now are :
    1) how to get sine value and multipy to get duty realize have tow use offset 1.15V and flip values to get full 360 wave
    2) In scalingduty.spin how does period in assembly work

    Here is my code thus far:

    {{ Demonstration of scaling Duty Cycle
    10kΩ
    APIN ─┳── Out

    .1µF

    Delta modulation has no fundamental freq but has quantization noise
    }}
    CON _clkmode = xtal1 + pll16x
    _xinfreq = 5_000_000

    VAR long parameter
    long period

    PUB SquareWave freqSynth bitDepth | x levelInc
    parameter := 0
    period := clkfreq / freqSynth
    cognew(@entry, @parameter)
    repeat
    time2 := cnt
    levelInc = $1_0000_0000 / bitDepth
    repeat x from 0 to bitDepth -1
    parameter := levelInc * x
    waitcnt(time += period/bitdepth)

    PUB triangleWave freqSynth bitDepth | x levelInc
    parameter := 0
    period := clkfreq / freqSynth
    cognew(@entry, @parameter)
    repeat
    time2 := cnt
    levelInc = $1_0000_0000 / bitDepth
    repeat x from 0 to bitDepth -1
    parameter := levelInc * x
    waitcnt(time2 += period/2/bitdepth )
    repeat x from bitDepth -1 to 0
    parameter := levelInc * x
    waitcnt(time2 += period/2/bitdepth )

    PUB sineWave frequency | x
    parameter = 0
    cognew(@entry, @parameter)
    repeat
    time2 := cnt
    repeat x from 0 to 90
    parameter := $8000_0000 + $8000_000 * sine value x
    waitcnt (time2 += period/360)
    '' need to repeat for quadrants 2-4

    DAT
    org

    entry mov dira, diraval
    mov ctra, ctraval

    mov time, cnt
    add time, period

    :loop rdlong value, par
    waitcnt time, period
    mov frqa, value
    jmp #:loop

    diraval long |< 1 + |< 0
    ctraval long %00111 << 26 + 1<<9 + 0 'NCO/PWM APIN=0 BPIN=1
    time res 1
    value res 1[noparse][[/noparse]code]
    once again thank you
  • Paul BakerPaul Baker Posts: 6,351
    edited 2006-11-28 18:39
    Sorry it took me so long to respond, I was away on vacation. You are correct the comment should say Duty Cycle.
    The way you have written your code, period wont work correctly, you need to place it in your RES space in your assembly code. Also you need to set it's value before starting the cog for your SineWave.

    Don't confuse period with your oscillating frequency, they are different. Period is the granularity in which the output value is updated, you can think of this as the sample rate of your generated waveform, or the time base along the X axis. It's parameter which sets the value generated, or the value along the Y-axis, this value is 3.3 x parameter/period.

    The assembly code on page 423 shows how to obtain the sine of a value, you would need to scale this then add an offset to obtain the final value proivided to the parameter.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2006-11-29 01:53
    Robert, you asked about how to "how to get sine value and multipy to get duty".

    You can get the sine value from the table in the HUB. There is no need to multiply until you need fine control of the amplitude of your sine wave. You can get a full amplitude sine wave (+/- 1.65 volts, 3.3 volts peak to peak), with a simple shift operation.

    The command to get the sine from the Hub is of the form,
    result := word[noparse][[/noparse]$E000 + y]
    where y is a variable (11 bits) that holds the phase from 0 to 90 degrees. The sine table consists of 2k word addresses that go from $E000 to $F001, and that represents angles from 0 to 90 degrees as a sixteen bit number (result).

    I'm not sure if you have seen this example, in the tutorials section, but it goes into detail about how to make a sine wave using the cog counters and the hub sine table in both spin and assembly:

    http://forums.parallax.com/showthread.php?p=606978

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • GavinGavin Posts: 134
    edited 2006-11-29 02:06
    I needed a frequency generator for tuning a RFID coil yesterday.
    Took a few miutes to make a cable and then prop was making waves.

    It could make a nice little bench tool, add a LCD for frequency generation and counting.
    Looking for a nice case to put it in with room for logic analyser cable connector.
    Hmm graphical LCD? no just use VGA, make a nice storage cro? Fast A/D?
    Every day I see more and more how useful this thing is.
  • Robert  HumistonRobert Humiston Posts: 8
    edited 2006-11-30 05:04
    Using Tracy Allens sinewave3.spin I have a usable sine generator. Thank you. Spin implementatiions were to slow.
    Two questions. I realize that afreq = Fout / clockfreq * 2^32 but how does one realize this equation using the propeller. The Goal is to be able to input a frequency with the keyboard and generate it.
    The second part of my application is to measure the frequency ouput can tsine waves be measured without some form wave-shaping.

    Thanks I really appreciate your support.
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2006-11-30 05:36
    Hi Robert,

    The frqa value can be computed using the following routines in spin or asm. Enter with
    a=Fout, your desired output frequency
    b=clkfreq, your Prop clock frequency
    bits=32.
    The result f is the required value of frqa.

    ' spin:
    ' enter with a and b: a < b, a < 2^31, b <= 2^31
    ' exit with f: f/2^32 = a/b
    ' if different number of bits, then f: f/(2^n) = a/b
    PRI frqVal(a, b, bits) : f            ' calculate a/b * 2^bits
      repeat bits                      'calculate f: a/b = f/(2^32)
        a <<= 1
        f <<= 1
        if a => b    '     
          a -= b
          f++ 
    
    




    ' pasm:
    ' enter with a and b: a < b, a < 2^31, b <= 2^31
    ' exit with f: f/2^32 = a/b
    ' if different number of bits, then f: f/(2^n) = a/b
    
    ratiox
        mov t,#32    ' number of bits
    ratioy            ' enter here for other than 32 bits
        mov f,#0    ' frequency parameter
    :loop
        shl a,#1        ' double the value of a
        shl f,#1        ' double the estimate of f, appoximation f/(2^t) =~ a/b
        cmpsub a, b     ' if a>=b then a:=a-b, carry:=1, else a unchanged, carry:=0
        addx f,#0        ' add carry to f
        djnz t,#:loop    ' do all bits
    ratiox_ret    ret
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com

    Post Edited (Tracy Allen) : 11/30/2006 5:41:06 AM GMT
  • Robert  HumistonRobert Humiston Posts: 8
    edited 2006-12-05 05:00
    Thanks everyone for the help.
    Now to return the favor.
    Here is a complete and working App
    This app uses Keyboard TV and jumper from pin·0 to 5

    Post Edited (Robert Humiston) : 12/6/2006 4:24:30 PM GMT
Sign In or Register to comment.