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.

ehrpwm period fails to be changed

I'm seeing an issue with updating the PWM period via the serial console. When I go to write a period via the sysfs I get an invalid argument error.

As I understand it, each PWM chip must have the same value for period for each submodule (ie PWMchip1:pwm0 and PWMchip1:pwm1 must have matching periods). However I'm trying to understand the nuances of setting this via the sysfs entries:

It's clear that even if both are disabled and have a 0 duty cycle, the periods can't be changed:

[root /sys/class/pwm/pwmchip1]# cat pwm0/enable
0
[root /sys/class/pwm/pwmchip1]# cat pwm1/enable
0
[root /sys/class/pwm/pwmchip1]# cat pwm0/duty_cycle
0
[root /sys/class/pwm/pwmchip1]# cat pwm1/duty_cycle
0
[root /sys/class/pwm/pwmchip1]# cat pwm0/period
50000
[root /sys/class/pwm/pwmchip1]# cat pwm1/period
50000
[root /sys/class/pwm/pwmchip1]# echo 60000 > pwm0/period
[  202.183000] ehrpwm 48300200.ehrpwm: Period value conflicts with channel 1
-sh: echo: write error: Invalid argument
[root /sys/class/pwm/pwmchip1]# echo 60000 > pwm1/period
[  209.133209] ehrpwm 48300200.ehrpwm: Period value conflicts with channel 0
-sh: echo: write error: Invalid argument

However, if I remove one of the submodules, then it seems I can set a period just fine:

[root /sys/class/pwm/pwmchip1]# echo 1 > unexport
[root /sys/class/pwm/pwmchip1]# ls
device     npwm       pwm0       uevent
export     power      subsystem  unexport
[root /sys/class/pwm/pwmchip1]#
[root /sys/class/pwm/pwmchip1]# echo 60000 > pwm0/period
[root /sys/class/pwm/pwmchip1]# echo 1 > export
[root /sys/class/pwm/pwmchip1]# cat pwm1/period
50000
[root /sys/class/pwm/pwmchip1]# cat pwm0/period
60000

What seems odd to me here, is that the periods do not match. I thought they had to be the same. If that is not the case, then why can't I adjust the periods while I have both pwm0 and pwm1 exported?

Once I get in this state of both having different periods, I can continue to modify pwm0 as I wish, but pwm1 can't be modified:

[root /sys/class/pwm/pwmchip1]# echo 70000 > pwm1/period
[  287.953025] ehrpwm 48300200.ehrpwm: Period value conflicts with channel 0
-sh: echo: write error: Invalid argument
[root /sys/class/pwm/pwmchip1]# echo 70000 > pwm0/period
[root /sys/class/pwm/pwmchip1]# cat pwm0/period
70000
[root /sys/class/pwm/pwmchip1]# cat pwm1/period
50000

The only modification that seems to be allowed is to set pwm1 to pwm0's value. However once that occurs neither pwm1 nor pwm0 can be changed anymore.

[root /sys/class/pwm/pwmchip1]# echo 70000 > pwm1/period
[root /sys/class/pwm/pwmchip1]# cat pwm1/period
70000
[root /sys/class/pwm/pwmchip1]#
[root /sys/class/pwm/pwmchip1]# echo 50000 > pwm0/period
[  330.573006] ehrpwm 48300200.ehrpwm: Period value conflicts with channel 1
-sh: echo: write error: Invalid argument

