├── test ├── test_helper.exs └── eink_test.exs ├── rel ├── plugins │ └── .gitignore ├── config.exs └── vm.args ├── README.md ├── config ├── config.exs ├── host.exs └── device.exs ├── .gitignore ├── rootfs_overlay └── etc │ └── iex.exs ├── lib ├── eink │ └── application.ex ├── eink.ex └── scenes │ └── main.ex ├── mix.exs └── mix.lock /test/test_helper.exs: -------------------------------------------------------------------------------- 1 | ExUnit.start() 2 | -------------------------------------------------------------------------------- /rel/plugins/.gitignore: -------------------------------------------------------------------------------- 1 | *.* 2 | !*.exs 3 | !.gitignore -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Eink tutorial 2 | 3 | After cloning, to try it on your host, run: 4 | 5 | ``` 6 | export MIX_TARGET=host 7 | mix deps.get 8 | mix scenic.run 9 | ``` 10 | -------------------------------------------------------------------------------- /test/eink_test.exs: -------------------------------------------------------------------------------- 1 | defmodule EinkTest do 2 | use ExUnit.Case 3 | doctest Eink 4 | 5 | test "greets the world" do 6 | assert Eink.hello() == :world 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /config/config.exs: -------------------------------------------------------------------------------- 1 | use Mix.Config 2 | 3 | targeting = 4 | case Mix.target() do 5 | :host -> :host 6 | _ -> :device 7 | end 8 | 9 | import_config "#{targeting}.exs" 10 | -------------------------------------------------------------------------------- /config/host.exs: -------------------------------------------------------------------------------- 1 | use Mix.Config 2 | 3 | # Note: We don't need the hal_module config anymore 4 | config :eink, :viewport, %{ 5 | name: :main_viewport, 6 | default_scene: {Eink.Scene.Main, nil}, 7 | # Match these to your inky display 8 | size: {212, 104}, 9 | opts: [scale: 1.0], 10 | drivers: [ 11 | %{ 12 | module: Scenic.Driver.Glfw 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # The directory Mix will write compiled artifacts to. 2 | /_build/ 3 | 4 | # If you run "mix test --cover", coverage assets end up here. 5 | /cover/ 6 | 7 | # The directory Mix downloads your dependencies sources to. 8 | /deps/ 9 | 10 | # Where 3rd-party dependencies like ExDoc output generated docs. 11 | /doc/ 12 | 13 | # Ignore .fetch files in case you like to edit your project deps locally. 14 | /.fetch 15 | 16 | # If the VM crashes, it generates a dump, let's ignore it too. 17 | erl_crash.dump 18 | -------------------------------------------------------------------------------- /rootfs_overlay/etc/iex.exs: -------------------------------------------------------------------------------- 1 | # Add Toolshed helpers to the IEx session 2 | use Toolshed 3 | 4 | if RingLogger in Application.get_env(:logger, :backends, []) do 5 | IO.puts """ 6 | RingLogger is collecting log messages from Elixir and Linux. To see the 7 | messages, either attach the current IEx session to the logger: 8 | 9 | RingLogger.attach 10 | 11 | or print the next messages in the log: 12 | 13 | RingLogger.next 14 | """ 15 | end 16 | 17 | # Be careful when adding to this file. Nearly any error can crash the VM and 18 | # cause a reboot. 19 | -------------------------------------------------------------------------------- /lib/eink/application.ex: -------------------------------------------------------------------------------- 1 | defmodule Eink.Application do 2 | @target Mix.target() 3 | 4 | use Application 5 | 6 | @spec start(any, any) :: :ignore | {:error, any} | {:ok, pid} 7 | def start(_type, _args) do 8 | opts = [strategy: :one_for_one, name: Eink.Supervisor] 9 | Supervisor.start_link(children(@target), opts) 10 | end 11 | 12 | def children(_target) do 13 | main_viewport_config = Application.get_env(:eink, :viewport) 14 | 15 | [ 16 | {Eink.Display, []}, 17 | {Scenic, viewports: [main_viewport_config]} 18 | ] 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/eink.ex: -------------------------------------------------------------------------------- 1 | defmodule Eink.Display do 2 | use GenServer 3 | 4 | def start_link(opts) do 5 | GenServer.start_link(__MODULE__, nil, opts) 6 | end 7 | 8 | @impl true 9 | def init(_) do 10 | {:ok, pid} = 11 | Inky.start_link(:phat, :red, %{ 12 | hal_mod: Application.get_env(:inky, :hal_module, Inky.RpiHAL) 13 | }) 14 | 15 | Inky.set_pixels(pid, fn x, y, _width, _height, _current -> 16 | # Delightful checkerboard 17 | x_odd = rem(x, 2) != 0 18 | y_odd = rem(y, 2) != 0 19 | 20 | case x_odd do 21 | true -> 22 | case y_odd do 23 | true -> :black 24 | false -> :accent 25 | end 26 | 27 | false -> 28 | case y_odd do 29 | true -> :accent 30 | false -> :white 31 | end 32 | end 33 | end) 34 | 35 | {:ok, nil} 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /lib/scenes/main.ex: -------------------------------------------------------------------------------- 1 | defmodule Eink.Scene.Main do 2 | use Scenic.Scene 3 | alias Scenic.Graph 4 | 5 | import Scenic.Primitives 6 | 7 | @font :roboto 8 | @font_size 20 9 | 10 | def init(_, _) do 11 | graph = 12 | Graph.build(font_size: @font_size, font: @font, theme: :light) 13 | |> rectangle({212, 32}, fill: :red) 14 | |> rectangle({212, 64}, t: {0, 32}, fill: :white) 15 | |> rectangle({212, 8}, t: {0, 32 + 64}, fill: :red) 16 | |> do_aligned_text("HELLO", :white, @font_size + 6, 212, 20) 17 | |> do_aligned_text("my name is", :white, @font_size - 6, 212, 28) 18 | |> do_aligned_text("Inky", :black, @font_size + 32, 212, 80) 19 | 20 | state = %{ 21 | graph: graph 22 | } 23 | 24 | {:ok, state, push: graph} 25 | end 26 | 27 | defp do_aligned_text(graph, text, fill, font_size, width, vpos) do 28 | text(graph, text, 29 | font_size: font_size, 30 | fill: fill, 31 | translate: {width / 2, vpos}, 32 | text_align: :center 33 | ) 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /rel/config.exs: -------------------------------------------------------------------------------- 1 | use Mix.Releases.Config, 2 | # This sets the default release built by `mix release` 3 | default_release: :default, 4 | # This sets the default environment used by `mix release` 5 | default_environment: :dev 6 | 7 | # For a full list of config options for both releases 8 | # and environments, visit https://hexdocs.pm/distillery/config/distillery.html 9 | 10 | # You may define one or more environments in this file, 11 | # an environment's settings will override those of a release 12 | # when building in that environment, this combination of release 13 | # and environment configuration is called a profile 14 | 15 | environment :dev do 16 | set(cookie: :"Unused with Nerves. See vm.args") 17 | end 18 | 19 | environment :prod do 20 | set(cookie: :"Unused with Nerves. See vm.args") 21 | end 22 | 23 | # You may define one or more releases in this file. 24 | # If you have not set a default release, or selected one 25 | # when running `mix release`, the first release in the file 26 | # will be used by default 27 | 28 | release :eink do 29 | set(version: current_version(:eink)) 30 | set(strip_debug_info: true) 31 | plugin(Nerves) 32 | plugin(Shoehorn) 33 | end 34 | -------------------------------------------------------------------------------- /config/device.exs: -------------------------------------------------------------------------------- 1 | use Mix.Config 2 | 3 | config :nerves, :firmware, rootfs_overlay: "rootfs_overlay" 4 | 5 | config :shoehorn, 6 | init: [:nerves_runtime, :nerves_init_gadget], 7 | app: Mix.Project.config()[:app] 8 | 9 | config :logger, backends: [RingLogger] 10 | 11 | keys = 12 | [ 13 | "./nerves.pub" 14 | ] 15 | |> Enum.filter(&File.exists?/1) 16 | 17 | if keys == [], 18 | do: 19 | Mix.raise(""" 20 | No SSH public keys found in ~/.ssh. An ssh authorized key is needed to 21 | log into the Nerves device and update firmware on it using ssh. 22 | See your project's config.exs for this error message. 23 | """) 24 | 25 | config :nerves_firmware_ssh, 26 | authorized_keys: Enum.map(keys, &File.read!/1) 27 | 28 | node_name = if Mix.env() != :prod, do: "eink" 29 | 30 | config :nerves_init_gadget, 31 | ifname: "usb0", 32 | address_method: :dhcpd, 33 | mdns_domain: "nerves.local", 34 | node_name: node_name, 35 | node_host: :mdns_domain 36 | 37 | config :eink, :viewport, %{ 38 | name: :main_viewport, 39 | default_scene: {Eink.Scene.Main, nil}, 40 | # Note: Match these to your inky display 41 | size: {212, 104}, 42 | opts: [scale: 1.0], 43 | drivers: [ 44 | %{ 45 | module: ScenicDriverInky, 46 | opts: [ 47 | # Note: Match these to your Inky display 48 | type: :phat, 49 | accent: :red, 50 | opts: %{ 51 | border: :black 52 | } 53 | ] 54 | } 55 | ] 56 | } 57 | -------------------------------------------------------------------------------- /rel/vm.args: -------------------------------------------------------------------------------- 1 | ## Add custom options here 2 | 3 | ## Distributed Erlang Options 4 | ## The cookie needs to be configured prior to vm boot for 5 | ## for read only filesystem. 6 | 7 | # -name eink@0.0.0.0 8 | -setcookie qxmzklclxypgv7vi2ukitotft6wfpft7jtbwosefjcdv5itgg5h4y5dej7sj3jkq 9 | 10 | ## Use Ctrl-C to interrupt the current shell rather than invoking the emulator's 11 | ## break handler and possibly exiting the VM. 12 | +Bc 13 | 14 | # Allow time warps so that the Erlang system time can more closely match the 15 | # OS system time. 16 | +C multi_time_warp 17 | 18 | ## Load code at system startup 19 | ## See http://erlang.org/doc/system_principles/system_principles.html#code-loading-strategy 20 | -mode embedded 21 | 22 | ## Save the shell history between reboots 23 | ## See http://erlang.org/doc/man/kernel_app.html for additional options 24 | -kernel shell_history enabled 25 | 26 | ## Enable heartbeat monitoring of the Erlang runtime system 27 | -heart -env HEART_BEAT_TIMEOUT 30 28 | 29 | ## Start the Elixir shell 30 | 31 | -noshell 32 | -user Elixir.IEx.CLI 33 | 34 | ## Enable colors in the shell 35 | -elixir ansi_enabled true 36 | 37 | ## Options added after -extra are interpreted as plain arguments and can be 38 | ## retrieved using :init.get_plain_arguments(). Options before the "--" are 39 | ## interpreted by Elixir and anything afterwards is left around for other IEx 40 | ## and user applications. 41 | -extra --no-halt 42 | -- 43 | --dot-iex /etc/iex.exs 44 | 45 | -------------------------------------------------------------------------------- /mix.exs: -------------------------------------------------------------------------------- 1 | defmodule Eink.MixProject do 2 | use Mix.Project 3 | 4 | @all_targets [:rpi, :rpi0, :rpi2, :rpi3, :rpi3a, :bbb, :x86_64] 5 | 6 | def project do 7 | [ 8 | app: :eink, 9 | version: "0.1.0", 10 | elixir: "~> 1.8", 11 | archives: [nerves_bootstrap: "~> 1.5"], 12 | start_permanent: Mix.env() == :prod, 13 | build_embedded: true, 14 | aliases: [loadconfig: [&bootstrap/1]], 15 | deps: deps() 16 | ] 17 | end 18 | 19 | # Starting nerves_bootstrap adds the required aliases to Mix.Project.config() 20 | # Aliases are only added if MIX_TARGET is set. 21 | def bootstrap(args) do 22 | Application.start(:nerves_bootstrap) 23 | Mix.Task.run("loadconfig", args) 24 | end 25 | 26 | # Run "mix help compile.app" to learn about applications. 27 | def application do 28 | [ 29 | mod: {Eink.Application, []}, 30 | extra_applications: [:logger, :runtime_tools] 31 | ] 32 | end 33 | 34 | # Run "mix help deps" to learn about dependencies. 35 | defp deps do 36 | [ 37 | # Dependencies for all targets 38 | {:nerves, "~> 1.4", runtime: false}, 39 | {:shoehorn, "~> 0.4"}, 40 | {:ring_logger, "~> 0.6"}, 41 | {:toolshed, "~> 0.2"}, 42 | {:scenic, "~> 0.10"}, 43 | {:inky, "~> 1.0"}, 44 | {:scenic_driver_inky, "~> 1.0", targets: [:rpi, :rpi0, :rpi2, :rpi3, :rpi3a]}, 45 | {:scenic_driver_glfw, "~> 0.10", targets: :host}, 46 | 47 | # Dependencies for all targets except :host 48 | {:nerves_runtime, "~> 0.6", targets: @all_targets}, 49 | {:nerves_init_gadget, "~> 0.4", targets: @all_targets}, 50 | 51 | # Dependencies for specific targets 52 | {:nerves_system_rpi, "~> 1.6", runtime: false, targets: :rpi}, 53 | {:nerves_system_rpi0, "~> 1.6", runtime: false, targets: :rpi0}, 54 | {:nerves_system_rpi2, "~> 1.6", runtime: false, targets: :rpi2}, 55 | {:nerves_system_rpi3, "~> 1.6", runtime: false, targets: :rpi3}, 56 | {:nerves_system_rpi3a, "~> 1.6", runtime: false, targets: :rpi3a}, 57 | {:nerves_system_bbb, "~> 2.0", runtime: false, targets: :bbb}, 58 | {:nerves_system_x86_64, "~> 1.6", runtime: false, targets: :x86_64} 59 | ] 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /mix.lock: -------------------------------------------------------------------------------- 1 | %{ 2 | "artificery": {:hex, :artificery, "0.4.2", "3ded6e29e13113af52811c72f414d1e88f711410cac1b619ab3a2666bbd7efd4", [:mix], [], "hexpm"}, 3 | "circuits_gpio": {:hex, :circuits_gpio, "0.4.1", "344dd34f2517687fd28723e5552571babff5469db05b697181cab860fe7eff23", [:make, :mix], [{:elixir_make, "~> 0.5", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"}, 4 | "circuits_spi": {:hex, :circuits_spi, "0.1.3", "a94889abc874e9976f397c649152776d9c0863e5fd3377203c7f0cf992d9609c", [:make, :mix], [{:elixir_make, "~> 0.5", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"}, 5 | "distillery": {:hex, :distillery, "2.0.14", "25fc1cdad06282334dbf4a11b6e869cc002855c4e11825157498491df2eed594", [:mix], [{:artificery, "~> 0.2", [hex: :artificery, repo: "hexpm", optional: false]}], "hexpm"}, 6 | "dns": {:hex, :dns, "2.1.2", "81c46d39f7934f0e73368355126e4266762cf227ba61d5889635d83b2d64a493", [:mix], [{:socket, "~> 0.3.13", [hex: :socket, repo: "hexpm", optional: false]}], "hexpm"}, 7 | "elixir_make": {:hex, :elixir_make, "0.6.0", "38349f3e29aff4864352084fc736fa7fa0f2995a819a737554f7ebd28b85aaab", [:mix], [], "hexpm"}, 8 | "font_metrics": {:hex, :font_metrics, "0.3.1", "025ff9957040eb4d6430c306a4445bad5d9f43ec24448c1647df7cb63b5dd88c", [:mix], [{:msgpax, "~> 2.2", [hex: :msgpax, repo: "hexpm", optional: false]}], "hexpm"}, 9 | "inky": {:hex, :inky, "1.0.0", "7275ffae2e752c524b3f1fa79ed1ba7a431e2014710fff338ffbb2f7202aa205", [:mix], [{:circuits_gpio, "~> 0.4", [hex: :circuits_gpio, repo: "hexpm", optional: false]}, {:circuits_spi, "~> 0.1", [hex: :circuits_spi, repo: "hexpm", optional: false]}], "hexpm"}, 10 | "mdns": {:hex, :mdns, "1.0.3", "f08414daf5636bf5cd364611e838818e9250c91a3282a817ad9174b03e757401", [:mix], [{:dns, "~> 2.0", [hex: :dns, repo: "hexpm", optional: false]}], "hexpm"}, 11 | "msgpax": {:hex, :msgpax, "2.2.3", "02be0be1b440a12d7e6f6c45662463d53d01a30b5bd4ab806276453b455f820a", [:mix], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm"}, 12 | "nerves": {:hex, :nerves, "1.4.5", "b1a5f41f3909d76e3ca7cec41f050d89f91c8c6755bc35b8d0e9265d9711c184", [:mix], [{:distillery, "~> 2.0.0", [hex: :distillery, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"}, 13 | "nerves_firmware_ssh": {:hex, :nerves_firmware_ssh, "0.4.4", "12b0d9c84ec9f79c1b0ac0de1c575372ef972d0c58ce21c36bf354062c6222d9", [:mix], [{:nerves_runtime, "~> 0.6", [hex: :nerves_runtime, repo: "hexpm", optional: false]}], "hexpm"}, 14 | "nerves_init_gadget": {:hex, :nerves_init_gadget, "0.6.0", "64eb8877b438678aed6d421737326a8cac3810b425e00abd5c7a3a0e95054988", [:mix], [{:mdns, "~> 1.0", [hex: :mdns, repo: "hexpm", optional: false]}, {:nerves_firmware_ssh, "~> 0.2", [hex: :nerves_firmware_ssh, repo: "hexpm", optional: false]}, {:nerves_network, "~> 0.3", [hex: :nerves_network, repo: "hexpm", optional: false]}, {:nerves_runtime, "~> 0.3", [hex: :nerves_runtime, repo: "hexpm", optional: false]}, {:one_dhcpd, "~> 0.1", [hex: :one_dhcpd, repo: "hexpm", optional: false]}, {:ring_logger, "~> 0.4", [hex: :ring_logger, repo: "hexpm", optional: false]}], "hexpm"}, 15 | "nerves_network": {:hex, :nerves_network, "0.5.5", "4690c362707f76c4072810bd9639b2ae8eb7dd9c21119656308b462a087230aa", [:make, :mix], [{:elixir_make, "~> 0.5", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nerves_network_interface, "~> 0.4.4", [hex: :nerves_network_interface, repo: "hexpm", optional: false]}, {:nerves_wpa_supplicant, "~> 0.5", [hex: :nerves_wpa_supplicant, repo: "hexpm", optional: false]}, {:one_dhcpd, "~> 0.2.0", [hex: :one_dhcpd, repo: "hexpm", optional: false]}, {:system_registry, "~> 0.7", [hex: :system_registry, repo: "hexpm", optional: false]}], "hexpm"}, 16 | "nerves_network_interface": {:hex, :nerves_network_interface, "0.4.6", "d50e57daca8154f0f780fd98eb5ae94a005579e0d72d69840e80e228375d88ad", [:make, :mix], [{:elixir_make, "~> 0.5", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"}, 17 | "nerves_runtime": {:hex, :nerves_runtime, "0.10.1", "4cefcfbcb99f237def5346e1dc881bda523811ede26adfd3a2204e6f26530146", [:make, :mix], [{:elixir_make, "~> 0.5", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:system_registry, "~> 0.5", [hex: :system_registry, repo: "hexpm", optional: false]}, {:uboot_env, "~> 0.1", [hex: :uboot_env, repo: "hexpm", optional: false]}], "hexpm"}, 18 | "nerves_system_bbb": {:hex, :nerves_system_bbb, "2.2.2", "799f3b5ef5403a1a24f095705bcc13a8556160254ad1e4e0a66acd880deed999", [:mix], [{:nerves, "~> 1.3", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_system_br, "1.7.2", [hex: :nerves_system_br, repo: "hexpm", optional: false]}, {:nerves_system_linter, "~> 0.3.0", [hex: :nerves_system_linter, repo: "hexpm", optional: false]}, {:nerves_toolchain_arm_unknown_linux_gnueabihf, "1.1.0", [hex: :nerves_toolchain_arm_unknown_linux_gnueabihf, repo: "hexpm", optional: false]}], "hexpm"}, 19 | "nerves_system_br": {:hex, :nerves_system_br, "1.7.2", "e34895b19241a6f847e16c4b659e89566376ee3a9e8af303f0d36c73d1a98c64", [:mix], [], "hexpm"}, 20 | "nerves_system_linter": {:hex, :nerves_system_linter, "0.3.0", "84e0f63c8ac196b16b77608bbe7df66dcf352845c4e4fb394bffd2b572025413", [:mix], [], "hexpm"}, 21 | "nerves_system_rpi": {:hex, :nerves_system_rpi, "1.7.2", "e367c750119f39bd9d2575d6ec48820b9a781a26df3aeb4d7e20fd28f70e961b", [:mix], [{:nerves, "~> 1.3", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_system_br, "1.7.2", [hex: :nerves_system_br, repo: "hexpm", optional: false]}, {:nerves_system_linter, "~> 0.3.0", [hex: :nerves_system_linter, repo: "hexpm", optional: false]}, {:nerves_toolchain_armv6_rpi_linux_gnueabi, "1.1.0", [hex: :nerves_toolchain_armv6_rpi_linux_gnueabi, repo: "hexpm", optional: false]}], "hexpm"}, 22 | "nerves_system_rpi0": {:hex, :nerves_system_rpi0, "1.7.2", "7bff1a168d83c1f4ece902ffc1a7f6b782d12062dbe01e47f77e29cb48d23369", [:mix], [{:nerves, "~> 1.3", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_system_br, "1.7.2", [hex: :nerves_system_br, repo: "hexpm", optional: false]}, {:nerves_system_linter, "~> 0.3.0", [hex: :nerves_system_linter, repo: "hexpm", optional: false]}, {:nerves_toolchain_armv6_rpi_linux_gnueabi, "1.1.0", [hex: :nerves_toolchain_armv6_rpi_linux_gnueabi, repo: "hexpm", optional: false]}], "hexpm"}, 23 | "nerves_system_rpi2": {:hex, :nerves_system_rpi2, "1.7.2", "a60dc0b90be150ec694b3dd1aab69e2b3cb900fb973343d557b6fbdb97af00d3", [:mix], [{:nerves, "~> 1.3", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_system_br, "1.7.2", [hex: :nerves_system_br, repo: "hexpm", optional: false]}, {:nerves_system_linter, "~> 0.3.0", [hex: :nerves_system_linter, repo: "hexpm", optional: false]}, {:nerves_toolchain_arm_unknown_linux_gnueabihf, "1.1.0", [hex: :nerves_toolchain_arm_unknown_linux_gnueabihf, repo: "hexpm", optional: false]}], "hexpm"}, 24 | "nerves_system_rpi3": {:hex, :nerves_system_rpi3, "1.7.2", "9b4373b954ab339bee91981cfa5a1011185c555eea1826fb39fc34aa44990e22", [:mix], [{:nerves, "~> 1.3", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_system_br, "1.7.2", [hex: :nerves_system_br, repo: "hexpm", optional: false]}, {:nerves_system_linter, "~> 0.3.0", [hex: :nerves_system_linter, repo: "hexpm", optional: false]}, {:nerves_toolchain_arm_unknown_linux_gnueabihf, "1.1.0", [hex: :nerves_toolchain_arm_unknown_linux_gnueabihf, repo: "hexpm", optional: false]}], "hexpm"}, 25 | "nerves_system_rpi3a": {:hex, :nerves_system_rpi3a, "1.7.2", "e6550986eb51fbd430aa044d252f769f031b0a2da855c0990fdb9aac62e539c0", [:mix], [{:nerves, "~> 1.3", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_system_br, "1.7.2", [hex: :nerves_system_br, repo: "hexpm", optional: false]}, {:nerves_system_linter, "~> 0.3.0", [hex: :nerves_system_linter, repo: "hexpm", optional: false]}, {:nerves_toolchain_arm_unknown_linux_gnueabihf, "1.1.0", [hex: :nerves_toolchain_arm_unknown_linux_gnueabihf, repo: "hexpm", optional: false]}], "hexpm"}, 26 | "nerves_system_x86_64": {:hex, :nerves_system_x86_64, "1.7.2", "ad6cb765aa32d49c8044aeffbdd9cb0e6837388521436ceb514b12f8bff58969", [:mix], [{:nerves, "~> 1.3", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_system_br, "1.7.2", [hex: :nerves_system_br, repo: "hexpm", optional: false]}, {:nerves_system_linter, "~> 0.3.0", [hex: :nerves_system_linter, repo: "hexpm", optional: false]}, {:nerves_toolchain_x86_64_unknown_linux_musl, "1.1.0", [hex: :nerves_toolchain_x86_64_unknown_linux_musl, repo: "hexpm", optional: false]}], "hexpm"}, 27 | "nerves_toolchain_arm_unknown_linux_gnueabihf": {:hex, :nerves_toolchain_arm_unknown_linux_gnueabihf, "1.1.0", "ca466a656f8653346a8551a35743f7c41046f3d53e945723e970cb4a7811e617", [:mix], [{:nerves, "~> 1.0", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_toolchain_ctng, "~> 1.5.0", [hex: :nerves_toolchain_ctng, repo: "hexpm", optional: false]}], "hexpm"}, 28 | "nerves_toolchain_armv6_rpi_linux_gnueabi": {:hex, :nerves_toolchain_armv6_rpi_linux_gnueabi, "1.1.0", "2753102e667d9778047b351618f3dfdc016b81148df58d142fee7630d96a31fe", [:mix], [{:nerves, "~> 1.0", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_toolchain_ctng, "~> 1.5.0", [hex: :nerves_toolchain_ctng, repo: "hexpm", optional: false]}], "hexpm"}, 29 | "nerves_toolchain_ctng": {:hex, :nerves_toolchain_ctng, "1.5.0", "34b8f5664858ff6ce09730b26221441398acd1fa361b8c6d744d9ec18238c16b", [:mix], [{:nerves, "~> 1.0", [hex: :nerves, repo: "hexpm", optional: false]}], "hexpm"}, 30 | "nerves_toolchain_x86_64_unknown_linux_musl": {:hex, :nerves_toolchain_x86_64_unknown_linux_musl, "1.1.0", "02b8cacdddb12d8dbac62324f893103cc0ca38fb4f7d6c1557d9236c93223219", [:mix], [{:nerves, "~> 1.0", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_toolchain_ctng, "~> 1.5.0", [hex: :nerves_toolchain_ctng, repo: "hexpm", optional: false]}], "hexpm"}, 31 | "nerves_wpa_supplicant": {:hex, :nerves_wpa_supplicant, "0.5.2", "4ec392fc08faf35f50d1070446c2e5019f6b85bd53f5716f904e3f75716d9596", [:make, :mix], [{:elixir_make, "~> 0.5", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"}, 32 | "one_dhcpd": {:hex, :one_dhcpd, "0.2.2", "2dfdcad61ed7c6d9f652bc1a06f14924a497de2c2aa2d4f48ee3b1aa13be0f33", [:make, :mix], [{:elixir_make, "~> 0.5", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"}, 33 | "ring_logger": {:hex, :ring_logger, "0.8.0", "b1baddc269099b2afe2ea3a87b8e2b71e57331c0000038ae55090068aac679db", [:mix], [], "hexpm"}, 34 | "rpi_fb_capture": {:hex, :rpi_fb_capture, "0.2.1", "23edff195b3cce53fde3b311bc1b86cac82046fb2ad77eae211dfcfa6684e5de", [:make, :mix], [{:elixir_make, "~> 0.5", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"}, 35 | "scenic": {:hex, :scenic, "0.10.2", "f4f0a00eed677ac50a7b297375c0323d03f4273580f17c50b877abfaf0c6dc1f", [:make, :mix], [{:elixir_make, "~> 0.5", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:font_metrics, "~> 0.3", [hex: :font_metrics, repo: "hexpm", optional: false]}], "hexpm"}, 36 | "scenic_driver_glfw": {:hex, :scenic_driver_glfw, "0.10.0", "01a00c8da910c56ef908bf886826a5a28989a3919b6e63b982e66ba226d3bf9d", [:make, :mix], [{:elixir_make, "~> 0.5", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:scenic, "~> 0.10", [hex: :scenic, repo: "hexpm", optional: false]}], "hexpm"}, 37 | "scenic_driver_inky": {:hex, :scenic_driver_inky, "1.0.0", "320131912311f1837a4f010ab79a1348ffcd870e576c8a6d232b4feb688a343c", [:mix], [{:inky, "~> 1.0.0", [hex: :inky, repo: "hexpm", optional: false]}, {:rpi_fb_capture, "~> 0.1", [hex: :rpi_fb_capture, repo: "hexpm", optional: false]}, {:scenic, "~> 0.9", [hex: :scenic, repo: "hexpm", optional: false]}, {:scenic_driver_nerves_rpi, "~> 0.9", [hex: :scenic_driver_nerves_rpi, repo: "hexpm", optional: false]}], "hexpm"}, 38 | "scenic_driver_nerves_rpi": {:hex, :scenic_driver_nerves_rpi, "0.10.0", "6aa51e6f026386b5f09a082e54a59f8fcdb7e838437f8d4bdb8fa26c9c77f228", [:make, :mix], [{:elixir_make, "~> 0.5", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:scenic, "~> 0.10", [hex: :scenic, repo: "hexpm", optional: false]}], "hexpm"}, 39 | "shoehorn": {:hex, :shoehorn, "0.5.0", "da8e37dbee92454dd8e20c86953de94bdcaddb2dcda6c72cf4a3de5f52e0f322", [:mix], [{:distillery, "~> 2.0", [hex: :distillery, repo: "hexpm", optional: false]}], "hexpm"}, 40 | "socket": {:hex, :socket, "0.3.13", "98a2ab20ce17f95fb512c5cadddba32b57273e0d2dba2d2e5f976c5969d0c632", [:mix], [], "hexpm"}, 41 | "system_registry": {:hex, :system_registry, "0.8.2", "df791dc276652fcfb53be4dab823e05f8269b96ac57c26f86a67838dbc0eefe7", [:mix], [], "hexpm"}, 42 | "toolshed": {:hex, :toolshed, "0.2.10", "31e33f3bfbd88085a5f34844930a75e579940417873eb8a5c25b9525ad1a1372", [:mix], [{:nerves_runtime, "~> 0.8", [hex: :nerves_runtime, repo: "hexpm", optional: true]}], "hexpm"}, 43 | "uboot_env": {:hex, :uboot_env, "0.1.1", "b01e3ec0973e99473234f27839e29e63b5b81eba6a136a18a78d049d4813d6c5", [:mix], [], "hexpm"}, 44 | } 45 | --------------------------------------------------------------------------------