245 lines
6.6 KiB
C
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;
|
|
}
|
|
|