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.

TM4C129XNCZAD: An extra byte in the Rx SPI FIFO

Part Number: TM4C129XNCZAD
Other Parts Discussed in Thread: ADS1298

Hello everyone.

I'm comunicating the TM4C129x with the ADS1298 through SPI, everything was working fine until I had to read a conversion from the ADS.

I'm starting the read when the DRDY is triggered and I realize that everytime in the lecture it comes an extra byte with a value of zero.

I have two functions, one of them send the RDATA (read data command), and the other function reads the values send by the ADS, if I do this then the extra byte appears.

Doing some tests I realize that if I debug the code and stop it in the call to the fuction that reads the data (after the command been send) the data comes without the extra byte, so I guess it was something related to timing so I added a delay and it works, now if I run normally the code I get the read without the extra byte, but why? What I'm doing wrong or what I'm not taking on count?

I saw the SPI data from the ADS on an oscilloscope and it comes without the extra byte so the Tiva is the one of the problem.

This is the sequence of the reading process:

if(bdataReady)
    {
      bdataReady = false;
      
      SendCommand(RDATA,0,0,NULL,NULL);
      vReadADSData(ui32ADCReadings);
      SysCtlDelay(200);
      SendCommand(START,0,0,NULL,NULL);
    }

And this is my function that reads from the ADS:

void vReadADSData(uint32_t *ui32ReadData)
{
  /*Clean the Rx FIFO*/
  uint32_t ui32FlushFIFO = 0;
  while(SSIDataGetNonBlocking(SSI2_BASE, &ui32FlushFIFO));
  
  /*Set the value to zero to used as dummy data*/
  ui32FlushFIFO = 0;
  
  for(uint8_t ui8ReadingIndex = 0; ui8ReadingIndex < BYTES_PER_RDATA + 1;
      ui8ReadingIndex++, ui32ReadData++)
  {
    SSIDataPut(SSI2_BASE, ui32FlushFIFO);
    SSIDataGet(SSI2_BASE, ui32ReadData);
  }
}

I can't figure it out why this is happening, if you need more info please let me know.

By the way... I can't choose the proper forum, I don't know why, it just appear wireless forums. Please help me to redirect this post to the proper forum.

Thank you.

Regards, Juan.

  • Sorry about not being able to chose the proper forum. That issue has now been fixed.

    I don't understand how the extra byte can be coming. You are using SSI2 as a master, you properly flush the receive FIFO, then you loop with SSIDataPut followed by SSIDataGet. How can you be receiving more bytes than times you call SSIDataPut? Where in the sequence does the extra byte come? Is it the first or last byte?
  • Hi Bob, a moderator doesn't can move my post to the proper forum?

    The extra byte it comes first

    Here is what I receive if I don't implement the delay between the functions I mention:

    And here is what I receive if I apply the delay:

    When I execute the code line by line and it doesn't have the delay, it works, I guess because of the delay applied by the debugger between line executions. From that fact is that I think is time related problem, but why?

    Thanks for your help Bob.

    Regards, Juan.

  • It sounds like you are reading the  ADS1298 too soon. Are you checking for !DRDY to go high and then to go low again before reading the data? You may want to compare the SSICLK to !DRDY on your scope.

  • I set the bdataReady true in a GPIO interrupt that is triggered in the falling edge, and is connected to the DRDY pin of the ADS1298. This flag starts the read and in the end I send another START command to make another conversion.

    Seeing the signals in the oscilloscope I realize that the falling edge of DRDY and the SPI signals doesn't match as it should, let me analize that part, maybe you are right.

    Meanwhile I let you the function of how the interrupt is initialized

    void vConfigGPIOs(void)
    {
      /*See if the GPIO D peripheral is enabled*/
      while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOD))
      {
        /*If isn't ready then try to enabled it and wait a few cycles to be ready*/
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
        SysCtlDelay(10);
      }
      
      /*Register the interrupt for the pin*/
      GPIOIntRegister(GPIO_PORTD_BASE, PortDIntHandler);
      
      /*The pin than triggers the interrupt is declared as input*/
      GPIOPinTypeGPIOInput(GPIO_PORTD_BASE, GPIO_PIN_5);
      
      /*The interrupt is configured in the desire pin and triggers 
        in the falling edge*/
      GPIOIntTypeSet(GPIO_PORTD_BASE, GPIO_PIN_5, GPIO_FALLING_EDGE);
      
      /*Clear unwanted interrupts before enabled it*/
      GPIOIntClear(GPIO_PORTD_BASE, GPIO_PIN_5);
            
      /*Enable interrupts*/
      GPIOIntEnable(GPIO_PORTD_BASE, GPIO_PIN_5);
    }

  • This is what I get in the oscilloscope:

    I forgot to mention in the image that the yellow rectangle is the data from the ADS1298

    Everything seems to be as expected, any ideas or comments?

    Regards, Juan.

  • This looks more like a ADS1298 issue than a TM4C issue. I am pushing this thread to the precision A2D experts.
  • When I was about to write the post I was thinking in publish it to the Precission converters forum but in the oscilloscope I saw that the zero doesn't come in the signals so I guess it was a TM4C issue.

  • But in the logic analyzer, it shows the first byte from the slave (ADS1298) as 0x00, the second byte as 0xC0. What the master is putting out is 0x12 then 0x00.
  • The 0x12 corresponds to the RDATA command, and the 0x00 beneath that command it should be read by the flush received FIFO

    while(SSIDataGetNonBlocking(SSI2_BASE, &ui32FlushFIFO));

    Immediately after, the ADS responds with the 3 status byte and the result from the conversion.
    There are ways to work around this situation but it bothers me, it shouldn't happen

    Regards, Juan
  • Hi Juan,

    Were you able to resolve this without the added delay? I'm not sure where the extra byte comes from but it seems like the ADS1298 is behaving as expected.
  • Hi Juan,
    First, I apologize for the delayed response. I was on vacation last week. Also, I am not that familiar with the ADS1298. If I understand what you are saying is that after he RDATA command, the ADS1298 replies with a three byte status and then the data. You are expecting the while loop with calls to SSIDataGetNonBlocking() to flush the three byte response from the buffer. Is my understanding correct?

    If this is the case, I suspect that the TM4C129 calls SSIDataGetNonBlocking() before the last byte of the response has been fully received (unless you add the delay). This causes the code to drop out of the while loop after only reading two bytes, leaving the last byte of the status to be read when you expect the data. Since the TM4C is the master, and it must transmit 3 bytes to read the 3 bytes of status, you would be better served by calling SSIDataGet() three times to clear the status bytes.
  • I have not heard back from you so I assume my last response helped answer your question. If not, you may reply or start another thread.