# 10BASE-T1S PHY SPI 인터페이스 완벽 정리
10BASE-T1S PHY 칩을 마이크로컨트롤러와 연결할 때 가장 많이 사용되는 인터페이스가 바로 SPI(Serial Peripheral Interface)예요. 전통적인 이더넷 PHY는 MII(Media Independent Interface) 계열로 MCU와 연결됐지만, 10BASE-T1S에서는 MACPHY 통합 칩이 등장하면서 SPI 인터페이스가 대세가 됐어요.
특히 Microchip의 LAN865x 시리즈, onsemi의 NCN26010 등 주요 10BASE-T1S MACPHY 칩들이 SPI를 주 인터페이스로 채택하고 있어요. 이 글에서는 SPI 기반 MACPHY 연동의 핵심 개념과 실전 구현 방법을 정리해 드릴게요.
## MACPHY 구조와 SPI의 역할
### 기존 PHY vs MACPHY 구조 차이
전통적인 이더넷 시스템에서는 MAC(Media Access Controller)과 PHY가 분리되어 있었어요. MAC은 MCU나 SoC 내부에 통합되고, 외부 PHY 칩은 RMII(Reduced Media Independent Interface) 또는 MII로 연결됐죠. 이 경우 MCU에 반드시 이더넷 MAC 하드웨어가 내장되어 있어야 한다는 제약이 있었어요.
10BASE-T1S MACPHY는 이 구조를 바꿨어요. MAC과 PHY 기능을 하나의 칩으로 통합하고, MCU와의 인터페이스를 SPI로 단순화했어요. 덕분에 이더넷 MAC이 없는 MCU도 이더넷 기능을 추가할 수 있게 됐어요. 소형 MCU, 저전력 마이크로컨트롤러에서도 이더넷을 사용할 수 있다는 점이 큰 혁신이에요.
### SPI를 통한 데이터 전송 흐름
SPI 기반 MACPHY에서 데이터 전송 흐름은 다음과 같아요.
애플리케이션에서 생성한 이더넷 프레임은 MCU의 드라이버를 통해 SPI로 MACPHY에 전달돼요. MACPHY 내부의 MAC 블록이 프레임을 처리하고, PHY 블록이 물리 선로로 신호를 내보내요. 수신 방향은 그 반대로, PHY가 수신한 신호를 MAC이 처리한 후 SPI를 통해 MCU로 전달해요.
SPI를 통한 데이터 전송은 단순 레지스터 읽기/쓰기와 이더넷 프레임의 청크(Chunk) 전송으로 구분돼요.
## Open Alliance SPI 프로토콜(TC6)
### TC6 표준 개요
10BASE-T1S MACPHY의 SPI 인터페이스는 **OPEN Alliance TC6(Technical Committee 6)**에서 표준화된 프로토콜을 따라요. 이 표준은 SPI를 통한 이더넷 프레임 전송과 레지스터 접근을 정의해요.
TC6 SPI 프로토콜의 핵심 특징은 다음과 같아요.
– **청크(Chunk) 기반 전송**: 이더넷 프레임을 64바이트 단위의 청크로 나누어 전송해요
– **전이중(Full-Duplex) 동시 전송**: 하나의 SPI 트랜잭션에서 TX와 RX 데이터를 동시에 처리해요
– **헤더/풋터 포함**: 각 청크에 제어 정보(DV, SV, EV, DNC 등)와 상태 정보가 포함돼요
– **CRC 보호**: 헤더 CRC(4비트)와 데이터 CRC(32비트)로 데이터 무결성을 보장해요
### SPI 청크 구조 상세
TC6의 SPI 청크는 TX 방향(MCU → MACPHY)과 RX 방향(MACPHY → MCU)이 동시에 교환돼요. 각 청크는 4바이트 헤더 + 64바이트 데이터 + 4바이트 풋터로 구성돼요.
TX 헤더의 주요 비트필드를 살펴볼게요.
– **DNC (Data Not Control)**: 1이면 데이터 청크, 0이면 제어 레지스터 접근
– **DV (Data Valid)**: 이 청크에 유효한 TX 데이터가 있으면 1
– **SV (Start Valid)**: 이 청크에 이더넷 프레임 시작이 포함되면 1
– **EV (End Valid)**: 이 청크에 이더넷 프레임 끝이 포함되면 1
– **EBO (End Byte Offset)**: 마지막 청크에서 유효 데이터의 마지막 바이트 위치
RX 풋터에는 수신 상태 정보가 포함돼요. RCA(Receive Chunks Available), TX 버퍼 여유 공간, 오류 플래그 등이 담겨요.
## SPI 레지스터 접근 방법
### 레지스터 읽기/쓰기 명령 형식
TC6 SPI에서 레지스터 접근은 DNC=0인 제어 청크를 사용해요. 레지스터 주소는 32비트 어드레스 공간으로 구성되며, 메모리 맵은 MMS(Memory Map Selector)에 따라 구분돼요.
레지스터 읽기 시 MCU는 헤더에 주소와 읽기 커맨드를 담아 전송하고, 다음 SPI 트랜잭션에서 데이터를 수신해요. 쓰기 시에는 헤더와 함께 쓸 데이터를 함께 전송해요.
주요 레지스터 구역은 다음과 같아요.
– **MMS 0x0**: 공통 제어 레지스터 (리셋, 인터럽트, 상태)
– **MMS 0x1**: MAC 제어 레지스터 (필터, 주소 설정)
– **MMS 0xA**: 10BASE-T1S 특화 레지스터 (PLCA 설정 등)
– **MMS 0xF**: 벤더별 확장 레지스터
### 초기화 레지스터 설정 예시
MACPHY 초기화 시 최소한으로 설정해야 할 레지스터를 살펴볼게요. 먼저 소프트 리셋을 수행해요. RESET 비트를 1로 설정하면 칩이 초기 상태로 복원돼요. 이후 리셋 완료를 폴링으로 확인한 뒤 설정을 진행해요.
PLCA 관련 레지스터에는 노드 ID(Node_ID)와 최대 노드 수(Node_Count), PLCA 버스트 카운트 등을 설정해요. MAC 주소 레지스터에는 디바이스의 이더넷 MAC 주소를 기입해요. 마지막으로 PLCA Enable 비트를 설정하면 통신이 시작돼요.
## MCU와의 하드웨어 연결 방법
### SPI 핀 연결 구성
10BASE-T1S MACPHY는 표준 4선 SPI(MOSI, MISO, SCLK, /CS) 외에 몇 가지 추가 신호선이 필요해요.
– **MOSI(Master Out Slave In)**: MCU에서 MACPHY로 데이터 전송
– **MISO(Master In Slave Out)**: MACPHY에서 MCU로 데이터 전송
– **SCLK(Serial Clock)**: SPI 클럭, 최대 25MHz (칩에 따라 다름)
– **/CS(Chip Select)**: MACPHY 선택 신호, 액티브 로우
– **/IRQ(Interrupt Request)**: MACPHY에서 MCU로의 인터럽트 신호
– **/RESET**: MACPHY 하드웨어 리셋 신호
SPI 클럭 주파수는 SPI Mode 0(CPOL=0, CPHA=0)으로 설정하는 경우가 많아요. 다만 칩마다 지원 모드가 다를 수 있으니 데이터시트를 확인해야 해요.
### 인터럽트 기반 드라이버 설계
MACPHY를 효율적으로 사용하려면 폴링보다 인터럽트 기반 드라이버를 설계하는 것이 좋아요. /IRQ 신호가 로우가 되면 MCU는 MACPHY의 상태 레지스터를 읽어 어떤 이벤트가 발생했는지 확인해요.
주요 인터럽트 이벤트는 다음과 같아요.
– **RXCE(RX Chunk Event)**: 수신 데이터 청크가 있음
– **TXBUE(TX Buffer Underrun Event)**: TX 버퍼 언더런 발생
– **TXPDE(TX Data Phase Delimiter Error)**: TX 데이터 오류
– **PLCAS(PLCA Status)**: PLCA 상태 변화
인터럽트 핸들러에서는 빠른 처리를 위해 최소한의 작업만 수행하고, 실제 데이터 처리는 태스크나 큐를 통해 별도로 진행하는 것을 권장해요.
## 소프트웨어 드라이버 구현 팁
### 오픈소스 드라이버 활용
10BASE-T1S SPI MACPHY용 드라이버는 오픈소스로도 제공돼요. Linux 커널 5.15 이상에서는 `drivers/net/ethernet/microchip/lan865x` 드라이버가 통합되어 있어요. RTOS 기반 환경에서는 Zephyr RTOS, FreeRTOS+TCP 등의 스택과 연동하는 레퍼런스 코드를 활용할 수 있어요.
드라이버 구현 시 주의할 점은 SPI DMA를 활용해 CPU 부하를 줄이는 것이에요. 10Mbps의 이더넷 데이터를 SPI로 처리하려면 최소 수 MHz의 SPI 클럭이 필요하고, CPU가 각 바이트를 직접 처리하면 부하가 상당히 커질 수 있어요. DMA 기반 SPI 전송으로 CPU 오버헤드를 최소화하는 것이 실전에서 중요한 포인트예요.
### 디버깅 시 체크 포인트
SPI MACPHY 디버깅 시 자주 만나는 문제와 해결책을 알아볼게요.
링크 업이 안 될 때는 PLCA 설정(Node_ID, Node_Count)이 네트워크의 다른 노드와 충돌하지 않는지 확인해요. 또한 MACPHY의 PHY 레지스터에서 링크 상태 비트를 직접 읽어 물리적 연결이 정상인지 확인해야 해요.
SPI 통신 오류가 발생할 때는 CRC 오류 카운터 레지스터를 점검해요. CRC 오류가 많다면 SPI 신호 무결성 문제(케이블 길이, 종단 처리, 클럭 속도)를 의심해볼 수 있어요.
TX 버퍼 언더런이 반복된다면 드라이버의 흐름 제어 로직을 점검하세요. RX 풋터의 TXBF(TX Buffer Free) 값을 확인하고 충분한 공간이 있을 때만 데이터를 전송하는 로직이 필요해요.
## 결론
10BASE-T1S PHY SPI 인터페이스, 특히 OPEN Alliance TC6 기반의 MACPHY 통신은 처음에는 복잡해 보이지만 청크 구조와 헤더/풋터 개념을 이해하면 체계적으로 구현할 수 있어요. SPI DMA 활용, 인터럽트 기반 설계, 그리고 오픈소스 드라이버를 적극 활용하면 개발 시간을 크게 줄일 수 있어요.
10BASE-T1S를 처음 도입하는 프로젝트라면 Microchip의 LAN865x EVB 같은 평가 보드와 함께 제공되는 예제 코드를 출발점으로 삼는 것을 추천해요. 표준 준수 드라이버 위에 애플리케이션을 구현하는 방식이 장기적으로 유지보수성에서도 유리해요.