This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP432P401R: Setting up DMA for multiple repeating ADC14 requests

Part Number: MSP432P401R


Hi,

I've been trying to get this code to work for a week or two now, and I'm having a heck of a time with it. I can see that three different pins are getting data written into the MEM0-MEM2 locations, using the debug tools, but can only get the data from MEM0 into an array I can actually use, prim_buffer0.

I have kindof merged two examples, and was trying to use a working DMA_INT1_IRQHandler to trigger software request of other channels, although this might not be the best way to do it. However, this doesn't work. I have some incrementing ints in the IRQ's, and only the first one ever increments.

#include "msp.h"
#include <driverlib.h>
#include <grlib.h>
#include "Crystalfontz128x128_ST7735.h"
#include <stdio.h>
#include <arm_math.h>
#include "arm_const_structs.h"


#define TEST_LENGTH_SAMPLES 1024
#define SAMPLE_LENGTH 1024
//#define NUMBER_OF_SAMPLES 512

/* ------------------------------------------------------------------
* Global variables for FFT Bin Example
* ------------------------------------------------------------------- */
uint32_t fftSize = SAMPLE_LENGTH;
uint32_t ifftFlag = 0;
uint32_t doBitReverse = 1;
volatile arm_status status;

/* Graphic library context */
Graphics_Context g_sContext;

#define SMCLK_FREQUENCY     48000000
#define SAMPLE_FREQUENCY    24000000


/* DMA Control Table */
#ifdef ewarm
#pragma data_alignment=256
#else
#pragma DATA_ALIGN(controlTable, 256)
#endif
uint8_t controlTable[256];


/* FFT data/processing buffers*/
float hann[SAMPLE_LENGTH];

int16_t prim_buffer0[SAMPLE_LENGTH];
int16_t prim_buffer1[SAMPLE_LENGTH];
int16_t prim_buffer2[SAMPLE_LENGTH];

int16_t alt_buffer0[SAMPLE_LENGTH];
int16_t alt_buffer1[SAMPLE_LENGTH];
int16_t alt_buffer2[SAMPLE_LENGTH];

volatile int switch_data = 0;

/* Timer_A PWM Configuration Parameter */
Timer_A_PWMConfig pwmConfig =
{
        TIMER_A_CLOCKSOURCE_SMCLK,
        TIMER_A_CLOCKSOURCE_DIVIDER_1,
        (SMCLK_FREQUENCY/SAMPLE_FREQUENCY),
        TIMER_A_CAPTURECOMPARE_REGISTER_1,
        TIMER_A_OUTPUTMODE_SET_RESET,
        (SMCLK_FREQUENCY/SAMPLE_FREQUENCY)/2
};

static uint16_t resultsBuffer[4];

volatile int adcIncrement = 0;
volatile int irq1Increment = 0;
volatile int irq2Increment = 0;
volatile int irq3Increment = 0;

void main(void)
{
    /* Halting WDT and disabling master interrupts */
    MAP_WDT_A_holdTimer();
    MAP_Interrupt_disableMaster();

    //memset(resultsBuffer, 0x00, 4);

    /* Set the core voltage level to VCORE1 */
    MAP_PCM_setCoreVoltageLevel(PCM_VCORE1);

    /* Set 2 flash wait states for Flash bank 0 and 1*/
    MAP_FlashCtl_setWaitState(FLASH_BANK0, 2);
    MAP_FlashCtl_setWaitState(FLASH_BANK1, 2);

    /* Initializes Clock System */
    MAP_CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_48);
    MAP_CS_initClockSignal(CS_MCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1 );
    MAP_CS_initClockSignal(CS_HSMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1 );
    MAP_CS_initClockSignal(CS_SMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1 );
    MAP_CS_initClockSignal(CS_ACLK, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1);

    /* Configuring Timer_A to have a period of approximately 500ms and
     * an initial duty cycle of 10% of that (3200 ticks)  */
    Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);

    /* Initializing ADC (MCLK/1/1) */
    ADC14_enableModule();
    ADC14_initModule(ADC_CLOCKSOURCE_MCLK, ADC_PREDIVIDER_1, ADC_DIVIDER_1, 0);

    ADC14_setSampleHoldTrigger(ADC_TRIGGER_SOURCE1, false);

//    /* Configuring GPIOs */

    MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN5,
                                                   GPIO_TERTIARY_MODULE_FUNCTION);
    MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN4,
                                                   GPIO_TERTIARY_MODULE_FUNCTION);
    MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4, GPIO_PIN3,
                                                   GPIO_TERTIARY_MODULE_FUNCTION);


    /* Configuring ADC Memory */
    MAP_ADC14_configureMultiSequenceMode(ADC_MEM0, ADC_MEM2, true);
    MAP_ADC14_configureConversionMemory(ADC_MEM0, ADC_VREFPOS_AVCC_VREFNEG_VSS,
                                        ADC_INPUT_A0, false);
    MAP_ADC14_configureConversionMemory(ADC_MEM1, ADC_VREFPOS_AVCC_VREFNEG_VSS,
                                        ADC_INPUT_A1, false);
    MAP_ADC14_configureConversionMemory(ADC_MEM2, ADC_VREFPOS_AVCC_VREFNEG_VSS,
                                        ADC_INPUT_A10, false);


    /* Set ADC result format to signed binary */
    ADC14_setResultFormat(ADC_SIGNED_BINARY);

    /* Configuring DMA module */
    DMA_enableModule();
    DMA_setControlBase(controlTable);


    DMA_disableChannelAttribute(DMA_CH7_ADC14,
                                 UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
                                 UDMA_ATTR_HIGH_PRIORITY |
                                 UDMA_ATTR_REQMASK);
    /* Setting Control Indexes. In this case we will set the source of the
     * DMA transfer to ADC14 Memory 0
     *  and the destination to the
     * destination data array. */
    MAP_DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH7_ADC14,
        UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH7_ADC14,
        UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[0],
        prim_buffer0, SAMPLE_LENGTH);

