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.

TMS320F28377S: Dual-Edge High Resolution Duty Cycle Control

Part Number: TMS320F28377S
Other Parts Discussed in Thread: TMS320F28075

Hi all,

I am trying to implement duty cycle control using the HRPWM functionality in the 28377S microcontroller.  I need to use up-down count mode in order as part of the average current mode control scheme I'm using in my interleaved buck converter.  Unfortunately I cannot get the high resolution edge control to work on both the rising and falling edges.  I found another set of posts (CCS/TMS320F28075: HrPWM Dual-edge Duty Mode) from 2-3 months ago but I couldn't find a useful conclusion from the posts.  I have a very similar HRPWM configuration function but I am not seeing the HRPWM functionality working unless I set my edge mode to be either rising or falling not both.  If anyone could provide any ideas as to why this is happening please let me know.  I need the high resolution control so any help I could get would be appreciated.

Lance

  • Hi Lance,

    If you have properly configured your HRPWM to be configured for dual edge control, then when you change the CMPAHR value you should see that delay applied to both edges of Channel B. When you change CMPBHR you will see that delay applied to both edges of Channel B. The naming is confusing, but as you probably read in the other thread that CMPAHR affects both edges of Channel A only, and CMPBHR affects both edges of Channel B only. This may or may not be your issue here, but that has been a common source of confusion in the past so wanted to bring that up.

    Could you provide the following:
    a) HRPWM configuration code
    b) Delay values in CMPBHR and a waveform of Channel A and/or Channel B as applicable from your oscilloscope

    Thanks!
    Kris
  • Hi Kris,

    I'm working on getting the scope captures and I'll post them later today.  For now I can post my configuration code for the EPWM/HRPWM modules.

    void Init_EPWM(void)
    {
       //
       // Setup TBCLK
       //
       //NOTE: The EPWM module for this processor has a built in hardware limitation on clock frequency of 60MHz to 100MHz for full functionality.
       //To handle this, an integer /2 of the main CPU clock is enabled by default in the register ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV
       EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up-down
       EPwm1Regs.TBPRD = EPWM_COUNT_PERIOD;       // Set timer period
       EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;    // Disable phase loading
       EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;// Used as sync signal for phase locked PWMs
       EPwm1Regs.TBPHS.bit.TBPHS = 0x0000;        // Phase is 0
       EPwm1Regs.TBCTR = 0x0000;                  // Clear counter
       EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;   // Clock ratio to SYSCLKOUT
       EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    
       //
       // Setup shadow register load on ZERO
       //
       EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
       EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
       EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
       EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
       //
       // Set Compare values
       //
       EPwm1Regs.CMPA.bit.CMPA = 0;             // Set Compare A value
       EPwm1Regs.CMPA.bit.CMPAHR = (1 << 8);
       EPwm1Regs.CMPB.bit.CMPB = 0;             // Set Compare B value
       EPwm1Regs.CMPB.bit.CMPBHR = (1 << 8);
       EPwm1Regs.CMPC = EPWM_ADC_SOC_COUNT;     // Set Compare C value
       EPwm1Regs.CMPD = EPWM_INTERRUPT_COUNT;   // Set Compare D value
    
       //
       // Set actions
       //
       EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;            // Set PWM1A on Zero
       EPwm1Regs.AQCTLA.bit.CAD = AQ_SET;    // Clear PWM1A on event A,
                                                     // up count
    
       EPwm1Regs.AQCTLB.bit.CBU = AQ_SET;            // Set PWM1B on Zero
       EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR;          // Clear PWM1B on event B,
                                                     // up count
       //
       // Setup Deadband (assumes non-inverted gate drive signals and EPWMxA as the source for both delays)
       // Presently creating dead band programmatically.  May need to use external deadband circuit to "steal" pulse width
       // That will allow the PWM module to stay in the (3, PERIOD-3) window at effective zero pulse width
       //
       /*EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
       EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
       EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL;
       EPwm1Regs.DBRED.bit.DBRED = 0x00A;	//100MHz EPWMCLK => 10ns per count, assume 100ns dead band to start
       EPwm1Regs.DBFED.bit.DBFED = 0x00A;	//100MHz EPWMCLK => 10ns per count, assume 100ns dead band to start*/
    
       //
       // Interrupt where we will change the Compare Values
       //
       EPwm1Regs.ETSEL.bit.INTSELCMP = 1;              // Select alternate compare source i.e. CMPC/CMPD
       EPwm1Regs.ETSEL.bit.INTSEL = ET_CTRD_CMPB;     // Select INT on CMPD down count
       EPwm1Regs.ETSEL.bit.INTEN = 1;                // Enable INT
       EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;           // Generate INT on 1st event
    
       //
       // Configure ADC SOCA signal
       //
       EPwm1Regs.ETSEL.bit.SOCASELCMP = 1;           //Use CMPC as ADC SOCA source
       EPwm1Regs.ETSEL.bit.SOCASEL = ET_CTRU_CMPA;   //ADC SOCA sent out on CMPC incrementing edge
       EPwm1Regs.ETSEL.bit.SOCAEN = 1;
       EPwm1Regs.ETPS.bit.SOCAPRD = ET_1ST;
    
       //
       //Configure High-Resolution PWM Registers
       //
       EALLOW;
       EPwm1Regs.HRCNFG.all = 0x0;
       EPwm1Regs.HRCNFG.bit.EDGMODE = HR_BEP;
       EPwm1Regs.HRCNFG.bit.CTLMODE = HR_CMP;
       EPwm1Regs.HRCNFG.bit.HRLOAD = HR_CTR_ZERO;
       EPwm1Regs.HRCNFG.bit.EDGMODEB = HR_BEP;
       EPwm1Regs.HRCNFG.bit.CTLMODEB = HR_CMP;
       EPwm1Regs.HRCNFG.bit.HRLOADB = HR_CTR_ZERO;
       EPwm1Regs.HRCNFG.bit.AUTOCONV = 0;
       EPwm1Regs.HRPCTL.bit.TBPHSHRLOADE = 1;
       EPwm1Regs.HRPCTL.bit.HRPE = 1;
       CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
       EPwm1Regs.TBCTL.bit.SWFSYNC = 1;
       EDIS;
    
       //
       // Configure Trip-Zone Module Registers
       //
       EALLOW;
       EPwm1Regs.TZCTL.all = 0xFFFF;
    #if HI_RES_CTRL
       EPwm1Regs.TZSEL.bit.CBC1 = TZ_ENABLE;        //Enable cycle by cycle trip zone functionality
       EPwm1Regs.TZCLR.bit.CBCPULSE = 0;            //Have cycle by cycle trip clear at zero count, unless the signal persists.
       EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO;
       EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_LO;
    #endif
       EDIS;
       if(DIPSWITCH_1_READ == TRUE){
       EALLOW;
       EPwm1Regs.TZSEL.bit.OSHT1 = TZ_ENABLE;
       EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO;
       EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_LO;
       EDIS;
       }
    
       //
       // Setup TBCLK
       //
       //NOTE: The EPWM module for this processor has a built in hardware limitation on clock frequency of 60MHz to 100MHz for full functionality.
       //To handle this, an integer /2 of the main CPU clock is enabled by default in the register ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV
       EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up-down
       EPwm2Regs.TBPRD = EPWM_COUNT_PERIOD;       // Set timer period
       EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE;    // Enable phase loading
       EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;// Pass on sync signal from master
       EPwm2Regs.TBPHS.bit.TBPHS = EPWM_PHASE_OFFSET_1;  // Phase is 90 degrees
       EPwm2Regs.TBCTR = 0x0000;                  // Clear counter
       EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;   // Clock ratio to SYSCLKOUT
       EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    
       //
       // Setup shadow register load on ZERO
       //
       EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
       EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
       EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
       EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
       //
       // Set Compare values
       //
       EPwm2Regs.CMPA.bit.CMPA = 0;     // Set compare A value
       EPwm2Regs.CMPA.bit.CMPAHR = (1 << 8);
       EPwm2Regs.CMPB.bit.CMPB = 0;     // Set Compare B value
       EPwm2Regs.CMPB.bit.CMPBHR = (1 << 8);
       EPwm2Regs.CMPC = EPWM_ADC_SOC_COUNT;     // Set Compare C value
       EPwm2Regs.CMPD = EPWM_INTERRUPT_COUNT;
       //
       // Set actions
       //
       EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;            // Set PWM1A on Zero
       EPwm2Regs.AQCTLA.bit.CAD = AQ_SET;          // Clear PWM1A on event A,
                                                     // up count
    
       EPwm2Regs.AQCTLB.bit.CBU = AQ_SET;            // Set PWM1B on Zero
       EPwm2Regs.AQCTLB.bit.CBD = AQ_CLEAR;          // Clear PWM1B on event B,
                                                     // up count
       //
       // Setup Deadband (assumes non-inverted gate drive signals and EPWMxA as the source for both delays)
       //
       /*EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
       EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
       EPwm2Regs.DBCTL.bit.IN_MODE = DBA_ALL;
       EPwm2Regs.DBRED.bit.DBRED = 0x00A;	//100MHz EPWMCLK => 10ns per count, assume 100ns dead band to start
       EPwm2Regs.DBFED.bit.DBFED = 0x00A;	//100MHz EPWMCLK => 10ns per count, assume 100ns dead band to start*/
    
       //
       // Interrupt where we will change the Compare Values
       //
       EPwm2Regs.ETSEL.bit.INTSELCMP = 1;
       EPwm2Regs.ETSEL.bit.INTSEL = ET_CTRD_CMPB;     // Select INT on CMPD down count
       EPwm2Regs.ETSEL.bit.INTEN = 1;                // Enable INT
       EPwm2Regs.ETPS.bit.INTPRD = ET_1ST;           // Generate INT on 1st event
    
       //
       // Configure ADC SOCA signal
       //
       EPwm2Regs.ETSEL.bit.SOCASELCMP = 1;           //Use CMPC as ADC SOCA source
       EPwm2Regs.ETSEL.bit.SOCASEL = ET_CTRU_CMPA;   //ADC SOCA sent out on CMPC incrementing edge
       EPwm2Regs.ETSEL.bit.SOCAEN = 1;
       EPwm2Regs.ETPS.bit.SOCAPRD = ET_1ST;
    
       //
       //Configure High-Resolution PWM Registers
       //
       EALLOW;
       EPwm2Regs.HRCNFG.all = 0x0;
       EPwm2Regs.HRCNFG.bit.EDGMODE = HR_BEP;
       EPwm2Regs.HRCNFG.bit.CTLMODE = HR_CMP;
       EPwm2Regs.HRCNFG.bit.HRLOAD = HR_CTR_ZERO;
       EPwm2Regs.HRCNFG.bit.EDGMODEB = HR_BEP;
       EPwm2Regs.HRCNFG.bit.CTLMODEB = HR_CMP;
       EPwm2Regs.HRCNFG.bit.HRLOADB = HR_CTR_ZERO;
       EPwm2Regs.HRCNFG.bit.AUTOCONV = 0;
       EPwm2Regs.HRPCTL.bit.TBPHSHRLOADE = 1;
       EPwm2Regs.HRPCTL.bit.HRPE = 1;
       CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
       EPwm2Regs.TBCTL.bit.SWFSYNC = 1;
       EDIS;
    
       //
       // Configure Trip-Zone Module Registers
       //
       EALLOW;
       EPwm2Regs.TZCTL.all = 0xFFFF;
    #if HI_RES_CTRL
       EPwm2Regs.TZSEL.bit.CBC1 = TZ_ENABLE;        //Enable cycle by cycle trip zone functionality
       EPwm2Regs.TZCLR.bit.CBCPULSE = 0;            //Have cycle by cycle trip clear at zero count, unless the signal persists.
       EPwm2Regs.TZCTL.bit.TZA = TZ_FORCE_LO;
       EPwm2Regs.TZCTL.bit.TZB = TZ_FORCE_LO;
    #endif
       EDIS;
       if(DIPSWITCH_2_READ == TRUE){
       EALLOW;
       EPwm2Regs.TZSEL.bit.OSHT1 = TZ_ENABLE;
       EPwm2Regs.TZCTL.bit.TZA = TZ_FORCE_LO;
       EPwm2Regs.TZCTL.bit.TZB = TZ_FORCE_LO;
       EDIS;
       }
    
       //
       // Setup TBCLK
       //
       //NOTE: The EPWM module for this processor has a built in hardware limitation on clock frequency of 60MHz to 100MHz for full functionality.
       //To handle this, an integer /2 of the main CPU clock is enabled by default in the register ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV
       EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up-down
       EPwm3Regs.TBPRD = EPWM_COUNT_PERIOD;       // Set timer period
       EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE;    // Enable phase loading
       EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;// Pass on sync signal from master
       EPwm3Regs.TBPHS.bit.TBPHS = EPWM_PHASE_OFFSET_2;  // Phase is 180 degrees
       EPwm3Regs.TBCTR = 0x0000;                  // Clear counter
       EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;   // Clock ratio to SYSCLKOUT
       EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    
       //
       // Setup shadow register load on ZERO
       //
       EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
       EPwm3Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
       EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
       EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
       //
       // Set Compare values
       //
       EPwm3Regs.CMPA.bit.CMPA = 0;     // Set compare A value
       EPwm3Regs.CMPA.bit.CMPAHR = (1 << 8);
       EPwm3Regs.CMPB.bit.CMPB = 0;     // Set Compare B value
       EPwm3Regs.CMPB.bit.CMPBHR = (1 << 8);
       EPwm3Regs.CMPC = EPWM_ADC_SOC_COUNT;     // Set Compare C value
       EPwm3Regs.CMPD = EPWM_INTERRUPT_COUNT;
    
       //
       // Set actions
       //
       EPwm3Regs.AQCTLA.bit.CAU = AQ_CLEAR;            // Set PWM1A on Zero
       EPwm3Regs.AQCTLA.bit.CAD = AQ_SET;          // Clear PWM1A on event A,
                                                     // up count
    
       EPwm3Regs.AQCTLB.bit.CBU = AQ_SET;            // Set PWM1B on Zero
       EPwm3Regs.AQCTLB.bit.CBD = AQ_CLEAR;          // Clear PWM1B on event B,
                                                     // up count
       //
       // Setup Deadband (assumes non-inverted gate drive signals and EPWMxA as the source for both delays)
       //
       /*EPwm3Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
       EPwm3Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
       EPwm3Regs.DBCTL.bit.IN_MODE = DBA_ALL;
       EPwm3Regs.DBRED.bit.DBRED = 0x00A;	//100MHz EPWMCLK => 10ns per count, assume 100ns dead band to start
       EPwm3Regs.DBFED.bit.DBFED = 0x00A;	//100MHz EPWMCLK => 10ns per count, assume 100ns dead band to start*/
    
       //
       // Interrupt where we will change the Compare Values
       //
       EPwm3Regs.ETSEL.bit.INTSELCMP = 1;
       EPwm3Regs.ETSEL.bit.INTSEL = ET_CTRD_CMPB;     // Select INT on CMPD down count
       EPwm3Regs.ETSEL.bit.INTEN = 1;                // Enable INT
       EPwm3Regs.ETPS.bit.INTPRD = ET_1ST;           // Generate INT on 1st event
    
       //
       // Configure ADC SOCA signal
       //
       EPwm3Regs.ETSEL.bit.SOCASELCMP = 1;           //Use CMPC as ADC SOCA source
       EPwm3Regs.ETSEL.bit.SOCASEL = ET_CTRU_CMPA;   //ADC SOCA sent out on CMPC incrementing edge
       EPwm3Regs.ETSEL.bit.SOCAEN = 1;
       EPwm3Regs.ETPS.bit.SOCAPRD = ET_1ST;
    
       //
       //Configure High-Resolution PWM Registers
       //
       EALLOW;
       EPwm3Regs.HRCNFG.all = 0x0;
       EPwm3Regs.HRCNFG.bit.EDGMODE = HR_BEP;
       EPwm3Regs.HRCNFG.bit.CTLMODE = HR_CMP;
       EPwm3Regs.HRCNFG.bit.HRLOAD = HR_CTR_ZERO;
       EPwm3Regs.HRCNFG.bit.EDGMODEB = HR_BEP;
       EPwm3Regs.HRCNFG.bit.CTLMODEB = HR_CMP;
       EPwm3Regs.HRCNFG.bit.HRLOADB = HR_CTR_ZERO;
       EPwm3Regs.HRCNFG.bit.AUTOCONV = 0;
       EPwm3Regs.HRPCTL.bit.TBPHSHRLOADE = 1;
       EPwm3Regs.HRPCTL.bit.HRPE = 1;
       CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
       EPwm3Regs.TBCTL.bit.SWFSYNC = 1;
       EDIS;
    
       //
       // Configure Trip-Zone Module Registers
       //
       EALLOW;
       EPwm3Regs.TZCTL.all = 0xFFFF;
    #if HI_RES_CTRL
       EPwm3Regs.TZSEL.bit.CBC1 = TZ_ENABLE;        //Enable cycle by cycle trip zone functionality
       EPwm3Regs.TZCLR.bit.CBCPULSE = 0;            //Have cycle by cycle trip clear at zero count, unless the signal persists.
       EPwm3Regs.TZCTL.bit.TZA = TZ_FORCE_LO;
       EPwm3Regs.TZCTL.bit.TZB = TZ_FORCE_LO;
    #endif
       EDIS;
       if(DIPSWITCH_3_READ == TRUE){
       EALLOW;
       EPwm3Regs.TZSEL.bit.OSHT1 = TZ_ENABLE;
       EPwm3Regs.TZCTL.bit.TZA = TZ_FORCE_LO;
       EPwm3Regs.TZCTL.bit.TZB = TZ_FORCE_LO;
       EDIS;
       }
    
       //
       // Setup TBCLK
       //
       //NOTE: The EPWM module for this processor has a built in hardware limitation on clock frequency of 60MHz to 100MHz for full functionality.
       //To handle this, an integer /2 of the main CPU clock is enabled by default in the register ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV
       EPwm4Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up-down
       EPwm4Regs.TBPRD = EPWM_COUNT_PERIOD;       // Set timer period
       EPwm4Regs.TBCTL.bit.PHSEN = TB_ENABLE;    // Enable phase loading
       EPwm4Regs.TBCTL.bit.PHSDIR = TB_UP;	// Count down to achieve 270 degree phase shift
       EPwm4Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;// Pass on sync signal from master
       EPwm4Regs.TBPHS.bit.TBPHS = EPWM_PHASE_OFFSET_3;  // Phase is 270 degrees (Note: Reversed count direction i.e. 360-90=270 degrees)
       EPwm4Regs.TBCTR = 0x0000;                  // Clear counter
       EPwm4Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;   // Clock ratio to SYSCLKOUT
       EPwm4Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    
       //
       // Setup shadow register load on ZERO
       //
       EPwm4Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
       EPwm4Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
       EPwm4Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
       EPwm4Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
       //
       // Set Compare values
       //
       EPwm4Regs.CMPA.bit.CMPA = 0;     // Set compare A value
       EPwm4Regs.CMPA.bit.CMPAHR = (1 << 8);
       EPwm4Regs.CMPB.bit.CMPB = 0;     // Set Compare B value
       EPwm4Regs.CMPB.bit.CMPBHR = (1 << 8);
       EPwm4Regs.CMPC = EPWM_ADC_SOC_COUNT;     // Set Compare C value
       EPwm4Regs.CMPD = EPWM_INTERRUPT_COUNT;
    
       //
       // Set actions
       //
       EPwm4Regs.AQCTLA.bit.CAU = AQ_CLEAR;            // Set PWM1A on Zero
       EPwm4Regs.AQCTLA.bit.CAD = AQ_SET;          // Clear PWM1A on event A,
                                                     // up count
    
       EPwm4Regs.AQCTLB.bit.CBU = AQ_SET;            // Set PWM1B on Zero
       EPwm4Regs.AQCTLB.bit.CBD = AQ_CLEAR;          // Clear PWM1B on event B,
                                                     // up count
       //
       // Setup Deadband (assumes non-inverted gate drive signals and EPWMxA as the source for both delays)
       //
       /*EPwm4Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
       EPwm4Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
       EPwm4Regs.DBCTL.bit.IN_MODE = DBA_ALL;
       EPwm4Regs.DBRED.bit.DBRED = 0x00A;	//100MHz EPWMCLK => 10ns per count, assume 100ns dead band to start
       EPwm4Regs.DBFED.bit.DBFED = 0x00A;	//100MHz EPWMCLK => 10ns per count, assume 100ns dead band to start*/
    
       //
       // Interrupt where we will change the Compare Values
       //
       EPwm4Regs.ETSEL.bit.INTSELCMP = 1;
       EPwm4Regs.ETSEL.bit.INTSEL = ET_CTRD_CMPB;     // Select INT on CMPD down count
       EPwm4Regs.ETSEL.bit.INTEN = 1;                // Enable INT
       EPwm4Regs.ETPS.bit.INTPRD = ET_1ST;           // Generate INT on 1st event
    
       //
       // Configure ADC SOCA signal
       //
       EPwm4Regs.ETSEL.bit.SOCASELCMP = 1;           //Use CMPC as ADC SOCA source
       EPwm4Regs.ETSEL.bit.SOCASEL = ET_CTRU_CMPA;   //ADC SOCA sent out on CMPC incrementing edge
       EPwm4Regs.ETSEL.bit.SOCAEN = 1;
       EPwm4Regs.ETPS.bit.SOCAPRD = ET_1ST;
    
       //
       //Configure High-Resolution PWM Registers
       //
       EALLOW;
       EPwm4Regs.HRCNFG.all = 0x0;
       EPwm4Regs.HRCNFG.bit.EDGMODE = HR_BEP;
       EPwm4Regs.HRCNFG.bit.CTLMODE = HR_CMP;
       EPwm4Regs.HRCNFG.bit.HRLOAD = HR_CTR_ZERO;
       EPwm4Regs.HRCNFG.bit.EDGMODEB = HR_BEP;
       EPwm4Regs.HRCNFG.bit.CTLMODEB = HR_CMP;
       EPwm4Regs.HRCNFG.bit.HRLOADB = HR_CTR_ZERO;
       EPwm4Regs.HRCNFG.bit.AUTOCONV = 0;
       EPwm4Regs.HRPCTL.bit.TBPHSHRLOADE = 1;
       EPwm4Regs.HRPCTL.bit.HRPE = 1;
       CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
       EPwm4Regs.TBCTL.bit.SWFSYNC = 1;
       EDIS;
    
       //
       // Configure Trip-Zone Module Registers
       //
       EALLOW;
       EPwm4Regs.TZCTL.all = 0xFFFF;
    #if HI_RES_CTRL
       EPwm4Regs.TZSEL.bit.CBC1 = TZ_ENABLE;        //Enable cycle by cycle trip zone functionality
       EPwm4Regs.TZCLR.bit.CBCPULSE = 0;            //Have cycle by cycle trip clear at zero count, unless the signal persists.
       EPwm4Regs.TZCTL.bit.TZA = TZ_FORCE_LO;
       EPwm4Regs.TZCTL.bit.TZB = TZ_FORCE_LO;
    #endif
       EDIS;
       if(DIPSWITCH_4_READ == TRUE){
       EALLOW;
       EPwm4Regs.TZSEL.bit.OSHT1 = TZ_ENABLE;
       EPwm4Regs.TZCTL.bit.TZA = TZ_FORCE_LO;
       EPwm4Regs.TZCTL.bit.TZB = TZ_FORCE_LO;
       EDIS;
       }
    
    #if CLA_BENCHMARK
       //Setup TBCLK Registers
       EPwm5Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
       EPwm5Regs.TBPRD = 0xFFFF;       // Set timer period
       EPwm5Regs.TBCTL.bit.PHSEN = TB_DISABLE;    // Enable phase loading
       EPwm5Regs.TBPHS.bit.TBPHS = 0x0000;  // Phase is 0 degrees
       EPwm5Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;   // Clock ratio to SYSCLKOUT
       EPwm5Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    #endif
    }

  • Hi Kris,

    I changed my code to set the HRPE registers to zero, which isn't the same as what I posted earlier. I have been working on capturing screenshots, but they haven't been very useful. Basically all I see is roughly 10ns jumps in the pulse width, not anything remotely close to 150ps of resolution. It seems like the HRPWM/MEP isn't doing anything at all.

    Lance
  • Hi Lance,

    I compared your code with the working example I posted in the other thread you referenced (attached again here for convenience).  It looks like the differences between the code are the AUTOCONVERT and HRPE values.  Here's the important segments:

               EALLOW;

               (*ePWM[j]).HRCNFG.all = 0x0;

               (*ePWM[j]).HRCNFG.bit.EDGMODE = HR_BEP;  // MEP control on falling edge

               (*ePWM[j]).HRCNFG.bit.CTLMODE = HR_CMP;

               (*ePWM[j]).HRCNFG.bit.HRLOAD  = HR_CTR_ZERO;

               (*ePWM[j]).HRCNFG.bit.EDGMODEB = HR_BEP; // MEP control on falling edge

               (*ePWM[j]).HRCNFG.bit.CTLMODEB = HR_CMP;

               (*ePWM[j]).HRCNFG.bit.HRLOADB  = HR_CTR_ZERO;

               #if (AUTOCONVERT)

               (*ePWM[j]).HRCNFG.bit.AUTOCONV = 1;      // Enable auto-conversion

                                                        // logic

              #endif

               (*ePWM[j]).HRPCTL.bit.HRPE = 0; // Turn off high-resolution period

                                               // control.

               (*ePWM[j]).CMPA.bit.CMPAHR = 0x3333;

               (*ePWM[j]).CMPB.bit.CMPBHR = 0x5555;

               EDIS;

    Can you try modifying those values and see if that makes any difference? If not, I'd recommend to run the example project and make sure you see the fine edge movements.

    Regards,

    Kris

    2161.hrpwm_duty_sfo_v8_e2e.c
    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    //###########################################################################
    //
    // FILE: HRPWM_Duty_SFO_V8_e2e.c
    //
    // TITLE: F2837xD Device HRPWM SFO V8 High-Resolution Period
    // (Up-Down Count) example
    //!
    //! Monitor ePWM6 A/B pins on an oscilloscope.
    //! Monitor a different EPWM A/B channels to
    //! compare the edge displacement to (any ePWM 1-8 will work).
    //!
    //! DESCRIPTION:
    //!
    //! This example has been modified to show dual edge displacement on the A and B
    //! channels of EPWM-6.
    //!
    //!
    //! \b int \b SFO(); \n
    //! updates MEP_ScaleFactor dynamically when HRPWM is in use
    //! updates HRMSTEP register (exists only in EPwm1Regs register space)
    //! with MEP_ScaleFactor value
    //! - returns 2 if error: MEP_ScaleFactor is greater than maximum value of 255
    //! (Auto-conversion may not function properly under this condition)
    //! - returns 1 when complete for the specified channel
    //! - returns 0 if not complete for the specified channel
    //!
    //! This example is intended to explain the HRPWM capabilities. The code can be
    //! optimized for code efficiency. Refer to TI's Digital power application
    //! examples and TI Digital Power Supply software libraries for details.
    //!
    //! All ePWM1 -7 all channels will have fine
    //! edge movement due to the HRPWM logic
    //!
    //! =======================================================================
    //! NOTE: For more information on using the SFO software library, see the
    //! F2837xD High-Resolution Pulse Width Modulator (HRPWM) Reference Guide
    //! =======================================================================
    //
    // Included Files
    //
    #include "F28x_Project.h"
    #include "SFO_V8.h"
    //
    // Defines
    //
    #define PWM_CH 9 // # of PWM channels
    #define STATUS_SUCCESS 1
    #define STATUS_FAIL 0
    #define AUTOCONVERT 0 // 1 = Turn auto-conversion ON
    // 0 = Turn auto-conversion OFF
    //
    // Globals
    //
    Uint16 UpdateFine;
    Uint16 DutyFine;
    Uint16 status;
    Uint16 CMPA_reg_val;
    Uint16 CMPAHR_reg_val;
    Uint16 CMPB_reg_val;
    Uint16 CMPBHR_reg_val;
    int MEP_ScaleFactor; // Global variable used by the SFO library
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • Hi Kris,

    I will try doing that. I have already modified by code set the HRPE registers to 0. That didn't seem to do anything. I was hoping not to use the AUTOCONV settings; I already have my ISR automatically calculating the proper CMPAHR/CMPBHR values assuming 150ps steps. I will let you know if using the AUTOCONV setting does anything.

    Best regards,

    Lance
  • Hi Kris,

    I was unable to get the dual edge HRPWM control to work. I tried sweeping through the HRPWM values with a fixed CMPA/CMPB setting, and with dual edge control the duty cycle would not change at all no matter what settings or values put in the CMPxHR registers. I switched the EPWMxA to the falling edge controlled and EPWMxB to be rising edge controlled. This works well enough for my needs, and I validated the HRPWM functionality was working. Thanks for all of the help.

    Lance
  • Lance,

    Sorry to hear these modifications didn't get you up and running with dual edge control. I can get your code loaded onto a device next week and see if I can locate the issue.

    Regards,
    Kris
  • Hi Lance,

    Good news. I got your code loaded and it seems to be working. I've attached the C file (sorry in advance, it was a quick patch for testing it out).  I made a few minor tweaks just for ease of comparison, but those can be reverted in your system to the original.

    To test, scope PWM1A and anything other PWM A channel on a PWM2-8 (I'm using EPWM6A). When you run, you should see a edge shift of about 8 ns on both edges of the signal. 

    After you verify that edge shift is there, go change EPwm1Regs.CMPA.bit.CMPAHR to 0. You should now see the PWM1A edges shift back to alignment with the other PWM.

    Let me know if you have any issues. Code attached.

    Regards,

    Kris

    e2e_updown_hr.c
    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    //###########################################################################
    //
    // FILE: HRPWM_Duty_SFO_V8_e2e.c
    //
    // TITLE: F2837xD Device HRPWM SFO V8 High-Resolution Period
    // (Up-Down Count) example
    //!
    //! Monitor ePWM6 A/B pins on an oscilloscope.
    //! Monitor a different EPWM A/B channels to
    //! compare the edge displacement to (any ePWM 1-8 will work).
    //!
    //! DESCRIPTION:
    //!
    //! This example has been modified to show dual edge displacement on the A and B
    //! channels of EPWM-6.
    //!
    //!
    //! \b int \b SFO(); \n
    //! updates MEP_ScaleFactor dynamically when HRPWM is in use
    //! updates HRMSTEP register (exists only in EPwm1Regs register space)
    //! with MEP_ScaleFactor value
    //! - returns 2 if error: MEP_ScaleFactor is greater than maximum value of 255
    //! (Auto-conversion may not function properly under this condition)
    //! - returns 1 when complete for the specified channel
    //! - returns 0 if not complete for the specified channel
    //!
    //! This example is intended to explain the HRPWM capabilities. The code can be
    //! optimized for code efficiency. Refer to TI's Digital power application
    //! examples and TI Digital Power Supply software libraries for details.
    //!
    //! All ePWM1 -7 all channels will have fine
    //! edge movement due to the HRPWM logic
    //!
    //! =======================================================================
    //! NOTE: For more information on using the SFO software library, see the
    //! F2837xD High-Resolution Pulse Width Modulator (HRPWM) Reference Guide
    //! =======================================================================
    //
    // Included Files
    //
    #include "F28x_Project.h"
    #include "SFO_V8.h"
    //
    // Defines
    //
    #define PWM_CH 9 // # of PWM channels
    #define STATUS_SUCCESS 1
    #define STATUS_FAIL 0
    #define AUTOCONVERT 0 // 1 = Turn auto-conversion ON
    // 0 = Turn auto-conversion OFF
    //
    // Globals
    //
    Uint16 UpdateFine;
    Uint16 DutyFine;
    Uint16 status;
    Uint16 CMPA_reg_val;
    Uint16 CMPAHR_reg_val;
    Uint16 CMPB_reg_val;
    Uint16 CMPBHR_reg_val;
    int MEP_ScaleFactor; // Global variable used by the SFO library
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX