Other Parts Discussed in Thread: CONTROLSUITE, C2000WARE
Tool/software: Code Composer Studio
I am currently trying to implement HRPWM on EPwm1 through EPwm3. However, I am not able to actually get high-resolution duty cycle control. The code compiles fine, but something isn't quite right.
Here is my PWM initialization code:
HRPWM initialization code was duplicated from processors.wiki.ti.com/.../C2000_HRPWM_High_Resolution_Period_and_Duty
/* Setup Sync*/ \
EPwm1Regs.TBCTL.bit.SYNCOSEL = 0; /* Pass through*/ \
EPwm2Regs.TBCTL.bit.SYNCOSEL = 0; /* Pass through*/ \
EPwm3Regs.TBCTL.bit.SYNCOSEL = 0; /* Pass through*/ \
\
\
/* Allow each timer to be sync'ed*/ \
EPwm1Regs.TBCTL.bit.PHSEN = 1; \
EPwm2Regs.TBCTL.bit.PHSEN = 1; \
EPwm3Regs.TBCTL.bit.PHSEN = 1; \
\
/* Init Timer-Base Period Register for EPWM1-EPWM3*/ \
EPwm1Regs.TBPRD = v.PeriodMax; \
EPwm2Regs.TBPRD = v.PeriodMax; \
EPwm3Regs.TBPRD = v.PeriodMax; \
\
/* Init Timer-Base Phase Register for EPWM1-EPWM3*/ \
EPwm1Regs.TBPHS.half.TBPHS = 0; \
EPwm2Regs.TBPHS.half.TBPHS = 0; \
EPwm3Regs.TBPHS.half.TBPHS = 0; \
\
/* Init Timer-Base Control Register for EPWM1-EPWM3*/ \
EPwm1Regs.TBCTL.all = PWM_INIT_STATE; \
EPwm2Regs.TBCTL.all = PWM_INIT_STATE; \
EPwm3Regs.TBCTL.all = PWM_INIT_STATE; \
\
/* Init Compare Control Register for EPWM1-EPWM3*/ \
EPwm1Regs.CMPCTL.all = CMPCTL_INIT_STATE; \
EPwm2Regs.CMPCTL.all = CMPCTL_INIT_STATE; \
EPwm3Regs.CMPCTL.all = CMPCTL_INIT_STATE; \
\
/* Init Action Qualifier Output A Register for EPWM1-EPWM3*/ \
EPwm1Regs.AQCTLA.all = AQCTLA_INIT_STATE; \
EPwm2Regs.AQCTLA.all = AQCTLA_INIT_STATE; \
EPwm3Regs.AQCTLA.all = AQCTLA_INIT_STATE; \
\
/* Init Dead-Band Generator Control Register for EPWM1-EPWM3*/ \
EPwm1Regs.DBCTL.all = DBCTL_INIT_STATE; \
EPwm2Regs.DBCTL.all = DBCTL_INIT_STATE; \
EPwm3Regs.DBCTL.all = DBCTL_INIT_STATE; \
\
/* Init Dead-Band Generator for EPWM1-EPWM3*/ \
EPwm1Regs.DBFED = DBCNT_INIT_STATE; \
EPwm1Regs.DBRED = DBCNT_INIT_STATE; \
EPwm2Regs.DBFED = DBCNT_INIT_STATE; \
EPwm2Regs.DBRED = DBCNT_INIT_STATE; \
EPwm3Regs.DBFED = DBCNT_INIT_STATE; \
EPwm3Regs.DBRED = DBCNT_INIT_STATE; \
\
/* Init PWM Chopper Control Register for EPWM1-EPWM3*/ \
EPwm1Regs.PCCTL.all = PCCTL_INIT_STATE; \
EPwm2Regs.PCCTL.all = PCCTL_INIT_STATE; \
EPwm3Regs.PCCTL.all = PCCTL_INIT_STATE; \
\
EALLOW; /* Enable EALLOW */ \
\
/* Init Trip Zone Select Register*/ \
EPwm1Regs.TZSEL.all = TZSEL_INIT_STATE; \
EPwm2Regs.TZSEL.all = TZSEL_INIT_STATE; \
EPwm3Regs.TZSEL.all = TZSEL_INIT_STATE; \
\
/* Init Trip Zone Control Register*/ \
EPwm1Regs.TZCTL.all = TZCTL_INIT_STATE; \
EPwm2Regs.TZCTL.all = TZCTL_INIT_STATE; \
EPwm3Regs.TZCTL.all = TZCTL_INIT_STATE; \
\
EDIS; /* Disable EALLOW*/
int16 MPeriod;
int32 Tmp;
// Now configure the HRPWM resources
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
EDIS;
//Write To CMP, TBPRD, TBPHS registers.
EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW; // set Shadow load
EPwm1Regs.TBPRD = pwm1.PeriodMax; // PWM frequency = 1/(2*TBPRD)
EPwm1Regs.CMPA.half.CMPA = pwm1.PeriodMax / 2; // set duty 50% initially
EPwm1Regs.CMPA.half.CMPAHR = (0 << 8); // initialize HRPWM extension
EPwm1Regs.TBPHS.all = 0;
//Configure modes, clock dividers and action qualifier
EPwm1Regs.TBCTR = 0;
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Select up-down count mode
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT
EPwm1Regs.TBCTL.bit.FREE_SOFT = 00;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // LOAD CMPA on CTR = 0
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm1Regs.AQCTLB.bit.ZRO = AQ_SET;
EPwm1Regs.AQCTLB.bit.PRD = AQ_CLEAR;
EALLOW;
//Configure HRPWM registers
EPwm1Regs.HRCNFG.all = 0x0;
EPwm1Regs.HRCNFG.bit.EDGMODE = HR_BEP; // MEP control on both edges
EPwm1Regs.HRCNFG.bit.CTLMODE = HR_CMP; // CMPAHR and TBPRDHR HR control
EPwm1Regs.HRCNFG.bit.HRLOAD = HR_CTR_ZERO_PRD; // load on CTR = 0 and CTR = TBPRD
EPwm1Regs.HRCNFG.bit.AUTOCONV = 1; // Enable autoconversion
EPwm1Regs.HRPCTL.bit.HRPE = 1; // Turn on high-resolution period control
//set TBCTL[PHSEN] = 1
EPwm1Regs.TBCTL.bit.PHSEN = 1;
//set HRPCTL[TBPHSHRLOADE] = 1
EPwm1Regs.HRPCTL.bit.TBPHSHRLOADE = 1;
EDIS;
//Write To CMP, TBPRD, TBPHS registers.
EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW; // set Shadow load
EPwm2Regs.TBPRD = pwm1.PeriodMax; // PWM frequency = 1/(2*TBPRD)
EPwm2Regs.CMPA.half.CMPA = pwm1.PeriodMax / 2; // set duty 50% initially
EPwm2Regs.CMPA.half.CMPAHR = (0 << 8); // initialize HRPWM extension
EPwm2Regs.TBPHS.all = 0;
//Configure modes, clock dividers and action qualifier
EPwm2Regs.TBCTR = 0;
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Select up-down count mode
EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT
EPwm2Regs.TBCTL.bit.FREE_SOFT = 00;
EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // LOAD CMPA on CTR = 0
EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm2Regs.AQCTLA.bit.CAU = AQ_SET;
EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm2Regs.AQCTLB.bit.ZRO = AQ_SET;
EPwm2Regs.AQCTLB.bit.PRD = AQ_CLEAR;
EALLOW;
//Configure HRPWM registers
EPwm2Regs.HRCNFG.all = 0x0;
EPwm2Regs.HRCNFG.bit.EDGMODE = HR_BEP; // MEP control on both edges
EPwm2Regs.HRCNFG.bit.CTLMODE = HR_CMP; // CMPAHR and TBPRDHR HR control
EPwm2Regs.HRCNFG.bit.HRLOAD = HR_CTR_ZERO_PRD; // load on CTR = 0 and CTR = TBPRD
EPwm2Regs.HRCNFG.bit.AUTOCONV = 1; // Enable autoconversion
EPwm2Regs.HRPCTL.bit.HRPE = 1; // Turn on high-resolution period control
//set TBCTL[PHSEN] = 1
EPwm2Regs.TBCTL.bit.PHSEN = 1;
//set HRPCTL[TBPHSHRLOADE] = 1
EPwm2Regs.HRPCTL.bit.TBPHSHRLOADE = 1;
EDIS;
//Write To CMP, TBPRD, TBPHS registers.
EPwm3Regs.TBCTL.bit.PRDLD = TB_SHADOW; // set Shadow load
EPwm3Regs.TBPRD = pwm1.PeriodMax; // PWM frequency = 1/(2*TBPRD)
EPwm3Regs.CMPA.half.CMPA = pwm1.PeriodMax / 2; // set duty 50% initially
EPwm3Regs.CMPA.half.CMPAHR = (0 << 8); // initialize HRPWM extension
EPwm3Regs.TBPHS.all = 0;
//Configure modes, clock dividers and action qualifier
EPwm3Regs.TBCTR = 0;
EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Select up-down count mode
EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT
EPwm3Regs.TBCTL.bit.FREE_SOFT = 00;
EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // LOAD CMPA on CTR = 0
EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm3Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm3Regs.AQCTLA.bit.CAU = AQ_SET;
EPwm3Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm3Regs.AQCTLB.bit.ZRO = AQ_SET;
EPwm3Regs.AQCTLB.bit.PRD = AQ_CLEAR;
EALLOW;
//Configure HRPWM registers
EPwm3Regs.HRCNFG.all = 0x0;
EPwm3Regs.HRCNFG.bit.EDGMODE = HR_BEP; // MEP control on both edges
EPwm3Regs.HRCNFG.bit.CTLMODE = HR_CMP; // CMPAHR and TBPRDHR HR control
EPwm3Regs.HRCNFG.bit.HRLOAD = HR_CTR_ZERO_PRD; // load on CTR = 0 and CTR = TBPRD
EPwm3Regs.HRCNFG.bit.AUTOCONV = 1; // Enable autoconversion
EPwm3Regs.HRPCTL.bit.HRPE = 1; // Turn on high-resolution period control
//set TBCTL[PHSEN] = 1
EPwm3Regs.TBCTL.bit.PHSEN = 1;
//set HRPCTL[TBPHSHRLOADE] = 1
EPwm3Regs.HRPCTL.bit.TBPHSHRLOADE = 1;
//Enable TBCLKSYNC
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
//Perform a software sync
EPwm1Regs.TBCTL.bit.SWFSYNC = 1;
EPwm2Regs.TBCTL.bit.SWFSYNC = 1;
EPwm3Regs.TBCTL.bit.SWFSYNC = 1;
EDIS;
Thank you!
-Peter