MAP_DMA_setChannelControl(UDMA_ALT_SELECT | DMA_CH7_ADC14, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1); MAP_DMA_setChannelTransfer(UDMA_ALT_SELECT | DMA_CH7_ADC14, UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[0], alt_buffer0, SAMPLE_LENGTH); /* Assigning/Enabling Interrupts */ MAP_DMA_assignInterrupt(DMA_INT1, 7); MAP_Interrupt_enableInterrupt(INT_DMA_INT1); MAP_DMA_assignChannel(DMA_CH7_ADC14); MAP_DMA_clearInterruptFlag(7); MAP_Interrupt_enableMaster(); // MAP_ADC14_enableInterrupt(ADC_INT2); // MAP_Interrupt_enableInterrupt(INT_ADC14); MAP_DMA_assignInterrupt(DMA_INT2, 1); MAP_Interrupt_enableInterrupt(INT_DMA_INT2); MAP_DMA_assignChannel(DMA_CH1_RESERVED0); MAP_DMA_clearInterruptFlag(1); MAP_DMA_assignInterrupt(DMA_INT3, 2); MAP_Interrupt_enableInterrupt(INT_DMA_INT3); MAP_DMA_assignChannel(DMA_CH2_RESERVED0); MAP_DMA_clearInterruptFlag(2); MAP_DMA_enableChannel(1); MAP_DMA_enableChannel(2); /* Now that the DMA is primed and setup, enabling the channels. The ADC14 * hardware should take over and transfer/receive all bytes */ MAP_DMA_enableChannel(7); MAP_ADC14_enableConversion(); /* Forcing a software transfer on DMA Channel 1 */ MAP_DMA_requestSoftwareTransfer(1); /* Forcing a software transfer on DMA Channel 2 */ MAP_DMA_requestSoftwareTransfer(2);
while(1) { MAP_PCM_gotoLPM0(); } } //void ADC14_IRQHandler(void) //{ // adcIncrement++; // // uint64_t status; // // status = MAP_ADC14_getEnabledInterruptStatus(); // MAP_ADC14_clearInterruptFlag(status); // // if(status & ADC_INT2) // { // MAP_ADC14_getMultiSequenceResult(resultsBuffer); // } // //} /* Completion interrupt for ADC14 MEM0 */ void DMA_INT1_IRQHandler(void) { irq1Increment++; /* Switch between primary and alternate bufferes with DMA's PingPong mode */ if (DMA_getChannelAttribute(7) & UDMA_ATTR_ALTSELECT) { DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH7_ADC14, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1); DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH7_ADC14, UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[0], prim_buffer0, SAMPLE_LENGTH); switch_data = 1; } else { DMA_setChannelControl(UDMA_ALT_SELECT | DMA_CH7_ADC14, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1); DMA_setChannelTransfer(UDMA_ALT_SELECT | DMA_CH7_ADC14, UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[0], alt_buffer0, SAMPLE_LENGTH); switch_data = 0; } MAP_DMA_requestSoftwareTransfer(1); MAP_DMA_requestSoftwareTransfer(2); } /* Completion interrupt for ADC14 MEM7 */ __attribute__((ramfunc)) void DMA_INT2_IRQHandler(void) { irq2Increment++; /* Switch between primary and alternate bufferes with DMA's PingPong mode */ if (DMA_getChannelAttribute(1) & UDMA_ATTR_ALTSELECT) { DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH1_RESERVED0, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1); DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH1_RESERVED0, UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[1], prim_buffer1, SAMPLE_LENGTH); } else { DMA_setChannelControl(UDMA_ALT_SELECT | DMA_CH1_RESERVED0, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1); DMA_setChannelTransfer(UDMA_ALT_SELECT | DMA_CH1_RESERVED0, UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[1], alt_buffer1, SAMPLE_LENGTH); } } /* Completion interrupt for ADC14 MEM8 */ __attribute__((ramfunc)) void DMA_INT3_IRQHandler(void) { irq3Increment++; /* Switch between primary and alternate bufferes with DMA's PingPong mode */ if (DMA_getChannelAttribute(2) & UDMA_ATTR_ALTSELECT) { DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH2_RESERVED0, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1); DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH2_RESERVED0, UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[2], prim_buffer2, SAMPLE_LENGTH); switch_data = 1; } else { DMA_setChannelControl(UDMA_ALT_SELECT | DMA_CH2_RESERVED0, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1); DMA_setChannelTransfer(UDMA_ALT_SELECT | DMA_CH2_RESERVED0, UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[2], alt_buffer2, SAMPLE_LENGTH); switch_data = 0; } //MAP_Interrupt_disableSleepOnIsrExit(); SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Pos; }

Could anyone give me some insight into what I need to do to actually set up the channels correctly, to get data into prim_buffer1 and prim_buffer2 from ADC14MEM1 and ADC14MEM2 respectively? I've been banging my head against this code for days now, and have rejiggered it in 30 different ways, and haven't made any progress yet.

Regards,

