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