This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F28P650DK: SPI DMA 外部回环通信

Part Number: TMS320F28P650DK
Other Parts Discussed in Thread: LAUNCHXL-F28P65X

我尝试将F28P65的spi_ex3_external_loopback示例工程修改为DMA传输,但是始终无法成功,无法进入DMA中断,同时使用逻辑分析仪无法捕捉到正常的SPI信号,但如果不使用DMA SPI通信正常,想咨询一下我的代码处理在哪里还有问题。完整工程见附件,我的测试平台是 LAUNCHXL-F28P65X 开发版,使用SPIA作为从,SPID作为主形成外部回环。

//#############################################################################
//
// FILE:   spi_ex3_external_loopback.c
//
// TITLE:  SPI Digital Loopback without using FIFOs and Interrupts
//
//! \addtogroup driver_example_list
//! <h1>SPI Digital External Loopback without FIFO Interrupts</h1>
//!
//! This program uses the external loopback between two SPI modules. Both
//! the SPI FIFOs and interrupts are not used in this example. SPIA is
//! configured as a peripheral and SPI B is configured as controller. This example
//! demonstrates full duplex communication where both controller and peripheral transmits
//! and receives data simultaneously.
//!
//
//#############################################################################
// $Copyright:
// Copyright (C) 2022 Texas Instruments Incorporated - http://www.ti.com
//
// Redistribution and use in source and binary forms, with or without 
// modification, are permitted provided that the following conditions 
// are met:
// 
//   Redistributions of source code must retain the above copyright 
//   notice, this list of conditions and the following disclaimer.
// 
//   Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the 
//   documentation and/or other materials provided with the   
//   distribution.
// 
//   Neither the name of Texas Instruments Incorporated nor the names of
//   its contributors may be used to endorse or promote products derived
//   from this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//###########################################################################

//
// Included Files
//
#include "CPU1_RAM/syscfg/board.h"
#include "driverlib.h"
#include "device.h"
#include "board.h"
#include <string.h>

//
// SPI_peripheral
//
#define SPI_peripheral_BASE SPIA_BASE
// slave      SPIA --> SPIA
// GPIO201    MOSI --> GPIO16
// GPIO202    MISO --> GPIO17
// GPIO203    CLK  --> GPIO18
// GPIO204    CS   --> GPIO57
//
// PICO - MOSI
#define SPI_peripheral_SPIPICO_GPIO 16
#define SPI_peripheral_SPIPICO_PIN_CONFIG GPIO_16_SPIA_PICO
// POCI - MISO
#define SPI_peripheral_SPIPOCI_GPIO 17
#define SPI_peripheral_SPIPOCI_PIN_CONFIG GPIO_17_SPIA_POCI
// CLK - CLK
#define SPI_peripheral_SPICLK_GPIO 18
#define SPI_peripheral_SPICLK_PIN_CONFIG GPIO_18_SPIA_CLK
// PTE - CS
#define SPI_peripheral_SPIPTE_GPIO 57
#define SPI_peripheral_SPIPTE_PIN_CONFIG GPIO_57_SPIA_PTE

//
// SPI_controller Pinmux
//
#define SPI_controller_BASE SPID_BASE
// master     SPIB --> SPID
// GPIO58     MOSI --> GPIO91
// GPIO59     MISO --> GPIO92
// GPIO60     CLK  --> GPIO93
// GPIO61     CS   --> GPIO94
//
// PICO - MOSI
#define SPI_controller_SPIPICO_GPIO 91
#define SPI_controller_SPIPICO_PIN_CONFIG GPIO_91_SPID_PICO
// POCI - MISO
#define SPI_controller_SPIPOCI_GPIO 92
#define SPI_controller_SPIPOCI_PIN_CONFIG GPIO_92_SPID_POCI
// CLK - CLK
#define SPI_controller_SPICLK_GPIO 93
#define SPI_controller_SPICLK_PIN_CONFIG GPIO_93_SPID_CLK
// PTE - CS
#define SPI_controller_SPIPTE_GPIO 94
#define SPI_controller_SPIPTE_PIN_CONFIG GPIO_94_SPID_PTE

void UserPinMux_init()
{
    //
    // PinMux for modules assigned to CPU1
    //
    // SPI_peripheral Pinmux
    GPIO_setPinConfig(SPI_peripheral_SPIPICO_PIN_CONFIG);
    GPIO_setPadConfig(SPI_peripheral_SPIPICO_GPIO, GPIO_PIN_TYPE_STD);
    GPIO_setQualificationMode(SPI_peripheral_SPIPICO_GPIO, GPIO_QUAL_ASYNC);

    GPIO_setPinConfig(SPI_peripheral_SPIPOCI_PIN_CONFIG);
    GPIO_setPadConfig(SPI_peripheral_SPIPOCI_GPIO, GPIO_PIN_TYPE_STD);
    GPIO_setQualificationMode(SPI_peripheral_SPIPOCI_GPIO, GPIO_QUAL_ASYNC);

    GPIO_setPinConfig(SPI_peripheral_SPICLK_PIN_CONFIG);
    GPIO_setPadConfig(SPI_peripheral_SPICLK_GPIO, GPIO_PIN_TYPE_STD);
    GPIO_setQualificationMode(SPI_peripheral_SPICLK_GPIO, GPIO_QUAL_ASYNC);

    GPIO_setPinConfig(SPI_peripheral_SPIPTE_PIN_CONFIG);
    GPIO_setPadConfig(SPI_peripheral_SPIPTE_GPIO, GPIO_PIN_TYPE_STD);
    GPIO_setQualificationMode(SPI_peripheral_SPIPTE_GPIO, GPIO_QUAL_ASYNC);
    // SPI_controller Pinmux
    GPIO_setPinConfig(SPI_controller_SPIPICO_PIN_CONFIG);
    GPIO_setPadConfig(SPI_controller_SPIPICO_GPIO, GPIO_PIN_TYPE_STD);
    GPIO_setQualificationMode(SPI_controller_SPIPICO_GPIO, GPIO_QUAL_ASYNC);

    GPIO_setPinConfig(SPI_controller_SPIPOCI_PIN_CONFIG);
    GPIO_setPadConfig(SPI_controller_SPIPOCI_GPIO, GPIO_PIN_TYPE_STD);
    GPIO_setQualificationMode(SPI_controller_SPIPOCI_GPIO, GPIO_QUAL_ASYNC);

    GPIO_setPinConfig(SPI_controller_SPICLK_PIN_CONFIG);
    GPIO_setPadConfig(SPI_controller_SPICLK_GPIO, GPIO_PIN_TYPE_STD);
    GPIO_setQualificationMode(SPI_controller_SPICLK_GPIO, GPIO_QUAL_ASYNC);

    GPIO_setPinConfig(SPI_controller_SPIPTE_PIN_CONFIG);
    GPIO_setPadConfig(SPI_controller_SPIPTE_GPIO, GPIO_PIN_TYPE_STD);
    GPIO_setQualificationMode(SPI_controller_SPIPTE_GPIO, GPIO_QUAL_ASYNC);
}

void UserSPI_peripheral_init(){
    SPI_disableModule(SPI_peripheral_BASE);
    SPI_setConfig(SPI_peripheral_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA0,
                  SPI_MODE_PERIPHERAL, 500000, 16);
    SPI_setPTESignalPolarity(SPI_peripheral_BASE, SPI_PTE_ACTIVE_LOW);
    SPI_disableFIFO(SPI_peripheral_BASE);
    SPI_disableLoopback(SPI_peripheral_BASE);
    SPI_setEmulationMode(SPI_peripheral_BASE, SPI_EMULATION_FREE_RUN);
    SPI_enableModule(SPI_peripheral_BASE);
}
void UserSPI_controller_init(){
    SPI_disableModule(SPI_controller_BASE);
    SPI_setConfig(SPI_controller_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA0,
                  SPI_MODE_CONTROLLER, 500000, 16);
    SPI_setPTESignalPolarity(SPI_controller_BASE, SPI_PTE_ACTIVE_LOW);
    SPI_disableFIFO(SPI_controller_BASE);
    SPI_disableLoopback(SPI_controller_BASE);
    SPI_setEmulationMode(SPI_controller_BASE, SPI_EMULATION_FREE_RUN);
    SPI_enableModule(SPI_controller_BASE);
}
void UserSPI_init(){
    UserSPI_peripheral_init();
    UserSPI_controller_init();
}

