I2C sous linux

13 septembre 2012

 Mode maître

En cherchant i2c Linux sur internet, on tombe rapidement sur les notes concernant le noyau. J’ai trouvé celles-ci : http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git ;a=blob ;f=Documentation/i2c/dev-interface

 Pré-requis

Nous avons pris le code bloc par bloc. Notre première observation est que nous sommes censés trouvé la liste de nos périphérique i2c dans /sys/class/i2c-dev/. Nous avions peur de ne rien trouver, mais c’est le contraire ! Nous en trouvons 4 sur notre PC fixe, 10 (!) sur notre PC portable. Dans chaque répertoire, on peut lire le fichier « name » pour avoir une idée de la provenance du port i2c.

Notre seconde observation est que le code va lire un périphérique dont l’accès se fait par le fichier /dev/i2c-x (x étant un nombre, la numérotation commence à 0). Nous n’avons pas de fichier ici. Une petite recherche sur le net nous indique la cause. Nous n’avons pas chargé le pilote. La commande suivante règle notre problème :

Ajout du pilote
sudo modprobe i2c-dev
Il est aussi possible de charger le pilote automatiquement au démarrage en le rajoutant dans /etc/modules.

Nous recopions alors le code petit à petit pour tomber sur des problèmes assez classiques de types non définis. S’il est bien indiqué de charger linux/i2c-dev.h, il nous a aussi fallu :

  • fcntl.h, notamment pour O_RDWR
  • linux/types.h, notamment pour __u8

Bon, et stdio.h pour printf, mais ça, ça ne nous a pas posé beaucoup de problèmes.

 Trouver le périphérique

Une fois que le programme compile, on peut s’interroger sur le bon périphérique à ouvrir. Les numéro étant attribués dynamiquement au démarrage, nous avons choisi de continuer à tester tous les périphériques.

Lorsque le périphérique répond, il faut alors deviner le protocole de communication. En i2c, les périphériques se comportent généralement comme une EPROM. Il faut d’abord envoyer deux adresses :

  • Celle du périphérique
  • Celle du registre à lire

Lors d’une recherche préparatoire précédente, nous avions lu que les écran se trouvaient généralement à l’adresse 0x50. Ignorant toute subtilité possible, nous codons un programme qui teste toutes les adresses (de 0 à 250) et tous les registres. Après chaque envoi, nous faisons une demande de lecture de 10 caractères. Nous recevons des données pour un seul périphérique (c’est donc très probablement notre écran) et pour les adresses 80 à 87. Quelque soit l’adresse, les données reçues sont identiques. Une petite conversion en hexadécimal nous fait remarquer que 80 = 0x50.

 Lire les données

Entre deux lectures, nous retrouvons souvent des chaînes de caractères communs. La raison est la suivantes : en faisant une demande de lecture du registre 42 de 10 caractères, nous lisons les registres 42 à 51. Il est normal de trouver des caractères en commun (et dans le même ordre) lors de la lecture suivante.

Pour simplifier la lecture, nous remplaçons tous les 0 (qui sont des caractères de fin de chaîne en C) par 32 (le code de l’espace). Enfin nous modifions le programme pour ne faire qu’une seule lecture de 250 caractère par périphérique au registre 0. Nous récupérons toutes les informations.

En regardant les données brutes, nous reconnaissons les modèles des écrans tels que :

  • HG294 (dalle de l’écran du PC portable)
  • B1975 S1 (Un écran pour PC fixe)
  • SMS24A45 (Un écran - plus grand - aussi pour PC fixe)

Mais nous avons aussi plein d’autres informations codées dont nous ne connaissons pas la signification.

C’est presque par chance que nous trouvons la signification des données. Le mot clé est EDID (Extended display identification data). La page wikipédia nous donne toutes les informations nécessaires pour décoder notre chaîne de caractères. Nous arrivons à trouver les années de fabrications des écrans, les tailles en centimètres mais pas les résolutions natives. Wikipédia nous aurait prévenu si nous l’avions lu.

 La suite

L’I2C en mode maître marche bien sous Linux. L’une des suite possible sera de transformer un port VGA en port I2C. Le logiciel semble prêt, mais on risque certainement de se heurter à quelques difficultés. Notre but est quand même de transformer notre Linux en esclave I2C, et là, un bout de code plus conséquent risque d’être nécessaire.

Édit : Nous nous apercevons, à la mise en ligne de l’article que les pilotes I2C pour le Raspberry Pi ne sont pas dans le noyau Linux de la version recommandée à ce jour (debian6 2012-04-19). Une piste par ici.

Commentaires

Luj, le 14/08/2012

Transformer le port en VGA en adaptateur I2C, ça fonctionne sans problème ! :) :) Merci les Poivrons

POIVRON, le 14/08/2012

Sur son site, l’association Pobot explique très clairement comment découvrir l’I2C (et ce, sans s’acharner avec du C).

Il ont aussi réussi, comme l’indique Luj, à transformer un port VGA en port I2C.

Leur article est ici !

Ajouter un commentaire

Pseudo :
Mail :

Texte :

Copyright "POIVRON" 2011-2023, tous droits réservés
Administration du site