Part Number: TMS320F28379D
Hello,
I ran into another problem concerning the EPWM interrupt generation. At the start of my ISR, I am setting GPIOs to monitor the handling of the ISR on the scope.
I am using two EPWM modules to generate a burst-mode operation to output a defined number of high-frequency pulses with a specific repetition rate (low frequence timer).
I am setting the compare register and use a counter which is decremented to keep track of the generated pulses in the ISR of the high frequency PWM module. If the desired number of pulses is generated (counter < 1)I am stopping to clear the interrupt flag and the pulse generation stops.
The second PWM (configured at a much lower frequency) is (re)setting the counter variable and clear the interrupt flag from the high frequency PWM and the process starts again.
This works quite well, however it seems that once the flag is cleared there is immediately an interrupt generated (2 interrupts directly one after another)
Yellow: GPIO test pin set at start and cleared at end of high-frequency ISR (GPIO 105)
Blue: generated PWM
Any idea what could be the reason for that? The problem is that the generated number of pulses varies from time to time since the counter is decremented already but no pulse is generated (b/c of shadow registers).
Looking forward to hear your thoughts.
Edit 1:
// EPWM2 timer configured such that interrupt occurs with a high rate of 100kHz
// Interrupt at every CNT=Zero event
__interrupt void epwm2ISR(void)
{
GPIO_writePin(105, 1);
if(pulse_cnt_val > 0)
{
EPWM_setCounterCompareValue(EPWM2_BASE, EPWM_COUNTER_COMPARE_A,compA_value);
pulse_cnt_val--;
}
else
{
EPWM_setCounterCompareValue(EPWM2_BASE, EPWM_COUNTER_COMPARE_A,0U);
EPWM_disableInterrupt(EPWM2_BASE);
}
//
// Clear INT flag for this timer
//
EPWM_clearEventTriggerInterruptFlag(EPWM2_BASE);
//
// Acknowledge interrupt group
//
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
GPIO_writePin(105, 0);
}
// EPWM7 timer configured such that interrupt occurs with a low rate of 1kHz
// Interrupt at every CNT=Zero event
// EPWM7 and EPWM2 not syncronized
__interrupt void epwm7ISR(void)
{
GPIO_writePin(104, 1);
// Update pulse count, compare register will be updated in EPWM2 interrupt
pulse_cnt_val = 10;
EPWM_enableInterrupt(EPWM2_BASE);
//
// Clear INT flag for this timer
//
EPWM_clearEventTriggerInterruptFlag(EPWM7_BASE);
//
// Acknowledge interrupt group
//
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
GPIO_writePin(104, 0);
}
EDIT 2: EPWM Init Code
//
// initEPWM2 - Configure Phase B
//
void initEPWM2()
{
//
// Set-up TBCLK
//
EPWM_setTimeBasePeriod(EPWM2_BASE, EPWM2_TIMER_TBPRD);
EPWM_setTimeBaseCounter(EPWM2_BASE, 0U);
EPWM_setPhaseShift(EPWM2_BASE, 0U);
EPWM_enablePhaseShiftLoad(EPWM2_BASE);
EPWM_setSyncOutPulseMode(EPWM2_BASE, EPWM_SYNC_OUT_PULSE_ON_EPWMxSYNCIN);
//
// Set up counter mode
//
EPWM_setTimeBaseCounterMode(EPWM2_BASE, EPWM_COUNTER_MODE_UP);
EPWM_setClockPrescaler(EPWM2_BASE,
EPWM_CLOCK_DIVIDER_1,
EPWM_HSCLOCK_DIVIDER_1);
//
// Set Compare values
//
EPWM_setCounterCompareValue(EPWM2_BASE,
EPWM_COUNTER_COMPARE_A,
EPWM2_CMPA);
EPWM_setCounterCompareValue(EPWM2_BASE,
EPWM_COUNTER_COMPARE_B,
EPWM2_CMPB);
EPWM_setCounterCompareValue(EPWM2_BASE,
EPWM_COUNTER_COMPARE_C,
EPWM2_CMPB);
//
// Set up shadowing
//
EPWM_setCounterCompareShadowLoadMode(EPWM2_BASE,
EPWM_COUNTER_COMPARE_A,
EPWM_COMP_LOAD_ON_SYNC_ONLY);
EPWM_setCounterCompareShadowLoadMode(EPWM2_BASE,
EPWM_COUNTER_COMPARE_B,
EPWM_COMP_LOAD_ON_SYNC_ONLY);
// used to trigger SOC-A
EPWM_setCounterCompareShadowLoadMode(EPWM2_BASE,
EPWM_COUNTER_COMPARE_C,
EPWM_COMP_LOAD_ON_SYNC_ONLY);
EPWM_selectPeriodLoadEvent(EPWM2_BASE, EPWM_SHADOW_LOAD_MODE_SYNC);
//
// Set actions
//
EPWM_setActionQualifierAction(EPWM2_BASE,
EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_HIGH,
EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(EPWM2_BASE,
EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_LOW,
EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
//Trigger ADC SOC
//
// Configure SOC-A to occur at CTR Zero
//
EPWM_setADCTriggerSource(EPWM2_BASE, EPWM_SOC_A, EPWM_SOC_TBCTR_U_CMPC);
EPWM_setADCTriggerEventPrescale(EPWM2_BASE, EPWM_SOC_A, 1);
EPWM_enableADCTrigger(EPWM2_BASE, EPWM_SOC_A);
//
// Interrupt where we will change the Compare Values
// Select INT on Time base counter zero event,
// Enable INT, generate INT on 1st event
//
EPWM_setInterruptSource(EPWM2_BASE, EPWM_INT_TBCTR_ZERO);
EPWM_enableInterrupt(EPWM2_BASE);
EPWM_setInterruptEventCount(EPWM2_BASE, 1U);
}
//
// initEPWM7 - Burst/Pulse Train Timer
//
void initEPWM7(void)
{
//
// Set-up TBCLK
//
EPWM_setTimeBasePeriod(EPWM7_BASE, EPWM7_TIMER_TBPRD);
EPWM_disablePhaseShiftLoad(EPWM7_BASE);
EPWM_setPhaseShift(EPWM7_BASE, 0U);
EPWM_setTimeBaseCounter(EPWM7_BASE, 0U);
EPWM_setTimeBaseCounterMode(EPWM7_BASE, EPWM_COUNTER_MODE_UP);
EPWM_setClockPrescaler(EPWM7_BASE,
EPWM_CLOCK_DIVIDER_1,
EPWM_HSCLOCK_DIVIDER_8);
EPWM_selectPeriodLoadEvent(EPWM7_BASE, EPWM_SHADOW_LOAD_MODE_COUNTER_ZERO);
//
// Set up shadowing
//
EPWM_setCounterCompareShadowLoadMode(EPWM7_BASE,
EPWM_COUNTER_COMPARE_A,
EPWM_COMP_LOAD_ON_CNTR_ZERO);
EPWM_setCounterCompareShadowLoadMode(EPWM7_BASE,
EPWM_COUNTER_COMPARE_B,
EPWM_COMP_LOAD_ON_CNTR_ZERO);
//
// Set Compare values
//
EPWM_setCounterCompareValue(EPWM7_BASE,
EPWM_COUNTER_COMPARE_A,
EPWM7_CMPA);
EPWM_setCounterCompareValue(EPWM7_BASE,
EPWM_COUNTER_COMPARE_B,
EPWM7_CMPB);
//
// Set actions
//
EPWM_setActionQualifierAction(EPWM7_BASE,
EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_HIGH,
EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(EPWM7_BASE,
EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_LOW,
EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
//
// Interrupt where we will change the Compare Values
// Select INT on Time base counter zero event,
// Enable INT, generate INT on 1st event
//
EPWM_setInterruptSource(EPWM7_BASE, EPWM_INT_TBCTR_ZERO);
EPWM_enableInterrupt(EPWM7_BASE);
EPWM_setInterruptEventCount(EPWM7_BASE, 1U);
}
EDIT 3:
Also interesting to note is that the ADC interrupt is not triggered when the premature execution of the EPW2_ISR occurs?
