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.

How to set up multiple ADC interrupts?

Hi,

I am wondering how to set up two ADC interrupts like ADCINT1 and ADCINT2, so each of them can control a group of SOCs independently. (especially when I need to use different sampling frequencies on different ADC inputs).

I haven't seen any examples using this kind of setting.

In the example (ControlSUITE--F28035),  interrupt ADCINT1 is configured to control SOC0, as shown below:

    EALLOW;

    AdcRegs.INTSEL1N2.bit.INT1E     = 1;    //Enabled ADCINT1
    AdcRegs.INTSEL1N2.bit.INT1CONT  = 0;    //Disable ADCINT1 Continuous mode
    
    AdcRegs.ADCSOC0CTL.bit.CHSEL     = 2;   
   
    AdcRegs.ADCSOC0CTL.bit.TRIGSEL     = 5;    //set SOC0 start trigger on EPWM1---> EPwm1 to SOCA
   
    AdcRegs.ADCSOC0CTL.bit.ACQPS     = 6;    //set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
  
    EDIS;

How should I configure ADCINT2, so it can only control SOC1?    just like the following?

   EALLOW;

  AdcRegs.INTSEL1N2.bit.INT2E     = 1;    //Enabled ADCINT2

  ...........

  ...........

  EDIS;

I don't really think it is that simple.

Hope someone can help with this.

Thank you,

