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.

SPI_Transfer with Null Rx buffer fails

Other Parts Discussed in Thread: TM4C129ENCPDT, SYSBIOS

According to the TI0RTOS 1.21 Getting started guide

The txBuf and rxBuf parameters are both pointers to data buffers. If txBuf is NULL, the driver sends SPI
frames with all data bits set to 0. If rxBuf is NULL, the driver discards all SPI frames received.

However when I set up an SPI transaction and set the rxBuf pointer to NULL I get a program termination.

As I am writing to an LCD which cannot supply data back it is very wasteful to need a Receive buffer.

I am using latest TIRTOS release tirtos_1_21_00_09

My code for the transfer works with an Rx buffer, crashes with Rxbuffer set to 0.

// Initialise LCD SPI transaction structure
lcdTransaction.
count = Size;
lcdTransaction.
txBuf = (Ptr)ui8Data;
lcdTransaction.
rxBuf = (Ptr)lcdRxBuffer;


// Initiate SPI transfer
lcdTransferOK =
SPI_transfer(LCD_SPI, &lcdTransaction);

 

  • Hi Barry,

    What device are you using?

    I've have filed a CQ (SDOCM00106237) to remove the need to have both uDMA (Tiva) channels active when you only need one. I'll see to have this escalated to have this fixed in an upcoming release.

    When with rxBuf is set as "NULL" a Tiva driver tries to write the data it receives at address 0x0. In the past revisions of silicon, I didn't see any problems as the data was just silently put into the "bit bucket", but recently (with newer devices) this behavior now generates a uDMA error or perhaps some other exception (rightfully so).

    For now, we'll have to look for a workaround (or you can tweak and rebuild the SPI driver...). Can you provide some more information as to what you mean by "crashing"? Are there any logs printed to the console?

  • Hello Tom

    Sorry for delay in getting back, have been away for work.

    The processor I am using is the TM4C129ENCPDT

    The exception was was an access of invalid address (I am assumming a write to 00000000)  I am going through and testing all the modules one by one under the ICD interface from CCE V5.1

    If you have a suggestion as to how to tweak the SPI code for now, that would be great.

  • What type of exception? Hardfault? Is there some exception log printed?

    TI-RTOS example board files install a DK_TM4C129X_errorDMAHwi Hwi function. You might be getting an error because of the uDMA.

    What silicon revision of the 129X do you have?

  • Chip is marked as follows:

    XM4C129

    ENCPDTI1

    3AC0E3w

    G4

    The error I get is:

    failure: A_badContext: bad calling context. See GateMutex API doc for details.

    xdc.runtime.Error.raise: terminating execution

    The code goes to loader_exit

    Stack trace  shows failure on assert in ti_sysbios_gates_GateMutex_enter

    HOSTwrite is the function from which the exception occurs

  • Barry,

    The SPI driver doesn't use a GateMutex. Are you using the SPI driver in callback mode? If so, the callback function gets called in a Hwi context. You can't enter a gate within a Hwi (because it can't block).

  • I am using the SPI in blocking mode..

    // Initialise SPI handle with Master mode

    SPI_Params_init(&lcdSpiParams);

    lcdSpiParams.mode = SPI_MASTER;

    lcdSpiParams.frameFormat = SPI_POL1_PHA1; // clock high in idle, clock on rising edge

    lcdSpiParams.transferMode = SPI_MODE_BLOCKING;

    lcdSpiParams.dataSize = 8;

    lcdSpiParams.bitRate = 250000;

    LCD_SPI = SPI_open(Board_SPI3, &lcdSpiParams);

     

    The only thing I changed for the error to occur was to set the RxBuffer pointer to NULL

    // Initialise LCD SPI transaction structure

    lcdTransaction.count = Size;

    lcdTransaction.txBuf = (Ptr)ui8Data;

    lcdTransaction.rxBuf = (Ptr)lcdRxBuffer;

    // Initiate SPI transfer

    lcdTransferOK = SPI_transfer(LCD_SPI, &lcdTransaction);

     

    works fine but

     

    // Initialise LCD SPI transaction structure

    lcdTransaction.count = Size;

    lcdTransaction.txBuf = (Ptr)ui8Data;

    lcdTransaction.rxBuf = NULL;

    // Initiate SPI transfer

    lcdTransferOK = SPI_transfer(LCD_SPI, &lcdTransaction);

     

    Gives me the exception

    I just tried again (Changing only the RxBuffer to NULL, all other code unchanged) and got the same exception

  • Hi Barry,

    sorry for the late reply (I dropped the ball on this one). Can you send me your CCS project? I'd like to build it and see where the exception is happening.

  • Hello Tom

    I have simplified project back from my complete project, still fails with same exception.

    ST7565.c has the code which causes issue

    // lcdTransaction.rxBuf = (Ptr)lcdRxBuffer; // This works

    lcdTransaction.rxBuf = 0; // This Fails

    4188.RM3118_TIVA_SPI.zip

  • Sorry please use this zip file.

    Previous one had config changes to move reset vectors from 0 for use with bootloader.

    This one is correct.

    3731.RM3118_TIVA_SPI.zip

  • Hello Tom

    Do you need anything else to investigate this?

    Barry

  • Hi Barry,

    sorry for the long wait.

    The gatemutex comes from the DMA Error Hwi that was created in the board.c. Removing the DMA error Hwi will prevent the interrupt (and gatemutex error); however, the uDMA will not transfer the complete data set over the wire.

    You have 2 options:

    1. With the current version of the driver in 1.21 you need to supply  a dummy (scratch) buffer of size "transaction.count".
    2. The 2nd option is to take an engineering version of the driver (which I've stress-tested myself) which will be made available in the next release of TI-RTOS. The instructions to build the driver is listed below:

    To add the engineering SPI drivers: (You probably will want to make a backup of this files first):

    • Extract the zip file over  your TI-RTOS installation; default is "C:\TI". It will replace the SPITivaDMA driver files and replace the board files for the examples. 5516.tirtos_1_21_00_09_SPITivaDMA_fix.zip
      • If you want to modify your board files directly, add in the spiTivaDMAscratchBuf pointer into the spiTivaDMAHWAttrs[] as shown here:

    #include <ti/drivers/SPI.h>
    #include <ti/drivers/spi/SPITivaDMA.h>
    
    /* SPI objects */
    SPITivaDMA_Object spiTivaDMAobjects[A30307P26_SPICOUNT];
    
    #pragma DATA_ALIGN(spiTivaDMAscratchBuf, 32)
    ULong   spiTivaDMAscratchBuf[A30307P26_SPICOUNT];
    
    /* SPI configuration structure, describing which pins are to be used */
    const SPITivaDMA_HWAttrs spiTivaDMAHWAttrs[A30307P26_SPICOUNT] = {
        {
            SSI0_BASE,
            INT_SSI0,
            &spiTivaDMAscratchBuf[0],
            0,
            UDMA_CHANNEL_SSI0RX,
            UDMA_CHANNEL_SSI0TX,
            uDMAChannelAssign,
            UDMA_CH10_SSI0RX,
            UDMA_CH11_SSI0TX
        },
        {
            SSI1_BASE,
            INT_SSI1,
            &spiTivaDMAscratchBuf[1],
            0,
            UDMA_SEC_CHANNEL_UART2RX_12,
            UDMA_SEC_CHANNEL_UART2TX_13,
            uDMAChannelAssign,
            UDMA_CH12_SSI2RX,
            UDMA_CH13_SSI2TX
        },
        {
            SSI3_BASE,
            INT_SSI3,
            &spiTivaDMAscratchBuf[2],
            0,
            UDMA_SEC_CHANNEL_TMR2A_14,
            UDMA_SEC_CHANNEL_TMR2B_15,
            uDMAChannelAssign,
            UDMA_CH14_SSI3RX,
            UDMA_CH15_SSI3TX
        }
    };

    • Rebuild TI-RTOS drivers (see the user manual) (..\xdctools_3_25_04_88\gmake.exe -f tirtos.mak drivers)
    • Rebuild your application or import a new spiloopback example from TI Resource explorer.

    Please, let me know if you have any problems with it.

  • Thanks for that Tom.

    I am doing option 1 at the moment.

    Any idea when new version will be released?

    Barry

  • Barry,

    TI-RTOS 2.00.02 release is scheduled for early-mid June.