Bug in Teensyduino 1.53? ADC examples not working

Status
Not open for further replies.

Alex_Str

New member
Hello. I just bought a couple of Teensys 4.0 to test for a project in which I would like fast ADC readings.
I was very impressed by the specs of the board and have plenty of ideas what to do with it. I just got up a little frustrated with the basic examples that come with the IDE not working.

Setup: Catalina MacOS, Teensyduino 1.53 installed in top of Arduino IDE (that got replaced, I suppose). I used the recommended installation for Catalina (standalone version).
Arduino IDE has ESP32 libraries installed as well. That is because I use the ESP32 as well, so was happy that did not get overridden.

When I run the example adc_dma from the example section it compiles and uploads and then prints nothing on the serial monitor.
Board is set to Teensy 4.0, so there should be no issue.
I modified the programme and it turns out that #ifdef ADC_USE_DMA is false and it runs the empty sketch. I modified the empty sketch in the end to print
"I don't seem to know about DMA" to the serial line, and this line does print in the serial monitor.
It seems to me that the Teensyduino uses an adc library of the ESP32 instead, or some other ADC library.

Anyway, I then downloaded the github version of the ADC library and placed it in my local Arduino library folder. Now the example adc_dma showed up in another section. This time it ran and produces numbers, and it all seems to work just fine. I am pretty sure that this is not intented behaviour, so was wondering if I can get this to work without having to copy things manually.
More seriously though the adc_timer_dma example runs the empty sketch again. There is something very wrong here. These sketches should all be running out of the box, right?

Am I doing something wrong here? Is there a mismatch between installed ESP32 libraries and the Teensy libraries that come with Teensyduino?

I want to use timed ADC readings from several ADCs and run a (complex) FFT on them. So I am really interested to learn how the adc_timer_dma example works as soon as I get it to run.

Any hint may be appreciated to get this running.

Best wishes,

Alex
 
I am not sure what state ADC library was when the last version of Teensyduino was released. That is usually some time during the Beta/Release cycle of Teensyduino, Paul will take in Pull Requests and/or get the current versions of libraries like ADC from the owner, in this case @pedvide.
And yes a goal is and should be it should just work. But often times not every library, example is run by anyone during the beta cycle for new releases.

So it is very possible that @pedvide has made changes since the version of Teensyduino released.

As for Working on MAC.. I don't do this much. I do have a secondary machine a MAC portable, but again it is very secondary. And yes with the latest changes to MAC OS, Paul could no longer release Teensyduino for the MAC, the same way that they used to. So now he needs to build a complete package including Arduino, such that it can pass all of the new MAC OS requirements for installation. So yes it replaces complete package. It does not replace your local libraries folder nor the stuff that is installed by the Arduino Board Manager which are stored in different location.

As for the Example sketch. If your board type is set to Teensy 4 (or any of the 3.x or LC...) I believe that define should be set.

That is in the library there is the file settings_defines.h
Which has section
Code:
// Use DMA?
#if defined(ADC_TEENSY_3_1) // Teensy 3.1
#define ADC_USE_DMA
#elif defined(ADC_TEENSY_3_0) // Teensy 3.0
#define ADC_USE_DMA
#elif defined(ADC_TEENSY_LC) // Teensy LC
#define ADC_USE_DMA
#elif defined(ADC_TEENSY_3_5) // Teensy 3.5
#define ADC_USE_DMA
#elif defined(ADC_TEENSY_3_6) // Teensy 3.6
#define ADC_USE_DMA
#elif defined(ADC_TEENSY_4) // Teensy 4, 4.1
#define ADC_USE_DMA
#endif

So should do something?

Edit: Note, a build should show you which library was used. So double check it is not grabbing some bogus one from somewhere else.

Like if you had some old version in your <sketches folder>/libraries

Which the Arduino IDE will use instead of the one installed by Teensyduino.
 
Thanks Kurt,

I deleted all local libraries from Documents/Arduino/libraries and then tried again. Same picture.
Then I followed your advice and compiled to see what library is being used.
The library is simply ignored with

#ifdef ADC_USE_DMA

#include <ADC.h>

so I replaced

#ifdef ADC_USE_DMA

#include <ADC.h>

by

#include <ADC.h>

#ifdef ADC_USE_DMA

and then get following error:

---------------------------------------------------------------------
Code:
/Applications/Teensyduino.app/Contents/Java/arduino-builder -dump-prefs -logger=machine -hardware /Applications/Teensyduino.app/Contents/Java/hardware -hardware /Users/alex/Library/Arduino15/packages -tools /Applications/Teensyduino.app/Contents/Java/tools-builder -tools /Applications/Teensyduino.app/Contents/Java/hardware/tools/avr -tools /Users/alex/Library/Arduino15/packages -built-in-libraries /Applications/Teensyduino.app/Contents/Java/libraries -libraries /Users/alex/Documents/Arduino/libraries -fqbn=teensy:avr:teensy40:usb=serial,speed=600,opt=o1std,keys=en-us -vid-pid=16C0_0483 -ide-version=10813 -build-path /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156 -warnings=none -build-cache /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_cache_563881 -verbose /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_modified_sketch_606246/adc_dma.ino
/Applications/Teensyduino.app/Contents/Java/arduino-builder -compile -logger=machine -hardware /Applications/Teensyduino.app/Contents/Java/hardware -hardware /Users/alex/Library/Arduino15/packages -tools /Applications/Teensyduino.app/Contents/Java/tools-builder -tools /Applications/Teensyduino.app/Contents/Java/hardware/tools/avr -tools /Users/alex/Library/Arduino15/packages -built-in-libraries /Applications/Teensyduino.app/Contents/Java/libraries -libraries /Users/alex/Documents/Arduino/libraries -fqbn=teensy:avr:teensy40:usb=serial,speed=600,opt=o1std,keys=en-us -vid-pid=16C0_0483 -ide-version=10813 -build-path /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156 -warnings=none -build-cache /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_cache_563881 -verbose /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_modified_sketch_606246/adc_dma.ino
Using board 'teensy40' from platform in folder: /Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr
Using core 'teensy4' from platform in folder: /Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr
Detecting libraries used...
/Applications/Teensyduino.app/Contents/Java/hardware/teensy/../tools/arm/bin/arm-none-eabi-g++ -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=153 -DARDUINO=10813 -DARDUINO_TEENSY40 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -I/Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/cores/teensy4 /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156/sketch/adc_dma.ino.cpp -o /dev/null -DARDUINO_LIB_DISCOVERY_PHASE
Alternatives for ADC.h: [ADC@8.0]
ResolveLibrary(ADC.h)
  -> candidates: [ADC@8.0]
