Edit your post and post your code between code tags <>
To sample A7 instead of A0, enable ADC channel 0 (From Arduino Due: ADC → DMA → USB @ 1MSPS · GitHub):
volatile int bufn, obufn;
const uint16_t bufsize = 256;
uint16_t buf[4][bufsize];
void setup()
{
SerialUSB.begin(250000);
while(!SerialUSB);
pinMode(LED_BUILTIN, OUTPUT);
adc_setup();
}
void loop() {
while (obufn == bufn); // wait for buffer to be full
SerialUSB.write((uint8_t *)buf[obufn], 512); // send it - 512 bytes = 256 uint16_t
obufn = (obufn + 1) & 3;
}
/*************** Configure ADC ******************************/
void adc_setup() {
PMC->PMC_PCER1 |= PMC_PCER1_PID37; // Enable ADC
ADC->ADC_MR = ADC_MR_TRGEN_DIS
| ADC_MR_FREERUN_ON // free running
| ADC_MR_PRESCAL(0);
ADC->ADC_ACR = ADC_ACR_IBCTL(0b01);
ADC->ADC_CHER = ADC_CHER_CH0; // Enable Channel 0 = A7
ADC->ADC_IER |= ADC_IER_ENDRX ;
NVIC_EnableIRQ(ADC_IRQn); // Enable ADC interrupt
/************* PDC/DMA buffer filling *******************/
ADC->ADC_RPR = (uint32_t)buf[0]; // DMA buffer
ADC->ADC_RCR = bufsize;
ADC->ADC_RNPR = (uint32_t)buf[1]; // next DMA buffer
ADC->ADC_RNCR = bufsize;
bufn = obufn = 1;
ADC->ADC_PTCR |= ADC_PTCR_RXTEN; // Enable PDC receiver channel request
ADC->ADC_CR = ADC_CR_START;
}
void ADC_Handler() { // move DMA pointer to next buffer
if ( ADC->ADC_ISR & ADC_ISR_ENDRX) {
bufn = (bufn + 1) & 3;
ADC->ADC_RNPR = (uint32_t)buf[bufn];
ADC->ADC_RNCR = bufsize;
}
// For debugging only
static uint32_t Count;
if (Count++ > 3906) { // 3906 = 10E6/256
Count = 0;
PIOB->PIO_ODSR ^= PIO_ODSR_P27;
}
}
With the code below, I can reach 999 938 Hz in Free Running Mode with Prescal (1) and 1 908 976 Hz with Prescal (0), not bad for ADC conversions followed by DAC conversions of 128 Half words buffers:
/*******************************************************************************************/
/* ADC and DAC in FREE Running Mode and PDC DMA */
/*******************************************************************************************/
volatile uint32_t Timestamp, Oldmicros;
volatile boolean Flag;
volatile uint8_t bufn, bufn_dac;
const uint16_t bufsize = 128; // size must be a power of 2
const uint8_t bufnumber = 4; // bufnumber > 2, better be a power of 2
const uint8_t _bufnumber = bufnumber - 1;
uint16_t buf[bufnumber][bufsize]; // bufnumber buffers of bufsize samples,
void setup()
{
Serial.begin(250000);
pinMode(LED_BUILTIN, OUTPUT);
adc_setup();
dac_setup();
Oldmicros = micros();
}
void loop()
{
if (Flag) {
Flag = false;
Serial.println(Timestamp);
}
}
/************* Configure adc_setup 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_DIS // Free Running Mode selected
| ADC_MR_FREERUN
| ADC_MR_PRESCAL(0); // Or PRESCAL (1) to reduce ADC frequency to 21 MHz
ADC->ADC_ACR = ADC_ACR_IBCTL(0b01); // For frequencies > 500 KHz
ADC->ADC_IER = ADC_IER_ENDRX; // End Of Conversion interrupt enable for channel 7
NVIC_EnableIRQ(ADC_IRQn); // Enable ADC interrupt
ADC->ADC_CHER = ADC_CHER_CH7; // Enable Channel 7 = A0
/********* code for PDC/DMA buffer filling sequence **********/
ADC->ADC_RPR = (uint32_t)buf[1]; // DMA buffer - First one will be buf[1]
ADC->ADC_RCR = bufsize;
ADC->ADC_RNPR = (uint32_t)buf[2]; // next DMA buffer
ADC->ADC_RNCR = bufsize;
bufn = 2;
ADC->ADC_PTCR |= ADC_PTCR_RXTEN; // Enable PDC Receiver channel request
ADC->ADC_CR = ADC_CR_START;
}
/********* Call back function for ADC PDC/DMA **************/
void ADC_Handler () {
bufn = (bufn + 1) & _bufnumber;
ADC->ADC_RNPR = (uint32_t)buf[bufn];
ADC->ADC_RNCR = bufsize;
bufn_dac = (bufn_dac + 1) & _bufnumber;
DACC->DACC_TNPR = (uint32_t)buf[bufn_dac];
DACC->DACC_TNCR = bufsize;
// For debugging only
static uint32_t Count;
if (Count++ == 7812) { //1000000/128 ~7812
Timestamp = micros() - Oldmicros;
Oldmicros = micros();
Flag = true;
Count = 0;
PIOB->PIO_ODSR ^= PIO_ODSR_P27; // Toggle LED_BUILTIN every 1 Hz
}
}
/************* Configure dac_setup function *******************/
void dac_setup ()
{
PMC->PMC_PCER1 = PMC_PCER1_PID38; // DACC power ON
DACC->DACC_CR = DACC_CR_SWRST ; // Reset DACC
DACC->DACC_MR = DACC_MR_TRGEN_DIS // Free Running Mode selected
| DACC_MR_USER_SEL_CHANNEL1 // select channel 1
| DACC_MR_REFRESH (1)
| DACC_MR_STARTUP_8
| DACC_MR_MAXS;
DACC->DACC_ACR = DACC_ACR_IBCTLCH0(0b10)
| DACC_ACR_IBCTLCH1(0b10)
| DACC_ACR_IBCTLDACCORE(0b01);
DACC->DACC_IER = DACC_IER_ENDTX;
DACC->DACC_CHER = DACC_CHER_CH1; // enable channel 1 = DAC1
/************* configure PDC/DMA for DAC *******************/
DACC->DACC_TPR = (uint32_t)buf[0]; // DMA buffer
DACC->DACC_TCR = bufsize;
DACC->DACC_TNPR = (uint32_t)buf[1]; // next DMA buffer
DACC->DACC_TNCR = bufsize;
bufn_dac = 1;
DACC->DACC_PTCR = DACC_PTCR_TXTEN; // Enable PDC Transmit channel request
}