<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv=Content-Type content="text/html; charset=us-ascii">
<meta name=Generator content="Microsoft Word 11 (filtered medium)">
<style>
<!--
/* Font Definitions */
@font-face
{font-family:"MS Mincho";
panose-1:2 2 6 9 4 2 5 8 3 4;}
@font-face
{font-family:"\@MS Mincho";
panose-1:2 2 6 9 4 2 5 8 3 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:12.0pt;
font-family:"Times New Roman";}
a:link, span.MsoHyperlink
{color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{color:purple;
text-decoration:underline;}
span.EmailStyle17
{mso-style-type:personal-compose;
font-family:Arial;
color:windowtext;}
@page Section1
{size:8.5in 11.0in;
margin:1.0in 1.25in 1.0in 1.25in;}
div.Section1
{page:Section1;}
-->
</style>
</head>
<body lang=EN-US link=blue vlink=purple>
<div class=Section1>
<p class=MsoNormal><font size=2 face=Arial><span lang=SV style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span lang=SV style='font-size:10.0pt;
font-family:Arial'>Hello All!<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span lang=SV style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>I have developed my saw DCO since last time, I will now describe
the design in more detail. <o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>Those of you who still remember the last report can skip to
[NEW].<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>First, the DCO uses the CCP1 and TMR1 of a PIC18. The
special event trigger in the CCP (capture-compare) module clears the TMR1 registers
and sets the interrupt flag when the timer TMR1 reaches a value written into
the CCP1 control registers. Effectively, you write a cycle length into the CCP1
and then get interrupts with high precision (1-cycle or 100ns glitches). The
interrupt handler (ISR) toggles a bit for a square/pulse wave or resets a ramp
generator for a saw wave. If you want different pulse widths, just use two
different periods. <o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>The ramp generator itself has not changed, it looks like
this: <a href="http://www.minod.com/saw_generator.gif">http://www.minod.com/saw_generator.gif</a><o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>The PIC18 derivative I use (PIC18F2320) has a built in
comparator which also triggers an interrupt to reset the ramp. Thus, by
increasing the ramp slope, I get hard synch sounds, since the ramp is reset
both at the timer (pitch) rate and when it reaches the maximum. <o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>The only trouble is to set the correct control voltage to
get the right current for charging the ramp capacitor. The CA3080 control input
is just a transistor base, and the voltage to current conversion is exponential.
The control voltage is thus A) highly temperature dependant as we all know, and
B) depends on the reference voltage to the DAC, the power supply in this case,
and C) also on component tolerances. <o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>[NEW]<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>Last night I implemented an auto-calibration procedure that
makes me kind of proud: Using the timer and comparator interrupts in the
bisection method, a high precision calibration is possible. (Those of you who
know the bisection method can skip the next paragraph)<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>It works like this: Initially, the “possible” range
is [0,65535] (16-bit DAC), and the initial guess is the mid point x in that
interval, that is 32767 (or 2.500 volts if you wish). Now, the ramp and timer
are started simultaneously, and which interrupt comes first determines the next
test value. If the timer is first, the ramp is too slow, and the lower interval
bound is updated to the test point, otherwise, the high side is updated. So the
possible next intervals are [32767,65535] or [0,32767]. The next guess is
computed as the midpoint in the interval and the sequence is repeated until x doesn’t
move. <o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>I get very high precision with this method. Calibration
points are taken once every octave, and then they are interpolated with a
second degree polynomial. The whole calibration procedure (9 points) takes just
over a second. The resulting saw amplitude is perfectly constant over the 20Hz to
5kHz range. It is adjusted for the current temperature, supply voltage and component
tolerances. <o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>The code necessary for the calibration routine was about 150
instructions of which 60 was freed up initialization data, so it wasn’t
too expensive. <o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>BTW, I also tested synthetic jitter to simulate vintage
machines. It sounded like sh*t. At large amounts it was a bit cool, like
DX7-ish, but the idea I had about ‘subliminal jitter’ making the
tone ‘warm’ and ‘analog’ or even ‘natural’ did
not work. It sounds like a beginner at the fiddle. IF you know what I mean. <o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>Fredrik C<o:p></o:p></span></font></p>
</div>
</body>
</html>