Generating high frequency signal with parallel DAC
WestSideX
Posts: 22
Hello,
Even I use 80 Mhz cpu clock·· I cannot get fast signal at the and of parallel Digital Analog Converter ( DAC0808, which is considered fast 150 ns settling time). [noparse][[/noparse]There is a opamp after DAC]
I just need to generate a triangle signal for testing, I need at least·20-30 KHz, · but I cannot exceed 300 Hz [noparse]:([/noparse]
/\/\/\/\/\/\/\/\/\/\/\/\/\/\
What should be the problem. (If I put waitcnt, It become slower) How can I make it faster?
Thx
here is the part of the code:
· dira[noparse][[/noparse]23..16]~~
· repeat
····· repeat z from Up to Down
······· outa[noparse][[/noparse]23..16]:=z
····· repeat z from·Down to·Up
······· outa[noparse][[/noparse]23..16]:=z
···
Even I use 80 Mhz cpu clock·· I cannot get fast signal at the and of parallel Digital Analog Converter ( DAC0808, which is considered fast 150 ns settling time). [noparse][[/noparse]There is a opamp after DAC]
I just need to generate a triangle signal for testing, I need at least·20-30 KHz, · but I cannot exceed 300 Hz [noparse]:([/noparse]
/\/\/\/\/\/\/\/\/\/\/\/\/\/\
What should be the problem. (If I put waitcnt, It become slower) How can I make it faster?
Thx
here is the part of the code:
· dira[noparse][[/noparse]23..16]~~
· repeat
····· repeat z from Up to Down
······· outa[noparse][[/noparse]23..16]:=z
····· repeat z from·Down to·Up
······· outa[noparse][[/noparse]23..16]:=z
···
Comments
-Phil
To generate a 30Khz triangle wave with 8bit samples you need to send data at 30Khz * 256samples to the DAC, that is 7.68 million samples per second. Since the fastest the Prop will run is 80Mhz and the "average" instruction takes 4 clocks, that means you need an assembly loop with about 2 instructions. The tightest loop is going to have two parts and at least a djnz in there so you're already looking at something less than 15Khz and probably less than 10. Sorry but I don't think that is in the range of what this chip can do. 2 - 3Khz is probably doable.
--Chuck
Thank you, what do you suggest me to use then in order to have some quick replacing?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Propeller Applications Engineer
Parallax, Inc.
Another option is to use an external counter/clock and have the propellor just set the clock divider to pick the freqeuncy. A small CPLD from Altera or Xilinx can do that pretty easily generating the stream of samples you need to feed into the DAC. The easiest interface to the propellor would be a bit wise serial one.
Lastly you could still do this with the propellor but sacrifice some linearity in your wave form. If you only send out 8 values for example for your wave (128, 192, 255, 192, 128, 64, 0, 64) then you only need 30khz * 8 or 240 thousand samples per second. That gives you 333 clocks to play with between samples and should be doable in assembler code. If you put a low pass filter on the output of the DAC you should eliminate much of the quantitization(sp?) noise. If whatever you are driving with the DAC can deal with it that would use the stuff you have on hand.
--Chuck
·
--Chuck
Let me know if you need any further assistance.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Propeller Applications Engineer
Parallax, Inc.
Post Edited (Paul Baker (Parallax)) : 2/4/2008 11:09:06 PM GMT
If you're committed to the propeller I think you either need to use the op-amp technique or go with fewer samples/waveform.
--Chuck
A most trivial problem, solved by many programmers within half an hour - as Chuck says: it is trivial on a DSP. It is also trivial on a Prop!
To stop this nonsense discussion I shall post you the code in a few minutes.... Can't believe this... Sorry.
Edit:
Well it had taken an hour... I dissented to a more general approach
Post Edited (deSilva) : 2/7/2008 6:54:34 AM GMT
This configuration permits any arbitrary waveform to be produced by simply setting the duty cycle of the counter connected to the pin at regular intervals.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Propeller Applications Engineer
Parallax, Inc.
Post Edited (Paul Baker (Parallax)) : 2/4/2008 11:36:25 PM GMT
I like the enthusiasm in this forum. Wondering if you're going to post a solution to generating 30khz triangle waves in general or through an 8 bit parallel DAC ? As Paul points out you can do some stuff with the counters, although I don't believe "delta-sigma" output classifies as "simple" for most people.
I'm guessing your code will set up the CounterA (or module in the cog and use the duty cycle mode to sweep it from 0% to 100% back to 0% etc.
Something I've not read yet in this thread is what the DAC is supposed to be driving. Some inputs won't tolerage a pwm'd signal very well and you'll need to buffer the output with some form of low pass RC filter and an opamp if you don't want the sampling noise to get through. There is also the question of output impedence, although I suspect that anything a DAC output pin can drive (caveat the sampling noise) a propellor pin can drive.
--Chuck
Wondering how effectively one could use a lookup table to generate a sine wave using that, one of the nice things about a DAC is a pretty glitch free change in frequency, although at 20Mhz I suspect you don't see the glitch even if you completely mess up the duty cycle transition and put out a delta T step at 100%.
--Chuck
Edit:
Sorry the SHIFTs had ben wrong in version 0.2
Post Edited (deSilva) : 2/5/2008 1:01:47 AM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Propeller Applications Engineer
Parallax, Inc.
But the loop in your code seems to be this:
It seems to average out to about 200ns per sample sent with some jitter in the output (not that I expect a whole lot of people who weren't looking with a scope would detect that). But it is only hits 20Khz whereas at the start the requirement seemed to be 20 - 30Khz.
I was thinking something similar to your design but feeding the FREQx register rather than OUTA (which with Paul's counter setup to a RC network / Opamp would be generating the signal). But it has the same issues vis-a-vis the ability to adjust the duty cycle dynamically. (at least that is my understanding of the Counter Modules educational app note, but I've only read it once so far and would love to be wrong.) The end of the day seems to be that the Propeller can stuff data into a register at approximately 200 nS per entry, assuming no HUB instructions. So if you wanted another COG to be sending say a new value to the COG doing the stuffing you're stuffing loop is going to get bit by a 22 clock penalty for the RDxxx instruction. (that's 275ns) so with a 212.5 nanosecond loop an adjustable oscillator would be about 500nS (assuming you never missed a beat) which is a bit less than 8Khz.
Now I know this is all arbitrary math (Who said it needs to be 256 samples per waveform for example). I'm trying to get a good feel for the capabilities of the chip and this has been exceptionally useful in that regard. I have a similar challenge on DACs but my frequency requirement is much much lower (60hz is good for example).
Thank you again deSilva for the assembly code, its very instructive.
--Chuck
you are on the right way, and - of course! - what still is missing is the "feeling" for the limits of the Propeller, many of us "Oldtimers" (I am now 6 months with the Prop ) have developed in the meantime...
For more insight I should strongly recommend my "Tutorial", link: ....... which also contains some instructive "side tracks"
In general I should also recommend using SERIAL DAC (be it a low pasor using any of the hundreds of fast serial converter chips.
But as you have noticed it CANNOT be faster than parallel I/O, as shifting out 8 bits will always need 12.5 ns *8 which is the time for 2 instructions, and most likely even 8 instructions.
I not only used 4 instructions. I also carefully arranged them - even beyond the cycle (!) - to avoid any jitter at all! This however had to be done by outputting only 255 rather than the expected 256 samples; and has to compensated for during the creation of the wave table...
There is some nice optimization using the bult-in video logic. It's main advantage is to free the processor during the output of FOUR bytes!
Note that the main reason for my loop unrolling was the limitation of the Propeller to acces bytes in the first place
Using the video logic will allow a loop of this kind:
handling 4 bytes rather than 1 during 200 ns. It will also allow a much simpler more flexible regulation of the frequency!!
So 80 kHz is feasible using a time AND amplitude resolution of 1/256 each!
You rightly remark that the TIME-resolution of 256 was NOT a given requirement. I don't know where it entered here, maybe for the reason that a that this is the only way to utilze the full ramp-up resolution.
Note that the wave table in my example code is not limited to powers of 2 but to multiples of 4.
---
Edit: corrected a stupid twist (ADC/DAC) done late at night
Post Edited (deSilva) : 2/5/2008 10:19:01 AM GMT
Your code doesn't work or I couldn't manage. Also sample on AN001 is only generating high (3.3 V), on oscilloscope no sawtooth.
What I do wrong?
CON _clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
VAR long parameter
PUB go | x
cognew(@entry, @parameter) 'startup DAC cog and point to DAC value
repeat
repeat x from 0 to period 'loop over the entire scale
parameter := $20C49B * x '$1_0000_0000 / period * x <- provides full scale voltage
waitcnt(1000 +cnt) 'wait awhile before changing the value
DAT
org
entry mov dira, diraval 'set APIN to output
mov ctra, ctraval 'establish counter A mode and APIN
mov time, cnt 'record current time
add time, period 'establish next period
:loop rdlong value, par 'get an up to date duty cycle
waitcnt time, period 'wait until next period
mov frqa, value 'update the duty cycle
jmp #:loop 'do it again
diraval long |< 0 'APIN direction
ctraval long %00111 << 26 + 0 'NCO/PWM APIN=0 {BPIN=1} <-not used
period long 2000 '40kHz period (_clkfreq / period)
time res 1
value res 1
Post Edited (stevenmess2004) : 2/5/2008 10:31:11 AM GMT
BTW: For things like PWM start reading my tutorial entry in the wiki,
which contains pointers to more advanved PWM programs...
Steven
@deSilva looks like our posts overlapped.
ist just fine
This is not a very considerate thing to do. Is this the case with code in the tutorials, also? When one is reading forums and there are "examples" of how to do things presented by others who are much more advanced, there is an expectation that what is presented is correct and functional. I, for one, would appreciate it if we could have that same level of confidence on this forum.
As an alternative, to get more frequencies with the single Prop, it is not a big deal to run the phase accumulator in a register instead of in a cog counter, and use all the associated cog counters in duty mode. In that case, the propeller can generate up to 14 different audio frequencies simultaneously (leaving one cog for I/O), having on the outside only the simple RC op-amp filters.
By the way, Chuck, an asm program does not necessarily have to wait 22 clocks for each hub read. A loop with a RDxxxx will lock-step. As you add or subtract instructions in the loop, you will see the timing take big jumps as that lock moves to the next level.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com