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-PROC: TMDSEVM6657 - SPI_transfer stuck

Part Number: TI-RTOS-PROC
Other Parts Discussed in Thread: TMDSEVM6657, SYSBIOS, OMAPL138

Hi, I am working with TMDSEVM6657 evaluation board. I am trying to establish simple SPI transmission to CS0 port. 

If I set the spiParams.transferTimeout = SPI_WAIT_FOREVER; then it gets stuck in SPI_transfer line (waiting for the semaphore), and if I set the transfer timeout to be a certain number, then it finishes transfer with the message SPI_TRANSFER_TIMEOUT. 

I am using the SPI_BasicExample_C6657_c66xExampleProject, where I only changed the main_spi_flash_read_example.c file, nothing else. 

This is what I use:

 

This is how my code looks:

#ifndef BARE_METAL
/* XDCtools Header files */
#include <xdc/std.h>
#include <xdc/cfg/global.h>
#include <xdc/runtime/System.h>
#include <stdio.h>
#include <xdc/runtime/Error.h>

/* BIOS Header files */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#endif

/* SPI Header files */
#include <ti/drv/spi/SPI.h>
#if defined(SOC_K2H) || defined(SOC_K2K) || defined(SOC_K2E) || defined(SOC_K2L) || defined(SOC_K2G) || defined(SOC_C6678) || defined(SOC_C6657) || defined(SOC_OMAPL137) || defined(SOC_OMAPL138)
#include <ti/drv/spi/src/v0/SPI_v0.h>
#endif
#include <ti/drv/spi/soc/SPI_soc.h>
#include <ti/drv/spi/test/src/SPI_log.h>
#include <ti/drv/spi/test/src/SPI_test.h>

/* Board Header files */
#include <ti/board/board.h>
#include <ti/board/src/flash/include/board_flash.h>

//Char myTaskStack[1024];
//Task_Struct myTaskStruct;
bool loop = true;

SPI_Handle spiHandle;
SPI_Params spiParams;
SPI_Transaction spiTransaction;
/*
* ======== Board_initSPI ========
*/
void Board_initSPI(void)
{
Board_initCfg boardCfg;
SPI_v0_HWAttrs spi_cfg;
Board_SoCInfo socInfo;
bool boardStatus;

/* Get the default SPI init configurations */
SPI_socGetInitCfg(0, &spi_cfg);

/* Update the SPI functional clock based on CPU clock*/
Board_getSoCInfo(&socInfo);
if(socInfo.sysClock != BOARD_SYS_CLK_DEFAULT)
{
spi_cfg.inputClkFreq = socInfo.sysClock/SPI_MODULE_CLOCK_DIVIDER;
}

/* Set the default SPI init configurations */
SPI_socSetInitCfg(0, &spi_cfg);


boardCfg = BOARD_INIT_PINMUX_CONFIG |
BOARD_INIT_MODULE_CLOCK |
BOARD_INIT_UART_STDIO;

boardStatus = Board_init(boardCfg);

if (boardStatus != BOARD_SOK)
{

printf("Board not OK!");
}
else{
printf("Board OK!");
}
}

/*
* ======== test function ========
*/
#ifdef BARE_METAL
void main()
#else
void spi_test(UArg arg0, UArg arg1)
#endif
{
bool transferOK;
SPI_v0_HWAttrs const *hwAttrs = NULL;
SPI_v0_Object *object = NULL;

#ifdef BARE_METAL
/* Call board init functions */
Board_initSPI();
#endif

System_printf("Start SPI task\n");

SPI_Params_init(&spiParams);
spiParams.transferMode = SPI_MODE_BLOCKING;
//spiParams.transferTimeout = SPI_WAIT_FOREVER;
spiParams.transferTimeout = 1000;
spiParams.transferCallbackFxn = NULL;
spiParams.mode = SPI_MASTER;
//spiParams.bitRate = 1000000;
//spiParams.dataSize = 8;
spiHandle = SPI_open(0, &spiParams);

if (!spiHandle)
{
printf("\n SPI_open failed. \n");
}

hwAttrs = (const SPI_v0_HWAttrs *)spiHandle->hwAttrs;
object = (SPI_v0_Object*)spiHandle->object;

while (loop) {

uint8_t transmitBuffer[1];
//uint8_t receiveBuffer[1];

transmitBuffer[0] = 0x01;

spiTransaction.count = 2;
spiTransaction.txBuf = transmitBuffer;
spiTransaction.rxBuf = NULL;

transferOK = SPI_transfer(spiHandle, &spiTransaction);
//printf("loop");
if (!transferOK){
printf("\nSPI transfer failed!\n");}
//printf("%x",receiveBuffer[0]);


}

}

