~ubuntu-branches/ubuntu/feisty/comedilib/feisty

« back to all changes in this revision

Viewing changes to lib/calib.c

  • Committer: Bazaar Package Importer
  • Author(s): David Schleef
  • Date: 2003-09-23 18:11:12 UTC
  • Revision ID: james.westby@ubuntu.com-20030923181112-sat05jyh702rb1at
Tags: upstream-0.7.21
ImportĀ upstreamĀ versionĀ 0.7.21

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    lib/calib.c
 
3
    functions for setting calibration
 
4
 
 
5
    Copyright (C) 2003 Frank Mori Hess <fmhess@users.sourceforge.net
 
6
 
 
7
    This library is free software; you can redistribute it and/or
 
8
    modify it under the terms of the GNU Lesser General Public
 
9
    License as published by the Free Software Foundation, version 2.1
 
10
    of the License.
 
11
 
 
12
    This library is distributed in the hope that it will be useful,
 
13
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
15
    Lesser General Public License for more details.
 
16
 
 
17
    You should have received a copy of the GNU Lesser General Public
 
18
    License along with this library; if not, write to the Free Software
 
19
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 
20
    USA.
 
21
*/
 
22
 
 
23
#define _GNU_SOURCE
 
24
 
 
25
#include <stdlib.h>
 
26
#include <stdio.h>
 
27
#include <string.h>
 
28
#include "libinternal.h"
 
29
 
 
30
static int set_calibration( comedi_t *dev, const comedi_calibration_t *parsed_file,
 
31
        unsigned int cal_index );
 
32
 
 
33
static int check_cal_file( comedi_t *dev, const comedi_calibration_t *parsed_file )
 
34
{
 
35
        if( strcmp( comedi_get_driver_name( dev ), parsed_file->driver_name ) )
 
36
        {
 
37
                COMEDILIB_DEBUG( 3, "driver name does not match '%s' from calibration file\n",
 
38
                        parsed_file->driver_name );
 
39
                return -1;
 
40
        }
 
41
 
 
42
        if( strcmp( comedi_get_board_name( dev ), parsed_file->board_name ) )
 
43
        {
 
44
                COMEDILIB_DEBUG( 3, "board name does not match '%s' from calibration file\n",
 
45
                        parsed_file->board_name );
 
46
                return -1;
 
47
        }
 
48
 
 
49
        return 0;
 
50
}
 
51
 
 
52
static inline int valid_channel( const comedi_calibration_t *parsed_file,
 
53
        unsigned int cal_index, unsigned int channel )
 
54
{
 
55
        int num_channels, i;
 
56
 
 
57
        num_channels = parsed_file->settings[ cal_index ].num_channels;
 
58
        if( num_channels == 0 ) return 1;
 
59
        for( i = 0; i < num_channels; i++ )
 
60
        {
 
61
                if( parsed_file->settings[ cal_index ].channels[ i ] == channel )
 
62
                        return 1;
 
63
        }
 
64
 
 
65
        return 0;
 
66
}
 
67
 
 
68
static inline int valid_range( const comedi_calibration_t *parsed_file,
 
69
        unsigned int cal_index, unsigned int range )
 
70
{
 
71
        int num_ranges, i;
 
72
 
 
73
        num_ranges = parsed_file->settings[ cal_index ].num_ranges;
 
74
        if( num_ranges == 0 ) return 1;
 
75
        for( i = 0; i < num_ranges; i++ )
 
76
        {
 
77
                if( parsed_file->settings[ cal_index ].ranges[ i ] == range )
 
78
                        return 1;
 
79
        }
 
80
 
 
81
        return 0;
 
82
}
 
83
 
 
84
static inline int valid_aref( const comedi_calibration_t *parsed_file,
 
85
        unsigned int cal_index, unsigned int aref )
 
86
{
 
87
        int num_arefs, i;
 
88
 
 
89
        num_arefs = parsed_file->settings[ cal_index ].num_arefs;
 
90
        if( num_arefs == 0 ) return 1;
 
91
        for( i = 0; i < num_arefs; i++ )
 
92
        {
 
93
                if( parsed_file->settings[ cal_index ].arefs[ i ] == aref )
 
94
                        return 1;
 
95
        }
 
96
 
 
97
        return 0;
 
98
}
 
99
 
 
100
static int apply_calibration( comedi_t *dev, const comedi_calibration_t *parsed_file,
 
101
        unsigned int subdev, unsigned int channel, unsigned int range, unsigned int aref )
 
102
{
 
103
        int num_cals, i, retval;
 
104
        int found_cal = 0;
 
105
 
 
106
        num_cals = parsed_file->num_settings;
 
107
 
 
108
        for( i = 0; i < num_cals; i++ )
 
109
        {
 
110
                if( parsed_file->settings[ i ].subdevice != subdev ) continue;
 
111
                if( valid_range( parsed_file, i, range ) == 0 ) continue;
 
112
                if( valid_channel( parsed_file, i, channel ) == 0 ) continue;
 
113
                if( valid_aref( parsed_file, i, aref ) == 0 ) continue;
 
114
 
 
115
                retval = set_calibration( dev, parsed_file, i );
 
116
                if( retval < 0 ) return retval;
 
117
                found_cal = 1;
 
118
        }
 
119
        if( found_cal == 0 )
 
120
        {
 
121
                COMEDILIB_DEBUG( 3, "failed to find matching calibration\n" );
 
122
                return -1;
 
123
        }
 
124
 
 
125
        return 0;
 
126
}
 
