Serial Scol plugin
plugin.cpp
1/*
2-----------------------------------------------------------------------------
3This source file is part of OpenSpace3D
4For the latest info, see http://www.openspace3d.com
5
6Copyright (c) 2012 I-maginer
7
8This program is free software; you can redistribute it and/or modify it under
9the terms of the GNU Lesser General Public License as published by the Free Software
10Foundation; either version 2 of the License, or (at your option) any later
11version.
12
13This program is distributed in the hope that it will be useful, but WITHOUT
14ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16
17You should have received a copy of the GNU Lesser General Public License along with
18this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19Place - Suite 330, Boston, MA 02111-1307, USA, or go to
20http://www.gnu.org/copyleft/lesser.txt
21
22-----------------------------------------------------------------------------
23*/
24
25/*
26 SERIAL IO library
27 First version : jully 2011
28 Author : Bastien Bourineau
29*/
30
44#include "plugin.h"
45#include "BufferedAsyncSerial.h"
46#include <scolMemoryHelper.hpp>
47
48#ifdef SCOL_STATIC
49extern cbmachine ww;
50extern mmachine mm;
51#else
52cbmachine ww;
53mmachine mm;
54#endif
55
56//OBJECT
57int OBJSERIALSCOL;
58int SERIALSCOL_NB_CB = 1;
59
60//===== CB UNIT ON ===
61int SCOL_SERIAL_READ_CB = 0;
62int SERIAL_READ_CB;
63
80int _openSIO (mmachine m)
81{
82 int k = 0;
83 int baudRate, parity, byteSize, stopBits;
84
85 int pUser = MMpull(m);
86 int pCbk = MMpull(m);
87 int pSettings = MMpull(m);
88 int pName = MMpull(m);
89
90 //MMechostr (0, "_openSIO : start\n");
91 // check IO device name
92 if (pName == NIL)
93 {
94 MMechostr (MSKDEBUG, "\n_openSIO error : IO device name is nil...\n");
95 MMset(m, 0, NIL);
96 return 0;
97 }
98
99 std::string portnum((char*)MMstartstr(m, MTOP(pName)));
100 if (pSettings == NIL)
101 {
102 baudRate = 9600;
103 parity = 0;
104 byteSize = 8;
105 stopBits = 0;
106 }
107 else
108 {
109 pSettings = MTOP(pSettings);
110 baudRate = MTOI(MMfetch (m, pSettings, 0));
111 parity = MTOI(MMfetch (m, pSettings, 1));
112 byteSize = MTOI(MMfetch (m, pSettings, 2));
113 stopBits = MTOI(MMfetch (m, pSettings, 3));
114 }
115
116 // check reading callback
117 if (pCbk == NIL)
118 {
119 MMechostr (0, "\n_openSIO error : reading callback is nil...\n");
120 MMset(m, 0, NIL);
121 return 0;
122 }
123
124 MMechostr(0, "_openSIO : new SerialIO\n");
125 // launch serial connection
126#ifndef ANDROID
127 boost::asio::serial_port_base::character_size bsize(byteSize);
128 boost::asio::serial_port_base::parity bparity = boost::asio::serial_port_base::parity((parity == 1) ? boost::asio::serial_port_base::parity::odd : (parity == 2) ? boost::asio::serial_port_base::parity::even : boost::asio::serial_port_base::parity::none);
129 boost::asio::serial_port_base::stop_bits bstop = boost::asio::serial_port_base::stop_bits((stopBits == 3) ? boost::asio::serial_port_base::stop_bits::onepointfive : (parity == 2) ? boost::asio::serial_port_base::stop_bits::two : boost::asio::serial_port_base::stop_bits::one);
130
131 BufferedAsyncSerial* serialObj = new BufferedAsyncSerial(portnum, baudRate, bparity, bsize, boost::asio::serial_port_base::flow_control(boost::asio::serial_port_base::flow_control::none), bstop);
132#else
133 BufferedAsyncSerial* serialObj = new BufferedAsyncSerial(portnum);
134#endif
135 if (serialObj == 0)
136 {
137 MMset(m, 0, NIL);
138 return 0;
139 }
140
141 //
142 // create scol SerialIO object
143 //
144
145 if ((MMpushPointer(m, serialObj) != 0))
146 {
147 SAFE_DELETE(serialObj);
148 MMset(m, 0, NIL);
149 return MERRMEM;
150 }
151
152 if ((k = OBJcreate(m, OBJSERIALSCOL, SCOL_PTR serialObj, NIL, 0))) return k;
153
154 /* add reflex */
155 if ((k = MMpush(m, pCbk))) return k; /* reading callback */
156 if ((k = MMpush(m, pUser))) return k; /* user param */
157 if ((k = OBJaddreflex(m, OBJSERIALSCOL, SCOL_SERIAL_READ_CB))) return k;
158
159 //MMechostr (0, "_openSIO : done SerialIO\n");
160 return 0;
161}
162
163
172int _closeSIO(mmachine m)
173{
174#ifdef _SCOL_DEBUG_
175 MMechostr(MSKDEBUG,"SCcloseSIO\n");
176#endif
177
178 int objtab = MMget(m, 0);
179 if (objtab == NIL)
180 {
181 MMechostr(MSKDEBUG, "_closeSIO : SerialIO NIL\n");
182 MMset(m, 0, NIL);
183 return 0;
184 }
185
186 OBJdelTM(m, OBJSERIALSCOL, objtab);
187 MMset(m, 0, ITOM(0));
188
189#ifdef _SCOL_DEBUG_
190 MMechostr(MSKDEBUG,"ok\n");
191#endif
192 return 0;
193}
194
195
205int _writeSIO(mmachine m)
206{
207 int s = MMpull(m);
208 int objtab = MMget(m, 0);
209 if ((s == NIL) || (objtab == NIL))
210 {
211 MMset(m, 0, NIL);
212 return 0;
213 }
214
215 BufferedAsyncSerial* serialObj = MMgetPointer<BufferedAsyncSerial*>(m, MTOP(objtab));
216 if (serialObj == 0)
217 {
218 MMset(m, 0, NIL);
219 return 0;
220 }
221
222 std::string data = (char*)MMstart(m, (MTOP(s))+1);
223 serialObj->writeString(data);
224
225 MMset(m, 0, ITOM(0));
226 return 0;
227}
228
229
230int getSerialReadCb(mmachine m, SCOL_PTR_TYPE id, SCOL_PTR_TYPE param)
231{
232 int k = 0;
234 std::string* data = (std::string*)param;
235
236 if (serialObj == 0)
237 {
238 delete(data);
239 return 0;
240 }
241
242 // OBJbeginreflex(mmachine, objecttype, objectptr, cbtype)
243 if (OBJbeginreflex(m, OBJSERIALSCOL, SCOL_PTR serialObj, SCOL_SERIAL_READ_CB))
244 {
245 delete(data);
246 return 0;
247 }
248
249 int res = MMmalloc (m,((data->size()+4)>>2)+1, TYPEBUF);
250 *(int*) MMstart(m, res) = data->size();
251 char* BS = (char*)MMstart(m, res + 1);
252 memcpy(BS, data->data(), data->size());
253
254 if ((k = MMpush(m, (res<<1) + 1))) return k;
255 if ((k = MMpush(m, ITOM(data->size())))) return k;
256
257 k=OBJcallreflex(m, 2);
258 delete(data);
259 return k;
260}
261
262static NativeDefinition sSerialDef[] =
263{
264 { "_openSIO", 5, "fun [Chn S [I I I I] fun [SerialIO u0 S I] I u0] SerialIO", _openSIO },
265 { "_closeSIO", 1, "fun [SerialIO] I", _closeSIO },
266 { "_writeSIO", 2, "fun [SerialIO S] I", _writeSIO }
267};
268
270int destroySerialIO(mmachine m, SCOL_PTR_TYPE handsys, int objtab)
271{
272 BufferedAsyncSerial* serialObj = MMgetPointer<BufferedAsyncSerial*>(m, MTOP(objtab));
273 SAFE_DELETE(serialObj);
274 MMsetPointer<BufferedAsyncSerial*>(m, MTOP(objtab), 0);
275
276 return 0;
277}
278
279
280// Everything inside _cond and _endcond is ignored by doxygen
282
286int LoadSerialIO(mmachine m)
287{
288 // Scol type declaration
289 OBJSERIALSCOL = OBJregister(SERIALSCOL_NB_CB, 0, destroySerialIO, "SerialIO");
290
291 //****************************** Callbacks for serial *******************************************************
292
293 //===== CB READ ===
294 SERIAL_READ_CB = OBJgetUserEvent();
295 OBJdefEvent(SERIAL_READ_CB, getSerialReadCb);
296
297 // load scol functions
298 int k = PKhardpak2(m, "serialIO.pkg-1.0", sizeof(sSerialDef) / sizeof(sSerialDef[0]), sSerialDef);
299
300 MMechostr(MSKDEBUG,"\n" );
301 return k;
302}
304
305#ifndef SCOL_STATIC
309extern "C" SCOL_EXPORT int ScolLoadPlugin(mmachine m, cbmachine w)
310{
311 int k = 0;
312 SCOLinitplugin(w);
313 LoadSerialIO(m);
314 return k;
315}
316
317
321extern "C" SCOL_EXPORT int ScolUnloadPlugin()
322{
323 return 0;
324}
325#else
329extern "C" SCOL_EXPORT int ScolSerialIOLoadPlugin(mmachine m, cbmachine w)
330{
331 int k = 0;
332 SCOLinitplugin(w);
333 LoadSerialIO(m);
334 return k;
335}
336
337
341extern "C" SCOL_EXPORT int ScolSerialIOUnloadPlugin()
342{
343 return 0;
344}
345#endif //SCOL_STATIC
void writeString(const std::string &s)
int _closeSIO(mmachine m)
_closeSIO : This function destroy a serial object and close the connection
Definition plugin.cpp:172
int _writeSIO(mmachine m)
_writeSIO : This function send data on serial device
Definition plugin.cpp:205
int _openSIO(mmachine m)
_openSIO : This function open a serial port
Definition plugin.cpp:80