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.

C2000WARE: Can higher priority interrupt executions at high frequency lead to the CPU never executing lower priority interrupts?

Part Number: C2000WARE


Hello,

I am developing a dual-CPU power converter. I have one converter running at 1MHz and the other running at 200-400kHz, and their interrupts are triggered by the ADC SOCs.

I have found during emulation that the priority at which I set the interrupts leads to very different performance of the code. 

I had originally planned to use ADCA1, ADCC1, TIMER0 and IPC0/IPC1 interrupts in each CPU to communicate between them. 

I find that if I use ADCA1 (1MHz) and ADCC1 (200-400kHz), TIMER0 and IPC0/IPC1 are never serviced.

I changed ADCC1 to instead use ADCC2 in group 10, which then leads to TIMER0 being executed as expected. ADCC2 also does execute, but only a select number of times (100~) and then is never executed again. 

I think there is quite clearly some kind of conflict between the ISR's - TIMER0/ADCA1 is always set again, before it is reset (I believe I am using continuous interrupts because I am using the CLA and digital controller library to read error and calculate new duty cycles and periods).

Is it just that the code in my 1MHz control loop takes too long to execute, and therefore because it has priority, after it has finished executing it has already set a new ADC flag and begins execution again?

Is there any solutions to this at all? IPC0/1 are not executing at all, the IPCSTS[IPC1] flag is constantly set showing that the interrupt flags have been set requesting a service routine to occur, but the CPU is never servicing them.

EDIT: I changed the ADC's to not be continuous and instead need manual reset of the INTs. I then checked the ADCAINT1OVF and ADCCINT2OVF and both have been set at 1, leading me to believe that my suspicions are true and that the PWM frequency generates a new interrupt before the last one has been handled. Is there any way to work around this? Is it just a matter of the control loop being too fast, or the code I have wrote being too slow to execute before the next PWM cycle comes along?

Any help appreciated.