/*
* ======== main ========
*/
#ifndef BARE_METAL
int main(void)
{
System_printf("Start Setup\n");

/* Call board init functions */
Board_initSPI();

/* Configure task. */
//Task_Params taskParams;
//Task_Params_init(&taskParams);
//taskParams.stack = myTaskStack;
//taskParams.stackSize = sizeof(myTaskStack);
//Task_construct(&myTaskStruct, spi_test, &taskParams, NULL);

System_printf("End Setup\n");


/* Start BIOS */
BIOS_start();
return (0);
}
#endif

Here is how the hwAttrs and object variables look like after opening the SPI_open:

And here is the outline of Variables before returning from SPI_transfer function in case when spi timeout is 1000:

What could be the reason for this?

If I can provide more information, please let me know.

Kind regards,

Dejana

  • Hello,

    What is the slave device in this case? Do you see anything on the pins at all? Any scope shots you can provide would help. 

    If you can provide a snapshot of the SPI registers before and after starting the transfer that would help as well. 

    I noticed you did not specify a frame format. The default is SPI_POL0_PHA0, please ensure this matches what the slave device expects.

    You also did not specify a pin mode, I believe the default is 3-pin mode. If you want to use CS, e.g., 4-pin mode, you can add the following in Board_initSPI().:

    spi_cfg.pinMode = SPI_PINMODE_4_PIN;

    You can also do this in spi_soc.c but you will need to rebuild the driver afterwards. 

    EDIT: Just saw pinMode is 1 in your variable window which indicates 4-pin mode so this is not the problem.

    You may also need to disable interrupts if not using them: 

    spi_cfg.enableIntr = false;

    Regards,
    Sahin

  • Hi Sahin, 

    The slave device is SPI NOR flash  - N25Q032A11ESE40F, which is located on the board. My plan is to take it off the board and use the SPI interface to communicate to data converters. I wanted to test SPI code before taking off the SPI NOR flash. 

    The data format that SPI NOR expects is SPI_POL0_PHA0, as per datasheet https://www.micron.com/products/nor-flash/serial-nor-flash/part-catalog/n25q032a11ese40f.  I have disabled the interrupts, but it still behaves on the same way. I will send you the scope shots but I will probably not be able to provide them before Monday. Should I expect to see the CLK signal as soon as the transfer is started?

    Here are the registers that I see, but I don't recognize the SPI registers:

    Shouldn't they be here?

    Kind regards,

    Dejana

  • Dejana,

    The SPI registers are not necessarily in the CCS register window. You may use the CCS memory window for that, the datasheet shows the SPI registers starts from 0x20BF0000.

    With the original SPI_BasicExample_C6657_c66xExampleProject test, you can test the SPI NOR flash on the EVM board without issue, correct? I am a little bit lost. Then you are figuring out how to change it to another device connected through expansion header? 

    Regards, Eric

  • Hi Eric,

    I have removed the SPI NOR flash from the board and I am using the SPI pins to communicate to other devices.

    I have found the solution to my problem, I haven't implemented the code correctly, therefore I wasn't enabling SPI transfer and that is why I had problems.

    Now it functions.

    Thank you for your support.

    Kind regards,

    Dejana

  • Hi Dejana,

    I got stuck at SPI_transfer() either. Please tell me how you solved it. Thanks in advance.

    Below is my code for SPI. Which part I need to modify to make SPI_transfer work?

    SPI_Params     params;
        SPI_Handle     handle;
        spiDataMsg    *spiMsg;
    
        SPI_Params_init(&params);
    
        params.mode = SPI_SLAVE;
        params.u.slaveParams.dmaCfg.txDmaChanNum =1U;
        params.u.slaveParams.dmaCfg.rxDmaChanNum =0U;
    
        /* Enable DMA and set DMA channels */
        params.dmaEnable = 1;
        params.dmaHandle = gDmaHandle;
    
        params.frameFormat = SPI_POL0_PHA0;
        params.pinMode = SPI_PINMODE_4PIN_CS;
    	params.transferMode = SPI_MODE_BLOCKING;
        params.transferTimeout = SPI_WAIT_FOREVER;
        params.bitRate  = 1000000;
        params.dataSize = 8;
    
        handle = SPI_open(0, &params);
        if (handle == NULL)
        {
            System_printf("Error: Unable to open the SPI Instance\n");
            return;
        }
    
        SPI_Transaction transaction;
        /* Configure Data Transfer */
        transaction.count = SPI_TEST_MSGLEN;
        transaction.txBuf = (void *)txBuf;
        transaction.rxBuf = (void *)rxBuf;
        //transaction.slaveIndex = 0U;
    
        /* Start Data Transfer */
        if (SPI_transfer(handle, &transaction) != true)
        {
            System_printf("Unsuccessful SPI transfer");
        }
       
        else
        {
            System_printf("SPI transfer OK\n");
        }