
Alles begann mit dem Erwerb eines interessanten Geräts auf dem Sekundärmarkt – dem Smart Response XE (). Es ist für Schulen gedacht: Jeder Schüler in der Klasse erhält ein Gerät, das wie ein elektronisches Notizbuch oder ein Übersetzer aus den 90ern aussieht. Der Lehrer stellt eine Frage, und die Schüler geben ihre Antworten über die Tastaturen der Geräte ein, die per Funk (802.15.4) an einen Empfänger verbunden sind, der am Computer des Lehrers angeschlossen ist.
Die Unterstützung dieser Geräte wurde vor einigen Jahren eingestellt, und das, was Schulen für 100-200 Dollar pro Stück gekauft haben, wird jetzt auf eBay für 10 Dollar oder weniger angeboten. Die Hardware eignet sich hervorragend für geekige Experimente:
- 60-Tasten-Tastatur
- Display mit einer Auflösung von 384×136, 2 Bit pro Pixel – ähnlich wie bei BK, CGA, aber 4 nicht Farben, sondern Helligkeitsstufen
- Mikrocontroller ATmega128RFA1 (128 kB Flash-Speicher, 4 kB EEPROM, 16 kB RAM, Transceiver nach Standard 802.15.4)
- externer Flash-Speicher von 1 Megabit (128 Kilobyte) mit SPI-Schnittstelle
- Fach für 4 AAA-Batterien.
Der Name des Mikrocontrollers deutet darauf hin, dass er zur AVR-Familie gehört, was die Aufgabe, ein Arduino-kompatibles Gerät zu erstellen, mehr als trivial macht…
Aus der Nachricht auf erfuhr der Autor, dass das (in diesem Link wird auch erklärt, wo was angeschlossen wird), sodass Spiele für Arduboy gestartet werden können:

Aber der Autor interessiert sich weniger dafür, auf dem Gerät zu spielen, als für das Lernen:
- Flash-Speicher mit SPI-Schnittstelle
- Bootloader für AVR
- der Standard 802.15.4
Der Autor begann mit dem Schreiben (GPL v3), das die Initialisierung des Displays, das Ausgeben von Text und Rechtecken sowie den Zugriff auf den Flash-Speicher mit SPI-Schnittstelle ermöglicht. Anschließend begann er, Ideen für die praktische Nutzung des Geräts zu entwickeln: ein tragbares, VT-100-kompatibles Terminal, Mehrspieler-Spiele. Nachdem er drei Geräte umgebaut hatte, beschloss er, sie zu «lehren», Sketche «over-the-air» zu empfangen. Das wäre nicht nur interessant, sondern auch sehr praktisch: das Gehäuse des Geräts jedes Mal zu öffnen, ist schwierig, und unter dem Deckel des Batteriefachs befinden sich nur Öffnungen, die den Anschluss eines JTAG-Programmers an das Board ermöglichen.

Das reicht aus, um den Arduino-Bootloader zu flashen, aber nicht den Sketch – der serielle Port ist nicht herausgeführt, ohne das Gehäuse zu öffnen, kommt man daher nicht weiter. Außerdem sind die TX0- und RX0-Leitungen des ersten seriellen Ports mit den Leitungen zur Abfrage der Tastaturmatrix kombiniert, und zwar mit denen, die für die Abfrage der Funktionstasten an den Seiten des Displays zuständig sind. Aber was soll man machen – der Autor hat Folgendes konstruiert:

Dort hat er die JTAG-Leitungen herausgeführt, und jetzt ist es nicht mehr notwendig, das Batteriefach zu öffnen. Damit man auch Sketches hochladen kann, hat er auch beide seriellen Ports an denselben Anschluss gelegt und einen Schalter hinzugefügt, da das Gerät mit eingesetzten Batterien physisch nicht anders abgeschaltet werden kann.
Es war notwendig, recht lange mit Lötkolben, Cuttermesser und Heißklebepistole zu arbeiten. Im Allgemeinen ist es deutlich bequemer, Sketches „über die Luft“ hochzuladen, man muss dringend etwas in dieser Hinsicht erfinden.
Die Arduino IDE verwendet für das Hochladen von Sketches das Programm . Es kommuniziert mit dem Mikrocontroller über das Protokoll , der den beidseitigen Dateitransfer ermöglicht. Er ist schlecht kompatibel mit Kanälen, in denen variable Latenzen, Verzerrungen und Datenverluste auftreten können. Wenn in einem seriellen Kanal etwas knistert oder andere Störungen auftreten, kann man verrückt werden, auf die Ursache zu kommen. Einmal hat der Autor ein halbes Tag geflucht, bis ihm klar wurde, dass es an einem schlechten Kabel und einem launischen CP2102-Interfacewandler lag. Selbst ein Mikrocontroller mit integriertem Interfacewandler, wie zum Beispiel der ATmega32u4, kann sich manchmal so „benehmen“. Jeder Arduino-Nutzer hat bemerkt, dass Programmierfehler beim Hochladen von Sketchen alles andere als selten sind. Manchmal verläuft der Schreibvorgang reibungslos, doch beim anschließenden Lesen wird ein Fehler gefunden. Das bedeutet nicht, dass bei der Aufnahme ein Fehler aufgetreten ist – der Fehler trat beim Lesen auf. Und jetzt stellen Sie sich vor, dass im „Drahtlos“-Betrieb genau dasselbe, jedoch viel häufiger passiert.
Nachdem der Autor verschiedene Ansätze zur Lösung dieses Problems ausprobiert hat, hat er Folgendes ausgeklügelt. Das Gerät verfügt über 128 Kilobyte Flash-Speicher mit SPI-Schnittstelle – Daten werden über Kabel empfangen (wir erinnern uns, dass der Autor bereits ein Gerät mit einer Anschlussbuchse hat), wir nutzen diesen Speicher als Puffer und senden die Daten über das Funkkanal an ein anderes Gerät. Ein Gruß von Cybiko.
Nach dem Schreiben des Codes zur Bedienung des Funkkanals und der Schriftart wurde der Bootloader länger als 4 Kilobyte. Daher musste der Wert von HFUSE von 0xDA auf 0xD8 geändert werden. Jetzt kann der Bootloader bis zu 8 Kilobyte lang sein, und die Startadresse beträgt 0x1E000. Dies ist im Makefile vermerkt, muss jedoch auch beim Flashen berücksichtigt werden. mit avrdude.
Der 802.15.4 Sender/Empfänger im ATmega128RFA1 ist ursprünglich für den Betrieb mit dem Protokoll vorgesehen. , der ziemlich komplex ist, daher entschied sich der Autor, stattdessen einfach Pakete zu übertragen. Dies ist hardwareseitig im ATmega128RFA1 implementiert, sodass nur wenig Code benötigt wird. Um es zudem zu vereinfachen, entschied sich der Autor, einen festen Kanal zu verwenden, ohne die Möglichkeit zu bieten, ihn sogar manuell auszuwählen. Der Standard 802.15.4 unterstützt 16 Kanäle mit Nummern von 11 bis 26. Diese sind stark ausgelastet, einige überlappen auch mit WiFi-Kanälen (ZigBee-Kanäle sind rot markiert, WiFi-Kanäle blau, grün und gelb).

