Comment faire du SPI CS HIGH PIN26 GPIO7?

Bonjour,

J’ai un programme en C++ qui écrit/lit une mémoire EEPROM 93LC46 via SPI (/dev/spidev0.1) :

  • PIN19 GPIO10 MOSI
  • PIN21 GPIO9 MISO
  • PIN23 GPIO11 CLOCK
  • PIN26 GPIO7 CS
  • PIN20 GROUND
  • PIN17 POWER 3.3v

Le programme tourne parfaitement sur un raspberry pi 3B+ avec une image stretch.
Sur cette même machine mais avec une image récente (Raspberry Pi OS port from Bookworm 32 ou 64 bit) le programme n’arrive pas à communiquer correctement.

J’ai regardé ce qu’il se passait de plus près à l’oscilloscope et il y a une différence indépendante de mon programme qui à mon sens pose problème :

  • dans la configuration qui fonctionne (stretch ou jusqu’à buster Index of /raspbian/images/raspbian-2020-02-14) le signal CS (PIN26 GPIO7) est bas
  • dans la configuration qui ne fonctionne pas (avec tout OS plus récent) le signal CS (PIN26 GPIO7) est haut

Peu-être lié au commit spi: bcm2835: fix gpio cs level inversion · raspberrypi/linux@5e31ba0 · GitHub qui semble être la date à partir de laquelle mon programme ne fonctionne plus sur les OS compilés après…

Y a-t-il un moyen de configurer un raspberry pour avoir le PIN26 GPIO7 en signal bas par défaut ?

Mes réponses sont purement théoriques. Je ne suis pas un grand connaisseur de ce type de communication, mais j’ai eu a faire deux trois intégration de module. Alors j’ai eu à comprendre un peu, tout comme des recherches pour savoir pourquoi ont ne peut pas redéfinir une pins à un type comme ont le souhaite (recherche sur sortie audio).

De la manière que tu le demande, j’en conclu que tu as en tête de « reprogrammer » le comportement du RPi. Tu pourrais si tu tombe sur les sources du Firmware du Raspberry Pi de modifier, si tu en as la capacité, le comportement des pins, en respectant les limites du matériel. Mais c’est risqué.

Dans un autre sens, si tu cherche à corriger de manière logiciel ou par « hack », il faudrait voir. Je ne sais pas quel type de signal tu attend exactement, mais selon ma petite recherche sur tes infos, j’ai cru voir un lien avec le WIring Pi. SI c’est le cas, je me demande si tu as activé le « 1-Wire » dans les options d’interface ? Ou si dans ton cas de figure faut pas plutot le désactiver ? Cette option est disponible (selon ma dernière visite) dans le sudo raspi-congi.

Sinon, si le signal est inversé, est-il possible de le corriger en l’inversant de nouveau ? Peut-être un petit ajout à la sortie peut corriger le signal selon ton projet.

Si tu as changé de OS, tu as alors démarré sur un config neuve, peut-être à tu oublier un élément requis pour ton projet ?

Je dis ça pour t’aider à « brainstormer » sur des pistes solution, à défaut de vraiment t’aider avec une vrai piste de solution.

Merci de ton aide !

Oui en effet je pars d’une carte SD que je n’ai pas installée ni configurée moi-même :

  • raspbian stretch (2019)
  • le signal CS PIN26 GPIO7 (spidev0.1) « bas » par défaut = 0 (tout comme les lignes MISO MOSI et clock)
  • un programme qui fonctionne en faisant un « select » du slave avec un signal « haut » = 1.

En partant d’une install fraîche avec une image buster 2020-02-14 (niveau config, je ne fais qu’activer SPI), je compile le programme et j’observe la même chose : signal 0 par défaut, select 1 et ça fonctionne !

Le problème apparaît dès que j’installe un OS plus récent, avec la même config (activation SPI), j’observe le signal 1 par défaut ce qui est à mon sens l’origine du problème pour le programme.

De cette démarche, comme j’utilise strictement le même matériel (je ne débranche pas un seul fil, je change seulement la carte SD), j’en déduis que la seule différence vient de la partie logicielle : l’OS, une configuration par défaut, une lib au runtime ou à la compilation…

A noter que depuis hier, j’ai avancé d’un cran (ou pas).
J’avais :

int mode = SPI_MODE_0 | SPI_CS_HIGH;
ioctl(fid, SPI_IOC_WR_MODE, &mode);

Puisque je n’ai qu’un seul slave, j’ai modifié le mode par :

int mode = SPI_MODE_0 | SPI_NO_CS;

Bilan, mon programme arrive à écrire, peut-être pas correctement mais en tout cas il sort en SUCCESS au lieu de tourner en boucle.
Par contre la lecture sort en FAIL, ce qui ne valide donc pas tellement l’écriture…

Je vais regarder du côté de ce 1-Wire, encore merci de ton attention !

Vuq ue je ne suis pas un grand connaisseur des GPIO j’ai lancé une recherche et je suis tombé sur ceci. à défaut de te donner une réponse viable, il te fournira des outils pour t’aider à débugger.

