I tried an very simple sketch to trigger a one channel ADC conversion at 40 KHz with an external trigger and it seems to work. However, I suspect that the external trigger can't work above a relatively low frequency.
/*****************************************************************/
/* ADC conversions at 40 KHz KHz */
/* Hook a jumper between pin 12 and PA11(pin 18) */
/*****************************************************************/
volatile uint32_t lastConversion;
volatile boolean Flag;
void setup()
{
pinMode(12, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
PMC->PMC_PCER0 |= PMC_PCER0_PID11; // PIOA power ON
PIOA->PIO_PDR = PIO_PA11B_ADTRG; //Disables PIO from controlling PIN
PIOA->PIO_ABSR = PIO_PA11B_ADTRG; //1-assigns to B peripheral
adc_setup();
}
void loop()
{
if (Flag == true)
{
Flag = false;
// A new conversion is available
}
digitalWrite(12, HIGH);
delayMicroseconds(25);
digitalWrite(12, LOW);
}
/************* Configure ADC function *******************/
void adc_setup() {
PMC->PMC_PCER1 |= PMC_PCER1_PID37; // ADC power on
ADC->ADC_CR = ADC_CR_SWRST; // Reset ADC
ADC->ADC_MR |= ADC_MR_TRGEN_EN // Hardware trigger select
| ADC_MR_TRGSEL_ADC_TRIG0 // Trigger by ADTRG
| ADC_MR_PRESCAL(1);
//ADC->ADC_ACR = ADC_ACR_IBCTL(0b01); // For frequencies > 500 KHz
ADC->ADC_CHER = ADC_CHER_CH7; // Enable ADC CH7 = A0
ADC->ADC_IER = ADC_IER_EOC7; // Interrupt on End of conversion
NVIC_EnableIRQ(ADC_IRQn); // Enable ADC interrupt
}
void ADC_Handler()
{
static uint32_t Count;
lastConversion = ADC->ADC_CDR[7];
//lastConversion = ADC->ADC_LCDR;//Do NOT clear EOC7 bit !
Flag = true;
if (Count++ > 40000)
{
Count = 0;
PIOB->PIO_ODSR ^= PIO_ODSR_P27;
}
}
For higher frequencies, an input capture on an input pin and plus an ADC software trigger (START/STOP) should do the trick.