SparkFun Forums 

Where electronics enthusiasts find answers.

Topics pertaining to the Arduino Core & software used with the Artemis module and Artemis development boards.
User avatar
By dlp
#209379
I've used the following sketch (modified from a handy site about Teensy FFT) to time the acquisition of 512 ADC values, but it tops out at about 65kS/s. How are we to acquire at or near the very impressive Artemis MS/s rates?

/*dlp - Using an Artemis Redboard, found for the original 512 samples at 50khz, the measured freq is 38.1khz
if you specify 14 or 16-bit resolution it stays the same
200khz = 65.1
100khz = 65.1
90khz = 65.1
80khz = 52.5
70khz = 52.5
60khz = 43.8
50khz = 38.1 (23.8% low)
40khz = 33.5 (16.2% low)
30khz = 26.6 (11.3% low)
20khz = 17.9 (10.5% low)
*/

#define SAMPLES 512 //Must be a power of 2
#define SAMPLING_FREQUENCY 50000 //Hz
#define REFRESH_RATE 10 //Hz

unsigned long sampling_period_us;
unsigned long useconds_sampling;

unsigned long refresh_period_us;
unsigned long useconds_refresh;
float SamplesAcqFreq;

double vReal[SAMPLES];
double vImag[SAMPLES];

uint8_t analogpin = A0;

void setup() {
Serial.begin(115200);
//analogReadResolution(14); //Set resolution to 14 bit
//analogReadResolution(16); //Set resolution to 16 bit - will pad ADC output with two zeros
sampling_period_us = round(1000000*(1.0/SAMPLING_FREQUENCY));
refresh_period_us = round(1000000*(1.0/REFRESH_RATE));
pinMode(analogpin, INPUT);
}

void loop() {
useconds_refresh = micros();
/*SAMPLING*/
for(int i=0; i<SAMPLES; i++)
{
useconds_sampling = micros();

vReal = analogRead(analogpin);
vImag = 0;

while(micros() < (useconds_sampling + sampling_period_us)){
//wait...
}
}
SamplesAcqFreq = SAMPLES/((float(micros())-useconds_refresh)/1000000);
Serial.println(SamplesAcqFreq); //print sample freq
while(micros() < (useconds_refresh + refresh_period_us)){ //wait for refresh time
//wait...
}
}

https://www.norwegiancreations.com/2019 ... -analysis/
By Valen
#209629
You are doing calculations on sample time in your code. But those are just make-believe results or after-the-fact rates. You probably need to change some register settings to change the ADC clock prescaler to affect the real sample rate. I am unaware of where to find the datasheet of the processor because I am too unfamiliar with the board/chip architecture. But that would be where the solution lies.
User avatar
By dlp
#210010
I modified a C-code example found in the Ambiq-Micro SDK (adc_lpmode0_dma.c ) and it now works on the Artemis Redboard & Arduino IDE.
Single-channel, single-ended, 14bit acquisition, choosing frequencies that will include one complete wave in the 512-point buffer I measure the following S/s:
500Hz with AVG_8 = 140kS/s.
3kHz with AVG_1 = 1.11MS/s.

Here's the sketch:

Edited by moderator to add code tags. Please use the code tag button above when posting code.
Code: Select all
//*****************************************************************************
//
//! @file adc_lpmode0_dma.c
//!
//! @brief This example takes samples with the ADC at high-speed using DMA.
//!
//! Purpose: This example shows the CTIMER-A3 triggering repeated samples of an external
//! input at 1.2Msps in LPMODE0.  The example uses the CTIMER-A3 to trigger
//! ADC sampling.  Each data point is 8 sample average and is transferred
//! from the ADC FIFO into an SRAM buffer using DMA.

#include "am_bsp.h"

// Define a circular buffer to hold the ADC samples
//*****************************************************************************
#define ADC_EXAMPLE_DEBUG   1
#define ResolutionBits 14

// ADC Sample buffer.
#define ADC_SAMPLE_BUF_SIZE 512
uint32_t g_ui32ADCSampleBuffer[ADC_SAMPLE_BUF_SIZE];

am_hal_adc_sample_t SampleBuffer[ADC_SAMPLE_BUF_SIZE];

unsigned long useconds_refresh;

// ADC Device Handle.
//static void *g_ADCHandle;


// ADC DMA complete flag.
volatile bool                   g_bADCDMAComplete;

// ADC DMA error flag.
volatile bool                   g_bADCDMAError;

// Define the ADC SE0 pin to be used. (A4)
const am_hal_gpio_pincfg_t g_AM_PIN_16_ADCSE0 =
{
    .uFuncSel       = AM_HAL_PIN_16_ADCSE0,
};


// Interrupt handler for the ADC.
//*****************************************************************************
extern "C" void am_adc_isr()  //must use 'extern "C" ' for the Artemis
{
    uint32_t ui32IntMask;

    // Read the interrupt status.
    if (AM_HAL_STATUS_SUCCESS != am_hal_adc_interrupt_status(g_ADCHandle, &ui32IntMask, false))
    {
        //am_util_stdio_printf("Error reading ADC interrupt status\n");
        Serial.println("Error reading ADC interrupt status");
    }

    // Clear the ADC interrupt.
    if (AM_HAL_STATUS_SUCCESS != am_hal_adc_interrupt_clear(g_ADCHandle, ui32IntMask))
    {
        //am_util_stdio_printf("Error clearing ADC interrupt status\n");
        Serial.println("Error clearing ADC interrupt status");
    }

    // If we got a DMA complete, set the flag.
    if (ui32IntMask & AM_HAL_ADC_INT_DCMP)
    {
        g_bADCDMAComplete = true;
    }

    // If we got a DMA error, set the flag.
    if (ui32IntMask & AM_HAL_ADC_INT_DERR)
    {
        g_bADCDMAError = true;
    }
}

// Set up the core for sleeping, and then go to sleep.
//*****************************************************************************
void sleep()
{
    // Disable things that can't run in sleep mode.
//#if (0 == ADC_EXAMPLE_DEBUG)
//    am_bsp_debug_printf_disable();
//#endif

    // Go to Deep Sleep.
    am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
    
    // Re-enable peripherals for run mode.
//#if (0 == ADC_EXAMPLE_DEBUG)
//    am_bsp_debug_printf_enable();
//#endif

}

