Pure Elixir library to interact with the sysfs interface to hardware PWM on Linux.
Usage
Fully manual
If you wish to just write and read to the sysfs Pwm interface, you can find path helpers in the Pwmx.Paths module.
iex> File.read(Pwmx.Paths.duty_cycle_path("pwmchip0", "1"))Helper functions
If you want an Elixir interface instead of calling File.write/2 or File.read/1 yourself, the module Pwmx.Backend.Sysfs.Ops has a stateless interface that actually performs the reads and writes.
iex> Pwmx.Backend.Sysfs.Ops.get_duty_cycle("pwmchip0", 1)Managed
The Pwmx.Output module can be used to spin up a genserver representing your output, managing its state.
iex> {:ok, pid} = Pwmx.Output.start_link({"virtualchip0", 1})
iex> Pwmx.Output.enable(pid) |> Pwmx.Output.set_period(1_000, :ms)
iex> 1_000_000_000 = Pwmx.Output.get_period(pid)Testing & non-linux hosts
In a test or non-linux environment, the Pwmx.Backend.Sysfs module is not used, and calls are instead dispatched to Pwmx.Backend.Virtual, which keeps track of your operations on PWM outputs with the Pwmx.State struct. This struct isn't meant to be used directly as it wouldn't be of particular help.
The application supervises a default backend registered as Pwmx.Backend. To test code that
drives PWM outputs without stepping on shared state, start your own isolated, configurable
virtual backend and pass it to Pwmx.Output.start_link/2 (or Pwmx.open/3). Each instance holds
its own state, so tests can run concurrently:
iex> {:ok, backend} = Pwmx.Backend.start_link(mode: :virtual, virtual_chips: %{"virtualchip0" => 4})
iex> {:ok, pid} = Pwmx.Output.start_link({"virtualchip0", 1}, backend: backend)
iex> Pwmx.Output.enable(pid) |> Pwmx.Output.set_period(1_000, :ms)
iex> 1_000_000_000 = Pwmx.Output.get_period(pid)
Summary
Functions
Lists the available outputs. Accepts an optional backend instance, defaulting
to the application-supervised Pwmx.Backend.
Spins up a Pwmx.Output GenServer. Accepts the same options as
Pwmx.Output.start_link/2, notably :backend to bind it to a specific backend instance.
Functions
@spec list_available_outputs(GenServer.server()) :: [{binary(), integer()}]
Lists the available outputs. Accepts an optional backend instance, defaulting
to the application-supervised Pwmx.Backend.
iex> Pwmx.list_available_outputs()
[
{"virtualchip0", 0},
{"virtualchip0", 1},
{"virtualchip0", 2},
{"virtualchip0", 3}
]
Spins up a Pwmx.Output GenServer. Accepts the same options as
Pwmx.Output.start_link/2, notably :backend to bind it to a specific backend instance.
iex> {:ok, _pid} = Pwmx.open("virtualchip0", 3)