Best regards,
Joel

  • I was going to guess that it could be that the transfers of data between CPU1 and CPU2 were taking too long. But this is only done for the 200kHz-400kHz loop, there is no reading or writing to the IPC registers performed in the 1MHz control loop. 

    I was going to ask whether the use of DMA would improve these above issues - but again, it looks like even the 1MHz loop that does not use any transfers or therefore require the use of the DMA, is too slow. Not sure where to go from here...

    Best regards,
    Joel

  • Is it just that the code in my 1MHz control loop takes too long to execute, and therefore because it has priority, after it has finished executing it has already set a new ADC flag and begins execution again?
    I have wrote being too slow to execute before the next PWM cycle comes along?

    Very likely.

    Any help appreciated.

    You can assign a profiling GPIO to each interrupt that you would set right after ISR entry and clear just before ISR exit. Then, using an oscilloscope, you can determine if one or more ISRs are taking too long to execute.

  • I guess that you would observe the frequency of the GPIO? Would you recommend having the continue to interrupt setting enabled, or would it rather be better to have to clear the INT at the end of the ISR along with clearing the GPIO you put alongside it?

    some of my ISRs are not triggering at all because it is IPC0/1 which is never being triggered, despite their flag being set in the registers. But continue to interrupt seems like the only way that you could use GPIO frequency to check how long they are taking to execute, because if this is disabled by the time I view the GPIO in the oscilloscope it will just be a 1 or 0 with no new interrupts.

    let me know your thoughts? 

    thanks,

    joel 

  • I guess that you would observe the frequency of the GPIO?

    Yes, the GPIO frequency and duration of ISR execution to see if it causes interrupt overflow.

    Would you recommend having the continue to interrupt setting enabled, or would it rather be better to have to clear the INT at the end of the ISR along with clearing the GPIO you put alongside it?

    For now, you would probably want to keep the continuous ADC interrupt setting or else the ADC ISRs will stop executing until you service the OVERFLOW states. Once you fix the root cause of the overflows, you will not need the continuous setting.

  • Okay, great, I will try that.

    As a side note, do you think a 1MHz control loop utilising the DCL is beyond the capabilities of this MCU? In this loop I am literally just sending some information to the CLA, performing an average current control controller  (uses two DCL loops) and then modulating the registers. But I know the system clock is 200MHz so I believed this would be achievable with this controller. 

    it may be that the speed of my controller is limited by the slower frequency ISR which is the one that includes a DCL, IPC transfers etc. Hopefully when I implement the GPIO tomorrow I can discover more.  But I’m actually leaning toward that my code may be not efficient rather than this being beyond the capability of the device. 

    Best regards

    Joel 

  • As a side note, do you think a 1MHz control loop utilising the DCL is beyond the capabilities of this MCU?

    A 1MHz loop is certainly possible, but inefficient code has the potential to break anything.

    This C28x Optimization Guide might help.

  • Tommy, thanks, this is very helpful material. 

    As a final question I would like to get your advice on the ADC sample technique - I am fairly sure this is what is slowing down my code. I trigger ADC samples from the PWM, which runs at 1MHz and there the time to acquire a new sample for the voltage and current can take a decent percentage of the control bandwidth.

    I may have asked this before but would using continuous ADC samples be the best solution for fast ADC sampling for high frequency control loops? It is my thinking that if the ADC runs continously in the background, the controller only needs to access the latest converter value rather than wait for the ADC sample to be taken and converted to a 12-bit digital representation. Come to think of it, I'm not sure if even if the ADC is indeed triggered by the PWM, that the code necessarily needs to "wait" for the conversion to take place? This would probably mean the controller takes the sample that was taken by the previous PWM cycle INT, but it shouldn't effect performance too much...

    Anyway, do you have any advice for which ADC/SOC configuration you would suggest for the fastest control loops? 

    Best regards,

    Joel

  • would using continuous ADC samples be the best solution for fast ADC sampling for high frequency control loops? It is my thinking that if the ADC runs continously in the background, the controller only needs to access the latest converter value rather than wait for the ADC sample to be taken and converted to a 12-bit digital representation.

    I would not consider the continuous sampling approach to be the best. The continuous samples would be converted asynchronously with your control loop so you would have to account for any distortions that would result from sampling time jitter.

    All ADC conversions can be considered to be "background" operations that are controlled by hardware with no explicit need for CPU software intervention.

    the code necessarily needs to "wait" for the conversion to take place?

    Waiting is suboptimal.


    Anyway, do you have any advice for which ADC/SOC configuration you would suggest for the fastest control loops? 

    The ADC conversions can be triggered using the EPWM at an earlier point of the control loop such that the results are ready just in time for ISR consumption.

    There are also example reference solutions in the Digital Power SDK.

  • Hi Tommy, 

    That makes sense - but my control loop, which is performed by the DCL library, is triggered I believe by my PWM signal - so I don't see how I can trigger the ADC samples any earlier. I will check out the Digital Power SDK and see if that helps any. Hopefully there are some with just as fast frequency.

    Best, 
    Joel

  • but my control loop, which is performed by the DCL library, is triggered I believe by my PWM signal - so I don't see how I can trigger the ADC samples any earlier

    An alternate approach would be to trigger the ADC SOCs using an arbitrary early EPWM CMPx value and service the control functions in the ADC EOC ISR.

  • Hi Tommy, 

    I am trying to implement this approach but I can't see how to it is any different than my current implementation, where the ADC is triggered at TBCTR = ZRO and the controller is serviced by the EOC ISR. What is the benefit of slightly delaying the start of conversion rather than just using ZRO?

    I was thinking to generate a new CMPC that is used to start the conversions, as you explain, however it seems in this register the only option is to use CMPA OR CMPC and no options to just use CMPC. If we use CMPA or CMPC and the controller starts a conversion on CMPA match, won't the time at which an EOC is generated depend on the duty cycle of the PWM modules that are set by the CMPA/CMPB values anyway? I'd suppose you would rather to launch the ADC's at a set point in the period that does not change? 

    Best regards,
    Joel

  • I am trying to implement this approach but I can't see how to it is any different than my current implementation, where the ADC is triggered at TBCTR = ZRO and the controller is serviced by the EOC ISR. What is the benefit of slightly delaying the start of conversion rather than just using ZRO?

    Your prior description made it sound like you were using the EPWM to trigger the control ISR and waiting for the ADC conversions to take place in the ISR. Starting the ADC conversions early and triggering the control ISR using ADC EOC would push the waiting for ADC conversions to the background without stalling ISR execution.

    I was thinking to generate a new CMPC that is used to start the conversions, as you explain, however it seems in this register the only option is to use CMPA OR CMPC and no options to just use CMPC.

    You have all of these to choose from:

    If we use CMPA or CMPC and the controller starts a conversion on CMPA match, won't the time at which an EOC is generated depend on the duty cycle of the PWM modules that are set by the CMPA/CMPB values anyway?

    I don't follow. The EOC trigger in EPWM time reference would be SOCA + ADC conversion time.

  • Hi Tommy,

    Here is what I have for the ETSEL and ETPS registers

    // Set up ADC trigger pulse to ADC SOCA (ADCAINT1)
    EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOCA
    EPwm1Regs.ETSEL.bit.SOCASEL = 1; // Enable event time-base counter equal to zero 
    EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event

    // Set up ADC trigger pulse to ADC SOCA (ADCAINT2)
    EPwm4Regs.ETSEL.bit.SOCAEN = 1; // Enable SOCA
    EPwm4Regs.ETSEL.bit.SOCASEL = 1; // Enable event time-base counter equal to zero 
    EPwm4Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event

    I don't think I wait for the ADC samples at any point, they are triggered by the SOCA pulses on both PWM1 and PWM4. The ISR's perform the following:
    Read ADC data > Launch CLA > Set dead-time, duty, and period > clear and acknowledge interrupt. And that's about it.

    Is there anything visibly wrong with this method?

    Best regards,
    Joel

  • Joel,

    Nothing stands out visibly.

    -Tommy