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

Leçons de niveau 15
Une page de Wikiversité, la communauté pédagogique libre.
Début de la boite de navigation du chapitre
Les nouvelles interfaces : de la nunchuk de Nintendo à android
Icône de la faculté
Chapitre no 4
Leçon : Very High Speed Integrated Circuit Hardware Description Language
Chap. préc. :Interfaces RS232 et USB
Chap. suiv. :VHDL et machines à états algorithmiques
fin de la boite de navigation du chapitre
En raison de limitations techniques, la typographie souhaitable du titre, « Very High Speed Integrated Circuit Hardware Description Language : Les nouvelles interfaces : de la nunchuk de Nintendo à android
Very High Speed Integrated Circuit Hardware Description Language/Les nouvelles interfaces : de la nunchuk de Nintendo à android
 », n'a pu être restituée correctement ci-dessus.

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.


Étude de la manette Nunchuk[modifier | modifier le wikicode]

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 :

Documentation de la Wii-Nunchuk

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[modifier | modifier le wikicode]

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
Byte 7 6 5 4 3 2 1 0
0 SX<7:0>
1 SY<7:0>
2 AX<9:2>
3 AY<9:2>
4 AZ<9:2>
5 AZ<1:0> AY<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[modifier | modifier le wikicode]

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[modifier | modifier le wikicode]

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)[modifier | modifier le wikicode]

Un essai présenté ici (chez dangerousprototypes) avec un de leur produit, le bus pirate, pour épier des communications nous donne :

I2C>[0xa4 0x40 0x00]<<<Wii Nunchuck initialize
I2C START CONDITION
WRITE: 0xA4 GOT ACK: YES<<<write address
WRITE: 0 × 40 GOT ACK: YES<<<write location (?)
WRITE: 0 × 00 GOT ACK: YES<<<write 0 to location 0 × 40 (?)
I2C STOP CONDITION
I2C>

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):

Ancienne trame d'initialisation

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)[modifier | modifier le wikicode]

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[modifier | modifier le wikicode]

Pour récupérer les 6 octets de données présentés plus haut. Cela se fait en deux étapes :

  1. envoi du pointeur à lire à la manette, ici au début en 0x00
  2. 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 :

I2C>[0xa4 0x00]<<<setup the read pointer
I2C START CONDITION
WRITE: 0xA4 GOT ACK: YES<<<write address
WRITE: 0 × 00 GOT ACK: YES<<<pointer to 0
I2C STOP CONDITION
I2C>[0xa5 r:6]<<<read nunchuck measurements
I2C START CONDITION
WRITE: 0xA5 GOT ACK: YES<<<read address
BULK READ 0 × 06 BYTES:<<read back 6 bytes
0 × 78 ACK 0x7A ACK 0x2F ACK 0x7D ACK 0x6E ACK 0 × 17 NACK
I2C STOP CONDITION
I2C>

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[modifier | modifier le wikicode]

Voici présenté la trame d'initialisation du pointeur dans la RAM de la manette Nunchuk (adaptée de PDF zx-nunchuk) :

Trame d'initialisation du pointeur

Cette trame est en général suivie par la commande de lecture (adaptée de PDF zx-nunchuk):

Demande de lecture, puis réception des 6 octets de données

Conception du périphérique[modifier | modifier le wikicode]

Le périphérique destiné à communiquer avec la manette Nunchuk devra être réalisé à partir de projets existants. Citons par exemple :

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[modifier | modifier le wikicode]

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[modifier | modifier le wikicode]

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 50MHz 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[modifier | modifier le wikicode]

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.

Commentaires sur le code VHDL[modifier | modifier le wikicode]

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 :

