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.

How to reduce delay between SPI packets? OMAPL138 - SPI - ADC (ADS8361)

Other Parts Discussed in Thread: OMAPL138, ADS8361

Hello,

I am trying to make an OMAPL138 DSP core talk with a 500ksps ADC (ADS8361) via SPI1. Since ADS8361 doesnt have a specific SPI port, I am sending 0xC0,0x00 and 0x00 as SIMO to the RD line of ADS8361 and reading 24 bits from the Data A of ADS8361 as SOMI (see the code snippet below). I am using PSP 1.30 and BIOS 5.41.

=================================

spiParams = Spi_PARAMS;

spiParams.hwiNumber = 8;
spiParams.spiHWCfgData.intrLevel = FALSE;
spiParams.opMode = Spi_OpMode_POLLED;

spiParams.outputClkFreq     = 20000000;
spiParams.loopbackEnabled   = FALSE;
spiParams.edmaHandle        = NULL;
   
spiParams.spiHWCfgData.pinOpModes = Spi_PinOpMode_SPISCS_4PIN;

spiParams.spiHWCfgData.configDatafmt[0].charLength   = 8;
   
spiParams.spiHWCfgData.configDatafmt[0].clkHigh      = TRUE ;
spiParams.spiHWCfgData.configDatafmt[0].lsbFirst     = FALSE;
spiParams.spiHWCfgData.configDatafmt[0].oddParity    = FALSE;
spiParams.spiHWCfgData.configDatafmt[0].parityEnable = FALSE ;
spiParams.spiHWCfgData.configDatafmt[0].phaseIn      = FALSE ;
spiParams.spiHWCfgData.configDatafmt[0].waitEnable   = FALSE;
spiParams.spiHWCfgData.configDatafmt[0].wDelay   = 0;
   
spiParams.spiHWCfgData.intrLevel     = TRUE;
   
spiParams.spiHWCfgData.waitDelay  = FALSE;

=================================

loopWrite[0] = 0xC0;
loopWrite[1] = 0x00;
loopWrite[2] = 0x00;
 
dataparam.bufLen       = 0x03;
dataparam.inBuffer     = &loopRead[0];
dataparam.outBuffer    = &loopWrite[0];
dataparam.flags        = Spi_CSHOLD;
dataparam.dataFormat   = Spi_DataFormat_0;
dataparam.chipSelect = 0x08;
   
size = dataparam.bufLen;
   
GIO_write(spiHandle, &dataparam, &size);

=================================

However, between the three 8 bit transmissions and after the last transmission, there is a huge gap (see scope shot below). These gaps effectively results in limiting the maximum sampling rate of the ADC to ~123ksps, which is way below than the 500ksps supported by the ADC.

I have all the delays set to zero and cant find what could be causing this issue. Can someone please help me reduce these "inter-packet" gaps and resolve this issue?

DSP/BIOS: 5.41.10.36

PSP: 1.30.00.06

CGT: 6.1.19

Development Board: OMAPL138 Experimenter

Thanks

Joe

  • Hi Joseph,

     

    I am currently looking into the issue, and will try to reproduce the same in my setup which might take a little time. In the meanwhile, can you try it in interrupt mode?. I am not very sure if the gap reduces, but you can give a try. Let us know your observations on this.

     

    Thanks & regards,

    Raghavendra

  • Hi Raghavendra,

    Thank you for your reply.

    I tried interrupt mode, but it made the timing worse. With interrupt mode the total duration for sending three bytes was close to 16.5us (it was about 8us with polling mode). In interrupt mode, there was about 6.5us between CS and first byte, while in polling mode, there was only 11 nano sec between CS and first byte.

    Another thing I noticed was changing configDatafmt.wDelay had no effect on the "gap" between the bytes transmitted. I tried changing the delay between transmissions from 0x0 to 0x3F.

    spiParams.spiHWCfgData.configDatafmt[0].wDelay = 0x3F;

    Do you know why?

    Thanks

    Joe

  • Update: The gap between the bytes in Interrupt mode is shorter (still not close enough) but the entire transmission takes longer since CS is activated way ahead. Am I setting something wrong?

    Thanks

    Joe

  • Hi Joseph,

    I conducted few tests, and did notice a gap between each byte transferred (which is ~1.6us). Walking through the code noticed that, in polled mode of operation after writing to the SPIDAT1 we are polling - until the RX Empty flag is set and reading(dummy read) the status from the slave followed by error checking. Otherwise, there is nothing else done apart from this. I think this part(polling and other stuff) of the code is adding on to this delay. And every part of the code being important, there is nothing much we can optimize further..

    Until now, this is my observation.Will surely keep you updated on this if there is any progress further..

     

    Thanks & regards,

    Raghavendra

  • Hi Raghavendra,

    Thank you for your response. I saw the code segment that you refer to in Spi.c. It seems like the gap depends on the chip used and not necessarily a function of SPI clk speed. That being the case, an estimated time for transferring 3 bytes is going to be above 6us, which translates to ~166kHz. Therefore, do you have any recommended alternatives to get the data rate up to 500KHz?

    Thanks

    Joe

  • Hi Joseph,

    Sorry for the delayed response..

    2068.Spi.txt

    With my continued tests/experiments on the Spi driver, I ended up optimizing the code. Attached is the part of SPI driver code with API spiPolledModeTransfer(...) updated(optimized). Please include this in your SPI driver, and try executing the same. 

    NOTE: 

    #define REMOVED_CODE_FOR_OPTIMIZATION 0 - Will Execute the optimized code..

    #define REMOVED_CODE_FOR_OPTIMIZATION 1 - Will execute normal SPI driver code..

     

    With this change in the API, I am able to cut down the gap by ~0.7us and now I observe only 0.9us gap(delay) between each byte transferred.. Kindly try this and let us know your observations. Hope this helps..

     

    Thanks & regards,

    Raghavendra

  • Hi Raghavendra,

    Thank You very much for taking the effort to optimise the driver code. I haven't tested your code yet. I will try it out and update you. I would prefer your driver approach as opposed to writing my own register level code as I may have to port the code to different platforms.

    Meanwhile, I wrote some test code that controls SPI in the register level and was able to achieve 700nS gap between packets. I also configured SPI1_SCS[3] as a GPIO pin and used that as chip select (3 wire mode. When I tried 4 wire mode with SPI1_SCS[3] as SPI function pin, the line would be pulled down "way way" before the first packet was sent). This, combined with using 16bit packets (2x16 bits instead of 3x8 bits), enabled me to get the sampling rate to >250ksps.

    The other issue I had with the original SPI driver (PSP 1.30) was that if I ran something similar to below, I would get a huge gap between each GIO operation essentially dropping down the ADC sampling rate to ~56ksps.

    loopWrite[0] = 0xC0;
    loopWrite[1] = 0x00;
    loopWrite[2] = 0x00;
     
    dataparam.bufLen       = 0x03;
    dataparam.inBuffer     = &loopRead[0];
    dataparam.outBuffer    = &loopWrite[0];
    dataparam.flags        = Spi_CSHOLD;
    dataparam.dataFormat   = Spi_DataFormat_0;
    dataparam.chipSelect = 0x08;
       
    size = dataparam.bufLen;


    while(TRUE){ //gap between GIO writes = ~18 us (56ksps) 
    GIO_write(spiHandle, &dataparam, &size);
    }

    I probably should use DMA rather than using DSP to poll the ADC. But I am not sure if DMA would help with increasing the sampling rate or not.

    Thank you,

    Joe