Tool/software:
Hello
I'm using the F280049C for my application, where I need to precisely control the high-resolution deadband between two submodules (EPWM1 and EPWM2). However, I'm unable to utilize the high-resolution (HR) capabilities of the deadband module. Additionally, there are no example codes available for the F280049C that demonstrate the use of an HR headband, nor is there any suggestion available in this forum using this HR capability of the deadband.
I have successfully generated an HRPWM signal and modified the duty cycle without any issues. However, I have not been able to achieve high-resolution control in the deadband module, as it appears to be limited to a 5ns resolution.
If you could provide examples or guidance on implementing HR deadband capabilities in the F280049C, it would greatly help in resolving this issue.
Hi Akash,
Let me find something for you. Please give me till end of day tomorrow.
Best,
Ryan Ma
Hi Akash,
Please find the .c and syscfg used to show deadband hr functionality. Since the DBHR only runs in half cycle mode if the TBCLK is 10nsec, then maximum sweep it can do with high resolution is 5nsec beyond which you can use mix for db and dbhr extension registers to achieve the required deadband
You can open ex1 for hrpwm and manually edit the syscfg file and .c from below and run.
//############################################################################# // // FILE: hrpwm_ex11_dbhr_sfo.c // // TITLE: HRPWM DB HR Control with SFO in Up-down count mode. // //! \addtogroup driver_example_list //! <h1>HRPWM Deadband Control with SFO</h1> //! //! This example modifies the MEP control registers to show edge displacement //! for high-resolution deadband control with ePWM in Up down count mode //! due to the HRPWM control extension of the respective ePWM module. //! //! This example calls the following TI's MEP Scale Factor Optimizer (SFO) //! software library V8 functions: //! //! \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 only uses 2 EPWMs. If all the EPWMs modules are being used //! then all the 3 HRPWMCAL modules should be caliberated. Here only one is //! being caliberated. For more details you can refer to the bitfield example //! C2000Ware\device_support\f28p65x\examples\cpu1\hrpwm_ex1_duty_sfo_v8. //! 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. //! //! \b External \b Connections \n //! - Monitor ePWM1/2 A/B pins on an oscilloscope. Both ePWM1 and ePWM2 are in active high complementary mode but only ePWM2 has deadband hr enabled. //! - Compare ePWM1A and ePWM2A to see how RED HR is applied on ePWM2A. //! - Compare ePWM1B and ePWM2B to see how FED HR is applied on the original signal to see an effective RED HR (due to inversion) on the inverted signal. // //############################################################################# // // // $Copyright: $ //############################################################################# // // Included Files // #include "board.h" #include "sfo_v8.h" // // Defines // #define EPWM_TIMER_TBPRD 100UL // // Globals // uint16_t dbfine = 2; uint16_t status; int MEP_ScaleFactor; // Global variable used by the SFO library // Result can be used for all HRPWM channels // This variable is also copied to HRMSTEP // register by SFO() function. volatile uint32_t ePWM[] = {0, myEPWM1_BASE, myEPWM2_BASE}; // //#####BEGIN_F28P65X##### // extern volatile uint32_t gHrpwmCal_base; // //#####END_F28P65X##### // // Function Prototypes // void error(void); // // Main // void main(void) { // // Initialize device clock and peripherals // Device_init(); // // Disable pin locks and enable internal pull ups. // Device_initGPIO(); // // Initialize PIE and clear PIE registers. Disables CPU interrupts. // Interrupt_initModule(); // // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // Interrupt_initVectorTable(); // //#####BEGIN_F28P65X##### // // // // We are only required to calibrate HRPWMCAL1 as we using EPWMs between 1-8. // // // gHrpwmCal_base = HRPWMCAL1_BASE; // //#####END_F28P65X##### // // 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) { status = SFO(); if(status == SFO_ERROR) { error(); // SFO function returns 2 if an error occurs & # of MEP } // steps/coarse step exceeds maximum of 255. } // // Disable sync(Freeze clock to PWM as well) // SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC); // // Initialize the EPWM GPIO Pins and change the XBAR inputs from using GPIO0 // Board_init(); //Set initial phase shift EPWM_setPhaseShift(myEPWM2_BASE, 2); // // Enable sync and clock to PWM // SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC); // // Enable Global Interrupt (INTM) and realtime interrupt (DBGM) // EINT; ERTM; for(;;) { // // Sweep DB Fine // for(dbfine = 2; dbfine < 127; dbfine += 1) { DEVICE_DELAY_US(100000); // Update DB RED & FED for ePWM2 instance only HRPWM_setRisingEdgeDelay(ePWM[2], dbfine); HRPWM_setFallingEdgeDelay(ePWM[2],dbfine); // // 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. } } } // // error - Halt debugger when called // void error (void) { ESTOP0; // Stop here and handle error }
/** * Import the modules used in this configuration. */ const epwm = scripting.addModule("/driverlib/epwm.js", {}, false); const epwm1 = epwm.addInstance(); const epwm2 = epwm.addInstance(); /** * Write custom configuration values to the imported modules. */ epwm1.$name = "myEPWM1"; epwm1.epwmTimebase_emulationMode = "EPWM_EMULATION_FREE_RUN"; epwm1.epwmTimebase_hsClockDiv = "EPWM_HSCLOCK_DIVIDER_1"; epwm1.hrpwm_cmpaHR = 50; epwm1.hrpwm_cmpbHR = 50; epwm1.epwmTimebase_counterMode = "EPWM_COUNTER_MODE_UP_DOWN"; epwm1.epwmTimebase_counterModeAfterSync = "EPWM_COUNT_MODE_UP_AFTER_SYNC"; epwm1.epwmCounterCompare_cmpA = 50; epwm1.epwmTimebase_syncOutPulseMode = "EPWM_SYNC_OUT_PULSE_DISABLED"; epwm1.epwmActionQualifier_EPWM_AQ_OUTPUT_A_ON_TIMEBASE_UP_CMPA = "EPWM_AQ_OUTPUT_HIGH"; epwm1.epwmActionQualifier_EPWM_AQ_OUTPUT_A_ON_TIMEBASE_DOWN_CMPA = "EPWM_AQ_OUTPUT_LOW"; epwm1.epwmTimebase_period = 100; epwm1.epwmDeadband_enableRED = true; epwm1.epwmDeadband_polarityFED = "EPWM_DB_POLARITY_ACTIVE_LOW"; epwm1.epwmDeadband_inputFED = "EPWM_DB_INPUT_EPWMB"; epwm1.epwmDeadband_enableFED = true; epwm1.epwmActionQualifier_EPWM_AQ_OUTPUT_B_ON_TIMEBASE_UP_CMPB = "EPWM_AQ_OUTPUT_HIGH"; epwm1.epwmActionQualifier_EPWM_AQ_OUTPUT_B_ON_TIMEBASE_DOWN_CMPB = "EPWM_AQ_OUTPUT_LOW"; epwm1.epwmCounterCompare_cmpB = 50; epwm1.epwm.$assign = "EPWM1"; epwm1.epwm.epwm_aPin.$assign = "GPIO0"; epwm1.epwm.epwm_bPin.$assign = "GPIO1"; epwm2.$name = "myEPWM2"; epwm2.epwmTimebase_emulationMode = "EPWM_EMULATION_FREE_RUN"; epwm2.epwmTimebase_period = 100; epwm2.hrpwm_enable = true; epwm2.hrpwm_autoConv = true; epwm2.epwmCounterCompare_cmpA = 50; epwm2.epwmCounterCompare_cmpB = 50; epwm2.epwmTimebase_hsClockDiv = "EPWM_HSCLOCK_DIVIDER_1"; epwm2.epwmTimebase_counterMode = "EPWM_COUNTER_MODE_UP_DOWN"; epwm2.epwmTimebase_counterModeAfterSync = "EPWM_COUNT_MODE_UP_AFTER_SYNC"; epwm2.epwmCounterCompare_cmpA = 50; epwm2.epwmActionQualifier_EPWM_AQ_OUTPUT_A_ON_TIMEBASE_UP_CMPA = "EPWM_AQ_OUTPUT_HIGH"; epwm2.epwmActionQualifier_EPWM_AQ_OUTPUT_A_ON_TIMEBASE_DOWN_CMPA = "EPWM_AQ_OUTPUT_LOW"; epwm2.epwmDeadband_enableRED = true; epwm2.epwmDeadband_deadbandCounterClockRate = "EPWM_DB_COUNTER_CLOCK_HALF_CYCLE"; epwm2.hrpwm_edgeModeDB = "HRPWM_DB_MEP_CTRL_RED_FED"; epwm2.epwmActionQualifier_EPWM_AQ_OUTPUT_B_ON_TIMEBASE_UP_CMPB = "EPWM_AQ_OUTPUT_HIGH"; epwm2.epwmActionQualifier_EPWM_AQ_OUTPUT_B_ON_TIMEBASE_DOWN_CMPB = "EPWM_AQ_OUTPUT_LOW"; epwm2.epwmCounterCompare_cmpB = 50; epwm2.epwmDeadband_polarityFED = "EPWM_DB_POLARITY_ACTIVE_LOW"; epwm2.epwmDeadband_inputFED = "EPWM_DB_INPUT_EPWMB"; epwm2.epwmDeadband_enableFED = true; epwm2.epwmTimebase_phaseEnable = true; epwm2.epwm.$assign = "EPWM2"; epwm2.epwm.epwm_aPin.$assign = "GPIO2"; epwm2.epwm.epwm_bPin.$assign = "GPIO3";
Thanks
Thanks, Prarthan,
I appreciate your support and guidance on implementing the high-resolution deadband functionality in the TMS320F280049C microcontroller. The C and SysConfig-based configuration you provided is helpful, but I am not very familiar with using DriverLib functions.
Would it be possible for you to provide the equivalent Bitfield-based code for configuring the ePWM module with high-resolution deadband control? Or alternatively, if you could guide me on how to translate this code to bitfield.
Thank you
Hi,
I would advise you look at the driverlib functions or look at the register configurations in CCS register view and come up with the corresponding bitfield writes.
The static configuration for syscfg generated code is done in board_init() function call from main().
I wont be able to write corresponding bitfield code for this example, eventually though you should also transfer to driverlib functions
Thanks
Hi Prarthan,
I tried modifying the driverlib code to use the bit-field approach. However, even with zero deadband, the waveforms are still not aligned. I tested this with both the code you provided and the bit-field version I wrote based on your code.
I also experimented with the phase shift register but still couldn't achieve alignment for at zero deadband. I've attached a screenshot of the scope for reference.
Let me know if you have any suggestions for resolving this.
Akash,
I have also noticed that complete alignment of two is not possible. There is some phase shift as soon as deadband module was enabled
But the DB HR was functioning properly.
Thanks