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.

Issue with SPI while polling for data (DM6446 EVM Rev C.)

Hi,

 

I’m using Davinci DM6446evm Rev C. board and I’ve got an issue while trying to implement polling mode for SPI driver. More specifically, the read from SPI_BUF register does not seem to work as documented (or probably I’m missing a point somewhere).

 

Upon reading, I get the previous value stored in SPIBUF field of SPI Buffer register not the value that’s been read recently. The value however, gets copied to the SPIBUF field after a minor delay and subsequent reads to this register give me values which are out of sync by one read.

 

Here’s my code snippet that performs the reading job.

 

 --------------------------------------------------------------


    UINT32 temp32;

    UINT32 buffer;

   

    /* Wait for the Rx register to get non-empty. */

    do

    {

        temp32 = READ_REG(SPI_BASE_ADDRESS + SPI_BUF);       

    }

    while ( (temp32 & SPI_BUF_RXEMPTY) == 1);

   

  

    /* Get the received data. Reading SPI Buffer is okay

for the second time since we will not get preempted

and subsequent reads to the register will not change

its values */

    buffer = (READ_REG(SPI_BASE_ADDRESS +

                  SPI_BUF)) & SPI_BUF_RXDATA;

 --------------------------------------------------------------

 

My observation is that introducing the slightest of delays (even a for loop to 10 will do the job) between the end of while statement and start of next will correct the values. Perhaps it gives time for the controller to actually place the value in SPIBUF.

 

I’ve verified from the manual that the SPIBUF field is populated prior to clearing out the RXEMPTY flag to indicate data presence.

 

Is this a known issue? If yes then what is the minimum delay that I need to introduce before reading SPIBUF field?

 

Any information that could help solving my problem will help.

 

Thanks!

  • Ayaz,

    Hi, I have not heard of any issues on this.  I have seen SPI polling done similarly but slightly different than your code example. Here's a way that Spectrum Digital uses on the EVM sample code SPI Polling testcases when used to read from a SPI EEPROM, this example is for DM355 davinci Device but both DM6446 and DM355 have the same SPI peripheral module.

    void spirom_cycle(Uint8 *buf, Uint16 len)
    {
        Uint16 i;

     /* Clear any old data */
     SPI_SPIBUF;

     /* spirom access cycle */
     for (i = 0; i <= len; i++)
     {
         // Wait for transmit ready
            while( SPI_SPIBUF & 0x10000000 );
            if (i == len )
                SPI_SPIDAT1 = (spidat1 & 0x0ffcffff) |  buf[i] ;
            else
                SPI_SPIDAT1 = spidat1 | buf[i];

      // Wait for receive data ready
            while ( SPI_SPIBUF & ( 0x80000000 ) );

            /* Read 1 byte */
            buf[i] = SPI_SPIBUF;
     }
    }

    The SPI polling example that includes this piece of code can be found at http://c6000.spectrumdigital.com/evmdm355/reve/files/EVMDM355_BSL_RevE.zip 

    under the directory structure of -> /evmdm355_v1/tests/spirom

    I hope it helps, and you can use it as reference.  Im not sure how to locate the SPI linux driver code inside TIs DVSDK sw, but i imagine it should have a similar methodology.

    regards,

    miguel

     

     

  • Hey,

     

    Apologies for not responding earlier. I had to attend to something urgent.

     

    As for the issue, well I've studied the reference code and its not doing things too differently. The issue on my board disappears when I use a delay of around 3-4 microseconds between receiving the signal for data and reading the actual data. 

     

    The document says that SPIBUF is populated prior to clearing SPI_BUF_RXEMPTY. Is it possible that the converse is happening and SPI_BUF_RXEMPTY is set before data is actually copied in SPIBUF? Is there a way to verify that?