source: BAORadio/libindi/v1.0.1/drivers/focuser/fli_pdf.c @ 614

Last change on this file since 614 was 490, checked in by campagne, 14 years ago

import libindi (JEC)

File size: 15.2 KB
Line 
1#if 0
2    FLI Precision Digital Focuer
3    Copyright (C) 2005 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#include <netinet/in.h>
35#include <netdb.h>
36
37#include "libfli.h"
38#include "indidevapi.h"
39#include "eventloop.h"
40#include "indicom.h"
41
42void ISInit(void);
43void getBasicData(void);
44void ISPoll(void *);
45void handleExposure(void *);
46void connectPDF(void);
47int  findPDF(flidomain_t domain);
48int  manageDefaults(char errmsg[]);
49int  checkPowerS(ISwitchVectorProperty *sp);
50int  checkPowerN(INumberVectorProperty *np);
51int  checkPowerT(ITextVectorProperty *tp);
52int  getOnSwitch(ISwitchVectorProperty *sp);
53int  isPDFConnected(void);
54
55double min(void);
56double max(void);
57
58extern char* me;
59extern int errno;
60
61#define mydev           "FLI PDF"
62#define MAIN_GROUP      "Main Control"
63#define currentPosition  FocuserN[0].value
64#define POLLMS          1000
65
66typedef struct {
67  flidomain_t domain;
68  char *dname;
69  char *name;
70  char *model;
71  long HWRevision;
72  long FWRevision;
73  long current_pos;
74  long home;
75} pdf_t;
76
77
78static flidev_t fli_dev;
79static pdf_t *FLIPDF;
80static int portSwitchIndex;
81static int simulation;
82static long targetPosition;
83
84long int Domains[] = { FLIDOMAIN_USB, FLIDOMAIN_SERIAL, FLIDOMAIN_PARALLEL_PORT,  FLIDOMAIN_INET };
85
86/*INDI controls */
87
88/* Connect/Disconnect */
89static ISwitch PowerS[]                 = {{"CONNECT" , "Connect" , ISS_OFF, 0, 0},{"DISCONNECT", "Disconnect", ISS_ON, 0, 0}};
90static ISwitchVectorProperty PowerSP    = { mydev, "CONNECTION" , "Connection", MAIN_GROUP, IP_RW, ISR_1OFMANY, 60, IPS_IDLE, PowerS, NARRAY(PowerS), "", 0};
91
92/* Types of Ports */
93static ISwitch PortS[]                  = {{"USB", "", ISS_ON, 0, 0}, {"Serial", "", ISS_OFF, 0, 0}, {"Parallel", "", ISS_OFF, 0, 0}, {"INet", "", ISS_OFF, 0, 0}};
94static ISwitchVectorProperty PortSP     = { mydev, "Port Type", "", MAIN_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, PortS, NARRAY(PortS), "", 0};
95 
96/* Focuser control */
97static INumber FocuserN[]         = { {"Position", "", "%2.0f", -10000., 10000., 1., 0, 0, 0, 0}};
98static INumberVectorProperty FocuserNP = { mydev, "Focuser", "", MAIN_GROUP, IP_RW, 0, IPS_IDLE, FocuserN, NARRAY(FocuserN), "", 0};
99
100/* Focuser home */
101static ISwitch HomeS[]                  = { {"Home", "", ISS_OFF, 0, 0} };
102static ISwitchVectorProperty HomeSP = { mydev, "Home", "", MAIN_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, HomeS, NARRAY(HomeS), "", 0};
103
104/* send client definitions of all properties */
105void ISInit()
106{
107        static int isInit=0;
108       
109        if (isInit)
110                return;
111       
112        /* USB by default {USB, SERIAL, PARALLEL, INET} */
113        portSwitchIndex = 0;
114
115        targetPosition = 0;
116
117        /* No Simulation by default */
118        simulation = 0;
119
120        /* Enable the following for simulation mode */
121        /*simulation = 1;
122        IDLog("WARNING: Simulation is on\n");*/
123       
124        IEAddTimer (POLLMS, ISPoll, NULL);
125       
126        isInit = 1; 
127}
128
129void ISGetProperties (const char *dev)
130{ 
131
132        ISInit();
133       
134        if (dev && strcmp (mydev, dev))
135                return;
136       
137        /* Main Control */
138        IDDefSwitch(&PowerSP, NULL);
139        IDDefSwitch(&PortSP, NULL);
140        IDDefSwitch(&HomeSP, NULL);
141        IDDefNumber(&FocuserNP, NULL);
142       
143       
144}
145 
146void ISNewBLOB (const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n) 
147{
148  INDI_UNUSED(dev);
149  INDI_UNUSED(name);
150  INDI_UNUSED(sizes);
151  INDI_UNUSED(blobsizes);
152  INDI_UNUSED(blobs);
153  INDI_UNUSED(formats);
154  INDI_UNUSED(names);
155  INDI_UNUSED(n);
156}
157void ISSnoopDevice (XMLEle *root) 
158{
159  INDI_UNUSED(root);
160}
161
162void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
163{
164        long err=0;
165
166        /* ignore if not ours */
167        if (dev && strcmp (dev, mydev))
168                return;
169           
170        ISInit();
171           
172        /* Port type */
173        if (!strcmp (name, PortSP.name))
174        {
175                PortSP.s = IPS_IDLE; 
176                IUResetSwitch(&PortSP);
177                IUUpdateSwitch(&PortSP, states, names, n);
178                portSwitchIndex = getOnSwitch(&PortSP);
179               
180                PortSP.s = IPS_OK; 
181                IDSetSwitch(&PortSP, NULL);
182                return;
183        }
184       
185        /* Connection */
186        if (!strcmp (name, PowerSP.name))
187        {
188                IUResetSwitch(&PowerSP);
189                IUUpdateSwitch(&PowerSP, states, names, n);
190                connectPDF();
191                return;
192        }
193
194        if (!strcmp(name, HomeSP.name))
195        {
196                if (!isPDFConnected()) 
197                {
198                        IDMessage(mydev, "Device not connected.");
199                        HomeSP.s = IPS_IDLE;
200                        IDSetSwitch(&HomeSP, NULL);
201                        return;
202                }
203
204               
205                if ( (err = FLIHomeFocuser(fli_dev)))
206                {
207                        HomeSP.s = IPS_ALERT;
208                        IDSetSwitch(&HomeSP, "FLIHomeFocuser() failed. %s.", strerror((int)-err));
209                        IDLog("FLIHomeFocuser() failed. %s.\n", strerror((int)-err));
210                        return;
211                }
212
213                HomeSP.s = IPS_OK;
214                IDSetSwitch(&HomeSP, "Focuser at home position.");
215                IDLog("Focuser at home position.\n");
216                return;
217        }
218       
219     
220}
221
222void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
223{
224        ISInit();
225       
226        /* ignore if not ours */ 
227        if (dev && strcmp (mydev, dev))
228                return;
229
230        /* suppress warning */
231        n=n; dev=dev; name=name; names=names; texts=texts;
232}
233
234
235void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
236{
237        long err;
238        long newPos;
239        names=names;
240        n = n;
241       
242        /* ignore if not ours */
243        if (dev && strcmp (dev, mydev))
244            return;
245           
246        ISInit();
247       
248       
249        if (!strcmp(FocuserNP.name, name)) {
250                if (simulation) 
251                {
252                        targetPosition = values[0];
253                        FocuserNP.s = IPS_BUSY;
254                        IDSetNumber(&FocuserNP, "Setting focuser position to %ld", targetPosition);
255                        IDLog("Setting focuser position to %ld", targetPosition);
256                        return;
257                }
258
259
260                if (!isPDFConnected()) 
261                {
262                        IDMessage(mydev, "Device not connected.");
263                        FocuserNP.s = IPS_IDLE;
264                        IDSetNumber(&FocuserNP, NULL);
265                        return;
266                }
267               
268                targetPosition = values[0];
269               
270                FocuserNP.s = IPS_BUSY;
271                IDSetNumber(&FocuserNP, "Setting focuser position to %ld", targetPosition);
272                IDLog("Setting focuser position to %ld\n", targetPosition);
273               
274                if ( (err = FLIStepMotor(fli_dev, targetPosition)))
275                {
276                        FocuserNP.s = IPS_ALERT;
277                        IDSetNumber(&FocuserNP, "FLIStepMotor() failed. %s.", strerror((int)-err));
278                        IDLog("FLIStepMotor() failed. %s.", strerror((int)-err));
279                        return;
280                }
281               
282                /* Check current focuser position */
283                if (( err = FLIGetStepperPosition(fli_dev, &newPos))) 
284                {
285                        FocuserNP.s = IPS_ALERT;
286                        IDSetNumber(&FocuserNP, "FLIGetStepperPosition() failed. %s.", strerror((int)-err));
287                        IDLog("FLIGetStepperPosition() failed. %s.\n", strerror((int)-err));
288                        return;
289                }
290               
291                if (newPos == targetPosition) 
292                {
293                        FLIPDF->current_pos = targetPosition;
294                        currentPosition = FLIPDF->current_pos;
295                        FocuserNP.s = IPS_OK;
296                        IDSetNumber(&FocuserNP, "Focuser position %ld", targetPosition);
297                        return;
298                }
299
300                return;
301        }
302}
303
304
305/* Retrieves basic data from the focuser upon connection like temperature, array size, firmware..etc */
306void getBasicData()
307{
308
309        char buff[2048];
310        long err;
311       
312        if ((err = FLIGetModel (fli_dev, buff, 2048)))
313        {
314                IDMessage(mydev, "FLIGetModel() failed. %s.", strerror((int)-err));
315                IDLog("FLIGetModel() failed. %s.\n", strerror((int)-err));
316                return;
317        }
318        else
319        {
320                if ( (FLIPDF->model = malloc (sizeof(char) * 2048)) == NULL)
321                {
322                IDMessage(mydev, "malloc() failed.");
323                IDLog("malloc() failed.");
324                return;
325                }
326               
327                strcpy(FLIPDF->model, buff);
328        }
329 
330        if (( err = FLIGetHWRevision(fli_dev, &FLIPDF->HWRevision)))
331        {
332                IDMessage(mydev, "FLIGetHWRevision() failed. %s.", strerror((int)-err));
333                IDLog("FLIGetHWRevision() failed. %s.\n", strerror((int)-err));
334               
335                return;
336        }
337       
338        if (( err = FLIGetFWRevision(fli_dev, &FLIPDF->FWRevision)))
339        {
340                IDMessage(mydev, "FLIGetFWRevision() failed. %s.", strerror((int)-err));
341                IDLog("FLIGetFWRevision() failed. %s.\n", strerror((int)-err));
342                return;
343        }
344       
345        if (( err = FLIGetStepperPosition(fli_dev, &FLIPDF->current_pos)))
346        {
347                IDSetNumber(&FocuserNP, "FLIGetStepperPosition() failed. %s.", strerror((int)-err));
348                IDLog("FLIGetStepperPosition() failed. %s.\n", strerror((int)-err));
349                return;
350        }
351 
352        currentPosition = FLIPDF->current_pos;
353
354        IDLog("Model: %s\n", FLIPDF->model);
355        IDLog("HW Revision %ld\n", FLIPDF->HWRevision);
356        IDLog("FW Revision %ld\n", FLIPDF->FWRevision);
357        IDLog("Initial focuser position %ld\n", FLIPDF->current_pos);
358        FocuserNP.s = IPS_OK;
359        IDSetNumber(&FocuserNP, NULL);
360       
361        IDLog("Exiting getBasicData()\n");
362 
363}
364
365void ISPoll(void *p)
366{
367  static int simMTC = 5;
368
369  p=p;
370  if (!isPDFConnected())
371  {
372      IEAddTimer (POLLMS, ISPoll, NULL);
373      return;
374  }
375
376
377  switch (FocuserNP.s)
378  {
379    case IPS_IDLE:
380    case IPS_OK:
381       break;
382 
383   
384   case IPS_BUSY:
385    /* Simulate that it takes 5 seconds to change positoin*/
386    if (simulation)
387    {
388        simMTC--;
389        if (simMTC == 0)
390        {
391           simMTC = 5;
392           currentPosition = targetPosition;
393           FocuserNP.s = IPS_OK;
394           IDSetNumber(&FocuserNP, "Focuser position %ld", targetPosition);
395           break;
396        }
397        IDSetNumber(&FocuserNP, NULL);
398        break;
399    }
400
401
402    /*if (( err = FLIGetFilterPos(fli_dev, &currentFilter)))
403        {
404                FocuserNP.s = IPS_ALERT;
405                IDSetNumber(&FocuserNP, "FLIGetFilterPos() failed. %s.", strerror((int)-err));
406                IDLog("FLIGetFilterPos() failed. %s.\n", strerror((int)-err));
407                return;
408        }
409
410        if (targetPosition == currentFilter)
411        {
412                FLIPDF->current_filter = currentFilter;
413                FocuserNP.s = IPS_OK;
414                IDSetNumber(&FocuserNP, "Filter set to slot #%2.0f", currentFilter);
415                return;
416        }
417       
418        IDSetNumber(&FocuserNP, NULL);*/
419        break;
420
421   case IPS_ALERT:
422    break;
423 }
424
425   IEAddTimer (POLLMS, ISPoll, NULL);
426
427}
428
429
430
431int getOnSwitch(ISwitchVectorProperty *sp)
432{
433  int i=0;
434 for (i=0; i < sp->nsp ; i++)
435 {
436   /*IDLog("Switch %s is %s\n", sp->sp[i].name, sp->sp[i].s == ISS_ON ? "On" : "Off");*/
437     if (sp->sp[i].s == ISS_ON)
438      return i;
439 }
440
441 return -1;
442}
443
444int checkPowerS(ISwitchVectorProperty *sp)
445{
446
447  if (simulation)
448   return 0;
449
450  if (PowerSP.s != IPS_OK)
451  {
452    if (!strcmp(sp->label, ""))
453        IDMessage (mydev, "Cannot change property %s while the focuser is offline.", sp->name);
454    else
455        IDMessage (mydev, "Cannot change property %s while the focuser is offline.", sp->label);
456       
457    sp->s = IPS_IDLE;
458    IDSetSwitch(sp, NULL);
459    return -1;
460  }
461
462  return 0;
463}
464
465int checkPowerN(INumberVectorProperty *np)
466{
467  if (simulation)
468   return 0;
469
470  if (PowerSP.s != IPS_OK)
471  {
472     if (!strcmp(np->label, ""))
473        IDMessage (mydev, "Cannot change property %s while the focuser is offline.", np->name);
474    else
475        IDMessage (mydev, "Cannot change property %s while the focuser is offline.", np->label);
476   
477    np->s = IPS_IDLE;
478    IDSetNumber(np, NULL);
479    return -1;
480  }
481
482  return 0;
483}
484
485int checkPowerT(ITextVectorProperty *tp)
486{
487   if (simulation)
488    return 0;
489
490  if (PowerSP.s != IPS_OK)
491  {
492    if (!strcmp(tp->label, ""))
493        IDMessage (mydev, "Cannot change property %s while the focuser is offline.", tp->name);
494    else
495        IDMessage (mydev, "Cannot change property %s while the focuser is offline.", tp->label);
496       
497    tp->s = IPS_IDLE;
498    IDSetText(tp, NULL);
499    return -1;
500  }
501
502  return 0;
503
504}
505
506void connectPDF()
507{
508        long err;
509        /* USB by default {USB, SERIAL, PARALLEL, INET} */
510        switch (PowerS[0].s)
511        {
512                case ISS_ON:
513                       
514                        if (simulation)
515                        {
516                                /* Success! */
517                                PowerS[0].s = ISS_ON;
518                                PowerS[1].s = ISS_OFF;
519                                PowerSP.s = IPS_OK;
520                                IDSetSwitch(&PowerSP, "Simulation PDF is online.");
521                                IDLog("Simulation PDF is online.\n");
522                                return;
523                        }
524
525                        IDLog("Current portSwitch is %d\n", portSwitchIndex);
526                        IDLog("Attempting to find the device in domain %ld\n", Domains[portSwitchIndex]);
527
528                        if (findPDF(Domains[portSwitchIndex]))
529                        {
530                                PowerSP.s = IPS_IDLE;
531                                PowerS[0].s = ISS_OFF;
532                                PowerS[1].s = ISS_ON;
533                                IDSetSwitch(&PowerSP, "Error: no focusers were detected.");
534                                IDLog("Error: no focusers were detected.\n");
535                                return;
536                        }
537                       
538                        if ((err = FLIOpen(&fli_dev, FLIPDF->name, FLIPDF->domain | FLIDEVICE_FOCUSER)))
539                        {
540                                PowerSP.s = IPS_IDLE;
541                                PowerS[0].s = ISS_OFF;
542                                PowerS[1].s = ISS_ON;
543                                IDSetSwitch(&PowerSP, "Error: FLIOpen() failed. %s.", strerror( (int) -err));
544                                IDLog("Error: FLIOpen() failed. %s.\n", strerror( (int) -err));
545                                return;
546                        }
547
548                        /* Success! */
549                        PowerS[0].s = ISS_ON;
550                        PowerS[1].s = ISS_OFF;
551                        PowerSP.s = IPS_OK;
552                        IDSetSwitch(&PowerSP, "Focuser is online. Retrieving basic data.");
553                        IDLog("Focuser is online. Retrieving basic data.\n");
554                        getBasicData();
555
556                        break;
557               
558                case ISS_OFF:
559
560                        if (simulation)
561                        {
562                                PowerS[0].s = ISS_OFF;
563                                PowerS[1].s = ISS_ON;
564                                PowerSP.s = IPS_IDLE;
565                                IDSetSwitch(&PowerSP, "Focuser is offline.");
566                                return;
567                        }
568
569                        PowerS[0].s = ISS_OFF;
570                        PowerS[1].s = ISS_ON;
571                        PowerSP.s = IPS_IDLE;
572                        if ((err = FLIClose(fli_dev))) 
573                        {
574                                PowerSP.s = IPS_ALERT;
575                                IDSetSwitch(&PowerSP, "Error: FLIClose() failed. %s.", strerror( (int) -err));
576                                IDLog("Error: FLIClose() failed. %s.\n", strerror( (int) -err));
577                                return;
578                        }
579                        IDSetSwitch(&PowerSP, "Focuser is offline.");
580                        break;
581        }
582}
583
584/* isPDFConnected: return 1 if we have a connection, 0 otherwise */
585int isPDFConnected(void)
586{
587   if (simulation)
588     return 1;
589
590   return ((PowerS[0].s == ISS_ON) ? 1 : 0);
591}
592
593int findPDF(flidomain_t domain)
594{
595        char **devlist;
596        long err;
597       
598        IDLog("In findPDF, the domain is %ld\n", domain);
599       
600        if (( err = FLIList(domain | FLIDEVICE_FOCUSER, &devlist)))
601        {
602                IDLog("FLIList() failed. %s\n", strerror((int)-err));
603                return -1;
604        }
605       
606        if (devlist != NULL && devlist[0] != NULL)
607        {
608                int i;
609
610                IDLog("Trying to allocate memory to FLIPDF\n");
611                if ((FLIPDF = malloc (sizeof (pdf_t))) == NULL)
612                {
613                        IDLog("malloc() failed.\n");
614                        return -1;
615                }
616               
617                for (i = 0; devlist[i] != NULL; i++)
618                {
619                        int j;
620       
621                        for (j = 0; devlist[i][j] != '\0'; j++)
622                                if (devlist[i][j] == ';')
623                                {
624                                        devlist[i][j] = '\0';
625                                        break;
626                                }
627                }
628
629                FLIPDF->domain = domain;
630               
631                /* Each driver handles _only_ one camera for now */
632                switch (domain)
633                {
634                        case FLIDOMAIN_PARALLEL_PORT:
635                                FLIPDF->dname = strdup("parallel port");
636                                break;
637       
638                        case FLIDOMAIN_USB:
639                                FLIPDF->dname = strdup("USB");
640                                break;
641       
642                        case FLIDOMAIN_SERIAL:
643                                FLIPDF->dname = strdup("serial");
644                                break;
645       
646                        case FLIDOMAIN_INET:
647                                FLIPDF->dname = strdup("inet");
648                                break;
649       
650                        default:
651                                FLIPDF->dname = strdup("Unknown domain");
652                }
653               
654                IDLog("Domain set OK\n");
655               
656                FLIPDF->name = strdup(devlist[0]);
657                               
658                if ((err = FLIFreeList(devlist)))
659                {
660                        IDLog("FLIFreeList() failed. %s.\n", strerror((int)-err));
661                        return -1;
662                }
663     
664        } /* end if */
665        else
666        {
667                if ((err = FLIFreeList(devlist)))
668                {
669                        IDLog("FLIFreeList() failed. %s.\n", strerror((int)-err));
670                        return -1;
671                }
672               
673                return -1;
674        }
675
676        IDLog("FindPDF() finished successfully.\n");
677        return 0;
678}
Note: See TracBrowser for help on using the repository browser.