Commit 91d31e5c authored by Éric Thiébaut's avatar Éric Thiébaut
Browse files

Implementation of start/stop, and check/update config

Some configuration options and on_wait_buffer callback still missing.
parent 81ab9630
# User visible changes in TAO library API
## Version 0.9.0
* Support for Finger Lakes Instrumentation (FLI) cameras.
## Version 0.8.2
This version was tested on Themis adaptive optics system on 2022-03-12.
* Deformable mirrors have new members `cmin` and `cmax` to indicate the minimum
and maximum values for an actuator command.
......
......@@ -33,10 +33,15 @@ static tao_status update_device_list();
// A handle fo a camera (see <libfipro.h>).
typedef int32_t fli_handle;
typedef struct fli_camera_ {
tao_camera base; // A FLI camera is also a TAO camera.
fli_handle handle;
// Number of acquisition buffers.
#define NBUFS 2
typedef struct fli_camera_ {
tao_camera base;///< A FLI camera is also a TAO camera.
fli_handle handle;///< Handle to device.
size_t bufsiz;///< Size of acquisition buffers.
void* bufs[NBUFS];///< Acquisition buffers.
int lastbuf;///< Index of last acquisition buffer.
} fli_camera;
// Function to deal with errors.
......@@ -55,6 +60,10 @@ static void fli_error(const char* func, int code);
} \
} while (0)
// Update exposure time and frame rate from current settings.
static tao_status update_exposure(
fli_camera* dev);
// Set the exposure time (in seconds) and the frame rate (in frames per
// second).
static tao_status set_exposure(
......@@ -62,20 +71,32 @@ static tao_status set_exposure(
double exposuretime,
double framerate);
// Set the pixel binning.
// Update the pixel binning from current settings.
static tao_status update_binning(
fli_camera* dev);
// Set the pixel binning to given settings.
static tao_status set_binning(
fli_camera* dev,
long xbin,
long ybin);
// Set the ROI.
static tao_status set_region(
// Update the image area from current settings.
static tao_status update_image_area(
fli_camera* dev);
// Set the the image area to given settings.
static tao_status set_image_area(
fli_camera* dev,
long xoff,
long yoff,
long width,
long height);
// Free all acquisition buffers.
static void free_buffers(
fli_camera* dev);
//-----------------------------------------------------------------------------
// Declaration of private methods and of the table grouping these methods for
// the unified camera API.
......@@ -206,6 +227,9 @@ static tao_status on_finalize(
// The camera is a FLI camera.
fli_camera* dev = (fli_camera*)cam;
// Free all acquisition buffers.
free_buffers(dev);
// Close the device.
if (dev->handle >= 0) {
fli_handle handle = dev->handle;
......@@ -225,18 +249,57 @@ static tao_status on_reset(
static tao_status on_update_config(
tao_camera* cam)
{
tao_store_error(__func__, TAO_NOT_YET_IMPLEMENTED);
return TAO_ERROR;
// The camera is a FLI camera.
fli_camera* dev = (fli_camera*)cam;
if (update_binning(dev) != TAO_OK ||
update_image_area(dev) != TAO_OK ||
update_exposure(dev) != TAO_OK) {
return TAO_ERROR;
}
return TAO_OK;
}
static tao_status on_check_config(
tao_camera* cam,
const tao_camera_config* cfg)
{
tao_store_error(__func__, TAO_NOT_YET_IMPLEMENTED);
// Name of caller for error messages.
const char* func = "tao_camera_check_configuration";
// Assume success for now
int code = TAO_SUCCESS;
// Check region of interest.
if (tao_camera_roi_check(&cfg->roi,
cam->info.sensorwidth,
cam->info.sensorheight) != TAO_OK) {
code = TAO_BAD_ROI;
goto error;
}
// Check exposure time and frame rate.
if (isnan(cfg->exposuretime) || isinf(cfg->exposuretime) ||
cfg->exposuretime < 0) {
code = TAO_BAD_EXPOSURETIME;
goto error;
}
if (isnan(cfg->framerate) || isinf(cfg->framerate) ||
cfg->framerate <= 0) {
code = TAO_BAD_FRAMERATE;
goto error;
}
// All parameters seem to be acceptable.
return TAO_OK;
// Errors branch here.
error:
tao_store_error(func, code);
return TAO_ERROR;
}
// Apply confiConfiguration. Configuration has already been checked.
static tao_status on_set_config(
tao_camera* cam,
const tao_camera_config* cfg)
......@@ -270,7 +333,7 @@ static tao_status on_set_config(
cfg->roi.yoff != cam->info.config.roi.yoff ||
cfg->roi.width != cam->info.config.roi.width ||
cfg->roi.height != cam->info.config.roi.height) {
if (set_region(dev, cfg->roi.xoff, cfg->roi.yoff,
if (set_image_area(dev, cfg->roi.xoff, cfg->roi.yoff,
cfg->roi.width, cfg->roi.height) != TAO_OK) {
return TAO_ERROR;
}
......@@ -282,23 +345,52 @@ static tao_status on_set_config(
return TAO_ERROR;
}
}
tao_store_error(__func__, TAO_NOT_YET_IMPLEMENTED);
return TAO_ERROR;
return TAO_OK;
}
static tao_status on_start(
tao_camera* cam)
{
// See FPROFrame_CaptureStart();
tao_store_error(__func__, TAO_NOT_YET_IMPLEMENTED);
return TAO_ERROR;
// The camera is a FLI camera.
fli_camera* dev = (fli_camera*)cam;
// Compute image size in bytes.
int size = FPROFrame_ComputeFrameSize(dev->handle);
if (size < 0) {
fli_error("FPROFrame_ComputeFrameSize", size);
return TAO_ERROR;
}
// Allocates acquisition buffers.
if (size != dev->bufsiz) {
// Free all acquisition buffers.
free_buffers(dev);
dev->bufsiz = size;
}
for (int i = 0; i < NBUFS; ++i) {
if (dev->bufs[i] == NULL) {
dev->bufs[i] = tao_malloc(size);
if (dev->bufs[i] == NULL) {
return TAO_ERROR;
}
}
}
dev->lastbuf = NBUFS - 1;
// Start image capture.
FLI_CALL(FPROFrame_CaptureStart,(dev->handle, 0), return TAO_ERROR);
return TAO_OK;
}
static tao_status on_stop(
tao_camera* cam)
{
// See FPROFrame_CaptureStop();
tao_store_error(__func__, TAO_NOT_YET_IMPLEMENTED);
return TAO_ERROR;
// The camera is a FLI camera.
fli_camera* dev = (fli_camera*)cam;
// Start image capture.
FLI_CALL(FPROFrame_CaptureStop,(dev->handle), return TAO_ERROR);
return TAO_OK;
}
static tao_status on_wait_buffer(
......@@ -335,6 +427,43 @@ static tao_status update_device_list()
#define NANOSECONDS_PER_SECOND 1e9
static void store_exposure(
fli_camera* dev,
uint64_t exposuretime_ns,
uint64_t framedelay_ns)
{
dev->base.info.config.exposuretime =
exposuretime_ns/NANOSECONDS_PER_SECOND;
dev->base.info.config.framerate =
NANOSECONDS_PER_SECOND/(exposuretime_ns
+ framedelay_ns);
}
// Update exposure time and frame rate from current settings.
static tao_status update_exposure(
fli_camera* dev)
{
uint64_t exposuretime_ns, framedelay_ns;
bool immediate;
for (int pass = 1; pass <= 2; ++pass) {
FLI_CALL(FPROCtrl_GetExposure,(dev->handle, &exposuretime_ns,
&framedelay_ns, &immediate),
return TAO_ERROR);
if (pass == 2 || !immediate) {
break;
}
FLI_CALL(FPROCtrl_SetExposure,(dev->handle, exposuretime_ns,
framedelay_ns, false),
return TAO_ERROR);
}
if (immediate) {
fputs("Warning: Failed to set `immediate` to `false` in "
"FPROCtrl_SetExposure.\n", stderr);
}
store_exposure(dev, exposuretime_ns, framedelay_ns);
return TAO_OK;
}
// Set the exposure time (in seconds) and the frame rate (in frames per
// second).
static tao_status set_exposure(
......@@ -352,34 +481,70 @@ static tao_status set_exposure(
(dev->handle, exposuretime_ns, framedelay_ns, false,
&actual_exposuretime_ns, &actual_framedelay_ns),
return TAO_ERROR);
dev->base.info.config.exposuretime =
actual_exposuretime_ns/NANOSECONDS_PER_SECOND;
dev->base.info.config.framerate =
NANOSECONDS_PER_SECOND/(actual_exposuretime_ns
+ actual_framedelay_ns);
store_exposure(dev, actual_exposuretime_ns, actual_framedelay_ns);
return TAO_OK;
}
// Update the pixel binning from current settings.
static tao_status update_binning(
fli_camera* dev)
{
uint32_t xbin, ybin;
FLI_CALL(FPROSensor_GetBinning,(dev->handle, &xbin, &ybin),
return TAO_ERROR);
dev->base.info.config.roi.xbin = xbin;
dev->base.info.config.roi.ybin = ybin;
return TAO_OK;
}
// Set the pixel binning.
// Set the pixel binning to given current settings.
static tao_status set_binning(
fli_camera* dev,
long xbin,
long ybin)
{
tao_store_error(__func__, TAO_NOT_YET_IMPLEMENTED);
return TAO_ERROR;
FLI_CALL(FPROSensor_SetBinning,(dev->handle, xbin, ybin),
return TAO_ERROR);
return update_binning(dev);
}
// Set the ROI.
static tao_status set_region(
// Update the image area from current settings.
static tao_status update_image_area(
fli_camera* dev)
{
uint32_t xoff, yoff, width, height;
FLI_CALL(FPROFrame_GetImageArea,
(dev->handle, &xoff, &yoff, &width, &height), return TAO_ERROR);
dev->base.info.config.roi.xoff = xoff;
dev->base.info.config.roi.yoff = yoff;
dev->base.info.config.roi.width = width;
dev->base.info.config.roi.height = height;
return TAO_OK;
}
// Set the image area to given current settings.
static tao_status set_image_area(
fli_camera* dev,
long xoff,
long yoff,
long width,
long height)
{
tao_store_error(__func__, TAO_NOT_YET_IMPLEMENTED);
return TAO_ERROR;
FLI_CALL(FPROFrame_SetImageArea,
(dev->handle, xoff, yoff, width, height), return TAO_ERROR);
return update_image_area(dev);
}
// Free all acquisition buffers.
static void free_buffers(
fli_camera* dev)
{
for (int i = 0; i < NBUFS; ++i) {
void* buf = dev->bufs[i];
dev->bufs[i] = NULL;
free(buf);
}
dev->bufsiz = 0;
}
//-----------------------------------------------------------------------------
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment