# Very High Speed Integrated Circuit Hardware Description Language/Les nouvelles interfaces : de la nunchuk de Nintendo à android

Dans ce chapitre nous avons l'intention d'étudier des interfaces un peu plus axées jeux que celles des chapitres précédents. Puisque nous avons l'intention de nous intéresser aux modestes jeux vidéo associés à des processeurs 8 bits nous voyons de la place pour étudier dans ce chapitre la manette de la console de jeux vidéo Wii de Nintendo. Un article publié dans Elektor (Septembre 2012) nous a décidé à nous intéresser à cette manette.
La deuxième extension possible est de s'intéresser aux téléphones portables et tablettes tactiles comme instrument de commande de jeux. D'un point de vue strictement technique ce choix peut sembler étrange : utiliser un téléphone portable (32 bits) pour commander un jeu vidéo qui tourne sur un processeur 8 bits ! Mais nous assumons ce choix : en fait nous sommes désespérés de voir nos effectifs étudiants baisser et cherchons à ce titre à avoir des démonstrations pour les portes ouvertes susceptibles d'intéresser nos jeunes. Est-ce le bon choix ? Seul l'avenir nous le dira.
Encore une fois ce chapitre est rédigé au fur et à mesure du déroulement des projets avec des étudiants. Cela peut le rendre parfois difficilement lisible puisque l'enseignant qui le rédige n'a aucun recul sur le sujet, mais espère que d'autres collègues et étudiants viendront à son secours.

## Étude de la manette Nunchuk

La manette Nunchuk est destinée à commander les jeux de la console Wii. Pour nous, nous la destinons au jeu pacman présenté dans un autre chapitre. Nous avons l'intention de nous intéresser au Joystick analogique et laissons l'étude de l'accéléromètre pour une autre année (autrement dit elle sera ajoutée plus tard).
Nous allons essayer dans la mesure du possible de garder la connectique de la Nunchuk. Si vous décidez de couper le câble, vous devez respecter les couleurs suivantes :
* blanc = masse
* rouge = 3,3 V
* vert = données
* jaune = horloge
Si vous désirez garder le connecteur, voici sa documentation :
L'accéléromètre est positionné de manière perpendiculaire au Joystick. Cela permet ainsi facilement le remplacement du Joystick par l'accéléromètre, ce qui sera peut être expérimenté plus tard.
Avant de vous engager plus loin, la lecture du protocole I²C est vivement conseillée.

### Le format des données

La manette Nunchuk envoie ses information comme 6 octets de données, lisibles à 0xa40008 et streamable en utilisant les modes Data Reporting qui incluent des octets d'extension (les octets non utilisés sont positionnés à 0x00). Les six octets de données sont (après decodage):
| | Bit | Bit | Bit | Bit | Bit | Bit | Bit | Bit |
| Byte | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 0 | SX<7:0> | SX<7:0> | SX<7:0> | SX<7:0> | SX<7:0> | SX<7:0> | SX<7:0> | SX<7:0> |
| 1 | SY<7:0> | SY<7:0> | SY<7:0> | SY<7:0> | SY<7:0> | SY<7:0> | SY<7:0> | SY<7:0> |
| 2 | AX<9:2> | AX<9:2> | AX<9:2> | AX<9:2> | AX<9:2> | AX<9:2> | AX<9:2> | AX<9:2> |
| 3 | AY<9:2> | AY<9:2> | AY<9:2> | AY<9:2> | AY<9:2> | AY<9:2> | AY<9:2> | AY<9:2> |
| 4 | AZ<9:2> | AZ<9:2> | AZ<9:2> | AZ<9:2> | AZ<9:2> | AZ<9:2> | AZ<9:2> | AZ<9:2> |
| 5 | AZ<1:0> | AZ<1:0> | AY<1:0> | AY<1:0> | AX<1:0> | AX<1:0> | BC | BZ |
(tableau tiré de wiibrew)
SX,SY sont les positions du Joystick analogique en X et Y, tandis que AX, AY, et AZ sont les donnée de l'accéléromètre sur 10 bits.
Avant d’utiliser ces données, le programmeur doit faire l'opération suivante : donnée exacte = (donnée lue XOR 0x17) + 0x17. Comme nous le spécifierons plus loin, nous n'utiliserons pas cette opération : nous demanderons à la manette de nous retourner les données de manière non cryptée. Ceci se choisit avec l'initialisation du dialogue.

### Le protocole d'échange

