diff --git a/audineccd.h b/audineccd.h new file mode 100644 index 0000000..09cff8a --- /dev/null +++ b/audineccd.h @@ -0,0 +1,105 @@ +/* + * -*- linux-c-kernel -*- + * Linux Kernel Module for the Audine Camera + * Copyright (C) 2000 Peter Kirchgessner + * http://www.kirchgessner.net, mailto:peter@kirchgessner.net + * + * Modified by F. Manenti for the use in the + * NOVA environnement (nova.sourceforge.net) + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The sample interface routines for the module have been taken from the + * Linux Kernel Module Programming Guide by Ori Pomerantz contained + * in the Linux Documentation Project. + * + */ +#ifndef _AUDINECCD_H_ +#define _AUDINECCD_H_ + +#ifndef MODULE +# define MODULE +#endif + +/* Device Declarations **************************** */ +/* The name for our device, as it will appear in /proc/devices */ +#define DEVICE_NAME "audineccd" + +/* Size if a buffer that must keep at least */ +/* one line of image data (2 bytes per pixel) */ +#define BUF_LEN 4096 + +#define PORT_STEP 1 + +#define ERR_NO_PORT ENXIO + +#undef PDEBUG +#ifdef DEBUG +# ifdef __KERNEL__ +# define PDEBUG(fmt, args...) printk(KERN_DEBUG "audine driver: ", fmt, ## args) +# else +# define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args) +# endif + +#else +# define PDEBUG(fmt, args...) /* Nothing ... */ +#endif + +#undef PDEBUGG +#define PDEBUGG(fmt, args...) /* Nothing */ + +#endif + +struct ccd_capability { + char name[128]; /* Name of CCD chip */ + int width; /* Sensible image width */ + int height; /* Sensible image height */ + int color; /* Has color */ + int minwidth; /* Actual geometry frame width */ + int minheight; /* Actual geometry frame height */ +}; + +/* IOCTL MACROS */ + +#define CCD_MGK 0xEE // Very high ... to register !!!! + +#define CCD_RD_CHIP _IOR(CCD_MGK, 0x01, struct ccd_capability) +#define CCD_RD_CCDL _IOR(CCD_MGK, 0x02, struct ccd_capability) +#define CCD_RD_GEOM _IOR(CCD_MGK, 0x03, struct ccd_capability) +#define CCD_RD_IMG _IOR(CCD_MGK, 0x04, unsigned long) /* Read image */ + +#define CCD_CLR _IOW(CCD_MGK, 0x05, unsigned long) /* chip Clearing */ + +#define CCD_SWTC_AMP _IOW(CCD_MGK, 0x06, unsigned long) +#define CCD_SWTC_SHT _IOW(CCD_MGK, 0x07, unsigned long) +#define CCD_SWTC_AX0 _IOW(CCD_MGK, 0x08, unsigned long) +#define CCD_SWTC_AX1 _IOW(CCD_MGK, 0x09, unsigned long) + +#define CCD_SET_AMP _IOW(CCD_MGK, 0x0a, unsigned long) +#define CCD_SET_SHT _IOW(CCD_MGK, 0x0b, unsigned long) +#define CCD_SET_AX0 _IOW(CCD_MGK, 0x0c, unsigned long) +#define CCD_SET_AX1 _IOW(CCD_MGK, 0x0d, unsigned long) + +#define CCD_SET_BNN _IOW(CCD_MGK, 0x0e, struct ccd_capability) // Binning + + +#define CCD_AV_IMG _IOR(CCD_MGK, 0x0f, unsigned long) // ma serve ???? + +#define CCD_SET_WND _IOW(CCD_MGK, 0x10, struct ccd_capability) // Window +#define CCD_RST_WND _IOW(CCD_MGK, 0x11, unsigned long) // CCD + +#define CCD_SET_PRT _IOW(CCD_MGK, 0x12, unsigned long) +#define CCD_RD_VER _IOW(CCD_MGK, 0x13, struct ccd_capability) // Version diff --git a/audinelib.c b/audinelib.c new file mode 100644 index 0000000..b934946 --- /dev/null +++ b/audinelib.c @@ -0,0 +1,610 @@ +/* + * -*- linux-c -*- + * Linux Kernel Module for the Audine Camera + * Copyright (C) 2001 Peter Kirchgessner + * http://www.kirchgessner.net, mailto:peter@kirchgessner.net + * + * Modified by F. Manenti for the use in the + * NOVA environment (nova.sourceforge.net) + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The sample interface routines for the module have been taken from the + * Linux Kernel Module Programming Guide by Ori Pomerantz contained + * in the Linux Documentation Project. + * + */ + +#include "audineccd.h" +#include "audinelib.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define AUD_DEVICE_FILE "/dev/audine" + +#define ERRNORET(a) return (errno = a, -(a)) + +#define AUD_HANDLE_CHECK(a) \ + { if (!(a)) ERRNORET (EINVAL); if ((a)->fd < 0) ERRNORET (EBADF); } + +struct aud_handle_s { + int fd; + int single_read; +}; + + +AUD_HANDLE aud_open (void) + +{AUD_HANDLE aud = (AUD_HANDLE)calloc (1, sizeof (struct aud_handle_s)); + + if (!aud) return 0; + + aud->fd = open (AUD_DEVICE_FILE, O_RDWR); + if (aud->fd < 0) + { + free (aud); + return 0; + } + + aud->single_read = 1; + + return aud; +} + + +void aud_close (AUD_HANDLE aud) + +{ + if (aud) + { + if (aud->fd >= 0) close (aud->fd); + free (aud); + } +} + + +char *aud_version (const AUD_HANDLE aud) + +{static struct ccd_capability Info; + char *version = ""; + int ret; + + if (aud) + { + ret = ioctl (aud->fd, CCD_RD_VER, &Info); + if (ret == 0) version = &(Info.name[0]); + } + return version; +} + + +int aud_clear (const AUD_HANDLE aud, int nclear) + +{int ret = 0; + + if (nclear > 0) ret = ioctl (aud->fd, CCD_CLR, &nclear); + return ret; +} + + +int aud_binning_set (const AUD_HANDLE aud, int vb, int hb) + +{struct ccd_capability Info; + + AUD_HANDLE_CHECK (aud); + if ((vb < 1) || (vb > 4) || (hb < 1) || (hb > 4)) + ERRNORET (EINVAL); + + Info.width = vb; + Info.height = hb; + return ioctl (aud->fd, CCD_SET_BNN, &Info); +} + + +int aud_binning_get (const AUD_HANDLE aud, int *vb, int *hb) + +{struct ccd_capability Info; + int ret; + + AUD_HANDLE_CHECK (aud); + + Info.width = 0; + Info.height = 0; + ret = ioctl (aud->fd, CCD_SET_BNN, &Info); + if (ret != 0) return ret; + if (vb) *vb = Info.width; + if (hb) *hb = Info.height; + return 0; +} + + +int aud_geometry_set (const AUD_HANDLE aud, int x, int y, int width, int height) + +{struct ccd_capability Info; + + AUD_HANDLE_CHECK (aud); + + Info.minwidth = x; + Info.minheight = y; + Info.width = width; + Info.height = height; + return ioctl (aud->fd, CCD_SET_WND, &Info); +} + + +int aud_geometry_reset (const AUD_HANDLE aud) + +{ + AUD_HANDLE_CHECK (aud); + + return ioctl (aud->fd, CCD_RST_WND); +} + + +int aud_geometry_get (const AUD_HANDLE aud, int *xorigin, int *yorigin, + int *winwidth, int *winheight, int *color) + +{struct ccd_capability Info; + int ret; + + AUD_HANDLE_CHECK (aud); + + ret = ioctl(aud->fd, CCD_RD_GEOM, &Info); + if (ret != 0) return ret; + + if (xorigin) *xorigin = Info.minwidth; + if (yorigin) *yorigin = Info.minheight; + if (winwidth) *winwidth = Info.width; + if (winheight) *winheight = Info.height; + if (color) *color = Info.color; + + return 0; +} + + +int aud_port_set (const AUD_HANDLE aud, int base) + +{ + AUD_HANDLE_CHECK (aud); + if (base <= 0) return -EINVAL; + return ioctl (aud->fd, CCD_SET_PRT, &base); +} + + +int aud_port_get (const AUD_HANDLE aud, int *base) + +{ + AUD_HANDLE_CHECK (aud); + if (!base) return -1; + *base = 0; + return ioctl (aud->fd, CCD_SET_PRT, base); +} + + +static int aud_line_ctrl_set (const AUD_HANDLE aud, int cmd, int ctrl) + +{ + AUD_HANDLE_CHECK (aud); + if ((ctrl != 1) && (ctrl != 2) && (ctrl != 4) && (ctrl != 8)) + ERRNORET (EINVAL); + return ioctl (aud->fd, cmd, &ctrl); +} + + +static int aud_line_set (const AUD_HANDLE aud, int cmd, int on_off) + +{ + AUD_HANDLE_CHECK (aud); + if (on_off != 0) on_off = 1; + return ioctl (aud->fd, cmd, &on_off); +} + + +int aud_amplifier_ctrl_set (const AUD_HANDLE aud, int ctrl) + +{ + return aud_line_ctrl_set (aud, CCD_SET_AMP, ctrl); +} + + +int aud_amplifier_set (const AUD_HANDLE aud, int on_off) + +{ + return aud_line_set (aud, CCD_SWTC_AMP, on_off); +} + + +int aud_shutter_ctrl_set (const AUD_HANDLE aud, int ctrl) + +{ + return aud_line_ctrl_set (aud, CCD_SET_SHT, ctrl); +} + + +int aud_shutter_set (const AUD_HANDLE aud, int on_off) + +{ + return aud_line_set (aud, CCD_SWTC_SHT, on_off); +} + + +int aud_aux0_ctrl_set (const AUD_HANDLE aud, int ctrl) + +{ + return aud_line_ctrl_set (aud, CCD_SET_AX0, ctrl); +} + + +int aud_aux0_set (const AUD_HANDLE aud, int on_off) + +{ + return aud_line_set (aud, CCD_SWTC_AX0, on_off); +} + + +int aud_aux1_ctrl_set (const AUD_HANDLE aud, int ctrl) + +{ + return aud_line_ctrl_set (aud, CCD_SET_AX1, ctrl); +} + + +int aud_aux1_set (const AUD_HANDLE aud, int on_off) + +{ + return aud_line_set (aud, CCD_SWTC_AX1, on_off); +} + + +int aud_ccd_info_get (const AUD_HANDLE aud, char **name, int *width, + int *height, int *color) + +{static struct ccd_capability Info; + int ret; + + AUD_HANDLE_CHECK (aud); + if ((ret = ioctl (aud->fd, CCD_RD_CHIP, &Info)) != 0) return ret; + + if (name) *name = Info.name; + if (width) *width = Info.width; + if (height) *height = Info.height; + if (color) *color = Info.color; + + return 0; +} + + +int aud_ccd_listentry_get (const AUD_HANDLE aud, int entry, char **name, + int *width, int *height, int *color) +{static struct ccd_capability Info; + int ret; + + AUD_HANDLE_CHECK (aud); + Info.color = entry; + if ((ret = ioctl (aud->fd, CCD_RD_CCDL, &Info)) != 0) return ret; + + if (name) *name = Info.name; + if (width) *width = Info.width; + if (height) *height = Info.height; + if (color) *color = Info.color; + + return 0; +} + + +void aud_single_read_set (AUD_HANDLE aud, int single_read) + +{ + if (aud) aud->single_read = single_read; +} + + +int aud_image_read (const AUD_HANDLE aud, char **buf, int *bufsize, + int *width, int *height, int *color) + +{int ret; + int nbytes, nread, len; + char *imgbuf; + + AUD_HANDLE_CHECK (aud); + if ((!buf) || (!bufsize)) ERRNORET (EINVAL); + if ((!width) || (!height) || (!color)) ERRNORET (EINVAL); + + if ((ret = aud_geometry_get (aud, 0, 0, width, height, color)) != 0) + return ret; + + /* We get 2 bytes per pixel */ + nbytes = *width * *height * 2; + + /* Do we have to free the user buffer ? */ + if ((*bufsize < nbytes) && (*buf)) + { + free (*buf); + *buf = 0; + *bufsize = 0; + } + + /* If buffer not supplied, allocate buffer */ + if (!(*buf)) + { + *buf = malloc (nbytes); + if (!*buf) ERRNORET (ENOMEM); + *bufsize = nbytes; + } + + /* Start reading image */ + if ((ret = ioctl(aud->fd, CCD_RD_IMG)) != 0) return ret; + + imgbuf = *buf; + while (nbytes > 0) + { + if (aud->single_read) + { + nread = nbytes; + } + else + { + nread = *width * 2; + if (nread > nbytes) + nread = nbytes; + } + len = read(aud->fd, imgbuf, nread); + if (len <= 0) return -1; + nbytes -= len; + imgbuf += len; + } + return 0; +} + + +static void aud_ccdstruct_log (const char *fct, int ret, + const struct ccd_capability *info) + +{ + printf ("\nFunction %s returned %d\n", fct, ret); + if (ret != 0) return; + printf ("Name : %-32s\n", info->name); + printf ("Width: %-6d Height: %-6d Minwidth: %-6d Minheight: %-6d Color: %d\n", + info->width, info->height, info->minwidth, info->minheight, + info->color); +} + + +void aud_ioctl_test (AUD_HANDLE aud) + +{int ret; + struct ccd_capability info; + char *buf = 0, *name; + int bufsize = 0, width, height, color; + int j; + + if ((!aud) || (aud->fd < 0)) return; + + /* Read driver version */ + ret = ioctl (aud->fd, CCD_RD_VER, &info); + aud_ccdstruct_log ("CCD_RD_VER", ret, &info); + + /* Read chip information */ + ret = ioctl (aud->fd, CCD_RD_CHIP, &info); + aud_ccdstruct_log ("CCD_RD_CHIP", ret, &info); + + /* Read geometry */ + ret = ioctl (aud->fd, CCD_RD_GEOM, &info); + aud_ccdstruct_log ("CCD_RD_GEOM", ret, &info); + + /* Set Window */ + info.minwidth = 1; + info.minheight = 2; + info.width = 200; + info.height = 100; + ret = ioctl (aud->fd, CCD_SET_WND, &info); + printf ("\nCalled CCD_SET_WND: (1,2) (200,100)\n"); + + /* Read geometry */ + ret = ioctl (aud->fd, CCD_RD_GEOM, &info); + aud_ccdstruct_log ("CCD_RD_GEOM", ret, &info); + + /* Set binning */ + info.width = 2; + info.height = 3; + printf ("\nSet binning %dx%d", info.width, info.height); + ret = ioctl (aud->fd, CCD_SET_BNN, &info); + aud_ccdstruct_log ("CCD_SET_BNN", ret, &info); + + /* Read geometry */ + ret = ioctl (aud->fd, CCD_RD_GEOM, &info); + aud_ccdstruct_log ("CCD_RD_GEOM", ret, &info); + + /* (Re-)Set binning */ + info.width = 1; + info.height = 1; + printf ("\nSet binning %dx%d", info.width, info.height); + ret = ioctl (aud->fd, CCD_SET_BNN, &info); + aud_ccdstruct_log ("CCD_SET_BNN", ret, &info); + + /* Read geometry */ + ret = ioctl (aud->fd, CCD_RD_GEOM, &info); + aud_ccdstruct_log ("CCD_RD_GEOM", ret, &info); + + /* Clear two times */ + info.width = 2; + printf ("\nStart clear %d times\n", info.width); fflush (stdout); + ret = ioctl (aud->fd, CCD_CLR, &info.width); + printf ("Clear finished.\n"); + + /* Reading */ + printf ("Start reading image\n"); + ret = aud_image_read (aud, &buf, &bufsize, &width, &height, &color); + printf ("Finished reading: ret=%d width=%d height=%d color=%d bufsize=%d\n", + ret, width, height, color, bufsize); + + /* Set binning */ + info.width = 2; + info.height = 3; + printf ("\nSet binning %dx%d", info.width, info.height); + ret = ioctl (aud->fd, CCD_SET_BNN, &info); + aud_ccdstruct_log ("CCD_SET_BNN", ret, &info); + + /* Reading */ + printf ("Start reading small image\n"); + ret = aud_image_read (aud, &buf, &bufsize, &width, &height, &color); + printf ("Finished reading: ret=%d width=%d height=%d color=%d bufsize=%d\n", + ret, width, height, color, bufsize); + + /* Reset window */ + ret = ioctl (aud->fd, CCD_RST_WND); + printf ("\nReset window\n"); + + /* Reset binning */ + info.width = 1; + info.height = 1; + printf ("\nSet binning %dx%d", info.width, info.height); + ret = ioctl (aud->fd, CCD_SET_BNN, &info); + aud_ccdstruct_log ("CCD_SET_BNN", ret, &info); + + /* Read geometry */ + ret = ioctl (aud->fd, CCD_RD_GEOM, &info); + aud_ccdstruct_log ("CCD_RD_GEOM", ret, &info); + + /* Reading */ + printf ("Start reading large image\n"); + ret = aud_image_read (aud, &buf, &bufsize, &width, &height, &color); + printf ("Finished reading: ret=%d width=%d height=%d color=%d bufsize=%d\n", + ret, width, height, color, bufsize); + + /* Read current port */ + ret = aud_port_get (aud, &j); + printf ("\naud_port_get returned with %d. Port=0x%x\n", ret, j); + + printf ("\nList of supported CCDs:\n"); + j = 0; + while (aud_ccd_listentry_get (aud, j, &name, &info.width, &info.height, + &info.color) == 0) + { + printf ("%d: %s, %dx%d, %d\n", j, name, info.width, info.height, info.color); + j++; + } + + +} + + +#define FITS_WRITE_BOOLCARD(fp,key,value) \ +{char card[81]; \ + sprintf (card, "%-8.8s= %20s%50s", key, value ? "T" : "F", " "); \ + fwrite (card, 1, 80, fp); } + +#define FITS_WRITE_LONGCARD(fp,key,value) \ +{char card[81]; \ + sprintf (card, "%-8.8s= %20ld%50s", key, (long)value, " "); \ + fwrite (card, 1, 80, fp); } + +#define FITS_WRITE_DOUBLECARD(fp,key,value) \ +{char card[81], dbl[21], *istr; \ + sprintf (dbl, "%20f", (double)value); istr = strstr (dbl, "e"); \ + if (istr) *istr = 'E'; \ + sprintf (card, "%-8.8s= %20.20s%50s", key, dbl, " "); \ + fwrite (card, 1, 80, fp); } + +#define FITS_WRITE_STRINGCARD(fp,key,value) \ +{char card[81]; int k;\ + sprintf (card, "%-8.8s= \'%s", key, value); \ + for (k = strlen (card); k < 81; k++) card[k] = ' '; \ + k = strlen (key); if (k < 8) card[19] = '\''; else card[11+k] = '\''; \ + fwrite (card, 1, 80, fp); } + +#define FITS_WRITE_CARD(fp,value) \ +{char card[81]; \ + sprintf (card, "%-80.80s", value); \ + fwrite (card, 1, 80, fp); } + +int audine_fits_write (const char *fname, const char *img, + int width, int height) +{ + FILE *fp; + char value[50]; + unsigned short *us_img = (unsigned short *) img; + unsigned short *row; + int x, y, high, low; + long pos; + time_t timp; + + fp = fopen(fname, "w"); + if (fp) { + FITS_WRITE_BOOLCARD(fp, "SIMPLE", 1); + FITS_WRITE_LONGCARD(fp, "BITPIX", 16); + FITS_WRITE_LONGCARD(fp, "NAXIS", 2); + FITS_WRITE_LONGCARD(fp, "NAXIS1", width); + FITS_WRITE_LONGCARD(fp, "NAXIS2", height); + FITS_WRITE_DOUBLECARD(fp, "BZERO", 0.0); + FITS_WRITE_DOUBLECARD(fp, "BSCALE", 1.0); + FITS_WRITE_DOUBLECARD(fp, "DATAMIN", 0.0); + FITS_WRITE_DOUBLECARD(fp, "DATAMAX", 32767.0); + FITS_WRITE_CARD(fp, " "); + FITS_WRITE_CARD(fp, "HISTORY THIS FILE WAS GENERATED BY AUDINELIB"); + FITS_WRITE_CARD(fp, " "); + + timp = time(NULL); + strftime(value, sizeof(value), "%d/%m/%Y", gmtime(&timp)); + FITS_WRITE_STRINGCARD(fp, "DATE", value); + + FITS_WRITE_CARD(fp, "END"); + + /* Fill up primary HDU to multiple of 2880 bytes */ + fflush(fp); + pos = ftell(fp) % 2880; + if (pos != 0) { + pos = 2880 - pos; + while (pos-- > 0) + putc(' ', fp); + } + + /* FITS standard requires integer data to be most significant + byte first, */ + /* image origin bottom left. We want to create an astronomical + oriented image (top is bottom, left is right) */ + for (y = 0; y < height; y++) { + row = us_img + y * width; + for (x = width - 1; x >= 0; x--) { + high = (row[x] >> 8) & 0xff; + low = (row[x] & 0xff); + putc(high, fp); + putc(low, fp); + } + } + /* Fill up file to multiple of 2880 bytes */ + fflush(fp); + pos = ftell(fp) % 2880; + if (pos != 0) { + pos = 2880 - pos; + while (pos-- > 0) + putc(0, fp); + } + fclose(fp); + } else { + return -1; + } + return 0; +} diff --git a/audinelib.h b/audinelib.h new file mode 100644 index 0000000..7d9816e --- /dev/null +++ b/audinelib.h @@ -0,0 +1,78 @@ +/* + * -*- linux-c -*- + * Library Module for the Audine Camera + * Copyright (C) 2001 Peter Kirchgessner + * http://www.kirchgessner.net, mailto:peter@kirchgessner.net + * + * Modified by F. Manenti for the use in the + * NOVA environment (nova.sourceforge.net) + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The sample interface routines for the module have been taken from the + * Linux Kernel Module Programming Guide by Ori Pomerantz contained + * in the Linux Documentation Project. + * + */ + +#ifndef _AUDINELIB_H_ +#define _AUDINELIB_H_ + +typedef struct aud_handle_s * AUD_HANDLE; + +AUD_HANDLE aud_open (void); + +void aud_close (AUD_HANDLE aud); + +char *aud_version (const AUD_HANDLE aud); + +int aud_image_read (const AUD_HANDLE aud, char **buf, int *bufsize, + int *width, int *height, int *color); +void aud_single_read_set (AUD_HANDLE aud, int single_read); + +int aud_ccd_info_get (const AUD_HANDLE aud, char **name, + int *width, int *height, int *color); + +int aud_ccd_listentry_get (const AUD_HANDLE aud, int entry, char **name, + int *width, int *height, int *color); + +int aud_binning_set (const AUD_HANDLE aud, int vb, int hb); +int aud_binning_get (const AUD_HANDLE aud, int *vb, int *hb); + +int aud_geometry_set (const AUD_HANDLE aud,int x,int y,int width,int height); +int aud_geometry_get (const AUD_HANDLE aud, int *xorigin, int *yorigin, + int *winwidth, int *winheight, int *color); +int aud_geometry_reset (const AUD_HANDLE aud); + +int aud_amplifier_ctrl_set (const AUD_HANDLE aud, int ctrl); +int aud_amplifier_set (const AUD_HANDLE aud, int off_on); + +int aud_shutter_ctrl_set (const AUD_HANDLE aud, int ctrl); +int aud_shutter_set (const AUD_HANDLE aud, int off_on); + +int aud_aux0_ctrl_set (const AUD_HANDLE aud, int ctrl); +int aud_aux0_set (const AUD_HANDLE aud, int off_on); + +int aud_aux1_ctrl_set (const AUD_HANDLE aud, int ctrl); +int aud_aux1_set (const AUD_HANDLE aud, int off_on); + +int aud_clear (const AUD_HANDLE, int nclear); + +void aud_ioctl_test (AUD_HANDLE aud); + +int audine_fits_write (const char *fname, const char *img, + int width, int height); +#endif diff --git a/delcam.c b/delcam.c new file mode 100644 index 0000000..e07a03d --- /dev/null +++ b/delcam.c @@ -0,0 +1,498 @@ +/*----------------------------------------------------------------------------- + * This is a driver for the DELCam Neutron CCD camera. This driver has some + * limitations: + * - Due to the dark current of a CCD, only timer measurements + * are useful. + * - If there is no beam, the measurement has to be aborted. + * - While reading the CCD, the computer locks up. + * - No intermediate results can be retrieved while data acquisition is + * active. This is due to the nature of the CCD readout: Each line is + * swapped into a line buffer which then is sequentially read. This + * may be a consequence of the fact that exposure just generates charges + * on the CCD. + * - This driver requires a Linux kernel module to be loaded beforehand. + * - The DELCam's paralell port connector MUST be connected to the + * paralell port of the computer running the SICServer. + * - This code works only on Linux, porting to other OS requires different + * drivers. + * The DELCam uses a CCD which was originally developed as CCD for amateur + * astronomers. The name of the project is Audine. This driver uses the + * audine driver code. Look in audinelib.h for a WWW pointer. + * + * copyright: see file COPYRIGHT + * + * Mark Koennecke, March 2007 + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "audinelib.h" + +/* This delay is not the real value, but approximated */ +/* time in ms to activate amplifier before use */ +#define AMPLIFIER_DELAY 1 + +/* Time in ms to activate shutter before/after exposure */ +#define SHUTTER_DELAY 200 +/*=================== DaDa Structure =========================*/ +typedef struct { + AUD_HANDLE aud_handle; + int amplictrl; + int shutterctrl; + int nClear; + int running; + int error; + int schnarch; + int width, height; + pCounter count; + }Delcam, *pDelcam; +/*====================== codes =============================================*/ +#define NOBEAM -120 +#define FAULT -121 +/*------------------------------------------------------------------- + Configures the HM from the options in pOpt and the HM data structure + Returns 1 on success, 0 on failure +---------------------------------------------------------------------*/ +static int DelcamConfigure(pHistDriver self, SConnection *pCon, + pStringDict pOpt, SicsInterp *pSics){ + pDelcam pPriv = NULL; + char buffer[80]; + int status, w, h; + + pPriv =(pDelcam)self->pPriv; + + if(StringDictGet(pOpt,"amplictrl",buffer, 79) == 1){ + pPriv->amplictrl = atoi(buffer); + } else { + pPriv->amplictrl = 0; + } + if(pPriv->amplictrl < 0 || pPriv->amplictrl > 8){ + SCWrite(pCon,"ERROR: invalid amplictrl value, range 0 - 8",eError); + pPriv->amplictrl = 0; + } + if(StringDictGet(pOpt,"shutterctrl",buffer, 79) == 1){ + pPriv->shutterctrl = atoi(buffer); + } else { + pPriv->shutterctrl = 0; + } + if(StringDictGet(pOpt,"clear",buffer, 79) == 1){ + pPriv->nClear = atoi(buffer); + } else { + pPriv->nClear = 1; + } + if(StringDictGet(pOpt,"schnarch",buffer, 79) == 1){ + pPriv->schnarch = atoi(buffer); + } else { + pPriv->schnarch = 1; + } + if(StringDictGet(pOpt,"counter",buffer, 79) == 1){ + pPriv->count = (pCounter)FindCommandData(pServ->pSics, + buffer, "SingleCounter"); + } + if(pPriv->count == NULL){ + SCWrite(pCon,"ERROR: no slave counter configured: need it desperatly!", + eError); + return 0; + } + pPriv->running = 0; + if(pPriv->aud_handle == NULL){ + pPriv->aud_handle = aud_open(); + if(pPriv->aud_handle == NULL){ + SCWrite(pCon,"ERROR: failed to open DELCam", eError); + return 0; + } + } + status = aud_geometry_get(pPriv->aud_handle, 0, 0, &w, &h,0); + if(status != 0) { + snprintf(buffer,80,"ERROR: errno %d while trying to read geometry", + errno); + SCWrite(pCon,buffer,eError); + return 0; + } + sprintf(buffer,"%d",w); + StringDictUpdate(self->pOption,"dim0",buffer); + sprintf(buffer,"%d",h); + StringDictUpdate(self->pOption,"dim1",buffer); + configureHMdata(self->data,self->pOption,pCon); + if(!resizeBuffer(self->data)) { + SCWrite(pCon,"ERROR: out of memory allocating HMData for DELCam",eError); + return 0; + } + pPriv->width = w; + pPriv->height = h; + + return 1; +} +/*-------------------------------------------------------------------- + Start histogramming, Returns HWFault on failure, 1 on success +----------------------------------------------------------------------*/ +static int DelcamStart(pHistDriver self,SConnection *pCon){ + pDelcam pPriv = NULL; + int status, i; + char buffer[80]; + + pPriv =(pDelcam)self->pPriv; + + /* + * configure counter + */ + if(self->eCount != eTimer){ + SCWrite(pCon,"WARNING: bad count mode switched to preset time", + eWarning); + } + SetCounterMode(pPriv->count, eTimer); + SetCounterPreset(pPriv->count,self->fCountPreset); + + /* + * deal with amplifier + */ + if(pPriv->amplictrl |= 0){ + status = aud_amplifier_ctrl_set (pPriv->aud_handle, pPriv->amplictrl); + if(status != 0){ + snprintf(buffer,80,"ERROR: failed to set amplifier, errno = %d", + errno); + SCWrite(pCon,buffer,eError); + pPriv->error = FAULT; + return HWFault; + } + } + status = aud_amplifier_set(pPriv->aud_handle, 0); + if(status != 0){ + snprintf(buffer,80,"ERROR: failed to start amplifier, errno = %d", + errno); + SCWrite(pCon,buffer,eError); + pPriv->error = FAULT; + return HWFault; + } + usleep(AMPLIFIER_DELAY*1000); + + /* + * deal with shutter + */ + if(pPriv->shutterctrl |= 0){ + status = aud_shutter_ctrl_set (pPriv->aud_handle, pPriv->shutterctrl); + if(status != 0){ + snprintf(buffer,80,"ERROR: failed to set shutterctrl, errno = %d", + errno); + SCWrite(pCon,buffer,eError); + pPriv->error = FAULT; + return HWFault; + } + status = aud_shutter_set(pPriv->aud_handle, 1); + if(status != 0){ + snprintf(buffer,80,"ERROR: failed to start shutter, errno = %d", + errno); + SCWrite(pCon,buffer,eError); + pPriv->error = FAULT; + return HWFault; + } + usleep(SHUTTER_DELAY*1000); + } + + /* + * clear + */ + status = aud_clear(pPriv->aud_handle, pPriv->nClear); + if(status != 0){ + snprintf(buffer,80,"ERROR: failed to clear CCD, errno = %d", + errno); + SCWrite(pCon,buffer,eError); + pPriv->error = FAULT; + return HWFault; + } + + pPriv->running = 1; + clearHMData(self->data); + return pPriv->count->pDriv->Start(pPriv->count->pDriv); +} +/*-------------------------------------------------------------------- + Stops histogramming, Returns HWFault on failure, 1 on success +----------------------------------------------------------------------*/ +static int DelcamHalt(pHistDriver self){ + pDelcam pPriv = NULL; + + pPriv =(pDelcam)self->pPriv; + return pPriv->count->pDriv->Halt(pPriv->count->pDriv); +} +/*-------------------------------------------------------------------- + Checks histogramming status, Returns HWFault on failure, + HWIdle when finished, HWBusy when counting +----------------------------------------------------------------------*/ +static int DelcamCountStatus(pHistDriver self,SConnection *pCon){ + pDelcam pPriv = NULL; + int status, color, imSize = 0, i; + float val; + char buffer[80]; + unsigned short *imData = NULL; + char *shittyCompiler = NULL; + + pPriv =(pDelcam)self->pPriv; + + status = pPriv->count->pDriv->GetStatus(pPriv->count->pDriv,&val); + if(status == HWNoBeam) { + SCWrite(pCon,"ERROR: NO BEAM, aborting CCD measurement",eError); + DelcamHalt(self); + pPriv->error = NOBEAM; + status = HWFault; + } + if(status != HWBusy && pPriv->running == 1) { + pPriv->running = 0; + /* + * stop the CCD and transfer data + */ + if(pPriv->shutterctrl |= 0){ + status = aud_shutter_set(pPriv->aud_handle, 0); + if(status != 0){ + snprintf(buffer,80,"ERROR: failed to close shutter, errno = %d", + errno); + SCWrite(pCon,buffer,eError); + pPriv->error = FAULT; + status = HWFault; + } + usleep(SHUTTER_DELAY*1000); + } + status = aud_amplifier_set(pPriv->aud_handle, 1); + if(status != 0){ + snprintf(buffer,80,"ERROR: failed to stop amplifier, errno = %d", + errno); + SCWrite(pCon,buffer,eError); + pPriv->error = FAULT; + status = HWFault; + } + /* usleep(AMPLIFIER_DELAY*1000); */ + + + usleep(pPriv->schnarch*1000); + + SCWrite(pCon, + "WARNING: computer freeze for ~15 sec is normal during readout", + eWarning); + + status = aud_image_read(pPriv->aud_handle, &shittyCompiler, + &imSize, &pPriv->width, + &pPriv->height, &color); + imData = (unsigned short *)shittyCompiler; + if(status != 0){ + snprintf(buffer,80,"ERROR: failed to read DELCam with errno = %d", + errno); + SCWrite(pCon,buffer,eError); + pPriv->error = FAULT; + status = HWFault; + } + if(imData != NULL){ + for(i = 0; i < pPriv->width*pPriv->height; i++){ + self->data->localBuffer[i] = (int) imData[i]; + } + free(imData); + } + } + return status; +} +/*-------------------------------------------------------------------- + Get info on error after last HWFault, returns 1 always. + Puts an int error code into *code and errLen chars of + error description into error +----------------------------------------------------------------------*/ +static int DelcamGetError(pHistDriver self,int *code, + char *error, int errLen){ + pDelcam pPriv = NULL; + + pPriv =(pDelcam)self->pPriv; + switch(pPriv->error){ + case FAULT: + snprintf(error,errLen,"ERROR: DELcam fault"); + *code = FAULT; + break; + case NOBEAM: + snprintf(error,errLen,"ERROR: ABORT for beam interruption"); + *code = FAULT; + break; + default: + return pPriv->count->pDriv->GetError(pPriv->count->pDriv, + code, error, errLen); + } + return 0; +} +/*-------------------------------------------------------------------- + Try to fix the HM error in code. Returns COREDO when the last + operation needs to be redone, COTERM when the error cannot be + fixed. +----------------------------------------------------------------------*/ +static int DelcamFixIt(pHistDriver self,int code){ + pDelcam pPriv = NULL; + + pPriv =(pDelcam)self->pPriv; + switch(code){ + case FAULT: + case NOBEAM: + return COTERM; + break; + default: + return + pPriv->count->pDriv->TryAndFixIt(pPriv->count->pDriv,code); + break; + } + return COTERM; +} +/*-------------------------------------------------------------------- + GetData reads updates the internal cache of monitor values + from the hardware, Returns 1 or HWFault +----------------------------------------------------------------------*/ +static int DelcamGetData(pHistDriver self,SConnection *pCon){ + pDelcam pPriv = NULL; + + pPriv =(pDelcam)self->pPriv; + return 1; +} +/*-------------------------------------------------------------------- + GetMonitor reads the monitor value i. Returns either the monitor + value or -9999 if no such monitor exists or an error occurred +----------------------------------------------------------------------*/ +static long DelcamGetMonitor(pHistDriver self,int i, SConnection *pCon){ + pDelcam pPriv = NULL; + + pPriv =(pDelcam)self->pPriv; + return GetMonitor(pPriv->count,i,pCon); +} +/*-------------------------------------------------------------------- + GetTime reads the total counting time. Returns either the + value or -9999.99 if no such value exists or an error occurred +----------------------------------------------------------------------*/ +static float DelcamGetTime(pHistDriver self,SConnection *pCon){ + pDelcam pPriv = NULL; + + pPriv =(pDelcam)self->pPriv; + return GetCountTime(pPriv->count,pCon); +} +/*-------------------------------------------------------------------- + Pause histogramming, Returns HWFault on failure, 1 on success +----------------------------------------------------------------------*/ +static int DelcamPause(pHistDriver self,SConnection *pCon){ + pDelcam pPriv = NULL; + + pPriv =(pDelcam)self->pPriv; + SCWrite(pCon,"WARNING: pausing pointless for CCD, IGNORED!",eWarning); + return 1; +} +/*-------------------------------------------------------------------- + Continue histogramming, Returns HWFault on failure, 1 on success +----------------------------------------------------------------------*/ +static int DelcamContinue(pHistDriver self,SConnection *pCon){ + pDelcam pPriv = NULL; + + pPriv =(pDelcam)self->pPriv; + SCWrite(pCon,"WARNING: pausing pointless for CCD, IGNORED!",eWarning); + return 1; +} +/*-------------------------------------------------------------------- + Free the data associated with the private data structure of the driver +----------------------------------------------------------------------*/ +static int DelcamFree(pHistDriver self){ + pDelcam pPriv = NULL; + + pPriv =(pDelcam)self->pPriv; + aud_close(pPriv->aud_handle); + free(pPriv); + return 1; +} +/*-------------------------------------------------------------------- + Set The HM data or a subset of it. Returns HWFault or 1 +----------------------------------------------------------------------*/ +static int DelcamSetHistogram(pHistDriver self, + SConnection *pCon, + int i, int iStart, int iEnd, HistInt *pData){ + pDelcam pPriv = NULL; + int j; + + pPriv =(pDelcam)self->pPriv; + SCWrite(pCon,"WARNING: driver does not support setting HM",eWarning); + return 1; +} +/*-------------------------------------------------------------------- + Set HM to a preset value, Returns HWFault on failure, 1 on success +----------------------------------------------------------------------*/ +static int DelcamPreset(pHistDriver self,SConnection *pCon, + HistInt value){ + pDelcam pPriv = NULL; + int j; + + pPriv =(pDelcam)self->pPriv; + for(j = 0; j < pPriv->width*pPriv->height; j++){ + self->data->localBuffer[j] = value; + } + return 1; +} +/*-------------------------------------------------------------------- + get The HM data or a subset of it. Returns HWFault or 1 +----------------------------------------------------------------------*/ +static int DelcamGetHistogram(pHistDriver self, + SConnection *pCon, + int i, int iStart, int iEnd, HistInt *pData){ + pDelcam pPriv = NULL; + HistInt *data = NULL; + pPriv =(pDelcam)self->pPriv; + + data = self->data->localBuffer + iStart; + if(iEnd > getHMDataLength(self->data) || iStart < 0){ + SCWrite(pCon,"ERROR: data length out of range",eError); + return 0; + } + memcpy(pData,data,(iEnd - iStart)*sizeof(HistInt)); + return 1; +} +/*-------------------------------------------------------------------- + Make the HMDriver, returns a driver or NULL on failure +----------------------------------------------------------------------*/ +pHistDriver MakeDelcamHM(pStringDict pOption){ + pHistDriver pNew = NULL; + pDelcam pPriv = NULL; + + /* create the general driver */ + pNew = CreateHistDriver(pOption); + if(!pNew){ + return NULL; + } + + /*Create private data structure*/ + pPriv = NULL; + pPriv = (pDelcam)malloc(sizeof(Delcam)); + if(pPriv == NULL){ + return NULL; + } + memset(pPriv,0,sizeof(Delcam)); + pPriv->width = 768; + pPriv->height = 512; + pNew->pPriv = pPriv; + + + /* add our options */ + StringDictAddPair(pOption,"amplictrl","0"); + StringDictAddPair(pOption,"shutterctrl","0"); + StringDictAddPair(pOption,"clear","1"); + StringDictAddPair(pOption,"schnarch","1"); + StringDictAddPair(pOption,"counter","unkown"); + + /* configure all those functions */ + pNew->Configure = DelcamConfigure; + pNew->Start = DelcamStart; + pNew->Halt = DelcamHalt; + pNew->GetCountStatus = DelcamCountStatus; + pNew->GetError = DelcamGetError; + pNew->TryAndFixIt = DelcamFixIt; + pNew->GetData = DelcamGetData; + pNew->GetHistogram = DelcamGetHistogram; + pNew->SetHistogram = DelcamSetHistogram; + pNew->GetMonitor = DelcamGetMonitor; + pNew->GetTime = DelcamGetTime; + pNew->Preset = DelcamPreset; + pNew->FreePrivate = DelcamFree; + pNew->Pause = DelcamPause; + pNew->Continue = DelcamContinue; + + return pNew; +} diff --git a/distance.tex b/distance.tex new file mode 100644 index 0000000..9438907 --- /dev/null +++ b/distance.tex @@ -0,0 +1,71 @@ +\documentclass{article} + \usepackage{epsfig} + \usepackage{graphics} + \usepackage{color} + \usepackage{german} + \usepackage{fleqn} + \newcommand{\cor}[1]{{\color{red} #1}} + \textwidth 170mm + \textheight 240mm + \unitlength 1mm + \parindent 0mm + \oddsidemargin 0mm +\begin{document} + +\textbf{Neudefinitionen der Distanzen und Winkel f\"ur AMOR} + +J. Stahn, \today +\vfill + +\includegraphics[width=\textwidth]{distances.eps} +\vfill + +\begin{tabular}{ll} + $\sf C $ & chopper \\ + $\sf F $ & Filter \\ + $\sf M $ & Monochromator / Polarisator \\ + $\sf S $ & sample \\ + $\sf A $ & Analysator \\ + $\sf D $ & Detektor \\ + $\sf D_x $ & Blende $x$ \\ +\end{tabular} \\ + +Nullpunkt ist bei $\sf C$ auf Strahlh\"ohe. \\ + +Jede horizontale Position wird auf der Skala auf dem Granitsockel +jeweils mit offset abgelesen. \\ +Bsp. $\sf S$: Am Fu\3 des Probentisches ist eine Marke zum Ablesen +angebracht. Abgelesen wird der Wert $\sf S'$. +Dieser hat die bekannte Distanz $l_{\sf S}$ zum wahren +$\sf S$. Au\3erdem l\"auft die Skala ,,falschherum'' mit einem +Nullpunkt bei $d = ???? \,\mathrm{mm}$. Es folgt \\ +${\sf S} = d - {\sf S'} - l_{\sf S}$ \\ +Es wird also einerseits eine ,,statische'' Tabelle benoetigt die $d$ +und alle $l_{\sf I}$ enth\"alt; sowie eine ,,dynamische'' mit den aktuellen +Positionen $\sf I'$. Letztere werden evtl.\ in Zukunft zum Teil \"uber Encoder +ausgelesen werden k\"onnen. + +\cor{rot}: vom Nutzer zu w\"ahlende Werte \hfill +\textsf{klein}: Winkel \hfill +\textsf{GROSS}: Distanzen +\begin{eqnarray} + \sf \cor{mom} & & \\[2ex] + \sf \cor{som} & & \\[1ex] + \sf \cor{STZ} & & \\[1ex] + \sf SOZ &=&\sf MSH \tan[ \cor{m2t} ] \\[2ex] + \sf com &=&\sf \cor{s2t} - \cor{m2t} \\[1ex] + \sf COX &=&\sf SDH \, \left( \cos[ com ] - 1 \right) \\[1ex] + \sf COZ &=&\sf SDH \, \sin[ com ] + SOZ \\[1ex] + \sf \cor{C3Z} & & \\[3ex] + \sf D_SB &=&\sf MB_S \, \tan[ \cor{m2t} ] - 10 \\[1ex] + \sf D_2B &=&\sf MD_2 \, \tan[ \cor{m2t} ] - 0.5 \, \cor{D_2T} \\[1ex] + \sf D_3B &=&\sf MD_3 \, \tan[ \cor{m2t} ] - 0.5 \, \cor{D_3T} \\[1ex] + \sf D_4B &=&\sf SOZ + SD_4 \, \tan[ com ] - 0.5 \, \cor{D_4T} \\[2ex] + \sf D_5B &=&\sf SOZ + SD_5 \, \tan[ com ] - 0.5 \, \cor{D_5T} \\[2ex] + \sf AOZ &=&\sf SOZ + SA \, \tan[ com ] \\[1ex] + \sf aom &=&\sf com + \cor{ath} \\[2ex] + \sf CD &=&\sf CMH + \sqrt{SMH^2 + SOZ^2} + SDH +\end{eqnarray} + + +\end{document} diff --git a/make_gen b/make_gen index e074b4f..e01e374 100644 --- a/make_gen +++ b/make_gen @@ -18,7 +18,7 @@ OBJ=psi.o buffer.o ruli.o dmc.o nxsans.o nextrics.o sps.o pimotor.o \ el737hpv2driv.o swmotor2.o tricssupport.o amorcomp.o \ $(MZOBJ) amordrive.o amorset.o tcpdornier.o sinqhttp.o\ dgrambroadcast.o sinq.o tabledrive.o tcpdocho.o julcho.o \ - ritastorage.o poldizug.o + ritastorage.o poldizug.o audinelib.o delcam.o MZOBJ=fsm.o logger.o sugar.o pardef.o ease.o strobj.o oxinst.o logreader.o \ ipsdriv.o ilmdriv.o itcdriv.o ighdriv.o euro2kdriv.o modbus.o arrobj.o \ diff --git a/psi.c b/psi.c index a046c40..e72d4d0 100644 --- a/psi.c +++ b/psi.c @@ -271,6 +271,8 @@ static pCounterDriver CreatePsiCounterDriver(SConnection *pCon, return pNew; } /*-------------------------------------------------------------------*/ +extern pHistDriver MakeDelcamHM(pStringDict options); /* in delcam.c */ +/*--------------------------------------------------------------------*/ static HistDriver *CreatePsiHistMem(char *name, pStringDict pOptions){ HistDriver *pNew = NULL; @@ -280,6 +282,8 @@ static HistDriver *CreatePsiHistMem(char *name, pStringDict pOptions){ pNew = MakeTDCHM(pOptions); } else if(strcmp(name,"sinqhttp") == 0){ pNew = CreateSinqHttpDriver(pOptions); + } else if(strcmp(name,"delcam") == 0){ + pNew = MakeDelcamHM(pOptions); } return pNew; } diff --git a/test/delcamtest.tcl b/test/delcamtest.tcl new file mode 100644 index 0000000..4b0ebab --- /dev/null +++ b/test/delcamtest.tcl @@ -0,0 +1,87 @@ +# -------------------------------------------------------------------------- +# Initialization script for testing the DELcam driver for SICS +# +# Started: Dr. Mark Koennecke, March 2007 +#--------------------------------------------------------------------------- +# O P T I O N S + +# --------------- Initialize Tcl internals -------------------------------- + +# first all the server options are set + +ServerOption ReadTimeOut 10 +# timeout when checking for commands. In the main loop SICS checks for +# pending commands on each connection with the above timeout, has +# PERFORMANCE impact! + +ServerOption AcceptTimeOut 10 +# timeout when checking for connection req. +# Similar to above, but for connections + +ServerOption ReadUserPasswdTimeout 500000 +# time to wiat for a user/passwd to be sent from a client. Increase this +# if there is a problem connecting to a server due to network overload\ + +ServerOption ServerPort 2911 +# the port number the server is going to listen at. The client MUST know +# this number in order to connect. It is in client.ini + +ServerOption InterruptPort 2913 +# The UDP port where the server will wait for Interrupts from clients. +# Obviously, clients wishing to interrupt need to know this number. + +ServerOption TelnetPort 1301 +ServerOption TelWord sicslogin + +#--------------------------------------------------------------------------- +# U S E R S +# Syntax: SicsUser name password userRightsCode +SicsUser Spy 007 1 + +#----------------- Counters ------------------------------------------------- +MakeCounter counter regress +counter setpar errortype 1 0 +counter setpar recover 1 1 +#------------------------------ +proc SICSValue {command} { + set txt [eval $command] + set l [split $txt =] + return [string trim [lindex $l 1]] +} +#------------------------------------------------------------------------- +# Histogram Memory +#------------------------------------------------------------------------ +MakeHM hm delcam +hm configure rank 2 +hm configure dim0 769 +hm configure dim1 512 +hm configure amplictrl 1 +hm configure shutterctrl 2 +hm configure clear 1 +hm configure counter counter +hm configure init 1 +hm init +#------------------------------------------------------------------------ +# SicsData +#------------------------------------------------------------------------ +sicsdatafactory new data +#------------------------------------------------------------------------ +# Adapters for SansStatus +#------------------------------------------------------------------------ +proc hmframe {no {update 0}} { + set dim [SICSValue "hm configure dim0"] + data putint 0 $dim + set dim [SICSValue "hm configure dim1"] + data putint 1 $dim + data copyhm 2 hm + data writeuu framedata +} +#--------------------------------------------------------------------------- +proc statusinfo {} { + return "Dummy info for DELcam" +} +#---------------------------------------------------------------------------- +Publish hmframe Spy +Publish statusinfo Spy + +restore