Finish firmware contract.
parent
d0b2c00153
commit
78650b67e5
|
@ -6,17 +6,22 @@ defmodule Farmbot.Firmware do
|
|||
|
||||
@doc "Move the bot to a position."
|
||||
def move_absolute(vec3) do
|
||||
GenStage.call(__MODULE__, {:move_absolute, vec3})
|
||||
GenStage.call(__MODULE__, {:move_absolute, [vec3]})
|
||||
end
|
||||
|
||||
@doc "Calibrate an axis."
|
||||
def calibrate(axis) do
|
||||
GenStage.call(__MODULE__, {:calibrate, axis})
|
||||
GenStage.call(__MODULE__, {:calibrate, [axis]})
|
||||
end
|
||||
|
||||
@doc "Find home on an axis."
|
||||
def find_home(axis) do
|
||||
GenStage.call(__MODULE__, {:find_home, axis})
|
||||
GenStage.call(__MODULE__, {:find_home, [axis]})
|
||||
end
|
||||
|
||||
@doc "Manually set an axis's current position to zero."
|
||||
def zero(axis) do
|
||||
GenStage.call(__MODULE__, {:zero, [axis]})
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
@ -24,7 +29,7 @@ defmodule Farmbot.Firmware do
|
|||
For a list of paramaters see `Farmbot.Firmware.Gcode.Param`
|
||||
"""
|
||||
def update_param(param, val) do
|
||||
GenStage.call(__MODULE__, {:update_param, param, val})
|
||||
GenStage.call(__MODULE__, {:update_param, [param, val]})
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
@ -32,27 +37,27 @@ defmodule Farmbot.Firmware do
|
|||
For a list of paramaters see `Farmbot.Firmware.Gcode.Param`
|
||||
"""
|
||||
def read_param(param) do
|
||||
GenStage.call(__MODULE__, {:read_param, param})
|
||||
GenStage.call(__MODULE__, {:read_param, [param]})
|
||||
end
|
||||
|
||||
@doc "Emergency lock Farmbot."
|
||||
def emergency_lock() do
|
||||
GenStage.call(__MODULE__, :emergency_lock)
|
||||
GenStage.call(__MODULE__, {:emergency_lock, []})
|
||||
end
|
||||
|
||||
@doc "Unlock Farmbot from Emergency state."
|
||||
def emergency_unlock() do
|
||||
GenStage.call(__MODULE__, :emergency_unlock)
|
||||
GenStage.call(__MODULE__, {:emergency_unlock, []})
|
||||
end
|
||||
|
||||
@doc "Read a pin."
|
||||
def read_pin(pin, mode) do
|
||||
GenStage.call(__MODULE__, {:read_pin, pin, mode})
|
||||
GenStage.call(__MODULE__, {:read_pin, [pin, mode]})
|
||||
end
|
||||
|
||||
@doc "Write a pin."
|
||||
def write_pin(pin, mode, value) do
|
||||
GenStage.call(__MODULE__, {:write_pin, pin, mode, value})
|
||||
GenStage.call(__MODULE__, {:write_pin, [pin, mode, value]})
|
||||
end
|
||||
|
||||
@doc "Start the firmware services."
|
||||
|
@ -63,14 +68,32 @@ defmodule Farmbot.Firmware do
|
|||
## GenStage
|
||||
|
||||
defmodule State do
|
||||
defstruct handler: nil, idle: false
|
||||
defstruct handler: nil, handler_mod: nil, idle: false
|
||||
end
|
||||
|
||||
def init([]) do
|
||||
handler_mod = Application.get_env(:farmbot, :behaviour)[:firmware_handler] || raise("No fw handler.")
|
||||
handler_mod =
|
||||
Application.get_env(:farmbot, :behaviour)[:firmware_handler] || raise("No fw handler.")
|
||||
|
||||
{:ok, handler} = handler_mod.start_link()
|
||||
Process.link(handler)
|
||||
{:producer_consumer, %State{handler: handler}, subscribe_to: [handler], dispatcher: GenStage.BroadcastDispatcher}
|
||||
|
||||
{
|
||||
:producer_consumer,
|
||||
%State{handler: handler, handler_mod: handler_mod},
|
||||
subscribe_to: [handler], dispatcher: GenStage.BroadcastDispatcher
|
||||
}
|
||||
end
|
||||
|
||||
def handle_call({fun, args}, _from, %{handler: handler, handler_mod: handler_mod} = state) do
|
||||
res =
|
||||
case apply(handler_mod, fun, [handler | args]) do
|
||||
{:ok, _} = res -> res
|
||||
:ok = res -> res
|
||||
{:error, _} = res -> res
|
||||
end
|
||||
|
||||
{:reply, res, [], state}
|
||||
end
|
||||
|
||||
def handle_events(gcodes, _from, state) do
|
||||
|
|
|
@ -38,6 +38,12 @@ defmodule Farmbot.Firmware.Handler do
|
|||
@doc "Calibrate an axis."
|
||||
@callback calibrate(handler, axis) :: fw_ret_val
|
||||
|
||||
@doc "Find home on an axis."
|
||||
@callback find_home(handler, axis) :: fw_ret_val
|
||||
|
||||
@doc "Manually set an axis's current position to zero."
|
||||
@callback zero(handler, axis) :: fw_ret_val
|
||||
|
||||
@doc "Update a paramater."
|
||||
@callback update_param(handler, fw_param, number) :: fw_ret_val
|
||||
|
||||
|
@ -50,9 +56,6 @@ defmodule Farmbot.Firmware.Handler do
|
|||
@doc "Unlock the firmware."
|
||||
@callback emergency_unlock(handler) :: fw_ret_val
|
||||
|
||||
@doc "Find home on an axis."
|
||||
@callback find_home(handler, axis) :: fw_ret_val
|
||||
|
||||
@doc "Read a pin."
|
||||
@callback read_pin(handler, pin, pin_mode) :: {:ok, number} | {:error, term}
|
||||
|
||||
|
|
|
@ -5,26 +5,106 @@ defmodule Farmbot.Firmware.StubHandler do
|
|||
require Logger
|
||||
|
||||
@behaviour Farmbot.Firmware.Handler
|
||||
alias Farmbot.Firmware.Vec3
|
||||
|
||||
## Firmware Handler Behaviour.
|
||||
|
||||
def start_link do
|
||||
Logger.warn("Firmware is being stubbed.")
|
||||
GenStage.start_link(__MODULE__, [])
|
||||
end
|
||||
|
||||
def move_absolute(pos) do
|
||||
GenStage.call(__MODULE__, {:move_absolute, pos})
|
||||
def move_absolute(handler, pos) do
|
||||
GenStage.call(handler, {:move_absolute, pos})
|
||||
end
|
||||
|
||||
def calibrate(handler, axis) do
|
||||
GenStage.call(handler, {:calibrate, axis})
|
||||
end
|
||||
|
||||
def find_home(handler, axis) do
|
||||
GenStage.call(handler, {:find_home, axis})
|
||||
end
|
||||
|
||||
def zero(handler, axis) do
|
||||
GenStage.call(handler, {:zero, axis})
|
||||
end
|
||||
|
||||
def update_param(handler, param, val) do
|
||||
GenStage.call(handler, {:update_param, param, val})
|
||||
end
|
||||
|
||||
def read_param(handler, param) do
|
||||
GenStage.call(handler, {:read_param, param})
|
||||
end
|
||||
|
||||
def emergency_lock(handler) do
|
||||
GenStage.call(handler, :emergency_lock)
|
||||
end
|
||||
|
||||
def emergency_unlock(handler) do
|
||||
GenStage.call(handler, :emergency_unlock)
|
||||
end
|
||||
|
||||
def read_pin(handler, pin, pin_mode) do
|
||||
GenStage.call(handler, {:read_pin, pin, pin_mode})
|
||||
end
|
||||
|
||||
def write_pin(handler, pin, pin_mode, value) do
|
||||
GenStage.call(handler, {:write_pin, pin, pin_mode, value})
|
||||
end
|
||||
|
||||
## GenStage Behaviour
|
||||
|
||||
defmodule State do
|
||||
defstruct []
|
||||
defstruct pos: nil,
|
||||
fw_params: %{},
|
||||
locked?: false
|
||||
end
|
||||
|
||||
def init([]) do
|
||||
state = %State{}
|
||||
state = %State{pos: struct(Vec3)}
|
||||
{:producer, state, dispatcher: GenStage.BroadcastDispatcher}
|
||||
end
|
||||
|
||||
def handle_demand(_amnt, state) do
|
||||
{:noreply, [], state}
|
||||
end
|
||||
|
||||
def handle_call({:move_absolute, pos}, _from, state) do
|
||||
{:reply, :ok, [{:report_current_position, pos.x, pos.y, pos.z}], %{state | pos: pos}}
|
||||
end
|
||||
|
||||
def handle_call({:calibrate, _axis}, _from, state) do
|
||||
{:reply, :ok, [], state}
|
||||
end
|
||||
|
||||
def handle_call({:find_home, _axis}, _from, state) do
|
||||
{:reply, :ok, [], state}
|
||||
end
|
||||
|
||||
def handle_call({:zero, axis}, _from, state) do
|
||||
state = %{state | pos: %{state.pos | axis => 0}}
|
||||
case axis do
|
||||
:x -> {:reply, :ok, [{:report_current_position, 0, state.pos.y, state.pos.z}], state}
|
||||
:y -> {:reply, :ok, [{:report_current_position, state.pos.x, 0, state.pos.z}], state}
|
||||
:z -> {:reply, :ok, [{:report_current_position, state.pos.x, state.pos.y, 0}], state}
|
||||
end
|
||||
end
|
||||
|
||||
def handle_call({:update_param, param, val}, _from, state) do
|
||||
{:reply, :ok, [], %{state | fw_params: Map.put(state.fw_params, param, val)}}
|
||||
end
|
||||
|
||||
def handle_call({:read_param, param}, _from, state) do
|
||||
{:reply, state.fw_params[param], [], state}
|
||||
end
|
||||
|
||||
def handle_call(:emergency_lock, _from, state) do
|
||||
{:reply, :ok, [], state}
|
||||
end
|
||||
|
||||
def handle_call(:emergency_unlock, _from, state) do
|
||||
{:reply, :ok, [], state}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,16 +7,48 @@ defmodule Farmbot.Firmware.UartHandler do
|
|||
alias Nerves.UART
|
||||
require Logger
|
||||
|
||||
@doc """
|
||||
Writes a string to the uart line
|
||||
"""
|
||||
def write(code) do
|
||||
GenStage.call(__MODULE__, {:write, code}, :infinity)
|
||||
def start_link do
|
||||
GenStage.start_link(__MODULE__, [])
|
||||
end
|
||||
|
||||
@doc "Starts a UART Firmware Handler."
|
||||
def start_link do
|
||||
GenStage.start_link(__MODULE__, [], name: __MODULE__)
|
||||
def move_absolute(handler, pos) do
|
||||
GenStage.call(handler, {:move_absolute, pos})
|
||||
end
|
||||
|
||||
def calibrate(handler, axis) do
|
||||
GenStage.call(handler, {:calibrate, axis})
|
||||
end
|
||||
|
||||
def find_home(handler, axis) do
|
||||
GenStage.call(handler, {:find_home, axis})
|
||||
end
|
||||
|
||||
def zero(handler, axis) do
|
||||
GenStage.call(handler, {:zero, axis})
|
||||
end
|
||||
|
||||
def update_param(handler, param, val) do
|
||||
GenStage.call(handler, {:update_param, param, val})
|
||||
end
|
||||
|
||||
def read_param(handler, param) do
|
||||
GenStage.call(handler, {:read_param, param})
|
||||
end
|
||||
|
||||
def emergency_lock(handler) do
|
||||
GenStage.call(handler, :emergency_lock)
|
||||
end
|
||||
|
||||
def emergency_unlock(handler) do
|
||||
GenStage.call(handler, :emergency_unlock)
|
||||
end
|
||||
|
||||
def read_pin(handler, pin, pin_mode) do
|
||||
GenStage.call(handler, {:read_pin, pin, pin_mode})
|
||||
end
|
||||
|
||||
def write_pin(handler, pin, pin_mode, value) do
|
||||
GenStage.call(handler, {:write_pin, pin, pin_mode, value})
|
||||
end
|
||||
|
||||
## Private
|
||||
|
@ -86,11 +118,6 @@ defmodule Farmbot.Firmware.UartHandler do
|
|||
{:noreply, [], state}
|
||||
end
|
||||
|
||||
def handle_call({:write, stuff}, _from, state) do
|
||||
r = UART.write(state.nerves, stuff)
|
||||
{:reply, r, [], state}
|
||||
end
|
||||
|
||||
def handle_demand(_amnt, state) do
|
||||
do_dispatch(state.codes, state)
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
defmodule Farmbot.Firmware.Vec3 do
|
||||
@moduledoc "A three position vector."
|
||||
|
||||
defstruct [:x, :y, :z]
|
||||
defstruct [x: -1, y: -1, z: -1]
|
||||
|
||||
@typedoc "Axis label."
|
||||
@type axis :: :x | :y | :z
|
||||
|
|
Loading…
Reference in New Issue