
Tout a commencé par l'achat par l'auteur d'un appareil intéressant sur le marché de l'occasion — Smart Response XE (). Il est destiné aux écoles : chaque élève de la classe reçoit un appareil semblable à un carnet électronique ou un traducteur des années 90, l'enseignant pose une question, et les élèves saisissent les réponses sur les claviers des appareils, qui sont transmises par radio (802.15.4) à un récepteur connecté à l'ordinateur de l'enseignant.
Le support de ces appareils a été arrêté il y a quelques années, et ce que les écoles achetaient entre 100 et 200 dollars pièce, apparaît maintenant sur eBay à 10 dollars ou moins. Le « matériel » est très adapté aux expériences de passionnés :
- un clavier de 60 touches
- un affichage avec une résolution de 384×136, 2 bits par pixel — similaire à BK, CGA, mais 4 couleurs de luminosité plutôt que de vraies couleurs
- microcontrôleur ATmega128RFA1 (128 Ko de mémoire flash, 4 Ko de ROM, 16 Ko de RAM, émetteur-récepteur conforme à 802.15.4)
- mémoire flash externe (par rapport au microcontrôleur, et non à l'ensemble de l'appareil) de 1 mégabit (128 Ko) avec interface SPI
- compartiment pour 4 piles AAA.
D'après le nom du microcontrôleur, on comprend qu'il appartient à la famille AVR, donc rendre l'appareil compatible avec Arduino est une tâche plus que triviale…
D'une nouvelle sur l'auteur a appris que cela (le même lien parle des connexions), permettant de lancer des jeux pour Arduboy :

Mais l'auteur est plus intéressé par la possibilité d'apprendre, plutôt que de jouer sur l'appareil :
- mémoire flash avec interface série SPI
- bootloaders pour AVR
- norme 802.15.4
L'auteur a commencé par écrire (GPL v3), permettant d'initialiser l'affichage, d'afficher du texte et des rectangles, ainsi que d'accéder à la mémoire flash avec l'interface SPI. Ensuite, il a commencé à imaginer des idées d'utilisation pratique de l'appareil : un terminal compatible VT-100 de poche, des jeux multijoueurs. Après avoir modifié trois appareils, il a décidé de « les apprendre » à recevoir des sketches « par voie aérienne ». Ce qui serait non seulement intéressant, mais aussi très pratique : le boîtier de l'appareil est difficile à ouvrir à chaque fois, et sous le capot du compartiment des piles se trouvent seulement des trous permettant de connecter un programmateur JTAG à la carte.

C'est suffisant pour télécharger le chargeur Arduino, mais pas le sketch — le port série n'est pas accessible, il faudra tout de même ouvrir le boîtier. De plus, les lignes TX0 et RX0 du premier port série sont associées aux lignes de sondage de la matrice du clavier, c'est-à-dire celles par lesquelles se fait l'interrogation des touches fonctionnelles de chaque côté de l'écran. Mais que faire — l'auteur a fabriqué ceci :

Il a donc connecté les lignes JTAG, et maintenant l'ouverture du compartiment des piles n'est plus nécessaire. Et pour pouvoir télécharger aussi des sketches, il a connecté à ce même port les deux ports série, ajoutant également un interrupteur, car avec les piles installées, il est physiquement impossible d'éteindre l'appareil autrement.
Il a fallu pas mal de temps pour travailler avec un fer à souder, un cutter et un pistolet à colle. En général, il est beaucoup plus pratique de télécharger des sketches 'sans fil', il faut donc rapidement inventer quelque chose.
L'IDE Arduino utilise le programme . Il interagit avec le microcontrôleur via le protocole , qui permet de transmettre des fichiers dans les deux sens. Il est mal compatible avec les canaux où des délais variables, des distorsions et des pertes de données peuvent se produire. Si quelque chose dans le canal série s'entrechoque ou grésille, on peut devenir fou en cherchant la raison. Une fois, l'auteur a passé la moitié de la journée à se rendre compte que c'était à cause d'un mauvais câble, ainsi qu'un convertisseur de signal capricieux CP2102. Même un microcontrôleur avec un convertisseur de signal intégré, par exemple, l'ATmega32u4, peut parfois avoir ce genre de 'caprices'. Chaque utilisateur d'Arduino a remarqué que les erreurs lors du téléchargement de sketches ne sont pas si rares. Parfois, l'enregistrement se passe bien, mais lors de la lecture de vérification, une erreur est détectée. Cela ne signifie pas qu'il y a eu une erreur lors de l'enregistrement — la défaillance s'est produite lors de la lecture. Et maintenant, imaginez qu'en 'sans fil', cela se produira de la même manière, mais beaucoup plus souvent.
Après avoir essayé différentes manières de surmonter ce problème, l'auteur a inventé ce qui suit. L'appareil dispose de 128 Ko de mémoire flash avec interface SPI — nous recevons des données par câbles (nous nous souvenons qu'un appareil avec un port sur le côté que l'auteur possède déjà), nous utilisons cette mémoire comme tampon, et nous envoyons les données à un autre appareil par voie radio. Une petite salutation de Cybiko.
Après avoir écrit le code pour fonctionner avec le canal radio, ainsi que la police, le chargeur est devenu plus long de 4 kilo-octets. Par conséquent, la valeur de HFUSE a dû être changée de 0xDA à 0xD8. Désormais, le chargeur peut avoir une longueur allant jusqu'à 8 kilo-octets, et l'adresse de départ est devenue 0x1E000. Cela est reflété dans le Makefile, mais doit également être pris en compte lors du téléchargement. avec avrdude.
Le récepteur émetteur standard 802.15.4 dans l'ATmega128RFA1 était à l'origine conçu pour fonctionner selon le protocole , qui est assez complexe, c'est pourquoi l'auteur a décidé de simplement transmettre des paquets à la place. Cela est implémenté matériellement dans l'ATmega128RFA1, donc peu de code sera nécessaire. Pour plus de simplicité, l'auteur a également choisi d'utiliser un canal fixe, sans permettre de le sélectionner manuellement. La norme 802.15.4 prend en charge 16 canaux numérotés de 11 à 26. Ils sont assez chargés, certains chevauchent également les canaux WiFi (les canaux ZigBee sont indiqués en rouge, ceux de WiFi en bleu, vert et jaune).

