/* ----------------------------------------------------------------------------- This source file is part of OpenSpace3D For the latest info, see http://www.openspace3d.com Copyright (c) 2016 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/29/2016 Author : Bourineau Bastien */ struct PlugGPIOledMatrix = [ GPIOLMAT_inst : PInstance, GPIOLMAT_shiftObj : ObjGpioShiftDriver, GPIOLMAT_bmp : ObjBitmap, GPIOLMAT_lData : [[[I I] r1] r1], GPIOLMAT_iNbFrames : I, GPIOLMAT_iTick : I, GPIOLMAT_iCurFrame : I ]mkPlugGPIOledMatrix;; /*! \brief Callback on instance destruction * * Prototype: fun [PInstance PlugGPIOledMatrix] I * * \param PInstance : destroyed plugIT instance * \param PlugGPIOledMatrix : gpio structure * * \return I : 0 **/ fun deleteOb(inst, obstr)= _dsGPIOshiftDriver obstr.GPIOLMAT_shiftObj; _DSbitmap obstr.GPIOLMAT_bmp; 0;; fun bitRead(value, bit)= (((value) >> (bit)) & 0x01);; fun bitSet(value, bit)= value | (1 << (bit));; fun bitClear(value, bit)= value & ~(1 << (bit));; fun bitWrite(value, bit, bitvalue)= if bitvalue then bitSet value bit else bitClear value bit;; fun cbPreRender(inst, sessionstr, etime, obstr)= let if etime < 1000 then 1 else etime / 1000 -> etime in let (set obstr.GPIOLMAT_iTick = obstr.GPIOLMAT_iTick + etime) -> rtick in if (rtick < (1000 / 10)) then nil else ( if (obstr.GPIOLMAT_iCurFrame < obstr.GPIOLMAT_iNbFrames) then nil else set obstr.GPIOLMAT_iCurFrame = 0; _setGPIOshiftDriverValues obstr.GPIOLMAT_shiftObj nth_list obstr.GPIOLMAT_lData obstr.GPIOLMAT_iCurFrame; set obstr.GPIOLMAT_iCurFrame = obstr.GPIOLMAT_iCurFrame + 1; set obstr.GPIOLMAT_iTick = 0; ); 0;; fun readBmp(obstr, bmp)= if (bmp == nil) then nil else ( set obstr.GPIOLMAT_lData = nil; let _GETbitmapSize bmp -> [bww bh] in let bww / bh -> nbpct in let bww / nbpct -> bw in let 0 -> curpct in ( while (curpct < nbpct) do ( let nil -> data in ( let 0 -> y in while (y < bh) do ( let 0 -> bits in let bw * curpct -> x in ( while (x < (bw * (curpct + 1))) do ( let G2Dgetrgb _GETpixel24 bmp x y -> [r g b] in let (r + g + b) / 3 -> av in let if (av > 128) then 0 else 1 -> val in ( set bits = bitWrite bits (mod x bw) val; ); set x = x + 1; ); set bits = bitWrite bits y + bw 1; set data = [bits 0]::data; ); set y = y + 1; ); set data = revertlist data; set obstr.GPIOLMAT_lData = lcat obstr.GPIOLMAT_lData data::nil; set curpct = curpct + 1; ); ); set obstr.GPIOLMAT_iNbFrames = nbpct; if (nbpct <= 1) then setPluginInstanceCbScenePreRender obstr.GPIOLMAT_inst nil else setPluginInstanceCbScenePreRender obstr.GPIOLMAT_inst mkfun4 @cbPreRender obstr; ); _setGPIOshiftDriverValues obstr.GPIOLMAT_shiftObj hd obstr.GPIOLMAT_lData; ); 0;; /*! \brief Callback on "Set pin X" dms action * * write pin state * * Prototype: fun [PInstance DMI S S I PlugGPIOledMatrix] 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 PlugGPIOledMatrix : gpio structure * * \return I : 0 **/ fun cbSetPicture(inst, from, action, param, rep, obstr)= let G2DloadBmp _channel param -> bmp in let _GETbitmapSize bmp -> [bw bh] in let G2DstrechBitmap _channel bmp ((bw / bh) * 8) 8 0x000000 -> sbmp in ( _DSbitmap obstr.GPIOLMAT_bmp; set obstr.GPIOLMAT_bmp = sbmp; readBmp obstr obstr.GPIOLMAT_bmp; ); 0;; /*! \brief Callback on "All on" dms action * * All shift pin to On * * Prototype: fun [PInstance DMI S S I PlugGPIOledMatrix] 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 PlugGPIOledMatrix : gpio structure * * \return I : 0 **/ fun cbOn(inst, from, action, param, reply, obstr)= setPluginInstanceCbScenePreRender inst nil; _setGPIOshiftDriverValues obstr.GPIOLMAT_shiftObj [0xff00 0]::nil; 0;; /*! \brief Callback on "All off" dms action * * All shift pin to Off * * Prototype: fun [PInstance DMI S S I PlugGPIOledMatrix] 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 PlugGPIOledMatrix : gpio structure * * \return I : 0 **/ fun cbOff(inst, from, action, param, reply, obstr)= setPluginInstanceCbScenePreRender inst nil; _setGPIOshiftDriverValues obstr.GPIOLMAT_shiftObj [0 0]::nil; 0;; /*! \brief Callback on "Set data" dms action * * Set the bits data * * Prototype: fun [PInstance DMI S S I PlugGPIOshift] 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 PlugGPIOshift : gpio structure * * \return I : 0 **/ fun cbSetData(inst, from, action, param, reply, obstr)= let strextr param -> l in let nil -> data in ( let 0 -> y in while l != nil do ( let hd l -> lp in let 0 -> x in let 0 -> bits in ( while (lp != nil) do ( let (atoi (hd lp)) -> p in ( set bits = bitWrite bits x !p; ); set lp = tl lp; set x = x + 1; ); set bits = bitWrite bits (mod y 8) + 8 1; set data = [bits 0]::data; set y = y + 1; ); set l = tl l; ); setPluginInstanceCbScenePreRender obstr.GPIOLMAT_inst nil; set obstr.GPIOLMAT_lData = (revertlist data)::nil; _setGPIOshiftDriverValues obstr.GPIOLMAT_shiftObj hd obstr.GPIOLMAT_lData; ); 0;; /*! \brief Callback on new plugIT instance * * Read the parameters from editor values and init GPIO pin * * Prototype: fun [PInstance] I * * \param PInstance : plugIT instance * * \return I : 0 **/ fun newOb(inst)= let atoi (getPluginInstanceParam inst "pinData") -> pindata in let if pindata == nil then 2 else pindata -> pindata in let atoi (getPluginInstanceParam inst "pinClock") -> pinclock in let if pinclock == nil then 3 else pinclock -> pinclock in let atoi (getPluginInstanceParam inst "pinLatch") -> pinlatch in let if pinlatch == nil then 4 else pinlatch -> pinlatch in let (getPluginInstanceParam inst "path") -> path in let G2DloadBmp _channel path -> bmp in let _GETbitmapSize bmp -> [bw bh] in let G2DstrechBitmap _channel bmp ((bw / bh) * 8) 8 0x000000 -> sbmp in let mkPlugGPIOledMatrix [inst nil sbmp nil 0 0 0] -> obstr in ( set obstr.GPIOLMAT_shiftObj = _crGPIOshiftDriver _channel pindata pinclock pinlatch 16; PluginRegisterAction inst "All on" mkfun6 @cbOn obstr; PluginRegisterAction inst "All off" mkfun6 @cbOff obstr; PluginRegisterAction inst "Set picture" mkfun6 @cbSetPicture obstr; PluginRegisterAction inst "Set data" mkfun6 @cbSetData obstr; readBmp obstr sbmp; setPluginInstanceCbDel inst mkfun2 @deleteOb obstr; ); 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;;