// Configure the ADC.
//*****************************************************************************
void adc_config_dma()
{
    am_hal_adc_dma_config_t       ADCDMAConfig;

    // Configure the ADC to use DMA for the sample transfer.
    ADCDMAConfig.bDynamicPriority = true;
    ADCDMAConfig.ePriority = AM_HAL_ADC_PRIOR_SERVICE_IMMED;
    ADCDMAConfig.bDMAEnable = true;
    ADCDMAConfig.ui32SampleCount = ADC_SAMPLE_BUF_SIZE;
    ADCDMAConfig.ui32TargetAddress = (uint32_t)g_ui32ADCSampleBuffer;
    if (AM_HAL_STATUS_SUCCESS != am_hal_adc_configure_dma(g_ADCHandle, &ADCDMAConfig))
    {
        //am_util_stdio_printf("Error - configuring ADC DMA failed.\n");
        Serial.println("Error - configuring ADC DMA failed.");
    }
    // Reset the ADC DMA flags.
    g_bADCDMAComplete = false;
    g_bADCDMAError = false;
    
}


// Configure the ADC.
//*****************************************************************************
void adc_config()
{
    am_hal_adc_config_t           ADCConfig;
    am_hal_adc_slot_config_t      ADCSlotConfig;

    // Initialize the ADC and get the handle.
    if ( AM_HAL_STATUS_SUCCESS != am_hal_adc_initialize(0, &g_ADCHandle) )
    {
        //am_util_stdio_printf("Error - reservation of the ADC instance failed.\n");
        Serial.println("Error - reservation of the ADC instance failed.");
    }

    // Power on the ADC.
    if (AM_HAL_STATUS_SUCCESS != am_hal_adc_power_control(g_ADCHandle,
                                                          AM_HAL_SYSCTRL_WAKE,
                                                          false) )
    {
        //am_util_stdio_printf("Error - ADC power on failed.\n");
        Serial.println("Error - ADC power on failed.");
    }

    // Set up the ADC configuration parameters. These settings are reasonable
    // for accurate measurements at a low sample rate.
    ADCConfig.eClock             = AM_HAL_ADC_CLKSEL_HFRC;
    ADCConfig.ePolarity          = AM_HAL_ADC_TRIGPOL_RISING;
    ADCConfig.eTrigger           = AM_HAL_ADC_TRIGSEL_SOFTWARE;
    ADCConfig.eReference         = AM_HAL_ADC_REFSEL_INT_2P0;
    /*
    AM_HAL_ADC_REFSEL_INT_2P0,
    AM_HAL_ADC_REFSEL_INT_1P5,
    AM_HAL_ADC_REFSEL_EXT_2P0,
    AM_HAL_ADC_REFSEL_EXT_1P5
    */
    ADCConfig.eClockMode         = AM_HAL_ADC_CLKMODE_LOW_LATENCY;
    ADCConfig.ePowerMode         = AM_HAL_ADC_LPMODE0; 
    ADCConfig.eRepeat            = AM_HAL_ADC_REPEATING_SCAN; //AM_HAL_ADC_SINGLE_SCAN
    if (AM_HAL_STATUS_SUCCESS != am_hal_adc_configure(g_ADCHandle, &ADCConfig))
    {
        //am_util_stdio_printf("Error - configuring ADC failed.\n");
        Serial.println("Error - configuring ADC failed.");
    }

    // Set up an ADC slot
    ADCSlotConfig.eMeasToAvg      = AM_HAL_ADC_SLOT_AVG_1;
    ADCSlotConfig.ePrecisionMode  = AM_HAL_ADC_SLOT_14BIT;
    ADCSlotConfig.eChannel        = AM_HAL_ADC_SLOT_CHSEL_SE0; 
    ADCSlotConfig.bWindowCompare  = false;
    ADCSlotConfig.bEnabled        = true;
    /*
    AM_HAL_ADC_SLOT_AVG_1,
    AM_HAL_ADC_SLOT_AVG_2,
    AM_HAL_ADC_SLOT_AVG_4,
    AM_HAL_ADC_SLOT_AVG_8,
    AM_HAL_ADC_SLOT_AVG_16,
    AM_HAL_ADC_SLOT_AVG_32,
    AM_HAL_ADC_SLOT_AVG_64,
    AM_HAL_ADC_SLOT_AVG_128
    
    AM_HAL_ADC_SLOT_14BIT,
    AM_HAL_ADC_SLOT_12BIT,
    AM_HAL_ADC_SLOT_10BIT,
    AM_HAL_ADC_SLOT_8BIT

        // Single-ended channels
    AM_HAL_ADC_SLOT_CHSEL_SE0, (pad 16, ArtemisRB A4)
    AM_HAL_ADC_SLOT_CHSEL_SE1, (pad 29, ArtemisRB A0)
    AM_HAL_ADC_SLOT_CHSEL_SE2, (pad 11, ArtemisRB A1)
    AM_HAL_ADC_SLOT_CHSEL_SE3, (pad 31, ArtemisRB A5)
    AM_HAL_ADC_SLOT_CHSEL_SE4, (pad 32, ArtemisRB A8)
    AM_HAL_ADC_SLOT_CHSEL_SE5, (pad 33, ArtemisRB A3)
    AM_HAL_ADC_SLOT_CHSEL_SE6, (pad 34, ArtemisRB A2)
    AM_HAL_ADC_SLOT_CHSEL_SE7, (pad 35, ArtemisRB n/a)
    AM_HAL_ADC_SLOT_CHSEL_SE8, (pad 13, ArtemisRB A10)
    AM_HAL_ADC_SLOT_CHSEL_SE9, (pad 12, ArtemisRB A9)
    // Differential channels. 
    AM_HAL_ADC_SLOT_CHSEL_DF0, pads 12 (-), pad 13(+)
    AM_HAL_ADC_SLOT_CHSEL_DF1, pads 15 (-), pad 14(+) (ArtemisRB n/a)
    // Miscellaneous other signals.
    AM_HAL_ADC_SLOT_CHSEL_TEMP,
    AM_HAL_ADC_SLOT_CHSEL_BATT,
    AM_HAL_ADC_SLOT_CHSEL_VSS


     */
    if (AM_HAL_STATUS_SUCCESS != am_hal_adc_configure_slot(g_ADCHandle, 0, &ADCSlotConfig))
    {
        //am_util_stdio_printf("Error - configuring ADC Slot 0 failed.\n");
        Serial.println("Error - configuring ADC Slot 0 failed.");
    }

    // Configure the ADC to use DMA for the sample transfer.
    adc_config_dma();
    // For this example, the samples will be coming in slowly. This means we
    // can afford to wake up for every conversion.
    //
    am_hal_adc_interrupt_enable(g_ADCHandle, AM_HAL_ADC_INT_DERR | AM_HAL_ADC_INT_DCMP );

    // Enable the ADC.
    //
    if (AM_HAL_STATUS_SUCCESS != am_hal_adc_enable(g_ADCHandle))
    {
        //am_util_stdio_printf("Error - enabling ADC failed.\n");
        Serial.println("Error - enabling ADC failed.");
    }
}


