Packages

Pure Elixir driver for EInk Panels

Current section

Files

Jump to
eink lib eink.ex
Raw

lib/eink.ex

# SPDX-FileCopyrightText: 2025 Gus Workman
# SPDX-FileCopyrightText: 2026 Frank Hunleth
# SPDX-License-Identifier: Apache-2.0
defmodule EInk do
@moduledoc """
Top-level API for driving e-paper panels.
`EInk` wraps a display driver module that implements the `EInk.Driver`
behaviour (for example `EInk.Driver.UC8179` or `EInk.Driver.UC8276`) and
exposes a single interface for clearing and drawing to the panel,
regardless of which controller chip is underneath.
{:ok, eink} =
EInk.new(EInk.Driver.UC8276,
spi_device: "spidev0.0",
reset_pin: 17,
busy_pin: 24,
dc_pin: 25
)
EInk.clear(eink, :white)
EInk.draw(eink, image_binary)
"""
require Logger
@type t() :: %__MODULE__{}
defstruct [:driver_mod, :driver]
@doc """
Initializes a display using the given driver module.
`driver_module` must implement the `EInk.Driver` behaviour. `opts` are
passed through to the driver's `new/1` callback and typically include
the GPIO pins and SPI device used to talk to the panel.
Resets and initializes the panel before returning.
"""
def new(driver_module, opts \\ []) do
{:ok, driver} = driver_module.new(opts)
driver_module.reset(driver)
driver_module.init(driver)
{:ok, %__MODULE__{driver: driver, driver_mod: driver_module}}
end
@doc """
Fills the panel with a solid color.
`color` is `:white` (default) or `:black`. `eink_opts` are passed through
to `draw/3`, e.g. `refresh_type: :full` or `refresh_type: :partial`.
"""
@spec clear(t(), :white | :black) :: :ok | {:error, any()}
def clear(%__MODULE__{} = eink, color \\ :white, eink_opts \\ []) do
%{width: w, height: h} = eink.driver_mod.capabilities()
num_pixels = w * h
num_bytes = Integer.floor_div(num_pixels, 8)
data =
case color do
:white ->
:binary.copy(<<0xFF>>, num_bytes)
:black ->
:binary.copy(<<0x00>>, num_bytes)
other ->
raise "Invalid color `#{other}`. Supported colors are `:white`, `:black`, and `gray`"
end
Logger.debug("clearing screen")
draw(eink, data, eink_opts)
end
@doc """
Draws a raw image to the panel.
`image` is a 1-bit-per-pixel binary, row-major, sized to the driver's
`width * height` capability. `opts` are driver-specific; the built-in
drivers accept `refresh_type: :full | :partial`.
"""
def draw(eink, image, opts \\ []) do
eink.driver_mod.draw(eink.driver, image, opts)
end
end