3 Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C.
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
10 Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
13 Redistributions in binary form must reproduce the above
14 copyright notice, this list of conditions and the following
15 disclaimer in the documentation and/or other materials
16 provided with the distribution.
18 Neither the name of Finger Lakes Instrumentation (FLI), LLC
19 nor the names of its contributors may be used to endorse or
20 promote products derived from this software without specific
21 prior written permission.
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27 REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 POSSIBILITY OF SUCH DAMAGE.
36 ======================================================================
38 Finger Lakes Instrumentation, L.L.C. (FLI)
39 web: http://www.fli-cam.com
40 email: support@fli-cam.com
47 #include <sys/param.h>
48 #include <netinet/in.h>
57 #include "libfli-libfli.h"
58 #include "libfli-mem.h"
59 #include "libfli-debug.h"
60 #include "libfli-filter-focuser.h"
63 Array of filterwheel info
65 Off = Offset of 0 filter from magnetic stop,
66 X - y = number of steps from filter x to filter y
68 static const wheeldata_t wheeldata
[] =
70 /* POS OFF 0-1 1-2 2-3 3-4 4-5 5-6 6-7 7-8 8-9 9-A A-B B-C C-D D-E F-F F-0 */
71 { 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
72 { 1, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
73 { 2, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
74 { 3, 48, { 80, 80, 80, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
75 { 4, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
76 { 5, 0, { 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
77 { 6, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
78 { 7, 14, { 34, 34, 35, 34, 34, 35, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
79 { 8, 18, { 30, 30, 30, 30, 30, 30, 30, 30, 0, 0, 0, 0, 0, 0, 0, 0} },
80 { 9, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
81 {10, 0, { 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0} },
82 {11, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
83 {12, 6,{ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0} },
84 {13, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
85 {14, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
86 {15, 0, { 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48} },
89 static long fli_stepmotor(flidev_t dev
, long steps
);
90 static long fli_getsteppos(flidev_t dev
, long *pos
);
91 static long fli_setfilterpos(flidev_t dev
, long pos
);
94 long fli_filter_focuser_open(flidev_t dev
)
96 #define FWSTRING "Filter Wheel (%ld position)"
97 #define FOCSTRING "Focuser"
98 #define MODEL_LEN (sizeof(FWSTRING) + 30)
102 unsigned short buf
[16];
103 flifilterdata_t
*fdata
= NULL
;
107 DEVICE
->io_timeout
= 1000;
111 buf
[0] = htons(0x8000);
112 IO(dev
, buf
, &wlen
, &rlen
);
113 if (ntohs(buf
[0]) != 0x8000)
115 debug(FLIDEBUG_WARN
, "Invalid echo, device not recognized, got %04x instead of %04x.", ntohs(buf
[0]), 0x8000);
122 buf
[0] = htons(0x8001);
123 IO(dev
, buf
, &wlen
, &rlen
);
124 DEVICE
->devinfo
.fwrev
= ntohs(buf
[0]);
125 if ((DEVICE
->devinfo
.fwrev
& 0xff00) != 0x8000)
127 debug(FLIDEBUG_WARN
, "Invalid echo, device not recognized.");
132 if ((DEVICE
->device_data
= xmalloc(sizeof(flifilterdata_t
))) == NULL
)
137 fdata
= DEVICE
->device_data
;
139 fdata
->stepspersec
= 100;
140 fdata
->currentslot
= -1;
142 if (DEVICE
->devinfo
.fwrev
== 0x8001) /* Old level of firmware */
144 if (DEVICE
->devinfo
.type
!= FLIDEVICE_FILTERWHEEL
)
150 debug(FLIDEBUG_INFO
, "Device is old fashioned filter wheel.");
153 /* FIX: should model info be set first? */
157 debug(FLIDEBUG_INFO
, "New version of hardware found.");
160 buf
[0] = htons(0x8002);
161 IO(dev
, buf
, &wlen
, &rlen
);
162 ndev
= ntohs(buf
[0]);
164 if ((ndev
& 0xff00) != 0x8000)
170 if ((DEVICE
->devinfo
.model
= (char *)xmalloc(MODEL_LEN
)) == NULL
)
172 debug(FLIDEBUG_FAIL
, "Could not allocate memory for model information.");
179 /* switch based on the jumper settings on the filter/focuser dongle, determines how many slots in the filter wheel */
183 if (DEVICE
->devinfo
.type
!= FLIDEVICE_FILTERWHEEL
)
189 snprintf(DEVICE
->devinfo
.model
, MODEL_LEN
, FWSTRING
, fdata
->numslots
);
193 if (DEVICE
->devinfo
.type
!= FLIDEVICE_FILTERWHEEL
)
199 snprintf(DEVICE
->devinfo
.model
, MODEL_LEN
, FWSTRING
, fdata
->numslots
);
203 if (DEVICE
->devinfo
.type
!= FLIDEVICE_FILTERWHEEL
)
209 snprintf(DEVICE
->devinfo
.model
, MODEL_LEN
, FWSTRING
, fdata
->numslots
);
214 if (DEVICE
->devinfo
.type
!= FLIDEVICE_FILTERWHEEL
)
219 snprintf(DEVICE
->devinfo
.model
, MODEL_LEN
, FWSTRING
, fdata
->numslots
);
223 fdata
->numslots
= 15;
224 fdata
->stepspersec
= 16;/* // 1/.06 */
225 if (DEVICE
->devinfo
.type
!= FLIDEVICE_FILTERWHEEL
)
230 snprintf(DEVICE
->devinfo
.model
, MODEL_LEN
, FWSTRING
, fdata
->numslots
);
235 if (DEVICE
->devinfo
.type
!= FLIDEVICE_FILTERWHEEL
)
240 fdata
->numslots
= 12;
241 fdata
->stepspersec
= 16; /*// 1/.06*/
243 snprintf(DEVICE
->devinfo
.model
, MODEL_LEN
, FWSTRING
, fdata
->numslots
);
247 fdata
->numslots
= 10;
248 fdata
->stepspersec
= 16; /*// 1/.06*/
249 if (DEVICE
->devinfo
.type
!= FLIDEVICE_FILTERWHEEL
)
254 snprintf(DEVICE
->devinfo
.model
, MODEL_LEN
, FWSTRING
, fdata
->numslots
);
259 if (DEVICE
->devinfo
.type
!= FLIDEVICE_FOCUSER
)
264 snprintf(DEVICE
->devinfo
.model
, MODEL_LEN
, FOCSTRING
);
276 if (DEVICE
->devinfo
.model
!= NULL
)
278 xfree(DEVICE
->devinfo
.model
);
279 DEVICE
->devinfo
.model
= NULL
;
282 if (DEVICE
->device_data
!= NULL
)
284 xfree(DEVICE
->device_data
);
285 DEVICE
->device_data
= NULL
;
291 debug(FLIDEBUG_INFO
, "Found a %ld slot filter wheel or a focuser.",
301 long fli_filter_focuser_close(flidev_t dev
)
305 if (DEVICE
->devinfo
.model
!= NULL
)
307 xfree(DEVICE
->devinfo
.model
);
308 DEVICE
->devinfo
.model
= NULL
;
311 if (DEVICE
->device_data
!= NULL
)
313 xfree(DEVICE
->device_data
);
314 DEVICE
->device_data
= NULL
;
320 long fli_filter_command(flidev_t dev
, int cmd
, int argc
, ...)
322 flifilterdata_t
*fdata
;
328 fdata
= DEVICE
->device_data
;
332 case FLI_SET_FILTER_POS
:
339 pos
= *va_arg(ap
, long *);
340 r
= fli_setfilterpos(dev
, pos
);
344 case FLI_GET_FILTER_POS
:
351 cslot
= va_arg(ap
, long *);
352 *cslot
= fdata
->currentslot
;
357 case FLI_GET_FILTER_COUNT
:
364 nslots
= va_arg(ap
, long *);
365 *nslots
= fdata
->numslots
;
377 steps
= va_arg(ap
, long *);
378 r
= fli_stepmotor(dev
, *steps
);
382 case FLI_GET_STEPPER_POS
:
389 pos
= va_arg(ap
, long *);
390 r
= fli_getsteppos(dev
, pos
);
403 long fli_focuser_command(flidev_t dev
, int cmd
, int argc
, ...)
420 steps
= va_arg(ap
, long *);
421 r
= fli_stepmotor(dev
, *steps
);
425 case FLI_GET_STEPPER_POS
:
432 pos
= va_arg(ap
, long *);
433 r
= fli_getsteppos(dev
, pos
);
437 case FLI_HOME_FOCUSER
:
441 r
= fli_setfilterpos(dev
, FLI_FILTERPOSITION_HOME
);
453 static long fli_stepmotor(flidev_t dev
, long steps
)
455 flifilterdata_t
*fdata
;
456 long dir
, timeout
, move
, stepsleft
;
458 unsigned short buf
[16];
464 fdata
= DEVICE
->device_data
;
475 debug(FLIDEBUG_INFO
, "Stepping %d steps.", move
);
478 timeout
= (move
/ fdata
->stepspersec
) + 2;
484 buf
[0] = htons((unsigned short) (0xa000 | (unsigned short) move
));
485 IO(dev
, buf
, &wlen
, &rlen
);
486 if ((ntohs(buf
[0]) & 0xf000) != 0xa000)
488 debug(FLIDEBUG_WARN
, "Invalid echo.");
494 buf
[0] = htons((unsigned short) (0x9000 | (unsigned short) move
));
495 IO(dev
, buf
, &wlen
, &rlen
);
496 if ((ntohs(buf
[0]) & 0xf000) != 0x9000)
498 debug(FLIDEBUG_WARN
, "Invalid echo.");
505 while (stepsleft
!= 0x7000)
507 buf
[0] = htons(0x7000);
508 IO(dev
, buf
, &wlen
, &rlen
);
509 stepsleft
= ntohs(buf
[0]);
511 if (((clock() - begin
) / CLOCKS_PER_SEC
) > timeout
)
513 debug(FLIDEBUG_WARN
, "A device timeout has occurred.");
522 static long fli_getsteppos(flidev_t dev
, long *pos
)
524 long poslow
, poshigh
;
526 unsigned short buf
[16];
529 buf
[0] = htons(0x6000);
530 IO(dev
, buf
, &wlen
, &rlen
);
531 poslow
= ntohs(buf
[0]);
532 if ((poslow
& 0xf000) != 0x6000)
535 buf
[0] = htons(0x6001);
536 IO(dev
, buf
, &wlen
, &rlen
);
537 poshigh
= ntohs(buf
[0]);
538 if ((poshigh
& 0xf000) != 0x6000)
541 if ((poshigh
& 0x0080) > 0)
543 *pos
= ((~poslow
) & 0xff) + 1;
544 *pos
+= (256 * ((~poshigh
) & 0xff));
549 *pos
= (poslow
& 0xff) + 256 * (poshigh
& 0xff);
555 static long fli_setfilterpos(flidev_t dev
, long pos
)
557 flifilterdata_t
*fdata
;
559 unsigned short buf
[16];
562 fdata
= DEVICE
->device_data
;
564 if (pos
== FLI_FILTERPOSITION_HOME
)
565 fdata
->currentslot
= FLI_FILTERPOSITION_HOME
;
567 if (fdata
->currentslot
< 0)
569 debug(FLIDEBUG_INFO
, "Home filter wheel/focuser.");
570 /* //set the timeout*/
571 DEVICE
->io_timeout
= (DEVICE
->devinfo
.type
== FLIDEVICE_FILTERWHEEL
? 5000 : 30000);
572 /*//10,12,15 pos filterwheel needs a longer timeout t*/
573 if(fdata
->numslots
== 12||fdata
->numslots
== 10)
575 DEVICE
->io_timeout
= 120000;
577 if(fdata
->numslots
== 15)
579 DEVICE
->io_timeout
= 200000;
584 buf
[0] = htons(0xf000);
585 IO(dev
, buf
, &wlen
, &rlen
);
586 if (ntohs(buf
[0]) != 0xf000)
589 DEVICE
->io_timeout
= 1000;
591 debug(FLIDEBUG_INFO
, "Moving %d steps to home position.",
592 wheeldata
[fdata
->numslots
].n_offset
);
594 COMMAND(fli_stepmotor(dev
, - (wheeldata
[fdata
->numslots
].n_offset
)));
595 fdata
->currentslot
= 0;
598 if (pos
== FLI_FILTERPOSITION_HOME
)
601 if (pos
>= fdata
->numslots
)
603 debug(FLIDEBUG_WARN
, "Requested slot (%d) exceeds number of slots.", pos
);
607 if (pos
== fdata
->currentslot
)
610 move
= pos
- fdata
->currentslot
;
613 move
+= fdata
->numslots
;
616 for (i
=0; i
< move
; i
++)
617 steps
+= wheeldata
[fdata
->numslots
].n_steps
[i
% fdata
->numslots
];
619 debug(FLIDEBUG_INFO
, "Move filter wheel %d steps.", steps
);
621 COMMAND(fli_stepmotor(dev
, - (steps
)));
622 fdata
->currentslot
= pos
;