Projektarbeit Konzeption eines RFID-Leseger atesflaemig/Studienarbeiten/RFID...September Ausgabe...

70
Projektarbeit Konzeption eines RFID-Leseger¨ ates Michel Steichen 19. Juli 2008

Transcript of Projektarbeit Konzeption eines RFID-Leseger atesflaemig/Studienarbeiten/RFID...September Ausgabe...

  • Projektarbeit

    Konzeption eines RFID-Lesegerätes

    Michel Steichen

    19. Juli 2008

  • In dieser Projektarbeit wird ein RFID-Lesegerät entworfen, welches RFID-Trans-

    ponder lesen und beschreiben kann. Der Aufbau des Gerätes ist einfach nach vollziehbar

    und besteht aus leicht beschaffbaren Bauteilen. Das entwickelte Gerät ist so konstru-

    iert, dass es zu Demonstrationszwecken auf Workshops oder Messen eingesetzt werden

    kann. Es bietet den Zuschauern somit einen kurzen Einblick in die Funktionsweise der

    RFID-Technologie.

  • Inhaltsverzeichnis

    1 Einleitung 5

    1.1 Definition von RFID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

    1.2 Der gewählte RFID-Standard . . . . . . . . . . . . . . . . . . . . . . . . 6

    1.3 Gliederung der Ausarbeitung . . . . . . . . . . . . . . . . . . . . . . . . . 6

    2 Das RFID-Lesegerät 8

    2.1 Einführung in die Theorie . . . . . . . . . . . . . . . . . . . . . . . . . . 8

    2.2 Hardware des Lesegerätes . . . . . . . . . . . . . . . . . . . . . . . . . . 9

    2.3 Technische Anleitung und Tips für den Nachbau . . . . . . . . . . . . . . 14

    3 Die Firmware 17

    3.1 Der Cross-Compiler und seine Tools . . . . . . . . . . . . . . . . . . . . . 17

    3.2 Theoretische Grundlagen . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

    3.2.1 Kommunikation von PCD zu PICC . . . . . . . . . . . . . . . . . 18

    3.2.2 Kommunikation von PICC zu PCD . . . . . . . . . . . . . . . . . 21

    3.2.3 Interaktion PICC/PCD . . . . . . . . . . . . . . . . . . . . . . . 23

    3.2.4 Fehlererkennung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

    3.3 Die MIFARE-Karte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

    3.3.1 Der Karten-Speicher . . . . . . . . . . . . . . . . . . . . . . . . . 27

    3.3.2 Der Karten-Befehlssatz . . . . . . . . . . . . . . . . . . . . . . . . 28

    3.4 Inbetriebnahme des Lesegerätes . . . . . . . . . . . . . . . . . . . . . . . 30

    4 Die PC-Software 33

    4.1 Das RFID-Paket . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

    4.1.1 Kommunikation zwischen Computer und Lesegerät . . . . . . . . 35

    4.1.2 Installation des RFID-Paketes . . . . . . . . . . . . . . . . . . . . 36

    4.1.3 Anwendung des RFID-Paketes . . . . . . . . . . . . . . . . . . . . 36

    4.2 Die JavaFX-Demo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

    3

  • 5 Zusammenfassung 40

    6 Anhang 41

    6.1 Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

    6.1.1 Platinenlayouts zum Belichten . . . . . . . . . . . . . . . . . . . . 41

    6.1.2 Bestückungsplan mit Bauteilliste . . . . . . . . . . . . . . . . . . 41

    6.2 Firmware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

    6.2.1 rfid.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

    6.2.2 rfid.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

    6.2.3 mifare.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

    6.2.4 mifare.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

    6.2.5 lcd.c/lcd.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

    6.2.6 Makefile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

    6.3 PC-Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

    6.3.1 RFIDInterface.java . . . . . . . . . . . . . . . . . . . . . . . . . . 60

    6.3.2 RFIDDevice.java . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

    4

  • 1 Einleitung

    In dieser Projektarbeit wird ein RFID-Lesegerät entwickelt, welches in der Lage ist,

    RFID-Transponder zu lesen und zu beschreiben.

    Mit dem Selbstbau dieses Gerätes zeigen wir, dass es mit einfachen und leicht erhältlichen

    Mitteln möglich ist, ein solchen RFID-Demonstrator zu bauen.

    Ein weiteres wichtiges Merkmal, ist die leicht verständliche Bedienung und Funktions-

    weise des Gerätes. Somit kann es dazu benutzt werden, die RFID-Technologie auf Messen

    oder Workshops zu veranschaulichen.

    1.1 Definition von RFID

    An dieser Stelle wollen wir dem Leser kurz erklären, was RFID eigentlich bedeutet.

    Das Akronym RFID steht für die englischen Begriffe”Radio frequency Identification“,

    was frei übersetzt soviel bedeutet wie”Identifikation anhand von elektromagnetischen

    Wellen“. Es handelt sich hierbei also um eine kontaktlose Übertragung von Daten zwi-

    schen einem Lesegerät und einem RFID-Transponder.

    Es gibt eine Reihe von unterschiedlichen RFID-Standards die sich hauptsächlich da-

    durch unterscheiden, dass sie verschiedene Frequenzbänder, beziehungsweise Übertra-

    gungsprotokolle, benutzen. In Tabelle 1.1 ist ein grober Überblick über die benutzten

    Frequenzbereiche mit einigen Beispielen für jeweils mögliche Anwendungsgebiete gege-

    ben.

    Frequenzbereich Anwendungsgebiet

    NF 30-500 kHz Tierchip (ISO 11785/11785) zur Identifikation von HaustierenHF 3–30 MHz Reisepass mit Chip, Smartcards ISO 14443A/B ISO 7816UHF 0,3–1 GHz Paletten- und Container-IdentifikationUHF 2,4–2,5 GHz Mautstationen

    Tabelle 1.1: Verschiedene RFID-Technologien

    5

  • 1.2 Der gewählte RFID-Standard

    Bei der Konzeption eines RFID-Lesegerätes, muss man sich erst einmal für einen (oder

    mehrere) der im letzten Abschnitt genannten Standards entscheiden.

    In unserem Falle, haben wir uns für die kontaktlose Chipkartentechnik von Mifare

    entschieden. Im Folgenden wollen wir diesen Entschluss erklären.

    Die Firma Mifare (Phillips) stellt die am meist benutzten RFID-Chips her. Mifare bie-

    tet eine ganze Produktpalette von Transpondern an, wie zum Beipiel: Mifare-Classic,

    Mifare-Ultralight, Mifare-DESFire um nur ein paar zu nennen. Alle Mifare Chips benut-

    zen eine Übertragungsfrequenz von 13,56 MHz und sind ganz nach dem ISO Standard

    14443A implementiert.

    In dem Frequenzbereich von 13,56 MHz ist es problemlos möglich, mit diskreten Bau-

    teilen, eine elektronische Schaltung aufzubauen die, ohne ein hochfrequenztaugliches

    Layout, einwandfrei funktioniert. In diesem Frequenzbereich redet man noch nicht von

    elektromagnetischen Wellen, der Datenaustausch erfolgt hier über induktive Kopplung

    und funktioniert somit laut [3], mit den hier benutzten Energiestärken, auch nur auf eine

    begrenzte Distanz von einigen Zentimetern bis höchstens zwei Metern.

    Ein weiteres Argument ist die relativ langsame Datenübertragung mit einer Geschwin-

    digkeit von 106 kbit/s. Somit ist es problemlos möglich, die empfangenen Daten anhand

    eines Standard-Mikrocontrollers (AVR, PIC, . . . ) auszuwerten.

    Unter anderem besitzt die Mifare-Ultralight-Karte einen EEPROM-Speicher mit einer

    Größe von 64 Byte, der ohne Verschlüsselungsalgorithmen ausgelesen und beschrieben

    werden kann.

    Schlussendlich ist das benötigte Know-how, um die Kommunikation mit einem Mifare

    RFID-Transponder zu realisieren, leicht erhältlich. Die ISO-Norm [3] gibt es im Internet

    als Draft-Version herunterzuladen und auf der Mifare-Webseite, bietet die Firma sehr

    genaue Informationen über ihre Produkte im Download Bereich an.

    1.3 Gliederung der Ausarbeitung

    Die folgende Ausarbeitung ist in drei große Kapitel gegliedert.

    Kapitel 2 beschreibt die Hardware des RFID-Lesegerätes und vermittelt alle benötigten

    Informationen um das Gerät nachzubauen. Die benutzte elekronische Schaltung stammt

    aus [1] und wurde vollständig übernommen. Für unsere Zwecke wurde die Schaltung um

    6

  • eine USB-Schnittstelle erweitert. Die gesamte Firmware wurde neu programmiert, sowie

    ein geeignetes Platinen-Layout für die neue Schaltung entwickelt.

    In Kapitel 3 werden wir auf unsere Firmware des Lesegerätes eingehen. Wir beschäftigen

    uns dabei mit der Theorie, wie eine Kommunikation zwischen RFID-Lesegerät und

    RFID-Transponder zustande kommt.

    Kapitel 4 beschreibt unsere PC-Software die zum Einsatz kommt, um das Lesegerät

    an einen Computer anzuschließen und zu steuern.

    Zum Abschluss unserer Arbeit zeigen wir dann noch kurz, wie und wo unser Lesegerät

    zu Demonstrationszwecken eingesetzt werden kann.

    7

  • 2 Das RFID-Lesegerät

    Das in unser Projektarbeit entworfene RFID-Lesegerät basiert auf einem Artikel aus der

    September Ausgabe 2006 der Zeitschrift Elektor [1]. Die Autoren beschäftigten sich mit

    der Frage, ob es machbar sei ein RFID-Lesegerät anhand von einfach erhältlichen und

    diskreten Bauteilen zu entwerfen. Das dies möglich ist, wurde in dem genannten Artikel

    gezeigt und soll nun noch einmal in dieser Ausarbeitung detailliert nachvollzogen werden.

    Das hier vorgestellte Gerät benutzt keine speziellen, für RFID ausgelegte, integrierte

    Schaltungen und überzeugt zudem mit der geringen Anzahl an verwendeten Bauteilen.

    Aus den teilweise übernommenen Schaltplänen, wurde mit Hilfe von Eagle [2] eine Plati-

    ne erstellt. Das Lesegerät wurde außerdem noch mit einer USB-Schnittstelle ausgerüstet,

    sowie einer LED-Lichterkette die mittels Software ein- und ausgeschaltet werden kann.

    Der genaue Sinn und Nutzen dieser Lichterkette wird in Kapitel 4 erläutert.

    Die Funktionen des Lesegerätes lassen sich alle (bis auf die Schreibfunktion) ohne PC,

    mit Hilfe eines kleinen Tastenfeldes und einem LCD-Display ausführen. Für erweiter-

    te Funktionalitäten lässt sich das Gerät per Software, über die USB-Schnittstelle eines

    Rechners ansteuern.

    In den folgenden Unterkapiteln wird nun der Hardware-Aufbau und die Funktionsweise

    der Schaltung beschrieben. Die Begriffe PCD (Proximity Coupling Device) und PICC

    (Proximity Integrated Circuit Card) benutzen wir gleichbedeutend zu RFID-Lesegerät,

    beziehungsweise RFID-Transponder.

    2.1 Einführung in die Theorie

    Um den Aufbau des Lesegerätes zu verstehen, geben wir eine grobe Beschreibung des

    Ablaufes einer kontaktlosen Datenübertragung zwischen PCD und PICC. Sämtliche

    benötigten Informationen für die Implementierung der Firmware und Software wurden

    dabei der Draft-Version der ISO-Norm 14443A [3] und dem Datenblatt [4] für Mifare-

    Ultralight-Karten entnommen.

    8

  • Zu Beginn jedes Datenaustausches, baut das Lesegerät ein elektromagnetisches Feld

    auf. In unserem Falle schwingt dieses Feld mit einer Frequenz von 13,56 MHz. Befindet

    sich jetzt eine PICC in Reichweite dieses Feldes, so wird sie mittels induktiver Kopplung

    mit Energie versorgt. Die PICC befindet sich dann in einem Wartezustand und ist bereit

    Befehle vom PCD zu empfangen.

    Das Senden eines Befehles von PCD nach PICC erfolgt mittels 100% Amplitudenmo-

    dulation des Trägers. Das bedeutet, das Energiefeld wird in der Tat vollständig ein- und

    ausgeschaltet. Dabei werden die zu übertragenden Bits so codiert, dass das Trägersignal

    immer nur für kurze Zeit ausgetastet wird. Somit bleibt die PICC mit Energie versorgt

    und kann die gesendete Bitfolge empfangen und verarbeiten.

    Die Antwort der PICC erfolgt ebenfalls mittels Amplitudenmodulation. Der RFID-

    Chip schaltet dazu, im Takte seiner Modulationsfrequenz, eine auf die Trägerfrequenz

    abgestimmte Last ein und aus. Dadurch wird dem Hochfrequenzfeld Energie entzogen

    und es bricht bei jedem Modulationsvorgang teilweise ein. Auf Seiten des Lesegerätes

    lassen sich diese Belastungen detektieren und entsprechend wieder dekodieren.

    Der letzte Abschnitt soll nur einen groben Einblick in die Funktionsweise einer kon-

    taktlosen Datenübertragung geben. Eine genauere und detaillierte Erklärung wird es in

    Kapitel 3 geben.

    2.2 Hardware des Lesegerätes

    Es folgt nun ein Überblick über die einzelnen Teile aus denen das Lesegerät besteht. Die

    fünf Hauptkomponenten lassen sich deutlich auf dem Platinen-Entwurf in Abbildung 2.1

    erkennen.

    a) die Sendeschaltung

    b) die Empfangsschaltung

    c) die digitale Auswertungseinheit mit Ein- und Ausgabeports

    d) die USB-Schnittstelle

    e) die Sende- und Empfangsantenne

    Auf dem Board gibt es außerdem noch drei weitere Schnittstellen:

    9

  • Abbildung 2.1: Platinenentwurf des Lesegerätes

    f) zum Anschließen eines LCD-Displays

    g) ISP-Schnittstelle zum Brennen der Firmware

    h) Anschluss für eine vier Tasten-Tastatur

    Auf Seite 11 ist der Schaltplan des Lesegerätes wiedergeben, anhand dessen nun die

    Funktionsweise und Aufgabe der einzelnen Komponenten nachvollzogen werden kann.

    a) die Sendeschaltung

    Die Sendeschaltung besteht aus einem digitalen Quarzoszillator und einer, aus zwei

    MOSFETs T1 und T2 bestehenden, Gegentaktstufe, um die vom Oszillator erzeugte

    Schwingung zu verstärken. Die digitale Schwingung wird sowohl für die Taktung des Mi-

    krocontrollers benutzt, als auch für die Erzeugung des Hochfrequenz-Feldes (HF-Feld).

    Die Entscheidung der Elektor-Autoren, den Mikrocontroller mit der Schwingfrequenz

    des HF-Feld zu takten, hat bei der späteren Programmierung der Firmware erhebli-

    che Vorteile. Das von der Gegentaktstufe verstärkte Signal gelangt nun auf den Serien-

    schwingkreis L1, C4. Mit dem Kondensator C4, der als Trimmer ausgelegt ist, lässt sich

    die maximale Amplitude des HF-Feldes einstellen. Mit Hilfe eines Einganges von Gatter

    IC1.B kann der Mikrocontroller das HF-Feld amplitudenmodulieren. Der Modulations-

    grad soll laut Norm 100% betragen, das heißt das HF-Feld wird immer vollständig ein-

    10

  • Abbildung 2.2: Schaltplan des Lesegerätes

    11

  • und ausgeschaltet.

    b) die Empfangsschaltung

    In der Empfangsschaltung wird das von dem RFID-Chip modulierte HF-Feld demo-

    duliert und anschließend digitalisiert. Wie man mit der Thomsonschen Schwingungs-

    formel überprüfen kann, liegt die Resonanzfrequenz des L7/C10 Schwingkreises bei

    ungefähr f = 12π√L7C10

    = 16.283·

    √3.3·10−14 = 876 kHz. Somit ist der Empfangskreis auf

    die 13.56 MHz/16 = 847,5 kHz Modulationsfrequenz der Mifare-Karte abgestimmt. Am

    Ausgang des Komparators steht nun das digitalisierte Signal zu Verfügung, welches vom

    Mikrocontroller weiterverarbeitet werden kann

    c) die digitale Auswertungseinheit mit Ein- und Ausgabeports

    Das Herzstück des Lesegerätes besteht aus einem ATmega16 von Atmel [5]. Dieser Mi-

    krocontroller ist mit 16 kB Flash, 1 kB Ram und einer maximalen Taktfrequenz von

    20 MHz bestens für die Aufarbeitung der empfangenen Daten geeignet. Der Mikrocon-

    troller sendet und empfängt nicht nur die Daten. Er muss sie auch codieren und de-

    kodieren. Des Weiteren muss er die Parität und die CRC-Checksumme der empfangen

    und gesendeten Daten berechnen. Er bietet dem Nutzer außerdem noch die Möglichkeit,

    die auszuführenden Befehle über eine Menüsteuerung mit Hilfe der Mini-Tastatur aus-

    zuwählen.

    d) die USB-Schnittstelle

    Um eine USB-Anbindung an den PC zu realisieren wurde der FT232RL-Chip von der

    Firma FTDI [6] verbaut. Der FT232 ist ein bidirektioneller USB/UART-Umsetzer. Er

    besitzt zudem einen internen EEPROM, der unterschiedliche Konfigurationen des Con-

    trollers ermöglicht (in unserem Projekt gehen wir von der Standardkonfiguration aus,

    die der Controller bei der Auslieferung hat). Er lässt sich problemlos an den internen

    UART des Mikrocontrollers anschließen. Die Kommunikation zwischen Mikrocontroller

    und FT232 erfolgt dabei seriell mit Hilfe von zwei Leitungen (TX, RX). Auf der anderen

    Seite kommuniziert der FT232 über USB mit dem PC. Der Hersteller bietet auf seiner

    Homepage, für alle gängigen Betriebssysteme (Mac OS X, Linux und Windows), gratis

    Treiber zum Herunterladen an. Nach der Installation der Treiber erscheint ein virtuel-

    ler serieller Port am Computer. Die Programmierung der PC-Software lässt sich daher

    ohne spezielle USB-Kenntnisse bewerkstelligen. Man muss lediglich mit dem virtuellen

    seriellen Port arbeiten. Die Umsetzung USB auf UART übernimmt dieser kompakte

    12

  • SMD-Chip (Surface Mounted Device) ganz von alleine.

    Eine weitere Funktionalität des FT232, die hier benutzt wurde, ist das Anbringen

    von zwei LEDs die die Zustände der RX und TX Leitungen wiedergeben sollen. Per

    Standard Einstellung werden diese Signale auf die ersten beiden, der vier I/O Pins des

    FT232, ausgegeben. Anhand der Aktivitäten der beiden LEDs kann der Benutzer leicht

    erkennen, ob gerade ein Datenaustausch zwischen PC und Lesegerät vonstatten geht.

    e)die Sende- und Empfangsantenne

    Die Sende- und Empfangsantenne finden ihren Platz auf einer 5 x 6,5 cm großen Platine.

    Es handelt sich dabei um zwei verschachtelte Luft-Spulen die mit Hilfe von Leiterbah-

    nen realisiert worden sind. Eine der beiden Windungen dient dabei als Sendeantenne

    (es ist dabei unerheblich für welche man sich entscheidet), die andere Windung wird

    als Schnüffelsonde für den Empfang benutzt. Zum Lesen und Beschreiben eines RFID-

    Transponders, wird dieser einfach auf die Antenne aufgelegt.

    f)LCD-Anschluss

    Der 14-polige Wannenstecker dient zum Anschluss des LCD-Displays. Für den Bau des

    Lesegerätes kam dabei ein zweizeiliges, unbeleuchtete Display mit jeweils 24 Zeichen pro

    Zeile zum Einsatz. Bei dem LCD handelt es sich um einen HD44780 kompatiblen Typ

    mit nur einer positiven Spannungsversorgung, also ohne negative Hilfsspannung. Die

    Programmierung erfolgt über vier Datenleitungen und drei Steuerleitungen. Mit dem

    Potentiometer neben dem Wannenstecker lässt sich der Kontrast des Displays einstellen.

    g)ISP-Schnittstelle

    Der kleinere zehn-polige Wannenstecker dient als ISP-Schnittstelle (In System Program-

    mer). Mit diesem Anschluss lässt sich die Firmware des AVRs brennen und updaten, ohne

    ihn für diesen Zweck ausbauen zu müssen.

    h)Tastatur-Anschluss

    An diese Anschlüsse werden die vier Taster für die Menüsteuerung, sowie ein Reset-

    Taste angeschlossen. Somit kann man bequem mittels einer vorwärts und rückwärts

    Taste durch das, mit dem Display, angezeigte Menü navigieren. Die Auswahl eines

    Menüeintrags erfolgt mit der Enter-Taste. Mit der Menü-Taste kann man dann wie-

    der elegant ins Hauptmenü zurückspringen.

    13

  • Der Nachbau des Lesegerätes ist im Prinzip einfach und unkritisch. Im nächsten Ab-

    schnitt soll jedoch noch einmal kurz darauf eingegangen werden.

    2.3 Technische Anleitung und Tips für den Nachbau

    In diesem Abschnitt beschreiben wir, wie die Anfertigung des Gerätes von statten ging.

    Die Grundplatine wurde mit einem selbstgebauten UV-LED-Belichtungsgerät belich-

    tet. Als beschichtetes Basismaterial diente dazu eine Platine des Herstellers Bungard.

    Mit einem 0.8 mm Bohrer wurden dann die Löcher für die Bauteile gebohrt. Bohrlöcher

    für Potentiometer und Wannenstecker wurden mit einem 1 mm Bohrer vergrößert. Das

    Löten der Bauelemente erfordert keine besonderen Maßnahmen mit Ausnahme des USB-

    Controllers, welcher leider nur in einer SMD-Ausführung im SSOP-Gehäuse verfügbar

    ist. Hierbei ist besonders viel Fingerspitzengefühl gefragt. Für das Löten von SMD-

    Bauteilen sind Werkzeuge und Materialen wie ein feiner Lötkolben, Flußmitteldispenser

    (FL 88 FLUXI), Entlötlitze und SMD-Lötzinn, mit 0,5 mm Durchmesser, unverzicht-

    bar. Besonders bewährt hat sich dabei die Methode die feinen SMD-Leiterbahnen zu-

    erst mit Lötzinn zu verzinnen. Anschließend wird Flußmitteldispenser auf die Leiter-

    bahnkontakte gegeben, das SMD-Teil auf der Platine positioniert und jeweils an zwei

    gegenüberliegenden Ecken angelötet. Bis dahin lassen sich noch leichte Positionskorrek-

    turen bewerkstelligen. Ist das Bauteil richtig ausgerichtet, fährt man mit der Lötspitze

    über sämtliche Beinchen des Bauteiles. Dabei schmilzt das vorher aufgetragene Lötzinn

    und verbindet die Anschlusskontakte des Bauteils mit der Platine. An den Stellen wo sich

    kleine Zinnbrückchen gebildet haben, wird das überflüssige Lötzinn mit der Entlötlitze

    entfernt. Man sollte auf jeden Fall sehr sparsam mit dem Lötzinn umgehen.

    Das Löten des SMD-Bauteiles hört sich anspruchsvoll an, lässt sich aber mit der ge-

    gebenen Anleitung problemlos durchführen.

    Im Anhang befindet sich ein Ausdruck des einseitigen Platinenlayoutes. Es kann als Be-

    lichtungsvorlage dienen um das Gerät nachzubauen. Eine Liste der benötigten Bauteile

    gibt es ebenfalls im Anhang. Alle verbauten Bauelemente lassen sich problemlos in je-

    dem guten Elektronikladen besorgen (zum Beispiel Reichelt [7]). Lediglich der 13,56 MHz

    Quarz war schwieriger zu bekommen und muss gegebenenfalls extra bestellt werden.

    Da das Lesegerät als autonomes, oder an einen Computer angeschlossenes, Demons-

    14

  • Abbildung 2.3: Das RFID-Lesegerät

    trationsgerät dienen soll wurde auch das Gehäuse-Layout dementsprechend angefertigt.

    Wie in Abbildung 2.3 zu erkennen ist besteht das”Sandwich-Gehäuse“ aus zwei Ple-

    xiglasscheiben, welche mit vier Bolzen zusammengeschraubt sind. Die untere Scheibe

    nimmt dabei die ganze Platine mit Tastatur auf. Auf der oberen Scheibe befindet sich

    das Display und von unten durchleuchtend ist die Antennen-Platine erkennbar. Durch

    diese Konstruktion lässt sich ein wunderbarer Einblick in das elektronische Innenleben

    des Gerätes geben, was für Vorführungszwecke besonders sinnvoll ist.

    Die 5V-Spannungsversorgung des Gerätes erfolgt über die USB-Schnittstelle. Somit

    ist beim Computerbetrieb kein weiteres externes Netzteil von Nöten. Aus Sicherheits-

    gründen sollte jedoch immer ein aktiver USB-Hub zwischen Gerät und Computer ge-

    schaltet werden. Zu einem wird bei einer Fehlfunktion des Gerätes (Fehler beim Löten)

    nicht der USB-Port des Computers zerstört. Und zum zweiten bietet der Hub eine kon-

    stante Stromquelle für das Lesegerät.

    In Kapitel 4 dieser Ausarbeitung geben wir noch ein Beispiel, wie das Lesegerät zu

    Demonstrationszwecken genutzt wird.

    Wie man aus diesem Kapitel leicht erkennen kann, hält sich der Hardware-Aufwand

    15

  • sehr in Grenzen. Der Hauptteil der Arbeit bestand darin, die Funktionsweise der be-

    nutzten RFID-Technologie zu verstehen, sowie den Mikrocontroller für diesen Zweck am

    geeignetsten zu programmieren.

    Das nächste Kapitel widmet sich also ganz der Theorie wie RFID funktioniert, sowie

    der Beschreibung der implementierten Firmware.

    16

  • 3 Die Firmware

    Wie schon angedeutet funktioniert ohne die geeignete Firmware gar nichts. Vor der ersten

    Inbetriebnahme der Hardware muss also erst einmal eine geeignete Steuersoftware in den

    Speicher des Mikrocontrollers geladen werden. Im folgenden Kapitel wird genau erklärt,

    wie wir dabei vorgegangen sind. Im Anhang zu dieser Ausarbeitung befindet sich der

    vollständige und funktionstüchtige Quelltext der Firmware. Da für die Entwicklung der

    Firmware recht umfangreiche Informationen benötigt werden, haben wir uns entschlossen

    dieses Wissen nach dem Top-down Prinzip zu vermitteln. Zu Anfang geben wir erst

    einmal einen globalen und abstrakten Überblick über die Technologie, um dann nach

    und nach detaillierte und grundlegende Kenntnisse zu vermitteln.

    3.1 Der Cross-Compiler und seine Tools

    In diesem Unterkapitel werden wir den benutzten Compiler, sowie weitere Tools vor-

    stellen, die für die Erzeugung der Firmware unerlässlich sind. Besonders praktisch und

    finanziell günstig ist die Tatsache, dass alle benutzte Programme und Tools unter der

    GNU General Public License (GPL) stehen und somit kostenlos aus dem Internet zu

    beziehen sind.

    Zum Programmieren des Mikrocontroller bietet sich besonders die Programmierspra-

    che C an. Als High-Level-Programmiersprache lassen sich mit ihr sehr schnell, kom-

    plexere Algorithmen implementieren. Des Weiteren ist auch die Lücke zwischen der

    C-Sprache und der unterliegenden Hardware (in unserem Fall der ATmega16 ) recht

    klein und somit Hardware-nahe. Das ist sehr wichtig, da wir uns sehr genau mit der

    Hardware beschäftigen und gegebenenfalls mit Assembler optimieren müssen. Ein wei-

    terer Vorteil für die in reinem C (ohne AVR-Assembler) programmierten Funktionen ist,

    dass sich die Möglichkeit anbietet den Code auf dem Computer auszuführen und auf

    eventuelle Fehler zu untersuchen. Dies war beispielsweise bei der Implementierung der

    CRC-Berechnungsfunktion sehr hilfreich. Ein Debuggen mit dem Mikrocontroller hätte

    die Entwicklungsarbeit nur sinnlos erschwert.

    17

  • Der größte Teil der Firmware wurde wegen der oben genannten Gründen in C pro-

    grammiert. Nur die zeitkritischen Funktionen wurden in AVR-Assembler implementiert.

    Der C-Code wurde mit dem Xcode-Editor von Mac OS X geschrieben und verwaltet.

    Da der gesamte Quelltext nur aus sechs Dateien besteht, wäre es auch durchaus möglich

    den Code in dem VIM-Editor zu schreiben und somit dem Konzept der kostenlosen

    Software gerecht zu bleiben. Zum Übersetzen des Quelltextes benutzen wir die Version

    4.0.2 des avr-gcc-Compilers. Der vom avr-gcc gelieferte binäre Code muss aber noch mit

    dem Tool avrobj in einen für den Mikrocontroller verträglichen Objektcode konvertiert

    werden. Die somit erzeugte Hex-Datei kann nun mit dem Programm avrdude und einer

    geeigneten Brennhardware auf den Mikrocontroller übertragen werden. Das Tool avr-

    dude unterstützt eine ganze Palette von Brennhardware. Wir haben uns hier für den

    günstigen mySmartUSB-Brenner von myAVR [8] entschieden. Um nicht jedes Mal die

    ganzen Kommandos eingeben zu müssen, wurde eine kleine Makefile erstellt, an welcher

    man sich im Anhang inspirieren kann. Beispielsweise bei einer Shell-Eingabe wie make

    burn wird der Quellcode kompiliert und der internen Speicher des AVRs geflasht.

    Nach diesem kurzen Überblick über die benutze Software, kommen wir nun zu den

    theoretischen Grundlagen die im weiteren Verlauf benötigt werden.

    3.2 Theoretische Grundlagen

    Um den genauen Ablauf einer PCD/PICC-Kommunikation auf der Bit-Ebene zu ver-

    stehen soll hier eine Sende- und Empfangsfunktion für das RFID-Lesegerät beschrieben

    werden.

    3.2.1 Kommunikation von PCD zu PICC

    Wie schon im zweiten Kapitel kurz angedeutet erfolgt der Datenaustausch mittels Am-

    plitudenmodulation des HF-Feldes.

    Als erstes soll nun erklärt werden wie die einzelnen Bits eines Bytes übertragen wer-

    den. Die Dauer eines Bits ist dabei auf 128/fc Sekunden festgelegt. Die Taktfrequenz

    fc (clock frequency) des Mikrocontrollers entspricht dabei genau 13,56 MHz, ist also

    identisch mit der Frequenz des benutzten Trägers. Diese Konstante wird im weiteren

    Textverlauf immer wieder auftreten, da sich von ihr sämtliche Wartezeiten und andere

    Modulationsfrequenzen ableiten lassen. Demnach entspricht die Zeitdauer, im folgen-

    den mit ETU (Elementry Time Unit) bezeichnet, eines Bits ungefähr 128/13,56 MHz

    18

  • Abbildung 3.1: Die drei benutzten Sequenzen

    = 9,44µs. Die Kodierung der Bits auf seitens des PCB erfolgt nach dem Miller-Code.

    Dabei wird ein Bit nur während einer Teilzeit seiner gesamten ETU ausgetastet, in un-

    serem Fall beträgt diese Teilzeit immer genau ein Viertel einer ETU. Abbildung 3.1 soll

    die drei verschieden Sequenzen verdeutlichen, mit denen die Bits kodiert werden. Bei

    der Sequenz X sieht man, dass das Bit nach der ersten Hälfte für eine Zeitspanne von

    ETU/4 ausgetastet wird. Bei der Sequenz Y erfolgt keine Austastung und bei Z wird

    am Anfang für eine Zeitdauer von ETU/4 ausgetastet. Wie aus dieser Kodierung leicht

    ersichtlich ist, sind die Zeiten während denen ausgetastet wird, das Hochfrequenzfeld

    also ausgeschaltet wird, nur sehr kurz. Dies ist durchaus erwünscht, da das HF-Feld

    nicht nur als Übertragungsmedium benutzt wird, sondern den PICC auch mit Energie

    versorgen muss.

    Nachdem wir die Kodierungsmuster kennengelernt haben soll nun in der Tabelle 3.1

    erklärt werden wann jeweils eine der drei Sequenzen benutzt wird, um jeweils eine logi-

    sche 1 oder eine logische 0 zu kodieren.

    19

  • Information Benutztes Muster

    Logische 1 X-SequenzLogische 0 Y-Sequenz mit den folgenden beiden Ausnahmen:

    1. Falls zwei oder mehrere hintereinander kommende lo-gische

    ”0“en zu übertragen sind, wird ab der zweiten

    logischen”0“ die Z-Sequenz benutzt.

    2. Wenn das erste Bit nach einem Übertragungsanfangeine logische

    ”0“ ist, so wird die Z-Sequenz für diese Bit

    benutzt und für alle direkt darauf folgenden logischen

    ”0“en.

    Start einer Übertragung Z-SequenzEnde einer Übertragung Logische

    ”0“ mit darauffolgender Y-Sequenz (0Y)

    Keine Datenübertragung Mindestens zwei Y-Sequenzen

    Tabelle 3.1: Benutzungsregeln

    Die Daten Bits Die kodierte Sequenz

    Z Z (Startsequenz)0 Z0 Z1 X1 X0 Y0 Z1 X0 Y0 Z (Endsequenz)Y Y (Endsequenz)

    Tabelle 3.2: Benutzungsregeln

    Um die Anwendung dieser Kodierungsregeln besser zu verstehen, erklären wir sie

    anhand eines kleinen Beispiels. Wählen wir willkürlich die hexadezimale Zahl 0x32.

    Ihre binäre Darstellung als Byte (8 Bit, falls nötig die höherwertigen Bits mit 0en

    auffüllen) entspricht 00110010. Aus der Tabelle 3.1 können wir entnehmen, dass ein

    zu übertragendes Byte immer mit einer Startsequenz Z eingeleitet wird und mit einer

    ”0Y“ Sequenz aufhört. Unser Byte sieht also dann wie folgt aus: Z001100100Y. Da das

    erste Bit eine logische Null ist wird es mit der 2. Ausnahmeregel für logische”0“ co-

    diert. Die vollständige Kodierung sieht dann wie folgt aus ZZZXXYZXYZY und lässt

    sich anhand der Tabelle 3.2 gut nachvollziehen. Aus Vollständigkeitsgründen sollte noch

    erwähnt werden, dass bei einer Übertragung die Reihenfolge der Bits erst umgedreht

    20

  • Abbildung 3.2: Manchester-Kodierung

    wird. Das bedeutet das erste übertragende Bit ist also immer das niedrigstwertige Bit

    (LSB), das letzte Bit das MSB. Außerdem ist bei einigen PICC-Befehlen die Länge des

    Befehls nicht 8 Bit sondern nur 7 Bit.

    3.2.2 Kommunikation von PICC zu PCD

    Die Datenübertragung von der PICC zum PCD erfolgt ebenfalls mittels Amplituden-

    modulation. Dazu schaltet die PICC periodisch eine interne, auf die Trägerfrequenz fc

    abgestimmte Last, ein und aus und kann somit dem Hochfrequenzfeld Energie entziehen.

    Der PCD kann nun, anhand dieser Amplitudeneinbrüche des Trägersignals, eine Ant-

    wort der PICC erkennen. Die Zeitlänge eines übertragenen Bits entspricht auch hier der

    im letzten Abschnitt definierten Zeitdauer ETU. Der eigentliche Unterschied taucht in

    der abweichenden Bit-Kodierung auf. Und zwar werden die Bits nach der Manchester-

    Methode übertragen. Somit wird eine logische 1 in der ersten Hälfte seiner ETU-Dauer

    moduliert und eine logische 0 während der zweiten Hälfte (wie in Abbildung 3.2 verdeut-

    licht). Wichtig hierbei zu verstehen ist die Tatsache, dass die PICC beim modulieren das

    Hochfrequenzfeld nicht während der ganzen ETU/2 Zeit belastet, vielmehr wird mit einer

    Unterträgerfrequenz fc/16 ( 847,5 kHz ) die Last periodisch ein- und ausgeschaltet. Man

    muss bedenken, dass jeder Amplitudeneinbruch des HF-Feldes eine kurze Energiever-

    sorgungsabschaltung für die PICC bedeutet. Durch einen internen Speicherkondensator

    kann die PICC diesen Energieentzug kurzzeitig überbrücken. Durch die benutzte Kodie-

    rung wird garantiert, dass diese Ausfälle so gering wie möglich bleiben. In Bild 3.3 soll

    veranschaulicht werden, wie eine solche Amplitudenmodulation der PICC aussieht.

    Die Sinusschwingung des HF-Feldes ist hier als durchgehender schwarzer Balken dar-

    gestellt. Dies ist damit zu begründen, dass die ETU-Zeitlängen 128 mal länger sind

    als eine Periodendauer der Trägerfrequenz. Dementsprechend wäre die Sinusform des

    Trägers in dem gewählten Maßstab nicht mehr deutlich zu erkennen. Die Stellen an de-

    21

  • Abbildung 3.3: Oszillogramm

    Sequenz Beschreibung

    D-Sequenz Der Träger wird während der ersten Hälftevon ETU moduliert

    E-Sequenz Der Träger wird während der zweiten Hälftevon ETU moduliert

    F-Sequenz Träger wird während der ganzen Dauer vonETU nicht moduliert

    Logische”1“ D-Sequenz

    Logische”0“ E-Sequenz

    Start einer Übertragung D-SequenzEnde einer Übertragung F-SequenzKeine Datenübertragung Träger bleibt unmoduliert

    Tabelle 3.3: Manchester-Verfahren

    nen das HF-Feld zum Teil einbricht, sind die Zeiten während denen moduliert wird. Die

    schwarzen Striche, die in diesen Lücken eingezeichnet sind, sollen die Amplitudenspit-

    zen der 847,5 kHz Modulationsfrequenz der PICC schematisieren. Es wurden bewusst

    vier solcher Striche eingezeichnet, da eine Periodendauer der Modulationsfrequenz des

    PICC 16/fc lange dauert und somit passen genau vier solcher Sinusschwingungen in

    einen Zeitspalt der Länge ETU/2 ( 16/fc * 4 = 64/fc = ETU/2).

    In Tabelle 3.3 sind die Kodierungsregeln für das benutzte Manchester-Verfahren aufge-

    listet. Diese Regeln wurden in Bild 3.3 angewendet und die somit dekodierte Information,

    welche in dem gezeichneten Oszillogramm enthalten ist, in binärer Darstellung unten-

    drunter geschrieben. Die eigentlichen Nutzdaten bestehen in diesem Beispiel lediglich aus

    der Bitfolge 101. Die erste 1 aus der dekodierten Bitfolge 11010 dient zur Ankündigung

    eines Übertragungsanfangs und die 0 am Schluss, mit anschließender F-Sequenz (Aus-

    bleiben der Modulation) soll das Ende der Übertragung kennzeichnen.

    22

  • Mit den ausführlichen Hinweisen und Erklärungen aus den letzten beiden Unterkapi-

    teln, soll nun die Interaktion zwischen PICC und PCD erläutert werden.

    3.2.3 Interaktion PICC/PCD

    In dem folgenden Abschnitt erklären wir ausführlich wie eine Kommunikation zwischen

    einem PCD und einer PICC von statten geht. Die Sende- und Empfangsfunktion, die in

    der Firmware des Lesegerätes enthalten ist, wurde dementsprechend implementiert. Eine

    wesentliche und praktische Gegebenheit, der wir uns zu Nutze machen, ist dass die PICC,

    laut der zugrunde liegenden ISO-Norm, mindestens nach einer festdefinierten Zeitspan-

    ne auf eine Anfrage des PCD antwortet. Diese Mindestzeit zwischen zwei aufeinander

    folgenden Übertragungsrahmen beträgt laut Spezifikation 948/fc, also 69,91µs. Deswei-

    teren lässt sich aus dem Mifare-Datenblatt[4] entnehmen, dass die maximale Länge einer

    PICC-Antwort auf 163 Bits beschränkt bleibt. Wie man auf die Berechnung dieser Zahl

    kommt wird im Verlauf dieses Kapitels erläutert. Unsere Sende- und Empfangsmethode

    implementieren wir also dementsprechend um einen potenziellen Empfang von einer 163

    langen Bit-Sequenz zu gewährleisteten.

    Aus diesen beiden Informationen, frühstmögliche Antwort der PICC und maximale

    Rahmenlänge, steht einer erfolgreichen Programmierung einer funktionsfähigen Sende-

    und Empfangsmethode nichts mehr im Wege.

    Die Funktion wurde komplett in Assembler implementiert, da es sich hierbei um zeit-

    kritische Programmabläufe handelt. Würde man hierfür C benutzen, könnten je nach

    gewählten Optimierungsoptionen und Compilerversionen, erhebliche Unterschiede in der

    binären Objektdatei entstehen und die korrekte Funktionalität der Firmware wäre nicht

    mehr gewährleistet.

    Die Kommunikation zwischen PCD und PICC wird immer vom PCD gestartet. Be-

    findet sich eine PICC in Reichweite, antwortet sie nach einer gewissen Wartezeit und

    steht dann für weitere Anfragen des PCD zu Verfügung. Aus diesem Grunde wurde das

    Senden und Empfangen von Informationen auch in einer Methode implementiert.

    Die meisten Befehle unseres µC werden in einem Taktzyklus ausgeführt, so auch der

    NOP-Befehl (NO Operation). Wie schon erwähnt arbeitet der Mikrocontroller ebenfalls

    mit der Taktfrequenz von fc. Da sämtliche Warte-, Bit- und Modulationszeiten immer

    ganze vielfache der Periodendauer von fc sind, lassen sich diese Wartezeiten somit sehr

    exakt nachbilden.

    23

  • Die zu versendeten Daten stehen in einem 82 Byte großem Puffer zum Abruf bereit.

    Die Überlegung besteht darin das Senden von Daten so leicht wie möglich zu machen

    und das auf Kosten von Ram-Speicher, der aber mit einem Kilobyte völlig ausreicht.

    Sämtliche Daten im Puffer sind schon nach dem Muster des zu erzeugenden Sendesi-

    gnals abgespeichert. Wie schon am Anfang dieses Kapitel erklärt, werden die Datenbits

    mit dem Miller-Code übertragen. Dazu wird ein Datenbit in vier gleiche Teilzeiten ein-

    geteilt, und jedem dieser Teilzeiten wird ein Bit aus dem Puffer geopfert. Beispielsweise

    werden für ein zu übertragendes Datenbit das mit der X-Sequenz kodiert wird, die vier

    Bits 1101 in den Puffer geschrieben. Der Puffer wird nun sequenziell durchlaufen und

    der Wert des aktuell gelesenen Bits (eins oder null) bestimmt, ob das HF-Feld ein- oder

    ausgeschaltet wird. Zwischen zwei solcher Bits muss natürlich ETU/4 = 2,35µs lange

    gewartet werden. In anderen Worten wir führen eine Folge von ETU/4 = 128/4 = 32

    NOP-Befehlen aus und lassen somit die erwünschte Zeit von 2,35µs verstreichen. Oder

    eleganter formuliert wir führen eine kleine nichts tuende Schleife aus die nach 32 Taktzy-

    klen abbricht. Aus technischen Gründen müssen wir auch noch die Zeit beachten, die der

    µC braucht um den gewünschten Wert an einem I/O-Port einzustellen. Beim ATmega16

    dauert das ungefähr ein Taktzyklus lang. Nach dem erfolgreichen Senden eines Befehles

    von Seiten des PCD warten wir, wie weiter oben schon gesagt, mindestens 69,91µs auf

    eine Antwort. Nach dieser vorgeschriebenen Wartezeit ist der µC bereit eine Antwort

    seitens der PICC zu erhalten. Dazu lassen wir noch einmal zusätzliche 32 Zyklen ver-

    streichen, um dann jeweils zweimal während jeder ETU-Zeiteinheit das empfange Signal

    abzutasten und das Resultat in den Datenpuffer zu speichern. Diese zusätzliche Wartezeit

    von einem Viertel einer ETU-Zeit, garantiert uns, dass wir das Empfangssignal immer in

    der Mitte der ersten und der zweiten Bithälfte abtasten. Diese Methode ermöglicht eine

    korrekte Interpretation des Empfangssignals. Würden wir am Anfang oder am Schluss

    einer Bithälfte abtasten, könnten Lesefehler entstehen, da mögliche high-low oder low-

    high Zustandsübergänge einen nicht definierten Zustand bilden können. Die empfangen

    Daten werden dann der Reihe nach in dem Puffer abgespeichert, wobei bei der Datenaus-

    tauschrichtung PICC zu PCD ein übertragenes Datenbit (wegen Manchester-Codierung)

    nur noch zwei Bits aus dem Puffer benötigt.

    Aus den während des Baus des Lesegerätes gesammelten Erfahrungen haben wir festge-

    stellt, dass es bei einer Datenübertragung durchaus zu längeren Verzögerungen als den

    69,91µs zwischen Senden und Empfangen kommen kann. Die einzige Kommunikation in

    denen die PICC die Antwortzeiten sehr exakt einhält ist bei einer Kollisionsauflösung,

    24

  • also dem Kommunizieren mit mehreren PICC in dem HF-Feld eines PCD. Sequenziel-

    les Auslesen von mehreren PICC wurde in dieser Ausarbeitung jedoch nicht behandelt.

    Ein Grund dafür ist die Tatsache, dass die Leistung des HF-Feld unseres Lesegerätes

    nur sehr schwach ausgelegt wurde und somit ist es fast unmöglich, dass zwei PICC in

    dem selben HF-Feld mit Energie versorgt werden können. Aus Vollständigkeitsgründen

    soll hier trotzdem noch erwähnt werden, dass der in der Norm beschriebene Kollisions-

    auflösungsalgorithmus genaues synchrones Timing aller beteiligten PICC erfordert. Des-

    wegen konnten wir auch nur beim Senden dieser Befehle eine ganz präzise Antwortzeit

    der PICC feststellen. Als weitere interessante Feststellung scheint noch erwähnenswert

    zu sein, dass die verspätete Antwort der PICC, immer ein Vielfaches der Länge einer

    ETU entspricht. Das hat den Vorteil, dass es unmöglich ist beim Abtasten aus dem Bit-

    Raster herauszufallen. Es bleibt also gewährleistet, dass wir das Signal immer genau im

    ersten Viertel und im letzten Viertel abtasten. Ein vor der Antwort des PICC angefan-

    genes Abtasten ist nicht weiter schlimm, da man dann lediglich 0 Werte empfängt und

    die beim Auswerten der Daten im Puffer einfach ignorieren kann. Bei einer Puffergröße

    von 82 Bytes ( 82 * 8 = 656 Bit ) und einer maximalen Rahmengröße von 163 Bit, blei-

    ben also 656 – 2 * 163 = 330 Bits im Puffer übrig. In Zeit ausgedrückt bedeutet dies, die

    Karte kann sich um insgesamt 330 * ETU = 3,11 ms verspäten, was aber nicht vorkommt.

    Zum Abschluss dieses Kapitels und um die Theorie ein bisschen anschaulicher zu ma-

    chen zeigen wir, anhand von Bild 3.4, ein Oszillogramm das beim Senden eines REQA-

    Befehles aufgenommen wurde. Das Band was man im oberen Kanal erkennen kann ist

    der Hochfrequenz-Träger. An den sieben Stellen wo der Träger ausgetastet ist, wurde er

    moduliert. Der zweite Kanal zeigt den digitalen Datenstrom den die Empfangsschaltung

    zeitgleich auswertet. Da es sich hierbei um die gerade gesendete Sequenz handelt, sind

    diese Empfangsdaten natürlich nicht relevant.

    Im nächsten Unterkapitel werden wir näher auf die benutzten Fehlererkennungsalgo-

    rithmen eingehen.

    3.2.4 Fehlererkennung

    Um Übertragungsfehler rechtzeitig zu erkennen und die Integrität der Daten zu gewährleisten,

    werden sämtliche übertragende Bytes einer Paritäts- und CRC-Kontrolle unterzogen. Ei-

    ne 16 Bit lange CRC-Summe wird dabei für alle Befehle mit Parameter berechnet. Diese

    zwei Prüfsummen Bytes werden an die zu übertragende Byte-Kette angehängt. Anschlie-

    25

  • Abbildung 3.4: Senden eines REQA Kommandos

    ßend wird an jedes Byte dieser Kette ein neuntes Bit angehängt, welches als Paritätsbit

    zur ungeraden Paritätskontrolle dient. Im Anhang der ISO-Norm [3] befindet sich ein

    optimierter in C geschriebener Algorithmus der die CRC-Kontrolle durchführt. Obwohl

    es zahlreiche Möglichkeiten gibt einen CRC-Algorithmus zu implementieren, empfehlen

    wir die Benutzung dieses vorgegebenen Code-Fragments. Der Code ist speziell auf das in

    dem Dokument ITU-T V.41 [9] vorgeschlagenen CRC-Verfahren zugeschnitten. Die ITU

    (International Telecommunication Union) schlägt vor das CRC-Polynom x16+x12+x5+1

    zu benutzen und als Startwert soll das CRC-Register den Wert 0x6363 enthalten. Sogar

    eine Umsetzung mittels Lookup-Tabelle wird sich kaum lohnen, da diese im Verhältnis zu

    der dadurch erfolgenden geringen Geschwindigkeitssteigerung weit mehr Speicherplatz

    in Anspruch nimmt. Es muss noch drauf geachtet werden, dass die beiden CRC-Bytes in

    der richtigen Reihenfolge an die Nutzdaten angehängt werden. Das heißt, das LSB-Byte

    zuerst, und anschließend das MSB.

    Der nächste Abschnitt befasst sich mit dem Aufbau der MIFARE-Ultralight-Karte.

    26

  • Byte Inhalt 0x00 0x01 0x02 0x03 Seite

    Seriennummer SN0 SN1 SN2 BCC0 0x00Seriennummer SN3 SN4 SN5 SN6 0x01Internal/Lock BCC1 Internal Lock0 Lock1 0x02

    OTP OTP0 OTP1 OTP2 OTP3 0x03Data R/W Data 00 Data 01 Data 02 Data 03 0x04Data R/W Data 04 Data 05 Data 06 Data 07 0x05Data R/W Data 08 Data 09 Data 10 Data 11 0x06Data R/W Data 12 Data 13 Data 14 Data 15 0x07Data R/W Data 16 Data 17 Data 18 Data 19 0x08Data R/W Data 20 Data 21 Data 22 Data 23 0x09Data R/W Data 24 Data 25 Data 26 Data 27 0x0AData R/W Data 28 Data 29 Data 30 Data 31 0x0BData R/W Data 32 Data 33 Data 34 Data 35 0x0CData R/W Data 36 Data 37 Data 38 Data 39 0x0DData R/W Data 40 Data 41 Data 42 Data 43 0x0EData R/W Data 44 Data 45 Data 46 Data 47 0x0F

    Tabelle 3.4: Mifare-Ultralight EEPROM-Speicher

    3.3 Die MIFARE-Karte

    In den folgenden beiden Abschnitten gehen wir näher auf die Speicherstruktur der

    Mifare-Karte ein und erläutern den von der Firmware unterstützten Befehlssatz.

    3.3.1 Der Karten-Speicher

    Der EEPROM-Speicher (Electrical Erasable Programmable Read Only Memory) der

    Mifare-Ultralight-Karte besteht aus 512 Bit, also 64 Bytes. Der Speicher ist in 16 Seiten

    mit jeweils 4 Bytes aufgeteilt. Im Prinzip stehen dem Benutzer aber nur 48 Bytes für

    Nutzdaten zur Verfügung. Wie in Tabelle 3.4 zu erkennen, beinhalten die ersten 9 Bytes

    die Seriennummer der Karte. Diese Speicherzellen können aus Sicherheitsgründen, um

    die weltweite Eindeutigkeit dieser Seriennummer zu gewährleisten, nicht mehr geändert

    werden. Ebenso unveränderbar ist das zweite Byte der Seite 0x02. Es ist für interne

    Zwecke reserviert und somit auch nicht beschreibbar.

    Die beiden letzten Bytes der Seite 0x02 dienen dazu die Seiten 0x03 bis 0x0E read-only

    zu machen. Dieser Vorgang ist, genauso wie das Schreiben der OTP0 - OTP3 Bytes (One

    Time Programmable) nicht mehr umkehrbar. Um ein versehentliches Schreiben dieser

    Speicherzellen zu vermeiden und die Karte somit unbrauchbar zu machen, wird das

    27

  • Schreiben dieser Seiten nicht von unserer Firmware unterstützt. Diese Funktionalität

    lässt sich aber jederzeit leicht nachrüsten. Jedoch sollte man sich vorher die genauen

    Erklärungen dazu im Datenblatt [4] durchlesen.

    Abschließend wollen wir noch angeben wie die Korrektheit der Seriennummer überprüft

    werden kann. Wenn die folgenden beiden Gleichungen erfüllt sind handelt es sich um eine

    gültige Seriennummer: BCC0 = 0x88⊕ SN0⊕ SN1⊕ SN2BCC1 = SN3⊕ SN4⊕ SN5⊕ SN6Der Operator ⊕ steht für die binäre XOR-Verknüpfung.

    3.3.2 Der Karten-Befehlssatz

    Die in diesem Abschnitt vorgestellte Kommandoliste besteht aus den wichtigsten und

    meist genutzten Befehlen. Die Mifare-Ultralight Karte-unterstützt noch ein paar weiterer

    Befehle, die aber im Rahmen dieser Projektarbeit nicht benutzt wurden. Die Erweiterung

    des Befehlssatzes ist jedoch problemlos durchführbar und nur mit geringem Aufwand

    verbunden. Bild 3.5 zeigt den Teil des Zustandsdiagramms der Mifare-Karte, den wir

    mit den implementierten Befehlen ablaufen können. Die gestrichelten Teile sind nicht

    umgesetzt, wurden aber wegen Erklärungsgründen eingezeichnet. Für das vollständigen

    Diagramm verweisen wir den Leser auf das Datenblatt [4].

    Wird die Karte mit Energie versorgt, geht sie über in den Ruhezustand und ist dann

    bereit bestimmte Befehle zu empfangen.

    1. Der REQA-Befehl.

    Mit Hilfe des REQA-Befehles (von REQuest Typ A), bringt man die Mifare-Karte

    in den Bereitschaftszustand. Falls dieser Vorgang erfolgreich war, antwortet die

    Karte mit einem ATQA (Answer To reQuest Typ A). Somit eignet sich dieses

    Kommando auch um das Vorhandensein einer PICC zu kontrollieren. Des Weiteren

    muss dieser Befehl nach jedem WRITE-Befehl gesendet werden. Dies steht nicht

    ganz explizit im Datenblatt und hat dazu geführt, dass die Implementierung des

    WRITE-Kommandos am Anfang nicht funktioniert hat. Der REQA-Befehl besteht

    nur aus aus sieben Bit, wobei das letzte Bit zur Paritätskontrolle dient. Es werden

    zudem keine Parameter benötigt.

    2. Der WUPA-Befehl.

    28

  • Abbildung 3.5: Zustandsdiagramm Mifare-Ultralight-Karte

    Mit dem WUPA-Befehl (Wake UP vom Typ A) erreicht man ebenfalls den Ready-

    Zustand. Des Weitern lässt sich die Karte aus dem Haltezustand mittels WUPA

    aufwecken. Wie bei REQA besteht der Befehl nur aus sieben Bit und wird ohne

    Parameter ausgeführt.

    3. Der READ-Befehl.

    Der READ-Befehl eignet sich dazu den Speicherinhalt der Karte auszulesen. Als

    Parameter benötigt er die Anfangsadresse des zu lesenden Bereiches. Jedes Byte

    der Anfrage wird um ein Paritätsbit erweitert und mit einer CRC-Prüfsumme am

    Ende abgeschlossen. Die Mifare-Karte antwortet indem sie 16 Bytes an Daten, von

    der ihr übermittelten Anfangsadresse an, zurück sendet. Um den READ-Befehl

    auszuführen, muss sich die Karte im Bereitschafts- oder im Aktivzustand befinden.

    4. Der WRITE-Befehl.

    Um den Datenspeicher der Karte mit Daten zu beschreiben, gibt es den WRITE-

    Befehl. Es können immer nur seitenweise Daten geschrieben werden. Die vier By-

    tes einer Seite werden dem Befehl als Parameter übergeben. Zur Fehlererkennung

    kommen auch hier Paritäts- und CRC-Kontrolle zum Einsatz. Wie schon erwähnt,

    sollte man nach einem erfolgreichen WRITE-Befehl nicht vergessen einen REQA-

    Befehl hinterher zu schicken, da ansonsten die Daten nicht übernommen werden.

    29

  • Kommando Hexcode Parameter Data Fehlercodes Antwort

    REQA 0x26 (7 Bit) - - Paritätsbit ATQA = 0x0044WUPA 0x52 (7 Bit) - - Paritätsbit ATQA = 0x0044READ 0x30 (8 Bit) Adresse: 0x00-0x0F - Paritätsbit,CRC 16 Byte DatenWRITE 0xA2 (8 Bit) Adresse: 0x00-0x0F 4 Byte Paritätsbit,CRC -

    Tabelle 3.5: Mifare-Ultralight-Befehle

    Der WRITE-Befehl lässt sich nur in dem Aktivzustand ausführen.

    Es soll noch erwähnt werden, dass nicht gültige oder nicht erwartete Befehle, von

    der Karte als Fehler interpretiert werden und sie sich somit selbst in den Ruhezustand

    zurücksetzt.

    Tabelle 3.5 fasst noch mal sämtliche Befehle mit ihren relevanten Informationen zu-

    sammen.

    Somit sind wir fast am Ende von Kapitel 3 angelangt. Abschließend wird nun noch

    erklärt was bei der ersten Inbetriebnahme des Lesegerätes berücksichtigt werden muss.

    3.4 Inbetriebnahme des Lesegerätes

    Kapitel 2 diente dazu dem Leser die Hardware des Lesegerätes näher zu bringen und

    dessen Nachbau zu ermöglichen. In Kapitel 3 wurden dann die Grundlagen der Mifare-

    Technologie beschrieben. Nach dem Lesen dieser beiden Kapitel sollte es also für einen

    technisch versierte Leser möglich sein ein funktionstüchtiges Gerät nachzubauen.

    Bevor das Gerät jedoch einwandfrei funktioniert, muss es noch kalibriert werden. Wir

    benötigen dafür ein Oszilloskopen (mit mindestens 15 MHz Bandbreite), eine Mifare-

    Ultralight-Karte und eine selbstgebaute Schnüffelsonde. Die Einstellmöglichkeiten be-

    grenzen sich auf die drei Potentiometer P1, P2 und P3 und den Trimmer T1. Die Namen

    beziehen sich auf die Bauteile in Abbildung 3.6.

    Als erstes werden wir die Amplitude des HF-Feldes mit Hilfe von T1 auf ein Maximum

    einstellen. Dazu bauen wir uns erst eine Schnüffelsonde indem wir fünf Windungen, ein

    Millimeter dicken Drahtes, auf einen 5 x 6,5 Zentimeter Rahmen wickeln. Die Windun-

    gen müssen schön nebeneinander gewickelt werden, um Verzerrungen des zu messenden

    Signals zu vermeiden. Die Spule wird nun an den Eingang des Oszilloskopen gehängt

    und das Lesegerät eingeschaltet. Das Display zeigt jetzt den ersten Menüeintrag an. Mit

    30

  • Abbildung 3.6: PCD Platine

    P3 lässt sich der Kontrast des LCDs einstellen. Beim Auflegen der Sonde auf die Anten-

    ne sollte jetzt eine 13,56 MHz Sinusschwingung sichtbar werden. T1 wird nun so lange

    verändert bis wir eine maximale Amplitude der Schwingung erreicht haben. Bei opti-

    maler induktiver Kopplung der beiden Spulen erreicht der Scheitelwert der Sinusschwin-

    gung fast 5 V. Damit ist der erste Kalibrierungsschritt abgeschlossen. Der Vollständigkeit

    halber wollen wir noch darauf hinweisen, dass mit dieser primitiven Einstellungsmetho-

    de nicht unbedingt die optimale Amplitude eingestellt werden kann. Da unsere Sonde

    lediglich aus einer Spule besteht und keinerlei Maßnahmen für eine korrekte Impedanz-

    Anpassung durchgeführt wurden, wird bei der Messung das HF-Feld dementsprechend

    belastet. Dieses einfache Verfahren ist jedoch für unsere Zwecke bestens geeignet und die

    korrekten Einstellungen waren jederzeit reproduzierbar. Für professionellere Einstellun-

    gen und präzise Messmethoden, verweisen wir auf die Methoden wie sie in [10] erläutert

    werden.

    Für den weiteren Verlauf der Kalibrierung, benötigen wir die RFID-Karte. Sie wird

    auf das Antennen-Feld des Lesegerätes aufgelegt. Dann stellen wir das Lesegerät auf

    den ersten Menüeintrag ein und halten die Enter-Taste gedrückt. Mit dem Oszillosko-

    pen messen wir das Signal, welches an dem Emitter von Transistor Q1 anliegt. P2 wird

    31

  • jetzt so lange verdreht bis zu dem Punkt an dem der Transistor das Rechtecksignal nicht

    mehr wegen Übersteuerung verzerrt. Wenn wir Glück haben, dann gibt das Lesegerät

    jetzt die Meldung heraus, dass eine Karte erkannt wurde. Falls dies nicht der Fall ist,

    lassen wir die Eingabe-Taste weiterhin gedrückt und drehen solange an P1, bis die Kar-

    te erkannt wird. P1 ist übrigens zuständig um die Schwellspannung des Komparators

    einzustellen.

    Nach der Kalibrierung müsste das Gerät einwandfrei funktionieren und der Leser kann

    sich nun, durch Ausprobieren, mit dessen Funktionen vertraut machen.

    Mit dem Abschluss dieses Kapitels besitzen wir ein autonomes funktionstüchtige

    RFID-Lesegerät. Wir können jetzt Seriennummern und Speicher von Mifare-Ultralight-

    Karten auslesen. Jedoch fehlt uns noch die Möglichkeit sinnvolle Daten in den Speicher

    der Karte zu schreiben. Dies ist nur mit Hilfe eines Computers machbar.

    Im nächsten Kapitel befassen wir uns deswegen mit der Entwicklung einer geeigneter

    PC Software für unser Lesegerät.

    32

  • 4 Die PC-Software

    Die Herausforderung der PC Software bestand darin, ein kleines Softwarepaket zu ent-

    wickeln, mit welchem man das Lesegerät über die USB-Schnittstelle steuern kann. Wie

    schon in Kapitel 2 erwähnt, wird als USB-Controller Chip der FT232 von FTDI [6] be-

    nutzt. Auf der Homepage des Herstellers finden wir geeignete Treiber für alle gängigen

    Betriebssysteme (Linux, OS X, Windows,...). Wie auch schon angedeutet, sind we-

    gen diesen Treibern, keine besonderen Kenntnisse über die Programmierung von USB-

    Schnittstellen erforderlich. Der Treiber erzeugt einen virtuellen seriellen Port der pro-

    blemlos, wie eine ganz konventionelle serielle Hardware-Schnittstelle, angesprochen und

    programmiert werden kann.

    Seitens der Softwareprogrammierung würde sich die C-Sprache natürlich bestens an-

    bieten. Da es sich hier jedoch um eine ganz spezifische Hardware nahe Programmierung

    handelt, könnten wir nicht garantieren, dass unserer C-Code auf jedem Betriebssys-

    tem kompilierbar ist. Es müssten also mehrere Versionen gewisser Programmstellen für

    die jeweiligen Betriebssysteme entworfen werden. Wegen dieses zusätzlichen Aufwandes,

    haben wir uns dazu entschlossen die ganze Software in Java zu implementieren. Un-

    ser Entschluss Java zu benutzen, basierte dabei auf der Hoffnung, dass man mit dieser

    Programmiersprache, Betriebssystem übergreifende funktionstüchtige Programme ent-

    wickeln kann. Vorgreifend können wir schon einmal verraten, dass unsere Forderungen

    und Hoffnungen bestens erfüllt wurden.

    Eine plattformübergreifende Programmierung war in unserem Fall besonders wichtig,

    weil sämtliche Arbeiten, inklusive das Verfassen dieser Ausarbeitung, mit Hilfe eines

    Intel iMac unter dem Betriebsystem OS X Tiger getätigt wurden. Um zu garantieren,

    dass unsere Software auch auf den weiter verbreiteten Betriebssystemen wie Linux und

    Windows lauffähig ist, haben wir uns schlussendlich für Java entschieden.

    Die Umsetzung der Software gliedert sich in zwei wesentlichen Hauptteile. Die Imple-

    mentierung einer Software-Bibliothek, mit Hilfe welcher die gesamte Funktionalität des

    Lesegerätes benutzt werden kann, sowie die Programmierung einer graphischen Demo,

    33

  • Abbildung 4.1: UML-Diagramm vom Paket-RFID

    die aus ein paar Slides besteht und dem Zuschauer aktiv erklären soll wie das Lesegerät,

    beziehungsweise allgemeiner die RFID-Technologie funktioniert.

    Im folgenden soll nun die Vorgehensweise bei der Implementierung der Java-Bibliothek

    erläutert werden.

    4.1 Das RFID-Paket

    Um eine plattformübergreifende Nutzung von seriellen und parallelen Hardware-Schnittstellen

    zu gewährleisten, hat Sun Microsystems die Java Communications Library [11] entwi-

    ckelt. Leider war zum Zeitpunkt unserer Projektarbeit keine lauffähige Version dieser

    Bibliothek für OS X verfügbar.

    Eine intensive Suche nach einer Alternative brachte schließlich Erfolg, als wir auf ei-

    ne frei verfügbare Nachimplementierung dieser Bibliothek aufmerksam wurden. Hierbei

    handelt es sich um die RXTX lib [12]. Die API (Aplication Programming Interface) die-

    ses Klons hält sich strikt an die Vorgaben des Originals. Der einzig wichtige Unterschied

    ist, dass sie für eine breite Auswahl von Betriebssystemen verfügbar ist, unter anderem

    OS X. Die Bibliothek wird unter der GNU Lesser General Public License, kurz LGPL,

    herausgegeben und kann somit ohne rechtliche Bedenken in unserem Softwarepaket ein-

    gesetzt werden.

    Unsere RFID-Bibliothek besteht aus den zwei Java Klassen RFIDInterface und RFID-

    Device. Das UML-Diagramm in Bild 4.1 verdeutlicht die Beziehung zwischen beiden

    34

  • Klassen und gibt einen Überblick über die verfügbaren Methoden. RFIDInterface ist

    eine abstrakte Klasse die nur zum Teil implementiert ist und selbst nicht instanziiert

    werden kann. RFIDDevice hingegen spezialisiert RFIDInterface und stellt dem Benutzer

    eine vollständige Klasse mit diversen nutzvollen Methoden zu Verfügung, mittels denen

    das RFID-Lesegerät über USB gesteuert werden kann. Sämtliche Funktionen die von der

    Firmware unterstützt werden, sind in Form von Methoden in der RFIDDevice Klasse

    implementiert worden. Das Ausführen einer beliebigen Methode läuft dabei immer gleich

    ab und soll nun willkürlich anhand der Methode Request() erläutert werden.

    4.1.1 Kommunikation zwischen Computer und Lesegerät

    Die Request() Methode, wie der Name es schon sagt, ist die Umsetzung des REQA-

    Befehles. Beim Ausführen dieser Klassenmethode wird im Hintergrund eine serielle Kom-

    munikation mit dem Lesegerät aufgebaut. Das Lesegerät muss sich dafür im USB Ver-

    bindungsmodus befinden (Menüeintrag 5). Mit Hilfe eines Zufallsgenerators wird eine

    32 Bit lange Sequenznummer erzeugt. Diese intern verwaltete Nummer identifiziert die

    aktuelle Verbindung und wird im Falle einer fehlerhaften Datenübertragung benutzt,

    um die Verbindung gezielt und kontrolliert zu beenden.

    Hinter den Kulissen und für den Benutzer unsichtbar, wird parallel zu jeder Daten-

    verbindung ein Thread gestartet. Dieser Thread überprüft periodisch, ob die aktuelle

    Verbindung reibungslos abläuft. Im Falle eines Fehlers, wie zum Beispiel ein Heraus-

    ziehen des USB-Kabels, hängt sich die unterliegende RXTX lib auf. Der Thread würde

    dann die Verbindung, in einem solchen Szenario, nach Ablauf eines festgelegten Timeouts

    schliessen. Mit dieser Vorgehensweise ist es fast unmöglich die Computersoftware, durch

    von außen wirkende Einflüsse seitens des Lesegerätes, zum Abstürzen zu bringen.

    Um dem Lesegerät nun mitzuteilen, dass ein REQA-Befehl ausgeführt werden soll,

    wird eine, für den REQA-Befehl festgelegte, Identifikationsnummer mit der Länge eines

    Bytes übertragen. Benötigt der Befehl noch Parameter (was bei REQA nicht der Fall

    ist), werden diese anschließend byteweise übertragen. Nachdem das Lesegerät alle Daten

    empfangen hat, führt es den Befehl aus und liefert das Ergebnis zurück. Für den REQA-

    Befehl gibt es als Rückgabewert nur die beiden Möglichkeiten, ob der Befehl erfolgreich

    war oder nicht. Ein positives Feedback bedeutet es liegt ein RFID-Transponder auf dem

    Lesegerät, eine negative Antwort heißt, dass kein Transponder in Reichweite ist. Somit

    haben wir also eine Möglichkeit herauszufinden, ob eine Karte aufliegt oder nicht. Die

    Methode isPICC() geht übrigens nach dem Prinzip vor und liefert dementsprechend den

    35

  • Wert true oder false.

    Falls in Zukunft weitere Funktionen in die Firmware integriert werden, so lässt sich das

    RFID-Paket schnell und leicht erweitern. Der intuitive und leicht verständliche Java-

    Programmcode befindet sich zur freien Nutzung im Anhang.

    Im nächsten Abschnitt werden sämtliche Schritte erklärt die für eine erfolgreiche In-

    stallation des RFID-Paketes nötig sind.

    4.1.2 Installation des RFID-Paketes

    Die folgende Anleitung erläutert die Vorgehensweise, die bei einer erfolgreichen Instal-

    lation des RFID-Paketes beachtet werden muss. Der Installationsvorgang gliedert sich

    dabei in drei Schritte:

    1. Installation der Treiber.

    Auf der Webseite des Herstellers FTDI [6] kann man sich den benötigten Treiber

    für den FT232RL-Chip herunter laden. Nach der Installation des Treibers erscheint

    ein virtueller serieller Port.

    2. Installation der RXTX lib.

    Die RXTX lib kann man sich unter [12] aus dem Internet herunter laden. Es

    stehen aktuell drei Versionen für die Betriebssysteme Linux, OS X und Windows

    zu Verfügung. Man hat nun die Wahl die Bibliothek selber zu kompilieren oder

    gleich die binären Dateien zu installieren. An diesem Punkt verweisen wir den

    Leser auf die hervorragende Wiki-Dokumentation der Entwickler.

    3. Installation des RFID-Paketes.

    Wenn man die ersten beiden Punkte erfolgreich abgeschlossen hat, kann man den

    Quelltext des RFID-Paketes, aus dem Anhang, kompilieren. Dem Leser steht nun

    eine funktionsfähige RFID-Bibliothek zur Verfügung, die er nach Lust und Laune

    benutzen und optimieren kann.

    Im nächsten Abschnitt soll anhand eines kleinen Code-Fragmentes demonstriert werden,

    wie das RFID-Paket angewendet werden kann.

    4.1.3 Anwendung des RFID-Paketes

    Listing 4.1 zeigt ein praktisches Anwendungsbeispiel für unsere RFID-Bibliothek. In Zei-

    le 1 wird das RFID-Paket eingebunden. Wie aus Zeile 8 und 36 ersichtlich wird, müssen

    36

  • die gesamten Aufrufe der RFID-Methoden von einem try/catch-Block umschlossen sein.

    Was für Exceptions geworfen werden, lässt sich in der RXTX-Dokumentation [12] nach-

    lesen. In Zeile 5 deklarieren wir eine Variable vom Typ RFIDDevice, die in Zeile 19

    initialisiert wird. Das Java-Programm muss mit einem gültigen seriellen Port als Pa-

    rameter aufgerufen werden. Wird kein Parameter übergeben, gibt das Programm mit

    Zeile 15 eine Liste von möglichen seriellen Schnittstellen heraus. Der Benutzer muss nun

    wissen oder ausprobieren an welcher dieser Schnittstellen sein Lesegerät angeschlossen

    ist. Unter Windows ist der Standardname für eine serielle Schnittstelle immer COM X,

    wobei X für eine Ziffer oder Zahl steht. Unter Unix und Linux Systemen könnte der

    Name der Schnittstelle wie /dev/tty.USBtoSerialXX aussehen. Die Namensgebung un-

    ter diesen Betriebssystemen ist meistens selbsterklärend und somit intuitiv verständlich.

    Um mögliche Frustrationen bei der Parameter Eingaben zu umgehen sollte man unter

    allen Betriebssystemen auf die Groß- und Kleinschreibung acht geben.

    Nehmen wir nun an es wurde ein gültiger Parameter übergeben und die serielle Schnitt-

    stelle wurde erfolgreich geöffnet. Dann kann man beispielsweise, wie in Zeile 20 gezeigt,

    dem Gerät mitteilen einen REQA-Befehl zu verschicken oder, wie in Zeile 21 bis 30, die

    eindeutige Seriennummer eines aufliegenden RFID-Transponders erlangen. Die genaue

    Syntax aller Methoden ist übrigens, mit Hilfe von Javadoc-Anweisungen, im Programm-

    code ausführlich erklärt. Nach dem Benutzen des Lesegerätes sollte man nicht vergessen

    die Hardware-Ressource wieder frei zu geben (siehe dazu Zeile 24 oder Zeile 31 ).

    Listing 4.1: Anwendungbeispiel des RFID-Paketes

    1 import RFID . ∗ ;2 import java . u t i l . ArrayList ;

    3

    4 class RFIDtest {5 RFIDDevice dev i c e ;

    6 public stat ic void main ( St r ing args [ ] )

    7 {8 try

    9 {10 ArrayList data = new ArrayList() ;

    11 i f ( args . l ength < 1)

    12 {

    37

  • 13 System . out . p r i n t l n ( ” S e r i e l l e n Port auswählen ” ) ;

    14 RFIDInterface . L i s tPor t s ( ) ;

    15 System . e x i t ( 1 ) ;

    16 }17 else

    18 {19 dev i c e = new RFIDDevice ( args [ 0 ] ) ;

    20 System . out . p r i n t l n ( ”>>Reply from PCD: ” + dev i ce . Request ( ) ) ;

    21 i f ( Device . GetUID( data ) . equa l s ( ”UID ERROR” ) )

    22 {23 System . out . p r i n t l n ( ”>>> Cannot read PICC” ) ;

    24 dev i ce . CloseDevice ( ) ;

    25 System . e x i t ( 1 ) ;

    26 }27 else

    28 {29 System . out . p r i n t l n ( ”>>PICC UID : ” +

    30 RFIDDevice . Ar rayL i s t2St r ing ( data ) ) ;

    31 dev i ce . CloseDevice ( ) ;

    32 System . e x i t ( 0 ) ;

    33 }34 }35 }36 catch ( Exception e )

    37 {38 System . out . p r i n t l n ( e ) ;

    39 i f ( dev i c e instanceof RFIDDevice )

    40 dev i ce . CloseDevice ( ) ;

    41 System . e x i t ( 1 ) ;

    42 }43 }44 }

    38

  • 4.2 Die JavaFX-Demo

    Zum Abschluss dieses Kapitels und der gesamten Ausarbeitung haben wir eine kleine

    graphische Demo entwickelt, die, mit Hilfe des Lesegerätes, einen praktischen Einblick

    in die Funktionsweise der RFID-Technologie geben soll. Diese Demo wurde extra für

    Vorführungen, auf Messen oder Workshops, konzipiert.

    Die graphisch interaktive Präsentation läuft voll automatisch ab und fängt nach je-

    dem Durchlauf wieder von vorne an. Die Demo ist in drei Slides aufgeteilt. Die erste

    Folie vermittelt dem Zuschauer einen kurzen theoretischen Überblick über die RFID-

    Technologie. Ausgestattet mit diesem theoretischen Grundwissen werden dann auf der

    zweiten Folie die verschiedenen Komponenten des RFID-Lesegerätes anschaulich erklärt.

    Die letzte Folie beinhaltet den interaktiven Teil der Vorführung. Der Zuschauer hat nun

    die Möglichkeit eine rote oder eine blaue RFID-Karte auf das Gerät aufzulegen. Die

    Stelle an der die Karte aufgelegt werden soll, wird dem Zuschauer mit Hilfe einer LED-

    Hintergrundbeleuchtung angezeigt. Anhand der Seriennummer ist es dem Gerät dann

    möglich dem Publikum mitzuteilen, welche der beiden Karten ausgewählt wurde.

    Die Demo wurde in der Skriptsprache JavaFX programmiert. In ihr lassen sich auf

    schnelle und einfache Weise multimediale und animierte Präsentationen realisieren. Ein

    weiterer Vorteil ist, dass sich problemlos existierende Java-Klassen, wie zum Beispiel die

    aus unserem RFID-Paket, aufrufen und eingliedern lassen.

    Da es nicht möglich ist die Demo in den Anhang zu stellen, kann ein Version per

    E-mail unter m [email protected] angefordert werden.

    39

  • 5 Zusammenfassung

    Das Hauptziel diese Projektarbeit war es, ein funktionsfähiges Lesegerät für RFID-

    Transponder zu entwickeln.

    Um dieses Ziel zu erreichen, mussten wir uns erst für einen der vielen RFID-Standards

    entscheiden. Anschließend haben wir uns detaillierte Informationen über die ausgewählte

    Technologie zusammengesucht. Als weitere Inspirationsquellen kamen uns andere frei

    verfügbare RFID-Projekte zu Gute.

    Um unser Projekt erfolgreich umzusetzen, benötigten wir sowohl elektronische und

    programmiertechnische Grundkenntnisse. Unser Lesegerät basiert zum größten Teil auf

    der in [1] veröffentlichten Schaltung. Das Gerät wird jedoch von einer, von Grund auf

    neu programmierten und umfangreicheren Firmware, gesteuert. Des Weiteren besitzt

    unser RFID-Demonstrator ein USB-Schnittstelle.

    Zusätzlich dazu haben wir ein Softwarepaket entwickelt, mit welchem man das Lese-

    gerät, mit Hilfe eines Computers, über den USB-Anschluss steuern kann.

    Am Schluss der Projektarbeit hatten wir schliesslich sämtliche Ziele erreicht und be-

    sitzen nun ein RFID-Lesegerät, welches alle gestellten Anforderungen erfüllt.

    Der Bau des Lesegerätes war sehr interessant und lehrreich, und hat dem Autor zahlrei-

    che Erfolgserlebnisse beschert.

    40

  • 6 Anhang

    6.1 Hardware

    6.1.1 Platinenlayouts zum Belichten

    Die Abbildungen 6.1 und 6.2 können als Vorlage zum Belichten benutzt werden. Die

    Breite der Platinen ist 10,1 cm beziehungweise 6,5 cm.

    6.1.2 Bestückungsplan mit Bauteilliste

    Liste der Bauteile mit Bestückungsplan in Abbildung 6.3

    C1 33 pF

    C2 33 pF

    C3 4,7 nF

    C4 330 pF

    C5 220 pF

    C6 220 pF

    C7 100 nF

    C8 220 pF

    C9 100 nF

    C10 330 pF

    C11 60 pF

    C12 100 nF

    C13 100 nF

    C14 100 nF

    C15 10 nF

    C18 100 nF

    C19 4,7µF

    D1 BAT42

    D2 BAT42

    IC1 FT232RL

    IC2 MEGA16-P

    IC3 LM393N

    IC4 74HC00N

    L5 2.2µH

    L6 100µH

    L7 100µH

    L8 0.1µH

    LED1 grün

    LED2 grün

    Q1 BC560

    Q2 BS250

    Q3 BS170

    Q4 13,56 MHz

    R1 2,2 MΩ

    R2 2,2 kΩ

    R3 2,2 kΩ

    R4 4,7 kΩ

    R5 4,7 kΩ

    R6 4,7 kΩ

    R7 1 kΩ

    R8 220 Ω

    R9 100 Ω

    R10 10 kΩ

    R11 1 kΩ

    R12 2,2 kΩ

    R13 1 kΩ

    R14 2,2 kΩ

    R15 330 Ω

    R16 25 kΩ

    R17 4,7 kΩ

    R18 4,7 kΩ

    R19 270 Ω

    R20 270 Ω

    SV1 ISP

    SV2 LCD

    USB connector

    41

  • Abbildung 6.1: Platine des Lesegeräts

    Abbildung 6.2: Platine der Antenne

    42

  • Abbildung 6.3: Bestückungsplan

    6.2 Firmware

    Die Firmware besteht aus den sechs Quelltextdateien rfid.c, rfid.h, mifare.c, mifare.h,

    lcd.c und lcd.h.

    6.2.1 rfid.h

    1 #include

    2 #include

    3 #include ” l cd . h”

    4

    5 #define XX 0xDD

    6 #define XY 0xDF

    7 #define XZ 0xD7

    8

    9 #define YX 0xFD

    10 #define YY 0xFF

    11 #define YZ 0xF7

    12

    13 #define ZX 0x7D

    14 #define ZY 0x7F

    15 #define ZZ 0x77

    16

    17 #define X 0xD0

    18 #define Y 0xF0

    19 #define Z 0x70

    20

    21 #define CRC16INITVAL 0x6363

    22 #define SENDRECEIVEBUFFERSIZE 82

    23 #define DATABUFFERSIZE 21

    24

    25 volat i le u in t 8 t da t a bu f f e r [DATABUFFERSIZE ] ;

    26 volat i le u in t 8 t s e nd and r e c e i v e bu f f e r [SENDRECEIVEBUFFERSIZE ] ;

    27

    28 //number o f PCD b i t s

    29 volat i le u in t 8 t PCD bit count LSB ;

    30 volat i le u in t 8 t PCD bit count MSB ;

    43

  • 31

    32 //number o f PICC b i t s

    33 volat i le u in t 8 t PICC bit count LSB ;

    34 volat i le u in t 8 t PICC bit count MSB ;

    35

    36 enum eReturnCode { REQA REPLY OK,REQA REPLY ERROR,37 WUPA REPLY OK,WUPA REPLY ERROR,

    38 READ REPLY OK,READ REPLY ERROR,

    39 WRITE OK,WRITE ERROR,BAD PAGE,

    40 CRC OK, CRC ERROR,

    41 UID OK, UID ERROR,

    42 EXIT USB OK, LED ON, LED OFF } ;43

    44 typedef enum eReturnCode eReturnCode ;

    45

    46 void EncodePCDRequest ( u i n t 8 t ) ;

    47 u in t16 t CRC16 ( u i n t 8 t ∗ , u i n t 8 t ) ;48 u i n t 8 t DecodePICCReply ( ) ;

    49 void DisplayDataBuffer ( u i n t 8 t ) ;

    50 i n l i n e void WaitCycles ( u in t 16 t ) ;

    51 eReturnCode READ ( u in t 8 t ) ;

    52 eReturnCode WRITE ( u in t 8 t , u i n t 8 t ∗ ) ;53 eReturnCode WUPA ( ) ;

    54 eReturnCode REQA ( ) ;

    55 u i n t 8 t Nibble2Hex ( u i n t 8 t ) ;

    56 u i n t 8 t GetByteFromDataBuffer ( u i n t 8 t ) ;

    57 void InitUSART ( ) ;

    58 u i n t 8 t RX( ) ;

    59 void TX( u in t 8 t ) ;

    6.2.2 rfid.c

    1 #include ” r f i d . h”

    2

    3 stat ic i n l i n e void EnableRFField ( ) ;

    4 stat ic i n l i n e void DisableRFField ( ) ;

    5 stat ic void REQA( ) ;

    6 stat ic void SendAndReceive ( ) ;

    7 stat ic void EraseBuf f e r s ( ) ;

    8

    9 u i n t 8 t GetByteFromDataBuffer ( u i n t 8 t byte )

    10 {11 i f ( byte < DATABUFFERSIZE )

    12 return da ta bu f f e r [ byte ] ;

    13 return 0 ;

    14 }15

    16 u i n t 8 t Nibble2Hex ( u i n t 8 t n ibb l e )

    17 {18 i f ( n ibb l e > 15 )

    19 return 0 ;

    20 i f ( n ibb l e < 10)

    21 return ( n ibb l e +48);

    22 else

    23 return ( n ibb l e +55);

    24 }25

    26 stat ic void EraseBuf f e r s ( )

    27 {28 u i n t 8 t loop ;

    29 for ( loop =0; loop < DATABUFFERSIZE; loop++)

    30 {31 da t a bu f f e r [ loop ] = 0x00 ;

    32 s end and r e c e i v e bu f f e r [ loop ] = 0x00 ;

    33 }34

    35 for ( ; loop < SENDRECEIVEBUFFERSIZE; loop++)

    36 {37 s end and r e c e i v e bu f f e r [ loop ] = 0x00 ;

    38 }39 }

    44

  • 40

    41 void EncodePCDRequest ( u i n t 8 t l ength )

    42 {43 u i n t 8 t l a s t b i t ;

    44 u i n t 8 t n ex t b i t ;

    45 u i n t 8 t n ibb l e count e r ;

    46 u i n t 8 t cur r en t byte ;

    47 u i n t 8 t p a r i t y b i t ;

    48 u i n t 8 t counter ;

    49 u i n t 8 t b i t ;

    50 u i n t 8 t byte ;

    51 u i n t 8 t sequence ;

    52 u i n t 8 t byte count ;

    53 byte count=length ;

    54

    55 // compute CRC and add to d a t a b u f f e r

    56 // crc i s on l y needed f o r read and wr i t e commands

    57 u in t16 t CRC checksum = CRC16 ( ( u i n t 8 t ∗) da ta bu f f e r , byte count ) ;58 da t a bu f f e r [ byte count ] = ( u i n t 8 t ) ( CRC checksum & 0x00FF ) ;

    59 da t a bu f f e r [ byte count +1] = ( u i n t 8 t ) ( CRC checksum >> 8 ) ;

    60 byte count += 2 ;

    61 // add s t a r t sequence and p a r i t y b i t

    62 // r e v e r s e s b i t s

    63 // one b i t i s r e p r e s en t e d in f ou r t ime un i t s

    64 //X = 0xD Y = 0xF and Z = 0x7

    65

    66 counter = 0 ;

    67 s end and r e c e i v e bu f f e r [ counter ] = Z ; // add s t a r t b i t

    68 l a s t b i t = 0 ;

    69 n ibb l e count e r = 1 ;

    70

    71 for ( byte=0; byte < byte count ; byte++)

    72 {73 cur r en t byte = da ta bu f f e r [ byte ] ;

    74 p a r i t y b i t = 1 ;

    75 for ( b i t =0; b i t < 8 ; b i t++)

    76 {77 nex t b i t = cur r ent byte & 0x01 ; //LSB

    78 cur r en t byte = cur r en t byte >> 1 ;

    79 p a r i t y b i t = pa r i t y b i t ˆ n ex t b i t ;

    80

    81 i f ( n ex t b i t == 1)

    82 sequence = X;

    83 else i f ( l a s t b i t == 0)

    84 sequence = Z ;

    85 else

    86 sequence = Y;

    87 s end and r e c e i v e bu f f e r [ counter ] = s end and r e c e i v e bu f f e r [ counter ] | ( sequence >>(4∗n ibb l e count e r ) ) ;88

    89 i f ( n ibb l e count e r == 1)

    90 {91 n ibb l e count e r = 0 ;

    92 counter++;

    93 }94 else

    95 n ibb l e count e r = 1 ;

    96 l a s t b i t = nex t b i t ;

    97 }98

    99 i f ( p a r i t y b i t == 1)

    100 sequence = X;

    101 else i f ( l a s t b i t == 0)

    102 sequence =Z ;

    103 else

    104 sequence = Y;

    105 s end and r e c e i v e bu f f e r [ counter ] = s end and r e c e i v e bu f f e r [ counter ] | ( sequence >>(4∗n ibb l e count e r ) ) ;106 i f ( n ibb l e count e r == 1)

    107 {108 n ibb l e count e r = 0 ;

    109 counter++;

    110 }111 else

    45

  • 112 n ibb l e count e r = 1 ;

    113 l a s t b i t = pa r i t y b i t ;

    114 }115 // end sequence

    116 i f ( l a s t b i t == 1)

    117 s end and r e c e i v e bu f f e r [ counter ] = s end and r e c e i v e bu f f e r [ counter ] | (Y>>(4∗n ibb l e count e r ) ) ;118 else

    119 s end and r e c e i v e bu f f e r [ counter ] = s end and r e c e i v e bu f f e r [ counter ] | (Z>>(4∗n ibb l e count e r ) ) ;120

    121 i f ( n ibb l e count e r == 1)

    122 {123 n ibb l e count e r = 0 ;

    124 counter++;

    125 }126 else

    127 n ibb l e count e r = 1 ;

    128 s end and r e c e i v e bu f f e r [ counter ] = s end and r e c e i v e bu f f e r [ counter ] | (Y>>(4∗n ibb l e count e r ) ) ;129 }130

    131 eReturnCode REQA()

    132 {133 EnableRFField ( ) ;

    134 REQA( ) ;

    135 SendAndReceive ( ) ;

    136 DecodePICCReply ( ) ;

    137 DisableRFField ( ) ;

    138

    139 i f ( ( da t a bu f f e r [ 0 ] == 0x44 ) && da ta bu f f e r [ 1 ] == 0x00 )

    140 return REQA REPLY OK;

    141 else

    142 return REQA REPLY ERROR;

    143 }144

    145 stat ic void REQA() // Reques t t ype A

    146 {147 //REQA code : 0 x26 (7 b i t s )

    148 // add s t a r t− and end b i t ; no p a r i t y b i t i s added149 // Modi f i ed M i l l e r encod ing : ZZ XX YZ XY ZY

    150 EraseBuf f e r s ( ) ;

    151 s end and r e c e i v e bu f f e r [0 ]=ZZ ;

    152 s end and r e c e i v e bu f f e r [1 ]=XX;

    153 s end and r e c e i v e bu f f e r [2 ]=YZ;

    154 s end and r e c e i v e bu f f e r [3 ]=XY;

    155 s end and r e c e i v e bu f f e r [4 ]=ZY;

    156 PCD bit count LSB = 0x28 ; // 40d

    157 PCD bit count MSB = 0x00 ;

    158 // re sponse 0 x0044

    159 //2 b y t e s w i th p a r i t y + 1 s t a r t b i t

    160 //38 eru = 0x26

    161 // sa v i n g 0 x0190 eru

    162 PICC bit count LSB = 0x90 ;

    163 PICC bit count MSB = 0x01 ;

    164 }165

    166 eReturnCode WUPA () //Wake up t ype A

    167 {168 //WUPA code : 0 x52 (7 b i t s )

    169 // add s t a r t− and end b i t ; no p a r i t y b i t i s added170 // Modi f i ed M i l l e r encod ing : ZZ XY ZX YX YY

    171 EraseBuf f e r s ( ) ;

    172 s end and r e c e i v e bu f f e r [0 ]=ZZ ;

    173 s end and r e c e i v e bu f f e r [1 ]=XY;

    174 s end and r e c e i v e bu f f e r [2 ]=ZX;

    175 s end and r e c e i v e bu f f e r [3 ]=YX;

    176 s end and r e c e i v e bu f f e r [4 ]=YY;

    177 PCD bit count LSB = 0x28 ; // 40d

    178 PCD bit count MSB = 0x00 ;

    179 // re sponse 0 x0044

    180 //2 b y t e s w i th p a r i t y + 1 s t a r t b i t

    181 //38 eru = 0x13

    182 PICC bit count LSB = 0x90 ; //

    183 PICC bit count MSB = 0x01 ;

    46

  • 184 EnableRFField ( ) ;

    185 SendAndReceive ( ) ;

    186 DisableRFField ( ) ;

    187 DecodePICCReply ( ) ;

    188

    189 i f ( ( da t a bu f f e r [ 0 ] == 0x44 ) && da ta bu f f e r [ 1 ] == 0x00 )

    190 return WUPA REPLY OK;

    191 else

    192 return WUPA REPLY ERROR;

    193 }194

    195 eReturnCode READ ( u in t 8 t page )

    196 {197 u in t16 t CRC checksum ;

    198

    199 i f ( page > 0x0F)

    200 return BAD PAGE;

    201 EnableRFField ( ) ;

    202 REQA( ) ;

    203 SendAndReceive ( ) ;

    204 DecodePICCReply ( ) ;

    205 i f ( ( da t a bu f f e r [ 0 ] != 0x44 ) | | da ta bu f f e r [ 1 ] != 0x00 )206 return REQA REPLY ERROR; // e x i t f u n c t i o n

    207 //READ code : 0 x30

    208 //Parameter : 0x00−0x0F209 //CRC check

    210 EraseBuf f e r s ( ) ; // very impor tan t

    211 da t a bu f f e r [ 0 ] = 0x30 ;

    212 da t a bu f f e r [ 1 ] = page ;

    213 EncodePCDRequest ( 2 ) ; // dont change , 2 i s l e n g t h o f command

    214 //2 cmd by t e s , 2 crc by t e s , 1 s t a r t b i t , 2 end b i t s , p a r i t y b i t s f o r each b y t e => 39 b i t s

    215 //−> 39 ∗ 4 −> 19 ,5 b y t e s216 PCD bit count LSB = 0x9C ; // 156d

    217 PCD bit count MSB = 0x00 ;

    218 PICC bit count LSB = 0x90 ; //

    219 PICC bit count MSB = 0x01 ;

    220 SendAndReceive ( ) ;

    221 DecodePICCReply ( ) ;

    222 DisableRFField ( ) ;

    223 //make CRC check

    224 CRC checksum = CRC16 ( ( u i n t 8 t ∗) da ta bu f f e r , 1 8 ) ;225 i f (CRC checksum != 0x0000 )

    226 return CRC ERROR; // e x i t f u n c t i o n

    227 return READ REPLY OK;

    228 }229

    230 i n l i n e void WaitCycles ( u in t 16 t count )

    231 {232 asm volat i le ( ”cp %A0 , z e r o r e g \n\ t ”233 ”cpc %B0 , z e r o r e g \n\ t ”234 ”breq 2 f \n\ t ”235 ” 1 : \n\ t ”236 ” sbiw %0,1 \n\ t ”237 ”brne 1b \n\ t ”238 ” 2 : ”

    239 : ”=w” ( count )

    240 : ”0” ( count )

    241 ) ;

    242 }243

    244 eReturnCode WRITE ( u in t 8 t page , u i n t 8 t ∗ data )245 {246 u in t16 t CRC checksum ;

    247

    248 i f ( ( page < 0x04 ) | | ( page > 0x0F) )249 return BAD PAGE;

    250

    251 EnableRFField ( ) ;

    252 REQA( ) ;

    253 SendAndReceive ( ) ;

    254 DecodePICCReply ( ) ;

    255 i f ( ( da t a bu f f e r [ 0 ] != 0x44 ) | | da ta bu f f e r [ 1 ] != 0x00 )

    47

  • 256 return REQA REPLY ERROR; // e x i t f u n c t i o n

    257

    258 EraseBuf f e r s ( ) ; // very impor tan t

    259

    260 // read (0)

    261 da t a bu f f e r [ 0 ] = 0x30 ;

    262 da t a bu f f e r [ 1 ] = 0x00 ;

    263 EncodePCDRequest ( 2 ) ;

    264 PCD bit count LSB = 0x9C ; // 156d

    265 PCD bit count MSB = 0x00 ;

    266 PICC bit count LSB = 0x90 ; //

    267 PICC bit count MSB = 0x01 ;

    268 SendAndReceive ( ) ;

    269 DecodePICCReply ( ) ;

    270 CRC checksum = CRC16 ( ( u i n t 8 t ∗) da ta bu f f e r , 1 8 ) ;271 i f (CRC checksum != 0x0000 )

    272 return CRC ERROR; // e x i t f u n c t i o n

    273

    274 EraseBuf f e r s ( ) ; // very impor tan t

    275 // w r i t e

    276 da t a bu f f e r [ 0 ] = 0xA2 ;

    277 da t a bu f f e r [ 1 ] = page ;

    278 da t a bu f f e r [ 2 ] = ∗data ;279 da t a bu f f e r [ 3 ] = ∗( data +1);280 da t a bu f f e r [ 4 ] = ∗( data +2);281 da t a bu f f e r [ 5 ] = ∗( data +3);282

    283 EncodePCDRequest ( 6 ) ;

    284 PCD bit count LSB = 0x2C ; // 300d

    285 PCD bit count MSB = 0x01 ;

    286 PICC bit count LSB = 0x90 ; //

    287 PICC bit count MSB = 0x01 ;

    288

    289 SendAndReceive ( ) ;

    290 // have to send REQA to comp le t e w r i t e command

    291 REQA( ) ;

    292 SendAndReceive ( ) ;

    293 DecodePICCReply ( ) ;

    294 DisableRFField ( ) ;

    295 return WRITE OK;

    296 }297

    298 u in t16 t CRC16 ( u i n t 8 t ∗ data , u i n t 8 t l ength )299 {300 u i n t 8 t byte ;

    301 u in t16 t CRC16 ;

    302 CRC16 = CRC16INITVAL;

    303

    304 do{305 byte = ∗data++;306 byte = ( byte ˆ( u i n t 8 t ) ( (CRC16) & 0x00FF ) ) ;

    307 byte = ( byte ˆ( byte 8)ˆ(( u in t 16 t ) byte

  • 328 // /////////////////////////

    329 // l a s t b y t e o f s e n d a n d r e c e i v e b u f f e r must be c l e a r e d

    330 // ensure s t h a t a l o r i t hm s t o p s

    331 // search f o r f i r s t b i t s e t in s e n d a n d r e c e i v e b u f f e r b i t s tream

    332 asm volat i le (

    333

    334 ”push r20 \n\ t ”335 ”push r21 \n\ t ”// b i t p o s i t i o n coun te r f o r r2336 ”push r22 \n\ t ”// cu r r en t b y t e from d a t a b u f f e r337 ”push r23 \n\ t ”// b i t p o s i t i o n coun te r f o r r4338 ”push r24 \n\ t ”// cu r r en t b y t e from e u b u f f e r339 ”push r25 \n\ t ”340 ”push r26 \n\ t ”341 ”push r27 \n\ t ”342 ”push r28 \n\ t ”//LSB o f Y343 ”push r29 \n\ t ”//MSB o f Y344 ”push r30 \n\ t ”//LSB o f Z345 ”push r31 \n\ t ”//MSB o f Z346

    347 // /////////////////

    348 // s t a r t o f i n i t //

    349 // /////////////////

    350

    351 ” l d i r28 , l o8 ( da t a bu f f e r )\n\ t ”// l oad &d a t a b u f f e r in Y352 ” l d i r29 , h i8 ( da t a bu f f e r )\n\ t ”353 ” l d i r30 , l o8 ( s e nd and r e c e i v e bu f f e r )\n\ t ”// l oad &e u b u f f e r in Z354 ” l d i r31 , h i8 ( s e nd and r e c e i v e bu f f e r )\n\ t ”355 ” l d i r21 , 8 \n\ t ”356 ” l d i r23 , 8 \n\ t ”357 ” ld r24 , Z+ \n\ t ”358 ” l d i r25 , 0xFF \n\ t ”// t imeou t359 //” l d i r26 , 0 \n\ t ”360 ” l d i r27 , 0x80 \n\ t ”//= 1 f o r odd p a r i t y361 ” l d i r20 , 0 \n\ t ”362

    363 // ///////////////

    364 // end o f i n i t //

    365 // ///////////////

    366

    367 // ////////////

    368 /// s e a r c h i n g f i r s t s e t b i t in e u b u f f e r

    369 // i f no b i t i s s e t w i t h i n t h e r25 b i t s o f e u b u f f e r−> q u i t w i t h e r r o r370 // ///////////

    371

    372 ” 10 : \n\ t ”373 ” r c a l l g e t b i t \n\ t ”374 ”dec r25 \n\ t ”375 ”breq 20 f \n\ t ”// e r r o r376 ” brcc 10b \n\ t ”377 // found 1

    378 ” r c a l l g e t b i t \n\ t ”// found 1 in b i t s tream ! ; nex t b i t has to be a 0 f o r c o r r e c t s t a r t sequence379 ” brcs 20 f \n\ t ”// i f C i s t s e t => e r r o r380 // decod ing data

    381 ” 15 : \n\ t ”382 ” r c a l l g e t b i t \n\ t ”383 ” brcc 11 f \n\ t ”384 ” r c a l l g e t b i t \n\ t ”// e x p e c t i n g 0385 ” brcs 20 f \n\ t ”// e r r o r i f 11 sequence386 ” sec \n\ t ”387 ” r c a l l pu t b i t \n\ t ”// decoded wi th s u c c e s s 10 −> 1388 ”rjmp 15b \n\ t ”389 ” 11 : \n\ t ”390 ” r c a l l g e t b i t \n\ t ”// e x c p e c t i n g 1391 ” brcc 12 f \n\ t ”// i f 00 sequence −> end o f stream392 ” c l c \n\ t ”393 ” r c a l l pu t b i t \n\ t ”// decoded wi th s u c c e s s 01 −> 0394 ”rjmp 15b \n\ t ”395 // put b i t from Carry in 2 r2

    396 // i f b y t e i s f u