I²C

Λογικές στάθμες των γραμμών SCL και SDA

Επειδή στον δίαυλο I2C συνδέεται ποικιλία συσκευών διαφόρων τεχνολογιών (CMOS, NMOS, Διπολικής τεχνολογίας), οι οποίες μπορεί να έχουν διαφορετικές τάσεις λειτουργίας, οι στάθμες του λογικού 0 (Low) και λογικού 1 (High) σε όλες τις νέες συσκευές δεν είναι σταθερές, αλλά εξαρτώνται από την τάση τροφοδοσίας.
Έτσι τα κατώφλια του λογικού 0 και του λογικού 1 τοποθετούνται στο 30% και το 70% της τάσης τροφοδοσίας VDD αντίστοιχα. Δηλ. μία τάση στην περιοχή 0-0,3VDD θεωρείται λογικό 0 (Low), ενώ μία τάση στην περιοχή 0,7VDD έως VDD, θεωρείται λογικό 1 (High).  Παλαιότερα τα κατώφλια  του λογικού 0 και 1 είχαν τοποθετηθεί στα 1,5V  και 3,0V αντίστοιχα.

Κύριοι και υποτελείς (Masters and Slaves)

Οι συσκευές στον δίαυλο I²C είναι είτε Κύριοι (Masters) είτε Yποτελείς (Slave). H Master συσκευή είναι αυτή που ελέγχει και οδηγεί τη γραμμή ρολογιού SCL (παράγει τους παλμούς ρολογιού). Οι Slave συσκευές είναι αυτές που ανταποκρίνονται στις συσκευές Master. Μία συσκευή Slave δεν μπορεί να ξεκινήσει μία μεταφορά πάνω στο δίαυλο, μόνο μία συσκευή Master μπορεί. Σε έναν δίαυλο μπορεί να είναι συνδεμένες πολλές Master και πολλές  Slave συσκευές. Και οι Master και οι Slave συσκευές μπορούν να μεταφέρουν δεδομένα στον δίαυλο, αλλά μόνο οι Master συσκευές ελέγχουν την μεταφορά.

Το φυσικό πρωτόκολλο του διαύλου I²C

Όταν μία Master συσκευή επιθυμεί  να επικοινωνήσει με μία Slave συσκευή, ξεκινά στέλνοντας στον δίαυλο μία ακολουθία έναρξης (start sequence). Η ακολουθία έναρξης, είναι μία από τις δύο ειδικές ακολουθίες που ορίζονται στο δίαυλο I²C.  Η άλλη είναι η ακολουθία λήξης (stop sequence). Οι ακολουθίες έναρξης και λήξης διαφέρουν στο ότι είναι οι μοναδικές περιπτώσεις  στις οποίες επιτρέπεται να αλλάζει η γραμμή δεδομένων (SDA), ενόσω η γραμμή ρολογιού (SCL) είναι σε κατάσταση λογικού 1 (high). Όταν μεταφέρονται δεδομένα, η γραμμή SDA πρέπει να παραμένει σταθερή και να μην αλλάζει όσο η γραμμή ρολογιού είναι high.  Οι ακολουθίες έναρξης και λήξης σημαδεύουν την έναρξη και τη λήξη μιας μεταφοράς με μία slave συσκευή. Δηλαδή ο δίαυλος θεωρείται ότι είναι απασχολημένος, μετά από μία ακολουθία έναρξης και ελεύθερος λίγο χρόνο μετά την ακολουθία λήξης.

 
Τα δεδομένα μεταφέρονται σε ακολουθίες των 8 bit. Τα bit τοποθετούνται στη γραμμή SDA, ξεκινώντας από το περισσότερο σημαντικό bit (MSB). Η γραμμή SCL μεταβαίνει στη κατάσταση high και μετά low.  Για κάθε 8 bit δεδομένων που μεταφέρονται, η συσκευή που λαμβάνει στέλνει πίσω ένα bit επιβεβαίωσης (ACK). Έτσι στην πραγματικότητα απαιτούνται 9 παλμοί ρολογιού, για την μεταφορά των 8 bit κάθε byte δεδομένων. Εάν η συσκευή που λαμβάνει, στείλει πίσω ένα low bit επιβεβαίωσης (ACK), τότε έχει λάβει τα δεδομένα και είναι έτοιμη να λάβει το επόμενο byte δεδομένων. Εάν στείλει πίσω ένα high bit επιβεβαίωσης (που συμβολίζεται και με NACK, από τη φράση Not Acknowledged), αυτό δείχνει ότι η συσκευή που λαμβάνει, δεν μπορεί να λάβει περαιτέρω δεδομένα και η master συσκευή πρέπει να τερματίσει την αποστολή δεδομένων, εκπέμποντας μία ακολουθία λήξης.

Διευθυνσιοδότηση συσκευών του I²C διαύλου

