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.

TMS320F28065: ISR handling

Part Number: TMS320F28065


While using ADC ISR at 33khz triggered by ePWM2, The ISR code was taking more than interrupt time, so part of code I had moved to ePWM1 ISR. Now the ADC ISR timing reduced but the frequency at which it occurs is not consistent as before (maybe PWM ISR is affecting it, PWM ISR running at 100khz). 

Please suggest how can I overcome this.

Can ADC ISR be given priority over others ?

Please guide me.

  • Ravi,

    Please see the PIE assignment table in the F2806x TRM, Table 1-119 on pages 176-177:

    www.ti.com/lit/spruh18

    Notice that ADCINT1 and ADCINT2 are located at INT1.1 and INT1.2 (high priority mode) and also at INT10.1 and INT10.2 (low priority mode). When located at INT1.1 and INT1.2, the ADC will have the highest priority over all other peripherals.

    In case you are interested, please see the F2806x Workshop to learn more about the device:

    processors.wiki.ti.com/.../C2000_Archived_Workshops

    I hope this helps. If this answers your question, please click the green "Verified Answer" button. Thanks.

    - Ken
  • Sir,

    Thanks for your response. I'm having:

    PieCtrlRegs.PIEIER3.bit.INTx1 = 1; // pwm1
    PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // Enable ADCINT1 in PIE group 1
    PieCtrlRegs.PIEIER9.bit.INTx1 = 1; // PIE Group 9, INT1 //sci rx
    PieCtrlRegs.PIEIER9.bit.INTx2 = 1; // PIE Group 9, INT2 //sci tx
    PieCtrlRegs.PIEIER9.bit.INTx3 = 1; // PIE Group 9, INT1 //sci rx
    PieCtrlRegs.PIEIER9.bit.INTx4 = 1; // PIE Group 9, INT2 //sci tx

    The ADC initialization is:

    //-------------------------------------------------------------------
    // ADC INITIALISATION
    //-------------------------------------------------------------------
    EALLOW;
    AdcRegs.ADCCTL1.bit.ADCBGPWD = 1; 
    AdcRegs.ADCCTL1.bit.ADCREFPWD = 1; 
    AdcRegs.ADCCTL1.bit.ADCPWDN = 1; 
    AdcRegs.ADCCTL1.bit.ADCENABLE = 1; 
    asm(" RPT#100 || NOP");

    AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1; 
    AdcRegs.ADCCTL1.bit.TEMPCONV = 0; 
    AdcRegs.ADCCTL2.bit.ADCNONOVERLAP = 1;
    //-------------------------------------------------------------------
    // Configure ADC
    //-------------------------------------------------------------------

    AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC1CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC2CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC3CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC4CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC5CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC6CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC7CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC8CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC9CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC10CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC11CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC12CTL.bit.TRIGSEL = 7;
    AdcRegs.ADCSOC13CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC14CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC15CTL.bit.TRIGSEL = 7; 

    AdcRegs.ADCSOC0CTL.bit.CHSEL = 0x0; // Convert channel
    AdcRegs.ADCSOC1CTL.bit.CHSEL = 0x1; // Convert channel
    AdcRegs.ADCSOC2CTL.bit.CHSEL = 0x2; // Convert channel
    AdcRegs.ADCSOC3CTL.bit.CHSEL = 0x3; // Convert channel
    AdcRegs.ADCSOC4CTL.bit.CHSEL = 0x4; // Convert channel
    AdcRegs.ADCSOC5CTL.bit.CHSEL = 0x5; // Convert channel
    AdcRegs.ADCSOC6CTL.bit.CHSEL = 0x6; // Convert channel
    AdcRegs.ADCSOC7CTL.bit.CHSEL = 0x7; // Convert channel
    AdcRegs.ADCSOC8CTL.bit.CHSEL = 0x8; // Convert channel
    AdcRegs.ADCSOC9CTL.bit.CHSEL = 0x9; // Convert channel
    AdcRegs.ADCSOC10CTL.bit.CHSEL = 0xA; // Convert channel
    AdcRegs.ADCSOC11CTL.bit.CHSEL = 0xB; // Convert channel
    AdcRegs.ADCSOC12CTL.bit.CHSEL = 0xC; // Convert channel
    AdcRegs.ADCSOC13CTL.bit.CHSEL = 0xD; // Convert channel
    AdcRegs.ADCSOC14CTL.bit.CHSEL = 0xE; // Convert channel
    AdcRegs.ADCSOC15CTL.bit.CHSEL = 0xF; // Convert channel

    AdcRegs.ADCSOC0CTL.bit.ACQPS = SAMPLE; // Acquisition window
    AdcRegs.ADCSOC1CTL.bit.ACQPS = SAMPLE; // Acquisition window
    AdcRegs.ADCSOC2CTL.bit.ACQPS = SAMPLE; // Acquisition window
    AdcRegs.ADCSOC3CTL.bit.ACQPS = SAMPLE; // Acquisition window
    AdcRegs.ADCSOC4CTL.bit.ACQPS = SAMPLE; // Acquisition window
    AdcRegs.ADCSOC5CTL.bit.ACQPS = SAMPLE; // Acquisition window
    AdcRegs.ADCSOC6CTL.bit.ACQPS = SAMPLE; // Acquisition window
    AdcRegs.ADCSOC7CTL.bit.ACQPS = SAMPLE; // Acquisition window
    AdcRegs.ADCSOC8CTL.bit.ACQPS = SAMPLE; // Acquisition window
    AdcRegs.ADCSOC9CTL.bit.ACQPS = SAMPLE; // Acquisition window
    AdcRegs.ADCSOC10CTL.bit.ACQPS = SAMPLE; // Acquisition window
    AdcRegs.ADCSOC11CTL.bit.ACQPS = SAMPLE; // Acquisition window
    AdcRegs.ADCSOC12CTL.bit.ACQPS = SAMPLE; // Acquisition window
    AdcRegs.ADCSOC13CTL.bit.ACQPS = SAMPLE; // Acquisition window
    AdcRegs.ADCSOC14CTL.bit.ACQPS = SAMPLE; // Acquisition window
    AdcRegs.ADCSOC15CTL.bit.ACQPS = SAMPLE; // Acquisition window


    //-------------------------------------------------------------------
    // ADCINT0 configuration
    //-------------------------------------------------------------------
    AdcRegs.INTSEL1N2.bit.INT1CONT = 0; 
    AdcRegs.INTSEL1N2.bit.INT1E = 1; 
    AdcRegs.INTSEL1N2.bit.INT1SEL = 15; 

    //-------------------------------------------------------------------
    EDIS;

    //------------------------------------------------------------------

    I'm getting irregular ADC ISR timings, please refer to attached picture. Please suggest me what is to be done. 

  • As a customer can I expect any answers?

  • Hi Ravi,

    Can you let me know what operations are being done in ADC & EPWM ISR. Is the ADC interrupt flags are getting cleared & acknowledged in the ADC ISR.

    Thanks
    Vasudha
  • Madam,

    I'm turning a controlled switch ON/OFF from AC signal in ADC ISR & I'm calculating 3 phase voltage/current RMS in ePWM ISR.

    The ADC interrupt is getting cleared in ADC ISR as:
    AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
    return;

    I want to know how can the irregular ADC ISR calling be avoided as this affects my switch ON/OFF operations due to changed timing. Pl. help.

  • Hi Ravi,

    How are you capturing the above timings? Can you also check the PWM ISR the same way in adidtion to ADC ISR. This is to check if PWM ISR is interfering with ADC ISR or not.

    Also can you check if simultaneous mode is getting configured in your application? Are there any other ADC configurations done, other than the code shared above?

    Thanks
    Vasudha

  • Madam,

    Timings are captured by set and clear action of GPIO.

    Pl. see attached image of ADC and PWM ISR captured together.

    I have not included  simultaneous mode config. but i have tried making SIMULEN0 to SIMULEN14, 0 and 1 but same ADC two times  calling is observed.

  • Hi Ravi,

    As per the captured timings, if the GPIO is set at the start of the ISR then the PWM ISR doesn't seem to interfere. So we can rule that out.

    Thanks
    Vasudha
  • Can you share the simulataneous mode related config or any other ADC related config done in your example?

    I am suspecting issue with simultaneous only.

    Thanks
    Vasudha
  • Madam,

    The only ADC config initializations are:

    ///////////////////////////////////////////////////////////////////////

    EALLOW;

    AdcRegs.ADCCTL1.bit.ADCBGPWD = 1;
    AdcRegs.ADCCTL1.bit.ADCREFPWD = 1; 
    AdcRegs.ADCCTL1.bit.ADCPWDN = 1; 
    AdcRegs.ADCCTL1.bit.ADCENABLE = 1; 
    asm(" RPT#100 || NOP");

    AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1; 
    AdcRegs.ADCCTL1.bit.TEMPCONV = 0; 
    AdcRegs.ADCCTL2.bit.ADCNONOVERLAP = 1; 
    //-------------------------------------------------------------------
    // Configure ADC
    //-------------------------------------------------------------------

    AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC1CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC2CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC3CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC4CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC5CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC6CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC7CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC8CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC9CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC10CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC11CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC12CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC13CTL.bit.TRIGSEL = 7; 
    AdcRegs.ADCSOC14CTL.bit.TRIGSEL = 7;
    AdcRegs.ADCSOC15CTL.bit.TRIGSEL = 7; 

    AdcRegs.ADCSOC0CTL.bit.CHSEL = 0x0; 
    AdcRegs.ADCSOC1CTL.bit.CHSEL = 0x1; 
    AdcRegs.ADCSOC2CTL.bit.CHSEL = 0x2; 
    AdcRegs.ADCSOC3CTL.bit.CHSEL = 0x3; 
    AdcRegs.ADCSOC4CTL.bit.CHSEL = 0x4; 
    AdcRegs.ADCSOC5CTL.bit.CHSEL = 0x5; 
    AdcRegs.ADCSOC6CTL.bit.CHSEL = 0x6; 
    AdcRegs.ADCSOC7CTL.bit.CHSEL = 0x7;
    AdcRegs.ADCSOC8CTL.bit.CHSEL = 0x8;
    AdcRegs.ADCSOC9CTL.bit.CHSEL = 0x9; 
    AdcRegs.ADCSOC10CTL.bit.CHSEL = 0xA; 
    AdcRegs.ADCSOC11CTL.bit.CHSEL = 0xB; 
    AdcRegs.ADCSOC12CTL.bit.CHSEL = 0xC; 
    AdcRegs.ADCSOC13CTL.bit.CHSEL = 0xD; 
    AdcRegs.ADCSOC14CTL.bit.CHSEL = 0xE;
    AdcRegs.ADCSOC15CTL.bit.CHSEL = 0xF; 

    AdcRegs.ADCSOC0CTL.bit.ACQPS = SAMPLE; 
    AdcRegs.ADCSOC1CTL.bit.ACQPS = SAMPLE; 
    AdcRegs.ADCSOC2CTL.bit.ACQPS = SAMPLE; 
    AdcRegs.ADCSOC3CTL.bit.ACQPS = SAMPLE;
    AdcRegs.ADCSOC4CTL.bit.ACQPS = SAMPLE; 
    AdcRegs.ADCSOC5CTL.bit.ACQPS = SAMPLE; 
    AdcRegs.ADCSOC6CTL.bit.ACQPS = SAMPLE; 
    AdcRegs.ADCSOC7CTL.bit.ACQPS = SAMPLE; 
    AdcRegs.ADCSOC8CTL.bit.ACQPS = SAMPLE; 
    AdcRegs.ADCSOC9CTL.bit.ACQPS = SAMPLE;
    AdcRegs.ADCSOC10CTL.bit.ACQPS = SAMPLE; 
    AdcRegs.ADCSOC11CTL.bit.ACQPS = SAMPLE; 
    AdcRegs.ADCSOC12CTL.bit.ACQPS = SAMPLE; 
    AdcRegs.ADCSOC13CTL.bit.ACQPS = SAMPLE; 
    AdcRegs.ADCSOC14CTL.bit.ACQPS = SAMPLE;
    AdcRegs.ADCSOC15CTL.bit.ACQPS = SAMPLE; 


    AdcRegs.INTSEL1N2.bit.INT1CONT = 0;
    AdcRegs.INTSEL1N2.bit.INT1E = 1; 
    AdcRegs.INTSEL1N2.bit.INT1SEL = 15; 

    //-------------------------------------------------------------------
    EDIS;

    ///////////////////////////////////////////////////////////////////////

    Why I think PWM ISR is affecting ADC ISR is: 

    By disabling PWM ISR or by reducing the calculations done in PWM ISR, proper calling of ADC ISR is observed.

    Pl. experts should come in this as we are using this in products and it should get solved.

  • Hi Ravi,

    Is the sync enabled between ePWM1 & EPWM2? Also let me know which event generates SOC trigger in epwm2 & which event generates interrupt for epwm1.

    Thanks
    Vasudha
  • Hi Ravi,

    If needed, you can share you code for better assistance.

    Thanks
    Vasudha
  • Madam,

    ePWM1 & 2 are not in sync. ePWM1 config:
    // ---------------------- Init EPWM1 ------------------------------------------------
    EALLOW;
    EPwm1Regs.TBPRD = ADC_ISR_F; // ADC_ISR_F = 2500
    EPwm1Regs.TBPHS.half.TBPHS = 0x0000;
    EPwm1Regs.TBCTR = 0x0000;
    EPwm1Regs.CMPA.half.CMPA = ADC_ISR_F / 2 ;
    EPwm1Regs.CMPB = ADC_ISR_F / 2 ;
    EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;
    EPwm1Regs.AQCTLA.bit.ZRO = AQ_CLEAR;
    EPwm1Regs.AQCTLB.bit.CAU = AQ_SET;
    EPwm1Regs.AQCTLB.bit.ZRO = AQ_CLEAR;
    // Set Dead Band for PWM1
    EPwm1Regs.DBCTL.bit.OUT_MODE = DB_DISABLE;
    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
    EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
    EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;
    EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;
    // Setup shadowing
    EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
    EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

    //trip zone setting
    EPwm1Regs.TZSEL.bit.CBC1 = 1;
    EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO;
    EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_LO;
    EPwm1Regs.TZEINT.bit.CBC = 1;

    // Interrupt where we will change the Deadband
    EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;
    EPwm1Regs.ETSEL.bit.INTEN = 1;
    EPwm1Regs.ETPS.bit.INTPRD = ET_3RD;

    EDIS;

    ///////////////////
    ePWM2 config:
    EALLOW;
    EPwm2Regs.TBPRD = ADC_ISR_F;
    EPwm2Regs.TBPHS.all = 0;
    EPwm2Regs.TBCTR = 0;
    EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;
    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
    EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;
    EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;
    EPwm2Regs.TBCTL.bit.HSPCLKDIV = TBH_DIV1;
    EPwm2Regs.TBCTL.bit.CLKDIV = TBH_DIV1;
    // Setup shadow register load on ZERO
    EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
    EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;


    //SOC Generation Setting
    EPwm2Regs.ETSEL.bit.SOCAEN = 1;
    EPwm2Regs.ETSEL.bit.SOCASEL = ET_CTR_PRD;
    EPwm2Regs.ETPS.bit.SOCAPRD = ET_1ST;


    EPwm2Regs.CMPA.half.CMPA = ADC_ISR_F / 2;//1666;
    EPwm2Regs.CMPB = ADC_ISR_F / 2;//1666;

    EPwm2Regs.AQCTLA.bit.CAU = AQ_SET;
    EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR;
    EPwm2Regs.AQCTLB.bit.CBU = AQ_SET;
    EPwm2Regs.AQCTLB.bit.CBD = AQ_CLEAR;
    EDIS;
    /////////////////////
    epwm1_isr used for RMS calculation of voltages & currents.

  • As a customer can I expect any answers?
  • Here are some recommendations:
    1) Reduce processor load in ISRs, redesign your code.
    2) Calculate your total required processing power, is your problem a timing issue or you just overloaded your CPU?
    3) Move timing critical ISRs to RAM to run them faster
    4) Use higher compiler optimization level
    5) write ISR in assembly
    6) Use CLA for some ISR
    7) Use a higher speed microcontroller

    The above list seems obvious, general list; but saved me several times.

    MHG
  • Hi Ravi,

    I think the problem is due to the SOC trigger & interrupt trigger being almost same.PFB the description of what I think is happening:


    // Interrupt where we will change the Deadband
    EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;
    EPwm1Regs.ETSEL.bit.INTEN = 1;
    EPwm1Regs.ETPS.bit.INTPRD = ET_3RD;

    Ravi said:
    //SOC Generation Setting
    EPwm2Regs.ETSEL.bit.SOCAEN = 1;
    EPwm2Regs.ETSEL.bit.SOCASEL = ET_CTR_PRD;
    EPwm2Regs.ETPS.bit.SOCAPRD = ET_1ST;

    At the thirt cnt = zero event, pwm ISR is hit and also the ADC has been already triggered on 2nd cntr = prd(difference of 1 cycle). So till the time ADC results are computed, PWM ISR is already getting executed and hence just after the ISR finishes, the pending ADC interrupt gets executed. And the next ADC conversion had already been triggered on 3rd cntr = prd event in the mean time & hence you see 2 consecutive ADC interrupts. The third ADC interrupt is uninterrupted & is executed as expected.

    I think you need to play around the ADC SOC trigger & EPWM interrupt trigger timings to avoid the conflict. You can try changing the triggers to any other event like CMPA/CMPB etc.

    Also, let me know the time EPWM ISR & ADC ISR takes?

    Let me know if this resolves your query.