typedef struct
{
    uint16_t pinId;      //gpio的pin脚
    uint16_t cpuId;      //使用cpu1还是cpu2
    uint32_t gpioMux;    //gpio引脚的复用
    uint16_t gpioDir;    //gpio引脚的方向:输入/输出
    uint16_t gpioPull;   //gpio是否需要上拉
    uint32_t analogMode; //是否是模拟引脚
}GpioCfg_Stu;

static void gpioX_Init(const GpioCfg_Stu *gpioInit)
{
    GPIO_setControllerCore(gpioInit->pinId, (GPIO_CoreSelect)gpioInit->cpuId);
    GPIO_setPinConfig(gpioInit->gpioMux);
    GPIO_setDirectionMode(gpioInit->pinId, (GPIO_Direction)gpioInit->gpioDir);
    GPIO_setPadConfig(gpioInit->pinId, gpioInit->gpioPull);
    if((gpioInit->gpioMux & 0xf) != 0)
        GPIO_setQualificationMode(gpioInit->pinId, GPIO_QUAL_ASYNC);
    if (((gpioInit->pinId >= 198U) && (gpioInit->pinId <= 242U)) || (gpioInit->pinId == 42U) || (gpioInit->pinId == 43U))
    {
        if(gpioInit->analogMode == GPIO_ANALOG_ENABLED)
            GPIO_setAnalogMode(gpioInit->pinId, GPIO_ANALOG_ENABLED);
        else
            GPIO_setAnalogMode(gpioInit->pinId, GPIO_ANALOG_DISABLED);
    }
}

typedef struct SpiPal{
    uint16_t spiId;
    uint32_t base;
    uint32_t msgNum;
    SPI_Mode mode;
    SPI_TransferProtocol protocol;
    SPI_PTEPolarity csPolarity;
    uint32_t bitRate;
    uint16_t dataBitWidth;
    uint8_t busy;
    void* buff;
    uint32_t buffSize;
    struct {
        GpioCfg_Stu cs, clk, miso, mosi;
    }gpio;
    struct {
        uint32_t dmaChBase;
    }tx;
    struct {
        uint32_t dmaChBase;
        void (*callback)(void* cbData);
        void* cbData;
        uint16_t* pReadBuf;
    }rx;
}SpiPal_Stu;

#pragma DATA_SECTION(dmaBuff, "ramgs0");
#define MAX_SPI_TXRX_BUFF_LEN   256
uint16_t dmaBuff[6][MAX_SPI_TXRX_BUFF_LEN] = {0};
SpiPal_Stu spi[4] = {0};

static SpiPal_Stu* SpiPal_DmaChToSpiHandle(uint32_t dmaChBase)
{
    uint16_t i = 0;
    for (i = 0; i < sizeof(spi)/sizeof(spi[0]); i++) {
        if ((spi[i].tx.dmaChBase == dmaChBase) || (spi[i].rx.dmaChBase == dmaChBase))
        {
            return &spi[i];
        }
    }
    return NULL;
}
static void SpiPal_SlaveDmaHandler(SpiPal_Stu* handle, uint32_t chBase)
{
    DMA_clearErrorFlag(chBase);
    if (DMA_getOverflowFlag(chBase))
        return;
    if (handle->rx.dmaChBase == chBase)
    {
        // rx dma channal
        memcpy(handle->rx.pReadBuf, handle->buff, handle->msgNum);
        DMA_stopChannel(handle->rx.dmaChBase);
        DMA_triggerSoftReset(handle->rx.dmaChBase);

        SPI_disableModule(handle->base);
        SPI_enableModule(handle->base);
        handle->busy = 0;
        if (handle->rx.callback)
        {
            handle->rx.callback(handle->rx.cbData);
        }
    } else if (handle->tx.dmaChBase == chBase)
    {
        // tx dma channal, do nothing
        DMA_stopChannel(handle->tx.dmaChBase);
        DMA_triggerSoftReset(handle->tx.dmaChBase);
    }else 
    {
    }
}