I hope it's not just me, and this seems like a very odd behavior to others. Can someone please help me understand why the PWM period is working like this?

  • Hi,

    I will forward this to the SW team.

  • Hi Mike,

    Could you share which SDK is this, so I can test it on my BBB?

    Best Regards,
    Yordan
  • Yordan Kovachev said:
    Hi Mike,

    Could you share which SDK is this, so I can test it on my BBB?

    This is actually a custom build for our board, but it's based heavily off the 7.00.00.00 SDK for the AM335x EVM

    -Mike

  • Hi Mike,

    I tested this on my BBB, and here is the result:
    root@am335x-evm:~# cd /sys/class/pwm/
    root@am335x-evm:/sys/class/pwm# ls
    pwmchip0 pwmchip2
    root@am335x-evm:/sys/class/pwm# cd pwmchip0/
    root@am335x-evm:/sys/class/pwm/pwmchip0# ls
    device export npwm power subsystem uevent unexport
    root@am335x-evm:/sys/class/pwm/pwmchip0#
    root@am335x-evm:/sys/class/pwm/pwmchip0#
    root@am335x-evm:/sys/class/pwm/pwmchip0#
    root@am335x-evm:/sys/class/pwm/pwmchip0#
    root@am335x-evm:/sys/class/pwm/pwmchip0# cat pwm0/enable
    cat: can't open 'pwm0/enable': No such file or directory
    root@am335x-evm:/sys/class/pwm/pwmchip0# ls
    device export npwm power subsystem uevent unexport
    root@am335x-evm:/sys/class/pwm/pwmchip0# echo 0 > export
    root@am335x-evm:/sys/class/pwm/pwmchip0# echo 1 > export
    root@am335x-evm:/sys/class/pwm/pwmchip0# ls
    device npwm pwm0 subsystem unexport
    export power pwm1 uevent
    root@am335x-evm:/sys/class/pwm/pwmchip0# cat pwm0/enable
    0
    root@am335x-evm:/sys/class/pwm/pwmchip0# cat pwm1/enable
    0
    root@am335x-evm:/sys/class/pwm/pwmchip0# cat pwm0/duty_cycle
    0
    root@am335x-evm:/sys/class/pwm/pwmchip0# cat pwm1/duty_cycle
    0
    root@am335x-evm:/sys/class/pwm/pwmchip0# cat pwm0/period
    0
    root@am335x-evm:/sys/class/pwm/pwmchip0# cat pwm1/period
    0
    root@am335x-evm:/sys/class/pwm/pwmchip0# echo 60000 > pwm0/period
    root@am335x-evm:/sys/class/pwm/pwmchip0# echo 60000 > pwm1/period
    root@am335x-evm:/sys/class/pwm/pwmchip0#

    As you can see I don't get the
    "[ 202.183000] ehrpwm 48300200.ehrpwm: Period value conflicts with channel 1
    -sh: echo: write error: Invalid argument"
    error message, and I am able to set 60000 in pwm0/period & pwm1/period without any problems. Moreover, after executing the above commands, the period of pwm0 & pwm1 is the same:
    root@am335x-evm:/sys/class/pwm/pwmchip0# cat pwm0/period
    60000
    root@am335x-evm:/sys/class/pwm/pwmchip0# cat pwm1/period
    60000
    root@am335x-evm:/sys/class/pwm/pwmchip0#

    My environment is: Beaglebone Black, running SDK7.0: Linux am335x-evm 3.12.10-ti2013.12.01 #1 Tue Sep 8 15:08:17 EEST 2015 armv7l GNU/Linux

    What I did was add the following lines in am335x-bone-common.dtsi:
    ocp {
         epwmss0: epwmss@48300000 {
                          status = "okay";
                          ehrpwm0: ehrpwm@48300200 {
                                          pinctrl-names = "default";
                                          pinctrl-0 = <&ehrpwm0_pins>;
                                          status = "okay";
                           };
         };

         epwmss1: epwmss@48302000 {
                          status = "okay";
                          ehrpwm1: ehrpwm@48302200 {
                                           pinctrl-names = "default";
                                           pinctrl-0 = <&ehrpwm1_pins>;
                                           status = "okay";
                          };
          };

    And the following pinmux settings:
    ehrpwm0_pins: ehrpwm0_pins {
                  pinctrl-single,pins = <
                        0x150 (PIN_OUTPUT_PULLUP | MUX_MODE3)
                        0x154 (PIN_OUTPUT_PULLUP | MUX_MODE3)
                  >;
    };

    ehrpwm1_pins: ehrpwm1_pins {
                  pinctrl-single,pins = <
                        0x48 (PIN_OUTPUT_PULLUP | MUX_MODE6)
                        0x4C (PIN_OUTPUT_PULLUP | MUX_MODE6)
                  >;
    };

    Best Regards,
    Yordan

  • Mike/Yanko,

    This behavior appears to be defined in ./drivers/pwm/pwm-tiehrpwm.c:

            /*
             * Period values should be same for multiple PWM channels as IP uses
             * same period register for multiple channels.
             */
            for (i = 0; i < NUM_PWM_CHANNEL; i++) {
                    if (pc->period_cycles[i] &&
                                    (pc->period_cycles[i] != period_cycles)) {
                            /*
                             * Allow channel to reconfigure period if no other
                             * channels being configured.
                             */
                            if (i == pwm->hwpwm)
                                    continue;

                            dev_err(chip->dev, "Period value conflicts with channel %d\n",
                                            i);
                            return -EINVAL;
                    }
            }

    The first part of the "if" statement would skip the check in the case that pc->period_cycles[i] is equal to zero.  That was the case in Yanko's experiment, but not in Mike's experiment.  I see the period gets set back to zero when you free a PWM.  So I think if you wanted to make a change to the period you would need to first free the PWM and then configure it.

    Brad