/Applications/Teensyduino.app/Contents/Java/hardware/teensy/../tools/arm/bin/arm-none-eabi-g++ -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=153 -DARDUINO=10813 -DARDUINO_TEENSY40 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -I/Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/cores/teensy4 -I/Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/ADC /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156/sketch/adc_dma.ino.cpp -o /dev/null -DARDUINO_LIB_DISCOVERY_PHASE
Using cached library dependencies for file: /Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/ADC/ADC.cpp
Using cached library dependencies for file: /Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/ADC/ADC_Module.cpp
Using cached library dependencies for file: /Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/ADC/AnalogBufferDMA.cpp
Generating function prototypes...
/Applications/Teensyduino.app/Contents/Java/hardware/teensy/../tools/arm/bin/arm-none-eabi-g++ -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=153 -DARDUINO=10813 -DARDUINO_TEENSY40 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -I/Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/cores/teensy4 -I/Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/ADC /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156/sketch/adc_dma.ino.cpp -o /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156/preproc/ctags_target_for_gcc_minus_e.cpp -DARDUINO_LIB_DISCOVERY_PHASE
/Applications/Teensyduino.app/Contents/Java/tools-builder/ctags/5.8-arduino11/ctags -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156/preproc/ctags_target_for_gcc_minus_e.cpp
Compiling sketch...
/Applications/Teensyduino.app/Contents/Java/hardware/teensy/../tools/precompile_helper /Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/cores/teensy4 /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156 /Applications/Teensyduino.app/Contents/Java/hardware/teensy/../tools/arm/bin/arm-none-eabi-g++ -x c++-header -O1 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=153 -DARDUINO=10813 -DARDUINO_TEENSY40 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -I/Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/cores/teensy4 /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156/pch/Arduino.h -o /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156/pch/Arduino.h.gch
Using previously compiled file: /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156/pch/Arduino.h.gch
/Applications/Teensyduino.app/Contents/Java/hardware/teensy/../tools/arm/bin/arm-none-eabi-g++ -c -O1 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=153 -DARDUINO=10813 -DARDUINO_TEENSY40 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -I/var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156/pch -I/Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/cores/teensy4 -I/Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/ADC /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156/sketch/adc_dma.ino.cpp -o /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156/sketch/adc_dma.ino.cpp.o
Compiling libraries...
Compiling library "ADC"
Using previously compiled file: /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156/libraries/ADC/AnalogBufferDMA.cpp.o
Using previously compiled file: /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156/libraries/ADC/ADC.cpp.o
Using previously compiled file: /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156/libraries/ADC/ADC_Module.cpp.o
Compiling core...
Using precompiled core: /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_cache_563881/core/core_189b2c9c57ac3f669330a8b8d658d974.a
Linking everything together...
/Applications/Teensyduino.app/Contents/Java/hardware/teensy/../tools/arm/bin/arm-none-eabi-gcc -O1 -Wl,--gc-sections,--relax -T/Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/cores/teensy4/imxrt1062.ld -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -o /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156/adc_dma.ino.elf /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156/sketch/adc_dma.ino.cpp.o /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156/libraries/ADC/ADC.cpp.o /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156/libraries/ADC/ADC_Module.cpp.o /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156/libraries/ADC/AnalogBufferDMA.cpp.o /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156/../arduino_cache_563881/core/core_189b2c9c57ac3f669330a8b8d658d974.a -L/var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156 -larm_cortexM7lfsp_math -lm -lstdc++
/var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156/sketch/adc_dma.ino.cpp.o: In function `setup':
/var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_modified_sketch_606246/adc_dma.ino:79: undefined reference to `AnalogBufferDMA::init(ADC*, signed char)'
/var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_modified_sketch_606246/adc_dma.ino:85: undefined reference to `AnalogBufferDMA::init(ADC*, signed char)'
collect2: error: ld returned 1 exit status
Using library ADC at version 8.0 in folder: /Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/ADC 
Error compiling for board Teensy 4.0.
---------------------------------------------------------------------

Indeed in /Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/ADC the file settings_defines.h contains the lines
// Use DMA?
#if defined(ADC_TEENSY_3_1) // Teensy 3.1
#define ADC_USE_DMA
#elif defined(ADC_TEENSY_3_0) // Teensy 3.0
#define ADC_USE_DMA
#elif defined(ADC_TEENSY_LC) // Teensy LC
#define ADC_USE_DMA
#elif defined(ADC_TEENSY_3_5) // Teensy 3.5
#define ADC_USE_DMA
#elif defined(ADC_TEENSY_3_6) // Teensy 3.6
#define ADC_USE_DMA
#elif defined(ADC_TEENSY_4) // Teensy 4, 4.1
#define ADC_USE_DMA
#endif

-----

but this somehow did not get translated.

It seems the supplied library does not work and #ADC_USE_DMA is set to false.
I would like to fix this without creating a Zombie version of Teensyduino that I can never again update.

Alex
 
Last edited by a moderator:
maybe the problem lies in
Code:
Using previously compiled file: /var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156/libraries/ADC/AnalogBufferDMA.cpp.o
to force a complete rebuild (whenever you change something in libraries)
either change something in tools (e.g. speed) or close and reopen Arduino.
Unfortunately Arduino has no easy Rebuild all option
 
You are right the examples were screwed up. I looked up in @pedvide's github and see the last code delta was:
https://github.com/pedvide/ADC/commit/550aee0a6040f703ca91293716012c2b54b65e33
Which title is: fix ADC_USE_DMA placement

i.e. how would that #define be defined if we had not already included the file that might define it...

My version (fork of @pedvide github project is in sync with his) and the adc_dma from there appears to compile fine for me for both T4 and T4.1.

So you might want to compare yours to the one up on his release and see if there are any differences. I know that the error messages:

/var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_build_859156/sketch/adc_dma.ino.cpp.o: In function `setup':
/var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_modified_sketch_606246/adc_dma.ino:79: undefined reference to `AnalogBufferDMA::init(ADC*, signed char)'
/var/folders/kr/g2dq1nfj5r3g9fqgvn440m1m0000gn/T/arduino_modified_sketch_606246/adc_dma.ino:85: undefined reference to `AnalogBufferDMA::init(ADC*, signed char)'

that lines 79 and 85 are not calls to init

Here is the version I built:
Code:
/* Example for using DMA with ADC
    This example uses DMA object to do the sampling.  It does not use a timer so it runs
    at whatever speed the ADC will run at with current settings.

    It should work for Teensy LC, 3.x and T4

  DMA: using AnalogBufferDMA with two buffers, this runs in continuous mode and when one buffer fills
    an interrupt is signaled, which sets flag saying it has data, which this test application
    scans the data, and computes things like a minimum, maximum, average values and an RMS value.
    For the RMS it keeps the average from the previous set of data.
*/

#include <ADC.h>
#include <AnalogBufferDMA.h>

#ifdef ADC_USE_DMA

// This version uses both ADC1 and ADC2
#if defined(KINETISL)
const int readPin_adc_0 = A0;
#elif defined(KINETISK)
const int readPin_adc_0 = A0;
const int readPin_adc_1 = A2;
#else
const int readPin_adc_0 = A0;
const int readPin_adc_1 = 26;
#endif

ADC *adc = new ADC(); // adc object
const uint32_t initial_average_value = 2048;

// Going to try two buffers here  using 2 dmaSettings and a DMAChannel
#ifdef KINETISL
const uint32_t buffer_size = 500;
#else
const uint32_t buffer_size = 1600;
#endif

DMAMEM static volatile uint16_t __attribute__((aligned(32))) dma_adc_buff1[buffer_size];
DMAMEM static volatile uint16_t __attribute__((aligned(32))) dma_adc_buff2[buffer_size];
AnalogBufferDMA abdma1(dma_adc_buff1, buffer_size, dma_adc_buff2, buffer_size);

#ifdef ADC_DUAL_ADCS
DMAMEM static volatile uint16_t __attribute__((aligned(32))) dma_adc2_buff1[buffer_size];
DMAMEM static volatile uint16_t __attribute__((aligned(32))) dma_adc2_buff2[buffer_size];
AnalogBufferDMA abdma2(dma_adc2_buff1, buffer_size, dma_adc2_buff2, buffer_size);
#endif

void setup() {
    while (!Serial && millis() < 5000) ;

    pinMode(LED_BUILTIN, OUTPUT);
    pinMode(readPin_adc_0, INPUT); //pin 23 single ended
#ifdef ADC_DUAL_ADCS
    pinMode(readPin_adc_1, INPUT);
#endif

    Serial.begin(9600);
    Serial.println("Setup ADC_0");
    // reference can be ADC_REFERENCE::REF_3V3, ADC_REFERENCE::REF_1V2 (not for Teensy LC) or ADC_REF_EXT.
    //adc->setReference(ADC_REFERENCE::REF_1V2, ADC_0); // change all 3.3 to 1.2 if you change the reference to 1V2

    adc->adc0->setAveraging(8); // set number of averages
    adc->adc0->setResolution(12); // set bits of resolution


    // always call the compare functions after changing the resolution!
    //adc->enableCompare(1.0/3.3*adc->getMaxValue(ADC_0), 0, ADC_0); // measurement will be ready if value < 1.0V
    //adc->enableCompareRange(1.0*adc->getMaxValue(ADC_1)/3.3, 2.0*adc->getMaxValue(ADC_1)/3.3, 0, 1, ADC_1); // ready if value lies out of [1.0,2.0] V

    // enable DMA and interrupts
    Serial.println("before enableDMA"); Serial.flush();


    // setup a DMA Channel.
    // Now lets see the different things that RingbufferDMA setup for us before
    abdma1.init(adc, ADC_0);
    abdma1.userData(initial_average_value); // save away initial starting average
#ifdef ADC_DUAL_ADCS
    Serial.println("Setup ADC_1");
    adc->adc1->setAveraging(8); // set number of averages
    adc->adc1->setResolution(12); // set bits of resolution
    abdma2.init(adc, ADC_1);
    abdma2.userData(initial_average_value); // save away initial starting average
    adc->adc1->startContinuous(readPin_adc_1);
#endif

    // Start the dma operation..
    adc->adc0->startContinuous(readPin_adc_0);

    Serial.println("End Setup");
}

char c = 0;


void loop() {

    // Maybe only when both have triggered?
#ifdef ADC_DUAL_ADCS
    if ( abdma1.interrupted() && abdma2.interrupted()) {
        if (abdma1.interrupted()) ProcessAnalogData(&abdma1, 0);
        if (abdma2.interrupted()) ProcessAnalogData(&abdma2, 1);
        Serial.println();
    }
#else
    if ( abdma1.interrupted()) {
        ProcessAnalogData(&abdma1, 0);
        Serial.println();
    }
#endif

}