J’ai vérifié le coup du 1-Wire, il est bien désactivé sur

  • l’ancienne carte (qui fonctionne),
  • la nouvelle install avec la vielle image (qui fonctionne),
  • la nouvelle install avec OS récent (qui ne fonctionne pas)

La sortie de la commande « gpio readall » met en évidence une seule différence

  • carte OK : GPIO. 7 est à 1 dans la colonne V
  • carte KO : GPIO. 7 est à 0 dans la colonne V
 +-----+-----+---------+------+---+---Pi 3B+-+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 |     |     |    3.3v |      |   |  1 || 2  |   |      | 5v      |     |     |
 |   2 |   8 |   SDA.1 | ALT0 | 1 |  3 || 4  |   |      | 5v      |     |     |
 |   3 |   9 |   SCL.1 | ALT0 | 1 |  5 || 6  |   |      | 0v      |     |     |
 |   4 |   7 | GPIO. 7 |   IN | 0 |  7 || 8  | 0 | IN   | TxD     | 15  | 14  |
 |     |     |      0v |      |   |  9 || 10 | 1 | IN   | RxD     | 16  | 15  |
 |  17 |   0 | GPIO. 0 |   IN | 0 | 11 || 12 | 0 | IN   | GPIO. 1 | 1   | 18  |
 |  27 |   2 | GPIO. 2 |   IN | 0 | 13 || 14 |   |      | 0v      |     |     |
 |  22 |   3 | GPIO. 3 |   IN | 0 | 15 || 16 | 0 | IN   | GPIO. 4 | 4   | 23  |
 |     |     |    3.3v |      |   | 17 || 18 | 0 | IN   | GPIO. 5 | 5   | 24  |
 |  10 |  12 |    MOSI | ALT0 | 0 | 19 || 20 |   |      | 0v      |     |     |
 |   9 |  13 |    MISO | ALT0 | 0 | 21 || 22 | 0 | IN   | GPIO. 6 | 6   | 25  |
 |  11 |  14 |    SCLK | ALT0 | 0 | 23 || 24 | 1 | OUT  | CE0     | 10  | 8   |
 |     |     |      0v |      |   | 25 || 26 | 1 | OUT  | CE1     | 11  | 7   |
 |   0 |  30 |   SDA.0 |   IN | 1 | 27 || 28 | 1 | IN   | SCL.0   | 31  | 1   |
 |   5 |  21 | GPIO.21 |   IN | 1 | 29 || 30 |   |      | 0v      |     |     |
 |   6 |  22 | GPIO.22 |   IN | 1 | 31 || 32 | 0 | IN   | GPIO.26 | 26  | 12  |
 |  13 |  23 | GPIO.23 |   IN | 0 | 33 || 34 |   |      | 0v      |     |     |
 |  19 |  24 | GPIO.24 |   IN | 0 | 35 || 36 | 0 | IN   | GPIO.27 | 27  | 16  |
 |  26 |  25 | GPIO.25 |   IN | 0 | 37 || 38 | 0 | IN   | GPIO.28 | 28  | 20  |
 |     |     |      0v |      |   | 39 || 40 | 0 | IN   | GPIO.29 | 29  | 21  |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+---Pi 3B+-+---+------+---------+-----+-----+

Au passage je trouve curieux que cette sortie ne corresponde pas à https://www.framboise314.fr/wp-content/uploads/2018/02/kit_composants_GPIO_01.png.
Mon CS est bien branché sur le PIN 26 qui correspond à

  • « (SPI_CE1_N) GPIO07 » sur l’image
  • « CE1 » sur la sortie « gpio readall » (qui elle donne le « GPIO. 7 » en pin 7 et tout un tas d’autres différences…)

Depuis j’ai constaté que l’écriture « nouvel OS + SPI_NO_CS » était bonne en faisant une lecture avec l’ancien OS.
Sauf que pour en avoir le coeur net, j’ai voulu renouveler l’expérience et là : l’écriture « nouvel OS + SPI_NO_CS » ne fonctionne plus… :frowning:
Pour ajouter un peu de piment, impossible de lancer le logiciel de l’oscilloscope, il crash au démarrage :frowning:

Bref n problèmes à régler en //, je reviendrai quand j’aurai stabilisé tout ça !

En tout cas je te remercie encore !

Tu peux t’aider avec ce guide qui permet de connaitre les définitions possible des PIN.

Pour ton GPIO 26 et 7

GPIO 26

Alt0 Alt1 Alt2 Alt3 Alt4 Alt5
SD0 DAT2 TE0 DPI D22 SD1 DAT2 JTAG TDI
  • Physical/Board pin 37
  • GPIO/BCM pin 26
  • Wiring Pi pin 25

GPIO 7 (SPI Chip Select 1)

Alt0 Alt1 Alt2 Alt3 Alt4 Alt5
SPI0 CE1 SMI SWE_N / SRW_N DPI D3 AVEOUT VID3 AVEIN VID3
  • Physical/Board pin 26
  • GPIO/BCM pin 7
  • Wiring Pi pin 11

