Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pi5 HW PWM not working #154

Closed
johansmitsnl opened this issue Sep 1, 2024 · 18 comments
Closed

Pi5 HW PWM not working #154

johansmitsnl opened this issue Sep 1, 2024 · 18 comments
Labels

Comments

@johansmitsnl
Copy link

johansmitsnl commented Sep 1, 2024

I'm on version 0.19.0 and this includes the commit 6bbc5ef.

This code works on a Pi4 but on my Pi5 I'm getting errors and don't know why.

I have set dtoverlay=pwm-2chan,pin=12,func=4,pin2=13,func2=4 in the config. Also with the permission udev rules:

SUBSYSTEM=="pwm*", PROGRAM="/bin/sh -c '\
    chown -R root:gpio /sys/class/pwm && chmod -R 770 /sys/class/pwm;\
    chown -R root:gpio /sys/devices/platform/soc/*.pwm/pwm/pwmchip* &&\
    chmod -R 770 /sys/devices/platform/soc/*.pwm/pwm/pwmchip*\
'"
$ pinctrl get 12,13
12: a0    pd | lo // GPIO12 = PWM0_CHAN0
13: a0    pd | lo // GPIO13 = PWM0_CHAN1
$  ls -l /sys/class/pwm
total 0
lrwxrwxrwx 1 root gpio 0 Sep  1 08:43 pwmchip0 -> ../../devices/platform/soc/107d517a80.pwm/pwm/pwmchip0/
lrwxrwxrwx 1 root gpio 0 Sep  1 08:43 pwmchip2 -> ../../devices/platform/axi/1000120000.pcie/1f00098000.pwm/pwm/pwmchip2/
lrwxrwxrwx 1 root gpio 0 Sep  1 08:43 pwmchip6 -> ../../devices/platform/axi/1000120000.pcie/1f0009c000.pwm/pwm/pwmchip6/

WHen I wanto to initialize the PWM pin:

    let servo_1 = Pwm::with_period(
        Channel::Pwm0,
        Duration::from_millis(SERVO_PWM_PERIOD_MS),
        Duration::from_micros(SERVO_PWM_PULSE_MAX_US),
        Polarity::Normal,
        true,
    )
    .expect("Should be able to connect to PWM pin");

When check the output of DeviceInfo It does read correctly:

rppal::system::DeviceInfo::new() = Ok(
    DeviceInfo {
        model: RaspberryPi5,
        soc: Bcm2712,
        peripheral_base: 1073741824,
        gpio_offset: 851968,
        gpio_lines: 28,
        gpio_interface: Rp1,
        pwm_chip: 2,
        pwm_channels: [
            2,
            3,
        ],
    },
)

I'm getting the error Io(Os { code: 13, kind: PermissionDenied, message: "Permission denied" }).

What am I'm missing here or is there still a bug somewhere?

@golemparts
Copy link
Owner

Hi @johansmitsnl. Getting a Permission Denied error from with_period typically means RPPAL can't export the channel, which it does by creating /sys/class/pwm/pwmchip2/pwm2. The first thing I would check is make sure the user you're logged in as is part of the gpio group.

@golemparts golemparts added the pwm label Sep 4, 2024
@johansmitsnl
Copy link
Author

Hi @golemparts. the user is part of the group:

uid=1000(piuser) gid=1000(piuser) groups=1000(piuser),4(adm),20(dialout),24(cdrom),27(sudo),29(audio),44(video),46(plugdev),60(games),100(users),102(input),105(render),106(netdev),993(gpio),994(i2c),995(spi)

I noticed with the current udev rules the permissions are wrong:

lrwxrwxrwx 1 root root     0 Sep  4 18:41 device -> ../../../1f00098000.pwm/
--w------- 1 root root 16384 Sep  4 18:41 export
-r--r--r-- 1 root root 16384 Sep  4 18:41 npwm
drwxr-xr-x 2 root root     0 Sep  4 18:41 power/
lrwxrwxrwx 1 root root     0 Jan  1  1970 subsystem -> ../../../../../../../class/pwm/
-rw-r--r-- 1 root root 16384 Jan  1  1970 uevent
--w------- 1 root root 16384 Sep  4 18:41 unexport

But when I chown them with sudo chown root:gpio -Rf * . and I try to touch of make a dir in: /sys/class/pwm/pwmchip2/pwm2 I get the permission denied:

touch /sys/class/pwm/pwmchip2/pwm2
touch: cannot touch '/sys/class/pwm/pwmchip2/pwm2': Permission denied

But even when I use sudo to create the directory I also get permission denied.

@golemparts
Copy link
Owner

golemparts commented Sep 5, 2024

