moved kdeaccessibility kdeaddons kdeadmin kdeartwork kdebindings kdeedu kdegames...
[kdeedu.git] / kstars / kstars / indi / fli / libfli-camera-usb.c
blob6bc88f1f31434b3af230a6829be7d8936e02ebbb
1 /*
3 Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C.
4 All rights reserved.
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
10 Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
13 Redistributions in binary form must reproduce the above
14 copyright notice, this list of conditions and the following
15 disclaimer in the documentation and/or other materials
16 provided with the distribution.
18 Neither the name of Finger Lakes Instrumentation (FLI), LLC
19 nor the names of its contributors may be used to endorse or
20 promote products derived from this software without specific
21 prior written permission.
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27 REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 POSSIBILITY OF SUCH DAMAGE.
36 ======================================================================
38 Finger Lakes Instrumentation, L.L.C. (FLI)
39 web: http://www.fli-cam.com
40 email: support@fli-cam.com
44 #ifdef WIN32
45 #include <winsock.h>
46 #else
47 #include <sys/param.h>
48 #include <netinet/in.h>
49 #endif
51 #include <stdio.h>
52 #include <errno.h>
53 #include <string.h>
54 #include <math.h>
56 #include "libfli-libfli.h"
57 #include "libfli-debug.h"
58 #include "libfli-mem.h"
59 #include "libfli-camera.h"
60 #include "libfli-camera-usb.h"
62 double dconvert(void *buf)
64 unsigned char *fnum = (unsigned char *) buf;
65 double sign, exponent, mantissa, result;
67 sign = (double) ((fnum[3] & 0x80)?(-1):(1));
68 exponent = (double) ((fnum[3] & 0x7f) << 1 | ((fnum[2] & 0x80)?1:0));
70 mantissa = 1.0 +
71 ((double) ((fnum[2] & 0x7f) << 16 | fnum[1] << 8 | fnum[0]) /
72 pow(2, 23));
74 result = sign * (double) pow(2, (exponent - 127.0)) * mantissa;
76 return result;
79 long fli_camera_usb_open(flidev_t dev)
81 flicamdata_t *cam;
82 long rlen, wlen;
83 unsigned short buf[32];
85 cam = DEVICE->device_data;
87 if ((cam->gbuf = xmalloc(USB_READ_SIZ_MAX)) == NULL)
88 return -ENOMEM;
90 buf[0] = htons(FLI_USBCAM_HARDWAREREV);
91 rlen = 2; wlen = 2;
92 IO(dev, buf, &wlen, &rlen);
93 DEVICE->devinfo.hwrev = ntohs(buf[0]);
95 buf[0] = htons(FLI_USBCAM_DEVICEID);
96 rlen = 2; wlen = 2;
97 IO(dev, buf, &wlen, &rlen);
98 DEVICE->devinfo.devid = ntohs(buf[0]);
100 buf[0] = htons(FLI_USBCAM_SERIALNUM);
101 rlen = 2; wlen = 2;
102 IO(dev, buf, &wlen, &rlen);
103 DEVICE->devinfo.serno = ntohs(buf[0]);
105 debug(FLIDEBUG_INFO, "DeviceID %d", DEVICE->devinfo.devid);
106 debug(FLIDEBUG_INFO, "SerialNum %d", DEVICE->devinfo.serno);
107 debug(FLIDEBUG_INFO, "HWRev %d", DEVICE->devinfo.hwrev);
108 debug(FLIDEBUG_INFO, "FWRev %d", DEVICE->devinfo.fwrev);
110 if (DEVICE->devinfo.fwrev < 0x0201)
112 int id;
114 for (id = 0; knowndev[id].index != 0; id++)
115 if (knowndev[id].index == DEVICE->devinfo.devid)
116 break;
118 if (knowndev[id].index == 0)
119 return -ENODEV;
121 cam->ccd.pixelwidth = knowndev[id].pixelwidth;
122 cam->ccd.pixelheight = knowndev[id].pixelheight;
124 wlen = sizeof(unsigned short) * 7;
125 rlen = 0;
126 buf[0] = htons(FLI_USBCAM_DEVINIT);
127 buf[1] = htons((unsigned short)knowndev[id].array_area.lr.x);
128 buf[2] = htons((unsigned short)knowndev[id].array_area.lr.y);
129 buf[3] = htons((unsigned short)(knowndev[id].visible_area.lr.x -
130 knowndev[id].visible_area.ul.x));
131 buf[4] = htons((unsigned short)(knowndev[id].visible_area.lr.y -
132 knowndev[id].visible_area.ul.y));
133 buf[5] = htons((unsigned short)knowndev[id].visible_area.ul.x);
134 buf[6] = htons((unsigned short)knowndev[id].visible_area.ul.y);
135 IO(dev, buf, &wlen, &rlen);
136 if ((DEVICE->devinfo.model =
137 (char *)xmalloc(strlen(knowndev[id].model) + 1)) == NULL)
138 return -ENOMEM;
139 strcpy(DEVICE->devinfo.model, knowndev[id].model);
141 switch(DEVICE->devinfo.fwrev & 0xff00)
143 case 0x0100:
144 cam->tempslope = (70.0 / 215.75);
145 cam->tempintercept = (-52.5681);
146 break;
148 case 0x0200:
149 cam->tempslope = (100.0 / 201.1);
150 cam->tempintercept = (-61.613);
151 break;
153 default:
154 cam->tempslope = 1e-12;
155 cam->tempintercept = 0;
158 else if (DEVICE->devinfo.fwrev >= 0x0201) /* Here, all the parameters are stored on the camera */
160 rlen = 64; wlen = 2;
161 buf[0] = htons(FLI_USBCAM_READPARAMBLOCK);
162 IO(dev, buf, &wlen, &rlen);
164 cam->ccd.pixelwidth = dconvert((char *) ((void *)buf) + 31);
165 cam->ccd.pixelheight = dconvert((char*) ((void *)buf) + 35);
166 cam->tempslope = dconvert((char *) ((void *)buf) + 23);
167 cam->tempintercept = dconvert((char *) ((void *)buf) + 27);
170 rlen = 32; wlen = 2;
171 buf[0] = htons(FLI_USBCAM_DEVICENAME);
172 IO(dev, buf, &wlen, &rlen);
174 if ((DEVICE->devinfo.devnam = (char *)xmalloc(rlen + 1)) == NULL)
175 return -ENOMEM;
176 memcpy(DEVICE->devinfo.devnam, buf, rlen);
177 DEVICE->devinfo.devnam[rlen] = '\0';
179 if(DEVICE->devinfo.model == NULL)
181 DEVICE->devinfo.model = xstrdup(DEVICE->devinfo.devnam);
184 rlen = 4; wlen = 2;
185 buf[0] = htons(FLI_USBCAM_ARRAYSIZE);
186 IO(dev, buf, &wlen, &rlen);
187 cam->ccd.array_area.ul.x = 0;
188 cam->ccd.array_area.ul.y = 0;
189 cam->ccd.array_area.lr.x = ntohs(buf[0]);
190 cam->ccd.array_area.lr.y = ntohs(buf[1]);
192 rlen = 4; wlen = 2;
193 buf[0] = htons(FLI_USBCAM_IMAGEOFFSET);
194 IO(dev, buf, &wlen, &rlen);
195 cam->ccd.visible_area.ul.x = ntohs(buf[0]);
196 cam->ccd.visible_area.ul.y = ntohs(buf[1]);
198 rlen = 4; wlen = 2;
199 buf[0] = htons(FLI_USBCAM_IMAGESIZE);
200 IO(dev, buf, &wlen, &rlen);
201 cam->ccd.visible_area.lr.x = cam->ccd.visible_area.ul.x + ntohs(buf[0]);
202 cam->ccd.visible_area.lr.y = cam->ccd.visible_area.ul.y + ntohs(buf[1]);
204 debug(FLIDEBUG_INFO, " Name: %s", DEVICE->devinfo.devnam);
205 debug(FLIDEBUG_INFO, " Array: (%4d,%4d),(%4d,%4d)",
206 cam->ccd.array_area.ul.x,
207 cam->ccd.array_area.ul.y,
208 cam->ccd.array_area.lr.x,
209 cam->ccd.array_area.lr.y);
210 debug(FLIDEBUG_INFO, " Visible: (%4d,%4d),(%4d,%4d)",
211 cam->ccd.visible_area.ul.x,
212 cam->ccd.visible_area.ul.y,
213 cam->ccd.visible_area.lr.x,
214 cam->ccd.visible_area.lr.y);
216 debug(FLIDEBUG_INFO, " Pix Size: (%g, %g)", cam->ccd.pixelwidth, cam->ccd.pixelheight);
217 debug(FLIDEBUG_INFO, " Temp.: T = AD x %g + %g", cam->tempslope, cam->tempintercept);
219 /* Initialize all varaibles to something */
221 cam->vflushbin = 4;
222 cam->hflushbin = 4;
223 cam->vbin = 1;
224 cam->hbin = 1;
225 cam->image_area.ul.x = cam->ccd.visible_area.ul.x;
226 cam->image_area.ul.y = cam->ccd.visible_area.ul.y;
227 cam->image_area.lr.x = cam->ccd.visible_area.lr.x;
228 cam->image_area.lr.y = cam->ccd.visible_area.lr.y;
229 cam->exposure = 100;
230 cam->frametype = FLI_FRAME_TYPE_NORMAL;
231 cam->flushes = 0;
232 cam->bitdepth = FLI_MODE_16BIT;
233 cam->exttrigger = 0;
234 cam->exttriggerpol = 0;
236 cam->grabrowwidth =
237 (cam->image_area.lr.x - cam->image_area.ul.x) / cam->hbin;
238 cam->grabrowcount = 1;
239 cam->grabrowcounttot = cam->grabrowcount;
240 cam->grabrowindex = 0;
241 cam->grabrowbatchsize = 1;
242 cam->grabrowbufferindex = cam->grabrowcount;
243 cam->flushcountbeforefirstrow = 0;
244 cam->flushcountafterlastrow = 0;
246 return 0;
249 long fli_camera_usb_get_array_area(flidev_t dev, long *ul_x, long *ul_y,
250 long *lr_x, long *lr_y)
252 flicamdata_t *cam;
253 long rlen, wlen;
254 unsigned short buf[8];
256 cam = DEVICE->device_data;
258 rlen = 4; wlen = 2;
259 buf[0] = htons(FLI_USBCAM_ARRAYSIZE);
260 IO(dev, buf, &wlen, &rlen);
261 cam->ccd.array_area.ul.x = 0;
262 cam->ccd.array_area.ul.y = 0;
263 cam->ccd.array_area.lr.x = ntohs(buf[0]);
264 cam->ccd.array_area.lr.y = ntohs(buf[1]);
266 *ul_x = cam->ccd.array_area.ul.x;
267 *ul_y = cam->ccd.array_area.ul.y;
268 *lr_x = cam->ccd.array_area.lr.x;
269 *lr_y = cam->ccd.array_area.lr.y;
271 return 0;
274 long fli_camera_usb_get_visible_area(flidev_t dev, long *ul_x, long *ul_y,
275 long *lr_x, long *lr_y)
277 flicamdata_t *cam;
278 long rlen, wlen;
279 unsigned short buf[8];
281 cam = DEVICE->device_data;
283 rlen = 4; wlen = 2;
284 buf[0] = htons(FLI_USBCAM_IMAGEOFFSET);
285 IO(dev, buf, &wlen, &rlen);
286 cam->ccd.visible_area.ul.x = ntohs(buf[0]);
287 cam->ccd.visible_area.ul.y = ntohs(buf[1]);
289 rlen = 4; wlen = 2;
290 buf[0] = htons(FLI_USBCAM_IMAGESIZE);
291 IO(dev, buf, &wlen, &rlen);
292 cam->ccd.visible_area.lr.x = cam->ccd.visible_area.ul.x + ntohs(buf[0]);
293 cam->ccd.visible_area.lr.y = cam->ccd.visible_area.ul.y + ntohs(buf[1]);
295 *ul_x = cam->ccd.visible_area.ul.x;
296 *ul_y = cam->ccd.visible_area.ul.y;
297 *lr_x = cam->ccd.visible_area.lr.x;
298 *lr_y = cam->ccd.visible_area.lr.y;
300 return 0;
303 long fli_camera_usb_set_exposure_time(flidev_t dev, long exptime)
305 flicamdata_t *cam;
306 long rlen, wlen;
307 unsigned short buf[8];
309 if (exptime < 0)
310 return -EINVAL;
312 cam = DEVICE->device_data;
314 rlen = 0; wlen = 8;
315 buf[0] = htons(FLI_USBCAM_SETEXPOSURE);
316 ((unsigned long *)((void *) buf))[1] = htonl(exptime);
317 IO(dev, buf, &wlen, &rlen);
319 cam->exposure = exptime;
321 return 0;
324 long fli_camera_usb_set_image_area(flidev_t dev, long ul_x, long ul_y,
325 long lr_x, long lr_y)
327 flicamdata_t *cam;
328 long rlen, wlen;
329 unsigned short buf[8];
331 cam = DEVICE->device_data;
333 if( (DEVICE->devinfo.fwrev < 0x0300) &&
334 ((DEVICE->devinfo.hwrev & 0xff00) == 0x0100) )
336 if( (lr_x > (cam->ccd.visible_area.lr.x * cam->hbin)) ||
337 (lr_y > (cam->ccd.visible_area.lr.y * cam->vbin)) )
339 debug(FLIDEBUG_WARN,
340 "FLISetVisibleArea(), area out of bounds: (%4d,%4d),(%4d,%4d)",
341 ul_x, ul_y, lr_x, lr_y);
345 if( (ul_x < cam->ccd.visible_area.ul.x) ||
346 (ul_y < cam->ccd.visible_area.ul.y) )
348 debug(FLIDEBUG_FAIL,
349 "FLISetVisibleArea(), area out of bounds: (%4d,%4d),(%4d,%4d)",
350 ul_x, ul_y, lr_x, lr_y);
351 return -EINVAL;
354 rlen = 0; wlen = 6;
355 buf[0] = htons(FLI_USBCAM_SETFRAMEOFFSET);
356 buf[1] = htons((unsigned short) cam->image_area.ul.x);
357 buf[2] = htons((unsigned short) cam->image_area.ul.y);
358 IO(dev, buf, &wlen, &rlen);
360 cam->image_area.ul.x = ul_x;
361 cam->image_area.ul.y = ul_y;
362 cam->image_area.lr.x = lr_x;
363 cam->image_area.lr.y = lr_y;
364 cam->grabrowwidth =
365 (cam->image_area.lr.x - cam->image_area.ul.x) / cam->hbin;
367 return 0;
370 long fli_camera_usb_set_hbin(flidev_t dev, long hbin)
372 flicamdata_t *cam;
373 long rlen, wlen;
374 unsigned short buf[8];
376 cam = DEVICE->device_data;
378 if ((hbin < 1) || (hbin > 16))
379 return -EINVAL;
381 rlen = 0; wlen = 6;
382 buf[0] = htons(FLI_USBCAM_SETBINFACTORS);
383 buf[1] = htons((unsigned short) hbin);
384 buf[2] = htons((unsigned short) cam->vbin);
385 IO(dev, buf, &wlen, &rlen);
387 cam->hbin = hbin;
388 cam->grabrowwidth =
389 (cam->image_area.lr.x - cam->image_area.ul.x) / cam->hbin;
391 return 0;
394 long fli_camera_usb_set_vbin(flidev_t dev, long vbin)
396 flicamdata_t *cam;
397 long rlen, wlen;
398 unsigned short buf[8];
400 cam = DEVICE->device_data;
402 if ((vbin < 1) || (vbin > 16))
403 return -EINVAL;
405 rlen = 0; wlen = 6;
406 buf[0] = htons(FLI_USBCAM_SETBINFACTORS);
407 buf[1] = htons((unsigned short) cam->hbin);
408 buf[2] = htons((unsigned short) vbin);
409 IO(dev, buf, &wlen, &rlen);
411 cam->vbin = vbin;
413 return 0;
416 long fli_camera_usb_get_exposure_status(flidev_t dev, long *timeleft)
418 long rlen, wlen;
419 unsigned short buf[8];
421 rlen = 4; wlen = 2;
422 buf[0] = htons(FLI_USBCAM_EXPOSURESTATUS);
423 IO(dev, buf, &wlen, &rlen);
424 *timeleft = ntohl(((unsigned long *)((void *) buf))[0]);
426 return 0;
429 long fli_camera_usb_set_temperature(flidev_t dev, double temperature)
431 flicamdata_t *cam;
432 unsigned short ad;
433 long rlen, wlen;
434 unsigned short buf[8];
436 cam = DEVICE->device_data;
438 if(DEVICE->devinfo.fwrev < 0x0200)
440 return 0;
443 if(cam->tempslope == 0.0)
445 ad = 255;
447 else
449 ad = (unsigned short) ((temperature - cam->tempintercept) / cam->tempslope);
452 debug(FLIDEBUG_INFO, "Temperature slope, intercept, AD val, %f %f %f %d", temperature, cam->tempslope, cam->tempintercept, ad);
454 rlen = 0; wlen = 4;
455 buf[0] = htons(FLI_USBCAM_TEMPERATURE);
456 buf[1] = htons(ad);
457 IO(dev, buf, &wlen, &rlen);
459 return 0;
462 long fli_camera_usb_get_temperature(flidev_t dev, double *temperature)
464 flicamdata_t *cam;
465 long rlen, wlen;
466 unsigned short buf[16];
468 cam = DEVICE->device_data;
470 rlen = 2; wlen = 2;
471 buf[0] = htons(FLI_USBCAM_TEMPERATURE);
472 IO(dev, buf, &wlen, &rlen);
473 *temperature = cam->tempslope * (double)((ntohs(buf[0]) & 0x00ff)) +
474 cam->tempintercept;
476 return 0;
479 long fli_camera_usb_grab_row(flidev_t dev, void *buff, size_t width)
481 flicamdata_t *cam;
482 long x;
483 long r;
485 cam = DEVICE->device_data;
487 if(width > (size_t) (cam->image_area.lr.x - cam->image_area.ul.x))
489 debug(FLIDEBUG_FAIL, "FLIGrabRow(), requested row too wide.");
490 debug(FLIDEBUG_FAIL, " Requested width: %d", width);
491 debug(FLIDEBUG_FAIL, " FLISetImageArea() width: %d",
492 cam->image_area.lr.x - cam->image_area.ul.x);
493 return -EINVAL;
496 if (cam->flushcountbeforefirstrow > 0)
498 if ((r = fli_camera_usb_flush_rows(dev, cam->flushcountbeforefirstrow, 1)))
499 return r;
501 cam->flushcountbeforefirstrow = 0;
504 if (cam->grabrowbufferindex >= cam->grabrowbatchsize)
506 /* We don't have the row in memory */
507 long rlen, wlen;
509 /* Do we have less than GrabRowBatchSize rows to grab? */
510 if (cam->grabrowbatchsize > (cam->grabrowcounttot - cam->grabrowindex))
512 cam->grabrowbatchsize = cam->grabrowcounttot - cam->grabrowindex;
515 rlen = cam->grabrowwidth * 2 * cam->grabrowbatchsize;
516 wlen = 6;
517 cam->gbuf[0] = htons(FLI_USBCAM_SENDROW);
518 cam->gbuf[1] = htons((unsigned short) cam->grabrowwidth);
519 cam->gbuf[2] = htons((unsigned short) cam->grabrowbatchsize);
520 IO(dev, cam->gbuf, &wlen, &rlen);
522 for (x = 0; x < (cam->grabrowwidth * cam->grabrowbatchsize); x++)
524 if ((DEVICE->devinfo.hwrev & 0xff00) == 0x0100)
526 cam->gbuf[x] = ntohs(cam->gbuf[x]) + 32768;
528 else
530 cam->gbuf[x] = ntohs(cam->gbuf[x]);
533 cam->grabrowbufferindex = 0;
536 for (x = 0; x < (long)width; x++)
538 ((unsigned short *)buff)[x] =
539 cam->gbuf[x + (cam->grabrowbufferindex * cam->grabrowwidth)];
542 cam->grabrowbufferindex++;
543 cam->grabrowindex++;
545 if (cam->grabrowcount > 0)
547 cam->grabrowcount--;
548 if (cam->grabrowcount == 0)
550 if ((r = fli_camera_usb_flush_rows(dev, cam->flushcountafterlastrow, 1)))
551 return r;
553 cam->flushcountafterlastrow = 0;
554 cam->grabrowbatchsize = 1;
558 return 0;
561 long fli_camera_usb_expose_frame(flidev_t dev)
563 flicamdata_t *cam;
564 short flags = 0;
565 long rlen, wlen;
566 unsigned short buf[16];
568 cam = DEVICE->device_data;
570 rlen = 0; wlen = 6;
571 buf[0] = htons(FLI_USBCAM_SETFRAMEOFFSET);
572 buf[1] = htons((unsigned short) cam->image_area.ul.x);
573 buf[2] = htons((unsigned short) cam->image_area.ul.y);
574 IO(dev, buf, &wlen, &rlen);
576 rlen = 0; wlen = 6;
577 buf[0] = htons(FLI_USBCAM_SETBINFACTORS);
578 buf[1] = htons((unsigned short) cam->hbin);
579 buf[2] = htons((unsigned short) cam->vbin);
580 IO(dev, buf, &wlen, &rlen);
582 rlen = 0; wlen = 6;
583 buf[0] = htons(FLI_USBCAM_SETFLUSHBINFACTORS);
584 buf[1] = htons((unsigned short) cam->hflushbin);
585 buf[2] = htons((unsigned short) cam->vflushbin);
586 IO(dev, buf, &wlen, &rlen);
588 rlen = 0; wlen = 8;
589 buf[0] = htons(FLI_USBCAM_SETEXPOSURE);
590 ((unsigned long *)((void *) buf))[1] = htonl(cam->exposure);
591 IO(dev, buf, &wlen, &rlen);
593 /* What flags do we need to send... */
594 /* Dark Frame */
595 flags |= (cam->frametype == FLI_FRAME_TYPE_DARK) ? 0x01 : 0x00;
596 /* External trigger */
597 flags |= (cam->exttrigger != 0) ? 0x04 : 0x00;
598 flags |= (cam->exttriggerpol != 0) ? 0x08 : 0x00;
600 debug(FLIDEBUG_INFO, "Exposure flags: %04x", flags);
602 debug(FLIDEBUG_INFO, "Flushing %d times.\n", cam->flushes);
603 if (cam->flushes > 0)
605 long r;
607 if ((r = fli_camera_usb_flush_rows(dev,
608 cam->ccd.array_area.lr.y - cam->ccd.array_area.ul.y,
609 cam->flushes)))
610 return r;
613 rlen = 0; wlen = 4;
614 buf[0] = htons(FLI_USBCAM_STARTEXPOSURE);
615 buf[1] = htons((unsigned short) flags);
616 IO(dev, buf, &wlen, &rlen);
618 cam->grabrowcount = cam->image_area.lr.y - cam->image_area.ul.y;
619 cam->grabrowcounttot = cam->grabrowcount;
620 cam->grabrowwidth = cam->image_area.lr.x - cam->image_area.ul.x;
621 cam->grabrowindex = 0;
622 cam->grabrowbatchsize = USB_READ_SIZ_MAX / (cam->grabrowwidth * 2);
624 /* Lets put some bounds on this... */
625 if (cam->grabrowbatchsize > cam->grabrowcounttot)
626 cam->grabrowbatchsize = cam->grabrowcounttot;
628 if (cam->grabrowbatchsize > 64)
629 cam->grabrowbatchsize = 64;
631 /* We need to get a whole new buffer by default */
632 cam->grabrowbufferindex = cam->grabrowbatchsize;
634 cam->flushcountbeforefirstrow = cam->image_area.ul.y;
635 cam->flushcountafterlastrow =
636 (cam->ccd.array_area.lr.y - cam->ccd.array_area.ul.y) -
637 ((cam->image_area.lr.y - cam->image_area.ul.y) * cam->vbin) -
638 cam->image_area.ul.y;
640 if (cam->flushcountbeforefirstrow < 0)
641 cam->flushcountbeforefirstrow = 0;
643 if (cam->flushcountafterlastrow < 0)
644 cam->flushcountafterlastrow = 0;
646 return 0;
649 long fli_camera_usb_flush_rows(flidev_t dev, long rows, long repeat)
651 flicamdata_t *cam;
652 long rlen, wlen;
653 unsigned short buf[16];
655 cam = DEVICE->device_data;
657 if (rows < 0)
658 return -EINVAL;
660 if (rows == 0)
661 return 0;
663 rlen = 0; wlen = 6;
664 buf[0] = htons(FLI_USBCAM_SETFLUSHBINFACTORS);
665 buf[1] = htons((unsigned short) cam->hflushbin);
666 buf[2] = htons((unsigned short) cam->vflushbin);
667 IO(dev, buf, &wlen, &rlen);
669 while (repeat > 0)
671 rlen = 0; wlen = 4;
672 buf[0] = htons(FLI_USBCAM_FLUSHROWS);
673 buf[1] = htons((unsigned short) rows);
674 IO(dev, buf, &wlen, &rlen);
675 repeat--;
678 return 0;
681 long fli_camera_usb_set_bit_depth(flidev_t dev, flibitdepth_t bitdepth)
683 dev=dev; bitdepth=bitdepth;
684 return -EINVAL;
687 long fli_camera_usb_read_ioport(flidev_t dev, long *ioportset)
689 flicamdata_t *cam;
690 long rlen, wlen;
691 unsigned short buf[8];
693 cam = DEVICE->device_data;
695 rlen = 1; wlen = 2;
696 buf[0] = htons(FLI_USBCAM_READIO);
697 IO(dev, buf, &wlen, &rlen);
698 *ioportset = ((unsigned char *)(void *)buf)[0];
700 return 0;
703 long fli_camera_usb_write_ioport(flidev_t dev, long ioportset)
705 flicamdata_t *cam;
707 long rlen, wlen;
708 unsigned short buf[8];
710 cam = DEVICE->device_data;
712 rlen = 0; wlen = 3;
713 buf[0] = htons(FLI_USBCAM_WRITEIO);
714 ((unsigned char *)(void *)buf)[2] = (char)ioportset;
715 IO(dev, buf, &wlen, &rlen);
717 return 0;
720 long fli_camera_usb_configure_ioport(flidev_t dev, long ioportset)
722 flicamdata_t *cam;
723 long rlen, wlen;
724 unsigned short buf[8];
726 cam = DEVICE->device_data;
728 rlen = 0; wlen = 3;
729 buf[0] = htons(FLI_USBCAM_WRITEDIR);
730 ((unsigned char *)(void *)buf)[2] = (char)ioportset;
731 IO(dev, buf, &wlen, &rlen);
733 return 0;
736 long fli_camera_usb_control_shutter(flidev_t dev, long shutter)
738 flicamdata_t *cam;
739 long rlen, wlen;
740 unsigned short buf[8];
742 cam = DEVICE->device_data;
744 rlen = 0; wlen = 3;
745 buf[0] = htons(FLI_USBCAM_SHUTTER);
746 ((unsigned char *)(void *)buf)[2] = (char)shutter;
747 IO(dev, buf, &wlen, &rlen);
749 return 0;
752 long fli_camera_usb_control_bgflush(flidev_t dev, long bgflush)
754 flicamdata_t *cam;
755 long rlen, wlen;
756 unsigned short buf[8];
758 cam = DEVICE->device_data;
760 if(DEVICE->devinfo.fwrev < 0x0300)
762 debug(FLIDEBUG_WARN, "Background flush commanded on early firmware.");
763 return -EFAULT;
766 if( (bgflush != FLI_BGFLUSH_STOP) &&
767 (bgflush != FLI_BGFLUSH_START) )
768 return -EINVAL;
770 rlen = 0; wlen = 4;
771 buf[0] = htons(FLI_USBCAM_BGFLUSH);
772 buf[1] = htons((unsigned short) bgflush);
773 IO(dev, buf, &wlen, &rlen);
775 return 0;