본문 바로가기
MCU/C2000

TMS320F28377D DSP SPI 사용법 : Bitfield 구조 활용 예제 코드(수정)

by linuxgo 2025. 8. 18.

TI의 TMS320F28377D는 C2000 Delfino 시리즈의 32비트 마이크로컨트롤러로, 고속 데이터 통신을 위해 SPI(Serial Peripheral Interface) 모듈을 제공합니다. SPI는 마스터-슬레이브 구조를 기반으로 한 고속 동기 직렬 통신 프로토콜로, 센서, 디스플레이, 메모리 장치 등과의 통신에 적합합니다. 이 문서에서는 TMS320F28377D SPI 모듈의 설정 방법, Bitfield 구조를 활용한 레지스터 설정, 그리고 실용적인 예제 코드를 제공하여 초보자와 숙련된 개발자 모두 쉽게 활용할 수 있도록 돕겠습니다.

1. TMS320F28377D SPI 모듈 개요

TMS320F28377D는 최대 4개의 SPI 모듈(SPIA, SPIB, SPIC, SPID)을 포함하며, 각 모듈은 마스터 또는 슬레이브 모드로 동작할 수 있습니다. 아래는 주요 사양입니다:

  • 클럭 소스: 시스템 클럭(SYSCLK, 최대 200MHz) 또는 저속 주변 클럭(LSPCLK)
  • 데이터 길이: 1~16비트 가변 데이터 워드
  • 클럭 속도: 최대 25MHz (마스터 모드)
  • 전송 모드: 4가지 클럭 위상/극성 조합 (SPI Mode 0~3)
  • FIFO: 16단계 송/수신 FIFO 지원
  • 인터럽트: 송신/수신 완료, 오버런, 언더런 등
  • 칩 셀렉트(CS): 소프트웨어 또는 하드웨어 제어
  • 주요 기능:
    • 마스터/슬레이브 모드 지원
    • 루프백 테스트 모드
    • SPI 타이밍 제어 (클럭 분주, 위상/극성 설정)
    • DMA 연동 가능

2. SPI Bitfield 설정 상세

TMS320F28377D의 SPI 레지스터는 Bitfield 구조로 정의되어 있으며, F2837xD_spi.h 헤더 파일을 통해 접근합니다. Bitfield는 레지스터의 개별 비트를 명확히 설정하여 코드 가독성과 유지보수성을 높입니다. 주요 레지스터와 Bitfield는 다음과 같습니다:

2.1 SPICCR (SPI Configuration Control Register)

  • bit.SPICHAR: 데이터 워드 길이 (0: 1비트, 15: 16비트)
  • bit.CLKPOLARITY: 클럭 극성 (0: 유휴 상태 Low, 1: 유휴 상태 High)
  • bit.HS_MODE: 고속 모드 활성화 (0: 비활성화, 1: 활성화, 기본적으로 비활성화 권장)
  • bit.SPISWRESET: SPI 소프트웨어 리셋 (0: 리셋, 1: 정상 동작)

2.2 SPICTL (SPI Operation Control Register)

  • bit.MASTER_SLAVE: 모드 선택 (0: 슬레이브, 1: 마스터)
  • bit.TALK: 송신 활성화 (1: 활성화)
  • bit.SPIINTENA: 인터럽트 활성화 (1: 활성화)
  • bit.CLK_PHASE: 클럭 위상 (0: 데이터 선행, 1: 데이터 후행)

2.3 SPIBRR (SPI Baud Rate Register)

  • bit.SPI_BIT_RATE: 보율 설정 (0~127, 보율 = LSPCLK / (SPI_BIT_RATE + 1))

2.4 SPISTS (SPI Status Register)

  • bit.BUFFULL_FLAG: 송신 버퍼 풀 플래그
  • bit.INT_FLAG: 수신 인터럽트 플래그
  • bit.OVERRUN_FLAG: 수신 오버런 플래그

2.5 SPIFFTX (SPI FIFO Transmit Register)

  • bit.TXFFIENA: 송신 FIFO 인터럽트 활성화
  • bit.TXFIFO: 송신 FIFO 리셋 (0: 리셋, 1: 정상)
  • bit.SPIFFENA: FIFO 활성화 (1: 활성화)

2.6 SPIFFRX (SPI FIFO Receive Register)

  • bit.RXFFIENA: 수신 FIFO 인터럽트 활성화
  • bit.RXFIFORESET: 수신 FIFO 리셋 (0: 리셋, 1: 정상)
  • bit.RXFFOVF: 수신 FIFO 오버플로우 플래그

2.7 SPIFFCT (SPI FIFO Control Register)

  • bit.TXDLY: 송신 지연 (0~7 클럭)

2.8 SPIPRI (SPI Priority Control Register)

  • bit.FREE: Free run 모드 (1: 디버깅 시 클럭 유지)
  • bit.SOFT: Soft run 모드 (0: 비활성화, 1: 활성화)
  • bit.TRIWIRE: 3선 모드 선택 (0: 4선, 1: 3선)
  • bit.STEINV: SPISSTE 신호 반전 (0: 정상, 1: 반전)

3. SPI 설정 절차

SPI 모듈을 효과적으로 설정하려면 다음 단계를 따라야 합니다:

  1. 시스템 초기화:
    •    InitSysCtrl()를 호출하여 시스템 클럭과 PLL을 초기화합니다.
    •    인터럽트를 비활성화하고 PIE를 초기화합니다 (DINT, InitPieCtrl, InitPieVectTable).
  2. SPI 클럭 활성화:
    •    CpuSysRegs.PCLKCR8.bit.SPI_A = 1 (또는 SPI_B, SPI_C)로 원하는 SPI 모듈의 클럭을 활성화합니다.
    •    보호된 레지스터 접근을 위해 EALLOWEDIS 사용.
  3. GPIO 설정:
    •    SPI 핀(SIMO, SOMI, SPICLK)을 해당 모듈로 설정합니다 (예: GPIO_SetupPinMux(SPI_SIMO_GPIO, GPIO_MUX_CPU1, 1)).
    •    칩 셀렉트(CS) 핀을 하드웨어(SPISSTE) 또는 소프트웨어(GPI로 설정, 예: GPIO_SetupPinMux(SPI_CS_GPIO, GPIO_MUX_CPU1, 0))로 제어.
  4. SPI 리셋:
    •    SPICCR.bit.SPISWRESET = 0으로 SPI 모듈 리셋, 설정 후 SPISWRESET = 1로 정상 동작.
  5. SPI 모드 설정:
    •    SPICCR.bit.CLKPOLARITYSPICTL.bit.CLK_PHASE로 클럭 위상/극성 설정 (Mode 0~3).
      •    Mode 0: CLKPOLARITY=0, CLK_PHASE=0 (Low at idle, 데이터 선행)
      •    Mode 1: CLKPOLARITY=0, CLK_PHASE=1 (Low at idle, 데이터 후행)
      •    Mode 2: CLKPOLARITY=1, CLK_PHASE=0 (High at idle, 데이터 선행)
      •    Mode 3: CLKPOLARITY=1, CLK_PHASE=1 (High at idle, 데이터 후행)
    •    SPICCR.bit.SPICHAR로 데이터 길이 설정.
    •    SPICTL.bit.MASTER_SLAVE로 마스터/슬레이브 모드 선택.
  6. 보율 설정:
    •    SPIBRR.bit.SPI_BIT_RATE로 보율 설정 (보율 = LSPCLK / (SPI_BIT_RATE + 1)).
  7. FIFO 설정 (필요 시):
    •    SPIFFTX.bit.SPIFFENA = 1로 FIFO 활성화.
    •    SPIFFTX.bit.TXFIFOSPIFFRX.bit.RXFIFORESET으로 FIFO 초기화.
  8. 인터럽트 설정 (필요 시):
    •    SPICTL.bit.SPIINTENA 또는 SPIFFTX.bit.TXFFIENA로 인터럽트 활성화.
    •    PIE 벡터 테이블에 인터럽트 서비스 루틴(ISR) 등록 (예: PieVectTable.SPIA_TX_INT).
  9. 디버깅 설정:
    •    SPIPRI.bit.FREE = 1로 디버깅 시 클럭 유지.
    •    SPIPRI.bit.SOFT = 0으로 Soft run 모드 비활성화.
  10. SPI 활성화:
    •    SPICTL.bit.TALK = 1로 송신 활성화.
    •    SPICCR.bit.SPISWRESET = 1로 SPI 동작 시작.

