\documentclass[german]{article}

\begin{document}

\title{Dallas 1–Wire mit Forth ansprechen}
\author{Bernd Paysan}
\maketitle

\begin{multicols}{2}
\begin{abstract}
  Das 1-Wire-Interface von Dallas/Maxim ist eine etwas neuere
  Alternative zu Bussen mit zwei oder drei Drähten (I²C oder SPI). Es
  gibt inzwischen eine Reihe von kleinen Geräten, die man mit dem
  Interface ansprechen kann. Der Artikel zeigt, wie das von Forth aus
  geht.
\end{abstract}

\section{Einleitung}
Wie bereits im Bericht von der Münchner Forth--Gruppe im letzten Heft
kurz angesprochen, beschäftige ich mich zur Zeit mit dem
1--Wire--Interface von Dallas. Am Beispiel eines iButton--Thermometers
zeige ich hier, wie man mit so einem 1--Wire--Gerät spricht.

Ähnlich wie I²S ist 1--Wire ein Open--Drain--Bus, d.h. ein Pullup
zieht die Leitung nach oben (und versorgt einfache Geräte wie iButtons
mit ein wenig Strom). Die Busteilnehmer haben alle einen
NMOS--Transistor, der die Leitung kurz auf 0 ziehen kann --- ein ganz
kurzer Puls ist eine 1, ein etwas längerer Puls ist eine 0, und zwei
wesentlich längere Pulse kennzeichnen Reset und die Present--Antwort
eines Gerätes.

\section{Serielle Schnittstelle}

Als Interface nutze ich den Dallas DS2480B\footnote{Datasheet:
  \url{http://datasheets.maxim-ic.com/en/ds/DS2480B.pdf}}, der
zunächst USB auf seriell umsetzt, und dann die serielle Schnittstelle
auf 1--Wire. Vom Betriebssystem (Linux) wird die USB--Zwischenschicht
im Treiber versteckt, d.h. man öffnet \verb|/dev/ttyUSB0| wie eine
serielle Schnittstelle. Lesen und Schreiben wird dann über
\verb|read-file| und \verb|write-file| erledigt.

Die serielle Schnittstelle muss ich dann noch auf die richtige
Geschwindigkeit setzen, und auch sonst noch einige Flags setzen ---
schließlich ist der DS2480B kein Terminal. Stattdessen nimmt er
Kommandos an --- solche zum Konfigurieren (die sind alle in
\verb|'stuff| untergebracht), oder solche, um den 1--Wire--Bus
anzusprechen (die sind mit Konstanten benannt).

Ich lege mir noch ein paar Buffer an, mit denen ich Daten hin- und
herschicken kann, ein \verb|>cmd|, um Kommandos zu schicken, und eine
Routine \verb|>results|, um die Resultate ohne blockierendes Warten
vom DS2480B zurückzubekommen. Damit kann ich das Protokoll jetzt
implementieren.

\section{Das 1--Wire--Protokoll}

Die Sequenz eines 1--Wire--Packets fängt mit dem Reset-- und
Present--Puls an. Danach kommt ein Byte, das als ``Master ROM Function
Command'' bezeichnet wird. Die möglichen Reaktionen:

\begin{tabular}{llp{4.3cm}}
\bf Cmd & \bf Name & \bf Daten \\ \hline
  33h & Read ROM & Device schickt 64--Bit--Adresse zurück \\
  55h & Match ROM & Device erkennt 64--Bit--Adresse \\
  F0h & Search ROM & Suche nach 64--Bit \\
  ECh & Alarm search & Suche, wenn Alarm gesetzt ist \\
  CCh & Skip ROM & Keine Adresse
\end{tabular}

Anschließend kommt dann die tatsächliche "`Nutzlast"', die Memory--
und Kontrollfunktionen. Derer gibt es bei einem iButton--Thermometer
fünf, nämlich

\begin{tabular}{llp{3.5cm}}
\bf Cmd & \bf Name & \bf Daten \\ \hline
  4Eh & Write Scratchpad & 2 Bytes Scratchpad \\
  BEh & Read Scratchpad & 9 Bytes Scratchpad \\
  48h & Copy Scratchpad & --/-- (dauert 10ms) \\
  44h & Convert Temp. & --/-- (dauert 0.75s) \\
  B8h & Recall & --/-- (Trigger Value nach Scratchpad)
\end{tabular}

In den ersten beiden Stellen des Scratchpads steht die Temperatur auf
ein halbes Grad genau, die letzten beiden (vor der Checksumme)
enthalten einen Bruch des Restwerts. Damit haben wir nun genügend
Informationen, um den Sensor am Bildschirm anzuzeigen:

\begin{figure}
  \centering
  \includegraphics{2007-0304/sensor}
  \caption{Sensor}
  \label{fig:sensor}
\end{figure}

Die Beschreibung der genauen Prozedur beim Auflisten der Devices
überlasse ich lieber dem Datenblatt von Dallas. Nur soviel: Auf dem
1--Wire--Bus werden für jedes Bit des Geräts drei Bits versendet,
dabei die ersten zwei vom Gerät, das letzte vom Master: Eins normal,
eins invertiert, und der Master dann, wie er sich entschieden hat. Auf
der seriellen Schnittstelle erhält man für diesen Vorgang zwei Bits
zurück, eines für die gewählte Adresse, das andere, ob es bei diesem
Bit einen Konflikt gab.

\section{Zusammenfassung}

Mit etwas mehr als hundert Zeilen bekommt man einen iButton--Sensor
mit Forth zum Laufen. Dallas hat auch ein User--Mode--Dateisystem für
Linux geschrieben, das die ganzen Geräte ansprechen kann. Da sind
viele tausend Zeilen Code vergraben, die zwar alle wunderschön
offengelegt sind, und auch kommentiert, aber einfach so viel, dass ich
lieber ein Reverse--Engineering--Tool (strace) angeworfen habe, um
damit dann schneller zum Ziel zu kommen.

\end{multicols}

\section{Listing}
\begin{quote}
\hrulefill 1wire.fs \hrulefill
\listinginput[1]{1}{2008-01/1wire.fs}
\hrulefill 1wire.m \hrulefill
\listinginput[1]{1}{2008-01/1wire.m}
\hrulefill
\end{quote}

\end{document}