Il s'est avéré que les canaux 15 et 26 sont les moins sensibles aux interférences WiFi. C'est le second que l'auteur a choisi. Avertissement : le traducteur ne sait pas s'il est permis de simplifier ainsi ZigBee. Peut-être vaut-il encore la peine de programmer un peu plus et de le réaliser complètement ?
Sur le premier des appareils, il faut implémenter une machine à états qui transmet des données selon le protocole STK500. Dans la plupart des cas, les messages transmis et reçus sont autonomes, mais certains sont liés à ceux qui ont déjà passé le canal. La description du dialogue est fournie. .
Un élément important de ce dialogue est la transmission des paquets destinés à être enregistrés dans la mémoire flash de l'appareil cible. Pour les microcontrôleurs simples de la famille AVR, la taille de la page est de 128 octets, mais pour l'ATmega128RFA1, elle est de 256. La mémoire flash qui se connecte via le protocole SPI a la même taille. Lorsque le programme dans le premier appareil télécharge le sketch, il ne l'envoie pas immédiatement au second, mais l'écrit dans cette mémoire. Lorsque l'Arduino IDE vérifie l'exactitude de l'enregistrement, il reçoit ce qui y a été écrit. Il faut maintenant transmettre les données reçues par radio au second appareil. À cet égard, le passage de la réception à l'envoi et vice versa se produit assez souvent. Le protocole STK500 est indifférent aux délais, mais ne tolère pas la perte de données (étrangement, il est dit plus haut que les délais de transmission des données ont aussi un impact). Et les pertes lors de la transmission sans fil sont inévitables. L'ATmega128RFA1 intègre une réalisation matérielle des demandes de répétition en cas de doutes sur l'exactitude de la transmission, mais l'auteur a décidé de le réaliser lui-même par voie logicielle. Il a développé un protocole dans lequel beaucoup plus de données passent dans un sens que dans l'autre.
Il n'est pas parfait, mais tout fonctionne. La page de 256 octets est divisée en quatre segments, chacun étant transmis par radio sous forme de paquet. Le paquet contient jusqu'à 125 octets de données plus un octet pour la longueur et deux pour le CRC. Ainsi, les fragments de 64 octets avec les numéros de pages et de segments (de 0 à 3) y sont inclus. Dans l'appareil récepteur, une variable est prévue pour suivre combien de segments ont été reçus, et lorsque les quatre arrivent, un accusé de réception est envoyé à l'appareil émetteur confirmant que l'ensemble de la page a été reçue. Pas de confirmation (le CRC ne correspond pas) — renvoyons toute la page. La vitesse est même supérieure à celle de la transmission par câble. Regardez :

Mais en fait, il serait bon de prévoir un moyen pratique de connecter un câble aux appareils pour télécharger des sketches par ce biais. Par exemple, placer à l'intérieur un tel convertisseur d'interface CP2102, comme sur la photo, et le coller à la carte de manière à ce qu'il résiste à la pression lors de la connexion et déconnexion du câble Micro USB.

Il y a également un régulateur de 3,3 volts (et comment l'utiliser dans un appareil alimenté par 6 volts — à condition qu'il y ait un régulateur similaire, et que l'on puisse ajouter deux diodes pour sélectionner automatiquement l'une ou l'autre source d'alimentation). Tous les trois LED de la carte du convertisseur d'interface doivent être désoudés, sinon elles vont surcharger la batterie lorsqu'elles y sont alimentées, et nuire au sondage du clavier et à l'utilisation de la mémoire flash avec l'interface SPI.
Poursuivre l'objectif s'est révélé encore plus intéressant que de l'atteindre (et pas besoin de cette blague sur le bus). L'auteur a appris beaucoup de choses sur les chargeurs pour AVR, la mémoire flash avec l'interface SPI, le protocole STK500 et la norme 802.15.4.
Tout le reste du code en plus de la bibliothèque décrite ci-dessus — , et il est aussi sous GPL v3. Twitter de l'auteur — .
Source : habr.com
