#include <ADC.h>
#include <DMAChannel.h>
#define BUFFER_SIZE 100
ADC adc;
// Variables for ADC0
volatile DMAMEM uint16_t adc0_buf[BUFFER_SIZE]; // buffer 1...
volatile uint8_t adc0_busy = 0;
DMAChannel adc0_dma;
// Variables for ADC1
volatile DMAMEM uint16_t adc1_buf[BUFFER_SIZE];
volatile uint8_t adc1_busy = 0;
DMAChannel adc1_dma;
// References for ISRs...
extern void adc0_dma_isr(void);
extern void adc1_dma_isr(void);
void setup() {
while (!Serial && millis() < 3000) ;
Serial.begin(115200);
Serial.println("Test DMA Analog Read");
// Initialize the
adc.setAveraging(4);
adc.setResolution(12);
adc.setConversionSpeed(ADC_CONVERSION_SPEED::MED_SPEED, ADC_0); // change the conversion speed
adc.setSamplingSpeed(ADC_SAMPLING_SPEED::MED_SPEED, ADC_0); // change the sampling speed
adc.setAveraging(4, ADC_1);
adc.setResolution(12, ADC_1);
adc.setConversionSpeed(ADC_CONVERSION_SPEED::MED_SPEED, ADC_1); // change the conversion speed
adc.setSamplingSpeed(ADC_SAMPLING_SPEED::MED_SPEED, ADC_1); // change the sampling speed
Serial.printf("First Read of A13: %d\n", adc.analogRead(A13));
Serial.printf("First Read of A14: %d\n", adc.analogRead(A14));
Serial.printf("First Read of A15: %d\n", adc.analogRead(A15));
Serial.printf("First Read of A16: %d\n", adc.analogRead(A16));
// Lets setup Analog 0 dma
adc0_dma.source((volatile uint16_t&)ADC0_RA);
adc0_dma.destinationBuffer(adc0_buf, sizeof(adc0_buf));
adc0_dma.triggerAtHardwareEvent (DMAMUX_SOURCE_ADC0);
adc0_dma.interruptAtCompletion();
adc0_dma.disableOnCompletion();
adc0_dma.attachInterrupt(&adc0_dma_isr);
NVIC_DISABLE_IRQ(IRQ_PDB); // we don't want or need the PDB interrupt
// Lets setup Analog 1 dma
adc1_dma.source((volatile uint16_t&)ADC1_RA);
adc1_dma.destinationBuffer(adc1_buf, sizeof(adc1_buf));
adc1_dma.triggerAtHardwareEvent (DMAMUX_SOURCE_ADC1);
adc1_dma.interruptAtCompletion();
adc1_dma.disableOnCompletion();
adc1_dma.attachInterrupt(&adc1_dma_isr);
}
void loop() {
// put your main code here, to run repeatedly:
Serial.println("Enter any key to run sample");
while (Serial.read() == -1) ;
while (Serial.read() != -1) ;
Serial.println("Start Sample");
memset((void*)adc0_buf, 0, sizeof(adc0_buf));
memset((void*)adc1_buf, 0, sizeof(adc1_buf));
uint32_t start_time = millis();
// Start 0
adc0_busy = 1;
adc1_busy = 1;
adc.adc0->startSingleRead(A14);
adc.adc1->startSingleRead(A13);
adc0_dma.enable();
adc1_dma.enable();
adc.enableDMA(ADC_0);
adc.enableDMA(ADC_1);
adc0_dma.enable();
adc1_dma.enable();
adc.adc0->startPDB(60 * 50);
adc.adc1->startPDB(60 * 50);
dumpDMA_TCD("ADC_0", &adc0_dma);
dumpDMA_TCD("ADC_1", &adc1_dma);
while (adc0_busy || adc1_busy) {
if ((millis() - start_time) > 1000) {
Serial.printf("Timeout %d %d\n", adc0_busy, adc1_busy);
break;
}
}
[COLOR="#FF0000"] PDB0_CH1C1 = 0;
PDB0_CH0C1 = 0;[/COLOR]
adc.adc0->stopPDB();
adc0_dma.disable();
adc.disableDMA(ADC_0);
adc0_dma.disable();
adc.adc1->stopPDB();
adc.adc1->stopPDB();
adc1_dma.disable();
adc.disableDMA(ADC_1);
dumpDMA_TCD("ADC_0", &adc0_dma);
dumpDMA_TCD("ADC_1", &adc1_dma);
Serial.printf("Sample completed: %d\n", millis() - start_time);
for (int i = 0; i < BUFFER_SIZE; i++) {
Serial.printf("%4u ", adc0_buf[i]);
if ((i % 20) == 19) Serial.println();
}
Serial.println("\n");
for (int i = 0; i < BUFFER_SIZE; i++) {
Serial.printf("%4u ", adc1_buf[i]);
if ((i % 20) == 19) Serial.println();
}
Serial.println();
}
void adc0_dma_isr(void)
{
adc0_busy = false;
adc0_dma.clearInterrupt();
adc0_dma.clearComplete();
}
void adc1_dma_isr(void)
{
adc1_busy = false;
adc1_dma.clearInterrupt();
adc1_dma.clearComplete();
}
typedef struct __attribute__((packed, aligned(4))) {
uint32_t SADDR;
int16_t SOFF;
uint16_t ATTR;
uint32_t NBYTES;
int32_t SLAST;
uint32_t DADDR;
int16_t DOFF;
uint16_t CITER;
int32_t DLASTSGA;
uint16_t CSR;
uint16_t BITER;
} TCD_DEBUG;
void dumpDMA_TCD(const char *psz, DMABaseClass *dmabc)
{
Serial.printf("%s %08x %08x:", psz, (uint32_t)dmabc, (uint32_t)dmabc->TCD);
TCD_DEBUG *tcd = (TCD_DEBUG*)dmabc->TCD;
Serial.printf("%08x %04x %04x %08x %08x ", tcd->SADDR, tcd->SOFF, tcd->ATTR, tcd->NBYTES, tcd->SLAST);
Serial.printf("%08x %04x %04x %08x %04x %04x\n", tcd->DADDR, tcd->DOFF, tcd->CITER, tcd->DLASTSGA,
tcd->CSR, tcd->BITER);
}