void ProcessAnalogData(AnalogBufferDMA *pabdma, int8_t adc_num) {
  uint32_t sum_values = 0;
  uint16_t min_val = 0xffff;
  uint16_t max_val = 0;

  uint32_t average_value = pabdma->userData();

  volatile uint16_t *pbuffer = pabdma->bufferLastISRFilled();
  volatile uint16_t *end_pbuffer = pbuffer + pabdma->bufferCountLastISRFilled();

  float sum_delta_sq = 0.0;
  if ((uint32_t)pbuffer >= 0x20200000u)  arm_dcache_delete((void*)pbuffer, sizeof(dma_adc_buff1));
  while (pbuffer < end_pbuffer) {
    if (*pbuffer < min_val) min_val = *pbuffer;
    if (*pbuffer > max_val) max_val = *pbuffer;
    sum_values += *pbuffer;
    int delta_from_center = (int) * pbuffer - average_value;
    sum_delta_sq += delta_from_center * delta_from_center;

    pbuffer++;
  }

  int rms = sqrt(sum_delta_sq / buffer_size);
  average_value = sum_values / buffer_size;
  Serial.printf(" %d - %u(%u): %u <= %u <= %u %d ", adc_num, pabdma->interruptCount(), pabdma->interruptDeltaTime(), min_val,
                average_value, max_val, rms);
  pabdma->clearInterrupt();

  pabdma->userData(average_value);
}

#else // make sure the example can run for any boards (automated testing)
void setup() {}
void loop() {}
#endif // ADC_USE_DMA
 
Hi again,

below is the example code included in Teensyduino. Is does not compile even if I close and open Arduino or change the speed setting. I don't feel competent to judge what the problem is.
Sorry, I don't know much about programming and libraries and only just started learning it as a hobby.
Anyway, now I realise that I should have seen that the examples are incorrect, in fact only some have been corrected in the most recent github version.
I have installed the github version back into the local folder and the example adc_timer_dma still has the same mixup and did not work because of it.
However, it does compile and work once the lines are interchanged.
More concretely,

#if defined(ADC_USE_DMA) && defined(ADC_USE_TIMER)

#include <ADC.h>
#include <DMAChannel.h>
#include <AnalogBufferDMA.h>

needs to be

#include <ADC.h>
#include <DMAChannel.h>
#include <AnalogBufferDMA.h>

#if defined(ADC_USE_DMA) && defined(ADC_USE_TIMER)

and voila, it works.

I don't know how to report this to the ADC maintainer.
Anyway, now you know, so hopefully it will work with the next version of Teensyduino, which I am looking forward to.

Many thanks for your help,

Alex

-------------------------------------------------------

/* Example for using DMA with ADC
This example uses DMA object to do the sampling. It does not use a timer so it runs
at whatever speed the ADC will run at with current settings.

It should work for Teensy LC, 3.x and T4

DMA: using AnalogBufferDMA with two buffers, this runs in continuous mode and when one buffer fills
an interrupt is signaled, which sets flag saying it has data, which this test application
scans the data, and computes things like a minimum, maximum, average values and an RMS value.
For the RMS it keeps the average from the previous set of data.
*/


#include <ADC.h>
#include <AnalogBufferDMA.h>

#ifdef ADC_USE_DMA



// This version uses both ADC1 and ADC2
#if defined(KINETISL)
const int readPin_adc_0 = A0;
#elif defined(KINETISK)
const int readPin_adc_0 = A0;
const int readPin_adc_1 = A2;
#else
const int readPin_adc_0 = A0;
const int readPin_adc_1 = 26;
#endif

ADC *adc = new ADC(); // adc object
const uint32_t initial_average_value = 2048;

// Going to try two buffers here using 2 dmaSettings and a DMAChannel
#ifdef KINETISL
const uint32_t buffer_size = 500;
#else
const uint32_t buffer_size = 1600;
#endif

DMAMEM static volatile uint16_t __attribute__((aligned(32))) dma_adc_buff1[buffer_size];
DMAMEM static volatile uint16_t __attribute__((aligned(32))) dma_adc_buff2[buffer_size];
AnalogBufferDMA abdma1(dma_adc_buff1, buffer_size, dma_adc_buff2, buffer_size);

#ifdef ADC_DUAL_ADCS
DMAMEM static volatile uint16_t __attribute__((aligned(32))) dma_adc2_buff1[buffer_size];
DMAMEM static volatile uint16_t __attribute__((aligned(32))) dma_adc2_buff2[buffer_size];
AnalogBufferDMA abdma2(dma_adc2_buff1, buffer_size, dma_adc2_buff2, buffer_size);
#endif

void setup() {
while (!Serial && millis() < 5000) ;

pinMode(LED_BUILTIN, OUTPUT);
pinMode(readPin_adc_0, INPUT); //pin 23 single ended
#ifdef ADC_DUAL_ADCS
pinMode(readPin_adc_1, INPUT);
#endif

Serial.begin(9600);
Serial.println("Setup ADC_0");
// reference can be ADC_REFERENCE::REF_3V3, ADC_REFERENCE::REF_1V2 (not for Teensy LC) or ADC_REF_EXT.
//adc->setReference(ADC_REFERENCE::REF_1V2, ADC_0); // change all 3.3 to 1.2 if you change the reference to 1V2

adc->adc0->setAveraging(8); // set number of averages
adc->adc0->setResolution(12); // set bits of resolution


// always call the compare functions after changing the resolution!
//adc->enableCompare(1.0/3.3*adc->getMaxValue(ADC_0), 0, ADC_0); // measurement will be ready if value < 1.0V
//adc->enableCompareRange(1.0*adc->getMaxValue(ADC_1)/3.3, 2.0*adc->getMaxValue(ADC_1)/3.3, 0, 1, ADC_1); // ready if value lies out of [1.0,2.0] V

// enable DMA and interrupts
Serial.println("before enableDMA"); Serial.flush();


// setup a DMA Channel.
// Now lets see the different things that RingbufferDMA setup for us before
abdma1.init(adc, ADC_0);
abdma1.userData(initial_average_value); // save away initial starting average
#ifdef ADC_DUAL_ADCS
Serial.println("Setup ADC_1");
adc->adc1->setAveraging(8); // set number of averages
adc->adc1->setResolution(12); // set bits of resolution
abdma2.init(adc, ADC_1);
abdma2.userData(initial_average_value); // save away initial starting average
adc->adc1->startContinuous(readPin_adc_1);
#endif

// Start the dma operation..
adc->adc0->startContinuous(readPin_adc_0);

Serial.println("End Setup");
}

