Beispiel #1
0
void epwmInit(int freq, int duty) {
	//InitGpio();
  	InitEPwmGpio();
	// EPWM Module 1 config
	EPwm1Regs.TBPRD = freq; // Period = 1500 TBCLK counts
	EPwm1Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero
	EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Symmetrical mode
	EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Master module
	EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;
	EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // Sync down-stream module
	EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
	EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
	EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR=Zero
	EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR=Zero
	EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // set actions for EPWM1A
	EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;
	EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module
	EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary
	EPwm1Regs.DBFED = 20; // FED = 20 TBCLKs  Target value = ~1us
	EPwm1Regs.DBRED = 20; // RED = 20 TBCLKs

	// EPWM Module 2 config
	EPwm2Regs.TBPRD = freq; // Period = 1500 TBCLK counts
	EPwm2Regs.TBPHS.half.TBPHS = 300; // Phase = 300/1500 * 360 = 120 deg
	EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Symmetrical mode
	EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Slave module
	EPwm2Regs.TBCTL.bit.PHSDIR = TB_DOWN; // Count DOWN on sync (=120 deg)
	EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;
	EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // sync flow-through
	EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
	EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
	EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR=Zero
	EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR=Zero
	EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; // set actions for EPWM2A
	EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR;
	EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module
	EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi Complementary
	EPwm2Regs.DBFED = 20; // FED = 20 TBCLKs
	EPwm2Regs.DBRED = 20; // RED = 20 TBCLKs

	EPwm1Regs.CMPA.half.CMPA = (freq / duty); // adjust duty for output EPWM1A
	EPwm2Regs.CMPA.half.CMPA = (freq / duty); // adjust duty for output EPWM2A
	return;
}
void main(void)
{
// Local variables
    int i;
    Uint32 temp;

// WARNING: Always ensure you call memcpy before running any functions from RAM
// InitSysCtrl includes a call to a RAM based function and without a call to
// memcpy first, the processor will go "into the weeds"
   #ifdef _FLASH
	memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
   #endif

// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the f2802x_SysCtrl.c file.
   InitSysCtrl();

// Step 2. Initialize GPIO:
// This example function is found in the f2802x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio();  // Skipped for this example
   InitEPwmGpio();

// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
   DINT;

// Initialize the PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the f2802x_PieCtrl.c file.
   InitPieCtrl();

// Disable CPU interrupts and clear all CPU interrupt flags:
   IER = 0x0000;
   IFR = 0x0000;

// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example.  This is useful for debug purposes.
// The shell ISR routines are found in f2802x_DefaultIsr.c.
// This function is found in f2802x_PieVect.c.
   InitPieVectTable();

// Step 4. Initialize all the Device Peripherals:
// Not required for this example

// For this example, only initialize the ePWM
// Step 5. User specific code, enable interrupts:
   UpdateFine = 1;
   DutyFine   = 0;
   status = SFO_INCOMPLETE;

// Calling SFO() updates the HRMSTEP register with calibrated MEP_ScaleFactor.
// MEP_ScaleFactor/HRMSTEP must be filled with calibrated value in order to
// use in equations below.
   while  (status== SFO_INCOMPLETE) // Call until complete
   {
       status = SFO();
       if (status == SFO_ERROR)
       {
           error();   // SFO function returns 2 if an error occurs & # of MEP
                      // steps/coarse step
       }              // exceeds maximum of 255.
   }


// Some useful Period vs Frequency values
//  SYSCLKOUT =     60 MHz       40 MHz
//  --------------------------------------
//  Period          Frequency    Frequency
//  1000            60 kHz       40 kHz
//  800             75 kHz       50 kHz
//  600             100 kHz      67 kHz
//  500             120 kHz      80 kHz
//  250             240 kHz      160 kHz
//  200             300 kHz      200 kHz
//  100             600 kHz      400 kHz
//  50              1.2 Mhz      800 kHz
//  25              2.4 Mhz      1.6 MHz
//  20              3.0 Mhz      2.0 MHz
//  12              5.0 MHz      3.3 MHz
//  10              6.0 MHz      4.0 MHz
//  9               6.7 MHz      4.4 MHz
//  8               7.5 MHz      5.0 MHz
//  7               8.6 MHz      5.7 MHz
//  6               10.0 MHz     6.6 MHz
//  5               12.0 MHz     8.0 MHz

//====================================================================
// ePWM and HRPWM register initialization
//====================================================================
   HRPWM_Config(10);        // ePWMx target
   EALLOW;

   for(;;)
   {
        // Sweep DutyFine as a Q15 number from 0.2 - 0.999
        for(DutyFine = 0x2300; DutyFine < 0x7000; DutyFine++)
        {
            if(UpdateFine)
            {
            /*
            // CMPA_reg_val is calculated as a Q0.
            // Since DutyFine is a Q15 number, and the period is Q0
            // the product is Q15. So to store as a Q0, we shift right
            // 15 bits.

            CMPA_reg_val = ((long)DutyFine * EPwm1Regs.TBPRD)>>15;

            // This next step is to obtain the remainder which was
            // truncated during our 15 bit shift above.
            // compute the whole value, and then subtract CMPA_reg_val
            // shifted LEFT 15 bits:
            temp = ((long)DutyFine * EPwm1Regs.TBPRD) ;
            temp = temp - ((long)CMPA_reg_val<<15);

            ** If auto-conversion is disabled, the following step can be skipped.
            // If autoconversion is enabled, the SFO function will write
            // the MEP_ScaleFactor to the HRMSTEP register and the hardware
            // will automatically scale the remainder in the CMPAHR register
            // by the MEP_ScaleFactor.
            // Because the remainder calculated above (temp) is in Q15 format,
            // it must be shifted left by 1 to convert to Q16 format for the
            // hardware to properly convert.
            CMPAHR_reg_val = temp<<1;

            ** If auto-conversion is enabled, the following step is performed
               automatically in hardware and can be skipped
            // This obtains the MEP count in digits, from
            // 0,1, .... MEP_Scalefactor.
            // 0x0080 (0.5 in Q8) is converted to 0.5 in Q15 by shifting left 7.
            // This is added to fractional duty*MEP_SF product in order to round
            // the decimal portion of the product up to the next integer if the decimal
            // portion is >=0.5.
            //
            //Once again since this is Q15
            // convert to Q0 by shifting:
            CMPAHR_reg_val = (temp*MEP_ScaleFactor+(0x0080<<7))>>15;

            ** If auto-conversion is enabled, the following step is performed
               automatically in hardware and can be skipped
            // Now the lower 8 bits contain the MEP count.
            // Since the MEP count needs to be in the upper 8 bits of
            // the 16 bit CMPAHR register, shift left by 8.
            CMPAHR_reg_val = CMPAHR_reg_val << 8;

            ** If auto-conversion is enabled, the following step is performed
               automatically in hardware and can be skipped
            // Add the offset and rounding
            CMPAHR_reg_val += 0x0080;

            // Write the values to the registers as one 32-bit or two 16-bits
            EPwm1Regs.CMPA.half.CMPA = CMPA_reg_val;
            EPwm1Regs.CMPA.half.CMPAHR = CMPAHR_reg_val;
            */

            // All the above operations may be condensed into
            // the following form:
            // EPWM1 calculations
                for(i=1;i<PWM_CH;i++)
                {
                    CMPA_reg_val = ((long)DutyFine * (*ePWM[i]).TBPRD)>>15;
                    temp = ((long)DutyFine * (*ePWM[i]).TBPRD) ;
                    temp = temp - ((long)CMPA_reg_val<<15);

                   #if (AUTOCONVERT)
                    CMPAHR_reg_val = temp<<1; // convert to Q16
                   #else

                    CMPAHR_reg_val = ((temp*MEP_ScaleFactor)+(0x0080<<7))>>15;
                    CMPAHR_reg_val = CMPAHR_reg_val << 8;
                   #endif

                   // Example for a 32 bit write to CMPA:CMPAHR
                    (*ePWM[i]).CMPA.all = ((long)CMPA_reg_val)<<16 | CMPAHR_reg_val; // loses lower 8-bits
                }
            }
            else
            {
            // CMPA_reg_val is calculated as a Q0.
            // Since DutyFine is a Q15 number, and the period is Q0
            // the product is Q15. So to store as a Q0, we shift right
            // 15 bits.
                for(i=1;i<PWM_CH;i++)
                {
                    (*ePWM[i]).CMPA.half.CMPA = ((long)DutyFine * (*ePWM[i]).TBPRD>>15);
                }
            }

        // Call the scale factor optimizer lib function SFO()
        // periodically to track for any change due to temp/voltage.
        // This function generates MEP_ScaleFactor by running the
        // MEP calibration module in the HRPWM logic. This scale
        // factor can be used for all HRPWM channels. The SFO()
        // function also updates the HRMSTEP register with the
        // scale factor value.

            status = SFO(); // in background, MEP calibration module continuously updates MEP_ScaleFactor
            if (status == SFO_ERROR)
            {
                error();   // SFO function returns 2 if an error occurs & # of MEP steps/coarse step
            }              // exceeds maximum of 255.
        } // end DutyFine for loop
    }     // end infinite for loop
Beispiel #3
0
//---------------------------------------------------------------------------
// InitEPwm: 
//---------------------------------------------------------------------------
// This function initializes the ePWM(s) to a known state.
//
void InitEPwm(void)
{
    InitEPwmGpio();

}
//
// Main
//
void main(void)
{
   EALLOW;
//
// Step 1. Initialize System Control for Control and Analog Subsystems
// Enable Peripheral Clocks
// This example function is found in the F2837xS_SysCtrl.c file.
//
    InitSysCtrl();
    EDIS;

    InitEPwmGpio();                   // EPWM1A and EPWM1B through all PWMS

    ePWM[1] = &EPwm1Regs;             // PWM Address Map
    ePWM[2] = &EPwm2Regs;             // PWM Address Map
    ePWM[3] = &EPwm3Regs;             // PWM Address Map
    ePWM[4] = &EPwm4Regs;             // PWM Address Map
    ePWM[5] = &EPwm5Regs;             // PWM Address Map
    ePWM[6] = &EPwm6Regs;             // PWM Address Map
    ePWM[7] = &EPwm7Regs;             // PWM Address Map
    ePWM[8] = &EPwm8Regs;             // PWM Address Map
    ePWM[9] = &EPwm9Regs;             // PWM Address Map

    InitEPwmGpio();                   // EPWM1A and EPWM1B -

    DINT; // Disable CPU interrupts

//
// Initialize PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
//

//
// This function is found in the F2837xS_PieCtrl.c file.
//
    InitPieCtrl();

//
// Disable CPU interrupts and clear all CPU interrupt flags:
//
    EALLOW;
    IER = 0x0000;
    IFR = 0x0000;

//
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example.  This is useful for debug purposes.
// The shell ISR routines are found in F2837xS_DefaultIsr.c.
// This function is found in F2837xS_PieVect.c.
//
    InitPieVectTable();

//
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
//
    EALLOW;  // This is needed to write to EALLOW protected registers
 // EDIS;   // This is needed to disable write to EALLOW protected registers

//
// Enable interrupts required for this example
//
    PieCtrlRegs.PIECTRL.bit.ENPIE = 1;   // Enable the PIE block
    IER = 0x400;                         // Enable CPU INT

//
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
//

//
// Step 5. User specific code, enable interrupts:
//
    update =1;
    DutyFine =0;

    EALLOW;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
    EDIS;

//
// EPwm and HRPWM register initialization
//
    HRPWM1_Config(30);         // EPwm1 target, Period = 10
    HRPWM2_Config(20);         // EPwm2 target, Period = 20
    HRPWM3_Config(20);         // EPwm3 target, Period = 10
    HRPWM4_Config(20);         // EPwm4 target, Period = 20
    HRPWM5_Config(20);         // EPwm1 target, Period = 10
    HRPWM6_Config(20);         // EPwm2 target, Period = 20
    HRPWM7_Config(20);         // EPwm3 target, Period = 10
    HRPWM8_Config(20);         // EPwm4 target, Period = 20

    EALLOW;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
    EDIS;

    while(update == 1)
    {
        //
        // Example, write to the HRPWM extension of CMPA / CMPB
        //
        EPwm1Regs.CMPA.bit.CMPAHR = DutyFine << 8;
        EPwm1Regs.CMPB.all = DutyFine << 8;
        EPwm2Regs.CMPA.bit.CMPAHR = DutyFine << 8;
        EPwm2Regs.CMPB.all = DutyFine << 8;

        //
        // Example, 32-bit write to CMPA:CMPAHR
        //
        EPwm3Regs.CMPA.all = ((Uint32)EPwm3Regs.CMPA.bit.CMPA << 16) +
                             (DutyFine << 8);
        EPwm3Regs.CMPB.all = DutyFine << 8;
        EPwm4Regs.CMPB.all = (DutyFine << 8);
        EPwm4Regs.CMPA.bit.CMPAHR = (DutyFine << 8);

        //
        // Example, write to the HRPWM extension of CMPA / CMPB
        //
        EPwm5Regs.CMPA.bit.CMPAHR = DutyFine << 8;
        EPwm5Regs.CMPB.all = DutyFine << 8;
        EPwm6Regs.CMPA.bit.CMPAHR = DutyFine << 8;
        EPwm6Regs.CMPB.all = DutyFine << 8;

        //
        // Example, write to the HRPWM extension of CMPA / CMPB
        //
        EPwm7Regs.CMPA.bit.CMPAHR = DutyFine << 8;
        EPwm7Regs.CMPB.all = DutyFine << 8;
        EPwm8Regs.CMPA.bit.CMPAHR = DutyFine << 8;
        EPwm8Regs.CMPB.all = DutyFine << 8;
    }

//
// Enable global Interrupts and higher priority real-time debug events:
//
    EINT;   // Enable Global interrupt INTM
    ERTM;   // Enable Global realtime interrupt DBGM

    for(;;); // Step 6. IDLE loop. Just sit and loop forever (optional):
}
void main(void)
{
// WARNING: Always ensure you call memcpy before running any functions from RAM
// InitSysCtrl includes a call to a RAM based function and without a call to
// memcpy first, the processor will go "into the weeds"
   #ifdef _FLASH
	memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
   #endif

// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the f2802x_SysCtrl.c file.
   InitSysCtrl();

// Step 2. Initialize GPIO:
// This example function is found in the f2802x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio();  // Skipped for this example
   InitEPwmGpio();

// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
   DINT;

// Initialize the PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the f2802x_PieCtrl.c file.
   InitPieCtrl();

// Disable CPU interrupts and clear all CPU interrupt flags:
   IER = 0x0000;
   IFR = 0x0000;

// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example.  This is useful for debug purposes.
// The shell ISR routines are found in f2802x_DefaultIsr.c.
// This function is found in f2802x_PieVect.c.
   InitPieVectTable();

// Step 4. Initialize all the Device Peripherals:
// Not required for this example

// For this example, only initialize the ePWM
// Step 5. User specific code, enable interrupts:

   // Calling SFO() updates the HRMSTEP register with calibrated MEP_ScaleFactor.
   // HRMSTEP must be populated with a scale factor value prior to enabling
   // high resolution period control.
   status = SFO_INCOMPLETE;
   while  (status== SFO_INCOMPLETE) // Call until complete
   {
       status = SFO();
       if (status == SFO_ERROR)
       {
           error();   // SFO function returns 2 if an error occurs & # of MEP
                      // steps/coarse step
       }              // exceeds maximum of 255.
   }

// Some useful PWM period vs Frequency values
//  TBCLK = 60 MHz
//===================
//  Period   Freq
//  1000     30 KHz
//  800    37.5 KHz
//  600      50 KHz
//  500      60 KHz
//  250     120 KHz
//  200     150 KHz
//  100     300 KHz
//  50      600 KHz
//  30        1 MHz
//  25      1.2 MHz
//  20      1.5 MHz
//  12      2.5 MHz
//  10        3 MHz
//  9       3.3 MHz
//  8       3.8 MHz
//  7       4.3 MHz
//  6       5.0 MHz
//  5       6.0 MHz

//====================================================================
// ePWM and HRPWM register initialization
//====================================================================
   Period = 500;
   PeriodFine=0xFFBF;
   HRPWM_Config(Period);

// Software Control variables
   Increment_Freq = 1;
   Increment_Freq_Fine = 1;
   IsrTicker = 0;
   UpdatePeriod = 0;
   UpdatePeriodFine = 0;

// User control variables:
   UpdateCoarse = 0;
   UpdateFine = 1;

// Reassign ISRs.
   EALLOW;	// This is needed to write to EALLOW protected registers
   PieVectTable.EPWM1_INT = &MainISR;
   EDIS;

// Enable PIE group 3 interrupt 1 for EPWM1_INT
   PieCtrlRegs.PIEIER3.bit.INTx1 = 1;

// Enable CNT_zero interrupt using EPWM1 Time-base
   EPwm1Regs.ETSEL.bit.INTEN = 1;   // Enable EPWM1INT generation
   EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;  // Enable interrupt CNT_zero event
   EPwm1Regs.ETPS.bit.INTPRD = 1;   // Generate interrupt on the 1st event
   EPwm1Regs.ETCLR.bit.INT = 1;     // Enable more interrupts

// Enable CPU INT3 for EPWM1_INT:
   IER |= M_INT3;

// Enable global Interrupts and higher priority real-time debug events:
   EINT;   // Enable Global interrupt INTM
   ERTM;	// Enable Global realtime interrupt DBGM

   EALLOW;
   EPwm1Regs.TBCTL.bit.SWFSYNC = 1;    // Synchronize high resolution phase to start HR period
   EDIS;

   for(;;)
   {
   		// The below code controls coarse edge movement
   		if(UpdateCoarse==1)
   		{
             if(Increment_Freq==1)           //Increase frequency to 600 kHz
             	Period= Period - 1;
             else
             	Period= Period + 1;          //Decrease frequency to 300 kHz

             if(Period<100 && Increment_Freq==1)
             	Increment_Freq=0;
             else if(Period>500 && Increment_Freq==0)
             	Increment_Freq=1;

             UpdatePeriod=1;
   		}

   		// The below code controls high-resolution fine edge movement
   		if(UpdateFine==1)
   		{
   			if(Increment_Freq_Fine==1)    // Increase high-resolution frequency
   				PeriodFine=PeriodFine-1;
   			else
   				PeriodFine=PeriodFine+1; // Decrement high-resolution frequency

   			if(PeriodFine<=0x3333 && Increment_Freq_Fine==1)
   				Increment_Freq_Fine=0;
   			else if(PeriodFine>= 0xFFBF && Increment_Freq_Fine==0)
   				Increment_Freq_Fine=1;

   			UpdatePeriodFine=1;
   		}

   		// Call the scale factor optimizer lib function SFO()
        // periodically to track for any change due to temp/voltage.
        // This function generates MEP_ScaleFactor by running the
        // MEP calibration module in the HRPWM logic. This scale
        // factor can be used for all HRPWM channels. HRMSTEP
        // register is automatically updated by the SFO function.

        status = SFO(); // in background, MEP calibration module continuously updates MEP_ScaleFactor
        if (status == SFO_ERROR)
        {
            error();   // SFO function returns 2 if an error occurs & # of MEP steps/coarse step
        }              // exceeds maximum of 255.
   }
}// end main
void main(void)
{
// WARNING: Always ensure you call memcpy before running any functions from RAM
// InitSysCtrl includes a call to a RAM based function and without a call to
// memcpy first, the processor will go "into the weeds"
   #ifdef _FLASH
	memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
   #endif

// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the f2802x_SysCtrl.c file.
   InitSysCtrl();

// Step 2. Initialize GPIO:
// This example function is found in the f2802x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio();  // Skipped for this example
   InitEPwmGpio();

// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
   DINT;

// Initialize the PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the f2802x_PieCtrl.c file.
   InitPieCtrl();

// Disable CPU interrupts and clear all CPU interrupt flags:
   IER = 0x0000;
   IFR = 0x0000;

// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example.  This is useful for debug purposes.
// The shell ISR routines are found in f2802x_DefaultIsr.c.
// This function is found in f2802x_PieVect.c.
   InitPieVectTable();

// Step 4. Initialize all the Device Peripherals:
// Not required for this example

// For this example, only initialize the ePWM
// Step 5. User specific code, enable interrupts:
   UpdateFine = 1;
   PeriodFine = 0;
   status = SFO_INCOMPLETE;

   // Calling SFO() updates the HRMSTEP register with calibrated MEP_ScaleFactor.
   // HRMSTEP must be populated with a scale factor value prior to enabling
   // high resolution period control.
   while  (status== SFO_INCOMPLETE) // Call until complete
   {
       status = SFO();
       if (status == SFO_ERROR)
       {
           error();   // SFO function returns 2 if an error occurs & # of MEP
                      // steps/coarse step
       }              // exceeds maximum of 255.
   }

// Some useful PWM period vs Frequency values
//  TBCLK = 60 MHz     40 MHz
//===============================
//  Period   Freq      Freq
//  1000     30 KHz    20 KHz
//  800    37.5 KHz    25 KHz
//  600      50 KHz    33 KHz
//  500      60 KHz    40 KHz
//  250     120 KHz    80 KHz
//  200     150 KHz   100 KHz
//  100     300 KHz   200 KHz
//  50      600 KHz   400 KHz
//  30        1 MHz   667 KHz
//  25      1.2 MHz   800 KHz
//  20      1.5 MHz     1 MHz
//  12      2.5 MHz   1.7 MHz
//  10        3 MHz     2 MHz
//  9       3.3 MHz   2.2 MHz
//  8       3.8 MHz   2.5 MHz
//  7       4.3 MHz   2.9 MHz
//  6       5.0 MHz   3.3 MHz
//  5       6.0 MHz   4.0 MHz

//====================================================================
// ePWM and HRPWM register initialization
//====================================================================
   HRPWM_Config(20);        // ePWMx target
   for(;;)
   {
        // Sweep PeriodFine as a Q16 number from 0.2 - 0.999
        for(PeriodFine = 0x3333; PeriodFine < 0xFFBF; PeriodFine++)
        {
            if(UpdateFine)
            {
            /*
            // Because auto-conversion is enabled, the desired
            // fractional period must be written directly to the
            // TBPRDHR (or TBPRDHRM) register in Q16 format
            // (lower 8-bits are ignored)

            EPwm1Regs.TBPRDHR = PeriodFine;

            // The hardware will automatically scale
            // the fractional period by the MEP_ScaleFactor
            // in the HRMSTEP register (which is updated
            // by the SFO calibration software).

            // Hardware conversion:
            // MEP delay movement = ((TBPRDHR(15:0) >> 8) *  HRMSTEP(7:0) + 0x80) >> 8

            */
                EPwm1Regs.TBPRDHR = PeriodFine; //In Q16 format
            }
            else
            {
                // No high-resolution movement on TBPRDHR.
                EPwm1Regs.TBPRDHR = 0;
            }

            // Call the scale factor optimizer lib function SFO(0)
            // periodically to track for any change due to temp/voltage.
            // This function generates MEP_ScaleFactor by running the
            // MEP calibration module in the HRPWM logic. This scale
            // factor can be used for all HRPWM channels. HRMSTEP
            // register is automatically updated by the SFO function.

            status = SFO(); // in background, MEP calibration module continuously updates MEP_ScaleFactor
            if (status == SFO_ERROR)
            {
                error();   // SFO function returns 2 if an error occurs & # of MEP steps/coarse step
            }              // exceeds maximum of 255.
        } // end PeriodFine for loop
    }     // end infinite for loop
}         // end main