This question is regarding the trip zone function of the ePWM. I am trying to use one of the ePWMs to implement a double pulse pulse signal for driving a power FET test rig I've custom built. I already have working code based on the configure signal example to modulate the duty cycle to generate pulses of different widths. The trip zone oneshot is to force the ePWM low for a number of cycles to create isolated double pulse waveforms.
A minimal example of what I am trying to achieve is below. The working code not relevant to this question is show as pseudocode in comments.
#include "driverlib.h" #include "device.h" #include "board.h" uint32_t epwm1IntCount; uint32_t epwmHaltCycles; epwmHaltCycles = 80000U; // number doesn't matter much here - read as some number of cycles EPWM_SignalParams pwmSignal1 = {10000, 0.5f, 0.5f, true, DEVICE_SYSCLK_FREQ, SYSCTL_EPWMCLK_DIV_2, EPWM_COUNTER_MODE_UP_DOWN, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1}; EPWM_SignalParams pwmSignal2 = {10000, 0.25f, 0.5f, true, DEVICE_SYSCLK_FREQ, SYSCTL_EPWMCLK_DIV_2, EPWM_COUNTER_MODE_UP_DOWN, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1}; __interrupt void modDutyCycle(void); __interrupt void TZ_PWM(void); void main(void) { epwm1IntCount = 0U; Device_init(); Device_initGPIO(); GPIO_togglePin(myGPIO11); // GPIO used to trip TZ GPIO starts high Interrupt_initModule(); Interrupt_initVectorTable(); Board_init(); SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC); EPWM_configureSignal(myEPWM1_BASE, &pwmSignal1); // Output wave EPWM_setSyncOutPulseMode(myEPWM1_BASE, EPWM_SYNC_OUT_PULSE_ON_COUNTER_ZERO); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC); asm(" RPT #5 || NOP"); /* Interrupt logic for duty cycle modulation - uses ePWM interrupts - not relevant to this question */ EPWM_setInterruptEventCount(myEPWM1_BASE, 1U); Interrupt_register(INT_EPWM1, &modDutyCycle); // Trip zone interrupt setup EPWM_disableTripZoneAdvAction(myEPWM1_BASE); EPWM_enableTripZoneSignals(myEPWM1_BASE, EPWM_TZ_SIGNAL_OSHT1); EPWM_setTripZoneAction(myEPWM1_BASE, EPWM_TZ_ACTION_EVENT_TZA, EPWM_TZ_ACTION_DISABLE); EPWM_enableTripZoneInterrupt(myEPWM1_BASE, EPWM_TZ_INTERRUPT_OST); Interrupt_enable(INT_EPWM1_TZ); Interrupt_register(INT_EPWM1_TZ, &pulsePWM); // Enable global Interrupts and higher priority real-time debug events: // EINT; // Enable Global interrupt INTM ERTM; // Enable Global realtime interrupt DBGM for(;;) { asm ("NOP"); } } __interrupt void modDutyCycle(void) { // modify duty cycle logic and branching - independent of what I'm asking GPIO_togglePin(myGPIO11); // trip TZ pin } __interrupt void TZ_PWM(void) { if (epwmHaltCycles > epwmHaltCycles) { epwmHaltCycles = 0U; GPIO_togglePin(myGPIO11); EPWM_clearOneShotTripZoneFlag(myEPWM1_BASE, EPWM_TZ_OST_FLAG_OST1); EPWM_clearTripZoneFlag(myEPWM1_BASE, (EPWM_TZ_INTERRUPT | EPWM_TZ_FLAG_CBC)); EPWM_clearTripZoneFlag(myEPWM1_BASE, (EPWM_TZ_INTERRUPT | EPWM_TZ_FLAG_OST)); Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP2); } else { epwmHaltCycles++; // increment cycles counter Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP2); // acknowledge interrupt to continue } }
I have based most of this on the trip zone example in ex1 and verified that I have properly multiplexed the pins on the MCU.
The behavior I get from this is not as I expect. As a test case, if I leave the TZ GPIO floating (it is configured as a pull up input) the EPWM shuts down and the logic in my TZ interrupt routine is not run (the breakpoints are not hit in debug mode). It is clear however that the EPWM is responding to something however, because if I run this logic with EPWM_TZ_ACTION_DISABLE instead of EPWM_TZ_ACTION_LOW this executes as if there is no oneshot TZ interrupt enabled. Is there something I am overlooking here? I'm looking for some pointers in the right direction for troubleshooting this.
James