Σε όλες τις slave συσκευές που συνδέονται στον δίαυλο, έχει αποδοθεί ένας αριθμός σαν διεύθυνση. Οι master συσκευές δεν είναι απαραίτητο να έχουν διεύθυνση, εκτός εάν υπάρχουν πολλές master συσκευές στον δίαυλο (περιβάλλον Multi-master). Οι master συσκευές μπορούν να διαλέξουν αυθαίρετα μία από τις συνδεμένες slave συσκευές για επικοινωνία,  χρησιμοποιώντας τη διεύθυνσή της. Οι διευθύνσεις των συσκευών του I²C διαύλου είναι είτε 7 bit (θεωρητικά έως 128 συσκευές στο δίαυλο), είτε 10 bit (θεωρητικά έως 1024 συσκευές στο δίαυλο) ή ακόμη και 16 bit  (θεωρητικά 65536 συσκευές στο δίαυλο). 
Εδώ θα μιλήσουμε για την περίπτωση που η διευθυνσιοδότηση  είναι 7-bit. Θεωρητικά με 7 bit μπορούμε να έχουμε έως και 128 συσκευές στο δίαυλο. Επειδή όμως ορισμένες διευθύνσεις χρησιμοποιούνται για ειδικούς σκοπούς, μόνο 112 διευθύνσεις είναι διαθέσιμες στην 7-μπιτη διευθυνσιοδότηση. Π.χ η I2C διεύθυνση 0, είναι γενική κλήση προς όλες τις συσκευές. Στον παρακάτω πίνακα φαίνονται οι διευθύνσεις που είναι δεσμευμένες για ειδικές χρήσεις.
Όταν στέλνουμε την διεύθυνση των 7–bit  Α6Α5Α4Α3Α2Α1Α0 της συσκευής με την οποία θέλουμε να επικοινωνήσουμε, ακόμη και τότε στέλνουμε 8 bit. To επιπλέον (R/W) bit χρησιμεύει να πληροφορήσει την slave συσκευή, εάν η master συσκευή πρόκειται να γράψει (δηλ. να στείλει δεδομένα)  ή να διαβάσει (δηλ. να λάβει δεδομένα) από αυτήν. Εάν το bit (R/W)  είναι μηδέν η master συσκευή πρόκειται να γράψει στη slave. Εάν είναι 1 (ένα) πρόκειται να διαβάσει από την slave.  Τα 7 bit της διεύθυνσης τοποθετούνται στα 7 πάνω (περισσότερο σημαντικά MSBs) bit του byte, ενώ bit ανάγνωσης/εγγραφής (R/W) στο λιγότερο σημαντικό bit (LSB), όπως απεικονίζεται στο παραπάνω σχήμα (το Α σημαίνει Address Bit, δηλ. bit διεύθυνσης).

Επιμήκυνση ρολογιού (Clock stretching)

Όταν η master συσκευή διαβάζει από τη slave, η slave τοποθετεί τα δεδομένα στον δίαυλο, αλλά είναι η master που ελέγχει το ρολόι. Τι συμβαίνει, εάν η slave δεν είναι έτοιμη να στείλει δεδομένα; Με slave συσκευές όπως σειριακές EEPROM δεν υπάρχει πρόβλημα, αλλά αν η slave συσκευή είναι ένας μικροεπεξεργαστής ή μικροελεγκτής, οι οποίοι έχουν να κάνουν και άλλες εργασίες, αυτό είναι ένα πρόβλημα.  Ο μικροεπεξεργαστής που παίζει το ρόλο της slave συσκευής, πρέπει π.χ να σώσει την κατάσταση του μικροεπεξεργαστή, να πάει στην υπορουτίνα διακοπής, να βρεί πια διεύθυνση θέλει η master  να διαβάσει, να πάρει τα δεδομένα και να τα τοποθετήσει στον καταχωρητή εκπομπής. Αυτό απαιτεί κάποιον χρόνο, κατά τον οποίο η master συσκευή θα συνεχίζει να στέλνει παλμούς και κατά συνέπεια να διαβάζει λανθασμένα δεδομένα.
Σε αυτήν την περίπτωση το πρωτόκολλο επιτρέπει η slave συσκευή να κρατάει το ρολόι σε κατάσταση λογικού 0 (low). Η master συσκευή από την άλλη πλευρά είναι υπεύθυνη, μετά από την απελευθέρωση της γραμμής ρολογιού, να ελέγξει εάν πράγματι πήγε στην υψηλή κατάσταση (high) προτού να συνεχίσει. Αυτός ο μηχανισμός λέγεται επιμήκυνση του ρολογιού. Για διαύλους με πολλές συσκευές, είναι σημαντικό να πάρουμε υπόψη την επιμήκυνση του ρολογιού, γιατί υπάρχει κίνδυνος η πιο αργή συσκευή να μειώσει την συνολική απόδοση του διαύλου.

Ένας γρήγορος τρόπος πρόσβασης στα δεδομένα

Πολλές I2C συσκευές έχουν έναν εσωτερικό καταχωρητή-δείκτη  ο οποίος δείχνει την θέση μνήμης από την οποία θα διαβάσουμε, ή στην οποία θα γράψουμε κατά την ακόλουθη ανάγνωση ή εγγραφή αντίστοιχα. Ο δείκτης αυτός αυξάνεται αυτόματα κατά 1 μετά από κάθε εγγραφή ή ανάγνωση. Στον δείκτη αυτόν έχουμε την δυνατότητα να γράψουμε την αρχική τιμή. Αυτό το χαρακτηριστικό δεν είναι μέρος του πρωτύπου I2C, αλλά είναι ένα πολύ χρήσιμο χαρακτηριστικό, όταν θέλουμε να γράψουμε ή να διαβάσουμε μεγάλο όγκο δεδομένων (π.χ σε I2C μνήμες RAM και ROM).