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.
I'm sending a periodic pulse to ecap1 from a function generator and trying to get the ecap to fetch the period.
What I want to do eventually is to have epwm1 to generate PWM with the same period fetched from ecap1.
I'm having trouble getting the pwm channel to generate a pulse with the same period as what the ecap reads.
Here is what I have so far. Please tell me what's wrong. It will be much appreciated.
#include "DSP28x_Project.h" // Device Headerfile and Examples Include File
// Prototype statements for functions found within this file.
interrupt void ecap1_isr(void);
void InitECapture(void);
void InitEPwmTimer(void);
void Fail(void);
// Global variables used in this example
Uint32 ECap1IntCount;
Uint32 ECap1PassCount;
Uint32 EPwm1TimerDirection;
Uint32 EPwm1TimerIntCount;
Uint32 DutyOnTime1;
Uint32 DutyOffTime1;
Uint32 DutyOnTime2;
Uint32 DutyOffTime2;
void main(void)
{
InitSysCtrl();
InitEPwm1Gpio();
InitECap1Gpio();
DINT;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
EALLOW;
PieVectTable.ECAP1_INT = &ecap1_isr;
EDIS;
InitEPwmTimer();
InitECapture();
// Initalize counters:
EPwm1TimerIntCount = 0;
ECap1IntCount = 0;
ECap1PassCount = 0;
DutyOnTime1 = 0;
DutyOffTime1 = 0;
DutyOnTime2 = 0;
DutyOffTime2 = 0;
// Enable CPU INT4 which is connected to ECAP1-4 INT:
IER |= M_INT4;
// Enable eCAP INTn in the PIE: Group 3 interrupt 1-6
PieCtrlRegs.PIEIER4.bit.INTx1 = 1;
// Enable global Interrupts and higher priority real-time debug events:
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
// Step 6. IDLE loop. Just sit and loop forever (optional):
for(;;)
{
asm(" NOP");
}
}
void InitECapture()
{
ECap1Regs.ECEINT.all = 0x0000; // Disable all capture interrupts
ECap1Regs.ECCLR.all = 0xFFFF; // Clear all CAP interrupt flags
ECap1Regs.ECCTL1.bit.CAPLDEN = 0; // Disable CAP1-CAP4 register loads
ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0; // Make sure the counter is stopped
// Configure peripheral registers
ECap1Regs.ECCTL2.bit.CONT_ONESHT = 1; // One-shot
ECap1Regs.ECCTL2.bit.STOP_WRAP = 3; // Stop at 4 events
ECap1Regs.ECCTL1.bit.CAP1POL = 0; // Rising edge
ECap1Regs.ECCTL1.bit.CAP2POL = 1; // Falling edge
ECap1Regs.ECCTL1.bit.CAP3POL = 0; // Rising edge
ECap1Regs.ECCTL1.bit.CAP4POL = 1; // Falling edge
ECap1Regs.ECCTL1.bit.CTRRST1 = 1; // Difference operation
ECap1Regs.ECCTL1.bit.CTRRST2 = 1; // Difference operation
ECap1Regs.ECCTL1.bit.CTRRST3 = 1; // Difference operation
ECap1Regs.ECCTL1.bit.CTRRST4 = 1; // Difference operation
ECap1Regs.ECCTL2.bit.SYNCI_EN = 1; // Enable sync in
ECap1Regs.ECCTL2.bit.SYNCO_SEL = 0; // Pass through
ECap1Regs.ECCTL1.bit.CAPLDEN = 1; // Enable capture units
ECap1Regs.ECCTL2.bit.CAP_APWM = 0;
ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1; // Start Counter
ECap1Regs.ECCTL2.bit.REARM = 1; // arm one-shot
ECap1Regs.ECCTL1.bit.CAPLDEN = 1; // Enable CAP1-CAP4 register loads
ECap1Regs.ECEINT.bit.CEVT2 = 1; // 2 events = interrupt
}
void InitEPwmTimer()
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
EDIS;
EPwm1Regs.TBPRD = 6000; // Set timer period
EPwm1Regs.TBPHS.half.TBPHS = 0x0000; // Phase is 0
EPwm1Regs.TBCTR = 0x0000; // Clear counter
// Setup TBCLK
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// Setup compare
EPwm1Regs.CMPA.half.CMPA = 3000;
// Set actions
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM1A on Zero
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR; // Set PWM1A on Zero
EPwm1Regs.AQCTLB.bit.CAD = AQ_SET;
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;
}
interrupt void ecap1_isr(void)
{
// Cap input is syc'ed to SYSCLKOUT so there may be
// a +/- 1 cycle variation
// Note: here Time-stamp directly represents the Duty cycle values.
DutyOnTime1 = ECap1Regs.CAP1; // Fetch Time-Stamp captured at T2
DutyOffTime1 = ECap1Regs.CAP2; // Fetch Time-Stamp captured at T3
DutyOnTime2 = ECap1Regs.CAP3; // Fetch Time-Stamp captured at T2
DutyOffTime2 = ECap1Regs.CAP4; // Fetch Time-Stamp captured at T3
if (ECap1Regs.CAP1+ECap1Regs.CAP2 < 6000)
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
EDIS;
EPwm1Regs.TBPRD = DutyOnTime1+DutyOffTime1;
EPwm1Regs.TBPHS.half.TBPHS = 0x0000; // Phase is 0
EPwm1Regs.TBCTR = 0x0000; // Clear counter
// Setup TBCLK
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// Setup compare
EPwm1Regs.CMPA.half.CMPA = (DutyOnTime1+DutyOffTime1)/2;
// Set actions
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM1A on Zero
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR; // Set PWM1A on Zero
EPwm1Regs.AQCTLB.bit.CAD = AQ_SET;
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;
}
else if(DutyOnTime1+DutyOffTime1 == 0)
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
EDIS;
EPwm1Regs.TBPRD = 6000;
EPwm1Regs.TBPHS.half.TBPHS = 0x0000; // Phase is 0
EPwm1Regs.TBCTR = 0x0000; // Clear counter
// Setup TBCLK
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// Setup compare
EPwm1Regs.CMPA.half.CMPA = 3000;
// Set actions
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM1A on Zero
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR; // Set PWM1A on Zero
EPwm1Regs.AQCTLB.bit.CAD = AQ_SET;
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;
}
ECap1PassCount++;
ECap1Regs.ECCLR.bit.CEVT2 = 1;
ECap1Regs.ECCLR.bit.INT = 1;
ECap1Regs.ECCTL2.bit.REARM = 1;
// Acknowledge this interrupt to receive more interrupts from group 4
PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;
}