Bonjour,
je préviens tout de suite, ma question est longue.
J'ai récemment fait l'acquisition d'un Raspberry Pi 2 que je souhaiterais pouvoir contrôler aisément (surtout les pins GPIO).
Toutefois, j'ai quelques exigences vis-à-vis du matériel et je sais qu'un interpréteur python est beaucoup plus long que le changement même de la valeur des registres par un programme compilé (comme en C).
C'est pourquoi je cherche à accéder directement aux registres plutôt qu'une autre solution.
Le circuit principal qui contrôle les pins GPIO est le circuit BCM2836 de chez Broadcom.
Mais aucune datasheet n'est disponible pour ce circuit.
Son cousin le BCM2835 lui a une datasheet très complète surtout pour les registres qui contrôlent les GPIO.
Ce que l'on note par l'examen du fichier /proc/iomem pour le raspberry pi 2, c'est que les registres concernant les périphériques commencent à l'adresse 0x3F000000 contrairement au raspberry pi qui commençaient à l'adresse 0x20000000.
On fait l'hypothèse que l'organisation des registres pour le circuit BCM2835 est la même que pour le BCM2836
Cela traduit qu'il existe un offset pour arriver aux registres des GPIO correspondant à un écart de 0x00200000.
En reprenant l'organisation qui est décrite entre les pages 89 et 101 de la datasheet de BCM2835, on peut écrire le code ci-dessous qui affiche les cinq registres de sélection Input/Output correspondant à l'état d'une pin GPIO.
Afin de vérifier que mon code fonctionnait, je me suis dit que j'allais tenter une petite expérience :Code:#include <stdio.h> #include <stdlib.h> /***************************************************************************** BCM2836 PRINCIPAUX GPIO REGISTRES *****************************************************************************/ #define BCM2836_PERI_BASE 0x3F000000 //adresse des registres des périphériques #define GPIO_BASE (BCM2836_PERI_BASE+0x00200000) //offset des registres GPIO #define GPIO_SELECT_FUNCTION(i) (GPIO_BASE + i*0x00000004) /*3 bits 000->INPUT 001->OUTPUT 0...2 sont les bits du GPIO 0 3...5 sont les bits du GPIO 1 ... ... ... 27...29 sont les bits du GPIO 9 30-31 sont réservés */ /****************************************************************************/ //affiche l'écriture binaire d'un unsigned int void affich_int_to_bits(unsigned int val) { int i,j; for (i=7;i>=0;i--) { for(j=3;j>=0;j--) { printf("%d",((val>>(4*i+j))&1)==1 ? 1 : 0); } printf(" "); } printf("\n"); } int main() { volatile unsigned int * addr = (unsigned int*) GPIO_SELECT_FUNCTION(0); int i; addr=malloc(sizeof(unsigned int)); for (i=0;i<5;i++) { printf("Registre %d : ",i); affich_int_to_bits(*(addr+i)); } return 0; }
j'utilise l'interpréteur python pour mettre la pin 1 dans le mode OUT.
Je tape :
je retourne alors à mon shell et je lance le programme C.Code:>>> import RPi.GPIO as GPIO >>> GPIO.setmode(GPIO.BCM) >>> GPIO.setup(1,GPIO.OUT)
Je m'attendais donc à avoir sur la première ligne : "Registre 0 : 0000 0000 0000 0000 0000 0000 0000 1000",
mais l'ordinateur m'a donné : "Registre 0 : 0000 0000 0000 0000 0000 0000 0000 0000".
Ma petite expérience a démontré que :
- soit mon hypothèse est fausse et seul Broadcom peut corriger mon erreur en publiant une datasheet de BCM2836 pour connaître les adresses des registres en question
- soit mon code C est erroné (c'est pour ça que je fais appel aux internautes)
- soit mon python est mauvais puisqu'il n'a rien changé dans les registres
Qu'en pensez-vous ?
Merci pour votre longue lecture.
-----