SPI(Serial Peripheral Interface)
1980년대 중반에 모토롤라가 처음 개발한 동기 시리얼 통신 인터페이스로 간략히 소개하면 다음과 같다.
- SPI(Serial Peripheral Interface)는 마이크로컨트롤러를 센서, 메모리(SPI-NAND, MMC 및 SD Card, …), 주변장치에 연결하는 데 사용되는 동기식 4선 직렬 링크이다. 이것은 단순한 “사실상의(de facto)” 표준이다.
- SPI는 마스터/슬레이브 구성을 사용하고, 싱글 마스터만을 지원하며 슬레이브는 1개 이상과 연결할 수 있다.
- 디폴트 구성에서 4 wire를 사용하며 Full Duplex를 지원한다.
- 컨트롤러에 따라 Half Duplex를 지원하는 여러 모드가 사용된다.
- 연속 전송을 위해 DMA Engine을 사용하여 Queue를 지원하는 컨트롤러도 있다.
- 다음 2개의 설정 조합으로 4개의 클럭 모드를 사용한다.
- CPOL(Clock Polarity)={0, 1}
- CPHA(Clock PHAse)={0, 1}
- 최대 클럭이 제한되지 않아 속도 제한이 없다.
- 구현이 간단하므로 저속 SPI Master 또는 SPI Slave는 GPIO pin을 사용하여 구현할 수도 있다.
기본 4개의 핀 구성
- SCLK
- 클럭
- SCK, CLK, SCL로 부르기도 한다.
- MOSI
- Master Output Slave Input
- SIMO, SDI, DI, SDA로 부르기도 한다.
- MISO
- Master Output Slave Input
- SOMI, SDO, DO, SDA로 부르기도 한다.
- SS#
- Slave Select (Low Active)
여러 SPI 전송 모드
다음과 같이 Half Duplex를 사용하는 여러 종류의 SPI 모드들을 지원하는 컨트롤러도 있다.
- 3 wire SPI
- Half Duplex 입출력 wire를 1개 지원한다.
- 저속 EEPROM 및 센서류에서 사용된다.
- Dual SPI
- Half Duplex 입출력 wire를 2개 지원한다. (단방향 속도가 2배)
- Quad SPI
- Half Duplex 입출력 wire를 4개 지원한다. (단방향 속도가 4배)
- SPI-Nor 플래시 및 SPI-Nand 플래시에 자주 사용된다.
연결 구성 방식
SPI 버스를 구성하는 방법으로 다음과 같이 두 가지 방식을 사용한다.
- 독립 slave 구성 방식
- SPI 디바이스를 선택하여 사용하는 방식이다.
- Daisy-chain slave 구성 방식
- 데이터 비트를 서로 밀어내는 방식이다.
SPI 장점
- Push-Pull 출력(Open Drain이 아닌)을 사용하여 상호간에 같은 전압을 사용하여 시그널 정합성과 고속을 지원한다.
- I2C 보다 낮은 소비 전력
- Arbitration이 없다.
- 슬레이브는 마스터가 보내주는 클럭만을 사용하고 정확성이 떨어져도 문제 없다.
SPI 단점
- 인밴드(디폴트 SPI wire)를 통해 주소가 지원되지 않아 다 수의 슬레이브를 사용 시 별도의 아웃밴드(칩 셀렉트 라인)를 통해 슬레이브를 선택해야 한다.
- HW Flow-control이 없다.
- 하나의 마스터만 지원한다.
- 에러 체킹을 지원하지 않는다.
- Hot 플러그를 지원하지 않는다.
- Dual, Quad, 3-wire를 지원하는 경우 Half-Duplex만 지원한다.
Applications
- EEPROM, 플래시 메모리
- MMC or SD Card
- LCD
- RTC(Real Time Clock)
- 각종 센서류
클럭 트리거 모드
SPI 컨트롤러들은 다음 테이블과 같이 4가지 모드 중 하나 이상을 지원한다.
CPOL:
- 0-클럭 idle이 low에서 출발
- 1-클럭 idle이 high에서 출발
CPHA:
- 0-시작 pulse에서 동작
- 1-종료 pulse에서 동작
모드에 따라 트리거되는 시점이 다음과 같이 다름을 알 수 있다.
Shift Register
SPI 장치들은 Shift Register를 가지고 있다.
- 기본적으로 MSB부터 전송되는데 특정 컨트롤러는 LSB부터 전송을 수행시키는 방법도 지원한다.
간단한 SPI의 Write 및 Read 동작
Quad SPI에서의 입출력 동작
디바이스 트리
Case 1) Broadcom Northstar SPI
arch/arm64/boot/dts/broadcom/northstar2$/ns2.dtsi
qspi: spi@66470200 { compatible = "brcm,spi-bcm-qspi", "brcm,spi-ns2-qspi"; reg = <0x66470200 0x184>, <0x66470000 0x124>, <0x67017408 0x004>, <0x664703a0 0x01c>; reg-names = "mspi", "bspi", "intr_regs", "intr_status_reg"; interrupts = <GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "spi_l1_intr"; clocks = <&iprocmed>; clock-names = "iprocmed"; num-cs = <2>; #address-cells = <1>; #size-cells = <0>; };
- num-cs
- 최대 2개의 슬레이브 셀렉트 기능을 갖고 있다.
arch/arm64/boot/dts/broadcom/northstar2$/ns2-svk.dts
&qspi { bspi-sel = <0>; flash: m25p80@0 { #address-cells = <1>; #size-cells = <1>; compatible = "m25p80"; reg = <0x0>; spi-max-frequency = <12500000>; m25p,fast-read; spi-cpol; spi-cpha; partition@0 { label = "boot"; reg = <0x00000000 0x000a0000>; }; partition@a0000 { label = "env"; reg = <0x000a0000 0x00060000>; }; partition@100000 { label = "system"; reg = <0x00100000 0x00600000>; }; partition@700000 { label = "rootfs"; reg = <0x00700000 0x01900000>; }; }; };
3V 전압으로 동작하는 Micron M25P80 시리얼 Nor 플래시 임베디드 메모리로 8Mbit 용량을 가지고 있다.
- spi-max-frequency
- frequency를 제한한다.
- 위의 예에서는 12.5Mhz
- m25p,fast-read
- fast-read를 지원한다.
- spi-cpol
- 클럭이 high부터 출발해야하는 경우 설정되는 속성이다.
- spi-cpha
- 클럭이 faling edge 방향에서 데이터와 동기되어야 하는 속성이다.
Case 2) Rockchip SPI
arch/arm64/boot/dts/rockchips/rk3399.dtsi
spi1: spi@ff1d0000 { compatible = "rockchip,rk3399-spi", "rockchip,rk3066-spi"; reg = <0x0 0xff1d0000 0x0 0x1000>; clocks = <&cru SCLK_SPI1>, <&cru PCLK_SPI1>; clock-names = "spiclk", "apb_pclk"; interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH 0>; pinctrl-names = "default"; pinctrl-0 = <&spi1_clk &spi1_tx &spi1_rx &spi1_cs0>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; };
arch/arm64/boot/dts/rockchips/rk3399-gru.dtsi
&spi1 { status = "okay"; pinctrl-names = "default", "sleep"; pinctrl-1 = <&spi1_sleep>; spiflash@0 { compatible = "jedec,spi-nor"; reg = <0>; /* May run faster once verified. */ spi-max-frequency = <10000000>; }; };
참고
- SPI Subsystem -1- (Basic) | 문c – 현재 글
- SPI Subsystem -2- (Driver) | 문c
- Serial Peripheral Interface (SPI) | sparkfun
- Groking the Linux SPI Subsystem | Matt Porter – 다운로드 pdf
- https://github.com/jackmitch/libsoc (lib/spi.c) | jackmitch
- What’s going on with SPI? (2014) | Linaro – 다운로드 pdf
안녕하세요 혹시 SPI 다음글은 없는건가요??
안녕하세요? 문영일입니다.
SPI 다음 글로 SPI Subsystem -2- 가 있지만 완성되지 않아 한동안 방치(?)하고 있습니다.
요즈음엔 커널 v5.0 코어 분석 글을 계속하고 있어서 조금 미뤄둔 상태입니다.
SPI 버스 및 디바이스는 다른 버스 및 디바이스에 비해 난이도가 쉬운편이므로
이론을 어느 정도 습득하시면 관련 코드를 보는 것이 보다 더 쉬워질 것입니다.
감사합니다.