127
 
 
128
static int set_calibration( comedi_t *dev, const comedi_calibration_t *parsed_file,
 
129
        unsigned int cal_index )
 
130
{
 
131
        int i, retval, num_caldacs;
 
132
 
 
133
        num_caldacs = parsed_file->settings[ cal_index ].num_caldacs;
 
134
        COMEDILIB_DEBUG( 4, "num_caldacs %i\n", num_caldacs );
 
135
 
 
136
        for( i = 0; i < num_caldacs; i++ )
 
137
        {
 
138
                comedi_caldac_t caldac;
 
139
 
 
140
                caldac = parsed_file->settings[ cal_index ].caldacs[ i ];
 
141
                COMEDILIB_DEBUG( 4, "subdev %i, ch %i, val %i\n", caldac.subdevice,
 
142
                        caldac.channel,caldac.value);
 
143
                retval = comedi_data_write( dev, caldac.subdevice, caldac.channel,
 
144
                        0, 0, caldac.value );
 
145
                if( retval < 0 ) return retval;
 
146
        }
 
147
 
 
148
        return 0;
 
149
}
 
150
 
 
151
EXPORT_ALIAS_DEFAULT(_comedi_apply_parsed_calibration,comedi_apply_parsed_calibration,0.7.20);
 
152
int _comedi_apply_parsed_calibration( comedi_t *dev, unsigned int subdev, unsigned int channel,
 
153
        unsigned int range, unsigned int aref, const comedi_calibration_t *calibration )
 
154
{
 
155
        int retval;
 
156
 
 
157
        retval = check_cal_file( dev, calibration );
 
158
        if( retval < 0 ) return retval;
 
159
 
 
160
        retval = apply_calibration( dev, calibration, subdev, channel, range, aref );
 
161
        return retval;
 
162
}
 
163
 
 
164
/* munge characters in board name that will cause problems with file paths */
 
165
static void fixup_board_name( char *name )
 
166
{
 
167
        while( ( name = strchr( name, '/' ) ) )
 
168
        {
 
169
                if( name )
 
170
                {
 
171
                        *name = '-';
 
172
                        name++;
 
173
                }
 
174
        }
 
175
}
 
176
 
 
177
EXPORT_ALIAS_DEFAULT(_comedi_get_default_calibration_path,comedi_get_default_calibration_path,0.7.20);
 
178
char* _comedi_get_default_calibration_path( comedi_t *dev )
 
179
{
 
180
        struct stat file_stats;
 
181
        char *file_path;
 
182
        char *board_name, *temp;
 
183
        char *driver_name;
 
184
 
 
185
        if( fstat( comedi_fileno( dev ), &file_stats ) < 0 )
 
186
        {
 
187
                COMEDILIB_DEBUG( 3, "failed to get file stats of comedi device file\n" );
 
188
                return NULL;
 
189
        }
 
190
 
 
191
        driver_name = comedi_get_driver_name( dev );
 
192
        if( driver_name == NULL )
 
193
        {
 
194
                return NULL;
 
195
        }
 
196
        temp = comedi_get_board_name( dev );
 
197
        if( temp == NULL )
 
198
        {
 
199
                return NULL;
 
200
        }
 
201
        board_name = strdup( temp );
 
202
 
 
203
        fixup_board_name( board_name );
 
204
        asprintf( &file_path, LOCALSTATEDIR "/comedi/calibrations/%s_%s_comedi%li",
 
205
                driver_name, board_name, ( unsigned long ) minor( file_stats.st_rdev ) );
 
206
 
 
207
        free( board_name );
 
208
        return file_path;
 
209
}
 
210
 
 
211
EXPORT_ALIAS_DEFAULT(_comedi_apply_calibration,comedi_apply_calibration,0.7.20);
 
212
int _comedi_apply_calibration( comedi_t *dev, unsigned int subdev, unsigned int channel,
 
213
        unsigned int range, unsigned int aref, const char *cal_file_path )
 
214
{
 
215
        char file_path[ 1024 ];
 
216
        int retval;
 
217
        comedi_calibration_t *parsed_file;
 
218
 
 
219
        if( cal_file_path )
 
220
        {
 
221
                strncpy( file_path, cal_file_path, sizeof( file_path ) );
 
222
        }else
 
223
        {
 
224
                char *temp;
 
225
 
 
226
                temp = comedi_get_default_calibration_path( dev );
 
227
                if( temp == NULL ) return -1;
 
228
                strncpy( file_path, temp, sizeof( file_path ) );
 
229
                free( temp );
 
230
        }
 
231
 
 
232
        parsed_file = comedi_parse_calibration_file( file_path );
 
233
        if( parsed_file == NULL )
 
234
        {
 
235
                COMEDILIB_DEBUG( 3, "failed to parse calibration file\n" );
 
236
                return -1;
 
237
        }
 
238
 
 
239
        retval = comedi_apply_parsed_calibration( dev, subdev, channel, range, aref, parsed_file );
 
240
 
 
241
        comedi_cleanup_calibration( parsed_file );
 
242
 
 
243
        return retval;
 
244
}