char c = 0;


void loop() {

// Maybe only when both have triggered?
#ifdef ADC_DUAL_ADCS
if ( abdma1.interrupted() && abdma2.interrupted()) {
if (abdma1.interrupted()) ProcessAnalogData(&abdma1, 0);
if (abdma2.interrupted()) ProcessAnalogData(&abdma2, 1);
Serial.println();
}
#else
if ( abdma1.interrupted()) {
ProcessAnalogData(&abdma1, 0);
Serial.println();
}
#endif

}

void ProcessAnalogData(AnalogBufferDMA *pabdma, int8_t adc_num) {
uint32_t sum_values = 0;
uint16_t min_val = 0xffff;
uint16_t max_val = 0;

uint32_t average_value = pabdma->userData();

volatile uint16_t *pbuffer = pabdma->bufferLastISRFilled();
volatile uint16_t *end_pbuffer = pbuffer + pabdma->bufferCountLastISRFilled();

float sum_delta_sq = 0.0;
if ((uint32_t)pbuffer >= 0x20200000u) arm_dcache_delete((void*)pbuffer, sizeof(dma_adc_buff1));
while (pbuffer < end_pbuffer) {
if (*pbuffer < min_val) min_val = *pbuffer;
if (*pbuffer > max_val) max_val = *pbuffer;
sum_values += *pbuffer;
int delta_from_center = (int) * pbuffer - average_value;
sum_delta_sq += delta_from_center * delta_from_center;

pbuffer++;
}

int rms = sqrt(sum_delta_sq / buffer_size);
average_value = sum_values / buffer_size;
Serial.printf(" %d - %u(%u): %u <= %u <= %u %d ", adc_num, pabdma->interruptCount(), pabdma->interruptDeltaTime(), min_val,
average_value, max_val, rms);
pabdma->clearInterrupt();

pabdma->userData(average_value);
}

#else // make sure the example can run for any boards (automated testing)
void setup() {}
void loop() {}
#endif // ADC_USE_DMA
 
To report to owner of library, go up to his library:
https://github.com/pedvide/ADC

Click on the issues tab and first see if there is already an issue for it.

Example for the examples for DMA, looks like @defragster opened one:
https://github.com/pedvide/ADC/issues/62

You might see if that one matches yours and if not and there are no others, you can open a new one and/or make a comment on @defrasters...

I am guessing in order to do this you need to have an account on github.
 
Hai

I try to use the adc_timer_dna and I recieve the error message :
Arduino:1.8.13 (Windows 10), TD: 1.53, Board:"Teensy 4.0, Audio, 600 MHz, Faster, US English"

C:\Users\GEBRUI~1\AppData\Local\Temp\arduino_build_119014\sketch\ADCadc_timer_dma_V5.ino.cpp.o: In function `setup':

C:\Users\Gebruiker\Documents\Arduino\MySketchs\ADCadc_timer_dma_V5/ADCadc_timer_dma_V5.ino:68: undefined reference to `AnalogBufferDMA::init(ADC*, signed char)'

