defmodule Fledex.LedStripDriver.SpiDriver do alias Fledex.Color.Correction @behaviour Fledex.LedStripDriver.Driver use Fledex.Color.Types @impl true @spec init(map) :: map def init(init_module_args) do config = %{ dev: init_module_args[:dev] || "spidev0.0", mode: init_module_args[:mode] || 0, bits_per_word: init_module_args[:bits_per_word] || 8, speed_hz: init_module_args[:speed_hz] || 1_000_000, delay_us: init_module_args[:delay_us] || 10, lsb_first: init_module_args[:lsb_first] || false, color_correction: init_module_args[:color_correction] || Correction.no_color_correction(), ref: nil } put_in(config.ref, open_spi(config)) end @spec open_spi(map) :: reference def open_spi(config) do {:ok, ref} = Circuits.SPI.open(config.dev, mode: config.mode, bits_per_word: config.bits_per_word, speed_hz: config.speed_hz, delay_us: config.delay_us, lsb_first: config.lsb_first ) ref end @impl true @spec transfer(list(colorint), pos_integer, map) :: map def transfer(leds, _counter, config) do binary = leds |> Correction.apply_rgb_correction(config.color_correction) |> Enum.reduce(<<>>, fn led, acc -> acc <> <> end) {:ok, _} = Circuits.SPI.transfer(config.ref, binary) config end @impl true @spec terminate(reason, map) :: :ok when reason: :normal | :shutdown | {:shutdown, term()} | term() def terminate(_reason, config) do Circuits.SPI.close(config.ref) end end