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.

DAC8741H: FIFO not Emptying upon read of FIFO_M2D register.

Part Number: DAC8741H

Hi 

I am using the SPI mode in DAC8741 and trying to read the FIFO_M2D regsiter.

I am waiting till carrier is detected using the modem status register and after a 20 milliseconds delay trying to read the FIFO_M2D.

Based the data prints it seems the the fifo is not emptying and keeps getting fuller.

See the log prints below.

What am I doing wrong?

Thanks

Pran Haran

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

CD = 0 (Read MODEM_STATUS):
rx: a0 c0 20
rx: a0 c0 02
Read data from the modem:
rx: a4 41 ff
rx: a4 51 ff
rx: a4 61 ff
rx: a4 71 ff
rx: a4 91 ff
rx: a4 a1 ff
rx: a4 b1 ff
rx: a4 c1 ff
rx: a4 e1 ff
rx: a4 f9 ff
rx: a4 05 ff
rx: a4 05 ff
rx: a4 05 ff
rx: a4 05 ff
rx: a4 05 ff
rx: a4 05 ff
rx: a4 05 ff
rx: a4 05 ff
rx: a4 05 ff
  • Hi Pran,


    I'm not sure what the issue is. My understanding of the device is that the read of the last data would completely pull it off the FIFO so it wouldn't be re-read. However, you should be able to read the MODEM STATUS register to see that the last read empties the receive FIFO (with FIFO_M2D_EMPTY) and you can check the FIFO_M2D register to check the FIFO level (and also the empty flag).

    Can you put up a scope shot of the SPI transaction to read the last piece of data? This does seem similar to something I had seen before where an extra 3 byte transaction of 0x00 was required to complete the read. I saw this in another E2E post here:

    https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/939504/dac8741h-reading-fifo

    Joseph Wu

  • Hi Joseph

    What is suggested by you almost works. Now I am able to empty the buffer and read valid data. But, from time to time the data is wrong. The HART packet shows crc error.  It is as though the modem made bit errors.  However, the signal is clean and another HART modem connected in parallel is able to decode it demodulate it properly. This implies that the signal clean and the problem is not noise related.  Also, only the erroneous bytes are wrong. The rest of the bytes are aligned perfectly and no bytes are missing.

    Interestingly, if I added 3-5 milli second delay after the dummy write of zeros and then read the data from the FIFO it seems to work fine so far.

    Can we rely on this delay to be accurate and sufficient? Is the SPI FIFO have any latency for multiple read when emptying the FIFO?

    Method:

    We are checking FIFO_M2D_EMPTY   bit to be 0 in the modem status register every 20 milliseconds. We then read the FIFO level from FIFO_M2D register.  then read the fifo data using the method described by the e2e post you mentioned. The 20 ms interval is so that we will end up reading 2-3 bytes at a time.

    We are not using interrupts at this time. Once the polling method works, we will migrate to use interrupts.

    Let me know if you can shed some light on the timings of the multiple FIFO read?

  • Pran,

    I'll need to talk to the digital designer on this one. I'm not sure why the extra delay on the dummy write of zeros seems to help, so he's probably the best resource on this one. Give me a little time and I'll get back to you soon.

    Joseph Wu

  • Pran,

    The digital designer only mentioned that there is a minimum timing between frames. In the datasheet, I believe that's the 3.06us listed in the timing requirements. If you're larger than that, he didn't think it would be a problem. 

    I would note that he did mention on thing about the original problem that you had mentioned. He said that once the FIFO is empty, the device would continue to output the last valid data, but the empty flag should be set. That would explain why you were repeatedly getting the last data.

    Joseph Wu

  • Joseph,

    The problem is that if I waited only 1 ms between reading the FIFO register, randomly I get wrong data. 2 ms seems to work fine. Both of these are well beyond the minimum time required between read. One works and the other does not. 

    Also, the requirement of the insertion of a dummy read is not mentioned anywhere in the datasheet. Normally, one just reads the FIFO register until empty flag is set while allowing for minimum time between reads. 

    My question is if I go ahead and deploy this method (with some arbitrary delay and the dummy read), can I be sure this will continue to work and assured by design that it will work.

    How was this function tested in the reference design?

  • Pran,


    I talked with the digital designer again and we'll need some more time to take a look at the design. From his recollection, the read command is executed at the rising edge of /CS, which should set up the read from the register. If that's the case, the read should work without the insertion of the dummy read. Additionally, the time between SPI commands should be as shown in the datasheet, with a minimum time between reads of about 3us.

    Because it's not behaving as we expect, we'll try to open up the original design to see if we can find where this issue comes from. In the mean time, when the time between reads is less than 1ms, how often do you get read errors? I just want to know approximately what sort of an error we're looking for.


    Joseph Wu

  • Pran,

    What is the frequency of the SCLK you're using to read the device. Also, do you think you could provide a logic analyzer plot of an error output? Again, I'm also like to know what error rate you are seeing.

    Joseph Wu

  • Pran,


    I've talked to the one of the design engineers again and he's verified that to read out the FIFO, you should send out the frame of all zeros to clock out the data. In most cases you can stack consecutive reads of the register, using a read frame to clock out data from the previous read frame. This is not the case with the FIFO. The FIFO is constructed differently with a cyclical register pointer that can be affected by the next frame. For that reason, use the frame of all zeros to clock out the data. Once he opened up the design to take a look, he was able to identify this issue.

    As for the occasional error in the FIFO read and the time space between the read frame and the zero frame, he didn't have any ideas. The read frame command is parsed at the rising of edge of /CS. However, the actual read of the FIFO does not take place until the middle of the zero frame. Because of this, he might be able to identify the error if the FIFO contents is known to compare with the data that comes up in error. I think we'd still want to know what the error rate is and what the SCLK rate is.


    Joseph Wu

  • Hi Joseph,

    I tested and tried to sort the crc errors.

    With no additional read delay (but more than 3 uS), the crc error happens all the time.

    With 1 ms between reads, the crc error happens 30% of the time. There are 3 different failures. I have captured them in the error-summary below. When the delay is increased to 2 ms, only the extra byte (08 at front) happens and the frequency goes down 1 in 10. The other patterns of errors disappear, When I increase the read delay to 3 ms, all crc errors disappear. 

    Let me know if you need anything else.

    Haran

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

    Last byte of packet is the 19 at the end ignore the extra bytes after that.

    Expected: 86 26 23 06 4a dd 0d 17 00 40 c4 10 50 53 1d f3 82 08 20 82 08 20 82 08 20 82 08 20 07 09 66 19 00 01
    Received: 86 26 23 06 4a dd 0d 17 00 40 c4 10 50 53 1d f3 82 08 20 82 08 20 82 08 20 82 08 20 07 09 66 f3 19 aa -- extra byte f3 (3rd byte from end)

    Expected: 86 26 23 06 4a dd 0d 17 00 40 c4 10 50 53 1d f3 82 08 20 82 08 20 82 08 20 82 08 20 07 09 66 19 00 01 00
    Received: 08 86 26 23 06 82 dd 0d 17 00 66 c4 10 50 53 ff f3 82 08 20 82 08 20 82 08 20 82 08 20 07 09 66 19 aa 08 ----- extra byte 08 (very first byte)

    Expected: 86 26 23 06 4a dd 0d 17 00 40 c4 10 50 53 1d f3 82 08 20 82 08 20 82 08 20 82 08 20 07 09 66 19 00 01 00
    Received: 08 86 26 23 06 82 dd 0d 17 00 66 c4 10 50 53 ff f3 82 08 20 82 08 20 82 08 20 82 08 20 07 09 66 19 aa 08 -- extra byte 08 and wrong byte 4a became 82,
    40 became 66

    Expected: 86 26 23 06 4a dd 0d 17 00 40 c4 10 50 53 1d f3 82 08 20 82 08 20 82 08 20 82 08 20 07 09 66 19 00 01
    Received: 86 26 23 06 4a dd 0d 17 00 40 c4 10 50 53 1d f3 82 08 20 82 08 20 82 08 20 82 08 20 07 09 66 f3 19 aa -- extra byte f3 (3rd byte from end)

    Expected: 86 26 23 06 4a dd 0d 17 00 40 c4 10 50 53 1d f3 82 08 20 82 08 20 82 08 20 82 08 20 07 09 66 19 00 01 00
    Received: 08 86 26 23 06 82 dd 0d 17 00 66 c4 10 50 53 1d f3 82 08 20 82 08 20 82 08 20 82 08 20 07 09 66 19 aa 08 -- extra byte 08 and wrong byte 4a became 82
    40 became 66
    Expected: 86 26 23 06 4a dd 0d 17 00 40 c4 10 50 53 1d f3 82 08 20 82 08 20 82 08 20 82 08 20 07 09 66 19 00 01
    Received: 86 26 23 06 4a dd 0d 17 00 40 c4 10 50 53 1d f3 82 08 20 82 08 20 82 08 20 82 08 20 07 09 66 f3 19 aa ----- extra byte f3 (3rd byte from end)

    Expected: 86 26 23 06 4a dd 0d 17 00 40 c4 10 50 53 1d f3 82 08 20 82 08 20 82 08 20 82 08 20 07 09 66 19 00 01
    Received: 86 26 23 06 4a dd 0d 17 00 40 c4 10 50 53 1d f3 82 08 20 82 08 20 82 08 20 82 08 20 07 09 1d 19 19 aa ---- 66 became 1d 4th byte from end.

    Expected: 86 26 23 06 4a dd 0d 17 00 40 c4 10 50 53 1d f3 82 08 20 82 08 20 82 08 20 82 08 20 07 09 66 19 00 01
    Received: 86 26 23 06 4a dd 0d 17 00 40 c4 10 50 53 1d f3 82 08 20 82 08 20 82 08 20 82 08 20 07 09 66 f3 19 aa ----- extra byte f3 (3rd byte from end)

    Expected: 86 26 23 06 4a dd 0d 17 00 40 c4 10 50 53 1d f3 82 08 20 82 08 20 82 08 20 82 08 20 07 09 66 19 00 01
    Received: 86 26 23 06 4a dd 0d 17 00 40 c4 10 50 53 1d f3 82 08 20 82 08 20 82 08 20 82 08 10 07 09 66 19 19 aa --- 20 became 10 7th byte from the end

    Expected: 86 26 23 06 4a dd 0d 17 00 40 c4 10 50 53 1d f3 82 08 20 82 08 20 82 08 20 82 08 20 07 09 66 19 00 01
    Received: 86 26 23 06 4a dd 0d 17 00 40 c4 10 50 53 1d f3 82 08 20 82 08 20 82 08 20 82 08 20 07 09 66 f3 19 aa----- extra byte f3 (3rd byte from end)

  • Pran,

    I've forwarded this onto the design engineer. I have a guess on what the extra byte error comes from, but I'll wait to see what he thinks before I respond back on that. I should have an answer later today.

    Joseph Wu

  • Pran,

    For these errors, are you using CRC and are you getting a CRC error along with the data?

    Joseph Wu

  • The CRC I am reporting the HART CRC which indicates some data read from the modem is wrong. It has nothing do with TI's CRC check of the SPI data.

  • Pran,

    The reason I asked about the CRC was to see if it affected the timing of the readout from the device. The digital designer did run a quick simulation to see if the device calculation of the CRC for SDO would have some unknown timing dependency, but he did not see any in his simulation.

    How do you determine the FIFO is empty to stop the read? For the read of the FIFO the extra byte comes 16 bytes after the that value appears in the readout. For example in the first sequence you wrote in the post, the extra byte of F3 comes 16 bytes after a read of F3 in the data. My thought was that there was some readout problem in the FIFO where the pointer somehow got pointed back to the first element in the FIFO. The FIFO is implemented as a set of registers where a 16 count pointer is used to track the FIFO. I didn't know if continuing to read the data somehow clocked the FIFO over

    Also, what is the SCLK rate?

    Joseph Wu

  • The SCLK is 1 MHz.

    We read the FIFO_M2D register and check the FIFO level and extract how many bytes are there.

        fifo_level = ((rxdata[1] & 0xf0) >> 4);
    Then we read the number of bytes of data ina for loop.
    The read data includes the dummy write of 0 and discarding the data comes out of it etc.
    Below is the code that reads the fifo.
    for (int i2 = 0; i2 < fifo_level; i2++)
    {
          buff[0] = 0xa4; // M2D_FIFO register
          int ret = spi_write(dev, &config, &tx_set);
    if (ret != 0)
    {
        printf("Issue with write\n");
    }
    spi_read(dev, &config, &rx_set);
    if (i2 != 0)                      // I have to ignore the first data for some reason
    {
           pdu_buffer[recvIndex++] = rxdata[2]; // actual data read
    }

    buff[0] = 0x0; // dummy write {0,0,0}
    ret = spi_write(dev, &config, &tx_set);
    if (ret != 0)
    {
    printf("Issue with write\n");
    }

    spi_read(dev, &config, &rx_set);
    k_sleep(K_MSEC(3));                     // this is the delay needed.

    }
    buff[0] = 0xa4;                              // extra step to get the last byte out.
    ret = spi_write(dev, &config, &tx_set);
    if (ret != 0)
    {
    printf("Issue with write\n");
    }
    spi_read(dev, &config, &rx_set);
    pdu_buffer[recvIndex++] = rxdata[2]; // actual data read.
  • 	for (int i2 = 0; i2 < fifo_level; i2++)
    	{
    		buff[0] = 0xa4;			// M2D_FIFO register
    		int ret = spi_write(dev, &config, &tx_set);
    		if (ret != 0)
    		{
    			printf("Issue with write\n");
    		}
    		spi_read(dev, &config, &rx_set);
    		if (i2 != 0)								// I have to ignore the first data for some reason
    		{
    			pdu_buffer[recvIndex++] = rxdata[2];	// actual data read
    		}
    
    		buff[0] = 0x0;								// dummy write {0,0,0}
    		ret = spi_write(dev, &config, &tx_set);
    		if (ret != 0)
    		{
    			printf("Issue with write\n");
    		}
    
    		spi_read(dev, &config, &rx_set);
    		k_sleep(K_MSEC(3));							// this is the delay needed.
    
    	}
    	buff[0] = 0xa4;									// rextra step to get the last byte out.
    	ret = spi_write(dev, &config, &tx_set);
    	if (ret != 0)
    	{
    		printf("Issue with write\n");
    	}
    	spi_read(dev, &config, &rx_set);
    	pdu_buffer[recvIndex++] = rxdata[2];		// actual data read.

  • Pran,

    I'll talk it over with the digital designer. I'm not much of a coder, so it may take a little time to go through this carefully. 


    Joseph Wu

  • Pran,


    I talked to the digital designer earlier today, and we didn't come to to many conclusions about the problem you're seeing. However we both think that the extra byte is from making one to many reads from the FIFO. Again, this extra byte is the same as the read from 16 bytes previous:

    What we would suggest is that during before reading the data, read the flag that indicates the FIFO is empty, just to verify that. If the FIFO is empty, then do not perform the read.

    Other than verifying the empty flag, I would also validate the parity and the CRC. When you get these extra bytes or bad data, are the parity or CRC checked? We wanted to know just to be sure.

    Other than that, what are you using for communications to the device? Is it a particular HART modem? Have to checked the waveform to verify that the FIFO data does not match the transmitted data?


    Joseph Wu

  • First thing we do before reading FIFO is to check that it is not empty.

    Then, I get a count of how many bytes are there in FIFO from FIFO_M2D register.

    Then, we read the FIFO_M2D: that many number of times. 

    I have tried checking FIFO empty before each read and it did not help.

    The only thing that has worked (based on your suggestion that I may be reading one too many bytes) is that if I always read one less byte than what the FIFO level indicates.

    This worked even after I removed all the extra milliseconds of delay between each FIFO read. Even at the end of packet, I read one less than what FIFO says. But I am not missing any bytes. So far so good!

    We are continuing to test and hope that it stays working. 

  • Pran,

    This does have me a bit stumped, but I'm glad that reading one byte less than the FIFO count is working for you. I'm still checking with the digital designer to see if he has any input on this one.  

    Joseph Wu