-module(pmod_acl2). -behavior(gen_server). -include("grisp.hrl"). -include("pmod_acl2.hrl"). % API -export([start_link/2]). -export([raw/0]). -export([g/0]). % Callbacks -export([init/1]). -export([handle_call/3]). -export([handle_cast/2]). -export([handle_info/2]). -export([code_change/3]). -export([terminate/2]). -define(SPI_MODE, #{clock => {low, leading}}). %--- Records ------------------------------------------------------------------- -record(state, { bus, mode = '2g' }). %--- API ----------------------------------------------------------------------- % @private start_link(Slot, _Opts) -> gen_server:start_link(?MODULE, Slot, []). raw() -> {_Mode, Result} = call(raw), Result. g() -> {Mode, Result} = call(raw), scale(Mode, Result). %--- Callbacks ----------------------------------------------------------------- % @private init(Slot) -> Bus = grisp_spi:open(Slot), verify_device(Bus), grisp_devices:register(Slot, ?MODULE), transfer(Bus, {?SPI_MODE, <>} ), {ok, #state{bus = Bus}}. % @private handle_call(raw, _From, State) -> Raw = xyz(State#state.bus), {reply, {State#state.mode, Raw}, State}. % @private handle_cast(Request, _State) -> error({unknown_cast, Request}). % @private handle_info(Info, _State) -> error({unknown_info, Info}). % @private code_change(_OldVsn, State, _Extra) -> {ok, State}. % @private terminate(_Reason, _State) -> ok. %--- Internal ------------------------------------------------------------------ call(Call) -> Dev = grisp_devices:default(?MODULE), gen_server:call(Dev#device.pid, Call). xyz(Bus) -> << XDATA_L, _:4, XDATA_H:4, YDATA_L, _:4, YDATA_H:4, ZDATA_L, _:4, ZDATA_H:4 >> = transfer(Bus, {?SPI_MODE, <>, 2, 6}), <> = <>, <> = <>, <> = <>, {X, Y, Z}. scale('2g', {X, Y, Z}) -> {X / 1000, Y / 1000, Z / 1000}. verify_device(Bus) -> [verify_device_reg(Bus, Name, Reg, Val) || {Name, Reg, Val} <- [ {analog_devices_device_id, ?DEVID_AD, ?AD_DEVID}, {analog_devices_mems_device_id, ?DEVID_MST, ?AD_MEMS_DEVID}, {device_id, ?PARTID, ?DEVID} ]]. verify_device_reg(Bus, Name, Reg, Val) -> case transfer(Bus, {?SPI_MODE, <>, 2, 1}) of <> -> ok; Other -> error({device_mismatch, {Name, Other}}) end. transfer(Bus, Message) -> [Response] = grisp_spi:transfer(Bus, [Message]), Response.