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.

ADC2 Issue on Concerto F28M36

Other Parts Discussed in Thread: CONTROLSUITE

Hi,

I am trying to utilize both ADC1 and ADC2 in the F28M36 Core. The setup is based on the Concerto Control Card and I am running into an issue that I couldn't solve.

The issue is very simple, configure all available channels for ADC1 and ADC2 and sample them using a trigger such as PWM1 compare event. When ADC1 is configured for this every thing works fine but if the same code is used to utilize the ADC2 module, no interrupts are generated. Please see the code below and provide insight into why the different behavior and why ADC2 is not able to generate EOC interrupts.

The following piece of code works fine and triggers the conversion interrupts as expected.

void ConfigAdc(void)

{

InitAdc1();

InitAdc2();

Adc1OffsetSelfCal();

Adc2OffsetSelfCal();

LoopCount = 0;

ConversionCount = 0;

g_c28EventCounter.cAdc1 = 0;

g_c28EventCounter.cAdc2 = 0;

// Configure ADC

EALLOW;

Adc1Regs.ADCSAMPLEMODE.all = 0x3F;

// Enable simultaneous sampling.

Adc1Regs.ADCCTL2.bit.ADCNONOVERLAP = 1;

// Enable non-overlap mode i.e. conversion and future sampling events dont overlap

Adc1Regs.ADCCTL1.bit.INTPULSEPOS = 1;

// ADCINT1 trips after AdcResults latch

Adc1Regs.INTSEL1N2.bit.INT1E = 1;

// Enabled ADCINT1

Adc1Regs.INTSEL1N2.bit.INT1CONT = 0;

// Disable ADCINT1 Continuous mode

Adc1Regs.INTSEL1N2.bit.INT1SEL = 0;

// setup EOC0 to trigger ADCINT1 to fire

AnalogSysctrlRegs.TRIG1SEL.all = 5;

// Assigning EPWM1SOCA to ADC TRIGGER 1 of the ADC module

Adc1Regs.ADCSOC0CTL.bit.CHSEL = 0;

// set SOC0 channel select to ADC2A0/ADC2B0

Adc1Regs.ADCSOC0CTL.bit.TRIGSEL = 5;

// Set Trigger 1 for Start of Conversion.

Adc1Regs.ADCSOC0CTL.bit.ACQPS = 6;

// set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

Adc1Regs.ADCSOC1CTL.bit.CHSEL = 2;

// set SOC1 channel select to ADC2A2/ADC2B2

Adc1Regs.ADCSOC1CTL.bit.TRIGSEL = 5;

// Set Trigger 1 for Start of Conversion.

Adc1Regs.ADCSOC1CTL.bit.ACQPS = 6;

// set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

Adc1Regs.ADCSOC2CTL.bit.CHSEL = 3;

// set SOC0 channel select to ADC2A3/ADC2B3

Adc1Regs.ADCSOC2CTL.bit.TRIGSEL = 5;

// Set Trigger 1 for Start of Conversion.

Adc1Regs.ADCSOC2CTL.bit.ACQPS = 6;

// set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

Adc1Regs.ADCSOC3CTL.bit.CHSEL = 4;

// set SOC1 channel select to ADC2A4/ADC2B4

Adc1Regs.ADCSOC3CTL.bit.TRIGSEL = 5;

// Set Trigger 1 for Start of Conversion.

Adc1Regs.ADCSOC3CTL.bit.ACQPS = 6;

// set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

Adc1Regs.ADCSOC4CTL.bit.CHSEL = 6;

// set SOC0 channel select to ADC2A7/ADC2B7

Adc1Regs.ADCSOC4CTL.bit.TRIGSEL = 5;

// Set Trigger 1 for Start of Conversion.

Adc1Regs.ADCSOC4CTL.bit.ACQPS = 6;

// set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

Adc1Regs.ADCSOC5CTL.bit.CHSEL = 7;

// set SOC1 channel select to ADC2A7/ADC2B7

Adc1Regs.ADCSOC5CTL.bit.TRIGSEL = 5;

// Set Trigger 1 for Start of Conversion.

Adc1Regs.ADCSOC5CTL.bit.ACQPS = 6;

// set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

EDIS;

 

}

Where as the code shown below utilizes ADC2 module but everything else remains the same and it does not work.

 

void ConfigAdc(void)