#define SPIPAL_DMA_LIST(_do)\
    _do(1)\
    _do(2)\
    _do(3)\
    _do(4)\
    _do(5)\
    _do(6)
#define SPIPAL_IRQ_HANDLER(_ch)                                                                                        \
    __interrupt void SpiPal_SlaveDmaCh##_ch##Handler(void)                                                             \
    {                                                                                                                  \
        SpiPal_Stu* spiHandle = SpiPal_DmaChToSpiHandle(DMA_CH##_ch##_BASE);                                           \
        SpiPal_SlaveDmaHandler(spiHandle, DMA_CH##_ch##_BASE);                                                         \
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP7);                                                                 \
    }
SPIPAL_DMA_LIST(SPIPAL_IRQ_HANDLER)

static void* SpiPal_DmaToChIsrHandler(uint32_t chBase)
{
    switch(chBase)
    {
        case DMA_CH1_BASE:
            return SpiPal_SlaveDmaCh1Handler;
        case DMA_CH2_BASE:
            return SpiPal_SlaveDmaCh2Handler;
        case DMA_CH3_BASE:
            return SpiPal_SlaveDmaCh3Handler;
        case DMA_CH4_BASE:
            return SpiPal_SlaveDmaCh4Handler;
        case DMA_CH5_BASE:
            return SpiPal_SlaveDmaCh5Handler;
        case DMA_CH6_BASE:
            return SpiPal_SlaveDmaCh6Handler;
        default:
            return NULL;
    }
}
static uint32_t SpiPal_DmaToChIsr(uint32_t chBase)
{
    switch(chBase)
    {
        case DMA_CH1_BASE:
            return INT_DMA_CH1;
        case DMA_CH2_BASE:
            return INT_DMA_CH2;
        case DMA_CH3_BASE:
            return INT_DMA_CH3;
        case DMA_CH4_BASE:
            return INT_DMA_CH4;
        case DMA_CH5_BASE:
            return INT_DMA_CH5;
        case DMA_CH6_BASE:
            return INT_DMA_CH6;
        default:
            return 0;
    }
}
static int32_t SpiPal_RxDmaInit(SpiPal_Stu* spiHandle)
{
    uint32_t config = 0;
    if (spiHandle->dataBitWidth == 16)
        config = DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_DISABLE | DMA_CFG_SIZE_16BIT;
    else if (spiHandle->dataBitWidth == 32)
        config = DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_DISABLE | DMA_CFG_SIZE_32BIT;
    else
        return -1;
    DMA_setEmulationMode(DMA_EMULATION_STOP);
    DMA_Trigger dmaRxTriggerMap[] = {DMA_TRIGGER_SPIARX, DMA_TRIGGER_SPIBRX, DMA_TRIGGER_SPICRX, DMA_TRIGGER_SPIDRX};
    DMA_configAddresses(spiHandle->rx.dmaChBase, spiHandle->buff, (uint16_t *)spiHandle->base + SPI_O_RXBUF);
    DMA_configBurst(spiHandle->rx.dmaChBase, 1U, 0, 1);
    DMA_configTransfer(spiHandle->rx.dmaChBase, 16U, 0, 1);
    DMA_configWrap(spiHandle->rx.dmaChBase, 65535U, 0, 65535U, 0);
    DMA_configMode(spiHandle->rx.dmaChBase, dmaRxTriggerMap[spiHandle->spiId], config);
    DMA_disableOverrunInterrupt(spiHandle->rx.dmaChBase);
    DMA_setInterruptMode(spiHandle->rx.dmaChBase, DMA_INT_AT_END);
    DMA_enableInterrupt(spiHandle->rx.dmaChBase);
    DMA_enableTrigger(spiHandle->rx.dmaChBase);
    DMA_stopChannel(spiHandle->rx.dmaChBase);
    Interrupt_register(SpiPal_DmaToChIsr(spiHandle->rx.dmaChBase), (void (*)(void))SpiPal_DmaToChIsrHandler(spiHandle->rx.dmaChBase));
    Interrupt_enable(SpiPal_DmaToChIsr(spiHandle->rx.dmaChBase));
    return 0;
}

static int32_t SpiPal_TxDmaInit(SpiPal_Stu* spiHandle)
{
    uint32_t config = 0;
    if (spiHandle->dataBitWidth == 16)
        config = DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_DISABLE | DMA_CFG_SIZE_16BIT;
    else if (spiHandle->dataBitWidth == 32)
        config = DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_DISABLE | DMA_CFG_SIZE_32BIT;
    else
        return -1;
    DMA_setEmulationMode(DMA_EMULATION_STOP);
    DMA_Trigger dmaTxTriggerMap[] = {DMA_TRIGGER_SPIATX, DMA_TRIGGER_SPIATX, DMA_TRIGGER_SPIATX, DMA_TRIGGER_SPIATX};
    DMA_configAddresses(spiHandle->tx.dmaChBase, (uint16_t *)spiHandle->base + SPI_O_TXBUF, spiHandle->buff);
    DMA_configBurst(spiHandle->tx.dmaChBase, 1U, 1, 0);
    DMA_configTransfer(spiHandle->tx.dmaChBase, 16U, 1, 0);
    DMA_configWrap(spiHandle->tx.dmaChBase, 65535U, 0, 65535U, 0);
    DMA_configMode(spiHandle->tx.dmaChBase, dmaTxTriggerMap[spiHandle->spiId], config);
    DMA_disableOverrunInterrupt(spiHandle->tx.dmaChBase);
    DMA_setInterruptMode(spiHandle->tx.dmaChBase, DMA_INT_AT_END);
    DMA_enableInterrupt(spiHandle->tx.dmaChBase);
    DMA_enableTrigger(spiHandle->tx.dmaChBase);
    DMA_stopChannel(spiHandle->tx.dmaChBase);
    Interrupt_register(SpiPal_DmaToChIsr(spiHandle->tx.dmaChBase), (void (*)(void))SpiPal_DmaToChIsrHandler(spiHandle->tx.dmaChBase));
    Interrupt_enable(SpiPal_DmaToChIsr(spiHandle->tx.dmaChBase));
    return 0;
}
static int32_t SpiPal_DmaInit(SpiPal_Stu* spiHandle)
{
    SpiPal_RxDmaInit(spiHandle);
    SpiPal_TxDmaInit(spiHandle);
    return 0;
}

static int32_t SpiPal_PinMux_init(SpiPal_Stu* spiHandle)
{
    gpioX_Init(&spiHandle->gpio.cs);
    gpioX_Init(&spiHandle->gpio.clk);
    gpioX_Init(&spiHandle->gpio.miso);
    gpioX_Init(&spiHandle->gpio.mosi);
    return 0;
}

static int32_t SPI_Hw_init(SpiPal_Stu* spiHandle)
{
    SPI_disableModule(spiHandle->base);
    SPI_setConfig(spiHandle->base, DEVICE_LSPCLK_FREQ, spiHandle->protocol,
                  spiHandle->mode, spiHandle->bitRate, spiHandle->dataBitWidth);
    SPI_setPTESignalPolarity(spiHandle->base, spiHandle->csPolarity);
    SPI_disableFIFO(spiHandle->base);
    SPI_disableLoopback(spiHandle->base);
    SPI_setEmulationMode(spiHandle->base, SPI_EMULATION_FREE_RUN);
    SPI_enableModule(spiHandle->base);
    return 0;
}

static SpiPal_Stu* SpiPal_idToHandle(uint16_t spiId)
{
    uint16_t i = 0;
    for (i = 0; i < sizeof(spi)/sizeof(spi[0]); i++)
    {
        if(spiId == spi[i].spiId)
            return &spi[i];
    }
    return NULL;
}

static int32_t SpiPal_Request(uint16_t spiId, uint16_t *pWriteBuf, uint16_t *pReadBuf, uint16_t msgNum)
{
    SpiPal_Stu* handle = SpiPal_idToHandle(spiId);
    if (handle->busy)
        return -1;
    //===DMA spi receive
    handle->msgNum = msgNum;
    handle->rx.pReadBuf = pReadBuf;
    DMA_configBurst(handle->rx.dmaChBase, 1U, 0, 1);
    DMA_configTransfer(handle->rx.dmaChBase, msgNum, 0, 1);

    //===DMA spi send
    memcpy(handle->buff, pWriteBuf, msgNum);
    DMA_configBurst(handle->tx.dmaChBase, 1U, 1, 0);
    DMA_configTransfer(handle->tx.dmaChBase, msgNum, 1, 0);

    DMA_triggerSoftReset(handle->rx.dmaChBase);
    DMA_triggerSoftReset(handle->tx.dmaChBase);

    handle->busy = 1;
    DMA_startChannel(handle->rx.dmaChBase);
    DMA_startChannel(handle->tx.dmaChBase);
    return 0;
}

static int32_t SpiPal_Transfer(uint16_t spiId, uint16_t *pWriteBuf, uint16_t *pReadBuf, uint16_t msgNum)
{
    SpiPal_Stu* handle = SpiPal_idToHandle(spiId);
    SpiPal_Request(spiId, pWriteBuf, pReadBuf, msgNum);
    while (handle->busy == 1);
    return 0;
}

static int32_t SpiPal_Init(SpiPal_Stu* spiHandle)
{
    int32_t ret = 0;
    ret = SpiPal_PinMux_init(spiHandle);
    if (ret != 0)
        return ret;
    ret = SPI_Hw_init(spiHandle);
    if (ret != 0)
        return ret;
    ret = SpiPal_DmaInit(spiHandle);
    if (ret != 0)
        return ret;
    return ret;
}


#define SPI_SLAVE_IDX 0
#define SPI_MASTER_IDX 1
#define SPI_SLAVE spi[SPI_SLAVE_IDX]
#define SPI_MASTER spi[SPI_MASTER_IDX]

void UserBoard_init()
{
    EALLOW;
    SPI_SLAVE.spiId = 0;
    SPI_SLAVE.base = SPI_peripheral_BASE;
    SPI_SLAVE.protocol = SPI_PROT_POL0PHA0;
    SPI_SLAVE.mode = SPI_MODE_PERIPHERAL;
    SPI_SLAVE.bitRate = 500000;
    SPI_SLAVE.dataBitWidth = 16;
    SPI_SLAVE.csPolarity = SPI_PTE_ACTIVE_LOW;
    SPI_SLAVE.gpio.cs.pinId = SPI_peripheral_SPIPTE_GPIO;
    SPI_SLAVE.gpio.cs.cpuId = GPIO_CORE_CPU1;
    SPI_SLAVE.gpio.cs.gpioMux = SPI_peripheral_SPIPTE_PIN_CONFIG;
    SPI_SLAVE.gpio.cs.gpioDir = GPIO_DIR_MODE_IN;
    SPI_SLAVE.gpio.cs.gpioPull = GPIO_PIN_TYPE_PULLUP;
    SPI_SLAVE.gpio.cs.analogMode = GPIO_ANALOG_DISABLED;
    SPI_SLAVE.gpio.clk.pinId = SPI_peripheral_SPICLK_GPIO;
    SPI_SLAVE.gpio.clk.cpuId = GPIO_CORE_CPU1;
    SPI_SLAVE.gpio.clk.gpioMux = SPI_peripheral_SPICLK_PIN_CONFIG;
    SPI_SLAVE.gpio.clk.gpioDir = GPIO_DIR_MODE_IN;
    SPI_SLAVE.gpio.clk.gpioPull = GPIO_PIN_TYPE_PULLUP;
    SPI_SLAVE.gpio.clk.analogMode = GPIO_ANALOG_DISABLED;
    SPI_SLAVE.gpio.miso.pinId = SPI_peripheral_SPIPOCI_GPIO;
    SPI_SLAVE.gpio.miso.cpuId = GPIO_CORE_CPU1;
    SPI_SLAVE.gpio.miso.gpioMux = SPI_peripheral_SPIPOCI_PIN_CONFIG;
    SPI_SLAVE.gpio.miso.gpioDir = GPIO_DIR_MODE_OUT;
    SPI_SLAVE.gpio.miso.gpioPull = GPIO_PIN_TYPE_PULLUP;
    SPI_SLAVE.gpio.miso.analogMode = GPIO_ANALOG_DISABLED;
    SPI_SLAVE.gpio.mosi.pinId = SPI_peripheral_SPIPICO_GPIO;
    SPI_SLAVE.gpio.mosi.cpuId = GPIO_CORE_CPU1;
    SPI_SLAVE.gpio.mosi.gpioMux = SPI_peripheral_SPIPICO_PIN_CONFIG;
    SPI_SLAVE.gpio.mosi.gpioDir = GPIO_DIR_MODE_IN;
    SPI_SLAVE.gpio.mosi.gpioPull = GPIO_PIN_TYPE_PULLUP;
    SPI_SLAVE.gpio.mosi.analogMode = GPIO_ANALOG_DISABLED;
    SPI_SLAVE.rx.dmaChBase = DMA_CH1_BASE;
    SPI_SLAVE.tx.dmaChBase = DMA_CH2_BASE;
    SPI_SLAVE.buff = dmaBuff[0];

    SPI_MASTER.spiId = 1;
    SPI_MASTER.base = SPI_controller_BASE;
    SPI_MASTER.protocol = SPI_PROT_POL0PHA0;
    SPI_MASTER.mode = SPI_MODE_CONTROLLER;
    SPI_MASTER.bitRate = 500000;
    SPI_MASTER.dataBitWidth = 16;
    SPI_MASTER.csPolarity = SPI_PTE_ACTIVE_LOW;
    SPI_MASTER.gpio.cs.pinId = SPI_controller_SPIPTE_GPIO;
    SPI_MASTER.gpio.cs.cpuId = GPIO_CORE_CPU1;
    SPI_MASTER.gpio.cs.gpioMux = SPI_controller_SPIPTE_PIN_CONFIG;
    SPI_MASTER.gpio.cs.gpioDir = GPIO_DIR_MODE_OUT;
    SPI_MASTER.gpio.cs.gpioPull = GPIO_PIN_TYPE_PULLUP;
    SPI_MASTER.gpio.cs.analogMode = GPIO_ANALOG_DISABLED;
    SPI_MASTER.gpio.clk.pinId = SPI_controller_SPICLK_GPIO;
    SPI_MASTER.gpio.clk.cpuId = GPIO_CORE_CPU1;
    SPI_MASTER.gpio.clk.gpioMux = SPI_controller_SPICLK_PIN_CONFIG;
    SPI_MASTER.gpio.clk.gpioDir = GPIO_DIR_MODE_OUT;
    SPI_MASTER.gpio.clk.gpioPull = GPIO_PIN_TYPE_PULLUP;
    SPI_MASTER.gpio.clk.analogMode = GPIO_ANALOG_DISABLED;
    SPI_MASTER.gpio.miso.pinId = SPI_controller_SPIPOCI_GPIO;
    SPI_MASTER.gpio.miso.cpuId = GPIO_CORE_CPU1;
    SPI_MASTER.gpio.miso.gpioMux = SPI_controller_SPIPOCI_PIN_CONFIG;
    SPI_MASTER.gpio.miso.gpioDir = GPIO_DIR_MODE_IN;
    SPI_MASTER.gpio.miso.gpioPull = GPIO_PIN_TYPE_PULLUP;
    SPI_MASTER.gpio.miso.analogMode = GPIO_ANALOG_DISABLED;
    SPI_MASTER.gpio.mosi.pinId = SPI_controller_SPIPICO_GPIO;
    SPI_MASTER.gpio.mosi.cpuId = GPIO_CORE_CPU1;
    SPI_MASTER.gpio.mosi.gpioMux = SPI_controller_SPIPICO_PIN_CONFIG;
    SPI_MASTER.gpio.mosi.gpioDir = GPIO_DIR_MODE_OUT;
    SPI_MASTER.gpio.mosi.gpioPull = GPIO_PIN_TYPE_PULLUP;
    SPI_MASTER.gpio.mosi.analogMode = GPIO_ANALOG_DISABLED;
    SPI_MASTER.rx.dmaChBase = DMA_CH3_BASE;
    SPI_MASTER.tx.dmaChBase = DMA_CH4_BASE;
    SPI_MASTER.buff = dmaBuff[1];
    //UserPinMux_init();
    SpiPal_PinMux_init(&SPI_SLAVE);
    SpiPal_PinMux_init(&SPI_MASTER);

    DMA_initController();

    SpiPal_DmaInit(&SPI_SLAVE);
    SpiPal_DmaInit(&SPI_MASTER);

    //UserSPI_init();
    SPI_Hw_init(&SPI_SLAVE);
    SPI_Hw_init(&SPI_MASTER);

    EDIS;
}

uint16_t TxData_Peripheral[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
uint16_t RxData_Peripheral[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint16_t TxData_Controller[] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
uint16_t RxData_Controller[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
int16_t resault = 0;

//
// Main
//
void main(void)
{
    uint16_t i;

    //
    // Initialize device clock and peripherals
    //
    Device_init();

    //
    // Disable pin locks and enable internal pullups.
    //
    Device_initGPIO();

    //
    // Initialize PIE and clear PIE registers. Disables CPU interrupts.
    //
    Interrupt_initModule();

    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    //
    Interrupt_initVectorTable();

    //
    // Board initialization
    //
    UserBoard_init();

    SpiPal_Request(SPI_SLAVE_IDX, TxData_Peripheral, RxData_Peripheral, sizeof(TxData_Peripheral));
    SpiPal_Transfer(SPI_MASTER_IDX, TxData_Controller, RxData_Controller, sizeof(TxData_Controller)+1);
    if(0 != memcmp(TxData_Controller, RxData_Peripheral, sizeof(TxData_Peripheral)))
    {
        resault = -1;
        ESTOP0;
    }
    if(0 != memcmp(TxData_Peripheral, RxData_Controller, sizeof(TxData_Peripheral)))
    {
        resault = -1;
        ESTOP0;
    }

    // //
    // // Loop forever. Suspend or place breakpoints to observe the buffers.
    // //
    // for(i = 0; i < 16; i++)
    // {
    //     //
    //     // Set the TX buffer of peripheral SPI.
    //     //
    //     SPI_writeDataNonBlocking(SPI_peripheral_BASE, TxData_Peripheral[i]);

    //     //
    //     // Set the the controller TX buffer. This triggers the data transmission
    //     //
    //     SPI_writeDataNonBlocking(SPI_controller_BASE, TxData_Controller[i]);

    //     //
    //     // Read the received data
    //     //
    //     RxData_Peripheral[i] = SPI_readDataBlockingNonFIFO(SPI_peripheral_BASE);
    //     RxData_Controller[i] = SPI_readDataBlockingNonFIFO(SPI_controller_BASE);

    //     //
    //     // Check the received data
    //     //
    //     if(RxData_Peripheral[i] != TxData_Controller[i])
    //     {
    //         resault = -1;
    //         ESTOP0;
    //     }
    //     if(RxData_Controller[i] != TxData_Peripheral[i])
    //     {
    //         resault = -1;
    //         ESTOP0;
    //     }
    // }
    ESTOP0;
    resault = 1;
    //
    // Loop forever
    //
    while(1);
}

spi_ex3_external_loopback.zip