// Initialize the ADC repetitive sample timer A3.
//*****************************************************************************
void init_timerA3_for_ADC()
{    
    // Start a timer to trigger the ADC periodically (1 second).?? Must be a hold-over from another version
    am_hal_ctimer_config_single(3, AM_HAL_CTIMER_TIMERA,
                                AM_HAL_CTIMER_HFRC_12MHZ    |
                                AM_HAL_CTIMER_FN_REPEAT     |
                                AM_HAL_CTIMER_INT_ENABLE);

    am_hal_ctimer_int_enable(AM_HAL_CTIMER_INT_TIMERA3);

    am_hal_ctimer_period_set(3, AM_HAL_CTIMER_TIMERA, 10, 5); //10 tick period, 5 ticks wide

    // Enable the timer A3 to trigger the ADC directly
    am_hal_ctimer_adc_trigger_enable();

    // Start the timer.
    am_hal_ctimer_start(3, AM_HAL_CTIMER_TIMERA);
}


void setup() {
     Serial.begin(115200);
     while (!Serial) {}
     Serial.println("Hi-speed ADC test");
    // Set the clock frequency.
     if (AM_HAL_STATUS_SUCCESS != am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0))
    {
        //am_util_stdio_printf("Error - configuring the system clock failed.\n");
        Serial.println("Error - configuring the system clock failed.");
    }

    // Set the default cache configuration and enable it.
    if (AM_HAL_STATUS_SUCCESS != am_hal_cachectrl_config(&am_hal_cachectrl_defaults))
    {
        //am_util_stdio_printf("Error - configuring the system cache failed.\n");
        Serial.println("Error - configuring the system cache failed.");
    }
    if (AM_HAL_STATUS_SUCCESS != am_hal_cachectrl_enable())
    {
        //am_util_stdio_printf("Error - enabling the system cache failed.\n");
        Serial.println("Error - enabling the system cache failed.");
    }

    // Configure the board for low power operation.
    am_bsp_low_power_init();

    // Enable only the first 512KB bank of Flash (0).  Disable Flash(1)
    if (AM_HAL_STATUS_SUCCESS != am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEM_FLASH_MIN))
    {
        //am_util_stdio_printf("Error - configuring the flash memory failed.\n");
        Serial.println("Error - configuring the flash memory failed.");
    }

    // Enable the first 32K of TCM SRAM.
    if (AM_HAL_STATUS_SUCCESS != am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEM_SRAM_32K_DTCM))
    {
        //am_util_stdio_printf("Error - configuring the SRAM failed.\n");
        Serial.println("Error - configuring the SRAM failed.");
    }

    // Start the ITM interface.
    am_bsp_itm_printf_enable();

    // Start the CTIMER A3 for timer-based ADC measurements.
    init_timerA3_for_ADC();

    // Enable interrupts.
    NVIC_EnableIRQ(ADC_IRQn);
    am_hal_interrupt_master_enable();

    // Set a pin to act as our ADC input
    am_hal_gpio_pinconfig(16, g_AM_PIN_16_ADCSE0); //artemis pad 16 is A4

    // Configure the ADC
    adc_config();

    // Trigger the ADC sampling for the first time manually.
    if (AM_HAL_STATUS_SUCCESS != am_hal_adc_sw_trigger(g_ADCHandle))
    {
        //am_util_stdio_printf("Error - triggering the ADC failed.\n");
        Serial.println("Error - triggering the ADC failed.");
    }

    // Print the banner.
    am_util_stdio_terminal_clear();
    //am_util_stdio_printf("ADC Example with 1.2Msps and LPMODE=0\n");
    Serial.println("ADC Example with 1.2Msps and LPMODE=0");

    // Allow time for all printing to finish.
    am_util_delay_ms(10);

    // We are done printing. Disable debug printf messages on ITM.
//#if (0 == ADC_EXAMPLE_DEBUG)
//    am_bsp_debug_printf_disable();
//#endif

  
}

void loop() {
        // Go to Deep Sleep.
        useconds_refresh = micros();
        if (!g_bADCDMAComplete)
        {
            sleep();
        }

        // Check for DMA errors.
        if (g_bADCDMAError)
        {
            //am_util_stdio_printf("DMA Error occured\n");
            Serial.println("DMA Error occured");
            while(1);
        }

        // Check if the ADC DMA completion interrupt occurred.
        if (g_bADCDMAComplete)
        {  
            for (int i=0; i<ADC_SAMPLE_BUF_SIZE; i++){
                  //14 bit is 0-16383 on a range of 0-2V  
                uint32_t result = g_ui32ADCSampleBuffer[i];//*(2.0 /16383.0);
                //Shift result depending on resolution, averaging
                result = result >> (6);
               // Serial.println(result);
                Serial.println(result*(2.0 /16383.0),3);
              }
             while(1){} 
#if ADC_EXAMPLE_DEBUG
            {
                uint32_t        ui32SampleCount;
                am_util_stdio_printf("DMA Complete\n");
                ui32SampleCount = ADC_SAMPLE_BUF_SIZE;
                if (AM_HAL_STATUS_SUCCESS != am_hal_adc_samples_read(g_ADCHandle, false,
                                                                     g_ui32ADCSampleBuffer,
                                                                     &ui32SampleCount,
                                                                     SampleBuffer))
                {
                    //am_util_stdio_printf("Error - failed to process samples.\n");
                    Serial.println("Error - failed to process samples.");
                }
            }
#endif

            // Reset the DMA completion and error flags.
            g_bADCDMAComplete = false;

            // Re-configure the ADC DMA.
            adc_config_dma();

            // Clear the ADC interrupts.
            if (AM_HAL_STATUS_SUCCESS != am_hal_adc_interrupt_clear(g_ADCHandle, 0xFFFFFFFF))
            {
                //am_util_stdio_printf("Error - clearing the ADC interrupts failed.\n");
                Serial.println("Error - clearing the ADC interrupts failed.");
            }

            // Trigger the ADC sampling for the first time manually.
            if (AM_HAL_STATUS_SUCCESS != am_hal_adc_sw_trigger(g_ADCHandle))
            {
                //am_util_stdio_printf("Error - triggering the ADC failed.\n");
                Serial.println("Error - triggering the ADC failed.");
            }
        } // if ()

}
User avatar
By dlp
#210099
There was a typo in the last working sketch for this so I'll re-post it.
Now that I've got 1 channel working, I'm going for 2 channels, but it's eluding me so far. Any thoughts?

