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.

TI-RTOS driver library issue with SPI 0

Other Parts Discussed in Thread: EK-TM4C129EXL

Hi there,

EK-TM4C129EXL

CCS 6.2

TI-RTOS 2.16.0.08

XDC tools 3.32.1.22

I do have a problem with SPI 0. So it is initialized as a slave and waits for the master. Whenever data comes in a system hangs and then only reset helps.

Here is the code:

7215.SPI_0.c

What am I missing here?

Thanks.

Stan

 

  • Stan,

    It would be helpful to know what the processor is doing after receiving the SPI data. When the system hangs, can you halt the processor with CCS and look at the call stack? Is it in abort? Is your task blocked on the semaphore?

    How often do you receive data on the SPI-0 handle? Are you expecting just one transfer or many? I'm wondering if it goes bad after just one transfer or on the next one.

    I would remove the call to System_flush. This will halt the processor while the data is sent to CCS. If a SPI interrupt happens at this point, it can cause problems.

    Have you tried the spilookback example? This would be a good starting point. You can start making small changes to the example to make it look like your program. Then you will know at what point it stops working. This will be very helpful.

    ~Ramsey

  • Hi Ramsey,

    So I do confirm that I still have a problem with SPI 0. I took spilookback demo example and made sure it worked on EK-TM4C129EXL. The demo involves SPI 2 as a Master and SPI 3 as a Slave. Followed your advice - small changes at a time, I replaced SPI 3 to SPI 0. As a result the slave (SPI 0) did not receive the message from the master (SPI 2).

    Jumper wire connections (SPI 2 to SPI 0):

    PQ0->PA2,  PQ1->PA3,  PQ2->PA4,  PQ3->PA5

    This as all changes I have made in the code:

    typedef enum EK_TM4C129EXL_SPIName {
    	EK_TM4C129EXL_SPI0 = 0,
        EK_TM4C129EXL_SPI2,
        //EK_TM4C129EXL_SPI3,
    
        EK_TM4C129EXL_SPICOUNT
    } EK_TM4C129EXL_SPIName;
    
    
    const SPITivaDMA_HWAttrs spiTivaDMAHWAttrs[EK_TM4C129EXL_SPICOUNT] = {
    	{
    		.baseAddr = SSI0_BASE,
    		.intNum = INT_SSI0,
    		.intPriority = (~0),
    		.scratchBufPtr = &spiTivaDMAscratchBuf[0],
    		.defaultTxBufValue = 0,
    		.rxChannelIndex = UDMA_CHANNEL_SSI0RX,
    		.txChannelIndex = UDMA_CHANNEL_SSI0TX,
    		.channelMappingFxn = uDMAChannelAssign,
    		.rxChannelMappingFxnArg = UDMA_CH10_SSI0RX,
    		.txChannelMappingFxnArg = UDMA_CH11_SSI0TX
    	},
    	{
            .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[1],
    //        .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]
        },
        {NULL, NULL, NULL}
    };
    
    
    void EK_TM4C129EXL_initSPI(void)
    {
    	/* SSI0 */
        SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
    
        GPIOPinConfigure(GPIO_PA2_SSI0CLK);
        GPIOPinConfigure(GPIO_PA3_SSI0FSS);
        GPIOPinConfigure(GPIO_PA4_SSI0XDAT0);
        GPIOPinConfigure(GPIO_PA5_SSI0XDAT1);
    
        GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_2 | GPIO_PIN_3 |
                                        GPIO_PIN_4 | GPIO_PIN_5);
    
        /* SSI2 */
        /*
         * NOTE: TI-RTOS examples configure pins PD0 & PD1 for SSI2 or I2C7.  Thus,
         * a conflict occurs when the I2C & SPI drivers are used simultaneously in
         * an application.  Modify the pin mux settings in this file and resolve the
         * conflict before running your the application.
         */
        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_TM4C129EXL_initDMA();
        SPI_init();
    }
    
    
    // in slaveTaskFxn
    slaveSpi = SPI_open(EK_TM4C129EXL_SPI0, &slaveSpiParams);
    
    
    // in masterTaskFxn
    masterSpi = SPI_open(EK_TM4C129EXL_SPI2, NULL);
    

    There is what I have in the console:

    ROV task Basic:

    ROV task Detailed:

    Execution Graph:

    The processor in the IDLE waiting for the event. So TI-RTOS seems healthy. The problem somewhere in SPI DMA. Unfortunately I do not see any obvious problem with initialization. So need help.

    Thanks.

  • Stan,

    All your changes look correct. The only problem I could identify are your jumper settings; they look incorrect. I used the following jumper settings, and the program works.

    SPI Master: SPI2
    SPI Slave: SPI0

    SCLK:   PD3 --> PA2
    MOSI:   PD1 --> PA5
    MISO:   PD0 --> PA4
    nCS:    PD2 --> PA3

    I have attached my version of the SPI loopback example for your inspection. I started with the example from TI-RTOS and then made the following changes.

    1. Instead of making just one SPI transfer, the program loops forever. The master initiates a SPI transfer once every three seconds.

    2. The master blinks LED D2 on each transfer. The slave blinks LED D3 on each transfer. I added an LED_Object structure. This makes it easy to blink the LED once or several times. The task calls LED_flash to start the flashing. I then use a Clock object to turn off and on the LED for as many flashes as requested.

    3. I removed all calls to System_flush because this is very intrusive. Each time this function is called, CCS actually halts the processor and reads the CIO buffer. Then the processor runs again. This is nice for the user, but can cause problems when using SPI bus at the same time. You will have to halt the processor and use ROV to look at the SysMin buffer. Try to halt the processor between the SPI transfers. The three second delay should make this easy.

    4. Use the Board.h file to define "friendly" names. For example, instead of using EK_TM4C129EXL_SPI2 in the application when calling SPI_open, I define Board_SPI_MASTER in Board.h and use that instead. Note there is a second definition in Board.h for SPI2: Board_WIFI_SPI. This is very confusing. It comes about because the same Board.h file is used for all examples on different devices. This is unfortunate. You can delete these extra defines.

    I think you are very close to making this work.

    ~Ramsey

    3755.SPI_loopback-EK_TM4C129EXL.zip

  • Hi Ramsey,

    You have done really good job! Thanks. Actually my HW jumper settings were right. I just posted a wrong ones. Sorry.

    I tried your code and it did not work as well. Then I checked again my jumpers and found a silkscreen was not clear. On my board PA3 and PA5 look identical. Then I checked the board user guide and yes I confused PA3 and PA5.

    Now everything works! Thanks!

    Stan

  • You are welcome. Thanks for the kind words.

    ~Ramsey