I3C
고친 사람 github-actions[bot]
I3C 는 한 기판 위의 칩들이 선 두 가닥으로 값을 주고받게 해 주는 통신 규칙입니다. 앞선 두 가닥 규격의 뒤를 이어 속도를 크게 올렸습니다. 프로세서가 버스(여러 칩이 함께 쓰는 선)에 달린 칩에게 주소를 나눠 줍니다. 칩이 프로세서를 부를 때도 같은 두 가닥을 씁니다.
쉽고 빠른 이해
I3C 는 프로세서가 선 두 가닥으로 여러 칩과 값을 주고받는 방법입니다. 예를 들어 스마트폰의 프로세서가 이 두 가닥으로 가속도 센서와 온도 센서의 값을 읽습니다.
앞서 쓰던 두 가닥 방식은 박자를 빠르게 올리기 어렵습니다. 칩이 프로세서를 부르려면 선을 한 가닥 더 깔아야 합니다. 칩마다 주소도 미리 정해 둬야 합니다. 칩이 많아질수록 선과 설정이 함께 늘어납니다.
어떻게 도는가:
- 켜지면 프로세서가 버스의 칩들에게 주소를 하나씩 나눠 줍니다
- 평소에는 프로세서가 그 주소로 칩을 불러 값을 읽고 씁니다
- 칩이 알릴 일이 생기면 같은 두 가닥으로 프로세서를 부릅니다
대가도 있습니다. 칩과 프로세서 양쪽이 따를 절차가 예전 방식보다 많습니다. 예전 방식의 칩을 같은 선에 섞어 달 때는 지켜야 할 조건이 붙습니다. 그래서 박자를 높일 필요가 없는 칩 몇 개만 다는 기판은 예전 방식을 그대로 씁니다.
상세
I3C(Improved Inter-Integrated Circuit, 개량 집적 회로 간 통신)는 I2C(Inter-Integrated Circuit, 집적 회로 간 통신)의 뒤를 잇는 통신 규격입니다. I2C 는 I3C 보다 앞서 쓰이던 두 가닥 규격입니다.
I3C 는 직렬 통신 버스입니다. 직렬 통신은 비트를 한 줄로 세워 하나씩 차례로 보내는 방식입니다. 버스는 여러 칩이 같은 선을 나눠 쓰는 연결입니다.
I3C 는 MIPI Alliance(Mobile Industry Processor Interface Alliance, 모바일 산업 프로세서 인터페이스 연합)가 정한 표준입니다. MIPI Alliance 는 휴대 기기의 칩과 칩을 잇는 규격을 정하는 업계 단체입니다.
I3C 가 노린 것은 스마트폰 안의 센서처럼 작은 칩이 많이 달리는 기판입니다. 그런 기판은 선 한 가닥이 늘 때마다 핀과 배선이 늘어납니다. I3C 는 선을 두 가닥에 묶어 둔 채 그 위에 할 일을 더 얹었습니다.
이 절은 먼저 I2C 에서 물려받은 것과 바꾼 것을 견줍니다. 그다음 주소를 나눠 주는 절차와 칩이 프로세서를 부르는 절차를 그림으로 봅니다. 끝으로 I2C 칩과 섞어 쓰는 조건과 쓰이는 곳을 봅니다.
I2C 에서 물려받은 두 가닥
I3C 의 선은 I2C 와 같은 두 가닥입니다. 데이터 비트를 싣는 선이 SDA(Serial Data, 직렬 데이터)입니다. 박자를 알리는 선이 SCL(Serial Clock, 직렬 클록)입니다. 받는 쪽은 SCL 이 한 번 오르내릴 때마다 SDA 의 비트를 하나 읽습니다.
버스 위의 칩은 두 역할로 나뉩니다. 컨트롤러는 대화를 시작하고 클록을 내는 칩입니다. 보통 프로세서가 이 역할을 맡습니다. 타깃은 컨트롤러가 주소로 부르면 답하는 칩입니다. 센서나 작은 메모리 칩이 타깃입니다.
flowchart TD
C["컨트롤러 · 프로세서"] --> B["I3C 버스 · SDA 와 SCL 두 가닥"]
B --> T1["타깃 · 가속도 센서"]
B --> T2["타깃 · 온도 센서"]
B --> T3["타깃 · I2C 칩(뒤 절 참고)"]
그림에서 컨트롤러에서 나가는 선은 두 가닥뿐입니다. 타깃 셋이 그 두 가닥을 나눠 씁니다. 컨트롤러는 주소로 그중 하나를 골라 부릅니다. 이 모양은 I2C 와 같습니다.
대화를 여닫는 신호도 I2C 와 같습니다. 여는 신호가 시작 조건입니다. 닫는 신호는 정지 조건입니다. 컨트롤러가 시작 조건을 낸 뒤 타깃 주소와 읽기·쓰기 방향을 보내면 대화가 열립니다. 그래서 I2C 를 아는 사람은 I3C 의 한 번 대화를 거의 그대로 읽을 수 있습니다.
I2C 와 SPI 사이에 선 I3C
I3C 를 이해하는 지름길은 두 이웃과 견주는 것입니다. 하나는 같은 두 가닥을 쓰는 I2C 입니다. 다른 하나는 선을 더 쓰는 대신 박자를 높게 올릴 수 있는 SPI(Serial Peripheral Interface, 직렬 주변 장치 인터페이스)입니다.
아래 표는 셋을 같은 축으로 놓습니다. 표의 「선을 몬다」는 선에 전압을 걸어 0 과 1 을 정한다는 뜻입니다.
| I2C | SPI | I3C | |
|---|---|---|---|
| 선 | 두 가닥 | 네 가닥 + 칩마다 선택선 하나 | 두 가닥 |
| 타깃을 고르는 법 | 미리 정한 주소 | 칩마다 깐 선택선 | 컨트롤러가 나눠 준 주소 |
| 선을 모는 법 | 끌어내리기만 함 | 올리고 내리기를 둘 다 함 | 대부분 올리고 내리기를 둘 다 함 |
| 타깃이 부를 때 | 선을 따로 깐다 | 선을 따로 깐다 | 같은 두 가닥으로 부른다 |
| 받았다는 답 | 바이트마다 있음 | 없음 | 주소에는 있음. 쓴 바이트에는 검사 비트 |
표에서 I3C 는 선의 수와 주소로 고르는 방식을 I2C 에서 가져왔습니다. 선을 모는 방식은 SPI 쪽에 가깝습니다. 표의 선택선은 컨트롤러가 말을 걸 칩 하나를 고르려고 칩마다 따로 까는 선입니다. 아래 소절들이 표의 줄을 하나씩 풉니다.
고르는 기준도 표에서 나옵니다. 박자를 높일 필요가 없는 칩 몇 개만 다는 기판이면 I2C 로 충분합니다. 한 칩과 큰 데이터를 아주 빠르게 주고받아야 하면 SPI 를 고릅니다. I3C 는 작은 칩이 많이 달려 선과 설정을 줄이고 싶은 기판에 맞습니다.
오픈 드레인 대신 푸시풀
I2C 는 오픈 드레인으로 신호를 냅니다. 오픈 드레인은 출력이 선을 낮은 전압으로 끌어내리기만 하는 방식입니다. 아무도 끌어내리지 않으면 선에 단 풀업 저항이 선을 높은 전압으로 천천히 되돌립니다.
이 되돌림이 I2C 를 느리게 만듭니다. 선은 작은 축전지처럼 전하를 머금습니다. 저항으로 그 전하를 채우는 데는 시간이 걸립니다. 그래서 0 에서 1 로 오르는 데 오래 걸립니다. 박자를 높게 올릴 수 없는 까닭입니다.
I3C 는 데이터를 보낼 때 푸시풀로 신호를 냅니다. 푸시풀은 출력이 선을 낮은 전압으로 끌어내리기도 하고 높은 전압으로 밀어 올리기도 하는 방식입니다. 저항을 기다리지 않으므로 오르는 데도 내리는 데도 오래 걸리지 않습니다.
다만 두 칩이 한꺼번에 선을 몰 수 있는 순간에는 I3C 도 오픈 드레인으로 돌아갑니다. 하나는 시작 조건 바로 뒤의 주소입니다. 이때 타깃이 자기 주소를 내며 컨트롤러를 부르려고 끼어들 수 있습니다(뒤 절 인밴드 인터럽트). 다른 하나는 받았다는 답입니다. 이때 선을 모는 쪽이 컨트롤러에서 타깃으로 넘어갑니다.
이런 순간에 둘이 동시에 밀고 당기면 선이 다칠 수 있습니다. 오픈 드레인이면 누가 끌어내려도 선은 0 이 될 뿐입니다.
속도
기본 전송 방식은 SDR(Single Data Rate, 단일 전송률) 모드입니다. 클록이 한 번 오르내릴 때 비트 하나를 나릅니다. 이 모드의 클록은 보통 12.5 MHz 입니다.
I2C 장치 다수가 쓰는 박자는 400 kHz 입니다. 같은 두 가닥 위에서 I3C 의 SDR 모드는 그 서른 배쯤의 박자로 비트를 나릅니다.
더 많이 나르는 HDR(High Data Rate, 고속 전송률) 모드도 있습니다. 같은 박자에 비트를 더 싣는 방식입니다. 클록이 오를 때와 내릴 때 모두 비트를 싣는 HDR-DDR(Double Data Rate, 이중 전송률)이 그 하나입니다.
주소를 나눠 주는 동적 주소 배정
I2C 에서는 타깃의 주소를 미리 정해 둬야 합니다. 같은 칩 둘을 한 버스에 달면 주소가 부딪힙니다. 어떤 칩이 어느 주소에 달렸는지도 소프트웨어가 미리 알고 있어야 합니다.
I3C 에서는 컨트롤러가 버스를 켤 때 타깃마다 주소를 나눠 줍니다. 이 절차가 동적 주소 배정(Dynamic Address Assignment, DAA)입니다. 나눠 주는 주소는 I2C 와 같은 7비트입니다.
나눠 주려면 타깃을 하나씩 가려내야 합니다. 그래서 타깃마다 공장에서 박아 넣은 48비트 고유 번호가 있습니다. 이 번호를 Provisioned ID라고 부릅니다. 번호 안에는 만든 회사와 부품 종류가 들어 있습니다.
절차는 이렇게 돕니다. 컨트롤러가 모든 타깃에게 「주소를 받아 가라」는 명령을 보냅니다. 아직 주소가 없는 타깃들은 일제히 자기 고유 번호를 앞자리 비트부터 한 비트씩 내보냅니다. 이때 선은 오픈 드레인이라 누가 0 을 내면 선이 0 이 됩니다.
1 을 내려던 타깃은 선이 0 인 것을 보고 물러납니다. 이 겨룸이 버스 중재입니다. 앞자리부터 견주므로 끝까지 남는 타깃은 고유 번호가 가장 작은 하나입니다.
sequenceDiagram
participant C as 컨트롤러
participant A as 타깃 A
participant B as 타깃 B
C->>A: 주소를 받아 가라
C->>B: 같은 명령
A-->>C: 고유 번호를 한 비트씩
B-->>C: 고유 번호를 한 비트씩
Note over A,B: 번호가 큰 B 는 중간에 물러난다
C->>A: 주소 0x08 을 준다
A-->>C: 받았다
Note over C,B: 다음 차례에 B 가 남아 주소를 받는다
그림에서 A 와 B 는 동시에 번호를 냅니다. 번호가 작은 A 가 남아 주소를 받습니다. 컨트롤러는 같은 일을 되풀이합니다. 아무도 번호를 내지 않으면 모든 타깃이 주소를 받은 것입니다.
절차가 끝나면 컨트롤러는 버스에 무엇이 달렸는지 압니다. 받아 온 고유 번호가 그대로 목록이 됩니다. 소프트웨어가 기판 구성을 미리 다 알고 있지 않아도 됩니다.
미리 주소를 정해 둔 칩도 있습니다. 그런 칩에게는 컨트롤러가 정해 둔 주소를 그대로 쓰라고 일러 줄 수도 있습니다. 겨룸 없이 주소가 정해지므로 켜는 시간이 짧아집니다.
선을 안 늘리는 인밴드 인터럽트
센서는 값이 바뀌었을 때 프로세서에게 알려야 합니다. 프로세서에게 하던 일을 멈추고 봐 달라고 부르는 신호가 인터럽트입니다. I2C 는 이 신호를 낼 길이 없습니다. 그래서 타깃마다 GPIO(General-Purpose Input/Output, 범용 입출력) 선을 하나씩 더 깔아 인터럽트를 냅니다.
I3C 에서는 타깃이 같은 두 가닥으로 인터럽트를 냅니다. 이것이 인밴드 인터럽트(In-Band Interrupt, IBI)입니다. 인밴드는 데이터가 다니는 선 안에서 처리한다는 뜻입니다.
부름은 버스가 쉬고 있을 때 타깃이 SDA 를 끌어내리는 데서 시작합니다. 그 뒤 차례는 아래 그림과 같습니다.
sequenceDiagram
participant C as 컨트롤러
participant T as 타깃 · 센서
Note over C,T: 버스가 쉬는 중
T->>C: SDA 를 끌어내린다
C->>T: 클록을 내기 시작한다
T->>C: 자기 주소
C-->>T: 받았다
T->>C: 무슨 일인지 알리는 바이트
그림의 첫 화살표는 타깃이 먼저 움직이는 유일한 순간입니다. 그 뒤로 박자는 컨트롤러가 냅니다. 주소가 먼저 오므로 컨트롤러는 누가 불렀는지 바로 압니다.
둘이 동시에 부르면 주소를 보내는 동안 버스 중재가 일어납니다. 주소가 작은 쪽이 이깁니다. 그래서 급한 칩에 작은 주소를 주면 그 칩의 인터럽트가 먼저 처리됩니다.
컨트롤러는 부름을 거절할 수도 있습니다. 거절하면 그 타깃은 나중에 다시 부릅니다. 특정 타깃의 인터럽트를 아예 끄는 명령도 있습니다.
나중에 끼어드는 핫 조인
버스가 돌고 있는 중에 새 칩이 켜질 수 있습니다. 전원을 아끼려고 꺼 두었던 칩이 깨어나는 경우가 그렇습니다. 이 칩에는 아직 주소가 없습니다.
핫 조인(Hot-Join)은 이런 칩이 버스에 끼어드는 절차입니다. 새 칩은 인밴드 인터럽트와 같은 방식으로 컨트롤러를 부릅니다. 다만 자기 주소 대신 합류 요청용으로 정해 둔 주소를 보냅니다. 컨트롤러는 이것을 보고 동적 주소 배정을 다시 돌려 새 칩에게 주소를 줍니다.
모두에게 거는 공통 명령
I3C 에는 모든 타깃이 알아듣는 명령 묶음이 있습니다. 이것이 공통 명령 코드(Common Command Code, CCC)입니다. 앞에서 본 「주소를 받아 가라」도 그중 하나입니다.
컨트롤러는 공통 명령을 두 방식으로 보냅니다. 모든 타깃이 듣는 주소로 보내면 버스 전체에 걸립니다. 타깃 하나에게만 보내는 방식도 있습니다.
공통 명령은 버스를 관리합니다. 주소를 나눠 주거나 거둬들입니다. 인터럽트를 켜거나 끕니다. 타깃이 한 번에 받을 수 있는 길이를 묻거나 정합니다. HDR 모드로 들어가라고 알리는 것도 공통 명령입니다.
바이트마다 답하지 않는 쓰기
I2C 에서는 타깃이 바이트를 받을 때마다 받았다는 답 ACK(Acknowledge, 확인 응답)를 보냅니다. 답을 보내려면 선을 모는 쪽이 컨트롤러에서 타깃으로 바뀌었다가 돌아와야 합니다. 바이트마다 이 넘겨주기가 끼어듭니다.
I3C 는 주소를 보낼 때만 ACK 를 받습니다. 데이터를 쓸 때는 바이트 여덟 비트 뒤에 컨트롤러가 아홉째 비트로 패리티 비트를 붙입니다. 패리티 비트는 바이트 안의 1 의 개수가 짝수인지 홀수인지 적어 두는 검사 비트입니다. 타깃은 이 비트로 바이트가 깨졌는지 스스로 가립니다.
읽을 때는 같은 아홉째 비트를 패리티 대신 타깃이 씁니다. 타깃은 이 비트로 「보낼 것이 더 있다」거나 「여기서 끝」이라고 알립니다. 넘겨주기 없이 한 방향으로 계속 흐르므로 빠릅니다.
클록 늘이기가 없다
I2C 타깃은 컨트롤러의 박자를 못 따라가면 SCL 을 끌어내려 박자를 늦춥니다. 이것이 클록 늘이기(clock stretching)입니다. 이 방식은 SCL 이 오픈 드레인이라 가능합니다.
I3C 에서는 SCL 을 컨트롤러 혼자 푸시풀로 몹니다. 타깃은 클록을 늦출 수 없습니다. 컨트롤러는 박자가 흔들리지 않는다고 믿고 클록을 높게 올릴 수 있습니다. 대신 받는 속도에 한계가 있는 타깃은 미리 「이 박자까지만 받는다」고 알려야 합니다.
I2C 칩과 한 버스에
I3C 버스에는 예전 I2C 타깃을 함께 달 수 있습니다. 이미 쓰던 I2C 센서를 버리지 않아도 됩니다.
섞어 다는 I2C 칩에는 조건이 둘 붙습니다. 하나는 아주 짧은 펄스를 걸러내는 필터가 있어야 한다는 것입니다. I3C 의 짧은 클록 펄스를 I2C 칩이 자기 신호로 잘못 읽으면 안 되기 때문입니다. 다른 하나는 클록 늘이기를 쓰지 않아야 한다는 것입니다.
I2C 칩이 섞인 버스에서는 컨트롤러가 I2C 칩에게 말할 때 I2C 의 낮은 박자로 말합니다. I3C 타깃끼리의 대화는 I3C 의 박자로 합니다. 그래서 섞어 달면 같은 시간에 나르는 데이터가 순수한 I3C 버스보다 줄어듭니다.
I3C Basic 과 쓰이는 곳
I3C Basic은 I3C 에서 자주 쓰는 기능만 추린 판입니다. MIPI Alliance 회원이 아니어도 구현할 수 있게 공개되어 있습니다. 로열티 없이 쓰는 환경을 노렸습니다. 그래서 휴대 기기 밖의 업계도 I3C Basic 을 가져다 씁니다.
처음 겨냥한 곳은 휴대 기기의 센서입니다. 가속도 센서·자이로 센서·온도 센서처럼 작고 많은 칩이 한 버스에 달립니다. 칩마다 인터럽트 선을 깔던 기판에서 선이 줄어듭니다.
백엔드 개발자에게 가까운 쓰임은 서버의 메모리 모듈입니다. 메모리 모듈에는 자기 용량과 속도 같은 정보를 담은 작은 칩이 붙어 있습니다. 서버는 이 정보를 부채널(sideband)인 I3C 로 읽습니다. 부채널은 데이터가 다니는 본 통로 옆에 관리용으로 따로 둔 통로입니다.
관련 항목
I3C 가 뒤를 잇거나 겨루는 기판 위 직렬 버스
I2C · SPI · SMBus · UART · 1-Wire · CAN
I3C 를 이루는 신호와 역할
SDA · SCL · 클록 · 시작 조건 · 정지 조건 · Provisioned ID
I3C 가 신호를 내는 전기 방식
오픈 드레인 · 푸시풀 · 풀업 저항 · 버스 중재 · 클록 늘이기 · 스파이크 필터
I3C 가 버스를 관리하는 절차
동적 주소 배정 · 인밴드 인터럽트 · 핫 조인 · 공통 명령 코드 · 패리티 비트 · ACK
I3C 의 전송 모드
SDR · HDR · HDR-DDR · I3C Basic
I3C 가 대신하는 별도 신호선
인터럽트 · GPIO · 칩 선택 · 인터럽트 컨트롤러
I3C 로 붙는 칩과 장비
센서 · 가속도 센서 · 자이로스코프 · 메모리 모듈 · SPD · BMC · 스마트폰
I3C 를 정한 단체와 같은 단체의 규격
MIPI Alliance · MIPI CSI · MIPI DSI · JEDEC
I3C 가 속하는 상위 분류
다른 이름: Improved Inter-Integrated Circuit · MIPI I3C · I3C 버스 · 개량 집적 회로 간 통신