Es stellte sich heraus, dass die Kanäle 15 und 26 am wenigsten anfällig für Störungen durch WiFi sind. Der Autor wählte den zweiten. Hinweis: Der Übersetzer weiß nicht, ob es erlaubt ist, ZigBee auf diese Weise zu vereinfachen. Vielleicht sollte man noch etwas programmieren und es vollständig implementieren?
Auf dem ersten Gerät muss ein Zustandsautomat implementiert werden, der Daten über das STK500-Protokoll überträgt. Im Großen und Ganzen sind die gesendeten und empfangenen Nachrichten eigenständig, aber einige hängen von zuvor über den Kanal gesendeten ab. Eine Beschreibung des Dialogs ist angeführt. .
Ein wichtiger Aspekt dieses Dialogs ist die Übertragung von Paketen, die zur Speicherung im Flash-Speicher des Zielgeräts bestimmt sind. Bei einfachen Mikrocontrollern der AVR-Familie beträgt die Seitenkapazität 128 Byte, während sie bei dem ATmega128RFA1 256 Byte beträgt. Das ist auch der Fall für den Flash-Speicher, der über das SPI-Protokoll angeschlossen wird. Wenn das Programm im ersten Gerät den Sketch hochlädt, wird dieser nicht sofort an das zweite Gerät übertragen, sondern zunächst in diesen Speicher geschrieben. Wenn die Arduino IDE die Richtigkeit der Speicherung überprüft, werden die aufgenommenen Daten gesendet. Jetzt müssen die empfangenen Daten über den Funkkanal an das zweite Gerät übertragen werden. Dabei erfolgt der Wechsel vom Empfang zum Senden und zurück recht häufig. Das STK500-Protokoll ist gegenüber Verzögerungen gleichgültig, toleriert jedoch keinen Datenverlust (es ist komisch, dass zuvor erwähnt wurde, dass Verzögerungen bei der Datenübertragung ebenfalls Auswirkungen haben). Datenverluste bei der drahtlosen Übertragung sind jedoch unvermeidlich. Im ATmega128RFA1 gibt es eine hardwareseitige Implementierung für erneute Anfragen im Fall von Zweifeln an der Übertragungsgenauigkeit, doch der Autor entschied sich, dies selbst programmatisch zu realisieren. Er entwickelte ein Protokoll, bei dem in eine Richtung deutlich mehr Daten übertragen werden als in die andere.
Es ist nicht perfekt, aber alles funktioniert. Eine 256-Byte-Seite wird in vier Segmente unterteilt, von denen jedes über einen Funkkanal als Paket übertragen wird. Ein Paket fasst bis zu 125 Byte Daten plus ein Byte für die Länge und zwei für die CRC. Die Fragmente mit einer Länge von 64 Byte zusammen mit den Seiten- und Segmentnummern (von 0 bis 3) werden dort untergebracht. Im Empfangsgerät ist eine Variable vorgesehen, die es ermöglicht, die Anzahl der empfangenen Segmente zu verfolgen. Sobald alle vier ankommen, wird an das sendende Gerät eine Bestätigung gesendet, dass die gesamte Seite empfangen wurde. Gibt es keine Bestätigung (CRC stimmt nicht überein) – wird die gesamte Seite erneut gesendet. Die Geschwindigkeit ist sogar höher als bei der Übertragung über Kabel. Siehe:

Tatsächlich sollte man einen praktischen Weg vorsehen, um Geräte über ein Kabel für das Hochladen von Sketchen anzuschließen. Zum Beispiel könnte man einen solchen CP2102-Schnittstellenwandler wie auf dem Foto innen anbringen und so an der Platine befestigen, dass er den Zugkräften beim Ein- und Ausstecken des Micro-USB-Kabels standhält.

Es gibt auch einen 3,3-Volt-Spannungsregler (und wie man ihn in einem Gerät mit 6-Volt-Stromversorgung verwendet — vorausgesetzt, es gibt einen solchen Regler, und man kann zwei Dioden hinzufügen, um automatisch auszuwählen, von welchem er die Versorgung beziehen soll). Von der Schnittstellenplatine müssen alle drei LEDs entfernt werden, da sie sonst die Batterien zusätzlich belasten, während sie davon betrieben werden, und die Abfrage der Tastatur sowie die Arbeit mit dem Flash-Speicher über das SPI-Interface stören können.
Das Verfolgen des Ziels stellte sich als sogar interessanter heraus als dessen Erreichung (und das ist kein Witz über den Bus). Der Autor hat viel über Bootloader für AVR, Flash-Speicher mit SPI-Interface, das STK500-Protokoll und den Standard 802.15.4 gelernt.
Der gesamte restliche Code, zusätzlich zu der oben beschriebenen Bibliothek — , und dieser steht ebenfalls unter GPL v3. Der Twitter-Account des Autors — .
Quelle: habr.com
