source: BAORadio/libindi/libindi/drivers/focuser/fli_pdf.c@ 689

Last change on this file since 689 was 490, checked in by campagne, 15 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.