Hi.
I'm trying to create an API for reading all analog input trough PDC controler. I inspire myself by this example: arduino-due-adc-channel-sequence
I check pin map with : Due-pinout-WEB.png
I modify a bit the code for reading all 12 input and put it into an array buffer. It work fine for A0 to A7, then when it come into reading data from ADC_SEQR2, it seem to do not work.
here the code. Thanks.
#include <Streaming.h>
int const NUM_CHANNELS=12;
uint16_t global_ADCounts_Array[NUM_CHANNELS]; // holds the raw data from the analog to digital
void setup_AtoD(){
// Arduino Due ADC->DMA
// modified by contravalent from code on the internet by "Stimmer"
// this routine reads the two arduino channels A0 and A1
// fills the array global_ADCounts_Array in the background, with data from the ADC
pmc_enable_periph_clk(ID_ADC); //power management controller told to turn on adc
ADC->ADC_CR |=1; //reset the adc
ADC->ADC_MR= 0x9038ff00; //this setting is used by arduino.
// prescale : ADC clock is mck/((prescale+1)*2). mck is 84MHZ.
// prescale : 0xFF=255=164.0625KHz
//ADC->ADC_MR &=0xFFFF00FF; //mode register "prescale" zeroed out.
//ADC->ADC_MR |=0x0000ff00; //slow down the adc clock so we don't interrupt so often . this divide sets it very slow
//ADC->ADC_EMR |= (1<<24); // turn on channel numbers
ADC->ADC_CHDR=0xFFFFFFFF; // disable all channels
ADC->ADC_CHER=0x3cff; // use channels A0 to A11
ADC->ADC_MR |=0x80000000; //USEQ bit set, saying use the sequence
ADC->ADC_SEQR1=0x01234567; // use A0 to A7 in order into array
ADC->ADC_SEQR2=0xdcba; //use A8 to A11 following in order into array
NVIC_EnableIRQ(ADC_IRQn); // interrupt controller set to enable adc.
ADC->ADC_IDR=~((1<<27)); // interrupt disable register, disables all interrupts but ENDRX
ADC->ADC_IER=(1<<27); // interrupt enable register, enables only ENDRX
Serial.println();
Serial.print("mode register ="); Serial.println(REG_ADC_MR, HEX);
Serial.print("channel enabled register ="); Serial.println(REG_ADC_CHSR, HEX);
Serial.print("sequence register1 ="); Serial.println(REG_ADC_SEQR1, HEX);
Serial.print("interrupts ="); Serial.println(REG_ADC_IMR, HEX); delay(5000);
// following are the DMA controller registers for this peripheral
// "receive buffer address"
ADC->ADC_RPR=(uint32_t) global_ADCounts_Array; // DMA receive pointer register points to beginning of global_ADCount
// "receive count"
ADC->ADC_RCR=NUM_CHANNELS; // receive counter set to 4
// "next-buffer address"
ADC->ADC_RNPR=(uint32_t)global_ADCounts_Array; // next receive pointer register DMA global_ADCounts_Arrayfer points to second set of data
// and "next count"
ADC->ADC_RNCR=NUM_CHANNELS; // and next counter is set to 4
// "transmit control register"
ADC->ADC_PTCR=1; // transfer control register for the DMA is set to enable receiver channel requests
// now that all things are set up, it is safe to start the ADC.....
ADC->ADC_MR |=0x80; // mode register of adc bit seven, free run, set to free running. starts ADC
}
void ADC_Handler()
{ // for the ATOD: re-initialize DMA pointers and count
int f=ADC->ADC_ISR; // read the interrupt status register
if (f & (1<<27)){ /// check the bit "endrx" in the status register
/// set up the "next pointer register"
ADC->ADC_RNPR=(uint32_t) global_ADCounts_Array; // "receive next pointer" register set to global_ADCounts_Array
// set up the "next count"
ADC->ADC_RNCR=NUM_CHANNELS; // "receive next" counter set to 12
}
}
void setup(){
Serial.begin(115200);
setup_AtoD();
analogReadResolution(12);
}
void loop() {
ADC_Handler();
int temp[NUM_CHANNELS];
for (int i = 0; i < NUM_CHANNELS; i++){
temp[i] = global_ADCounts_Array[i]&=0xFFF;
Serial << "temp 0 = " << temp[i] << endl;
}
Serial << endl;
delay(500);
}