In order to evaluate the ADC of this MCU I wrote a simple test software to continuously read out one ADC channel (see attachment “main.c”).
I use the FIFO feature of the ADC to always get 8 samples at once per ISR call.
Actually this code works well as long as no overrun occurs in the ADC FIFO (or in other words, as long as I always read the “ADC_R” register before the next ADC sample is available).
But if for some reason I lose at least one ADC sample (FIFO overrun occurs, for example due to a higher priority ISR), the FIFO seems to be out of sync for all future reads. So from this time on, I always get the 8 ADC samples in a wrong order when reading the “ADC_R” register.
The datasheet says that if FIFO is full, then the next conversion will override old data in case of no read action.
This is fine, but it seems then that the internal FIFO pointer has been shifted even for the next interrupts...
For better understanding, I have attached some pictures of my measurement:
- “scope_1.png” shows the signals on the MCU pins PTC0 (AD8) and PTE0 (“SCOPE_PIN” in the sample code)
- Green line: Waveform on the ADC input pin (sawtooth from a waveform generator)
- Yellow line: Activity of the ADC ISR (low = background task, high = ISR processing).
- “values_1.png” shows the measured ADC values
- Gray bars: Count of ADC values fetched in the ISR (array “adc_count_buffer”)
- Red dots: Measured ADC values (array “adc_buffer” which was filled by reading the FIFO register “ADC_R”)
As you can see, I have simulated a FIFO overrun in the middle of the measurement with a short busy wait in the ADC ISR. Before this overrun, all ADC values are correct, but after it the order of the ADC samples is wrong. This makes it impossible to design a robust and reliable firmware, because losing one single ADC sample can lead to permanently wrong ADC results in future.
Do you have an idea what’s going wrong here and how I can avoid this?
Thanks in advance,