« Very High Speed Integrated Circuit Hardware Description Language/Les nouvelles interfaces : de la nunchuk de Nintendo à android » : différence entre les versions

Contenu supprimé Contenu ajouté
Snawei (discussion | contributions)
m orthographe
m Robot : Remplacement de texte automatisé (-(<|</)source([ \t>]) +\1syntaxhighlight\2)
Ligne 159 :
Voici donc ce cœur i2c maître en VHDL (Auteur : à priori Richard Herveille, ancienne version de son cœur [http://opencores.org/project,i2c téléchargeable chez Opencores]). Ce cœur est compatible [[w:Wishbone_(bus_informatique)|wishbone]] ce qui ne nous intéresse pas puisque notre processeur ne l'est pas. Voici le code en question :
{{Boîte déroulante|titre=Cœur i2c maître (VHDL)|contenu=
<sourcesyntaxhighlight lang="VHDL">
--
-- Simple I2C controller
Ligne 775 :
-- SDA <= SDAo;
end architecture structural;
</syntaxhighlight>
</source>
En toute franchise nous ne souvenons plus exactement si nous l'avons modifié un peu. Nous regarderons les commentaires plus tard.
}}
Ligne 790 :
Comme le titre l'indique, il s'agit d'une machine d'états que nous allons détailler quelque peu maintenant.
{{Boîte déroulante|titre=Une machine d'états pour diriger le maître i2c|contenu=
<sourcesyntaxhighlight lang="VHDL">
-- 30 Oct 2012 version 0.1
-- 11 décembre 2012 version 0.8
Ligne 1 150 :
END PROCESS;
END arch_seqNunchuk;
</syntaxhighlight>
</source>
Nous avons retiré toute la partie qui nous a servi à déboguer.
}}
Ligne 1 165 :
 
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 :
<sourcesyntaxhighlight lang="VHDL">
-- two registers managment
PROCESS(sys_clk) BEGIN
Ligne 1 182 :
END IF;
END PROCESS;
</syntaxhighlight>
</source>
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 :
<sourcesyntaxhighlight lang="VHDL">
-- ouput managment
PROCESS(Reg1) BEGIN
Ligne 1 204 :
end if;
END PROCESS;
</syntaxhighlight>
</source>
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.
 
Ligne 1 214 :
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.
{{Boîte déroulante|titre=Une nouvelle machine d'états (inutilisable seule)|contenu=
<sourcesyntaxhighlight lang="VHDL">
-- 30 Oct 2012 v 0.9
-- 9th July 2013 v 1.0
Ligne 1 569 :
END PROCESS;
END arch_seqNunchuk;
</syntaxhighlight>
</source>
}}
Ce module utilise un FIFO logicore [[w:Xilinx|Xilinx]] qui présente plusieurs inconvénients :
Ligne 1 628 :
}}
* 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 :
<sourcesyntaxhighlight lang="VHDL">
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';
Ligne 1 637 :
state_next <= s1;
END IF;
</syntaxhighlight>
</source>
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.
<sourcesyntaxhighlight lang="VHDL">
WHEN s12 => O_write <='1';start <='1';Dout <= x"A5";timer_init <= '0';
O_read <= '0';stop<='0';O_ack_n<='1';
Ligne 1 648 :
state_next <= s12;
END IF;
</syntaxhighlight>
</source>
* écriture de l'octet suivant : elle se fait par un code du type :
<sourcesyntaxhighlight lang="VHDL">
WHEN s6 => O_write <='1';start <='0';Dout <= x"FB";timer_init <= '0';
O_read <= '0';stop<='0';O_ack_n<='1';
Ligne 1 659 :
state_next <= s6;
END IF;
</syntaxhighlight>
</source>
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.
<sourcesyntaxhighlight lang="VHDL">
WHEN s7 => O_write <='1';start <='0';Dout <= x"00";timer_init <= '1';
O_read <= '0';stop<='1';O_ack_n<='1';
Ligne 1 671 :
state_next <= s7;
END IF;
</syntaxhighlight>
</source>
* 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 :
<sourcesyntaxhighlight lang="VHDL">
WHEN s13 => O_write <='0';start <='0';Dout <= x"00";timer_init <= '0';
O_read <= '1';stop<='0';O_ack_n<='0';
Ligne 1 686 :
write_Reg1<='1';write_Reg2<='0';write_Reg6<='0';
state_next <= s14;
</syntaxhighlight>
</source>
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 :
<sourcesyntaxhighlight lang="VHDL">
WHEN s19 => O_write <='0';start <='0';Dout <= x"00";timer_init <= '1';
O_read <= '1';stop<='1';O_ack_n<='1';
Ligne 1 698 :
state_next <= s19;
END IF;
</syntaxhighlight>
</source>
read et stop sont positionné ainsi que "ack_n" à un, ce qui signifie pas d'acquittement.
 
Ligne 1 821 :
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) :
<sourcesyntaxhighlight lang="c">
// 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);
</syntaxhighlight>
</source>
Et voici comment on lit les informations :
<sourcesyntaxhighlight lang="c">
ch = usart_receive2();
// if (bit_is_set(PINB,PINB6)) if (raqG_y<182) delta_raqG_y=1;
Ligne 1 833 :
if (ch == 'd') if (raqG_y<182) delta_raqG_y=1;
if (ch == 'u') if (raqG_y>0) delta_raqG_y=-1;
</syntaxhighlight>
</source>
Lire le [[../Travail pratique/Autres projets pour ATMEL ATMega8#Projet Pong et téléphones portables .282012.2F2013.29|chapitre correspondant]] où le Bluetooth est utilisé pour faire bouger une raquette d'un jeu de [[w:Pong|Pong]].