vendredi 2 février 2018

Chapitre 18 : gérer le GPIO du Raspberry avec l'assembleur



Après tous ces chapitres consacrés à l’affichage, nous allons voir les routines pour  programmer le GPIO du Raspberry (qui je le rappelle est un modèle B). Classiquement nous allons faire clignoter une led connectée au pin 18 du GPIO. Vous trouverez sur Internet toutes les explications pratiques pour effectuer le montage électronique nécessaire (par ex : https://thepihut.com/blogs/raspberry-pi-tutorials/27968772-turning-on-an-led-with-your-raspberry-pis-gpio-pins).
 Curieusement, le programme va reprendre la fonction principale des programmes précédents car la programmation du GPIO va commencer par l’ouverture du périphérique et le mapping en mémoire des zones associées.
Mais le périphérique à ouvrir va s’appeler /dev/gpiomem  et les zones mémoires à utiliser sont très détaillées ( voir la documentation BCM2835-ARM-Peripherals).
Après le mapping des registres du GPIO en mémoire, il faut sélectionner la broche qui va être utilisée en sortie. Nous allons utiliser la broche physique 12 qui correspond au N° de pin 18 en appelant la sous routine selectPin. Oui c’est un truc bizarre il y a 2 numérotations différentes des broches et donc j’appellerais broche, la borne physique et pin le N° logique affecté à cette broche. Vous trouverez sur internet de nombreux schémas qui présentent la relation entre les 2 suivant les modèles du Raspberry. 
La sélection en sortie nécessite la modification de 3 bits avec le code fonction (Input ou Output) au bon emplacement dans un des 4 registres GPIO possibles ( attention ne pas confondre les registres du processeur (r0, r1 etc) avec les registres du GPIO). Pour cela il faut diviser le N° de pin (ici 18) par 10, le résultat donnera le N° du registre GPIO à mettre à jour et le reste donnera le rang du pin dans ce registre.  Mais attention, il faut mettre à jour les 3 bits sans modifier les autres sinon bonjour les dégâts. C’est le rôle de la suite des instructions de manipulation des bits qui prépare le registre r2 du processeur.

   mov r0,r3             @ rang du pin dans le registre
   add r3,r3,r0,lsl #1   @ calcul de la position dans le registre = rang * 3
   mov r1,#MASKPIN       @ masque des 3 bits à sélectionner
   lsl r1,r1,r3           @ déplacement du masque en fonction de la position
   bic r2,r2,r1           @ raz des 3 bits concernés dans le registre
   lsl r6,r6,r3           @ déplacement du code fonction à la bonne position
   orr r2,r2,r6           @ maj du code fonction à la bonne position
   str r2,[r5,r4,lsl#2]   @ stockage du registre à sa bonne place dans la mémoire

 Ensuite ce registre sera stocké au bon emplacement de la mémoire mappée. Ouf !!!
Ensuite, nous trouvons une petite boucle d’attente avant d’effectuer une extinction de la broche du GPIO (clear). Il est indiqué dans la documentation qu’il faut faire un clear avant d’effectuer un allumage de la broche. Contrairement au programme d’animation vu précédemment, nous n’utilisons pas le call système wait pour gérer le temps d’attente mais nous avons utilisé une simple boucle à titre d’exemple.
Dans la routine clearPin, nous commençons par sélectionner le registre du GPIO à mettre à jour. Là c’est plus simple car il n’y a que 2 registres concernés un pour les pins 0 à 31 l’autre pour les pins supérieurs à 32 (et plus exactement de 32 à 53). Et il n’est nécessaire que de positionner à 1 le bit équivalent à la position du pin.
Puis après un nouveau temps d’attente nous appelons la routine d’allumage du pin. C’est le même principe
 que la routine précédente sauf que les 2 registres ne sont pas les mêmes ( donnés par des offsets différents GPSET et GPCLR).
Vous remarquerez que l’allumage et l’extinction consistent à mettre le bit correspondant au N° de pin à 1 mais sur des registres différents. Ceci évite de commettre des erreurs !!
Lors des tests, la led ne s’allume pas !! Après avoir vérifié de nombreuses fois le programme et le câblage, je me suis aperçu que la led avait un sens de branchement : le fil long de la led doit être du coté de la broche 12 !!.
Normalement, ce programme fonctionne avec plusieurs versions du Raspberry qui utilise le BCM2835.
 Exercices : modifier le pin utilisé.
                     Faire clignoter 2 leds alternativement.
                       Lire la documentation BCM2835 et implémenter les autres fonctions.

Aucun commentaire:

Enregistrer un commentaire