I2C protocol

전에 유영창님이 마소에 쓴 칼럼을 포스팅하긴 했는데 내용이 리눅스 디바이스 드라이버 쪽이라 이번에는 protocol관점에서 간단하게 포스팅 하기로 했다.

I2C는 일종의 protocol이라 디바이스마다 동작이 상이할 수도 있지만 기본 개념만 알고있으면 스펙을 보고 쉽게 제어할 수 있을 것이다. 이제 부터 시작~!

I²C 는 필립스에서 개발한 직렬 컴퓨터 버스이며 마더보드, 임베디드 시스템, 휴대폰등에 저속의 주변 기기를 연결하기 위해 사용된다. I²C 라는 이름은 Inter-Integrated Circuit의 약자이며 "eye-squared-see[아이-스퀘어-씨]" 라고 발음한다.

I2C의 장점은 단지 2개의 wire로만 통신이 가능하다는데 있다.
1개의 wire는 SCL로 uni-direction이며 Master에서만 출력한다.
나머지 하나의 wire는 SDA로 bi-direction이며 Master와 Slave에서 In/out으로 동작한다.
(물론 Multi-master환경에서는 SCL역시 bi-direction으로 동작하나 여기서는 Single-master임을 가정한다.)

DIAGRAM


위의 그림과 같이 Master에는 여러개의 Slave가 SDA, SCL의 wire로 연결되어 있으며,
SDA, SCL에는 pull-up register가 달려있다.
각 Slave마다 Slave address가 존재하며 Slave에 따라 10bit또는 7bit으로 이루어져있다.
Slave Bit수에 의해 동일한 버스에 1024개 또는 128개의 Slave가 존재할 수 있으나 이중 16개는 예약되어있다.
(즉, 1008개와 112개가 최대이나 프로토콜일 뿐이므로 굳이 예약된 것에 대한 것이 잊어버리자-_ -b)

WAVEFORM


신호는 크게 START bit , DATA bits, STOP bit의 3가지로 나뉜다.

START와 STOP은 SCL이 HIGH일 때 변하며, DATA는 SCL이 LOW일 때 변한다.
(protocol이 진행 중이지 않을 경우에는 pull-up register에 의해 SDA, SCL모두 HIGH상태이다.)

START는 위의 파형과 같이 SCL이 HIGH일 때 SDA가 Falling하는 경우로 slave에게 protocol이 시작됨을 알린다.

STOP은 SCL이 HIGH일 때 SDA가 Rising하는 경우로 slave에게 protocol이 종료 됨을 알린다.

DATA는 SCL이 LOW일 때 SDA가 변하며 SCL이 HIGH일 때 SDA값이 valid하다.
또한 DATA bits는 ACK와 R/W신호를 포함한다.(R/W신호는 HIGH일 경우 READ, LOW일 경우 WRITE이다.)

I2C 전송은 마스터 입장에서 크게 2가지 경우로 나뉘다. Slave에 data를 write하는 Transfer와 Slave로 부터 read하는 receive의 경우이다.

START와 STOP, R/W 신호는 무조건 Master에서 생성하는 것이나 data와 ack는 Transfer인지 Receive인지에 따라 Master 혹은 Slave에서 생성한다.

I2C Transfer
다음은 0x33의 Slave address를 가지는 장치의 0x12번 register에 data 0x21를 write하는 예이다.
(노란색 부분은 Master가 발생시킨 신호이며 푸른색은 Slave가 발생시킨 신호임에 유의한다.)

  • Start+Slave Address :
    Master에서 start signal을 발생시킨 후 slave address를 버스에 던져 준다.
    각 slave device는 master가 던진 address를 자신의 address와 비교하여 맞지 않으면 아무 동작도 하지 않고(SDA는 pull-up에 의해 HIGH상태유지), 맞으면 ACK타이밍에 SDA를 LOW로 만들어 준다.
    (R/W signal은 write인 '0'임에 유의한다.)
  • Register Address :
    Master는 Slave address단계에서 ACK를 확인한 후 해당하는 register address를 다시 버스에 던지고 ACK신호를 기다린다.
  • DATA+Stop :
    Register Address단계에서 ACK가 발생했으면 Master는 다시 쓰고자 하는 Data값을 bus로 던지면 Slave는 ACK신호를 발생시키게 되고, Master는 그 후 Stop signal을 발생시켜 통신을 종료한다.

I2C Receive
다음은 0x33 Slave address의 0x12번 register를 read하는 예이다.

  • Start+Slave Address+Register Address :
    이 구간의 동작은 앞서의 Transger동작과 같다. R/W sinal이 우선 write인 '0'임에 유의한다.
  • Restart+Slave Address :
    Master는 Re-start signal을 발생 시키고 다시 Slave address를 READ signal('HIGH')와 함께 발생시키고,
    Slave는 ACK signal을 발생시킨다.
  • DATA + Stop :
    Slave는 해당하는 register의 값을 SDA를 통해 발생시키게 되고 Master는 ACK를 날린 후 Stop signal과 함께 통신을 종료한다.

위의 Transfer와 Receive의 예는 Texas Instruments의 TPS65010이라는 칩을 예로 든 것이다.
I2C를 사용하는 Slave device마다 대동소이한 형태의 통신을 하기때문에 I2C의 기본 개념과 해당 장치의 Spec만 잘 보면 I2C를 통하여 쉽게 장치를 컨트롤할 수 있을 것이다.

<참고자료 : wikipedia i2c, 유영창님의 "임베디드 리눅스로 I2C버스에 접근하자", tps65010.pdf>

+ Recent posts