comedilib/comedi_calibrate/save_cal.c
2003-08-16 23:18:07 +00:00

245 lines
6.6 KiB
C

/*
comedi_calibrate/save_cal.c - stuff for saving calibration info to
a file.
Copyright (C) 2003 Frank Mori Hess <fmhess@users.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
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include <string.h>
#include <comedilib.h>
#include "calib.h"
void write_caldac( FILE *file, comedi_caldac_t caldac )
{
static const char *indent = "\t\t\t\t";
fprintf( file, "%s", indent );
fprintf( file, "{\n" );
fprintf( file, "%s", indent );
fprintf( file, "\tsubdevice => %i,\n", caldac.subdevice );
fprintf( file, "%s", indent );
fprintf( file, "\tchannel => %i,\n", caldac.channel );
fprintf( file, "%s", indent );
fprintf( file, "\tvalue => %i,\n", caldac.value );
fprintf( file, "%s", indent );
fprintf( file, "}" );
}
void write_calibration_setting( FILE *file, comedi_calibration_setting_t setting )
{
static const char *indent = "\t\t";
int i;
fprintf( file, "%s", indent );
fprintf( file, "{\n" );
fprintf( file, "%s", indent );
fprintf( file, "\tsubdevice => %i,\n", setting.subdevice );
fprintf( file, "%s", indent );
fprintf( file, "\tchannels => [" );
for( i = 0; i < setting.num_channels; i++ )
fprintf( file, "%i,", setting.channels[ i ] );
fprintf( file, "],\n" );
fprintf( file, "%s", indent );
fprintf( file, "\tranges => [" );
for( i = 0; i < setting.num_ranges; i++ )
fprintf( file, "%i,", setting.ranges[ i ] );
fprintf( file, "],\n" );
fprintf( file, "%s", indent );
fprintf( file, "\tarefs => [" );
for( i = 0; i < setting.num_arefs; i++ )
fprintf( file, "%i,", setting.arefs[ i ] );
fprintf( file, "],\n" );
fprintf( file, "%s", indent );
fprintf( file, "\tcaldacs =>\n" );
fprintf( file, "%s", indent );
fprintf( file, "\t[\n" );
for( i = 0; i < setting.num_caldacs; i++ )
{
write_caldac( file, setting.caldacs[ i ] );
fprintf( file, ",\n" );
}
fprintf( file, "%s", indent );
fprintf( file, "\t],\n" );
fprintf( file, "%s", indent );
fprintf( file, "}" );
}
int write_calibration_perl_hash( FILE *file, const comedi_calibration_t *calibration )
{
int i;
time_t now;
now = time( NULL );
fprintf( file, "#calibration file generated by comedi_calibrate\n"
"#%s\n", ctime( &now ) );
fprintf( file, "{\n" );
fprintf( file, "\tdriver_name => \"%s\",\n", calibration->driver_name );
fprintf( file, "\tboard_name => \"%s\",\n", calibration->board_name );
fprintf( file, "\tcalibrations =>\n"
"\t[\n" );
for( i = 0; i < calibration->num_settings; i++ )
{
write_calibration_setting( file, calibration->settings[ i ] );
fprintf( file, ",\n" );
}
fprintf( file, "\t],\n"
"}\n");
return 0;
}
int write_calibration_file( calibration_setup_t *setup )
{
FILE *file;
int retval;
assert( setup->new_calibration != NULL );
assert( setup->cal_save_file_path );
file = fopen( setup->cal_save_file_path, "w" );
if( file == NULL )
{
fprintf( stderr, "failed to open file %s for writing\n",
setup->cal_save_file_path );
perror( "fopen" );
return -1;
}
DPRINT( 0, "writing calibration to %s\n", setup->cal_save_file_path );
retval = write_calibration_perl_hash( file, setup->new_calibration );
fclose( file );
return retval;
}
comedi_calibration_setting_t* sc_alloc_calibration_setting( calibration_setup_t *setup )
{
comedi_calibration_setting_t *temp;
temp = realloc( setup->new_calibration->settings,
( setup->new_calibration->num_settings + 1 ) * sizeof( comedi_calibration_setting_t ) );
assert( temp != NULL );
setup->new_calibration->settings = temp;
memset( &setup->new_calibration->settings[ setup->new_calibration->num_settings ],
0, sizeof( comedi_calibration_setting_t ) );
setup->new_calibration->num_settings++;
return &setup->new_calibration->settings[ setup->new_calibration->num_settings - 1 ];
}
void sc_push_caldac( comedi_calibration_setting_t *saved_cal, caldac_t caldac )
{
int i;
/* check if caldac is already listed, in which case we just update */
for( i = 0; i < saved_cal->num_caldacs; i++ )
{
if( saved_cal->caldacs[ i ].subdevice != caldac.subdev ) continue;
if( saved_cal->caldacs[ i ].channel != caldac.chan ) continue;
break;
}
if( i < saved_cal->num_caldacs )
{
saved_cal->caldacs[ i ].value = caldac.current;
return;
}
saved_cal->caldacs = realloc( saved_cal->caldacs,
( saved_cal->num_caldacs + 1 ) * sizeof( caldac_t ) );
if( saved_cal->caldacs == NULL )
{
fprintf( stderr, "memory allocation failure\n" );
abort();
}
saved_cal->caldacs[ saved_cal->num_caldacs ].subdevice = caldac.subdev;
saved_cal->caldacs[ saved_cal->num_caldacs ].channel = caldac.chan;
saved_cal->caldacs[ saved_cal->num_caldacs ].value = caldac.current;
saved_cal->num_caldacs++;
}
void sc_push_channel( comedi_calibration_setting_t *saved_cal, int channel )
{
if( channel == SC_ALL_CHANNELS )
{
saved_cal->num_channels = 0;
if( saved_cal->channels )
{
free( saved_cal->channels );
saved_cal->channels = NULL;
}
}else
{
saved_cal->channels = realloc( saved_cal->channels,
( saved_cal->num_channels + 1 ) * sizeof( int ) );
if( saved_cal->channels == NULL )
{
fprintf( stderr, "memory allocation failure\n" );
abort();
}
saved_cal->channels[ saved_cal->num_channels++ ] = channel;
}
}
void sc_push_range( comedi_calibration_setting_t *saved_cal, int range )
{
if( range == SC_ALL_RANGES )
{
saved_cal->num_ranges = 0;
if( saved_cal->ranges )
{
free( saved_cal->ranges );
saved_cal->ranges = NULL;
}
}
else
{
saved_cal->ranges = realloc( saved_cal->ranges,
( saved_cal->num_ranges + 1 ) * sizeof( int ) );
if( saved_cal->ranges == NULL )
{
fprintf( stderr, "memory allocation failure\n" );
abort();
}
saved_cal->ranges[ saved_cal->num_ranges++ ] = range;
}
}
void sc_push_aref( comedi_calibration_setting_t *saved_cal, int aref )
{
assert( saved_cal->num_arefs < CS_MAX_AREFS_LENGTH );
if( aref == SC_ALL_AREFS )
saved_cal->num_arefs = 0;
else
saved_cal->arefs[ saved_cal->num_arefs++ ] = aref;
}