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.

TMS320C6748: Using DMA in SPI adds extra time overhead before and after SPI transaction

Part Number: TMS320C6748
Other Parts Discussed in Thread: OMAPL138

I am trying to use DMA for SPI in C6748 DSP. Using DMA would add an additional time after CS (around 8 us) and 21 us at the end of SPI transaction

SDK used : processor_sdk_rtos_omapl138_6_03_00_106

I found a related issue in https://e2e.ti.com/support/legacy_forums/embedded/tirtos/f/355/t/98047?SPI-DMA-timing
But rebuilding the EDMA drivers as suggested in the thread doesnot help.

Could you please let me know what could be the possible reason for this additional time and how to remove this?

  

  • Hello,

    Can you confirm you have tried building your application using the release version of the EDMA lib? This can be done by adding the following to your projects .cfg file:

    var Edma        	= xdc.loadPackage ("ti.sdo.edma3.drv.sample");
    var drv        		= xdc.loadPackage ("ti.sdo.edma3.drv");
    var rm        		= xdc.loadPackage ("ti.sdo.edma3.rm");
    
    Edma.profile="release";
    drv.profile="release";
    rm.profile="release";

    You can also verify it is using the release lib by checking the linking phase of the build log, you should see something like this:

    Inside EDMA3 Drv getLibs
        will link with ti.sdo.edma3.drv:lib/674/release/edma3_lld_drv.ae674

    This indicates it is correctly linking the release version of the EDMA3 Drv lib. 

    If you have already tried this, please share a register dump of the SPI. Do you have CSHOLD enabled?

    Regards,
    Sahin

  • Hi Sahin,

    Thanks for the quick response. 

    Yes, we are using release versions of the EDMA libraries. 

    Seems like the CSHOLD bit is enabled in the SPIDAT1 register after initialization of the SPI peripheral using SPI_open file. Please find the register dump in the attached file (SPI peripheral used is SPI1)

    A quick dig through the driver code revealed that the CSHOLD bit is set after 

     SPIData1Setup(hwAttrs->baseAddr, SPI_DELAY_ON, hwAttrs->csNum); function call in SPI_open_v0 (in SPI_v0.c)

    Do we have any options to disable the CSHOLD through the SPI driver? 

    Note : In my application, I am controlling the chip select lines without using the SPI driver.0486.Register dump.txt

  • Hi Sahin, 

    I tried clearing the CSHOLD bit as shown below after the SPI_open function is called. 

        uint32_t spiDat1Reg = spiCfg.baseAddr + CSL_SPI_SPIDAT1;
        HWREG(spiDat1Reg)  &= ~CSL_SPI_SPIDAT1_CSHOLD_MASK;

    As per the function SPI_primeTransfer_v0, I assume the CSHOLD will not be set back when using DMA transfer. 

    Even after with the above mentioned change, I am observing a similar waveform (SPI with DMA) shared above. 

  • Hi ,

    We are still unable to find the root cause of the delays. Could you please guide us in further debugging the issue? 

  • Hello,

    Sorry for the delay, I have been out of office. 

    • Are you using polling mode or blocking mode? Do you see any difference in latency between the two modes? 

    • Please make sure the RXINTEN bit in SPIINT0 is cleared to 0 when the DMA is being used to service received data from the SPI. This prevents the CPU from responding to the received data in addition to the DMA.

    • It appears the "csHold" field is set to on at the beginning of SPI_primeTransfer_v0(), please make sure this isn't overwriting your code.
    uint32_t                 csHold = SPI_CSHOLD_ON;
    
    • From looking at your register dump, it does appear CSHOLD in SPIDAT1 is still enabled. Was this register dump taken before you added the logic to disable CSHOLD?

    Regards,
    Sahin


  • Hi Sahin,

    Please find the responses in blue

    • Are you using polling mode or blocking mode? Do you see any difference in latency between the two modes? 
      operMode parameter of SPI_v0_Object structure will be SPI_OPER_MODE_BLOCKING if we use the DMA mode. If we don't use the DMA mode this parameter will be SPI_OPER_MODE_POLLING.

      There is a difference in the latency with these two modes. With DMA, we have a initial setup time of around 8 us and close time(after the end of transaction) of 20 us. In case if DMA is not used, the startup and close time is 3 us each. Please refer to the waveforms "SPI with DMA" and "SPI without DMA" shared initially.

    • Please make sure the RXINTEN bit in SPIINT0 is cleared to 0 when the DMA is being used to service received data from the SPI. This prevents the CPU from responding to the received data in addition to the DMA.
      RXINTEN bit in SPIINT0 register is always disabled (Cleared to zero)

    • It appears the "csHold" field is set to on at the beginning of SPI_primeTransfer_v0(), please make sure this isn't overwriting your code.

    This code is not overwriting the CSHOLD bit value in the register. When we use DMA, I assume the the csHold variable in the SPI_primeTransfer_v0() function is not used. I have also verified that CSHOLD is not getting set during transaction.

    • From looking at your register dump, it does appear CSHOLD in SPIDAT1 is still enabled. Was this register dump taken before you added the logic to disable CSHOLD?

    This register dump shared before was taken before I added the logic to disable CSHOLD. Please find the register dump after a SPI transaction attached with this post.RegisterDump.txt

  • Hi

    It would be really helpful if you could look into the responses above and let me know how we can debug this further.

  • To debug the issue further few GPIO toggles were inserted in functions of SPI_dma.c specifically
    in SPI_dmaTransfer and SPI_dmaRxIsrHandler functions.

    As mentioned in link, the delay seems to be introduced by EDMA3_DRV_getPaRAM() and EDMA3_DRV_setPaRaM()
    functions in SPI_dmaTransfer function.

    Also after the transaction, there is delay of around 11 us for the SPI_dmaRxIsrHandler function to be called. The transfer complete semaphore is released only at E.


    A - SPI transfer is called. CS is made low using GPIO_write function separately
    B - Actual SPI transactions here

    Duration between A and B - 10 microseconds

    C- End of SPI transaction. Transfer 12 bytes in 6.8 microseconds (SPI clock is 15 MHz)
    D- SPI_dmaRxIsrHandler function is called here

    Duration between C and D - 11.4 microseconds


    E - SPI transfer function unblocks here.


    Total transaction duration - A to E - around 41.6 microseconds

  • Hi Harikrishnan,

    Thank you for the detailed summary of the issue. I have relayed this to the software design team and will post a reply here once I have received a response.

    Regards,
    Sahin