374 lines
14 KiB
TeX
374 lines
14 KiB
TeX
\subsection{Audio Digital-Analog-Converter}
|
|
|
|
A digital to analog converter takes a digital number and converts it to a
|
|
analog signal. The output of one such conversion is called a sample. With
|
|
enough samples per second various different waveforms can be produced, which,
|
|
when amplified and put onto a speaker, can be heared by the human ear as a tone.
|
|
With various tones in series a melody can be produced, which is what the DAC in
|
|
this implementation does.
|
|
|
|
\subsubsection{TLC 7528 Dual R2R Ladder DAC}
|
|
|
|
The TLC 7528 is a Dual output parallel input R2R Ladder DAC with a maximum
|
|
sample rate of 10MHz \cite{tlc7528}, and which (should be) is monotonic over the
|
|
entire D/A Conversion Range. The TLC-7528 was the only component chosen, where
|
|
availability was not a factor, but rather it's design. It is the cheapest
|
|
dual R2R Ladder dac which takes \textbf{PARALLEL} input, which is an important
|
|
feature, because the backbone of the project is its parallel bus. Further the
|
|
DAC was developed for audio aplications\cite{tlc7528} which made its use obvious
|
|
and the TLC-7528 was the only IC available as DIP
|
|
\footnote{DIP... Dual Inline Package}, of which the pinout can be seen in Figure
|
|
\ref{fig:tlc7528_pinout}
|
|
|
|
\begin{figure}[H]
|
|
\centering
|
|
\includesvg[height=.3\textheight, angle=0]{pics/slas062e_pinout.svg}
|
|
\caption{TLC-7528 Pinout\cite{tlc7528}}
|
|
\label{fig:tlc7528_pinout}
|
|
\end{figure}
|
|
|
|
\subsubsection{IDT7201 CMOS FIFO Buffer}
|
|
|
|
The IDT7201 is an asychronous CMOS FIFO, which means that it can be read with
|
|
a completely independant speed from which it is written and vice versa. It has
|
|
9 bit words, which can be seen in Figure \ref{fig:idt7201_pinout}, and can
|
|
store up to 256 words\cite{idt7201}. It is used as a buffer
|
|
to store data describing the targeted waveform in order to free time on the
|
|
parallel bus for interaction with the 16550 UART.
|
|
|
|
\begin{figure}[H]
|
|
\centering
|
|
\includesvg[height=.3\textheight, angle=0]{pics/idt7201_pinout.svg}
|
|
\caption{IDT-7201 Pinout\cite{idt7201}}
|
|
\label{fig:idt7201_pinout}
|
|
\end{figure}
|
|
|
|
\subsubsection{Theory verfication}
|
|
|
|
Before tests of the complete unit were conducted, the functionality of the
|
|
device and the validity of the knowledge of operations were performed. For that
|
|
the DAC was directly connected to the ATMega without the FIFO in front of it.
|
|
A saw was generated on only the DACA channel, which was put into voltage mode
|
|
as described in the datasheet\cite{tlc7528} and seen in Figure
|
|
\ref{fig:tlc7528_volt}.
|
|
After the result seen in Figure \ref{fig:tlc7528_saw_nonlin}
|
|
was measured, a lot of effort was put in to determine the source of the heavy
|
|
noise, however no obvious conclusions can be made, execpt that it comes from the
|
|
DAC itself and is consistant over whatever frequency used. A damaged IC could be
|
|
the reason or a sloppy production progress. Filters can be used to reduce the
|
|
noise, however this was not done in this thesis, as the generated audio does
|
|
not seem to suffer from these non-linearities as badly as when measured
|
|
standalone.
|
|
|
|
\begin{figure}[H]
|
|
\centering
|
|
\includesvg[height=.3\textheight, angle=0]{pics/slas062e_volt.svg}
|
|
\caption{TLC-7528 in voltage modet\cite{tlc7528}}
|
|
\label{fig:tlc7528_volt}
|
|
\end{figure}
|
|
|
|
\begin{figure}[H]
|
|
\begin{tikzpicture}
|
|
\begin{axis}[
|
|
ylabel=REFA Voltage,
|
|
xlabel=Time,
|
|
grid=both,
|
|
minor tick num=5,
|
|
xmin=-2.030599999999999e-05,
|
|
xmax=0.000598364,
|
|
width=\textwidth,
|
|
height=0.4\textheight]
|
|
|
|
\addplot table [x=t, y=c1, col sep=comma, mark=none] {meas/20200210_saw_nonlin.csv};
|
|
\end{axis}
|
|
\end{tikzpicture}
|
|
\caption{Measurement of a generated SAW signal via the TLC7528}
|
|
\label{fig:tlc7528_saw_nonlin}
|
|
|
|
\end{figure}
|
|
|
|
\subsubsection{Schematics}
|
|
Based on the descriptions in the datasheets the schematic in figure
|
|
\ref{fig:schem_dac} was developed.
|
|
|
|
\begin{figure}[H]
|
|
\centering
|
|
\includegraphics[height=.65\textheight, angle=-90]{schem_pdf/dac.pdf}
|
|
\caption{The schematic of the DAC Module}
|
|
\label{fig:schem_dac}
|
|
\end{figure}
|
|
|
|
\paragraph{Element Description}
|
|
|
|
Diodes D1 through D4 are used as OR-Gates in conjunction with R1 and R2 to
|
|
generate the $\lnot MODRD$ and $\lnot MODWR$ signals for the D Flip-Flop
|
|
\footnote{74HC374\cite{74hc374}} and FIFO respectively, by these formulas:
|
|
|
|
$\lnot MODRD = \lnot RD \lor \lnot MS2$
|
|
|
|
$\lnot MODWR = \lnot WR \lor \lnot MS2$
|
|
|
|
On a read access the output enable of the D-Latch becomes low, which writes
|
|
the status bits of the FIFO onto the data bus. C1, C2 and C3 are for stability
|
|
reasons and are good practice similar to the UART module. 74HC00 is a quad
|
|
NAND-Gate\cite{74hc00} which is only used for inversion, chosen, like the
|
|
74HC374, for availability reasons. The A part of the NAND-Gate inverts the $MR$
|
|
signal from the bus to a $\lnot MR$ signal, as the FIFOs reset is low active.
|
|
The B part of the NAND-Gate inverts the FIFO Empty flag. It's output is
|
|
connected to the $\lnot WR$ input of the DAC, which means that the DAC doesn't
|
|
convert the input anymore, if the FIFO Empty flag is set to low.
|
|
|
|
The NE555 generates the audio clock signal, which should be the double of
|
|
44.1kHz\footnote{Because we have 2 output channels} as 44.1kHz is the standard
|
|
samling rate of CD-Audio\cite{iec60908}. Resistors R9 and R10 togehter with C7
|
|
form the Oscillator part of the NE55. C4 is for stability reasons and doesn't
|
|
define the frequency of the oscillator.
|
|
|
|
The generated clock is used for the $\lnot RD$ of the FIFO and inverted on the
|
|
DAC, which makes the data available on the output before being stored into the
|
|
DAC as it receives the signal to store the data after the FIFO makes it
|
|
available on the bus.
|
|
|
|
The DAC is operated in voltage mode, as described in Figure \ref{fig:tlc7528_volt},
|
|
with it's voltage source beeing available at either $3.472V_{pp}$ for
|
|
professional
|
|
audio or $0.894V_{pp}$ for consumer audio, as defined per convention.\cite{audiob}
|
|
The voltage source can be controlled via Jumper JP1.
|
|
|
|
C5 and C6 together with the load resistance on the audio jack form a high pass
|
|
with a cutoff frequency of
|
|
|
|
$f_C = \frac{1}{2\pi R C} = \frac{1}{2\times \pi\times 10K\Omega\times 100\mu F} = 0.159154943Hz$
|
|
|
|
which should cover the hearable spectrum. The high pass was needed to generate
|
|
a positive and negative half of the wave form, as the DC-Offset with a frequency
|
|
of 0Hz is orders of magnitudes lower than the $f_C$ of the highpass gets
|
|
filtered away.
|
|
|
|
R7 and R8 have been installed in order to unload the capacitors after device
|
|
poweroff.
|
|
|
|
\paragraph{Functional Description}
|
|
|
|
On a read of the module the $\lnot MS2$ line goes low as well as the $\lnot RD$
|
|
line, which combined by the as OR gate used diodes D1/D2 and resistor R1 forms
|
|
the MODREAD
|
|
signal. The modread signal is passed on to the $\lnot OE$ pin of the D-Flip-Flop
|
|
which writes the FIFO status bits onto the data bus.
|
|
|
|
On write the same or gate is formed with diodes D3/D4 and resistor R2 which
|
|
combines signals $\lnot MS2$ and $\lnot WR$ into MODWRITE. MODWRITE is then fed
|
|
into the $\lnot W$ pin of the FIFO which stores the data on the data bus into
|
|
it's internal buffer.
|
|
|
|
The FIFO is read with the clock generated by the NE555
|
|
(see the NE555 paragraph below) which puts the data onto the bus between FIFO
|
|
and DAC. The DAC reads the data into its internal buffer after the FIFO has put
|
|
it onto the DATA lanes due to the inversion by the B part of the 74HC00 and the
|
|
output beeing mapped to the $\lnot CS$ pin of the DAC. When
|
|
the FIFO is empty it produces nonsense as output, to mittigate errors resulting
|
|
from this the $\lnot EF$ output of the FIFO is inverted by the C part of the
|
|
74HC00 and put onto the $\lnot WR$ pin of the DAC.
|
|
|
|
The maximum amplitude can be selected by jumper JP1. Generated waveforms by the
|
|
DAC are filtered against a DC offset via the highpasses built by C5/R7 and C6/R8
|
|
respectively. The resulting waveform can be measured on audio jack J1.
|
|
|
|
\paragraph{NE55 Clock Source}
|
|
|
|
Though used as a clock source, the NE555 is a bad clock source, if a stable
|
|
frequency is needed, because it varies widely with temperature, preasure and
|
|
ageing
|
|
elements. A better solution would have been a quartz, which is divided down to
|
|
the desired frequency, which was what CD-Drives used to do, but more commonly in
|
|
modern CD Drives, an ASIC
|
|
\footnote{ASIC...Application-specific integrated circuit}
|
|
with an internal PLL is used, thus the required quartz can no longer be sourced
|
|
via conventional electronic resellers.
|
|
|
|
\subsubsection{DAC Module Read}
|
|
|
|
On a read the status bits of the FIFO, which has been latched into the 74HC374
|
|
D-Flip-Flop, are written onto the Data bus. Table \ref{tab:dac_data} defines the
|
|
layout of these status bits on the data bus.
|
|
|
|
\begin{table}[H]
|
|
\centering
|
|
\begin{tabular}{| c | r |}
|
|
\hline
|
|
\textbf{Bit position} & \textbf{Usage}\\
|
|
\hline
|
|
\hline
|
|
0 & FIFO empty flag \\
|
|
\hline
|
|
1 & Not used (originally FIFO low)\\
|
|
\hline
|
|
2 & FIFO half full\\
|
|
\hline
|
|
3 & FIFO full \\
|
|
\hline
|
|
4 & Not used\\
|
|
\hline
|
|
5 & Not used\\
|
|
\hline
|
|
6 & Not used\\
|
|
\hline
|
|
7 & Not used\\
|
|
\hline
|
|
\end{tabular}
|
|
\caption{The layout of the Data Bus on DAC read}
|
|
\label{tab:dac_data}
|
|
\end{table}
|
|
|
|
|
|
\subsubsection{Demonstration Software}
|
|
|
|
\paragraph{SAW Generator}
|
|
|
|
To prove that read and write access from the D Flip-Flop and the FIFO are
|
|
working,
|
|
the same saw signal has been generated as in figure \ref{fig:tlc7528_saw_nonlin}
|
|
, however the signal was put into the FIFO and not the DAC directly. The
|
|
resulting saw wave can be seen in figure \ref{fig:tlc7528_saw_fifo} together
|
|
with the FIFO Empty flag. The FIFO Empty flag, as explained before, is inverted
|
|
and starts/ends the complete D/A conversion, until further data is received.
|
|
|
|
\begin{figure}[H]
|
|
\begin{tikzpicture}
|
|
\begin{axis}[
|
|
ylabel=REFA Voltage,
|
|
xlabel=Time,
|
|
grid=both,
|
|
minor tick num=5,
|
|
xmin=0.02023862769230769,
|
|
xmax=0.02642198769230769,
|
|
width=\textwidth,
|
|
height=0.4\textheight]
|
|
|
|
\addplot table [x=t, y=c1, col sep=comma, mark=none] {meas/20200308fifo_44_1_saw_withfifoempty.csv};
|
|
\addplot table [x=t, y=c2, col sep=comma, mark=none] {meas/20200308fifo_44_1_saw_withfifoempty.csv};
|
|
\legend{REFA,$\lnot EF$}
|
|
\end{axis}
|
|
\end{tikzpicture}
|
|
\caption{Measurement of a generated SAW signal with the FIFO Empty flag}
|
|
\label{fig:tlc7528_saw_fifo}
|
|
|
|
\end{figure}
|
|
|
|
The time difference betwen a store and complete write cycle can be seen in figure
|
|
\ref{fig:fifo_dac_store}, while figure \ref{fig:fifo_dac} shows the
|
|
transmission between dac and fifo in more detail.
|
|
\begin{figure}[H]
|
|
\centering
|
|
\includegraphics[width=\textwidth, angle=0]{meas/20200308fifo_44_1_cnt.png}
|
|
\caption{A transmission between the FIFO and the DAC}
|
|
\label{fig:fifo_dac}
|
|
\end{figure}
|
|
|
|
\begin{figure}[H]
|
|
\centering
|
|
\includegraphics[width=\textwidth, angle=0]{meas/20200308fifo_44_1_saw.png}
|
|
\caption{A fifo store operation in contrast to the load operation}
|
|
\label{fig:fifo_dac_store}
|
|
\end{figure}
|
|
|
|
The initialisation routines and read/write operations for the DAC module are
|
|
basically the same as for the UART module, and have thus been ommitted. They
|
|
can be seen in listing \ref{lst:16550-transmit}.
|
|
|
|
\lstinputlisting[language=C,frame=trBL,
|
|
breaklines=true, breakautoindent=true, formfeed=\newpage,
|
|
label={lst:dac_saw}, caption={SAW Generation for the DAC with FIFO},
|
|
style=cstyle, firstline=134, lastline=144]
|
|
{code/dac/saw_fifo_backplane/src/main.c}
|
|
|
|
|
|
\paragraph{Sine Generator}
|
|
|
|
As a further example a sine was generated and played on the DAC. The ATMega
|
|
itself is not powerful enough to generate the sine on the fly, therefore a
|
|
lookup-table had to be generated, which can be seen in listing
|
|
\ref{lst:dac_sine_lut}. How the data is transmitted to the FIFO can be seen
|
|
in listing \ref{lst:dac_sine} and figure \ref{fig:fifo_sine_store}, and the
|
|
resulting sine on both output channels can be seen in figure
|
|
\ref{fig:sine_dacab}.
|
|
|
|
\lstinputlisting[language=C,frame=trBL,
|
|
breaklines=true, breakautoindent=true, formfeed=\newpage,
|
|
label={lst:dac_sine_lut}, caption={Sine LUT Generation},
|
|
style=cstyle, firstline=118, lastline=123]
|
|
{code/dac/sine_fifo_backplane/src/main.c}
|
|
|
|
The look-up table has a size of 256, which is the maximum value an 8 bit integer
|
|
can take. This size was chosen to make operation faster as it only takes
|
|
one cycle to load an array value into a register and another one to store it
|
|
into the GPIO register. The sine table in further examples was pre-genrated on
|
|
the compiling host to reduce startup time. The mothod shown in listing
|
|
\ref{lst:dac_sine_lut} is not fast due to the lack of a floating point unit
|
|
on the AVR. \cite{atmega2560}
|
|
|
|
\lstinputlisting[language=C,frame=trBL,
|
|
breaklines=true, breakautoindent=true, formfeed=\newpage,
|
|
label={lst:dac_sine}, caption={DAC Sine Generation},
|
|
style=cstyle, firstline=141, lastline=152]
|
|
{code/dac/sine_fifo_backplane/src/main.c}
|
|
|
|
\begin{figure}[H]
|
|
\centering
|
|
\includegraphics[width=\textwidth, angle=0]{meas/20200310sine_dac.png}
|
|
\caption{Storage and retrieval of a sine to and from the FIFO}
|
|
\label{fig:fifo_sine_store}
|
|
\end{figure}
|
|
|
|
\begin{figure}[H]
|
|
\begin{tikzpicture}
|
|
\begin{axis}[
|
|
ylabel=Channel Voltage,
|
|
xlabel=Time,
|
|
grid=both,
|
|
minor tick num=5,
|
|
xmin=-0.001746707777777778,
|
|
xmax=0.001774992222222222,
|
|
width=\textwidth,
|
|
height=0.4\textheight]
|
|
|
|
\addplot table [x=t, y=c1, col sep=comma, mark=none] {meas/20200310sine_dac_osz.csv};
|
|
\addplot table [x=t, y=c2, col sep=comma, mark=none] {meas/20200310sine_dac_osz.csv};
|
|
\legend{DACA,DACB}
|
|
\end{axis}
|
|
\end{tikzpicture}
|
|
\caption{Measuremet of the generated sine from the sine LUT on DACA and DACB}
|
|
\label{fig:sine_dacab}
|
|
|
|
\end{figure}
|
|
|
|
\subsubsection{Addressing DACA and DACB}
|
|
|
|
The DAC used has 2 output channels which can be selected by the
|
|
$\lnot DACA/DACB$ pin as seen in figure \ref{fig:tlc7528_pinout}. This pin was
|
|
mapped to bit 0 of the address bus in order to make use of it. Bit 8 on the fifo
|
|
was used to store the bit. It was not implemented with half the bus clock to
|
|
make both channels independent of each other. This however uses more time on the
|
|
backend because it means the fifo is used up at twice the speed. No current
|
|
example makes use of this, but it may be used in future examples and
|
|
implementations on this unit.
|
|
|
|
On the audio jack DACA is mapped to the right channel and DACB to the left
|
|
channel.
|
|
|
|
\subsubsection{Final Module}
|
|
|
|
The final module can be seen in figure \ref{fig:dac_mod} with, from bottom to
|
|
top, the 74HC374 D-Flip-Flop, the IDT-7201 FIFO, the 74HC00 NAND-Gates, the
|
|
TLC-7528 DAC and the NE555 oszillator. The jumper on the left is the voltage
|
|
select and the jumper on the right the clock select. The two pin headers on the
|
|
top have been installed for voltage measurement on the left and right audio
|
|
channels while the audio jack is in use.
|
|
|
|
\begin{figure}[H]
|
|
\centering
|
|
\includegraphics[width=\textwidth, angle=90]{pics/dac}
|
|
\caption{The final DAC module}
|
|
\label{fig:dac_mod}
|
|
\end{figure}
|
|
|