Edited by moderator to add code tags.
Code: Select all
//*****************************************************************************
//
//! @file adc_lpmode0_dma.c
//!
//! @brief This example takes samples with the ADC at high-speed using DMA.
//!
//! Purpose: This example shows the CTIMER-A3 triggering repeated samples of an external
//! input at 1.2Msps in LPMODE0.  The example uses the CTIMER-A3 to trigger
//! ADC sampling.  Each data point is 8 sample average and is transferred
//! from the ADC FIFO into an SRAM buffer using DMA.

#include "am_bsp.h"

// Define a circular buffer to hold the ADC samples
//*****************************************************************************
#define ADC_EXAMPLE_DEBUG   1
#define ResolutionBits 14

// ADC Sample buffer.
#define ADC_SAMPLE_BUF_SIZE 512
uint32_t g_ui32ADCSampleBuffer[ADC_SAMPLE_BUF_SIZE];

am_hal_adc_sample_t SampleBuffer[ADC_SAMPLE_BUF_SIZE];

unsigned long useconds_refresh;

// ADC Device Handle.
//static void *g_ADCHandle;


// ADC DMA complete flag.
volatile bool                   g_bADCDMAComplete;

// ADC DMA error flag.
volatile bool                   g_bADCDMAError;

// Define the ADC SE0 pin to be used. (A4)
const am_hal_gpio_pincfg_t g_AM_PIN_16_ADCSE0 =
{
    .uFuncSel       = AM_HAL_PIN_16_ADCSE0,
};


// Interrupt handler for the ADC.
//*****************************************************************************
extern "C" void am_adc_isr()  //must use 'extern "C" ' for the Artemis
{
    uint32_t ui32IntMask;

    // Read the interrupt status.
    if (AM_HAL_STATUS_SUCCESS != am_hal_adc_interrupt_status(g_ADCHandle, &ui32IntMask, false))
    {
        //am_util_stdio_printf("Error reading ADC interrupt status\n");
        Serial.println("Error reading ADC interrupt status");
    }

    // Clear the ADC interrupt.
    if (AM_HAL_STATUS_SUCCESS != am_hal_adc_interrupt_clear(g_ADCHandle, ui32IntMask))
    {
        //am_util_stdio_printf("Error clearing ADC interrupt status\n");
        Serial.println("Error clearing ADC interrupt status");
    }

    // If we got a DMA complete, set the flag.
    if (ui32IntMask & AM_HAL_ADC_INT_DCMP)
    {
        g_bADCDMAComplete = true;
    }

    // If we got a DMA error, set the flag.
    if (ui32IntMask & AM_HAL_ADC_INT_DERR)
    {
        g_bADCDMAError = true;
    }
}

// Set up the core for sleeping, and then go to sleep.
//*****************************************************************************
void sleep()
{
    // Disable things that can't run in sleep mode.
//#if (0 == ADC_EXAMPLE_DEBUG)
//    am_bsp_debug_printf_disable();
//#endif

    // Go to Deep Sleep.
    am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
    
    // Re-enable peripherals for run mode.
//#if (0 == ADC_EXAMPLE_DEBUG)
//    am_bsp_debug_printf_enable();
//#endif

}

// Configure the ADC.
//*****************************************************************************
void adc_config_dma()
{
    am_hal_adc_dma_config_t       ADCDMAConfig;

    // Configure the ADC to use DMA for the sample transfer.
    ADCDMAConfig.bDynamicPriority = true;
    ADCDMAConfig.ePriority = AM_HAL_ADC_PRIOR_SERVICE_IMMED;
    ADCDMAConfig.bDMAEnable = true;
    ADCDMAConfig.ui32SampleCount = ADC_SAMPLE_BUF_SIZE;
    ADCDMAConfig.ui32TargetAddress = (uint32_t)g_ui32ADCSampleBuffer;
    if (AM_HAL_STATUS_SUCCESS != am_hal_adc_configure_dma(g_ADCHandle, &ADCDMAConfig))
    {
        //am_util_stdio_printf("Error - configuring ADC DMA failed.\n");
        Serial.println("Error - configuring ADC DMA failed.");
    }
    // Reset the ADC DMA flags.
    g_bADCDMAComplete = false;
    g_bADCDMAError = false;
    
}