Julian

  • Hi Julian,
    I will take a look at this but I will need to go through line by line and it will take some time.

    (1) You include a number of things associated with the ARM CMSIS-DSPLIB, but I do not actually see you using the APIs. Do you intend to use the ARM DSPLIB?
    (2) The sample frequency, which is used with the smclk frequency to calculate the timer trigger of the adc, is set to 24000000 (24Msps). The maximum you will get in 14-bit mode is 1Msps. Please note that you are converting 3 channels so the fastest you will be able to do this is 1Msps/3.
    (3) The number of flash wait states can be set to '1' with the Revision C silicon. If you are using revision B silicon and need to use the 2 flash wait states then what you are doing will not work because the revision B silicon has an errata against the multi-channel end of conversion trigger of the DMA. Please verify that you are using revision C (red launch pad) and change the flash wait states to '1'.
    (4) The adc clock source is selected to be MCLK, which is 48Mhz. Please change this to a source that is less than or equal to 25Mhz.
    (5) The DMA is configured so that channel 7 is triggered by the ADC and this DMA channel will trigger an interrupt (DMA1) when 1024 transfers have been made by the primary and then again by the alternate. DMA2 and DMA3 are assigned channels, but those channels are not defined. I do not know what the DMA will do because no size has been defined.

    I would recommend starting with a more simple example that simply measures the three adc channels and then in the isr moves the data (without the DMA) from the ADCMEM location to the desired memory location.

    Chris

    dev.ti.com/.../

    www.ti.com/.../slau356f.pdf
  • Hi Chris,

    Thanks for taking a look at this!

    1) No I wasn't intending to use the DSPLIB; that was probably part of the initial example I used. I will pare it back a bit.

    2) OK, that makes sense; eventually, I'd like to sample 3 pins each of which has a variation of the same 100kHz waveform on it, looking for phase angle; thus I'd like it to sample pretty quick. Ideally I'd like to grab 3 pins simultaneously as quickly as possible, for say 1000 samples,  sit and crunch numbers for a bit, and then repeat. Incidentally, when I change these sample frequencies, my resolution - sampling a function generator attached on pin 5.5 - in prim_buffer0 does seem to go down significantly; it's clean to about a 10kHz waveform, and breaks down by about 50kHz.

    3) I am using the Red launch pad; so I change both FlashBank0 and 1 to 1 then?

    4) OK, can do

    5) Ah okay, I wasn't entirely clear on how that worked. I had set up DMA2 and DMA3 with nearly identical setups to the ADC, but it just seemed to break things.

    This is the code as I have it after making those adjustments:

    #include "msp.h"
    #include <driverlib.h>
    #include <stdio.h>
    
    #define SAMPLE_LENGTH 1024
    
    #define SMCLK_FREQUENCY     25000000
    #define SAMPLE_FREQUENCY    333333
    
    
    /* DMA Control Table */
    #ifdef ewarm
    #pragma data_alignment=256
    #else
    #pragma DATA_ALIGN(controlTable, 256)
    #endif
    uint8_t controlTable[256];
    
    int16_t prim_buffer0[SAMPLE_LENGTH];
    int16_t prim_buffer1[SAMPLE_LENGTH];
    int16_t prim_buffer2[SAMPLE_LENGTH];
    
    int16_t alt_buffer0[SAMPLE_LENGTH];
    int16_t alt_buffer1[SAMPLE_LENGTH];
    int16_t alt_buffer2[SAMPLE_LENGTH];
    
    volatile int switch_data = 0;
    
    
    /* Timer_A PWM Configuration Parameter */
    Timer_A_PWMConfig pwmConfig =
    {
            TIMER_A_CLOCKSOURCE_SMCLK,
            TIMER_A_CLOCKSOURCE_DIVIDER_1,
            (SMCLK_FREQUENCY/SAMPLE_FREQUENCY),
            TIMER_A_CAPTURECOMPARE_REGISTER_1,
            TIMER_A_OUTPUTMODE_SET_RESET,
            (SMCLK_FREQUENCY/SAMPLE_FREQUENCY)/2
    };
    
    volatile int adcIncrement = 0;
    volatile int irq1Increment = 0;
    volatile int irq2Increment = 0;
    volatile int irq3Increment = 0;
    
    void main(void)
    {
        /* Halting WDT and disabling master interrupts */
        MAP_WDT_A_holdTimer();
        MAP_Interrupt_disableMaster();
    
        //memset(resultsBuffer, 0x00, 4);
    
        /* Set the core voltage level to VCORE1 */
        MAP_PCM_setCoreVoltageLevel(PCM_VCORE1);
    
        /* Set 2 flash wait states for Flash bank 0 and 1*/
        MAP_FlashCtl_setWaitState(FLASH_BANK0, 1);
        MAP_FlashCtl_setWaitState(FLASH_BANK1, 1);
    
        /* Initializes Clock System */
        MAP_CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_48);
        MAP_CS_initClockSignal(CS_MCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1 );
        MAP_CS_initClockSignal(CS_HSMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1 );
        MAP_CS_initClockSignal(CS_SMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1 );
        MAP_CS_initClockSignal(CS_ACLK, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1);
    
        /* Configuring Timer_A to have a period of approximately 500ms and
         * an initial duty cycle of 10% of that (3200 ticks)  */
        Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);
    
        /* Initializing ADC (MCLK/1/1) */
        ADC14_enableModule();
        ADC14_initModule(ADC_CLOCKSOURCE_SMCLK, ADC_PREDIVIDER_1, ADC_DIVIDER_1, 0);
    
        ADC14_setSampleHoldTrigger(ADC_TRIGGER_SOURCE1, false);
    
    //    /* Configuring GPIOs (4.3 A10) */
    //    GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4, GPIO_PIN3,
    //    GPIO_TERTIARY_MODULE_FUNCTION);
    
        MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN5,
                                                       GPIO_TERTIARY_MODULE_FUNCTION);
        MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN4,
                                                       GPIO_TERTIARY_MODULE_FUNCTION);
        MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4, GPIO_PIN3,
                                                       GPIO_TERTIARY_MODULE_FUNCTION);
    
    
        /* Configuring ADC Memory */
    //    ADC14_configureSingleSampleMode(ADC_MEM0, true);
    //    ADC14_configureConversionMemory(ADC_MEM0, ADC_VREFPOS_AVCC_VREFNEG_VSS,
    //    ADC_INPUT_A10, false);
    
        MAP_ADC14_configureMultiSequenceMode(ADC_MEM0, ADC_MEM2, true);
        MAP_ADC14_configureConversionMemory(ADC_MEM0, ADC_VREFPOS_AVCC_VREFNEG_VSS,
                                            ADC_INPUT_A0, false);
        MAP_ADC14_configureConversionMemory(ADC_MEM1, ADC_VREFPOS_AVCC_VREFNEG_VSS,
                                            ADC_INPUT_A1, false);
        MAP_ADC14_configureConversionMemory(ADC_MEM2, ADC_VREFPOS_AVCC_VREFNEG_VSS,
                                            ADC_INPUT_A10, false);
    
    
        /* Set ADC result format to signed binary */
        ADC14_setResultFormat(ADC_SIGNED_BINARY);
    
        /* Configuring DMA module */
        DMA_enableModule();
        DMA_setControlBase(controlTable);
    
    
        DMA_disableChannelAttribute(DMA_CH7_ADC14,
                                     UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
                                     UDMA_ATTR_HIGH_PRIORITY |
                                     UDMA_ATTR_REQMASK);
        /* Setting Control Indexes. In this case we will set the source of the
         * DMA transfer to ADC14 Memory 0
         *  and the destination to the
         * destination data array. */
        MAP_DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH7_ADC14,
                                  UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
        MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH7_ADC14,
                                   UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[0],
                                   prim_buffer0, SAMPLE_LENGTH);
    
        MAP_DMA_setChannelControl(UDMA_ALT_SELECT | DMA_CH7_ADC14,
                                  UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
        MAP_DMA_setChannelTransfer(UDMA_ALT_SELECT | DMA_CH7_ADC14,
                                   UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[0],
                                   alt_buffer0, SAMPLE_LENGTH);
    
    /* UNCOMMENTING THIS SECTION MAKES irq1Increment STOP AT 1023 */
    //    DMA_disableChannelAttribute(DMA_CH1_RESERVED0,
    //                                 UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
    //                                 UDMA_ATTR_HIGH_PRIORITY |
    //                                 UDMA_ATTR_REQMASK);
    //
    //
    //    DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH1_RESERVED0,
    //                          UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    //    DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH1_RESERVED0,
    //                           UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[1],
    //                           prim_buffer1, SAMPLE_LENGTH);
    //
    //    DMA_setChannelControl(UDMA_ALT_SELECT | DMA_CH1_RESERVED0,
    //                          UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    //    DMA_setChannelTransfer(UDMA_ALT_SELECT | DMA_CH1_RESERVED0,
    //                           UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[1],
    //                           alt_buffer1, SAMPLE_LENGTH);
    //
    //    DMA_disableChannelAttribute(DMA_CH2_RESERVED0,
    //                                 UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
    //                                 UDMA_ATTR_HIGH_PRIORITY |
    //                                 UDMA_ATTR_REQMASK);
    //
    //    DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH2_RESERVED0,
    //                          UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    //    DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH2_RESERVED0,
    //                           UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[2],
    //                           prim_buffer2, SAMPLE_LENGTH);
    //
    //    DMA_setChannelControl(UDMA_ALT_SELECT | DMA_CH2_RESERVED0,
    //                          UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    //    DMA_setChannelTransfer(UDMA_ALT_SELECT | DMA_CH2_RESERVED0,
    //                           UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[2],
    //                           alt_buffer2, SAMPLE_LENGTH);
    
    
        /* Assigning/Enabling Interrupts */
        MAP_DMA_assignInterrupt(DMA_INT1, 7);
        MAP_Interrupt_enableInterrupt(INT_DMA_INT1);
        MAP_DMA_assignChannel(DMA_CH7_ADC14);
        MAP_DMA_clearInterruptFlag(7);
    
        MAP_DMA_assignInterrupt(DMA_INT2, 1);
        MAP_Interrupt_enableInterrupt(INT_DMA_INT2);
        MAP_DMA_assignChannel(DMA_CH1_RESERVED0);
        MAP_DMA_clearInterruptFlag(1);
    
        MAP_DMA_assignInterrupt(DMA_INT3, 2);
        MAP_Interrupt_enableInterrupt(INT_DMA_INT3);
        MAP_DMA_assignChannel(DMA_CH2_RESERVED0);
        MAP_DMA_clearInterruptFlag(2);
    
        MAP_Interrupt_enableMaster();
    
    //    MAP_ADC14_enableSampleTimer(ADC_AUTOMATIC_ITERATION);
    
        MAP_DMA_enableChannel(1);
        MAP_DMA_enableChannel(2);
    
    
        /* Now that the DMA is primed and setup, enabling the channels. The ADC14
         * hardware should take over and transfer/receive all bytes */
          MAP_DMA_enableChannel(7);
          MAP_ADC14_enableConversion();
    //    MAP_ADC14_toggleConversionTrigger();
    
    //    /* Forcing a software transfer on DMA Channel 1 */
        MAP_DMA_requestSoftwareTransfer(1);
    //    /* Forcing a software transfer on DMA Channel 2 */
        MAP_DMA_requestSoftwareTransfer(2);
    
        while(1)
        {
            MAP_PCM_gotoLPM0();
    
        }
    }
    
    //void ADC14_IRQHandler(void)
    //{
    //    adcIncrement++;
    //
    //    uint64_t status;
    //
    //    status = MAP_ADC14_getEnabledInterruptStatus();
    //    MAP_ADC14_clearInterruptFlag(status);
    //
    //    if(status & ADC_INT2)
    //    {
    //        MAP_ADC14_getMultiSequenceResult(resultsBuffer);
    //    }
    //
    //}
    
    //
    /* Completion interrupt for ADC14 MEM0 */
    void DMA_INT1_IRQHandler(void)
    {
        irq1Increment++;
        /* Switch between primary and alternate bufferes with DMA's PingPong mode */
        if (DMA_getChannelAttribute(7) & UDMA_ATTR_ALTSELECT)
        {
            DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH7_ADC14,
                UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
            DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH7_ADC14,
                UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[0],
                prim_buffer0, SAMPLE_LENGTH);
            switch_data = 1;
        }
        else
        {
            DMA_setChannelControl(UDMA_ALT_SELECT | DMA_CH7_ADC14,
                UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
            DMA_setChannelTransfer(UDMA_ALT_SELECT | DMA_CH7_ADC14,
                UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[0],
                alt_buffer0, SAMPLE_LENGTH);
            switch_data = 0;
        }
    
        MAP_DMA_requestSoftwareTransfer(1);
        MAP_DMA_requestSoftwareTransfer(2);
    }
    
    
    /* Completion interrupt for ADC14 MEM7 */
    __attribute__((ramfunc))
    void DMA_INT2_IRQHandler(void)
    {
        irq2Increment++;
        /* Switch between primary and alternate bufferes with DMA's PingPong mode */
        if (DMA_getChannelAttribute(1) & UDMA_ATTR_ALTSELECT)
        {
            DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH1_RESERVED0,
            UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
            DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH1_RESERVED0,
            UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[1],
            prim_buffer1, SAMPLE_LENGTH);
        }
        else
        {
            DMA_setChannelControl(UDMA_ALT_SELECT | DMA_CH1_RESERVED0,
            UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
            DMA_setChannelTransfer(UDMA_ALT_SELECT | DMA_CH1_RESERVED0,
            UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[1],
            alt_buffer1, SAMPLE_LENGTH);
        }
    }
    
    /* Completion interrupt for ADC14 MEM8 */
    __attribute__((ramfunc))
    void DMA_INT3_IRQHandler(void)
    {
        irq3Increment++;
        /* Switch between primary and alternate bufferes with DMA's PingPong mode */
        if (DMA_getChannelAttribute(2) & UDMA_ATTR_ALTSELECT)
        {
            DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH2_RESERVED0,
            UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
            DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH2_RESERVED0,
            UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[2],
            prim_buffer2, SAMPLE_LENGTH);
            switch_data = 1;
        }
        else
        {
            DMA_setChannelControl(UDMA_ALT_SELECT | DMA_CH2_RESERVED0,
            UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
            DMA_setChannelTransfer(UDMA_ALT_SELECT | DMA_CH2_RESERVED0,
            UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[2],
            alt_buffer2, SAMPLE_LENGTH);
            switch_data = 0;
        }
        //MAP_Interrupt_disableSleepOnIsrExit();
        SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Pos;
    }
    

    More or less it works the same; If I uncomment the setup of CH1 and CH2 I was attempting, it causes irq1increment to stop at 1023, but neither the IRQ2 or IRQ3 functions ever run anyway.

    I'll take a stab at a normal multi-pin repeat ADC example shortly, but suspect I will need to use DMA in the end, since I would like to sample as fast as possible, in order to resolve a 100kHz waveform.

    Thanks again for taking a look at this!

  • I've taken a stab at normal multi-pin repeat ADC, and have managed to get it working in the manner I desire, with the exception that I need it to be about 50% faster.

    /* DriverLib Includes */
    #include <ti/devices/msp432p4xx/driverlib/driverlib.h>
    
    /* Standard Includes */
    #include <stdint.h>
    #include <stdbool.h>
    #include <stddef.h>
    
    
    /* Statics */
    static volatile int index = 0;
    static volatile int values1[1000];
    static volatile int values2[1000];
    static volatile int values3[1000];
    
    
    int main(void)
    {
        /* Halting the Watchdog  */
        MAP_WDT_A_holdTimer();
    
        /* Setting Flash wait state */
        MAP_FlashCtl_setWaitState(FLASH_BANK0, 1);
        MAP_FlashCtl_setWaitState(FLASH_BANK1, 1);
        
        /* Setting DCO to 48MHz  */
        MAP_PCM_setPowerState(PCM_AM_LDO_VCORE1);
        MAP_CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_48);
    
        /* Enabling the FPU for floating point operation */
        MAP_FPU_enableModule();
        MAP_FPU_enableLazyStacking();
    
    
        //![Single Sample Mode Configure]
        /* Initializing ADC (MCLK/1/4) */
        MAP_ADC14_enableModule();
        MAP_ADC14_initModule(ADC_CLOCKSOURCE_MCLK, ADC_PREDIVIDER_1, ADC_DIVIDER_2, 0);
    
        MAP_ADC14_setResolution(ADC_8BIT);
    
        /* Configuring GPIOs (5.5 A0) */
        MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN5,
                                                       GPIO_TERTIARY_MODULE_FUNCTION);
        MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN4,
                                                       GPIO_TERTIARY_MODULE_FUNCTION);
        MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4, GPIO_PIN3,
                                                       GPIO_TERTIARY_MODULE_FUNCTION);
    
        /* Configuring ADC Memory */
        MAP_ADC14_configureMultiSequenceMode(ADC_MEM0, ADC_MEM2, true);
        MAP_ADC14_configureConversionMemory(ADC_MEM0, ADC_VREFPOS_AVCC_VREFNEG_VSS,
                                            ADC_INPUT_A0, false);
        MAP_ADC14_configureConversionMemory(ADC_MEM1, ADC_VREFPOS_AVCC_VREFNEG_VSS,
                                            ADC_INPUT_A1, false);
        MAP_ADC14_configureConversionMemory(ADC_MEM2, ADC_VREFPOS_AVCC_VREFNEG_VSS,
                                            ADC_INPUT_A10, false);
    
    
        /* Configuring Sample Timer */
        MAP_ADC14_enableSampleTimer(ADC_AUTOMATIC_ITERATION);
    
        /* Enabling/Toggling Conversion */
        MAP_ADC14_enableConversion();
        MAP_ADC14_toggleConversionTrigger();
        //![Single Sample Mode Configure]
    
        /* Enabling interrupts */
        MAP_ADC14_enableInterrupt(ADC_INT0);
        MAP_Interrupt_enableInterrupt(INT_ADC14);
        MAP_Interrupt_enableMaster();
    
        while (1)
        {
            MAP_PCM_gotoLPM0();
        }
        
    }
    
    /* ADC Interrupt Handler. This handler is called whenever there is a conversion
     * that is finished for ADC_MEM0.
     */
    void ADC14_IRQHandler(void)
    {
        uint64_t status = MAP_ADC14_getEnabledInterruptStatus();
        MAP_ADC14_clearInterruptFlag(status);
    
        if (ADC_INT0 & status)
        {
            //NB: getMultiSequenceResult is SLOWER
            //MAP_ADC14_getResultArray(ADC_MEM0, ADC_MEM2, resultsBuffer); //??? doesn't work?
    
            values1[index] = MAP_ADC14_getResult(ADC_MEM0);
            values2[index] = MAP_ADC14_getResult(ADC_MEM1);
            values3[index++] = MAP_ADC14_getResult(ADC_MEM2);
    
    if (index >= 1000) { index = 0; } } }

    I'm doing some printing to serial once the index = 1000, and it is working reasonably well up to a 70kHz waveform; another 50% would get me over the 100kHz I need; is there any ways, DMA or otherwise, to speed this up?

  • Julian,

       I see some challenges with what you are trying to do.  Specifically, since you are doing a sequence of channels I can see two options of moving the data.

    (1)  You can use the DMA in scatter-gather mode.  This is a complex implementation and you can see an example here, SLAA741: 

    http://www.ti.com/lit/an/slaa741a/slaa741a.pdf

    (2)  You can use the ADC IRQ as you have done.  The issue you run into is the amount of time it takes to service the interrupt.    I have attached an example that attempts to reduce the time by using the DMA.  In this way I do not actually move the data, but just trigger the DMA to move the data.  I measured about 4us to service the interrupt and trigger the DMA.  Assuming that the ADC takes about 3us to measure all three channels, I set the DMA trigger conservatively to 120khz.

    Let me know if you have any additional questions.

    Chris  

    /*
     * adc14_multiple_channel_no_repeat_timera_source_01.c
     *
     * Timer (300kHz) Triggered sequence of conversions (ADC14 6,7,8),
     * where each conversion in the sequence is performed immediately
     * after the previous.  After the last conversion in the sequence
     * the ADC14 waits for the timer trigger.
     *
     * The ISR moves information from ADCMEM6-ADCMEME8 to three
     * seperate buffers buffer0[], buffer1[], buffer2[]
     *
     */
    
    #include <ti/devices/msp432p4xx/driverlib/driverlib.h>
    
    /* Standard Includes */
    #include <stdint.h>
    #include <string.h>
    
    #define NUMBER_OF_SAMPLES   1024
    
    /* DMA Control Table */
    #if defined(__TI_COMPILER_VERSION__)
    #pragma DATA_ALIGN(MSP_EXP432P401RLP_DMAControlTable, 1024)
    #elif defined(__IAR_SYSTEMS_ICC__)
    #pragma data_alignment=1024
    #elif defined(__GNUC__)
    __attribute__ ((aligned (1024)))
    #elif defined(__CC_ARM)
    __align(1024)
    #endif
    static DMA_ControlTable MSP_EXP432P401RLP_DMAControlTable[16];
    
    uint16_t prim_buffer0[NUMBER_OF_SAMPLES];
    uint16_t prim_buffer1[NUMBER_OF_SAMPLES];
    uint16_t prim_buffer2[NUMBER_OF_SAMPLES];
    
    uint16_t alt_buffer0[NUMBER_OF_SAMPLES];
    uint16_t alt_buffer1[NUMBER_OF_SAMPLES];
    uint16_t alt_buffer2[NUMBER_OF_SAMPLES];
    
    
    volatile int switch_data = 0;
    
    /*
     * Timer_A Continuous Mode Configuration Parameter
     *
     * 3 Conversions
     * each takes approximately 23 ADC Clocks
     * 3*23/25Mhz = 2.76us (360ksps)
     *
     * 4 us to handle IRQ and request data transfer
     *
     * 6.76us -> 7us or 142khz
     *
     * 1/((199+1)/24M) = 120khz
     */
    const Timer_A_PWMConfig timerA_PWM =
    {
        .clockSource = TIMER_A_CLOCKSOURCE_SMCLK,
        .clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1,
        .timerPeriod = 199,
        .compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_1,
        .compareOutputMode TIMER_A_OUTPUTMODE_SET_RESET,
        .dutyCycle = 100
    };
    
    uint16_t measureIndex;
    
    int main(void)
    {
        uint16_t ii;
        uint16_t *tempPtr0,*tempPtr1,*tempPtr2;
    
        uint32_t average0,average1,average2;
    
        /* Halting WDT  */
        MAP_WDT_A_holdTimer();
        MAP_Interrupt_disableMaster();
        MAP_Interrupt_enableSleepOnIsrExit();
    
        /* Zero-filling buffer */
        memset(prim_buffer0,0x0000,NUMBER_OF_SAMPLES);
        memset(prim_buffer1,0x0000,NUMBER_OF_SAMPLES);
        memset(prim_buffer2,0x0000,NUMBER_OF_SAMPLES);
    
        memset(alt_buffer0,0x0000,NUMBER_OF_SAMPLES);
        memset(alt_buffer1,0x0000,NUMBER_OF_SAMPLES);
        memset(alt_buffer2,0x0000,NUMBER_OF_SAMPLES);
    
        measureIndex = 0;
    
        /*
         * Use default settings for 48Mhz DCO
         */
        MAP_PCM_setCoreVoltageLevel(PCM_VCORE1);
        MAP_FlashCtl_setWaitState(FLASH_BANK0, 1);
        MAP_FlashCtl_setWaitState(FLASH_BANK1, 1);
    
        /*
         * Setting up clocks
         * MCLK = MCLK = 24MHz
         * SMCLK = MCLK/2 = 24Mhz
         * ACLK = REFO = 32Khz
         */
        MAP_CS_setDCOFrequency(48000000);
        MAP_CS_initClockSignal(CS_ACLK, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1);
        MAP_CS_initClockSignal(CS_SMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_2);
        MAP_CS_initClockSignal(CS_MCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);
    
        /* Configuring DMA module */
        MAP_DMA_enableModule();
        MAP_DMA_setControlBase(MSP_EXP432P401RLP_DMAControlTable);
    
        /* Setting Control Indexes. In this case we will set the source of the
         * DMA transfer to ADC14 Memory 6
         *  and the destination to the
         * destination data array. */
        MAP_DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH0_RESERVED0,
            UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
        MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH0_RESERVED0,
            UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[6],
            prim_buffer0, NUMBER_OF_SAMPLES);
    
        MAP_DMA_setChannelControl(UDMA_ALT_SELECT | DMA_CH0_RESERVED0,
            UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
        MAP_DMA_setChannelTransfer(UDMA_ALT_SELECT | DMA_CH0_RESERVED0,
            UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[6],
            alt_buffer0, NUMBER_OF_SAMPLES);
    
        /* Setting Control Indexes. In this case we will set the source of the
         * DMA transfer to ADC14 Memory 7
         *  and the destination to the
         * destination data array. */
        MAP_DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH1_RESERVED0,
            UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
        MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH1_RESERVED0,
            UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[7],
            prim_buffer1, NUMBER_OF_SAMPLES);
    
        MAP_DMA_setChannelControl(UDMA_ALT_SELECT | DMA_CH1_RESERVED0,
            UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
        MAP_DMA_setChannelTransfer(UDMA_ALT_SELECT | DMA_CH1_RESERVED0,
            UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[7],
            alt_buffer1, NUMBER_OF_SAMPLES);
    
        /* Setting Control Indexes. In this case we will set the source of the
         * DMA transfer to ADC14 Memory 8
         *  and the destination to the
         * destination data array. */
        MAP_DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH2_RESERVED0,
            UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
        MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH2_RESERVED0,
            UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[8],
            prim_buffer2, NUMBER_OF_SAMPLES);
    
        MAP_DMA_setChannelControl(UDMA_ALT_SELECT | DMA_CH2_RESERVED0,
            UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
        MAP_DMA_setChannelTransfer(UDMA_ALT_SELECT | DMA_CH2_RESERVED0,
            UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[8],
            alt_buffer2, NUMBER_OF_SAMPLES);
    
        /* Assigning/Enabling Interrupts */
        MAP_DMA_assignInterrupt(DMA_INT1, 0);
        MAP_DMA_assignInterrupt(DMA_INT2, 1);
        MAP_DMA_assignInterrupt(DMA_INT3, 2);
    
        MAP_Interrupt_enableInterrupt(INT_DMA_INT1);
        MAP_Interrupt_enableInterrupt(INT_DMA_INT2);
        MAP_Interrupt_enableInterrupt(INT_DMA_INT3);
        MAP_DMA_enableChannel(0);
        MAP_DMA_enableChannel(1);
        MAP_DMA_enableChannel(2);
    
        /* Setting reference voltage to 2.5 and enabling reference */
        MAP_REF_A_setReferenceVoltage(REF_A_VREF2_5V);
        MAP_REF_A_enableReferenceVoltage();
    
        /* Initializing ADC (MCLK/1/1) */
        MAP_ADC14_enableModule();
        MAP_ADC14_initModule(ADC_CLOCKSOURCE_ADCOSC, ADC_PREDIVIDER_1, ADC_DIVIDER_1,
                0);
    
        /* Configuring GPIOs for Analog In P4.5,4.6,4.7 */
        MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4,
                GPIO_PIN5 | GPIO_PIN6 | GPIO_PIN7, GPIO_TERTIARY_MODULE_FUNCTION);
    
        /* Debug: Configuring P1.0 as output */
        MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
    
        /* Debug: Configure P2.0, P2.1 */
        MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN0);
        MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN1);
    
        /* Configuring ADC Memory (ADC_MEM6 - ADC_MEM8 (A6 - A8)  without repeat)
         * with internal 2.5v reference */
        MAP_ADC14_configureMultiSequenceMode(ADC_MEM6, ADC_MEM8, false);
        MAP_ADC14_configureConversionMemory(ADC_MEM6,
                ADC_VREFPOS_INTBUF_VREFNEG_VSS,
                ADC_INPUT_A6, ADC_NONDIFFERENTIAL_INPUTS);
        MAP_ADC14_configureConversionMemory(ADC_MEM7,
                ADC_VREFPOS_INTBUF_VREFNEG_VSS,
                ADC_INPUT_A7, ADC_NONDIFFERENTIAL_INPUTS);
        MAP_ADC14_configureConversionMemory(ADC_MEM8,
                ADC_VREFPOS_INTBUF_VREFNEG_VSS,
                ADC_INPUT_A8, ADC_NONDIFFERENTIAL_INPUTS);
    
        /*
         * Configuring the sample trigger to be sourced from Timer_A0 CCR1
         * and setting it to automatic iteration after it is triggered
         */
        MAP_ADC14_setSampleHoldTrigger(ADC_TRIGGER_SOURCE1, false);
    
        /*
         * Setting up the sample timer to automatically step through the sequence
         * convert.
         */
        MAP_ADC14_enableSampleTimer(ADC_AUTOMATIC_ITERATION);
    
        /*
         * Enabling the interrupt when a conversion on channel 8
         * and enabling conversions
         */
        MAP_ADC14_enableInterrupt(ADC_INT8);
        MAP_ADC14_enableConversion();
        /*
         * Clear IFGs before enabling interrupt
         */
        MAP_ADC14_clearInterruptFlag(0xFFFFFFFFFFFFFFFF);
        MAP_Interrupt_enableInterrupt(INT_ADC14);
    
        MAP_Interrupt_enableMaster();
    
        /* Starting the Timer */
        MAP_Timer_A_generatePWM(TIMER_A0_BASE, &timerA_PWM);
    
        while(1)
        {
            MAP_Interrupt_enableSleepOnIsrExit();
            MAP_PCM_gotoLPM0();
            __no_operation();
            MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN1);
    
            /* Computer real FFT using the completed data buffer */
            if (switch_data == 1)
            {
                tempPtr0 = prim_buffer0;
                tempPtr1 = prim_buffer1;
                tempPtr2 = prim_buffer2;
            }
            else
            {
                tempPtr0 = alt_buffer0;
                tempPtr1 = alt_buffer1;
                tempPtr2 = alt_buffer2;
            }
            average0 = 0;
            average1 = 0;
            average2 = 0;
            for (ii=0; ii<NUMBER_OF_SAMPLES; ii++)
            {
                average0 += tempPtr0[ii];
                average1 += tempPtr1[ii];
                average2 += tempPtr2[ii];
            }
            average0 = average0 >> 10;
            average1 = average1 >> 10;
            average2 = average2 >> 10;
            MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN1);
        }
    }
    
    /*
     * This interrupt is fired whenever the sequence is completed
     *
     */
    __attribute__((ramfunc))
    void ADC14_IRQHandler(void)
    {
        uint64_t status;
        // Turn on LED
    
        //MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN0);
    //    BITBAND_PERI(P1->OUT, 0) = 1;
    
        status = MAP_ADC14_getEnabledInterruptStatus();
        MAP_ADC14_clearInterruptFlag(status);
        if(status & ADC_INT8)
        {
            //MAP_ADC14_disableConversion();
            BITBAND_PERI(ADC14->CTL0, ADC14_CTL0_ENC_OFS) = 0;
            /* Forcing a software transfer on DMA Channel 0 */
            //MAP_DMA_requestSoftwareTransfer(0);
            BITBAND_PERI(DMA_Channel->SW_CHTRIG, DMA_SW_CHTRIG_CH0_OFS) = 1;
            /* Forcing a software transfer on DMA Channel 1 */
            //MAP_DMA_requestSoftwareTransfer(1);
            BITBAND_PERI(DMA_Channel->SW_CHTRIG, DMA_SW_CHTRIG_CH1_OFS) = 1;
            /* Forcing a software transfer on DMA Channel 2 */
            //MAP_DMA_requestSoftwareTransfer(2);
            BITBAND_PERI(DMA_Channel->SW_CHTRIG, DMA_SW_CHTRIG_CH2_OFS) = 1;
    //        BITBAND_PERI(P1->OUT, 0) = 0;
            //MAP_ADC14_enableConversion();
            BITBAND_PERI(ADC14->CTL0, ADC14_CTL0_ENC_OFS) = 1;
        }
        //MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);
    }
    
    /* Completion interrupt for ADC14 MEM6 */
    __attribute__((ramfunc))
    void DMA_INT1_IRQHandler(void)
    {
        /* Switch between primary and alternate bufferes with DMA's PingPong mode */
        if (MAP_DMA_getChannelAttribute(0) & UDMA_ATTR_ALTSELECT)
        {
    //        MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH0_RESERVED0,
    //            UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[6],
    //            prim_buffer0, NUMBER_OF_SAMPLES);
            MSP_EXP432P401RLP_DMAControlTable[0].control =
                    (MSP_EXP432P401RLP_DMAControlTable[0].control & 0xff000000 ) |
                    (((NUMBER_OF_SAMPLES)-1)<<4) | UDMA_MODE_PINGPONG;
        }
        else
        {
    //        MAP_DMA_setChannelTransfer(UDMA_ALT_SELECT | DMA_CH0_RESERVED0,
    //            UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[6],
    //            alt_buffer0, NUMBER_OF_SAMPLES);
            MSP_EXP432P401RLP_DMAControlTable[8].control =
                    (MSP_EXP432P401RLP_DMAControlTable[8].control & 0xff000000 ) |
                    (((NUMBER_OF_SAMPLES)-1)<<4) | UDMA_MODE_PINGPONG;
        }
        // Toggle at n measures of adc6
    //    MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P2, GPIO_PIN0);
        P2->OUT ^= BIT0;
    }
    
    /* Completion interrupt for ADC14 MEM7 */
    __attribute__((ramfunc))
    void DMA_INT2_IRQHandler(void)
    {
        /* Switch between primary and alternate bufferes with DMA's PingPong mode */
        if (MAP_DMA_getChannelAttribute(1) & UDMA_ATTR_ALTSELECT)
        {
    //        DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH1_RESERVED0,
    //            UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[7],
    //            prim_buffer1, NUMBER_OF_SAMPLES);
            MSP_EXP432P401RLP_DMAControlTable[1].control =
                    (MSP_EXP432P401RLP_DMAControlTable[1].control & 0xff000000 ) |
                    (((NUMBER_OF_SAMPLES)-1)<<4) | UDMA_MODE_PINGPONG;
        }
        else
        {
    //        MAP_DMA_setChannelTransfer(UDMA_ALT_SELECT | DMA_CH1_RESERVED0,
    //            UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[7],
    //            alt_buffer1, NUMBER_OF_SAMPLES);
            MSP_EXP432P401RLP_DMAControlTable[9].control =
                    (MSP_EXP432P401RLP_DMAControlTable[9].control & 0xff000000 ) |
                    (((NUMBER_OF_SAMPLES)-1)<<4) | UDMA_MODE_PINGPONG;
        }
        // Toggle at n measures of adc7
        //MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P2, GPIO_PIN0);
        P2->OUT ^= BIT0;
    }
    
    /* Completion interrupt for ADC14 MEM8 */
    __attribute__((ramfunc))
    void DMA_INT3_IRQHandler(void)
    {
        /* Switch between primary and alternate bufferes with DMA's PingPong mode */
        if (MAP_DMA_getChannelAttribute(2) & UDMA_ATTR_ALTSELECT)
        {
    //        MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH2_RESERVED0,
    //            UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[8],
    //            prim_buffer2, NUMBER_OF_SAMPLES);
            MSP_EXP432P401RLP_DMAControlTable[2].control =
                    (MSP_EXP432P401RLP_DMAControlTable[2].control & 0xff000000 ) |
                    (((NUMBER_OF_SAMPLES)-1)<<4) | UDMA_MODE_PINGPONG;
            switch_data = 1;
        }
        else
        {
    //        MAP_DMA_setChannelTransfer(UDMA_ALT_SELECT | DMA_CH2_RESERVED0,
    //            UDMA_MODE_PINGPONG, (void*) &ADC14->MEM[8],
    //            alt_buffer2, NUMBER_OF_SAMPLES);
            MSP_EXP432P401RLP_DMAControlTable[10].control =
                    (MSP_EXP432P401RLP_DMAControlTable[10].control & 0xff000000 ) |
                    (((NUMBER_OF_SAMPLES)-1)<<4) | UDMA_MODE_PINGPONG;
            switch_data = 0;
        }
        // Toggle at n measures of adc8
        //MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P2, GPIO_PIN0);
        P2->OUT ^= BIT0;
        MAP_Interrupt_disableSleepOnIsrExit();
    }
    

**Attention** This is a public forum