I had some time to look into the hardware PWM code some more. My earlier mention of the creation of /sys/class/pwm/pwmchip2/pwm2 causing the Permission Denied error wasn't accurate, as the creation of pwm2 is triggered by writing a 2 (for channel 0) to /sys/class/pwm/pwmchip2/export.

I checked the permissions on my Pi 5, which are different from yours:

--w--w---- 1 root gpio 16384 Sep  4 11:41 export
-r--r--r-- 1 root gpio 16384 Sep  4 11:41 npwm
drwxrwxr-x 2 root gpio     0 Sep  4 11:41 power
lrwxrwxrwx 1 root gpio     0 Sep  4 11:41 subsystem -> ../../../../../../../class/pwm
-rw-rw-r-- 1 root gpio 16384 Sep  4 11:41 uevent
--w--w---- 1 root gpio 16384 Sep  4 11:41 unexport

I don't actually recall having to edit /etc/udev/rules.d/99-com.rules anymore, so it's possible that recommendation in the documentation is no longer needed for more recent versions of Raspberry Pi OS. Could you check what permissions it defaults to after deleting those rules and rebooting?

@johansmitsnl
Copy link
Author

Without the udev rules the permissions are not of the GPIO group:

$ stat /sys/class/pwm/pwmchip2/export
  File: /sys/class/pwm/pwmchip2/export
  Size: 16384     	Blocks: 0          IO Block: 16384  regular file
Device: 0,18	Inode: 23381       Links: 1
Access: (0200/--w-------)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-09-05 19:14:28.863921234 +0200
Modify: 2024-09-05 19:14:28.863283257 +0200
Change: 2024-09-05 19:14:28.863283257 +0200
 Birth: -

I don't run as root but as a normal user so this can't work since the permission is 200 and not even writable for the group.

I changes the udev rule to this:

SUBSYSTEM=="pwm*", PROGRAM="/bin/sh -c '\
    chown -R root:gpio /sys/class/pwm && chmod -R 770 /sys/class/pwm;\
    chown -R root:gpio /sys/devices/platform/soc/*.pwm/pwm/pwmchip* &&\
    chown root:gpio /sys/class/pwm/pwmchip*/export &&\
    chmod 220 /sys/class/pwm/pwmchip*/export &&\
    chmod -R 770 /sys/devices/platform/soc/*.pwm/pwm/pwmchip*\

This makes sure the permission is correct on the export path.

But this is also not sufficient due to permission lacking write permission on the new created pwm2 directory:

$ ls -l /sys/class/pwm/pwmchip2/pwm2
-r--r--r-- 1 root root 16384 Sep  5 19:27 capture
-rw-r--r-- 1 root root 16384 Sep  5 19:27 duty_cycle
-rw-r--r-- 1 root root 16384 Sep  5 19:27 enable
-rw-r--r-- 1 root root 16384 Sep  5 19:27 period
-rw-r--r-- 1 root root 16384 Sep  5 19:27 polarity
drwxr-xr-x 2 root root     0 Sep  5 19:27 power/
-rw-r--r-- 1 root root 16384 Sep  5 19:27 uevent

By manually adding chmod -R g+rw on the pwm2 dir it still isn't solved and I still get the permission denied error.

$ ls -l /sys/class/pwm/pwmchip2/pwm2=
-r--rw-r-- 1 root gpio 16384 Sep  5 19:27 capture
-rw-rw-r-- 1 root gpio 16384 Sep  5 19:32 duty_cycle
-rw-rw-r-- 1 root gpio 16384 Sep  5 19:32 enable
-rw-rw-r-- 1 root gpio 16384 Sep  5 19:32 period
-rw-rw-r-- 1 root gpio 16384 Sep  5 19:32 polarity
drwxrwxr-x 2 root gpio     0 Sep  5 19:27 power/
-rw-rw-r-- 1 root gpio 16384 Sep  5 19:27 uevent

@golemparts
Copy link
Owner

If this is happening with a fresh install of a recent Raspberry Pi OS release, I think at this point it's better if you ask about this on the official Raspberry Pi forum, as this does not appear to be an RPPAL issue but a linux one, and I'm not familiar enough with how best to solve permission issues like this.

I'd appreciate it if you can let me know when you've found a solution, as it may be useful to people who run into the same problem.

@johansmitsnl
Copy link
Author

Yes this is a fresh install of 1 week ago. I'll let you know the outcome but I'm on holiday for the next 3 weeks so it might take some time for me to reply.

@johansmitsnl
Copy link
Author

Created a question on the pi forum

@johansmitsnl
Copy link
Author

No response on the forum but I did a reinstall on the pi.

Now the permissions are the same as yours but I have an issue with the Channel::Pwm1 that fails. The Channel::Pwm0 does not panic.

Now my output of the directory is like this:

ls -l /sys/class/pwm/pwmchip2/
total 0
lrwxrwxrwx 1 root gpio     0 Oct 30 20:32 device -> ../../../1f0009c000.pwm
--w--w---- 1 root gpio 16384 Oct 30 20:42 export
-r--r--r-- 1 root gpio 16384 Oct 30 20:32 npwm
drwxrwxr-x 2 root gpio     0 Oct 30 20:32 power
lrwxrwxrwx 1 root gpio     0 Oct 30 20:32 subsystem -> ../../../../../../../class/pwm
-rw-rw-r-- 1 root gpio 16384 Oct 30 20:32 uevent
--w--w---- 1 root gpio 16384 Oct 30 20:40 unexport

Full firmware config:

# /boot/firmware/config.txt

# For more options and information see
# http://rptl.io/configtxt
# Some settings may impact device functionality. See link above for details

# Uncomment some or all of these to enable the optional hardware interfaces
dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on

# Enable audio (loads snd_bcm2835)
dtparam=audio=on

# Additional overlays and parameters are documented
# /boot/firmware/overlays/README

# Automatically load overlays for detected cameras
camera_auto_detect=1

# Automatically load overlays for detected DSI displays
display_auto_detect=1

# Automatically load initramfs files, if found
auto_initramfs=1

# Enable DRM VC4 V3D driver
dtoverlay=vc4-kms-v3d
max_framebuffers=2

# Don't have the firmware create an initial video= setting in cmdline.txt.
# Use the kernel's default instead.
disable_fw_kms_setup=1

# Run in 64-bit mode
arm_64bit=1

# Disable compensation for displays with overscan
disable_overscan=1

# Run as fast as firmware / board allows
arm_boost=1

[cm4]
# Enable host mode on the 2711 built-in XHCI USB controller.
# This line should be removed if the legacy DWC2 controller is required
# (e.g. for USB device mode) or if USB support is not required.
otg_mode=1

[cm5]
dtoverlay=dwc2,dr_mode=host
dtoverlay=pwm-2chan,pin=12,func=4,pin2=13,func2=4

[all]

Maybe a suggestion where to look as all permissions seem correct?

@golemparts
Copy link
Owner

Glad to hear a fresh install fixed the initial problem. I'm not sure what would cause an issue with PWM1 when PWM0 is working. Your configuration looks correct. What error are you getting?

@johansmitsnl
Copy link
Author

The code I use is:

let servo_2 = Pwm::with_period(
        Channel::Pwm1,
        Duration::from_millis(SERVO_PWM_PERIOD_MS),
        Duration::from_micros(SERVO_PWM_PULSE_MAX_US),
        Polarity::Normal,
        true,
    )
    .expect("Should be able to connect to PWM 2 pin");

And the error running the code:

thread 'main' panicked at recorder/src/gpio.rs:285:6:
Should be able to connect to PWM 2 pin: Io(Os { code: 16, kind: ResourceBusy, message: "Device or resource busy" })

@johansmitsnl
Copy link
Author

@golemparts do you have ideas what can cause this or where you able to test/verify it on a pi5?

@golemparts
Copy link
Owner

I haven't had a chance to test this myself, but if the error message is accurate, I would suspect some other process is using that PWM channel. Another possibility is RPPAL is trying to access the wrong PWM channel, but I would expect a Permission denied error in that case.

On the Pi 5, RPPAL will use /sys/class/pwm/pwmchip2/pwm2 for Pwm0 and /sys/class/pwm/pwmchip2/pwm3 for Pwm1. You could try exporting pwm3 from the commandline and check what error message you get.

I should have some time this upcoming weekend to test the second PWM channel myself and see if I get the same error.

@johansmitsnl
Copy link
Author

@golemparts thanks for the feedback and your time to test. How can I check it on the command line?

@golemparts
Copy link
Owner

golemparts commented Nov 21, 2024

Check out this answer for some example command line commands. You'll want to use pwmchip2 instead of the device mentioned in the example, and echo 3 to export pwm3. RPPAL basically does the same thing.

@golemparts
Copy link
Owner

@johansmitsnl I just ran some tests on my Pi 5, and both PWM channels worked fine. However, while recreating your setup I did notice an issue in your /boot/firmware/config.txt. You have the pwm-2chan overlay listed under [cm5] instead of [all]. Try moving it there and rebooting. Hopefully that'll resolve the issue for you.

@golemparts
Copy link
Owner

Closing this due to inactivity. If you're still encountering this issue and the above-mentioned didn't resolve it, please let me know.

@golemparts
Copy link
Owner

An issue was discovered specifically related to PWM on GPIO12/13 on a Pi 5, which was fixed in release 0.22.0. If you're still encountering this issue, try that release.

@johansmitsnl
Copy link
Author

I did some testing but could not get it to work so I didn't provide a update of nothing to report. But with the 0.22.0 it works again 👍

Thanks for the effort!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants