libfli1-1.7/0000755000175000017500000000000011145355500010512 5ustar jrjrlibfli1-1.7/libfli-filter-focuser.c0000644000175000017500000006037311110507327015055 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifdef WIN32 //#include #else #include #include #include #endif #include #include #include #include #include #include #include "libfli-libfli.h" #include "libfli-mem.h" #include "libfli-debug.h" #include "libfli-filter-focuser.h" //#define SHOWFUNCTIONS extern double dconvert(void *buf); /* From libfli-camera-usb.c */ /* Array of filterwheel info Pos = # of filters Off = Offset of 0 filter from magnetic stop, X - y = number of steps from filter x to filter y */ static const wheeldata_t wheeldata[] = { /* 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 */ { 3, 48, { 80, 80, 80, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, /* Index 0 */ { 5, 0, { 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, /* Index 1 */ { 7, 14, { 34, 34, 35, 34, 34, 35, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, /* Index 2 */ { 8, 18, { 30, 30, 30, 30, 30, 30, 30, 30, 0, 0, 0, 0, 0, 0, 0, 0} }, /* Index 3 */ {10, 0, { 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0} }, /* Index 4 */ {12, 6, { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0} }, /* Index 5 */ {15, 0, { 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48} }, /* Index 6 */ { 7, 14, { 52, 52, 52, 52, 52, 52, 52, 52, 0, 0, 0, 0, 0, 0, 0, 0} }, /* Index 7 */ {20, 494, { 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29} }, /* Index 7 */ {12, 35, { 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, /* Index 7 */ }; #define FLI_BLOCK (1) #define FLI_NON_BLOCK (0) static long fli_stepmotor(flidev_t dev, long steps, long block); static long fli_getsteppos(flidev_t dev, long *pos); static long fli_setfilterpos(flidev_t dev, long pos); static long fli_getstepsremaining(flidev_t dev, long *pos); static long fli_focuser_getfocuserextent(flidev_t dev, long *extent); static long fli_focuser_readtemperature(flidev_t dev, flichannel_t channel, double *temperature); long fli_filter_focuser_probe(flidev_t dev) { int err = 0; long rlen, wlen; unsigned short buf[16]; CHKDEVICE(dev); DEVICE->io_timeout = 200; wlen = 2; rlen = 2; buf[0] = htons(0x8000); IO(dev, buf, &wlen, &rlen); if (ntohs(buf[0]) != 0x8000) { debug(FLIDEBUG_WARN, "Invalid echo, no FLI serial device found."); err = -ENODEV; } return err; } long fli_filter_focuser_open(flidev_t dev) { int err = 0; long rlen, wlen; unsigned short buf[16]; flifilterfocuserdata_t *fdata = NULL; CHKDEVICE(dev); DEVICE->io_timeout = 200; wlen = 2; rlen = 2; buf[0] = htons(0x8000); IO(dev, buf, &wlen, &rlen); if (ntohs(buf[0]) != 0x8000) { debug(FLIDEBUG_WARN, "Invalid echo, device not recognized, got %04x instead of %04x.", ntohs(buf[0]), 0x8000); err = -ENODEV; goto done; } wlen = 2; rlen = 2; buf[0] = htons(0x8001); IO(dev, buf, &wlen, &rlen); DEVICE->devinfo.fwrev = ntohs(buf[0]); if ((DEVICE->devinfo.fwrev & 0xff00) != 0x8000) { debug(FLIDEBUG_WARN, "Invalid echo, device not recognized."); err = -ENODEV; goto done; } if ((DEVICE->device_data = xmalloc(sizeof(flifilterfocuserdata_t))) == NULL) { err = -ENOMEM; goto done; } fdata = DEVICE->device_data; fdata->tableindex = -1; fdata->stepspersec = 100; fdata->currentslot = -1; if (DEVICE->devinfo.fwrev == 0x8001) /* Old level of firmware */ { if (DEVICE->devinfo.type != FLIDEVICE_FILTERWHEEL) { debug(FLIDEBUG_INFO, "Device detected is not filterwheel, old firmware?"); err = -ENODEV; goto done; } debug(FLIDEBUG_INFO, "Device is old fashioned filter wheel."); fdata->tableindex = 1; // FIX: should model info be set first? return 0; } debug(FLIDEBUG_INFO, "New version of hardware found."); wlen = 2; rlen = 2; buf[0] = htons(0x8002); IO(dev, buf, &wlen, &rlen); fdata->hwtype = ntohs(buf[0]); if ((fdata->hwtype & 0xff00) != 0x8000) { err = -ENODEV; goto done; } /* ndev is either jumper settings or FW return code */ fdata->hwtype &= 0x00ff; switch (fdata->hwtype) { case 0x00: if (DEVICE->devinfo.type != FLIDEVICE_FILTERWHEEL) { err = -ENODEV; goto done; } fdata->tableindex = 1; fdata->numslots = wheeldata[fdata->tableindex].n_pos; break; case 0x01: if (DEVICE->devinfo.type != FLIDEVICE_FILTERWHEEL) { err = -ENODEV; goto done; } fdata->tableindex = 0; fdata->numslots = wheeldata[fdata->tableindex].n_pos; break; case 0x02: if (DEVICE->devinfo.type != FLIDEVICE_FILTERWHEEL) { err = -ENODEV; goto done; } fdata->tableindex = 2; fdata->numslots = wheeldata[fdata->tableindex].n_pos; break; case 0x03: if (DEVICE->devinfo.type != FLIDEVICE_FILTERWHEEL) { err = -ENODEV; goto done; } fdata->tableindex = 3; fdata->numslots = wheeldata[fdata->tableindex].n_pos; break; case 0x04: if (DEVICE->devinfo.type != FLIDEVICE_FILTERWHEEL) { err = -ENODEV; goto done; } fdata->tableindex = 6; fdata->stepspersec= 16; // 1 /.06 fdata->numslots = wheeldata[fdata->tableindex].n_pos; break; case 0x05: if (DEVICE->devinfo.type != FLIDEVICE_FILTERWHEEL) { err = -ENODEV; goto done; } fdata->tableindex = 5; fdata->stepspersec= 16; // 1/.06 fdata->numslots = wheeldata[fdata->tableindex].n_pos; break; case 0x06: if (DEVICE->devinfo.type != FLIDEVICE_FILTERWHEEL) { err = -ENODEV; goto done; } fdata->tableindex = 4; fdata->stepspersec= 16; // 1/.06 fdata->numslots = wheeldata[fdata->tableindex].n_pos; break; case 0x07: if (DEVICE->devinfo.type != FLIDEVICE_FOCUSER) { err = -ENODEV; goto done; } if ((DEVICE->devinfo.fwrev & 0x00ff) < 0x30) { fdata->extent = 2100; fdata->numtempsensors = 0; } else if ((DEVICE->devinfo.fwrev & 0x00ff) == 0x30) { fdata->extent = 7000; fdata->numtempsensors = 1; } else { fdata->extent = 7000; fdata->numtempsensors = 2; } break; case 0x08: if (DEVICE->devinfo.type != FLIDEVICE_FILTERWHEEL) { err = -ENODEV; goto done; } fdata->tableindex = 7; fdata->stepspersec= 20; fdata->numslots = wheeldata[fdata->tableindex].n_pos; break; case 0x09: if (DEVICE->devinfo.type != FLIDEVICE_FILTERWHEEL) { err = -ENODEV; goto done; } fdata->tableindex = 8; fdata->stepspersec= 20; fdata->numslots = wheeldata[fdata->tableindex].n_pos; break; case 0x0a: if (DEVICE->devinfo.type != FLIDEVICE_FILTERWHEEL) { err = -ENODEV; goto done; } fdata->tableindex = 9; fdata->stepspersec= 20; fdata->numslots = wheeldata[fdata->tableindex].n_pos; break; case 0xff: /* This is a newer FLI filter or focuser wheen PCB */ if (DEVICE->devinfo.type == FLIDEVICE_FILTERWHEEL) { /* Get the number of filters */ wlen = 2; rlen = 2; buf[0] = htons(0x8008); IO(dev, buf, &wlen, &rlen); fdata->numslots = ntohs(buf[0]) & 0x00ff; } else if (DEVICE->devinfo.type == FLIDEVICE_FOCUSER) { /* Get the number of filters */ wlen = 2; rlen = 2; buf[0] = htons(0x8006); IO(dev, buf, &wlen, &rlen); fdata->extent = ntohs(buf[0]); /* Get the number of temperature sensors */ wlen = 2; rlen = 2; buf[0] = htons(0x800a); IO(dev, buf, &wlen, &rlen); fdata->numtempsensors = ntohs(buf[0]) & 0x00ff; } else { err = -ENODEV; goto done; } /* Step rate */ wlen = 2; rlen = 2; buf[0] = htons(0x8009); IO(dev, buf, &wlen, &rlen); fdata->stepspersec = ntohs(buf[0]) & 0x0fff; debug(FLIDEBUG_INFO, "Extent: %d Steps/sec: %d Temp Sensors: %d", fdata->extent, fdata->stepspersec, fdata->numtempsensors); fdata->tableindex = (-1); break; default: debug(FLIDEBUG_FAIL, "Unknown device %d attached.", fdata->hwtype); err = -ENODEV; goto done; } /* Now get the model name, either construct it or get it from device. */ if (err == 0) { if (fdata->hwtype < 0xfe) /* Older style hardware */ { if (DEVICE->devinfo.type == FLIDEVICE_FILTERWHEEL) { if ((DEVICE->devinfo.fwrev & 0x00ff) <= 0x30) { if (xasprintf(&DEVICE->devinfo.model, "Filter Wheel (%ld position)", fdata->numslots) < 0) { debug(FLIDEBUG_WARN, "Could not allocate memory for model information."); } } if ((DEVICE->devinfo.fwrev & 0x00ff) >= 0x31) { if ((DEVICE->devinfo.model = (char *) xmalloc(33)) == NULL) { debug(FLIDEBUG_WARN, "Could not allocate memory for model information."); } else { memset(DEVICE->devinfo.model, '\0', 33); wlen = 2; rlen = 32; DEVICE->devinfo.model[0] = 0x80; DEVICE->devinfo.model[1] = 0x03; IO(dev, DEVICE->devinfo.model, &wlen, &rlen); } } } if (DEVICE->devinfo.type == FLIDEVICE_FOCUSER) { if (xasprintf(&DEVICE->devinfo.model, "FLI Focuser") < 0) { debug(FLIDEBUG_WARN, "Could not allocate memory for model information."); } } } else /* Newer style hardware */ { if ((DEVICE->devinfo.model = (char *) xmalloc(33)) == NULL) { debug(FLIDEBUG_WARN, "Could not allocate memory for model information."); } else { memset(DEVICE->devinfo.model, '\0', 33); wlen = 2; rlen = 32; DEVICE->devinfo.model[0] = 0x80; DEVICE->devinfo.model[1] = 0x03; IO(dev, DEVICE->devinfo.model, &wlen, &rlen); } } } done: if (err) { if (DEVICE->devinfo.model != NULL) { xfree(DEVICE->devinfo.model); DEVICE->devinfo.model = NULL; } if (DEVICE->device_data != NULL) { xfree(DEVICE->device_data); DEVICE->device_data = NULL; } return err; } debug(FLIDEBUG_INFO, "Found '%s'", DEVICE->devinfo.model); return 0; } long fli_filter_focuser_close(flidev_t dev) { CHKDEVICE(dev); if (DEVICE->devinfo.model != NULL) { xfree(DEVICE->devinfo.model); DEVICE->devinfo.model = NULL; } if (DEVICE->device_data != NULL) { xfree(DEVICE->device_data); DEVICE->device_data = NULL; } return 0; } long fli_filter_command(flidev_t dev, int cmd, int argc, ...) { flifilterfocuserdata_t *fdata; long r; va_list ap; va_start(ap, argc); CHKDEVICE(dev); fdata = DEVICE->device_data; switch (cmd) { case FLI_SET_FILTER_POS: if (argc != 1) r = -EINVAL; else { long pos; pos = *va_arg(ap, long *); r = fli_setfilterpos(dev, pos); } break; case FLI_GET_FILTER_POS: if (argc != 1) r = -EINVAL; else { long *cslot; cslot = va_arg(ap, long *); *cslot = fdata->currentslot; r = 0; } break; case FLI_GET_FILTER_COUNT: if (argc != 1) r = -EINVAL; else { long *nslots; nslots = va_arg(ap, long *); *nslots = fdata->numslots; r = 0; } break; case FLI_STEP_MOTOR: if (argc != 1) r = -EINVAL; else { long *steps; steps = va_arg(ap, long *); r = fli_stepmotor(dev, *steps, FLI_BLOCK); } break; case FLI_STEP_MOTOR_ASYNC: if (argc != 1) r = -EINVAL; else { long *steps; steps = va_arg(ap, long *); r = fli_stepmotor(dev, *steps, FLI_NON_BLOCK); } break; case FLI_GET_STEPPER_POS: if (argc != 1) r = -EINVAL; else { long *pos; pos = va_arg(ap, long *); r = fli_getsteppos(dev, pos); } break; case FLI_GET_STEPS_REMAINING: if (argc != 1) r = -EINVAL; else { long *pos; pos = va_arg(ap, long *); r = fli_getstepsremaining(dev, pos); } break; default: r = -EINVAL; } va_end(ap); return r; } long fli_focuser_command(flidev_t dev, int cmd, int argc, ...) { long r; va_list ap; va_start(ap, argc); CHKDEVICE(dev); switch (cmd) { case FLI_STEP_MOTOR: if (argc != 1) r = -EINVAL; else { long *steps; steps = va_arg(ap, long *); r = fli_stepmotor(dev, *steps, FLI_BLOCK); } break; case FLI_STEP_MOTOR_ASYNC: if (argc != 1) r = -EINVAL; else { long *steps; steps = va_arg(ap, long *); r = fli_stepmotor(dev, *steps, FLI_NON_BLOCK); } break; case FLI_GET_STEPPER_POS: if (argc != 1) r = -EINVAL; else { long *pos; pos = va_arg(ap, long *); r = fli_getsteppos(dev, pos); } break; case FLI_GET_STEPS_REMAINING: if (argc != 1) r = -EINVAL; else { long *pos; pos = va_arg(ap, long *); r = fli_getstepsremaining(dev, pos); } break; case FLI_GET_FOCUSER_EXTENT: if (argc != 1) r = -EINVAL; else { long *extent; extent = va_arg(ap, long *); r = fli_focuser_getfocuserextent(dev, extent); } break; case FLI_HOME_FOCUSER: if (argc != 0) r = -EINVAL; else r = fli_setfilterpos(dev, FLI_FILTERPOSITION_HOME); break; case FLI_READ_TEMPERATURE: if (argc != 2) r = -EINVAL; else { double *temperature; flichannel_t channel; channel = va_arg(ap, flichannel_t); temperature = va_arg(ap, double *); r = fli_focuser_readtemperature(dev, channel, temperature); } break; default: r = -EINVAL; } va_end(ap); return r; } static long fli_stepmotor(flidev_t dev, long steps, long block) { flifilterfocuserdata_t *fdata; long dir, timeout, move, stepsleft; long rlen, wlen; unsigned short buf[16]; clock_t begin; fdata = DEVICE->device_data; #ifdef SHOWFUNCTIONS debug(FLIDEBUG_INFO, "Entering " __FUNCTION__); #endif /* Support HALT operation when steps == 0 */ if (steps == 0) { rlen = 2; wlen = 2; buf[0] = htons((unsigned short) 0xa000); IO(dev, buf, &wlen, &rlen); if ((ntohs(buf[0]) & 0xf000) != 0xa000) { debug(FLIDEBUG_WARN, "Invalid echo."); return -EIO; } return 0; } dir = steps; steps = abs(steps); while (steps > 0) { if (steps > 4095) move = 4095; else move = steps; #ifdef SHOWFUNCTIONS debug(FLIDEBUG_INFO, "Entering " __FUNCTION__); #endif steps -= move; timeout = (move / fdata->stepspersec) + 2; rlen = 2; wlen = 2; if (dir < 0) { buf[0] = htons((unsigned short) (0xa000 | (unsigned short) move)); IO(dev, buf, &wlen, &rlen); if ((ntohs(buf[0]) & 0xf000) != 0xa000) { debug(FLIDEBUG_WARN, "Invalid echo."); return -EIO; } } else { buf[0] = htons((unsigned short) (0x9000 | (unsigned short) move)); IO(dev, buf, &wlen, &rlen); if ((ntohs(buf[0]) & 0xf000) != 0x9000) { debug(FLIDEBUG_WARN, "Invalid echo."); return -EIO; } } begin = clock(); stepsleft = 0; while ( (stepsleft != 0x7000) && (block != 0) ) { #ifdef WIN32 Sleep(100); #else usleep(100000); #endif buf[0] = htons(0x7000); IO(dev, buf, &wlen, &rlen); stepsleft = ntohs(buf[0]); if (((clock() - begin) / CLOCKS_PER_SEC) > timeout) { debug(FLIDEBUG_WARN, "A device timeout has occurred."); return -EIO; } } } return 0; } static long fli_getsteppos(flidev_t dev, long *pos) { long poslow, poshigh; long rlen, wlen; unsigned short buf[16]; #ifdef SHOWFUNCTIONS debug(FLIDEBUG_INFO, "Entering " __FUNCTION__); #endif rlen = 2; wlen = 2; buf[0] = htons(0x6000); IO(dev, buf, &wlen, &rlen); poslow = ntohs(buf[0]); if ((poslow & 0xf000) != 0x6000) return -EIO; buf[0] = htons(0x6001); IO(dev, buf, &wlen, &rlen); poshigh = ntohs(buf[0]); if ((poshigh & 0xf000) != 0x6000) return -EIO; if ((poshigh & 0x0080) > 0) { *pos = ((~poslow) & 0xff) + 1; *pos += (256 * ((~poshigh) & 0xff)); *pos = -(*pos); } else { *pos = (poslow & 0xff) + 256 * (poshigh & 0xff); } return 0; } static long fli_getstepsremaining(flidev_t dev, long *pos) { long rlen = 2, wlen = 2; unsigned short buf[16]; #ifdef SHOWFUNCTIONS debug(FLIDEBUG_INFO, "Entering " __FUNCTION__); #endif buf[0] = htons(0x7000); IO(dev, buf, &wlen, &rlen); *pos = ntohs(buf[0]) & 0x0fff; return 0; } static long fli_homedevice(flidev_t dev, long block) { flifilterfocuserdata_t *fdata; long rlen, wlen; unsigned short buf[16]; fdata = DEVICE->device_data; #ifdef SHOWFUNCTIONS debug(FLIDEBUG_INFO, "Entering " __FUNCTION__); #endif /* Older hardware */ if (fdata->hwtype < 0xfe) { debug(FLIDEBUG_INFO, "Home filter wheel/focuser."); if (DEVICE->devinfo.type == FLIDEVICE_FILTERWHEEL) { switch (fdata->numslots) { case 12: case 10: DEVICE->io_timeout = 120000; break; case 15: DEVICE->io_timeout = 200000; break; default: DEVICE->io_timeout = 5000; break; } } else { DEVICE->io_timeout = 30000; } wlen = 2; rlen = 2; buf[0] = htons(0xf000); IO(dev, buf, &wlen, &rlen); if (ntohs(buf[0]) != 0xf000) return -EIO; /* Reduce overall timeout to speed operations with serial port */ DEVICE->io_timeout = 200; /* This is required to prevent offsetting the focuser */ if (DEVICE->devinfo.type != FLIDEVICE_FOCUSER) { debug(FLIDEBUG_INFO, "Moving %d steps to home position.", wheeldata[fdata->tableindex].n_offset); COMMAND(fli_stepmotor(dev, - (wheeldata[fdata->tableindex].n_offset), FLI_BLOCK)); fdata->currentslot = 0; } } else /* New HW */ { clock_t begin; unsigned short stepsleft; rlen = 2; wlen = 2; buf[0] = htons((unsigned short) 0xf000); IO(dev, buf, &wlen, &rlen); if ((ntohs(buf[0]) & 0xf000) != 0xf000) { debug(FLIDEBUG_WARN, "Invalid echo."); return -EIO; } begin = clock(); stepsleft = 0x04; while ( ((stepsleft & 0x04) != 0) && (block != 0) ) { #ifdef WIN32 Sleep(100); #else usleep(100000); #endif buf[0] = htons(0xb000); IO(dev, buf, &wlen, &rlen); stepsleft = ntohs(buf[0]); } fdata->currentslot = 0; } return 0; } static long fli_setfilterpos(flidev_t dev, long pos) { flifilterfocuserdata_t *fdata; long rlen, wlen; unsigned short buf[16]; long move, i, steps; fdata = DEVICE->device_data; #ifdef SHOWFUNCTIONS debug(FLIDEBUG_INFO, "Entering " __FUNCTION__); #endif if (pos == FLI_FILTERPOSITION_HOME) fdata->currentslot = FLI_FILTERPOSITION_HOME; if (fdata->currentslot < 0) { fli_homedevice(dev, FLI_BLOCK); } if (pos == FLI_FILTERPOSITION_HOME) return 0; if (pos >= fdata->numslots) { debug(FLIDEBUG_WARN, "Requested slot (%d) exceeds number of slots.", pos); return -EINVAL; } if (pos == fdata->currentslot) return 0; if (fdata->hwtype < 0xfe) { move = pos - fdata->currentslot; if (move < 0) move += fdata->numslots; steps = 0; if (fdata->numslots != 0) for (i=0; i < move; i++) steps += wheeldata[fdata->tableindex].n_steps[i % fdata->numslots]; debug(FLIDEBUG_INFO, "Move filter wheel %d steps.", steps); if (steps != 0) COMMAND(fli_stepmotor(dev, - (steps), FLI_BLOCK)); fdata->currentslot = pos; } else { clock_t begin; unsigned short stepsleft; rlen = 2; wlen = 2; buf[0] = htons((unsigned short) (0xc000 | (unsigned short) pos)); IO(dev, buf, &wlen, &rlen); if ((ntohs(buf[0]) & 0xf000) != 0xc000) { debug(FLIDEBUG_WARN, "Invalid echo."); return -EIO; } begin = clock(); stepsleft = 0; while (stepsleft != 0x7000) { #ifdef WIN32 Sleep(100); #else usleep(100000); #endif buf[0] = htons(0x7000); IO(dev, buf, &wlen, &rlen); stepsleft = ntohs(buf[0]); } fdata->currentslot = pos; } return 0; } long fli_focuser_getfocuserextent(flidev_t dev, long *extent) { flifilterfocuserdata_t *fdata; fdata = DEVICE->device_data; #ifdef SHOWFUNCTIONS debug(FLIDEBUG_INFO, "Entering " __FUNCTION__); #endif *extent = fdata->extent; return 0; } long fli_focuser_readtemperature(flidev_t dev, flichannel_t channel, double *temperature) { flifilterfocuserdata_t *fdata; long rlen, wlen; short buf[64]; short b; int i; fdata = DEVICE->device_data; #ifdef SHOWFUNCTIONS debug(FLIDEBUG_INFO, "Entering " __FUNCTION__); #endif if (fdata->numtempsensors == 0) { debug(FLIDEBUG_WARN, "This device does not support temperature reading."); return -EINVAL; } if (channel > fdata->numtempsensors) { debug(FLIDEBUG_WARN, "Device has %d channels, %d channel requested.", fdata->numtempsensors, channel); return -EINVAL; } if (fdata->hwtype == 0xff) { wlen = 2; rlen = 2; buf[0] = htons(0x1000 | (unsigned short) channel); IO(dev, buf, &wlen, &rlen); *temperature = (double) ((signed char) (buf[0] & 0x00ff)) + ((double) ((buf[0] >> 8) & 0x00ff) / 256); debug(FLIDEBUG_INFO, "Temperature: %f", *temperature); } else if (fdata->hwtype == 0x07) { if ((DEVICE->devinfo.fwrev & 0x00ff) == 0x30) { wlen = 2; rlen = 2; buf[0] = htons(0x1000 | (unsigned short) channel); IO(dev, buf, &wlen, &rlen); b = ntohs(buf[0]); *temperature = (double) b / 256.0; if (*temperature < -45.0) { return -EINVAL; } } if ((DEVICE->devinfo.fwrev & 0x00ff) > 0x30) { /* Ok, some constants are sent back with each temperature reading */ wlen = 2; rlen = 2 + 4 * 7; buf[0] = htons(0x1000 | (unsigned short) channel); IO(dev, buf, &wlen, &rlen); b = ntohs(buf[0]); *temperature = 0.0; for (i = 0; i < 7; i++) { *temperature += dconvert(((char *) buf) + (2 + i * 4)) * pow((double) b, (double) i); } if (*temperature < (-45.0)) { debug(FLIDEBUG_WARN, "External sensor not plugged in."); return -EINVAL; } } } return 0; } libfli1-1.7/libfli-usb-sys.c0000644000175000017500000001331211110507327013520 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #include #include #include #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)) #include #include #else #include #endif #include #include #include #include #include "libfli-libfli.h" #include "libfli-sys.h" #include "libfli-usb.h" #include "fliusb_ioctl.h" long linux_usb_connect(flidev_t dev, fli_unixio_t *io, char *name) { struct usb_device_descriptor usbdesc; int confg, r; if (ioctl(io->fd, FLIUSB_GET_DEVICE_DESCRIPTOR, &usbdesc) == -1) { debug(FLIDEBUG_FAIL, "%s: Could not read descriptor: %s", __PRETTY_FUNCTION__, strerror(errno)); return -EIO; } if (usbdesc.idVendor != FLIUSB_VENDORID) { debug(FLIDEBUG_INFO, "%s: Not a FLI device!", __PRETTY_FUNCTION__); return -ENODEV; } switch (usbdesc.idProduct) { /* These are valid product IDs */ case FLIUSB_CAM_ID: case FLIUSB_FOCUSER_ID: case FLIUSB_FILTER_ID: case FLIUSB_PROLINE_ID: break; default: /* Anything else is unknown */ return -ENODEV; } DEVICE->devinfo.devid = usbdesc.idProduct; DEVICE->devinfo.fwrev = usbdesc.bcdDevice; confg = 0; r = ioctl (io->fd, USBDEVFS_SETCONFIGURATION, &confg); debug(FLIDEBUG_INFO, "USBDEVFS_SETCONFIGURATION return %i", r); confg = 1; r = ioctl (io->fd, USBDEVFS_SETCONFIGURATION, &confg); debug(FLIDEBUG_INFO, "USBDEVFS_SETCONFIGURATION return %i", r); return 0; } long linux_bulktransfer(flidev_t dev, int ep, void *buf, long *len) { fli_unixio_t *io; fliusb_bulktransfer_t bulkxfer; size_t remaining; int err = 0; #define _DEBUG #ifdef _DEBUG debug(FLIDEBUG_INFO, "%s: attempting %ld bytes %s", __PRETTY_FUNCTION__, *len, (ep & USB_DIR_IN) ? "in" : "out"); #endif io = DEVICE->io_data; #ifdef _DEBUG if ((ep & 0xf0) == 0) { char buffer[1024]; int i; sprintf(buffer, "OUT %6ld: ", *len); for (i = 0; i < ((*len > 16)?16:*len); i++) { sprintf(buffer + strlen(buffer), "%02x ", ((unsigned char *) buf)[i]); } debug(FLIDEBUG_INFO, buffer); } #endif /* _DEBUG */ remaining = *len; while (remaining) /* read up to USB_READ_SIZ_MAX bytes at a time */ { int bytes; bulkxfer.ep = ep; bulkxfer.count = MIN(remaining, USB_READ_SIZ_MAX); bulkxfer.timeout = DEVICE->io_timeout; bulkxfer.buf = buf + *len - remaining; /* This ioctl returns the number of bytes transfered */ bytes = ioctl(io->fd, (ep & USB_DIR_IN) ? FLIUSB_BULKREAD : FLIUSB_BULKWRITE, &bulkxfer); if (bytes < 0) break; remaining -= bytes; if (bytes < bulkxfer.count) break; } /* Set *len to the number of bytes actually transfered */ if (remaining) err = -errno; *len -= remaining; #ifdef _DEBUG if ((ep & 0xf0) != 0) { char buffer[1024]; int i; sprintf(buffer, " IN %6ld: ", *len); for (i = 0; i < ((*len > 16)?16:*len); i++) { sprintf(buffer + strlen(buffer), "%02x ", ((unsigned char *) buf)[i]); } debug(FLIDEBUG_INFO, buffer); } #endif /* _DEBUG */ return err; } long linux_bulkwrite(flidev_t dev, void *buf, long *wlen) { int ep; switch (DEVICE->devinfo.devid) { case FLIUSB_CAM_ID: case FLIUSB_FOCUSER_ID: case FLIUSB_FILTER_ID: ep = 0x02; break; case FLIUSB_PROLINE_ID: ep = 0x01; break; default: debug(FLIDEBUG_FAIL, "Unknown device type."); return -EINVAL; } return linux_bulktransfer(dev, ep | USB_DIR_OUT, buf, wlen); } long linux_bulkread(flidev_t dev, void *buf, long *rlen) { int ep; switch (DEVICE->devinfo.devid) { case FLIUSB_CAM_ID: case FLIUSB_FOCUSER_ID: case FLIUSB_FILTER_ID: ep = 0x02; break; case FLIUSB_PROLINE_ID: ep = 0x01; break; default: debug(FLIDEBUG_FAIL, "Unknown device type."); return -EINVAL; } return linux_bulktransfer(dev, ep | USB_DIR_IN, buf, rlen); } long linux_usb_disconnect(flidev_t dev) { return 0; } libfli1-1.7/.cproject0000644000175000017500000007462311110507327012336 0ustar jrjr libfli1-1.7/.project0000644000175000017500000000452011110507327012160 0ustar jrjr libfli org.eclipse.cdt.managedbuilder.core.genmakebuilder clean,full,incremental, org.eclipse.cdt.make.core.cleanBuildTarget clean org.eclipse.cdt.make.core.enableCleanBuild true ?name? org.eclipse.cdt.make.core.append_environment true org.eclipse.cdt.make.core.stopOnError true org.eclipse.cdt.make.core.buildCommand make org.eclipse.cdt.make.core.contents org.eclipse.cdt.make.core.activeConfigSettings org.eclipse.cdt.make.core.buildLocation ${workspace_loc:/libfli/Debug} org.eclipse.cdt.make.core.useDefaultBuildCmd true org.eclipse.cdt.make.core.enableAutoBuild false org.eclipse.cdt.make.core.enableFullBuild true org.eclipse.cdt.make.core.buildArguments org.eclipse.cdt.make.core.fullBuildTarget all org.eclipse.cdt.make.core.autoBuildTarget all org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder org.eclipse.cdt.managedbuilder.core.ScannerConfigNature org.eclipse.cdt.managedbuilder.core.managedBuildNature org.eclipse.cdt.core.cnature libfli1-1.7/libfli-camera-parport.c0000644000175000017500000004711611110507327015041 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifdef WIN32 #include #else #include #include #endif #include #include #include #include "libfli-libfli.h" #include "libfli-mem.h" #include "libfli-debug.h" #include "libfli-camera.h" #include "libfli-camera-parport.h" long fli_camera_parport_open(flidev_t dev) { flicamdata_t *cam; long rlen, wlen; unsigned short buf; int id; cam = DEVICE->device_data; /* Set timeout values */ cam->readto = 1000; cam->writeto = 1000; cam->dirto = 1000; rlen = 2; wlen = 2; buf = htons(C_ADDRESS(1, EPARAM_ECHO)); IO(dev, &buf, &wlen, &rlen); if (buf != htons(C_ADDRESS(1, EPARAM_ECHO))) { debug(FLIDEBUG_FAIL, "Echo back from camera failed."); return -EIO; } rlen = 2; wlen = 2; buf = htons(C_ADDRESS(1, EPARAM_DEVICE)); IO(dev, &buf, &wlen, &rlen); DEVICE->devinfo.hwrev = ntohs(buf) & 0x00ff; rlen = 2; wlen = 2; buf = htons(C_ADDRESS(1, EPARAM_CCDID)); IO(dev, &buf, &wlen, &rlen); DEVICE->devinfo.devid = ntohs(buf) & 0x00ff; for (id = 0; knowndev[id].index != 0; id++) if (knowndev[id].index == DEVICE->devinfo.devid) break; if (knowndev[id].index == 0) return -ENODEV; cam->ccd.array_area.ul.x = knowndev[id].array_area.ul.x; cam->ccd.array_area.ul.y = knowndev[id].array_area.ul.y; cam->ccd.array_area.lr.x = knowndev[id].array_area.lr.x; cam->ccd.array_area.lr.y = knowndev[id].array_area.lr.y; cam->ccd.visible_area.ul.x = knowndev[id].visible_area.ul.x; cam->ccd.visible_area.ul.y = knowndev[id].visible_area.ul.y; cam->ccd.visible_area.lr.x = knowndev[id].visible_area.lr.x; cam->ccd.visible_area.lr.y = knowndev[id].visible_area.lr.y; cam->ccd.pixelwidth = knowndev[id].pixelwidth; cam->ccd.pixelheight = knowndev[id].pixelheight; if ((DEVICE->devinfo.model = (char *)xmalloc(strlen(knowndev[id].model) + 1)) == NULL) return -ENOMEM; strcpy(DEVICE->devinfo.model, knowndev[id].model); debug(FLIDEBUG_INFO, " Name: %s", DEVICE->devinfo.devnam); debug(FLIDEBUG_INFO, " Array: (%4d,%4d),(%4d,%4d)", cam->ccd.array_area.ul.x, cam->ccd.array_area.ul.y, cam->ccd.array_area.lr.x, cam->ccd.array_area.lr.y); debug(FLIDEBUG_INFO, " Visible: (%4d,%4d),(%4d,%4d)", cam->ccd.visible_area.ul.x, cam->ccd.visible_area.ul.y, cam->ccd.visible_area.lr.x, cam->ccd.visible_area.lr.y); rlen = 2; wlen = 2; buf = htons(C_ADDRESS(1, EPARAM_SNHIGH)); IO(dev, &buf, &wlen, &rlen); DEVICE->devinfo.serno = (ntohs(buf) & 0x00ff) << 8; rlen = 2; wlen = 2; buf = htons(C_ADDRESS(1, EPARAM_SNLOW)); IO(dev, &buf, &wlen, &rlen); DEVICE->devinfo.serno |= (ntohs(buf) & 0x00ff); rlen = 2; wlen = 2; buf = htons(C_ADDRESS(1, EPARAM_FIRM)); IO(dev, &buf, &wlen, &rlen); DEVICE->devinfo.fwrev = (ntohs(buf) & 0x00ff); /* Initialize all varaibles to something */ switch(DEVICE->devinfo.hwrev) { case 0x01: cam->tempslope = (100.0 / 201.1); cam->tempintercept = (-61.613); break; case 0x02: cam->tempslope = (70.0 / 215.75); cam->tempintercept = (-52.5681); break; default: debug(FLIDEBUG_WARN, "Could not set temperature parameters."); break; } cam->vflushbin = 4; cam->hflushbin = 4; cam->vbin = 1; cam->hbin = 1; cam->image_area.ul.x = cam->ccd.visible_area.ul.x; cam->image_area.ul.y = cam->ccd.visible_area.ul.y; cam->image_area.lr.x = cam->ccd.visible_area.lr.x; cam->image_area.lr.y = cam->ccd.visible_area.lr.y; cam->exposure = 100; cam->frametype = FLI_FRAME_TYPE_NORMAL; cam->flushes = 0; cam->bitdepth = FLI_MODE_16BIT; cam->exttrigger = 0; cam->grabrowwidth = (cam->image_area.lr.x - cam->image_area.ul.x) / cam->hbin; cam->grabrowcount = 1; cam->grabrowcounttot = cam->grabrowcount; cam->grabrowindex = 0; cam->grabrowbatchsize = 1; cam->grabrowbufferindex = cam->grabrowcount; cam->flushcountbeforefirstrow = 0; cam->flushcountafterlastrow = 0; return 0; } long fli_camera_parport_get_array_area(flidev_t dev, long *ul_x, long *ul_y, long *lr_x, long *lr_y) { flicamdata_t *cam; cam = DEVICE->device_data; *ul_x = cam->ccd.array_area.ul.x; *ul_y = cam->ccd.array_area.ul.y; *lr_x = cam->ccd.array_area.lr.x; *lr_y = cam->ccd.array_area.lr.y; return 0; } long fli_camera_parport_get_visible_area(flidev_t dev, long *ul_x, long *ul_y, long *lr_x, long *lr_y) { flicamdata_t *cam; cam = DEVICE->device_data; *ul_x = cam->ccd.visible_area.ul.x; *ul_y = cam->ccd.visible_area.ul.y; *lr_x = cam->ccd.visible_area.lr.x; *lr_y = cam->ccd.visible_area.lr.y; return 0; } long fli_camera_parport_set_exposure_time(flidev_t dev, long exptime) { flicamdata_t *cam; cam = DEVICE->device_data; if (exptime < 0) return -EINVAL; cam->exposure = exptime; if (exptime <= 15000) /* Less than thirty seconds..., 8.192e-3 sec */ { cam->expdur = 1; cam->expmul = (long) (((double) exptime) / 8.192); } else if (exptime <= 2000000) /* Less than one hour */ { cam->expdur = (long) (1.0 / 8.192e-3); cam->expmul = (long) (exptime / 1000); } else { cam->expdur = (long) (10.0 / 8.192e-3); cam->expmul = (long) (exptime / 10000); } return 0; } long fli_camera_parport_set_image_area(flidev_t dev, long ul_x, long ul_y, long lr_x, long lr_y) { flicamdata_t *cam; cam = DEVICE->device_data; if ((ul_x < cam->ccd.visible_area.ul.x) || (ul_y < cam->ccd.visible_area.ul.y) || (lr_x > cam->ccd.visible_area.lr.x) || (lr_y > cam->ccd.visible_area.lr.y)) return -EINVAL; cam->image_area.ul.x = ul_x; cam->image_area.ul.y = ul_y; cam->image_area.lr.x = lr_x; cam->image_area.lr.y = lr_y; return 0; } long fli_camera_parport_set_hbin(flidev_t dev, long hbin) { flicamdata_t *cam; cam = DEVICE->device_data; if ((hbin < 1) || (hbin > 16)) return -EINVAL; cam->hbin = hbin; return 0; } long fli_camera_parport_set_vbin(flidev_t dev, long vbin) { flicamdata_t *cam; cam = DEVICE->device_data; if ((vbin < 1) || (vbin > 16)) return -EINVAL; cam->vbin = vbin; return 0; } long fli_camera_parport_get_exposure_status(flidev_t dev, long *timeleft) { flicamdata_t *cam; long rlen, wlen; unsigned short buf; cam = DEVICE->device_data; rlen = 2; wlen = 2; buf = htons(C_SHUTTER(1,0)); IO(dev, &buf, &wlen, &rlen); if ((ntohs(buf) & 0xf000) != C_SHUTTER(0,0)) { debug(FLIDEBUG_FAIL, "(exposurestatus) echo back from camera failed."); return -EIO; } *timeleft = (long)((double)(ntohs(buf) & 0x07ff) * ((double)cam->expdur * 8.192)); return 0; } long fli_camera_parport_set_temperature(flidev_t dev, double temperature) { flicamdata_t *cam; long rlen, wlen; unsigned short buf; cam = DEVICE->device_data; rlen = 2; wlen = 2; buf = (unsigned short)((temperature - cam->tempintercept) / cam->tempslope); buf = htons((unsigned short) C_TEMP(buf)); IO(dev, &buf, &wlen, &rlen); if ((ntohs(buf) & 0xf000) != C_TEMP(0)) { debug(FLIDEBUG_FAIL, "(settemperature) echo back from camera failed."); return -EIO; } return 0; } long fli_camera_parport_get_temperature(flidev_t dev, double *temperature) { flicamdata_t *cam; long rlen, wlen; unsigned short buf; cam = DEVICE->device_data; rlen = 2; wlen = 2; buf = htons(C_TEMP(0x0800)); IO(dev, &buf, &wlen, &rlen); if ((ntohs(buf) & 0xf000) != C_TEMP(0)) { debug(FLIDEBUG_FAIL, "(settemperature) echo back from camera failed."); return -EIO; } *temperature = cam->tempslope * (double)(ntohs(buf) & 0x00ff) + cam->tempintercept; return 0; } long fli_camera_parport_grab_row(flidev_t dev, void *buff, size_t width) { flicamdata_t *cam; long r; double dTm; long rlen, wlen; unsigned short buf; long grabwidth; cam = DEVICE->device_data; if (cam->flushcountbeforefirstrow > 0) { if ((r = fli_camera_parport_flush_rows(dev, cam->flushcountbeforefirstrow, 1))) return r; cam->flushcountbeforefirstrow = 0; } dTm = (25.0e-6) * cam->ccd.array_area.lr.x + 1e-3; dTm = dTm / 1e-6; cam->readto = (long)dTm; cam->writeto = (long)dTm; if (cam->removebias) { // grabwidth = cam->ccd.array_area.lr.x - cam->ccd.array_area.ul.x + (50 + 64) - cam->image_area.ul.x; grabwidth = (cam->ccd.array_area.lr.x - cam->ccd.array_area.ul.x + (5 + 64) - cam->image_area.ul.x) / cam->hbin; } else { grabwidth = cam->grabrowwidth; } rlen = 0; wlen = 2; buf = htons((unsigned short) C_SEND(grabwidth)); IO(dev, &buf, &wlen, &rlen); if (cam->bitdepth == FLI_MODE_8BIT) { unsigned char *cbuf; int x; if ((cbuf = xmalloc(grabwidth)) == NULL) { debug(FLIDEBUG_FAIL, "Failed memory allocation during row grab."); return -ENOMEM; } rlen = grabwidth; wlen = 0; r = DEVICE->fli_io(dev, cbuf, &wlen, &rlen); if (r != 0) { debug(FLIDEBUG_WARN, "Couldn't grab entire row (8-bit), got %d of %d bytes.", r, grabwidth); } for (x = 0; x < (int)width; x++) { ((char *)buff)[x] = (((cbuf[x]) + 128) & 0x00ff); } xfree(cbuf); } else { unsigned short *sbuf; int x; if ((sbuf = xmalloc(grabwidth * sizeof(unsigned short))) == NULL) { debug(FLIDEBUG_FAIL, "Failed memory allocation during row grab."); return -ENOMEM; } rlen = grabwidth * sizeof(unsigned short); wlen = 0; r = DEVICE->fli_io(dev, sbuf, &wlen, &rlen); if (r != 0) { debug(FLIDEBUG_WARN, "Couldn't grab entire row (16-bit), got %d of %d bytes.", r, grabwidth); } for (x = 0; x < (int)width; x++) { if (DEVICE->devinfo.hwrev == 0x01) /* IMG camera */ { ((unsigned short *)buff)[x] = ntohs(sbuf[x]) + 32768; } else { ((unsigned short *)buff)[x] = ntohs(sbuf[x]); } } if (cam->removebias) { for (x = grabwidth - (64 / cam->hbin); x < grabwidth; x++) { unsigned short d; if (DEVICE->devinfo.hwrev == 0x01) /* IMG camera */ d = ntohs(sbuf[x]) + 32768; else d = ntohs(sbuf[x]); cam->pix_sum += (double) d; cam->pix_cnt += 1.0; } for (x = 0; x < (int)width; x++) { ((unsigned short *)buff)[x] = ((unsigned short *)buff)[x] - (unsigned short) ((cam->pix_sum / cam->pix_cnt) - cam->biasoffset); } debug(FLIDEBUG_INFO, "Overscan bias average: %g (%d)", (cam->pix_sum / cam->pix_cnt), (unsigned short) ((cam->pix_sum / cam->pix_cnt) - 200.0)); } xfree(sbuf); } rlen = 2; wlen = 0; IO(dev, &buf, &wlen, &rlen); if (cam->removebias) { if (ntohs(buf) != C_SEND(grabwidth)) { debug(FLIDEBUG_WARN, "Width: %d, requested %d.", width, grabwidth * sizeof(unsigned short)); debug(FLIDEBUG_WARN, "Got 0x%04x instead of 0x%04x.", ntohs(buf), C_SEND(grabwidth)); debug(FLIDEBUG_WARN, "Didn't get command echo at end of row."); } } else { if (ntohs(buf) != C_SEND(width)) { debug(FLIDEBUG_WARN, "Width: %d, requested %d.", width, grabwidth * sizeof(unsigned short)); debug(FLIDEBUG_WARN, "Got 0x%04x instead of 0x%04x.", ntohs(buf), C_SEND(width)); debug(FLIDEBUG_WARN, "Didn't get command echo at end of row."); } } if (cam->grabrowcount > 0) { cam->grabrowcount--; if (cam->grabrowcount == 0) { if ((r = fli_camera_parport_flush_rows(dev, cam->flushcountafterlastrow, 1))) return r; cam->flushcountafterlastrow = 0; cam->grabrowbatchsize = 1; } } cam->readto = 1000; cam->writeto = 1000; return 0; } long fli_camera_parport_expose_frame(flidev_t dev) { flicamdata_t *cam; long rlen, wlen; unsigned short buf; cam = DEVICE->device_data; debug(FLIDEBUG_INFO, "Setting X Row Offset."); rlen = 2; wlen = 2; buf = htons((unsigned short) D_XROWOFF(cam->image_area.ul.x)); IO(dev, &buf, &wlen, &rlen); if (cam->removebias) { debug(FLIDEBUG_INFO, "Setting X Row Width to %d.", cam->ccd.array_area.lr.x - cam->ccd.array_area.ul.x + 5 + 64); buf = htons((unsigned short) D_XROWWID(cam->ccd.array_area.lr.x - cam->ccd.array_area.ul.x + 5 + 64)); IO(dev, &buf, &wlen, &rlen); } else { debug(FLIDEBUG_INFO, "Setting X Row Width to %d.", cam->ccd.array_area.lr.x - cam->ccd.array_area.ul.x); buf = htons((unsigned short) D_XROWWID(cam->ccd.array_area.lr.x - cam->ccd.array_area.ul.x)); IO(dev, &buf, &wlen, &rlen); } debug(FLIDEBUG_INFO, "Setting X Flush Bin."); buf = htons((unsigned short) D_XFLBIN(cam->hflushbin)); IO(dev, &buf, &wlen, &rlen); debug(FLIDEBUG_INFO, "Setting Y Flush Bin."); buf = htons((unsigned short) D_YFLBIN(cam->vflushbin)); IO(dev, &buf, &wlen, &rlen); debug(FLIDEBUG_INFO, "Setting X Bin."); buf = htons((unsigned short) D_XBIN(cam->hbin)); IO(dev, &buf, &wlen, &rlen); debug(FLIDEBUG_INFO, "Setting Y Bin."); buf = htons((unsigned short) D_YBIN(cam->vbin)); IO(dev, &buf, &wlen, &rlen); debug(FLIDEBUG_INFO, "Setting Exposure Duration."); buf = htons((unsigned short) D_EXPDUR(cam->expdur)); IO(dev, &buf, &wlen, &rlen); if (cam->bitdepth == FLI_MODE_8BIT) { debug(FLIDEBUG_INFO, "Eight Bit."); buf = htons((unsigned short)((cam->exttrigger > 0) ? C_RESTCFG(0,0,1,7) : C_RESTCFG(0,0,0,7))); } else { debug(FLIDEBUG_INFO, "Sixteen Bit."); buf = htons((unsigned short)((cam->exttrigger > 0) ? C_RESTCFG(0,0,1,15) : C_RESTCFG(0,0,0,15))); } IO(dev, &buf, &wlen, &rlen); if (cam->flushes > 0) { int r; debug(FLIDEBUG_INFO, "Flushing array."); if ((r = fli_camera_parport_flush_rows(dev, cam->ccd.array_area.lr.y - cam->ccd.array_area.ul.y, cam->flushes))) return r; } debug(FLIDEBUG_INFO, "Exposing."); buf = htons((unsigned short) C_SHUTTER((cam->frametype == FLI_FRAME_TYPE_DARK)?0:1, cam->expmul)); IO(dev, &buf, &wlen, &rlen); cam->grabrowwidth = cam->image_area.lr.x - cam->image_area.ul.x; cam->flushcountbeforefirstrow = cam->image_area.ul.y; cam->flushcountafterlastrow = (cam->ccd.array_area.lr.y - cam->ccd.array_area.ul.y) - ((cam->image_area.lr.y - cam->image_area.ul.y) * cam->vbin) - cam->image_area.ul.y; if (cam->flushcountafterlastrow < 0) cam->flushcountafterlastrow = 0; cam->pix_sum = 0.0; cam->pix_cnt = 0.0; cam->grabrowcount = cam->image_area.lr.y - cam->image_area.ul.y; return 0; } long fli_camera_parport_flush_rows(flidev_t dev, long rows, long repeat) { flicamdata_t *cam; double dTm; long rlen, wlen; unsigned short buf; if (rows < 0) return -EINVAL; if (rows == 0) return 0; cam = DEVICE->device_data; dTm = ((25e-6) / (cam->hflushbin / 2)) * cam->ccd.array_area.lr.x + 1e-3; dTm = dTm * rows; dTm = dTm / 1e-6; cam->readto = (long)dTm; cam->writeto = (long)dTm; while (repeat>0) { long retval; rlen = 2; wlen = 2; buf = htons((unsigned short) C_FLUSH(rows)); retval = DEVICE->fli_io(dev, &buf, &wlen, &rlen); if (retval != 0) { cam->readto = 1000; cam->writeto = 1000; return retval; } repeat--; } return 0; } long fli_camera_parport_set_bit_depth(flidev_t dev, flibitdepth_t bitdepth) { flicamdata_t *cam; cam = DEVICE->device_data; if (DEVICE->devinfo.type != 0x01) /* IMG cameras only support this */ return -EINVAL; if ((bitdepth != FLI_MODE_8BIT) && (bitdepth != FLI_MODE_16BIT)) { debug(FLIDEBUG_FAIL, "Invalid bit depth setting."); return -EINVAL; } cam->bitdepth = bitdepth; return 0; } static void correctioportdatawrite(flidev_t dev, unsigned short *Data) { unsigned short data; data = 0; switch(DEVICE->devinfo.hwrev) { case 0x01: data |= (*Data & FLICCD_IO_P0)?0x01:0; data |= (*Data & FLICCD_IO_P1)?0x02:0; data |= (*Data & FLICCD_IO_P2)?0x04:0; data |= (*Data & FLICCD_IO_P3)?0x80:0; break; case 0x02: data |= (*Data & FLICCD_IO_P0)?0x08:0; data |= (*Data & FLICCD_IO_P1)?0x10:0; data |= (*Data & FLICCD_IO_P2)?0x20:0; data |= (*Data & FLICCD_IO_P3)?0x40:0; break; default: break; } *Data = data; return; } static void correctioportdataread(flidev_t dev, unsigned short *Data) { unsigned short data; data = 0; switch (DEVICE->devinfo.hwrev) { case 0x01: data |= (*Data & 0x01)?FLICCD_IO_P0:0; data |= (*Data & 0x02)?FLICCD_IO_P1:0; data |= (*Data & 0x04)?FLICCD_IO_P2:0; data |= (*Data & 0x80)?FLICCD_IO_P3:0; break; case 0x02: data |= (*Data & 0x08)?FLICCD_IO_P0:0; data |= (*Data & 0x10)?FLICCD_IO_P1:0; data |= (*Data & 0x20)?FLICCD_IO_P2:0; data |= (*Data & 0x40)?FLICCD_IO_P3:0; break; default: break; } *Data = data; return; } long fli_camera_parport_read_ioport(flidev_t dev, long *ioportset) { long rlen, wlen; unsigned short buf; rlen = 2; wlen = 2; buf = htons(0x7900); IO(dev, &buf, &wlen, &rlen); *ioportset = ntohs(buf) & 0x00ff; correctioportdataread(dev, (unsigned short *) ioportset); return 0; } long fli_camera_parport_write_ioport(flidev_t dev, long ioportset) { long rlen, wlen; unsigned short buf; correctioportdatawrite(dev, (unsigned short *) &ioportset); buf = htons((unsigned short) (0x7100 | (ioportset & 0x00ff))); rlen = 2; wlen = 2; IO(dev, &buf, &wlen, &rlen); return 0; } long fli_camera_parport_configure_ioport(flidev_t dev, long ioportset) { long rlen, wlen; unsigned short buf; correctioportdatawrite(dev, (unsigned short *) &ioportset); buf = htons((unsigned short) (0x7000 | (ioportset & 0x00ff))); rlen = 2; wlen = 2; IO(dev, &buf, &wlen, &rlen); return 0; } long fli_camera_parport_control_shutter(flidev_t dev, long shutter) { long rlen, wlen; unsigned short buf; rlen = 2; wlen = 2; buf = htons(D_EXPDUR(0)); IO(dev, &buf, &wlen, &rlen); switch (shutter) { case FLI_SHUTTER_CLOSE: debug(FLIDEBUG_INFO, "Closing shutter."); buf = htons(C_SHUTTER(0, 0)); IO(dev, &buf, &wlen, &rlen); break; case FLI_SHUTTER_OPEN: buf = htons(C_SHUTTER(1, 1)); IO(dev, &buf, &wlen, &rlen); break; default: return -EINVAL; } return 0; } libfli1-1.7/libfli-camera.c0000644000175000017500000004726711110507327013363 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #include #include #include #include "libfli-libfli.h" #include "libfli-debug.h" #include "libfli-mem.h" #include "libfli-camera.h" #include "libfli-camera-parport.h" #include "libfli-camera-usb.h" const fliccdinfo_t knowndev[] = { /* id model array_area visible_area */ {1, "KAF-0260C0-2", {{0, 0}, {534, 520}}, {{12, 4}, {524, 516}}, 1.0, 20.0, 20.0}, {2, "KAF-0400C0-2", {{0, 0}, {796, 520}}, {{14, 4}, {782, 516}}, 1.0, 20.0, 20.0}, {3, "KAF-1000C0-2", {{0, 0}, {1042, 1032}}, {{8, 4}, {1032, 1028}}, 1.0, 24.0, 24.0}, {4, "KAF-1300C0-2", {{0, 0}, {1304, 1028}}, {{4, 2}, {1284, 1026}}, 1.0, 20.0, 20.0}, {5, "KAF-1400C0-2", {{0, 0}, {1348, 1037}}, {{14,14}, {782, 526}}, 1.0, 20.0, 20.0}, {6, "KAF-1600C0-2", {{0, 0}, {1564, 1032}}, {{14, 4}, {1550, 1028}}, 1.0, 20.0, 20.0}, {7, "KAF-4200C0-2", {{0, 0}, {2060, 2048}}, {{25, 2}, {2057, 2046}}, 1.0, 20.0, 20.0}, {8, "SITe-502S", {{0, 0}, {527, 512}}, {{15, 0}, {527, 512}}, 1.0, 20.0, 20.0}, {9, "TK-1024", {{0, 0}, {1124, 1024}}, {{50, 0}, {1074, 1024}}, 1.0, 24.0, 24.0}, {10, "TK-512", {{0, 0}, {563, 512}}, {{51, 0}, {563, 512}}, 1.0, 24.0, 24.0}, {11, "SI-003A", {{0, 0}, {1056, 1024}}, {{16, 0}, {1040, 1024}}, 1.0, 24.0, 24.0}, // {11, "SI-003A", {{0, 0}, {1120, 1024}}, {{0, 0}, {1120, 1024}}, 1.0, 24.0, 24.0}, {12, "KAF-6300", {{0, 0}, {3100, 2056}}, {{16, 4}, {3088, 2052}}, 1.0, 9.0, 9.0}, {13, "KAF-3200", {{0, 0}, {2267, 1510}}, {{46,34}, {2230, 1506}}, 1.0, 6.8, 6.8}, {14, "SI424A", {{0, 0}, {2088, 2049}}, {{20, 0}, {2068, 2049}}, 1.0, 6.8, 6.8}, {15, "CCD47-10", {{0, 0}, {1072, 1027}}, {{8, 0}, {1064, 1027}}, 0.0, 0.0, 0.0}, {16, "CCD77", {{0, 0}, {527, 512}}, {{15, 0}, {527, 512}}, 0.0, 0.0, 0.0}, {17, "CCD42-40", {{0, 0}, {2148, 2048}}, {{50, 0}, {2098, 2048}}, 1.0, 13.5, 13.5}, {18, "KAF-4300", {{0, 0}, {2102, 2092}}, {{8, 4}, {2092, 2088}}, 1.0, 24.0, 24.0}, {19, "KAF-16801", {{0, 0}, {4145, 4128}}, {{44,29}, {4124, 4109}}, 1.0, 9.0, 9.0}, {0, "Unknown Model", {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, 0.0, 0.0, 0.0} }; /* Common camera routines */ static long fli_camera_get_pixel_size(flidev_t dev, double *pixel_x, double *pixel_y); #define fli_camera_parport_get_pixel_size fli_camera_get_pixel_size #define fli_camera_usb_get_pixel_size fli_camera_get_pixel_size static long fli_camera_set_frame_type(flidev_t dev, fliframe_t frametype); #define fli_camera_parport_set_frame_type fli_camera_set_frame_type #define fli_camera_usb_set_frame_type fli_camera_set_frame_type static long fli_camera_set_flushes(flidev_t dev, long nflushes); #define fli_camera_parport_set_flushes fli_camera_set_flushes #define fli_camera_usb_set_flushes fli_camera_set_flushes long fli_camera_open(flidev_t dev) { int r; CHKDEVICE(dev); if ((DEVICE->device_data = xcalloc(1, sizeof(flicamdata_t))) == NULL) return -ENOMEM; // load_camera_defaults(); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_open(dev); break; case FLIDOMAIN_USB: r = fli_camera_usb_open(dev); break; default: r = -EINVAL; } if (r) { xfree(DEVICE->device_data); DEVICE->device_data = NULL; } return r; } long fli_camera_close(flidev_t dev) { flicamdata_t *cam; CHKDEVICE(dev); cam = DEVICE->device_data; if (cam->gbuf != NULL) { xfree(cam->gbuf); cam->gbuf = NULL; } if (DEVICE->devinfo.model != NULL) { xfree(DEVICE->devinfo.model); DEVICE->devinfo.model = NULL; } if (DEVICE->devinfo.devnam != NULL) { xfree(DEVICE->devinfo.devnam); DEVICE->devinfo.devnam = NULL; } if (DEVICE->device_data != NULL) { xfree(DEVICE->device_data); DEVICE->device_data = NULL; } return 0; } long fli_camera_command(flidev_t dev, int cmd, int argc, ...) { long r = 0; va_list ap; va_start(ap, argc); CHKDEVICE(dev); switch (cmd) { case FLI_GET_PIXEL_SIZE: if (argc != 2) r = -EINVAL; else { double *pixel_x, *pixel_y; pixel_x = va_arg(ap, double *); pixel_y = va_arg(ap, double *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_get_pixel_size(dev, pixel_x, pixel_y); break; case FLIDOMAIN_USB: r = fli_camera_usb_get_pixel_size(dev, pixel_x, pixel_y); break; default: r = -EINVAL; } } break; case FLI_GET_ARRAY_AREA: if (argc != 4) r = -EINVAL; else { long *ul_x, *ul_y, *lr_x, *lr_y; ul_x = va_arg(ap, long *); ul_y = va_arg(ap, long *); lr_x = va_arg(ap, long *); lr_y = va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_get_array_area(dev, ul_x, ul_y, lr_x, lr_y); break; case FLIDOMAIN_USB: r = fli_camera_usb_get_array_area(dev, ul_x, ul_y, lr_x, lr_y); break; default: r = -EINVAL; } } break; case FLI_GET_VISIBLE_AREA: if (argc != 4) r = -EINVAL; else { long *ul_x, *ul_y, *lr_x, *lr_y; ul_x = va_arg(ap, long *); ul_y = va_arg(ap, long *); lr_x = va_arg(ap, long *); lr_y = va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_get_visible_area(dev, ul_x, ul_y, lr_x, lr_y); break; case FLIDOMAIN_USB: r = fli_camera_usb_get_visible_area(dev, ul_x, ul_y, lr_x, lr_y); break; default: r = -EINVAL; } } break; case FLI_SET_EXPOSURE_TIME: if (argc != 1) r = -EINVAL; else { long exptime; exptime = *va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_set_exposure_time(dev, exptime); break; case FLIDOMAIN_USB: r = fli_camera_usb_set_exposure_time(dev, exptime); break; default: r = -EINVAL; } } break; case FLI_SET_IMAGE_AREA: if (argc != 4) r = -EINVAL; else { long ul_x, ul_y, lr_x, lr_y; ul_x = *va_arg(ap, long *); ul_y = *va_arg(ap, long *); lr_x = *va_arg(ap, long *); lr_y = *va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_set_image_area(dev, ul_x, ul_y, lr_x, lr_y); break; case FLIDOMAIN_USB: r = fli_camera_usb_set_image_area(dev, ul_x, ul_y, lr_x, lr_y); break; default: r = -EINVAL; } } break; case FLI_SET_HBIN: if (argc != 1) r = -EINVAL; else { long hbin; hbin = *va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_set_hbin(dev, hbin); break; case FLIDOMAIN_USB: r = fli_camera_usb_set_hbin(dev, hbin); break; default: r = -EINVAL; } } break; case FLI_SET_VBIN: if (argc != 1) r = -EINVAL; else { long vbin; vbin = *va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_set_vbin(dev, vbin); break; case FLIDOMAIN_USB: r = fli_camera_usb_set_vbin(dev, vbin); break; default: r = -EINVAL; } } break; case FLI_SET_FRAME_TYPE: if (argc != 1) r = -EINVAL; else { long frametype; frametype = *va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_set_frame_type(dev, frametype); break; case FLIDOMAIN_USB: r = fli_camera_usb_set_frame_type(dev, frametype); break; default: r = -EINVAL; } } break; case FLI_CANCEL_EXPOSURE: if (argc != 0) r = -EINVAL; else { flicamdata_t *cam; cam = DEVICE->device_data; cam->grabrowcount = 1; cam->grabrowcounttot = cam->grabrowcount; cam->grabrowindex = 0; cam->grabrowbatchsize = 1; cam->grabrowbufferindex = cam->grabrowcount; cam->flushcountbeforefirstrow = 0; cam->flushcountafterlastrow = 0; switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = DEVICE->fli_command(dev, FLI_CONTROL_SHUTTER, (long) FLI_SHUTTER_CLOSE); break; case FLIDOMAIN_USB: r = fli_camera_usb_cancel_exposure(dev); break; default: r = -EINVAL; } } break; case FLI_GET_EXPOSURE_STATUS: if (argc != 1) r = -EINVAL; else { long *timeleft; timeleft = va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_get_exposure_status(dev, timeleft); break; case FLIDOMAIN_USB: r = fli_camera_usb_get_exposure_status(dev, timeleft); break; default: r = -EINVAL; } } break; case FLI_SET_TEMPERATURE: if (argc != 1) r = -EINVAL; else { double temperature; temperature = *va_arg(ap, double *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_set_temperature(dev, temperature); break; case FLIDOMAIN_USB: r = fli_camera_usb_set_temperature(dev, temperature); break; default: r = -EINVAL; } } break; case FLI_READ_TEMPERATURE: if (argc != 2) r = -EINVAL; else { double *temperature; flichannel_t channel; channel = va_arg(ap, flichannel_t); temperature = va_arg(ap, double *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_get_temperature(dev, temperature); break; case FLIDOMAIN_USB: r = fli_camera_usb_read_temperature(dev, channel, temperature); break; default: r = -EINVAL; } } break; case FLI_GET_TEMPERATURE: if (argc != 1) r = -EINVAL; else { double *temperature; temperature = va_arg(ap, double *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_get_temperature(dev, temperature); break; case FLIDOMAIN_USB: r = fli_camera_usb_get_temperature(dev, temperature); break; default: r = -EINVAL; } } break; case FLI_GRAB_ROW: if (argc != 2) r = -EINVAL; else { void *buf; size_t width; buf = va_arg(ap, void *); width = *va_arg(ap, size_t *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_grab_row(dev, buf, width); break; case FLIDOMAIN_USB: r = fli_camera_usb_grab_row(dev, buf, width); break; default: r = -EINVAL; } } break; case FLI_EXPOSE_FRAME: if (argc != 0) r = -EINVAL; else { switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_expose_frame(dev); break; case FLIDOMAIN_USB: r = fli_camera_usb_expose_frame(dev); break; default: r = -EINVAL; } } break; case FLI_FLUSH_ROWS: if (argc != 2) r = -EINVAL; else { long rows, repeat; rows = *va_arg(ap, long *); repeat = *va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_flush_rows(dev, rows, repeat); break; case FLIDOMAIN_USB: r = fli_camera_usb_flush_rows(dev, rows, repeat); break; default: r = -EINVAL; } } break; case FLI_SET_FLUSHES: if (argc != 1) r = -EINVAL; else { long nflushes; nflushes = *va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_set_flushes(dev, nflushes); break; case FLIDOMAIN_USB: r = fli_camera_usb_set_flushes(dev, nflushes); break; default: r = -EINVAL; } } break; case FLI_SET_BIT_DEPTH: if (argc != 1) r = -EINVAL; else { flibitdepth_t bitdepth; bitdepth = *va_arg(ap, flibitdepth_t *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_set_bit_depth(dev, bitdepth); break; case FLIDOMAIN_USB: r = fli_camera_usb_set_bit_depth(dev, bitdepth); break; default: r = -EINVAL; } } break; case FLI_READ_IOPORT: if (argc != 1) r = -EINVAL; else { long *ioportset; ioportset = va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_read_ioport(dev, ioportset); break; case FLIDOMAIN_USB: r = fli_camera_usb_read_ioport(dev, ioportset); break; default: r = -EINVAL; } } break; case FLI_WRITE_IOPORT: if (argc != 1) r = -EINVAL; else { long ioportset; ioportset = *va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_write_ioport(dev, ioportset); break; case FLIDOMAIN_USB: r = fli_camera_usb_write_ioport(dev, ioportset); break; default: r = -EINVAL; } } break; case FLI_CONFIGURE_IOPORT: if (argc != 1) r = -EINVAL; else { long ioportset; ioportset = *va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_configure_ioport(dev, ioportset); break; case FLIDOMAIN_USB: r = fli_camera_usb_configure_ioport(dev, ioportset); break; default: r = -EINVAL; } } break; case FLI_CONTROL_SHUTTER: if (argc != 1) r = -EINVAL; else { long shutter; flicamdata_t *cam; cam = DEVICE->device_data; shutter = *va_arg(ap, long *); if( (shutter == FLI_SHUTTER_EXTERNAL_TRIGGER_LOW) || (shutter == FLI_SHUTTER_EXTERNAL_TRIGGER_HIGH) ) { debug(FLIDEBUG_INFO, "External trigger."); cam->exttrigger = 1; cam->exttriggerpol = (shutter == FLI_SHUTTER_EXTERNAL_TRIGGER_LOW)?0:1; r = 0; } else { debug(FLIDEBUG_INFO, "No External trigger.\n"); cam->exttrigger = 0; switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_control_shutter(dev, shutter); break; case FLIDOMAIN_USB: r = fli_camera_usb_control_shutter(dev, shutter); break; default: r = -EINVAL; } } } break; case FLI_CONTROL_BGFLUSH: if (argc != 1) r = -EINVAL; else { long bgflush; flicamdata_t *cam; cam = DEVICE->device_data; bgflush = *va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = -EFAULT; break; case FLIDOMAIN_USB: r = fli_camera_usb_control_bgflush(dev, bgflush); break; default: r = -EINVAL; } } break; case FLI_GET_COOLER_POWER: if (argc != 1) r = -EINVAL; else { double *cooler_power; cooler_power = va_arg(ap, double *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = -EFAULT; break; case FLIDOMAIN_USB: r = fli_camera_usb_get_cooler_power(dev, cooler_power); break; default: r = -EINVAL; } } break; case FLI_GET_STATUS: if (argc != 1) r = -EINVAL; else { long *camera_status; camera_status = va_arg(ap, long *); *camera_status = 0xffffffff; switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = 0; break; case FLIDOMAIN_USB: r = fli_camera_usb_get_camera_status(dev, camera_status); break; default: r = -EINVAL; } } break; case FLI_GET_CAMERA_MODE: if (argc != 1) r = -EINVAL; else { flimode_t *camera_mode; camera_mode = va_arg(ap, flimode_t *); *camera_mode = 0; switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = 0; break; case FLIDOMAIN_USB: r = fli_camera_usb_get_camera_mode(dev, camera_mode); break; default: r = -EINVAL; } } break; case FLI_SET_CAMERA_MODE: if (argc != 1) r = -EINVAL; else { flimode_t camera_mode; camera_mode = va_arg(ap, flimode_t); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = 0; break; case FLIDOMAIN_USB: r = fli_camera_usb_set_camera_mode(dev, camera_mode); break; default: r = -EINVAL; } } break; case FLI_GET_CAMERA_MODE_STRING: if (argc != 3) r = -EINVAL; else { flimode_t camera_mode; char *buf; size_t len; camera_mode = va_arg(ap, flimode_t); buf = va_arg(ap, char *); len = va_arg(ap, size_t); memset(buf, '\0', len); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: if (camera_mode == 0) { r = 0; strncpy(buf, "Default Mode", len - 1); } else { r = -EINVAL; } break; case FLIDOMAIN_USB: r = fli_camera_usb_get_camera_mode_string(dev, camera_mode, buf, len); break; default: r = -EINVAL; } } break; default: r = -EINVAL; } va_end(ap); return r; } static long fli_camera_get_pixel_size(flidev_t dev, double *pixel_x, double *pixel_y) { flicamdata_t *cam; cam = DEVICE->device_data; *pixel_x = (double)cam->ccd.pixelwidth; *pixel_y = (double)cam->ccd.pixelheight; return 0; } static long fli_camera_set_frame_type(flidev_t dev, fliframe_t frametype) { flicamdata_t *cam; cam = DEVICE->device_data; if ((frametype < FLI_FRAME_TYPE_NORMAL) || (frametype > FLI_FRAME_TYPE_DARK)) return -EINVAL; cam->frametype = frametype; return 0; } static long fli_camera_set_flushes(flidev_t dev, long nflushes) { flicamdata_t *cam; cam = DEVICE->device_data; if((nflushes < 0) || (nflushes > 16)) return -EINVAL; cam->flushes = nflushes; return 0; } libfli1-1.7/libfli.dxx0000644000175000017500000000244411110507327012502 0ustar jrjr/* -*- mode: c; -*- */ /** @name FLI Software Development Library @version 1.40 @author \URL[Finger Lakes Instrumentation]{http://www.fli-cam.com} \\ Copyright (c) 2000-2002 Finger Lakes Instrumentation (FLI), LLC. \\ All rights reserved. @memo Windows and Linux support for FLI CCD cameras, filter wheels, and focusers. */ //@{ /** @name Introduction This library provides a core set of functions for programming FLI CCD cameras, filter wheels, and focusers under Windows and Linux. The type definitions, function prototypes, and definitions/enumerations of constant values used by library functions are spcified in \texttt{libfli.h}. All library functions return zero on sucessful completion, and non-zero if an error occurred. The exact nature of an error can be found by treating the negative of a function's return value as a system error code, for example: \begin{verbatim} if ((err = FLIOpen(&dev, name, domain))) { fprintf(stderr, "Error FLIOpen: %s\n", strerror((int)-err)); exit(1); } \end{verbatim} */ /** @name Library Defined Types */ //@{ //@Include: libfli.h //@} /** @name Library Functions */ //@{ //@Include: libfli.c //@} //@} libfli1-1.7/libfli-serial.h0000644000175000017500000000371311110507327013403 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifndef _LIBFLI_SERIAL_H_ #define _LIBFLI_SERIAL_H_ #define BAUDRATE B1200 long unix_serialio(flidev_t dev, void *buf, long *wlen, long *rlen); #endif /* _LIBFLI_SERIAL_H_ */ libfli1-1.7/libfli-parport.c0000644000175000017500000000647611110507327013617 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #include #include #include #include #include "libfli-libfli.h" #include "libfli-debug.h" #include "libfli-camera.h" #include "fli_ioctl.h" long unix_parportio_linux(flidev_t dev, void *buf, long *wlen, long *rlen) { fli_unixio_t *io; flicamdata_t *cam; int err = 0, locked = 0; long org_wlen = *wlen, org_rlen = *rlen; int wto, rto, dto; io = DEVICE->io_data; cam = DEVICE->device_data; if ((err = unix_fli_lock(dev))) { debug(FLIDEBUG_WARN, "Lock failed"); goto done; } locked = 1; /* Convert timeout to jiffies */ wto = cam->writeto / 1000 * HZ; rto = cam->readto / 1000 * HZ; dto = cam->dirto / 1000 * HZ; if (ioctl(io->fd, FLI_SET_WTO, &wto)) { err = -errno; goto done; } if (ioctl(io->fd, FLI_SET_DTO, &dto)) { err = -errno; goto done; } if (ioctl(io->fd, FLI_SET_RTO, &rto)) { err = -errno; goto done; } if (*wlen > 0) { if ((*wlen = write(io->fd, buf, *wlen)) != org_wlen) { debug(FLIDEBUG_WARN, "write failed, only %d of %d bytes written", *wlen, org_wlen); err = -errno; goto done; } } if (*rlen > 0) { if ((*rlen = read(io->fd, buf, *rlen)) != org_rlen) { debug(FLIDEBUG_WARN, "read failed, only %d of %d bytes read", *rlen, org_rlen); err = -errno; goto done; } } done: if (locked) { int r; if ((r = unix_fli_unlock(dev))) debug(FLIDEBUG_WARN, "Unlock failed"); if (err == 0) err = r; } return err; } libfli1-1.7/libfli-mem.h0000644000175000017500000000432411110507327012701 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifndef _LIBFLI_MEM_H_ #define _LIBFLI_MEM_H_ void *xmalloc(size_t size); void *xcalloc(size_t nmemb, size_t size); #ifdef __linux__ void *xmemalign(size_t alignment, size_t size); #endif /* __linux__ */ void xfree(void *ptr); void *xrealloc(void *ptr, size_t size); int xfree_all(void); char *xstrdup(const char *s); int xasprintf(char **strp, const char *fmt, ...); char *xstrndup(const char *s, size_t siz); #endif /* _LIBFLI_MEM_H_ */ libfli1-1.7/libfli-debug.h0000644000175000017500000000400711110507327013207 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifndef _LIBFLI_DEBUG_H_ #define _LIBFLI_DEBUG_H_ /* Debug functions */ int debugclose(void); int debugopen(char *host); void debug(int level, char *format, ...); void setdebuglevel(char *host, int level); #endif /* _LIBFLI_DEBUG_H_ */ libfli1-1.7/libfli-camera-usb.c0000644000175000017500000013066211110507327014142 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifdef WIN32 #include #else #include #include #include #endif #include #include #include #include #include "libfli-libfli.h" #include "libfli-debug.h" #include "libfli-mem.h" #include "libfli-camera.h" #include "libfli-camera-usb.h" #include "libfli-usb.h" /* These routines are defined because everyone wants to change the size of long... * and we will now make everything BYTE aligned and the proper byte order */ #define MSW(x) (unsigned short) ((x >> 16) & 0xffff) #define LSW(x) (unsigned short) (x & 0xffff) #define MSB(x) (unsigned char) ((x >> 8) & 0xff) #define LSB(x) (unsigned char) (x & 0xff) #define IOBUF_MAX_SIZ (64) typedef unsigned char iobuf_t; #define IOREAD_U8(b, i, y) { y = *(b + i); } #define IOREAD_U16(b, i, y) { y = (*(b + i) << 8) | *(b + i + 1); } #define IOREAD_U32(b, i, y) { y = (*(b + i) << 24) | *(b + i + 1) << 16 | \ *(b + i + 2) << 8 | *(b + i + 3); } #define IOWRITE_U8(b, i, y) { *(b + i) = (unsigned char) y; } #define IOWRITE_U16(b, i, y) { *(b + i) = MSB(y); *(b + i + 1) = LSB(y); } #define IOWRITE_U32(b, i, y) { *(b + i) = MSB(MSW(y)); *(b + i + 1) = LSB(MSW(y)); \ *(b + i + 2) = MSB(LSW(y)); *(b + i + 3) = LSB(LSW(y)); } #define IOREAD_LF(b, i, y) { y = dconvert(b + i); } double dconvert(void *buf) { unsigned char *fnum = (unsigned char *) buf; double sign, exponent, mantissa, result; sign = (double) ((fnum[3] & 0x80)?(-1):(1)); exponent = (double) ((fnum[3] & 0x7f) << 1 | ((fnum[2] & 0x80)?1:0)); mantissa = 1.0 + ((double) ((fnum[2] & 0x7f) << 16 | fnum[1] << 8 | fnum[0]) / pow(2, 23)); result = sign * (double) pow(2, (exponent - 127.0)) * mantissa; return result; } long fli_camera_usb_open(flidev_t dev) { flicamdata_t *cam; iobuf_t buf[IOBUF_MAX_SIZ]; long rlen, wlen; // long r = 0; cam = DEVICE->device_data; #ifdef __linux__ /* Linux needs this page aligned, hopefully this is 512 byte aligned too... */ cam->max_usb_xfer = (USB_READ_SIZ_MAX / getpagesize()) * getpagesize(); cam->gbuf_siz = 2 * cam->max_usb_xfer; if ((cam->gbuf = xmemalign(getpagesize(), cam->gbuf_siz)) == NULL) return -ENOMEM; #else /* Just 512 byte align it... */ cam->max_usb_xfer = (USB_READ_SIZ_MAX & 0xfffffe00); cam->gbuf_siz = 2 * cam->max_usb_xfer; if ((cam->gbuf = xmalloc(cam->gbuf_siz)) == NULL) return -ENOMEM; #endif switch (DEVICE->devinfo.devid) { /* MaxCam and IMG cameras */ case FLIUSB_CAM_ID: { short camtype; IOWRITE_U16(buf, 0, FLI_USBCAM_HARDWAREREV); rlen = 2; wlen = 2; IO(dev, buf, &wlen, &rlen); IOREAD_U16(buf, 0, DEVICE->devinfo.hwrev); IOWRITE_U16(buf, 0, FLI_USBCAM_DEVICEID); rlen = 2; wlen = 2; IO(dev, buf, &wlen, &rlen); IOREAD_U16(buf, 0, camtype); IOWRITE_U16(buf, 0, FLI_USBCAM_SERIALNUM); rlen = 2; wlen = 2; IO(dev, buf, &wlen, &rlen); IOREAD_U16(buf, 0, DEVICE->devinfo.serno); /* The following devices need information downloaded to them */ if (DEVICE->devinfo.fwrev < 0x0201) { int id; for (id = 0; knowndev[id].index != 0; id++) if (knowndev[id].index == camtype) break; if (knowndev[id].index == 0) return -ENODEV; cam->ccd.pixelwidth = knowndev[id].pixelwidth; cam->ccd.pixelheight = knowndev[id].pixelheight; wlen = 14; rlen = 0; IOWRITE_U16(buf, 0, FLI_USBCAM_DEVINIT); IOWRITE_U16(buf, 2, (unsigned short) knowndev[id].array_area.lr.x); IOWRITE_U16(buf, 4, (unsigned short) knowndev[id].array_area.lr.y); IOWRITE_U16(buf, 6, (unsigned short) (knowndev[id].visible_area.lr.x - knowndev[id].visible_area.ul.x)); IOWRITE_U16(buf, 8, (unsigned short) (knowndev[id].visible_area.lr.y - knowndev[id].visible_area.ul.y)); IOWRITE_U16(buf, 10, (unsigned short) knowndev[id].visible_area.ul.x); IOWRITE_U16(buf, 12, (unsigned short) knowndev[id].visible_area.ul.y); IO(dev, buf, &wlen, &rlen); DEVICE->devinfo.model = xstrndup(knowndev[id].model, 32); switch(DEVICE->devinfo.fwrev & 0xff00) { case 0x0100: cam->tempslope = (70.0 / 215.75); cam->tempintercept = (-52.5681); break; case 0x0200: cam->tempslope = (100.0 / 201.1); cam->tempintercept = (-61.613); break; default: cam->tempslope = 1e-12; cam->tempintercept = 0; } } /* Here, all the parameters are stored on the camera */ else if (DEVICE->devinfo.fwrev >= 0x0201) { rlen = 64; wlen = 2; IOWRITE_U16(buf, 0, FLI_USBCAM_READPARAMBLOCK); IO(dev, buf, &wlen, &rlen); IOREAD_LF(buf, 31, cam->ccd.pixelwidth); IOREAD_LF(buf, 35, cam->ccd.pixelheight); IOREAD_LF(buf, 23, cam->tempslope); IOREAD_LF(buf, 27, cam->tempintercept); } rlen = 32; wlen = 2; IOWRITE_U16(buf, 0, FLI_USBCAM_DEVICENAME); IO(dev, buf, &wlen, &rlen); DEVICE->devinfo.devnam = xstrndup((char *) buf, 32); if(DEVICE->devinfo.model == NULL) { DEVICE->devinfo.model = xstrndup(DEVICE->devinfo.devnam, 32); } rlen = 4; wlen = 2; IOWRITE_U16(buf, 0, FLI_USBCAM_ARRAYSIZE); IO(dev, buf, &wlen, &rlen); cam->ccd.array_area.ul.x = 0; cam->ccd.array_area.ul.y = 0; IOREAD_U16(buf, 0, cam->ccd.array_area.lr.x); IOREAD_U16(buf, 2, cam->ccd.array_area.lr.y); rlen = 4; wlen = 2; IOWRITE_U16(buf, 0, FLI_USBCAM_IMAGEOFFSET); IO(dev, buf, &wlen, &rlen); IOREAD_U16(buf, 0, cam->ccd.visible_area.ul.x); IOREAD_U16(buf, 2, cam->ccd.visible_area.ul.y); rlen = 4; wlen = 2; IOWRITE_U16(buf, 0, FLI_USBCAM_IMAGESIZE); IO(dev, buf, &wlen, &rlen); IOREAD_U16(buf, 0, cam->ccd.visible_area.lr.x); cam->ccd.visible_area.lr.x += cam->ccd.visible_area.ul.x; IOREAD_U16(buf, 2, cam->ccd.visible_area.lr.y); cam->ccd.visible_area.lr.y += cam->ccd.visible_area.ul.y; #ifdef WIN32 /* Check the registry to determine if we are overriding any settings */ { HKEY hKey; DWORD overscan_x = 0, overscan_y = 0; DWORD whole_array = 0; DWORD len; if (RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Finger Lakes Instrumentation\\libfli", &hKey) == ERROR_SUCCESS) { /* Check for overscan data */ len = sizeof(DWORD); if (RegQueryValueEx(hKey, "overscan_x", NULL, NULL, (LPBYTE) &overscan_x, &len) == ERROR_SUCCESS) { debug(FLIDEBUG_INFO, "Found a request for horizontal overscan of %d pixels.", overscan_x); } len = sizeof(DWORD); if (RegQueryValueEx(hKey, "overscan_y", NULL, NULL, (LPBYTE) &overscan_y, &len) == ERROR_SUCCESS) { debug(FLIDEBUG_INFO, "Found a request for vertical overscan of %d pixels.", overscan_y); } len = sizeof(DWORD); RegQueryValueEx(hKey, "whole_array", NULL, NULL, (LPBYTE) &whole_array, &len); cam->ccd.array_area.ul.x = 0; cam->ccd.array_area.ul.y = 0; cam->ccd.array_area.lr.x += overscan_x; cam->ccd.array_area.lr.y += overscan_y; if (whole_array == 0) { cam->ccd.visible_area.lr.x += overscan_x; cam->ccd.visible_area.lr.y += overscan_y; } else { cam->ccd.visible_area.ul.x = 0; cam->ccd.visible_area.ul.y = 0; cam->ccd.visible_area.lr.x = cam->ccd.array_area.lr.x; cam->ccd.visible_area.lr.y = cam->ccd.array_area.lr.y; } RegCloseKey(hKey); } else { debug(FLIDEBUG_INFO, "Could not find registry key."); } } #endif /* Initialize all variables to something */ cam->vflushbin = 4; cam->hflushbin = 4; cam->vbin = 1; cam->hbin = 1; cam->image_area.ul.x = cam->ccd.visible_area.ul.x; cam->image_area.ul.y = cam->ccd.visible_area.ul.y; cam->image_area.lr.x = cam->ccd.visible_area.lr.x; cam->image_area.lr.y = cam->ccd.visible_area.lr.y; cam->exposure = 100; cam->frametype = FLI_FRAME_TYPE_NORMAL; cam->flushes = 0; cam->bitdepth = FLI_MODE_16BIT; cam->exttrigger = 0; cam->exttriggerpol = 0; cam->background_flush = 1; cam->grabrowwidth = (cam->image_area.lr.x - cam->image_area.ul.x) / cam->hbin; cam->grabrowcount = 1; cam->grabrowcounttot = cam->grabrowcount; cam->grabrowindex = 0; cam->grabrowbatchsize = 1; cam->grabrowbufferindex = cam->grabrowcount; cam->flushcountbeforefirstrow = 0; cam->flushcountafterlastrow = 0; #ifdef _SETUPDEFAULTS /* Now to set up the camera defaults */ rlen = 0; wlen = 6; IOWRITE_U16(buf, 0, FLI_USBCAM_SETFRAMEOFFSET); IOWRITE_U16(buf, 2, cam->image_area.ul.x); IOWRITE_U16(buf, 4, cam->image_area.ul.y); IO(dev, buf, &wlen, &rlen); rlen = 0; wlen = 6; IOWRITE_U16(buf, 0, FLI_USBCAM_SETBINFACTORS); IOWRITE_U16(buf, 2, cam->hbin); IOWRITE_U16(buf, 4, cam->vbin); IO(dev, buf, &wlen, &rlen); rlen = 0; wlen = 6; IOWRITE_U16(buf, 0, FLI_USBCAM_SETFLUSHBINFACTORS); IOWRITE_U16(buf, 2, cam->hflushbin); IOWRITE_U16(buf, 4, cam->vflushbin); IO(dev, buf, &wlen, &rlen); #endif } break; /* Proline Camera */ case FLIUSB_PROLINE_ID: { /* Let's get information about the hardware */ wlen = 2; rlen = 6; IOWRITE_U16(buf, 0, PROLINE_GET_HARDWAREINFO); IO(dev, buf, &wlen, &rlen); IOREAD_U16(buf, 0, DEVICE->devinfo.hwrev); IOREAD_U16(buf, 2, DEVICE->devinfo.serno); IOREAD_U16(buf, 4, rlen); /* Configuration data from ProLine is little endian, I can't believe * that I did this oh well, I'll deal with it! */ if (DEVICE->devinfo.hwrev >= 0x0100) { wlen = 2; IOWRITE_U16(buf, 0, PROLINE_GET_CAMERAINFO); IO(dev, buf, &wlen, &rlen); cam->ccd.array_area.ul.x = 0; cam->ccd.array_area.ul.y = 0; cam->ccd.array_area.lr.x = (buf[1] << 8) + buf[0]; cam->ccd.array_area.lr.y = (buf[3] << 8) + buf[2]; cam->ccd.visible_area.ul.x = (buf[9] << 8) + buf[8]; cam->ccd.visible_area.ul.y = (buf[11] << 8) + buf[10]; cam->ccd.visible_area.lr.x = (buf[5] << 8) + buf[4] + cam->ccd.visible_area.ul.x; cam->ccd.visible_area.lr.y = (buf[7] << 8) + buf[6] + cam->ccd.visible_area.ul.y; cam->ccd.pixelwidth = dconvert(&buf[12]); cam->ccd.pixelheight = dconvert(&buf[16]); rlen = 64; wlen = 2; IOWRITE_U16(buf, 0, PROLINE_GET_DEVICESTRINGS); IO(dev, buf, &wlen, &rlen); DEVICE->devinfo.devnam = xstrndup((char *) &buf[0], 32); DEVICE->devinfo.model = xstrndup((char *) &buf[32], 32); } /* Initialize all varaibles to something */ cam->vflushbin = 0; cam->hflushbin = 0; cam->vbin = 1; cam->hbin = 1; cam->image_area.ul.x = cam->ccd.visible_area.ul.x; cam->image_area.ul.y = cam->ccd.visible_area.ul.y; cam->image_area.lr.x = cam->ccd.visible_area.lr.x; cam->image_area.lr.y = cam->ccd.visible_area.lr.y; cam->exposure = 100; cam->frametype = FLI_FRAME_TYPE_NORMAL; cam->flushes = 0; cam->bitdepth = FLI_MODE_16BIT; cam->exttrigger = 0; cam->exttriggerpol = 0; cam->background_flush = 1; cam->tempslope = 1.0; cam->tempintercept = 0.0; cam->grabrowwidth = (cam->image_area.lr.x - cam->image_area.ul.x) / cam->hbin; cam->grabrowcount = 1; cam->grabrowcounttot = cam->grabrowcount; cam->grabrowindex = 0; cam->grabrowbatchsize = 1; cam->grabrowbufferindex = cam->grabrowcount; cam->flushcountbeforefirstrow = 0; cam->flushcountafterlastrow = 0; /* Now to set up the camera defaults */ } break; default: return -ENODEV; } debug(FLIDEBUG_INFO, "DeviceID %d", DEVICE->devinfo.devid); debug(FLIDEBUG_INFO, "SerialNum %d", DEVICE->devinfo.serno); debug(FLIDEBUG_INFO, "HWRev %d", DEVICE->devinfo.hwrev); debug(FLIDEBUG_INFO, "FWRev %d", DEVICE->devinfo.fwrev); debug(FLIDEBUG_INFO, " Name: %s", DEVICE->devinfo.devnam); debug(FLIDEBUG_INFO, " Array: (%4d,%4d),(%4d,%4d)", cam->ccd.array_area.ul.x, cam->ccd.array_area.ul.y, cam->ccd.array_area.lr.x, cam->ccd.array_area.lr.y); debug(FLIDEBUG_INFO, " Visible: (%4d,%4d),(%4d,%4d)", cam->ccd.visible_area.ul.x, cam->ccd.visible_area.ul.y, cam->ccd.visible_area.lr.x, cam->ccd.visible_area.lr.y); debug(FLIDEBUG_INFO, " Pix Size: (%g, %g)", cam->ccd.pixelwidth, cam->ccd.pixelheight); debug(FLIDEBUG_INFO, " Temp.: T = AD x %g + %g", cam->tempslope, cam->tempintercept); return 0; } long fli_camera_usb_get_array_area(flidev_t dev, long *ul_x, long *ul_y, long *lr_x, long *lr_y) { flicamdata_t *cam = DEVICE->device_data; switch (DEVICE->devinfo.devid) { /* MaxCam and IMG cameras */ case FLIUSB_CAM_ID: { } break; /* Proline Camera */ case FLIUSB_PROLINE_ID: { } break; default: debug(FLIDEBUG_WARN, "Hmmm, shouldn't be here, operation on NO camera..."); break; } *ul_x = cam->ccd.array_area.ul.x; *ul_y = cam->ccd.array_area.ul.y; *lr_x = cam->ccd.array_area.lr.x; *lr_y = cam->ccd.array_area.lr.y; return 0; } long fli_camera_usb_get_visible_area(flidev_t dev, long *ul_x, long *ul_y, long *lr_x, long *lr_y) { flicamdata_t *cam = DEVICE->device_data; switch (DEVICE->devinfo.devid) { /* MaxCam and IMG cameras */ case FLIUSB_CAM_ID: { } break; /* Proline Camera */ case FLIUSB_PROLINE_ID: { } break; default: debug(FLIDEBUG_WARN, "Hmmm, shouldn't be here, operation on NO camera..."); break; } *ul_x = cam->ccd.visible_area.ul.x; *ul_y = cam->ccd.visible_area.ul.y; *lr_x = cam->ccd.visible_area.lr.x; *lr_y = cam->ccd.visible_area.lr.y; return 0; } long fli_camera_usb_set_exposure_time(flidev_t dev, long exptime) { flicamdata_t *cam = DEVICE->device_data; if (exptime < 0) return -EINVAL; switch (DEVICE->devinfo.devid) { /* MaxCam and IMG cameras */ case FLIUSB_CAM_ID: { long rlen, wlen; iobuf_t buf[8]; rlen = 0; wlen = 8; IOWRITE_U16(buf, 0, FLI_USBCAM_SETEXPOSURE); IOWRITE_U32(buf, 4, exptime); IO(dev, buf, &wlen, &rlen); } break; /* Proline Camera */ case FLIUSB_PROLINE_ID: { } break; default: debug(FLIDEBUG_WARN, "Hmmm, shouldn't be here, operation on NO camera..."); break; } cam->exposure = exptime; return 0; } long fli_camera_usb_set_image_area(flidev_t dev, long ul_x, long ul_y, long lr_x, long lr_y) { flicamdata_t *cam = DEVICE->device_data; int r = 0; if( (DEVICE->devinfo.fwrev < 0x0300) && ((DEVICE->devinfo.hwrev & 0xff00) == 0x0100) && (DEVICE->devinfo.devid != FLIUSB_PROLINE_ID)) { if( (lr_x > (cam->ccd.visible_area.lr.x * cam->hbin)) || (lr_y > (cam->ccd.visible_area.lr.y * cam->vbin)) ) { debug(FLIDEBUG_WARN, "FLISetImageArea(), area out of bounds: (%4d,%4d),(%4d,%4d)", ul_x, ul_y, lr_x, lr_y); return -EINVAL; } } if( (ul_x < 0) || (ul_y < 0) ) { debug(FLIDEBUG_FAIL, "FLISetImageArea(), area out of bounds: (%4d,%4d),(%4d,%4d)", ul_x, ul_y, lr_x, lr_y); return -EINVAL; } debug(FLIDEBUG_INFO, "Setting image area to: (%4d,%4d),(%4d,%4d)", ul_x, ul_y, lr_x, lr_y); switch (DEVICE->devinfo.devid) { /* MaxCam and IMG cameras */ case FLIUSB_CAM_ID: { long rlen, wlen; iobuf_t buf[IOBUF_MAX_SIZ]; rlen = 0; wlen = 6; IOWRITE_U16(buf, 0, FLI_USBCAM_SETFRAMEOFFSET); IOWRITE_U16(buf, 2, ul_x); IOWRITE_U16(buf, 4, ul_y); IO(dev, buf, &wlen, &rlen); } break; /* Proline Camera */ case FLIUSB_PROLINE_ID: { /* JIM! perform some bounds checking... */ } break; default: debug(FLIDEBUG_WARN, "Hmmm, shouldn't be here, operation on NO camera..."); break; } if (r == 0) { cam->image_area.ul.x = ul_x; cam->image_area.ul.y = ul_y; cam->image_area.lr.x = lr_x; cam->image_area.lr.y = lr_y; cam->grabrowwidth = (cam->image_area.lr.x - cam->image_area.ul.x) / cam->hbin; } return 0; } long fli_camera_usb_set_hbin(flidev_t dev, long hbin) { iobuf_t buf[IOBUF_MAX_SIZ]; long rlen, wlen; // long r = 0; flicamdata_t *cam = DEVICE->device_data; if ((hbin < 1) || (hbin > 16)) return -EINVAL; switch (DEVICE->devinfo.devid) { /* MaxCam and IMG cameras */ case FLIUSB_CAM_ID: { rlen = 0; wlen = 6; IOWRITE_U16(buf, 0, FLI_USBCAM_SETBINFACTORS); IOWRITE_U16(buf, 2, hbin); IOWRITE_U16(buf, 4, cam->vbin); IO(dev, buf, &wlen, &rlen); } break; /* Proline Camera */ case FLIUSB_PROLINE_ID: { /* We do nothing here, h_bin is sent with start exposure command this is a bug, TDI imaging will require this */ } break; default: debug(FLIDEBUG_WARN, "Hmmm, shouldn't be here, operation on NO camera..."); break; } cam->hbin = hbin; cam->grabrowwidth = (cam->image_area.lr.x - cam->image_area.ul.x) / cam->hbin; return 0; } long fli_camera_usb_set_vbin(flidev_t dev, long vbin) { iobuf_t buf[IOBUF_MAX_SIZ]; long rlen, wlen; // long r = 0; flicamdata_t *cam = DEVICE->device_data; if ((vbin < 1) || (vbin > 16)) return -EINVAL; switch (DEVICE->devinfo.devid) { /* MaxCam and IMG cameras */ case FLIUSB_CAM_ID: { rlen = 0; wlen = 6; IOWRITE_U16(buf, 0, FLI_USBCAM_SETBINFACTORS); IOWRITE_U16(buf, 2, cam->hbin); IOWRITE_U16(buf, 4, vbin); IO(dev, buf, &wlen, &rlen); } break; /* Proline Camera */ case FLIUSB_PROLINE_ID: { /* We do nothing here, h_bin is sent with start exposure command this is a bug, TDI imaging will require this */ } break; default: debug(FLIDEBUG_WARN, "Hmmm, shouldn't be here, operation on NO camera..."); break; } cam->vbin = vbin; return 0; } long fli_camera_usb_get_exposure_status(flidev_t dev, long *timeleft) { switch (DEVICE->devinfo.devid) { /* MaxCam and IMG cameras */ case FLIUSB_CAM_ID: { long rlen, wlen; iobuf_t buf[4]; rlen = 4; wlen = 2; IOWRITE_U16(buf, 0, FLI_USBCAM_EXPOSURESTATUS); IO(dev, buf, &wlen, &rlen); IOREAD_U32(buf, 0, *timeleft); } break; /* Proline Camera */ case FLIUSB_PROLINE_ID: { long rlen, wlen; iobuf_t buf[IOBUF_MAX_SIZ]; rlen = 4; wlen = 2; IOWRITE_U16(buf, 0, PROLINE_COMMAND_GET_EXPOSURE_STATUS); IO(dev, buf, &wlen, &rlen); *timeleft = (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3]; } break; default: debug(FLIDEBUG_WARN, "Hmmm, shouldn't be here, operation on NO camera..."); break; } return 0; } long fli_camera_usb_cancel_exposure(flidev_t dev) { /* flicamdata_t *cam = DEVICE->device_data; */ switch (DEVICE->devinfo.devid) { /* MaxCam and IMG cameras */ case FLIUSB_CAM_ID: { long rlen, wlen; iobuf_t buf[IOBUF_MAX_SIZ]; rlen = 0; wlen = 4; IOWRITE_U16(buf, 0, FLI_USBCAM_ABORTEXPOSURE); IO(dev, buf, &wlen, &rlen); /* MaxCam (bug in firmware prevents shutter closing), so issue quick exposure... */ rlen = 0; wlen = 8; /* Bias frame */ IOWRITE_U16(buf, 0, FLI_USBCAM_SETEXPOSURE); IOWRITE_U32(buf, 4, 10); IO(dev, buf, &wlen, &rlen); /* Expose the bias frame */ rlen = 0; wlen = 4; IOWRITE_U16(buf, 0, FLI_USBCAM_STARTEXPOSURE); IOWRITE_U16(buf, 2, 0); IO(dev, buf, &wlen, &rlen); } break; /* Proline Camera */ case FLIUSB_PROLINE_ID: { long rlen = 2, wlen = 2; iobuf_t buf[IOBUF_MAX_SIZ]; IOWRITE_U16(buf, 0, PROLINE_COMMAND_CANCEL_EXPOSURE); IO(dev, buf, &wlen, &rlen); } break; default: debug(FLIDEBUG_WARN, "Hmmm, shouldn't be here, operation on NO camera..."); break; } return 0; } long fli_camera_usb_set_temperature(flidev_t dev, double temperature) { flicamdata_t *cam = DEVICE->device_data; switch (DEVICE->devinfo.devid) { /* MaxCam and IMG cameras */ case FLIUSB_CAM_ID: { unsigned short ad; long rlen, wlen; iobuf_t buf[4]; if(DEVICE->devinfo.fwrev < 0x0200) return 0; if(cam->tempslope == 0.0) ad = 255; else ad = (unsigned short) ((temperature - cam->tempintercept) / cam->tempslope); debug(FLIDEBUG_INFO, "Temperature slope, intercept, AD val, %f %f %f %d", temperature, cam->tempslope, cam->tempintercept, ad); rlen = 0; wlen = 4; IOWRITE_U16(buf, 0, FLI_USBCAM_TEMPERATURE); IOWRITE_U16(buf, 2, ad); IO(dev, buf, &wlen, &rlen); } break; /* Proline Camera */ case FLIUSB_PROLINE_ID: { long rlen, wlen; iobuf_t buf[IOBUF_MAX_SIZ]; unsigned short a; short s_temp; s_temp = (short) (temperature * 256.0); rlen = 2; wlen = 4; IOWRITE_U16(buf, 0, PROLINE_COMMAND_SET_TEMPERATURE); IOWRITE_U16(buf, 2, s_temp); IO(dev, buf, &wlen, &rlen); a = (buf[0] << 8) + buf[1]; debug(FLIDEBUG_INFO, "Got %d from camera.", a); } break; default: debug(FLIDEBUG_WARN, "Hmmm, shouldn't be here, operation on NO camera..."); break; } return 0; } long fli_camera_usb_read_temperature(flidev_t dev, flichannel_t channel, double *temperature) { flicamdata_t *cam = DEVICE->device_data; iobuf_t buf[IOBUF_MAX_SIZ]; long rlen, wlen; long r = 0; switch (DEVICE->devinfo.devid) { /* MaxCam and IMG cameras */ case FLIUSB_CAM_ID: { if (channel == 0) { rlen = 2; wlen = 2; IOWRITE_U16(buf, 0, FLI_USBCAM_TEMPERATURE); IO(dev, buf, &wlen, &rlen); *temperature = cam->tempslope * ((double) buf[1]) + cam->tempintercept; } else { r = -EINVAL; } } break; /* Proline Camera */ case FLIUSB_PROLINE_ID: { double base, ccd; rlen = 14; wlen = 2; IOWRITE_U16(buf, 0, PROLINE_COMMAND_GET_TEMPERATURE); IO(dev, buf, &wlen, &rlen); ccd = (double) ((signed char) buf[0]) + ((double) buf[1] / 256); base = (double) ((signed char) buf[2]) + ((double) buf[3] / 256); switch (channel) { case FLI_TEMPERATURE_CCD: *temperature = ccd; break; case FLI_TEMPERATURE_BASE: *temperature = base; break; default: r = -EINVAL; break; } //#define CHECK_ERRLIM #ifdef CHECK_ERRLIM { unsigned long cnt; rlen = 4; wlen = 2; IOWRITE_U16(buf, 0, 0x0103); IO(dev, buf, &wlen, &rlen); IOREAD_U32(buf, 0, cnt); debug(FLIDEBUG_WARN, "USBERRCNT: %d", cnt); } #endif } break; default: debug(FLIDEBUG_WARN, "Hmmm, shouldn't be here, operation on NO camera..."); break; } return r; } long fli_camera_usb_get_temperature(flidev_t dev, double *temperature) { return fli_camera_usb_read_temperature(dev, 0, temperature); } long fli_camera_usb_grab_row(flidev_t dev, void *buff, size_t width) { flicamdata_t *cam = DEVICE->device_data; if(width > (size_t) (cam->image_area.lr.x - cam->image_area.ul.x)) { debug(FLIDEBUG_FAIL, "FLIGrabRow(), requested row too wide."); debug(FLIDEBUG_FAIL, " Requested width: %d", width); debug(FLIDEBUG_FAIL, " FLISetImageArea() width: %d", cam->image_area.lr.x - cam->image_area.ul.x); return -EINVAL; } switch (DEVICE->devinfo.devid) { /* MaxCam and IMG cameras */ case FLIUSB_CAM_ID: { long x; long r; if (cam->flushcountbeforefirstrow > 0) { debug(FLIDEBUG_INFO, "Flushing %d rows before image download.", cam->flushcountbeforefirstrow); if ((r = fli_camera_usb_flush_rows(dev, cam->flushcountbeforefirstrow, 1))) return r; cam->flushcountbeforefirstrow = 0; } if (cam->grabrowbufferindex >= cam->grabrowbatchsize) { /* We don't have the row in memory */ long rlen, wlen; /* Do we have less than GrabRowBatchSize rows to grab? */ if (cam->grabrowbatchsize > (cam->grabrowcounttot - cam->grabrowindex)) { cam->grabrowbatchsize = cam->grabrowcounttot - cam->grabrowindex; if (cam->grabrowbatchsize < 1) cam->grabrowbatchsize = 1; } debug(FLIDEBUG_INFO, "Grabbing %d rows of width %d.", cam->grabrowbatchsize, cam->grabrowwidth); rlen = cam->grabrowwidth * 2 * cam->grabrowbatchsize; wlen = 6; cam->gbuf[0] = htons(FLI_USBCAM_SENDROW); cam->gbuf[1] = htons((unsigned short) cam->grabrowwidth); cam->gbuf[2] = htons((unsigned short) cam->grabrowbatchsize); IO(dev, cam->gbuf, &wlen, &rlen); for (x = 0; x < (cam->grabrowwidth * cam->grabrowbatchsize); x++) { if ((DEVICE->devinfo.hwrev & 0xff00) == 0x0100) { cam->gbuf[x] = ntohs(cam->gbuf[x]) + 32768; } else { cam->gbuf[x] = ntohs(cam->gbuf[x]); } } cam->grabrowbufferindex = 0; } for (x = 0; x < (long)width; x++) { ((unsigned short *)buff)[x] = cam->gbuf[x + (cam->grabrowbufferindex * cam->grabrowwidth)]; } cam->grabrowbufferindex++; cam->grabrowindex++; if (cam->grabrowcount > 0) { cam->grabrowcount--; if (cam->grabrowcount == 0) { if (cam->flushcountafterlastrow > 0) { debug(FLIDEBUG_INFO, "Flushing %d rows after image download.", cam->flushcountafterlastrow); if ((r = fli_camera_usb_flush_rows(dev, cam->flushcountafterlastrow, 1))) return r; } cam->flushcountafterlastrow = 0; cam->grabrowbatchsize = 1; } } } break; /* Proline Camera */ /* grabrowindex -- current row being grabbed grabrowbatchsize -- number of words to grab grabrowcounttot -- number of words left in buffer grabrowbufferindex -- location of the beginning of the row in the buffer flushcountafterlastrow -- unused */ case FLIUSB_PROLINE_ID: { long rlen, rtotal; /* First we need to determine if the row is in memory */ if (cam->grabrowcounttot < cam->grabrowwidth) { long loadindex = 0; /* Ok, the buffer is double sized (cam->max_usb_xfer * 2) and can * hold cam->max_usb_xfer / 2 words. We need to figure out which * half of the buffer to fill with data */ /* Which half of the buffer are we in, which half to load? */ if (cam->grabrowbufferindex == 0) { loadindex = 0; } else if (cam->grabrowbufferindex < (cam->max_usb_xfer / 2)) { loadindex = (cam->max_usb_xfer / 2); } else if (cam->grabrowbufferindex == (cam->max_usb_xfer / 2)) { loadindex = (cam->max_usb_xfer / 2); } else if (cam->grabrowbufferindex > (cam->max_usb_xfer / 2)) { loadindex = 0; } /* Determine how many bytes to transfer */ rlen = (((cam->grabrowcount - cam->grabrowindex) * cam->grabrowwidth) - cam->grabrowcounttot) * 2; if (rlen > cam->max_usb_xfer) rlen = cam->max_usb_xfer; memset(&cam->gbuf[loadindex], 0x00, rlen); rtotal = rlen; debug(FLIDEBUG_INFO, "Transferring %d starting at %d, buffer starts at %d.", rlen, cam->grabrowcounttot, cam->grabrowbufferindex); if ((usb_bulktransfer(dev, 0x82, &cam->gbuf[loadindex], &rlen)) != 0) /* Grab the buffer */ { debug(FLIDEBUG_FAIL, "Read failed..."); } if (rlen != rtotal) { debug(FLIDEBUG_FAIL, "Transfer did not complete, padding..."); memset(&cam->gbuf[cam->grabrowcounttot], 0x00, (rtotal - rlen)); } cam->grabrowcounttot += (rlen / 2); } /* Double check that row is in memory (an IO operation could have failed.) */ if (cam->grabrowcounttot >= cam->grabrowwidth) { long l = 0; while (l < cam->grabrowwidth) { /* Are we at the end of the buffer? */ if ((cam->grabrowbufferindex + cam->grabrowwidth) < ((cam->max_usb_xfer / 2) * 2) ) { /* Not near end of buffer */ while (l < cam->grabrowwidth) { ((unsigned short *) buff)[l] = ((cam->gbuf[cam->grabrowbufferindex] << 8) & 0xff00) | ((cam->gbuf[cam->grabrowbufferindex] >> 8) & 0x00ff); cam->grabrowbufferindex ++; l ++; } } else { /* Near end of buffer */ while (cam->grabrowbufferindex < ((cam->max_usb_xfer / 2) * 2)) { ((unsigned short *) buff)[l] = ((cam->gbuf[cam->grabrowbufferindex] << 8) & 0xff00) | ((cam->gbuf[cam->grabrowbufferindex] >> 8) & 0x00ff); cam->grabrowbufferindex ++; l ++; } cam->grabrowbufferindex = 0; } } cam->grabrowcounttot -= cam->grabrowwidth; cam->grabrowindex ++; } } break; default: debug(FLIDEBUG_WARN, "Hmmm, shouldn't be here, operation on NO camera..."); break; } return 0; } long fli_camera_usb_expose_frame(flidev_t dev) { flicamdata_t *cam = DEVICE->device_data; iobuf_t buf[IOBUF_MAX_SIZ]; long rlen, wlen; long r = 0; switch (DEVICE->devinfo.devid) { /* MaxCam and IMG cameras */ case FLIUSB_CAM_ID: { short flags = 0; rlen = 0; wlen = 6; IOWRITE_U16(buf, 0, FLI_USBCAM_SETFRAMEOFFSET); IOWRITE_U16(buf, 2, cam->image_area.ul.x); IOWRITE_U16(buf, 4, cam->image_area.ul.y); IO(dev, buf, &wlen, &rlen); rlen = 0; wlen = 6; IOWRITE_U16(buf, 0, FLI_USBCAM_SETBINFACTORS); IOWRITE_U16(buf, 2, cam->hbin); IOWRITE_U16(buf, 4, cam->vbin); IO(dev, buf, &wlen, &rlen); rlen = 0; wlen = 6; IOWRITE_U16(buf, 0, FLI_USBCAM_SETFLUSHBINFACTORS); IOWRITE_U16(buf, 2, cam->hflushbin); IOWRITE_U16(buf, 4, cam->vflushbin); IO(dev, buf, &wlen, &rlen); rlen = 0; wlen = 8; IOWRITE_U16(buf, 0, FLI_USBCAM_SETEXPOSURE); IOWRITE_U32(buf, 4, cam->exposure); IO(dev, buf, &wlen, &rlen); /* What flags do we need to send... */ /* Dark Frame */ flags |= (cam->frametype == FLI_FRAME_TYPE_DARK) ? 0x01 : 0x00; /* External trigger */ flags |= (cam->exttrigger != 0) ? 0x04 : 0x00; flags |= (cam->exttriggerpol != 0) ? 0x08 : 0x00; debug(FLIDEBUG_INFO, "Exposure flags: %04x", flags); debug(FLIDEBUG_INFO, "Flushing %d times.", cam->flushes); // debug(FLIDEBUG_INFO, "Flushing bin factor(X,Y) %d, %d.", cam->hflushbin, cam->vflushbin); if (cam->flushes > 0) { long r; if ((r = fli_camera_usb_flush_rows(dev, cam->ccd.array_area.lr.y - cam->ccd.array_area.ul.y, cam->flushes))) return r; } debug(FLIDEBUG_INFO, "Starting exposure."); rlen = 0; wlen = 4; IOWRITE_U16(buf, 0, FLI_USBCAM_STARTEXPOSURE); IOWRITE_U16(buf, 2, flags); IO(dev, buf, &wlen, &rlen); cam->grabrowcount = cam->image_area.lr.y - cam->image_area.ul.y; cam->grabrowcounttot = cam->grabrowcount; cam->grabrowwidth = cam->image_area.lr.x - cam->image_area.ul.x; cam->grabrowindex = 0; if (cam->grabrowwidth > 0){ cam->grabrowbatchsize = USB_READ_SIZ_MAX / (cam->grabrowwidth * 2); } else { return -1; } /* Lets put some bounds on this... */ if (cam->grabrowbatchsize > cam->grabrowcounttot) cam->grabrowbatchsize = cam->grabrowcounttot; if (cam->grabrowbatchsize > 64) cam->grabrowbatchsize = 64; /* We need to get a whole new buffer by default */ cam->grabrowbufferindex = cam->grabrowbatchsize; cam->flushcountbeforefirstrow = cam->image_area.ul.y; cam->flushcountafterlastrow = (cam->ccd.array_area.lr.y - cam->ccd.array_area.ul.y) - ((cam->image_area.lr.y - cam->image_area.ul.y) * cam->vbin) - cam->image_area.ul.y; if (cam->flushcountbeforefirstrow < 0) cam->flushcountbeforefirstrow = 0; if (cam->flushcountafterlastrow < 0) cam->flushcountafterlastrow = 0; } break; case FLIUSB_PROLINE_ID: { short h_offset; cam->grabrowcount = cam->image_area.lr.y - cam->image_area.ul.y; // Rows High cam->grabrowwidth = cam->image_area.lr.x - cam->image_area.ul.x; // Pixels Wide cam->flushcountbeforefirstrow = cam->image_area.ul.y; // Vertical Offset h_offset = cam->image_area.ul.x; // Horizontal Offset cam->grabrowindex = 0; cam->grabrowbatchsize = 0; cam->grabrowcounttot = 0; cam->grabrowbufferindex = 0; cam->flushcountafterlastrow = 0; if (cam->grabrowwidth <= 0) return -EINVAL; rlen = 0; wlen = 32; IOWRITE_U16(buf, 0, PROLINE_COMMAND_EXPOSE); /* Number of pixels wide */ IOWRITE_U16(buf, 2, cam->grabrowwidth); /* Horizontal offset */ IOWRITE_U16(buf, 4, h_offset); /* Number of vertical rows to grab */ IOWRITE_U16(buf, 6, cam->grabrowcount); /* Vertical offset */ IOWRITE_U16(buf, 8, cam->flushcountbeforefirstrow); /* Horizontal bin */ IOWRITE_U8(buf, 10, cam->hbin); /* Vertical bin */ IOWRITE_U8(buf, 11, cam->vbin); /* Exposure */ IOWRITE_U32(buf, 12, cam->exposure); /* Now the exposure flags */ buf[16] = (cam->frametype == FLI_FRAME_TYPE_DARK) ? 0x01 : 0x00; buf[16] |= ((cam->exttrigger != 0) && (cam->exttriggerpol == 0)) ? 0x02 : 0x00; buf[16] |= ((cam->exttrigger != 0) && (cam->exttriggerpol != 0)) ? 0x04 : 0x00; /* Perform the transation */ IO(dev, buf, &wlen, &rlen); } break; default: debug(FLIDEBUG_WARN, "Hmmm, shouldn't be here, operation on NO camera..."); break; } return r; } long fli_camera_usb_flush_rows(flidev_t dev, long rows, long repeat) { flicamdata_t *cam = DEVICE->device_data; iobuf_t buf[IOBUF_MAX_SIZ]; long rlen, wlen; long r = 0; if (rows < 0) return -EINVAL; if (rows == 0) return 0; switch (DEVICE->devinfo.devid) { /* MaxCam and IMG cameras */ case FLIUSB_CAM_ID: { rlen = 0; wlen = 6; IOWRITE_U16(buf, 0, FLI_USBCAM_SETFLUSHBINFACTORS); IOWRITE_U16(buf, 2, cam->hflushbin); IOWRITE_U16(buf, 4, cam->vflushbin); IO(dev, buf, &wlen, &rlen); while (repeat > 0) { debug(FLIDEBUG_INFO, "Flushing %d rows.", rows); rlen = 0; wlen = 4; IOWRITE_U16(buf, 0, FLI_USBCAM_FLUSHROWS); IOWRITE_U16(buf, 2, rows); IO(dev, buf, &wlen, &rlen); repeat--; } } break; /* Proline Camera */ case FLIUSB_PROLINE_ID: { } break; default: debug(FLIDEBUG_WARN, "Hmmm, shouldn't be here, operation on NO camera..."); break; } return r; } long fli_camera_usb_set_bit_depth(flidev_t dev, flibitdepth_t bitdepth) { // flicamdata_t *cam = DEVICE->device_data; // iobuf_t buf[IOBUF_MAX_SIZ]; // long rlen = 0, wlen = 0; long r = 0; switch (DEVICE->devinfo.devid) { /* MaxCam and IMG cameras */ case FLIUSB_CAM_ID: { r = -EINVAL; } break; /* Proline Camera */ case FLIUSB_PROLINE_ID: { r = -EINVAL; } break; default: debug(FLIDEBUG_WARN, "Hmmm, shouldn't be here, operation on NO camera..."); break; } return r; } long fli_camera_usb_read_ioport(flidev_t dev, long *ioportset) { // flicamdata_t *cam = DEVICE->device_data; iobuf_t buf[IOBUF_MAX_SIZ]; long rlen, wlen; long r = 0; switch (DEVICE->devinfo.devid) { /* MaxCam and IMG cameras */ case FLIUSB_CAM_ID: { rlen = 1; wlen = 2; IOWRITE_U16(buf, 0, FLI_USBCAM_READIO); IO(dev, buf, &wlen, &rlen); IOREAD_U8(buf, 0, *ioportset); } break; /* Proline Camera */ case FLIUSB_PROLINE_ID: { rlen = 2; wlen = 2; IOWRITE_U16(buf, 0, PROLINE_COMMAND_READ_IOPORT); IO(dev, buf, &wlen, &rlen); IOREAD_U8(buf, 1, *ioportset); } break; default: debug(FLIDEBUG_WARN, "Hmmm, shouldn't be here, operation on NO camera..."); break; } return r; } long fli_camera_usb_write_ioport(flidev_t dev, long ioportset) { // flicamdata_t *cam = DEVICE->device_data; iobuf_t buf[IOBUF_MAX_SIZ]; long rlen, wlen; long r = 0; switch (DEVICE->devinfo.devid) { /* MaxCam and IMG cameras */ case FLIUSB_CAM_ID: { rlen = 0; wlen = 3; IOWRITE_U16(buf, 0, FLI_USBCAM_WRITEIO); IOWRITE_U8(buf, 2, ioportset); IO(dev, buf, &wlen, &rlen); } break; /* Proline Camera */ case FLIUSB_PROLINE_ID: { rlen = 2; wlen = 4; IOWRITE_U16(buf, 0, PROLINE_COMMAND_WRITE_IOPORT); IOWRITE_U16(buf, 2, ioportset); IO(dev, buf, &wlen, &rlen); } break; default: debug(FLIDEBUG_WARN, "Hmmm, shouldn't be here, operation on NO camera..."); break; } return r; } long fli_camera_usb_configure_ioport(flidev_t dev, long ioportset) { // flicamdata_t *cam = DEVICE->device_data; iobuf_t buf[IOBUF_MAX_SIZ]; long rlen, wlen; long r = 0; switch (DEVICE->devinfo.devid) { /* MaxCam and IMG cameras */ case FLIUSB_CAM_ID: { rlen = 0; wlen = 3; IOWRITE_U16(buf, 0, FLI_USBCAM_WRITEDIR); IOWRITE_U8(buf, 2, ioportset); IO(dev, buf, &wlen, &rlen); } break; /* Proline Camera */ case FLIUSB_PROLINE_ID: { rlen = 2; wlen = 4; IOWRITE_U16(buf, 0, PROLINE_COMMAND_CONFIGURE_IOPORT); IOWRITE_U16(buf, 2, ioportset); IO(dev, buf, &wlen, &rlen); } break; default: debug(FLIDEBUG_WARN, "Hmmm, shouldn't be here, operation on NO camera..."); break; } return r; } long fli_camera_usb_control_shutter(flidev_t dev, long shutter) { // flicamdata_t *cam = DEVICE->device_data; iobuf_t buf[IOBUF_MAX_SIZ]; long rlen, wlen; long r = 0; switch (DEVICE->devinfo.devid) { /* MaxCam and IMG cameras */ case FLIUSB_CAM_ID: { rlen = 0; wlen = 3; IOWRITE_U16(buf, 0, FLI_USBCAM_SHUTTER); IOWRITE_U8(buf, 2, shutter); IO(dev, buf, &wlen, &rlen); } break; /* Proline Camera */ case FLIUSB_PROLINE_ID: { unsigned char c = 0; debug(FLIDEBUG_INFO, "JIM!!"); switch (shutter) { case FLI_SHUTTER_CLOSE: c = 0x00; break; case FLI_SHUTTER_OPEN: c = 0x01; break; default: r = -EINVAL; break; } if (r != 0) break; rlen = 2; wlen = 3; IOWRITE_U16(buf, 0, PROLINE_COMMAND_SET_SHUTTER); IOWRITE_U8(buf, 2, c); debug(FLIDEBUG_INFO, "%s shutter.", (buf[2] == 0)? "Closing":"Opening"); IO(dev, buf, &wlen, &rlen); } break; default: debug(FLIDEBUG_WARN, "Hmmm, shouldn't be here, operation on NO camera..."); break; } return r; } long fli_camera_usb_control_bgflush(flidev_t dev, long bgflush) { flicamdata_t *cam = DEVICE->device_data; iobuf_t buf[IOBUF_MAX_SIZ]; long rlen, wlen; long r = 0; if( (bgflush != FLI_BGFLUSH_STOP) && (bgflush != FLI_BGFLUSH_START) ) return -EINVAL; cam->background_flush = (bgflush == FLI_BGFLUSH_STOP)? 0 : 1; switch (DEVICE->devinfo.devid) { /* MaxCam and IMG cameras */ case FLIUSB_CAM_ID: { if(DEVICE->devinfo.fwrev < 0x0300) { debug(FLIDEBUG_WARN, "Background flush commanded on early firmware."); return -EFAULT; } rlen = 0; wlen = 4; IOWRITE_U16(buf, 0, FLI_USBCAM_BGFLUSH); IOWRITE_U16(buf, 2, bgflush); IO(dev, buf, &wlen, &rlen); } break; /* Proline Camera */ case FLIUSB_PROLINE_ID: { } break; default: debug(FLIDEBUG_WARN, "Hmmm, shouldn't be here, operation on NO camera..."); break; } return r; } long fli_camera_usb_get_cooler_power(flidev_t dev, double *power) { // flicamdata_t *cam = DEVICE->device_data; iobuf_t buf[IOBUF_MAX_SIZ]; long rlen, wlen; long r = 0; *power = 0.0; switch (DEVICE->devinfo.devid) { /* MaxCam and IMG cameras */ case FLIUSB_CAM_ID: { return -EFAULT; } break; /* Proline Camera */ case FLIUSB_PROLINE_ID: { short pwm; rlen = 14; wlen = 2; IOWRITE_U16(buf, 0, PROLINE_COMMAND_GET_TEMPERATURE); IO(dev, buf, &wlen, &rlen); IOREAD_U16(buf, 4, pwm); *power = (double) pwm; } break; default: debug(FLIDEBUG_WARN, "Hmmm, shouldn't be here, operation on NO camera..."); break; } debug(FLIDEBUG_INFO, "Cooler power: %f", *power); return r; } long fli_camera_usb_get_camera_status(flidev_t dev, long *camera_status) { // flicamdata_t *cam = DEVICE->device_data; iobuf_t buf[IOBUF_MAX_SIZ]; long rlen, wlen; long r = 0; switch (DEVICE->devinfo.devid) { /* MaxCam and IMG cameras */ case FLIUSB_CAM_ID: { } break; /* Proline Camera */ case FLIUSB_PROLINE_ID: { rlen = 4; wlen = 2; IOWRITE_U16(buf, 0, PROLINE_COMMAND_GET_STATUS); IO(dev, buf, &wlen, &rlen); IOREAD_U32(buf, 0, *camera_status); } break; default: debug(FLIDEBUG_WARN, "Hmmm, shouldn't be here, operation on NO camera..."); break; } return r; } long fli_camera_usb_get_camera_mode(flidev_t dev, flimode_t *camera_mode) { // flicamdata_t *cam = DEVICE->device_data; iobuf_t buf[IOBUF_MAX_SIZ]; long rlen, wlen; long r = 0; switch (DEVICE->devinfo.devid) { /* MaxCam and IMG cameras */ case FLIUSB_CAM_ID: { *camera_mode = 0; } break; /* Proline Camera */ case FLIUSB_PROLINE_ID: { rlen = 2; wlen = 2; IOWRITE_U16(buf, 0, PROLINE_COMMAND_GET_CURRENT_MODE); IO(dev, buf, &wlen, &rlen); IOREAD_U16(buf, 0, *camera_mode); } break; default: debug(FLIDEBUG_WARN, "Hmmm, shouldn't be here, operation on NO camera..."); break; } return r; } long fli_camera_usb_set_camera_mode(flidev_t dev, flimode_t camera_mode) { // flicamdata_t *cam = DEVICE->device_data; iobuf_t buf[IOBUF_MAX_SIZ]; long rlen, wlen; long r = 0; switch (DEVICE->devinfo.devid) { /* MaxCam and IMG cameras */ case FLIUSB_CAM_ID: { if (camera_mode > 0) r = -EINVAL; } break; /* Proline Camera */ case FLIUSB_PROLINE_ID: { flimode_t mode; rlen = 2; wlen = 4; IOWRITE_U16(buf, 0, PROLINE_COMMAND_SET_MODE); IOWRITE_U16(buf, 2, camera_mode); IO(dev, buf, &wlen, &rlen); IOREAD_U16(buf, 0, mode); if (mode != camera_mode) { debug(FLIDEBUG_FAIL, "Error setting camera mode, tried %d, performed %d.", camera_mode, mode); r = -EINVAL; } } break; default: debug(FLIDEBUG_WARN, "Hmmm, shouldn't be here, operation on NO camera..."); break; } return r; } long fli_camera_usb_get_camera_mode_string(flidev_t dev, flimode_t camera_mode, char *dest, size_t siz) { // flicamdata_t *cam = DEVICE->device_data; iobuf_t buf[IOBUF_MAX_SIZ]; long rlen, wlen; long r = 0; switch (DEVICE->devinfo.devid) { /* MaxCam and IMG cameras */ case FLIUSB_CAM_ID: { if (camera_mode > 0) r = -EINVAL; else strncpy((char *) dest, "Default Mode", siz - 1); } break; /* Proline Camera */ case FLIUSB_PROLINE_ID: { rlen = 32; wlen = 4; IOWRITE_U16(buf, 0, PROLINE_COMMAND_GET_MODE_STRING); IOWRITE_U16(buf, 2, camera_mode); IO(dev, buf, &wlen, &rlen); strncpy((char *) dest, (char *) buf, MIN(siz - 1, 31)); if (dest[0] == '\0') r = -EINVAL; } break; default: debug(FLIDEBUG_WARN, "Hmmm, shouldn't be here, operation on NO camera..."); break; } return r; } libfli1-1.7/libfli-camera-parport.h0000644000175000017500000001066511110507327015045 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifndef _LIBFLI_CAMERA_PARPORT_H_ #define _LIBFLI_CAMERA_PARPORT_H_ /* Define command and data word formats */ #define C_ADDRESS(addr,ext) (0x8000|(((addr)<<8)&0x0f00)|((ext)&0x00ff)) #define C_RESTCFG(gain,chnl,exttrig,res) (0x9000|(((gain)<<8)&0x0f00)|(((chnl)<<5)&0x00e0)|(((exttrig)<<4)&0x0010)|(((res)&0x000f))) #define C_SHUTTER(open,dmult) (0xa000|((dmult)&0x07ff)|(((open)<<11)&0x0800)) #define C_SEND(x) (0xb000|((x)&0x0fff)) #define C_FLUSH(x) (0xc000|((x)&0x0fff)) #define C_VSKIP(x) (0xd000|((x)&0x0fff)) #define C_HSKIP(x) (0xe000|((x)&0x0fff)) #define C_TEMP(x) (0xf000|((x)&0x0fff)) #define D_XROWOFF(x) (0x0000|((x)&0x0fff)) #define D_XROWWID(x) (0x1000|((x)&0x0fff)) #define D_XFLBIN(x) (0x2000|((x)&0x0fff)) #define D_YFLBIN(x) (0x3000|((x)&0x0fff)) #define D_XBIN(x) (0x4000|((x)&0x0fff)) #define D_YBIN(x) (0x5000|((x)&0x0fff)) #define D_EXPDUR(x) (0x6000|((x)&0x0fff)) #define D_RESERVE(x) (0x7000|((x)&0x0fff)) /* Define extended parameter fields for querying camera */ #define EPARAM_ECHO (0x00) #define EPARAM_CCDID (0x01) #define EPARAM_FIRM (0x02) #define EPARAM_SNHIGH (0x03) #define EPARAM_SNLOW (0x04) #define EPARAM_SIGGAIN (0x05) #define EPARAM_DEVICE (0x06) /* I/O Bit definitions */ #define FLICCD_IO_P0 (0x01) #define FLICCD_IO_P1 (0x02) #define FLICCD_IO_P2 (0x04) #define FLICCD_IO_P3 (0x08) long fli_camera_parport_open(flidev_t dev); long fli_camera_parport_get_array_area(flidev_t dev, long *ul_x, long *ul_y, long *lr_x, long *lr_y); long fli_camera_parport_get_visible_area(flidev_t dev, long *ul_x, long *ul_y, long *lr_x, long *lr_y); long fli_camera_parport_set_exposure_time(flidev_t dev, long exptime); long fli_camera_parport_set_image_area(flidev_t dev, long ul_x, long ul_y, long lr_x, long lr_y); long fli_camera_parport_set_hbin(flidev_t dev, long hbin); long fli_camera_parport_set_vbin(flidev_t dev, long vbin); long fli_camera_parport_get_exposure_status(flidev_t dev, long *timeleft); long fli_camera_parport_set_temperature(flidev_t dev, double temperature); long fli_camera_parport_get_temperature(flidev_t dev, double *temperature); long fli_camera_parport_grab_row(flidev_t dev, void *buf, size_t width); long fli_camera_parport_expose_frame(flidev_t dev); long fli_camera_parport_flush_rows(flidev_t dev, long rows, long repeat); long fli_camera_parport_set_bit_depth(flidev_t dev, flibitdepth_t bitdepth); long fli_camera_parport_read_ioport(flidev_t dev, long *ioportset); long fli_camera_parport_write_ioport(flidev_t dev, long ioportset); long fli_camera_parport_configure_ioport(flidev_t dev, long ioportset); long fli_camera_parport_control_shutter(flidev_t dev, long shutter); #endif /* _LIBFLI_CAMERA_PARPORT_H_ */ libfli1-1.7/libfli-camera-usb.h0000644000175000017500000001313011110507327014135 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifndef _LIBFLI_CAMERA_USB_H_ #define _LIBFLI_CAMERA_USB_H_ #define FLI_USBCAM_DEVICENAME 0x01 #define FLI_USBCAM_DEVICEMFG 0x02 #define FLI_USBCAM_VERSION 0x03 #define FLI_USBCAM_DEVICEID 0x04 #define FLI_USBCAM_SERIALNUM 0x05 #define FLI_USBCAM_HARDWAREREV 0x06 #define FLI_USBCAM_DEVINIT 0x07 #define FLI_USBCAM_READPARAMBLOCK 0x08 #define FLI_USBCAM_ARRAYSIZE 0x100 #define FLI_USBCAM_IMAGEOFFSET 0x102 #define FLI_USBCAM_IMAGESIZE 0x103 #define FLI_USBCAM_TEMPERATURE 0x104 #define FLI_USBCAM_SETFRAMEOFFSET 0x105 #define FLI_USBCAM_SETBINFACTORS 0x106 #define FLI_USBCAM_SETFLUSHBINFACTORS 0x107 #define FLI_USBCAM_SETEXPOSURE 0x108 #define FLI_USBCAM_STARTEXPOSURE 0x109 #define FLI_USBCAM_ABORTEXPOSURE 0x10a #define FLI_USBCAM_EXPOSURESTATUS 0x10b #define FLI_USBCAM_FLUSHROWS 0x10c #define FLI_USBCAM_SENDROW 0x10d #define FLI_USBCAM_SETDAC 0x10e #define FLI_USBCAM_SHUTTER 0x10f #define FLI_USBCAM_WRITEIO 0x110 #define FLI_USBCAM_READIO 0x111 #define FLI_USBCAM_WRITEDIR 0x112 #define FLI_USBCAM_BGFLUSH 0x114 #define PROLINE_GET_HARDWAREINFO (0x0001) #define PROLINE_GET_DEVICESTRINGS (0x0002) #define PROLINE_GET_CAMERAINFO (0x0003) #define PROLINE_COMMAND_GET_ROW (0x0004) #define PROLINE_COMMAND_EXPOSE (0x0005) #define PROLINE_COMMAND_GET_EXPOSURE_STATUS (0x0006) #define PROLINE_COMMAND_CANCEL_EXPOSURE (0x0007) #define PROLINE_COMMAND_GET_TEMPERATURE (0x0008) #define PROLINE_COMMAND_SET_TEMPERATURE (0x0009) #define PROLINE_COMMAND_SET_SHUTTER (0x000a) #define PROLINE_COMMAND_SET_BGFLUSH (0x000b) #define PROLINE_COMMAND_GET_STATUS (0x000c) #define PROLINE_COMMAND_GET_CURRENT_MODE (0x000d) #define PROLINE_COMMAND_GET_MODE_STRING (0x000e) #define PROLINE_COMMAND_SET_MODE (0x000f) #define PROLINE_COMMAND_CONFIGURE_IOPORT (0x0010) #define PROLINE_COMMAND_WRITE_IOPORT (0x0011) #define PROLINE_COMMAND_READ_IOPORT (0x0012) long fli_camera_usb_open(flidev_t dev); long fli_camera_usb_get_array_area(flidev_t dev, long *ul_x, long *ul_y, long *lr_x, long *lr_y); long fli_camera_usb_get_visible_area(flidev_t dev, long *ul_x, long *ul_y, long *lr_x, long *lr_y); long fli_camera_usb_set_exposure_time(flidev_t dev, long exptime); long fli_camera_usb_set_image_area(flidev_t dev, long ul_x, long ul_y, long lr_x, long lr_y); long fli_camera_usb_set_hbin(flidev_t dev, long hbin); long fli_camera_usb_set_vbin(flidev_t dev, long vbin); long fli_camera_usb_get_exposure_status(flidev_t dev, long *timeleft); long fli_camera_usb_cancel_exposure(flidev_t dev); long fli_camera_usb_set_temperature(flidev_t dev, double temperature); long fli_camera_usb_get_temperature(flidev_t dev, double *temperature); long fli_camera_usb_grab_row(flidev_t dev, void *buff, size_t width); long fli_camera_usb_expose_frame(flidev_t dev); long fli_camera_usb_flush_rows(flidev_t dev, long rows, long repeat); long fli_camera_usb_set_bit_depth(flidev_t dev, flibitdepth_t bitdepth); long fli_camera_usb_read_ioport(flidev_t dev, long *ioportset); long fli_camera_usb_write_ioport(flidev_t dev, long ioportset); long fli_camera_usb_configure_ioport(flidev_t dev, long ioportset); long fli_camera_usb_control_shutter(flidev_t dev, long shutter); long fli_camera_usb_control_bgflush(flidev_t dev, long bgflush); long fli_camera_usb_set_dac(flidev_t dev, unsigned long dacset); long fli_camera_usb_get_cooler_power(flidev_t dev, double *power); long fli_camera_usb_get_camera_status(flidev_t dev, long *camera_status); long fli_camera_usb_get_camera_mode_string(flidev_t dev, flimode_t camera_mode, char *dest, size_t siz); long fli_camera_usb_set_camera_mode(flidev_t dev, flimode_t camera_mode); long fli_camera_usb_get_camera_mode(flidev_t dev, flimode_t *camera_mode); long fli_camera_usb_read_temperature(flidev_t dev, flichannel_t channel, double *temperature); #endif /* _LIBFLI_CAMERA_USB_H_ */ libfli1-1.7/libfli-serial.c0000644000175000017500000001156011110507327013375 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #include #include #include #include #include #include #include "libfli-libfli.h" #include "libfli-debug.h" #include "libfli-sys.h" #include "libfli-serial.h" long unix_serialio(flidev_t dev, void *buf, long *wlen, long *rlen) { int err = 0, locked = 0, gotattr = 0; long org_wlen = *wlen, org_rlen = *rlen; struct termios old_termios, new_termios; fli_unixio_t *io; io = DEVICE->io_data; if ((err = unix_fli_lock(dev))) { debug(FLIDEBUG_WARN, "Lock failed"); goto done; } locked = 1; if (tcgetattr(io->fd, &old_termios)) { err = -errno; debug(FLIDEBUG_WARN, "tcgetattr() failed: %s", strerror(errno)); goto done; } gotattr = 1; bzero(&new_termios, sizeof(struct termios)); new_termios.c_cflag = CS8 | CREAD | CLOCAL; new_termios.c_cc[VMIN] = 1; new_termios.c_cc[VTIME] = 0; /* Set the input baud rate */ if (cfsetispeed(&new_termios, BAUDRATE)) { err = -errno; debug(FLIDEBUG_WARN, "cfsetispeed() failed: %s", strerror(errno)); goto done; } /* Set the output baud rate */ if (cfsetospeed(&new_termios, BAUDRATE)) { err = -errno; debug(FLIDEBUG_WARN, "cfsetospeed() failed: %s", strerror(errno)); goto done; } if (tcsetattr(io->fd, TCSANOW, &new_termios)) { err = -errno; // FIX: Should this be FLIDEBUG_FAIL debug(FLIDEBUG_WARN, "tcsetattr() failed: %s", strerror(errno)); goto done; } if ((*wlen = write(io->fd, buf, org_wlen)) != org_wlen) { err = -errno; debug(FLIDEBUG_WARN, "write() failed, only %d of %d bytes written", *wlen, org_wlen); goto done; } if (tcdrain(io->fd)) { err = -errno; debug(FLIDEBUG_WARN, "tcdrain() failed: %s", strerror(errno)); goto done; } for (*rlen = 0; *rlen < org_rlen; ) { ssize_t r; fd_set readfds; struct timeval timeout; timeout.tv_sec = DEVICE->io_timeout / 1000; timeout.tv_usec = (DEVICE->io_timeout % 1000) * 1000; FD_ZERO(&readfds); FD_SET(io->fd, &readfds); switch (select(io->fd + 1, &readfds, NULL, NULL, &timeout)) { case -1: /* An error occurred */ err = -errno; debug(FLIDEBUG_WARN, "select() failed: %s", strerror(errno)); break; case 0: /* A timeout occurred */ err = -ETIMEDOUT; debug(FLIDEBUG_WARN, "A serial communication timeout occurred"); break; default: /* There's some data to read */ if ((r = read(io->fd, buf + *rlen, org_rlen - *rlen)) <= 0) { err = -errno; debug(FLIDEBUG_WARN, "read() failed, only %d of %d bytes read", r, org_rlen - *rlen); } else *rlen += r; break; } if (err) break; } done: if (gotattr) { if (tcsetattr(io->fd, TCSANOW, &old_termios)) { if (err == 0) err = -errno; debug(FLIDEBUG_WARN, "tcsetattr() failed, could not restore terminal settings: %s", strerror(errno)); } } if (locked) { int r; if ((r = unix_fli_unlock(dev))) debug(FLIDEBUG_WARN, "Unlock failed"); if (err == 0) err = r; } return err; } libfli1-1.7/libfli-sys.c0000644000175000017500000002314311110507327012734 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #include #include #include #include #include #include #include #include #include #include #include #include "libfli-libfli.h" #include "libfli-debug.h" #include "libfli-mem.h" #include "libfli-camera.h" #include "libfli-filter-focuser.h" #include "libfli-sys.h" #include "libfli-parport.h" #include "libfli-usb.h" #include "libfli-serial.h" static long unix_fli_list_parport(flidomain_t domain, char ***names); static long unix_fli_list_usb(flidomain_t domain, char ***names); static long unix_fli_list_serial(flidomain_t domain, char ***names); long unix_fli_connect(flidev_t dev, char *name, long domain) { fli_unixio_t *io; CHKDEVICE(dev); if (name == NULL) return -EINVAL; /* Lock functions should be set before any other functions used */ DEVICE->fli_lock = unix_fli_lock; DEVICE->fli_unlock = unix_fli_unlock; DEVICE->domain = domain & 0x00ff; DEVICE->devinfo.type = domain & 0xff00; debug(FLIDEBUG_INFO, "Domain: 0x%04x", DEVICE->domain); debug(FLIDEBUG_INFO, " Type: 0x%04x", DEVICE->devinfo.type); if ((io = xcalloc(1, sizeof(fli_unixio_t))) == NULL) return -ENOMEM; if ((io->fd = open(name, O_RDWR)) == -1) { xfree(io); return -errno; } switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: DEVICE->fli_io = unix_parportio; break; case FLIDOMAIN_USB: { int r; if ((r = unix_usb_connect(dev, io, name))) { close(io->fd); xfree(io); return r; } DEVICE->fli_io = unix_usbio; } break; case FLIDOMAIN_SERIAL: DEVICE->fli_io = unix_serialio; break; default: close(io->fd); xfree(io); return -EINVAL; } switch (DEVICE->devinfo.type) { case FLIDEVICE_CAMERA: DEVICE->fli_open = fli_camera_open; DEVICE->fli_close = fli_camera_close; DEVICE->fli_command = fli_camera_command; break; case FLIDEVICE_FOCUSER: DEVICE->fli_open = fli_focuser_open; DEVICE->fli_close = fli_focuser_close; DEVICE->fli_command = fli_focuser_command; break; case FLIDEVICE_FILTERWHEEL: DEVICE->fli_open = fli_filter_open; DEVICE->fli_close = fli_filter_close; DEVICE->fli_command = fli_filter_command; break; default: close(io->fd); xfree(io); return -EINVAL; } DEVICE->io_data = io; DEVICE->name = xstrdup(name); DEVICE->io_timeout = 60 * 1000; /* 1 min. */ return 0; } long unix_fli_disconnect(flidev_t dev) { int err = 0; fli_unixio_t *io; CHKDEVICE(dev); if ((io = DEVICE->io_data) == NULL) return -EINVAL; switch (DEVICE->domain) { case FLIDOMAIN_USB: err = unix_usb_disconnect(dev); break; default: break; } if (close(io->fd)) if (!err) err = -errno; xfree(DEVICE->io_data); DEVICE->io_data = NULL; DEVICE->fli_lock = NULL; DEVICE->fli_unlock = NULL; DEVICE->fli_io = NULL; DEVICE->fli_open = NULL; DEVICE->fli_close = NULL; DEVICE->fli_command = NULL; return err; } #if defined(_USE_FLOCK_) long unix_fli_lock(flidev_t dev) { fli_unixio_t *io = DEVICE->io_data; if (io == NULL) return -ENODEV; if (flock(io->fd, LOCK_EX) == -1) return -errno; else return 0; } long unix_fli_unlock(flidev_t dev) { fli_unixio_t *io = DEVICE->io_data; if (io == NULL) return -ENODEV; if (flock(io->fd, LOCK_UN) == -1) return -errno; else return 0; } #else /* !defined(_USE_FLOCK_) */ #define PUBLIC_DIR "/var/spool/lock" long unix_fli_lock(flidev_t dev) { int fd, err = 0, locked = 0, i; char tmpf[] = PUBLIC_DIR "/temp.XXXXXX", lockf[PATH_MAX], name[PATH_MAX]; FILE *f; unsigned int backoff = 10000; pid_t pid; if ((fd = mkstemp(tmpf)) == -1) return -errno; if ((f = fdopen(fd, "w")) == NULL) { err = -errno; goto done; } fprintf(f, "%d\n", getpid()); fclose(f); if (chmod(tmpf, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) == -1) { err = -errno; goto done; } for (i = 0; DEVICE->name[i] != '\0' && i < PATH_MAX; i++) name[i] = (DEVICE->name[i] == '/') ? '-' : DEVICE->name[i]; name[MIN(i, PATH_MAX - 1)] = '\0'; if (snprintf(lockf, PATH_MAX, PUBLIC_DIR "/libfli%s.lock", name) >= PATH_MAX) { err = -EOVERFLOW; goto done; } do { if (link(tmpf, lockf) == -1) { int r; if (errno != EEXIST) { err = -errno; goto done; } if ((f = fopen(lockf, "r")) == NULL) continue; r = fscanf(f, "%d\n", &pid); fclose(f); if (r != 1) continue; if (kill(pid, 0)) { if (errno == ESRCH) { debug(FLIDEBUG_WARN, "Removing stale lock file"); unlink(lockf); } continue; } else { usleep(backoff); if ((backoff <<= 2) == 0) { err = -ETIMEDOUT; goto done; } } } else locked = 1; } while (!locked); done: unlink(tmpf); return err; } long unix_fli_unlock(flidev_t dev) { char lockf[PATH_MAX], name[PATH_MAX]; FILE *f; pid_t pid = -1; int i; for (i = 0; DEVICE->name[i] != '\0' && i < PATH_MAX; i++) name[i] = (DEVICE->name[i] == '/') ? '-' : DEVICE->name[i]; name[MIN(i, PATH_MAX - 1)] = '\0'; if (snprintf(lockf, PATH_MAX, PUBLIC_DIR "/libfli%s.lock", name) >= PATH_MAX) return -EOVERFLOW; if ((f = fopen(lockf, "r")) == NULL) { debug(FLIDEBUG_WARN, "Trying to unlock `%s' when not locked", DEVICE->name); return -errno; } if (fscanf(f, "%d\n", &pid) != 1) debug(FLIDEBUG_WARN, "Invalid lock file for `%s'", DEVICE->name); fclose(f); if (pid != -1 && pid != getpid()) debug(FLIDEBUG_WARN, "Forcing unlock of `%s' from process %d", DEVICE->name, pid); unlink(lockf); return 0; } #undef PUBLIC_DIR #endif /* defined(_USE_FLOCK_) */ long unix_fli_list(flidomain_t domain, char ***names) { *names = NULL; switch (domain & 0x00ff) { case FLIDOMAIN_PARALLEL_PORT: return unix_fli_list_parport(domain, names); break; case FLIDOMAIN_USB: return unix_fli_list_usb(domain, names); break; case FLIDOMAIN_SERIAL: return unix_fli_list_serial(domain, names); break; default: return -EINVAL; } /* Not reached */ return -EINVAL; } static long unix_fli_list_glob(char *pattern, flidomain_t domain, char ***names) { int retval, i, found = 0; char **list; glob_t g; if ((retval = glob(pattern, 0, NULL, &g))) { #ifdef GLOB_NOMATCH if (retval != GLOB_NOMATCH) { globfree(&g); return -errno; } /* retval == GLOB_NOMATCH */ g.gl_pathc = 0; #else globfree(&g); return -errno; #endif } if ((list = xmalloc((g.gl_pathc + 1) * sizeof(char *))) == NULL) { globfree(&g); return -ENOMEM; } for (i = 0; i < g.gl_pathc; i++) { flidev_t dev; if (FLIOpen(&dev, g.gl_pathv[i], domain)) continue; if ((list[found] = xmalloc(strlen(g.gl_pathv[i]) + strlen(DEVICE->devinfo.model) + 2)) == NULL) { int j; FLIClose(dev); for (j = 0; j < found; j++) xfree(list[j]); xfree(list); globfree(&g); return -ENOMEM; } sprintf(list[found], "%s;%s", g.gl_pathv[i], DEVICE->devinfo.model); FLIClose(dev); found++; } globfree(&g); /* Terminate the list */ list[found++] = NULL; list = xrealloc(list, found * sizeof(char *)); *names = list; return 0; } #ifdef __linux__ static long unix_fli_list_parport(flidomain_t domain, char ***names) { return unix_fli_list_glob(PARPORT_GLOB, domain, names); } #else static long unix_fli_list_parport(flidomain_t domain, char ***names) { return -EINVAL; } #endif static long unix_fli_list_usb(flidomain_t domain, char ***names) { return unix_fli_list_glob(USB_GLOB, domain, names); } static long unix_fli_list_serial(flidomain_t domain, char ***names) { return unix_fli_list_glob(SERIAL_GLOB, domain, names); } libfli1-1.7/libfli-debug.c0000644000175000017500000000631011110507327013201 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #include #include #include #include "libfli-libfli.h" #define LOGPREFIX "libfli" static char *_loghost = NULL; static flidebug_t _loglevel = FLIDEBUG_NONE; static int _logopen = 0; int sysloglevel(int level) { switch (level) { case FLIDEBUG_INFO: return LOG_INFO; break; case FLIDEBUG_WARN: return LOG_WARNING; break; case FLIDEBUG_FAIL: return LOG_ERR; break; case FLIDEBUG_ALL: return LOG_EMERG | LOG_ALERT | LOG_CRIT | LOG_ERR | LOG_WARNING | LOG_NOTICE | LOG_INFO | LOG_DEBUG; break; } return 0; } int debugopen(char *host) { if (host != NULL) openlog(LOGPREFIX, LOG_PID | LOG_PERROR, LOG_USER); return 0; } int debugclose(void) { if (_loghost != NULL) closelog(); return 0; } void debug(int level, char *format, ...) { va_list ap; va_start(ap, format); if (_loghost != NULL) vsyslog(sysloglevel(level), format, ap); else if (level > FLIDEBUG_NONE && level <= _loglevel) { fprintf(stderr, LOGPREFIX ": "); vfprintf(stderr, format, ap); fprintf(stderr, "\n"); } va_end(ap); return; } void setdebuglevel(char *host, int level) { _loghost = host; _loglevel = level; if (level == FLIDEBUG_NONE) { debugclose(); _logopen = 0; return; } if (!_logopen) { debugopen(host); _logopen = 1; } if (host != NULL) setlogmask(LOG_UPTO(sysloglevel(level))); return; } libfli1-1.7/libfli.c0000644000175000017500000012616211110507327012125 0ustar jrjr/* Copyright (c) 2000, 2002 Finger Lakes Instrumentation (FLI), L.L.C. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #include #include #include #include "libfli-libfli.h" #include "libfli-mem.h" #include "libfli-debug.h" static long devalloc(flidev_t *dev); static long devfree(flidev_t dev); static long fli_open(flidev_t *dev, char *name, long domain); static long fli_close(flidev_t dev); static long fli_freelist(char **names); flidevdesc_t *devices[MAX_OPEN_DEVICES] = {NULL,}; /*#define SHOWFUNCTIONS*/ const char* version = \ "FLI Software Development Library for " __SYSNAME__ " " __LIBFLIVER__; static long devalloc(flidev_t *dev) { int i; if (dev == NULL) return -EINVAL; for (i = 0; i < MAX_OPEN_DEVICES; i++) if (devices[i] == NULL) break; if (i == MAX_OPEN_DEVICES) return -ENODEV; if ((devices[i] = (flidevdesc_t *)xcalloc(1, sizeof(flidevdesc_t))) == NULL) return -ENOMEM; *dev = i; return 0; } static long devfree(flidev_t dev) { CHKDEVICE(dev); if (DEVICE->io_data != NULL) { debug(FLIDEBUG_WARN, "close didn't free io_data (not NULL)"); xfree(DEVICE->io_data); DEVICE->io_data = NULL; } if (DEVICE->device_data != NULL) { debug(FLIDEBUG_WARN, "close didn't free device_data (not NULL)"); xfree(DEVICE->device_data); DEVICE->device_data = NULL; } if (DEVICE->sys_data != NULL) { debug(FLIDEBUG_WARN, "close didn't free sys_data (not NULL)"); xfree(DEVICE->sys_data); DEVICE->sys_data = NULL; } if (DEVICE->name != NULL) { xfree(DEVICE->name); DEVICE->name = NULL; } xfree(DEVICE); DEVICE = NULL; return 0; } static long fli_open(flidev_t *dev, char *name, long domain) { int retval; debug(FLIDEBUG_INFO, "Entering FLIOpen()"); debug(FLIDEBUG_INFO, "Trying to open file <%s> in domain %d.", name, domain); if ((retval = devalloc(dev)) != 0) { debug(FLIDEBUG_WARN, "error devalloc() %d [%s]", retval, strerror(-retval)); return retval; } debug(FLIDEBUG_INFO, "Got device index %d", *dev); if ((retval = fli_connect(*dev, name, domain)) != 0) { debug(FLIDEBUG_WARN, "fli_connect() error %d [%s]", retval, strerror(-retval)); devfree(*dev); return retval; } if ((retval = devices[*dev]->fli_open(*dev)) != 0) { debug(FLIDEBUG_WARN, "fli_open() error %d [%s]", retval, strerror(-retval)); fli_disconnect(*dev); devfree(*dev); return retval; } return retval; } static long fli_close(flidev_t dev) { CHKDEVICE(dev); CHKFUNCTION(DEVICE->fli_close); debug(FLIDEBUG_INFO, "Closing device index: %d ", dev); DEVICE->fli_close(dev); fli_disconnect(dev); devfree(dev); return 0; } static long fli_freelist(char **names) { int i; if (names == NULL) return 0; for (i = 0; names[i] != NULL; i++) xfree(names[i]); xfree(names); return 0; } /* This is for FLI INTERNAL USE ONLY */ #ifdef WIN32 long usb_bulktransfer(flidev_t dev, int ep, void *buf, long *len); #else long linux_bulktransfer(flidev_t dev, int ep, void *buf, long *len); #define usb_bulktransfer linux_bulktransfer #endif LIBFLIAPI FLIUsbBulkIO(flidev_t dev, int ep, void *buf, long *len) { return usb_bulktransfer(dev, ep, buf, len); } /* This function is not implemented */ LIBFLIAPI FLIGrabFrame(flidev_t dev, void* buff, size_t buffsize, size_t* bytesgrabbed) { return -EFAULT; } /** Cancel an exposure for a given camera. This function cancels an exposure in progress by closing the shutter. @param dev Camera to cancel the exposure of. @return Zero on success. @return Non-zero on failure. @see FLIExposeFrame @see FLIGetExposureStatus @see FLISetExposureTime */ LIBFLIAPI FLICancelExposure(flidev_t dev) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_CANCEL_EXPOSURE, 0); } /** Close a handle to a FLI device. @param dev The device handle to be closed. @return Zero on success. @return Non-zero on failure. @see FLIOpen */ LIBFLIAPI FLIClose(flidev_t dev) { long r; #ifdef SHOWFUNCTIONS debug(FLIDEBUG_INFO, "Entering " __FUNCTION__); #endif r = fli_close(dev); #ifdef SHOWFUNCTIONS debug(FLIDEBUG_INFO, "Exiting " __FUNCTION__); #endif return r; } /** Get the array area of the given camera. This function finds the \emph{total} area of the CCD array for camera \texttt{dev}. This area is specified in terms of a upper-left point and a lower-right point. The upper-left x-coordinate is placed in \texttt{ul_x}, the upper-left y-coordinate is placed in \texttt{ul_y}, the lower-right x-coordinate is placed in \texttt{lr_x}, and the lower-right y-coordinate is placed in \texttt{lr_y}. @param dev Camera to get the array area of. @param ul_x Pointer to where the upper-left x-coordinate is to be placed. @param ul_y Pointer to where the upper-left y-coordinate is to be placed. @param lr_x Pointer to where the lower-right x-coordinate is to be placed. @param lr_y Pointer to where the lower-right y-coordinate is to be placed. @return Zero on success. @return Non-zero on failure. @see FLIGetVisibleArea @see FLISetImageArea */ LIBFLIAPI FLIGetArrayArea(flidev_t dev, long* ul_x, long* ul_y, long* lr_x, long* lr_y) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_GET_ARRAY_AREA, 4, ul_x, ul_y, lr_x, lr_y); } /** Flush rows of a given camera. This function flushes \texttt{rows} rows of camera \texttt{dev} \texttt{repeat} times. @param dev Camera to flush rows of. @param rows Number of rows to flush. @param repeat Number of times to flush each row. @return Zero on success. @return Non-zero on failure. @see FLISetNFlushes */ LIBFLIAPI FLIFlushRow(flidev_t dev, long rows, long repeat) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_FLUSH_ROWS, 2, &rows, &repeat); } /** Get firmware revision of a given device. @param dev Device to find the firmware revision of. @param fwrev Pointer to a long which will receive the firmware revision. @return Zero on success. @return Non-zero on failure. @see FLIGetModel @see FLIGetHWRevision @see FLIGetSerialNum */ LIBFLIAPI FLIGetFWRevision(flidev_t dev, long *fwrev) { CHKDEVICE(dev); *fwrev = DEVICE->devinfo.fwrev; return 0; } /** Get the hardware revision of a given device. @param dev Device to find the hardware revision of. @param hwrev Pointer to a long which will receive the hardware revision. @return Zero on success. @return Non-zero on failure. @see FLIGetModel @see FLIGetFWRevision @see FLIGetSerialNum */ LIBFLIAPI FLIGetHWRevision(flidev_t dev, long *hwrev) { CHKDEVICE(dev); *hwrev = DEVICE->devinfo.hwrev; return 0; } /** Get the current library version. This function copies up to \texttt{len - 1} characters of the current library version string followed by a terminating \texttt{NULL} character into the buffer pointed to by \texttt{ver}. @param ver Pointer to a character buffer where the library version string is to be placed. @param len The size in bytes of the buffer pointed to by \texttt{ver}. @return Zero on success. @return Non-zero on failure. */ LIBFLIAPI FLIGetLibVersion(char* ver, size_t len) { if (len > 0 && ver == NULL) return -EINVAL; if ((size_t) snprintf(ver, len, "%s", version) >= len) return -EOVERFLOW; else return 0; } /** Get the model of a given device. This function copies up to \texttt{len - 1} characters of the model string for device \texttt{dev}, followed by a terminating \texttt{NULL} character into the buffer pointed to by \texttt{model}. @param dev Device to find model of. @param model Pointer to a character buffer where the model string is to be placed. @param len The size in bytes of buffer pointed to by \texttt{model}. @return Zero on success. @return Non-zero on failure. @see FLIGetHWRevision @see FLIGetFWRevision @see FLIGetSerialNum */ LIBFLIAPI FLIGetModel(flidev_t dev, char* model, size_t len) { if (model == NULL) return -EINVAL; CHKDEVICE(dev); if (DEVICE->devinfo.model == NULL) { model[0] = '\0'; return 0; } if ((size_t) snprintf(model, len, "%s", DEVICE->devinfo.model) >= len) return -EOVERFLOW; else return 0; } /** Find the dimensions of a pixel in the array of the given device. @param dev Device to find the pixel size of. @param pixel_x Pointer to a double which will receive the size (in microns) of a pixel in the x direction. @param pixel_y Pointer to a double which will receive the size (in microns) of a pixel in the y direction. @return Zero on success. @return Non-zero on failure. @see FLIGetArrayArea @see FLIGetVisibleArea */ LIBFLIAPI FLIGetPixelSize(flidev_t dev, double *pixel_x, double *pixel_y) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_GET_PIXEL_SIZE, 2, pixel_x, pixel_y); } /** Get the visible area of the given camera. This function finds the \emph{visible} area of the CCD array for the camera \texttt{dev}. This area is specified in terms of a upper-left point and a lower-right point. The upper-left x-coordinate is placed in \texttt{ul_x}, the upper-left y-coordinate is placed in \texttt{ul_y}, the lower-right x-coordinate is placed in \texttt{lr_x}, the lower-right y-coordinate is placed in \texttt{lr_y}. @param dev Camera to get the visible area of. @param ul_x Pointer to where the upper-left x-coordinate is to be placed. @param ul_y Pointer to where the upper-left y-coordinate is to be placed. @param lr_x Pointer to where the lower-right x-coordinate is to be placed. @param lr_y Pointer to where the lower-right y-coordinate is to be placed. @return Zero on success. @return Non-zero on failure. @see FLIGetArrayArea @see FLISetImageArea */ LIBFLIAPI FLIGetVisibleArea(flidev_t dev, long* ul_x, long* ul_y, long* lr_x, long* lr_y) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_GET_VISIBLE_AREA, 4, ul_x, ul_y, lr_x, lr_y); } /** Get a handle to an FLI device. This function requires the filename and domain of the requested device. Valid device filenames can be obtained using the \texttt{FLIList()} function. An application may use any number of handles associated with the same physical device. When doing so, it is important to lock the appropriate device to ensure that multiple accesses to the same device do not occur during critical operations. @param dev Pointer to where a device handle will be placed. @param name Pointer to a string where the device filename to be opened is stored. For parallel port devices that are not probed by \texttt{FLIList()} (Windows 95/98/Me), place the address of the parallel port in a string in ascii form ie: "0x378". @param domain Domain to apply to \texttt{name} for device opening. This is a bitwise ORed combination of interface method and device type. Valid interfaces include \texttt{FLIDOMAIN_PARALLEL_PORT}, \texttt{FLIDOMAIN_USB}, \texttt{FLIDOMAIN_SERIAL}, and \texttt{FLIDOMAIN_INET}. Valid device types include \texttt{FLIDEVICE_CAMERA}, \texttt{FLIDOMAIN_FILTERWHEEL}, and \texttt{FLIDOMAIN_FOCUSER}. @return Zero on success. @return Non-zero on failure. @see FLIList @see FLIClose @see flidomain_t */ LIBFLIAPI FLIOpen(flidev_t *dev, char *name, flidomain_t domain) { long r; #ifdef SHOWFUNCTIONS debug(FLIDEBUG_INFO, "Entering " __FUNCTION__); #endif r = fli_open(dev, name, domain); #ifdef SHOWFUNCTIONS debug(FLIDEBUG_INFO, "Exiting " __FUNCTION__); #endif return r; } /** Enable debugging of API operations and communications. Use this function in combination with FLIDebug to assist in diagnosing problems that may be encountered during programming. When usings Microsoft Windows operating systems, creating an empty file C:\\FLIDBG.TXT will override this option. All debug output will then be directed to this file. @param host Name of the file to send debugging information to. This parameter is ignored under Linux where \texttt{syslog(3)} is used to send debug messages (see \texttt{syslog.conf(5)} for how to configure syslogd). @param level Debug level. A value of \texttt{FLIDEBUG_NONE} disables debugging. Values of \texttt{FLIDEBUG_FAIL}, \texttt{FLIDEBUG_WARN}, and \texttt{FLIDEBUG_INFO} enable progressively more verbose debug messages. @return Zero on success. @return Non-zero on failure. */ LIBFLIAPI FLISetDebugLevel(char *host, flidebug_t level) { setdebuglevel(host, level); return 0; } /** Set the exposure time for a camera. This function sets the exposure time for the camera \texttt{dev} to \texttt{exptime} msec. @param dev Camera to set the exposure time of. @param exptime Exposure time in msec. @return Zero on success. @return Non-zero on failure. @see FLIExposeFrame @see FLICancelExposure @see FLIGetExposureStatus */ LIBFLIAPI FLISetExposureTime(flidev_t dev, long exptime) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_SET_EXPOSURE_TIME, 1, &exptime); } /** Set the horizontal bin factor for a given camera. This function sets the horizontal bin factor for the camera \texttt{dev} to \texttt{hbin}. The valid range of the \texttt{hbin} parameter is from 1 to 16. @param dev Camera to set horizontal bin factor of. @param hbin Horizontal bin factor. @return Zero on success. @return Non-zero on failure. @see FLISetVBin @see FLISetImageArea */ LIBFLIAPI FLISetHBin(flidev_t dev, long hbin) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_SET_HBIN, 1, &hbin); } /** Set the frame type for a given camera. This function sets the frame type for camera \texttt{dev} to \texttt{frametype}. The \texttt{frametype} parameter is either \texttt{FLI_FRAME_TYPE_NORMAL} for a normal frame where the shutter opens or \texttt{FLI_FRAME_TYPE_DARK} for a dark frame where the shutter remains closed. @param cam Camera to set the frame type of. @param frametype Frame type: \texttt{FLI_FRAME_TYPE_NORMAL} or \texttt{FLI_FRAME_TYPE_DARK}. @return Zero on success. @return Non-zero on failure. @see fliframe_t @see FLIExposeFrame */ LIBFLIAPI FLISetFrameType(flidev_t dev, fliframe_t frametype) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_SET_FRAME_TYPE, 1, &frametype); } /** Get the cooler power level. The function places the current cooler power in percent in the location pointed to by \texttt{power}. @param dev Camera to find the cooler power of. @param timeleft Pointer to where the cooler power (in percent) will be placed. @return Zero on success. @return Non-zero on failure. @see FLISetTemperature @see FLIGetTemperature */ LIBFLIAPI FLIGetCoolerPower(flidev_t dev, double *power) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_GET_COOLER_POWER, 1, power); } LIBFLIAPI FLIGetCameraModeString(flidev_t dev, flimode_t mode_index, char *mode_string, size_t siz) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_GET_CAMERA_MODE_STRING, 3, mode_index, mode_string, siz); } LIBFLIAPI FLIGetCameraMode(flidev_t dev, flimode_t *mode_index) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_GET_CAMERA_MODE, 1, mode_index); } LIBFLIAPI FLISetCameraMode(flidev_t dev, flimode_t mode_index) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_SET_CAMERA_MODE, 1, mode_index); } LIBFLIAPI FLIGetDeviceStatus(flidev_t dev, long *camera_status) { CHKDEVICE(dev); *camera_status = 0xffffffff; return DEVICE->fli_command(dev, FLI_GET_STATUS, 1, camera_status); } /** Set the image area for a given camera. This function sets the image area for camera \texttt{dev} to an area specified in terms of a upper-left point and a lower-right point. The upper-left x-coordinate is \texttt{ul_x}, the upper-left y-coordinate is \texttt{ul_y}, the lower-right x-coordinate is \texttt{lr_x}, and the lower-right y-coordinate is \texttt{lr_y}. Note that the given lower-right coordinate must take into account the horizontal and vertical bin factor settings, but the upper-left coordinate is absolute. In other words, the lower-right coordinate used to set the image area is a virtual point $(lr_x', lr_y')$ determined by: \[ lr_x' = ul_x + (lr_x - ul_x) / hbin \] \[ lr_y' = ul_y + (lr_y - ul_y) / vbin \] Where $(lr_x', lr_y')$ is the coordinate to pass to the \texttt{FLISetImageArea} function, $(ul_x, ul_y)$ and $(lr_x, lr_y)$ are the absolute coordinates of the desired image area, $hbin$ is the horizontal bin factor, and $vbin$ is the vertical bin factor. @param dev Camera to set image area of. @param ul_x Upper-left x-coordinate of image area. @param ul_y Upper-left y-coordinate of image area. @param lr_x Lower-right x-coordinate of image area ($lr_x'$ from above). @param lr_y Lower-right y-coordinate of image area ($lr_y'$ from above). @return Zero on success. @return Non-zero on failure. @see FLIGetVisibleArea @see FLIGetArrayArea */ LIBFLIAPI FLISetImageArea(flidev_t dev, long ul_x, long ul_y, long lr_x, long lr_y) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_SET_IMAGE_AREA, 4, &ul_x, &ul_y, &lr_x, &lr_y); } /** Set the vertical bin factor for a given camera. This function sets the vertical bin factor for the camera \texttt{dev} to \texttt{vbin}. The valid range of the \texttt{vbin} parameter is from 1 to 16. @param dev Camera to set vertical bin factor of. @param vbin Vertical bin factor. @return Zero on success. @return Non-zero on failure. @see FLISetHBin @see FLISetImageArea */ LIBFLIAPI FLISetVBin(flidev_t dev, long vbin) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_SET_VBIN, 1, &vbin); } /** Find the remaining exposure time of a given camera. This functions places the remaining exposure time (in milliseconds) in the location pointed to by \texttt{timeleft}. @param dev Camera to find the remaining exposure time of. @param timeleft Pointer to where the remaining exposure time (in milliseonds) will be placed. @return Zero on success. @return Non-zero on failure. @see FLIExposeFrame @see FLICancelExposure @see FLISetExposureTime */ LIBFLIAPI FLIGetExposureStatus(flidev_t dev, long *timeleft) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_GET_EXPOSURE_STATUS, 1, timeleft); } /** Set the temperature of a given camera. This function sets the temperature of the CCD camera \texttt{dev} to \texttt{temperature} degrees Celsius. The valid range of the \texttt{temperature} parameter is from -55 C to 45 C. @param dev Camera device to set the temperature of. @param temperature Temperature in Celsius to set CCD camera cold finger to. @return Zero on success. @return Non-zero on failure. @see FLIGetTemperature */ LIBFLIAPI FLISetTemperature(flidev_t dev, double temperature) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_SET_TEMPERATURE, 1, &temperature); } /** Get the temperature of a given camera. This function places the temperature of the CCD camera cold finger of device \texttt{dev} in the location pointed to by \texttt{temperature}. @param dev Camera device to get the temperature of. @param temperature Pointer to where the temperature will be placed. @return Zero on success. @return Non-zero on failure. @see FLISetTemperature */ LIBFLIAPI FLIGetTemperature(flidev_t dev, double *temperature) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_GET_TEMPERATURE, 1, temperature); } /** Grab a row of an image. This function grabs the next available row of the image from camera device \texttt{dev}. The row of width \texttt{width} is placed in the buffer pointed to by \texttt{buff}. The size of the buffer pointed to by \texttt{buff} must take into account the bit depth of the image, meaning the buffer size must be at least \texttt{width} bytes for an 8-bit image, and at least 2*\texttt{width} for a 16-bit image. @param dev Camera whose image to grab the next available row from. @param buff Pointer to where the next available row will be placed. @param width Row width in pixels. @return Zero on success. @return Non-zero on failure. @see FLIGrabFrame */ LIBFLIAPI FLIGrabRow(flidev_t dev, void *buff, size_t width) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_GRAB_ROW, 2, buff, &width); } /** Expose a frame for a given camera. This function exposes a frame according to the settings (image area, exposure time, bit depth, etc.) of camera \texttt{dev}. The settings of \texttt{dev} must be valid for the camera device. They are set by calling the appropriate set library functions. This function returns after the exposure has started. @param dev Camera to expose the frame of. @return Zero on success. @return Non-zero on failure. @see FLISetExposureTime @see FLISetFrameType @see FLISetImageArea @see FLISetHBin @see FLISetVBin @see FLISetNFlushes @see FLISetBitDepth @see FLIGrabFrame @see FLICancelExposure @see FLIGetExposureStatus */ LIBFLIAPI FLIExposeFrame(flidev_t dev) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_EXPOSE_FRAME, 0); } /** Set the gray-scale bit depth for a given camera. This function sets the gray-scale bit depth of camera \texttt{dev} to \texttt{bitdepth}. The \texttt{bitdepth} parameter is either \texttt{FLI_MODE_8BIT} for 8-bit mode or \texttt{FLI_MODE_16BIT} for 16-bit mode. Many cameras do not support this mode. @param dev Camera to set the bit depth of. @param bitdepth Gray-scale bit depth: \texttt{FLI_MODE_8BIT} or \texttt{FLI_MODE_16BIT}. @return Zero on success. @return Non-zero on failure. @see flibitdepth_t @see FLIExposeFrame */ LIBFLIAPI FLISetBitDepth(flidev_t dev, flibitdepth_t bitdepth) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_SET_BIT_DEPTH, 1, &bitdepth); } /** Set the number of flushes for a given camera. This function sets the number of times the CCD array of camera \texttt{dev} is flushed by the FLIExposeFrame \emph{before} exposing a frame to \texttt{nflushes}. The valid range of the \texttt{nflushes} parameter is from 0 to 16. Some FLI cameras support background flushing. Background flushing continuously flushes the CCD eliminating the need for pre-exposure flushing. @param dev Camera to set the number of flushes of. @param nflushes Number of times to flush CCD array before an exposure. @return Zero on success. @return Non-zero on failure. @see FLIFlushRow @see FLIExposeFrame @see FLIControlBackgroundFlush */ LIBFLIAPI FLISetNFlushes(flidev_t dev, long nflushes) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_SET_FLUSHES, 1, &nflushes); } /** Read the I/O port of a given camera. This function reads the I/O port on camera \texttt{dev} and places the value in the location pointed to by \texttt{ioportset}. @param dev Camera to read the I/O port of. @param ioportset Pointer to where the I/O port data will be stored. @return Zero on success. @return Non-zero on failure. @see FLIWriteIOPort @see FLIConfigureIOPort */ LIBFLIAPI FLIReadIOPort(flidev_t dev, long *ioportset) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_READ_IOPORT, 1, ioportset); } /** Write to the I/O port of a given camera. This function writes the value \texttt{ioportset} to the I/O port on camera \texttt{dev}. @param dev Camera to write I/O port of. @param ioportset Data to be written to the I/O port. @return Zero on success. @return Non-zero on failure. @see FLIReadIOPort @see FLIConfigureIOPort */ LIBFLIAPI FLIWriteIOPort(flidev_t dev, long ioportset) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_WRITE_IOPORT, 1, &ioportset); } /** Configure the I/O port of a given camera. This function configures the I/O port on camera \texttt{dev} with the value \texttt{ioportset}. The I/O configuration of each pin on a given camera is determined by the value of \texttt{ioportset}. Setting a respective I/O bit enables the port bit for output while clearing an I/O bit enables to port bit for input. By default, all I/O ports are configured as inputs. @param dev Camera to configure the I/O port of. @param ioportset Data to configure the I/O port with. @return Zero on success. @return Non-zero on failure. @see FLIReadIOPort @see FLIWriteIOPort */ LIBFLIAPI FLIConfigureIOPort(flidev_t dev, long ioportset) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_CONFIGURE_IOPORT, 1, &ioportset); } /** Lock a specified device. This function establishes an exclusive lock (mutex) on the given device to prevent access to the device by any other function or process. @param dev Device to lock. @return Zero on success. @return Non-zero on failure. @see FLIUnlockDevice */ LIBFLIAPI FLILockDevice(flidev_t dev) { CHKDEVICE(dev); return DEVICE->fli_lock(dev); } /** Unlock a specified device. This function releases a previously established exclusive lock (mutex) on the given device to allow access to the device by any other function or process. @param dev Device to unlock. @return Zero on success. @return Non-zero on failure. @see FLILockDevice */ LIBFLIAPI FLIUnlockDevice(flidev_t dev) { CHKDEVICE(dev); return DEVICE->fli_unlock(dev); } /** Control the shutter on a given camera. This function controls the shutter function on camera \texttt{dev} according to the \texttt{shutter} parameter. @param dev Device to control the shutter of. @param shutter How to control the shutter. A value of \texttt{FLI_SHUTTER_CLOSE} closes the shutter and \texttt{FLI_SHUTTER_OPEN} opens the shutter. \texttt{FLI_SHUTTER_EXTERNAL_TRIGGER_LOW}, \texttt{FLI_SHUTTER_EXTERNAL_TRIGGER} causes the exposure to begin only when a logic LOW is detected on I/O port bit 0. \texttt{FLI_SHUTTER_EXTERNAL_TRIGGER_HIGH} causes the exposure to begin only when a logic HIGH is detected on I/O port bit 0. This setting may not be available on all cameras. @return Zero on success. @return Non-zero on failure. @see flishutter_t */ LIBFLIAPI FLIControlShutter(flidev_t dev, flishutter_t shutter) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_CONTROL_SHUTTER, 1, &shutter); } /* The following function is for internal use only, improper use of this function can lead to permanent damage of the attached device. */ LIBFLIAPI FLISetDAC(flidev_t dev, unsigned long dacset) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_SET_DAC, 1, &dacset); } /** Enables background flushing of CCD array. This function enables the background flushing of the CCD array camera \texttt{dev} according to the \texttt{bgflush} parameter. Note that this function may not succeed on all FLI products as this feature may not be available. @param dev Device to control the background flushing of. @param bgflush Enables or disables background flushing. A value of \texttt{FLI_BGFLUSH_START} begins background flushing. It is important to note that background flushing is stopped whenever \texttt{FLIExposeFrame()} or \texttt{FLIControlShutter()} are called. \texttt{FLI_BGFLUSH_STOP} stops all background flush activity. @return Zero on success. @return Non-zero on failure. @see flibgflush_t */ LIBFLIAPI FLIControlBackgroundFlush(flidev_t dev, flibgflush_t bgflush) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_CONTROL_BGFLUSH, 1, &bgflush); } /** List available devices. This function returns a pointer to a NULL terminated list of device names. The pointer should be freed later with \texttt{FLIFreeList()}. Each device name in the returned list includes the filename needed by \texttt{FLIOpen()}, a separating semicolon, followed by the model name or user assigned device name. @param domain Domain to list the devices of. This is a bitwise ORed combination of interface method and device type. Valid interfaces include \texttt{FLIDOMAIN_PARALLEL_PORT}, \texttt{FLIDOMAIN_USB}, \texttt{FLIDOMAIN_SERIAL}, and \texttt{FLIDOMAIN_INET}. Valid device types include \texttt{FLIDEVICE_CAMERA}, \texttt{FLIDOMAIN_FILTERWHEEL}, and \texttt{FLIDOMAIN_FOCUSER}. @param names Pointer to where the device name list will be placed. @return Zero on success. @return Non-zero on failure. @see flidomain_t @see FLIFreeList @see FLIOpen */ LIBFLIAPI FLIList(flidomain_t domain, char ***names) { debug(FLIDEBUG_INFO, "FLIList() domain %04x", domain); return fli_list(domain, names); } /** Free a previously generated device list. Use this function after \texttt{FLIList()} to free the list of device names. @param names Pointer to the list. @return Zero on success. @return Non-zero on failure. @see FLIList */ LIBFLIAPI FLIFreeList(char **names) { return fli_freelist(names); } /** Set the filter wheel position of a given device. Use this function to set the filter wheel position of \texttt{dev} to \texttt{filter}. @param dev Filter wheel device handle. @param filter Desired filter wheel position. @return Zero on success. @return Non-zero on failure. @see FLIGetFilterPos */ LIBFLIAPI FLISetFilterPos(flidev_t dev, long filter) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_SET_FILTER_POS, 1, &filter); } /** Get the filter wheel position of a given device. Use this function to get the filter wheel position of \texttt{dev}. @param dev Filter wheel device handle. @param filter Pointer to where the filter wheel position will be placed. @return Zero on success. @return Non-zero on failure. @see FLISetFilterPos */ LIBFLIAPI FLIGetFilterPos(flidev_t dev, long *filter) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_GET_FILTER_POS, 1, filter); } /** Get the number of motor steps remaining. Use this function to determine if the stepper motor of \texttt{dev} is still moving. @param dev Filter wheel device handle. @param filter Pointer to where the number of remaning steps will be placed. @return Zero on success. @return Non-zero on failure. @see FLISetFilterPos */ LIBFLIAPI FLIGetStepsRemaining(flidev_t dev, long *steps) { long r; CHKDEVICE(dev); #ifdef SHOWFUNCTIONS debug(FLIDEBUG_INFO, "Entering " __FUNCTION__); #endif r = DEVICE->fli_command(dev, FLI_GET_STEPS_REMAINING, 1, steps); #ifdef SHOWFUNCTIONS debug(FLIDEBUG_INFO, "Exiting " __FUNCTION__); #endif return r; } /** Get the filter wheel filter count of a given device. Use this function to get the filter count of filter wheel \texttt{dev}. @param dev Filter wheel device handle. @param filter Pointer to where the filter wheel filter count will be placed. @return Zero on success. @return Non-zero on failure. */ LIBFLIAPI FLIGetFilterCount(flidev_t dev, long *filter) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_GET_FILTER_COUNT, 1, filter); } /** Step the filter wheel or focuser motor of a given device. Use this function to move the focuser or filter wheel \texttt{dev} by an amount \texttt{steps}. This function is non-blocking. @param dev Filter wheel or focuser device handle. @param steps Number of steps to move the focuser or filter wheel. @return Zero on success. @return Non-zero on failure. @see FLIGetStepperPosition */ LIBFLIAPI FLIStepMotorAsync(flidev_t dev, long steps) { long r; CHKDEVICE(dev); #ifdef SHOWFUNCTIONS debug(FLIDEBUG_INFO, "Entering " __FUNCTION__); #endif r = DEVICE->fli_command(dev, FLI_STEP_MOTOR_ASYNC, 1, &steps); #ifdef SHOWFUNCTIONS debug(FLIDEBUG_INFO, "Exiting " __FUNCTION__); #endif return r; } /** Step the filter wheel or focuser motor of a given device. Use this function to move the focuser or filter wheel \texttt{dev} by an amount \texttt{steps}. @param dev Filter wheel or focuser device handle. @param steps Number of steps to move the focuser or filter wheel. @return Zero on success. @return Non-zero on failure. @see FLIGetStepperPosition */ LIBFLIAPI FLIStepMotor(flidev_t dev, long steps) { long r; CHKDEVICE(dev); #ifdef SHOWFUNCTIONS debug(FLIDEBUG_INFO, "Entering " __FUNCTION__); #endif r = DEVICE->fli_command(dev, FLI_STEP_MOTOR, 1, &steps); #ifdef SHOWFUNCTIONS debug(FLIDEBUG_INFO, "Exiting " __FUNCTION__); #endif return r; } /** Get the stepper motor position of a given device. Use this function to read the stepper motor position of filter wheel or focuser \texttt{dev}. @param dev Filter wheel or focuser device handle. @param position Pointer to where the postion of the stepper motor will be placed. @return Zero on success. @return Non-zero on failure. @see FLIStepMotor */ LIBFLIAPI FLIGetStepperPosition(flidev_t dev, long *position) { long r; CHKDEVICE(dev); #ifdef SHOWFUNCTIONS debug(FLIDEBUG_INFO, "Entering " __FUNCTION__); #endif r = DEVICE->fli_command(dev, FLI_GET_STEPPER_POS, 1, position); #ifdef SHOWFUNCTIONS debug(FLIDEBUG_INFO, "Exiting " __FUNCTION__); #endif return r; } /** Home focuser \texttt{dev}. The home position is closed as far as mechanically possiable. @param dev Focuser device handle. @return Zero on success. @return Non-zero on failure. */ LIBFLIAPI FLIHomeFocuser(flidev_t dev) { long r; CHKDEVICE(dev); #ifdef SHOWFUNCTIONS debug(FLIDEBUG_INFO, "Entering " __FUNCTION__); #endif r = DEVICE->fli_command(dev, FLI_HOME_FOCUSER, 0); #ifdef SHOWFUNCTIONS debug(FLIDEBUG_INFO, "Exiting " __FUNCTION__); #endif return r; } /** Retreive the maximum extent for FLI focuser \texttt{dev}. @param dev Focuser device handle. @param extent Pointer to where the maximum extent of the focuser will be placed. @return Zero on success. @return Non-zero on failure. */ LIBFLIAPI FLIGetFocuserExtent(flidev_t dev, long *extent) { long r; CHKDEVICE(dev); #ifdef SHOWFUNCTIONS debug(FLIDEBUG_INFO, "Entering " __FUNCTION__); #endif r = DEVICE->fli_command(dev, FLI_GET_FOCUSER_EXTENT, 1, extent); #ifdef SHOWFUNCTIONS debug(FLIDEBUG_INFO, "Exiting " __FUNCTION__); #endif return r; } /** Retreive temperature from the FLI focuser \texttt{dev}. Valid channels are \texttt{FLI_TEMPERATURE_INTERNAL} and \texttt{FLI_TEMPERATURE_EXTERNAL}. @param dev Focuser device handle. @param channel Channel to be read. @param extent Pointer to where the channel temperature will be placed. @return Zero on success. @return Non-zero on failure. */ LIBFLIAPI FLIReadTemperature(flidev_t dev, flichannel_t channel, double *temperature) { long r; CHKDEVICE(dev); #ifdef SHOWFUNCTIONS debug(FLIDEBUG_INFO, "Entering " __FUNCTION__); #endif r = DEVICE->fli_command(dev, FLI_READ_TEMPERATURE, 2, channel, temperature); #ifdef SHOWFUNCTIONS debug(FLIDEBUG_INFO, "Exiting " __FUNCTION__); #endif return r; } /* This stuff is used by the next four functions */ typedef struct list { char *filename; char *name; long domain; struct list *next; } list_t; static list_t *firstdevice = NULL; static list_t *currentdevice = NULL; /** Creates a list of all devices within a specified \texttt{domain}. Use \texttt{FLIDeleteList()} to delete the list created with this function. This function is the first called begin the iteration through the list of current FLI devices attached. @param domain Domain to search for devices, set to zero to search all domains. This parameter must contain the device type. @return Zero on success. @return Non-zero on failure. @see FLIDeleteList @see FLIListFirst @see FLIListNext */ LIBFLIAPI FLICreateList(flidomain_t domain) { char **list; flidomain_t domord[5]; int i, j, k; for (i = 0; i < 5; i++) { domord[i] = 0; } if (firstdevice != NULL) { FLIDeleteList(); } currentdevice = NULL; if ((domain & 0x00ff) != 0) { domord[0] = domain; } else { domord[0] = domain | FLIDOMAIN_PARALLEL_PORT; domord[1] = domain | FLIDOMAIN_USB; domord[2] = domain | FLIDOMAIN_SERIAL; } i = 0; while (domord[i] != 0) { debug(FLIDEBUG_INFO, "Searching for domain 0x%04x.", domord[i]); FLIList(domord[i], &list); if (list != NULL) { j = 0; while (list[j] != NULL) { if (firstdevice == NULL) { firstdevice = (list_t *)xmalloc(sizeof(list_t)); if (firstdevice == NULL) return -ENOMEM; currentdevice = firstdevice; } else { currentdevice->next = (list_t *) xmalloc(sizeof(list_t)); if (currentdevice->next == NULL) return -ENOMEM; currentdevice = currentdevice->next; } currentdevice->next = NULL; currentdevice->domain = domord[i]; currentdevice->filename = NULL; currentdevice->name = NULL; k = 0; while (k < (int) strlen(list[j])) { if (list[j][k] == ';') { currentdevice->filename = (char *) xmalloc(k+1); if (currentdevice->filename != NULL) { strncpy(currentdevice->filename, list[j], k); currentdevice->filename[k] = '\0'; } currentdevice->name = (char *) xmalloc(strlen(&list[j][k+1]) + 1); if (currentdevice->name != NULL) { strcpy(currentdevice->name, &list[j][k+1]); } break; } k++; } j++; } FLIFreeList(list); } i++; } return 0; } /** Deletes a list of devices created by \texttt{FLICreateList()}. @return Zero on success. @return Non-zero on failure. @see FLICreateList @see FLIListFirst @see FLIListNext */ LIBFLIAPI FLIDeleteList(void) { list_t *dev = firstdevice; list_t *last; while (dev != NULL) { if (dev->filename != NULL) xfree(dev->filename); if (dev->name != NULL) xfree(dev->name); last = dev; dev = dev->next; xfree(last); } firstdevice = NULL; currentdevice = NULL; return 0; } /** Obtains the first device in the list. Use this function to get the first \texttt{domain}, \texttt{filename} and \texttt{name} from the list of attached FLI devices created using the function \texttt{FLICreateList()}. Use \texttt{FLIListNext()} to obtain more found devices. @param domain Pointer to where to domain of the device will be placed. @param filename Pointer to where the filename of the device will be placed. @param fnlen Length of the supplied buffer to hold the filename. @param name Pointer to where the name of the device will be placed. @param namelen Length of the supplied buffer to hold the name. @return Zero on success. @return Non-zero on failure. @see FLICreateList @see FLIDeleteList @see FLIListNext */ LIBFLIAPI FLIListFirst(flidomain_t *domain, char *filename, size_t fnlen, char *name, size_t namelen) { currentdevice = firstdevice; return FLIListNext(domain, filename, fnlen, name, namelen); } /** Obtains the next device in the list. Use this function to get the next \texttt{domain}, \texttt{filename} and \texttt{name} from the list of attached FLI devices created using the function \texttt{FLICreateList()}. @param domain Pointer to where to domain of the device will be placed. @param filename Pointer to where the filename of the device will be placed. @param fnlen Length of the supplied buffer to hold the filename. @param name Pointer to where the name of the device will be placed. @param namelen Length of the supplied buffer to hold the name. @return Zero on success. @return Non-zero on failure. @see FLICreateList @see FLIDeleteList @see FLIListFirst */ LIBFLIAPI FLIListNext(flidomain_t *domain, char *filename, size_t fnlen, char *name, size_t namelen) { if (currentdevice == NULL) { *domain = 0; filename[0] = '\0'; name[0] = '\0'; return -EBADF; } *domain = currentdevice->domain; strncpy(filename, currentdevice->filename, fnlen); filename[fnlen-1] = '\0'; strncpy(name, currentdevice->name, namelen); name[namelen-1] = '\0'; currentdevice = currentdevice->next; return 0; } libfli1-1.7/fliusb_ioctl.h0000644000175000017500000000566411110507327013352 0ustar jrjr/* Copyright (c) 2005 Finger Lakes Instrumentation (FLI), L.L.C. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), L.L.C. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifndef _FLIUSB_IOCTL_H_ #define _FLIUSB_IOCTL_H_ #include /* Structure to describe bulk transfers */ typedef struct { u_int8_t ep; void *buf; size_t count; unsigned int timeout; /* in msec */ } fliusb_bulktransfer_t; /* 8-bit special value to identify ioctl 'type' */ #define FLIUSB_IOC_TYPE 0xf1 /* Recognized ioctl commands */ #define FLIUSB_GETRDEPADDR _IOR(FLIUSB_IOC_TYPE, 1, u_int8_t) #define FLIUSB_SETRDEPADDR _IOW(FLIUSB_IOC_TYPE, 2, u_int8_t) #define FLIUSB_GETWREPADDR _IOR(FLIUSB_IOC_TYPE, 3, u_int8_t) #define FLIUSB_SETWREPADDR _IOW(FLIUSB_IOC_TYPE, 4, u_int8_t) #define FLIUSB_GETBUFFERSIZE _IOR(FLIUSB_IOC_TYPE, 5, size_t) #define FLIUSB_SETBUFFERSIZE _IOW(FLIUSB_IOC_TYPE, 6, size_t) #define FLIUSB_GETTIMEOUT _IOR(FLIUSB_IOC_TYPE, 7, unsigned int) #define FLIUSB_SETTIMEOUT _IOW(FLIUSB_IOC_TYPE, 8, unsigned int) #define FLIUSB_BULKREAD _IOW(FLIUSB_IOC_TYPE, 9, fliusb_bulktransfer_t) #define FLIUSB_BULKWRITE _IOW(FLIUSB_IOC_TYPE, 10, fliusb_bulktransfer_t) #define FLIUSB_GET_DEVICE_DESCRIPTOR _IOR(FLIUSB_IOC_TYPE, 11, struct usb_device_descriptor) #define FLIUSB_IOC_MAX 11 #endif /* _FLIUSB_IOCTL_H_ */ libfli1-1.7/CMakeLists.txt0000644000175000017500000000131611110507327013251 0ustar jrjr#this is just a basic CMakeLists.txt, for more information see the cmake manpage cmake_minimum_required(VERSION 2.4.7) ADD_DEFINITIONS(-Wall -O2) set(fli_LIB_SRCS libfli.c libfli-camera.c libfli-camera-parport.c libfli-camera-usb.c libfli-filter-focuser.c libfli-mem.c libfli-serial.c libfli-sys.c libfli-usb.c libfli-debug.c libfli-parport.c libfli-usb-sys.c ) #build a shared library ADD_LIBRARY(fli SHARED ${fli_LIB_SRCS}) set_target_properties(fli PROPERTIES VERSION 1.7 SOVERSION 1) #need to link to some other libraries ? just add them here TARGET_LINK_LIBRARIES(fli) #add an install target here INSTALL(FILES libfli.h DESTINATION include) INSTALL(TARGETS fli LIBRARY DESTINATION lib${LIB_POSTFIX}) libfli1-1.7/libfli-usb.h0000644000175000017500000000542611110507327012720 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifndef _LIBFLI_USB_H_ #define _LIBFLI_USB_H_ #if defined(__linux__) #define unix_bulkwrite linux_bulkwrite #define unix_bulkread linux_bulkread #define unix_usb_connect linux_usb_connect #define unix_usb_disconnect linux_usb_disconnect #define unix_bulktransfer linux_bulktransfer #elif defined(__FreeBSD__) || defined(__NetBSD__) #define unix_bulkwrite bsd_bulkwrite #define unix_bulkread bsd_bulkread #define unix_usb_connect bsd_usb_connect #define unix_usb_disconnect bsd_usb_disconnect #define unix_bulktransfer bsd_bulktransfer #else #error "Unknown system" #endif long unix_bulkwrite(flidev_t dev, void *buf, long *wlen); long unix_bulkread(flidev_t dev, void *buf, long *rlen); long unix_usbio(flidev_t dev, void *buf, long *wlen, long *rlen); long unix_usb_connect(flidev_t dev, fli_unixio_t *io, char *name); long unix_usb_disconnect(flidev_t dev); long unix_bulktransfer(flidev_t dev, int ep, void *buf, long *len); #define usb_bulktransfer unix_bulktransfer /* XXX */ #endif /* _LIBFLI_USB_H_ */ libfli1-1.7/LICENSE.BSD0000644000175000017500000000225011110507327012123 0ustar jrjrRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. libfli1-1.7/libfli-filter-focuser.h0000644000175000017500000000525411110507327015057 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifndef _FLI_FILTER_FOCUSER_H_ #define _FLI_FILTER_FOCUSER_H_ #define FLI_FILTERPOSITION_HOME (-1) /* Filter wheel and focuser parameters */ typedef struct _flifilterfocuserdata_t { long tableindex; long stepspersec; long currentslot; long numslots; long numtempsensors; long extent; long hwtype; } flifilterfocuserdata_t; typedef struct { int n_pos; int n_offset; int n_steps[32]; } wheeldata_t; long fli_filter_focuser_open(flidev_t dev); #define fli_filter_open fli_filter_focuser_open #define fli_focuser_open fli_filter_focuser_open long fli_filter_focuser_close(flidev_t dev); #define fli_filter_close fli_filter_focuser_close #define fli_focuser_close fli_filter_focuser_close long fli_filter_command(flidev_t dev, int cmd, int argc, ...); long fli_focuser_command(flidev_t dev, int cmd, int argc, ...); long fli_filter_focuser_probe(flidev_t dev); #endif /* _FLI_FILTER_FOCUSER_H_ */ libfli1-1.7/libfli-mem.c0000644000175000017500000001445111110507327012676 0ustar jrjr/* Copyright (c) 2000, 2002 Finger Lakes Instrumentation (FLI), L.L.C. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifdef __linux__ #define _XOPEN_SOURCE 600 #define _GNU_SOURCE #endif /* __linux__ */ #include #include #include #include #include "libfli-libfli.h" #include "libfli-mem.h" #define DEFAULT_NUM_POINTERS (1024) static struct _mem_ptrs { void **pointers; int total; int used; } allocated = {NULL, 0, 0}; static void *saveptr(void *ptr) { int i, err = 0; if (allocated.used + 1 > allocated.total) { void **tmp; int newtotal; if (allocated.total == 0) newtotal = DEFAULT_NUM_POINTERS; else newtotal = 2 * allocated.total; if ((tmp = realloc(allocated.pointers, newtotal * sizeof(void **))) == NULL) { err = 1; goto done; } allocated.pointers = tmp; memset(allocated.pointers + allocated.total, 0, (newtotal - allocated.total) * sizeof(void **)); allocated.total = newtotal; } for (i = 0; i < allocated.total; i++) if (allocated.pointers[i] == NULL) break; if (i == allocated.total) { /* This shouldn't happen */ debug(FLIDEBUG_WARN, "Internal memory allocation error"); err = 1; goto done; } allocated.pointers[i] = ptr; allocated.used++; done: if (err) { free(ptr); return NULL; } return ptr; } static void **findptr(void *ptr) { int i; for (i = 0; i < allocated.total; i++) if (allocated.pointers[i] == ptr) return &allocated.pointers[i]; debug(FLIDEBUG_WARN, "Invalid pointer not found: %p", ptr); return NULL; } static int deleteptr(void *ptr) { void **allocatedptr; if ((allocatedptr = findptr(ptr)) == NULL) return -1; *allocatedptr = NULL; allocated.used--; return 0; } void *xmalloc(size_t size) { void *ptr; if ((ptr = malloc(size)) == NULL) return NULL; return saveptr(ptr); } void *xcalloc(size_t nmemb, size_t size) { void *ptr; if ((ptr = calloc(nmemb, size)) == NULL) return NULL; return saveptr(ptr); } #ifdef __linux__ void *xmemalign(size_t alignment, size_t size) { int err; void *ptr; if ((err = posix_memalign(&ptr, alignment, size))) { debug(FLIDEBUG_WARN, "posix_memalign() failed: %d", err); return NULL; } return saveptr(ptr); } #endif /* __linux__ */ void xfree(void *ptr) { if (deleteptr(ptr)) return; free(ptr); return; } void *xrealloc(void *ptr, size_t size) { void **allocatedptr, *tmp; if ((allocatedptr = findptr(ptr)) == NULL) return NULL; if ((tmp = realloc(ptr, size)) == NULL) return NULL; *allocatedptr = tmp; return tmp; } int xfree_all(void) { int i; int freed = 0; for (i = 0; i < allocated.total; i++) { if (allocated.pointers[i] != NULL) { free(allocated.pointers[i]); allocated.pointers[i] = NULL; allocated.used--; freed++; } } if (allocated.used != 0) debug(FLIDEBUG_WARN, "Internal memory handling error"); if (allocated.pointers != NULL) free(allocated.pointers); allocated.pointers = NULL; allocated.used = 0; allocated.total = 0; return freed; } char *xstrdup(const char *s) { char *tmp; #ifdef WIN32 #define strdup _strdup #endif if ((tmp = strdup(s)) == NULL) return NULL; return saveptr(tmp); } char *xstrndup(const char *s, size_t siz) { char *tmp; size_t len; if (strlen(s) > siz) len = siz; else len = strlen(s); tmp = (char *) xmalloc(len + 1); if (tmp == NULL) return NULL; strncpy(tmp, s, len); tmp[len] = '\0'; return tmp; } #ifdef __linux__ int xasprintf(char **strp, const char *fmt, ...) { va_list ap; char *tmp; int err; va_start(ap, fmt); if ((err = vasprintf(&tmp, fmt, ap)) < 0) goto done; if (saveptr(tmp) == NULL) err = -1; done: va_end(ap); return err; } #else int xasprintf(char **strp, const char *fmt, ...) { va_list ap; char *p; int n, size = 100; /* Guess we need no more than 100 bytes. */ if ((p = (char *) xmalloc (size)) == NULL) return (-1); while (1) { /* Try to print in the allocated space. */ va_start(ap, fmt); #ifdef WIN32 n = _vsnprintf (p, size, fmt, ap); #else n = vsnprintf (p, size, fmt, ap); #endif va_end(ap); /* If that worked, send the string. */ if (n > -1 && n < size) { *strp = p; return n; } /* Else try again with more space. */ if (n > -1) /* glibc 2.1 */ size = n + 1; /* precisely what is needed */ else /* glibc 2.0 */ size *= 2; /* twice the old size */ if ((p = (char *) xrealloc (p, size)) == NULL) return (-1); } } #endif libfli1-1.7/fli_ioctl.h0000644000175000017500000001047711110507327012636 0ustar jrjr/* Copyright (c) 2000 Finger Lakes Instrumentation (FLI), LLC. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation (FLI) web: http://www.fli-cam.com email: fli@rpa.net */ #ifndef _FLI_IOCTL_H #define _FLI_IOCTL_H #include /* 8-bit special value to identify ioctl 'type' */ #define FLI_IOCTL_TYPE 'F' /* Macros declaring ioctl commands and the variables they operate on */ #define FLI_IOCTL_MISC_CMDS \ FLI_IOCTL_CMD(FLI_RESET_PORT_VALUES, **NONE**) \ FLI_IOCTL_CMD(FLI_LOCK_PORT, **NONE**) \ FLI_IOCTL_CMD(FLI_UNLOCK_PORT, **NONE**) #define FLI_IOCTL_SPECIAL_SET_CMDS \ FLI_IOCTL_CMD(FLI_SET_DMABUFFSIZE, dmabuffsize) #define FLI_IOCTL_SET_CMDS \ FLI_IOCTL_CMD(FLI_SET_DMATHRESH, dmathresh) \ FLI_IOCTL_CMD(FLI_SET_DTO, dto) \ FLI_IOCTL_CMD(FLI_SET_RTO, rto) \ FLI_IOCTL_CMD(FLI_SET_WTO, wto) \ FLI_IOCTL_CMD(FLI_SET_LTL, ltl) \ FLI_IOCTL_CMD(FLI_SET_DIR, dir) \ FLI_IOCTL_CMD(FLI_SET_NUMREAD, numread) \ FLI_IOCTL_CMD(FLI_SET_NUMWRITE, numwrite) \ FLI_IOCTL_CMD(FLI_SET_NUMDTO, numdto) \ FLI_IOCTL_CMD(FLI_SET_NUMRTO, numrto) \ FLI_IOCTL_CMD(FLI_SET_NUMWTO, numwto) #define FLI_IOCTL_GET_CMDS \ FLI_IOCTL_CMD(FLI_GET_DMABUFFSIZE, dmabuffsize) \ FLI_IOCTL_CMD(FLI_GET_DMATHRESH, dmathresh) \ FLI_IOCTL_CMD(FLI_GET_DTO, dto) \ FLI_IOCTL_CMD(FLI_GET_RTO, rto) \ FLI_IOCTL_CMD(FLI_GET_WTO, wto) \ FLI_IOCTL_CMD(FLI_GET_DIR, dir) \ FLI_IOCTL_CMD(FLI_GET_LTL, ltl) \ FLI_IOCTL_CMD(FLI_GET_NUMREAD, numread) \ FLI_IOCTL_CMD(FLI_GET_NUMWRITE, numwrite) \ FLI_IOCTL_CMD(FLI_GET_NUMDTO, numdto) \ FLI_IOCTL_CMD(FLI_GET_NUMRTO, numrto) \ FLI_IOCTL_CMD(FLI_GET_NUMWTO, numwto) /* Enumerate ioctl numbers */ #undef FLI_SET_CMD #define FLI_IOCTL_CMD(cmd, var) cmd##_NUM, enum { FLI_IOCTL_MISC_CMDS FLI_IOCTL_SPECIAL_SET_CMDS FLI_IOCTL_SET_CMDS FLI_IOCTL_GET_CMDS }; /* Enumerate the actual ioctl commands */ #undef FLI_IOCTL_CMD #define FLI_IOCTL_CMD(cmd, var) \ enum {cmd = _IO(FLI_IOCTL_TYPE, cmd##_NUM)}; FLI_IOCTL_MISC_CMDS; #undef FLI_IOCTL_CMD #define FLI_IOCTL_CMD(cmd, var) \ enum {cmd = _IOW(FLI_IOCTL_TYPE, cmd##_NUM, int)}; FLI_IOCTL_SPECIAL_SET_CMDS; FLI_IOCTL_SET_CMDS; #undef FLI_IOCTL_CMD #define FLI_IOCTL_CMD(cmd, var ) \ enum {cmd = _IOR(FLI_IOCTL_TYPE, cmd##_NUM, int)}; FLI_IOCTL_GET_CMDS; #endif /* _FLI_IOCTL_H */ libfli1-1.7/libfli.h0000644000175000017500000002242311110507327012125 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #define DllImport __declspec( dllimport ) #define DllExport __declspec( dllexport ) #ifndef _LIBFLI_H_ #define _LIBFLI_H_ #include /** An opaque handle used by library functions to refer to FLI hardware. */ typedef long flidev_t; /** The domain of an FLI device. This consists of a bitwise ORed combination of interface method and device type. Valid interfaces are \texttt{FLIDOMAIN_PARALLEL_PORT}, \texttt{FLIDOMAIN_USB}, \texttt{FLIDOMAIN_SERIAL}, and \texttt{FLIDOMAIN_INET}. Valid device types are \texttt{FLIDEVICE_CAMERA}, \texttt{FLIDOMAIN_FILTERWHEEL}, and \texttt{FLIDOMAIN_FOCUSER}. @see FLIOpen @see FLIList */ typedef long flidomain_t; #define FLIDOMAIN_NONE (0x00) #define FLIDOMAIN_PARALLEL_PORT (0x01) #define FLIDOMAIN_USB (0x02) #define FLIDOMAIN_SERIAL (0x03) #define FLIDOMAIN_INET (0x04) #define FLIDOMAIN_SERIAL_19200 (0x05) #define FLIDOMAIN_SERIAL_1200 (0x06) #define FLIDEVICE_NONE (0x000) #define FLIDEVICE_CAMERA (0x100) #define FLIDEVICE_FILTERWHEEL (0x200) #define FLIDEVICE_FOCUSER (0x300) /** The frame type for an FLI CCD camera device. Valid frame types are \texttt{FLI_FRAME_TYPE_NORMAL} and \texttt{FLI_FRAME_TYPE_DARK}. @see FLISetFrameType */ typedef long fliframe_t; #define FLI_FRAME_TYPE_NORMAL (0) #define FLI_FRAME_TYPE_DARK (1) /** The gray-scale bit depth for an FLI camera device. Valid bit depths are \texttt{FLI_MODE_8BIT} and \texttt{FLI_MODE_16BIT}. @see FLISetBitDepth */ typedef long flibitdepth_t; #define FLI_MODE_8BIT (0) #define FLI_MODE_16BIT (1) /** Type used for shutter operations for an FLI camera device. Valid shutter types are \texttt{FLI_SHUTTER_CLOSE}, \texttt{FLI_SHUTTER_OPEN}, \texttt{FLI_SHUTTER_EXTERNAL_TRIGGER}, \texttt{FLI_SHUTTER_EXTERNAL_TRIGGER_LOW}, and \texttt{FLI_SHUTTER_EXTERNAL_TRIGGER_HIGH}. @see FLIControlShutter */ typedef long flishutter_t; #define FLI_SHUTTER_CLOSE (0x0000) #define FLI_SHUTTER_OPEN (0x0001) #define FLI_SHUTTER_EXTERNAL_TRIGGER (0x0002) #define FLI_SHUTTER_EXTERNAL_TRIGGER_LOW (0x0002) #define FLI_SHUTTER_EXTERNAL_TRIGGER_HIGH (0x0004) /** Type used for background flush operations for an FLI camera device. Valid bgflush types are \texttt{FLI_BGFLUSH_STOP} and \texttt{FLI_BGFLUSH_START}. @see FLIControlBackgroundFlush */ typedef long flibgflush_t; #define FLI_BGFLUSH_STOP (0x0000) #define FLI_BGFLUSH_START (0x0001) /** Type used to determine which temperature channel to read. Valid channel types are \texttt{FLI_TEMPERATURE_INTERNAL} and \texttt{FLI_TEMPERATURE_EXTERNAL}. @see FLIReadTemperature */ typedef long flichannel_t; #define FLI_TEMPERATURE_INTERNAL (0x0000) #define FLI_TEMPERATURE_EXTERNAL (0x0001) #define FLI_TEMPERATURE_CCD (0x0000) #define FLI_TEMPERATURE_BASE (0x0001) /** Type specifying library debug levels. Valid debug levels are \texttt{FLIDEBUG_NONE}, \texttt{FLIDEBUG_INFO}, \texttt{FLIDEBUG_WARN}, and \texttt{FLIDEBUG_FAIL}. @see FLISetDebugLevel */ typedef long flidebug_t; typedef long flimode_t; /* Status settings */ #define FLI_CAMERA_STATUS_UNKNOWN (0xffffffff) #define FLI_CAMERA_STATUS_MASK (0x000000ff) #define FLI_CAMERA_STATUS_IDLE (0x00) #define FLI_CAMERA_STATUS_WAITING_FOR_TRIGGER (0x01) #define FLI_CAMERA_STATUS_EXPOSING (0x02) #define FLI_CAMERA_STATUS_READING_CCD (0x03) #define FLI_CAMERA_DATA_READY (0x80000000) #define FLIDEBUG_NONE (0x00) #define FLIDEBUG_INFO (0x01) #define FLIDEBUG_WARN (0x02) #define FLIDEBUG_FAIL (0x04) #define FLIDEBUG_ALL (FLIDEBUG_INFO | FLIDEBUG_WARN | FLIDEBUG_FAIL) #define FLI_IO_P0 (0x01) #define FLI_IO_P1 (0x02) #define FLI_IO_P2 (0x04) #define FLI_IO_P3 (0x08) #ifdef WIN32 #ifndef LIBFLIAPI //#define LIBFLIAPI __declspec(dllimport) long __stdcall #define LIBFLIAPI __declspec(dllexport) long __stdcall #endif #else #define LIBFLIAPI long #endif /* Library API Function prototypes */ #ifdef __cplusplus extern "C" { // only need to export C interface if used by C++ source code #endif LIBFLIAPI FLIOpen(flidev_t *dev, char *name, flidomain_t domain); LIBFLIAPI FLISetDebugLevel(char *host, flidebug_t level); LIBFLIAPI FLIClose(flidev_t dev); LIBFLIAPI FLIGetLibVersion(char* ver, size_t len); LIBFLIAPI FLIGetModel(flidev_t dev, char* model, size_t len); LIBFLIAPI FLIGetPixelSize(flidev_t dev, double *pixel_x, double *pixel_y); LIBFLIAPI FLIGetHWRevision(flidev_t dev, long *hwrev); LIBFLIAPI FLIGetFWRevision(flidev_t dev, long *fwrev); LIBFLIAPI FLIGetArrayArea(flidev_t dev, long* ul_x, long* ul_y, long* lr_x, long* lr_y); LIBFLIAPI FLIGetVisibleArea(flidev_t dev, long* ul_x, long* ul_y, long* lr_x, long* lr_y); LIBFLIAPI FLISetExposureTime(flidev_t dev, long exptime); LIBFLIAPI FLISetImageArea(flidev_t dev, long ul_x, long ul_y, long lr_x, long lr_y); LIBFLIAPI FLISetHBin(flidev_t dev, long hbin); LIBFLIAPI FLISetVBin(flidev_t dev, long vbin); LIBFLIAPI FLISetFrameType(flidev_t dev, fliframe_t frametype); LIBFLIAPI FLICancelExposure(flidev_t dev); LIBFLIAPI FLIGetExposureStatus(flidev_t dev, long *timeleft); LIBFLIAPI FLISetTemperature(flidev_t dev, double temperature); LIBFLIAPI FLIGetTemperature(flidev_t dev, double *temperature); LIBFLIAPI FLIGetCoolerPower(flidev_t dev, double *power); LIBFLIAPI FLIGrabRow(flidev_t dev, void *buff, size_t width); LIBFLIAPI FLIExposeFrame(flidev_t dev); LIBFLIAPI FLIFlushRow(flidev_t dev, long rows, long repeat); LIBFLIAPI FLISetNFlushes(flidev_t dev, long nflushes); LIBFLIAPI FLISetBitDepth(flidev_t dev, flibitdepth_t bitdepth); LIBFLIAPI FLIReadIOPort(flidev_t dev, long *ioportset); LIBFLIAPI FLIWriteIOPort(flidev_t dev, long ioportset); LIBFLIAPI FLIConfigureIOPort(flidev_t dev, long ioportset); LIBFLIAPI FLILockDevice(flidev_t dev); LIBFLIAPI FLIUnlockDevice(flidev_t dev); LIBFLIAPI FLIControlShutter(flidev_t dev, flishutter_t shutter); LIBFLIAPI FLIControlBackgroundFlush(flidev_t dev, flibgflush_t bgflush); LIBFLIAPI FLISetDAC(flidev_t dev, unsigned long dacset); LIBFLIAPI FLIList(flidomain_t domain, char ***names); LIBFLIAPI FLIFreeList(char **names); LIBFLIAPI FLISetFilterPos(flidev_t dev, long filter); LIBFLIAPI FLIGetFilterPos(flidev_t dev, long *filter); LIBFLIAPI FLIGetFilterCount(flidev_t dev, long *filter); LIBFLIAPI FLIStepMotor(flidev_t dev, long steps); LIBFLIAPI FLIStepMotorAsync(flidev_t dev, long steps); LIBFLIAPI FLIGetStepperPosition(flidev_t dev, long *position); LIBFLIAPI FLIGetStepsRemaining(flidev_t dev, long *steps); LIBFLIAPI FLIHomeFocuser(flidev_t dev); LIBFLIAPI FLICreateList(flidomain_t domain); LIBFLIAPI FLIDeleteList(void); LIBFLIAPI FLIListFirst(flidomain_t *domain, char *filename, size_t fnlen, char *name, size_t namelen); LIBFLIAPI FLIListNext(flidomain_t *domain, char *filename, size_t fnlen, char *name, size_t namelen); LIBFLIAPI FLIReadTemperature(flidev_t dev, flichannel_t channel, double *temperature); LIBFLIAPI FLIGetFocuserExtent(flidev_t dev, long *extent); LIBFLIAPI FLIUsbBulkIO(flidev_t dev, int ep, void *buf, long *len); LIBFLIAPI FLIGetDeviceStatus(flidev_t dev, long *camera_status); LIBFLIAPI FLIGetCameraModeString(flidev_t dev, flimode_t mode_index, char *mode_string, size_t siz); LIBFLIAPI FLIGetCameraMode(flidev_t dev, flimode_t *mode_index); LIBFLIAPI FLISetCameraMode(flidev_t dev, flimode_t mode_index); #ifdef __cplusplus } #endif #endif /* _LIBFLI_H_ */ libfli1-1.7/libfli-camera.h0000644000175000017500000000642311110507327013355 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifndef _LIBFLI_CAMERA_H_ #define _LIBFLI_CAMERA_H_ typedef struct { int x; /* X coordinate */ int y; /* Y coordinate */ } point_t; typedef struct { point_t ul; /* Upper-left */ point_t lr; /* Lower-right */ } area_t; /* CCD Parameter list */ typedef struct { short index; char *model; area_t array_area; area_t visible_area; double fillfactor; double pixelwidth; double pixelheight; } fliccdinfo_t; typedef struct { long readto; long writeto; long dirto; fliccdinfo_t ccd; /* Acquisistion parameters */ area_t image_area; long vbin; long hbin; long vflushbin; long hflushbin; long exposure; long expdur; long expmul; long frametype; long flushes; long bitdepth; long exttrigger; long exttriggerpol; double tempslope; double tempintercept; long grabrowcount; long grabrowcounttot; long grabrowindex; long grabrowwidth; long grabrowbatchsize; long grabrowbufferindex; long flushcountbeforefirstrow; long flushcountafterlastrow; double pix_sum; double pix_cnt; /* Booleans */ int removebias; int biasoffset; int background_flush; int force_overscan; unsigned short *gbuf; unsigned long gbuf_siz; unsigned long max_usb_xfer; } flicamdata_t; extern const fliccdinfo_t knowndev[]; long fli_camera_open(flidev_t dev); long fli_camera_close(flidev_t dev); long fli_camera_command(flidev_t dev, int cmd, int argc, ...); #endif /* _LIBFLI_CAMERA_H_ */ libfli1-1.7/libfli-libfli.h0000644000175000017500000001561311110507327013367 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifndef _LIBFLI_LIBFLI_H_ #define _LIBFLI_LIBFLI_H_ #include #ifdef WIN32 #define LIBFLIAPI __declspec(dllexport) long __stdcall #endif #include "libfli.h" #include "libfli-sys.h" #include "libfli-debug.h" #ifndef MIN #define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif #define __STRINGIFY(x) ___STRINGIFY(x) #define ___STRINGIFY(x) #x #define __LIBFLIVER_MAJOR__ 1 #define __LIBFLIVER__ __STRINGIFY(__LIBFLIVER_MAJOR__) "." \ __STRINGIFY(__LIBFLI_MINOR__) #define CHKDEVICE(xdev) \ do { \ if((xdev < 0) || (xdev >= MAX_OPEN_DEVICES)) \ { \ debug(FLIDEBUG_WARN, \ "Attempt to use a device out of range (%d)", xdev); \ return -EINVAL; \ } \ if(devices[xdev] == NULL) \ { \ debug(FLIDEBUG_WARN, \ "Attempt to use a NULL device (%d)", xdev); \ return -EINVAL; \ } \ } while(0) #define CHKFUNCTION(func) \ do { \ if(func == NULL) \ { \ debug(FLIDEBUG_WARN, \ "Attempt to use a NULL function (" #func ")"); \ return -EINVAL; \ } \ } while(0) #define IO(dev, buf, wlen, rlen) \ do { \ int err; \ if((err = devices[dev]->fli_io(dev, buf, wlen, rlen))) \ { \ debug(FLIDEBUG_WARN, "Communication error: %d [%s]", \ err, strerror(-err)); \ return err; \ } \ } while(0) #define COMMAND(function) \ do { \ int err; \ if((err = function)) \ { \ debug(FLIDEBUG_WARN, \ "Function `" #function "' failed, error: %d [%s]", \ err, strerror(-err)); \ return err; \ } \ } while(0) #define FLIUSB_VENDORID 0xf18 #define FLIUSB_CAM_ID 0x02 #define FLIUSB_PROLINE_ID 0x0a #define FLIUSB_FILTER_ID 0x07 #define FLIUSB_FOCUSER_ID 0x06 #define FLIUSB_CFW4_ID 0x0b #define FLIUSB_PDF2_ID 0x0c #define FLIUSB_GUIDER_ID 0x0d #define MAX_OPEN_DEVICES (32) #define MAX_SEARCH_LIST (16) #ifndef MIN #define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif /* Common device information */ typedef struct _flidevinfo_t { long type; long fwrev; long hwrev; long devid; long serno; char *model; char *devnam; char *serial; } flidevinfo_t; /* A specific device instance */ typedef struct _flidevdesc_t { char *name; /* The device name */ long domain; /* The device's domain */ flidevinfo_t devinfo; /* Device information */ long io_timeout; /* Timeout in msec for all I/O */ void *io_data; /* For holding I/O specific data */ void *device_data; /* For holding device specific data */ void *sys_data; /* For holding system specific data */ /* System-specific functions */ long (*fli_lock)(flidev_t dev); long (*fli_unlock)(flidev_t dev); /* Domain-specific functions */ long (*fli_io)(flidev_t dev, void *buf, long *wlen, long *rlen); /* Device-specific functions */ long (*fli_open)(flidev_t dev); long (*fli_close)(flidev_t dev); long (*fli_command)(flidev_t dev, int cmd, int argc, ...); } flidevdesc_t; extern const char* version; extern flidevdesc_t *devices[MAX_OPEN_DEVICES]; #define DEVICE devices[dev] /* Device commands, the format is FLI_COMMAND(, ) */ #define FLI_COMMANDS \ FLI_COMMAND(FLI_NONE, 0) \ FLI_COMMAND(FLI_GET_PIXEL_SIZE, 2) \ FLI_COMMAND(FLI_GET_ARRAY_AREA, 4) \ FLI_COMMAND(FLI_GET_VISIBLE_AREA, 4) \ FLI_COMMAND(FLI_SET_EXPOSURE_TIME, 1) \ FLI_COMMAND(FLI_SET_IMAGE_AREA, 4) \ FLI_COMMAND(FLI_SET_HBIN, 1) \ FLI_COMMAND(FLI_SET_VBIN, 1) \ FLI_COMMAND(FLI_SET_FRAME_TYPE, 1) \ FLI_COMMAND(FLI_CANCEL_EXPOSURE, 0) \ FLI_COMMAND(FLI_GET_EXPOSURE_STATUS, 1) \ FLI_COMMAND(FLI_SET_TEMPERATURE, 1) \ FLI_COMMAND(FLI_GET_TEMPERATURE, 1) \ FLI_COMMAND(FLI_GRAB_ROW, 2) \ FLI_COMMAND(FLI_EXPOSE_FRAME, 0) \ FLI_COMMAND(FLI_FLUSH_ROWS, 2) \ FLI_COMMAND(FLI_SET_FLUSHES, 1) \ FLI_COMMAND(FLI_SET_BIT_DEPTH, 1) \ FLI_COMMAND(FLI_READ_IOPORT, 1) \ FLI_COMMAND(FLI_WRITE_IOPORT, 1) \ FLI_COMMAND(FLI_CONFIGURE_IOPORT, 1) \ FLI_COMMAND(FLI_CONTROL_SHUTTER, 1) \ FLI_COMMAND(FLI_CONTROL_BGFLUSH, 1) \ FLI_COMMAND(FLI_SET_DAC, 1) \ FLI_COMMAND(FLI_SET_FILTER_POS, 1) \ FLI_COMMAND(FLI_GET_FILTER_POS, 1) \ FLI_COMMAND(FLI_GET_STEPS_REMAINING, 1) \ FLI_COMMAND(FLI_GET_FILTER_COUNT, 1) \ FLI_COMMAND(FLI_STEP_MOTOR, 1) \ FLI_COMMAND(FLI_STEP_MOTOR_ASYNC, 1) \ FLI_COMMAND(FLI_GET_STEPPER_POS, 1) \ FLI_COMMAND(FLI_GET_FOCUSER_EXTENT, 1) \ FLI_COMMAND(FLI_READ_TEMPERATURE, 2) \ FLI_COMMAND(FLI_HOME_FOCUSER, 0) \ FLI_COMMAND(FLI_GET_COOLER_POWER, 1) \ FLI_COMMAND(FLI_SET_CAMERA_MODE, 1) \ FLI_COMMAND(FLI_GET_CAMERA_MODE_STRING, 2) \ FLI_COMMAND(FLI_GET_CAMERA_MODE, 1) \ FLI_COMMAND(FLI_GET_SERIAL_STRING, 2) \ FLI_COMMAND(FLI_SET_CAMERA_GAIN, 1) \ FLI_COMMAND(FLI_GET_CAMERA_GAIN, 1) \ FLI_COMMAND(FLI_SET_CAMERA_OFFSET, 1) \ FLI_COMMAND(FLI_GET_CAMERA_OFFSET, 1) \ FLI_COMMAND(FLI_GET_STATUS, 1) \ /* Enumerate the commands */ enum _commands { #define FLI_COMMAND(name, args) name, FLI_COMMANDS #undef FLI_COMMAND }; #endif /* _LIBFLI_LIBFLI_H_ */ libfli1-1.7/libfli-parport.h0000644000175000017500000000417011110507327013611 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifndef _LIBFLI_PARPORT_H_ #define _LIBFLI_PARPORT_H_ #if defined(__linux__) #define unix_parportio unix_parportio_linux #elif defined(__FreeBSD__) || defined(__NetBSD__) #define unix_parportio NULL #else #error "Unknown system" #endif long unix_parportio_linux(flidev_t dev, void *buf, long *wlen, long *rlen); #endif /* _LIBFLI_PARPORT_H_ */ libfli1-1.7/libfli-sys.h0000644000175000017500000000576411110507327012752 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifndef _LIBFLI_SYS_H #define _LIBFLI_SYS_H #include #define LIBFLIAPI long #ifndef MIN #define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif #if defined(__linux__) #define __SYSNAME__ "Linux" #define __LIBFLI_MINOR__ 71 #define USB_READ_SIZ_MAX (1024 * 128) #define _USE_FLOCK_ #define PARPORT_GLOB "/dev/ccd*" #define USB_GLOB "/dev/fliusb*" #define SERIAL_GLOB "/dev/ttyS[0-9]*" #elif defined(__FreeBSD__) #define __SYSNAME__ "FreeBSD" #define __LIBFLI_MINOR__ 13 #define USB_READ_SIZ_MAX 65536 #define USB_GLOB "/dev/ugen[0-9]" #define SERIAL_GLOB "/dev/cuaa*" #elif defined (__NetBSD__) #define __SYSNAME__ "NetBSD" #define __LIBFLI_MINOR__ 13 #define USB_READ_SIZ_MAX 65536 #define USB_GLOB "/dev/ugen*.0" __STRINGIFY(FLI_USB_CMDENDPOINT) #define SERIAL_GLOB "/dev/dty0*" #else #error "Unknown system" #endif typedef struct { int fd; } fli_unixio_t; long unix_fli_connect(flidev_t dev, char *name, long domain); long unix_fli_disconnect(flidev_t dev); long unix_fli_lock(flidev_t dev); long unix_fli_unlock(flidev_t dev); long unix_fli_list(flidomain_t domain, char ***names); #define fli_connect unix_fli_connect #define fli_disconnect unix_fli_disconnect #define fli_list unix_fli_list #endif /* _LIBFLI_SYS_H */ libfli1-1.7/libfli-usb.c0000644000175000017500000000527711110507326012716 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #include #include "libfli-libfli.h" #include "libfli-debug.h" #include "libfli-sys.h" #include "libfli-usb.h" long unix_usbio(flidev_t dev, void *buf, long *wlen, long *rlen) { int err = 0, locked = 0; long org_wlen = *wlen, org_rlen = *rlen; if ((err = unix_fli_lock(dev))) { debug(FLIDEBUG_WARN, "Lock failed"); goto done; } locked = 1; if (*wlen > 0) { if ((err = unix_bulkwrite(dev, buf, wlen))) { debug(FLIDEBUG_WARN, "Bulkwrite failed, wrote %d of %d bytes", *wlen, org_wlen); goto done; } } if (*rlen > 0) { if ((err = unix_bulkread(dev, buf, rlen))) { debug(FLIDEBUG_WARN, "Bulkread failed, read %d of %d bytes", *rlen, org_rlen); goto done; } } done: if (locked) { int r; if ((r = unix_fli_unlock(dev))) debug(FLIDEBUG_WARN, "Unlock failed"); if (err == 0) err = r; } return err; }