본문 바로가기
MCU/C2000

TMS320F28388D DSP SDFM 사용법: DriverLib API로 SDFM 설정 및 코드(수정)

by linuxgo 2025. 8. 17.

이 문서에서는 Texas Instruments의 TMS320F28388D 마이크로컨트롤러에서 SDFM(Sigma-Delta Filter Module) 모듈을 DriverLib API를 사용하여 설정하고 사용하는 방법을 상세히 다룹니다. C2000 시리즈의 고성능 마이크로컨트롤러인 TMS320F28388D의 SDFM 모듈을 활용하여 시그마-델타 아날로그 신호를 디지털 데이터로 변환하는 방법을 배우고, 다양한 독립적인 예제 코드를 통해 실제 구현 방법을 익힐 수 있습니다. 각 코드에는 상세한 주석이 포함되어 있으며, Code Composer Studio(CCS) 환경에서 실행 가능합니다.

1. TMS320F28388D SDFM 개요

TMS320F28388D는 Texas Instruments의 C2000 시리즈에 속하는 고성능 32비트 마이크로컨트롤러로, 최대 8개의 SDFM 채널을 제공합니다. SDFM 모듈은 시그마-델타 방식의 아날로그-디지털 변환을 지원하며, 전력 관리, 모터 제어, 센서 인터페이스 등 고해상도 데이터 처리가 필요한 실시간 애플리케이션에 최적화되어 있습니다.

SDFM 모듈의 주요 특징

  • 고해상도 변환: 16비트 이상의 고해상도 디지털 데이터 출력 지원.
  • 다채널 처리: 최대 8개의 독립적인 시그마-델타 채널 제공.
  • 필터링 옵션: Sinc 필터(Sinc1, Sinc2, Sinc3)를 통해 다양한 필터링 설정 가능.
  • 인터럽트 지원: 데이터 준비 완료, 오버플로우, 언더플로우 등 다양한 이벤트에 대한 인터럽트 처리.
  • 클럭 및 동기화: 외부 또는 내부 클럭 소스를 사용하여 유연한 동기화 가능.
  • DriverLib 지원: 하드웨어 레지스터를 직접 조작하는 대신 추상화된 API로 설정 간소화.

2. 주요 SDFM DriverLib API 함수

아래는 TMS320F28388D의 SDFM 모듈을 제어하기 위해 자주 사용되는 DriverLib API 함수와 그 사용 방법입니다. C2000Ware 6.00.00.00 기준으로 작성되었습니다.

2.1. SDFM 기본 설정 관련 함수

  • SDFM_enableFilter(base, filter)
    • 설명: 특정 SDFM 필터를 활성화합니다.
    • 매개변수:
      • base (SDFM 모듈의 베이스 주소, 예: SDFM1_BASE).
      • filter (필터 번호, 예: SDFM_FILTER_1).
    • 사용 예:
      SDFM_enableFilter(SDFM1_BASE, SDFM_FILTER_1);
      
  • SDFM_disableFilter(base, filter)
    • 설명: 특정 SDFM 필터를 비활성화합니다.
    • 매개변수:
      • base (SDFM 모듈의 베이스 주소).
      • filter (필터 번호).
    • 사용 예:
      SDFM_disableFilter(SDFM1_BASE, SDFM_FILTER_1);
      
  • SDFM_setupModulatorClock(base, filter, clockMode)
    • 설명: 모듈레이터 클럭 소스와 모드를 설정합니다.
    • 매개변수:
      • base (SDFM 모듈의 베이스 주소).
      • filter (필터 번호, 예: SDFM_FILTER_1).
      • clockMode (클럭 모드, 예: SDFM_MODULATOR_CLK_EQUAL_DATA_RATE).
    • 사용 예:
      SDFM_setupModulatorClock(SDFM1_BASE, SDFM_FILTER_1, SDFM_MODULATOR_CLK_EQUAL_DATA_RATE);
      
  • SDFM_setPWMSyncSource(base, filter, syncSource)
    • 설명: 특정 필터의 동기화 소스를 PWM SOC 신호로 설정합니다.
    • 매개변수:
      • base (SDFM 모듈의 베이스 주소).
      • filter (필터 번호).
      • syncSource (동기화 소스, 예: SDFM_SYNC_PWM1_SOCA).
    • 사용 예:
      SDFM_setPWMSyncSource(SDFM1_BASE, SDFM_FILTER_1, SDFM_SYNC_PWM1_SOCA);
      
  • SDFM_enableMainFilter(base)
    • 설명: SDFM 모듈의 마스터 필터를 활성화하여 동기화 및 동작을 시작합니다.
    • 매개변수:
      • base (SDFM 모듈의 베이스 주소).
    • 사용 예:
      SDFM_enableMainFilter(SDFM1_BASE);
      
  • SDFM_enableExternalReset(base, filter)
    • 설명: 특정 필터의 외부 리셋(예: PWM SOC)을 활성화합니다.
    • 매개변수:
      • base (SDFM 모듈의 베이스 주소).
      • filter (필터 번호).
    • 사용 예:
      SDFM_enableExternalReset(SDFM1_BASE, SDFM_FILTER_1);
      

2.2. 필터 설정 관련 함수

  • SDFM_configDataFilter(base, filterConfig, enableConfig)
    • 설명: 데이터 필터의 종류(Sinc1/2/3), 오버샘플링 비율(OSR), 출력 포맷 등을 설정합니다.
    • 매개변수:
      • base (SDFM 모듈의 베이스 주소).
      • filterConfig (필터 번호, 필터 타입, OSR 설정, 예: SDFM_FILTER_1 | SDFM_FILTER_SINC3 | SDFM_SET_OSR(128)).
      • enableConfig (필터 활성화 및 데이터 포맷, 예: SDFM_DATA_FORMAT_32_BIT | SDFM_FILTER_ENABLE).
    • 사용 예:
      uint16_t filterConfig = SDFM_FILTER_1 | SDFM_FILTER_SINC3 | SDFM_SET_OSR(128);
      uint16_t enableConfig = SDFM_DATA_FORMAT_32_BIT | SDFM_FILTER_ENABLE;
      SDFM_configDataFilter(SDFM1_BASE, filterConfig, enableConfig);
      
  • SDFM_enableFilter(base, filter)
    • 설명: 특정 데이터 필터를 활성화합니다.
    • 매개변수:
      • base (SDFM 모듈의 베이스 주소).
      • filter (필터 번호).
    • 사용 예:
      SDFM_enableFilter(SDFM1_BASE, SDFM_FILTER_1);
      
  • SDFM_disableFilter(base, filter)
    • 설명: 특정 데이터 필터를 비활성화합니다.
    • 매개변수:
      • base (SDFM 모듈의 베이스 주소).
      • filter (필터 번호).
    • 사용 예:
      SDFM_disableFilter(SDFM1_BASE, SDFM_FILTER_1);
      

2.3. 인터럽트 관련 함수

  • SDFM_enableInterrupt(base, filter, interruptSource)
    • 설명: 특정 필터의 인터럽트를 활성화합니다.
    • 매개변수:
      • base (SDFM 모듈의 베이스 주소).
      • filter (필터 번호).
      • interruptSource (인터럽트 소스, 예: SDFM_MODULATOR_FAILURE_INTERRUPT, SDFM_DATA_FILTER_ACKNOWLEDGE_INTERRUPT).
    • 사용 예:
      SDFM_enableInterrupt(SDFM1_BASE, SDFM_FILTER_1, 
                          SDFM_MODULATOR_FAILURE_INTERRUPT | SDFM_DATA_FILTER_ACKNOWLEDGE_INTERRUPT);
      
  • SDFM_clearInterruptFlag(base, flag)
    • 설명: 인터럽트 플래그를 지웁니다.
    • 매개변수:
      • base (SDFM 모듈의 베이스 주소).
      • flag (지울 인터럽트 플래그, 예: SDFM_INT_MASK).
    • 사용 예:
      SDFM_clearInterruptFlag(SDFM1_BASE, SDFM_INT_MASK);
      
  • Interrupt_register(intNumber, handler)
    • 설명: 인터럽트 서비스 루틴(ISR)을 등록합니다.
    • 매개변수:
      • intNumber (인터럽트 번호, 예: INT_SDFM1).
      • handler (ISR 함수 포인터).
    • 사용 예:
      Interrupt_register(INT_SDFM1, &sdfm1ISR);
      
  • SDFM_enableMainInterrupt(base)
    • 설명: SDFM 모듈의 마스터 인터럽트를 활성화하여 필터 인터럽트를 CPU로 전달합니다.
    • 매개변수:
      • base (SDFM 모듈의 베이스 주소).
    • 사용 예:
      SDFM_enableMainInterrupt(SDFM1_BASE);
      

2.4. 데이터 읽기 관련 함수

  • SDFM_getFilterData(base, filter)
    • 설명: 지정된 필터의 변환된 데이터를 읽습니다.
    • 매개변수:
      • base (SDFM 모듈의 베이스 주소).
      • filter (필터 번호).
    • 반환값: 32비트 또는 16비트 필터링된 데이터 (SDFM_DATA_FORMAT_32_BIT 설정 시 32비트).
    • 사용 예:
      int32_t data = SDFM_getFilterData(SDFM1_BASE, SDFM_FILTER_1);
      
  • SDFM_setOutputDataFormat(base, filter, format)
    • 설명: 필터 데이터의 출력 포맷(16비트 또는 32비트)을 설정합니다.
    • 매개변수:
      • base (SDFM 모듈의 베이스 주소).
      • filter (필터 번호).
      • format (데이터 포맷, 예: SDFM_DATA_FORMAT_32_BIT).
    • 사용 예:
      SDFM_setOutputDataFormat(SDFM1_BASE, SDFM_FILTER_1, SDFM_DATA_FORMAT_32_BIT);
      

3. SDFM 설정 및 동작 원리

  1. 시스템 초기화:
    • 시스템 클럭, PLL, 주변 장치 초기화: Device_init().
    • GPIO 초기화: Device_initGPIO().
    • 인터럽트 모듈 초기화: Interrupt_initModule(), Interrupt_initVectorTable().
  2. SDFM 모듈 설정:
    • 클럭 활성화: SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SD1).
    • 모듈레이터 클럭 설정: SDFM_setupModulatorClock(base, filter, clockMode).
    • 필터 설정: SDFM_configDataFilter(base, filterConfig, enableConfig)로 Sinc1/2/3, OSR, 데이터 포맷 설정.
    • 동기화 설정: SDFM_setPWMSyncSource(base, filter, syncSource)로 PWM SOC 신호 동기화.
    • 마스터 필터 활성화: SDFM_enableMainFilter(base).
    • 외부 리셋 활성화: SDFM_enableExternalReset(base, filter).
  3. 인터럽트 설정 (선택):
    • 인터럽트 활성화: SDFM_enableInterrupt(base, filter, interruptSource)로 데이터 준비 완료(SDFM_DATA_FILTER_ACKNOWLEDGE_INTERRUPT) 또는 모듈레이터 실패 인터럽트 설정.
    • ISR 등록: Interrupt_register(INT_SDFM1, &sdfm1ISR).
    • 마스터 인터럽트 활성화: SDFM_enableMainInterrupt(base).
  4. GPIO 설정:
    • SDFM 입력 핀 설정: GPIO_setPinConfig(GPIO_48_SD1_D1), GPIO_49_SD1_C1 등으로 SD-Dx, SD-Cx 설정.
    • ePWM 출력 핀 설정: GPIO_setPinConfig(GPIO_0_EPWM1A).
  5. SDFM 활성화 및 데이터 읽기:
    • 필터 활성화: SDFM_enableFilter(base, filter).
    • 데이터 읽기: SDFM_getFilterData(base, filter)로 필터링된 데이터 획득.
    • 인터럽트 기반 데이터 처리: ISR에서 SDFM_getFilterData 호출 및 SDFM_clearInterruptFlag로 플래그 초기화.

