I am trying to use PWM 6,7,8.
PWM6 and PWM7 will run nominally at 125000 Hz and PWM8 run at a frequency 4x PWM6 and PWM7. This is a variable frequency application using HR period control.
PWM 8 is the trigger to the ADC and is required to be phase synchronized to PWM6 and PWM7.
Every time I change the frequency of all 3 PWMs, I loose phase synchronization from PWM8 to PWM6 and PWM7. Some frequencies will cause PWM6 and PWM7 and PWM8 to be phase aligned but most will not.
Am I doing something wrong when I change frequency or is it my initialization?
below is my frequency setting code followed by the PWM initialization:
#define RESONATE_PWM_LEFT EPwm6Regs
#define RESONATE_PWM_RIGHT EPwm7Regs
#define ADC_PWM EPwm8Regs
void H_bridge_set_frequency_registers(uint32_t freq)
{
uint32_t integer;
uint32_t frac;
uint32_t period;
uint32_t ADC_period = 0;
float freq_f = freq;
if (freq >= 10000 && freq <= 320000)
{
//convert freq to period
period = 25600000000.0/freq_f;
//get the period calculated and divide by 4 for ADC sample frequency
ADC_period = (period >> 2);
integer = (ADC_period >> 8);
//mask off the fraction
frac = (ADC_period & 0xFF);
//set ADC freq as 4 times pwm period
ADC_PWM.TBPRD = integer-1;
ADC_PWM.TBPRDHR = (frac << 8);
frac = (period & 0xFF);
integer = (period >> 8);
//set PWM out freq
RESONATE_PWM_LEFT.TBPRD = integer-1;
RESONATE_PWM_LEFT.TBPRDHR = (frac << 8);
RESONATE_PWM_RIGHT.TBPRD = integer-1;
RESONATE_PWM_RIGHT.TBPRDHR = (frac << 8);
}
}
void resonate_left_PWM_setup(void)
{
int period = 800;
RESONATE_PWM_LEFT.TBCTL.bit.PRDLD = TB_SHADOW; // set Shadow load
RESONATE_PWM_LEFT.TBCTL.bit.PHSEN = 0;
RESONATE_PWM_LEFT.TBPRD = period-1; // PWM frequency = 1/(2*TBPRD)
RESONATE_PWM_LEFT.CMPA.bit.CMPA = period / 2; // set duty 50% initially
RESONATE_PWM_LEFT.CMPA.bit.CMPAHR = (1 << 8); // initialize HRPWM extension
RESONATE_PWM_LEFT.CMPB.bit.CMPB = period / 2; // set duty 50% initially
RESONATE_PWM_LEFT.CMPB.all |= 1;
RESONATE_PWM_LEFT.TBPHS.all = 0;
RESONATE_PWM_LEFT.TBCTR = 0;
RESONATE_PWM_LEFT.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Select up count mode
RESONATE_PWM_LEFT.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;
RESONATE_PWM_LEFT.TBCTL.bit.HSPCLKDIV = TB_DIV1;
RESONATE_PWM_LEFT.TBCTL.bit.CLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT
RESONATE_PWM_LEFT.TBCTL.bit.FREE_SOFT = 11;
RESONATE_PWM_LEFT.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // LOAD CMPA on CTR = 0
RESONATE_PWM_LEFT.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
RESONATE_PWM_LEFT.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
RESONATE_PWM_LEFT.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
RESONATE_PWM_LEFT.AQCTLA.bit.ZRO = AQ_SET; // PWM toggle high/low
RESONATE_PWM_LEFT.AQCTLA.bit.CAU = AQ_CLEAR;
RESONATE_PWM_LEFT.AQCTLB.bit.ZRO = AQ_SET; // PWM toggle high/low
RESONATE_PWM_LEFT.AQCTLB.bit.CBU = AQ_CLEAR;
RESONATE_PWM_LEFT.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module
RESONATE_PWM_LEFT.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary
RESONATE_PWM_LEFT.DBCTL.bit.IN_MODE = DBA_ALL; // EPWM1A is source for both delays
RESONATE_PWM_LEFT.DBFED.bit.DBFED = 10;
RESONATE_PWM_LEFT.DBRED.bit.DBRED = 10;
EALLOW;
RESONATE_PWM_LEFT.HRCNFG.all = 0x0;
RESONATE_PWM_LEFT.HRCNFG.bit.EDGMODE = HR_BEP; // MEP control on both edges.
RESONATE_PWM_LEFT.HRCNFG.bit.CTLMODE = HR_CMP; // CMPAHR and TBPRDHR HR control.
RESONATE_PWM_LEFT.HRCNFG.bit.HRLOAD = HR_CTR_ZERO; // load on CTR = 0 and CTR = TBPRD
RESONATE_PWM_LEFT.HRCNFG.bit.EDGMODEB = HR_BEP; // MEP control on both edges
RESONATE_PWM_LEFT.HRCNFG.bit.CTLMODEB = HR_CMP; // CMPBHR and TBPRDHR HR control
RESONATE_PWM_LEFT.HRCNFG.bit.HRLOADB = HR_CTR_ZERO; // load on CTR = 0 and CTR = TBPRD
RESONATE_PWM_LEFT.HRCNFG.bit.AUTOCONV = 1; // Enable autoconversion for HR period
//RESONATE_PWM_LEFT.HRPCTL.bit.TBPHSHRLOADE = 1; // Enable TBPHSHR sync (required for updwn count HR control)
RESONATE_PWM_LEFT.HRPCTL.bit.HRPE = 1; // Turn on high-resolution period control.
EDIS;
}
void resonate_right_PWM_setup(void)
{
int period = 800;
RESONATE_PWM_RIGHT.TBCTL.bit.PRDLD = TB_SHADOW; // set Shadow load
RESONATE_PWM_RIGHT.TBCTL.bit.PHSEN = TB_ENABLE;
RESONATE_PWM_RIGHT.TBPRD = period-1; // PWM frequency = 1/(2*TBPRD)
RESONATE_PWM_RIGHT.CMPA.bit.CMPA = period / 2; // set duty 50% initially
RESONATE_PWM_RIGHT.CMPA.bit.CMPAHR = (1 << 8); // initialize HRPWM extension
RESONATE_PWM_RIGHT.CMPB.bit.CMPB = period / 2; // set duty 50% initially
RESONATE_PWM_RIGHT.CMPB.all |= 1;
RESONATE_PWM_RIGHT.TBPHS.all = 0;
RESONATE_PWM_RIGHT.TBCTR = 0;
RESONATE_PWM_RIGHT.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Select up count mode
RESONATE_PWM_RIGHT.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
RESONATE_PWM_RIGHT.TBCTL.bit.HSPCLKDIV = TB_DIV1;
RESONATE_PWM_RIGHT.TBCTL.bit.CLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT
RESONATE_PWM_RIGHT.TBCTL.bit.FREE_SOFT = 11;
RESONATE_PWM_RIGHT.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // LOAD CMPA on CTR = 0
RESONATE_PWM_RIGHT.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
RESONATE_PWM_RIGHT.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
RESONATE_PWM_RIGHT.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
RESONATE_PWM_RIGHT.AQCTLA.bit.ZRO = AQ_CLEAR; // PWM toggle high/low
RESONATE_PWM_RIGHT.AQCTLA.bit.CAU = AQ_SET;
RESONATE_PWM_RIGHT.AQCTLB.bit.ZRO = AQ_CLEAR; // PWM toggle high/low
RESONATE_PWM_RIGHT.AQCTLB.bit.CBU = AQ_SET;
RESONATE_PWM_RIGHT.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module
RESONATE_PWM_RIGHT.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary
RESONATE_PWM_RIGHT.DBCTL.bit.IN_MODE = DBA_ALL; // EPWM1A is source for both delays
RESONATE_PWM_RIGHT.DBFED.bit.DBFED = 10;
RESONATE_PWM_RIGHT.DBRED.bit.DBRED = 10;
EALLOW;
RESONATE_PWM_RIGHT.HRCNFG.all = 0x0;
RESONATE_PWM_RIGHT.HRCNFG.bit.EDGMODE = HR_BEP; // MEP control on both edges.
RESONATE_PWM_RIGHT.HRCNFG.bit.CTLMODE = HR_CMP; // CMPAHR and TBPRDHR HR control.
RESONATE_PWM_RIGHT.HRCNFG.bit.HRLOAD = HR_CTR_ZERO; // load on CTR = 0 and CTR = TBPRD
RESONATE_PWM_RIGHT.HRCNFG.bit.EDGMODEB = HR_BEP; // MEP control on both edges
RESONATE_PWM_RIGHT.HRCNFG.bit.CTLMODEB = HR_CMP; // CMPBHR and TBPRDHR HR control
RESONATE_PWM_RIGHT.HRCNFG.bit.HRLOADB = HR_CTR_ZERO; // load on CTR = 0 and CTR = TBPRD
RESONATE_PWM_RIGHT.HRCNFG.bit.AUTOCONV = 1; // Enable autoconversion for HR period
RESONATE_PWM_RIGHT.HRPCTL.bit.TBPHSHRLOADE = 1; // Enable TBPHSHR sync (required for updwn count HR control)
RESONATE_PWM_RIGHT.HRPCTL.bit.HRPE = 1; // Turn on high-resolution period control.
EDIS;
}
void ADC_PWM_setup(void)
{
int period = 200;
ADC_PWM.ETSEL.bit.SOCAEN = 0; // Disable SOC on A group
ADC_PWM.ETSEL.bit.SOCASEL = 4; // Select SOC on up-count
ADC_PWM.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event
ADC_PWM.TBCTL.bit.PRDLD = TB_SHADOW; // set Shadow load
ADC_PWM.TBCTL.bit.PHSEN = TB_ENABLE;
ADC_PWM.TBPRD = period-1; // PWM frequency = 1/(2*TBPRD)
ADC_PWM.CMPA.bit.CMPA = period / 2; // set duty 50% initially
ADC_PWM.CMPA.bit.CMPAHR = (0 << 8); // initialize HRPWM extension
ADC_PWM.CMPB.bit.CMPB = period / 2; // set duty 50% initially
ADC_PWM.CMPB.all |= 1;
ADC_PWM.TBPHS.all = 0;
ADC_PWM.TBCTR = 0;
ADC_PWM.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Select up count mode
ADC_PWM.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
ADC_PWM.TBCTL.bit.HSPCLKDIV = TB_DIV1;
ADC_PWM.TBCTL.bit.CLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT
//EPwm4Regs.TBCTL.bit.FREE_SOFT = 11;
ADC_PWM.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // LOAD CMPA on CTR = 0
ADC_PWM.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
ADC_PWM.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
ADC_PWM.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
ADC_PWM.AQCTLA.bit.ZRO = AQ_SET; // PWM toggle high/low
ADC_PWM.AQCTLA.bit.CAU = AQ_CLEAR;
ADC_PWM.AQCTLB.bit.ZRO = AQ_SET; // PWM toggle high/low
ADC_PWM.AQCTLB.bit.CBU = AQ_CLEAR;
ADC_PWM.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module
ADC_PWM.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary
ADC_PWM.DBCTL.bit.IN_MODE = DBA_ALL; // EPWM1A is source for both delays
//EPwm4Regs.DBFED.bit.DBFED = 10;
//EPwm4Regs.DBRED.bit.DBRED = 10;
EALLOW;
ADC_PWM.HRCNFG.all = 0x0;
ADC_PWM.HRCNFG.bit.EDGMODE = HR_BEP; // MEP control on both edges.
ADC_PWM.HRCNFG.bit.CTLMODE = HR_CMP; // CMPAHR and TBPRDHR HR control.
ADC_PWM.HRCNFG.bit.HRLOAD = HR_CTR_ZERO; // load on CTR = 0 and CTR = TBPRD
ADC_PWM.HRCNFG.bit.EDGMODEB = HR_BEP; // MEP control on both edges
ADC_PWM.HRCNFG.bit.CTLMODEB = HR_CMP; // CMPBHR and TBPRDHR HR control
ADC_PWM.HRCNFG.bit.HRLOADB = HR_CTR_ZERO; // load on CTR = 0 and CTR = TBPRD
ADC_PWM.HRCNFG.bit.AUTOCONV = 1; // Enable autoconversion for HR period
ADC_PWM.HRPCTL.bit.TBPHSHRLOADE = 1; // Enable TBPHSHR sync (required for updwn count HR control)
ADC_PWM.HRPCTL.bit.HRPE = 1; // Turn on high-resolution period control.
//ADC_PWM.TBCTL.bit.SWFSYNC = 1;
EDIS;
}