• TI thinks resolved

Linux/AM3358: PWM initialization from PRU

Part Number: AM3358

Tool/software: Linux

We are trying to use the PRU on a BeagleBone Black to generate a PWM using ePWM1.  I've modified the dtb to include the pins.

Initially, the PWMSS1.EPWM_TBCTL is 131 and after initialization is it 128. I think that's correct.  The CTRMODE changes from frozen to up count and the other bits remain the same.

Also, If I set PWMSS1.EPWM_TBCNT to something like 100 it never changes on subsequent reads.

I've verified that

PWMSS1.EPQM_TBPRD, PWMSS1.EPWM_CMPA and PWMSS1.EPWM_CMPB are all set to values I set.

It's as though the clock isn't going. Here are the details:

           brake_bone_pins: brake_bone_pins {

                       pinctrl-single,pins = <

                       0x0A0 (MUX_MODE5) /* pr1_pru1_pru_r30_0,  P8->45, debug pin a */

                       0x0A4 (MUX_MODE5) /* pr1_pru1_pru_r30_1,  P8->46, debug pin b*/

 

                       0x0AC (MUX_MODE5) /* pr1_pru1_pru_r30_3,  P8->44, QEI enable*/

 

                       0x0E0 (PIN_INPUT_PULLDOWN | MUX_MODE6) /* pr1_pru1_pru_r31_8, P8->27, fault */

 

                       0x0D0 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* eQEP1A_in P8->35 */

                       0x0D4 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* eQEP1B_in P8->33 */

                       0x0D8 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* eQEP1_index          P8->31 */

                       0x0DC (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* eQEP1_strobe        P8->32 */

 

                       0x0E8 (MUX_MODE5) /* pr1_pru1_pru_r30_10, P8->28, motor trigger 1 */

                       0x0E4 (MUX_MODE5) /* pr1_pru1_pru_r30_9,  P8->29, PWM enable A */

                       0x0EC (MUX_MODE5) /* pr1_pru1_pru_r30_11, P8->30, PWM enable B */

 

                        0x048 (PIN_OUTPUT_PULLDOWN | MUX_MODE6) /* ePWM1A, P9.14, brake current A */

                        0x04C (PIN_OUTPUT_PULLDOWN | MUX_MODE6) /* ePWM1B, P9.16, brake current B */

                       >;

           };

I based my PRU code on this GitHub project:

https://github.com/mhaberler/BBBIOlib/blob/master/BBBio_lib/BBBiolib_PWMSS.c

In the PRU code, I have the following routines PWM_Init & PWM_Enable. I call PWM_Init 1st followed by PWM_Enable(1). I'm sure the period and duty cycle aren't right, but for now I just want to see something on the output pins. I've captured a few of the registers so that you can see what they look like. As you can see I explicitly set TBCNT, but it always returns 0 (values below are in decimal). I read the following registers every 10ms -- always with the same results.

CM_PER_EPWMSS1 = 2

PWMSS1.EPWM_TBCTL = 128

PWMSS1.CLKSTATUS = 273

PWMSS1.EPWM_TBSTS = 1

PWMSS1.EPWM_TBCNT = 0

 

void PWM_Init(void)

{

   /* Enable PWMSS1 clock signal generation */

   while (!(CM_PER_EPWMSS1 & 0x2))

       CM_PER_EPWMSS1 |= 0x2;

 

   PWMSS1.SYSCONFIG =

             (2 << 4)           // smart standby mode

           | (2 << 2);          // smart idle mode

 

   PWMSS1.EPWM_TBCTL |= 0x3;   // freeze

 

   PWMSS1.EPWM_TBPRD = 50000;

   PWMSS1.EPWM_CMPA  = 30000;

   PWMSS1.EPWM_CMPB  = 20000;

 

   PWMSS1.EPWM_TBCNT = 100;

}

 

void PWM_Enable(bool enable)

{

            if(enable)

            {

           PWMSS1.EPWM_AQCTLA =

                       (0x3 << 4)       // cmpa = set

                       | (0x2 << 0);     // zero = high

 

           PWMSS1.EPWM_AQCTLB =

                       (0x3 << 8)       // cmpa = set

                       | (0x2 << 0);     // zero = high

 

           PWMSS1.EPWM_TBCNT = 0;

 

           PWMSS1.EPWM_TBCTL &= ~0x3;   // up-mode

            }

            else

            {

           PWMSS1.EPWM_TBCTL |= 0x3;      // freeze

           PWMSS1.EPWM_AQCTLA =

                       (0x3 << 4)       // cmpa = set

                       | (0x1 << 0);     // zero = force low

 

           PWMSS1.EPWM_AQCTLB =

                       (0x3 << 8)       // cmpa = set

                       | (0x1 << 0);     // zero = force low

 

           PWMSS1.EPWM_TBCNT = 0;

            }

}