4. SDFM 예제 코드

아래는 독립적인 SDFM 예제 코드로, C2000Ware의 DriverLib를 기반으로 작성되었습니다. GPIO 설정은 별도의 initGPIO() 함수로 분리되어 있으며, 모든 코드는 CCS에서 바로 실행 가능합니다. 각 코드에는 상세한 주석을 추가하여 초보자도 이해할 수 있도록 했습니다.

TMS320F28388D DSP SDFM

4.1. 예제 1: 기본 SDFM 데이터 읽기

SDFM1의 채널 1을 사용하여 Sinc3 필터로 데이터를 읽습니다.

//###########################################################################
// 파일명: sdfm_filter_sync_cpuread.c
// 제목: TMS320F28388D용 SDFM 필터 동기 CPU 읽기 예제
// 설명:
//  이 예제는 SDFM1 모듈을 4개의 필터로 설정하여 Sinc3 필터, OSR=128로 동작하며,
//  폴링 방식으로 데이터를 읽습니다. 비교기 설정(Sinc3, OSR=32, HLT=0x7FFF, LLT=0x0000)
//  및 핀맵(SDFM_PIN_MUX_OPTION2, GPIO48~55)을 포함합니다. 시스템 제어 및 디버깅을 위해
//  sysctl.h와 sdfm.h의 정의를 사용하며, 디버깅용 LED(GPIO31)와 상태 변수(sdfmStatus)를 활용합니다.
// C2000Ware 버전: 6.00.00.00
//###########################################################################
// 포함된 파일
#include "driverlib.h"      // C2000 DriverLib의 주요 헤더 파일, 시스템 제어 및 주변 장치 설정
#include "device.h"         // TMS320F28388D 디바이스별 정의(예: 클럭, GPIO 설정)

// 정의
#define MAX_SAMPLES               1024              // 최대 샘플 수 (데이터 저장 배열 크기)
#define SDFM_PIN_MUX_OPTION1      1                // SDFM 핀맵 옵션 1 (GPIO16~31)
#define SDFM_PIN_MUX_OPTION2      2                // SDFM 핀맵 옵션 2 (GPIO48~55, 기본값)
#define SDFM_PIN_MUX_OPTION3      3                // SDFM 핀맵 옵션 3 (GPIO122~137)

// 전역 변수
volatile uint32_t sdfmStatus = 0;                  // SDFM 상태 플래그: 0(초기화 완료), 1(동작 중), 0xFFFF(오류/완료)
volatile int16_t filter1Result[MAX_SAMPLES];        // 필터 1의 출력 데이터를 저장하는 배열 (16비트)
volatile int16_t filter2Result[MAX_SAMPLES];        // 필터 2의 출력 데이터를 저장하는 배열 (16비트)
volatile int16_t filter3Result[MAX_SAMPLES];        // 필터 3의 출력 데이터를 저장하는 배열 (16비트)
volatile int16_t filter4Result[MAX_SAMPLES];        // 필터 4의 출력 데이터를 저장하는 배열 (16비트)

// 데이터 섹션 할당: 메모리 최적화를 위해 각 필터 데이터를 별도의 RAM 섹션에 배치
#pragma DATA_SECTION(filter1Result, "Filter1_RegsFile"); // 필터 1 데이터 -> RAMLS0
#pragma DATA_SECTION(filter2Result, "Filter2_RegsFile"); // 필터 2 데이터 -> RAMLS1
#pragma DATA_SECTION(filter3Result, "Filter3_RegsFile"); // 필터 3 데이터 -> RAMLS2
#pragma DATA_SECTION(filter4Result, "Filter4_RegsFile"); // 필터 4 데이터 -> RAMLS3

// 함수 프로토타입 선언
void configureSDFMPins(uint16_t sdfmPinOption);    // SDFM 핀 설정 함수
void setPinConfig2(void);                          // SDFM 핀맵 옵션 2 설정 함수 (GPIO48~55)

// GPIO 초기화 함수
// 역할: 디버깅용 LED(GPIO31)와 SDFM1 핀(GPIO48~55)을 설정
void initGPIO(void)
{
    EALLOW; // 시스템 레지스터 접근을 위한 보호 해제

    // GPIO48~55를 SDFM1 데이터 및 클럭 입력으로 설정 (SD1_D1, SD1_C1 ~ SD1_D4, SD1_C4)
    // SDFM_PIN_MUX_OPTION2 사용 (GPIO48~55)
    configureSDFMPins(SDFM_PIN_MUX_OPTION2);

    // GPIO31을 디버깅용 LED로 설정 (LAUNCHXL-F28379D 기준, GPIO31은 기본 LED)
    GPIO_setPinConfig(GPIO_31_GPIO31);           // GPIO31을 일반 GPIO로 설정
    GPIO_setDirectionMode(31, GPIO_DIR_MODE_OUT); // 출력 모드로 설정 (LED 제어용)
    GPIO_setPadConfig(31, GPIO_PIN_TYPE_STD);    // 표준 패드 설정 (내부 풀업 비활성화)
    GPIO_setQualificationMode(31, GPIO_QUAL_ASYNC); // 비동기 입력 모드 (지연 없음)
    GPIO_writePin(31, 0);                        // 초기 상태: LED OFF

    EDIS; // 시스템 레지스터 보호 복원
}

// SDFM1 초기화 함수
// 역할: SDFM1 모듈의 4개 필터를 설정 (Sinc3, OSR=128, 16비트 출력, 비교기 포함)
void initSDFM(void)
{
    EALLOW; // 시스템 제어 레지스터 접근을 위한 보호 해제

    // SDFM1 모듈의 클럭 활성화 (sysctl.h의 SysCtl_enablePeripheral 사용)
    // SYSCTL_PERIPH_CLK_SD1: SDFM1 모듈에 클럭 공급
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SD1);
    SYSCTL_REGWRITE_DELAY; // 레지스터 쓰기 안정성을 위한 지연

    // SDFM 타입 설정: 데이터 ACK로 SDINT 생성 (Type 1: 각 필터별 데이터 준비 플래그)
    // 폴링 방식에서 데이터 준비 여부를 확인하기 위해 설정
    SysCtl_configureType(SYSCTL_SDFMTYPE, 0, 1);
    SYSCTL_REGWRITE_DELAY; // 레지스터 쓰기 안정성을 위한 지연

    // 모듈레이터 클럭 설정: 각 필터의 클럭을 데이터 속도와 동일하게 설정
    // SDFM_MODULATOR_CLK_EQUAL_DATA_RATE: 모듈레이터 클럭 = 데이터 속도
    SDFM_setupModulatorClock(SDFM1_BASE, SDFM_FILTER_1, SDFM_MODULATOR_CLK_EQUAL_DATA_RATE);
    SDFM_setupModulatorClock(SDFM1_BASE, SDFM_FILTER_2, SDFM_MODULATOR_CLK_EQUAL_DATA_RATE);
    SDFM_setupModulatorClock(SDFM1_BASE, SDFM_FILTER_3, SDFM_MODULATOR_CLK_EQUAL_DATA_RATE);
    SDFM_setupModulatorClock(SDFM1_BASE, SDFM_FILTER_4, SDFM_MODULATOR_CLK_EQUAL_DATA_RATE);

    // 비교기 설정: Sinc3 필터, OSR=32, 고임계값(HLT)=0x7FFF, 저임계값(LLT)=0x0000
    // 제로 크로스 임계값은 비활성화 (config3=0)
    uint16_t hlt = 0x7FFF, llt = 0x0000; // 고임계값(최대), 저임계값(최소)
    SDFM_configComparator(SDFM1_BASE, 
                         (SDFM_FILTER_1 | SDFM_FILTER_SINC_3 | SDFM_SET_OSR(32)),
                         SDFM_THRESHOLD(hlt, llt), 0); // 필터 1 비교기 설정
    SDFM_configComparator(SDFM1_BASE, 
                         (SDFM_FILTER_2 | SDFM_FILTER_SINC_3 | SDFM_SET_OSR(32)),
                         SDFM_THRESHOLD(hlt, llt), 0); // 필터 2 비교기 설정
    SDFM_configComparator(SDFM1_BASE, 
                         (SDFM_FILTER_3 | SDFM_FILTER_SINC_3 | SDFM_SET_OSR(32)),
                         SDFM_THRESHOLD(hlt, llt), 0); // 필터 3 비교기 설정
    SDFM_configComparator(SDFM1_BASE, 
                         (SDFM_FILTER_4 | SDFM_FILTER_SINC_3 | SDFM_SET_OSR(32)),
                         SDFM_THRESHOLD(hlt, llt), 0); // 필터 4 비교기 설정

    // 데이터 필터 설정: Sinc3 필터, OSR=128, 16비트 출력, 7비트 오른쪽 시프트
    // SDFM_DATA_FORMAT_16_BIT: 출력 데이터 포맷을 16비트로 설정
    // SDFM_FILTER_ENABLE: 필터 활성화
    // SDFM_SHIFT_VALUE(0x0007): 7비트 오른쪽 시프트로 데이터 정렬
    SDFM_configDataFilter(SDFM1_BASE, 
                         (SDFM_FILTER_1 | SDFM_FILTER_SINC_3 | SDFM_SET_OSR(128)),
                         (SDFM_DATA_FORMAT_16_BIT | SDFM_FILTER_ENABLE | SDFM_SHIFT_VALUE(0x0007)));
    SDFM_configDataFilter(SDFM1_BASE, 
                         (SDFM_FILTER_2 | SDFM_FILTER_SINC_3 | SDFM_SET_OSR(128)),
                         (SDFM_DATA_FORMAT_16_BIT | SDFM_FILTER_ENABLE | SDFM_SHIFT_VALUE(0x0007)));
    SDFM_configDataFilter(SDFM1_BASE, 
                         (SDFM_FILTER_3 | SDFM_FILTER_SINC_3 | SDFM_SET_OSR(128)),
                         (SDFM_DATA_FORMAT_16_BIT | SDFM_FILTER_ENABLE | SDFM_SHIFT_VALUE(0x0007)));
    SDFM_configDataFilter(SDFM1_BASE, 
                         (SDFM_FILTER_4 | SDFM_FILTER_SINC_3 | SDFM_SET_OSR(128)),
                         (SDFM_DATA_FORMAT_16_BIT | SDFM_FILTER_ENABLE | SDFM_SHIFT_VALUE(0x0007)));

    // 마스터 필터 활성화: 모든 필터를 동기화하여 동작 시작
    SDFM_enableMainFilter(SDFM1_BASE);

    // 외부 리셋 비활성화: PWM 동기화 신호를 사용하지 않음
    SDFM_disableExternalReset(SDFM1_BASE, SDFM_FILTER_1);
    SDFM_disableExternalReset(SDFM1_BASE, SDFM_FILTER_2);
    SDFM_disableExternalReset(SDFM1_BASE, SDFM_FILTER_3);
    SDFM_disableExternalReset(SDFM1_BASE, SDFM_FILTER_4);

    // 개별 필터 활성화: 각 필터를 개별적으로 활성화 (SDFM_enableModule 대체)
    SDFM_enableFilter(SDFM1_BASE, SDFM_FILTER_1);
    SDFM_enableFilter(SDFM1_BASE, SDFM_FILTER_2);
    SDFM_enableFilter(SDFM1_BASE, SDFM_FILTER_3);
    SDFM_enableFilter(SDFM1_BASE, SDFM_FILTER_4);

    // 상태 업데이트: SDFM 초기화 완료 및 동작 중
    sdfmStatus = 1;

    EDIS; // 시스템 레지스터 보호 복원
}

