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.

TMS320F28027: SPI Driver code in InstaSpin Example

Expert 3400 points

Part Number: TMS320F28027
Other Parts Discussed in Thread: DRV8305, MOTORWARE

Hi,

Have seen an issue with the below code (from the function DRV8305_readSpi in the file DRV8305.C), the line that checks for the status of the FIFO, records that there is a word in the buffer,however reading the result (incoming SPI word), at times this happens about 1% of the time, is reading the previously received word and not the latest one…..

So my suspicion was that for some reason the actual word has not yet fully been received (while you transmit 16bits, which started with the Write instruction, it takes time for all 16bits to be received), so I added some delay after the write and it solved the issue. BUT this is not a solution, we need to understand why it happening.

 So the question is why would the buffer status comeback as valid with a word, while there is no word there? The status supposed to be resetted with the Reset of the SPI SPI_resetRxFifo(obj->spiHandle);??

 

Please let me know.

 

BTW, why are we reading the the EMU register and not RX register or better the FIFO?

 

 

  // build the control word

  ctrlWord = (uint16_t)DRV8305_buildCtrlWord(CtrlMode_Read,regAddr,data);

 

  // reset the Rx fifo pointer to zero

  SPI_resetRxFifo(obj->spiHandle);

  SPI_enableRxFifo(obj->spiHandle);

 

  // write the command

  SPI_write(obj->spiHandle,ctrlWord);

 

  // wait for the response to populate the RX fifo, else a wait timeout will occur

  while((RxFifoCnt < SPI_FifoStatus_1_Word) && (WaitTimeOut < 0xffff))

  {

    RxFifoCnt = SPI_getRxFifoStatus(obj->spiHandle);

       if(++WaitTimeOut > 0xfffe)

       {

             obj->RxTimeOut = true;

       }

  }

 

  // Read the word

  readWord = SPI_readEmu(obj->spiHandle);

  • Etai,

    It appears that the DRV8305.c file in Motorware 18 incorrectly calls SPI_readEmu() as you had mentioned. You should replace SPI_readEmu() with SPI_read().

    You are also correct that calling SPI_resetRxFIfo() followed by SPI_enableRxFifo() will reset the FIFO counters back to 0. The SPIRXEMU will reflect the current status of SPIRXBUF as soon as the last character has been received. As you are polling for the FIFO status to have more than 0 words, you shouldn't see any old data.

    To help get to the bottom of what is happening in the existing code, you might want to add some GPIO debugging to see when the SPIRXEMU register is being read in relation to the previous SPI word being transmitted. That should help us get down to the timings here.

    Thanks,
    Mark
  • Hey Etai,

    Just checking in to see if this helped resolve your issue?

    -Mark
  • Hi,

    No, not one bit and the system did not seem to log my response as well......

    So adding ANYTHING to the code around this area disrupts the timing and essentially make this issue from happening, see my initial take, I added a delay and it solved the issue.... so that is none starter.

    The key sentence in the answer you guys gave was "As you are polling for the FIFO status to have more than 0 words, you shouldn't see any old data" - YES! That is what we all expect, YET it does NOT happen! So what is going on here... can you test it in house and see what is going on.... this is with our code, it happens less than one percent of the time, so be patient, but it happens within a couple of minutes of testing.

    Etai
  • Etai,

    I will be looking into this further. I am going to target some time tomorrow.

    Thanks,
    Mark
  • Etai,

    I am pretty sure that I found the root here.

    First. Replace the SPI_readEmu() function with SPI_read(). It is not causing the issue in this situation since the RXFIFO is reset on every call. 

    The actual issue is that the WaitTimeOut is declared as static. Meaning that the value will persist across invocations of the DRV8305_readSpi() function. Every time this function is called, the WaitTimeOut variable will increment some amount (+5 in every call during my testing). After enough calls of this function, the variable will max out, and the FIFO status while loop will fail, allowing the SPI to immediately read the buffer regardless of if the previous word was done or not.

    To prevent this issue, replace
    static volatile uint16_t WaitTimeOut = 0;
    with
    volatile uint16_t WaitTimeOut = 0;

    I have not done a full disposition of the file to see if there are other instances of this quirk, but it is incorrect.

    We are not planning to fix this bug in the existing motorware framework, but will ensure it is not present in the next framework.

    Thanks,
    Mark

  • Thank you Mark!!!

    I will check if indeed it resolve the issue  and will get back to you! MUCH appreciated!

    Etai

  • This did the trick! Thank you, great work!

    Etai
  • I'm glad that this helped. I have submitted tickets to ensure that this issue is fixed in the next framework.

    Just to reiterate for those who may see this later, This issue will NOT be fixed in MotorWare. Please implement the changes as recommended in the earlier reply (e2e.ti.com/.../2501923 )

    Thanks,
    Mark