diff options
| -rw-r--r-- | src/cameras/pco.c | 50 | ||||
| -rw-r--r-- | src/cameras/pf.c | 21 | ||||
| -rw-r--r-- | src/uca.c | 62 | ||||
| -rw-r--r-- | src/uca.h | 21 | ||||
| -rw-r--r-- | test/control.c | 30 | 
5 files changed, 127 insertions, 57 deletions
| diff --git a/src/cameras/pco.c b/src/cameras/pco.c index ff2daff..b84ee01 100644 --- a/src/cameras/pco.c +++ b/src/cameras/pco.c @@ -12,7 +12,7 @@  #define GET_PCO(uca) ((struct pco_edge_t *)(uca->user)) -#define set_void(p, type, value) { *((type *) p) = value; } +#define set_void(p, type, value) { *((type *) p) = (type) value; }  static uint32_t uca_pco_set_bitdepth(struct uca_camera_t *cam, uint8_t *bitdepth) @@ -105,8 +105,30 @@ static uint32_t uca_pco_get_property(struct uca_camera_t *cam, enum uca_property              {                  /* FIXME: how to ensure, that buffer is large enough? */                  SC2_Camera_Name_Response name; -                if (pco_read_property(pco, GET_CAMERA_NAME, &name, sizeof(name)) == PCO_NOERROR) -                    strcpy((char *) data, name.szName); + +                /* FIXME: This is _not_ a mistake. For some reason (which I +                 * still have to figure out), it is sometimes not possible to +                 * read the camera name... unless the same call precedes that +                 * one.*/ +                pco_read_property(pco, GET_CAMERA_NAME, &name, sizeof(name)); +                pco_read_property(pco, GET_CAMERA_NAME, &name, sizeof(name)); +                strcpy((char *) data, name.szName); +            } +            break; + +        case UCA_PROP_TEMPERATURE_SENSOR: +            { +                SC2_Temperature_Response temperature; +                if (pco_read_property(pco, GET_TEMPERATURE, &temperature, sizeof(temperature)) == PCO_NOERROR) +                    set_void(data, uint32_t, temperature.sCCDtemp / 10); +            } +            break; + +        case UCA_PROP_TEMPERATURE_CAMERA: +            { +                SC2_Temperature_Response temperature; +                if (pco_read_property(pco, GET_TEMPERATURE, &temperature, sizeof(temperature)) == PCO_NOERROR) +                    set_void(data, uint32_t, temperature.sCamtemp);              }              break; @@ -144,6 +166,14 @@ static uint32_t uca_pco_get_property(struct uca_camera_t *cam, enum uca_property                  return UCA_ERR_PROP_GENERAL;              break; +        case UCA_PROP_DELAY: +            { +                uint32_t exposure; +                if (pco_get_delay_exposure(pco, (uint32_t *) data, &exposure) != PCO_NOERROR) +                    return UCA_ERR_PROP_INVALID; +            } +            break; +          case UCA_PROP_DELAY_MIN:              set_void(data, uint32_t, pco->description.dwMinDelayDESC);              break; @@ -152,6 +182,14 @@ static uint32_t uca_pco_get_property(struct uca_camera_t *cam, enum uca_property              set_void(data, uint32_t, pco->description.dwMaxDelayDESC);              break; +        case UCA_PROP_EXPOSURE: +            { +                uint32_t delay; +                if (pco_get_delay_exposure(pco, &delay, (uint32_t *) data) != PCO_NOERROR) +                    return UCA_ERR_PROP_INVALID; +            } +            break; +          case UCA_PROP_EXPOSURE_MIN:              set_void(data, uint32_t, pco->description.dwMinExposureDESC);              break; @@ -161,7 +199,7 @@ static uint32_t uca_pco_get_property(struct uca_camera_t *cam, enum uca_property              break;          case UCA_PROP_BITDEPTH: -            set_void(data, uint8_t, 16); +            set_void(data, uint32_t, 16);              break;          default: @@ -224,14 +262,12 @@ uint32_t uca_pco_init(struct uca_camera_t **cam, struct uca_grabber_t *grabber)      uca->grab = &uca_pco_grab;      /* Prepare camera for recording */ +    pco_set_scan_mode(pco, PCO_SCANMODE_SLOW);      pco_set_rec_state(pco, 0);      pco_set_timestamp_mode(pco, 2);      pco_set_timebase(pco, 1, 1);       pco_arm_camera(pco); -    if (pco->transfer.DataFormat != (SCCMOS_FORMAT_TOP_CENTER_BOTTOM_CENTER | PCO_CL_DATAFORMAT_5x16)) -        pco->transfer.DataFormat = SCCMOS_FORMAT_TOP_CENTER_BOTTOM_CENTER | PCO_CL_DATAFORMAT_5x16; -      /* Prepare frame grabber for recording */      int val = FG_CL_8BIT_FULL_10;      grabber->set_property(grabber, FG_CAMERA_LINK_CAMTYP, &val); diff --git a/src/cameras/pf.c b/src/cameras/pf.c index 92ffa5d..bd9cd49 100644 --- a/src/cameras/pf.c +++ b/src/cameras/pf.c @@ -45,18 +45,16 @@ static struct uca_pf_map uca_to_pf[] = {      { UCA_PROP_Y_OFFSET_MIN,"Window.Y.Min" },      { UCA_PROP_Y_OFFSET_MAX,"Window.Y.Max" },      { UCA_PROP_EXPOSURE,    "ExposureTime" }, -    { UCA_PROP_EXPOSURE_MIN, "ExposureTime.Min" }, -    { UCA_PROP_EXPOSURE_MAX, "ExposureTime.Max" }, +    { UCA_PROP_EXPOSURE_MIN,"ExposureTime.Min" }, +    { UCA_PROP_EXPOSURE_MAX,"ExposureTime.Max" }, +    { UCA_PROP_DELAY,       "Trigger.Delay" }, +    { UCA_PROP_DELAY_MIN,   "Trigger.Delay.Min" }, +    { UCA_PROP_DELAY_MAX,   "Trigger.Delay.Max" },      { UCA_PROP_FRAMERATE,   "FrameRate" }, +    { UCA_PROP_TRIGGER_MODE,"Trigger.Source" },      { -1, NULL }  }; -static uint32_t uca_pf_set_bitdepth(struct uca_camera_t *cam, uint8_t *bitdepth) -{ -    /* TODO: it's not possible via CameraLink so do it via frame grabber */ -    return 0; -} -  static uint32_t uca_pf_acquire_image(struct uca_camera_t *cam, void *buffer)  {      return UCA_NO_ERROR; @@ -67,6 +65,8 @@ static uint32_t uca_pf_set_property(struct uca_camera_t *cam, enum uca_property_      struct uca_grabber_t *grabber = cam->grabber;      TOKEN t = INVALID_TOKEN;      int i = 0; + +    /* Find a valid pf token for the property */      while (uca_to_pf[i].uca_prop != -1) {          if (uca_to_pf[i].uca_prop == property)              t = pfProperty_ParseName(0, uca_to_pf[i].pf_prop); @@ -156,12 +156,17 @@ static uint32_t uca_pf_get_property(struct uca_camera_t *cam, enum uca_property_                          strcpy((char *) data, value.value.p);                      }                      break; + +                case PF_MODE: +                    set_void(data, uint32_t, (uint32_t) value.value.i); +                    break;              }              return UCA_NO_ERROR;          }          i++;      } +    /* Handle all special cases */      switch (property) {          case UCA_PROP_BITDEPTH:              set_void(data, uint8_t, 8); @@ -33,39 +33,43 @@ const char *uca_unit_map[] = {      "ms",      "s",      "rows", -    "fps" +    "fps", +    "°C",      ""   };  static struct uca_property_t property_map[UCA_PROP_LAST+1] = { -    { "general.name",           uca_na,     uca_string,  uca_read },  -    { "image.width",            uca_pixel,  uca_uint32t, uca_readwrite },  -    { "image.width.min",        uca_pixel,  uca_uint32t, uca_read },  -    { "image.width.max",        uca_pixel,  uca_uint32t, uca_read },  -    { "image.height",           uca_pixel,  uca_uint32t, uca_readwrite },  -    { "image.height.min",       uca_pixel,  uca_uint32t, uca_read },  -    { "image.height.max",       uca_pixel,  uca_uint32t, uca_read },  -    { "image.offset.x",         uca_pixel,  uca_uint32t, uca_readwrite },  -    { "image.offset.x.min",     uca_pixel,  uca_uint32t, uca_read },  -    { "image.offset.x.max",     uca_pixel,  uca_uint32t, uca_read },  -    { "image.offset.y",         uca_pixel,  uca_uint32t, uca_readwrite },  -    { "image.offset.y.min",     uca_pixel,  uca_uint32t, uca_read },  -    { "image.offset.y.max",     uca_pixel,  uca_uint32t, uca_read },  -    { "image.bitdepth",         uca_bits,   uca_uint8t,  uca_read},  -    { "time.exposure",          uca_us,     uca_uint32t, uca_readwrite },  -    { "time.exposure.min",      uca_ns,     uca_uint32t, uca_read },  -    { "time.exposure.max",      uca_ms,     uca_uint32t, uca_read },  -    { "time.delay",             uca_us,     uca_uint32t, uca_readwrite },  -    { "time.delay.min",         uca_ns,     uca_uint32t, uca_read },  -    { "time.delay.max",         uca_ms,     uca_uint32t, uca_read },  -    { "time.framerate",         uca_fps,    uca_uint32t, uca_read },  -    { "mode.trigger",           uca_na,     uca_uint32t, uca_readwrite },  -    { "mode.timestamp",         uca_na,     uca_uint32t, uca_readwrite },  -    { "mode.scan",              uca_na,     uca_uint32t, uca_readwrite },  -    { "ipe.interlace.samplerate", uca_na,   uca_uint32t, uca_readwrite },  -    { "ipe.interlace.threshold.pixel", uca_na, uca_uint32t, uca_readwrite },  -    { "ipe.interlace.threshold.row", uca_na, uca_uint32t,   uca_readwrite }, -    { "mode.correction",        uca_na,     uca_uint32t, uca_readwrite },  +    { "General.Name",           uca_na,     uca_string,  uca_read },  +    { "Image.Width",            uca_pixel,  uca_uint32t, uca_readwrite },  +    { "Image.Width.Min",        uca_pixel,  uca_uint32t, uca_read },  +    { "Image.Width.Max",        uca_pixel,  uca_uint32t, uca_read },  +    { "Image.Height",           uca_pixel,  uca_uint32t, uca_readwrite },  +    { "Image.Height.Min",       uca_pixel,  uca_uint32t, uca_read },  +    { "Image.Height.Max",       uca_pixel,  uca_uint32t, uca_read },  +    { "Image.Offset.x",         uca_pixel,  uca_uint32t, uca_readwrite },  +    { "Image.Offset.x.Min",     uca_pixel,  uca_uint32t, uca_read },  +    { "Image.Offset.x.Max",     uca_pixel,  uca_uint32t, uca_read },  +    { "Image.Offset.y",         uca_pixel,  uca_uint32t, uca_readwrite },  +    { "Image.Offset.y.Min",     uca_pixel,  uca_uint32t, uca_read },  +    { "Image.Offset.y.Max",     uca_pixel,  uca_uint32t, uca_read },  +    { "Image.Bitdepth",         uca_bits,   uca_uint32t, uca_read},  +    { "Time.Exposure",          uca_us,     uca_uint32t, uca_readwrite },  +    { "Time.Exposure.Min",      uca_ns,     uca_uint32t, uca_read },  +    { "Time.Exposure.Max",      uca_ms,     uca_uint32t, uca_read },  +    { "Time.Delay",             uca_us,     uca_uint32t, uca_readwrite },  +    { "Time.Delay.Min",         uca_ns,     uca_uint32t, uca_read },  +    { "Time.Delay.Max",         uca_ms,     uca_uint32t, uca_read },  +    { "Time.Framerate",         uca_fps,    uca_uint32t, uca_read },  +    { "Temperature.Sensor",     uca_dc,     uca_uint32t, uca_read }, +    { "Temperature.Camera",     uca_dc,     uca_uint32t, uca_read }, +    { "Trigger.Mode",           uca_na,     uca_uint32t, uca_readwrite },  +    { "Trigger.Exposure",       uca_na,     uca_uint32t, uca_readwrite }, +    { "Mode.Timestamp",         uca_na,     uca_uint32t, uca_readwrite },  +    { "Mode.Scan",              uca_na,     uca_uint32t, uca_readwrite },  +    { "Interlace.Samplerate",   uca_na,     uca_uint32t, uca_readwrite },  +    { "Interlace.Threshold.Pixel", uca_na,  uca_uint32t, uca_readwrite },  +    { "Interlace.Threshold.Row", uca_na,    uca_uint32t, uca_readwrite }, +    { "Mode.correction",        uca_na,     uca_uint32t, uca_readwrite },       { NULL, 0, 0, 0 }  }; @@ -66,7 +66,10 @@ enum uca_property_ids {      UCA_PROP_DELAY_MIN,      UCA_PROP_DELAY_MAX,      UCA_PROP_FRAMERATE, +    UCA_PROP_TEMPERATURE_SENSOR, +    UCA_PROP_TEMPERATURE_CAMERA,      UCA_PROP_TRIGGER_MODE, +    UCA_PROP_TRIGGER_EXPOSURE,      /* pco.edge specific */      UCA_PROP_TIMESTAMP_MODE, @@ -87,11 +90,14 @@ enum uca_property_ids {  #define UCA_TIMESTAMP_ASCII     0x01  #define UCA_TIMESTAMP_BINARY    0x02 -/* Trigger mode for UCA_PROP_TRIGGERMODE */ -#define UCA_TRIGGER_AUTO        1 -#define UCA_TRIGGER_INTERNAL    2 +/* Trigger mode for UCA_PROP_TRIGGER_MODE */ +#define UCA_TRIGGER_AUTO        1   /**< free-run mode */ +#define UCA_TRIGGER_SOFTWARE    2  #define UCA_TRIGGER_EXTERNAL    3 +#define UCA_TRIGGER_EXP_CAMERA  1   /**< camera-controlled exposure time */ +#define UCA_TRIGGER_EXP_LEVEL   2   /**< level-controlled (trigger signal) exposure time */ +  /* Correction modes for UCA_PROP_CORRECTION_MODE */  #define UCA_CORRECT_OFFSET      0x01  #define UCA_CORRECT_HOTPIXEL    0x02 @@ -107,12 +113,13 @@ struct uca_property_t {      enum uca_unit {          uca_pixel = 0,          uca_bits, -        uca_ns, -        uca_us, -        uca_ms, +        uca_ns,     /**< nano seconds */ +        uca_us,     /**< micro seconds */ +        uca_ms,     /**< milli seconds */          uca_s,          uca_rows, -        uca_fps, +        uca_fps,    /**< frames per second */ +        uca_dc,     /**< degree celsius */          uca_na      } unit; diff --git a/test/control.c b/test/control.c index 5444755..2cf8a4f 100644 --- a/test/control.c +++ b/test/control.c @@ -11,7 +11,7 @@ struct ThreadData {      GdkPixbuf *pixbuf;      int width;      int height; - +    int bits;      struct uca_camera_t *cam;  }; @@ -35,7 +35,7 @@ static void destroy(GtkWidget *widget, gpointer data)      gtk_main_quit ();  } -void grey_to_rgb(guchar *output, guchar *input, int width, int height) +void convert_8bit_to_rgb(guchar *output, guchar *input, int width, int height)  {      for (int x = 0; x < width; x++) {          for (int y = 0; y < height; y++) { @@ -47,6 +47,20 @@ void grey_to_rgb(guchar *output, guchar *input, int width, int height)      }  } +void convert_16bit_to_rgb(guchar *output, guchar *input, int width, int height) +{ +    uint16_t *in = (uint16_t *) input; +    for (int x = 0; x < width; x++) { +        for (int y = 0; y < height; y++) { +            const int off = y*width + x; +            guchar val = (uint8_t) ((in[off]/65536.0f)*256.0f); +            output[off*3] = val; +            output[off*3+1] = val; +            output[off*3+2] = val; +        } +    } +} +  void *grab_thread(void *args)  {      struct ThreadData *data = (struct ThreadData *) args; @@ -54,7 +68,10 @@ void *grab_thread(void *args)      while (TRUE) {          cam->grab(cam, (char *) data->buffer); -        grey_to_rgb(data->pixels, data->buffer, data->width, data->height); +        if (data->bits == 8) +            convert_8bit_to_rgb(data->pixels, data->buffer, data->width, data->height); +        else if (data->bits == 16) +            convert_16bit_to_rgb(data->pixels, data->buffer, data->width, data->height);          gdk_threads_enter();          gdk_flush(); @@ -216,7 +233,6 @@ int main(int argc, char *argv[])      cam->get_property(cam, UCA_PROP_WIDTH, &width);      cam->get_property(cam, UCA_PROP_HEIGHT, &height);      cam->get_property(cam, UCA_PROP_BITDEPTH, &bits_per_sample); -    bits_per_sample = 8;      g_thread_init(NULL);      gdk_threads_init(); @@ -246,21 +262,23 @@ int main(int argc, char *argv[])      g_signal_connect (window, "destroy",                G_CALLBACK (destroy), uca); -    GdkPixbuf *pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, bits_per_sample, width, height); +    GdkPixbuf *pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, width, height);      gtk_image_set_from_pixbuf(GTK_IMAGE(image), pixbuf);      gtk_widget_show(image);      gtk_widget_show(window);      /* start grabbing and thread */ +    int mem_size = bits_per_sample == 8 ? 1 : 2;      struct ThreadData td;      uca_cam_alloc(cam, 20);      td.image  = image;      td.pixbuf = pixbuf; -    td.buffer = (guchar *) g_malloc(width * height); +    td.buffer = (guchar *) g_malloc(mem_size * width * height);      td.pixels = gdk_pixbuf_get_pixels(pixbuf);      td.width  = width;      td.height = height; +    td.bits   = bits_per_sample;      td.cam    = cam;      cam->start_recording(cam);      if (!g_thread_create(grab_thread, &td, FALSE, &error)) { | 
