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.

RTOS/EK-TM4C1294XL: Trying to use an other SPI peripheral in spiloopback example.

Part Number: EK-TM4C1294XL

Tool/software: TI-RTOS

Hello everyone,

I'm trying to understand how SPI works in TI-RTOS on a Tiva C Series TM4C1294 (EK-TM4C1294XL). I started with the spiloopback example. I wanted to add SSI1 peripheral as SPI slave. So, in EK_TM4C1294XL.c, I modified the SPI section like this :

const SPITivaDMA_HWAttrs spiTivaDMAHWAttrs[EK_TM4C1294XL_SPICOUNT] = {
     {
        .baseAddr = SSI1_BASE, // NOT WORKING WITH SSI1
        .intNum = INT_SSI1,
        .intPriority = (~0),
        .scratchBufPtr = &spiTivaDMAscratchBuf[0],
        .defaultTxBufValue = 0,
        .rxChannelIndex = UDMA_SEC_CHANNEL_SSI1RX,
        .txChannelIndex = UDMA_SEC_CHANNEL_SSI1TX,
        .channelMappingFxn = uDMAChannelAssign,
        .rxChannelMappingFxnArg = UDMA_CH10_SSI1RX,
        .txChannelMappingFxnArg = UDMA_CH11_SSI1TX
    },
    {
        .baseAddr = SSI2_BASE,
        .intNum = INT_SSI2,
        .intPriority = (~0),
        .scratchBufPtr = &spiTivaDMAscratchBuf[1],
        .defaultTxBufValue = 0,
        .rxChannelIndex = UDMA_SEC_CHANNEL_UART2RX_12,
        .txChannelIndex = UDMA_SEC_CHANNEL_UART2TX_13,
        .channelMappingFxn = uDMAChannelAssign,
        .rxChannelMappingFxnArg = UDMA_CH12_SSI2RX,
        .txChannelMappingFxnArg = UDMA_CH13_SSI2TX
    },
    {
        .baseAddr = SSI3_BASE,
        .intNum = INT_SSI3,
        .intPriority = (~0),
        .scratchBufPtr = &spiTivaDMAscratchBuf[2],
        .defaultTxBufValue = 0,
        .rxChannelIndex = UDMA_SEC_CHANNEL_TMR2A_14,
        .txChannelIndex = UDMA_SEC_CHANNEL_TMR2B_15,
        .channelMappingFxn = uDMAChannelAssign,
        .rxChannelMappingFxnArg = UDMA_CH14_SSI3RX,
        .txChannelMappingFxnArg = UDMA_CH15_SSI3TX
    }
};

const SPI_Config SPI_config[] = {
    {
        .fxnTablePtr = &SPITivaDMA_fxnTable,
        .object = &spiTivaDMAObjects[0],
        .hwAttrs = &spiTivaDMAHWAttrs[0]
    },
    {
        .fxnTablePtr = &SPITivaDMA_fxnTable,
        .object = &spiTivaDMAObjects[1],
        .hwAttrs = &spiTivaDMAHWAttrs[1]
    },
    {
        .fxnTablePtr = &SPITivaDMA_fxnTable,
        .object = &spiTivaDMAObjects[2],
        .hwAttrs = &spiTivaDMAHWAttrs[2]
    },
    {NULL, NULL, NULL}
};

/*
 *  ======== EK_TM4C1294XL_initSPI ========
 */
void EK_TM4C1294XL_initSPI(void)
{
    /* SSI1 */
    SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI1);

    GPIOPinConfigure(GPIO_PB5_SSI1CLK);
    GPIOPinConfigure(GPIO_PB4_SSI1FSS);
    GPIOPinConfigure(GPIO_PE4_SSI1XDAT0);
    GPIOPinConfigure(GPIO_PE5_SSI1XDAT1);

    GPIOPinTypeSSI(GPIO_PORTB_BASE, GPIO_PIN_4 | GPIO_PIN_5);
    GPIOPinTypeSSI(GPIO_PORTE_BASE, GPIO_PIN_4 | GPIO_PIN_5);

    /* SSI2 */
    SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI2);

    GPIOPinConfigure(GPIO_PD3_SSI2CLK);
    GPIOPinConfigure(GPIO_PD2_SSI2FSS);
    GPIOPinConfigure(GPIO_PD1_SSI2XDAT0);
    GPIOPinConfigure(GPIO_PD0_SSI2XDAT1);

    GPIOPinTypeSSI(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1 |
                                    GPIO_PIN_2 | GPIO_PIN_3);


    /* SSI3 */
    SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI3);

    GPIOPinConfigure(GPIO_PQ0_SSI3CLK);
    GPIOPinConfigure(GPIO_PQ1_SSI3FSS);
    GPIOPinConfigure(GPIO_PQ2_SSI3XDAT0);
    GPIOPinConfigure(GPIO_PQ3_SSI3XDAT1);

    GPIOPinTypeSSI(GPIO_PORTQ_BASE, GPIO_PIN_0 | GPIO_PIN_1 |
                                    GPIO_PIN_2 | GPIO_PIN_3);

    EK_TM4C1294XL_initDMA();
    SPI_init();
}

If I use, in SPI_open(), index 1 (SSI2) as slave and index 2 (SSI3) as master, it works fine. But if I use index 0 (SSI1) as slave and index 2 (SSI3) as master I have this error :

DMA error code: 1
DMA error!!

I was wondering what I have missed ? Any help is welcome :-) .

Thanks,

