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/TM4C1294NCPDT: SPI_transfer() crashes for SPI1

Part Number: TM4C1294NCPDT

Tool/software: TI-RTOS

Respected sir,

                 I am using all the SSI modules. SSI 0,2,3 works fine but SSI1 crashes at SPI_transfer(). After debugging i found the problem in following statement in SPITivaDMA.c file.

                         if (!Semaphore_pend(Semaphore_handle(&(object->transferComplete)),
                            object->transferTimeout))

               I have tried following solution from Forum

        1. Selecting right device in properties->general->device.   2. I have used ROV for stack level checking but all stacks seems ok.  3. I have increased stack size for HWI.

               But none of above works. I have attached snaps of ROV and SSI module configuration code.

Void spiFxn (UArg arg0, UArg arg1)
{
   // SPI_Handle masterSpi;
   // SPI_Transaction masterTransaction;
   // bool transferOK;
//************************************SPI FOR DAC*************************************
    /* Initialize SPI handle as default master */
    SPI_Params spiParamsdac;
    SPI_Params_init(&spiParamsdac);
    spiParamsdac.transferMode = SPI_MODE_BLOCKING;
    spiParamsdac.transferTimeout = SPI_WAIT_FOREVER;
    spiParamsdac.transferCallbackFxn = NULL;
    spiParamsdac.mode = SPI_MASTER;
    spiParamsdac.bitRate = 1000000;
    spiParamsdac.dataSize =8;
    spiParamsdac.frameFormat =SPI_POL1_PHA1;
    spiParamsdac.custom =(uintptr_t) NULL;
	masterSpi = SPI_open(Board_SPI1, &spiParamsdac); //  change the cs pin to GPIO???????
    if (masterSpi == NULL) {
        System_abort("Error initializing DAC_SPI\n");
    }
    else {
//        System_printf("DAC_SPI initialized\n");
//        System_flush();
    }

    /* Initialize master SPI transaction structure */
    masterTransaction.count = SPI_MSG_LENGTH;
    masterTransaction.txBuf = (Ptr)masterTxBuffer;
    masterTransaction.rxBuf = (Ptr)masterRxBuffer;
    GPIO_write(Board_LDAC, 0);  // LDAC PIN OF DAC ALWAYS KEEP LOW
//***************************SPI FOR ADC*************************************************

    SPI_Params spiParams;
    SPI_Params_init(&spiParams);
    spiParams.transferMode = SPI_MODE_BLOCKING;
    spiParams.transferTimeout = SPI_WAIT_FOREVER;
    spiParams.transferCallbackFxn = NULL;
    spiParams.mode = SPI_MASTER;
    spiParams.bitRate = 1000000;
    spiParams.dataSize =16;
    spiParams.frameFormat =SPI_POL1_PHA0;
    spiParams.custom =(uintptr_t) NULL;
    adcSpi = SPI_open(Board_SPI0, &spiParams);
    if (adcSpi == NULL) {
        System_abort("Error initializing ADC_SPI\n");
    }
    else {
//        System_printf("ADC_SPI initialized\n");
//        System_flush();
    }

    /* Initialize master SPI transaction structure */
    adcTransaction.count = ADC_SPI_MSG_LENGTH;
    adcTransaction.txBuf = (Ptr)adcTxBuffer;
    adcTransaction.rxBuf = (Ptr)adcRxBuffer;

//    GPIO_write(Board_ADC_CONVST, Board_LED_ON);
   // User specific code, enable interrupts:
    Xint1Count = 0;   // Count XINT1 interrupts
	TimerCount = 0;   // Count Timer0 interrupts
    LoopCount = 0;    // Count times through idle loop
	Flag = 0;
	Reg_Word = 0;

	// Initialize Buffer Tables
   for (n=0; n<BUF_SIZE; n++)
   {
    ADS833x_Buf[n] = n;
   }

   for (n=0; n<SIZE; n++)
   {
    ADS833x_Result[n] = n;
   }


   ADS833x_init();

   // Step 6. IDLE loop:
       // Select input Channel if Manual Channel Selection is enabled in CFR register
   	ADS833x_Buf[2] = ADS833x_CFR_Reg & 0x0800;
   	if (ADS833x_Buf[2] == 0)
   	{
        System_printf("\n manual channel select\n");
        System_flush();
       Channel_Number = 0;      // Should be 0~7,Channel number for Manual channel select
       ADS833x_Channel_Select(Channel_Number);   // Select ADC input channel
       }
   	timerFlag = 1;
//**************************************************END ADC******************************************************
//**************************************************ABSOLUTE ENCODER*************************************
//**************************************************Channel 0*************************************
    SPI_Params spiParamsabsa;
    SPI_Params_init(&spiParamsabsa);
    spiParamsabsa.transferMode = SPI_MODE_BLOCKING;
    spiParamsabsa.transferTimeout = SPI_WAIT_FOREVER;
    spiParamsabsa.transferCallbackFxn = NULL;
    spiParamsabsa.mode = SPI_MASTER;
    spiParamsabsa.bitRate = 295000; //295K
    spiParamsabsa.dataSize =16;
    spiParamsabsa.frameFormat = SPI_POL1_PHA1;
    spiParamsabsa.custom =(uintptr_t) NULL;
    absaSpi = SPI_open(Board_SPI2, &spiParamsabsa);
    if (absaSpi == NULL) {
        System_abort("Error initializing ABSA_SPI\n");
    }
    else {
        System_printf("ABSA_SPI initialized\n");
        System_flush();
    }

    /* Initialize master SPI transaction structure */
    absaTransaction.count = ABSA_SPI_MSG_LENGTH;
    absaTransaction.txBuf = (Ptr)absaTxBuffer;
    absaTransaction.rxBuf = (Ptr)absaRxBuffer;

    //**************************************************Channel 1*************************************

    SPI_Params spiParamsabsb;
    SPI_Params_init(&spiParamsabsb);
    spiParamsabsb.transferMode = SPI_MODE_BLOCKING;
    spiParamsabsb.transferTimeout = SPI_WAIT_FOREVER;
    spiParamsabsb.transferCallbackFxn = NULL;
    spiParamsabsb.mode = SPI_MASTER;
    spiParamsabsb.bitRate = 250000;
    spiParamsabsb.dataSize =16;
    spiParamsabsb.frameFormat =SPI_POL1_PHA0;
    spiParamsabsb.custom =(uintptr_t) NULL;
    absbSpi = SPI_open(Board_SPI3, &spiParamsabsb);
    if (absbSpi == NULL) {
        System_abort("Error initializing ABSB_SPI\n");
    }
    else {
        System_printf("ABSB_SPI initialized\n");
        System_flush();
    }

    /* Initialize master SPI transaction structure */
    absbTransaction.count = ABSB_SPI_MSG_LENGTH;
    absbTransaction.txBuf = (Ptr)absbTxBuffer;
    absbTransaction.rxBuf = (Ptr)absbRxBuffer;
//**************************************************END ABSOLUTE ENCODER*************************************

}