// SDFM 핀 설정 함수
// 역할: SDFM1 모듈의 데이터 및 클럭 입력 핀을 설정 (기본: OPTION2, GPIO48~55)
void configureSDFMPins(uint16_t sdfmPinOption)
{
    uint16_t pin;
    EALLOW; // GPIO 레지스터 접근을 위한 보호 해제

    switch (sdfmPinOption)
    {
        case SDFM_PIN_MUX_OPTION2: // GPIO48~55 (SD1_D1, SD1_C1 ~ SD1_D4, SD1_C4)
            for (pin = 48; pin <= 55; pin++) // SDFM1 전용 핀 설정
            {
                GPIO_setDirectionMode(pin, GPIO_DIR_MODE_IN); // 입력 모드로 설정
                GPIO_setControllerCore(pin, GPIO_CORE_CPU1);  // CPU1이 GPIO 제어 (sysctl.h)
                GPIO_setPadConfig(pin, GPIO_PIN_TYPE_STD);    // 표준 패드 (풀업 비활성화)
                GPIO_setQualificationMode(pin, GPIO_QUAL_ASYNC); // 비동기 입력 모드
            }
            setPinConfig2(); // OPTION2용 핀맵 설정 호출
            break;
        default: // 지원되지 않는 핀맵 옵션 처리
            sdfmStatus = 0xFFFF; // 오류 상태 설정
            GPIO_writePin(31, 0); // LED OFF
            ESTOP0; // 디버깅용 정지 (CCS에서 중단점 역할)
            break;
    }

    EDIS; // GPIO 레지스터 보호 복원
}

// SDFM_PIN_MUX_OPTION2 핀 설정 함수
// 역할: GPIO48~55를 SDFM1의 데이터 및 클럭 입력으로 설정
void setPinConfig2(void)
{
    EALLOW; // GPIO 레지스터 접근을 위한 보호 해제
    GPIO_setPinConfig(GPIO_48_SD1_D1); // GPIO48: 필터 1 데이터 입력
    GPIO_setPinConfig(GPIO_49_SD1_C1); // GPIO49: 필터 1 클럭 입력
    GPIO_setPinConfig(GPIO_50_SD1_D2); // GPIO50: 필터 2 데이터 입력
    GPIO_setPinConfig(GPIO_51_SD1_C2); // GPIO51: 필터 2 클럭 입력
    GPIO_setPinConfig(GPIO_52_SD1_D3); // GPIO52: 필터 3 데이터 입력
    GPIO_setPinConfig(GPIO_53_SD1_C3); // GPIO53: 필터 3 클럭 입력
    GPIO_setPinConfig(GPIO_54_SD1_D4); // GPIO54: 필터 4 데이터 입력
    GPIO_setPinConfig(GPIO_55_SD1_C4); // GPIO55: 필터 4 클럭 입력
    EDIS; // GPIO 레지스터 보호 복원
}

// 메인 함수
// 역할: 시스템 초기화, SDFM 설정, 폴링 방식으로 데이터 읽기 및 상태 표시
void main(void)
{
    // 시스템 초기화: 시스템 클럭, PLL, 주변 장치 설정 (device.h)
    Device_init();

    // GPIO 초기화: 기본 GPIO 설정 (device.h)
    Device_initGPIO();

    // SDFM 관련 GPIO 설정: SDFM1 핀과 디버깅용 LED 설정
    initGPIO();

    // 인터럽트 모듈 초기화: 폴링 방식이지만 확장성을 위해 포함
    Interrupt_initModule();
    Interrupt_initVectorTable();

    // 시스템 클럭 확인: 200MHz로 설정되어 있는지 확인 (SYSCTL_DEFAULT_OSC_FREQ 기준)
    uint32_t sysClockHz = SysCtl_getClock(SYSCTL_DEFAULT_OSC_FREQ);
    if (sysClockHz != 200000000)
    {
        sdfmStatus = 0xFFFF; // 오류 상태 설정 (클럭 불일치)
        GPIO_writePin(31, 0); // LED OFF
        ESTOP0; // 디버깅용 정지
    }

    // SDFM1 초기화: 4개 필터 설정 및 동작 시작
    initSDFM();

    // 초기화 오류 확인: sdfmStatus가 1이 아니면 오류
    if (sdfmStatus != 1)
    {
        sdfmStatus = 0xFFFF; // 오류 상태 설정
        GPIO_writePin(31, 0); // LED OFF
        ESTOP0; // 디버깅용 정지
    }

    // 데이터 읽기 루프: 폴링 방식으로 SDFM 데이터를 읽고 저장
    static uint16_t loopCounter = 0; // 샘플 카운터 (0~MAX_SAMPLES-1)
    for(;;)
    {
        // 샘플링 제한 확인: MAX_SAMPLES(1024)에 도달하면 종료
        if (loopCounter < MAX_SAMPLES)
        {
            // 모든 필터의 데이터 준비 플래그 확인 (SDFM_getNewFilterDataStatus)
            if (SDFM_getNewFilterDataStatus(SDFM1_BASE, SDFM_FILTER_1) &&
                SDFM_getNewFilterDataStatus(SDFM1_BASE, SDFM_FILTER_2) &&
                SDFM_getNewFilterDataStatus(SDFM1_BASE, SDFM_FILTER_3) &&
                SDFM_getNewFilterDataStatus(SDFM1_BASE, SDFM_FILTER_4))
            {
                // 데이터 읽기: 32비트 데이터의 상위 16비트를 16비트로 변환하여 저장
                // 7비트 시프트는 SDFM_configDataFilter에서 이미 처리됨
                filter1Result[loopCounter] = (int16_t)(SDFM_getFilterData(SDFM1_BASE, SDFM_FILTER_1) >> 16U);
                filter2Result[loopCounter] = (int16_t)(SDFM_getFilterData(SDFM1_BASE, SDFM_FILTER_2) >> 16U);
                filter3Result[loopCounter] = (int16_t)(SDFM_getFilterData(SDFM1_BASE, SDFM_FILTER_3) >> 16U);
                filter4Result[loopCounter++] = (int16_t)(SDFM_getFilterData(SDFM1_BASE, SDFM_FILTER_4) >> 16U);
            }
        }
        else
        {
            // 샘플링 완료: 상태를 오류/완료로 설정하고 정지
            sdfmStatus = 0xFFFF;
            GPIO_writePin(31, 0); // LED OFF
            ESTOP0; // 디버깅용 정지
        }

        // 디버깅용 상태 표시: sdfmStatus=1이면 LED ON, 아니면 OFF
        GPIO_writePin(31, (sdfmStatus == 1) ? 1 : 0);

        // 1초 지연: CPU 부하 감소 및 디버깅용 (실제 애플리케이션에서는 조정 가능)
        DEVICE_DELAY_US(1000000);
    }
}

설명:

  • 기능: SDFM1의 채널 1을 사용하여 Sinc3 필터로 아날로그 데이터를 디지털로 변환.
  • 설정: 20MHz 모듈레이터 클럭, Sinc3 필터, OSR=128.
  • GPIO: GPIO48(SD1_D1), GPIO49(SD1_C1), GPIO31(LED).
  • 출력: 변환된 데이터는 filterData 변수에 저장, 정상 동작 시 LED ON.

4.2. 예제 2: 인터럽트를 사용한 SDFM 데이터 읽기

SDFM1의 데이터 준비 완료 인터럽트를 사용하여 데이터를 읽습니다.

//###########################################################################
// 제목: TMS320F28388D용 SDFM 필터 동기 CPU 읽기 예제 (인터럽트 방식)
// 설명:
//  이 예제는 SDFM1 모듈의 4개 필터를 Sinc3 필터, OSR=128로 설정하여 인터럽트 방식으로
//  데이터를 읽습니다. GPIO48~55(SDFM_PIN_MUX_OPTION2)를 사용하며, 디버깅용 LED(GPIO31)
//  와 상태 변수(sdfmStatus)를 활용합니다. 데이터는 filter1Result~filter4Result 배열에
//  저장되며, 최대 1024 샘플까지 수집합니다. 시스템 제어는 sysctl.h와 driverlib.h를 기반으로
//  하며, C2000Ware 6.00.00.00 버전에 호환되도록 작성되었습니다. 인터럽트는 데이터 준비
//  완료 및 모듈레이터 실패 시 호출되며, 변환된 데이터는 16비트 형식으로 저장됩니다.
// 외부 연결:
//  - SDFM_PIN_MUX_OPTION2: GPIO48~55 (SD1_D1, SD1_C1 ~ SD1_D4, SD1_C4)
// 감시 변수:
//  - filter1Result: 필터 1 출력 데이터
//  - filter2Result: 필터 2 출력 데이터
//  - filter3Result: 필터 3 출력 데이터
//  - filter4Result: 필터 4 출력 데이터
// C2000Ware 버전: 6.00.00.00
//###########################################################################
// 포함된 파일
#include "driverlib.h"      // C2000 DriverLib의 주요 헤더 파일, 시스템 제어 및 주변 장치 설정
#include "device.h"         // TMS320F28388D 디바이스별 정의(예: 클럭, GPIO 설정)

// 정의
#define MAX_SAMPLES               1024              // 최대 샘플 수 (데이터 저장 배열 크기)
#define SDFM_PIN_MUX_OPTION1      1                // SDFM 핀맵 옵션 1 (GPIO16~31)
#define SDFM_PIN_MUX_OPTION2      2                // SDFM 핀맵 옵션 2 (GPIO48~55, 기본값)
#define SDFM_PIN_MUX_OPTION3      3                // SDFM 핀맵 옵션 3 (GPIO122~137)

// 전역 변수
volatile uint32_t sdfmStatus = 0;                  // SDFM 상태 플래그: 0(초기화 완료), 1(동작 중), 0xFFFF(오류/완료)
volatile int16_t filter1Result[MAX_SAMPLES];        // 필터 1 출력 데이터를 저장하는 배열 (16비트)
volatile int16_t filter2Result[MAX_SAMPLES];        // 필터 2 출력 데이터를 저장하는 배열 (16비트)
volatile int16_t filter3Result[MAX_SAMPLES];        // 필터 3 출력 데이터를 저장하는 배열 (16비트)
volatile int16_t filter4Result[MAX_SAMPLES];        // 필터 4 출력 데이터를 저장하는 배열 (16비트)