-- two registers managment
  PROCESS(sys_clk) BEGIN
    IF rising_edge(sys_clk) THEN
	 IF Init ='1' THEN Reg1 <= "10000000";
	 ELSIF s_write_reg1='1' THEN
		 Reg1 <= s_mstr_dout;
           END IF;
    END IF;
  END PROCESS;
  PROCESS(sys_clk) BEGIN
    IF rising_edge(sys_clk) THEN
	 IF s_write_reg2='1' THEN
		 Reg2 <= s_mstr_dout;
	 END IF;
    END IF;
  END PROCESS;

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 :

-- ouput managment 
  PROCESS(Reg1) BEGIN
    if Reg1 > x"C0" then 
	 Right <= '1'; else Right <= '0';
    end if;
    if Reg1 < x"30" then 
	 Left <= '1'; else Left <= '0';
    end if;
  END PROCESS;
  PROCESS(Reg2) BEGIN  
    if Reg2 > x"C0" then 
	 Up <= '1'; else Up <= '0';
    end if;
    if Reg2 < x"30" then 
	 Down <= '1'; else Down <= '0';
    end if;	 
  END PROCESS;

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[modifier | modifier le wikicode]

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 :

  1. 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
  2. on a un exemple de gaspillage de ressources ici : le FIFO est 16x8 alors qu'on utilisera seulement 6x8 données
  3. 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[modifier | modifier le wikicode]

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[modifier | modifier le wikicode]

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.

  • 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 :
WHEN s1 => O_write <='1';start <='1';Dout <= x"A4";timer_init <= '0'; -- start fait le write
           O_read <= '0';stop<='0';O_ack_n<='1';
           write_Reg1<='0';write_Reg2<='0';write_Reg6<='0';
           IF cmd_ack = '1' THEN
              state_next <= s2;
           ELSE
              state_next <= s1;
           END IF;

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.

WHEN s12 => O_write <='1';start <='1';Dout <= x"A5";timer_init <= '0';
           O_read <= '0';stop<='0';O_ack_n<='1';
           write_Reg1<='0';write_Reg2<='0';write_Reg6<='0';
           IF cmd_ack = '1' THEN
              state_next <= s13;
           ELSE
              state_next <= s12;
           END IF;
  • écriture de l'octet suivant : elle se fait par un code du type :
WHEN s6 => O_write <='1';start <='0';Dout <= x"FB";timer_init <= '0';
	 O_read <= '0';stop<='0';O_ack_n<='1';
	 write_Reg1<='0';write_Reg2<='0';write_Reg6<='0';
	 IF cmd_ack = '1' THEN
	 state_next <= s7;
	 ELSE
                state_next <= s6;
            END IF;

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.
WHEN s7 => O_write <='1';start <='0';Dout <= x"00";timer_init <= '1';
	 O_read <= '0';stop<='1';O_ack_n<='1';
	 write_Reg1<='0';write_Reg2<='0';write_Reg6<='0';
	 IF cmd_ack = '1' THEN
	 state_next <= s8;
	 ELSE
                state_next <= s7;
           END IF;
  • 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 :
WHEN s13 => O_write <='0';start <='0';Dout <= x"00";timer_init <= '0';
            O_read <= '1';stop<='0';O_ack_n<='0';
	 write_Reg1<='0';write_Reg2<='0';write_Reg6<='0';
	 IF cmd_ack = '1' THEN
	 state_next <= s20;						 
	 ELSE
                     state_next <= s13;						
            END IF;
WHEN s20 => O_write <='0';start <='0';Dout <= x"00";timer_init <= '0';
	 O_read <= '1';stop<='0';O_ack_n<='0';
	 write_Reg1<='1';write_Reg2<='0';write_Reg6<='0';
            state_next <= s14;

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 :
WHEN s19 => O_write <='0';start <='0';Dout <= x"00";timer_init <= '1';
            O_read <= '1';stop<='1';O_ack_n<='1';
	 write_Reg1<='0';write_Reg2<='0';write_Reg6<='0';
	 IF cmd_ack = '1' THEN
	 state_next <= s15;
	 ELSE
                    state_next <= s19;
            END IF;

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[modifier | modifier le wikicode]

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.

Voir aussi[modifier | modifier le wikicode]

Le thème de l'i2c est abordé sous un autre angle (celui de l'esclave) dans un autre chapitre de ce livre :

Interfacer un téléphone portable[modifier | modifier le wikicode]

Nous nous limiterons dans ce chapitre aux téléphones portables Android et laissons de côté les téléphones d'Apple.

L'évolution du marché des téléphones portables en fait un outil idéal de plus en plus utilisé comme entrée de commandes de montages électroniques. Besoin de vous convaincre ?

  • une publicité Somfy de commande de volets roulants par téléphones portable durant l'été 2012
  • Androled: pilotez votre électronique via le WIFI sous Android (elektor septembre 2012)
  • AndroCar: véhicule piloté par l'inclinaison de votre téléphone (elektor octobre 2012)
  • Vidéo YouTube (en français) d'un drone (AR.Drone de Parrot) commandé par téléphone portable

Ces exemples utilisent essentiellement le WIFI mais il existe d'autres moyens de communiquer. Pour l'année scolaire 2012/2013, nous avons décidé d’en explorer deux, avec toujours le même objectif, commander des jeux vidéo qui eux s'exécutent dans un FPGA. Voici ces deux méthodes :

  • utiliser un kit adapté avec un PIC 24F qui gère une liaison USB maître sur laquelle on vient brancher le téléphone portable
  • utiliser la liaison Bluetooth en interfaçant un module FB155BC de chez Firmetch pour un prix avoisinant les 30 

La première façon de procéder est certainement la plus mauvaise d'un point de vue technique (pour notre problème bien sûr). En final on aura un processeur 32 bits (celui du téléphone), un processeur 16 bits (le PIC 24F du kit) et un processeur 8 bits dans le FPGA. Tout cela pour faire tourner un jeu des années 1980 (puisque c’est le processeur 8 bits qui l'exécute). Si la solution technique n’est pas bonne, le mot Android a suffi pour intéresser des étudiants à ce projet... La connexion USB maître reste intéressante à explorer d'un point de vue intellectuel de toute façon.

La deuxième façon de procéder est certainement plus naturelle puisqu'elle supprime l'étage du processeur 16 bits. Mais n'ayant que très peu d'expérience dans le Bluetooth, nous espérons ne pas tomber dans des pièges qui ne nous permettraient pas de finir le projet.

Écrire le programme Android[modifier | modifier le wikicode]

Le programme Android des deux applications est très similaire. Nous avons décidé de les examiner dans la même section tous les deux. L'application se présentera comme deux flèches sur un téléphone portable et l'appui sur les flèches déclenchera un envoi par USB pour l'un et un envoi par Bluetooth pour l'autre.

Nous n'avons pas l'intention de faire un cours sur Andoid dans cette section mais seulement de donner les programmes en les commentant. Vous pouvez lire (en) Andoid Software Development en attendant sa traduction en français.

Solution USB[modifier | modifier le wikicode]

La très grande majorité des téléphones portables ou des tablettes tactiles contiennent d'office une liaison USB. Un problème peut cependant éventuellement se poser pour les tablettes car certaines possèdent une liaison pouvant être soit maître soit esclave. Le kit choisi impose qu'on lui connecte une liaison USB esclave, puisque c’est lui qui joue le rôle du maître. C'est pour cela qu'un processeur 16 bits a été utilisé. À noter que chez Microchip un autre kit existe mettant en œuvre un processeur 32 bits. Chez son concurrent Atmel, seul un kit 32 bits est disponible, ce fabriquant ne disposant pas de processeurs 16 bits.

Solution Bluetooth[modifier | modifier le wikicode]

Cette solution nécessite un circuit spécialisé. Nous avons choisi un FB155BC de chez Firmetch mais il en existe bien d'autres. Ce circuit est alimenté en 3,3 V, comme notre FPGA. La communication entre ce circuit et le FPGA se fera par liaison série et commandes Hayes ou commandes AT.

Nous avons peu d'expérience dans la communication série avec les commandes Hayes. Pour expérimenter et en apprendre plus nous avons décidé d’utiliser le FPGA pour passer d'un hyperterminal sur un PC au circuit FB155BC. Cette solution peut paraitre étrange mais elle évite les conversions de tensions de la RS232 : en fait elles sont déjà réalisées dans la carte FPGA. Nous allons décrire en détail cette solution maintenant.

Connecter un PC en RS232 pour dialoguer[modifier | modifier le wikicode]

Par défaut le circuit est configuré en 9600 bauds, pas de parité, 1 bit de stop (sans protocole matériel).

Nous avons l'intention d’utiliser notre carte FPGA comme interface entre un PC qui exécute un hyperterminal et la carte Bluetooth. Cette méthode va nous permettre d'expérimenter doucement comment se passe la connexion entre notre téléphone portable et notre carte Bluetooth. En fait tout ceci est relativement simple à réaliser et nous allons le documenter maintenant.


Voici donc une série de commandes importantes explorées avec notre hyperterminal.

Donner un nom au périphérique[modifier | modifier le wikicode]

Tout périphérique Bluetooth possède une adresse et un nom. Son adresse ne peut pas être changée mais ce n’est pas le cas de son nom. La commande qui permet de donner un nom est :

  • Envoyer AT+BTNAME=xxxxxxxxxxxx

où xxxxxxxxxxxx est à remplacer par un nom. On aura par exemple :

  1. Envoyer AT+BTNAME=test↵
  2. Recevoir OK

À partir de maintenant le Firmtech sera vu sous le nom "test" si l’on fait une recherche des périphériques bluetooth à proximité. Cette recherche est naturellement réalisée par le téléphone ou la tablette Android.

Le mode esclave[modifier | modifier le wikicode]

Voici le dialogue destiné à passer le circuit Firmtech FB155BX en mode esclave :

  1. Envoyer “AT&F” au circuit Bluetooth
  2. “OK” doit être reçu comme réponse du Firmtech FB155BX
  3. le circuit FB155BX redémarre
  4. “BTWIN Slave mode start” doit être reçu comme deuxième réponse du Firmtech FB155BX
  5. “OK” doit être reçu comme troisième réponse du Firmtech FB155BX
Le mode maître[modifier | modifier le wikicode]

Voici le dialogue destiné à passer le circuit Firmtech FB155BX en mode maître :

  1. Envoyer “AT+BTROLE=M” au circuit Bluetooth
  2. “OK” doit être reçu comme réponse du Firmtech FB155BX
  3. Envoyer “ATZ” au circuit Bluetooth
  4. le circuit FB155BX redémarre
  5. “BTWIN Master mode start” doit être reçu comme deuxième réponse du Firmtech FB155BX
  6. “OK” doit être reçu comme troisième réponse du Firmtech FB155BX
Retour au mode esclave[modifier | modifier le wikicode]

Voici le dialogue destiné à repasser le circuit Firmtech FB155BX en mode esclave :

  1. Envoyer “AT+BTROLE=S” au circuit Bluetooth
  2. “OK” doit être reçu comme réponse du Firmtech FB155BX
  3. Envoyer “ATZ” au circuit Bluetooth
  4. le circuit FB155BX redémarre
  5. “BTWIN Slave mode start” doit être reçu comme deuxième réponse du Firmtech FB155BX
  6. “OK” doit être reçu comme troisième réponse du Firmtech FB155BX
Recherche en mode maître[modifier | modifier le wikicode]

Voici le dialogue destiné à passer le circuit Firmtech FB155BX en mode recherche à partir du mode maître :

  1. Envoyer “AT+BTINQ?” au circuit Bluetooth
  2. “OK” doit être reçu comme réponse du Firmtech FB155BX puis peu de temps après :
  3. des informations sont envoyées sur les périphériques bluetooth proches sont envoyées
  4. “OK” doit être reçu comme réponse du Firmtech FB155BX en final

