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.

ADC Continuous Conversion Order on TMS570LS3137

Other Parts Discussed in Thread: TMS570LS20216, TMS570LS3137

I am using a TMS570LS3137 and TMS570LS20216 dev board, I see the same behaviour on both boards.

I have ADC 2 Group 1 set up to continuously convert 2 ADC channels (8 and 9). FIFO size and threshold interrupt is set to 4.  Memory BNDA=0 and BNDB=2. I set it up to trigger an interrupt when the the FIFO is full, so that I can read the new data. The interrupt works and the ADC conversions work. After I read the last entry in the FIFO, the ADC fills the FIFO with new data (I do not set the group select register again), but sometimes the data is placed in the FIFO in the wrong order.

When reading ADC channels 8 and 9 into a 4 entry FIFO, I expect the first and third entries to be the conversion of channel 8 and the second and fourth entries to be the conversion value of channel 9. However sometimes channel 9 is in the first and third entries.

I am monitoring 0xFF3A0000 directly:

I see this sometimes (This is the expected behavior)

0xFF3A0000: 0x00008XXX

0xFF3A0004: 0x00009XXX

0xFF3A0008: 0x00008XXX

0xFF3A000C: 0x00009XXX

 

I see this other times (This is NOT the expected behavior)

0xFF3A0000: 0x00009XXX

0xFF3A0004: 0x00008XXX

0xFF3A0008: 0x00009XXX

0xFF3A000C: 0x00008XXX

 

I have never seen this happen when using single conversion groups with multiple inputs. This makes reading the continuous data via ADC->GxBUF[1].BUFFER0 upredictable.

The TRM states that conversions always start with the lowest channel, is this not the case when continuous conversion groups restart conversion due to an empty buffer?

  • Hello Jeremy,

    I have forwarded your question to one of our ADC experts. They should get back with you shortly to discuss the unexpected behavior with the ADC.

  • Hello Jeremy,

    When a conversion group is configured for continuous conversion, the ADC core will keep performing ADC conversions without considering the state of the group's FIFO buffer.

     There are two interrupts that you could use for reading the results out: FIFO buffer threshold interrupt and FIFO buffer overrun interrupt.

     The FIFO buffer overrun interrupt (or FIFO full interrupt) is the one you are using. This condition occurs when the ADC tries to write a conversion result to the FIFO when it is already full. In your case, an overrun will be signaled when the ADC tries to write the conversion result for channel 8 after there are already 4 new conversions written to the FIFO. This effectively means that you are bound to lose at least one conversion result. You could lose even more depending on how long it takes for the CPU to get to this ISR and start reading the results out of the FIFO.

     I have attached a document that shows the time sequence of conversion results and the timing of the FIFO overrun interrupt generation. As you can see, there is a degree of unpredictability introduced by the fact that the CPU and the ADC are working asynchronous to each other.

    5482.ADC_continuous_conversions.pdf

    Let's say you configure a FIFO size such that you would not see a FIFO full condition, assuming the worst case delay in servicing the group's FIFO threshold interrupt. Then you can define a FIFO threshold of 4 for this group. That is, the ADC will interrupt the CPU each time there are at least 4 conversion results. There is this uncertainty still because the ADC can store more conversion results while the CPU has still not started reading out the 4 results. This can only truly be avoided if you can ensure that the CPU reads out the available data before the ADC gets ready to store more results (but then you wouldn't have seen an issue if that were the case).

     The best way to ensure predictability is to use single conversion mode, and then to periodically trigger the group using a timer event, while giving enough time between triggers to let the CPU service the interrupt and read out the required number of conversion results.

     Alternatively, you can configure a DMA channel to transfer each conversion result into CPU RAM. The DMA can then interrupt the CPU when the required number of conversion results have been transferred. You can even implement a double-buffer scheme in CPU RAM using two DMA channels that are alternately triggered.

    Hope this helps.

    Regards, Sunil