Other Parts Discussed in Thread: SYSCONFIG
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;
}
}