4. SPI 설정 고려사항

  • 클럭 설정: LSPCLK(기본 50MHz)에서 보율 계산 (예: SPIBRR=49 → 1MHz).
  • 모드 선택: 대상 장치의 SPI 모드(0~3) 확인 (클럭 위상/극성).
  • 칩 셀렉트: 하드웨어 CS(SPISTE) 또는 소프트웨어 GPIO 제어.
  • FIFO 사용: 대량 데이터 전송 시 FIFO 활성화로 효율성 증대.
  • 인터럽트: 실시간 데이터 처리 시 인터럽트 활용.
  • 루프백 테스트: SPICCR.bit.LOOPBACK으로 내부 테스트 가능.

5. 실용적인 SPI 예제 코드 (Bitfield 구조)

아래는 TMS320F28377D SPI 모듈을 Bitfield 구조로 설정한 3개의 실용적인 예제 코드입니다. 각 예제는 Code Composer Studio(CCS)와 C2000Ware 환경에서 실행 가능합니다.

TMS320F28377D SPI

5.1 예제 1: 기본 SPI 마스터 전송

/**
 * spi_basic_master.c
 * Description: TMS320F28377D SPI 기본 마스터 전송 (8비트, 1MHz, Mode 0) 예제
 * Compiler: Code Composer Studio (TI C2000 Compiler)
 * Target: TMS320F28377D
 * Note: 슬레이브 장치는 Mode 0, 8비트, 1MHz를 지원해야 함
 */

#include "F28x_Project.h"

#define SPI_SIMO_GPIO   16  // SPIA SIMO
#define SPI_SOMI_GPIO   17  // SPIA SOMI
#define SPI_CLK_GPIO    18  // SPIA SPICLK
#define SPI_CS_GPIO     19  // SPIA CS (소프트웨어 제어)
#define BLINKY_LED_GPIO 31  // LED GPIO

// SPI GPIO 설정 함수
void setupSPIGpio(void)
{
    // GPIO 설정 (SPIA: SIMO, SOMI, SPICLK, CS, LED)
    GPIO_SetupPinMux(SPI_SIMO_GPIO, GPIO_MUX_CPU1, 1); // GPIO16을 SPIA SIMO로 설정
    GPIO_SetupPinMux(SPI_SOMI_GPIO, GPIO_MUX_CPU1, 1); // GPIO17을 SPIA SOMI로 설정
    GPIO_SetupPinMux(SPI_CLK_GPIO, GPIO_MUX_CPU1, 1);  // GPIO18을 SPIA SPICLK로 설정
    GPIO_SetupPinMux(SPI_CS_GPIO, GPIO_MUX_CPU1, 0);   // GPIO19를 일반 GPIO로 설정 (CS)
    GPIO_SetupPinOptions(SPI_CS_GPIO, GPIO_OUTPUT, GPIO_PUSHPULL); // CS 출력 설정
    GPIO_SetupPinMux(BLINKY_LED_GPIO, GPIO_MUX_CPU1, 0); // GPIO31을 LED로 설정
    GPIO_SetupPinOptions(BLINKY_LED_GPIO, GPIO_OUTPUT, GPIO_PUSHPULL); // LED 출력 설정
    GPIO_WritePin(BLINKY_LED_GPIO, 1); // LED 켜기
    GPIO_WritePin(SPI_CS_GPIO, 1);     // CS 초기 High
}