/*
 *  =============================== SPI ===============================
 */
/* Place into subsections to allow the TI linker to remove items properly */
#if defined(__TI_COMPILER_VERSION__)
#pragma DATA_SECTION(SPI_config, ".const:SPI_config")
#pragma DATA_SECTION(spiTivaDMAHWAttrs, ".const:spiTivaDMAHWAttrs")
#endif

#include <ti/drivers/SPI.h>
#include <ti/drivers/spi/SPITivaDMA.h>

SPITivaDMA_Object spiTivaDMAObjects[EK_TM4C1294XL_SPICOUNT];

#if defined(__TI_COMPILER_VERSION__)
#pragma DATA_ALIGN(spiTivaDMAscratchBuf, 32)
#elif defined(__IAR_SYSTEMS_ICC__)
#pragma data_alignment=32
#elif defined(__GNUC__)
__attribute__ ((aligned (32)))
#endif
uint32_t spiTivaDMAscratchBuf[EK_TM4C1294XL_SPICOUNT];

const SPITivaDMA_HWAttrs spiTivaDMAHWAttrs[EK_TM4C1294XL_SPICOUNT] = {
    {
        .baseAddr = SSI2_BASE,
        .intNum = INT_SSI2,
        .intPriority = (~0),
        .scratchBufPtr = &spiTivaDMAscratchBuf[0],
        .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
    },
    {
        .baseAddr = SSI0_BASE,
        .intNum = INT_SSI0,
        .intPriority = (~0),
        .scratchBufPtr = &spiTivaDMAscratchBuf[2],
        .defaultTxBufValue = 0,
        .rxChannelIndex = UDMA_SEC_CHANNEL_SSI1RX,
        .txChannelIndex = UDMA_SEC_CHANNEL_SSI1TX,
        .channelMappingFxn = uDMAChannelAssign,
        .rxChannelMappingFxnArg = UDMA_CH10_SSI0RX,
        .txChannelMappingFxnArg = UDMA_CH11_SSI0TX
    },
    {
        .baseAddr = SSI1_BASE,
        .intNum = INT_SSI1,
        .intPriority = (~0),
        .scratchBufPtr = &spiTivaDMAscratchBuf[3],
        .defaultTxBufValue = 0,
        .rxChannelIndex = UDMA_SEC_CHANNEL_SSI1RX,
        .txChannelIndex = UDMA_SEC_CHANNEL_SSI1TX,
        .channelMappingFxn = uDMAChannelAssign,
        .rxChannelMappingFxnArg = UDMA_CH10_SSI1RX,
        .txChannelMappingFxnArg = UDMA_CH11_SSI1TX
    }
};

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]
    },
    {
        .fxnTablePtr = &SPITivaDMA_fxnTable,
        .object = &spiTivaDMAObjects[3],
        .hwAttrs = &spiTivaDMAHWAttrs[3]
    },
    {NULL, NULL, NULL}
};

/*
 *  ======== EK_TM4C1294XL_initSPI ========
 */
void EK_TM4C1294XL_initSPI(void)
{
    /* 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);

//    GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE,GPIO_PIN_2);
//    GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_2, 4);

    /* 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_2 | GPIO_PIN_3);

    GPIOPinTypeGPIOOutput(GPIO_PORTQ_BASE,GPIO_PIN_1);
    GPIOPinWrite(GPIO_PORTQ_BASE, GPIO_PIN_1,2);

//********************************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);
//********************************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);

    EK_TM4C1294XL_initDMA();
    SPI_init();
}

  • Hi Digvijay,

    Can you elaborate on what you mean by crash? Do you get an exception, hang, or API failure.

    Todd
  • Respected sir,
    Thank you for the reply. The issue has been solved. The DMA channel for SSI1 were conflicting with DMA channel for SSI0. When i changed DMA channel problem got solved.

    Regards,
    Digvijay
  • Digvijay,

    I'm having similar trouble with using SSI1 and have found this post to be very helpful.  I can get SSI2 and SSI3 working just fine.  However, I'm having great difficulty with SSI1.  Would you mind posting your DMA configuration solution as a reference?  Did you have to change the DMA Channel Map Select and Index?  Are there other register setup requirements for SSI1 not necessarily needed for SSI3?  I've posted this question to the forum (link) and would greatly appreciate any help you could provide.  Thank you!

  • My trouble was also with the uDMA channel although I'm not clear why as I never defined the SSI0 as a conflicting code as you found in your own.   Please find the included code for future reference.  Does this look OK?  Feel free to suggest changes if you see something wrong.  Seems to work on the Launchpad board.

    Ryan

    const SPITivaDMA_HWAttrs spiTivaDMAHWAttrs[EK_TM4C1294XL_SPICOUNT] = {
       {
             .baseAddr = SSI1_BASE,
            .intNum = INT_SSI1,
            .intPriority = (~0),
            .scratchBufPtr = &spiTivaDMAscratchBuf[0],
            .defaultTxBufValue = 0,
            .rxChannelIndex = 24,
            .txChannelIndex = 25,
            .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
        }
    };

  • Hi ,

           SSI configuration looks ok. If still creating DMA conflict problem, my guess is may be it is conflicting with other peripheral which uses DMA cannels. As I am not in office I am not able to give you detailed information.

    Regards,

    Digvijay

  • Hi I also very interested to see complete code that you fixed, can u please provide, thanks.

    I find it strange why there no SPI version of UDMA_SEC_CHANNEL_UART2RX_12?, what this rxChannelIndex/txChannelIndex really mean?
  • hi richard,
    Here is the code with the changes i have made.

    const SPITivaDMA_HWAttrs spiTivaDMAHWAttrs[EK_TM4C1294XL_SPICOUNT] = {
    {
    .baseAddr = SSI2_BASE,
    .intNum = INT_SSI2,
    .intPriority = (~0),
    .scratchBufPtr = &spiTivaDMAscratchBuf[0],
    .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
    },
    {
    .baseAddr = SSI0_BASE,
    .intNum = INT_SSI0,
    .intPriority = (~0),
    .scratchBufPtr = &spiTivaDMAscratchBuf[2],
    .defaultTxBufValue = 0,
    .rxChannelIndex = UDMA_SEC_CHANNEL_SSI1RX,
    .txChannelIndex = UDMA_SEC_CHANNEL_SSI1TX,
    .channelMappingFxn = uDMAChannelAssign,
    .rxChannelMappingFxnArg = UDMA_CH10_SSI0RX,
    .txChannelMappingFxnArg = UDMA_CH11_SSI0TX
    },
    {
    .baseAddr = SSI1_BASE,
    .intNum = INT_SSI1,
    .intPriority = (~0),
    .scratchBufPtr = &spiTivaDMAscratchBuf[3],
    .defaultTxBufValue = 0,
    .rxChannelIndex = UDMA_SEC_CHANNEL_ADC10,
    .txChannelIndex = UDMA_SEC_CHANNEL_ADC11,
    .channelMappingFxn = uDMAChannelAssign,
    .rxChannelMappingFxnArg = UDMA_CH24_SSI1RX,
    .txChannelMappingFxnArg = UDMA_CH25_SSI1TX
    }
    };


    Regards,
    Digvijay.