/*
-----------------------------------------------------------------------------
This source file is part of OpenSpace3D
For the latest info, see http://www.openspace3d.com
Copyright (c) 2012 I-maginer
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt
-----------------------------------------------------------------------------
*/
/*
Version : 1.0
First version : 05/08/2010
Author : Bourineau Bastien
*/
var iDeviceBootTime = 3500;; //some devices like arduino can take some time to initialize
/*! \brief Callback on instance destruction
*
* Prototype: fun [PInstance SerialIO] I
*
* \param PInstance : destroyed plugIT instance
* \param SerialIO : serial object
*
* \return I : 0
**/
fun deleteOb(inst, p)=
let p -> [inst scom sport speed parity bytesize stopbits lastchar trm] in
(
if (trm == nil) then nil else
_deltimer trm;
_closeSIO scom;
);
0;;
/*! \brief Split buffer to separator separate messages
*
* Prototype: fun [S S] [S r1]
*
* \param S : buffer
* \param S : separator
*
* \return [S r1] : splitted buffer
**/
fun getbuffer(s, sep)=
let strlen s -> size in
let strlen sep -> sizesep in
let nil -> nbuf in
let 0 -> lpos in
let 0 -> pos in
if (sizesep == 0) then
["" s::nbuf]
else
(
while ((set pos = (strfind sep s lpos)) != nil) do
(
//addLogMessage strcatn (itoa pos)::" "::(substr s lpos (pos - lpos))::nil;
if nbuf == nil then
set nbuf = (substr s lpos (pos - lpos))::nil
else
set nbuf = lcat nbuf (substr s lpos (pos - lpos))::nil;
0;
set lpos = pos + sizesep;
);
let "" -> rbuf in
(
if (lpos >= size) then nil else
set rbuf = substr s lpos (size - lpos);
[rbuf nbuf];
);
);;
/*! \brief Callback on serial receive data
*
* Prototype: fun [SerialIO [PInstance S S] S I] I
*
* \param SerialIO : serial object
* \param [PInstance S] : plugIT instance and last buffer
* \param S : data
* \param I : data size
*
* \return I : 0
**/
fun cbRead(com, p, data, size)=
let p -> [inst slastchar buffer] in
let getbuffer (strcat buffer data) slastchar -> [rest lbuf] in
(
mutate p <- [_ _ rest];
while lbuf != nil do
(
// Send "Read" event messages
SendPluginEvent inst "Read" hd lbuf nil;
set lbuf = tl lbuf;
);
);
0;;
/*! \brief Callback on "Send" dms action
*
* Write param link data to serial object
*
* Prototype: fun [PInstance DMI S S I [SerialIO I I I I S]] I
*
* \param PInstance : plugIT instance
* \param DMI : DMS module who call the action (not used)
* \param S : name of the launched action
* \param S : data posted in DMS action link
* \param I : reply flag (not used)
* \param [SerialIO S] : Serial object and char to add at the end of message
*
* \return I : 0
**/
fun cbSend(inst, from, action, param, reply, p)=
let p -> [inst scom sport speed parity bytesize stopbits lastchar trm] in
_writeSIO scom strcat param lastchar;
0;;
fun cbConnectTrm(trm, p)=
_deltimer trm;
mutate p <- [_ _ _ _ _ _ _ _ nil];
let p -> [inst _ _ _ _ _ _ _ _] in
SendPluginEvent inst "Opened" nil nil;
0;;
/*! \brief Callback on "Set com port" dms action
*
* Reconnect the serial com on a new port
*
* Prototype: fun [PInstance DMI S S I [SerialIO I I I I S]] I
*
* \param PInstance : plugIT instance
* \param DMI : DMS module who call the action (not used)
* \param S : name of the launched action
* \param S : data posted in DMS action link
* \param I : reply flag (not used)
* \param [SerialIO I I I I S] : Serial object and char to add at the end of message
*
* \return I : 0
**/
fun cbSetComPort(inst, from, action, param, reply, p)=
let p -> [inst scom sport speed parity bytesize stopbits lastchar trm] in
(
if (trm == nil) then nil else
_deltimer trm;
_closeSIO scom;
let _openSIO _channel param [speed parity bytesize stopbits] @cbRead [inst lastchar ""] -> ncom in
mutate p <- [_ ncom param _ _ _ _ _ (_rfltimer _starttimer _channel iDeviceBootTime @cbConnectTrm p)];
);
0;;
fun cbConnect(inst, from, action, param, reply, p)=
let p -> [inst scom sport speed parity bytesize stopbits lastchar trm] in
(
if (trm == nil) then nil else
_deltimer trm;
_closeSIO scom;
let _openSIO _channel sport [speed parity bytesize stopbits] @cbRead [inst lastchar ""] -> ncom in
mutate p <- [_ ncom _ _ _ _ _ _ (_rfltimer _starttimer _channel iDeviceBootTime @cbConnectTrm p)];
);
0;;
fun cbDisconnect(inst, from, action, param, reply, p)=
let p -> [inst scom sport speed parity bytesize stopbits lastchar trm] in
(
if (trm == nil) then nil else
_deltimer trm;
_closeSIO scom;
mutate p <- [_ nil _ _ _ _ _ _ nil];
);
0;;
/*! \brief Callback on new plugIT instance
*
* Read the parameters from editor values and connect the serial port
*
* Prototype: fun [PInstance] I
*
* \param PInstance : plugIT instance
*
* \return I : 0
**/
fun newOb(inst)=
let (getPluginInstanceParam inst "port") -> sport in
let if sport == nil then "1" else sport -> sport in
let atoi (getPluginInstanceParam inst "speed") -> speed in
let if speed == nil then 9600 else speed -> speed in
let atoi (getPluginInstanceParam inst "bytesize") -> bytesize in
let if bytesize == nil then 8 else bytesize -> bytesize in
let atoi (getPluginInstanceParam inst "parity") -> parity in
let if parity == nil then 0 else parity -> parity in
let atoi (getPluginInstanceParam inst "stopbits") -> stopbits in
let if stopbits == nil then 0 else stopbits -> stopbits in // 0 equal to onestopbit
let atoi (getPluginInstanceParam inst "lastchar") -> lastchar in
let if lastchar == nil then 0 else lastchar -> lastchar in
let atoi (getPluginInstanceParam inst "init") -> init in
let if init == nil then 1 else init -> init in
// NONE CR CRLF
let if lastchar == 1 then ctoa 13 else if lastchar == 2 then (strcat (ctoa 13) (ctoa 10)) else "" -> slastchar in
let if (!init) then nil else _openSIO _channel sport [speed parity bytesize stopbits] @cbRead [inst slastchar ""] -> scom in
let if (!init) then nil else _starttimer _channel iDeviceBootTime -> trm in
let [inst scom sport speed parity bytesize stopbits slastchar trm] -> p in
(
if (!init) then nil else
_rfltimer trm @cbConnectTrm p;
PluginRegisterAction inst "Connect" mkfun6 @cbConnect p;
PluginRegisterAction inst "Disconnect" mkfun6 @cbDisconnect p;
PluginRegisterAction inst "Send" mkfun6 @cbSend p;
PluginRegisterAction inst "Set com port" mkfun6 @cbSetComPort p;
setPluginInstanceCbDel inst mkfun2 @deleteOb p;
);
0;;
/*! \brief Global plugIT function to initialize the plugIT callbacks
*
* Prototype: fun [S] I
*
* \param S : plugIT file path
*
* \return I : 0
**/
fun IniPlug(file)=
PlugRegister @newOb nil;
setPluginEditor @dynamicedit;
0;;