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.

Continuous ADC sampling on all ADC pins

Part Number: LAUNCHXL-F28379D


The application requires that all of the ADC pins be sampled continuously.  From this post, the continuous function of the ADCs will act as a pseudo-simultaneous sample for ADCA, ADCB, and ADCC since the period between reading the result registers will far higher than that of the ADCs maximum sample period in the final application.  Ideally, the ADC would be configured for continuous operation, started, and then the result registers could be read periodically without the need for ADC interrupt checking or waiting for the end of a conversion.  Is this possible?

The following code, based on the adc_soc_continuous example in the bitfield examples, seems to only sample one time.  What's preventing continuous sampling?

//
// Included Files
//
#include "F28x_Project.h"

//
// Function Prototypes
//
void ConfigureADC(void);
void initADCContinuous(void);

//
// Defines
//
#define RESULTS_BUFFER_SIZE 16 //buffer for storing conversion results
                                //(size must be multiple of 16)

//
// Globals
//
Uint16 AdcaResults[RESULTS_BUFFER_SIZE];
Uint16 AdcbResults[RESULTS_BUFFER_SIZE];
Uint16 AdccResults[RESULTS_BUFFER_SIZE];
Uint16 resultsIndex;

void main(void)
{
//
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the F2837xD_SysCtrl.c file.
//
    InitSysCtrl();

//
// Step 2. Initialize GPIO:
// This example function is found in the F2837xD_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
//
    InitGpio(); // Skipped for this example

//
// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
//
    DINT;

//
// Initialize the PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the F2837xD_PieCtrl.c file.
//
    InitPieCtrl();

//
// Disable CPU interrupts and clear all CPU interrupt flags:
//
    IER = 0x0000;
    IFR = 0x0000;

//
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example.  This is useful for debug purposes.
// The shell ISR routines are found in F2837xD_DefaultIsr.c.
// This function is found in F2837xD_PieVect.c.
//
    InitPieVectTable();

//
// Configure the ADC and power it up
//
    ConfigureADC();

//
// Setup the ADC for continuous conversions
//
    initADCContinuous();

//
// Enable global Interrupts and higher priority real-time debug events:
//
    EINT;  // Enable Global interrupt INTM
    ERTM;  // Enable Global realtime interrupt DBGM

//
// Initialize results buffer
//
    for(resultsIndex = 0; resultsIndex < RESULTS_BUFFER_SIZE; resultsIndex++)
    {
        AdcaResults[resultsIndex] = 0;
        AdcbResults[resultsIndex] = 0;
        AdccResults[resultsIndex] = 0;
    }
    resultsIndex = 0;

//
// take conversions indefinitely in loop
//

    AdcaRegs.ADCSOCFRC1.all = 0xFFFF;
    AdcbRegs.ADCSOCFRC1.all = 0x00FF;
    AdccRegs.ADCSOCFRC1.all = 0x00FF;
    do
    {

        //
        //initialize results index
        //
        resultsIndex = 0;

        //
        //software force start SOC0 to SOC7
        //



            AdcaResults[0] = AdcaResultRegs.ADCRESULT0;
            AdcaResults[1] = AdcaResultRegs.ADCRESULT1;
            AdcaResults[2] = AdcaResultRegs.ADCRESULT2;
            AdcaResults[3] = AdcaResultRegs.ADCRESULT3;
            AdcaResults[4] = AdcaResultRegs.ADCRESULT4;
            AdcaResults[5] = AdcaResultRegs.ADCRESULT5;

            AdcbResults[2] = AdcbResultRegs.ADCRESULT2;
            AdcbResults[3] = AdcbResultRegs.ADCRESULT3;
            AdcbResults[4] = AdcbResultRegs.ADCRESULT4;
            AdcbResults[5] = AdcbResultRegs.ADCRESULT5;

            AdccResults[2] = AdccResultRegs.ADCRESULT2;
            AdccResults[3] = AdccResultRegs.ADCRESULT3;
            AdccResults[4] = AdccResultRegs.ADCRESULT4;
            AdccResults[5] = AdccResultRegs.ADCRESULT5;

            AdcaResults[14] = AdcaResultRegs.ADCRESULT14;
            AdcaResults[15] = AdcaResultRegs.ADCRESULT15;

    }while(1);
}

