\documentclass[12pt,a4paper]{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}
\usepackage{graphicx}
\usepackage{amsmath,amssymb,amsfonts}
\usepackage[table,dvipsnames]{xcolor}
\usepackage{array}
\usepackage{makecell}
\usepackage{refstyle}
\usepackage{float}



\definecolor{tablehead}{hsb}{0,0,0.9}
\newcolumntype{C}[1]{>{\centering\arraybackslash}p{#1}}

\title{Pinlock: Dokumentation}
\subtitle{Mikrocontroller-Seminar}
\author{Leonard Kugis, Mattes Melius}

\begin{document}

\maketitle

\tableofcontents

\newpage

\section{Idee}
Für unser Mikrocontroller-Projekt haben wir uns für ein vierstelliges Zahlenschloss entschieden.
Dieses soll nach Eingabe eines validen Codes in einen "Geöffnet"-Zustand wechselt und
im "Geschlossen"-Zustand verweilt, wenn der Code inkorrekt war.
Zudem soll dem Benutzer die Möglichkeit gegeben werden einen persönlich gewählten
Code einzuspeichern und den alten zu Überschreiben.

\section{Hardware}

\subsection{Platinenaufbau}
Unser Mikrocontroller liegt auf einer 100mmx80mm großen Platine welche über zwei Kupferlagen verfügt.
Als Hauptbaustein wird der ATmega16A benutzt. Des weiteren befinden sich auf unserer Platine neben üblichen
Grundbausteinen eine Ausgabe- sowie eine "externe" Eingabe-Einheit, als auch Status-LEDs.
\begin{figure}[H]
\centering
\includegraphics[width=15cm,height=10cm,keepaspectratio]{resources/Pinlock_Schema}
\caption{Schaltbild Hauptschaltung}
\end{figure}

\newpage

\subsection{Mikrocontroller ATmega16A}
Der ATmega16A ist ein 8-Bit CMOS Controller, welcher bei einer Spannung von 2,7- 5V arbeitet.
In unserem Projekt nutzen wir nicht alle Features des Bausteins.
Um unsere Schaltung zu realisieren, brauchen wir die GPIO, die eingebaute AVR-CPU und das EEPROM.

Mit der GPIO und der AVR-CPU ist es uns möglich die Inputs aus der Eingabematrix in Sinnvolle werte umzurechnen
und in den Registern der CPU einzuspeichern. Diese werden nun auch an die Display-Units weitergegeben, welche diese anzeigen
können um dem Benutzer visuell darzustellen, welche Zahlen eingegeben wurden, ob richtige Eingabe erfolgt ist oder ob ein Code invalide war.
Auch der Zustand (geöffnet/geschlossen) wird in den Registern des ATmega's gespeichert und auch an die Status-LEDs gesendet.

Im EEPROM wird der valide Code abgespeichert, sodass dieser auch nach einen Neustart zur Verfügung steht und nicht gelöscht wird.
So ist es dem Nutzer möglich den Code bis zu 100,000 zu ändern.

\subsection{Sonstige Komponenten}

\subsubsection{Zahleneingabe}
Für die Eingabe des Codes benutzen wir eine reguläre Eingabematrix, welche an einem 8-Bit serial-in,
parallel-out Schieberegister, dem "74HC164",  und einem einfachen Schieberegister, "74LS166".
Durch die beiden Bauteile können wir eindeutig die Eingabe auslesen und wird als 8-Bit Zahl  an den ATmega16A
gesendet.

\begin{figure}[H]
\centering
\includegraphics[width=15cm,height=8cm,keepaspectratio]{resources/buttons}
\caption{Schaltbild Eingabecontroller}
\end{figure}

\subsubsection{Zahlenausgabe}
Die Display-Unit besteht bei unserem Projekt aus einer 7-Segment-Display und einen eigenen Displaytreiber-Baustein,
welcher vom Controller eine 8-Bit Zahl bekommt und diese direkt als korrekte Zahl im Display anzeigt. Um unseren vierstelligen
Code dazustellen haben wir auch vier dieser Units.

\begin{figure}[H]
\centering
\includegraphics[width=15cm,height=10cm,keepaspectratio]{resources/Display_Schema}
\caption{Schaltbild Display-Units}
\end{figure}


\newpage

\subsubsection{Statusanzeige}
Um den momentanen Zustand anzuzeigen ist neben den Anzeigevariationen im Display acht LEDs auf der Platine verbaut, vor welchen ein Schieberegister
geschaltet ist welches Statusinformationen als eine 8-Bit-Sequenz vom ATmega bekommt. Durch diese Sequenz Leuten in bestimmten Zuständen die
zugehörigen LEDs.

\begin{figure}[H]
\centering
\includegraphics[width=15cm,height=10cm,keepaspectratio]{resources/Status_LED_Schema}
\caption{Schaltbild Status-LEDs}
\end{figure}


\newpage

\section{Software}

Das Programm wurde in AVR-Assembler geschrieben, mit Assemblerdirektiven
für den \emph{Avra}-Assembler.
Grundsätzlich wurden für dieses Programm die in Tabelle~\ref{tbl:registermap}
Register-Neudefinitionen vorgenommen, um den Code lesbarer zu gestalten.

\begin{table}[!htb]
  \centering
  \begin{tabular}{|C{0.2\linewidth}|C{0.2\linewidth}|C{0.5\linewidth}|}
    \hline
    \rowcolor{tablehead} ATmega16A Register & Neu definierte Registerbezeichnung & Funktion \\ \hline
    \texttt{r16} & \texttt{tmp0} & Temporäres Pufferregister 0 \\ \hline
    \texttt{r17} & \texttt{par0} & Parameterregister 0 \\ \hline
    \texttt{r18} & \texttt{par1} & Parameterregister 1 \\ \hline
    \texttt{r19} & \texttt{tmp1} & Temporäres Pufferregister 1 \\ \hline
    \texttt{r20} & \texttt{tmp2} & Temporäres Pufferregister 2 \\ \hline
    \texttt{r21} & \texttt{ret0} & Rückgaberegister 0 \\ \hline
    \texttt{r22} & \texttt{ret1} & Rückgaberegister 1 \\ \hline
    \texttt{r23} & \texttt{par2} & Parameterregister 2 \\ \hline
    \texttt{r24} & \texttt{par3} & Parameterregister 3 \\ \hline
    \texttt{r25} & \texttt{par4} & Parameterregister 4 \\ \hline
    \texttt{r26} & \texttt{ret2} & Rückgaberegister 2 \\ \hline
    \texttt{r27} & \texttt{heart} & Debug \\ \hline
    \texttt{r28} & \texttt{dig0} & Pufferregister für Ziffern 0 und 1 \\ \hline
    \texttt{r29} & \texttt{dig1} & Pufferregister für Ziffern 2 und 3 \\ \hline
  \end{tabular}
  \caption{Neu definierte Registerbezeichnungen für Register des ATmega16A}
  \label{tbl:registermap}
\end{table}

\subsection{Grundprinzip}

Nach Zurücksetzen des Mikrocontrollers durchläuft das Programm eine Initialisierungsroutine.
Diese beinhaltet im Wesentlichen folgende Schritte:

\begin{enumerate}
  \item Initialisierung des Stackpointers mit den Grenzen des verfügbaren RAMs
  \item Konfiguration der GPIO-Ports
  \item Initialisierung der Displays
  \item Lesen des Zugangscodes aus dem EEPROM
\end{enumerate}

Anschließend wird eine endlose Hauptschleife durchlaufen, die folgende Aktionen
periodisch ausführt:

\begin{enumerate}
  \item Warte 12240 Zyklen.
  \item Lese alle Tasten der Eingabematrix aus.
  \item Ermittle Änderungen des neuen Tastenstatus zu dem alten Tastenstatus.
  \item Bei positiver Flanke (Taste war vorher nicht gedrückt und ist jetzt gedrückt):
    Behandle den Tastendruck bezüglich des aktuellen Zustands (s.u.).
  \item Puffere den neuen Tastenstatus.
\end{enumerate}

Die einzelnen Routinen, die dabei aufgerufen werden, werden genauer in Sektion~\ref{sec:functions} erläutert.

Die Behandlung der (neu) gedrückten Taste bezüglich des aktuellen Zustandes erfolgt nach der
in Abbildung~\ref{fig:states} dargestellten \emph{Finite-State-Machine} (FSM).
Die Zustände sind dabei nach folgendem Schema benannt:

\begin{tabular}{r@{: }l r@{: }l}
  \texttt{A} & \emph{Authenticating}, Authentifizierung findet gerade durch Codeeingabe statt \\
  \texttt{AS} & \emph{Authentication Submitted}, Code wurde bestätigt und wird überprüft \\
  \texttt{AD} & \emph{Authenticated}, Benutzer ist authentifiziert und hat Zugriff \\
  \texttt{C} & \emph{Change}, Benutzer ändert den Zugriffscode
\end{tabular}

Dabei folgt die Notation der Transitionsbedingungen dem Schema \\
\colorbox{lightgray}{\texttt{<Auslöser> / <Wesentliche Aktionen>}}.
Die Tastendarstellungen innerhalb des Programmes unterliegen dabei der Zuordnung in
Tabelle~\ref{tbl:keymap}.

\begin{figure}[!htb]
  \centering
  \includegraphics[width=0.7\linewidth, keepaspectratio]{resources/states}
  \caption{FSM der Behandlung von Tastendrücken (schematisch)}
  \label{fig:states}
\end{figure}

\begin{table}[!htb]
  \centering
  \begin{tabular}{|c|c|}
    \hline
    \rowcolor{tablehead} Taste extern & Taste intern \\ \hline
    \texttt{0..9} & \texttt{0x00..0x09} \\ \hline
    \texttt{A..D} & \texttt{0x0A..0x0D} \\ \hline
    \texttt{*} & \texttt{0x0E} \\ \hline
    \texttt{\#} & \texttt{0x0F} \\ \hline
  \end{tabular}
  \caption{Zuordnung von externen zu internen Tastendarstellungen}
  \label{tbl:keymap}
\end{table}

\subsection{Routinen}\label{sec:functions}

\subsubsection{\texttt{wait}}

\begin{tabular}{r@{: }l r@{: }l}
  Parameter & \makecell[l]{\texttt{par0}: Wartezyklen Stufe 1, \\ \texttt{par1}: Wartezyklen Stufe 2, \\ \texttt{par2}: Wartezyklen Stufe 3} \\
  Rückgabe & -
\end{tabular}

Warte über drei verschachtelte Schleifen mit verschiedenen Durchlaufzahlen.
Die gesamte, zu wartende Zyklendauer beträgt somit
$\Delta t_\text{ges} = \text{\texttt{par0}} \cdot \text{\texttt{par1}} \cdot \text{\texttt{par2}}$.

\subsubsection{\texttt{write\_code}}

\begin{tabular}{r@{: }l r@{: }l}
  Parameter & - \\
  Rückgabe & -
\end{tabular}

Schreibe statisch die Werte 0x01 und 0x23 (entspricht der Zahlenkombination \texttt{0123})
in das EEPROM an die Adressen 0x00 und 0x01.

\subsubsection{\texttt{load\_code}}

\begin{tabular}{r@{: }l r@{: }l}
  Parameter & - \\
  Rückgabe & \makecell[l]{\texttt{ret0}: Ziffern 0 und 1, \\ \texttt{ret1}: Ziffern 2 und 3}
\end{tabular}

Lese die gespeicherte Zahlenkombination aus dem EEPROM (Adressen 0x00 und 0x01) aus.

\subsubsection{\texttt{shift\_out}}

\begin{tabular}{r@{: }l r@{: }l}
  Parameter & \makecell[l]{\texttt{par0}: Zu schreibendes Byte, \\
    \texttt{par1..par2}: Adresse zur Funktion, um 0 zu schreiben, \\
    \texttt{par3..par4}: Adresse zur Funktion, um 1 zu schreiben} \\
  Rückgabe & -
\end{tabular}

Schreibe ein Byte Bit für Bit durch Funktionsaufrufe, welche das Schreiben
des 0- und 1-Bits implementieren. Das können beispielsweise Funktionen sein,
die 0 bzw. 1 an ein Schieberegister anlegen.

\subsubsection{\texttt{shift\_in}}

\begin{tabular}{r@{: }l r@{: }l}
  Parameter & \makecell[l]{\texttt{par0..par1}: Adresse zur Funktion, um einen Clockzyklus zu durchlaufen, \\
    \texttt{par2..par3}: Adresse zur Funktion, das zugehörige Bit zu lesen} \\
  Rückgabe & \makecell[l]{\texttt{ret0}: Gelesenes Byte}
\end{tabular}

Lese ein Byte Bit für Bit aus einem Schieberegister. Das Durchlaufen eines Clockzyklus und Lesen des
Bits ist in übergebenen Funktionen implementiert.

\subsubsection{\texttt{eeprom\_write}}

\begin{tabular}{r@{: }l r@{: }l}
  Parameter & \makecell[l]{\texttt{par0..par1}: Zieladresse, \\
    \texttt{par2}: Zu schreibender Wert} \\
  Rückgabe & -
\end{tabular}

Schreibt ein Byte an die gegebene Adresse in das interne EEPROM.

\subsubsection{\texttt{eeprom\_read}}

\begin{tabular}{r@{: }l r@{: }l}
  Parameter & \makecell[l]{\texttt{par0..par1}: Adresse} \\
  Rückgabe & \makecell[l]{\texttt{ret0}: Gelesener Wert}
\end{tabular}

Liest ein Byte von der gegebenen Adresse im internen EEPROM.

\subsubsection{\texttt{status}}

\begin{tabular}{r@{: }l r@{: }l}
  Parameter & \makecell[l]{\texttt{par0}: Statusbits} \\
  Rückgabe & -
\end{tabular}

Gibt die gegebenen Statusbits über die LEDs aus.
Dabei wird das Schieberegister dafür benutzt.

\subsubsection{\texttt{display}}

\begin{tabular}{r@{: }l r@{: }l}
  Parameter & \makecell[l]{\texttt{par0}: Displaynummer, \\ \texttt{par1}: Darzustellende Ziffer} \\
  Rückgabe & -
\end{tabular}

Zeige die gegebene Ziffer auf dem gegebenen Display.

\subsubsection{\texttt{set\_digit}}

\begin{tabular}{r@{: }l r@{: }l}
  Parameter & \makecell[l]{\texttt{par0}: Ziffernstelle, \\ \texttt{par1}: Ziffer} \\
  Rückgabe & -
\end{tabular}

Schreibt die Ziffer an die Ziffernstelle des internen Puffers.

\subsubsection{\texttt{get\_digit}}

\begin{tabular}{r@{: }l r@{: }l}
  Parameter & \makecell[l]{\texttt{par0}: Ziffernstelle} \\
  Rückgabe & \makecell[l]{\texttt{ret0}: Ziffer an der Stelle}
\end{tabular}

Liest die Ziffer der gegebenen Stelle von dem internen Puffer.

\subsubsection{\texttt{input}}

\begin{tabular}{r@{: }l r@{: }l}
  Parameter & - \\
  Rückgabe & \makecell[l]{\texttt{ret0}: Tastenstatus mit Belegung: \texttt{0852*741}, \\
    \texttt{ret1}: Tastenstatus mit Belegung: \texttt{DCBA\#963}}
\end{tabular}

Liest den Tastenstatus aller Tasten aus. Ein 1-Bit entspricht einer gedrückten,
ein 0-Bit einer nicht gedrückten Taste.
Das Auslesen der Tasten der Eingabematrix erfolgt über die Schieberegister:
eines (Serial-In-Parallel-Out) zur Selektion der auszulesenden Zeile und eines (Parallel-In-Serial-Out)
zum eigentlichen Auslesen selbiger. Dies wird innerhalb der Ausleseroutine mit jeder
Zeile gemacht, um gedrückte Tasten zu identifizieren.

\subsubsection{\texttt{translate}}

\begin{tabular}{r@{: }l r@{: }l}
  Parameter & \makecell[l]{\texttt{par0}: Tastenstatus Bits \texttt{7..0}, \\
    \texttt{par1}: Tastenstatus Bits \texttt{15..8}} \\
  Rückgabe & \makecell[l]{\texttt{ret0}: Übersetzter Tastencode}
\end{tabular}

Übersetzt den Tastenstatus in die entsprechende, interne Tastendarstellung.
Dabei wird nach der Zuordnung aus Tabelle~\ref{tbl:keymap} vorgegangen.

\subsubsection{\texttt{handle}}

\begin{tabular}{r@{: }l r@{: }l}
  Parameter & \makecell[l]{\texttt{par0}: Aktueller Zustand, \\
    \texttt{par1}: Tastencode} \\
  Rückgabe & \makecell[l]{\texttt{ret0}: Neuer Zustand}
\end{tabular}

Behandle den Tastencode unter dem aktuellen Zustand.
Das Zustandsfeld hat folgende Belegung (ein Zeichen entspricht einem Bit):

\begin{center}
  \texttt{CSSSSSDD}
\end{center}

\begin{tabular}{r@{: }l r@{: }l}
  \texttt{0} & Reserviert \\
  \texttt{C} & Pufferbit für Blinken der ausgewählten Stelle \\
  \texttt{S} & Zustandsinformationen \\
  \texttt{D} & Aktuell ausgewähltes Display
\end{tabular}

Die Behandlung erfolgt nach dem in Abbildung~\ref{fig:states} dargestellten Schema.

\section{Bedienung}

Nach Zurücksetzen des Systems ist man in der Authentifizierungsphase.
In dieser ist die richtige Ziffernkombination einzugeben, welcher vorher gespeichert wurde.
Der Standardcode ist \texttt{0123}.
Es stehen dabei folgende Optionen zur Auswahl:

\begin{tabular}{r@{: }l r@{: }l}
  \texttt{0..9} & Ziffer eingeben \\
  \texttt{A} & Eingabe bestätigen \\
  \texttt{*} & Zeigerposition nach links schieben \\
  \texttt{\#} & Zeigerposition nach rechts schieben
\end{tabular}

Wurde die falsche Ziffernkombination eingegeben und bestätigt,
erlischen alle Displays für wenige Sekunden und es ist eine erneute Eingabe möglich. \\
Wurde die richtige Ziffernkombination eingegeben und bestätigt, wird dies mit
setzen aller Displays auf 0 und erlischen des Zeigers angezeigt.
Man ist nun authentifiziert, was einem Zugriff auf das System darstellt.
In diesem Zustand stehen folgende Funktionen zur Auswahl:

\begin{tabular}{r@{: }l r@{: }l}
  \texttt{B} & Ändern des Zugangscodes \\
  \texttt{D} & Ausloggen
\end{tabular}

Der Zugangscode lässt sich nach Drücken von \texttt{B} mit der selben Steuerung
wie bei der Zifferneingabe in der Authentifizierungsphase ändern, wobei
\texttt{A} dem Bestätigen der Änderung entspricht. Dabei wird der Zugangscode
in den persistenten Speicher geschrieben und in zukünftigen Authentifizierungsphasen
abgefragt. \\
Durch Ausloggen wird der authentifizierte Zustand verlassen und man ist wieder in
der Authentifizierungsphase.

\end{document}
