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

Hey ! If someone does need the PWM outputs of the mangopi to actually come out on the header, you can checkout my branch here : GitHub - Lucassifoni/nerves_system_mangopi_mq_pro at pwm-ability · GitHub

Here is a dynamic overlay that correctly muxes the pins, on top of the 6.18.36 kernel update : nerves_system_mangopi_mq_pro/pwm-7ch-overlay.dts at pwm-ability · Lucassifoni/nerves_system_mangopi_mq_pro · GitHub

For ease of use, you can checkout my two helper libraries, DtsBuddy and Pwmx, described here : Two helper libraries, DtsBuddy and Pwmx

Here is how to get leds blinking on the exposed channels in an iex session :

iex(livebook@nerves.local)1> import DtsBuddy.Sigil
DtsBuddy.Sigil
iex(livebook@nerves.local)2> DtsBuddy.enable_overlays
:ok
iex(livebook@nerves.local)3> DtsBuddy.overlays_enabled?
true
iex(livebook@nerves.local)4> compiled =
  ~DTS"""
  /dts-v1/;
  /plugin/;
  &{/soc/pinctrl@2000000} {
    pwm0_pb5:  pwm0-pb5  { pins = "PB5";  function = "pwm0"; };
    pwm1_pb6:  pwm1-pb6  { pins = "PB6";  function = "pwm1"; };
    pwm2_pb11: pwm2-pb11 { pins = "PB11"; function = "pwm2"; };
    pwm3_pb0:  pwm3-pb0  { pins = "PB0";  function = "pwm3"; };
    pwm4_pb1:  pwm4-pb1  { pins = "PB1";  function = "pwm4"; };
    pwm5_pd21: pwm5-pd21 { pins = "PD21"; function = "pwm5"; };
    pwm7_pb10: pwm7-pb10 { pins = "PB10"; function = "pwm7"; };
  };
  &{/soc/pwm@2000c00} {
    pinctrl-names = "default";
    pinctrl-0 = <&pwm0_pb5>, <&pwm1_pb6>, <&pwm2_pb11>, <&pwm3_pb0>,
                <&pwm4_pb1>, <&pwm5_pd21>, <&pwm7_pb10>;
    status = "okay";
  };
  """pwm7ch
{:ok, "/data/pwm7ch.dtbo", "pwm7ch"}
iex(livebook@nerves.local)5> DtsBuddy.load(compiled)
:ok
iex(livebook@nerves.local)6> DtsBuddy.status("pwm7ch")
:applied
iex(livebook@nerves.local)7> Pwmx.list_available_outputs()
[
  {"pwmchip0", 0},
  {"pwmchip0", 1},
  {"pwmchip0", 2},
  {"pwmchip0", 3},
  {"pwmchip0", 4},
  {"pwmchip0", 5},
  {"pwmchip0", 6},
  {"pwmchip0", 7}
]
iex(livebook@nerves.local)8>
outs = for ch <- [0, 1, 2, 3, 4, 5, 7], into: %{} 
  {:ok, pid} = Pwmx.Output.start_link({"pwmchip0", ch})
  pid |> Pwmx.Output.set_period(500_000, :us) |> Pwmx.Output.set_duty_cycle_absolute(250_000, :us)  |> Pwmx.Output.enable()
  {ch, pid}
end
  • PWM5 on header pin 11
  • PWM0 on header pin 12
  • PWM3 on header pin 15
  • PWM4 on header pin 16
  • PWM1 on header pin 35
  • PWM2 on header pin 31
  • and PWM7 on pin 29 all work :slight_smile: .