// 데이터 섹션 할당: 메모리 최적화를 위해 각 필터 데이터를 별도의 RAM 섹션에 배치
#pragma DATA_SECTION(filter1Result, "Filter1_RegsFile"); // 필터 1 데이터 -> RAMLS0
#pragma DATA_SECTION(filter2Result, "Filter2_RegsFile"); // 필터 2 데이터 -> RAMLS1
#pragma DATA_SECTION(filter3Result, "Filter3_RegsFile"); // 필터 3 데이터 -> RAMLS2
#pragma DATA_SECTION(filter4Result, "Filter4_RegsFile"); // 필터 4 데이터 -> RAMLS3

// 함수 프로토타입 선언
void configureSDFMPins(uint16_t sdfmPinOption);    // SDFM 핀 설정 함수
void setPinConfig2(void);                          // SDFM 핀맵 옵션 2 설정 함수 (GPIO48~55)
__interrupt void sdfm1ISR(void);                   // SDFM1 인터럽트 서비스 루틴

// GPIO 초기화 함수
// 역할: SDFM1의 데이터 및 클럭 입력 핀(GPIO48~55)과 디버깅용 LED(GPIO31)를 설정
void initGPIO(void)
{
    EALLOW; // 시스템 레지스터 접근을 위한 보호 해제

    // SDFM1 핀 설정: SDFM_PIN_MUX_OPTION2 (GPIO48~55)
    configureSDFMPins(SDFM_PIN_MUX_OPTION2);

    // GPIO31을 디버깅용 LED로 설정
    // 정상 동작 시 LED ON, 오류 시 LED OFF
    GPIO_setPinConfig(GPIO_31_GPIO31);           // GPIO31을 일반 GPIO로 설정
    GPIO_setDirectionMode(31, GPIO_DIR_MODE_OUT); // 출력 모드로 설정 (LED 제어용)
    GPIO_setPadConfig(31, GPIO_PIN_TYPE_PULLUP); // 내부 풀업 저항 활성화
    GPIO_setQualificationMode(31, GPIO_QUAL_ASYNC); // 비동기 입력 모드 (지연 없음)
    GPIO_writePin(31, 0);                        // 초기 상태: LED OFF

    EDIS; // 시스템 레지스터 보호 복원
}

// SDFM1 인터럽트 서비스 루틴 (ISR)
// 역할: 데이터 준비 완료 또는 모듈레이터 실패 인터럽트 발생 시 데이터를 읽고 상태 업데이트
__interrupt void sdfm1ISR(void)
{
    static uint16_t loopCounter = 0; // 샘플 카운터 (0~MAX_SAMPLES-1)
    volatile uint32_t sdfmReadFlagRegister = 0; // SDFM 플래그 레지스터 값 저장

    // 데이터 포맷 설정: 16비트 출력 포맷으로 설정 (ISR에서 명시적 설정)
    SDFM_setOutputDataFormat(SDFM1_BASE, SDFM_FILTER_1, SDFM_DATA_FORMAT_16_BIT);
    SDFM_setOutputDataFormat(SDFM1_BASE, SDFM_FILTER_2, SDFM_DATA_FORMAT_16_BIT);
    SDFM_setOutputDataFormat(SDFM1_BASE, SDFM_FILTER_3, SDFM_DATA_FORMAT_16_BIT);
    SDFM_setOutputDataFormat(SDFM1_BASE, SDFM_FILTER_4, SDFM_DATA_FORMAT_16_BIT);

    // SDFM 플래그 레지스터 읽기: SDIFLG 레지스터 상태 확인
    sdfmReadFlagRegister = HWREG(SDFM1_BASE + SDFM_O_SDIFLG);

    // 샘플링 제한 확인: MAX_SAMPLES(1024)에 도달하지 않은 경우 데이터 읽기
    if (loopCounter < MAX_SAMPLES)
    {
        // 각 필터 데이터 읽기: 32비트 데이터의 상위 16비트를 16비트로 변환하여 저장
        // 7비트 시프트는 SDFM_configDataFilter에서 이미 처리됨
        filter1Result[loopCounter] = (int16_t)(SDFM_getFilterData(SDFM1_BASE, SDFM_FILTER_1) >> 16U);
        filter2Result[loopCounter] = (int16_t)(SDFM_getFilterData(SDFM1_BASE, SDFM_FILTER_2) >> 16U);
        filter3Result[loopCounter] = (int16_t)(SDFM_getFilterData(SDFM1_BASE, SDFM_FILTER_3) >> 16U);
        filter4Result[loopCounter++] = (int16_t)(SDFM_getFilterData(SDFM1_BASE, SDFM_FILTER_4) >> 16U);

        // 인터럽트 플래그 지우기: 메인 인터럽트 및 필터별 플래그 초기화
        SDFM_clearInterruptFlag(SDFM1_BASE, SDFM_MAIN_INTERRUPT_FLAG | 0xFFFF);

        // 플래그 레지스터 재확인: 플래그가 제대로 지워졌는지 확인
        sdfmReadFlagRegister = HWREG(SDFM1_BASE + SDFM_O_SDIFLG);
        if (sdfmReadFlagRegister != 0x0)
        {
            sdfmStatus = 0xFFFF; // 플래그 지우기 실패 시 오류 상태 설정
            GPIO_writePin(31, 0); // LED OFF
            ESTOP0; // 디버깅용 정지
        }

        // 상태 업데이트: SDFM 동작 중
        sdfmStatus = 1;
    }
    else
    {
        // 샘플링 완료: 상태를 오류/완료로 설정하고 정지
        sdfmStatus = 0xFFFF;
        GPIO_writePin(31, 0); // LED OFF
        ESTOP0; // 디버깅용 정지
    }

    // 인터럽트 그룹 ACK: 그룹 5(SDFM1) 인터럽트 처리 완료 신호
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP5);
}

// SDFM1 초기화 함수
// 역할: SDFM1 모듈의 4개 필터를 설정 (Sinc3, OSR=128, 인터럽트 방식)
void initSDFM(void)
{
    EALLOW; // 시스템 제어 레지스터 접근을 위한 보호 해제

    // SDFM1 모듈의 클럭 활성화
    // SYSCTL_PERIPH_CLK_SD1을 통해 SDFM1에 시스템 클럭 공급
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SD1);
    SYSCTL_REGWRITE_DELAY; // 레지스터 쓰기 안정성을 위한 지연

    // SDFM 타입 설정: 데이터 ACK로 SDINT 생성 (Type 1: 인터럽트용 플래그)
    // 인터럽트 방식에서 데이터 준비 플래그를 사용하도록 설정
    SysCtl_configureType(SYSCTL_SDFMTYPE, 0, 1);
    SYSCTL_REGWRITE_DELAY; // 레지스터 쓰기 안정성을 위한 지연

    // 모듈레이터 클럭 설정: 각 필터의 클럭을 데이터 속도와 동일하게 설정
    // SDFM_MODULATOR_CLK_EQUAL_DATA_RATE: 모듈레이터 클럭 = 데이터 속도
    SDFM_setupModulatorClock(SDFM1_BASE, SDFM_FILTER_1, SDFM_MODULATOR_CLK_EQUAL_DATA_RATE);
    SDFM_setupModulatorClock(SDFM1_BASE, SDFM_FILTER_2, SDFM_MODULATOR_CLK_EQUAL_DATA_RATE);
    SDFM_setupModulatorClock(SDFM1_BASE, SDFM_FILTER_3, SDFM_MODULATOR_CLK_EQUAL_DATA_RATE);
    SDFM_setupModulatorClock(SDFM1_BASE, SDFM_FILTER_4, SDFM_MODULATOR_CLK_EQUAL_DATA_RATE);

    // 비교기 설정: Sinc3 필터, OSR=32, 고임계값(HLT)=0x7FFF, 저임계값(LLT)=0x0000
    // 제로 크로스 임계값은 비활성화 (config3=0)
    uint16_t hlt = 0x7FFF, llt = 0x0000; // 고임계값(최대), 저임계값(최소)
    SDFM_configComparator(SDFM1_BASE,
                         (SDFM_FILTER_1 | SDFM_FILTER_SINC_3 | SDFM_SET_OSR(32)),
                         SDFM_THRESHOLD(hlt, llt), 0); // 필터 1 비교기 설정
    SDFM_configComparator(SDFM1_BASE,
                         (SDFM_FILTER_2 | SDFM_FILTER_SINC_3 | SDFM_SET_OSR(32)),
                         SDFM_THRESHOLD(hlt, llt), 0); // 필터 2 비교기 설정
    SDFM_configComparator(SDFM1_BASE,
                         (SDFM_FILTER_3 | SDFM_FILTER_SINC_3 | SDFM_SET_OSR(32)),
                         SDFM_THRESHOLD(hlt, llt), 0); // 필터 3 비교기 설정
    SDFM_configComparator(SDFM1_BASE,
                         (SDFM_FILTER_4 | SDFM_FILTER_SINC_3 | SDFM_SET_OSR(32)),
                         SDFM_THRESHOLD(hlt, llt), 0); // 필터 4 비교기 설정

    // 데이터 필터 설정: Sinc3 필터, OSR=128, 16비트 출력, 7비트 오른쪽 시프트
    // SDFM_DATA_FORMAT_16_BIT: 출력 데이터를 16비트로 변환 (상위 16비트 사용)
    // SDFM_FILTER_ENABLE: 필터 활성화
    // SDFM_SHIFT_VALUE(0x0007): 데이터 정렬을 위해 7비트 오른쪽 시프트
    SDFM_configDataFilter(SDFM1_BASE,
                         (SDFM_FILTER_1 | SDFM_FILTER_SINC_3 | SDFM_SET_OSR(128)),
                         (SDFM_DATA_FORMAT_16_BIT | SDFM_FILTER_ENABLE | SDFM_SHIFT_VALUE(0x0007)));
    SDFM_configDataFilter(SDFM1_BASE,
                         (SDFM_FILTER_2 | SDFM_FILTER_SINC_3 | SDFM_SET_OSR(128)),
                         (SDFM_DATA_FORMAT_16_BIT | SDFM_FILTER_ENABLE | SDFM_SHIFT_VALUE(0x0007)));
    SDFM_configDataFilter(SDFM1_BASE,
                         (SDFM_FILTER_3 | SDFM_FILTER_SINC_3 | SDFM_SET_OSR(128)),
                         (SDFM_DATA_FORMAT_16_BIT | SDFM_FILTER_ENABLE | SDFM_SHIFT_VALUE(0x0007)));
    SDFM_configDataFilter(SDFM1_BASE,
                         (SDFM_FILTER_4 | SDFM_FILTER_SINC_3 | SDFM_SET_OSR(128)),
                         (SDFM_DATA_FORMAT_16_BIT | SDFM_FILTER_ENABLE | SDFM_SHIFT_VALUE(0x0007)));

    // 마스터 필터 활성화: 모든 필터를 동기화하여 동작 시작
    SDFM_enableMainFilter(SDFM1_BASE);

    // 외부 리셋 비활성화: PWM 동기화 신호 사용 안 함
    SDFM_disableExternalReset(SDFM1_BASE, SDFM_FILTER_1);
    SDFM_disableExternalReset(SDFM1_BASE, SDFM_FILTER_2);
    SDFM_disableExternalReset(SDFM1_BASE, SDFM_FILTER_3);
    SDFM_disableExternalReset(SDFM1_BASE, SDFM_FILTER_4);

    // 인터럽트 설정: 데이터 준비 완료 및 모듈레이터 실패 인터럽트 활성화
    // SDFM_MODULATOR_FAILURE_INTERRUPT: 모듈레이터 클럭 오류 감지
    // SDFM_DATA_FILTER_ACKNOWLEDGE_INTERRUPT: 데이터 준비 완료 시 인터럽트
    SDFM_enableInterrupt(SDFM1_BASE, SDFM_FILTER_1,
                         (SDFM_MODULATOR_FAILURE_INTERRUPT | SDFM_DATA_FILTER_ACKNOWLEDGE_INTERRUPT));
    SDFM_enableInterrupt(SDFM1_BASE, SDFM_FILTER_2,
                         (SDFM_MODULATOR_FAILURE_INTERRUPT | SDFM_DATA_FILTER_ACKNOWLEDGE_INTERRUPT));
    SDFM_enableInterrupt(SDFM1_BASE, SDFM_FILTER_3,
                         (SDFM_MODULATOR_FAILURE_INTERRUPT | SDFM_DATA_FILTER_ACKNOWLEDGE_INTERRUPT));
    SDFM_enableInterrupt(SDFM1_BASE, SDFM_FILTER_4,
                         (SDFM_MODULATOR_FAILURE_INTERRUPT | SDFM_DATA_FILTER_ACKNOWLEDGE_INTERRUPT));

    // 비교기 임계값 인터럽트 비활성화: HLT/LLT 인터럽트 사용 안 함
    SDFM_disableInterrupt(SDFM1_BASE, SDFM_FILTER_1,
                         (SDFM_HIGH_LEVEL_THRESHOLD_INTERRUPT | SDFM_LOW_LEVEL_THRESHOLD_INTERRUPT));
    SDFM_disableInterrupt(SDFM1_BASE, SDFM_FILTER_2,
                         (SDFM_HIGH_LEVEL_THRESHOLD_INTERRUPT | SDFM_LOW_LEVEL_THRESHOLD_INTERRUPT));
    SDFM_disableInterrupt(SDFM1_BASE, SDFM_FILTER_3,
                         (SDFM_HIGH_LEVEL_THRESHOLD_INTERRUPT | SDFM_LOW_LEVEL_THRESHOLD_INTERRUPT));
    SDFM_disableInterrupt(SDFM1_BASE, SDFM_FILTER_4,
                         (SDFM_HIGH_LEVEL_THRESHOLD_INTERRUPT | SDFM_LOW_LEVEL_THRESHOLD_INTERRUPT));

    // 마스터 인터럽트 활성화: 필터 인터럽트를 CPU로 전달
    SDFM_enableMainInterrupt(SDFM1_BASE);

    // 개별 필터 활성화: 각 필터를 명시적으로 활성화
    SDFM_enableFilter(SDFM1_BASE, SDFM_FILTER_1);
    SDFM_enableFilter(SDFM1_BASE, SDFM_FILTER_2);
    SDFM_enableFilter(SDFM1_BASE, SDFM_FILTER_3);
    SDFM_enableFilter(SDFM1_BASE, SDFM_FILTER_4);

    // 상태 업데이트: SDFM 초기화 완료 및 동작 중
    sdfmStatus = 1;

    EDIS; // 시스템 레지스터 보호 복원
}

