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.

Am335x Problems Running 4 Simultaneos EHRPWMs

Hi,

I am using a BeageBone Black and attempting to run 4 PWMs, all the same frequency but each with a different duty cycle. Using EHRPWM0 A and B by itself gives me 2 correct outputs according to the scope. The same goes for EHRPWM1 A and B. However when I try to run EHRPWM0 and EHRPWM1 both together, the last one to be initialized is the only one that works. I would like some help looking over my code and possibly pinpointing where I am going wrong.

It might help to understand this code to know that it is a 4 wheeled robot that has a motor per wheel. The motors are controlled by h-bridges that are fed by pwm inputs to vary the current output to the motor based on duty cycle. EHRPWM0A controls the rear left h-bridge, EHRPWM0B controls the real right h-bridge, EHRPWM1A controls the front left h-bridge, and EHRPWM1B controls the fron right h-bridge.

 

Here is my code to initialize the PWMs:

#define PWM_LEFT_FRONT_EN (GPIO_1_18) // 17
#define PWM_RIGHT_FRONT_EN (GPIO_1_19) // 18
#define PWM_LEFT_REAR_EN (GPIO_0_2) // 22
#define PWM_RIGHT_REAR_EN (GPIO_0_3) // 21

#define CLOCK_DIV_VAL_H_BRIDGES (10)
#define EHRPWM_MODULE_FREQ_H_BRIDGES (100000000)
/* Set up EHRPWM 0 and 1 for H-Bridge control. */

	/* Set up pwm 0*/
	PWMSSModuleClkConfig(0);
	EHRPWMClockEnable(SOC_PWMSS0_REGS);
	PWMSSTBClkEnable(0);

	EHRPWMTimebaseClkConfig(SOC_EPWM_0_REGS,EHRPWM_MODULE_FREQ_H_BRIDGES/CLOCK_DIV_VAL_H_BRIDGES,EHRPWM_MODULE_FREQ_H_BRIDGES);
	EHRPWMTimebaseSyncDisable(SOC_EPWM_0_REGS);
	EHRPWMSyncOutModeSet(SOC_EPWM_0_REGS, EHRPWM_SYNCOUT_DISABLE);
	EHRPWMTBEmulationModeSet(SOC_EPWM_0_REGS, EHRPWM_FREE_RUN);
	EHRPWMPWMOpFreqSet(SOC_EPWM_0_REGS, EHRPWM_MODULE_FREQ_H_BRIDGES, EHRPWM_MODULE_FREQ_H_BRIDGES/1000 ,EHRPWM_COUNT_UP, EHRPWM_SHADOW_WRITE_ENABLE);
	EHRPWMLoadCMPA(SOC_EPWM_0_REGS, 0, EHRPWM_SHADOW_WRITE_ENABLE,
			   EHRPWM_COMPA_NO_LOAD, EHRPWM_CMPCTL_OVERWR_SH_FL);
	EHRPWMLoadCMPB(SOC_EPWM_0_REGS, 0, EHRPWM_SHADOW_WRITE_ENABLE,
			   EHRPWM_COMPB_NO_LOAD, EHRPWM_CMPCTL_OVERWR_SH_FL);
	EHRPWMConfigureAQActionOnA(SOC_EPWM_0_REGS,
							   EHRPWM_AQCTLA_ZRO_DONOTHING,
							   EHRPWM_AQCTLA_PRD_EPWMXAHIGH,
							   EHRPWM_AQCTLA_CAU_EPWMXALOW,
							   EHRPWM_AQCTLA_CAD_DONOTHING,
							   EHRPWM_AQCTLA_CBU_DONOTHING,
							   EHRPWM_AQCTLA_CBD_DONOTHING,
							   EHRPWM_AQSFRC_ACTSFA_DONOTHING);
	EHRPWMConfigureAQActionOnB(SOC_EPWM_0_REGS,
							   EHRPWM_AQCTLB_ZRO_DONOTHING,
							   EHRPWM_AQCTLB_PRD_EPWMXBHIGH,
							   EHRPWM_AQCTLB_CAU_DONOTHING,
							   EHRPWM_AQCTLB_CAD_DONOTHING,
							   EHRPWM_AQCTLB_CBU_EPWMXBLOW,
							   EHRPWM_AQCTLB_CBD_DONOTHING,
							   EHRPWM_AQSFRC_ACTSFB_DONOTHING);
	EHRPWMDBOutput(SOC_EPWM_0_REGS, EHRPWM_DBCTL_OUT_MODE_BYPASS);
	EHRPWMChopperDisable(SOC_EPWM_0_REGS);
	EHRPWMTZTripEventDisable(SOC_EPWM_0_REGS,(bool)EHRPWM_TZ_ONESHOT);
	EHRPWMTZTripEventDisable(SOC_EPWM_0_REGS,(bool)EHRPWM_TZ_CYCLEBYCYCLE);
	EHRPWMHRDisable(SOC_EPWM_0_REGS);

	Delay(0xFFFFFF);
        /* Set up PWM 1 */
	PWMSSModuleClkConfig(1);
	EHRPWMClockEnable(SOC_PWMSS1_REGS);
	PWMSSTBClkEnable(1);


	EHRPWMTimebaseClkConfig(SOC_EPWM_1_REGS,EHRPWM_MODULE_FREQ_H_BRIDGES/CLOCK_DIV_VAL_H_BRIDGES,EHRPWM_MODULE_FREQ_H_BRIDGES);
	EHRPWMTimebaseSyncDisable(SOC_EPWM_1_REGS);
	EHRPWMSyncOutModeSet(SOC_EPWM_1_REGS, EHRPWM_SYNCOUT_DISABLE);
	EHRPWMTBEmulationModeSet(SOC_EPWM_1_REGS, EHRPWM_FREE_RUN);
	EHRPWMPWMOpFreqSet(SOC_EPWM_1_REGS, EHRPWM_MODULE_FREQ_H_BRIDGES, EHRPWM_MODULE_FREQ_H_BRIDGES/1000 , EHRPWM_COUNT_UP,EHRPWM_SHADOW_WRITE_ENABLE);
	EHRPWMLoadCMPA(SOC_EPWM_1_REGS, 0, EHRPWM_SHADOW_WRITE_ENABLE,
			EHRPWM_COMPA_LOAD_COUNT_EQUAL_PERIOD, EHRPWM_CMPCTL_OVERWR_SH_FL);
	EHRPWMLoadCMPB(SOC_EPWM_1_REGS, 0, EHRPWM_SHADOW_WRITE_ENABLE,
			EHRPWM_COMPB_LOAD_COUNT_EQUAL_PERIOD, EHRPWM_CMPCTL_OVERWR_SH_FL);
	EHRPWMConfigureAQActionOnA(SOC_EPWM_1_REGS,
							   EHRPWM_AQCTLA_ZRO_DONOTHING,
							   EHRPWM_AQCTLA_PRD_EPWMXAHIGH,
							   EHRPWM_AQCTLA_CAU_EPWMXALOW,
							   EHRPWM_AQCTLA_CAD_DONOTHING,
							   EHRPWM_AQCTLA_CBU_DONOTHING,
							   EHRPWM_AQCTLA_CBD_DONOTHING,
							   EHRPWM_AQSFRC_ACTSFA_DONOTHING);
	EHRPWMConfigureAQActionOnB(SOC_EPWM_1_REGS,
							   EHRPWM_AQCTLB_ZRO_DONOTHING,
							   EHRPWM_AQCTLB_PRD_EPWMXBHIGH,
							   EHRPWM_AQCTLB_CAU_DONOTHING,
							   EHRPWM_AQCTLB_CAD_DONOTHING,
							   EHRPWM_AQCTLB_CBU_EPWMXBLOW,
							   EHRPWM_AQCTLB_CBD_DONOTHING,
							   EHRPWM_AQSFRC_ACTSFB_DONOTHING);
	EHRPWMDBOutput(SOC_EPWM_1_REGS, EHRPWM_DBCTL_OUT_MODE_BYPASS);
	EHRPWMChopperDisable(SOC_EPWM_1_REGS);
	EHRPWMTZTripEventDisable(SOC_EPWM_1_REGS,(bool)EHRPWM_TZ_ONESHOT);
	EHRPWMTZTripEventDisable(SOC_EPWM_1_REGS,(bool)EHRPWM_TZ_CYCLEBYCYCLE);
	EHRPWMHRDisable(SOC_EPWM_1_REGS);


