PWM device defined in Device Tree as pwm
node:
PWM node is an abstract object which is an umbrella on top of GPIO group and clocks.
There are many GPIO groups on Raspberry Pi, which are configured in https://github.com/torvalds/linux/blob/522214d9be9c9f00f34ed89cb95e901b7ac31c59/arch/arm/boot/dts/bcm283x.dtsi#L114
By default PWM node uses pwm0_gpio40
and pwm1_gpio45
. Pins 40 and
45 are not exposed in Raspberry PI - these are (I guess) pins which
are used internally by audio output.
To enable PWM on exposed pins 12 and 13 we need to change the value of
pinctrl-0
parameter in the device tree.
There are probably easier ways to patch Device Tree (overlays..). But here is the way to recompile the entire Device Tree without recompiling the kernel.
(root)# dnf install rpmdevtools git bc openssl-devel
Commands below do not need require root privileges.
Fetch the kernel srpm file:
$ dnf download --source kernel
Unpack srpm to ~/rpmbuild
:
$ rpm -i kernel-4.14.8-300.fc27.src.rpm
Prepare kernel source tree:
$ rpmbuild --nodeps -bp --with baseonly --target armv7l ~/rpmbuild/SPECS/kernel.spec
Switch to the directory wuth unpacked kernel sources:
$ cd ~/rpmbuild/BUILD/kernel-4.14.fc27/linux-4.14.8-300.fc27.armv7l/
Get the Fedora kernel .config
file
$ cp configs/kernel-4.14.8-armv7hl.config .config
Modify Device Tree in arch/arm/boot/dts/
folder. For example this patch enables PWM on GPIO12 and GPIO13:
$ git diff arch/arm/boot/dts/bcm2835-rpi.dtsi
diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index e36c392..398f822 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -77,7 +77,7 @@
&pwm {
pinctrl-names = "default";
- pinctrl-0 = <&pwm0_gpio40 &pwm1_gpio45>;
+ pinctrl-0 = <&pwm0_gpio12 &pwm1_gpio13>;
status = "okay";
};
Compile Device Tree:
$ make V=1 ARCH=arm dtbs dtbs_install INSTALL_DTBS_PATH=custom-dts
Now in custom-dts/
we have new .dtb files.
In Fedora for ARM U-Boot Bootloader is used to run Extlinux Bootloader, which then chooses which kernel, initrd and dtb images to boot.
The following must be done as root.
Copy custom device tree to /boot
:
# cp -r <path>/custom-dts /boot/custom
Modify /boot/extlinux/extlinux.conf
to use dtb files from custom
device tree (add new item with custom fdtdir
parameter and choose it
as default).
# extlinux.conf generated by appliance-creator
ui menu.c32
menu autoboot Welcome to Fedora. Automatic boot in # second{,s}. Press a key for options.
menu title Fedora Boot Options.
menu hidden
timeout 20
totaltimeout 600
default=Fedora (Customized)
label Fedora (Customized)
kernel /vmlinuz-4.14.8-300.fc27.armv7hl
append ro root=UUID=b35d7f9e-3d7c-4e43-8ba9-4c5439ca27e3 LANG=en_US.UTF-8
fdtdir /custom/
initrd /initramfs-4.14.8-300.fc27.armv7hl.img
label Fedora (4.14.8-300.fc27.armv7hl) 27 (Twenty Seven)
kernel /vmlinuz-4.14.8-300.fc27.armv7hl
append ro root=UUID=b35d7f9e-3d7c-4e43-8ba9-4c5439ca27e3 LANG=en_US.UTF-8
fdtdir /dtb-4.14.8-300.fc27.armv7hl/
initrd /initramfs-4.14.8-300.fc27.armv7hl.img
label Fedora-Minimal-armhfp-27-1.6 (4.13.9-300.fc27.armv7hl)
kernel /vmlinuz-4.13.9-300.fc27.armv7hl
append ro root=UUID=b35d7f9e-3d7c-4e43-8ba9-4c5439ca27e3
fdtdir /dtb-4.13.9-300.fc27.armv7hl/
initrd /initramfs-4.13.9-300.fc27.armv7hl.img
Reboot!
As root:
cd /sys/class/pwm/
cd pwmchip0/
echo 0 > export
cd pwm0/
echo 100000 > period
echo 10000 > duty_cycle
echo 1 > enable
Connect LED to GPIO12 and check that it is dimmed.