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.
Hello Experts ,
I have a implemented independant modulation on epwm8 (EPWM8A & EPWMB).
I have some confusion on the action qualifier settings and interrupt settings.
Here is the function:
void HAL_setupBrCpPWMs(HAL_MTR_Handle handle) { HAL_MTR_Obj *obj = (HAL_MTR_Obj*) handle; //obj->pwmHandle[3] contains the base address of ePWM8 EPWM_setClockPrescaler(obj->pwmHandle[3], EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_2); EPWM_setTimeBaseCounterMode(obj->pwmHandle[3], EPWM_COUNTER_MODE_UP); //Switching frequency 5Khz EPWM_setTimeBasePeriod(obj->pwmHandle[3], 10000U); EPWM_setPhaseShift(obj->pwmHandle[3], 0U); EPWM_setCounterCompareShadowLoadMode(obj->pwmHandle[3], EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO); EPWM_setCounterCompareShadowLoadMode(obj->pwmHandle[3], EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO); EPWM_setCounterCompareValue(obj->pwmHandle[3], EPWM_COUNTER_COMPARE_A, 0); EPWM_setCounterCompareValue(obj->pwmHandle[3], EPWM_COUNTER_COMPARE_B, 0); EPWM_setActionQualifierAction(obj->pwmHandle[3], EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO); EPWM_setActionQualifierAction(obj->pwmHandle[3], EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA); EPWM_setActionQualifierAction(obj->pwmHandle[3], EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO); EPWM_setActionQualifierAction(obj->pwmHandle[3], EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB); // configure sync EPWM_setSyncOutPulseMode(obj->pwmHandle[3], EPWM_SYNC_OUT_PULSE_ON_EPWMxSYNCIN); EPWM_setInterruptSource(obj->pwmHandle[3], EPWM_INT_TBCTR_ZERO); EPWM_enableInterrupt(obj->pwmHandle[3]); EPWM_setInterruptEventCount(obj->pwmHandle[3], 1); EPWM_disableInterrupt(obj->pwmHandle[3]); //Enabled in interrupt_enable() along with all other interrupts }
I was looking at the example in C2000Ware_4_01_00_00\device_support\f2837xd\examples\cpu1\epwm_up_aq
In InitEPwm1Example(), the interrupt, it says generate interrupt on the third event, does this mean that the interrupt will be generated after 3 pwm cycles?
Im ny initilialization function, i am trying to generate an interrupt on every pwm cycle.
1. Is it possible to have 2 interrupts separately and mapped to different functions? (__interrupt void epwm8A() & __interrupt void epwm8B()
2. I am trying to log the active pwm cycles, so that i know exactly how many cycles the PWM is active. I am currently doing somthing like this:
__interrupt void BrCP_ISR(void) { if(BrCpVars[0].dutyCycle > 0) { BrCpVars[0].BrCpActiveCycles++; } if(BrCpVars[1].dutyCycle > 0) { BrCpVars[1].BrCpActiveCycles++; } EPWM_clearEventTriggerInterruptFlag(EPWM8_BASE); Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3); }
But the above does not match with the real data(pwm pulses), which i am measuring on a scope, Pls Help!
Hi AK,
To start, I wanted to highlight some of our resources that have some helpful information on these topics.
I highly recommend you read through the EPWM developer's guide, which walks through a very clear and simple setting up of the EPWM using all of the various submodules. This includes the action qualifiers as well as interrupt generate via the event trigger submodule. It shows how you can easily configure this using the sysconfig GUI, but also does show the driverlib code as well.
Another resource is the EPWM video series. You can watch through all of them (they are pretty short videos) or also skip to the submodules you are having trouble with (such as the event trigger submodule or action qualifier submodule).
If these are not detailed enough, the TRM sections have quite detailed descriptions of applying these here are a few you may find helpful:
Let me know if any of these help clarify things! If not, feel free to comment back here and I'll be happy to assist further
Best Regards,
Allison
Hi Allison,
Thanks for the TRM document! I was referring that only and made a draft the PWM initialization function, I think i got the action qualifiers correctly setup, i am able to change the PWM duty cycles independently.
One thing that was mentioned in the TRM(Section 15.6.5):
It states that CMPA/CMPB must be loaded on TBPRD, Does this mean that ,we need to generate an interrupt which triggers on (TBCTR = TBPRD)?
and during this event, load the new values of in CMPA/CMPB?
Looking at the driverlib example (epwm_ex13_up_aq), initEPWM1():
The interrupt is generated on EPWM_INT_TBCTR_ZERO event(Time-base counter equal to zero)
Secondly , if we generate the interrupt when the Time-base counter is equal to zero, how do we know if this interrupt is generated by CMPA counter resetting to zero or the CMPB resetting to zero?, Is it a common interrupt?
Edit:
Another clarification in the c2000ware driverlib API for epwm:
Can we OR multiple interrupt sources like this:?
EPWM_setInterruptSource( obj->pwmHandle[3], (EPWM_INT_TBCTR_ZERO | EPWM_INT_TBCTR_U_CMPA | EPWM_INT_TBCTR_U_CMPB));
Could you please clarify on the above..
Thanks!
Hi AK, my responses are below in blue.
Thanks for the TRM document! I was referring that only and made a draft the PWM initialization function, I think i got the action qualifiers correctly setup, i am able to change the PWM duty cycles independently.
Glad to hear this!
One thing that was mentioned in the TRM(Section 15.6.5). It states that CMPA/CMPB must be loaded on TBPRD, Does this mean that ,we need to generate an interrupt which triggers on (TBCTR = TBPRD)? and during this event, load the new values of in CMPA/CMPB?
No, you do not necessarily need to generate an interrupt on TBPRD. The statement is that you must "load" CMPA/B on CTR=PRD. Shadow loading is usually done by the hardware. This means that you must configure your shadow load settings so that a shadow-to active load occurs on CTR=PRD events. These configurations are in the CMPCTL register - see the TRM register descriptions below. For example: for CMPA, you need to SHDWAMODE = 0 (enable shadow load mode) and LOADAMODE = 01 (load on CTR = PRD).
Looking at the driverlib example (epwm_ex13_up_aq), initEPWM1(), the interrupt is generated on EPWM_INT_TBCTR_ZERO event(Time-base counter equal to zero). Secondly , if we generate the interrupt when the Time-base counter is equal to zero, how do we know if this interrupt is generated by CMPA counter resetting to zero or the CMPB resetting to zero?, Is it a common interrupt?
I'm unsure of what you are asking here. If you have interrupt event generation settings as such:
Interrupt occurs on every CTR = 0 event.
Then you will have an interrupt occur whenever the counter is equal to 0. CMPA has nothing to do with this. When you change a CMPA value, it doesn't affect the incrementing/decrementing of the counter. All it does is change the value that the counter has to "match" with in order for some action to occur (e.g. if you specified the action qualifiers to set the PWM high/low on CMPA. In this case, it would change when your PWM output goes high/low).
There is no CMPA counter or CMPB "counter". CMPA and CMPB are just values stored by the PWM module that it compares to the actual EPWM counter (TBCTR). When the values match, a pulse is generated that can be used to cause other actions to occur as a result.
Edit:
Another clarification in the c2000ware driverlib API for epwm:
Can we OR multiple interrupt sources like this:
EPWM_setInterruptSource(
obj->pwmHandle[3],
(EPWM_INT_TBCTR_ZERO | EPWM_INT_TBCTR_U_CMPA | EPWM_INT_TBCTR_U_CMPB))
Could you please clarify on the above.
As the TRM states, "The event that can cause an interrupt is configured by the interrupt selection (ETSEL[INTSEL]) and (ETSEL[INTSELCMP]) bits." The options for these configurations are defined in the register descriptions as below. So you cannot select multiple of these values for the register at the same time.
Most all the information you need here is in TRM and other resources I listed. I would also recommend you leverage the sysconfig GUI if you are not already doing so. You can quite easily set up interrupts for PWM with it
Hope this helps!
Best Regards,
Allison