In your interrupt handler, ADC_Handler()
, you set sample_buffer_full
when the buffer is full. I don't see anywhere in the code where sample_buffer_full
ever gets reset (cleared) once it's been set.
That disables the body of the interrupt handler – ie, the handler's structure is
if (!sample_buffer_full) { ...body of handler... }
– and in particular, prevents adc_get_latest_value(ADC);
from occurring. The source code of adc_get_latest_value();
is like
uint32_t adc_get_latest_value(const Adc *p_adc) {
return p_adc->ADC_LCDR;
}
which accesses the ADC data register. According to section 43.6.4 Conversion Results on page 1322 of the data sheet, Atmel-11057-32-bit-Cortex-M3-Microcontroller-SAM3X-SAM3A_Datasheet.pdf,
The channel EOC bit in the Status Register (ADC_SR) is set and the DRDY is set. In the case of a connected PDC channel, DRDY rising triggers a data transfer request. In any case, either EOC and DRDY can trigger an interrupt.
Reading one of the ADC_CDR registers clears the corresponding EOC bit. Reading ADC_LCDR clears the DRDY bit and EOC bit corresponding to the last converted channel.
It appears to me that your code enables interrupts, fills a buffer, sets sample_buffer_full
, then spins in ADC_Handler()
. That is, repeatedly executes ADC_Handler()
without clearing the EOC bit.
Note, for oscilloscope applications with a Due, I suggest using DMA buffers instead of one interrupt per conversion. See thread #137635, speed of analogRead, in forum.arduino.cc for DMA code to read one or two analog channels on a Due at one sample per microsecond. Also see edaboard.com/thread283843 and forum.arduino.cc #186169
- 8.9k
- 3
- 21
- 33