C:\Users\Gebruiker\Documents\Arduino\MySketchs\ADCadc_timer_dma_V5/ADCadc_timer_dma_V5.ino:74: undefined reference to `AnalogBufferDMA::init(ADC*, signed char)'

collect2.exe: error: ld returned 1 exit status

Fout bij het compileren voor board Teensy 4.0

I have tried the examples in this forum but all have the same result and it seems imposible to get a working example

The complete code:

/* Example for triggering the ADC with Timer using DMA instead of interrupts
Valid for the current Teensy 3.x and 4.0.


Timers:
On Teensy 3.x this uses the PDB timer.

On Teensy 4, this uses one or two of the unused QTimers.

Setting it up: The variables readPin must be defined for a pin that is valid for the first (or only)
ADC. If the processor has a second ADC and is enabled, than readPin2 must be configured to be a pin
that is valid on the second ADC.

DMA: using AnalogBufferDMA with two buffers, this runs in continuous mode and when one buffer fills
an interrupt is signaled, which sets flag saying it has data, which this test application
scans the data, and computes things like a minimum, maximum, average values and an RMS value.
For the RMS it keeps the average from the previous set of data.
*/

//#if defined(ADC_USE_DMA) && defined(ADC_USE_TIMER)

#include <ADC.h>
#include <DMAChannel.h>
#include <AnalogBufferDMA.h>

//#define PRINT_DEBUG_INFO

// This version uses both ADC1 and ADC2
#ifdef ADC_DUAL_ADCS
const int readPin_adc_0 = A0;
const int readPin_adc_1 = A2;
#else
const int readPin_adc_0 = A0;
const int readPin_adc_1 = 26;
#endif

ADC *adc = new ADC(); // adc object
const uint32_t initial_average_value = 2048;

extern void dumpDMA_structures(DMABaseClass *dmabc);
elapsedMillis elapsed_sinc_last_display;

// Going to try two buffers here using 2 dmaSettings and a DMAChannel

const uint32_t buffer_size = 1600;
DMAMEM static volatile uint16_t __attribute__((aligned(32))) dma_adc_buff1[buffer_size];
DMAMEM static volatile uint16_t __attribute__((aligned(32))) dma_adc_buff2[buffer_size];
AnalogBufferDMA abdma1(dma_adc_buff1, buffer_size, dma_adc_buff2, buffer_size);

#ifdef ADC_DUAL_ADCS
DMAMEM static volatile uint16_t __attribute__((aligned(32))) dma_adc_buff2_1[buffer_size];
DMAMEM static volatile uint16_t __attribute__((aligned(32))) dma_adc_buff2_2[buffer_size];
AnalogBufferDMA abdma2(dma_adc_buff2_1, buffer_size, dma_adc_buff2_2, buffer_size);
#endif

void setup() {
Serial.begin(9600);
while (!Serial && millis() < 5000) ;

pinMode(LED_BUILTIN, OUTPUT);
pinMode(readPin_adc_0, INPUT); // Not sure this does anything for us
#ifdef ADC_DUAL_ADCS
pinMode(readPin_adc_1, INPUT);
#endif

Serial.println("Setup both ADCs");
// Setup both ADCs
adc->adc0->setAveraging(8); // set number of averages
adc->adc0->setResolution(12); // set bits of resolution
#ifdef ADC_DUAL_ADCS
adc->adc1->setAveraging(8); // set number of averages
adc->adc1->setResolution(12); // set bits of resolution
#endif

// enable DMA and interrupts
//Serial.println("before enableDMA"); Serial.flush();


// setup a DMA Channel.
// Now lets see the different things that RingbufferDMA setup for us before
abdma1.init(adc, ADC_0/*, DMAMUX_SOURCE_ADC_ETC*/);
abdma1.userData(initial_average_value); // save away initial starting average
#ifdef ADC_DUAL_ADCS
abdma2.init(adc, ADC_1/*, DMAMUX_SOURCE_ADC_ETC*/);
abdma2.userData(initial_average_value); // save away initial starting average
#endif
//Serial.println("After enableDMA"); Serial.flush();

// Start the dma operation..
adc->adc0->startSingleRead(readPin_adc_0); // call this to setup everything before the Timer starts, differential is also possible
adc->adc0->startTimer(3000); //frequency in Hz

// Start the dma operation..
#ifdef ADC_DUAL_ADCS
adc->adc1->startSingleRead(readPin_adc_1); // call this to setup everything before the Timer starts, differential is also possible
adc->adc1->startTimer(3000); //frequency in Hz
#endif

print_debug_information();

Serial.println("End Setup");
elapsed_sinc_last_display = 0;
}

void loop() {

// Maybe only when both have triggered?
#ifdef ADC_DUAL_ADCS
if ( abdma1.interrupted() && (abdma2.interrupted())) {
if ( abdma1.interrupted()) {
ProcessAnalogData(&abdma1, 0);
}
if ( abdma2.interrupted()) {
ProcessAnalogData(&abdma2, 1);
}
Serial.println();
elapsed_sinc_last_display = 0;
}
#else
if ( abdma1.interrupted()) {
ProcessAnalogData(&abdma1, 0);
Serial.println();
elapsed_sinc_last_display = 0;
}
#endif
if (elapsed_sinc_last_display > 5000) {
// Nothing in 5 seconds, show a heart beat.
digitalWriteFast(13, HIGH);
delay(250);
digitalWriteFast(13, LOW);
delay(250);
digitalWriteFast(13, HIGH);
delay(250);
digitalWriteFast(13, LOW);
elapsed_sinc_last_display = 0;
}
}

void ProcessAnalogData(AnalogBufferDMA *pabdma, int8_t adc_num) {
uint32_t sum_values = 0;
uint16_t min_val = 0xffff;
uint16_t max_val = 0;

uint32_t average_value = pabdma->userData();

volatile uint16_t *pbuffer = pabdma->bufferLastISRFilled();
volatile uint16_t *end_pbuffer = pbuffer + pabdma->bufferCountLastISRFilled();

float sum_delta_sq = 0.0;
if ((uint32_t)pbuffer >= 0x20200000u) arm_dcache_delete((void*)pbuffer, sizeof(dma_adc_buff1));
while (pbuffer < end_pbuffer) {
if (*pbuffer < min_val) min_val = *pbuffer;
if (*pbuffer > max_val) max_val = *pbuffer;
sum_values += *pbuffer;
int delta_from_center = (int) * pbuffer - average_value;
sum_delta_sq += delta_from_center * delta_from_center;

pbuffer++;
}

int rms = sqrt(sum_delta_sq / buffer_size);
average_value = sum_values / buffer_size;
Serial.printf(" %d - %u(%u): %u <= %u <= %u %d ", adc_num, pabdma->interruptCount(), pabdma->interruptDeltaTime(), min_val,
average_value, max_val, rms);
pabdma->clearInterrupt();

pabdma->userData(average_value);
}

void print_debug_information()
{
#ifdef PRINT_DEBUG_INFO
// Lets again try dumping lots of data.
Serial.println("\n*** DMA structures for ADC_0 ***");
dumpDMA_structures(&(abdma1._dmachannel_adc));
dumpDMA_structures(&(abdma1._dmasettings_adc[0]));
dumpDMA_structures(&(abdma1._dmasettings_adc[1]));
Serial.println("\n*** DMA structures for ADC_1 ***");
dumpDMA_structures(&(abdma2._dmachannel_adc));
dumpDMA_structures(&(abdma2._dmasettings_adc[0]));
dumpDMA_structures(&(abdma2._dmasettings_adc[1]));

#if defined(__IMXRT1062__)

Serial.println("\n*** ADC and ADC_ETC ***");
Serial.printf("ADC1: HC0:%x HS:%x CFG:%x GC:%x GS:%x\n", IMXRT_ADC1.HC0, IMXRT_ADC1.HS, IMXRT_ADC1.CFG, IMXRT_ADC1.GC, IMXRT_ADC1.GS);
Serial.printf("ADC2: HC0:%x HS:%x CFG:%x GC:%x GS:%x\n", IMXRT_ADC2.HC0, IMXRT_ADC2.HS, IMXRT_ADC2.CFG, IMXRT_ADC2.GC, IMXRT_ADC2.GS);
Serial.printf("ADC_ETC: CTRL:%x DONE0_1:%x DONE2_ERR:%x DMA: %x\n", IMXRT_ADC_ETC.CTRL,
IMXRT_ADC_ETC.DONE0_1_IRQ, IMXRT_ADC_ETC.DONE2_ERR_IRQ, IMXRT_ADC_ETC.DMA_CTRL);
for (uint8_t trig = 0; trig < 8; trig++) {
Serial.printf(" TRIG[%d] CTRL: %x CHAIN_1_0:%x\n",
trig, IMXRT_ADC_ETC.TRIG[trig].CTRL, IMXRT_ADC_ETC.TRIG[trig].CHAIN_1_0);
}
#endif
#endif
}

#ifdef PRINT_DEBUG_INFO
void dumpDMA_structures(DMABaseClass *dmabc)
{
Serial.printf("%x %x:", (uint32_t)dmabc, (uint32_t)dmabc->TCD);

Serial.printf("SA:%x SO:%d AT:%x NB:%x SL:%d DA:%x DO: %d CI:%x DL:%x CS:%x BI:%x\n", (uint32_t)dmabc->TCD->SADDR,
dmabc->TCD->SOFF, dmabc->TCD->ATTR, dmabc->TCD->NBYTES, dmabc->TCD->SLAST, (uint32_t)dmabc->TCD->DADDR,
dmabc->TCD->DOFF, dmabc->TCD->CITER, dmabc->TCD->DLASTSGA, dmabc->TCD->CSR, dmabc->TCD->BITER);
}
#endif

//#else // make sure the example can run for any boards (automated testing)
//void setup() {}
//void loop() {}
//#endif // ADC_USE_TIMER and DMA
 
The solution replace .h by .cpp in #include <AnalogBufferDMA.cpp> and remove //#if

Hai

/* Example for triggering the ADC with Timer using DMA instead of interrupts
Valid for the current Teensy 3.x and 4.0.


Timers:
On Teensy 3.x this uses the PDB timer.

On Teensy 4, this uses one or two of the unused QTimers.

Setting it up: The variables readPin must be defined for a pin that is valid for the first (or only)
ADC. If the processor has a second ADC and is enabled, than readPin2 must be configured to be a pin
that is valid on the second ADC.

DMA: using AnalogBufferDMA with two buffers, this runs in continuous mode and when one buffer fills
an interrupt is signaled, which sets flag saying it has data, which this test application
scans the data, and computes things like a minimum, maximum, average values and an RMS value.
For the RMS it keeps the average from the previous set of data.
*/

//#if defined(ADC_USE_DMA) && defined(ADC_USE_TIMER)

#include <ADC.h>
#include <DMAChannel.h>
//#include <AnalogBufferDMA.h>
#include <AnalogBufferDMA.cpp>
//#define PRINT_DEBUG_INFO

// This version uses both ADC1 and ADC2
#ifdef ADC_DUAL_ADCS
const int readPin_adc_0 = A0;
const int readPin_adc_1 = A2;
#else
const int readPin_adc_0 = A0;
const int readPin_adc_1 = 26;
#endif

ADC *adc = new ADC(); // adc object
const uint32_t initial_average_value = 2048;

extern void dumpDMA_structures(DMABaseClass *dmabc);
elapsedMillis elapsed_sinc_last_display;

// Going to try two buffers here using 2 dmaSettings and a DMAChannel

const uint32_t buffer_size = 1600;
DMAMEM static volatile uint16_t __attribute__((aligned(32))) dma_adc_buff1[buffer_size];
DMAMEM static volatile uint16_t __attribute__((aligned(32))) dma_adc_buff2[buffer_size];
AnalogBufferDMA abdma1(dma_adc_buff1, buffer_size, dma_adc_buff2, buffer_size);

#ifdef ADC_DUAL_ADCS
DMAMEM static volatile uint16_t __attribute__((aligned(32))) dma_adc_buff2_1[buffer_size];
DMAMEM static volatile uint16_t __attribute__((aligned(32))) dma_adc_buff2_2[buffer_size];
AnalogBufferDMA abdma2(dma_adc_buff2_1, buffer_size, dma_adc_buff2_2, buffer_size);
#endif

void setup() {
Serial.begin(9600);
while (!Serial && millis() < 5000) ;

pinMode(LED_BUILTIN, OUTPUT);
pinMode(readPin_adc_0, INPUT); // Not sure this does anything for us
#ifdef ADC_DUAL_ADCS
pinMode(readPin_adc_1, INPUT);
#endif

Serial.println("Setup both ADCs");
// Setup both ADCs
adc->adc0->setAveraging(8); // set number of averages
adc->adc0->setResolution(12); // set bits of resolution
#ifdef ADC_DUAL_ADCS
adc->adc1->setAveraging(8); // set number of averages
adc->adc1->setResolution(12); // set bits of resolution
#endif

// enable DMA and interrupts
//Serial.println("before enableDMA"); Serial.flush();


// setup a DMA Channel.
// Now lets see the different things that RingbufferDMA setup for us before
abdma1.init(adc, ADC_0/*, DMAMUX_SOURCE_ADC_ETC*/);
abdma1.userData(initial_average_value); // save away initial starting average
#ifdef ADC_DUAL_ADCS
abdma2.init(adc, ADC_1/*, DMAMUX_SOURCE_ADC_ETC*/);
abdma2.userData(initial_average_value); // save away initial starting average
#endif
//Serial.println("After enableDMA"); Serial.flush();

// Start the dma operation..
adc->adc0->startSingleRead(readPin_adc_0); // call this to setup everything before the Timer starts, differential is also possible
adc->adc0->startTimer(3000); //frequency in Hz

// Start the dma operation..
#ifdef ADC_DUAL_ADCS
adc->adc1->startSingleRead(readPin_adc_1); // call this to setup everything before the Timer starts, differential is also possible
adc->adc1->startTimer(3000); //frequency in Hz
#endif

print_debug_information();

Serial.println("End Setup");
elapsed_sinc_last_display = 0;
}

void loop() {

// Maybe only when both have triggered?
#ifdef ADC_DUAL_ADCS
if ( abdma1.interrupted() && (abdma2.interrupted())) {
if ( abdma1.interrupted()) {
ProcessAnalogData(&abdma1, 0);
}
if ( abdma2.interrupted()) {
ProcessAnalogData(&abdma2, 1);
}
Serial.println();
elapsed_sinc_last_display = 0;
}
#else
if ( abdma1.interrupted()) {
ProcessAnalogData(&abdma1, 0);
Serial.println();
elapsed_sinc_last_display = 0;
}
#endif
if (elapsed_sinc_last_display > 5000) {
// Nothing in 5 seconds, show a heart beat.
digitalWriteFast(13, HIGH);
delay(250);
digitalWriteFast(13, LOW);
delay(250);
digitalWriteFast(13, HIGH);
delay(250);
digitalWriteFast(13, LOW);
elapsed_sinc_last_display = 0;
}
}

void ProcessAnalogData(AnalogBufferDMA *pabdma, int8_t adc_num) {
uint32_t sum_values = 0;
uint16_t min_val = 0xffff;
uint16_t max_val = 0;

uint32_t average_value = pabdma->userData();

volatile uint16_t *pbuffer = pabdma->bufferLastISRFilled();
volatile uint16_t *end_pbuffer = pbuffer + pabdma->bufferCountLastISRFilled();

float sum_delta_sq = 0.0;
if ((uint32_t)pbuffer >= 0x20200000u) arm_dcache_delete((void*)pbuffer, sizeof(dma_adc_buff1));
while (pbuffer < end_pbuffer) {
if (*pbuffer < min_val) min_val = *pbuffer;
if (*pbuffer > max_val) max_val = *pbuffer;
sum_values += *pbuffer;
int delta_from_center = (int) * pbuffer - average_value;
sum_delta_sq += delta_from_center * delta_from_center;

pbuffer++;
}

int rms = sqrt(sum_delta_sq / buffer_size);
average_value = sum_values / buffer_size;
Serial.printf(" %d - %u(%u): %u <= %u <= %u %d ", adc_num, pabdma->interruptCount(), pabdma->interruptDeltaTime(), min_val,
average_value, max_val, rms);
pabdma->clearInterrupt();

pabdma->userData(average_value);
}

void print_debug_information()
{
#ifdef PRINT_DEBUG_INFO
// Lets again try dumping lots of data.
Serial.println("\n*** DMA structures for ADC_0 ***");
dumpDMA_structures(&(abdma1._dmachannel_adc));
dumpDMA_structures(&(abdma1._dmasettings_adc[0]));
dumpDMA_structures(&(abdma1._dmasettings_adc[1]));
Serial.println("\n*** DMA structures for ADC_1 ***");
dumpDMA_structures(&(abdma2._dmachannel_adc));
dumpDMA_structures(&(abdma2._dmasettings_adc[0]));
dumpDMA_structures(&(abdma2._dmasettings_adc[1]));

#if defined(__IMXRT1062__)

Serial.println("\n*** ADC and ADC_ETC ***");
Serial.printf("ADC1: HC0:%x HS:%x CFG:%x GC:%x GS:%x\n", IMXRT_ADC1.HC0, IMXRT_ADC1.HS, IMXRT_ADC1.CFG, IMXRT_ADC1.GC, IMXRT_ADC1.GS);
Serial.printf("ADC2: HC0:%x HS:%x CFG:%x GC:%x GS:%x\n", IMXRT_ADC2.HC0, IMXRT_ADC2.HS, IMXRT_ADC2.CFG, IMXRT_ADC2.GC, IMXRT_ADC2.GS);
Serial.printf("ADC_ETC: CTRL:%x DONE0_1:%x DONE2_ERR:%x DMA: %x\n", IMXRT_ADC_ETC.CTRL,
IMXRT_ADC_ETC.DONE0_1_IRQ, IMXRT_ADC_ETC.DONE2_ERR_IRQ, IMXRT_ADC_ETC.DMA_CTRL);
for (uint8_t trig = 0; trig < 8; trig++) {
Serial.printf(" TRIG[%d] CTRL: %x CHAIN_1_0:%x\n",
trig, IMXRT_ADC_ETC.TRIG[trig].CTRL, IMXRT_ADC_ETC.TRIG[trig].CHAIN_1_0);
}
#endif
#endif
}

#ifdef PRINT_DEBUG_INFO
void dumpDMA_structures(DMABaseClass *dmabc)
{
Serial.printf("%x %x:", (uint32_t)dmabc, (uint32_t)dmabc->TCD);

Serial.printf("SA:%x SO:%d AT:%x NB:%x SL:%d DA:%x DO: %d CI:%x DL:%x CS:%x BI:%x\n", (uint32_t)dmabc->TCD->SADDR,
dmabc->TCD->SOFF, dmabc->TCD->ATTR, dmabc->TCD->NBYTES, dmabc->TCD->SLAST, (uint32_t)dmabc->TCD->DADDR,
dmabc->TCD->DOFF, dmabc->TCD->CITER, dmabc->TCD->DLASTSGA, dmabc->TCD->CSR, dmabc->TCD->BITER);
}
#endif

//#else // make sure the example can run for any boards (automated testing)
//void setup() {}
//void loop() {}
//#endif // ADC_USE_TIMER and DMA
 
Status
Not open for further replies.
Back
Top