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:
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,
This definitely looks like a hardware bug.
The oldest conversion gets overwritten by the new conversion, but the front of the FIFO does not get updated.
To avoid this you probably have to set the ADC as the highest priority interrupt.
Alternatively you can try to use the DMA to transfer the FIFO ta a local buffer.
If those are not feasible and you don't mind losing samples you need to check the overrun flag each time the FIFO is going to be read and empty it if the overrun flag is set.
Unfortunately the ASCANE bit did not change anything, so the problem still exists.
And detecting an overrun is not possible (unexpected interrupt can arrive anytime), so I don’t know when I have to reset the FIFO...
Do you have any other recommandation ?
Note : I insert the 2 screeshot that you could not read.
Can you set the ASCANE bit in ADC_SC4 register and have a try? If you set the bit, the FIFO always use the first dummied FIFO channels when it is enabled.
If the above method can not fix the issue, as a workaround, you can write 0x1F to ADCH bits in ADC_SC1 register to reset the FIFO when overrun event happens.
BTW, I can not see the scope_1.png and values_1.png you submitted.
Hope it can help you.