Présentation générale

Généralités

Le bus I2C est caractérisé par une liaison en mode série réalisée à l’aide de 3 fils (2 signaux + la masse). C’est la société Philips qui en a créé le concept au début des années 80. Son succès est lié à sa simplicité. Voici l’architecture type d’un bus I2C :

i2c architecture example

Ce bus bus fonctionne en mode Maître/Esclave. Ceci signifie que c’est toujours le maître qui initie la communication.

Les données transitent par 2 lignes :

  • SDA (→ Serial DAta) : signal — généré par le Maître ou l’Esclave — qui va coder les données.

  • SCL (→ Serial CLock) : signal d’horloge — généré par le Maître — qui va cadencer les échanges de données

    On distingue 5 classes de périphériques en fonction des fréquences max. supportées pour SCL :

    1. "`Standard mode (Sm)`" ≤ 100 kbit/s,

    2. "`Fast mode (Fm)`" ≤ 400 kbit/s,

    3. "`Fast plus mode (Fm+)`" ≤ 1 Mbit/s,

    4. "`High-speed mode (Hs-mode)`" ≤ 3,4 Mbit/s,

    5. "`Ultra-fast mode (UFm)`" ≤ 5 Mbit/s, unidirectionnel uniquement.

La communication sur le bus est orchestrée de la manière suivante :

  1. Le maître initie le transfert par une combinaision spéciale des signaux SDA et SCL (→ la condition de start).

  2. Le maître envoie sur le bus l’adresse du composant avec qui il souhaite communiquer et indique en même temps l’opération qu’il désire effectuer (→ écriture ou lecture).

    Chacun des esclaves possède une adresse fixe dans une plage de valeurs figée par construction (→ consulter la datasheet du composant pour l’obtenir).

  3. L’esclave qui reconnaît son adresse répond à son tour par un signal de confirmation (→ ACK pour Acknowledge ou accusé de réception en français)

  4. Le maître continue la procédure de communication (écriture/lecture) avec l’esclave.

    La communication I2C est orientée octet.

    Ceci signifie que toutes les données qui transitent sur le bus sont décomposées en valeurs sur 8 bits et que chacune d’elles doit être confirmée par le récepteur à l’aide d’un accusé de réception (→ ACK si transfert OK, NACK dans le cas contraire).

  5. Le maître met fin à la communication par une combinaison spéciale des signaux SDA et SCL (→ la condition de stop).

Détail du protocole

Repos

Au repos — c-à-d en dehors d’une communication — les signaux SDA et SCL sont au niveau logique 1 du fait de la nature de l’étage de sortie des composants I2C (→ dît de type “collecteur ouvert”) et de la présence des résistances de pull-up .

START et STOP

Pour signaler le début d’une nouvelle communication I2C, le maître va forcer le signal SDA à 0 alors que SCL restera au niveau 1 : c’est la condition de START

La fin d’une communication sera, quant à elle, signalée par le maître par un front montant sur SDA alors que SCL est à 1 : c’est la condition de STOP

En dehors de ces 2 situations, SDA ne doit pas changer d’état alors que SCL est à 1 : ceci serait en effet interprété comme un début ou une fin de communication.

start stop

Codage des bits de donnée

La valeur de chaque bit qui compose un octet de donnée est déterminé par le niveau sur SDA lorsque SCL est à 1.

Les changements de niveau sur SDA pour coder les bit d’un octet de donnée doivent impérativement intervenir lorsque SCL est à 0 sous peine d’être interprété comme des conditions de START ou de STOP

codage bits

Transmission de l’adresse + sens du transfert

Chaque composant est identifié sur le bus I2C par une adresse unique sur 7 bits :

  • Les bits de poids fort sont figés par construction pour chaque type de circuit

  • Les bits de poids faible sont généralement configurables en forçant à 0 ou à 1 certaines broches du composant.

    Ceci permet d’avoir plusieurs composants identiques sur le bus en leur affectant des adresses différentes.

Cette adresse est complétée d'1 bit supplémentaire (→ R/W) qui indique ce que le maître veut faire avec l’esclave : lire ou écrire.

L’octet résultant (7 bits d’adresse + 1 bit de sens de transfert), est systématiquement transmis par le maître suite à la condition de START.

codage adresse