// SDFM 핀 설정 함수
// 역할: SDFM1 모듈의 데이터 및 클럭 입력 핀을 설정 (기본: OPTION2, GPIO48~55)
void configureSDFMPins(uint16_t sdfmPinOption)
{
    uint16_t pin;
    EALLOW; // GPIO 레지스터 접근을 위한 보호 해제

    switch (sdfmPinOption)
    {
        case SDFM_PIN_MUX_OPTION2: // GPIO48~55 (SD1_D1, SD1_C1 ~ SD1_D4, SD1_C4)
            for (pin = 48; pin <= 55; pin++) // SDFM1 전용 핀 설정
            {
                GPIO_setDirectionMode(pin, GPIO_DIR_MODE_IN); // 입력 모드로 설정
                GPIO_setControllerCore(pin, GPIO_CORE_CPU1);  // CPU1이 GPIO 제어 (sysctl.h)
                GPIO_setPadConfig(pin, GPIO_PIN_TYPE_STD);    // 표준 패드 (풀업 비활성화)
                GPIO_setQualificationMode(pin, GPIO_QUAL_ASYNC); // 비동기 입력 모드
            }
            setPinConfig2(); // OPTION2용 핀맵 설정 호출
            break;
        default: // 지원되지 않는 핀맵 옵션 처리
            sdfmStatus = 0xFFFF; // 오류 상태 설정
            GPIO_writePin(31, 0); // LED OFF
            ESTOP0; // 디버깅용 정지
            break;
    }

    EDIS; // GPIO 레지스터 보호 복원
}

// SDFM_PIN_MUX_OPTION2 핀 설정 함수
// 역할: GPIO48~55를 SDFM1의 데이터 및 클럭 입력으로 설정
void setPinConfig2(void)
{
    EALLOW; // GPIO 레지스터 접근을 위한 보호 해제
    GPIO_setPinConfig(GPIO_48_SD1_D1); // GPIO48: 필터 1 데이터 입력
    GPIO_setPinConfig(GPIO_49_SD1_C1); // GPIO49: 필터 1 클럭 입력
    GPIO_setPinConfig(GPIO_50_SD1_D2); // GPIO50: 필터 2 데이터 입력
    GPIO_setPinConfig(GPIO_51_SD1_C2); // GPIO51: 필터 2 클럭 입력
    GPIO_setPinConfig(GPIO_52_SD1_D3); // GPIO52: 필터 3 데이터 입력
    GPIO_setPinConfig(GPIO_53_SD1_C3); // GPIO53: 필터 3 클럭 입력
    GPIO_setPinConfig(GPIO_54_SD1_D4); // GPIO54: 필터 4 데이터 입력
    GPIO_setPinConfig(GPIO_55_SD1_C4); // GPIO55: 필터 4 클럭 입력
    EDIS; // GPIO 레지스터 보호 복원
}

// 메인 함수
// 역할: 시스템 초기화, SDFM 설정, 인터럽트 활성화, 상태 표시
void main(void)
{
    // 시스템 초기화: 시스템 클럭, PLL, 주변 장치 설정
    Device_init();

    // GPIO 초기화: 기본 GPIO 설정 (device.h)
    Device_initGPIO();

    // SDFM 관련 GPIO 설정: GPIO48~55(SDFM1) 및 LED(GPIO31)
    initGPIO();

    // 인터럽트 모듈 초기화: 인터럽트 벡터 테이블과 컨트롤러 설정
    Interrupt_initModule();
    Interrupt_initVectorTable();

    // SDFM1 인터럽트 ISR 등록
    // INT_SDFM1에 sdfm1ISR 함수 연결 (SDFM 필터 데이터 준비 및 모듈레이터 실패)
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP5);
    Interrupt_register(INT_SDFM1, &sdfm1ISR);
    Interrupt_enable(INT_SDFM1);

    // 시스템 클럭 확인: 200MHz로 설정되어 있는지 확인
    // SYSCTL_DEFAULT_OSC_FREQ(10MHz)를 기준으로 계산
    uint32_t sysClockHz = SysCtl_getClock(SYSCTL_DEFAULT_OSC_FREQ);
    if (sysClockHz != 200000000)
    {
        sdfmStatus = 0xFFFF;      // 오류 상태 설정 (클럭 불일치)
        GPIO_writePin(31, 0);     // LED OFF로 오류 표시
        ESTOP0;                   // 디버깅용 정지
    }

    // SDFM1 모듈 초기화: 4개 필터 설정 및 인터럽트 활성화
    initSDFM();

    // 초기화 오류 확인: sdfmStatus가 1이 아니면 오류 처리
    if (sdfmStatus != 1)
    {
        sdfmStatus = 0xFFFF;      // 오류 상태 설정
        GPIO_writePin(31, 0);     // LED OFF로 오류 표시
        ESTOP0;                   // 디버깅용 정지
    }

    // 글로벌 인터럽트 활성화: SDFM1 인터럽트 처리 시작
    EINT;
    ERTM; // 실시간 디버깅 인터럽트 활성화

    // 무한 루프: 인터럽트 대기 및 상태 표시
    for(;;)
    {
        // 디버깅용 상태 표시: sdfmStatus=1이면 LED ON, 아니면 OFF
        GPIO_writePin(31, (sdfmStatus == 1) ? 1 : 0);
        DEVICE_DELAY_US(1000000); // 1초 지연 (CPU 부하 감소 및 디버깅용)
    }
}

설명:

  • 기능: SDFM1의 데이터 준비 완료 인터럽트를 사용하여 변환된 데이터를 읽음.
  • 설정: 20MHz 모듈레이터 클럭, Sinc3 필터, OSR=128, 데이터 준비 완료 인터럽트 활성화.
  • GPIO: GPIO48(SD1_D1), GPIO49(SD1_C1), GPIO31(LED).
  • 결과: 변환된 데이터는 ISR에서 filterData 변수에 저장, 정상 동작 시 LED ON.

4.3. 예제 3: 다중 채널 SDFM 설정

SDFM1의 채널 1과 2를 동시에 사용하여 데이터를 읽습니다.

//###########################################################################
// 제목: TMS320F28388D용 SDFM 필터 동기 CPU 읽기 예제 (인터럽트 방식)
// 설명:
//  이 예제는 SDFM1 모듈의 2개 채널(필터 1: Sinc3, OSR=128; 필터 2: Sinc2, OSR=64)을
//  설정하여 인터럽트 방식으로 데이터를 읽습니다. GPIO48~51(SDFM_PIN_MUX_OPTION2)을 사용하며,
//  디버깅용 LED(GPIO31)와 상태 변수(sdfmStatus)를 활용합니다. 데이터는 filterData1,
//  filterData2 변수에 저장됩니다. 시스템 제어는 sysctl.h와 driverlib.h를 기반으로 하며,
//  C2000Ware 6.00.00.00 버전에 호환되도록 작성되었습니다. 인터럽트는 데이터 준비 완료 및
//  모듈레이터 실패 시 호출되며, 변환된 데이터는 32비트 형식으로 저장됩니다.
// 외부 연결:
//  - SDFM_PIN_MUX_OPTION2: GPIO48~51 (SD1_D1, SD1_C1, SD1_D2, SD1_C2)
// 감시 변수:
//  - filterData1: 필터 1 출력 데이터
//  - filterData2: 필터 2 출력 데이터
// C2000Ware 버전: 6.00.00.00
//###########################################################################
// 포함된 파일
#include "driverlib.h"      // C2000 DriverLib의 주요 헤더 파일, 시스템 제어 및 주변 장치 설정
#include "device.h"         // TMS320F28388D 디바이스별 정의(예: 클럭, GPIO 설정)

// 정의
#define SDFM_PIN_MUX_OPTION2      2                // SDFM 핀맵 옵션 2 (GPIO48~51, 기본값)

// 전역 변수
volatile uint32_t sdfmStatus = 0;                  // SDFM 상태 플래그: 0(초기화 완료), 1(동작 중), 0xFFFF(오류)
volatile int32_t filterData1 = 0;                  // 필터 1 출력 데이터를 저장하는 변수 (32비트)
volatile int32_t filterData2 = 0;                  // 필터 2 출력 데이터를 저장하는 변수 (32비트)

