292 lines
12 KiB
TeX
292 lines
12 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 due to it's design.It is the cheapest
|
||
|
dual R2R Ladder dac which takes \textbf{PARALLEL} input, which was an important
|
||
|
feature, because the backbone of the project is its parallel bus. Further the
|
||
|
DAC was developed for audio aplications\cite{tlc7528} 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 directl connected to the ATMega without the FIFO infront 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 \ref{fig:tlc7528_saw_nonlin}
|
||
|
was found a lot of effort was put in to determine the source of the heavy noise,
|
||
|
however no obvious conclusion 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 $\not 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 R$ 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 \ref{fig:tlc7528_volt},
|
||
|
with it's voltage source beeing available at either 3.472Vpp for professional
|
||
|
audio or 0.894Vpp 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{NE55 Clock Source}
|
||
|
|
||
|
Though used as a clovk source, the NE555 is a bad clock source if a stable
|
||
|
clock is needed, because it varies widely with temperature, preasure and aging
|
||
|
elements. A better solution would have been a quartz which is divided down to
|
||
|
the desired frequency, whichwas what CD Drives used to do, but more commonly in
|
||
|
modern CD Drives, an ASIC with internal PLL is used, thus the required quartz
|
||
|
can no longer be sourced.
|
||
|
|
||
|
\subsubsection{Demonstration Software}
|
||
|
|
||
|
\paragraph{SAW Generator}
|
||
|
|
||
|
To prove 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 stor and complete write cycle can be seen in figure
|
||
|
\ref{fig:fifo_dac_store}, while the 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} and partially 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}
|
||
|
|
||
|
\section{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.
|