//
// ConfigureADC - Write ADC configurations and power up the ADC for both
//                ADC A and ADC B
//
void ConfigureADC(void)
{
    EALLOW;

    //
    //write configurations
    //
    AdcaRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4
    AdcSetMode(ADC_ADCA, ADC_RESOLUTION_16BIT, ADC_SIGNALMODE_SINGLE);

    AdcbRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4
    AdcSetMode(ADC_ADCB, ADC_RESOLUTION_16BIT, ADC_SIGNALMODE_SINGLE);

    AdccRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4
    AdcSetMode(ADC_ADCC, ADC_RESOLUTION_16BIT, ADC_SIGNALMODE_SINGLE);

    //
    //Set pulse positions to late
    //
    AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;
    AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1;
    AdccRegs.ADCCTL1.bit.INTPULSEPOS = 1;

    //
    //power up the ADC
    //
    AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
    AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;
    AdccRegs.ADCCTL1.bit.ADCPWDNZ = 1;

    //
    //delay for 1ms to allow ADC time to power up
    //
    DELAY_US(1000);

    EDIS;
}

//
// SetupADCContinuous - setup the ADC to continuously convert on one channel
//
void initADCContinuous(void)
{
    Uint16 acqps;

        //
        // Determine minimum acquisition window (in SYSCLKS) based on resolution
        //
        if(ADC_RESOLUTION_12BIT == AdcaRegs.ADCCTL2.bit.RESOLUTION)
        {
            acqps = 14; //75ns
        }
        else //resolution is 16-bit
        {
            acqps = 63; //320ns
        }

        EALLOW;
        AdcaRegs.ADCSOC0CTL.bit.CHSEL  = 0;  //SOC will convert on channel
        AdcaRegs.ADCSOC1CTL.bit.CHSEL  = 1;  //SOC will convert on channel
        AdcaRegs.ADCSOC2CTL.bit.CHSEL  = 2;  //SOC will convert on channel
        AdcaRegs.ADCSOC3CTL.bit.CHSEL  = 3;  //SOC will convert on channel
        AdcaRegs.ADCSOC4CTL.bit.CHSEL  = 4;  //SOC will convert on channel
        AdcaRegs.ADCSOC5CTL.bit.CHSEL  = 5;  //SOC will convert on channel
        AdcaRegs.ADCSOC14CTL.bit.CHSEL = 14;  //SOC will convert on channel
        AdcaRegs.ADCSOC15CTL.bit.CHSEL = 15;  //SOC will convert on channel

        AdcbRegs.ADCSOC2CTL.bit.CHSEL  = 2;  //SOC will convert on channel
        AdcbRegs.ADCSOC3CTL.bit.CHSEL  = 3;  //SOC will convert on channel
        AdcbRegs.ADCSOC4CTL.bit.CHSEL  = 4;  //SOC will convert on channel
        AdcbRegs.ADCSOC5CTL.bit.CHSEL  = 5;  //SOC will convert on channel

        AdccRegs.ADCSOC2CTL.bit.CHSEL  = 2;  //SOC will convert on channel
        AdccRegs.ADCSOC3CTL.bit.CHSEL  = 3;  //SOC will convert on channel
        AdccRegs.ADCSOC4CTL.bit.CHSEL  = 4;  //SOC will convert on channel
        AdccRegs.ADCSOC5CTL.bit.CHSEL  = 5;  //SOC will convert on channel

        AdcaRegs.ADCSOC0CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcaRegs.ADCSOC1CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcaRegs.ADCSOC2CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcaRegs.ADCSOC3CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcaRegs.ADCSOC4CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcaRegs.ADCSOC5CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcaRegs.ADCSOC6CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcaRegs.ADCSOC7CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcaRegs.ADCSOC8CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcaRegs.ADCSOC9CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcaRegs.ADCSOC10CTL.bit.ACQPS = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcaRegs.ADCSOC11CTL.bit.ACQPS = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcaRegs.ADCSOC12CTL.bit.ACQPS = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcaRegs.ADCSOC13CTL.bit.ACQPS = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcaRegs.ADCSOC14CTL.bit.ACQPS = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcaRegs.ADCSOC15CTL.bit.ACQPS = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles


        AdcbRegs.ADCSOC0CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                           //1 SYSCLK cycles
        AdcbRegs.ADCSOC1CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcbRegs.ADCSOC2CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcbRegs.ADCSOC3CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcbRegs.ADCSOC4CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcbRegs.ADCSOC5CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcbRegs.ADCSOC6CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcbRegs.ADCSOC7CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcbRegs.ADCSOC8CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcbRegs.ADCSOC9CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcbRegs.ADCSOC10CTL.bit.ACQPS = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcbRegs.ADCSOC11CTL.bit.ACQPS = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcbRegs.ADCSOC12CTL.bit.ACQPS = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdcbRegs.ADCSOC13CTL.bit.ACQPS = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
                                                   //1 SYSCLK cycles


        AdccRegs.ADCSOC0CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                                   //1 SYSCLK cycles
        AdccRegs.ADCSOC1CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdccRegs.ADCSOC2CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdccRegs.ADCSOC3CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdccRegs.ADCSOC4CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdccRegs.ADCSOC5CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdccRegs.ADCSOC6CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdccRegs.ADCSOC7CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdccRegs.ADCSOC8CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdccRegs.ADCSOC9CTL.bit.ACQPS  = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdccRegs.ADCSOC10CTL.bit.ACQPS = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdccRegs.ADCSOC11CTL.bit.ACQPS = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdccRegs.ADCSOC12CTL.bit.ACQPS = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles
        AdccRegs.ADCSOC13CTL.bit.ACQPS = acqps;    //sample window is acqps +
                                                   //1 SYSCLK cycles

        AdcaRegs.ADCINTSEL1N2.bit.INT1CONT = 1;
        AdcaRegs.ADCINTSEL1N2.bit.INT2CONT = 1;
        AdcaRegs.ADCINTSEL3N4.bit.INT3CONT = 1;
        AdcaRegs.ADCINTSEL3N4.bit.INT4CONT = 1;

        AdcbRegs.ADCINTSEL1N2.bit.INT1CONT = 1;
        AdcbRegs.ADCINTSEL1N2.bit.INT2CONT = 1;
        AdcbRegs.ADCINTSEL3N4.bit.INT3CONT = 1;
        AdcbRegs.ADCINTSEL3N4.bit.INT4CONT = 1;

        AdccRegs.ADCINTSEL1N2.bit.INT1CONT = 1;
        AdccRegs.ADCINTSEL1N2.bit.INT2CONT = 1;
        AdccRegs.ADCINTSEL3N4.bit.INT3CONT = 1;
        AdccRegs.ADCINTSEL3N4.bit.INT4CONT = 1;

        AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 6;  //end of SOC6 will set INT1 flag
        AdcaRegs.ADCINTSEL1N2.bit.INT2SEL = 14; //end of SOC14 will set INT2 flag
        AdcaRegs.ADCINTSEL3N4.bit.INT3SEL = 7;  //end of SOC7 will set INT3 flag
        AdcaRegs.ADCINTSEL3N4.bit.INT4SEL = 15; //end of SOC15 will set INT4 flag

        AdcbRegs.ADCINTSEL1N2.bit.INT1SEL = 6;  //end of SOC6 will set INT1 flag
        AdcbRegs.ADCINTSEL1N2.bit.INT2SEL = 14; //end of SOC14 will set INT2 flag
        AdcbRegs.ADCINTSEL3N4.bit.INT3SEL = 7;  //end of SOC7 will set INT3 flag
        AdcbRegs.ADCINTSEL3N4.bit.INT4SEL = 15; //end of SOC15 will set INT4 flag

        AdccRegs.ADCINTSEL1N2.bit.INT1SEL = 6;  //end of SOC6 will set INT1 flag
        AdccRegs.ADCINTSEL1N2.bit.INT2SEL = 14; //end of SOC14 will set INT2 flag
        AdccRegs.ADCINTSEL3N4.bit.INT3SEL = 7;  //end of SOC7 will set INT3 flag
        AdccRegs.ADCINTSEL3N4.bit.INT4SEL = 15; //end of SOC15 will set INT4 flag

        //
        //ADCINT2 will trigger first 8 SOCs
        //
        AdcaRegs.ADCINTSOCSEL1.bit.SOC0 = 2;
        AdcaRegs.ADCINTSOCSEL1.bit.SOC1 = 2;
        AdcaRegs.ADCINTSOCSEL1.bit.SOC2 = 2;
        AdcaRegs.ADCINTSOCSEL1.bit.SOC3 = 2;
        AdcaRegs.ADCINTSOCSEL1.bit.SOC4 = 2;
        AdcaRegs.ADCINTSOCSEL1.bit.SOC5 = 2;
        AdcaRegs.ADCINTSOCSEL1.bit.SOC6 = 2;
        AdcaRegs.ADCINTSOCSEL1.bit.SOC7 = 2;

        AdcbRegs.ADCINTSOCSEL1.bit.SOC0 = 2;
        AdcbRegs.ADCINTSOCSEL1.bit.SOC1 = 2;
        AdcbRegs.ADCINTSOCSEL1.bit.SOC2 = 2;
        AdcbRegs.ADCINTSOCSEL1.bit.SOC3 = 2;
        AdcbRegs.ADCINTSOCSEL1.bit.SOC4 = 2;
        AdcbRegs.ADCINTSOCSEL1.bit.SOC5 = 2;
        AdcbRegs.ADCINTSOCSEL1.bit.SOC6 = 2;
        AdcbRegs.ADCINTSOCSEL1.bit.SOC7 = 2;


        AdccRegs.ADCINTSOCSEL1.bit.SOC0 = 2;
        AdccRegs.ADCINTSOCSEL1.bit.SOC1 = 2;
        AdccRegs.ADCINTSOCSEL1.bit.SOC2 = 2;
        AdccRegs.ADCINTSOCSEL1.bit.SOC3 = 2;
        AdccRegs.ADCINTSOCSEL1.bit.SOC4 = 2;
        AdccRegs.ADCINTSOCSEL1.bit.SOC5 = 2;
        AdccRegs.ADCINTSOCSEL1.bit.SOC6 = 2;
        AdccRegs.ADCINTSOCSEL1.bit.SOC7 = 2;

        //
        //ADCINT1 will trigger second 8 SOCs
        //
        AdcaRegs.ADCINTSOCSEL2.bit.SOC8 = 1;
        AdcaRegs.ADCINTSOCSEL2.bit.SOC9 = 1;
        AdcaRegs.ADCINTSOCSEL2.bit.SOC10 = 1;
        AdcaRegs.ADCINTSOCSEL2.bit.SOC11 = 1;
        AdcaRegs.ADCINTSOCSEL2.bit.SOC12 = 1;
        AdcaRegs.ADCINTSOCSEL2.bit.SOC13 = 1;
        AdcaRegs.ADCINTSOCSEL2.bit.SOC14 = 1;
        AdcaRegs.ADCINTSOCSEL2.bit.SOC15 = 1;

        AdcbRegs.ADCINTSOCSEL2.bit.SOC8 = 1;
        AdcbRegs.ADCINTSOCSEL2.bit.SOC9 = 1;
        AdcbRegs.ADCINTSOCSEL2.bit.SOC10 = 1;
        AdcbRegs.ADCINTSOCSEL2.bit.SOC11 = 1;
        AdcbRegs.ADCINTSOCSEL2.bit.SOC12 = 1;
        AdcbRegs.ADCINTSOCSEL2.bit.SOC13 = 1;

        AdccRegs.ADCINTSOCSEL2.bit.SOC8 = 1;
        AdccRegs.ADCINTSOCSEL2.bit.SOC9 = 1;
        AdccRegs.ADCINTSOCSEL2.bit.SOC10 = 1;
        AdccRegs.ADCINTSOCSEL2.bit.SOC11 = 1;
        AdccRegs.ADCINTSOCSEL2.bit.SOC12 = 1;
        AdccRegs.ADCINTSOCSEL2.bit.SOC13 = 1;

        EDIS;

        //
        //software force start SOC0 to SOC15 on A for ADCIN14 and ADCIN15
        //
        AdcaRegs.ADCSOCFRC1.all = 0xFFFF;
        AdcbRegs.ADCSOCFRC1.all = 0x00FF;
        AdccRegs.ADCSOCFRC1.all = 0x00FF;
}