Ah merci ça confirme bien ce que je pensais : GPIO 7 = SPI CS 1 = PIN26 (physical/board).
C’est cohérent avec les illustrations que l’on peut trouver mais pas avec « gpio readall » qui semble DEPRECATED.

Pour le remplacer, ça parle de « raspi-gpio get » qui semble lui-même remplacé par « pinctrl »…
J’ai aussi trouvé GPIOreadall qui lui, donne une sortie ressemblant à « gpio readall », mais cohérente !

Je note une chose intéressante, au démarrage avec la carte buster 2020-02-14 j’ai en sortie de « ~/GPIOreadall/gpioreadall.py » :

+----------------------------+  Pi 3B+  +----------------------------+
| BCM | Name      | Mode | V |  Board   | V | Mode | Name      | BCM |
+-----+-----------+------+---+----++----+---+------+-----------+-----+
|        3.3v                |  1 ||  2 |             5v             |
|   2 | SDA1      | ALT0 | 1 |  3 ||  4 |             5v             |
|   3 | SCL1      | ALT0 | 1 |  5 ||  6 |             GND            |
|   4 | GPIO4     | IN   | 1 |  7 ||  8 | 0 | IN   | GPIO14    |  14 |
|        GND                 |  9 || 10 | 1 | IN   | GPIO15    |  15 |
|  17 | GPIO17    | IN   | 0 | 11 || 12 | 0 | IN   | GPIO18    |  18 |
|  27 | GPIO27    | IN   | 0 | 13 || 14 |             GND            |
|  22 | GPIO22    | IN   | 0 | 15 || 16 | 0 | IN   | GPIO23    |  23 |
|        3.3v                | 17 || 18 | 0 | IN   | GPIO24    |  24 |
|  10 | SPI0_MOSI | ALT0 | 0 | 19 || 20 |             GND            |
|   9 | SPI0_MISO | ALT0 | 0 | 21 || 22 | 0 | IN   | GPIO25    |  25 |
|  11 | SPI0_SCLK | ALT0 | 0 | 23 || 24 | 1 | OUT  | GPIO8     |   8 |
|        GND                 | 25 || 26 | 1 | OUT  | GPIO7     |   7 |
|   0 | GPIO0     | IN   | 1 | 27 || 28 | 1 | IN   | GPIO1     |   1 |
|   5 | GPIO5     | IN   | 1 | 29 || 30 |             GND            |
|   6 | GPIO6     | IN   | 1 | 31 || 32 | 0 | IN   | GPIO12    |  12 |
|  13 | GPIO13    | IN   | 0 | 33 || 34 |             GND            |
|  19 | GPIO19    | IN   | 0 | 35 || 36 | 0 | IN   | GPIO16    |  16 |
|  26 | GPIO26    | IN   | 0 | 37 || 38 | 0 | IN   | GPIO20    |  20 |
|        GND                 | 39 || 40 | 0 | IN   | GPIO21    |  21 |
+-----+-----------+------+---+----++----+---+------+-----------+-----+

On peut lire que GPIO7 est à 1.
A la suite de l’exécution du programme, la seule différence, c’est GPIO7 à 0 !
C’est donc bien le programme qui change l’état grâce à l’initialisation :

int mode = SPI_MODE_0 | SPI_CS_HIGH;
ioctl(fid, SPI_IOC_WR_MODE, &mode);

Sur l’OS récent, visiblement le programme n’arrive pas à initialiser pour faire du CS HIGH (GPIO7 reste à 1 après l’exécution KO) et on trouve tout un tas de choses à ce sujet :

- https://forums.raspberrypi.com/viewtopic.php?t=304156
- https://forums.raspberrypi.com/viewtopic.php?t=331853
- https://github.com/doceme/py-spidev/issues/106
- https://github.com/raspberrypi/linux/issues/3745
- https://forums.raspberrypi.com/viewtopic.php?t=313422
- ...

(dsl pour les liens non clickables, je n’en ai droit qu’à deux)

Malheureusement je n’arrive pas encore à extraire LA solution de tout ça mais je ne désespère pas !

Merci.

Newer is not necessary better

Surement que le nouveau OS, vu l’ajout de sécurité, rencontre des problème avec certains aspect matériel/logiciel des GPIO. Si le problème est rapporté (déjà tu n’es pas seul alors ne te décourage pas) surement que l’équipe du Raspberry travaille sur une résolution sur la prochaine version du OS.

Moi je ne travail pas avec le nouveau OS pour ces raisons (PC ou RPi), trop de modifications qui font que les guides ne marchent pas tous et que certaines sécurité complique le tout. Deplus, j’ai de vieux RPi, le nouveau OS les rend plus lent.

newer is not necessary better

Bien entendu ! C’est pour ça que je suis parti de la stretch 2019 (carte fournie que je n’ai pas installée et qui fonctionne) et que j’ai remonté version par version

Je serai ravis de revenir avec une solution très bientôt j’espère, encore merci pour tout !