void main(void)
{
    // 시스템 초기화
    InitSysCtrl(); // 시스템 클럭 및 PLL 초기화
    InitGpio();    // GPIO 초기화
    DINT;          // 모든 인터럽트 비활성화
    InitPieCtrl(); // PIE 초기화
    IER = 0x0000;  // CPU 인터럽트 비활성화
    IFR = 0x0000;  // 대기 중인 인터럽트 플래그 지우기
    InitPieVectTable(); // PIE 벡터 테이블 초기화

    // SPI GPIO 설정
    setupSPIGpio();

    // SPIA 클럭 활성화
    EALLOW;
    CpuSysRegs.PCLKCR8.bit.SPI_A = 1; // SPIA 모듈 클럭 활성화
    EDIS;

    // SPIA 설정 (Bitfield 사용, F2837xD_spi.h 준수)
    SpiaRegs.SPICCR.bit.SPISWRESET = 0;    // SPI 리셋
    SpiaRegs.SPICCR.bit.SPICHAR = 7;       // 8비트 데이터 (0: 1비트, 7: 8비트)
    SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;   // Mode 0: 클럭 극성 0 (Low at idle)
    SpiaRegs.SPICTL.bit.CLK_PHASE = 0;     // Mode 0: 클럭 위상 0 (데이터 선행)
    SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;  // 마스터 모드
    SpiaRegs.SPICTL.bit.TALK = 1;          // 송신 활성화
    SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = 49; // 보율 1MHz (LSPCLK=50MHz/(49+1))
    SpiaRegs.SPIPRI.bit.FREE = 1;          // Free run 모드 (디버깅 시 클럭 유지)
    SpiaRegs.SPIPRI.bit.SOFT = 0;          // Soft run 모드 비활성화
    SpiaRegs.SPICCR.bit.SPISWRESET = 1;    // SPI 활성화

    // 글로벌 인터럽트 및 실시간 모드 활성화
    EINT; // 글로벌 인터럽트 활성화
    ERTM; // 실시간 모드 활성화

    // 데이터 전송
    Uint16 data = 0x00AA; // 테스트 데이터 (8비트: 0xAA)
    GPIO_WritePin(SPI_CS_GPIO, 0); // CS Low
    SpiaRegs.SPITXBUF = data;      // 송신 버퍼에 데이터 쓰기
    while(SpiaRegs.SPISTS.bit.INT_FLAG == 0); // 수신 완료 대기
    Uint16 received = SpiaRegs.SPIRXBUF;      // 수신 데이터 읽기
    GPIO_WritePin(SPI_CS_GPIO, 1); // CS High

    // 수신 데이터 검증
    if (received != data) {
        GPIO_WritePin(BLINKY_LED_GPIO, 0); // 데이터 불일치 시 LED 끄기
        for(;;); // 오류 상태에서 정지
    }

    // LED 깜빡임 루프
    for(;;)
    {
        GPIO_WritePin(BLINKY_LED_GPIO, 0); // LED 끄기
        DELAY_US(1000*500);                // 500ms 대기
        GPIO_WritePin(BLINKY_LED_GPIO, 1); // LED 켜기
        DELAY_US(1000*500);                // 500ms 대기
    }
}

설명:

  • 기능: SPIA를 마스터 모드로 설정하여 8비트 데이터(0x55AA)를 1MHz로 전송 및 수신.
  • 설정: Mode 0(클럭 극성/위상 0), 8비트 데이터, 보율 1MHz, 마스터 모드.
  • GPIO: GPIO16(SIMO), GPIO17(SOMI), GPIO18(SPICLK), GPIO19(SPISSTE), GPIO31(LED).
  • 출력: SPIA를 통해 데이터 송수신, 정상 동작 시 LED ON.

5.2 예제 2: SPI FIFO 사용

/**
 * spi_fifo.c
 * Description: TMS320F28377D SPI FIFO 사용 예제 (8비트, 1MHz, Mode 1)
 * Compiler: Code Composer Studio (TI C2000 Compiler)
 * Target: TMS320F28377D
 * Note: 슬레이브 장치는 Mode 1, 8비트, 1MHz를 지원해야 함
 */

#include "F28x_Project.h"

#define SPI_SIMO_GPIO   16  // SPIA SIMO
#define SPI_SOMI_GPIO   17  // SPIA SOMI
#define SPI_CLK_GPIO    18  // SPIA SPICLK
#define SPI_CS_GPIO     19  // SPIA CS (소프트웨어 제어)
#define BLINKY_LED_GPIO 31  // LED GPIO