{

InitAdc1();

InitAdc2();

Adc1OffsetSelfCal();

Adc2OffsetSelfCal();

LoopCount = 0;

ConversionCount = 0;

g_c28EventCounter.cAdc1 = 0;

g_c28EventCounter.cAdc2 = 0;

// Configure ADC

EALLOW;

Adc2Regs.ADCSAMPLEMODE.all = 0x3F;

// Enable simultaneous sampling.

Adc2Regs.ADCCTL2.bit.ADCNONOVERLAP = 1;

// Enable non-overlap mode i.e. conversion and future sampling events dont overlap

Adc2Regs.ADCCTL1.bit.INTPULSEPOS = 1;

// ADCINT1 trips after AdcResults latch

Adc2Regs.INTSEL1N2.bit.INT1E = 1;

// Enabled ADCINT1

Adc2Regs.INTSEL1N2.bit.INT1CONT = 0;

// Disable ADCINT1 Continuous mode

Adc2Regs.INTSEL1N2.bit.INT1SEL = 0;

// setup EOC0 to trigger ADCINT1 to fire

AnalogSysctrlRegs.TRIG1SEL.all = 5;

// Assigning EPWM1SOCA to ADC TRIGGER 1 of the ADC module

Adc2Regs.ADCSOC0CTL.bit.CHSEL = 0;

// set SOC0 channel select to ADC2A0/ADC2B0

Adc2Regs.ADCSOC0CTL.bit.TRIGSEL = 5;

// Set Trigger 1 for Start of Conversion.

Adc2Regs.ADCSOC0CTL.bit.ACQPS = 6;

// set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

Adc2Regs.ADCSOC1CTL.bit.CHSEL = 2;

// set SOC1 channel select to ADC2A2/ADC2B2

Adc2Regs.ADCSOC1CTL.bit.TRIGSEL = 5;

// Set Trigger 1 for Start of Conversion.

Adc2Regs.ADCSOC1CTL.bit.ACQPS = 6;

// set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

Adc2Regs.ADCSOC2CTL.bit.CHSEL = 3;

// set SOC0 channel select to ADC2A3/ADC2B3

Adc2Regs.ADCSOC2CTL.bit.TRIGSEL = 5;

// Set Trigger 1 for Start of Conversion.

Adc2Regs.ADCSOC2CTL.bit.ACQPS = 6;

// set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

Adc2Regs.ADCSOC3CTL.bit.CHSEL = 4;

// set SOC1 channel select to ADC2A4/ADC2B4

Adc2Regs.ADCSOC3CTL.bit.TRIGSEL = 5;

// Set Trigger 1 for Start of Conversion.

Adc2Regs.ADCSOC3CTL.bit.ACQPS = 6;

// set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

Adc2Regs.ADCSOC4CTL.bit.CHSEL = 6;

// set SOC0 channel select to ADC2A7/ADC2B7

Adc2Regs.ADCSOC4CTL.bit.TRIGSEL = 5;

// Set Trigger 1 for Start of Conversion.

Adc2Regs.ADCSOC4CTL.bit.ACQPS = 6;

// set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

Adc2Regs.ADCSOC5CTL.bit.CHSEL = 7;

// set SOC1 channel select to ADC2A7/ADC2B7

Adc2Regs.ADCSOC5CTL.bit.TRIGSEL = 5;

// Set Trigger 1 for Start of Conversion.

Adc2Regs.ADCSOC5CTL.bit.ACQPS = 6;

// set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

EDIS;

 

}

 

  • Muhammad Sami1 said:
    When ADC1 is configured for this every thing works fine but if the same code is used to utilize the ADC2 module, no interrupts are generated.

    Have you modified PieVectTable, PieCtrlRegs, and IER to set ADC2 interrupt?

    Best regards,

    Maria

  • I have both ADCINT1 and ADCINT2 configured as shown in the code below. A counter is incremented to see if the interrupt is firing. I have also noticed that the interrupt count is 1 so interrupts only trigger once and after that no more interrupt even though the compare event is triggering continuously.

    // Code for firing ADC SOC

    //Set event triggers (SOCA) for ADC SOC1
    EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group
    EPwm1Regs.ETSEL.bit.SOCASEL = ET_CTRU_CMPA; // Select SOC from CMPA on upcount
    EPwm1Regs.ETPS.bit.SOCAPRD = 3; // Generate pulse on every 3rd event

    // Code for initialing ADC Interrupts.

    EALLOW; // This is needed to write to EALLOW protected registers
    PieVectTable.ADCINT1 = &adc1_isr;
    PieVectTable.ADCINT2 = &adc2_isr;
    EDIS; // This is needed to disable write to EALLOW protected registers

    IER |= M_INT1;

    PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // Enable INT 1.1 in the PIE
    PieCtrlRegs.PIEIER1.bit.INTx2 = 1; // Enable INT 1.2 in the PIE


    __interrupt void adc1_isr(void)
    {
    g_c28EventCounter.cAdc1++;

    Adc1Regs.ADCINTFLGCLR.bit.ADCINT1 = 1; //Clear ADCINT1 flag reinitialize for next SOC
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE
    }

    __interrupt void adc2_isr(void)
    {
    g_c28EventCounter.cAdc2++;

    Adc2Regs.ADCINTFLGCLR.bit.ADCINT2 = 1; //Clear ADCINT2 flag reinitialize for next SOC
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE
    }

  • Muhammad,

    It looks like you are using ADCINT1 for both ADCs so nothing is generating ADCINT2.  Instead, they are both generating ADCINT1 because the ADCINTx signals are shared between ADCs.

    Adc1Regs.INTSEL1N2.bit.INT1E = 1;

    // Enabled ADCINT1

    Adc1Regs.INTSEL1N2.bit.INT1CONT = 0;

    // Disable ADCINT1 Continuous mode

    Adc1Regs.INTSEL1N2.bit.INT1SEL = 0;

    // setup EOC0 to trigger ADCINT1 to fire

    ....

    Adc2Regs.INTSEL1N2.bit.INT1E = 1;

    // Enabled ADCINT1

    Adc2Regs.INTSEL1N2.bit.INT1CONT = 0;

    // Disable ADCINT1 Continuous mode

    Adc2Regs.INTSEL1N2.bit.INT1SEL = 0;

    // setup EOC0 to trigger ADCINT1 to fire

    -Tommy

  • Hi Tommy,

    I have already tried ADCINT2 using the following changes but no luck either. In this situation you get back to back interrupts as if the interrupt is not even getting acknowledged in the ISR even though both the ISR handlers clear the interrupt pending flags for their respective interrupt. 

    Adc2Regs.INTSEL1N2.bit.INT2E = 1; // Enabled ADCINT2
    Adc2Regs.INTSEL1N2.bit.INT2CONT = 0; // Disable ADCINT2 Continuous mode
    Adc2Regs.INTSEL1N2.bit.INT2SEL = 0; // Setup EOC0 to trigger ADCINT2 to fire

    I also observed that the ISR is always triggered by both ADCs at least once even though it is not configured to do so, which seems strange.

    In addition, with interrupt 2 enabled for ADC2, the flag still indicates interrupt 1 pending for ADC2 which does not make sense as the ADC1 is not even configured for generating any interrupts.

    I have tried all these combinations, please let me know if you have any questions,

    I would also like to request a piece of code or sample that could scan all the 24 ADC channels for both ADC1 and ADC2 modules in simultaneous mode and provides event triggers for both ADC modules  to capture the sampled signals. This will really help. 

  • Muhammad,

    I think you are on the right track, but there might be interrupt triggers carried over between test runs.  Did you try to fully power off/on the board to make sure that everything has been reset?  I usually do this when making significant changes to the interrupt settings.  A device reset is also recommended between runs.

    It also sounds like there might be too many variables in play here.  I would recommend getting ADC1 to work by itself using ADCINT1.  Then, get ADC2 to work by itself with ADCINT2.  When those are working standalone, it should be much easier to integrate the two together.

    -Tommy

  • Hi Tommy,

    As I mentioend at the begining of the post that If I just use ADC1 it works fine, Its the ADC2 that has the problem. I have been working on this for almost a week and tried various combinations, I am using Flash for code runs and cycled power completely to ensure that the chip goes through full power on reset. In addition I am using TI provided code shown below for initializing, configuring and calibrating the ADCs and I am at a loss here. Besides I am seeing the chip behavior which is rather erratic and I haven't found any explanation for the behavior described in the post anywhere in the Concerto user manaul. 

    InitAdc1();

    InitAdc2();

    Adc1OffsetSelfCal();

    Adc2OffsetSelfCal();

    I would really appreciate if you could provide a code snippet that works with ADC2. Modifying a functional ADC1 code for ADC2 hasn't helped me so far and I have gone through the user manual and available samples many times to figure out the problem area but no luck, so here I am and I have to post it here to get the expert opinion and hoping for a resolution.

     

  • Hi Tommy, Really hoping to get a resolution for this issue. 

    And I also should have referred to you as a Mastermind based on your ranking and not an expert. Just noticed that. My mistake and my apologies. 

  • Muhammad,

    Here is a modified version of the ControlSUITE example that works on my setup.

    -Tommy