I am using Delfino F28335 HRPWM peripherals with one-sided modulation. For my application I need to change the PWM carrier. i.e. the value in the TBPRD register from approximately 150 kHz to 300 kHz depending on the external control messages. I have a problem with this change that once in a few cases one of the PWM-s stops working. I use three HRPWM-s and typically tow of them work properly after the change and one of them once in 4-5 times stops modulating. It happens irregularly, seems to depend on the current duty cycle value. It also seems this problem might be related to the fact that the problematic PWM has more high-frequency content than the other two and in result faster changing duty cycle value. The duty cycle is loaded by an interrupt procedure based on the synchronically filled array of integers updated by McBSP using DMA.
The code snippets – the interrupt setup section, ISR_Run is an assembler routine that calculates and feeds ePWM and HRPWM duty cycle/edge position:
EALLOW;
PieVectTable.EPWM1_INT = &ISR_Run; // Map Interrupt
EDIS;
PieCtrlRegs.PIEIER3.bit.INTx1 = 1; // PIE level enable, Grp3 / Int1
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTRU_CMPB; // INT on CMPB event
EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on every event
// Enable Peripheral, global Ints and higher priority real-time debug events:
IER |= M_INT3; // Enable CPU INT3 connected to EPWM1-6 INTs:
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
The change of the PWM carrier value is currently just simple assignments:
(*ePWM[1]).TBPRD = (prd);
(*ePWM[2]).TBPRD = (prd);
(*ePWM[3]).TBPRD = (prd);
(*ePWM[4]).TBPRD = (prd);
(*ePWM[5]).TBPRD = (prd);
(*ePWM[6]).TBPRD = (prd);
What shall I try in order to get rid of this problem ? Maybe some PWM register reconfiguration before the duty cycle change or PWM interrupts should be performed ? I have made some different workarounds but for now with no success.
Pawel