avec :

  • A6…​A0 : adresse de l’esclave sur 7 bits

  • R/W : sens du transfert initié par le maitre (R/W)

    • R/W = 0 → le maître veut transmettre des données

    • R/W = 1 → le maitre veut lire des données

Accusé de réception

Lors d’une communication, le destinataire du message doit toujours accuser réception de chaque octet reçu auprès de l’expéditeur.

Cet accusé de réception (→ acknowledge en anglais) prend place lors de l’impulsion de l’horloge SCL qui suit la transmission du 8ème bit d’un octet :

  1. L’émetteur (maître ou esclave selon le sens de transfert) “relâche” la ligne SDASDA passe au niveau 1.

  2. Le récepteur (maitre ou esclave) force à 0 ou à 1 le signal SDA, avant que SCL repasse à l’état 1, pour valider ou non le transfert d’octet

  3. L’émetteur lit et interprète le niveau présent sur SDA :

    • SDA = 0 traduit un transfert réussi (→ ACK) : l’émetteur peut poursuivre la transmission

    • SDA = 1 traduit l’échec du transfert (→ NACK) : l’émetteur doit mettre fin à la transmission

wavedrom i2c ack
Principe de fonctionnement de l'acknowledge

avec :

  • SDA Maître : signal SDA généré par le maître

  • SDA Esclave : signal SDA généré par l’esclave

  • Ligne SDA : signal SDA résultant de la combinaison entre SDA Maître et SDA Esclave (→ ET binaire). C’est celui que l’on visualisera sur une capture avec l’analyseur logique.

Types d’échange

Les principaux types d’échange que l’on peut rencontrer lors d’une communication entre un maître et un esclave sont les suivants :

  • Écriture

  • Lecture

  • Écriture suivie d’une lecture

Écriture

Dans ce type d’échange, le maître est l’émetteur et l’esclave, le récepteur.

write

Exemple :

  • Fixer le seuil de température haut ou bas d’un capteur de température réf. AT30TSE752 au delà ou en deçà duquel un signal alarme sera généré

    write at30tse752

Lecture

Dans ce type d’échange, le maître est le récepteur et l’esclave, l’émetteur.

Même si l’échange se déroule correctement, le maître doit y mettre fin par l’envoi dun NACK après réception du dernier octet.

Ceci implique que toute demande de lecture depuis le logiciel doit spécifier le nombre d’octet à lire et que ce nombre doit être en accord avec ce que l’esclave peut fournir.

read

Exemple :

  • Lecture de l’état des entrées sur un I/O port expander réf. MAX7321.

    read max7321

Écriture suivie d’une lecture

Dans ce type d’échange, le maître émet dans un 1er temps une commande puis enchaîne avec la lecture de la donnée rendue disponible par cette commande.

2 cas peuvent alors se présenter :

  1. la donnée est disponible immédiatement. Ex. : lecture de la valeur d’un des registres internes de l’esclave

  2. la donnée nécessite un certain temps avant d’être disponible. Ex. : acquisition d’une grandeur physique (température, lumière, pression…​) par un esclave de type capteur

Dans le 1er cas (→ donnée disponible immédiatement), l’échange prendra cette forme :

write plus read

Exemple :

  • Lecture de la valeur d’un des registres 8 bits du capteur de température réf. DS1621 (sélection du registre désiré puis lecture de sa valeur)

    write read ds1621

Dans le 2èmecas (→ donné disponible après un délai), 2 solutions sont généralement proposées :

  1. envoi de la commande avec un échange de type “Écriture” puis un échange de type “Lecture” après un délai spécifié dans la datasheet de l’esclave

  2. la technique du clock stretching qui consiste à enchainer, à la suite, un échange de type “Écriture” et un échange de type “Lecture” mais en faisant en sorte que l’esclave fasse “patienter” le maître pendant la lecture tant que la donnée n’est pas disponible et ceci, en forçant SCL à 0.

    L’implémentation matérielle du bus I2C sur le microprocesseur de la Raspberry Pi présente un bug qui peut empêcher la communication avec des périphériques I2C qui nécessite l’utilisation du clock stretching.

    Pour plus de détails, voir :

Exemple : Ces 2 techniques sont utilisables avec le capteur de température/humidité SHT31 :

wait and clock stretching sht31
Extrait datasheet capteur SHT31

🞄  🞄  🞄