Code to change the duty cycle of the desired h-bridge:

Front-Left Motor:

EHRPWMLoadCMPA(SOC_EPWM_1_REGS, 1000 * (percentFL/100.0f),
EHRPWM_SHADOW_WRITE_ENABLE,
EHRPWM_COMPA_LOAD_COUNT_EQUAL_PERIOD, 
EHRPWM_CMPCTL_OVERWR_SH_FL);


Front-Right Motor:

EHRPWMLoadCMPB(SOC_EPWM_1_REGS, 1000 * (percentFR/100.0f),
EHRPWM_SHADOW_WRITE_ENABLE, 
EHRPWM_COMPB_LOAD_COUNT_EQUAL_PERIOD, 
EHRPWM_CMPCTL_OVERWR_SH_FL);


Rear-Left Motor:

EHRPWMLoadCMPA(SOC_EPWM_0_REGS, 1000 * (percentRL/100.0f),
EHRPWM_SHADOW_WRITE_ENABLE,
EHRPWM_COMPA_LOAD_COUNT_EQUAL_PERIOD,
EHRPWM_CMPCTL_OVERWR_SH_FL);

Rear-Right Motor:

EHRPWMLoadCMPB(SOC_EPWM_0_REGS, 1000 * (percentRR/100.0f), 
EHRPWM_SHADOW_WRITE_ENABLE, 
EHRPWM_COMPB_LOAD_COUNT_EQUAL_PERIOD, 
EHRPWM_CMPCTL_OVERWR_SH_FL); 



