Permalink
Browse files

plugin add_event/3, added polarity handling to input event

  • Loading branch information...
1 parent b5cb5c6 commit cedc433dbfbfb07eef1523eea87ffa5bd0c60c92 @tonyrog committed Mar 3, 2014
Showing with 38 additions and 13 deletions.
  1. +3 −3 src/hex_gpio.erl
  2. +35 −10 src/hex_gpio_server.erl
View
@@ -27,16 +27,16 @@
-export([validate_event/2,
init_event/2,
- add_event/2,
+ add_event/3,
del_event/1,
output/2]).
%%
%% add_event(Flags::[{atom(),term()}, Signal::signal()) ->
%% {ok, Ref:reference()} | {error, Reason}
%%
-add_event(Flags, Signal) ->
- hex_gpio_server:add_event(Flags, Signal).
+add_event(Flags, Signal, Cb) ->
+ hex_gpio_server:add_event(Flags, Signal, Cb).
%%
%% del_event(Ref::reference()) ->
View
@@ -43,11 +43,20 @@
-type edge_mask_t() :: 0..3. %% ?EDGE_xxx (union of all subs)
+-record(sub,
+ {
+ ref :: reference(),
+ edge_mask :: edge_mask_t(),
+ polarity :: boolean(),
+ signal :: term(),
+ callback :: atom() | function()
+ }).
+
-record(pinsub,
{
pin_key :: {PinReg::integer(),Pin::integer()},
edge_mask = 0 :: edge_mask_t(),
- subs = [] :: [{Ref::reference(),Edge::edge_mask_t(),Signal::term()}]
+ subs = [] :: [#sub{}]
}).
-record(state, {
@@ -111,17 +120,17 @@ init([]) ->
%% @end
%%--------------------------------------------------------------------
handle_call({add_event,Flags,Signal,Cb}, _From, State) ->
- %% pin_reg = 0..N, pin = 0..N, interrupt=rising|falling|both
PinReg = proplists:get_value(pin_reg, Flags, 0),
Pin = proplists:get_value(pin, Flags),
Edge = proplists:get_value(interrupt, Flags, both),
+ Polarity = proplists:get_value(polarity, Flags, false),
EdgeMask = case Edge of
falling -> ?EDGE_FALLING;
rising -> ?EDGE_RISING;
both -> ?EDGE_BOTH
end,
Ref = make_ref(),
- case add_pinsub(Ref, {PinReg,Pin}, EdgeMask, Signal, Cb, State) of
+ case add_pinsub(Ref, {PinReg,Pin}, EdgeMask, Polarity, Signal, Cb, State) of
{ok,State1} ->
{reply, {ok,Ref}, State1};
Error ->
@@ -175,9 +184,15 @@ handle_info({gpio_interrupt, PinReg, Pin, Value}, State) ->
end,
%% polarity? on this level? then easy to share.
lists:foreach(
- fun({_Ref,EdgeMask,Signal,Cb}) ->
+ fun(#sub { edge_mask=EdgeMask,
+ polarity=Polarity,
+ signal=Signal,
+ callback=Cb}) ->
if EdgeMask band TriggerMask =/= 0 ->
- callback(Cb,Signal,[{value,Value}]);
+ Value1 = if Polarity -> 1-Value;
+ true -> Value
+ end,
+ callback(Cb,Signal,[{value,Value1}]);
true ->
ok
end
@@ -224,14 +239,19 @@ callback(Cb,Signal,Env) when is_function(Cb, 2) ->
Cb(Signal,Env).
-add_pinsub(Ref,Key={PinReg,Pin},EdgeMask,Signal,Cb,State) ->
+add_pinsub(Ref,Key={PinReg,Pin},EdgeMask,Polarity,Signal,Cb,State) ->
case lists:keytake(Key, #pinsub.pin_key, State#state.pin_list) of
false ->
case set_interrupt_mask(PinReg, Pin, EdgeMask) of
ok ->
+ Sub = #sub { ref = Ref,
+ edge_mask = EdgeMask,
+ polarity = Polarity,
+ signal = Signal,
+ callback = Cb },
PinSub = #pinsub { pin_key = Key,
edge_mask = EdgeMask,
- subs = [{Ref,EdgeMask,Signal,Cb}]
+ subs = [Sub]
},
PinList1 = [PinSub | State#state.pin_list],
RefList1 = [{Ref, Key} | State#state.ref_list],
@@ -249,7 +269,12 @@ add_pinsub(Ref,Key={PinReg,Pin},EdgeMask,Signal,Cb,State) ->
ok
end,
if Res =:= ok ->
- Subs1 = [{Ref,EdgeMask,Signal,Cb}|PinSub#pinsub.subs],
+ Sub = #sub { ref = Ref,
+ edge_mask = EdgeMask,
+ polarity = Polarity,
+ signal = Signal,
+ callback = Cb },
+ Subs1 = [Sub|PinSub#pinsub.subs],
PinSub1 = PinSub#pinsub { edge_mask = Mask1,
subs = Subs1 },
PinList1 = [PinSub1 | PinList],
@@ -271,11 +296,11 @@ del_pinsub(Ref, State) ->
%% {error, enoent}; %% strange!
{ok, State#state { ref_list = RefList1 }};
{value,PinSub,PinList} ->
- case lists:keytake(Ref, 1, PinSub#pinsub.subs) of
+ case lists:keytake(Ref, #sub.ref, PinSub#pinsub.subs) of
false ->
%% {error, enoent}; %% strange!
{ok, State#state { ref_list = RefList1 }};
- {value,{_Ref,_Edge,_Signal,_Cb},Subs1} ->
+ {value,#sub{},Subs1} ->
%% re calculate the pin mask
Mask1 = lists:foldl(fun({_,M,_}, M0) ->
M bor M0

0 comments on commit cedc433

Please sign in to comment.