// 함수 프로토타입 선언
void configureSDFMPins(uint16_t sdfmPinOption);    // SDFM 핀 설정 함수
void setPinConfig2(void);                          // SDFM 핀맵 옵션 2 설정 함수 (GPIO48~51)
__interrupt void sdfm1ISR(void);                   // SDFM1 인터럽트 서비스 루틴

// GPIO 초기화 함수
// 역할: SDFM1의 데이터 및 클럭 입력 핀(GPIO48~51)과 디버깅용 LED(GPIO31)를 설정
void initGPIO(void)
{
    EALLOW; // 시스템 레지스터 접근을 위한 보호 해제

    // SDFM1 핀 설정: SDFM_PIN_MUX_OPTION2 (GPIO48~51)
    configureSDFMPins(SDFM_PIN_MUX_OPTION2);

    // GPIO31을 디버깅용 LED로 설정
    // 정상 동작 시 LED ON, 오류 시 LED OFF
    GPIO_setPinConfig(GPIO_31_GPIO31);           // GPIO31을 일반 GPIO로 설정
    GPIO_setDirectionMode(31, GPIO_DIR_MODE_OUT); // 출력 모드로 설정 (LED 제어용)
    GPIO_setPadConfig(31, GPIO_PIN_TYPE_PULLUP); // 내부 풀업 저항 활성화
    GPIO_setQualificationMode(31, GPIO_QUAL_ASYNC); // 비동기 입력 모드 (지연 없음)
    GPIO_writePin(31, 0);                        // 초기 상태: LED OFF

    EDIS; // 시스템 레지스터 보호 복원
}

// SDFM1 인터럽트 서비스 루틴 (ISR)
// 역할: 데이터 준비 완료 또는 모듈레이터 실패 인터럽트 발생 시 데이터를 읽고 상태 업데이트
__interrupt void sdfm1ISR(void)
{
    volatile uint32_t sdfmReadFlagRegister = 0; // SDFM 플래그 레지스터 값 저장

    // 데이터 포맷 설정: 32비트 출력 포맷으로 설정 (필터 데이터는 32비트로 읽음)
    SDFM_setOutputDataFormat(SDFM1_BASE, SDFM_FILTER_1, SDFM_DATA_FORMAT_32_BIT);
    SDFM_setOutputDataFormat(SDFM1_BASE, SDFM_FILTER_2, SDFM_DATA_FORMAT_32_BIT);

    // SDFM 플래그 레지스터 읽기: SDIFLG 레지스터 상태 확인
    sdfmReadFlagRegister = HWREG(SDFM1_BASE + SDFM_O_SDIFLG);

    // 필터 데이터 읽기: 각 필터의 데이터를 32비트로 저장
    filterData1 = SDFM_getFilterData(SDFM1_BASE, SDFM_FILTER_1);
    filterData2 = SDFM_getFilterData(SDFM1_BASE, SDFM_FILTER_2);

    // 인터럽트 플래그 지우기: 메인 인터럽트 및 필터별 플래그 초기화
    SDFM_clearInterruptFlag(SDFM1_BASE, SDFM_MAIN_INTERRUPT_FLAG | 0xFFFF);

    // 플래그 레지스터 재확인: 플래그가 제대로 지워졌는지 확인
    sdfmReadFlagRegister = HWREG(SDFM1_BASE + SDFM_O_SDIFLG);
    if (sdfmReadFlagRegister != 0x0)
    {
        sdfmStatus = 0xFFFF; // 플래그 지우기 실패 시 오류 상태 설정
        GPIO_writePin(31, 0); // LED OFF
        ESTOP0; // 디버깅용 정지
    }

    // 상태 업데이트: SDFM 동작 중
    sdfmStatus = 1;

    // 인터럽트 그룹 ACK: 그룹 5(SDFM1) 인터럽트 처리 완료 신호
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP5);
}

// SDFM1 초기화 함수
// 역할: SDFM1 모듈의 2개 필터를 설정 (필터 1: Sinc3, OSR=128; 필터 2: Sinc2, OSR=64)
void initSDFM(void)
{
    EALLOW; // 시스템 제어 레지스터 접근을 위한 보호 해제

    // SDFM1 모듈의 클럭 활성화
    // SYSCTL_PERIPH_CLK_SD1을 통해 SDFM1에 시스템 클럭 공급
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SD1);
    SYSCTL_REGWRITE_DELAY; // 레지스터 쓰기 안정성을 위한 지연

    // SDFM 타입 설정: 데이터 ACK로 SDINT 생성 (Type 1: 인터럽트용 플래그)
    // 인터럽트 방식에서 데이터 준비 플래그를 사용하도록 설정
    SysCtl_configureType(SYSCTL_SDFMTYPE, 0, 1);
    SYSCTL_REGWRITE_DELAY; // 레지스터 쓰기 안정성을 위한 지연

    // 모듈레이터 클럭 설정: 각 필터의 클럭을 데이터 속도와 동일하게 설정
    // SDFM_MODULATOR_CLK_EQUAL_DATA_RATE: 모듈레이터 클럭 = 데이터 속도
    SDFM_setupModulatorClock(SDFM1_BASE, SDFM_FILTER_1, SDFM_MODULATOR_CLK_EQUAL_DATA_RATE);
    SDFM_setupModulatorClock(SDFM1_BASE, SDFM_FILTER_2, SDFM_MODULATOR_CLK_EQUAL_DATA_RATE);

    // 데이터 필터 설정
    // 필터 1: Sinc3, OSR=128, 32비트 출력, 고해상도 변환에 적합
    SDFM_configDataFilter(SDFM1_BASE, 
                         (SDFM_FILTER_1 | SDFM_FILTER_SINC_3 | SDFM_SET_OSR(128)),
                         (SDFM_DATA_FORMAT_32_BIT | SDFM_FILTER_ENABLE));
    // 필터 2: Sinc2, OSR=64, 32비트 출력, 빠른 응답에 적합
    SDFM_configDataFilter(SDFM1_BASE, 
                         (SDFM_FILTER_2 | SDFM_FILTER_SINC_2 | SDFM_SET_OSR(64)),
                         (SDFM_DATA_FORMAT_32_BIT | SDFM_FILTER_ENABLE));

    // 마스터 필터 활성화: 모든 필터를 동기화하여 동작 시작
    SDFM_enableMainFilter(SDFM1_BASE);

    // 외부 리셋 비활성화: PWM 동기화 신호 사용 안 함
    SDFM_disableExternalReset(SDFM1_BASE, SDFM_FILTER_1);
    SDFM_disableExternalReset(SDFM1_BASE, SDFM_FILTER_2);

    // 인터럽트 설정: 데이터 준비 완료 및 모듈레이터 실패 인터럽트 활성화
    // SDFM_MODULATOR_FAILURE_INTERRUPT: 모듈레이터 클럭 오류 감지
    // SDFM_DATA_FILTER_ACKNOWLEDGE_INTERRUPT: 데이터 준비 완료 시 인터럽트
    SDFM_enableInterrupt(SDFM1_BASE, SDFM_FILTER_1, 
                         (SDFM_MODULATOR_FAILURE_INTERRUPT | SDFM_DATA_FILTER_ACKNOWLEDGE_INTERRUPT));
    SDFM_enableInterrupt(SDFM1_BASE, SDFM_FILTER_2, 
                         (SDFM_MODULATOR_FAILURE_INTERRUPT | SDFM_DATA_FILTER_ACKNOWLEDGE_INTERRUPT));

    // 비교기 임계값 인터럽트 비활성화: HLT/LLT 인터럽트 사용 안 함
    SDFM_disableInterrupt(SDFM1_BASE, SDFM_FILTER_1, 
                         (SDFM_HIGH_LEVEL_THRESHOLD_INTERRUPT | SDFM_LOW_LEVEL_THRESHOLD_INTERRUPT));
    SDFM_disableInterrupt(SDFM1_BASE, SDFM_FILTER_2, 
                         (SDFM_HIGH_LEVEL_THRESHOLD_INTERRUPT | SDFM_LOW_LEVEL_THRESHOLD_INTERRUPT));

    // 마스터 인터럽트 활성화: 필터 인터럽트를 CPU로 전달
    SDFM_enableMainInterrupt(SDFM1_BASE);

    // 개별 필터 활성화: 각 필터를 명시적으로 활성화
    SDFM_enableFilter(SDFM1_BASE, SDFM_FILTER_1);
    SDFM_enableFilter(SDFM1_BASE, SDFM_FILTER_2);

    // 상태 업데이트: SDFM 초기화 완료 및 동작 중
    sdfmStatus = 1;

    EDIS; // 시스템 레지스터 보호 복원
}

// SDFM 핀 설정 함수
// 역할: SDFM1 모듈의 데이터 및 클럭 입력 핀을 설정 (기본: OPTION2, GPIO48~51)
void configureSDFMPins(uint16_t sdfmPinOption)
{
    uint16_t pin;
    EALLOW; // GPIO 레지스터 접근을 위한 보호 해제

    switch (sdfmPinOption)
    {
        case SDFM_PIN_MUX_OPTION2: // GPIO48~51 (SD1_D1, SD1_C1, SD1_D2, SD1_C2)
            for (pin = 48; pin <= 51; pin++) // SDFM1 전용 핀 설정
            {
                GPIO_setDirectionMode(pin, GPIO_DIR_MODE_IN); // 입력 모드로 설정
                GPIO_setControllerCore(pin, GPIO_CORE_CPU1);  // CPU1이 GPIO 제어 (sysctl.h)
                GPIO_setPadConfig(pin, GPIO_PIN_TYPE_PULLUP); // 내부 풀업 저항 활성화
                GPIO_setQualificationMode(pin, GPIO_QUAL_ASYNC); // 비동기 입력 모드
            }
            setPinConfig2(); // OPTION2용 핀맵 설정 호출
            break;
        default: // 지원되지 않는 핀맵 옵션 처리
            sdfmStatus = 0xFFFF; // 오류 상태 설정
            GPIO_writePin(31, 0); // LED OFF
            ESTOP0; // 디버깅용 정지
            break;
    }

    EDIS; // GPIO 레지스터 보호 복원
}

// SDFM_PIN_MUX_OPTION2 핀 설정 함수
// 역할: GPIO48~51를 SDFM1의 데이터 및 클럭 입력으로 설정
void setPinConfig2(void)
{
    EALLOW; // GPIO 레지스터 접근을 위한 보호 해제
    GPIO_setPinConfig(GPIO_48_SD1_D1); // GPIO48: 필터 1 데이터 입력
    GPIO_setPinConfig(GPIO_49_SD1_C1); // GPIO49: 필터 1 클럭 입력
    GPIO_setPinConfig(GPIO_50_SD1_D2); // GPIO50: 필터 2 데이터 입력
    GPIO_setPinConfig(GPIO_51_SD1_C2); // GPIO51: 필터 2 클럭 입력
    EDIS; // GPIO 레지스터 보호 복원
}