Martin

  • Is there someone who knows something about that ^ ?
  • Martin,

    Sorry for the slow reply. Looks like you have everything configured correctly. It might be a resource conflict somewhere. Perhaps the same UDMA channel is assigned to another peripheral. Let's start by double-checking the basics.

    Have you added SPI1 to EK_TM4C1294XL.h?

    typedef enum EK_TM4C1294XL_SPIName {
        EK_TM4C1294XL_SPI1 = 0,
        EK_TM4C1294XL_SPI2,
        EK_TM4C1294XL_SPI3,
    
        EK_TM4C1294XL_SPICOUNT
    } EK_TM4C1294XL_SPIName;
    

    Have you updated Board.h?

    #define Board_SPI1                  EK_TM4C1294XL_SPI1
    #define Board_SPI2                  EK_TM4C1294XL_SPI2
    #define Board_SPI3                  EK_TM4C1294XL_SPI3
    

    And update the program to use the new Board.h defines.

    ~Ramsey

  • Hi Ramsey,

    Thank you for your reply.

    I already done that modifications before. Here what I have :

    EK_TM4C129XL.h :

    typedef enum EK_TM4C1294XL_SPIName {
        EK_TM4C1294XL_SPI1 = 0,
        EK_TM4C1294XL_SPI2,
        EK_TM4C1294XL_SPI3,
    
        EK_TM4C1294XL_SPICOUNT
    } EK_TM4C1294XL_SPIName;

    Board.h :

    #define Board_SPI0                  EK_TM4C1294XL_SPI1
    #define Board_SPI1                  EK_TM4C1294XL_SPI2
    #define Board_SPI2                  EK_TM4C1294XL_SPI3

    spiloopback.c :

    /* Initialize SPI handle with slave mode */
    SPI_Params_init(&slaveSpiParams);
    slaveSpiParams.mode = SPI_SLAVE;
    slaveSpi = SPI_open(Board_SPI0, &slaveSpiParams);
    if (slaveSpi == NULL) {
        System_abort("Error initializing SPI\n");
    }
    else {
        System_printf("SPI initialized\n");
    }
    /* Initialize SPI handle as default master */
    masterSpi = SPI_open(Board_SPI2, NULL);
    if (masterSpi == NULL) {
        System_abort("Error initializing SPI\n");
    }
    else {
        System_printf("SPI initialized\n");
    }

    It seems the problem come from the µDMA but I don't know much about it. Maybe an ISR not set ?

    Thanks,

    Martin

  • Any idea of a solution ? I really need help. :-)

    Thanks,
    Martin
  • I found the solution ! The initialization of the spiTivaDMAHWAttrs structure was incorrect for SSI1.

    Here is the good initialization :

    const SPITivaDMA_HWAttrs spiTivaDMAHWAttrs[EK_TM4C1294XL_SPICOUNT] = {
         {
            .baseAddr = SSI1_BASE,
            .intNum = INT_SSI1,
            .intPriority = (~0),
            .scratchBufPtr = &spiTivaDMAscratchBuf[0],
            .defaultTxBufValue = 0,
            .rxChannelIndex = UDMA_CHANNEL_SSI1RX,
            .txChannelIndex = UDMA_CHANNEL_SSI1TX,
            .channelMappingFxn = uDMAChannelAssign,
            .rxChannelMappingFxnArg = UDMA_CH24_SSI1RX,
            .txChannelMappingFxnArg = UDMA_CH25_SSI1TX
        },
        {
            .baseAddr = SSI2_BASE,
            .intNum = INT_SSI2,
            .intPriority = (~0),
            .scratchBufPtr = &spiTivaDMAscratchBuf[1],
            .defaultTxBufValue = 0,
            .rxChannelIndex = UDMA_SEC_CHANNEL_UART2RX_12,
            .txChannelIndex = UDMA_SEC_CHANNEL_UART2TX_13,
            .channelMappingFxn = uDMAChannelAssign,
            .rxChannelMappingFxnArg = UDMA_CH12_SSI2RX,
            .txChannelMappingFxnArg = UDMA_CH13_SSI2TX
        },
        {
            .baseAddr = SSI3_BASE,
            .intNum = INT_SSI3,
            .intPriority = (~0),
            .scratchBufPtr = &spiTivaDMAscratchBuf[2],
            .defaultTxBufValue = 0,
            .rxChannelIndex = UDMA_SEC_CHANNEL_TMR2A_14,
            .txChannelIndex = UDMA_SEC_CHANNEL_TMR2B_15,
            .channelMappingFxn = uDMAChannelAssign,
            .rxChannelMappingFxnArg = UDMA_CH14_SSI3RX,
            .txChannelMappingFxnArg = UDMA_CH15_SSI3TX
        }
    };

    I changed this :

    .rxChannelIndex = UDMA_SEC_CHANNEL_SSI1RX,
    .txChannelIndex = UDMA_SEC_CHANNEL_SSI1TX,
    
    .rxChannelMappingFxnArg = UDMA_CH10_SSI1RX,
    .txChannelMappingFxnArg = UDMA_CH11_SSI1TX

    by this :

    .rxChannelIndex = UDMA_CHANNEL_SSI1RX,
    .txChannelIndex = UDMA_CHANNEL_SSI1TX,
    
    .rxChannelMappingFxnArg = UDMA_CH24_SSI1RX,
    .txChannelMappingFxnArg = UDMA_CH25_SSI1TX

    But I don't know why now it's working. Someone from TI could explain to me ? :-)

    Thanks,

    Martin

  • Martin,

    I'm unable to identify why your new configuration works and the old one does not. The macro names are very confusing. The channel mapping values define which channels are actually used. The channel index values must always match the lower 16 bits of the mapping functions. But the macro names for the channel indexes are very confusing.

    That said, I don't see anything wrong with your original configuration. The best I can suggest is that some other peripheral was using channels 10 and 11.

    I'm sorry I was too busy to help you out. Thank you for posting your findings. It helps the community.

    ~Ramsey