// SPI GPIO 설정 함수
void setupSPIGpio(void)
{
    // GPIO 설정 (SPIA: SIMO, SOMI, SPICLK, CS, LED)
    GPIO_SetupPinMux(SPI_SIMO_GPIO, GPIO_MUX_CPU1, 1); // GPIO16을 SPIA SIMO로 설정
    GPIO_SetupPinMux(SPI_SOMI_GPIO, GPIO_MUX_CPU1, 1); // GPIO17을 SPIA SOMI로 설정
    GPIO_SetupPinMux(SPI_CLK_GPIO, GPIO_MUX_CPU1, 1);  // GPIO18을 SPIA SPICLK로 설정
    GPIO_SetupPinMux(SPI_CS_GPIO, GPIO_MUX_CPU1, 0);   // GPIO19를 일반 GPIO로 설정 (CS)
    GPIO_SetupPinOptions(SPI_CS_GPIO, GPIO_OUTPUT, GPIO_PUSHPULL); // CS 출력 설정
    GPIO_SetupPinMux(BLINKY_LED_GPIO, GPIO_MUX_CPU1, 0); // GPIO31을 LED로 설정
    GPIO_SetupPinOptions(BLINKY_LED_GPIO, GPIO_OUTPUT, GPIO_PUSHPULL); // LED 출력 설정
    GPIO_WritePin(BLINKY_LED_GPIO, 1); // LED 켜기
    GPIO_WritePin(SPI_CS_GPIO, 1);     // CS 초기 High
}

void main(void)
{
    // 시스템 초기화
    InitSysCtrl(); // 시스템 클럭 및 PLL 초기화
    InitGpio();    // GPIO 초기화
    DINT;          // 모든 인터럽트 비활성화
    InitPieCtrl(); // PIE 초기화
    IER = 0x0000;  // CPU 인터럽트 비활성화
    IFR = 0x0000;  // 대기 중인 인터럽트 플래그 지우기
    InitPieVectTable(); // PIE 벡터 테이블 초기화

    // SPI GPIO 설정
    setupSPIGpio();

    // SPIA 클럭 활성화
    EALLOW;
    CpuSysRegs.PCLKCR8.bit.SPI_A = 1; // SPIA 모듈 클럭 활성화
    EDIS;

    // SPIA 설정 (Bitfield 사용, F2837xD_spi.h 준수)
    SpiaRegs.SPICCR.bit.SPISWRESET = 0;    // SPI 리셋
    SpiaRegs.SPICCR.bit.SPICHAR = 7;       // 8비트 데이터 (0: 1비트, 7: 8비트)
    SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;   // Mode 1: 클럭 극성 0 (Low at idle)
    SpiaRegs.SPICTL.bit.CLK_PHASE = 1;     // Mode 1: 클럭 위상 1 (데이터 후행)
    SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;  // 마스터 모드
    SpiaRegs.SPICTL.bit.TALK = 1;          // 송신 활성화
    SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = 49; // 보율 1MHz (LSPCLK=50MHz/(49+1))
    SpiaRegs.SPIPRI.bit.FREE = 1;          // Free run 모드 (디버깅 시 클럭 유지)
    SpiaRegs.SPIPRI.bit.SOFT = 0;          // Soft run 모드 비활성화

    // FIFO 설정
    SpiaRegs.SPIFFTX.bit.SPIFFENA = 1;     // FIFO 활성화
    SpiaRegs.SPIFFTX.bit.TXFIFO = 1;       // 송신 FIFO 리셋 해제
    SpiaRegs.SPIFFRX.bit.RXFIFORESET = 1;  // 수신 FIFO 리셋 해제
    SpiaRegs.SPIFFCT.bit.TXDLY = 0;        // 송신 지연 없음
    SpiaRegs.SPICCR.bit.SPISWRESET = 1;    // SPI 활성화

    // 글로벌 인터럽트 및 실시간 모드 활성화
    EINT; // 글로벌 인터럽트 활성화
    ERTM; // 실시간 모드 활성화

    // 다중 데이터 전송
    Uint16 data[] = {0x00AA, 0x0055, 0x00FF, 0x0088}; // 테스트 데이터 배열 (8비트 데이터)
    int i;
    for(i = 0; i < 4; i++) {
        GPIO_WritePin(SPI_CS_GPIO, 0); // CS Low
        SpiaRegs.SPITXBUF = data[i];   // FIFO에 데이터 쓰기
        while(SpiaRegs.SPIFFRX.bit.RXFFST < 1); // 수신 FIFO에 데이터 대기
        Uint16 received = SpiaRegs.SPIRXBUF;    // 수신 데이터 읽기
        GPIO_WritePin(SPI_CS_GPIO, 1); // CS High
        // 수신 데이터 검증
        if (received != data[i]) {
            GPIO_WritePin(BLINKY_LED_GPIO, 0); // 데이터 불일치 시 LED 끄기
            for(;;); // 오류 상태에서 정지
        }
        DELAY_US(100); // 슬레이브 장치 안정화를 위한 짧은 지연
    }

    // LED 깜빡임 루프
    for(;;)
    {
        GPIO_WritePin(BLINKY_LED_GPIO, 0); // LED 끄기
        DELAY_US(1000*500);                // 500ms 대기
        GPIO_WritePin(BLINKY_LED_GPIO, 1); // LED 켜기
        DELAY_US(1000*500);                // 500ms 대기
    }
}

설명:

  • 기능: SPIA를 마스터 모드로 설정하여 8비트 데이터 배열을 FIFO를 통해 1MHz로 전송 및 수신.
  • 설정: Mode 1(클럭 극성 0, 위상 1), 8비트 데이터, 보율 1MHz, FIFO 활성화.
  • GPIO: GPIO16(SIMO), GPIO17(SOMI), GPIO18(SPICLK), GPIO19(SPISSTE), GPIO31(LED).
  • 출력: SPIA를 통해 다중 데이터 송수신, 정상 동작 시 LED ON.

5.3 예제 3: SPI 인터럽트 기반 데이터 전송

/**
 * spi_interrupt.c
 * Description: TMS320F28377D SPI 인터럽트 기반 데이터 전송 예제 (8비트, 1MHz, Mode 0)
 * Compiler: Code Composer Studio (TI C2000 Compiler)
 * Target: TMS320F28377D
 * Note: 슬레이브 장치는 Mode 0, 8비트, 1MHz를 지원해야 함
 */

#include "F28x_Project.h"

#define SPI_SIMO_GPIO   16  // SPIA SIMO
#define SPI_SOMI_GPIO   17  // SPIA SOMI
#define SPI_CLK_GPIO    18  // SPIA SPICLK
#define SPI_CS_GPIO     19  // SPIA CS (소프트웨어 제어)
#define BLINKY_LED_GPIO 31  // LED GPIO

volatile Uint16 tx_data = 0x00A5; // 송신 데이터 (8비트: 0xA5)
volatile Uint16 rx_data = 0;     // 수신 데이터

// SPI GPIO 설정 함수
void setupSPIGpio(void)
{
    // GPIO 설정 (SPIA: SIMO, SOMI, SPICLK, CS, LED)
    GPIO_SetupPinMux(SPI_SIMO_GPIO, GPIO_MUX_CPU1, 1); // GPIO16을 SPIA SIMO로 설정
    GPIO_SetupPinMux(SPI_SOMI_GPIO, GPIO_MUX_CPU1, 1); // GPIO17을 SPIA SOMI로 설정
    GPIO_SetupPinMux(SPI_CLK_GPIO, GPIO_MUX_CPU1, 1);  // GPIO18을 SPIA SPICLK로 설정
    GPIO_SetupPinMux(SPI_CS_GPIO, GPIO_MUX_CPU1, 0);   // GPIO19를 일반 GPIO로 설정 (CS)
    GPIO_SetupPinOptions(SPI_CS_GPIO, GPIO_OUTPUT, GPIO_PUSHPULL); // CS 출력 설정
    GPIO_SetupPinMux(BLINKY_LED_GPIO, GPIO_MUX_CPU1, 0); // GPIO31을 LED로 설정
    GPIO_SetupPinOptions(BLINKY_LED_GPIO, GPIO_OUTPUT, GPIO_PUSHPULL); // LED 출력 설정
    GPIO_WritePin(BLINKY_LED_GPIO, 1); // LED 켜기
    GPIO_WritePin(SPI_CS_GPIO, 1);     // CS 초기 High
}

// SPIA 송신 인터럽트 서비스 루틴
__interrupt void spiA_isr(void)
{
    GPIO_WritePin(SPI_CS_GPIO, 0); // CS Low
    rx_data = SpiaRegs.SPIRXBUF;   // 수신 데이터 읽기
    if (rx_data != tx_data) {      // 수신 데이터 검증
        GPIO_WritePin(BLINKY_LED_GPIO, 0); // 데이터 불일치 시 LED 끄기
    }
    SpiaRegs.SPITXBUF = tx_data;   // 다음 데이터 송신
    GPIO_WritePin(SPI_CS_GPIO, 1); // CS High
    SpiaRegs.SPIFFTX.bit.TXFFINTCLR = 1; // 송신 인터럽트 플래그 클리어
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP6; // PIE ACK 클리어
}

void main(void)
{
    // 시스템 초기화
    InitSysCtrl(); // 시스템 클럭 및 PLL 초기화
    InitGpio();    // GPIO 초기화
    DINT;          // 모든 인터럽트 비활성화
    InitPieCtrl(); // PIE 초기화
    IER = 0x0000;  // CPU 인터럽트 비활성화
    IFR = 0x0000;  // 대기 중인 인터럽트 플래그 지우기
    InitPieVectTable(); // PIE 벡터 테이블 초기화

    // 인터럽트 벡터 설정
    EALLOW;
    PieVectTable.SPIA_TX_INT = &spiA_isr; // SPIA 송신 인터럽트 벡터 설정
    EDIS;

    // SPI GPIO 설정
    setupSPIGpio();

    // SPIA 클럭 활성화
    EALLOW;
    CpuSysRegs.PCLKCR8.bit.SPI_A = 1; // SPIA 모듈 클럭 활성화
    EDIS;

    // SPIA 설정 (Bitfield 사용, F2837xD_spi.h 준수)
    SpiaRegs.SPICCR.bit.SPISWRESET = 0;    // SPI 리셋
    SpiaRegs.SPICCR.bit.SPICHAR = 7;       // 8비트 데이터 (0: 1비트, 7: 8비트)
    SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;   // Mode 0: 클럭 극성 0 (Low at idle)
    SpiaRegs.SPICTL.bit.CLK_PHASE = 0;     // Mode 0: 클럭 위상 0 (데이터 선행)
    SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;  // 마스터 모드
    SpiaRegs.SPICTL.bit.TALK = 1;          // 송신 활성화
    SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = 49; // 보율 1MHz (LSPCLK=50MHz/(49+1))
    SpiaRegs.SPIPRI.bit.FREE = 1;          // Free run 모드 (디버깅 시 클럭 유지)
    SpiaRegs.SPIPRI.bit.SOFT = 0;          // Soft run 모드 비활성화

    // FIFO 및 인터럽트 설정
    SpiaRegs.SPIFFTX.bit.SPIFFENA = 1;     // FIFO 활성화
    SpiaRegs.SPIFFTX.bit.TXFIFO = 1;       // 송신 FIFO 리셋 해제
    SpiaRegs.SPIFFRX.bit.RXFIFORESET = 1;  // 수신 FIFO 리셋 해제
    SpiaRegs.SPIFFTX.bit.TXFFIENA = 1;     // 송신 FIFO 인터럽트 활성화
    SpiaRegs.SPIFFTX.bit.TXFFINTCLR = 1;   // 송신 인터럽트 플래그 클리어
    PieCtrlRegs.PIEIER6.bit.INTx1 = 1;     // PIE 그룹 6, SPIA TX 인터럽트 활성화
    IER |= M_INT6;                         // CPU 인터럽트 6 활성화
    SpiaRegs.SPICCR.bit.SPISWRESET = 1;    // SPI 활성화

    // 글로벌 인터럽트 및 실시간 모드 활성화
    EINT; // 글로벌 인터럽트 활성화
    ERTM; // 실시간 모드 활성화

    // 초기 데이터 송신
    GPIO_WritePin(SPI_CS_GPIO, 0); // CS Low
    SpiaRegs.SPITXBUF = tx_data;   // 초기 데이터 송신
    GPIO_WritePin(SPI_CS_GPIO, 1); // CS High

    // LED 깜빡임 루프
    for(;;)
    {
        GPIO_WritePin(BLINKY_LED_GPIO, 0); // LED 끄기
        DELAY_US(1000*500);                // 500ms 대기
        GPIO_WritePin(BLINKY_LED_GPIO, 1); // LED 켜기
        DELAY_US(1000*500);                // 500ms 대기
    }
}

