Pages List
List view
STM32 Peripheral
SPI
SPI (Serial Peripheral Interface)
- SPI 통신에는 최소 4개 이상의 I/O Pin(SCLK, MOSI, MISO, NSS)이 필요하다.
- MISO(Master In Slave Out) : MISO 핀은 슬레이브가 마스터로 데이터를 보낼 때, 다시 말하면 마스터가 슬레이브로부터 데이터를 받는 목적으로 사용된다.
- MOSI(Master Out Slave In) : MOSI 핀은 마스터가 슬레이브로 데이터를 보낼 때, 다시 말하면 슬레이브가 마스터로부터 데이터를 받는 목적으로 사용된다.
- SCK(Serial Clock) : Master-Slave의 데이터 전송(MISO, MOSI)은 SCK에 Synchronize되어 수행된다. SCK는 Master가 generate하고, Slave는 SCK를 control 할 수 없다.
- GPIO pin(Slave Select Pin) : SPI와 NSS 설정에 따라, GPIO pin은 Master와 통신할 Slave를 선택하는데 사용된다. Slave가 하나라면 GPIO pin을 사용할 필요는 없지만, 1:n 통신의 경우에는 GPIO pin으로 Slave의 NSS를 GND로 내려주는 방식으로 Master와 통신할 Slave를 선택한다.
Maximum speed, typical use, maximum distance of various communication protocols
거리가 가까운 주변장치들(MCU<->Flash memory, Display, SRAM, etc.)과 통신할 때는 SPI/I2C를 사용하지만 거리가 멀어지면 CAN, Ethernet, RS232, RS485 통신을 사용해야 한다.
SPI Introduction
- Master가 Slave와 SPI 통신을 하려면 Master와 Slave 모두 SPI Interface를 지원해야 한다. (당연히)
- Master가 Slave와 SPI로 통신하려고 할 때, GPIO로 Slave의 NSS를 GND로 내려주어야 한다. 그래야 Slave의 나머지 핀들(MISO, MOSI)이 Hi-z 상태에서 벗어나 activate된다.
- Master가 SCK에 따라 MOSI 핀과 MISO 핀으로 데이터 통신이 이루어진다.
Minimal SPI Bus
Application에 따라 SPI의 모든 wire를 사용하지 않아도 되는 경우도 존재한다.
예를 들어, Master가 Slave로 데이터를 보내기만 하고, Slave는 Master로부터 데이터를 받기만 하는 경우에는 두개의 wire로도 충분하다.
Slave의 NSS 핀은 SW적으로 GND로 내릴 수 있다.
SPI Hardware : Behind the scenes
SPI 통신은 Shift 레지스터의 데이터를 하나씩 Shift하는 방식으로 이루어진다.
그래서 MISO line이 연결된 경우, Master가 Slave로 1byte를 보낼 때 마다 Master도 Slave로부터 1byte를 받게 된다.
Customizing SPI Bus : Bus Configuration
SPI Bus는 Target device와 Application에 따라 Configuration이 달라진다.
- Full – Duplex Communication
SPI는 기본적으로 Full-Duplex Communication으로 Configuration된다.
Full-Duplex Communication에서는 Master와 Slave의 Shift 레지스터가 MISO, MOSI 핀의 단방향 라인을 통해 연결된다.
데이터는 Master에 의해 생성된 SCK의 clock edge에 동기화되어 전송된다.
- Half – Duplex Communication
Half-Duplex Communication에서는 Master와 Slave의 Shift 레지스터가 1개의 wire로 연결되어 있다.
데이터는 미리 정해진 방향으로 SCK clock edge에 동기화되어 전송된다.
Half-Duplex Communication을 지원하지 않는 device도 존재하기 때문에, Reference manual을 참고하는 것이 바람직하다.
- Simplex Communication
Simplex Communication에서는 “Transmit only”와 “Receive only” 2가지 모드만 존재한다.
물리적으로 단 하나의 wire만 연결하기 때문에, Master와 Slave는 Transmit과 Receive중 하나만 할 수 있다.
Simplex Communication은 Full-Duplex의 configuration과 동일하게 설정하면 되고, 남은 하나의 핀은 다른 목적의 GPIO로 사용할 수 있다.
SPI Functional Block Diagram
- ST의 경우, Shift 레지스터의 width가 최대 16bit라서 한번에 16bit 단위의 데이터 송수신이 가능하다.
- MISO핀을 통해 Shift 레지스터에 data frame(8bit 또는 16bit)이 들어오면, 이 data frame은 Rx buffer로 옮겨지고 여기서 데이터를 읽을 수 있다.
- Shift 레지스터가 비어있는 경우(SPI is not busy)에 Tx buffer에 데이터를 쓰면, 이 데이터가 Shift 레지스터로 옮겨지고 MOSI 핀을 통해 데이터가 전송된다.
- Rx buffer가 가득 찼을 때와 Tx buffer가 비었을 때, Interrupt를 발생시킬 수 있다. 그리고 이 Interrupt를 이용해서 데이터의 송신과 수신을 할 수 있다.
Slave Select(NSS) Pin Management
① Device가 Slave mode일 때
Slave mode일 때, NSS는 일반적인 “Chip Select” 입력의 기능을 하고, Master와 통신을 가능하게 한다.
② Device가 Master mode일 때
Master mode일 때, NSS는 output 또는 input 중에 하나로 사용될 수 있다.
Input으로 사용될 때는 NSS pin으로 Multi-Master Collision을 방지할 수 있고, Output으로 사용될 때는 하나의 Slave의 Slave select 신호로 사용할 수 있다.
Two Types of Slave Managements
① Software Slave Management
Software적으로 Slave를 Management하려면, Slave의 SPIx_CR1 레지스터의 SSM bit를 1로 set해주어야 한다.
SSM bit가 set된 상태에서, SSI bit를 1로 set하면 NSS pin이 내부적으로 VDD로 풀업되고, SSI bit를 0으로 clear하면 NSS pin이 내부적으로 GND로 풀다운된다.
② Hardware Slave Management
Hardware적으로 Slave를 Management하는 경우에는 Slave의 SSM bit는 0으로 clear되어야 하고, SSI bit의 값은 무엇이든 상관 없다.
그러면 Slave는 Master가 NSS pin을 GND로 풀다운 해주기를 기다리는 상태가 된다.
Master가 다수의 Slave 중 하나를 선택하는 경우에는 Software Slave Management 방식을 사용할 수 없다. GPIO pin으로 Slave를 Hardware Slave Management 방식으로 선택해야 한다.
통신하고 싶은 Slave의 NSS pin은 GND로 풀다운하고, 다른 Slave들의 NSS pin은 VDD로 풀업해서 Hi-z 상태로 만든다.
해당 Configuration에서는 Master의 NSS pin은 사용되지 않는다. Error를 피하기 위해 Master의 NSS pin은 configuring하지 않거나, NSS의 AF로 configuring 할 경우에는 VDD로 풀업시키는 것이 바람직하다.
SPI Communication Format
- SPI 통신에는 CPHA(SCLK Phase), CPOL(SCLK Polarity), DFF(Data Frame Format)의 중요한 3가지 요소가 존재한다.
- Serial clock(SCK)은 data line의 정보를 shifting하고 sampling을 동기화 시킨다.
- Communication Format은 Clock phase, Clock polarity, Data frame format에 dependent한데, 통신이 원활하게 이루어지려면 Master와 Slave의 communication format이 동일해야 한다. 그렇지 않으면 data가 corrupted 될 수 있다.
- Data Format에는 8bit data format과 16bit data format이 있는데, 8bit data format이 default이다.
CPOL (Clock Polarity)
SPI Control 레지스터의 CPOL bit가 0이면, Clock의 Idle 상태(Master-Slave간에 통신이 없을 때)가 Low이다.
CPOL bit가 1이면, Clock의 idle 상태(Master-Slave간에 통신이 없을 때)가 High이다.
CPHA (Clock Phase)
CPHA bit 값에 따라, SCLK의 첫번째 edge에서 Slave Data Capture가 이루어질 것인지 두번째 edge에서 Slave의 Data Capture가 이루어질 것인지를 결정할 수 있다.
그리고 CPOL bit 값으로 Idle 상태의 Level(High/Low)를 결정함으로써, SCLK의 Rising edge에서 Data를 capture할 것인지 Falling edge에서 Data를 capture할 것인지를 결정할 수 있다.
① CPHA = 1 인 경우
CPHA bit가 1일 때, Master는 항상 SCLK의 가장 첫번째 clock edge에서 data를 보내고, Slave의 data capture(sample)는 SCLK의 두번째 clock edge에서 이루어진다.
(Rising edge에서 data를 capture하고 싶다면, CPOL bit를 1로 설정하고, Falling edge에서 data를 capture하고 싶다면, CPOL bit를 0으로 설정하면 된다.)
② CPHA = 0 인 경우
CPHA bit가 0일 때, Master는 항상 SCLK의 두번째 clock edge에서 data를 보내고, Slave의 data capture(sample)는 SCLK의 첫번째 clock edge에서 이루어진다.
(Rising edge에서 data를 capture하고 싶다면, CPOL bit를 0으로 설정하고, Falling edge에서 data를 capture하고 싶다면, CPOL bit를 1로 설정한다.)
(Rising edge에서 data를 capture하고 싶다면, CPOL bit를 0으로 설정하고, Falling edge에서 data를 capture하고 싶다면, CPOL bit를 1로 설정한다.)
User Application의 requirement에 따라 CPHA와 CPOL을 결정해야한다.
(특정 requirement가 없다면, 일반적으로 CPHA와 CPOL을 모두 default값인 0으로 설정한다.)
(특정 requirement가 없다면, 일반적으로 CPHA와 CPOL을 모두 default값인 0으로 설정한다.)
Different SPI Modes
CPHA와 CPOL의 조합에 의해 4가지 SPI Modes가 가능하다.
CPOL bit로 Idle 상태의 Level을 결정함으로써, High에서 toggle을 시작할지 아니면 Low 에서 toggle을 시작할지를 결정한다.
그리고 CPHA bit로 SCLK의 첫번째 edge에서 Data Capture 할것인지 아니면 두번째 edge에서 Data Capture 할것인지를 마지막으로 결정한다.
SPI CPOL & CPHA waveform example
SCK가 Low에서 시작되므로(Idle 상태가 Low) CPOL bit는 0이고, Data Capture는 SCK의 trailing edge(2번째 edge)에서 수행되므로 CPHA bit는 1이다.
SPI 통신 속도는 1.2MHz로 Data Transaction 시작과 Data Capture 사이의 시간 간격이 0.4us임을 그림에서 확인할 수 있다.
만약 통신 케이블의 길이가 매우 길다면, 0.4us 안에 Data가 준비되지 않아서 Slave나 Master가 garbage data를 Capture할 수 있다.
그래서 통신 케이블의 길이와 주변의 noise를 고려해서 통신 속도를 설정해야 한다는 사실을 항상 유념해야 한다.
SPI Serial clock frequency
APB1 Bus에 hanging 하고 있는 SPI2/SPI3는 최대 42MHz의 peripheral clock을 공급받지만, SCLK는 내부의 Prescalar 때문에 최대 21MHz의 속도를 가진다.
SPI1은 최대 84MHz 속도의 APB2 Bus에 hanging 하고 있기 때문에, SCLK는 최대 42MHz의 속도를 가진다.
SPI Driver development. API requirements & Configurable items
SPI Send data
SPI의 data 송신은 Tx buffer에 data를 write함으로써 시작된다.
그러나 Tx buffer가 empty가 아닌 경우에 data를 write하게 되면 data corruption이 발생한다.
그래서 data를 write하기 전에 가장 먼저 Tx buffer가 empty인지 확인해야 한다.
Tx buffer가 empty이면 SPI_SR의 TXE bit가 set 상태로 나타나고, TXE bit가 clear 상태이면, Tx buffer가 empty가 아니므로 TXE bit가 set될 때까지 기다려야 한다.
사실 Tx buffer와 Rx buffer는 Firmware의 직접적인 접근이 불가능한 레지스터이다.
그래서 Transmitter 모드에서는 SPI_DR 레지스터에 write한 값이 Tx buffer에 copy되고, Shift 레지스터에 전달된다.
Receiver 모드에서는 외부에서 Shift 레지스터로 받은 data가 Rx buffer로 전달되고, 다시 SPI_DR 레지스터로 copy된다.
결과적으로 Tx와 Rx 동작이 모두 SPI_DR 레지스터를 통해서 이루어진다.
예제 1) SPI Tx test with blocking call API
Master의 NSS pin은 반드시 +VCC로 풀업되어 있어야 한다.
Master의 SSM을 disable한 경우에는 NSS pin을 물리적으로 +VCC에 연결해 주어야 하고, SSM을 enable한 경우에는 SSI bit를 set해서 NSS pin을 내부적으로 +VCC에 연결해 주어야 한다.
Non multi-master mode일 때, 위와 같이 설정하지 않으면 SPI_CR1의 MODF bit가 set 되면서, SPI의 mode가 master에서 slave로 강제로 바뀌게 된다. (STM32F4 RM의 897p 참고)
예제 2) SPI Tx only test with blocking call API (Arduino)
SSM = 0, SPE = 1 이면, NSS output은 Low가 되고,
SSM = 0, SPE = 0 이면, NSS output은 High가 된다.
단, NSS output이 enable되려면, SSOE bit가 set되어야 한다.
[ 결과 ]
SPI Receive data
Master에서 command code를 보내면, Slave는 ACK이나 NACK을 Master에게 보내주어야 한다.
그런데 Slave는 스스로 data transfer를 initiate할 수 없으므로, Master는 Slave의 Shift 레지스터에 dummy byte를 보내는 방식으로 Slave의 data를 가져와야 한다.
SPI Command Handling with blocking call API (Arduino)
Master에서 Slave로 data를 보내면, Slave의 Shift 레지스터에 있던 쓰레기 data가 Master로 Shift된다.
따라서, 이 쓰레기 data로 인해 Master의 RXNE bit가 set되면, Master는 이 data를 읽어서 RXNE bit를 clear해주어야 한다.
[ 결과 ]
SPI Interrupts
SPI 통신에서 Interrupt는 다음과 같은 경우에 발생할 수 있다.
- Tx buffer가 empty 상태가 되어 data를 송신할 수 있을 때
- Rx buffer에 data가 수신 되었을 때
- Master mode fault
- Overrun error
Interrupt는 각각 enable되거나 disable될 수 있다.
SPI는 GPIO Interrupt의 EXTI block과는 다르게, IRQ line이 바로 NVIC에 연결되고 각자 고유의 IRQ line을 가진다.
Handling of SPI Interrupts
SPI Interrupt는 6가지 원인으로 발생할 수 있다. (크게는 3가지 : TXE, RXNE, ERROR)
어떤 인터럽트가 발생했는지는 SR의 각 flag를 확인해야 한다.
예를 들어, RXNE 때문에 발생했다면 RXNE event에 대한 코드를 작성해서 Handling하면 된다.
SPISPI (Serial Peripheral Interface)Maximum speed, typical use, maximum distance of various communication protocolsSPI IntroductionMinimal SPI BusSPI Hardware : Behind the scenesCustomizing SPI Bus : Bus ConfigurationSPI Functional Block DiagramSlave Select(NSS) Pin Management① Device가 Slave mode일 때② Device가 Master mode일 때Two Types of Slave Managements① Software Slave Management② Hardware Slave ManagementSPI Communication FormatCPOL (Clock Polarity)CPHA (Clock Phase)① CPHA = 1 인 경우② CPHA = 0 인 경우Different SPI ModesSPI CPOL & CPHA waveform exampleSPI Serial clock frequencySPI Driver development. API requirements & Configurable itemsSPI Send data예제 1) SPI Tx test with blocking call API예제 2) SPI Tx only test with blocking call API (Arduino)[ 결과 ]SPI Receive dataSPI Command Handling with blocking call API (Arduino)[ 결과 ]SPI InterruptsHandling of SPI Interrupts