I2C - Kasimashi/Systemes-embarques GitHub Wiki

I2C

L'I2C pour inter integrated circuit est un standard dans les bus de communications, introduits dans les années 1980 par Philips. Il permet de faire communiquer deux périphériques en utilisant deux fils : un serial data line (SDA) et un serial clock line (SCL). Les deux fils permet de réduire le nombre de broches physique, le rend bon marché et simple à interfacer. Les données d'un tel bus peuvent être transmisse dans les 100Kbits/s dans le mode standard, 400Kbits/s pour le mode rapide, et plus de 3.4 Mbits/s pour le mode très rapide.

I2C_wiring

Chaques périphériques, y compris le périphérique maitre possède une unique addresse qui est typiquement sur 7,10, ou 16 bits. Suivant la fonction, chaques devices peut être emmeteur ou recepteur. Par exemple une sonde de température numérique peut se comporter en éméteur. Un écran LCD en recepteur. Une mémoire peut être émétrice ou receptrice.

Le maitre configure l'itinitalisation du transfert des données sur le bus, il genère aussi le signal de l'horloge qui permet de transférer les données sur le bus, et aussi termine le transfer sur chaques infos demandés. Les périphériques connectés aux maitres (master) sont appelées les esclaves (slaves). Plusieurs maitres peuvent co-exister sur le même bus I2C. Lorsque plusieurs maîtres veulent contrôler le bus, une procédure d'arbitrage est alors effectuée. La capacité du bus limite le nombre d'appareils pouvant être connectés au bus.

I2C : Les broches I2C

Les broches utilisés pour les périphériques maitres et esclaves sont SDA et SCL. Ces derniers doivent être configuré en drain ouvert. Le drain ouvert est une sortie spécial. La broche de sortie est connectée à une source de tension positive si un haut actif est configurée (logique 1). La broche de sortie est dans un état d'impédance élevée si un état bas (0 logique) est configuré. L'impédance élevée est souvent obtenue en maintenant la sortie en flottante, c'est à dire non connecté à la masse ou à une source de tension positive.

Le software peut configurer le SDA et le SCL en drain ouvert. Cependant la résistance de pull-up dans le processeur est trop grande, souvent de l'ordre de 100kohms. Une si grande résistance fournit une puissance de rappel trop faible pour I2C. Pour réduire les temps de rise d'une ligne I2C on utilise souvent des résistances plus faible de l'ordre de 3kohms.

Comme montré dans la première image, la ligne SDA et SLC sont connecté au VCC avec deux résistances de pull up. Les valeurs de résistances conseillés sont 4.7Kohms pour du low speed, 3kohm pour du standard speed, et 1kohm pour du high speed.

Pour le calcul des résistances de pull up il faut : Faire un compromis entre la vitesse et la puissance dissipé dans la résistance. En utilisant une résistance plus faible on utilise plus de puissance mais nous sommes capable d'utiliser le bus plus rapidement.

Pour mieux comprendre ce qu'il se passe regardons le front montant de l'horloge SCL par exemple : I2C_Rising_time

En réalité le front montant n'est pas instantannée. La raison de cela est une capacitance parasite sur le bus I2C. Si le temps de montée et de décente est trop longue le signal I2C ne sera pas capable de transmettre les données.

Plus d'info ici : I2C_Pull_Up_Resistor

I2C : Le protocole.

I2C_Protocol

Le protocole I2C comment toujours par un bit de start et termine par un bit de stop.

  • Le bit de start est défini comme une transition d'un état haut vers bas de la ligne SDA, quand la ligne SCL est haute.
  • Le bit de stop est défini comme une transition d'un état bas vers haut de la ligne SDA, quand la ligne SCL est haute.

C'est le maitre qui génère les bits de start et de stop. Les périphériques eux sont capables de détecter ces états. Après que le bit de start a été instancié, le maitre envoi les données bytes par bytes, Pour chaques bytes le MSB est transféré en premier. Ensuite l'esclave envoi un acknowledge bit vers le maitre, pour informer le maitre de la bonne reception du byte.

Après qu'un byte a été transféré, le receveur doit répondre à l'emmeteur en emmettant un bit ACK ou NACK. De ce fait, le transmetteur relache la ligne SDA durant la 9ième période d'horloge (ACK Clock period) donc le recepteur peut tirer SDA vers le bas. Si le SDA est vers le bas, l'ACK est confirmé. Si le SDA est vers le haut, on obtient un NACK.

I2C_ACK_NACK

  • Quand le maitre envoi une donnée à l'esclave, un NACK de l'esclave signifie que la communication a échoué. Dans ce cas le maitre doit alors envoyer un bit de stop du transfert courant et redémarrer le transfert avec un bit de start.
  • Quand l'esclave envoi une donnée au maitre, un NACK du maitre signifie que le maitre a envoyé un bit de stop pour terminer la communication après que le bytes ai été transféré.