// Configure the ADC.
//*****************************************************************************
void adc_config()
{
    am_hal_adc_config_t           ADCConfig;
    am_hal_adc_slot_config_t      ADCSlotConfig;

    // Initialize the ADC and get the handle.
    if ( AM_HAL_STATUS_SUCCESS != am_hal_adc_initialize(0, &g_ADCHandle) )
    {
        //am_util_stdio_printf("Error - reservation of the ADC instance failed.\n");
        Serial.println("Error - reservation of the ADC instance failed.");
    }

    // Power on the ADC.
    if (AM_HAL_STATUS_SUCCESS != am_hal_adc_power_control(g_ADCHandle,
                                                          AM_HAL_SYSCTRL_WAKE,
                                                          false) )
    {
        //am_util_stdio_printf("Error - ADC power on failed.\n");
        Serial.println("Error - ADC power on failed.");
    }

    // Set up the ADC configuration parameters. These settings are reasonable
    // for accurate measurements at a low sample rate.
    ADCConfig.eClock             = AM_HAL_ADC_CLKSEL_HFRC;
    ADCConfig.ePolarity          = AM_HAL_ADC_TRIGPOL_RISING;
    ADCConfig.eTrigger           = AM_HAL_ADC_TRIGSEL_SOFTWARE;
    ADCConfig.eReference         = AM_HAL_ADC_REFSEL_INT_2P0;
    /*
    AM_HAL_ADC_REFSEL_INT_2P0,
    AM_HAL_ADC_REFSEL_INT_1P5,
    AM_HAL_ADC_REFSEL_EXT_2P0,
    AM_HAL_ADC_REFSEL_EXT_1P5
    */
    ADCConfig.eClockMode         = AM_HAL_ADC_CLKMODE_LOW_LATENCY;
    ADCConfig.ePowerMode         = AM_HAL_ADC_LPMODE0; 
    ADCConfig.eRepeat            = AM_HAL_ADC_REPEATING_SCAN; //AM_HAL_ADC_SINGLE_SCAN
    if (AM_HAL_STATUS_SUCCESS != am_hal_adc_configure(g_ADCHandle, &ADCConfig))
    {
        //am_util_stdio_printf("Error - configuring ADC failed.\n");
        Serial.println("Error - configuring ADC failed.");
    }

    // Set up an ADC slot
    ADCSlotConfig.eMeasToAvg      = AM_HAL_ADC_SLOT_AVG_1;
    ADCSlotConfig.ePrecisionMode  = AM_HAL_ADC_SLOT_14BIT;
    ADCSlotConfig.eChannel        = AM_HAL_ADC_SLOT_CHSEL_SE0; 
    ADCSlotConfig.bWindowCompare  = false;
    ADCSlotConfig.bEnabled        = true;
    /*
    AM_HAL_ADC_SLOT_AVG_1,
    AM_HAL_ADC_SLOT_AVG_2,
    AM_HAL_ADC_SLOT_AVG_4,
    AM_HAL_ADC_SLOT_AVG_8,
    AM_HAL_ADC_SLOT_AVG_16,
    AM_HAL_ADC_SLOT_AVG_32,
    AM_HAL_ADC_SLOT_AVG_64,
    AM_HAL_ADC_SLOT_AVG_128
    
    AM_HAL_ADC_SLOT_14BIT,
    AM_HAL_ADC_SLOT_12BIT,
    AM_HAL_ADC_SLOT_10BIT,
    AM_HAL_ADC_SLOT_8BIT

        // Single-ended channels
    AM_HAL_ADC_SLOT_CHSEL_SE0, (pad 16, ArtemisRB A4)
    AM_HAL_ADC_SLOT_CHSEL_SE1, (pad 29, ArtemisRB A0)
    AM_HAL_ADC_SLOT_CHSEL_SE2, (pad 11, ArtemisRB A1)
    AM_HAL_ADC_SLOT_CHSEL_SE3, (pad 31, ArtemisRB A5)
    AM_HAL_ADC_SLOT_CHSEL_SE4, (pad 32, ArtemisRB A8)
    AM_HAL_ADC_SLOT_CHSEL_SE5, (pad 33, ArtemisRB A3)
    AM_HAL_ADC_SLOT_CHSEL_SE6, (pad 34, ArtemisRB A2)
    AM_HAL_ADC_SLOT_CHSEL_SE7, (pad 35, ArtemisRB n/a)
    AM_HAL_ADC_SLOT_CHSEL_SE8, (pad 13, ArtemisRB A10)
    AM_HAL_ADC_SLOT_CHSEL_SE9, (pad 12, ArtemisRB A9)
    // Differential channels. 
    AM_HAL_ADC_SLOT_CHSEL_DF0, pads 12 (-), pad 13(+)
    AM_HAL_ADC_SLOT_CHSEL_DF1, pads 15 (-), pad 14(+) (ArtemisRB n/a)
    // Miscellaneous other signals.
    AM_HAL_ADC_SLOT_CHSEL_TEMP,
    AM_HAL_ADC_SLOT_CHSEL_BATT,
    AM_HAL_ADC_SLOT_CHSEL_VSS


     */
    if (AM_HAL_STATUS_SUCCESS != am_hal_adc_configure_slot(g_ADCHandle, 0, &ADCSlotConfig))
    {
        //am_util_stdio_printf("Error - configuring ADC Slot 0 failed.\n");
        Serial.println("Error - configuring ADC Slot 0 failed.");
    }

    // Configure the ADC to use DMA for the sample transfer.
    adc_config_dma();
    // For this example, the samples will be coming in slowly. This means we
    // can afford to wake up for every conversion.
    //
    am_hal_adc_interrupt_enable(g_ADCHandle, AM_HAL_ADC_INT_DERR | AM_HAL_ADC_INT_DCMP );

    // Enable the ADC.
    //
    if (AM_HAL_STATUS_SUCCESS != am_hal_adc_enable(g_ADCHandle))
    {
        //am_util_stdio_printf("Error - enabling ADC failed.\n");
        Serial.println("Error - enabling ADC failed.");
    }
}


// Initialize the ADC repetitive sample timer A3.
//*****************************************************************************
void init_timerA3_for_ADC()
{    
    // Start a timer to trigger the ADC periodically (1 second).?? Must be a hold-over from another version
    am_hal_ctimer_config_single(3, AM_HAL_CTIMER_TIMERA,
                                AM_HAL_CTIMER_HFRC_12MHZ    |
                                AM_HAL_CTIMER_FN_REPEAT     |
                                AM_HAL_CTIMER_INT_ENABLE);

    am_hal_ctimer_int_enable(AM_HAL_CTIMER_INT_TIMERA3);

    am_hal_ctimer_period_set(3, AM_HAL_CTIMER_TIMERA, 10, 5); //10 tick period, 5 ticks wide

    // Enable the timer A3 to trigger the ADC directly
    am_hal_ctimer_adc_trigger_enable();

    // Start the timer.
    am_hal_ctimer_start(3, AM_HAL_CTIMER_TIMERA);
}


void setup() {
     Serial.begin(115200);
     while (!Serial) {}
     Serial.println("Hi-speed ADC test");
    // Set the clock frequency.
     if (AM_HAL_STATUS_SUCCESS != am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0))
    {
        //am_util_stdio_printf("Error - configuring the system clock failed.\n");
        Serial.println("Error - configuring the system clock failed.");
    }

    // Set the default cache configuration and enable it.
    if (AM_HAL_STATUS_SUCCESS != am_hal_cachectrl_config(&am_hal_cachectrl_defaults))
    {
        //am_util_stdio_printf("Error - configuring the system cache failed.\n");
        Serial.println("Error - configuring the system cache failed.");
    }
    if (AM_HAL_STATUS_SUCCESS != am_hal_cachectrl_enable())
    {
        //am_util_stdio_printf("Error - enabling the system cache failed.\n");
        Serial.println("Error - enabling the system cache failed.");
    }

    // Configure the board for low power operation.
    am_bsp_low_power_init();

    // Enable only the first 512KB bank of Flash (0).  Disable Flash(1)
    if (AM_HAL_STATUS_SUCCESS != am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEM_FLASH_MIN))
    {
        //am_util_stdio_printf("Error - configuring the flash memory failed.\n");
        Serial.println("Error - configuring the flash memory failed.");
    }

    // Enable the first 32K of TCM SRAM.
    if (AM_HAL_STATUS_SUCCESS != am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEM_SRAM_32K_DTCM))
    {
        //am_util_stdio_printf("Error - configuring the SRAM failed.\n");
        Serial.println("Error - configuring the SRAM failed.");
    }

    // Start the ITM interface.
    am_bsp_itm_printf_enable();

    // Start the CTIMER A3 for timer-based ADC measurements.
    init_timerA3_for_ADC();

    // Enable interrupts.
    NVIC_EnableIRQ(ADC_IRQn);
    am_hal_interrupt_master_enable();

    // Set a pin to act as our ADC input
    am_hal_gpio_pinconfig(16, g_AM_PIN_16_ADCSE0); //artemis pad 16 is A4

    // Configure the ADC
    adc_config();

    // Trigger the ADC sampling for the first time manually.
    if (AM_HAL_STATUS_SUCCESS != am_hal_adc_sw_trigger(g_ADCHandle))
    {
        //am_util_stdio_printf("Error - triggering the ADC failed.\n");
        Serial.println("Error - triggering the ADC failed.");
    }

    // Print the banner.
    am_util_stdio_terminal_clear();
    //am_util_stdio_printf("ADC Example with 1.2Msps and LPMODE=0\n");
    Serial.println("ADC Example with 1.2Msps and LPMODE=0");

    // Allow time for all printing to finish.
    am_util_delay_ms(10);

    // We are done printing. Disable debug printf messages on ITM.
