Hello,
I am using the TMS320F28335 DSP to control the phaseshift between two PWM modules (i.e. ePWM1A and ePWM5A). To my understanding according to the datasheet (page 28), I set up my PWM modules such that all PWM modules are synchronized to the ePWM1 module.
What I noted is, that an increasing value in the phaseshift register moves the waveform of the PWM module. However, the direction the waveform is moved is opposite to what I actually want :D
In particular, increasing the phaseshift for ePWM5A yields a move in the waveform to the left with respect to ePWM1A. In other words, an increasing value in the TBPHS register leads to a waveforms shifted to the left with respect to the fixed ePWM1A channel. Below you'll find my code and I did some screenshots of the waveforms for two different phaseshift values to clarify my concern. I would like to achieve the opposite behavior, i.e. an increased value in the TBPHS register moves the waveform to right with respect to ePWM1A.
Do you maybe see where my misunderstanding / wrong C implementation is? Thank you for your help.
#include "DSP28x_Project.h"
#include "DCL.h"
void InitialADC();
void InitePWM1();
void InitePWM2();
void InitePWM5();
void InitePWM6();
__interrupt void ADC_isr();
__interrupt void TZ_isr();
// Flash functionality
extern Uint16 RamfuncsLoadStart;
extern Uint16 RamfuncsLoadEnd;
extern Uint16 RamfuncsRunStart;
Uint16 phaseshift;
Uint16 phaseshift1;
volatile int32 dummy;
volatile Uint16 ConversionCount;
volatile float32 Voltage1[256];
volatile float32 Current[256];
void main(void) {
// Initialize PLL, Watchdog, enable peripheral clocks
InitSysCtrl();
// Used to program to flash
MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
// Initialize ePWM and TZ
InitEPwmGpio();
InitTzGpio();
// Initialize PIE control registers
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
// Initialize PIE vector table to default ISR
InitPieVectTable();
// Remap the ISR function to the PIE vector table
EALLOW;
PieVectTable.ADCINT = &ADC_isr;
PieVectTable.EPWM1_TZINT = &TZ_isr;
EDIS;
// First step of setting up the ADC sampling rate
EALLOW;
SysCtrlRegs.HISPCP.all = 3; // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3) = 25.0 MHz
EDIS;
// Synchronization already done in the InitSysCtrl() function --> Ask the TI support to verify
/*
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Enable time base clock synchronization with SYSCLKOUT from DSP
EDIS;
*/
InitFlash();
dummy = 0;
// Initialize the ADC
InitAdc();
phaseshift1 = 4; // Compensating a ca. 15ns delay between ePWM1 and ePWM6
InitialADC(); // Set up the ADC for voltage and current measurement
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
EDIS;
InitePWM1();
InitePWM2();
InitePWM5();
InitePWM6();
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;
/*
* Set GPIO4 as output to measure execution time within ISR
*/
EALLOW;
// Set GPIO10 as a GPIO - already done in InitGpio()
GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 0;
// Set GPIO10 as an output
GpioCtrlRegs.GPADIR.bit.GPIO4 = 1;
EDIS;
PieCtrlRegs.PIEIER1.bit.INTx6 = 1; // Group 1, bit 6 for ADC
PieCtrlRegs.PIEIER2.bit.INTx1 = 1; // Group 2, bit 1 for ePWM1_TZ
IER |= M_INT1; // Sets the interrupt enable bit of group 1
IER |= M_INT2; // Sets the interrupt enable bit of group 3
EINT; // Enable global interrupts INTM
for(;;)
{
}
}
__interrupt void ADC_isr(void)
{
Voltage1[ConversionCount] = AdcRegs.ADCRESULT0 >>4; // Read value from ADCINA5
Current[ConversionCount] = AdcRegs.ADCRESULT1 >>4; // Read value from ADCINB5
EPwm5Regs.TBPHS.half.TBPHS = dummy; // ePWM5 and ePWM6 will have phaseshift
EPwm6Regs.TBPHS.half.TBPHS = phaseshift1; // Compensate ca. 16ns delay of ePWM6
// If 256 conversions have been logged, start over
if(ConversionCount == 255)
{
ConversionCount = 0;
}
else
{
ConversionCount++;
}
// Re-initialize for next ADC
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clears the interrupt flag bit
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE
}
void InitialADC(void)
{
// Configure ADC
AdcRegs.ADCTRL3.bit.ADCCLKPS = 1; // Set the ADC sampling rate: 25MHz/(2*1+1) = 8.3MHz
AdcRegs.ADCTRL1.bit.ACQ_PS = 0; //
AdcRegs.ADCTRL1.bit.SEQ_CASC = 0; // Cascaded mode
AdcRegs.ADCTRL1.bit.CONT_RUN = 0; // Start-stop mode
AdcRegs.ADCTRL3.bit.SMODE_SEL = 1; // Simultaneous sampling mode
AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1; // ePWM starts SOCA trigger
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0; // One conversion
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 5; // ADCINA5 and ADCINB5
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Interrupt request enabled
}
void InitePWM1(void)
{
// Enable SOCA for ADC measurements
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOCA
EPwm1Regs.ETSEL.bit.SOCASEL = 4; // Generate SOCA pulse at 50% duty cycle
EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event
EPwm1Regs.TBPRD = 1499; // Set the PWM period time
EPwm1Regs.CMPA.half.CMPA = (1499+1)/2;
EPwm1Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Up count mode
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Slave module
EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // Sync down-stream module
EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0; // Set time base clock to SYSCLKOUT
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = 0; // Loads on either CTR=0 or CTR=PRD
EPwm1Regs.CMPCTL.bit.LOADBMODE = 0; // Loads on either CTR=0 or CTR=PRD
EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // Sets pin when CTR=PRD
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Clears pin when CTR=COMPA
EPwm1Regs.DBCTL.bit.IN_MODE = 0; // ePWMxA source for falling and rising edge
EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // DB full enable
EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active high complementary
EPwm1Regs.DBRED = DT;
EPwm1Regs.DBFED = DT;
}
void InitePWM2(void)
{
EPwm2Regs.TBPRD = 1499; // Set the PWM period time
EPwm2Regs.CMPA.half.CMPA = (1499+1)/2;
EPwm2Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Up count mode
EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Slave module
EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // Sync down-stream module
EPwm2Regs.TBCTL.bit.HSPCLKDIV = 0; // Set time base clock to SYSCLKOUT
EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm2Regs.CMPCTL.bit.LOADAMODE = 0; // Loads on either CTR=0 or CTR=PRD
EPwm2Regs.CMPCTL.bit.LOADBMODE = 0; // Loads on either CTR=0 or CTR=PRD
EPwm2Regs.AQCTLA.bit.ZRO = AQ_CLEAR; // Clears pin when CTR=PRD
EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; // Sets pin when CTR=COMPA
EALLOW;
EPwm2Regs.TZSEL.bit.OSHT3 = 1; // Enable TZ3
EPwm2Regs.TZCTL.bit.TZA = 2; // Clear ePWM2A on TZ event
EPwm2Regs.TZCTL.bit.TZB = 2; // Clear ePWM2B on TZ event
EDIS;
EPwm2Regs.DBCTL.bit.IN_MODE = 0; // ePWMxA source for falling and rising edge
EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // DB full enable
EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active high complementary
EPwm2Regs.DBRED = DT;
EPwm2Regs.DBFED = DT;
}
void InitePWM5(void)
{
EPwm5Regs.TBPRD = 1499; // Set the PWM period time
EPwm5Regs.CMPA.half.CMPA = (1499+1)/2;
EPwm5Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero
EPwm5Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Up count mode
EPwm5Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Master module
EPwm5Regs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwm5Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // Sync down-stream module
EPwm5Regs.TBCTL.bit.HSPCLKDIV = 0; // Set time base clock to SYSCLKOUT
EPwm5Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm5Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm5Regs.CMPCTL.bit.LOADAMODE = 0; // Loads on either CTR=0 or CTR=PRD
EPwm5Regs.CMPCTL.bit.LOADBMODE = 0; // Loads on either CTR=0 or CTR=PRD
EPwm5Regs.AQCTLA.bit.ZRO = AQ_SET; // Sets pin when CTR=PRD
EPwm5Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Clears pin when CTR=COMPA
EALLOW;
EPwm5Regs.TZSEL.bit.OSHT3 = 1; // Enable TZ3
EPwm5Regs.TZCTL.bit.TZA = 2; // Clear ePWM5A on TZ event
EPwm5Regs.TZCTL.bit.TZB = 2; // Clear ePWM5B on TZ event
EDIS;
EPwm5Regs.DBCTL.bit.IN_MODE = 0; // ePWMxA source for falling and rising edge
EPwm5Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // DB full enable
EPwm5Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active high complementary
EPwm5Regs.DBRED = DT;
EPwm5Regs.DBFED = DT;
}
void InitePWM6(void)
{
EPwm6Regs.TBPRD = 1499; // Set the PWM period time
EPwm6Regs.CMPA.half.CMPA = (1499+1)/2;
EPwm6Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero
EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Up count mode
EPwm6Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Slave module
EPwm6Regs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // Sync down-stream module
EPwm6Regs.TBCTL.bit.HSPCLKDIV = 0; // Set time base clock to SYSCLKOUT
EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm6Regs.CMPCTL.bit.LOADAMODE = 0; // Loads on either CTR=0 or CTR=PRD
EPwm6Regs.CMPCTL.bit.LOADBMODE = 0; // Loads on either CTR=0 or CTR=PRD
EPwm6Regs.AQCTLA.bit.ZRO = AQ_CLEAR; // Clears pin when CTR=PRD
EPwm6Regs.AQCTLA.bit.CAU = AQ_SET; // Sets pin when CTR=COMPA
EALLOW;
EPwm6Regs.TZSEL.bit.OSHT3 = 1; // Enable TZ3
EPwm6Regs.TZCTL.bit.TZA = 2; // Clear ePWM6A on TZ event
EPwm6Regs.TZCTL.bit.TZB = 2; // Clear ePWM6B on TZ event
EDIS;
EPwm6Regs.DBCTL.bit.IN_MODE = 0; // ePWMxA source for falling and rising edge
EPwm6Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // DB full enable
EPwm6Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active low complementary
EPwm6Regs.DBRED = DT;
EPwm6Regs.DBFED = DT;
}



