From bc029da6d1b6bb0c248f4c2c697e3b5e36ff8901 Mon Sep 17 00:00:00 2001 From: Anders Blomdell <anders.blomdell@control.lth.se> Date: Tue, 26 Mar 2019 16:41:33 +0100 Subject: [PATCH] Add julia adaptor --- adaptors/julia/AnalogIn.jl | 38 ++++++++++ adaptors/julia/AnalogOut.jl | 35 ++++++++++ adaptors/julia/DigitalIn.jl | 38 ++++++++++ adaptors/julia/DigitalOut.jl | 35 ++++++++++ adaptors/julia/EncoderIn.jl | 38 ++++++++++ adaptors/julia/Makefile | 1 + adaptors/julia/MobergIO.jl | 35 ++++++++++ adaptors/julia/moberg.jl | 126 ++++++++++++++++++++++++++++++++++ adaptors/julia/test_moberg.jl | 66 ++++++++++++++++++ 9 files changed, 412 insertions(+) create mode 100644 adaptors/julia/AnalogIn.jl create mode 100644 adaptors/julia/AnalogOut.jl create mode 100644 adaptors/julia/DigitalIn.jl create mode 100644 adaptors/julia/DigitalOut.jl create mode 100644 adaptors/julia/EncoderIn.jl create mode 100644 adaptors/julia/Makefile create mode 100644 adaptors/julia/MobergIO.jl create mode 100755 adaptors/julia/moberg.jl create mode 100644 adaptors/julia/test_moberg.jl diff --git a/adaptors/julia/AnalogIn.jl b/adaptors/julia/AnalogIn.jl new file mode 100644 index 0000000..ac4d4a1 --- /dev/null +++ b/adaptors/julia/AnalogIn.jl @@ -0,0 +1,38 @@ +mutable struct AnalogInChannel + context::Ptr{Nothing} + read::Ptr{Nothing} +end + +mutable struct AnalogIn + moberg::Moberg + index::UInt32 + channel::AnalogInChannel + AnalogIn(moberg::Moberg, index::Unsigned) = ( + channel = AnalogInChannel(0,0); + checkOK(ccall((:moberg_analog_in_open, "libmoberg"), + Status, + (Moberg, Cint, Ref{AnalogInChannel}), + moberg, index, channel)); + self = new(moberg, index, channel); + finalizer(close, self); + self + ) +end + +function close(ain::AnalogIn) + # println("closing $(ain)") + checkOK(ccall((:moberg_analog_in_close, "libmoberg"), + Status, + (Moberg, Cint, AnalogInChannel), + ain.moberg, ain.index, ain.channel)) +end + +function read(ain::AnalogIn) + result = Ref{Cdouble}(0.0) + checkOK(ccall(ain.channel.read, + Status, + (Ptr{Nothing}, Ptr{Cdouble}), + ain.channel.context, result)) + return result[] +end + diff --git a/adaptors/julia/AnalogOut.jl b/adaptors/julia/AnalogOut.jl new file mode 100644 index 0000000..534960f --- /dev/null +++ b/adaptors/julia/AnalogOut.jl @@ -0,0 +1,35 @@ +mutable struct AnalogOutChannel + context::Ptr{Nothing} + write::Ptr{Nothing} +end + +mutable struct AnalogOut + moberg::Moberg + index::UInt32 + channel::AnalogOutChannel + AnalogOut(moberg::Moberg, index::Unsigned) = ( + channel = AnalogOutChannel(0,0); + checkOK(ccall((:moberg_analog_out_open, "libmoberg"), + Status, + (Moberg, Cint, Ref{AnalogOutChannel}), + moberg, index, channel)); + self = new(moberg, index, channel); + finalizer(close, self); + self + ) +end + +function close(aout::AnalogOut) + # println("closing $(aout)") + checkOK(ccall((:moberg_analog_out_close, "libmoberg"), + Status, + (Moberg, Cint, AnalogOutChannel), + aout.moberg, aout.index, aout.channel)) +end; + +function write(aout::AnalogOut, value::Cdouble) + checkOK(ccall(aout.channel.write, + Status, + (Ptr{Nothing}, Cdouble), + aout.channel.context, value)) +end diff --git a/adaptors/julia/DigitalIn.jl b/adaptors/julia/DigitalIn.jl new file mode 100644 index 0000000..74c455d --- /dev/null +++ b/adaptors/julia/DigitalIn.jl @@ -0,0 +1,38 @@ +mutable struct DigitalInChannel + context::Ptr{Nothing} + read::Ptr{Nothing} +end + +mutable struct DigitalIn + moberg::Moberg + index::UInt32 + channel::DigitalInChannel + DigitalIn(moberg::Moberg, index::Unsigned) = ( + channel = DigitalInChannel(0,0); + checkOK(ccall((:moberg_digital_in_open, "libmoberg"), + Status, + (Moberg, Cint, Ref{DigitalInChannel}), + moberg, index, channel)); + self = new(moberg, index, channel); + finalizer(close, self); + self + ) +end + +function close(din::DigitalIn) + # println("closing $(din)") + checkOK(ccall((:moberg_digital_in_close, "libmoberg"), + Status, + (Moberg, Cint, DigitalInChannel), + din.moberg, din.index, din.channel)) +end + +function read(din::DigitalIn) + result = Ref{Cint}(0) + checkOK(ccall(din.channel.read, + Status, + (Ptr{Nothing}, Ptr{Cint}), + din.channel.context, result)) + return result[] != 0 +end + diff --git a/adaptors/julia/DigitalOut.jl b/adaptors/julia/DigitalOut.jl new file mode 100644 index 0000000..7dc18b7 --- /dev/null +++ b/adaptors/julia/DigitalOut.jl @@ -0,0 +1,35 @@ +mutable struct DigitalOutChannel + context::Ptr{Nothing} + write::Ptr{Nothing} +end + +mutable struct DigitalOut + moberg::Moberg + index::UInt32 + channel::DigitalOutChannel + DigitalOut(moberg::Moberg, index::Unsigned) = ( + channel = DigitalOutChannel(0,0); + checkOK(ccall((:moberg_digital_out_open, "libmoberg"), + Status, + (Moberg, Cint, Ref{DigitalOutChannel}), + moberg, index, channel)); + self = new(moberg, index, channel); + finalizer(close, self); + self + ) +end + +function close(dout::DigitalOut) + # println("closing $(dout)") + checkOK(ccall((:moberg_digital_out_close, "libmoberg"), + Status, + (Moberg, Cint, DigitalOutChannel), + dout.moberg, dout.index, dout.channel)) +end; + +function write(dout::DigitalOut, value::Bool) + checkOK(ccall(dout.channel.write, + Status, + (Ptr{Nothing}, Cint), + dout.channel.context, value ? 1 : 0)) +end diff --git a/adaptors/julia/EncoderIn.jl b/adaptors/julia/EncoderIn.jl new file mode 100644 index 0000000..b45046f --- /dev/null +++ b/adaptors/julia/EncoderIn.jl @@ -0,0 +1,38 @@ +mutable struct EncoderInChannel + context::Ptr{Nothing} + read::Ptr{Nothing} +end + +mutable struct EncoderIn + moberg::Moberg + index::UInt32 + channel::EncoderInChannel + EncoderIn(moberg::Moberg, index::Unsigned) = ( + channel = EncoderInChannel(0,0); + checkOK(ccall((:moberg_encoder_in_open, "libmoberg"), + Status, + (Moberg, Cint, Ref{EncoderInChannel}), + moberg, index, channel)); + self = new(moberg, index, channel); + finalizer(close, self); + self + ) +end + +function close(ein::EncoderIn) + # println("closing $(ein)") + checkOK(ccall((:moberg_encoder_in_close, "libmoberg"), + Status, + (Moberg, Cint, EncoderInChannel), + ein.moberg, ein.index, ein.channel)) +end + +function read(ein::EncoderIn) + result = Ref{Clong}(0) + checkOK(ccall(ein.channel.read, + Status, + (Ptr{Nothing}, Ptr{Clong}), + ein.channel.context, result)) + return result[] +end + diff --git a/adaptors/julia/Makefile b/adaptors/julia/Makefile new file mode 100644 index 0000000..1263948 --- /dev/null +++ b/adaptors/julia/Makefile @@ -0,0 +1 @@ +all: diff --git a/adaptors/julia/MobergIO.jl b/adaptors/julia/MobergIO.jl new file mode 100644 index 0000000..ec35eeb --- /dev/null +++ b/adaptors/julia/MobergIO.jl @@ -0,0 +1,35 @@ +module MobergIO + + +struct Status + result::Clong +end + +function checkOK(status::Status) + if status.result != 0 + error("Moberg call failed with errno $(status.result)") + end +end + +mutable struct Moberg + handle::Ptr{Nothing} +end + +function Moberg() + handle = ccall((:moberg_new, "libmoberg"), Ptr{Moberg}, ()) + m = Moberg(handle) + finalizer(close, m) + m +end + +function close(h::Moberg) + ccall((:moberg_free, "libmoberg"), Nothing, (Moberg,), h) +end + +include("AnalogIn.jl") +include("AnalogOut.jl") +include("DigitalIn.jl") +include("DigitalOut.jl") +include("EncoderIn.jl") + +end diff --git a/adaptors/julia/moberg.jl b/adaptors/julia/moberg.jl new file mode 100755 index 0000000..e45888a --- /dev/null +++ b/adaptors/julia/moberg.jl @@ -0,0 +1,126 @@ +#!/usr/bin/julia + +struct moberg_status + result::Clong +end + +function check_OK(status::moberg_status) + if status.result != 0 + error("Moberg call failed with errno $(status.result)") + end +end + +mutable struct moberg + handle::Ptr{Nothing} +end + +function moberg() + handle = ccall((:moberg_new, "libmoberg"), Ptr{Nothing}, ()) + println(handle) + m = moberg(handle) + function close(h::moberg) + println(h) + ccall((:moberg_free, "libmoberg"), Nothing, (Ptr{Nothing},), + h.handle) + end + finalizer(close, m) + m +end + +mutable struct moberg_analog_in + context::Ptr{Nothing} + do_read::Ptr{Nothing} + handle::moberg + moberg_analog_in(m::moberg, index::Unsigned) = ( + self = new(); + check_OK(ccall((:moberg_analog_in_open, "libmoberg"), + moberg_status, + (Ptr{Nothing}, Cint, Ref{moberg_analog_in}), + m.handle, index, self)); + self.handle = m; + function close(channel::moberg_analog_in) + println(channel) + ccall((:moberg_analog_in_close, "libmoberg"), + moberg_status, + (Ptr{Nothing}, Cint, moberg_analog_in), + channel.handle.handle, index, self) + end; + finalizer(close, self); + self + ) +end + +mutable struct moberg_analog_out + context::Ptr{Nothing} + do_write::Ptr{Nothing} + handle::moberg + moberg_analog_out(m::moberg, index::Unsigned) = ( + self = new(); + check_OK(ccall((:moberg_analog_out_open, "libmoberg"), + moberg_status, + (Ptr{Nothing}, Cint, Ref{moberg_analog_out}), + m.handle, index, self)); + self.handle = m; + function close(channel::moberg_analog_out) + println(channel) + ccall((:moberg_analog_out_close, "libmoberg"), + moberg_status, + (Ptr{Nothing}, Cint, moberg_analog_out), + channel.handle.handle, index, self) + end; + finalizer(close, self); + self + ) +end + +function read(ain::moberg_analog_in) + result = Ref{Cdouble}(0.0) + check_OK(ccall(ain.do_read, + moberg_status, + (Ptr{Nothing}, Ptr{Cdouble}), + ain.context, result)) + return result[] +end + +function write(aout::moberg_analog_out, value::Cdouble) + check_OK(ccall(aout.do_write, + moberg_status, + (Ptr{Nothing}, Cdouble), + aout.context, value)) +end + +function test() + m = moberg() + println(m) + + for v in -10.0:2.0:10 + for i in 30:31 + try + aout = moberg_analog_out(m, Unsigned(i)) + value = v + i - 32; + write(aout, value) + print("$value ") + catch + println("analog_out $i does not exist") + end + end + println() + sleep(0.1) + for j in 30:33 + try + ain = moberg_analog_in(m, Unsigned(j)) + println(read(ain)) + catch + println("analog_in $j does not exist") + end + end + println() + GC.gc() + end +end + +test() + +println("DONE") +GC.gc() +println("Really DONE") diff --git a/adaptors/julia/test_moberg.jl b/adaptors/julia/test_moberg.jl new file mode 100644 index 0000000..3f3a22d --- /dev/null +++ b/adaptors/julia/test_moberg.jl @@ -0,0 +1,66 @@ +#!/usr/bin/julia + +push!(LOAD_PATH, ".") + +using MobergIO +import MobergIO: read, write + +function test() + m = MobergIO.Moberg() + println(m) + + for v in -10.0:2.0:10 + for i in 30:31 + try + aout = MobergIO.AnalogOut(m, Unsigned(i)) + value = v + i - 32; + write(aout, value) + print("$value ") + catch ex + println("analog_out $i does not exist $(ex)") + end + end + println() + sleep(0.01) + for j in 30:33 + try + ain = MobergIO.AnalogIn(m, Unsigned(j)) + println(read(ain)) + catch ex + println("analog_in $j does not exist $(ex)") + end + end + println() +# GC.gc() + end + for v in false:true + for i in 30:36 + try + dout = MobergIO.DigitalOut(m, Unsigned(i)) + value = xor(v, isodd(i)) + write(dout, value) + print("$value ") + catch ex + println("digital_out $i does not exist $(ex)") + end + end + println() + for i in 30:36 + try + din = MobergIO.DigitalIn(m, Unsigned(i)) + print("$(read(din)) ") + catch ex + println("digital_out $i does not exist $(ex)") + end + end + println() + println() + sleep(0.01) + end +end + +test() + +println("DONE") +GC.gc() +println("Really DONE") -- GitLab