C2000 HRPWM High Resolution Period and Duty

From Texas Instruments Wiki
Jump to: navigation, search

Introduction

This article discusses how to properly initialize the ePWM and HRPWM module to achieve high-resolution period and duty.

Electrical Specifications

Electrical specifications can change between devices, peripheral types and device families. Always refer to the data manual and errata for a particular device for Electrical Specifications.


C2000 ePWM and HRPWM Types

The C2000 Real-Time Control Peripherals Reference Guide (SPRU566) has a detailed summary of the different "types" of ePWM and HRPWM modules found on C28x devices and lists the associated reference manual for each. In this context a type change represents a functional feature difference in a peripheral module. Within a peripheral type, there may be minor differences between devices that do not affect the basic functionality of the module. These device-specific differences, if any, are also documented in SPRU566.

By knowing the peripheral "type" (i.e. type 0, type 1...) the user can determine which devices have which feature based ePWM and HRPWM.

Problem Statement

What is the proper way to configure the HRPWM for high-resolution duty and period control in up-down count (symmetric) mode? (Piccolo and newer devices)

Solution

The following provides all the steps necessary to correctly configure the PWM module/s for high-resolution duty and period control in up-down count mode. Failure to follow this procedure can result in unpredictable behavior.

// Disable TBCLKSYNC
    EALLOW;
        SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
    EDIS;
 
//Write To CMP, TBPRD, TBPHS registers.
    (*ePWM[j]).TBCTL.bit.PRDLD = TB_SHADOW;                 // set Shadow load
    (*ePWM[j]).TBPRD = period;                              // PWM frequency = 1/(2*TBPRD)
    (*ePWM[j]).CMPA.half.CMPA = period / 2;                 // set duty 50% initially
    (*ePWM[j]).CMPA.half.CMPAHR = (0 << 8);                 // initialize HRPWM extension
    (*ePWM[j]).TBPHS.all = 0;
 
//Configure modes, clock dividers and action qualifier
    (*ePWM[j]).TBCTR = 0;
    (*ePWM[j]).TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;         // Select up-down count mode
    (*ePWM[j]).TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
    (*ePWM[j]).TBCTL.bit.HSPCLKDIV = TB_DIV1;
    (*ePWM[j]).TBCTL.bit.CLKDIV = TB_DIV1;                  // TBCLK = SYSCLKOUT
    (*ePWM[j]).TBCTL.bit.FREE_SOFT = 00;
 
    (*ePWM[j]).CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;          // LOAD CMPA on CTR = 0
    (*ePWM[j]).CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    (*ePWM[j]).CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    (*ePWM[j]).CMPCTL.bit.SHDWBMODE = CC_SHADOW;
 
    (*ePWM[j]).AQCTLA.bit.CAU = AQ_SET;
    (*ePWM[j]).AQCTLA.bit.CAD = AQ_CLEAR;
    (*ePWM[j]).AQCTLB.bit.ZRO = AQ_SET
    (*ePWM[j]).AQCTLB.bit.PRD = AQ_CLEAR;
 
//Configure HRPWM registers
    EALLOW;
     (*ePWM[j]).HRCNFG.all = 0x0;
     (*ePWM[j]).HRCNFG.bit.EDGMODE = HR_BEP;                // MEP control on both edges
     (*ePWM[j]).HRCNFG.bit.CTLMODE = HR_CMP;                // CMPAHR and TBPRDHR HR control
     (*ePWM[j]).HRCNFG.bit.HRLOAD  = HR_CTR_ZERO_PRD;       // load on CTR = 0 and CTR = TBPRD
     (*ePWM[j]).HRCNFG.bit.AUTOCONV = 1;                    // Enable autoconversion
     (*ePWM[j]).HRPCTL.bit.HRPE = 1;                        // Turn on high-resolution period control
 
//set TBCTL[PHSEN] = 1
     (*ePWM[j]).TBCTL.bit.PHSEN = 1;
 
//set HRPCTL[TBPHSHRLOADE] = 1
     (*ePWM[j]).HRPCTL.bit.TBPHSHRLOADE = 1;
 
//Do the same to all other PWM modules
…
 
//Enable TBCLKSYNC
     SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
 
//Perform a software sync
     EPwm1Regs.TBCTL.bit.SWFSYNC = 1;//Disable TBCTL[PHSEN] and HRPCTL[TBPHSHRLOADE] if not needed by the application code