//#if (0 == ADC_EXAMPLE_DEBUG)
//    am_bsp_debug_printf_disable();
//#endif

  
}

void loop() {
        // Go to Deep Sleep.
        useconds_refresh = micros();
        if (!g_bADCDMAComplete)
        {
            sleep();
        }

        // Check for DMA errors.
        if (g_bADCDMAError)
        {
            //am_util_stdio_printf("DMA Error occured\n");
            Serial.println("DMA Error occured");
            while(1);
        }

        // Check if the ADC DMA completion interrupt occurred.
        if (g_bADCDMAComplete)
        {  
            for (int i=0; i<ADC_SAMPLE_BUF_SIZE; i++){
                  //14 bit is 0-16383 on a range of 0-2V  
                uint32_t result = g_ui32ADCSampleBuffer[i];//*(2.0 /16383.0);
                //Shift result depending on resolution, averaging
                result = result >> (6);
               // Serial.println(result);
                Serial.println(result*(2.0 /16383.0),3);
              }
             while(1){}   //pause execution


            // Reset the DMA completion and error flags.
            g_bADCDMAComplete = false;

            // Re-configure the ADC DMA.
            adc_config_dma();

            // Clear the ADC interrupts.
            if (AM_HAL_STATUS_SUCCESS != am_hal_adc_interrupt_clear(g_ADCHandle, 0xFFFFFFFF))
            {
                //am_util_stdio_printf("Error - clearing the ADC interrupts failed.\n");
                Serial.println("Error - clearing the ADC interrupts failed.");
            }

            // Trigger the ADC sampling for the first time manually.
            if (AM_HAL_STATUS_SUCCESS != am_hal_adc_sw_trigger(g_ADCHandle))
            {
                //am_util_stdio_printf("Error - triggering the ADC failed.\n");
                Serial.println("Error - triggering the ADC failed.");
            }
        } // if ()

}
User avatar
By dlp
#210296
Here's a mod to the sketch that will do 2 Channels at high speed. A 2kHz signal will put 2 completes waves in the buffer and I measure a sample frequency of 552kS/s per channel. As expected half the frequency of a single channel.

MODERATOR NOTE: PLEASE USE CODE TAGS WHEN INCLUDING CODE.
Code: Select all
//*****************************************************************************
//
//! @file adc_lpmode0_dma.c
//!
//! @brief This example takes samples with the ADC at high-speed using DMA.
//!
//! Purpose: This example shows the CTIMER-A3 triggering repeated samples of an external
//! input at 1.2Msps in LPMODE0. The example uses the CTIMER-A3 to trigger
//! ADC sampling. Each data point is 8 sample average and is transferred
//! from the ADC FIFO into an SRAM buffer using DMA.

// uses bit-masking to parse out the data

#include "am_bsp.h"


// ADC Sample buffer.
 
#define ADC_SAMPLE_BUF_SIZE (1024) //2channels at 512 samples.  Ch1 and Ch2 alternate in the buffer

uint32_t g_ui32ADCSampleBuffer[ADC_SAMPLE_BUF_SIZE];

unsigned long useconds_refresh;

// ADC Device Handle. Already declared.
//static void *g_ADCHandle;

// ADC DMA complete flag.
volatile bool g_bADCDMAComplete;

// ADC DMA error flag.
volatile bool g_bADCDMAError;

// Define the ADC SE0 pin to be used. (A4)
const am_hal_gpio_pincfg_t g_AM_PIN_16_ADCSE0 =
{
  .uFuncSel = AM_HAL_PIN_16_ADCSE0,
};

// Define the ADC SE3 pin to be used. (A5)
const am_hal_gpio_pincfg_t g_AM_PIN_31_ADCSE3 =
{
  .uFuncSel = AM_HAL_PIN_31_ADCSE3,
};

// Interrupt handler for the ADC.
//*****************************************************************************
extern "C" void am_adc_isr() //must use 'extern "C" ' for the Artemis
{
  uint32_t ui32IntMask;

  // Read the interrupt status.
  if (AM_HAL_STATUS_SUCCESS != am_hal_adc_interrupt_status(g_ADCHandle, &ui32IntMask, false))
  {
    Serial.println("Error reading ADC interrupt status");
  }

  // Clear the ADC interrupt.
  if (AM_HAL_STATUS_SUCCESS != am_hal_adc_interrupt_clear(g_ADCHandle, ui32IntMask))
  {
    Serial.println("Error clearing ADC interrupt status");
  }

  // If we got a DMA complete, set the flag.
  if (ui32IntMask & AM_HAL_ADC_INT_DCMP)
  {
    g_bADCDMAComplete = true;
  }

  // If we got a DMA error, set the flag.
  if (ui32IntMask & AM_HAL_ADC_INT_DERR)
  {
    g_bADCDMAError = true;
  }
}

// Set up the core for sleeping, and then go to sleep.
//*****************************************************************************
void sleep()
{
  // Disable things that can't run in sleep mode.
  //#if (0 == ADC_EXAMPLE_DEBUG)
  // am_bsp_debug_printf_disable();
  //#endif

  // Go to Deep Sleep.
  am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);

  // Re-enable peripherals for run mode.
  //#if (0 == ADC_EXAMPLE_DEBUG)
  // am_bsp_debug_printf_enable();
  //#endif

}

// Configure the ADC.
//*****************************************************************************
void adc_config_dma()
{
  am_hal_adc_dma_config_t ADCDMAConfig;

  // Configure the ADC to use DMA for the sample transfer.
  ADCDMAConfig.bDynamicPriority = true;
  ADCDMAConfig.ePriority = AM_HAL_ADC_PRIOR_SERVICE_IMMED;
  ADCDMAConfig.bDMAEnable = true;
  ADCDMAConfig.ui32SampleCount = ADC_SAMPLE_BUF_SIZE;
  ADCDMAConfig.ui32TargetAddress = (uint32_t)g_ui32ADCSampleBuffer;
  if (AM_HAL_STATUS_SUCCESS != am_hal_adc_configure_dma(g_ADCHandle, &ADCDMAConfig))
  {
    Serial.println("Error - configuring ADC DMA failed.");
  }
  // Reset the ADC DMA flags.
  g_bADCDMAComplete = false;
  g_bADCDMAError = false;

}


// Configure the ADC.
//*****************************************************************************
void adc_config()
{
  am_hal_adc_config_t ADCConfig;
  am_hal_adc_slot_config_t ADCSlotConfig;

  // Initialize the ADC and get the handle.
  if ( AM_HAL_STATUS_SUCCESS != am_hal_adc_initialize(0, &g_ADCHandle) )
  {
    Serial.println("Error - reservation of the ADC instance failed.");
  }

  // Power on the ADC.
  if (AM_HAL_STATUS_SUCCESS != am_hal_adc_power_control(g_ADCHandle,
      AM_HAL_SYSCTRL_WAKE,
      false) )
  {
    //am_util_stdio_printf("Error - ADC power on failed.\n");
    Serial.println("Error - ADC power on failed.");
  }

  // Set up the ADC configuration parameters. These settings are reasonable
  // for accurate measurements at a low sample rate.
  ADCConfig.eClock = AM_HAL_ADC_CLKSEL_HFRC;
  ADCConfig.ePolarity = AM_HAL_ADC_TRIGPOL_RISING;
  ADCConfig.eTrigger = AM_HAL_ADC_TRIGSEL_SOFTWARE;
  ADCConfig.eReference = AM_HAL_ADC_REFSEL_INT_2P0;
  /*
    AM_HAL_ADC_REFSEL_INT_2P0,
    AM_HAL_ADC_REFSEL_INT_1P5,
    AM_HAL_ADC_REFSEL_EXT_2P0,
    AM_HAL_ADC_REFSEL_EXT_1P5
  */
  ADCConfig.eClockMode = AM_HAL_ADC_CLKMODE_LOW_LATENCY;
  ADCConfig.ePowerMode = AM_HAL_ADC_LPMODE0;
  ADCConfig.eRepeat = AM_HAL_ADC_REPEATING_SCAN; //AM_HAL_ADC_SINGLE_SCAN
  if (AM_HAL_STATUS_SUCCESS != am_hal_adc_configure(g_ADCHandle, &ADCConfig))
  {
    //am_util_stdio_printf("Error - configuring ADC failed.\n");
    Serial.println("Error - configuring ADC failed.");
  }

  // Set up an ADC slot 0
  ADCSlotConfig.eMeasToAvg = AM_HAL_ADC_SLOT_AVG_1;
  ADCSlotConfig.ePrecisionMode = AM_HAL_ADC_SLOT_14BIT;
  ADCSlotConfig.eChannel = AM_HAL_ADC_SLOT_CHSEL_SE0; //A4
  ADCSlotConfig.bWindowCompare = false;
  ADCSlotConfig.bEnabled = true;
  /*
    AM_HAL_ADC_SLOT_AVG_1,
    AM_HAL_ADC_SLOT_AVG_2,
    AM_HAL_ADC_SLOT_AVG_4,
    AM_HAL_ADC_SLOT_AVG_8,
    AM_HAL_ADC_SLOT_AVG_16,
    AM_HAL_ADC_SLOT_AVG_32,
    AM_HAL_ADC_SLOT_AVG_64,
    AM_HAL_ADC_SLOT_AVG_128

    AM_HAL_ADC_SLOT_14BIT,
    AM_HAL_ADC_SLOT_12BIT,
    AM_HAL_ADC_SLOT_10BIT,
    AM_HAL_ADC_SLOT_8BIT

    // Single-ended channels
    AM_HAL_ADC_SLOT_CHSEL_SE0, (pad 16, ArtemisRB A4)
    AM_HAL_ADC_SLOT_CHSEL_SE1, (pad 29, ArtemisRB A0)
    AM_HAL_ADC_SLOT_CHSEL_SE2, (pad 11, ArtemisRB A1)
    AM_HAL_ADC_SLOT_CHSEL_SE3, (pad 31, ArtemisRB A5)
    AM_HAL_ADC_SLOT_CHSEL_SE4, (pad 32, ArtemisRB A8)
    AM_HAL_ADC_SLOT_CHSEL_SE5, (pad 33, ArtemisRB A3)
    AM_HAL_ADC_SLOT_CHSEL_SE6, (pad 34, ArtemisRB A2)
    AM_HAL_ADC_SLOT_CHSEL_SE7, (pad 35, ArtemisRB n/a)
    AM_HAL_ADC_SLOT_CHSEL_SE8, (pad 13, ArtemisRB A10)
    AM_HAL_ADC_SLOT_CHSEL_SE9, (pad 12, ArtemisRB A9)
    // Differential channels.
    AM_HAL_ADC_SLOT_CHSEL_DF0, pads 12 (-), pad 13(+)
    AM_HAL_ADC_SLOT_CHSEL_DF1, pads 15 (-), pad 14(+) (ArtemisRB n/a)
    // Miscellaneous other signals.
    AM_HAL_ADC_SLOT_CHSEL_TEMP,
    AM_HAL_ADC_SLOT_CHSEL_BATT,
    AM_HAL_ADC_SLOT_CHSEL_VSS
  */

  if (AM_HAL_STATUS_SUCCESS != am_hal_adc_configure_slot(g_ADCHandle, 0, &ADCSlotConfig))
  {
    //am_util_stdio_printf("Error - configuring ADC Slot 0 failed.\n");
    Serial.println("Error - configuring ADC Slot 0 failed.");
  }

  // Set up an ADC slot 1
  ADCSlotConfig.eMeasToAvg = AM_HAL_ADC_SLOT_AVG_1;
  ADCSlotConfig.ePrecisionMode = AM_HAL_ADC_SLOT_14BIT;
  ADCSlotConfig.eChannel = AM_HAL_ADC_SLOT_CHSEL_SE3;  //A5
  ADCSlotConfig.bWindowCompare = false;
  ADCSlotConfig.bEnabled = true;
  if (AM_HAL_STATUS_SUCCESS != am_hal_adc_configure_slot(g_ADCHandle, 1, &ADCSlotConfig))
  {
    Serial.println("Error - configuring ADC Slot 0 failed.");
  }

  // Configure the ADC to use DMA for the sample transfer.
  adc_config_dma();
  
  //
  am_hal_adc_interrupt_enable(g_ADCHandle, AM_HAL_ADC_INT_DERR | AM_HAL_ADC_INT_DCMP );

  // Enable the ADC.
  if (AM_HAL_STATUS_SUCCESS != am_hal_adc_enable(g_ADCHandle))
  {
    Serial.println("Error - enabling ADC failed.");
  }
}


