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.
Tool/software:
I am unable to configure the EPWMs to load CMPA on a SYNCIN event.
Here is my setup:
I'm using EPWM Modules 1 through 11. I need to load the shadowed CMPA and CMPB value for EPWMs 9 through 11 simultaneously for my design. Right now, I am attempting to do the following
- EPWM 1 configured to generate SYNCOUT pulse when TBCTR=0
- EPWM 2 through 11 configured to use SYNCOUT = SYNCIN
- EPWM 1 through 8 configured to be active high (not complementary)
- EPWM 9 through 11 configured to be active high complementary
- EPWM 9 through 11 configured to load CMPA and CMPB on SYNCIN
This last part is the the one that doesn't seem to work for me.
I have attached a working test project that demonstrates the issue.
The relevant code is in lines 561-577
EPwm9Regs.CMPCTL.bit.LOADAMODE = 0; EPwm9Regs.CMPCTL.bit.LOADASYNC = 2; EPwm9Regs.CMPCTL.bit.LOADBMODE = 0; EPwm9Regs.CMPCTL.bit.LOADBSYNC = 2; EPwm10Regs.CMPCTL.bit.LOADAMODE = 0; EPwm10Regs.CMPCTL.bit.LOADASYNC = 2; EPwm10Regs.CMPCTL.bit.LOADBMODE = 0; EPwm10Regs.CMPCTL.bit.LOADBSYNC = 2; EPwm11Regs.CMPCTL.bit.LOADAMODE = 0; EPwm11Regs.CMPCTL.bit.LOADASYNC = 2; EPwm11Regs.CMPCTL.bit.LOADBMODE = 0; EPwm11Regs.CMPCTL.bit.LOADBSYNC = 2;
Hi Rahul,
Can you please double check that your Sync-IN source for those PWMs is set up correctly?
Please send a snippet of the Sync select registers to verify that the sync source is set up correctly - if this is true, then the loading scheme should work if you have set up shadow load on sync.
Best Regards,
Allison
Hi Allison,
I verified that the SYNCO TO SYNCI chain is functioning as I expect by connecting SYNCOs via the EXTSYNCOUT and OutputXBAR to a GPIO pin and probing with an oscilloscope.
However, despite the SYNCI configuration, the CMPA/B load is not being triggered.
Here are the settings copied from the configure_EPWM function in the project that I attached.
EALLOW; CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0; // stop TBCTR incrementing EDIS; // EPWM 1 EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1; // CLKDIV=1 TBCLK=EPWMCLK/(HSPCLKDIV*CLKDIV) EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // HSPCLKDIV=1 EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Up-down mode EPwm1Regs.TBPRD = EPWM_TBPRD; // Counter period EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Shadow mode active for CMPA EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // Shadow mode active for CMPB EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on TBCTR=TBPRD EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // Load on TBCTR=TBPRD EPwm1Regs.CMPA.bit.CMPA = EPWM_TBPRD; // Initial value of CMPA EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Set EPWMA low on TBCTR=CMPA during up count EPwm1Regs.AQCTLA.bit.CAD = AQ_SET; // Set EPWMA high on TBCTR=CMPA during down count EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Pass through SYNCIN signal (doesn't matter for what we're doing) EPwm1Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Enable loading of PHS register on sync event // We will initially enable this so that we can force a sync to set up the phase shifts. // After forcing the sync, we will disable this. // Note: if this is enabled on EPWM1, the input X-BAR should be reconfigured to something // other than GPIO0 (otherwise TBCTR will be loaded with TBPHS when EPWM toggles) EPwm1Regs.TBPHS.bit.TBPHS = TBCTR_INIT_1; // load TBCTR with this value on phase load event to set up phase shifts between carriers EPwm1Regs.TBCTR = 0; // start counter with value of 0 (TBCTR will be written with TBPHS when we force a sync) EPwm1Regs.TBCTL.bit.PHSDIR = DIR_1; // some carriers will start counting up and some will start counting down // depending on their phase shifts EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HI; // this switch is shorted, so we don't invert the B channel EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // Enable both falling and rising edge delays EPwm1Regs.DBFED.bit.DBFED = EPWM_DEADTIME; // Set delay for falling edge (DBFED) EPwm1Regs.DBRED.bit.DBRED = EPWM_DEADTIME; // Set delay for rising edge (DBRED) // EPWM 2 EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1; // CLKDIV=1 TBCLK=EPWMCLK/(HSPCLKDIV*CLKDIV) EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // HSPCLKDIV=1 EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Up-down mode EPwm2Regs.TBPRD = EPWM_TBPRD; // Counter period EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Shadow mode active for CMPA EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // Shadow mode active for CMPB EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on TBCTR=TBPRD EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // Load on TBCTR=TBPRD EPwm2Regs.CMPA.bit.CMPA = EPWM_TBPRD; // Initial value of CMPA EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Set EPWMA low on TBCTR=CMPA during up count EPwm2Regs.AQCTLA.bit.CAD = AQ_SET; // Set EPWMA high on TBCTR=CMPA during down count EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Pass through SYNCIN signal (doesn't matter for what we're doing) EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Enable loading of PHS register on sync event // We will initially enable this so that we can force a sync to set up the phase shifts. // After forcing the sync, we will disable this. // Note: if this is enabled on EPWM1, the input X-BAR should be reconfigured to something // other than GPIO0 (otherwise TBCTR will be loaded with TBPHS when EPWM toggles) EPwm2Regs.TBPHS.bit.TBPHS = TBCTR_INIT_2; // load TBCTR with this value on phase load event to set up phase shifts between carriers EPwm2Regs.TBCTR = 0; // start counter with value of 0 (TBCTR will be written with TBPHS when we force a sync) EPwm2Regs.TBCTL.bit.PHSDIR = DIR_2; // some carriers will start counting up and some will start counting down // depending on their phase shifts EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HI; // Active high complementary - EPWMxB is inverted. EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // Enable both falling and rising edge delays EPwm2Regs.DBFED.bit.DBFED = EPWM_DEADTIME; // Set delay for falling edge (DBFED) EPwm2Regs.DBRED.bit.DBRED = EPWM_DEADTIME; // Set delay for rising edge (DBRED) // EPWM 3 EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1; // CLKDIV=1 TBCLK=EPWMCLK/(HSPCLKDIV*CLKDIV) EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // HSPCLKDIV=1 EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Up-down mode EPwm3Regs.TBPRD = EPWM_TBPRD; // Counter period EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Shadow mode active for CMPA EPwm3Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // Shadow mode active for CMPB EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on TBCTR=TBPRD EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // Load on TBCTR=TBPRD EPwm3Regs.CMPA.bit.CMPA = EPWM_TBPRD; // Initial value of CMPA EPwm3Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Set EPWMA low on TBCTR=CMPA during up count EPwm3Regs.AQCTLA.bit.CAD = AQ_SET; // Set EPWMA high on TBCTR=CMPA during down count EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Pass through SYNCIN signal (doesn't matter for what we're doing) EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Enable loading of PHS register on sync event // We will initially enable this so that we can force a sync to set up the phase shifts. // After forcing the sync, we will disable this. // Note: if this is enabled on EPWM1, the input X-BAR should be reconfigured to something // other than GPIO0 (otherwise TBCTR will be loaded with TBPHS when EPWM toggles) EPwm3Regs.TBPHS.bit.TBPHS = TBCTR_INIT_3; // load TBCTR with this value on phase load event to set up phase shifts between carriers EPwm3Regs.TBCTR = 0; // start counter with value of 0 (TBCTR will be written with TBPHS when we force a sync) EPwm3Regs.TBCTL.bit.PHSDIR = DIR_3; // some carriers will start counting up and some will start counting down // depending on their phase shifts EPwm3Regs.DBCTL.bit.POLSEL = DB_ACTV_HI; // Active high complementary - EPWMxB is inverted. EPwm3Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // Enable both falling and rising edge delays EPwm3Regs.DBFED.bit.DBFED = EPWM_DEADTIME; // Set delay for falling edge (DBFED) EPwm3Regs.DBRED.bit.DBRED = EPWM_DEADTIME; // Set delay for rising edge (DBRED) // EPWM 4 EPwm4Regs.TBCTL.bit.CLKDIV = TB_DIV1; // CLKDIV=1 TBCLK=EPWMCLK/(HSPCLKDIV*CLKDIV) EPwm4Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // HSPCLKDIV=1 EPwm4Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Up-down mode EPwm4Regs.TBPRD = EPWM_TBPRD; // Counter period EPwm4Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Shadow mode active for CMPA EPwm4Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // Shadow mode active for CMPB EPwm4Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on TBCTR=TBPRD EPwm4Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // Load on TBCTR=TBPRD EPwm4Regs.CMPA.bit.CMPA = EPWM_TBPRD; // Initial value of CMPA EPwm4Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Set EPWMA low on TBCTR=CMPA during up count EPwm4Regs.AQCTLA.bit.CAD = AQ_SET; // Set EPWMA high on TBCTR=CMPA during down count EPwm4Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Pass through SYNCIN signal (doesn't matter for what we're doing) EPwm4Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Enable loading of PHS register on sync event // We will initially enable this so that we can force a sync to set up the phase shifts. // After forcing the sync, we will disable this. // Note: if this is enabled on EPWM1, the input X-BAR should be reconfigured to something // other than GPIO0 (otherwise TBCTR will be loaded with TBPHS when EPWM toggles) EPwm4Regs.TBPHS.bit.TBPHS = TBCTR_INIT_4; // load TBCTR with this value on phase load event to set up phase shifts between carriers EPwm4Regs.TBCTR = 0; // start counter with value of 0 (TBCTR will be written with TBPHS when we force a sync) EPwm4Regs.TBCTL.bit.PHSDIR = DIR_4; // some carriers will start counting up and some will start counting down // depending on their phase shifts EPwm4Regs.DBCTL.bit.POLSEL = DB_ACTV_HI; // Active high complementary - EPWMxB is inverted. EPwm4Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // Enable both falling and rising edge delays EPwm4Regs.DBFED.bit.DBFED = EPWM_DEADTIME; // Set delay for falling edge (DBFED) EPwm4Regs.DBRED.bit.DBRED = EPWM_DEADTIME; // Set delay for rising edge (DBRED) // EPWM 5 EPwm5Regs.TBCTL.bit.CLKDIV = TB_DIV1; // CLKDIV=1 TBCLK=EPWMCLK/(HSPCLKDIV*CLKDIV) EPwm5Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // HSPCLKDIV=1 EPwm5Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Up-down mode EPwm5Regs.TBPRD = EPWM_TBPRD; // Counter period EPwm5Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Shadow mode active for CMPA EPwm5Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // Shadow mode active for CMPB EPwm5Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on TBCTR=TBPRD EPwm5Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // Load on TBCTR=TBPRD EPwm5Regs.CMPA.bit.CMPA = EPWM_TBPRD; // Initial value of CMPA EPwm5Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Set EPWMA low on TBCTR=CMPA during up count EPwm5Regs.AQCTLA.bit.CAD = AQ_SET; // Set EPWMA high on TBCTR=CMPA during down count EPwm5Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Pass through SYNCIN signal (doesn't matter for what we're doing) EPwm5Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Enable loading of PHS register on sync event // We will initially enable this so that we can force a sync to set up the phase shifts. // After forcing the sync, we will disable this. // Note: if this is enabled on EPWM1, the input X-BAR should be reconfigured to something // other than GPIO0 (otherwise TBCTR will be loaded with TBPHS when EPWM toggles) EPwm5Regs.TBPHS.bit.TBPHS = TBCTR_INIT_5; // load TBCTR with this value on phase load event to set up phase shifts between carriers EPwm5Regs.TBCTR = 0; // start counter with value of 0 (TBCTR will be written with TBPHS when we force a sync) EPwm5Regs.TBCTL.bit.PHSDIR = DIR_5; // some carriers will start counting up and some will start counting down // depending on their phase shifts EPwm5Regs.DBCTL.bit.POLSEL = DB_ACTV_HI; // Active high complementary - EPWMxB is inverted. EPwm5Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // Enable both falling and rising edge delays EPwm5Regs.DBFED.bit.DBFED = EPWM_DEADTIME; // Set delay for falling edge (DBFED) EPwm5Regs.DBRED.bit.DBRED = EPWM_DEADTIME; // Set delay for rising edge (DBRED) // EPWM 6 EPwm6Regs.TBCTL.bit.CLKDIV = TB_DIV1; // CLKDIV=1 TBCLK=EPWMCLK/(HSPCLKDIV*CLKDIV) EPwm6Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // HSPCLKDIV=1 EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Up-down mode EPwm6Regs.TBPRD = EPWM_TBPRD; // Counter period EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Shadow mode active for CMPA EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // Shadow mode active for CMPB EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on TBCTR=TBPRD EPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // Load on TBCTR=TBPRD EPwm6Regs.CMPA.bit.CMPA = EPWM_TBPRD; // Initial value of CMPA EPwm6Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Set EPWMA low on TBCTR=CMPA during up count EPwm6Regs.AQCTLA.bit.CAD = AQ_SET; // Set EPWMA high on TBCTR=CMPA during down count EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Pass through SYNCIN signal (doesn't matter for what we're doing) EPwm6Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Enable loading of PHS register on sync event // We will initially enable this so that we can force a sync to set up the phase shifts. // After forcing the sync, we will disable this. // Note: if this is enabled on EPWM1, the input X-BAR should be reconfigured to something // other than GPIO0 (otherwise TBCTR will be loaded with TBPHS when EPWM toggles) EPwm6Regs.TBPHS.bit.TBPHS = TBCTR_INIT_6; // load TBCTR with this value on phase load event to set up phase shifts between carriers EPwm6Regs.TBCTR = 0; // start counter with value of 0 (TBCTR will be written with TBPHS when we force a sync) EPwm6Regs.TBCTL.bit.PHSDIR = DIR_6; // some carriers will start counting up and some will start counting down // depending on their phase shifts EPwm6Regs.DBCTL.bit.POLSEL = DB_ACTV_HI; // Active high complementary - EPWMxB is inverted. EPwm6Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // Enable both falling and rising edge delays EPwm6Regs.DBFED.bit.DBFED = EPWM_DEADTIME; // Set delay for falling edge (DBFED) EPwm6Regs.DBRED.bit.DBRED = EPWM_DEADTIME; // Set delay for rising edge (DBRED) // EPWM 7 EPwm7Regs.TBCTL.bit.CLKDIV = TB_DIV1; // CLKDIV=1 TBCLK=EPWMCLK/(HSPCLKDIV*CLKDIV) EPwm7Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // HSPCLKDIV=1 EPwm7Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Up-down mode EPwm7Regs.TBPRD = EPWM_TBPRD; // Counter period EPwm7Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Shadow mode active for CMPA EPwm7Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // Shadow mode active for CMPB EPwm7Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on TBCTR=TBPRD EPwm7Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // Load on TBCTR=TBPRD EPwm7Regs.CMPA.bit.CMPA = EPWM_TBPRD; // Initial value of CMPA EPwm7Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Set EPWMA low on TBCTR=CMPA during up count EPwm7Regs.AQCTLA.bit.CAD = AQ_SET; // Set EPWMA high on TBCTR=CMPA during down count EPwm7Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Pass through SYNCIN signal (doesn't matter for what we're doing) EPwm7Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Enable loading of PHS register on sync event // We will initially enable this so that we can force a sync to set up the phase shifts. // After forcing the sync, we will disable this. // Note: if this is enabled on EPWM1, the input X-BAR should be reconfigured to something // other than GPIO0 (otherwise TBCTR will be loaded with TBPHS when EPWM toggles) EPwm7Regs.TBPHS.bit.TBPHS = TBCTR_INIT_7; // load TBCTR with this value on phase load event to set up phase shifts between carriers EPwm7Regs.TBCTR = 0; // start counter with value of 0 (TBCTR will be written with TBPHS when we force a sync) EPwm7Regs.TBCTL.bit.PHSDIR = DIR_7; // some carriers will start counting up and some will start counting down // depending on their phase shifts EPwm7Regs.DBCTL.bit.POLSEL = DB_ACTV_HI; // Active high complementary - EPWMxB is inverted. EPwm7Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // Enable both falling and rising edge delays EPwm7Regs.DBFED.bit.DBFED = EPWM_DEADTIME; // Set delay for falling edge (DBFED) EPwm7Regs.DBRED.bit.DBRED = EPWM_DEADTIME; // Set delay for rising edge (DBRED) // EPWM 8 EPwm8Regs.TBCTL.bit.CLKDIV = TB_DIV1; // CLKDIV=1 TBCLK=EPWMCLK/(HSPCLKDIV*CLKDIV) EPwm8Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // HSPCLKDIV=1 EPwm8Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Up-down mode EPwm8Regs.TBPRD = EPWM_TBPRD; // Counter period EPwm8Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Shadow mode active for CMPA EPwm8Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // Shadow mode active for CMPB EPwm8Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on TBCTR=TBPRD EPwm8Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // Load on TBCTR=TBPRD EPwm8Regs.CMPA.bit.CMPA = EPWM_TBPRD; // Initial value of CMPA EPwm8Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Set EPWMA low on TBCTR=CMPA during up count EPwm8Regs.AQCTLA.bit.CAD = AQ_SET; // Set EPWMA high on TBCTR=CMPA during down count EPwm8Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Pass through SYNCIN signal (doesn't matter for what we're doing) EPwm8Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Enable loading of PHS register on sync event // We will initially enable this so that we can force a sync to set up the phase shifts. // After forcing the sync, we will disable this. // Note: if this is enabled on EPWM1, the input X-BAR should be reconfigured to something // other than GPIO0 (otherwise TBCTR will be loaded with TBPHS when EPWM toggles) EPwm8Regs.TBPHS.bit.TBPHS = TBCTR_INIT_8; // load TBCTR with this value on phase load event to set up phase shifts between carriers EPwm8Regs.TBCTR = 0; // start counter with value of 0 (TBCTR will be written with TBPHS when we force a sync) EPwm8Regs.TBCTL.bit.PHSDIR = DIR_8; // some carriers will start counting up and some will start counting down // depending on their phase shifts EPwm8Regs.DBCTL.bit.POLSEL = DB_ACTV_HI; // Active high complementary - EPWMxB is inverted. EPwm8Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // Enable both falling and rising edge delays EPwm8Regs.DBFED.bit.DBFED = EPWM_DEADTIME; // Set delay for falling edge (DBFED) EPwm8Regs.DBRED.bit.DBRED = EPWM_DEADTIME; // Set delay for rising edge (DBRED) // EPWM 9 EPwm9Regs.TBCTL.bit.CLKDIV = TB_DIV1; // CLKDIV=1 TBCLK=EPWMCLK/(HSPCLKDIV*CLKDIV) EPwm9Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // HSPCLKDIV=1 EPwm9Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Up-down mode EPwm9Regs.TBPRD = EPWM_TBPRD; // Counter period EPwm9Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Shadow mode active for CMPA EPwm9Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // Shadow mode active for CMPB EPwm9Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on TBCTR=TBPRD EPwm9Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // Load on TBCTR=TBPRD EPwm9Regs.CMPA.bit.CMPA = EPWM_CMP_INIT; // Initial value of CMPA EPwm9Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Set EPWMA low on TBCTR=CMPA during up count EPwm9Regs.AQCTLA.bit.CAD = AQ_SET; // Set EPWMA high on TBCTR=CMPA during down count EPwm9Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Pass through SYNCIN signal (doesn't matter for what we're doing) EPwm9Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Enable loading of PHS register on sync event // We will initially enable this so that we can force a sync to set up the phase shifts. // After forcing the sync, we will disable this. // Note: if this is enabled on EPWM1, the input X-BAR should be reconfigured to something // other than GPIO0 (otherwise TBCTR will be loaded with TBPHS when EPWM toggles) EPwm9Regs.TBPHS.bit.TBPHS = TBCTR_INIT_9; // load TBCTR with this value on phase load event to set up phase shifts between carriers EPwm9Regs.TBCTR = 0; // start counter with value of 0 (TBCTR will be written with TBPHS when we force a sync) EPwm9Regs.TBCTL.bit.PHSDIR = DIR_9; // some carriers will start counting up and some will start counting down // depending on their phase shifts EPwm9Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active high complementary - EPWMxB is inverted. EPwm9Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // Enable both falling and rising edge delays EPwm9Regs.DBFED.bit.DBFED = EPWM_DEADTIME; // Set delay for falling edge (DBFED) EPwm9Regs.DBRED.bit.DBRED = EPWM_DEADTIME; // Set delay for rising edge (DBRED) // EPWM 10 EPwm10Regs.TBCTL.bit.CLKDIV = TB_DIV1; // CLKDIV=1 TBCLK=EPWMCLK/(HSPCLKDIV*CLKDIV) EPwm10Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // HSPCLKDIV=1 EPwm10Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Up-down mode EPwm10Regs.TBPRD = EPWM_TBPRD; // Counter period EPwm10Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Shadow mode active for CMPA EPwm10Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // Shadow mode active for CMPB EPwm10Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on TBCTR=TBPRD EPwm10Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // Load on TBCTR=TBPRD EPwm10Regs.CMPA.bit.CMPA = EPWM_CMP_INIT; // Initial value of CMPA EPwm10Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Set EPWMA low on TBCTR=CMPA during up count EPwm10Regs.AQCTLA.bit.CAD = AQ_SET; // Set EPWMA high on TBCTR=CMPA during down count EPwm10Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Pass through SYNCIN signal (doesn't matter for what we're doing) EPwm10Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Enable loading of PHS register on sync event // We will initially enable this so that we can force a sync to set up the phase shifts. // After forcing the sync, we will disable this. // Note: if this is enabled on EPWM1, the input X-BAR should be reconfigured to something // other than GPIO0 (otherwise TBCTR will be loaded with TBPHS when EPWM toggles) EPwm10Regs.TBPHS.bit.TBPHS = TBCTR_INIT_10; // load TBCTR with this value on phase load event to set up phase shifts between carriers EPwm10Regs.TBCTR = 0; // start counter with value of 0 (TBCTR will be written with TBPHS when we force a sync) EPwm10Regs.TBCTL.bit.PHSDIR = DIR_10; // some carriers will start counting up and some will start counting down // depending on their phase shifts EPwm10Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active high complementary - EPWMxB is inverted. EPwm10Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // Enable both falling and rising edge delays EPwm10Regs.DBFED.bit.DBFED = EPWM_DEADTIME; // Set delay for falling edge (DBFED) EPwm10Regs.DBRED.bit.DBRED = EPWM_DEADTIME; // Set delay for rising edge (DBRED) // EPWM 11 EPwm11Regs.TBCTL.bit.CLKDIV = TB_DIV1; // CLKDIV=1 TBCLK=EPWMCLK/(HSPCLKDIV*CLKDIV) EPwm11Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // HSPCLKDIV=1 EPwm11Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Up-down mode EPwm11Regs.TBPRD = EPWM_TBPRD; // Counter period EPwm11Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Shadow mode active for CMPA EPwm11Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // Shadow mode active for CMPB EPwm11Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on TBCTR=TBPRD EPwm11Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // Load on TBCTR=TBPRD EPwm11Regs.CMPA.bit.CMPA = EPWM_CMP_INIT; // Initial value of CMPA EPwm11Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Set EPWMA low on TBCTR=CMPA during up count EPwm11Regs.AQCTLA.bit.CAD = AQ_SET; // Set EPWMA high on TBCTR=CMPA during down count EPwm11Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Pass through SYNCIN signal (doesn't matter for what we're doing) EPwm11Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Enable loading of PHS register on sync event // We will initially enable this so that we can force a sync to set up the phase shifts. // After forcing the sync, we will disable this. // Note: if this is enabled on EPWM1, the input X-BAR should be reconfigured to something // other than GPIO0 (otherwise TBCTR will be loaded with TBPHS when EPWM toggles) EPwm11Regs.TBPHS.bit.TBPHS = TBCTR_INIT_11; // load TBCTR with this value on phase load event to set up phase shifts between carriers EPwm11Regs.TBCTR = 0; // start counter with value of 0 (TBCTR will be written with TBPHS when we force a sync) EPwm11Regs.TBCTL.bit.PHSDIR = DIR_11; // some carriers will start counting up and some will start counting down // depending on their phase shifts EPwm11Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active high complementary - EPWMxB is inverted. EPwm11Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // Enable both falling and rising edge delays EPwm11Regs.DBFED.bit.DBFED = EPWM_DEADTIME; // Set delay for falling edge (DBFED) EPwm11Regs.DBRED.bit.DBRED = EPWM_DEADTIME; // Set delay for rising edge (DBRED) // setting the trip zone registers // we will use the trip zone to short out the upper 8 pairs of switches to use the 12-level hardware as a 4-Level EALLOW; EPwm9Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // Set EPWMA high when the trip-zone is triggered EPwm9Regs.TZCTL.bit.TZB = TZ_FORCE_LO; // Set EPWMB high when the trip-zone is triggered EPwm9Regs.TZSEL.bit.OSHT1 = 1; // Enable TZ1 as a one-shot TZ event source EPwm9Regs.TZEINT.bit.OST = 0; // Enable TZ interrupt EPwm9Regs.TZCLR.bit.OST = 1; // Clear OST flag EPwm10Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // Set EPWMA high when the trip-zone is triggered EPwm10Regs.TZCTL.bit.TZB = TZ_FORCE_LO; // Set EPWMB high when the trip-zone is triggered EPwm10Regs.TZSEL.bit.OSHT1 = 1; // Enable TZ1 as a one-shot TZ event source EPwm10Regs.TZEINT.bit.OST = 0; // Enable TZ interrupt EPwm10Regs.TZCLR.bit.OST = 1; // Clear OST flag EPwm11Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // Set EPWMA high when the trip-zone is triggered EPwm11Regs.TZCTL.bit.TZB = TZ_FORCE_LO; // Set EPWMB high when the trip-zone is triggered EPwm11Regs.TZSEL.bit.OSHT1 = 1; // Enable TZ1 as a one-shot TZ event source EPwm11Regs.TZEINT.bit.OST = 0; // Enable TZ interrupt EPwm11Regs.TZCLR.bit.OST = 1; // Clear OST flag EDIS; // configure EPWMs to load CMPA and CMPB only when a sync is received EPwm9Regs.CMPCTL.bit.LOADAMODE = 0; EPwm9Regs.CMPCTL.bit.LOADASYNC = 2; EPwm9Regs.CMPCTL.bit.LOADBMODE = 0; EPwm9Regs.CMPCTL.bit.LOADBSYNC = 2; EPwm10Regs.CMPCTL.bit.LOADAMODE = 0; EPwm10Regs.CMPCTL.bit.LOADASYNC = 2; EPwm10Regs.CMPCTL.bit.LOADBMODE = 0; EPwm10Regs.CMPCTL.bit.LOADBSYNC = 2; EPwm11Regs.CMPCTL.bit.LOADAMODE = 0; EPwm11Regs.CMPCTL.bit.LOADASYNC = 2; EPwm11Regs.CMPCTL.bit.LOADBMODE = 0; EPwm11Regs.CMPCTL.bit.LOADBSYNC = 2; // SOC trigger for sampling EPwm1Regs.ETSEL.bit.SOCASEL = ET_CTR_ZERO; // ADCSOCA on TBCTR=TBPRD EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate SOCA on 1st event EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOCA generation // set up PWM1 interrupt for main control loop EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on TBPRD event EPwm1Regs.ETSEL.bit.INTEN = 0; // Disable INT EPwm1Regs.ETPS.bit.INTPRD = 1; // Generate INT on 1st event EPwm1Regs.ETCLR.bit.INT = 1; // Clear interrupt flag /* * EPWM signals propagate via a daisy chain depicted in TRM section 15.4.3.3 * According to the TRM, the longest daisy chain propagation path must not exceed four EPWM modules. * If necessary, the sync chain can be modified with appropriate settings of bits in SyncSocRegs.SYNCSELECT * * However, in practice, it is unclear how many modules can be chained before the syncin->syncout pulse propagation delay is] * greater than 1 EPWMCLK. * * To set sync phase shifts properly, we need to modify the default EXTSYNC1 setup such that it does not interfere with the SWFSYNC * that we use to sync all the modules. * * By default, EXTSYNC1 is connected to INPUT5 on the Input XBAR, and INPUT5 is connected to GPIO0 which we are using for EPWM1A. * * SWFSYNC and the synchronization input signal EPWMxSYNCI both trigger EPWM sync (TRM section 15.4.3.3 and Fig. 15-5). * Leaving the default value for EXTSYNC1 can cause improper phase alignment if a rising edge on EPWM1 occurs before PHSEN is disabled * (for example if this routine is interrupted between the SWFSYNC = 1 and PHSEN = 0 operations). To ensure reliable phase alignment, * we will connect INPUT5 on the Input XBAR to an unused GPIO pin such that the only synchronizing signal is the SWFSYNC. */ /* * EPWM sync triggers are latched until TBCTR is loaded with the value of TBPHS on the next TBCLK edge (TRM section 15.4.3.3) * Using SWFSYNC to synchronize a chain while TBCLKs are incrementing will result in a delay of TBCLK between the first EPWM module * in the chain and the subsequent ones, as the SYNCOUT signal only results in a synchronization at the next TBCLK edge. * * Therefore, when possible, the SWFSYNC should be set (and consequently latched) before the TBCLKSYNC bit is set to 1. */ EALLOW; InputXbarRegs.INPUT1SELECT = 26; // route INPUT1 to GPIO 26 that we will use exclusively for tripping PWMs InputXbarRegs.INPUT5SELECT = 25; // route INPUT5 to an unused GPIO pin to not interfere with EXTSYNC1 EDIS; EALLOW; EPwm1Regs.TBCTL.bit.SWFSYNC = 1; // force synchronization of EPWMs in chain starting with EPWM1 CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1; // start all TBCTR incrementing EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // turn off PHSEN for all EPWMs to prevent subsequent phase loading EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE; EPwm3Regs.TBCTL.bit.PHSEN = TB_DISABLE; EPwm4Regs.TBCTL.bit.PHSEN = TB_DISABLE; EPwm5Regs.TBCTL.bit.PHSEN = TB_DISABLE; EPwm6Regs.TBCTL.bit.PHSEN = TB_DISABLE; EPwm7Regs.TBCTL.bit.PHSEN = TB_DISABLE; EPwm8Regs.TBCTL.bit.PHSEN = TB_DISABLE; EPwm9Regs.TBCTL.bit.PHSEN = TB_DISABLE; EPwm10Regs.TBCTL.bit.PHSEN = TB_DISABLE; EPwm11Regs.TBCTL.bit.PHSEN = TB_DISABLE; EDIS; EALLOW; EPwm1Regs.TBCTL.bit.SYNCOSEL = 3; // SYNCOSEL for EPWM1 on CTR = 0 EPwm1Regs.TBCTL2.bit.SYNCOSELX = 1; EPwm1Regs.CMPC = 0; SyncSocRegs.SYNCSELECT.bit.EPWM4SYNCIN = 0; // these are the default values SyncSocRegs.SYNCSELECT.bit.EPWM7SYNCIN = 0; SyncSocRegs.SYNCSELECT.bit.EPWM10SYNCIN = 0; SyncSocRegs.SYNCSELECT.bit.SYNCOUT = 0; // see TRM 9.4 for where these settings come from // we will use Output 1 on the Output XBAR OutputXbarRegs.OUTPUT1MUX0TO15CFG.bit.MUX14 = 3; // select EXTSYNCOUT in its corresponding mux (see TRM Table 9.4) OutputXbarRegs.OUTPUT1MUXENABLE.bit.MUX14 = 1; // enable OUTPUT1 EDIS;
Hi Rahul,
Thanks for the information. Please give me another few days to take a look.
Best Regards,
Allison
Hi Allison,
Thanks. Looking forward to hearing back from you and/or anyone else on the C2000 team.
Regards,
Rahul
Hi Rahul,
No update yet- I will follow up tomorrow. Appreciate the patience!
Best Regards,
Allison
Hi Allison Nguyen,
After extensive trial and error, I have determined that the way to get CMPA to load on SYNCI is to set
EPwmxRegs.TBCTL.bit.PHSEN = 1
In other words, the PHSEN bit does more than just loading TBCTR with the value of TBPHS on sync, it also appears to gate whether CMPA gets loaded on sync.
There's no mention of this anywhere in the Technical Reference Manual. I'd like to understand whether this is indeed the way PHSEN is designed to operate within the EPWM module or if it only works in this project by some coincidence.
I have attached a new zip file that can be A/B tested to verify this behavior.
3187.test_epwm_sync.zip
Here, lines 645 to 655 are commented out and because PHSEN is set to 1 for all modules, the CMPA load on SYNCI behavior is as expected.
If you uncomment these lines (set PHSEN = 0 for all modules) the loading no longer works.
Best,
Rahul
Hi Rahul,
Appreciate the perseverance- glad you were able to get the desired output.
The PHSEN bit will determine whether the sync pulse is able to be used as a SYNC-IN source for the PWM, so this behavior aligns with the TRM when it mentions "Clearing the TBCTL[PHSEN] bit configures the ePWM to ignore the synchronization input pulse." The SYNC-IN pulse is what is used for the loading strobe.
However, it may not be clear in regard the SYNC signal being used for other register loading (beyond TBPHS). I will make a note for this to be clarified in this section in the future
Best Regards,
Allison
Hi Allison,
Appreciate the note to clarify this in the future. I interpreted the statement you're referring to about TBCTL as only applying to the TB submodule, not CC also. It appears from the explanation that TBCTL[PHSEN] configures all submodules within the EPWM module to ignore the SYNCIN pulse.
Best,
Rahul