Les informations peuvent être décomposées en :

  • adresse, par exemple “001901000002”,
  • un nom de périphérique, par exemple “FB155v2.2.0”
  • une classe de périphérique, par exemple “1F00”.
Connexion au périphérique en mode maître[modifier | modifier le wikicode]

Une fois les informations trouvées, il vous suffit de réaliser :

  1. Envoyer “ATD001901000002” au circuit Bluetooth
  2. “OK” doit être reçu comme réponse du Firmtech FB155BX puis peu de temps après :
  3. “CONNECT 001901000002” doit être reçu du Firmtech FB155BX.
Déconnexion du périphérique[modifier | modifier le wikicode]

Voici le dialogue destiné à déconnecter le circuit Firmtech FB155BX

  1. Envoyer “+++” au circuit Bluetooth
  2. “OK” doit être reçu comme réponse du Firmtech FB155BX
  3. Envoyer “ATH” au circuit Bluetooth
  4. “OK” doit être reçu comme réponse du Firmtech FB155BX
  5. “DISCONNECT” doit être reçu comme réponse du Firmtech FB155BX

La mise en place de ces protocoles par un processeur embarqué dans un FPGA est présentée dans le lien projet 2012/2013.


Accepter une connexion en mode esclave[modifier | modifier le wikicode]

Il faut d’abord donner un nom à notre périphérique, nom qui sera utilisé dans la liste des périphériques bluetooth détecté (par le téléphone ou la tablette).

  1. Envoyer “AT+BTSCAN” au circuit Bluetooth au départ. Cela permet au Bluetooth de l'Android de détecter le Fimtech
  2. Choisir le périphérique correspondant au Firmtech, puis entrer le mot de passe sur le téléphone (1234)

et la connexion est faite. Comme vous pouvez le constater la connexion en mode esclave est très simple et ne nécessite donc pas d'analyse complexe des chaines reçues en réponse. Voici comment on peut envisager les choses par exemple avec des programmes en c (détaillés dans un autre chapitre) :

// bluetooth ready for connexion
  usart_send2('A');usart_send2('T');usart_send2('+');usart_send2('B');usart_send2('T');
  usart_send2('S');usart_send2('C');usart_send2('A');usart_send2('N');usart_send2(0x0D);

Et voici comment on lit les informations :

      ch = usart_receive2();
// if (bit_is_set(PINB,PINB6)) if (raqG_y<182) delta_raqG_y=1; 
// if (bit_is_set(PINB,PINB7)) if (raqG_y>0) delta_raqG_y=-1;
      if (ch == 'd') if (raqG_y<182) delta_raqG_y=1; 
      if (ch == 'u') if (raqG_y>0) delta_raqG_y=-1;

Lire le chapitre correspondant où le Bluetooth est utilisé pour faire bouger une raquette d'un jeu de Pong.

Exploration de l'ADK[modifier | modifier le wikicode]

Lors de la conférence Google I/O 2011, a été annoncé l’arrivée de l’Android Open Accessory Development Kit (ADK). Il permet de rajouter une connectivité physique à un périphérique Android à l’aide d’une carte électronique, un peu comme le IOIO. La partie matérielle correspond à shield Arduino USB Maitre. Cette nouvelle fonctionnalité a été intégrée dans Android 3.1 et 2.3.4.

Cette solution sera explorée plus tard, mais pour l'instant, vous pouvez en chercher une description dans une section suivante "Voir aussi" en fin de chapitre.


Ce chapitre nous a amené à nous intéresser à des interfaces nouvelles. Pour les explorer de manière différente, nous allons nous intéresser pour finir ce chapitre à la communication entre un micro-contrôleur et un FPGA. Il s'agit d'un vaste sujet que nous allons aborder par des projets.

Voir aussi[modifier | modifier le wikicode]