source: BAORadio/libindi/v1.0.1/drivers/filter_wheel/trutech_wheel.c @ 614

Last change on this file since 614 was 501, checked in by frichard, 14 years ago

-BAOControl : petite interface permettant de contrôler les antennes via le pilote indi_BAO
-Le pilote indi_BAO utilise désormais libindi v 0.7

File size: 12.0 KB
Line 
1#if 0
2   True Technology Filter Wheel
3    Copyright (C) 2006 Jasem Mutlaq (mutlaqja AT ikarustech DOT com)
4
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    This library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with this library; if not, write to the Free Software
17    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18
19#endif
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <stdarg.h>
25#include <math.h>
26#include <unistd.h>
27#include <time.h>
28#include <fcntl.h>
29#include <errno.h>
30#include <sys/stat.h>
31#include <sys/time.h>
32#include <sys/types.h>
33#include <sys/socket.h>
34
35#include "indidevapi.h"
36#include "eventloop.h"
37#include "indicom.h"
38
39void ISInit(void);
40void getBasicData(void);
41void ISPoll(void *);
42void handleExposure(void *);
43void connectFilter(void);
44int  manageDefaults(char errmsg[]);
45int  checkPowerS(ISwitchVectorProperty *sp);
46int  checkPowerN(INumberVectorProperty *np);
47int  checkPowerT(ITextVectorProperty *tp);
48int  getOnSwitch(ISwitchVectorProperty *sp);
49int  isFilterConnected(void);
50
51static int targetFilter;
52static int fd;
53const unsigned char COMM_PRE  = 0x01;
54const unsigned char COMM_INIT = 0xA5;
55const unsigned char COMM_FILL = 0x20;
56
57#define mydev                           "TruTech Wheel"
58#define MAIN_GROUP                      "Main Control"
59#define currentFilter                   FilterPositionN[0].value
60#define POLLMS                          3000
61#define DEFAULT_FILTER_COUNT            5
62#define MAX_FILTER_COUNT                10
63#define ERRMSG_SIZE                     1024
64
65#define CMD_SIZE                        5
66#define CMD_JUNK                        64
67#define CMD_RESP                        15
68
69#define FILTER_TIMEOUT                  15                                      /* 15 Seconds before timeout */
70#define FIRST_FILTER                    1
71
72#define DEBUG_ON                        0
73#define SIMULATION_ON                   0
74
75
76/*INDI controls */
77
78/* Connect/Disconnect */
79static ISwitch PowerS[]                 = {{"CONNECT" , "Connect" , ISS_OFF, 0, 0},{"DISCONNECT", "Disconnect", ISS_ON, 0, 0}};
80static ISwitchVectorProperty PowerSP    = { mydev, "CONNECTION" , "Connection", MAIN_GROUP, IP_RW, ISR_1OFMANY, 60, IPS_IDLE, PowerS, NARRAY(PowerS), "", 0};
81
82/* Connection Port */
83static IText PortT[]                    = {{"PORT", "Port", 0, 0, 0, 0}};
84static ITextVectorProperty PortTP               = { mydev, "DEVICE_PORT", "Ports", MAIN_GROUP, IP_RW, 0, IPS_IDLE, PortT, NARRAY(PortT), "", 0};
85
86/* Home/Learn Swtich */
87static ISwitch HomeS[]                  = {{"Find" , "" , ISS_OFF, 0, 0}};
88static ISwitchVectorProperty HomeSP     = { mydev, "HOME" , "", MAIN_GROUP, IP_RW, ISR_1OFMANY, 60, IPS_IDLE, HomeS, NARRAY(HomeS), "", 0};
89
90/* Filter Count */
91static INumber FilterCountN[]     = { {"Count", "", "%2.0f",  0 , MAX_FILTER_COUNT, 1, DEFAULT_FILTER_COUNT, 0, 0, 0}};
92static INumberVectorProperty FilterCountNP = { mydev, "Filter Count", "", MAIN_GROUP, IP_RW, 0, IPS_IDLE, FilterCountN, NARRAY(FilterCountN), "", 0};
93
94/* Filter Position */
95static INumber FilterPositionN[]          = { {"FILTER_SLOT_VALUE", "Active Filter", "%2.0f",  1 , DEFAULT_FILTER_COUNT, 1, 1, 0, 0, 0}};
96static INumberVectorProperty FilterPositionNP = { mydev, "FILTER_SLOT", "Filter", MAIN_GROUP, IP_RW, 0, IPS_IDLE, FilterPositionN, NARRAY(FilterPositionN), "", 0};
97
98/* send client definitions of all properties */
99void ISInit()
100{
101        static int isInit=0;
102       
103        if (isInit)
104                return;
105       
106
107        targetFilter = -1;
108        fd = -1;
109
110        isInit = 1; 
111}
112
113void ISGetProperties (const char *dev)
114{ 
115
116        ISInit();
117       
118        if (dev && strcmp (mydev, dev))
119                return;
120       
121        /* Main Control */
122        IDDefSwitch(&PowerSP, NULL);
123        IDDefText(&PortTP, NULL);
124        IDDefNumber(&FilterCountNP, NULL);
125        IDDefSwitch(&HomeSP, NULL);
126        IDDefNumber(&FilterPositionNP, NULL);
127}
128
129void ISNewBLOB (const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n) 
130{
131  INDI_UNUSED(dev);
132  INDI_UNUSED(name);
133  INDI_UNUSED(sizes);
134  INDI_UNUSED(blobsizes);
135  INDI_UNUSED(blobs);
136  INDI_UNUSED(formats);
137  INDI_UNUSED(names);
138  INDI_UNUSED(n);
139}
140void ISSnoopDevice (XMLEle *root) 
141{
142  INDI_UNUSED(root);
143}
144
145void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
146{
147        int err;
148        char error_message[ERRMSG_SIZE];
149
150        /* ignore if not ours */
151        if (dev && strcmp (dev, mydev))
152                return;
153           
154        ISInit();
155           
156        /* Connection */
157        if (!strcmp (name, PowerSP.name))
158        {
159                IUUpdateSwitch(&PowerSP, states, names, n);
160                connectFilter();
161                return;
162        }
163
164        /* Home Search */
165        if (!strcmp (name, HomeSP.name))
166        {
167                int nbytes=0;
168                unsigned char type = 0x03;
169                unsigned char chksum = COMM_INIT + type + COMM_FILL;
170                /*char filter_command[5] = { COMM_PRE, COMM_INIT, type, COMM_FILL, chksum };*/
171                unsigned char filter_command[CMD_SIZE];
172                snprintf(filter_command, CMD_SIZE,  "%c%c%c%c%c", COMM_PRE, COMM_INIT, type, COMM_FILL, chksum);
173
174                if (checkPowerS(&HomeSP))
175                        return;
176
177                if (!SIMULATION_ON)
178                    err = tty_write(fd, filter_command, CMD_SIZE, &nbytes);
179
180
181                if (DEBUG_ON)
182                {
183                    IDLog("Home Search Command (int): #%d#%d#%d#%d#%d#\n",COMM_PRE, COMM_INIT, type, COMM_FILL, chksum);
184                    IDLog("Home Search Command (char): #%c#%c#%c#%c#%c#\n",COMM_PRE, COMM_INIT, type, COMM_FILL, chksum);
185                }
186
187                /* Send Home Command */
188                if (err != TTY_OK)
189                {
190               
191                        tty_error_msg(err, error_message, ERRMSG_SIZE);
192                       
193                        HomeSP.s = IPS_ALERT;
194                        IDSetSwitch(&HomeSP, "Sending command Home to filter failed. %s", error_message);
195                        IDLog("Sending command Home to filter failed. %s\n", error_message);
196
197                        return;
198                }
199
200                FilterPositionN[0].value = 1;
201                FilterPositionNP.s = IPS_OK;
202                HomeSP.s = IPS_OK;
203                IDSetSwitch(&HomeSP, "Filter set to HOME.");
204                IDSetNumber(&FilterPositionNP, NULL);
205               
206        }
207       
208     
209}
210
211void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
212{
213        ISInit();
214       
215        /* ignore if not ours */ 
216        if (dev && strcmp (mydev, dev))
217                return;
218
219        if (!strcmp(name, PortTP.name))
220        {
221                if (IUUpdateText(&PortTP, texts, names, n))
222                  return;
223
224                PortTP.s = IPS_OK;
225                IDSetText(&PortTP, NULL);
226        }
227       
228}
229
230
231void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
232{
233        long err;
234        INumber *np;
235        n = n;
236       
237        /* ignore if not ours */
238        if (dev && strcmp (dev, mydev))
239            return;
240           
241        ISInit();
242       
243        if (!strcmp(FilterPositionNP.name, name)) 
244        {
245
246                if (!isFilterConnected()) 
247                {
248                        IDMessage(mydev, "Filter is not connected.");
249                        FilterPositionNP.s = IPS_IDLE;
250                        IDSetNumber(&FilterPositionNP, NULL);
251                        return;
252                }
253
254                np = IUFindNumber(&FilterPositionNP, names[0]);
255                if (np == &FilterPositionN[0])
256                {
257                       
258                        targetFilter = values[0];
259                        int nbytes=0;
260                        unsigned char type = 0x01;
261                        unsigned char chksum = COMM_INIT + type + (unsigned char) targetFilter;
262                        /*char filter_command[5] = { COMM_PRE, COMM_INIT, type, targetFilter, chksum };*/
263                        unsigned char filter_command[CMD_SIZE];
264
265
266                        if (targetFilter < FilterPositionN[0].min || targetFilter > FilterPositionN[0].max)
267                        {
268                                FilterPositionNP.s = IPS_ALERT;
269                                IDSetNumber(&FilterPositionNP, "Error: valid range of filter is from %d to %d", (int) FilterPositionN[0].min, (int) FilterPositionN[0].max);
270                                return;
271                        }
272
273                        IUUpdateNumber(&FilterPositionNP, values, names, n);
274
275                        snprintf(filter_command, CMD_SIZE,  "%c%c%c%c%c", COMM_PRE, COMM_INIT, type, targetFilter, chksum);
276
277                        if (DEBUG_ON)
278                        {
279                            IDLog("Filter Position Command (int): #%d#%d#%d#%d#%d#\n",COMM_PRE, COMM_INIT, type, targetFilter, chksum);
280                            IDLog("Filter Position Command (char): #%c#%c#%c#%c#%c#\n",COMM_PRE, COMM_INIT, type, targetFilter, chksum);
281                        }
282
283                        if (!SIMULATION_ON)
284                            err = tty_write(fd, filter_command, CMD_SIZE, &nbytes);
285
286
287                        FilterPositionNP.s = IPS_OK;
288                        IDSetNumber(&FilterPositionNP, "Setting current filter to slot %d", targetFilter);
289                }
290                else
291                {
292                        FilterPositionNP.s = IPS_IDLE;
293                        IDSetNumber(&FilterPositionNP, NULL);
294                }
295               
296                return;
297        }
298
299        if (!strcmp(FilterCountNP.name, name)) 
300        {
301
302                if (!isFilterConnected()) 
303                {
304                        IDMessage(mydev, "Filter is not connected.");
305                        FilterCountNP.s = IPS_IDLE;
306                        IDSetNumber(&FilterCountNP, NULL);
307                        return;
308                }
309
310                np = IUFindNumber(&FilterCountNP, names[0]);
311                if (np == &FilterCountN[0])
312                {
313                        if (IUUpdateNumber(&FilterCountNP, values, names, n) <0)
314                                return;
315
316                        FilterPositionN[0].min = 1;
317                        FilterPositionN[0].max = (int) FilterCountN[0].value;
318                        IUUpdateMinMax(&FilterPositionNP);
319
320                        FilterCountNP.s = IPS_OK;
321                        IDSetNumber(&FilterCountNP, "Updated number of available filters to %d", ((int) FilterCountN[0].value));
322                }
323                else
324                {
325                        FilterCountNP.s = IPS_IDLE;
326                        IDSetNumber(&FilterCountNP, NULL);
327                }
328               
329                return;
330        }
331
332}
333
334int getOnSwitch(ISwitchVectorProperty *sp)
335{
336  int i=0;
337 for (i=0; i < sp->nsp ; i++)
338 {
339     if (sp->sp[i].s == ISS_ON)
340      return i;
341 }
342
343 return -1;
344
345}
346
347int checkPowerS(ISwitchVectorProperty *sp)
348{
349
350  if (PowerSP.s != IPS_OK)
351  {
352    if (!strcmp(sp->label, ""))
353        IDMessage (mydev, "Cannot change property %s while the wheel is offline.", sp->name);
354    else
355        IDMessage (mydev, "Cannot change property %s while the wheel is offline.", sp->label);
356       
357    sp->s = IPS_IDLE;
358    IDSetSwitch(sp, NULL);
359    return -1;
360  }
361
362  return 0;
363}
364
365int checkPowerN(INumberVectorProperty *np)
366{
367  if (PowerSP.s != IPS_OK)
368  {
369     if (!strcmp(np->label, ""))
370        IDMessage (mydev, "Cannot change property %s while the wheel is offline.", np->name);
371    else
372        IDMessage (mydev, "Cannot change property %s while the wheel is offline.", np->label);
373   
374    np->s = IPS_IDLE;
375    IDSetNumber(np, NULL);
376    return -1;
377  }
378
379  return 0;
380}
381
382int checkPowerT(ITextVectorProperty *tp)
383{
384  if (PowerSP.s != IPS_OK)
385  {
386    if (!strcmp(tp->label, ""))
387        IDMessage (mydev, "Cannot change property %s while the wheel is offline.", tp->name);
388    else
389        IDMessage (mydev, "Cannot change property %s while the wheel is offline.", tp->label);
390       
391    tp->s = IPS_IDLE;
392    IDSetText(tp, NULL);
393    return -1;
394  }
395
396  return 0;
397
398}
399
400void connectFilter()
401{
402        int err;
403        char errmsg[ERRMSG_SIZE];
404 
405        switch (PowerS[0].s)
406        {
407                case ISS_ON:
408                        if (SIMULATION_ON)
409                        {
410                            PowerSP.s = IPS_OK;
411                            IDSetSwitch(&PowerSP, "Simulated Filter Wheel is online.");
412                            return;
413                        }
414
415                        if ( (err = tty_connect(PortT[0].text, 9600, 8, 0, 1, &fd)) != TTY_OK)
416                        {
417                                PowerSP.s = IPS_ALERT;
418                                IDSetSwitch(&PowerSP, "Error: cannot connect to %s. Make sure the filter is connected and you have access to the port.", PortT[0].text);
419                                tty_error_msg(err, errmsg, ERRMSG_SIZE);
420                                IDLog("Error: %s\n", errmsg);
421                                return;
422                        }
423
424
425                        PowerSP.s = IPS_OK;
426                        IDSetSwitch(&PowerSP, "Filter Wheel is online. True Technology filter wheel suffers from several bugs. Please refer to http://indi.sf.net/profiles/trutech.html for more details.");
427                        break;
428               
429                case ISS_OFF:
430                        if (SIMULATION_ON)
431                        {
432                          PowerSP.s = IPS_OK;
433                          IDSetSwitch(&PowerSP, "Simulated Filter Wheel is offline.");
434                          return;
435                        }
436
437                        if ( (err = tty_disconnect(fd)) != TTY_OK)
438                        {
439                                PowerSP.s = IPS_ALERT;
440                                IDSetSwitch(&PowerSP, "Error: cannot disconnect.");
441                                tty_error_msg(err, errmsg, ERRMSG_SIZE);
442                                IDLog("Error: %s\n", errmsg);
443                                return;
444                        }
445
446                        PowerSP.s = IPS_IDLE;
447                        IDSetSwitch(&PowerSP, "Filter Wheel is offline.");
448                        break;
449        }
450}
451
452/* isFilterConnected: return 1 if we have a connection, 0 otherwise */
453int isFilterConnected(void)
454{
455   return ((PowerS[0].s == ISS_ON) ? 1 : 0);
456}
457
Note: See TracBrowser for help on using the repository browser.