I2C Protokolünün Tanıtılması
I2C (Inter-Integrated Circuit), 1980'li yılların başında, Philips Semiconductor tarafından geliştirilmiş bir seri iletişim protokülüdür.
İşlemci ve mikrodenetleyiciler, aynı veri yolu (bus) üzerinden, birden çok çevre birimiyle (peripheral) haberleşebilmelidir. Çevre birimlerine örnek olarak, EEPROM, Analog Sayısal Dönüştürücü (ADC), LCD sürücü ve zamanlayıcı (Real Timer) aygıtlarını gösterebiliriz. Ayrıca başka işlemciler de çevre birimi olabilmektedir.
Aynı veri yolu birden çok birim tarafından kontrollü bir şekilde paylaşılmalı ve iletişim kurulacak çevre birimi, işlemci tarafından, herhangi bir yöntemle seçilebilmelidir. Bu seçim ayrı bir adres yolu üzerinden yapılabilir. Fakat bu durumda işlemcinin, normalde başka amaçlarla kullanabileceği bazı uçların, sadece adresleme için tahsis edilmesi zorunluluğu ortaya çıkacaktır. Ayrıca bu adres yolları sebebiyle, PCB'nin karmaşıklığı da artacaktır.
Yukarıda bahsettiğimiz dezavantajları gidermek için Philips, yakın mesafelerde düşük band genişliği ile çalışan, 2 kablolu (2 Wired), I2C protokolünü geliştirmiştir. I2C protokolü, biri clock diğeri de veri olmak üzere 2 adet iletişim kanalına sahiptir. Bu kanallar, SCL (Serial Clock) ve SDA (Serial Data) olarak isimlendirilmektedir. SDA veri iletişimi için kullanılmakta, SCL ile ise gönderen ve alan taraflar veri senkronizasyonunu sağlamaktadır.
SDA ve SCL veri yolları üzerinde birçok aygıt bulunabilir. Bu aygıtlar, düğümleri (node) oluşturmaktadır. İletişimi başlatan taraf (CPU, mikrodenetleyici) master, karşı taraf ise slave olarak isimlendirilir. SCL master'ın kontrolündedir ancak slave de, ihtiyaç halinde, SCL'deki elektriksel seviyeyi değiştirebilmektedir.
Slave aygıtlar genel olarak, bir bölümü sabit diğerleri ise programlananabilen 7 bit'lik adreslere sahiptir. Örneğin, ilk 4 bit üretim aşamasında belirlenirken diğer 3 bit ise elektriksel olarak programlanabilir. Bu kullanıma ileride değineceğiz. Master, bu adres üzerinden slave aygıta ulaşabilmektedir. Adresleme, veri transferinde olduğu gibi, SDA üzerinden seri biçimde olmaktadır. I2C, standard 100kHz, fast 400kHz ve high speed 3.4MHz olmak üzere 3 farklı hızı desteklemektedir.
Not: Protokole sonradan yapılan eklentilerle beraber 10bit'lik adreslerin de kullanılabilmesi mümkündür.
Örnek bir I2C bağlantısı aşağıdaki gibidir.
Not: I2C veri yolu üzerindeki birimler open drain veya open collector özelliği göstermektedir. Bu birimler tarafından, SDA ve SDC üzerindeki elektriksel seviye ancak aşağıya yani lojik 0 seviyesine çekilebilir, lojik 1 yapılamaz. Bu sebeple SDA ve SDC hatları birer pull-up direnciyle lojik 1 seviyesine çekilmelidir. Pull-up direnci olarak 1K ile 10K aralığında dirençler kullanılabilmektedir.
I2C ile ilgili temel özellikleri maddeler halinde aşağıdaki gibi özetleyebiliriz.
- I2C birçok aygıt arasında, ayrı bir adres yoluna ihtiyaç duymaksızın, 2 kablolu bir iletişim kanalı oluşturur. Ayrıca referans olarak ortak bir toprak hattına (ground) ihtiyaç vardır.
- I2C, SDA ve SDC olmak üzere 1 adet veri ve 1 adet clock kanalına sahiptir.
- CPU ve mikrodenetleyici gibi, iletişimi başlatan birim master olarak isimlendirilir ve saat frekansını (clock) üretmekten sorumludur. Ayrıca iletişim yine master tarafından sonlandırılır.
- Slave çevre birimleri genellikle 7 bitlik adreslere sahiptir ve bu birimlere bu adresler üzerinden erişilir. Aynı veriyolu üzerine 112 tane aygıt bulunabilir. Bazı adresler rezerve edilmiş durumdadır bu sebeple 7 bitlik adres alanının tamamı aygıtlar için kullanılamamaktadır. (CBUS adres desteği, Start Byte, General Call, 10 bit adresleme desteği için ayrılmış adresler, farklı bus formatlarını desteklemek için ayrılmış adresler gibi rezerve adresler bulunmaktadır)
- Master ve slave arasındaki iletişim çift yönlüdür (bidirectional). İletişimin yönünü master belirler.
- İletişim yolu üzerinde birden çok master bulunabilir.
- İletişim hızını yani verinin ne zaman gönderileceğini ve okunacağını, SCL üzerinden, master dikte etmektedir. Fakat slave, bu hızda veri gönderemediği veya işleyemediği durumda SCL'nin elektriksel seviyesini değiştirerek (lojik 0 yaparak) iletişimi belli bir süre bloklayabilmektedir. Bu işlem clock stretching olarak isimlendirilir.
- I2C ile aynı kart üzerinde olduğu gibi kartlar arasında da iletişim mümkündür, maksimum iletişim kanal uzunluğu yaklaşık 4m'dir.
- I2C veriyolu herhangi bir anda ya iletişim modundandır yada idle konumdadır.
I2C İletişim Aşamaları
I2C veri transferi aşağıdaki aşamalardan oluşmaktadır.
- Hattın boşta olması durumu (Idle): Herhangi bir veri transferinin gerçekleşmediği durumdur. Bu aşamada SCL ve SDA hatları lojik 1 seviyesindedir.
- Başlangıç aşaması: SCL lojik 1 iken, SDA'nın lojik 1'den 0 çekilmesiyle oluşur. Bu işlem master tarafından yapılmaktadır.
- Adresleme aşaması: Bu aşamada, master tarafından, iletişime geçilecek slave aygıt adresi ve iletişim modu gönderilmektedir. İletişim modu, master tarafından okuma mı yoksa yazma işlemi mi yapılacağını belirler.
- Veri iletim aşaması: Bit düzeyinde veri iletişiminin yapıldığı aşamadır.
- Sonlandırma aşaması: SCL lojik 1 iken, SDA'nın lojik 0'dan 1'e çekilmesiyle oluşur. Bu işlem master tarafından yapılmaktadır, başlangıç aşamasının tersi olarak düşünülebilir.
- Başlangıç aşamasının tekrarlanması (Repeated start): Bazen, bir iletişim kurulmuş olmasına karşın, iletişim sonlandırılmadan, yeni bir başlangıç durumu oluşturulmakta ve slave yeniden adreslenmektedir. Bu sayede hattın kullanımı kaybedilmemekte ve aygıtlar arasındaki iletişim kesilmeden, birbirini takip eden okuma ve yazma işlemleri (combined read/write) yapılabilmektedir. Ayrıca EEPROM gibi çevre birimlerine yeni komutlar gönderebilmek için başlangıç durumunun yeniden oluşturulması gerekebilmektedir. EEPROM ancak başlangıç sinyalinden sonra bazı komutları anlayabilmektedir.
Şimdi IC2 aşamalarında daha yakından bakalım.
Veri transferi sırasında, SDA hattındaki verinin, SCL lojik 0 iken değişmesi ve 1 iken değişmemesi gerekmektedir. SCL lojik 0'dan 1'e geçerken (yükselen kenar) veri örneklenmektedir. Bu sebeple SCL lojik 1 iken SDA'nın lojik seviyesinin değişmesi, iletişimin başlatılması ve sonlandırılması gibi, özel anlamlara gelmektedir.
IC2 üzerindeki iletişim 8 bit'lik paketler şeklindedir, sonrasında alıcı taraf 9.bit olarak bir onay biti (ACK/NACK) göndermektedir. Lojik 0 ACK, lojik 1 ise NACK anlamına gelmektedir. ACK ve NACK master ve slave için aşağıdaki anlamlara gelmektedir.
Eğer veriyi gönderen taraf master ve alıcı slave ise, slave tarafından gönderilen ACK verinin doğru bir şekilde alındığını, NACK ise bir problem olduğunu gösterir. Veriyi gönderen taraf slave ise, master yeni bir veri paketi talep ediyorsa ACK, etmiyorsa NACK gönderir ve sonrasında iletişimi sonlandırır. Buradaki NACK biti bir probleme işaret etmemektedir.
Master ve slave arasında 1 byte'lık alışveriş sırasında, SDA üzerinden, gidip gelen veri aşağıdaki şekilde gösterilmiştir.
Şimdi, alt seviye programlamayla uğraşmaksızın, Linux üzerinde I2C protokolünün nasıl kullanılabildiğine bakalım.