Thanks in advance,
Eddie



  • Moving this to the Starterware forum.

  • Since your code looks good to me just an idea what you could try: how about first enabling/initialising all clocks for 0 and 1 together and then setting up the EHRPWM's`?

  • Thank you for the help! I looked into setting the clocks next to each other and consequently through trial and error discovered that this code was deciding whitch pwm module was working. Whoever was enabled last was the one that would be running.

    	PWMSSTBClkEnable(1);
    	PWMSSTBClkEnable(0);
    
    
    

    Upon further inspection the code was setting them was = instead of |= thus overriding all the others.

    HWREG(SOC_CONTROL_REGS + CONTROL_PWMSS_CTRL) = CONTROL_PWMSS_CTRL_PWMSS0_TBCLKEN;

    So the modified version of PWMSSTBClkEnable() is as follows: 

    /**
     * \brief   This function Enables TBCLK(Time Base Clock) for specific
     *          EPWM instance of pwmsubsystem.
     *
     * \param   instance  It is the instance number of EPWM of pwmsubsystem.
     *
     **/
    void PWMSSTBClkEnable(unsigned int instance)
    {
        switch(instance)
        {
    
             case 0:
                   HWREG(SOC_CONTROL_REGS + CONTROL_PWMSS_CTRL) |= CONTROL_PWMSS_CTRL_PWMSS0_TBCLKEN;
                   break;
    
             case 1:
                   HWREG(SOC_CONTROL_REGS + CONTROL_PWMSS_CTRL) |= CONTROL_PWMSS_CTRL_PWMMS1_TBCLKEN;
                   break;
    
             case 2:
                   HWREG(SOC_CONTROL_REGS +  CONTROL_PWMSS_CTRL) |= CONTROL_PWMSS_CTRL_PWMSS2_TBCLKEN;
                   break;
    
             default:
             break;
        }
    }