// Initialize the ADC repetitive sample timer A3.
//*****************************************************************************
void init_timerA3_for_ADC()
{
  // Start a timer to trigger the ADC periodically 
  am_hal_ctimer_config_single(3, AM_HAL_CTIMER_TIMERA,
                              AM_HAL_CTIMER_HFRC_12MHZ |
                              AM_HAL_CTIMER_FN_REPEAT |
                              AM_HAL_CTIMER_INT_ENABLE);

  am_hal_ctimer_int_enable(AM_HAL_CTIMER_INT_TIMERA3);

  am_hal_ctimer_period_set(3, AM_HAL_CTIMER_TIMERA, 10, 5); //10 tick period, 5 ticks wide

  // Enable the timer A3 to trigger the ADC directly
  am_hal_ctimer_adc_trigger_enable();

  // Start the timer.
  am_hal_ctimer_start(3, AM_HAL_CTIMER_TIMERA);
}


void setup() {
  Serial.begin(115200);
  while (!Serial) {}
  Serial.println("2 Channel Hi-speed ADC test");
  // Set the clock frequency.
  if (AM_HAL_STATUS_SUCCESS != am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0))
  {
    Serial.println("Error - configuring the system clock failed.");
  }

  // Set the default cache configuration and enable it.
  if (AM_HAL_STATUS_SUCCESS != am_hal_cachectrl_config(&am_hal_cachectrl_defaults))
  {
    Serial.println("Error - configuring the system cache failed.");
  }
  if (AM_HAL_STATUS_SUCCESS != am_hal_cachectrl_enable())
  {
    Serial.println("Error - enabling the system cache failed.");
  }

  // Configure the board for low power operation.
  am_bsp_low_power_init();

  // Enable only the first 512KB bank of Flash (0). Disable Flash(1)
  if (AM_HAL_STATUS_SUCCESS != am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEM_FLASH_MIN))
  {
    Serial.println("Error - configuring the flash memory failed.");
  }

  // Enable the first 32K of TCM SRAM.
  if (AM_HAL_STATUS_SUCCESS != am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEM_SRAM_32K_DTCM))
  {
    Serial.println("Error - configuring the SRAM failed.");
  }

  // Start the ITM interface.
  //am_bsp_itm_printf_enable();

  // Start the CTIMER A3 for timer-based ADC measurements.
  init_timerA3_for_ADC();

  // Enable interrupts.
  NVIC_EnableIRQ(ADC_IRQn);
  am_hal_interrupt_master_enable();

  // Set a pin to act as our ADC input
  am_hal_gpio_pinconfig(16, g_AM_PIN_16_ADCSE0); //artemis pad 16 is A4
   am_hal_gpio_pinconfig(31, g_AM_PIN_31_ADCSE3); //artemis pad 31 is A5

  // Configure the ADC
  adc_config();

  // Trigger the ADC sampling for the first time manually.
  if (AM_HAL_STATUS_SUCCESS != am_hal_adc_sw_trigger(g_ADCHandle))
  {
    Serial.println("Error - triggering the ADC failed.");
  }

  // Print the banner.
  am_util_stdio_terminal_clear();
  Serial.println("ADC Example with 1.2Msps and LPMODE=0");

  // Allow time for all printing to finish.
  am_util_delay_ms(10);

}

void loop() {
  // Go to Deep Sleep.
  useconds_refresh = micros();
  if (!g_bADCDMAComplete)
  {
    sleep();
  }

  // Check for DMA errors.
  if (g_bADCDMAError)
  {
    //am_util_stdio_printf("DMA Error occured\n");
    Serial.println("DMA Error occured");
    while (1);
  }

  // Check if the ADC DMA completion interrupt occurred.
  if (g_bADCDMAComplete)
  { 
    bool toggle = 0;
    for (int i = 0; i < ADC_SAMPLE_BUF_SIZE; i++) {
      //14 bit is 0-16383 on a range of 0-2V
      uint32_t result = g_ui32ADCSampleBuffer[i];
      uint32_t mask = 0xFFFC0;  // all ones for bits 6-19, other bits zeroed
      //Shift result depending on resolution, averaging
      result = result & mask; //get bits 6-19 data only
      result = result >> (6); //remove the fractional values

      // Serial.println(result);
      if (!toggle){
      Serial.print(result * (2.0 / 16383.0), 3);
      Serial.print(",");      
      }
      else{
        Serial.println(result * (2.0 / 16383.0), 3);
      }
      toggle = !toggle;
    }
    
    
    while (1) {}  // stop to view data


    // Reset the DMA completion and error flags.
    g_bADCDMAComplete = false;

    // Re-configure the ADC DMA.
    adc_config_dma();

    // Clear the ADC interrupts.
    if (AM_HAL_STATUS_SUCCESS != am_hal_adc_interrupt_clear(g_ADCHandle, 0xFFFFFFFF))
    {
      //am_util_stdio_printf("Error - clearing the ADC interrupts failed.\n");
      Serial.println("Error - clearing the ADC interrupts failed.");
    }

    // Trigger the ADC sampling for the first time manually.
    if (AM_HAL_STATUS_SUCCESS != am_hal_adc_sw_trigger(g_ADCHandle))
    {
      //am_util_stdio_printf("Error - triggering the ADC failed.\n");
      Serial.println("Error - triggering the ADC failed.");
    }
  } 

}
User avatar
By dlp
#231268
I noticed that this example no longer works. It gets to the line about enabling the first 32k of SRAM and hangs.
No errors are given.

So change this line:
Code: Select all
   

  // Enable the first 32K of TCM SRAM.
  if (AM_HAL_STATUS_SUCCESS != am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEM_SRAM_32K_DTCM))
  {
    Serial.println("Error - configuring the SRAM failed.");
  }


To this and it works again:
Code: Select all
    
    // Enable the first 128K of SRAM.

    if (AM_HAL_STATUS_SUCCESS != am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEM_SRAM_128K))
    {
        //am_util_stdio_printf("Error - configuring the SRAM failed.\n");
        Serial.println("Error - configuring the SRAM failed.");
    }
User avatar
By Mrest03
#239987
Hi dlp,

I have been making my way through your example code posted above on my Artemis Nano (with the most recent correction you noted in your second comment), however for some reason I am getting a Mbed OS Hard fault. I have traced it back to the function call am_bsp_low_power_init() in the code that initiates/sets the system into low power mode that seems to be causing the issue. Any ideas of suggestions as to why this might be causing the crash?

Thanks in advance!
 Topic permissions

You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum