datasheets/2245.tex

654 lines
30 KiB
TeX

\include{preamble.tex}
\graphicspath{{images/2245}{images}}
\usepackage{tikz-timing}
\usetikztiminglibrary{counters}
\title{2245 LVDS-TTL}
\author{M-Labs Limited}
\date{January 2022}
\revision{Revision 2}
\companylogo{\includegraphics[height=0.73in]{artiq_sinara.pdf}}
\begin{document}
\maketitle
\section{Features}
\begin{itemize}
\item{16 LVDS channels.}
\item{Input and output capable.}
\item{No galvanic isolation.}
\item{High speed and low jitter.}
\item{RJ45 connectors.}
\end{itemize}
\section{Applications}
\begin{itemize}
\item{Photon counting.}
\item{External equipment trigger.}
\item{Optical shutter control.}
\item{Serial communication to remote devices.}
\end{itemize}
\section{General Description}
The 2245 LVDS-TTL card is a 4hp EEM module.
It adds general-purpose digital I/O capabilities to carrier cards such as 1124 Kasli and 1125 Kasli-SoC.
Each card provides sixteen digital channels each, controlled through 2 EEM connectors.
Each EEM connector controls eight channels independently.
Single EEM operation is possible.
Each RJ45 connector exposes four digital channels in the LVDS format.
The direction (input or output) of each channel can be selected using DIP switches.
Outputs are intended to drive 100\textOmega~loads, inputs are 100\textOmega~terminated.
This card can achieve higher speed and lower jitter than the isolated 2118/2128 BNC/SMA-TTL cards.
Only shielded Ethernet Cat-6 cables should be connected.
% Switch to next column
\vfill\break
\newcommand*{\MyLabel}[3][2cm]{\parbox{#1}{\centering #2 \\ #3}}
\newcommand*{\MymyLabel}[3][4cm]{\parbox{#1}{\centering #2 \\ #3}}
\newcommand{\inputcolorboxminted}[3][4]{%
\begin{tcolorbox}[colback=white]
\inputminted[#2, gobble=#1]{python}{#3}
\end{tcolorbox}
}
\begin{figure}[h]
\centering
\scalebox{0.88}{
\begin{circuitikz}[european, scale=0.95, every label/.append style={align=center}]
% RJ45 Connectors
\draw (0, 2.8) node[twoportshape, t={\MyLabel{RJ45}{CH 0-3}}, circuitikz/bipoles/twoport/width=1.4, scale=0.5, rotate=-90] (eth0) {};
\draw (0, 1.0) node[twoportshape, t={\MyLabel{RJ45}{CH 4-7}}, circuitikz/bipoles/twoport/width=1.4, scale=0.5, rotate=-90] (eth1) {};
\draw (0, -1.0) node[twoportshape, t={\MyLabel{RJ45}{CH 8-11}}, circuitikz/bipoles/twoport/width=1.4, scale=0.5, rotate=-90] (eth2) {};
\draw (0, -2.8) node[twoportshape, t={\MyLabel{RJ45}{CH 12-15}}, circuitikz/bipoles/twoport/width=1.4, scale=0.5, rotate=-90] (eth3) {};
% Repeaters for channels
% Channel 7 repeaters
\draw (1.8, 0.4) node[twoportshape, t={\MyLabel{CH 7}{Repeaters}}, circuitikz/bipoles/twoport/width=1.6, scale=0.5] (rep7) {};
% Omission dots
\node at (1.8, 0.8)[circle,fill,inner sep=0.7pt]{};
\node at (1.8, 1.0)[circle,fill,inner sep=0.7pt]{};
\node at (1.8, 1.2)[circle,fill,inner sep=0.7pt]{};
% Channel 4 repeaters
\draw (1.8, 1.6) node[twoportshape, t={\MyLabel{CH 4}{Repeaters}}, circuitikz/bipoles/twoport/width=1.6, scale=0.5] (rep4) {};
% Channel 3 repeaters
\draw (1.8, 2.2) node[twoportshape, t={\MyLabel{CH 3}{Repeaters}}, circuitikz/bipoles/twoport/width=1.6, scale=0.5] (rep3) {};
% Omission dots
\node at (1.8, 2.6)[circle,fill,inner sep=0.7pt]{};
\node at (1.8, 2.8)[circle,fill,inner sep=0.7pt]{};
\node at (1.8, 3.0)[circle,fill,inner sep=0.7pt]{};
% Channel 0 repeaters
\draw (1.8, 3.4) node[twoportshape, t={\MyLabel{CH 0}{Repeaters}}, circuitikz/bipoles/twoport/width=1.6, scale=0.5] (rep0) {};
% Channel 8 repeaters
\draw (1.8, -0.4) node[twoportshape, t={\MyLabel{CH 8}{Repeaters}}, circuitikz/bipoles/twoport/width=1.6, scale=0.5] (rep8) {};
% Omission dots
\node at (1.8, -0.8)[circle,fill,inner sep=0.7pt]{};
\node at (1.8, -1.0)[circle,fill,inner sep=0.7pt]{};
\node at (1.8, -1.2)[circle,fill,inner sep=0.7pt]{};
% Channel 11 repeaters
\draw (1.8, -1.6) node[twoportshape, t={\MyLabel{CH 11}{Repeaters}}, circuitikz/bipoles/twoport/width=1.6, scale=0.5] (rep11) {};
% Channel 12 repeaters
\draw (1.8, -2.2) node[twoportshape, t={\MyLabel{CH 12}{Repeaters}}, circuitikz/bipoles/twoport/width=1.6, scale=0.5] (rep12) {};
% Omission dots
\node at (1.8, -2.6)[circle,fill,inner sep=0.7pt]{};
\node at (1.8, -2.8)[circle,fill,inner sep=0.7pt]{};
\node at (1.8, -3.0)[circle,fill,inner sep=0.7pt]{};
% Channel 15 repeaters
\draw (1.8, -3.4) node[twoportshape, t={\MyLabel{CH 15}{Repeaters}}, circuitikz/bipoles/twoport/width=1.6, scale=0.5] (rep15) {};
% Direction switches
\draw (4.6, 0.4) node[twoportshape,t=\MymyLabel{Per-channel \phantom{spac} x8 }{Input/Output Switch}, circuitikz/bipoles/twoport/width=2.7, scale=0.5] (ioswitch0) {};
\draw (4.6, -0.4) node[twoportshape,t=\MymyLabel{Per-channel \phantom{spac} x8 }{Input/Output Switch}, circuitikz/bipoles/twoport/width=2.7, scale=0.5] (ioswitch1) {};
\begin{scope}[xshift=5cm, yshift=0.65cm, scale=0.12, every node/.style={scale=0.1}, rotate=-90 ]
\draw (0.4, 0) to[short,-o](0.75, 0);
\draw (0.78, 0)-- +(30: 0.46);
\draw (1.25, 0)to[short,o-](1.6, 0);
\end{scope}
\begin{scope}[xshift=5cm, yshift=-0.15cm, scale=0.12, every node/.style={scale=0.1}, rotate=-90 ]
\draw (0.4, 0) to[short,-o](0.75, 0);
\draw (0.78, 0)-- +(30: 0.46);
\draw (1.25, 0)to[short,o-](1.6, 0);
\end{scope}
% I2C I/O expanders
\draw (4.6, 1.6) node[twoportshape,t=\MymyLabel{IO Expander}{for I2C Bus}, circuitikz/bipoles/twoport/width=2.7, scale=0.5] (i2c0) {};
\draw (4.6, -1.6) node[twoportshape,t=\MymyLabel{IO Expander}{for I2C Bus}, circuitikz/bipoles/twoport/width=2.7, scale=0.5] (i2c1) {};
% 2 Aesthetic EEPROMs
\draw (4.6, 2.2) node[twoportshape,t={EEPROM}, circuitikz/bipoles/twoport/width=2.7, scale=0.5] (eeprom0) {};
\draw (4.6, -2.2) node[twoportshape,t={EEPROM}, circuitikz/bipoles/twoport/width=2.7, scale=0.5] (eeprom1) {};
% EEMs from core device / controllers
\draw (7.2, 1.9) node[twoportshape, t={EEM Port 0}, circuitikz/bipoles/twoport/width=3.6, scale=0.7, rotate=-90] (eem0) {};
\draw (7.2, -1.9) node[twoportshape, t={EEM Port 1}, circuitikz/bipoles/twoport/width=3.6, scale=0.7, rotate=-90] (eem1) {};
% Connect RJ45 to LVDS DIO channels
% CH 0
\draw [latexslim-] (rep0.west) -- (0.7, 3.4);
\draw [-] (0.7, 3.4) -- (0.7, 3.1);
\draw [-latexslim] (0.7, 3.1) -- (0.25, 3.1);
% CH 1
\draw [latexslim-latexslim] (0.25, 2.9) -- (0.9, 2.9);
\node [label=center:\tiny{CH 1}] at (1.2, 2.9) {};
% CH 2
\draw [latexslim-latexslim] (0.25, 2.7) -- (0.9, 2.7);
\node [label=center:\tiny{CH 2}] at (1.2, 2.7) {};
% CH 3
\draw [latexslim-] (rep3.west) -- (0.7, 2.2);
\draw [-] (0.7, 2.2) -- (0.7, 2.5);
\draw [-latexslim] (0.7, 2.5) -- (0.25, 2.5);
% CH 4
\draw [latexslim-] (rep4.west) -- (0.7, 1.6);
\draw [-] (0.7, 1.6) -- (0.7, 1.3);
\draw [-latexslim] (0.7, 1.3) -- (0.25, 1.3);
% CH 5
\draw [latexslim-latexslim] (0.25, 1.1) -- (0.9, 1.1);
\node [label=center:\tiny{CH 5}] at (1.2, 1.1) {};
% CH 6
\draw [latexslim-latexslim] (0.25, 0.9) -- (0.9, 0.9);
\node [label=center:\tiny{CH 6}] at (1.2, 0.9) {};
% CH 7
\draw [latexslim-] (rep7.west) -- (0.7, 0.4);
\draw [-] (0.7, 0.4) -- (0.7, 0.7);
\draw [-latexslim] (0.7, 0.7) -- (0.25, 0.7);
% CH 8
\draw [latexslim-] (rep8.west) -- (0.7, -0.4);
\draw [-] (0.7, -0.4) -- (0.7, -0.7);
\draw [-latexslim] (0.7, -0.7) -- (0.25, -0.7);
% CH 9
\draw [latexslim-latexslim] (0.25, -0.9) -- (0.9, -0.9);
\node [label=center:\tiny{CH 9}] at (1.2, -0.9) {};
% CH 10
\draw [latexslim-latexslim] (0.25, -1.1) -- (0.9, -1.1);
\node [label=center:\tiny{CH 10}] at (1.2, -1.1) {};
% CH 11
\draw [latexslim-] (rep11.west) -- (0.7, -1.6);
\draw [-] (0.7, -1.6) -- (0.7, -1.3);
\draw [-latexslim] (0.7, -1.3) -- (0.25, -1.3);
% CH 12
\draw [latexslim-] (rep12.west) -- (0.7, -2.2);
\draw [-] (0.7, -2.2) -- (0.7, -2.5);
\draw [-latexslim] (0.7, -2.5) -- (0.25, -2.5);
% CH 13
\draw [latexslim-latexslim] (0.25, -2.7) -- (0.9, -2.7);
\node [label=center:\tiny{CH 13}] at (1.2, -2.7) {};
% CH 14
\draw [latexslim-latexslim] (0.25, -2.9) -- (0.9, -2.9);
\node [label=center:\tiny{CH 14}] at (1.2, -2.9) {};
% CH 15
\draw [latexslim-] (rep15.west) -- (0.7, -3.4);
\draw [-] (0.7, -3.4) -- (0.7, -3.1);
\draw [-latexslim] (0.7, -3.1) -- (0.25, -3.1);
% Interconnect repeaters controlled by EEM 0
\draw [latexslim-] (2.4, 3.5) -- (2.9, 3.5);
\draw [latexslim-] (2.4, 2.3) -- (2.9, 2.3);
\draw [latexslim-] (2.4, 1.7) -- (2.9, 1.7);
\draw [latexslim-] (2.4, 0.5) -- (2.9, 0.5);
\draw [-] (2.9, 3.5) -- (2.9, 0.5);
\draw [latexslim-] (2.4, 3.3) -- (3.1, 3.3);
\draw [latexslim-] (2.4, 2.1) -- (3.1, 2.1);
\draw [latexslim-] (2.4, 1.5) -- (3.1, 1.5);
\draw [latexslim-] (2.4, 0.3) -- (3.1, 0.3);
\draw [-] (3.1, 3.3) -- (3.1, 0.3);
% Interconnect repeaters controlled by EEM 1
\draw [latexslim-] (2.4, -3.5) -- (2.9, -3.5);
\draw [latexslim-] (2.4, -2.3) -- (2.9, -2.3);
\draw [latexslim-] (2.4, -1.7) -- (2.9, -1.7);
\draw [latexslim-] (2.4, -0.5) -- (2.9, -0.5);
\draw [-] (2.9, -3.5) -- (2.9, -0.5);
\draw [latexslim-] (2.4, -3.3) -- (3.1, -3.3);
\draw [latexslim-] (2.4, -2.1) -- (3.1, -2.1);
\draw [latexslim-] (2.4, -1.5) -- (3.1, -1.5);
\draw [latexslim-] (2.4, -0.3) -- (3.1, -0.3);
\draw [-] (3.1, -3.3) -- (3.1, -0.3);
% Junction between I/O expander and I/O switches
\node at (4.6, 1.0)[circle,fill,inner sep=0.7pt]{};
\draw [-latexslim] (i2c0.south) -- (4.6, 1.0);
\draw [-latexslim] (ioswitch0.north) -- (4.6, 1.0);
\draw [-] (4.6, 1.0) -- (3.1, 1.0);
\node at (4.6, -1.0)[circle,fill,inner sep=0.7pt]{};
\draw [-latexslim] (i2c1.north) -- (4.6, -1.0);
\draw [-latexslim] (ioswitch1.south) -- (4.6, -1.0);
\draw [-] (4.6, -1.0) -- (2.9, -1.0);
% Connect EEM Ports
\draw [-latexslim] (2.9, 2.8) -- (6.85, 2.8);
\draw [latexslim-latexslim] (eeprom0.east) -- (6.85, 2.2);
\draw [latexslim-latexslim] (i2c0.east) -- (6.85, 1.6);
\draw [-latexslim] (3.1, -2.8) -- (6.85, -2.8);
\draw [latexslim-latexslim] (eeprom1.east) -- (6.85, -2.2);
\draw [latexslim-latexslim] (i2c1.east) -- (6.85, -1.6);
\end{circuitikz}
}
\caption{Simplified Block Diagram}
\end{figure}
\begin{figure}[h]
\centering
\scalebox{0.88}{
\begin{circuitikz}[european, scale=0.95, every label/.append style={align=center}]
% Channel 0 input repeater
\draw (3, 3.8) node[buffer, circuitikz/bipoles/twoport/width=1.2, scale=0.5] (rep_in0) {};
% Extra node to raise the upper boundary of the ch7 dotted area
\draw[color=white, text=black] (3, 5.3) node[twoportshape, circuitikz/bipoles/twoport/width=0.4, scale=0.4 ] (rep_out0_north) {};
% Left-extend the dotted area to enclose the intersection between input & output
\draw[color=white, text=black] (2.1, 5.2) node[twoportshape, circuitikz/bipoles/twoport/width=0.4, scale=0.4 ] (rep_out0_west) {};
% Right-extend the dotted area to enclose intersection & DIR text
\draw[color=white, text=black] (3.8, 5.2) node[twoportshape, circuitikz/bipoles/twoport/width=0.4, scale=0.4 ] (rep_out0_east) {};
% Channel 0 output repeater, defined after previous node to coverup white boundaries
\draw (3, 5.0) node[buffer, circuitikz/bipoles/twoport/width=1.2, scale=-0.5] (rep_out0) {};
% Channel 0 boundary
\node[draw, dotted, thick, rounded corners, inner xsep=0.7em, inner ysep=0.4em, fit=(rep_in0)(rep_out0)(rep_out0_north)(rep_out0_west)(rep_out0_east)] (sig0) {};
\node[fill=white, scale=0.7] at (sig0.north) {CH X Repeaters};
% Channel 0 direction line
\draw [latexslim-latexslim] (3, 4.0) -- (3, 4.8);
\draw [-] (3, 4.4) -- (4.6, 4.4);
\node [label=center:\tiny{CH X}] at (5.0, 4.5) {};
\node [label=center:\tiny{Direction}] at (5.0, 4.3) {};
% Expose & interconnect internal LVDS inputs
\node at (3.8, 5.0)[circle,fill,inner sep=0.7pt]{};
\draw [latexslim-] (rep_out0.west) -- (3.8, 5.0);
\draw [-latexslim] (rep_in0.east) -- (3.8, 3.8) -- (3.8, 5.0);
\draw [latexslim-latexslim] (3.8, 5.0) -- (4.6, 5.0);
\node [label=center:\tiny{CH X}] at (5.0, 5.1) {};
\node [label=center:\tiny{EEM I/O}] at (5.0, 4.9) {};
% Expose external LVDS I/O
\node at (2.1, 4.4)[circle,fill,inner sep=0.7pt]{};
\draw [-latexslim] (rep_out0.east) -- (2.1, 5.0) -- (2.1, 4.4);
\draw [latexslim-] (rep_in0.west) -- (2.1, 3.8) -- (2.1, 4.4);
\draw [latexslim-latexslim] (2.1, 4.4) -- (1.3, 4.4);
\node [label=center:\tiny{CH X}] at (0.9, 4.5) {};
\node [label=center:\tiny{LVDS I/O}] at (0.9, 4.3) {};
\end{circuitikz}
}
\caption{Detailed diagram for channel repeaters}
\end{figure}
\begin{figure}[hbt!]
\centering
\includegraphics[height=2.1in]{DIO_RJ45_FP.pdf}
\includegraphics[height=2.1in]{photo2245.jpg}
\caption{LVDS-TTL Card photo}
\end{figure}
% For wide tables, a single column layout is better. It can be switched
% page-by-page.
\onecolumn
\section{Electrical Specifications}
Information in this section is based on the datasheet of the repeaters IC (FIN1101K8X\footnote{\label{repeaters}https://www.onsemi.com/pdf/datasheet/fin1101-d.pdf}).
\begin{table}[h]
\begin{threeparttable}
\caption{Recommended Input Voltage}
\begin{tabularx}{\textwidth}{l | c | c c c | c | X}
\thickhline
\textbf{Parameter} & \textbf{Symbol} & \textbf{Min.} & \textbf{Typ.} & \textbf{Max.} &
\textbf{Unit} & \textbf{Conditions} \\
\hline
Magnitude of differential input & $|V_{ID}|$ & 0.1 & & 3.3 & V \\
\hline
Common mode input & $V_{IC}$ & $|V_{ID}|/2$ & & $3.3-|V_{ID}|/2$ & V \\
\hline
Differential input threshold HIGH & $V_{TH}$ & & & 100 & mV & \\
\hline
Differential input threshold LOW & $V_{TL}$ & -100 & & & mV & \\
\thickhline
\end{tabularx}
\end{threeparttable}
\end{table}
The recommended operating temperature is $-40\degree C \leq T_A \leq 85\degree C$.
All specifications are in the recommended operating temperature range unless otherwise noted.
All typical values of DC specifications are at $T_A = 25\degree C$.
\begin{table}[h]
\begin{threeparttable}
\caption{DC Specifications}
\begin{tabularx}{\textwidth}{l | c | c c c | c | X}
\thickhline
\textbf{Parameter} & \textbf{Symbol} & \textbf{Min.} & \textbf{Typ.} & \textbf{Max.} &
\textbf{Unit} & \textbf{Conditions} \\
\hline
Output differentiual Voltage & $V_{OD}$ & 250 & 330 & 450 & mV & \multirow{4}{*}{With 100$\Omega$ load.} \\
\cline{0-5}
$|V_{OD}|$ change (LOW-to-HIGH) & $\Delta V_{OD}$ & & & 25 & mV & \\
\cline{0-5}
Offset voltage & $V_{OS}$ & 1.125 & 1.23 & 1.375 & V & \\
\cline{0-5}
$|V_{OS}|$ change (LOW-to-HIGH) & $\Delta V_{OS}$ & & & 25 & mV & \\
\hline
Short circuit output current & $I_{OS}$ & & $\pm3.4$ & $\pm6$ & mA & \\
\hline
Input current & $I_{IN}$ & & & $\pm20$ & \textmu A & Recommended Input Voltage \\
\thickhline
\end{tabularx}
\end{threeparttable}
\end{table}
\newpage
All typical values of AC specifications are at $T_A = 25\degree C$, $V_{ID} = 300mV$, $V_{IC} = 1.3V$ unless otherwise specified.
\begin{table}[h]
\begin{threeparttable}
\caption{AC Specifications}
\begin{tabularx}{\textwidth}{l | c | c c c | c | X}
\thickhline
\textbf{Parameter} & \textbf{Symbol} & \textbf{Min.} & \textbf{Typ.} & \textbf{Max.} &
\textbf{Unit} & \textbf{Conditions} \\
\hline
Differential Output Rise Time & \multirow{2}{*}{$t_{TLHD}$} & \multirow{2}{*}{0.29} & \multirow{2}{*}{0.40} & \multirow{2}{*}{0.58} & \multirow{2}{*}{ns} & duty Cycle = 50\%.\\
(20\% to 80\%) & & & & & & \\
\cline{0-5}
Differential Output Fall Time & \multirow{2}{*}{$t_{THLD}$} & \multirow{2}{*}{0.29} & \multirow{2}{*}{0.40} & \multirow{2}{*}{0.58} & \multirow{2}{*}{ns} & \\
(80\% to 20\%) & & & & & & \\
\cline{0-5}
Pulse width distortion & $PWD$ & & 0.01 & 0.2 & ns & \\
\hline
LVDS data jitter, & \multirow{2}{*}{$t_{DJ}$} & & \multirow{2}{*}{85} & \multirow{2}{*}{125} & \multirow{2}{*}{ps} & $PRBS=2^{23}-1$\\
deterministic & & & & & & 800 Mbps\\
\hline
LVDS clock jitter, & \multirow{2}{*}{$t_{RJ}$} & & \multirow{2}{*}{2.1} & \multirow{2}{*}{3.5} & \multirow{2}{*}{ps} & \multirow{2}{*}{400 MHz clock}\\
random (RMS) & & & & & & \\
\thickhline
\end{tabularx}
\end{threeparttable}
\end{table}
\section{Configuring IO Direction \& Termination}
The IO direction can be configured by switches, which are found at the top of the card.
\begin{multicols}{2}
IO direction switches partly decides the IO direction of each bank.
\begin{itemize}
\itemsep0em
\item Closed switch (ON) \\
Fix the corresponding channel to output. The direction cannot be changed by I\textsuperscript{2}C.
\item Opened switch (OFF) \\
Switch to input mode. The direction is input by default. Configurable by I\textsuperscript{2}C.
\end{itemize}
\columnbreak
\begin{center}
\centering
\includegraphics[height=1.5in]{lvds_ttl_switches.jpg}
\captionof{figure}{Position of switches}
\end{center}
\end{multicols}
\newpage
\section{Example ARTIQ code}
The sections below demonstrate simple usage scenarios of the 2245 LVDS-TTL card with the ARTIQ control system.
They do not exhaustively demonstrate all the features of the ARTIQ system.
The full documentation for the ARTIQ software and gateware is available at \url{https://m-labs.hk}.
Timing accuracy in the examples below is well under 1 nanosecond thanks to the ARTIQ RTIO system.
\subsection{One pulse per second}
The channel should be configured as output in both the gateware and hardware.
\inputcolorboxminted{firstline=9,lastline=14}{examples/ttl.py}
\subsection{Morse code}
This example demonstrates some basic algorithmic features of the ARTIQ-Python language.
\inputcolorboxminted{firstline=22,lastline=39}{examples/ttl.py}
\newpage
\subsection{Counting rising edges in a 1ms window}
The channel should be configured as input in both the gateware and hardware.
\inputcolorboxminted{firstline=47,lastline=52}{examples/ttl.py}
This example code uses the software counter, which has a maximum count rate of approximately 1 million events per second.
If the gateware counter is enabled on the TTL channel, it can typically count up to 125 million events per second:
\inputcolorboxminted{firstline=60,lastline=65}{examples/ttl.py}
\subsection{Responding to an external trigger}
One channel needs to be configured as input, and the other as output.
\inputcolorboxminted{firstline=74,lastline=80}{examples/ttl.py}
\newcommand{\wrapspacer}[1]% #1 = special text
{\bgroup
\sbox0{\begin{minipage}{\linewidth}\hrule height0pt
#1\hrule height0pt
\end{minipage}}%
\dimen0=\dimexpr \ht0+\dp0\relax
\loop\ifdim\dimen0>\baselineskip
\strut\vspace{-\baselineskip}\newline
\advance\dimen0 by -\baselineskip
\repeat
\noindent\strut\usebox0\par
\egroup}
\newpage
\subsection{SPI Master Device}
If a EEM port is configured as \texttt{dio\char`_spi} instead of \texttt{dio}, its associated TTL channels can be configured as SPI master devices.
Invocation of an SPI transfer follows this pattern:
\begin{enumerate}
% The config register can be set using set_config.
% However, the only difference between these 2 methods is that set_config accepts an arbitrary
% frequency, then translate into the rough frequency divisor for set_config_mu.
% It doesn't guarantee such frequency would be set as the SPI frequency
% In addition, finding clock division is quite easy. set_config_mu seems to be a more
% straight-forward & representative of the actual implementation.
\item Set the \texttt{config} register (e.g. using \texttt{set\char`_config\char`_mu()}).
\item Start the SPI transfer by writing the \texttt{data} register using \texttt{write()}.
\item If the data from the SPI slave is to be read (i.e. \texttt{SPI\char`_INPUT} was set in \texttt{config}), invoke \texttt{read()} to read.
\end{enumerate}
The list of configurations supported in the gateware are listed as below:
\begin{table}[h]
\centering
\begin{tabular}{|c|l|}
\hline
Flag & Description \\ \hline
\texttt{SPI\char`_OFFLINE} & Switch all pins to high impedance mode. \\ \hline
\texttt{SPI\char`_END} & Next SPI transfer is the last of the transcation. \\ \hline
\texttt{SPI\char`_INPUT} & Submit SPI read data as RTIO input event when the transfer is complete. \\ \hline
\texttt{SPI\char`_CS\char`_POLARITY} & Active level of chip select (CS) \\ \hline
\texttt{SPI\char`_CLK\char`_POLARITY} & Idle level of serial clock (SCK) \\ \hline
\texttt{SPI\char`_CLK\char`_PHASE} & Data is sampled on falling edge \& shifted out on rising edge. \\ \hline
\texttt{SPI\char`_LSB\char`_FIRST} & LSB is the first on bit on the wire. \\ \hline
\texttt{SPI\char`_HALF\char`_DUPLEX} & Use 3-wire SPI, where MOSI is both input \& output capable. \\ \hline
\end{tabular}
\end{table}
The following ARTIQ example demonstrates the flow of an SPI transcation with a typical SPI setup with 3 homogeneous slaves.
The direction switches on the LVDS-TTL card should be set to the correct IO direction for all relevant channels before powering on.
\begin{center}
\begin{circuitikz}[european, scale=1, every label/.append style={align=center}]
% SPI master
\draw (0, 1.8) node[twoportshape, t={}, circuitikz/bipoles/twoport/width=2.8, circuitikz/bipoles/twoport/height=2, scale=1] (master) {};
\node [label={center:\large{SPI Master}}] at (-0.6, 2.05) {};
\node [label={center:\large{(LVDS-TTL)}}] at (-0.6, 1.55) {};
\node [label=left:{SCK}] at (2, 2.8) {};
\node [label=left:{MOSI}] at (2, 2.4) {};
\node [label=left:{MISO}] at (2, 2.0) {};
\node [label=left:{CS0}] at (2, 1.6) {};
\node [label=left:{CS1}] at (2, 1.2) {};
\node [label=left:{CS2}] at (2, 0.8) {};
% SPI slaves
% The top one will have its SCK, MOSI, MISO aligned with the master, for wiring simplicity
\draw (7, 2.2) node[twoportshape, t={}, circuitikz/bipoles/twoport/width=2.8, circuitikz/bipoles/twoport/height=1.4, scale=1] (slave0) {};
\node [label={center:\large{SPI Slave 0}}] at (7.6, 2.2) {};
\node [label=right:{SCK}] at (5, 2.8) {};
\node [label=right:{MOSI}] at (5, 2.4) {};
\node [label=right:{MISO}] at (5, 2.0) {};
\node [label=right:{$\mathrm{\overline{CS}}$}] at (5, 1.6) {};
% The top one will have its SCK, MOSI, MISO aligned with the master, for wiring simplicity
\draw (7, 0) node[twoportshape, t={}, circuitikz/bipoles/twoport/width=2.8, circuitikz/bipoles/twoport/height=1.4, scale=1] (slave1) {};
\node [label={center:\large{SPI Slave 1}}] at (7.6, 0) {};
\node [label=right:{SCK}] at (5, 0.6) {};
\node [label=right:{MOSI}] at (5, 0.2) {};
\node [label=right:{MISO}] at (5, -0.2) {};
\node [label=right:{$\mathrm{\overline{CS}}$}] at (5, -0.6) {};
% The top one will have its SCK, MOSI, MISO aligned with the master, for wiring simplicity
\draw (7, -2.2) node[twoportshape, t={}, circuitikz/bipoles/twoport/width=2.8, circuitikz/bipoles/twoport/height=1.4, scale=1] (slave2) {};
\node [label={center:\large{SPI Slave 2}}] at (7.6, -2.2) {};
\node [label=right:{SCK}] at (5, -1.6) {};
\node [label=right:{MOSI}] at (5, -2.0) {};
\node [label=right:{MISO}] at (5, -2.4) {};
\node [label=right:{$\mathrm{\overline{CS}}$}] at (5, -2.8) {};
% Connect the master to slave 0
\draw [-latexslim] (1.95, 2.8) -- (5.05, 2.8);
\draw [-latexslim] (1.95, 2.4) -- (5.05, 2.4);
\draw [latexslim-] (1.95, 2.0) -- (5.05, 2.0);
\draw [-latexslim] (1.95, 1.6) -- (5.05, 1.6);
% Connect slave 1
\draw [-latexslim] (4.2, 2.8) -- (4.2, 0.6) -- (5.05, 0.6);
\draw [-latexslim] (3.8, 2.4) -- (3.8, 0.2) -- (5.05, 0.2);
\draw [-] (3.4, 2.0) -- (3.4, -0.2) -- (5.05, -0.2);
\draw [-latexslim] (1.95, 1.2) -- (3.0, 1.2) -- (3.0, -0.6) -- (5.05, -0.6);
% Connect slave 2
\draw [-latexslim] (4.2, 0.6) -- (4.2, -1.6) -- (5.05, -1.6);
\draw [-latexslim] (3.8, 0.2) -- (3.8, -2.0) -- (5.05, -2.0);
\draw [-] (3.4, -0.2) -- (3.4, -2.4) -- (5.05, -2.4);
\draw [-latexslim] (1.95, 0.8) -- (2.6, 0.8) -- (2.6, -2.8) -- (5.05, -2.8);
% Add dot to intersection to distinguish from overlaps
\node at (4.2, 2.8)[circle,fill,inner sep=0.7pt]{};
\node at (3.8, 2.4)[circle,fill,inner sep=0.7pt]{};
\node at (3.4, 2.0)[circle,fill,inner sep=0.7pt]{};
\node at (4.2, 0.6)[circle,fill,inner sep=0.7pt]{};
\node at (3.8, 0.2)[circle,fill,inner sep=0.7pt]{};
\node at (3.4, -0.2)[circle,fill,inner sep=0.7pt]{};
\end{circuitikz}
\end{center}
\newpage
\subsubsection{SPI Configuration}
The following examples will assume the SPI communication has the following properties:
\begin{itemize}
\item Chip select (CS) is active low
\item Serial clock (SCK) idle level is low
\item Data is sampled on rising edge of SCK \& shifted out on falling edge of SCK
\item Most significant bit (MSB) first
\item Full duplex
\end{itemize}
The base line configuration for an \texttt{SPIMaster} instance can be defined as such:
\inputcolorboxminted[0]{firstline=2,lastline=8}{examples/spi.py}
The \texttt{SPI\char`_END} \& \texttt{SPI\char`_INPUT} flags will be modified during runtime in the following example.
\subsubsection{SPI frequency}
Frequency of the SPI clock must be the result of RTIO clock frequency divided by an integer factor from [2, 257].
In the folowing examples, the SPI frequency will be set to 1 MHz by dividing the RTIO frequency (125 MHz) by 125.
\inputcolorboxminted[0]{firstline=10,lastline=10}{examples/spi.py}
\subsubsection{SPI write}
Typically, an SPI write operation involves sending an instruction and data to the SPI slaves.
Suppose the instruction and data are 8 bits and 32 bits respectively.
The timing diagram of such write operation is shown in the following.
\begin{center}
\begin{tikztimingtable}
[
timing/d/background/.style={fill=white},
timing/lslope=0.2
]
$\mathrm{\overline{CS}}$ & H51{L}H \\
SCK & LL31{T}; 2{[dotted] T}; 17{T} L \\
% The better approach is to use pass the counter (\tikztimingcounter{Q}) to a macro,
% then print the label from macro. But it turns out tikz-timing will print
% the counter value separately, even with an additional macro.
% Therefore, it does not work properly.
MOSI & [timing/counter/new={char=I, reset char=J, reset type=arg, increment=-1, text format=I}, timing/counter/new={char=A, reset char=R, reset type=arg, increment=-1, text format=D}]
UJ{7}8{2I}R{31}8{2A}; [dotted] D [dotted] D{}; R{7}8{2A}2U \\
MOSI & 53U \\
\end{tikztimingtable}%
\end{center}
\newpage
Suppose the instruction is \texttt{0x13}, while the data is \texttt{0xDEADBEEF}. In addition, both slave 1 \& 2 are selected. This SPI transcation can be performed by the following code.
\inputcolorboxminted{firstline=18,lastline=27}{examples/spi.py}
\subsubsection{SPI read}
A 32-bits read is represented by the following timing diagram.
\begin{center}
\begin{tikztimingtable}
[
timing/d/background/.style={fill=white},
timing/lslope=0.2
]
$\mathrm{\overline{CS}}$ & H51{L}H \\
SCK & LL31{T}; 2{[dotted] T}; 17{T} L \\
% The better approach is to use pass the counter (\tikztimingcounter{Q}) to a macro,
% then print the label from macro. But it turns out tikz-timing will print
% the counter value separately, even with an additional macro.
% Therefore, it does not work properly.
MOSI & [timing/counter/new={char=I, reset char=J, reset type=arg, increment=-1, text format=I}]
UJ{7}8{2I}36U \\
MOSI & [timing/counter/new={char=A, reset char=R, reset type=arg, increment=-1, text format=D}]
17UR{31}8{2A}; [dotted] D [dotted] D{}; R{7}8{2A}2U \\
\end{tikztimingtable}%
\end{center}
Suppose the instruction is \texttt{0x81}, where only slave 0 is selected. This SPI transcation can be performed by the following code.
\inputcolorboxminted{firstline=35,lastline=49}{examples/spi.py}
\newpage
\section{Ordering Information}
To order, please visit \url{https://m-labs.hk} and select the 2245 LVDS-TTL in the ARTIQ Sinara crate configuration tool. The card may also be ordered separately by writing to \url{mailto:sales@m-labs.hk}.
\section*{}
\vspace*{\fill}
\input{footnote.tex}
\end{document}