Configuring PWM channel outputs on the Allwinner D1 (MangoPi MQ Pro)

Hello dear Nerves users,

I’m trying to get a PWM output to show up on the 40-pin header on the MangoPI, specifically physical pin 35, or GPIO 38 as seen from Elixir. My goal is to have a few PWM channels physically available on the header to control them with the sysfs (/sys/class/pwm) interface.

To summarize :

  • I think I found the relevant information in the D1 manual.
  • I’m pretty sure I do not know how to properly apply it.

I found the following pin multiplexing table in the official D1 documentation (beware : 1300+ pages)

Further, since this pin should be handled by PB6, I found the relevant register address :

And the bit pattern to configure PB6 to use the PWM1 channel :

My understanding is that I should be able to get the PWM1 channel on PB6 / GPIO38 by setting the register at address 0x02000000 + 0x0030 to the bit pattern 000001010000000000000000 or 0x050000 (since PB6_SELECT is set by using the bits 27 to 24).

I found samples of DTS files online for similar purposes that I tried to modify, some compiling, and some not, but none having any tangible effect towards my goal.

I would greatly appreciate any direction on that matter. Am I looking at the wrong level of abstraction by thinking in terms of bit patterns and registers, and pinmux configuration is instead done at a slightly higher level ?

I know it’s been a while since you posted this, but just in case you haven’t figured it out, or if anyone else stumbles upon this in the future, here’s a example of enabling a PWM channel on the t113s. Pwm by ConnorRigby · Pull Request #1 · ConnorRigby/nerves_system_underglow3 · GitHub

it should be the same on the D1. The source file for pinctrl will be in here sunxi - drivers/pinctrl/sunxi - Linux source code (v6.8.1) - Bootlin


Thanks a lot for these resources, I should be able to leverage them. I’ve put the project on the backburner for a while, but should be getting to it quite soon.
It’s also very nice to have that kind of samples for more advanced topics on the forum :slight_smile: .

1 Like

It’s been a while, but I finally have time to dig into this more, I’ll leave a trail of notes here. Feel free to correct me if something is wrong. Resources online are sparse.

A device tree file (like the resource linked above) describes the hardware and peripherals at system build time. It is different from a DTS file made to produce a DTBO file, a runtime overlay re-configuring some of the hardware, that you load with configFS. This first differenciation took me some time.

So, to write a DTS file to reconfigure some hardware, you have to know how your device tree is currently configured. You either wrote it, or a system author wrote it (my situation).

You can get the device tree of a running Nerves system where the dtc binary is present like this :

iex> cmd("dtc -I fs -O dtb -o /data/system.dtb /proc/device-tree")

Then, you can de-compile this system.dtb file to a DTS file, with :

iex> cmd("dtc -I dtb -O dts -o /data/system.dts /system.dtb")

This extracted DTS file is a good starting point to write overlays for a specific system.