본문 바로가기
Embedded SW/Embedded SW Introduction

16. Aurix SPI 개발 수행 (2)

by 방구석 임베디드 2021. 7. 27.
반응형

이제 설계 파라미터는 정리가 되었습니다.

Aurix MCU를 이용하여 SPI 설계를 수행해 보도록 하겠습니다.

 

Infineon은 demo code를 제공합니다.

QSPI 관련 demo code를 확인하면 아래와 같습니다.

저는 이 demo code를 최대한 활용하여 설계를 해보도록 하겠습니다.

void Driver_SpiInit(void)
{
    Driver_Spi3Init();
}

static void Driver_Spi3Init(void)
{
    IfxQspi_SpiMaster_Config        spiMasterConfig;
    IfxQspi_SpiMaster_ChannelConfig spiMasterChannelConfig;

    /* create module config */
    IfxQspi_SpiMaster_initModuleConfig(&spiMasterConfig, &MODULE_QSPI3);

    /* set the maximum baudrate */
    spiMasterConfig.base.maximumBaudrate = 10000000;

    /* ISR priorities and interrupt target */
    spiMasterConfig.base.txPriority  = ISR_PRIORITY_QSPI3_TX;
    spiMasterConfig.base.rxPriority  = ISR_PRIORITY_QSPI3_RX;
    spiMasterConfig.base.erPriority  = ISR_PRIORITY_QSPI3_ER;
    spiMasterConfig.base.isrProvider = (IfxSrc_Tos)IfxCpu_getCoreIndex();

    /* pin configuration */
    const IfxQspi_SpiMaster_Pins pins = {&IfxQspi3_SCLK_P22_3_OUT,                               /* SCLK */
                                         IfxPort_OutputMode_pushPull,
                                         &IfxQspi3_MTSR_P22_0_OUT,  IfxPort_OutputMode_pushPull, /* MTSR */
                                         &IfxQspi3_MRSTE_P22_1_IN,  IfxPort_InputMode_pullDown,  /* MRST */
                                         IfxPort_PadDriver_cmosAutomotiveSpeed3                   /* pad driver mode */
    };
    spiMasterConfig.pins = &pins;

    /* initialize module */
    IfxQspi_SpiMaster_initModule(&g_QspiCpu.drivers.spiMaster, &spiMasterConfig);

    /* create channel config */
    IfxQspi_SpiMaster_initChannelConfig(&spiMasterChannelConfig,
        &g_QspiCpu.drivers.spiMaster);

    /* set the baudrate for this channel */
    spiMasterChannelConfig.base.baudrate = 1000000;
    spiMasterChannelConfig.base.mode.shiftClock = SpiIf_ShiftClock_shiftTransmitDataOnTrailingEdge;
    spiMasterChannelConfig.base.mode.dataWidth = 16u;

    const IfxQspi_SpiMaster_Output slsOutput = {&IfxQspi3_SLSO13_P23_1_OUT,
                                                IfxPort_OutputMode_pushPull,
                                                IfxPort_PadDriver_cmosAutomotiveSpeed1};

    spiMasterChannelConfig.sls.output.pin    = slsOutput.pin;
    spiMasterChannelConfig.sls.output.mode   = slsOutput.mode;
    spiMasterChannelConfig.sls.output.driver = slsOutput.driver;

    /* initialize channel */
    IfxQspi_SpiMaster_initChannel(&g_QspiCpu.drivers.spiMasterChannel,
        &spiMasterChannelConfig);
}

위의 코드가 바로 Demo Code를 이용하여 초기화 설정을 수행한 코드입니다.

우선 Pin의 연결을 변경하였습니다.

QSPI3번 모듈과 연결된 Pin 위치로 변경을 하였습니다.

QSPI3번에 연결할수 있는 핀들의 후보군들이 있습니다.

이중에서, 현재 개발보드에 연결된 pin은 아래와 같습니다.

이미 이렇게 지정이 되어 있기 때문에 코드에서 아래와 같이 연결을 해주면 됩니다.

    /* pin configuration */
    const IfxQspi_SpiMaster_Pins pins = {&IfxQspi3_SCLK_P22_3_OUT,                               /* SCLK */
                                         IfxPort_OutputMode_pushPull,
                                         &IfxQspi3_MTSR_P22_0_OUT,  IfxPort_OutputMode_pushPull, /* MTSR */
                                         &IfxQspi3_MRSTE_P22_1_IN,  IfxPort_InputMode_pullDown,  /* MRST */
                                         IfxPort_PadDriver_cmosAutomotiveSpeed3                   /* pad driver mode */
    };
    
        const IfxQspi_SpiMaster_Output slsOutput = {&IfxQspi3_SLSO13_P23_1_OUT,
                                                IfxPort_OutputMode_pushPull,
                                                IfxPort_PadDriver_cmosAutomotiveSpeed1};

그리고 저는 SCK의 Clock 주기를 1MHz로 설정해야 합니다.

또한 CPHA를 0으로 설정해야 하고

한번 보내는 비트를 16비트로 설정해야 합니다.

그 코드 부분은 아래와 같습니다.

    spiMasterChannelConfig.base.baudrate = 1000000;
    spiMasterChannelConfig.base.mode.shiftClock = SpiIf_ShiftClock_shiftTransmitDataOnTrailingEdge;
    spiMasterChannelConfig.base.mode.dataWidth = 16u;

원래 레지스터 하나하나 세팅해야 하는 것이 맞으나,

인피니언은 ILLD라는 Driver Stack을 제공해 주기 때문에

위와 같이 Parameter만 넣어주면 잘 Setting을 해줍니다.

추후, 레지스터 하나하나를 분석해 보도록 하겠습니다.

 

우선, 잘 동작하는지만 확인하도록 하겠습니다.

 

이제 초기화는 끝났습니다.

발사를 시키도록 하겠습니다.

 

void SpiDemo_run(void)
{
    g_QspiCpu.qspiBuffer.spi3TxBuffer[0] = 0x12u;
    g_QspiCpu.qspiBuffer.spi3TxBuffer[1] = 0x34u;

    while (IfxQspi_SpiMaster_getStatus(&g_QspiCpu.drivers.spiMasterChannel) == SpiIf_Status_busy){}

    IfxQspi_SpiMaster_exchange(&g_QspiCpu.drivers.spiMasterChannel, &g_QspiCpu.qspiBuffer.spi3TxBuffer[0], &g_QspiCpu.qspiBuffer.spi3RxBuffer[0], 1u);
}

발사 코드는 위와 같습니다.

저는 0x12를 발사하고 그리고 0x34를 발사할 것입니다.

이렇게 16비트가 발사되는지를 확인해 보도록 하겠습니다.

저는 Logic Analyzer를 아주 좋아합니다.

개인적으로 구매도 하였습니다.

그 Tool을 이용하여 이렇게 4개의 핀을 연결하였습니다.

이제 Logic Analyzer를 살펴 보도록 하겠습니다.

제가 보내고 싶은 데이터가 보내지고 있는 것을 확인할수 있습니다.

16비트를 보내고 있고

0x12를 보내고 그 다음 0x34를 보내고 있습니다.

그리고 Polarity도 맞고

SCK의 주파수도 1MHz로 보내고 있는 것을 확인할수 있습니다.

 

Delay는 우선 조절하지 않았습니다.

이것은 나중에 맞출게요 ^^

 

사실 제가 Data를 보냈지만 RTC로부터 아무런 Feedback을 받지 못하였습니다.

그냥 제가 일방적으로 아무 의미없는 0x12 0x34를 보냈으니까요!

의미있는 정보를 보내주어야지!

IC쪽도 그에 맞는 Data를 MISO를 통해서 보내주겠죠?

 

이제 의미있는 데이터를 보내보도록 하겠습니다.

다시말해서 RTC의 상태 Register를 읽어서 Feedback 받는 동작을 구현해 보도록 하겠습니다.

 

오늘 포스팅은 이것으로 마칠께요 ^^

반응형

댓글