Frank

  • I am sure there are other ways to sample different ADC inputs at different rates. I just want to know if it is possible to use multiple ADC interrupts to do it.

    Thank you,

    Frank

  • Hi Frank,

    You can set AdcRegs.ADCINTSOCSEL1.bit.SOC1 = 0x10 ; This will allow ADCINT2 to trigger SOC1.

  • Hi Vishal,

    Thank you. This is what I've been looking for.

    Now, I have a few related questions.

    1. I think I still have to enable ADCINT2 before using it.     Does the following sample code look okay?

        EALLOW;
        AdcRegs.INTSEL1N2.bit.INT1E     = 1;             // for ADCINT1
        AdcRegs.INTSEL1N2.bit.INT1CONT  = 0;        
        AdcRegs.ADCSOC0CTL.bit.CHSEL     = 2;    
        AdcRegs.ADCSOC0CTL.bit.TRIGSEL     = 5;    
        AdcRegs.ADCSOC0CTL.bit.ACQPS     = 6;    
        
        AdcRegs.INTSEL1N2.bit.INT2E     = 1;            // For ADCINT2
        AdcRegs.INTSEL1N2.bit.INT2CONT  = 0;
        AdcRegs.ADCINTSOCSEL1.bit.SOC1  = 0x10;
        EDIS;
        
        EPwm1Regs.ETSEL.bit.SOCAEN    = 1;           // Enable SOC on A group
        EPwm1Regs.ETSEL.bit.SOCASEL    = 4;        // Select SOC from from CPMA on upcount
        EPwm1Regs.ETPS.bit.SOCAPRD     = 1;        // Generate pulse on 1st event
        EPwm1Regs.CMPA.half.CMPA     = 0x0080;    // Set compare A value
        EPwm1Regs.TBPRD                 = 0xFFFF;        // Set period for ePWM1
        EPwm1Regs.TBCTL.bit.CTRMODE     = 0;        // count up and start
       

    2. Once it is set up like this, then  I have to use ADCINTFLGCLR to control ADCINT2, right?

    Frank

  • 1. Not exactly. If I understand correctly, you want SOC0 to be triggered by EPWM1SOCA and SOC1 by ADCINT2? If this is the case then you have setup SOC0 correctly but SOC1 should be setup as follows

        EALLOW;
        AdcRegs.INTSEL1N2.bit.INT2E     = 1;             // for ADCINT2
        AdcRegs.INTSEL1N2.bit.INT2CONT  = 0;      
        AdcRegs.INTSEL1N2.bit.INT2SEL  = 0x00;  //IMPORTANT - I have chosen EOC0 to trigger ADCINT2
           
        AdcRegs.ADCSOC1CTL.bit.CHSEL     = 2;     //Assuming you are sampling the same channel
        AdcRegs.ADCSOC1CTL.bit.TRIGSEL     = 5;    
        AdcRegs.ADCSOC1CTL.bit.ACQPS     = 6;    
        AdcRegs.ADCINTSOCSEL1.bit.SOC1  = 0x10;  //ADCINT2 will trigger SOC1, ADCSOC1CTL.bit.TRIGSEL will be ignored!
        EDIS;

    So the way this will work is EPWM1SOCA(triggers on CMPA match) will trigger SOC0-> ADC will sample channel 2, convert it, generate EOC0 signal which, in turn, generates ADCINT2.

    ADCINT2 will trigger SOC1 to sample channel2 and convert it . At this point ADINT2FLG is set and needs to be cleared by writing to the ADCINTFLGCLR register before the next SOC1 can begin.

  • Hi Vishal,

    Thank you for your reply.

    So, if it is configured like this, then I think I can determine the sampling frequency of SOC1 by choosing how often to clear ADCINT2FLG.  Is that correct?

    Specifically,,

    1. If I clear ADCINT2FLG as frequently as ADCINT2 receives ECO0, then SOC0 and SOC1 will have the same sampling frequency. (Everytime, SOC1 begins right after SOC0 finishes)

    2. If I want SOC0's sampling frequency to be 10 times higher than SOC1's sampling frequency, then I can write the code like this,

    int EOC_COUNT;
    int SOC0_Value;
    int SOC1_Value;

    main()
    {
        EOC_COUNT = 0;
        .......
        //configuration part
        .......
    }

    interrup void ADC_isr (void)
    {
        SOC0_Value = AdcResult.ADCRESULT0;
        SOC1_Value = AdcResult.ADCRESULT1;
        
        if ( EOC_COUNT == 9 )
        {
            AdcRegs.ADCINTFLGCLR.bit.ADCINT2 = 1;
            EOC_COUNT = 0;
        }
        
        else EOC_COUNT++ ;
        
        AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1 ;
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;

    }

    3.If I want SOC0's sampling frequency to be 1/10 of SOC1's sampling frequency, then I think I have to use SOC2 associated with ePWM2 which is 10 times faster than ePWM1, then set up EOC2 to trigger SOC1?

    Please let me know if my understanding is correct for the three cases above,

    Thank you so much,

    Frank

              

  • 1. If I clear ADCINT2FLG as frequently as ADCINT2 receives ECO0, then SOC0 and SOC1 will have the same sampling frequency. (Everytime, SOC1 begins right after SOC0 finishes)

    Correct

    2. If I want SOC0's sampling frequency to be 10 times higher than SOC1's sampling frequency, then I can write the code like this,

    int EOC_COUNT;
    int SOC0_Value;
    int SOC1_Value;

    main()
    {
        EOC_COUNT = 0;
        .......
        //configuration part
        .......
    }

    Id like to point out here that this will work, but you will probably experience some drift in the sampling instances over time as this approach relies on software branching which causes overhead that is likely to add up over time. If you want strict sampling times its best to do this in hardware i.e. setup two PWMs, one 10x faster than the other, synchronize them and then have these PWMs trigger SOC0 and SOC1 respectively.


    interrup void ADC_isr (void)
    {
        SOC0_Value = AdcResult.ADCRESULT0;
        SOC1_Value = AdcResult.ADCRESULT1;
        
        if ( EOC_COUNT == 9 )
        {
            AdcRegs.ADCINTFLGCLR.bit.ADCINT2 = 1;
            EOC_COUNT = 0;
        }
        
        else EOC_COUNT++ ;
        
        AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1 ;
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;

    }

    3.If I want SOC0's sampling frequency to be 1/10 of SOC1's sampling frequency, then I think I have to use SOC2 associated with ePWM2 which is 10 times faster than ePWM1, then set up EOC2 to trigger SOC1?

    You can have EPWM1SOCA trigger SOC0 and EPWM2SOCA trigger SOC1; EPWM2 will run at 10x EPWM1 as you suggested, but remember to sync these two PWMs

    Please let me know if my understanding is correct for the three cases above,

    Thank you so much,

    Frank

  • Hi Vishal,

    Thank you for answering my questions.

    Up to this point, it really shows that one ADC interrupt can totally handle the tasks in my application.

    So, I really want to know, in what kind of situations that we must have multiple ADC interrupts in a project ?

    Can I say that only one ADC interrupt is needed if strict sampling times are required ?

    Thank you,

    Frank

  • Hi,

    Can anyone help me with the two questions above?

    Thanks,

    Frank