Hi,
I was talking to Nima Eskandari but the thread is closed, so I try making this related question, instead.
Hi Nima, here I am, bothering you again... I hope, we can reopen the thread!
To continue with the interrupts question, "TMS320F28379D: ePWM interrupts on TBCTR = CMPA and also on TBCTR = CMPB",
I have made my tests and your idea works good, but I found out that I can also use Period on ePWMxA and CMPB on the ePWMxB to generate the interrupts I need. It seems to be more simple...
However, the timing does not work as I expected:
Interrupts A and B on ePWM2 are supposed to activate an interrupt on ePWM1, which clears GPIO56 pin to low, just after the A-pin of the ePWM1 goes high.
Ideally, this should happen after around 5 uS, but this is not so crucial, as long as this remains allways the same.
The interrupts are working, but the timing not.
GPIO56 goes low at any moment, but not on the moment I want.
My logic analyzer shows, also, that the interrupts of ePWM2 are comming some (randomly) 4 till 7 uS before the changing to Low or High happens on the ePWM2-output A,
while I am expecting it just on this time or slightly after, but not before.
So, I have two questions:
1 - Why does the interrupt comes so far before the time it should come?
This is, so far, not so disturbing for my application, but:
2 - Why is Pin56 going low randomly in time?
I know, there is a propagation delay of around 14 SYSCLK till the ISR is called, but this does not explain this behaviour.
Te relevant parts of the code are included.
I wish you a nice weekend, or, better, a nice week!
Gustavo
myPeriod = 730; // Freq = 67,8 kHz, Period 14,75 uS
myDutyA = 718; // duty is 98,31%
myDutyB = 50;
myDutyFineA = 1;
myDutyFineB = 1;
myPeriodGrand = 786;
myDutyGrand = 451;
//
// epwm1_isr
//
__interrupt void epwm1_isr(void)
{
EPwm1Regs.ETSEL.bit.INTEN = 0; // Disable ePWM1 INT, until epwm2_isr enables it again
GpioDataRegs.GPBCLEAR.bit.GPIO61 = 1; // This should allways happen at the same place, ideally 6uS after ePWM1 goes High (which, in turn, remains High during 14,38 uS)
DELAY_US(100); // this is only for clarity. Here is some code
GpioDataRegs.GPBSET.bit.GPIO61 = 1; // set GPIO61 high
if(modo == 0b110)
{
modo = 0b010; // 100: time-base counter equal to CMPA when the timer is incrementing
DELAY_US(5); // Here is some code
}
else
{
modo = 0b110; // 110: time-base counter equal to CMPB when the timer is incrementing
DELAY_US(5); // Here is some code
}
EPwm2Regs.ETSEL.bit.INTSEL = modo;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; // Acknowledge this interrupt to receive more interrupts from group 3
}
//
// epwm2_isr
__interrupt void epwm2_isr(void)
{
EPwm1Regs.ETCLR.bit.INT = 1; // Clear INT flag for ePWM1 timer
EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT on ePWM1
EPwm2Regs.ETCLR.bit.INT = 1; // Clear INT flag for this timer
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; // Acknowledge this interrupt to receive more interrupts from group 3
}
void HRPWM1_Config(myPeriod)
{
EPwm1Regs.TBCTL.bit.PRDLD = TB_IMMEDIATE; // set Immediate load
EPwm1Regs.TBPRD = myPeriod; // PWM frequency
EPwm1Regs.CMPA.bit.CMPA = myDutyA; // set duty for ePWM1A
EPwm1Regs.CMPA.bit.CMPAHR = (myDutyFineA << 8); // set duty fine for ePWM1A
EPwm1Regs.CMPB.bit.CMPB = myDutyB; // set duty for ePWM1B - for the interrupt
EPwm1Regs.CMPB.all |= (myDutyFineB << 8); // set HR-duty for ePWM1B - for the interrupt
EPwm1Regs.TBPHS.all = 0;
EPwm1Regs.TBCTR = 0;
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;
EPwm1Regs.AQCTLB.bit.ZRO = AQ_SET;
EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR;
// INT on CMPB
EPwm1Regs.ETSEL.bit.INTEN = 0; // Disable INT - It will be enabled in epwm2_isr
EPwm1Regs.ETPS.bit.INTPSSEL = 0x0;
EPwm1Regs.ETPS.bit.INTPRD = 0x2; // Generate an interrupt on the second event
EPwm1Regs.ETSEL.bit.INTSELCMP = 0x0; // 0: time-base counter equal to CMPB when the timer is incrementing
EPwm1Regs.ETSEL.bit.INTSEL = 0x6; // 110: time-base counter equal to CMPB.
EALLOW;
EPwm1Regs.HRCNFG.all = 0x0;
EPwm1Regs.HRCNFG.bit.EDGMODE = HR_FEP;
EPwm1Regs.HRCNFG.bit.CTLMODE = HR_CMP;
EPwm1Regs.HRCNFG.bit.HRLOAD = HR_CTR_ZERO;
EPwm1Regs.HRCNFG.bit.EDGMODEB = HR_FEP;
EPwm1Regs.HRCNFG.bit.CTLMODEB = HR_CMP;
EPwm1Regs.HRCNFG.bit.HRLOADB = HR_CTR_ZERO;
EDIS;
}
//
// HRPWM2_Config
//
void HRPWM2_Config(period) // low freq.
{
EPwm2Regs.TBCTL.bit.PRDLD = TB_IMMEDIATE; // set Immediate load
EPwm2Regs.TBPRD = myPeriodGrand; // PWM frequency
EPwm2Regs.CMPB.bit.CMPB = myDutyGrand; // set duty
EPwm2Regs.CMPA.bit.CMPA = myDutyGrand; // set duty ????
EPwm2Regs.TBPHS.all = 0;
EPwm2Regs.TBCTR = 0;
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Start ePWM in COUNT_UP mode
EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;
EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
EPwm2Regs.TBCTL.bit.HSPCLKDIV = 0b100; // to have a very low freq
EPwm2Regs.TBCTL.bit.CLKDIV = 0x4; // Time Base Clock Pre-Scale
EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET;
EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;
EPwm2Regs.AQCTLB.bit.ZRO = AQ_SET;
EPwm2Regs.AQCTLB.bit.CBU = AQ_CLEAR;
// need INT on CMPB and on Period:
EPwm2Regs.ETPS.bit.INTPSSEL = 0x0;
EPwm2Regs.ETPS.bit.INTPRD = 0x1; // 01: Generate an interrupt on the first event INTCNT = 01 (first event)
EPwm2Regs.ETSEL.bit.INTSELCMP = 0x0; // time-base counter equal to CMPA or CMPB when the timer is incrementing to INTSEL selection mux.
EPwm2Regs.ETSEL.bit.INTSEL = modo; // start with 110: time-base counter equal to CMPB. In the epwm1_isr swap ot between 010 (for Period) and 110 (for CMPB)
// I do not use HRPWM here. I guess I do not need this?
// EALLOW;
// EPwm2Regs.HRCNFG.all = 0x0;
// EPwm2Regs.HRCNFG.bit.EDGMODE = HR_FEP;
// EPwm2Regs.HRCNFG.bit.CTLMODE = HR_CMP;
// EPwm2Regs.HRCNFG.bit.HRLOAD = HR_CTR_ZERO;
// EPwm2Regs.HRCNFG.bit.EDGMODEB = HR_FEP;
// EPwm2Regs.HRCNFG.bit.CTLMODEB = HR_CMP;
// EPwm2Regs.HRCNFG.bit.HRLOADB = HR_CTR_ZERO;
// EDIS;
}