//
// End of file
//

  • Hi Curtis,

    Some quick notes:

    //
    //software force start SOC0 to SOC15 on A for ADCIN14 and ADCIN15
    //
    AdcaRegs.ADCSOCFRC1.all = 0xFFFF;
    AdcbRegs.ADCSOCFRC1.all = 0x00FF;
    AdccRegs.ADCSOCFRC1.all = 0x00FF;

    Don't use the individual SW forces in your final code. It should be OK for now, but Instead see the parallel SW force example which will show you how to start the samples in parallel so they stay synchronous and also see the 'ensuring synchronous operation' section of the TRM.

    Note that these SW force statements should be the same for all 3 ADCs since you are using all SOCs on all ADCs.

    ---

    AdcSetMode(ADC_ADCA, ADC_RESOLUTION_16BIT, ADC_SIGNALMODE_SINGLE);

    16-bit single-ended mode is not supported. We can't really say what we expect the conversion results to be in this mode.

    ---

    How are you determining that the sample only occurred once? Are you just watching the registers in real-time mode in the expressions window? You should be able to see the RRPointer changing erratically in real-time mode if it is continuously converting.

    Are the inputs driven or floating? If floating they may change once and then stay at a some static value.
  • Hey Devin,

    Thank you for your notes!  I've looked at the TRM and the synchronous example.  I will use a single XBAR to trigger the ADC sampling on all of the ADC channels.  Hopefully, only one trigger will be necessary to kick off the continuous sampling of the ADCs.

    I've also changed the resolution back to 12 bits.

    Initially, I thought only one sample was being taken because upon starting the program, some nonzero values were being placed into some result registers, but after looking at the RRPOINTER value, it remains at a value of 0.  I'm not sure if that means it has only done sample 0 or if it's just not sampling at all.

    Not all of the inputs are being driven, but I'm driving one pin at a time and checking the ADC result register corresponding to that pin.

    Is it possible to have the ADC running without checking, clearing, or waiting for ADC interrupts?  Should AdcaRegs.ADCINTSEL1N2.bit.INT1CONT be set to 0 or to 1?  If I'm not checking for the interrupt or flag, would that value even matter?

    Thanks!

  • Hi Curtis,

    Yeah, it should be possible for the ADC to convert continuously w/o intervention.

    You want the INT1CONT and INT2CONT bits to be set so that the ADC interrupt event at the end of the set of conversions will propagate to trigger the other set even if you don't clear the ADCINT flag with the CPU or with a CPU interrupt.

    Because only ADCINT1 and ADCINT2 have CONT setting, I think you want to modify the code to only use these two flags. It should be ADCINT1 from EOC6 triggers SOC8-15 and ADCINT2 from EOC14 triggers SOC0-7.

    The RR pointer tells you which SOC would have priority next. It sounds like all 16 SOCs convert once and then you are stuck with the sequence not repeating...maybe because of the ADCINT CONT settings I mentioned above.
  • Hey Devin,

    I've set up synchronous sampling and continuous sampling in the following function. Before calling the while loop for recording ADC samples, I also toggle the XBAR GPIO high then low to start conversions. No samples seem to be recorded even when tying the ADC pin high.

    The RR Pointer seems to stay at 10000 for ADC A, B, and C when watching the register values. The ADC free counter is changing.


    I'm not sure what I'm missing, but here's the setup:
    void SetupADCSoftwareSync(void)
    {
    Uint16 acqps;

    //
    // Determine minimum acquisition window (in SYSCLKS) based on resolution
    //
    if(ADC_RESOLUTION_12BIT == AdcaRegs.ADCCTL2.bit.RESOLUTION)
    {
    acqps = 14; //75ns
    }
    else //resolution is 16-bit
    {
    acqps = 63; //320ns
    }

    //
    //Select the channels to convert and end of conversion flag
    //ADCA
    //
    EALLOW;
    AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0; //SOC0 will convert pin A0
    AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is acqps +
    //1 SYSCLK cycles
    AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 4; //line 5 of the input X-BAR will
    //trigger the ADC

    AdcaRegs.ADCSOC1CTL.bit.CHSEL = 1; //SOC1 will convert pin A1
    AdcaRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is acqps +
    //1 SYSCLK cycles
    AdcaRegs.ADCSOC1CTL.bit.TRIGSEL = 4; //line 5 of the input X-BAR will
    //trigger the ADC

    AdcaRegs.ADCSOC2CTL.bit.CHSEL = 2; //SOC2 will convert pin A2
    AdcaRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is acqps +
    //1 SYSCLK cycles
    AdcaRegs.ADCSOC2CTL.bit.TRIGSEL = 4; //line 5 of the input X-BAR will
    //trigger the ADC

    AdcaRegs.ADCSOC3CTL.bit.CHSEL = 3; //SOC3 will convert pin A3
    AdcaRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is acqps +
    //1 SYSCLK cycles
    AdcaRegs.ADCSOC3CTL.bit.TRIGSEL = 4; //line 5 of the input X-BAR will
    //trigger the ADC

    AdcaRegs.ADCSOC4CTL.bit.CHSEL = 4; //SOC4 will convert pin A4
    AdcaRegs.ADCSOC4CTL.bit.ACQPS = acqps; //sample window is acqps +
    //1 SYSCLK cycles
    AdcaRegs.ADCSOC4CTL.bit.TRIGSEL = 4; //line 5 of the input X-BAR will
    //trigger the ADC

    AdcaRegs.ADCSOC5CTL.bit.CHSEL = 5; //SOC5 will convert pin A5
    AdcaRegs.ADCSOC5CTL.bit.ACQPS = acqps; //sample window is acqps +
    //1 SYSCLK cycles
    AdcaRegs.ADCSOC5CTL.bit.TRIGSEL = 4; //line 5 of the input X-BAR will
    //trigger the ADC

    AdcaRegs.ADCSOC14CTL.bit.CHSEL = 14; //SOC14 will convert pin A14
    AdcaRegs.ADCSOC14CTL.bit.ACQPS = acqps; //sample window is acqps +
    //1 SYSCLK cycles
    AdcaRegs.ADCSOC14CTL.bit.TRIGSEL = 4; //line 5 of the input X-BAR will
    //trigger the ADC

    AdcaRegs.ADCSOC15CTL.bit.CHSEL = 15; //SOC15 will convert pin A15
    AdcaRegs.ADCSOC15CTL.bit.ACQPS = acqps; //sample window is acqps +
    //1 SYSCLK cycles
    AdcaRegs.ADCSOC15CTL.bit.TRIGSEL = 4; //line 5 of the input X-BAR will
    //trigger the ADC


    //
    //ADCB
    //
    AdcbRegs.ADCSOC2CTL.bit.CHSEL = 2; //SOC2 will convert pin B2
    AdcbRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is acqps +
    //1 SYSCLK cycles
    AdcbRegs.ADCSOC2CTL.bit.TRIGSEL = 4; //line 5 of the input X-BAR will
    //trigger the ADC

    AdcbRegs.ADCSOC3CTL.bit.CHSEL = 3; //SOC3 will convert pin B3
    AdcbRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is acqps +
    //1 SYSCLK cycles
    AdcbRegs.ADCSOC3CTL.bit.TRIGSEL = 4; //line 5 of the input X-BAR will
    //trigger the ADC

    AdcbRegs.ADCSOC4CTL.bit.CHSEL = 4; //SOC4 will convert pin B4
    AdcbRegs.ADCSOC4CTL.bit.ACQPS = acqps; //sample window is acqps +
    //1 SYSCLK cycles
    AdcbRegs.ADCSOC4CTL.bit.TRIGSEL = 4; //line 5 of the input X-BAR will
    //trigger the ADC

    AdcbRegs.ADCSOC5CTL.bit.CHSEL = 5; //SOC5 will convert pin B5
    AdcbRegs.ADCSOC5CTL.bit.ACQPS = acqps; //sample window is acqps +
    //1 SYSCLK cycles
    AdcbRegs.ADCSOC5CTL.bit.TRIGSEL = 4; //line 5 of the input X-BAR will
    //trigger the ADC


    //
    //ADCC
    //
    AdccRegs.ADCSOC2CTL.bit.CHSEL = 2; //SOC2 will convert pin C2
    AdccRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is acqps +
    //1 SYSCLK cycles
    AdccRegs.ADCSOC2CTL.bit.TRIGSEL = 4; //line 5 of the input X-BAR will
    //trigger the ADC

    AdccRegs.ADCSOC3CTL.bit.CHSEL = 3; //SOC3 will convert pin C3
    AdccRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is acqps +
    //1 SYSCLK cycles
    AdccRegs.ADCSOC3CTL.bit.TRIGSEL = 4; //line 5 of the input X-BAR will
    //trigger the ADC

    AdccRegs.ADCSOC4CTL.bit.CHSEL = 4; //SOC4 will convert pin C4
    AdccRegs.ADCSOC4CTL.bit.ACQPS = acqps; //sample window is acqps +
    //1 SYSCLK cycles
    AdccRegs.ADCSOC4CTL.bit.TRIGSEL = 4; //line 5 of the input X-BAR will
    //trigger the ADC

    AdccRegs.ADCSOC5CTL.bit.CHSEL = 5; //SOC5 will convert pin C5
    AdccRegs.ADCSOC5CTL.bit.ACQPS = acqps; //sample window is acqps +
    //1 SYSCLK cycles
    AdccRegs.ADCSOC5CTL.bit.TRIGSEL = 4; //line 5 of the input X-BAR will
    //trigger the ADC


    // Set up continuous ADC operation
    AdcaRegs.ADCINTSEL1N2.bit.INT1CONT = 1;
    AdcaRegs.ADCINTSEL1N2.bit.INT2CONT = 1;
    // AdcaRegs.ADCINTSEL3N4.bit.INT3CONT = 1;
    // AdcaRegs.ADCINTSEL3N4.bit.INT4CONT = 1;

    AdcbRegs.ADCINTSEL1N2.bit.INT1CONT = 1;
    AdcbRegs.ADCINTSEL1N2.bit.INT2CONT = 1;
    // AdcbRegs.ADCINTSEL3N4.bit.INT3CONT = 1;
    // AdcbRegs.ADCINTSEL3N4.bit.INT4CONT = 1;

    AdccRegs.ADCINTSEL1N2.bit.INT1CONT = 1;
    AdccRegs.ADCINTSEL1N2.bit.INT2CONT = 1;
    // AdccRegs.ADCINTSEL3N4.bit.INT3CONT = 1;
    // AdccRegs.ADCINTSEL3N4.bit.INT4CONT = 1;

    AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 6; //end of SOC6 will set INT1 flag
    AdcaRegs.ADCINTSEL1N2.bit.INT2SEL = 14; //end of SOC14 will set INT2 flag
    // AdcaRegs.ADCINTSEL3N4.bit.INT3SEL = 7; //end of SOC7 will set INT3 flag
    // AdcaRegs.ADCINTSEL3N4.bit.INT4SEL = 15; //end of SOC15 will set INT4 flag

    AdcbRegs.ADCINTSEL1N2.bit.INT1SEL = 6; //end of SOC6 will set INT1 flag
    AdcbRegs.ADCINTSEL1N2.bit.INT2SEL = 14; //end of SOC14 will set INT2 flag
    // AdcbRegs.ADCINTSEL3N4.bit.INT3SEL = 7; //end of SOC7 will set INT3 flag
    // AdcbRegs.ADCINTSEL3N4.bit.INT4SEL = 15; //end of SOC15 will set INT4 flag

    AdccRegs.ADCINTSEL1N2.bit.INT1SEL = 6; //end of SOC6 will set INT1 flag
    AdccRegs.ADCINTSEL1N2.bit.INT2SEL = 14; //end of SOC14 will set INT2 flag
    // AdccRegs.ADCINTSEL3N4.bit.INT3SEL = 7; //end of SOC7 will set INT3 flag
    // AdccRegs.ADCINTSEL3N4.bit.INT4SEL = 15; //end of SOC15 will set INT4 flag

    }
  • Hi Curtis,

    You should get at least one conversions for each configured SOC when the GPIO associated with input XBAR 5 toggles, so you might want to double-check your XBAR settings.

    What should happen (duplicated on each ADC) is:

    XBAR triggers SOC0 to SOC7
    -->I'm not sure that you have all the SOCs configured. You'll need them based on the way the default ping-pong continuous sampling code is setup. You can reduce the number of SOCs later when you understand the code.

    EOC6 triggers ADCINT1
    -->This seems to be configured from the INT side, but you don't have SOC6, so EOC6 doesn't occur?

    ADCINT1 triggers SOC8-15
    -->These SOCs don't need an SOC.TRIGSEL setting, but they do need an 'INTSOCSEL' setting to tell the SOCs to be triggered by the ADCINT flag:
    AdcaRegs.ADCINTSOCSEL2.bit.SOC8 = 1;
    AdcaRegs.ADCINTSOCSEL2.bit.SOC9 = 1;
    ...

    EOC14 triggers ADCINT2
    -->This seems to be configured from the INT side, but you don't have SOC14 on all ADCs, so EOC14 doesn't occur?

    ADCINT2 triggers SOC0-7
    -->These SOCs need an SOC.TRIGSEL setting in addition to the 'INTSOCSEL' setting. The triggers are OR'ed so both XBAR5 or ADCINT2 will trigger the SOC
    AdcaRegs.ADCINTSOCSEL1.bit.SOC0 = 2;
    AdcaRegs.ADCINTSOCSEL1.bit.SOC1 = 2;
    ...

    ADCINT1 and ADCINT2 need to be set to continuous mode so that the process can repeat indefinitely...
    -->This seems to be configured in your code

    Note that a given SOC can convert any channel, so you don't need SOC14 to convert channel 14; you could do SOC0 = CH14, SOC1 = CH0, SOC2 = CH1, etc. Generally you'd allocate SOCs from the lowest (SOC0) upwards until you have the desired number of channels. However, to start with allocate all 16 SOCs on all ADCs because that is how the example continuous conversion code is setup.
  • Hi Devin,

    I did have some issues in my XBAR setup. I muxed the pin incorrectly to be OUTPUTXBAR instead of a regular GPIO. Now the code will sample once upon software toggling the GPIO linked to the XBAR INPUT5, but it only samples once.

    SOC0-7 follow this setup for A, B, and C:
    AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0;
    AdcaRegs.ADCSOC0CTL.bit.ACQPS = 14;
    AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 4; // This selects XBAR as a trigger
    AdcaRegs.ADCINTSOCSEL1.bit.SOC0 = 2; // This selects ADCINT2 as a trigger

    When EOC6 occurs, ADCINT1 is set, if I understand correctly.

    SOC8-15 follow this setup for A, B, and C:
    AdcaRegs.ADCSOC8CTL.bit.CHSEL = 8;
    AdcaRegs.ADCSOC8CTL.bit.ACQPS = 14;
    AdcaRegs.ADCINTSOCSEL2.bit.SOC8 = 1; // This selects ADCINT1 as a trigger

    AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 6; //end of SOC6 will set INT1 flag
    AdcaRegs.ADCINTSEL1N2.bit.INT2SEL = 14; //end of SOC14 will set INT2 flag

    The sequence would be XBAR triggers SOC0-7. EOC6 triggers ADCINT1. ADCINT1 triggers SOC8-15. EOC14 triggers ADCINT2. ADCINT2 triggers SOC0-7, starting the sequence again indefinitely. That makes sense to me now, thank you! I'm still unsure of what's stopping the ADCs from sampling more than one time.

    For good measure, the XBAR setup is as follows:
    EALLOW;
    InputXbarRegs.INPUT5SELECT = 34; //GPIO34 will trigger the input XBAR line 5
    GPIO_SetupPinOptions(34, GPIO_OUTPUT, GPIO_PUSHPULL);
    GPIO_SetupPinMux(34, GPIO_MUX_CPU1, 0);
    GpioDataRegs.GPBCLEAR.bit.GPIO34 = 1; //GPIO34 set as low
    EDIS;

    In my main function, I set the GPIO high and immediately clear it. After this, a while loop captures the results of the ADCRESULTS registers.

    Thank you for your help with this!
  • Hi Curtis,

    It seems like your understanding is correct and your post succinctly describes the required settings. The only other point is that ADCINT1 and 2 need to be set to continuous mode so that the CPU doesn't need to intervene to clear the ADCINT flags. It looks like you had that setting in your other snippet, so that is probably not the problem.

    Do you see SOC8-15 each get a single sample too, or only SOC0-7?

    Do you see ADCINT1 and ADCINT2 being set? If you clear them in the expressions window while the code is running do they become set again?

    Do you see RR pointer, ADCBSY, and/or ADCBSYCHN changing in the expressions window (RRPOINTER should be in the range 0 to 15 after a sample has occurred)?
  • Hi Devin,

    I have the continuous setting as follows for A, B, and C:
    AdcaRegs.ADCINTSEL1N2.bit.INT1CONT = 1;
    AdcaRegs.ADCINTSEL1N2.bit.INT2CONT = 1;

    SOC8-15 don't appear to be getting a single sample.

    ADCINT1 and ADCINT2 are already cleared. Setting them while the code runs causes them to be immediately cleared again.

    The RR pointer is fixed at 7, which makes sense that 8-15 aren't getting samples. ADCBSY = 0 and ADCBSYCHN = 7.

    Is it necessary to have the two stages of ADCINTs? In other words, could SOC0-15 be triggered by (XBAR || ADCINT1) and then have EOC15 trigger ADCINT1?

  • By setting up (XBAR || ADCINT1) to trigger SOC0-15 and EOC15 to trigger ADCINT1, the code works. I also added the following lines for A, B, and C to enable the ADCINTs:
    AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;

    Thanks for your help, Devin!