// 메인 함수
// 역할: 시스템 초기화, SDFM 설정, 인터럽트 활성화, 상태 표시
void main(void)
{
    // 시스템 초기화: 시스템 클럭, PLL, 주변 장치 설정
    Device_init();

    // GPIO 초기화: 기본 GPIO 설정 (device.h)
    Device_initGPIO();

    // SDFM 관련 GPIO 설정: GPIO48~51(SDFM1) 및 LED(GPIO31)
    initGPIO();

    // 인터럽트 모듈 초기화: 인터럽트 벡터 테이블과 컨트롤러 설정
    Interrupt_initModule();
    Interrupt_initVectorTable();

    // SDFM1 인터럽트 ISR 등록
    // INT_SDFM1에 sdfm1ISR 함수 연결 (SDFM 필터 데이터 준비 및 모듈레이터 실패)
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP5);
    Interrupt_register(INT_SDFM1, &sdfm1ISR);
    Interrupt_enable(INT_SDFM1);

    // 시스템 클럭 확인: 200MHz로 설정되어 있는지 확인
    // SYSCTL_DEFAULT_OSC_FREQ(10MHz)를 기준으로 계산
    uint32_t sysClockHz = SysCtl_getClock(SYSCTL_DEFAULT_OSC_FREQ);
    if (sysClockHz != 200000000)
    {
        sdfmStatus = 0xFFFF;      // 오류 상태 설정 (클럭 불일치)
        GPIO_writePin(31, 0);     // LED OFF로 오류 표시
        ESTOP0;                   // 디버깅용 정지
    }

    // SDFM1 모듈 초기화: 2개 필터 설정 및 인터럽트 활성화
    initSDFM();

    // 초기화 오류 확인: sdfmStatus가 1이 아니면 오류 처리
    if (sdfmStatus != 1)
    {
        sdfmStatus = 0xFFFF;      // 오류 상태 설정
        GPIO_writePin(31, 0);     // LED OFF로 오류 표시
        ESTOP0;                   // 디버깅용 정지
    }

    // 글로벌 인터럽트 활성화: SDFM1 인터럽트 처리 시작
    EINT;
    ERTM; // 실시간 디버깅 인터럽트 활성화

    // 무한 루프: 인터럽트 대기 및 상태 표시
    for(;;)
    {
        // 디버깅용 상태 표시: sdfmStatus=1이면 LED ON, 아니면 OFF
        GPIO_writePin(31, (sdfmStatus == 1) ? 1 : 0);
        DEVICE_DELAY_US(1000000); // 1초 지연 (CPU 부하 감소 및 디버깅용)
    }
}

설명:

  • 기능: SDFM1의 채널 1(Sinc3, OSR=128)과 채널 2(Sinc2, OSR=64)를 사용하여 두 채널의 데이터를 읽음.
  • 설정: 20MHz 모듈레이터 클럭, 두 필터 독립 설정.
  • GPIO: GPIO48(SD1_D1), GPIO49(SD1_C1), GPIO50(SD1_D2), GPIO51(SD1_C2), GPIO31(LED).
  • 결과: 두 채널의 변환된 데이터는 filterData1, filterData2에 저장, 정상 동작 시 LED ON.
  • 용도: 다중 센서 데이터 수집.

4.4. 예제 4: SDFM과 ePWM 동기화

SDFM1과 ePWM1을 동기화하여 ePWM의 SOCA 신호로 SDFM 데이터 샘플링을 트리거합니다.

//###########################################################################
// 제목: TMS320F28388D용 SDFM 필터 PWM 동기 CPU 읽기 예제 (인터럽트 방식)
// 설명:
//  이 예제는 SDFM1 모듈의 필터 1(Sinc3, OSR=128)을 설정하여 인터럽트 방식으로 데이터를
//  읽습니다. GPIO48(SD1_D1), GPIO49(SD1_C1)를 사용하며, ePWM1의 SOCA 신호(100kHz,
//  50% 듀티 사이클)로 동기화합니다. ePWM1은 GPIO0(EPWM1A)을 통해 출력됩니다.
//  디버깅용 LED(GPIO31)와 상태 변수(sdfmStatus)를 활용하며, 데이터는 filterData
//  배열(최대 1024 샘플)에 저장됩니다. 시스템 제어는 sysctl.h와 driverlib.h를 기반으로
//  하며, C2000Ware 6.00.00.00 버전에 호환되도록 작성되었습니다. 인터럽트는 데이터 준비
//  완료 및 모듈레이터 실패 시 호출되며, 변환된 데이터는 32비트 형식으로 저장됩니다.
// 외부 연결:
//  - SDFM: GPIO48(SD1_D1), GPIO49(SD1_C1)
//  - ePWM: GPIO0(EPWM1A)
// 감시 변수:
//  - filterData: 필터 1 출력 데이터 배열
// C2000Ware 버전: 6.00.00.00
//###########################################################################
// 포함된 파일
#include "driverlib.h"      // C2000 DriverLib의 주요 헤더 파일, 시스템 제어 및 주변 장치 설정
#include "device.h"         // TMS320F28388D 디바이스별 정의(예: 클럭, GPIO 설정)

// 정의
#define MAX_SAMPLES               1024              // 최대 샘플 수 (데이터 저장 배열 크기)
#define SDFM_PIN_MUX_OPTION2      2                // SDFM 핀맵 옵션 2 (GPIO48~49)
#define SDFM_INT_MASK             0x8000F000U      // SDFM 인터럽트 플래그 마스크
#define EPWM_TIMER_TBPRD          2000             // ePWM 주기 (100kHz, 200MHz/2000)

// 전역 변수
uint32_t sdfmInstance = SDFM1_BASE;                // SDFM1 모듈 베이스 주소
uint32_t pwmInstance = EPWM1_BASE;                 // ePWM1 모듈 베이스 주소
volatile uint32_t sdfmStatus = 0;                  // SDFM 상태 플래그: 0(초기화 완료), 1(동작 중), 0xFFFF(오류)
volatile int32_t filterData[MAX_SAMPLES];          // 필터 1 출력 데이터를 저장하는 배열 (32비트)
#pragma DATA_SECTION(filterData, "Filter1_RegsFile"); // 데이터 메모리 섹션 할당 (RAMLS0)

// 함수 프로토타입 선언
void configureSDFMPins(uint16_t sdfmPinOption);    // SDFM 핀 설정 함수
void setPinConfig2(void);                          // SDFM 핀맵 옵션 2 설정 함수 (GPIO48~49)
void initEPWM(uint32_t epwmInstance);              // ePWM 초기화 함수
__interrupt void sdfm1ISR(void);                   // SDFM1 인터럽트 서비스 루틴

// GPIO 초기화 함수
// 역할: SDFM1의 데이터 및 클럭 입력 핀(GPIO48~49), ePWM1 출력 핀(GPIO0), 디버깅용 LED(GPIO31)를 설정
void initGPIO(void)
{
    EALLOW; // 시스템 레지스터 접근을 위한 보호 해제

    // SDFM1 핀 설정: SDFM_PIN_MUX_OPTION2 (GPIO48~49)
    configureSDFMPins(SDFM_PIN_MUX_OPTION2);

    // GPIO0을 ePWM1A 출력으로 설정
    // 100kHz PWM 신호 출력용
    GPIO_setPinConfig(GPIO_0_EPWM1A);           // GPIO0: ePWM1A 출력
    GPIO_setDirectionMode(0, GPIO_DIR_MODE_OUT);  // 출력 모드로 설정
    GPIO_setPadConfig(0, GPIO_PIN_TYPE_PULLUP);  // 내부 풀업 저항 활성화
    GPIO_setQualificationMode(0, GPIO_QUAL_ASYNC); // 비동기 입력 모드

    // GPIO31을 디버깅용 LED로 설정
    // 정상 동작 시 LED ON, 오류 시 LED OFF
    GPIO_setPinConfig(GPIO_31_GPIO31);           // GPIO31: 일반 GPIO
    GPIO_setDirectionMode(31, GPIO_DIR_MODE_OUT); // 출력 모드로 설정 (LED 제어용)
    GPIO_setPadConfig(31, GPIO_PIN_TYPE_PULLUP); // 내부 풀업 저항 활성화
    GPIO_setQualificationMode(31, GPIO_QUAL_ASYNC); // 비동기 입력 모드
    GPIO_writePin(31, 0);                        // 초기 상태: LED OFF

    EDIS; // 시스템 레지스터 보호 복원
}

// SDFM1 인터럽트 서비스 루틴 (ISR)
// 역할: 데이터 준비 완료 또는 모듈레이터 실패 인터럽트 발생 시 데이터를 읽고 상태 업데이트
__interrupt void sdfm1ISR(void)
{
    static uint16_t loopCounter = 0; // 샘플 카운터 (0~MAX_SAMPLES-1)
    volatile uint32_t sdfmReadFlagRegister = 0; // SDFM 플래그 레지스터 값 저장

    // 인터럽트 플래그 확인: SDIFLG 레지스터의 인터럽트 마스크 확인
    sdfmReadFlagRegister = HWREG(sdfmInstance + SDFM_O_SDIFLG);
    if ((sdfmReadFlagRegister & SDFM_INT_MASK) != SDFM_INT_MASK)
    {
        return; // 인터럽트 조건 미충족 시 ISR 종료
    }

    // 샘플링 제한 확인: MAX_SAMPLES(1024)에 도달하면 카운터 초기화
    if (loopCounter >= MAX_SAMPLES)
    {
        loopCounter = 0;
    }

    // 데이터 포맷 설정: 32비트 출력 포맷으로 설정
    SDFM_setOutputDataFormat(sdfmInstance, SDFM_FILTER_1, SDFM_DATA_FORMAT_32_BIT);

    // 필터 데이터 읽기: 필터 1의 데이터를 32비트로 저장
    filterData[loopCounter++] = SDFM_getFilterData(sdfmInstance, SDFM_FILTER_1);

    // 인터럽트 플래그 지우기: 메인 인터럽트 및 필터별 플래그 초기화
    SDFM_clearInterruptFlag(sdfmInstance, SDFM_INT_MASK);

    // 플래그 레지스터 재확인: 플래그가 제대로 지워졌는지 확인
    sdfmReadFlagRegister = HWREG(sdfmInstance + SDFM_O_SDIFLG);
    if (sdfmReadFlagRegister != 0x0)
    {
        sdfmStatus = 0xFFFF; // 플래그 지우기 실패 시 오류 상태 설정
        GPIO_writePin(31, 0); // LED OFF
        ESTOP0; // 디버깅용 정지
    }

    // 상태 업데이트: SDFM 동작 중
    sdfmStatus = 1;

    // 인터럽트 그룹 ACK: 그룹 5(SDFM1) 인터럽트 처리 완료 신호
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP5);
}

// ePWM 초기화 함수
// 역할: ePWM1을 100kHz, 50% 듀티 사이클로 설정하고 SOCA 트리거 생성
void initEPWM(uint32_t epwmInstance)
{
    EALLOW; // 시스템 레지스터 접근을 위한 보호 해제

    // TBCLK 동기화 비활성화: PWM 클럭 설정 전 비활성화
    SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

    // ePWM1 설정: 주기=2000(100kHz), Up 카운터 모드
    EPWM_setTimeBasePeriod(epwmInstance, EPWM_TIMER_TBPRD); // 주기 설정
    EPWM_setPhaseShift(epwmInstance, 0U); // 위상 0
    EPWM_setTimeBaseCounter(epwmInstance, 0U); // 카운터 초기화
    EPWM_setTimeBaseCounterMode(epwmInstance, EPWM_COUNTER_MODE_UP); // Up 카운터
    EPWM_setClockPrescaler(epwmInstance, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1); // 클럭 분주 1

    // CMPA 설정: 50% 듀티 사이클 (1000)
    EPWM_setCounterCompareValue(epwmInstance, EPWM_COUNTER_COMPARE_A, EPWM_TIMER_TBPRD / 2);

    // 액션 설정: 카운터=0에서 HIGH, CMPA에서 LOW
    EPWM_setActionQualifierAction(epwmInstance, EPWM_AQ_OUTPUT_A,
                                  EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO, EPWM_AQ_OUTPUT_HIGH);
    EPWM_setActionQualifierAction(epwmInstance, EPWM_AQ_OUTPUT_A,
                                  EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA, EPWM_AQ_OUTPUT_LOW);

    // SOCA 트리거 설정: 카운터=0일 때 발생
    EPWM_enableADCTrigger(epwmInstance, EPWM_SOC_A); // SOCA 활성화
    EPWM_setADCTriggerSource(epwmInstance, EPWM_SOC_A, EPWM_SOC_TBCTR_ZERO); // 카운터=0에서 트리거
    EPWM_setADCTriggerEventPrescale(epwmInstance, EPWM_SOC_A, 1); // 프리스케일 1 (매 주기 트리거)

    // TBCLK 동기화 활성화: PWM 클럭 시작
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

    EDIS; // 시스템 레지스터 보호 복원
}

// SDFM1 초기화 함수
// 역할: SDFM1 필터 1(Sinc3, OSR=128)을 설정하고 ePWM1 SOCA로 동기화
void initSDFM(void)
{
    EALLOW; // 시스템 제어 레지스터 접근을 위한 보호 해제

    // SDFM1 모듈의 클럭 활성화
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SD1);
    SYSCTL_REGWRITE_DELAY; // 레지스터 쓰기 안정성을 위한 지연

    // ePWM1 모듈의 클럭 활성화
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM1);
    SYSCTL_REGWRITE_DELAY; // 레지스터 쓰기 안정성을 위한 지연

    // SDFM 타입 설정: 데이터 ACK로 SDINT 생성 (Type 1: 인터럽트용 플래그)
    SysCtl_configureType(SYSCTL_SDFMTYPE, 0, 1);
    SYSCTL_REGWRITE_DELAY; // 레지스터 쓰기 안정성을 위한 지연

    // 모듈레이터 클럭 설정: 필터 1의 클럭을 데이터 속도와 동일하게 설정
    SDFM_setupModulatorClock(sdfmInstance, SDFM_FILTER_1, SDFM_MODULATOR_CLK_EQUAL_DATA_RATE);

    // 데이터 필터 설정: Sinc3, OSR=128, 32비트 출력
    SDFM_configDataFilter(sdfmInstance,
                         ((uint16_t)SDFM_FILTER_1 | (uint16_t)SDFM_FILTER_SINC_3 | SDFM_SET_OSR(128)),
                         ((uint16_t)SDFM_DATA_FORMAT_32_BIT | (uint16_t)SDFM_FILTER_ENABLE));

    // SDFM 동기화: ePWM1 SOCA 신호로 필터 1 동기화
    SDFM_setPWMSyncSource(sdfmInstance, SDFM_FILTER_1, SDFM_SYNC_PWM1_SOCA);

    // 마스터 필터 활성화: 필터 동기화 및 동작 시작
    SDFM_enableMainFilter(sdfmInstance);

    // 외부 리셋 활성화: ePWM1 SOCA로 동기화
    SDFM_enableExternalReset(sdfmInstance, SDFM_FILTER_1);

    // 인터럽트 설정: 데이터 준비 완료 및 모듈레이터 실패 인터럽트 활성화
    SDFM_enableInterrupt(sdfmInstance, SDFM_FILTER_1,
                         ((uint16_t)SDFM_MODULATOR_FAILURE_INTERRUPT | (uint16_t)SDFM_DATA_FILTER_ACKNOWLEDGE_INTERRUPT));

    // 비교기 임계값 인터럽트 비활성화: HLT/LLT 인터럽트 사용 안 함
    SDFM_disableInterrupt(sdfmInstance, SDFM_FILTER_1,
                         ((uint16_t)SDFM_HIGH_LEVEL_THRESHOLD_INTERRUPT | (uint16_t)SDFM_LOW_LEVEL_THRESHOLD_INTERRUPT));

    // 마스터 인터럽트 활성화: 필터 인터럽트를 CPU로 전달
    SDFM_enableMainInterrupt(sdfmInstance);

    // 개별 필터 활성화: 필터 1을 명시적으로 활성화
    SDFM_enableFilter(sdfmInstance, SDFM_FILTER_1);

    // 상태 업데이트: SDFM 및 ePWM 초기화 완료 및 동작 중
    sdfmStatus = 1;

    EDIS; // 시스템 레지스터 보호 복원
}

// SDFM 핀 설정 함수
// 역할: SDFM1 모듈의 데이터 및 클럭 입력 핀을 설정 (기본: OPTION2, GPIO48~49)
void configureSDFMPins(uint16_t sdfmPinOption)
{
    uint16_t pin;
    EALLOW; // GPIO 레지스터 접근을 위한 보호 해제

    switch (sdfmPinOption)
    {
        case SDFM_PIN_MUX_OPTION2: // GPIO48~49 (SD1_D1, SD1_C1)
            for (pin = 48; pin <= 49; pin++) // SDFM1 전용 핀 설정
            {
                GPIO_setDirectionMode(pin, GPIO_DIR_MODE_IN); // 입력 모드로 설정
                GPIO_setControllerCore(pin, GPIO_CORE_CPU1);  // CPU1이 GPIO 제어
                GPIO_setPadConfig(pin, GPIO_PIN_TYPE_PULLUP); // 내부 풀업 저항 활성화
                GPIO_setQualificationMode(pin, GPIO_QUAL_ASYNC); // 비동기 입력 모드
            }
            setPinConfig2(); // OPTION2용 핀맵 설정 호출
            break;
        default: // 지원되지 않는 핀맵 옵션 처리
            sdfmStatus = 0xFFFF; // 오류 상태 설정
            GPIO_writePin(31, 0); // LED OFF
            ESTOP0; // 디버깅용 정지
            break;
    }

    EDIS; // GPIO 레지스터 보호 복원
}

// SDFM_PIN_MUX_OPTION2 핀 설정 함수
// 역할: GPIO48~49를 SDFM1의 데이터 및 클럭 입력으로 설정
void setPinConfig2(void)
{
    EALLOW; // GPIO 레지스터 접근을 위한 보호 해제
    GPIO_setPinConfig(GPIO_48_SD1_D1); // GPIO48: 필터 1 데이터 입력
    GPIO_setPinConfig(GPIO_49_SD1_C1); // GPIO49: 필터 1 클럭 입력
    EDIS; // GPIO 레지스터 보호 복원
}

// 메인 함수
// 역할: 시스템 초기화, SDFM 및 ePWM 설정, 인터럽트 활성화, 상태 표시
void main(void)
{
    // 시스템 초기화: 시스템 클럭, PLL, 주변 장치 설정
    Device_init();

    // GPIO 초기화: 기본 GPIO 설정
    Device_initGPIO();

    // SDFM 및 ePWM 관련 GPIO 설정: GPIO48~49(SDFM1), GPIO0(EPWM1A), LED(GPIO31)
    initGPIO();

    // 인터럽트 모듈 초기화: 인터럽트 벡터 테이블과 컨트롤러 설정
    Interrupt_initModule();
    Interrupt_initVectorTable();

    // SDFM1 인터럽트 ISR 등록
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP5);
    Interrupt_register(INT_SDFM1, &sdfm1ISR);
    Interrupt_enable(INT_SDFM1);

    // 시스템 클럭 확인: 200MHz로 설정되어 있는지 확인
    uint32_t sysClockHz = SysCtl_getClock(SYSCTL_DEFAULT_OSC_FREQ);
    if (sysClockHz != 200000000)
    {
        sdfmStatus = 0xFFFF;      // 오류 상태 설정 (클럭 불일치)
        GPIO_writePin(31, 0);     // LED OFF로 오류 표시
        ESTOP0;                   // 디버깅용 정지
    }

    // ePWM1 초기화: 100kHz, 50% 듀티 사이클
    initEPWM(pwmInstance);

    // SDFM1 초기화: 필터 설정 및 인터럽트 활성화
    initSDFM();

    // 초기화 오류 확인: sdfmStatus가 1이 아니면 오류 처리
    if (sdfmStatus != 1)
    {
        sdfmStatus = 0xFFFF;      // 오류 상태 설정
        GPIO_writePin(31, 0);     // LED OFF로 오류 표시
        ESTOP0;                   // 디버깅용 정지
    }

    // ePWM 카운터 대기: 안정적인 동기화를 위해 TBCTR이 550 이상일 때까지 대기
    while((HWREGH(pwmInstance + EPWM_O_TBCTR)) < 550);

    // 글로벌 인터럽트 활성화: SDFM1 인터럽트 처리 시작
    EINT;
    ERTM; // 실시간 디버깅 인터럽트 활성화

    // 무한 루프: 인터럽트 대기 및 상태 표시
    for(;;)
    {
        // 디버깅용 상태 표시: sdfmStatus=1이면 LED ON, 아니면 OFF
        GPIO_writePin(31, (sdfmStatus == 1) ? 1 : 0);
        DEVICE_DELAY_US(1000000); // 1초 지연 (CPU 부하 감소 및 디버깅용)
    }
}

설명:

빌드 설정 점검

  • 링커 파일 (2838x_RAM_lnk_cpu1.cmd):
    cmd
     
    SECTIONS
    {
        Filter1_RegsFile : > RAMLS0, PAGE = 1
    }
  • 기능: ePWM1의 SOCA 신호로 SDFM1 데이터 샘플링을 동기화.
  • 설정: ePWM1(100kHz, 50% 듀티), SDFM1(Sinc3, OSR=128), ePWM1 SOCA로 동기화.
  • GPIO: GPIO48(SD1_D1), GPIO49(SD1_C1), GPIO0(ePWM1A), GPIO31(LED).
  • 결과: ePWM1의 주기에 맞춰 데이터 샘플링, 변환된 데이터는 filterData에 저장, 정상 동작 시 LED ON.
  • 용도: PWM 기반 모터 제어와 센서 데이터 동기화.

5. 추가 고려 사항

  • OSR 선택: 오버샘플링 비율(OSR)은 해상도와 샘플링 속도의 균형을 결정. OSR이 높을수록 해상도는 높아지지만 샘플링 속도는 느려짐.
  • 필터 선택: Sinc3는 고해상도에 적합, Sinc1은 빠른 응답에 적합. 애플리케이션 요구사항에 따라 선택.
  • 클럭 설정: 모듈레이터 클럭은 일반적으로 10~20MHz로 설정. 외부 클럭 사용 시 동기화 주의.
  • GPIO 설정: SDFM 핀은 외부 풀업 저항이 필요할 수 있음. 회로 설계 확인.
  • C2000Ware: 예제 코드는 C2000Ware의 DriverLib 기반. C:\ti\c2000에 설치.
  • 디버깅: Code Composer Studio의 .syscfg 툴로 SDFM 및 GPIO 설정 시각적 구성 가능.

키워드: TMS320F28388D, SDFM, DriverLib, C2000, 시그마-델타, 아날로그-디지털 변환, Code Composer Studio, Sinc 필터, 인터럽트, 동기화, 다중 채널