/* ----------------------------------------------------------------------------- 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;;