설명:

  • 기능: SPIA를 마스터 모드로 설정하여 8비트 데이터(0xA5A5)를 인터럽트를 통해 1MHz로 연속 송수신.
  • 설정: Mode 0(클럭 극성/위상 0), 8비트 데이터, 보율 1MHz, FIFO 및 송신 인터럽트 활성화.
  • GPIO: GPIO16(SIMO), GPIO17(SOMI), GPIO18(SPICLK), GPIO19(SPISSTE), GPIO31(LED).
  • 출력: SPIA를 통해 연속 데이터 송수신, 정상 동작 시 LED ON.

6. 사용 방법

6.1 환경 설정

  • C2000Ware 설치: C:\ti\c2000\C2000Ware_x_xx_xx_xx에서 라이브러리 다운로드.
  • CCS 프로젝트: TMS320F28377D 타겟으로 프로젝트 생성, F28x_Project.h 포함.
  • 링커 파일: device_support\f2837xd 폴더에서 링커 파일 추가.

6.2 코드 실행

  • 각 예제를 별도의 .c 파일로 저장하거나, main.c에 복사.
  • 원하는 예제만 실행되도록 다른 코드 주석 처리.

6.3 하드웨어 준비

  • SPI 연결: SIMO, SOMI, SPICLK, SPISSTE 핀을 슬레이브 장치에 연결.
  • 칩 셀렉트: SPISSTE를 하드웨어 CS로 사용하거나 GPIO로 소프트웨어 제어.
  • LED: GPIO31에 LED 연결 (정상 동작 확인용).
  • 테스트 장치: SPI 슬레이브 장치(예: EEPROM, 센서) 연결.

6.4 디버깅

  • CCS Expressions 창: SpiaRegs.SPIRXBUF, SpiaRegs.SPISTS 확인.
  • 인터럽트 상태: SpiaRegs.SPIFFTX.bit.TXFFINT 점검.
  • 레지스터 모니터링: SpiaRegs.SPICCR, SpiaRegs.SPICTL 확인.
  • 오실로스코프: SPICLK, SIMO, SOMI 신호 확인.

7. 추가 팁

  • 루프백 테스트: SPICCR.bit.LOOPBACK = 1로 내부 테스트.
  • 보율 최적화: 대상 장치의 최대 클럭 속도 확인.
  • C2000Ware 참고: C:\ti\c2000\C2000Ware_x_xx_xx_xx\device_support\f2837xd\examples\cpu1\spi.
  • 문제 해결:
    •    데이터 손실: FIFO 상태(SPIFFRX.bit.RXFFST) 확인.
    •    통신 실패: 클럭 위상/극성, 보율 설정 점검.
    •    인터럽트 미동작: PIE 설정, ISR 등록 확인.
  • TI 리소스: TI E2E 포럼, C2000Ware 예제.

8. 결론

이 문서는 TMS320F28377D SPI 모듈의 설정 방법과 Bitfield 구조를 활용한 예제 코드를 제공하여, 초보자부터 숙련된 개발자까지 쉽게 활용할 수 있도록 구성했습니다. 기본 마스터 전송, FIFO 사용, 인터럽트 기반 전송 예제를 통해 다양한 SPI 애플리케이션에 적용 가능합니다.

키워드: TMS320F28377D, SPI, C2000, 마이크로컨트롤러, Code Composer Studio, FIFO, 인터럽트, 마스터 모드,  직렬 통신, 클럭 위상, 보율