% \node [below, align=center] at (\x, 0) {RO \\ 0};
}
\newcommand{\bitlabels}[2]{
\foreach\bit in {1,...,#1}{
\pgfmathsetmacro\result{#2}
\node [above] at (\bit-0.5, 1) {\pgfmathprintnumber{\result}};
}
}
\begin{document}
\section{Digital Interface}
\begin{center}
\begin{tabular}{ c|c|c }
Pin & Direction & Function\\
\hline
SCK & in & SCK for SPI communication/SCK for PLL communication\\
MOSI & in & MOSI for SPI communication/MOSI for PLL communication\\
MISO & out & MISO for SPI communication/MUX for PLL communication\\
NSS & in & Chip Select for SPI communication/LE for PLL communication\\
INTR & out & Active high interrupt indicator\\
RESET & in & FPGA reset\\
AUX1 & in & Selector for direct communication with Source PLL\\
AUX2 & in & Selector for direct communication with LO PLL\\
AUX3 & in & Active low sweep enable. Has to be high when changing settings\\
\end{tabular}
\end{center}
Depending on the voltage on AUX1/AUX2 the SPI port controls either the FPGA or one of the MAX2871 PLLs:
\begin{center}
\begin{tabular}{ c|c|c }
AUX1 & AUX2 & Function\\
\hline
low & low & SPI communication with FPGA\\
high & low & Direct feedthrough of SCK, MOSI, MISO and NSS to Source PLL\\
low & high & Direct feedthrough of SCK, MOSI, MISO and NSS to LO PLL\\
high & high & Invalid\\
\end{tabular}
\end{center}
When communicating with a PLL, the MUX output of the MAX2871 is forwarded to MISO and the NSS signal is forwarded to the LE pin. As the LE pin should stay low until after a valid register has been shifted in (see MAX2871 datasheet), set NSS low before switching to PLL communication mode.
\section{SPI Protocol}
Each SPI transfer starts with pulling NSS low and ends with NSS returning to high level. SPI communication is done in words of 16\,bits. The first word after NSS is pulled low is the command word and determines the amount and meaning of the following words.
The word received while transmitting the command word is the interrupt status register:
\item\textbf{SH:} Sweep halted due to halt bit set. Sweep will be resumed once the resume command is issued.
\item\textbf{OR:} Data overrun occured (only cleared by resetting the FPGA)
\item\textbf{ND:} New data available
\item\textbf{SU:} Source unlocked
\item\textbf{LU:} LO unlocked
\end{itemize}
\subsection{Writing a register}
Writing a register requires the transfer of two words: First the control word selecting the destination address and a second word containing the new register value:
Initiate the sweep config transfer by sending the command word:
\begin{center}
\begin{tikzpicture}
\bitrect{16}{16-\bit}
\rwbits{0}{1}{0}
\rwbits{1}{1}{0}
\rwbits{2}{1}{0}
\rwbits{3}{13}{Sweep point}
\end{tikzpicture}
\end{center}
The maximum number of points per sweep is 4501, thus the highest valid value for "Sweep point" is 4500. After the control word, send the six words of the sweep config (see section~\ref{sweepconfig}) while keeping NSS low. The sweep config is transmitted MSB first.
\subsection{Reading a sampling result}
Whenever the ND bit in the interrupt status register is set, new sampling data is available and can be read via SPI. It has to be read before the next sampling data arrives otherwise the old data will be overwritten.
Initiate the reading of sampling data by sending the command word:
Afterwards, read up to 19 words before setting NSS high. These 19 words will contain the sampling result (see section~\ref{result}), transmitted with the least significant word first.
When the halt bit is set in the SweepConfig, the FPGA will configure the Source and LO as requested but will not start the settling timer (and subsequently the sampling process) until this resume command is issued. The halted sweep is indicated by the sweep halted bit in the status register.
\begin{center}
\begin{tikzpicture}
\bitrect{16}{16-\bit}
\rwbits{0}{1}{0}
\rwbits{1}{1}{0}
\rwbits{2}{1}{1}
\robits{3}{13}{reserved}
\end{tikzpicture}
\end{center}
\subsection{Reading ADC limits}
The FPGA keeps track of the highest and lowest sample of each ADC to detect saturation and verify signal levels.
Initiate the reading of ADC limit data by sending the command word:
\begin{center}
\begin{tikzpicture}
\bitrect{16}{16-\bit}
\rwbits{0}{1}{1}
\rwbits{1}{1}{1}
\rwbits{2}{1}{1}
\robits{3}{13}{reserved}
\end{tikzpicture}
\end{center}
Afterwards, read 6 words before setting NSS high. These 6 words will contain the sampling result:
\begin{center}
\begin{tikzpicture}
\bitrect{16}{96-\bit}
\rwbits{0}{16}{Port 1 minimum}
\end{tikzpicture}
\begin{tikzpicture}
\bitrect{16}{80-\bit}
\rwbits{0}{16}{Port 1 maximum}
\end{tikzpicture}
\begin{tikzpicture}
\bitrect{16}{64-\bit}
\rwbits{0}{16}{Port 2 minimum}
\end{tikzpicture}
\begin{tikzpicture}
\bitrect{16}{48-\bit}
\rwbits{0}{16}{Port 2 maximum}
\end{tikzpicture}
\begin{tikzpicture}
\bitrect{16}{32-\bit}
\rwbits{0}{16}{Reference minimum}
\end{tikzpicture}
\begin{tikzpicture}
\bitrect{16}{16-\bit}
\rwbits{0}{16}{Reference maximum}
\end{tikzpicture}
\end{center}
\subsection{Resetting the ADC limit}
Issuing this command result in all minimum values set to 32767 and all maximum values set to -32768.
Initiate the reading of the DFT result (see section~\ref{dft}) by sending the command word:
\begin{center}
\begin{tikzpicture}
\bitrect{16}{16-\bit}
\rwbits{0}{1}{1}
\rwbits{1}{1}{0}
\rwbits{2}{1}{1}
\robits{3}{13}{reserved}
\end{tikzpicture}
\end{center}
Afterwards, read 12 words before setting NSS high. These 12 words will contain the first bin of the DFT, the least significant word is transmitted first:
\begin{center}
\begin{tikzpicture}
\bitrect{16}{192-\bit}
\rwbits{0}{16}{Port 1 I[47:32]}
\end{tikzpicture}
\begin{tikzpicture}
\bitrect{16}{176-\bit}
\rwbits{0}{16}{Port 1 I[31:16]}
\end{tikzpicture}
\begin{tikzpicture}
\bitrect{16}{168-\bit}
\rwbits{0}{16}{Port 1 I[15:0]}
\end{tikzpicture}
\begin{tikzpicture}
\bitrect{16}{144-\bit}
\rwbits{0}{16}{Port 1 Q[47:32]}
\end{tikzpicture}
\begin{tikzpicture}
\bitrect{16}{128-\bit}
\rwbits{0}{16}{Port 1 Q[31:16]}
\end{tikzpicture}
\begin{tikzpicture}
\bitrect{16}{112-\bit}
\rwbits{0}{16}{Port 1 Q[15:0]}
\end{tikzpicture}
\begin{tikzpicture}
\bitrect{16}{96-\bit}
\rwbits{0}{16}{Port 2 I[47:32]}
\end{tikzpicture}
\begin{tikzpicture}
\bitrect{16}{80-\bit}
\rwbits{0}{16}{Port 2 I[31:16]}
\end{tikzpicture}
\begin{tikzpicture}
\bitrect{16}{64-\bit}
\rwbits{0}{16}{Port 2 I[15:0]}
\end{tikzpicture}
\begin{tikzpicture}
\bitrect{16}{48-\bit}
\rwbits{0}{16}{Port 2 Q[47:32]}
\end{tikzpicture}
\begin{tikzpicture}
\bitrect{16}{32-\bit}
\rwbits{0}{16}{Port 2 Q[31:16]}
\end{tikzpicture}
\begin{tikzpicture}
\bitrect{16}{16-\bit}
\rwbits{0}{16}{Port 2 Q[15:0]}
\end{tikzpicture}
\end{center}
Repeating this procedure will return the next DFT bin. For each bin, the CS pin has to be toggled and the command word needs to be sent again (each DFT bin requires a new SPI transaction). The DFT interrupt is reset once all bins have been read. Alternatively, toggling the DFT off and on (by disabling and enabling its interrupt) will also reset the interrupt flag.
\item\textbf{SPP[12:0]:} The register contains the number of samples per point in increments of 16 samples (e.g. SPP=0b0000001000=0x08 uses 128 samples per point). The value of this register is only used if SweepConfig[92:90] is set to 000. Otherwise it is overwritten for the sweep point with one of seven preselected values.
The minimum value for this register is 112, which results in a samplerate of roughly \SI{914.3}{\kilo\hertz}. If Presc is set to a lower value, the data acquisition from the ADC is not done when the next sample starts and samples will be skipped.
See datasheet of MAX2871 for bit descriptions. Bits for the fields N, FRAC, M, VCO and DIV\_A are "don't care" as they will be overwritten by the SweepConfig setting.
In addition to the single bin DFT configured through the ADC prescaler and phase increment registers (see \ref{reg:ADC} and \ref{reg:phaseinc}), the FPGA also includes a multiple point DFT. This DFT only operates on the port 1 and port 2 receivers and is intended to speed up spectrum analyzer measurements. If enabled, the DFT runs in parallel to all other calculations.
The SweepConfig contains data for the source and LO1 PLL as well as the attenuator and source filter. Each point in the sweep, needs a valid SweepConfig before the sweep is started.
\begin{center}
\begin{tikzpicture}
\bitrect{16}{96-\bit}
\rwbits{0}{1}{HS}
\rwbits{1}{2}{SettlingTime}
\rwbits{3}{3}{Samples}
\rwbits{6}{2}{SourceFilter}
\rwbits{8}{8}{LO M[11:4]}
\end{tikzpicture}
\begin{tikzpicture}
\bitrect{16}{80-\bit}
\rwbits{0}{4}{LO M[3:0]}
\rwbits{4}{12}{LO FRAC[11:0]}
\end{tikzpicture}
\begin{tikzpicture}
\bitrect{16}{64-\bit}
\rwbits{0}{3}{LO DIV\_A[2:0]}
\rwbits{3}{6}{LO VCO[5:0]}
\rwbits{9}{7}{LO N[6:0]}
\end{tikzpicture}
\begin{tikzpicture}
\bitrect{16}{48-\bit}
\rwbits{0}{1}{BS}
\rwbits{1}{7}{Attenuator[6:0]}
\rwbits{8}{8}{Source M[11:4]}
\end{tikzpicture}
\begin{tikzpicture}
\bitrect{16}{32-\bit}
\rwbits{0}{4}{Source M[3:0]}
\rwbits{4}{12}{Source FRAC[11:0]}
\end{tikzpicture}
\begin{tikzpicture}
\bitrect{16}{16-\bit}
\rwbits{0}{3}{Source DIV\_A[2:0]}
\rwbits{3}{6}{Source VCO[5:0]}
\rwbits{9}{7}{Source N[6:0]}
\end{tikzpicture}
\end{center}
\begin{itemize}
\item\textbf{HS: Halt sweep.} If set, settling and sampling of this sweep point will be postponed until the sweep resume command is issued.
\item\textbf{SettlingTime:} Amount of time between locking of PLLs and beginning of ADC sampling
\begin{center}
\begin{tabular}{ c|c }
Setting & Time\\
\hline
00 &\SI{20}{\micro\second}\\
01 &\SI{60}{\micro\second}\\
10 &\SI{180}{\micro\second}\\
11 &\SI{540}{\micro\second}\\
\end{tabular}
\end{center}
\item\textbf{Samples:} Number of ADC samples to take
\begin{center}
\begin{tabular}{ c|c|c }
Setting & Samples & Equivalent IF bandwidth\\
\hline
000 & Defined by SPP register &\SI{914}{\kilo\hertz}/SPP\\
Each point in the sweep generates two sampling results. The first one contains the measurement when the source was routed to Port 1, the second sampling result was taken when the source was routed to Port 2.