Bien que le signal d'horloge de transfert soit généré par le maître, l'esclave peut également contrôler indirectement la vitesse de transfert via l'étirement de l'horloge. Si l'esclave est trop occupé pour recevoir un autre octet, il maintient la ligne SCL au niveau bas pour forcer le maître à attendre. En raison de la logique "AND" du fil, le maître ne peut pas piloter SCL haut si l'esclave maintient SCL à bas. Le maître reprend le transfert de données après que l'esclave a libéré SCL.

I2C_Block_Diagram

Les processeurs peuvent posséder plusieurs interfaces I2C. Sur l'image ci dessus on retrouve le block diagram d'un STM32. Les octets stockés dans le registre de données sont décalés vers ou vers la ligne SDA via un registre de décalage de données interne, avec le MSB entrant ou sortant en premier.

  • Quand le maitre transfert une donnée vers l'esclave, l'hardware du maitre set automatiquement le TxE (Transmitter buffer empty) flag dans le status register si le maitre a reçu un ACK de l'esclave. Cela informe le software d'envoyer le byte suivant.
  • D'autre part, si le master a reçu un byte avec succès, l'hardware du maitre set automatiquement le RxNE (Receiver buffer not empty) flag dans le status register. Cela informe le software qu'il peut lire le bit reçu.

Si les interruptions sont utiliss, les interruptions I2C prennent places dans les conditions suivantes :

  • L'I2C du master génère une interruption si le start bit est envoyé, une slave addresse est envoyée, l'hardware sets le flag Txe ou RxNE, ou que le transfert de toutes les données soit complété.
  • L'I2C du slave gènère une interruption si l'addresse reçu correspond avec sa propre addresse, un bit de stop est reçu, l'hardware sets le flag Txe ou RxNE.

Quand il existe plusieurs périphériques sur le bus, le "clock synchronisation" et le "bus arbitration" est requis. Durant l'IDLE, le SCL et le SDA sont à l'état haut.

  • Clock Synchronisation : L'interface SCL de tout les périphériques sont sur une logique "AND". Quand 1 maitre met le SCL à bas, aucun autre ne peux le mettre à haut.
  • Bus arbitration : Sur un front descendant SCL, chaques maitre vérifient si le SDA correspond à ce qu'il a envoyé. Chaque fois qu'un maître essaie de transmettre un niveau haut mais détecte un niveau bas sur SDA, ce maître perd l'arbitrage. Chaque maître perdant est immédiatement passé en mode esclave reçu car le maître gagnant peut être en train de l'adresser. Un maître perdant redémarrera le transfert après avoir détecté un bit STOP.

I2C : Trames de données

Un slave peut avoir une addresse sur 7 ou 10 bits.

Dans le cas d'un slave qui a une addresse sur 7 bits.

  1. Le maitre commence par envoyer un bit de start, le slave address, et un bit ($R/\overline{\rmW}$) qui représente la direction de transfert. Le slave a qui s'addresse la donnée renverra un bit ACK. La direction de la donnée est représenté par le bit ($R/\overline{\rmW}$) : si le ($R/\overline{\rmW}$) bit est à 1, le master est en attente d'une data du slave. Si le ($R/\overline{\rmW}$) est à 0, le master redemande au slave de rester en écoute.
  2. Après que le slave ai fait son ACK sur son addresse, la direction des données est donnée par le ($R/\overline{\rmW}$) bit. Les datas sont transférés octet par octet. Chaqu'un suivi d'un ACK ou d'un NACK. Il faut donc 9 cycle pour envoyer 1 octet.
  3. Le maitre termine la communication en envoyant le bit de stop à l'esclave. Il se peut que le maitre génére un bit de start sans bit de stop avant. Cela permet au master de communiquer avec un autre slave ou avec le même esclave sans relacher le bus. Par example, un maitre peut envoyer une commande à un slave puis immédiatement recevoir une donnée de l'esclave.

I2C_Frame

Dans le cas d'un slave qui a une addresse sur 10 bits la trame change légèrement.

  • Après avoir envoyé le start bytes, le premier octet envoyé par le master correspond à une suite de 5 bits constants (0b11110) + les deux bits MSB de l'addresse de l'esclave. Ensuite il envoi un bit ($R/\overline{\rmW}$). Ensuite dans un second temps, le maitre envoi les 8 bits restant qui sont les bits de poids plus faible.
  • Quand le master envoi les premiers bits, il se peut que plusieurs esclaves réponses. Plusieurs ACK peuvent donc apparaitre pour la première période.
  • Quand le master envoi les bits suivants, au plus 1 device doit répondre. Plusieurs ACK n'est pas voulu lors de cette opération.
⚠️ **GitHub.com Fallback** ⚠️