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
//--------------------------------------------------------------------------- // 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