Le protocole d'échange est le protocole I²C. Pour le mettre en œuvre, il va nous falloir étudier un module VHDL et le transformer en périphérique. Avant cela, détaillons ce protocole.
Le protocole considère la manette Nunchuk comme esclave. Cet esclave a une adresse fixée par Nintendo de 0x52 (sur 7 bits). Ces 7 bits sont décalés vers le poids fort (d'une position) et on lui ajoute un bit de lecture/écriture (en poids faible) ce qui se transforme en deux identificateurs : écriture 0xA4 et lecture 0xA5.
Tout échange avec la manette nécessite une initialisation.

#### Protocole d'initialisation

Nos lectures nous ont conduit a découvrir deux initialisations différentes :
* PDF zx-nunchuk repris aussi dans un TP universitaire et ici aussi
* interface Nunchuk USB : Elektor (Septembre 2012) p16
Nous allons pour le moment présenter les deux techniques.

##### Initialisation courte (ancienne manière)

Un essai présenté ici (chez dangerousprototypes) avec un de leur produit, le bus pirate, pour épier des communications nous donne :
qui nous montre que l'initialisation consiste à envoyer 3 octets : 0xa4 0x40 0x00.
Si l’on veut un peu plus de détail, voici une représentation schématique (adaptée de PDF zx-nunchuk):
Nous avons adapté l'acquittement des trames directement à notre utilisation : c’est soit la manette qui acquitte soit le FPGA. Ici tout le monde peut se rendre compte que c’est toujours la manette.
Cette méthode ne fonctionne que sur les manettes de Nintendo filaires. Cela tombe bien c’est ce qui nous intéresse.

##### Initialisation à la Elektor (nouvelle méthode)

Cette initialisation est un peu plus complexe puisqu'elle se décompose par l'envoi de deux fois trois octets :
* envoi de trois octets : 0xA4 0xF0 0x55
* suivi encore de trois octets : 0xA4 0xFB 0x00
Cette méthode d'initialisation devrait fonctionner avec à peu près tous les matériels. Elle possède l'avantage de retourner les données non cryptées.
À part l'initialisation de la manette, il nous faut naturellement récupérer ses données de temps en temps.

#### La récupération des données

Pour récupérer les 6 octets de données présentés plus haut. Cela se fait en deux étapes :
* envoi du pointeur à lire à la manette, ici au début en 0x00
* récupération des six octets en envoyant la commande read à l'adresse 0x52, c'est-à-dire en envoyant l'octet 0xA5.
Voici ce que donne le bus pirate :
Pour information les données retournées concernant le joystick (en tout cas celui que nous avons en notre possession) sont approximativement :
* SX retourne des données autour de 35 (complètement à gauche) jusqu'à 228(complètement à droite),
* SY retourne des données autour de 27 jusqu'à 220.
* au centre on a environ 128 pour les deux.

##### Résumé de la lecture

Voici présenté la trame d'initialisation du pointeur dans la RAM de la manette Nunchuk (adaptée de PDF zx-nunchuk) :
Cette trame est en général suivie par la commande de lecture (adaptée de PDF zx-nunchuk):

### Conception du périphérique

Le périphérique destiné à communiquer avec la manette Nunchuk devra être réalisé à partir de projets existants. Citons par exemple :
* i2c Master Slave chez Opencores.org, projet réalisé par Eli Smertenko. Malheureusement ce cœur n'est absolument pas documenté, il faut donc se remonter les manches pour l’utiliser.
* conception d'un contrôleur I2C en VHDL
* PDF these magister qui décrit en français un contrôleur i2c en VHDL
Il nous faut choisir parmi ces trois possibilités. Nous avons essayé i2c Master Slave sans succès. Cela ne veut pas dire que le cœur ne fonctionne pas mais que nous n'avons pas trouvé les bonnes commandes avec notre machine d'états. Finalement nos recherches sur Internet nous ont permis de trouver un autre cœur I2C maître, avec une conception qui nous a plu... pour finir de le faire fonctionner au bout de trois semaines ! Celui-ci peut être trouvé ICI sur Internet

#### Notre i2c maître

La Nunchuk étant un périphérique i2c esclave, il nous faut un i2c maître pour dialoguer avec. Le maître est, entre autres, responsable de la réalisation de l'horloge, de la réalisation des "START" et "STOP".
Voici donc ce cœur i2c maître en VHDL (Auteur : à priori Richard Herveille, ancienne version de son cœur téléchargeable chez Opencores). Ce cœur est compatible wishbone ce qui ne nous intéresse pas puisque notre processeur ne l'est pas. Voici le code en question :

##### Commentaires sur le code VHDL

Vous trouverez dans ce code souvent le commentaire : "-- 4x SCL". Ce commentaire est faux. En fait il faut réaliser 5x SCL à cause de l'état "idle" par lequel on passe systématiquement. Comme il y a plusieurs états idle, il s'agit de celui de "i2c_core". Nous avons pensé à cela dès que nous avons lu le code et cela a été confirmé par une étude à l'oscilloscope.
Cette entrée "4x SCL" nous a posé aussi un souci et nous ne savions pas exactement ce qu’il fallait y faire ! Au départ, nous nous sommes donc lancé avec un compteur 8 bits qui comptait à une fréquence "4x SCL". Mais une lecture approfondie du code nous a montré qu’il fallait en fait y mettre une valeur unique qui est chargée de temps en temps et qui est décrémentée et qui arrivée à zéro génère une validation : et c’est cette validation qui doit arriver tous les "4x SCL" euh pardon ! tous les "5x SCL". Cette valeur est positionnée dans le module de la section suivante à "01100100". Cherchons comment est calculée cette valeur ? On a une horloge de 50 MHz soit 50 000 kHz et l’on doit fabriquer 5x 100 kHz (SCL est donc à 100 kHz). La division donne 100 qui en binaire donne 1100100. Voila donc l'explication.
Il est grand temps maintenant de présenter la partie que nous avons réalisé autour de ce cœur.

#### Notre machine d'états

Comme le titre l'indique, il s'agit d'une machine d'états que nous allons détailler quelque peu maintenant.
Ce code est un peu long et sera commenté un peu plus loin.
Pour ceux qui sont intéressés par ce code sachez qu’il a été publié ici le 11/12/12 mais qu’il risque d'évoluer un peu : la partie combinatoire sera revue plus tard... Revenez voir de temps en temps : nous retirerons cet avertissement dès que nous considèrerons que ce code est terminé.
* mis à jour le 17/12/12 pour gérer le bouton Z
* mis à jour le 16/01/2013 pour gérer le bouton C.
* ce code a été interfacé au pacman avec succès sauf pour les boutons C et Z, puis ...
* mis à jour dans une section un peu plus loin le 12 juillet 2013 avec un FIFO comme interface (semble fonctionner complètement maintenant)
* réalisation d'un périphérique i2c plus générique pour l'ATMega16 (décrit ICI) le 14 janvier 2017. Vous le trouverez dans la partie travaux pratiques de ce livre : Utiliser des shields Arduino.

##### Commentaires sur le code VHDL

Ce code nous montre que nous avons choisi l’initialisation longue qui a l'avantage de ne pas nécessiter de décodage de ce qui est reçu de la Nunchuk.
Cette machine d'états lit les six octets retournés par la Nunchuk mais ne mémorise que les deux premiers et le dernier. Les deux registres qui servent à mémoriser l'information du joystick analogique sont gérés par le code VHDL :
L'initialisation d'un des deux registres (et pas des autres) est un vestige des tests et peut être retirée.
Nous avons choisi de sortir les informations "Up", "Down", "Left", "Right" car cette manette est destinée à remplacer un vieux Joystick à 4 interrupteurs qui nous fournissait donc une information binaire sur les quatre directions. Il n’est pas difficile à ce stade de lire les valeurs des accéléromètres mais nous laissons ce problème pour un projet d'une année future. La réalisation de ces quatre bits est faite par le circuit combinatoire :
Les valeurs C0 et 30 peuvent être changées si l’on a besoin de plus de sensibilité pour la manette. Ces valeurs C0 et 30 correspondent à la manette presque à fond de chaque côté mais nous permettent surtout de ne pas avoir deux déplacements à la fois. Si vous avez l'intention de faire un déplacement vers la droite, rien ne dit que vous n'allez pas légèrement déplacer le joystick analogique légèrement vers le haut (ou vers le bas). Il serait bon que dans ce cas précis que seul le déplacement vers la droite soit pris en compte : d'où les valeurs assez élevées (0xC0) et assez basses (0x30). Ces valeurs doivent être ajustées à vos manettes.
La numérotation des états de la machine d'états semble anarchique mais montre simplement les errements de l'auteur pour faire fonctionner l'ensemble.

#### Un nouveau module pour gérer l’ensemble des données de la Nunchuk

Le projet pacman 2013 doit utiliser l’ensemble des données de la manette Nunchuk y compris les données de l'accéléromètre. Nous publions le code dans ce chapitre mais il est parfaitement inutilisable sans microprocesseur embarqué puisque l'interface choisie est un FIFO. Au risque de me répéter, lisez pacman 2013 qui l’utilisera complètement (pas avant avril 2014 quand le projet sera terminé).
L'objectif de ce module est demander à la Nunchuk ses six données et de les mettre dans un FIFO. L'avantage est que du point de vue du futur processeur, ce module nécessitera une seule adresse de registre pour être lu.
Ce module utilise un FIFO logicore Xilinx qui présente plusieurs inconvénients :
* ce logicore n’est pas utilisable avec des FPGA non fournis par Xilinx. Sachez cependant, qu’il est facile de trouver l'équivalent en VHDL pur sur Internet
* on a un exemple de gaspillage de ressources ici : le FIFO est 16x8 alors qu'on utilisera seulement 6x8 données
* le signal data_present du FIFO est sorti du module et sera utilisé par le processeur. Or ce qu’il faudrait sortir c’est un signal "full" quand on a rempli nos six données. Nous espérons améliorer cela plus tard.

#### Fichier ucf

Le fichier ucf est relativement important ici. Il faut sortir l'i2c avec des résistances de tirage.

### Résumé pour les utilisateurs de l'i2c

Les nombreux lecteurs de ce livre (le sont-il vraiment, nombreux ?) peuvent être attirés par l'aspect i2c mais sans la Nunchuk. Nous leur dédions ce petit résumé qui pourra, nous l'espérons, les faire réaliser des applications i2c dans leur FPGA.
Rappelons que la machine d'état partielle présentée ci-dessous fonctionne à 50 MHz.
Dans toute cette section nous avons choisi un style de programmation des machines d'états un peu lourd puisque sa partie combinatoire de sortie est systématiquement écrite pour chacun des états. Pour tous ces signaux intéressez-vous seulement à :
* O_write
* start
* Dout
* O_read
* stop
* O_ack_n
Tous sont des sorties de la machine d'états destinés à commander le cœur i2c.
* Le start ne fonctionne pas tout seul : il est toujours lié à une écriture par le maître. Le premier octet d'ailleurs qui est écrit à cette occasion est l'adresse de l'esclave. Il est réalisé dans notre cas par :
où vous voyez write et start positionnés en même temps ainsi que 0xA4 qui est l'adresse 0x52 décalée de un bit vers la gauche et avec le bit de poids faible à 0 qui signifie que l’on va continuer à écrire. Le code ci-dessous par contre est du même type sauf que dans 0xA5 le bit de poids faible est positionné ce qui signifie que l'état suivant, ici s13, va lire.
* écriture de l'octet suivant : elle se fait par un code du type :
où seul write est positionné à 1.
* écriture du dernier octet : il est différent en ce sens qu’il est suivi par un STOP. Il faut alors positionner simultanément write et stop à 1.
* lecture des octets : une fois demandé une lecture, les octets de données arrivent en rafale. C'est au maître de générer les acquittements et le "non acquittement" du dernier octet suivi du stop. Voici le code de lecture du premier octet :
Vous voyez une gestion de deux états. L'état s20 est destiné à mémoriser ce que l’on vient de lire dans un registre. ack_n = '0' signifie qu'on acquitte.
* lecture du dernier octet avec non acquittement suivi d'un STOP :
read et stop sont positionné ainsi que "ack_n" à un, ce qui signifie pas d'acquittement.
Nous allons passer à un tout autre sujet maintenant, les téléphones Android.

### Les difficultés rencontrées ne sont-elles pas résolues par d'autres

La réalisation du contrôleur maître pour la Nunchuk a été pour nous une épreuve... et nous savons que si en lieu et place de cette manette, nous désirons lire un accéléromètre MPU6050, par exemple, tout est à refaire ! Refaire la machine d'états n’est pas si simple et il faut prévoir ses tests. En clair nous cherchons depuis longtemps un moyen plus générique de faire les choses.
Nous avons trouvé un contrôleur i2c intelligent. Ce contrôleur développé par Mike Field est utilisé dans quelques uns de ses projets surtout en maître. Il l'a conçu pour éviter de réaliser justement des machines d'états complexes en remarquant que dans un FPGA, il n'y a pas lieu de faire tourner la machine d'état à une fréquence de 50 MHz puisqu'en général l'i2c plafonne à 1 MHz. Le problème est que le code VHDL disponible sur son site n'est pas complet et que Mike Field n'a jamais répondu à nos sollicitations. Comme il manque une instruction très importante pour l'i2c, nous avons tenté de compléter son code mais sans succès. C'est donc une autre voie qu'il nous faut suivre...
Après tout ces déboires et plusieurs années, notre expérience avec i2c dans les microcontrôleurs a un peu progressé. Lorsque nous avons réalisé le périphérique pour la Nunchuk en 2012, nous pensions que les périphériques i2c des microcontrôleurs étaient sophistiqués et qu'il serait difficile de les égaler. Mais la rédaction du chapitre sur l'i2C dans le livre sur les AVRs nous a montré que le matériel ne prenait pas grand chose en charge en fait. C'est au programmeur de gérer le protocole, même si ce n'est pas lui qui gère l'horloge. Nous avons donc décidé de copier partiellement la gestion de l'i2c des AVRs dans nos processeurs embarqués. Ce travail est réalisé dans la partie TP : Utiliser des Shields Arduino avec les FPGA.