2 A little auto-calibration utility, for boards
5 copyright (C) 1999,2000,2001,2002 by David Schleef
6 copyright (C) 2003 by Frank Mori Hess
10 /***************************************************************************
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU Lesser General Public License as *
15 * the Free Software Foundation; either version 2.1 of the License, or *
16 * (at your option) any later version. *
18 ***************************************************************************/
36 char ni_id[] = "$Id$";
41 int (*cal)( calibration_setup_t *setup);
42 void (*setup_observables)( calibration_setup_t *setup );
47 static int ni_setup_board( calibration_setup_t *setup , const char *device_name );
48 static void ni_setup_observables( calibration_setup_t *setup );
49 static void ni_setup_observables_611x( calibration_setup_t *setup );
51 static int cal_ni_at_mio_16e_2(calibration_setup_t *setup);
52 static int cal_ni_daqcard_ai_16xe_50(calibration_setup_t *setup);
53 static int cal_ni_at_mio_16e_1(calibration_setup_t *setup);
54 static int cal_ni_pci_mio_16e_1(calibration_setup_t *setup);
55 static int cal_ni_pci_6024e(calibration_setup_t *setup);
56 static int cal_ni_pci_6025e(calibration_setup_t *setup);
57 static int cal_ni_pci_6035e(calibration_setup_t *setup);
58 static int cal_ni_pci_6036e(calibration_setup_t *setup);
59 static int cal_ni_pci_6071e(calibration_setup_t *setup);
60 static int cal_ni_pxi_6071e(calibration_setup_t *setup);
61 static int cal_ni_at_mio_16e_10(calibration_setup_t *setup);
62 static int cal_ni_pci_mio_16xe_50(calibration_setup_t *setup);
63 static int cal_ni_pci_6023e(calibration_setup_t *setup);
64 static int cal_ni_at_mio_16xe_50(calibration_setup_t *setup);
65 static int cal_ni_pci_mio_16xe_10(calibration_setup_t *setup);
66 static int cal_ni_pci_6052e(calibration_setup_t *setup);
67 static int cal_ni_pci_6032e(calibration_setup_t *setup);
68 static int cal_ni_daqcard_ai_16e_4(calibration_setup_t *setup);
69 static int cal_ni_pci_611x(calibration_setup_t *setup);
70 static int cal_ni_pci_mio_16e_4(calibration_setup_t *setup);
71 static int cal_ni_daqcard_6062e(calibration_setup_t *setup);
72 static int cal_ni_daqcard_6024e(calibration_setup_t *setup);
74 static double ni_get_reference( calibration_setup_t *setup, int lsb_loc,int msb_loc);
76 static struct board_struct boards[]={
77 { "at-mio-16e-2", STATUS_DONE, cal_ni_at_mio_16e_2, ni_setup_observables, 0x1a9, 0x1aa },
78 { "DAQCard-ai-16xe-50", STATUS_DONE, cal_ni_daqcard_ai_16xe_50, ni_setup_observables, 0x1be, 0x1bf },
79 { "at-mio-16xe-50", STATUS_SOME, cal_ni_at_mio_16xe_50, ni_setup_observables, 0x1b5, 0x1b6 },
80 { "at-mio-16e-1", STATUS_SOME, cal_ni_at_mio_16e_1, ni_setup_observables, 0x1a9, 0x1aa },
81 { "pci-mio-16e-1", STATUS_DONE, cal_ni_pci_mio_16e_1, ni_setup_observables, 0x1a9, 0x1aa },
82 { "pci-6025e", STATUS_SOME, cal_ni_pci_6025e, ni_setup_observables, 0x1af, 0x1b0 },
83 { "pci-6034e", STATUS_UNKNOWN, NULL, ni_setup_observables, -1, -1 },
84 { "pci-6035e", STATUS_DONE, cal_ni_pci_6035e, ni_setup_observables, 0x1af, 0x1b0 },
85 { "pci-6036e", STATUS_DONE, cal_ni_pci_6036e, ni_setup_observables, 0x1ab, 0x1ac },
86 { "pci-6071e", STATUS_DONE, cal_ni_pci_6071e, ni_setup_observables, 0x1a9, 0x1aa },
87 { "pxi-6071e", STATUS_GUESS, cal_ni_pxi_6071e, ni_setup_observables, -1, -1 },
88 { "at-mio-16e-10", STATUS_GUESS, cal_ni_at_mio_16e_10, ni_setup_observables, 0x1a7, 0x1a8 },
89 { "pci-mio-16xe-50", STATUS_SOME, cal_ni_pci_mio_16xe_50, ni_setup_observables, 0x1b5, 0x1b6 },
90 { "pci-6023e", STATUS_DONE, cal_ni_pci_6023e, ni_setup_observables, 0x1bb, 0x1bc },
91 { "pci-mio-16xe-10", STATUS_DONE, cal_ni_pci_mio_16xe_10, ni_setup_observables, 0x1ae, 0x1af },
92 { "pci-6052e", STATUS_GUESS, cal_ni_pci_6052e, ni_setup_observables, 0x19f, 0x1a0 },
93 { "pci-6024e", STATUS_SOME, cal_ni_pci_6024e, ni_setup_observables, 0x1af, 0x1b0 },
94 { "pci-mio-16e-4", STATUS_SOME, cal_ni_pci_mio_16e_4, ni_setup_observables, 0x1a9, 0x1aa },
95 { "pci-6032e", STATUS_DONE, cal_ni_pci_6032e, ni_setup_observables, 0x1ae, 0x1af },
96 { "DAQCard-ai-16e-4", STATUS_DONE, cal_ni_daqcard_ai_16e_4, ni_setup_observables, 0x1b5, 0x1b6 },
97 { "pci-6110", STATUS_DONE, cal_ni_pci_611x, ni_setup_observables_611x, 0x1d4, 0x1d5 },
98 { "pci-6111", STATUS_DONE, cal_ni_pci_611x, ni_setup_observables_611x, 0x1d4, 0x1d5 },
99 { "DAQCard-6062E", STATUS_DONE, cal_ni_daqcard_6062e, ni_setup_observables, 0x1a9, 0x1aa },
100 { "DAQCard-6024E", STATUS_SOME, cal_ni_daqcard_6024e, ni_setup_observables, -1, -1 },
101 { "at-mio-16de-10", STATUS_UNKNOWN, NULL, ni_setup_observables, 0x1a7, 0x1a8 },
102 { "at-mio-16xe-10", STATUS_UNKNOWN, NULL, ni_setup_observables, 0x1b7, 0x1b8 },
103 { "at-ai-16xe-10", STATUS_UNKNOWN, NULL, ni_setup_observables, 0x1b7, 0x1b8 },
104 { "pci-6031e", STATUS_UNKNOWN, NULL, ni_setup_observables, 0x1ae, 0x1af },
105 { "pci-6033e", STATUS_UNKNOWN, NULL, ni_setup_observables, 0x1ae, 0x1af },
107 { "at-mio-64e-3", cal_ni_16e_1 },
108 // { "at-mio-16xe-50", cal_ni_unknown },
109 // { "pxi-6030e", cal_ni_unknown },
110 // { "pxi-6040e", cal_ni_unknown },
111 { "pxi-6025e", cal_ni_6023e }, // guess
112 // { "pci-6711", cal_ni_unknown },
113 // { "pci-6713", cal_ni_unknown },
114 // { "pxi-6070e", cal_ni_unknown },
115 // { "pxi-6052e", cal_ni_unknown },
118 #define n_boards (sizeof(boards)/sizeof(boards[0]))
120 static const int ni_num_observables = 20;
122 ni_zero_offset_low = 0,
125 ni_unip_zero_offset_low,
126 ni_unip_zero_offset_high,
127 ni_unip_reference_low,
134 ni_ao0_unip_zero_offset,
135 ni_ao0_unip_reference,
136 ni_ao0_unip_low_linearity,
137 ni_ao0_unip_mid_linearity,
138 ni_ao1_unip_zero_offset,
139 ni_ao1_unip_reference,
140 ni_ao1_unip_low_linearity,
141 ni_ao1_unip_mid_linearity,
143 static inline unsigned int ni_ao_zero_offset( unsigned int channel )
145 if( channel ) return ni_ao1_zero_offset;
146 else return ni_ao0_zero_offset;
148 static inline unsigned int ni_ao_reference( unsigned int channel )
150 if( channel ) return ni_ao1_reference;
151 else return ni_ao0_reference;
153 static inline unsigned int ni_ao_mid_linearity( unsigned int channel )
155 if( channel ) return ni_ao1_linearity;
156 else return ni_ao0_linearity;
158 static inline unsigned int ni_ao_unip_zero_offset( unsigned int channel )
160 if( channel ) return ni_ao1_unip_zero_offset;
161 else return ni_ao0_unip_zero_offset;
163 static inline unsigned int ni_ao_unip_reference( unsigned int channel )
165 if( channel ) return ni_ao1_unip_reference;
166 else return ni_ao0_unip_reference;
168 static inline unsigned int ni_ao_unip_low_linearity( unsigned int channel )
170 if( channel ) return ni_ao1_unip_low_linearity;
171 else return ni_ao0_unip_low_linearity;
173 static inline unsigned int ni_ao_unip_mid_linearity( unsigned int channel )
175 if( channel ) return ni_ao1_unip_mid_linearity;
176 else return ni_ao0_unip_mid_linearity;
179 static const int num_ao_observables_611x = 4;
180 static int ni_ao_zero_offset_611x( const calibration_setup_t *setup,
181 unsigned int channel, unsigned int range ) {
182 assert( range == 0 );
185 static int ni_ao_reference_611x( const calibration_setup_t *setup,
186 unsigned int channel, unsigned int range ) {
187 assert( range == 0 );
188 return 2 * channel + 1;
190 static int ni_zero_offset_611x( const calibration_setup_t *setup,
191 unsigned int channel, unsigned int range ) {
192 return num_ao_observables_611x + 8 * range + 2 * channel;
194 static int ni_reference_611x( const calibration_setup_t *setup,
195 unsigned int channel, unsigned int range ) {
196 return num_ao_observables_611x + 8 * range + 2 * channel + 1;
199 enum reference_sources {
204 REF_CALSRC_CALSRC = 4,
209 static inline unsigned int REF_DAC_GND( unsigned int channel )
211 if( channel ) return REF_DAC1_GND;
212 else return REF_DAC0_GND;
214 static inline unsigned int REF_DAC_CALSRC( unsigned int channel )
216 if( channel ) return REF_DAC1_CALSRC;
217 else return REF_DAC0_CALSRC;
220 static struct board_struct* ni_board( calibration_setup_t *setup )
222 return setup->private_data;
227 int adc_pregain_offset;
228 int adc_postgain_offset;
230 int adc_pregain_offset_fine;
231 int adc_postgain_offset_fine;
236 int dac_gain_fine[ 2 ];
237 int dac_linearity[ 2 ];
238 } ni_caldac_layout_t;
240 static int cal_ni_generic( calibration_setup_t *setup,
241 const ni_caldac_layout_t *layout );
243 static inline void init_ni_caldac_layout( ni_caldac_layout_t *layout )
247 layout->adc_pregain_offset = -1;
248 layout->adc_postgain_offset = -1;
249 layout->adc_gain = -1;
250 layout->adc_unip_offset = -1;
251 layout->adc_pregain_offset_fine = -1;
252 layout->adc_postgain_offset_fine = -1;
253 layout->adc_gain_fine = -1;
254 for( i = 0; i < 2; i++ )
256 layout->dac_offset[ i ] = -1;
257 layout->dac_gain[ i ] = -1;
258 layout->dac_gain_fine[ i ] = -1;
259 layout->dac_linearity[ i ] = -1;
263 int ni_setup( calibration_setup_t *setup , const char *device_name )
267 retval = ni_setup_board( setup, device_name );
268 if( retval < 0 ) return retval;
269 setup_caldacs( setup, setup->caldac_subdev );
274 static int ni_setup_board( calibration_setup_t *setup, const char *device_name )
278 for(i = 0; i < n_boards; i++ ){
279 if(!strcmp( device_name, boards[i].name )){
280 setup->status = boards[i].status;
281 setup->do_cal = boards[i].cal;
282 setup->private_data = &boards[ i ];
283 boards[i].setup_observables( setup );
287 if( i == n_boards ) return -1;
291 static void ni_setup_ao_observables( calibration_setup_t *setup )
294 comedi_insn tmpl, po_tmpl;
295 unsigned int channel;
296 int ai_bipolar_lowgain;
297 int ao_bipolar_lowgain;
298 int ao_unipolar_lowgain;
300 ai_bipolar_lowgain = get_bipolar_lowgain( setup->dev, setup->ad_subdev);
301 ao_bipolar_lowgain = get_bipolar_lowgain( setup->dev, setup->da_subdev);
302 ao_unipolar_lowgain = get_unipolar_lowgain( setup->dev, setup->da_subdev);
304 memset(&tmpl,0,sizeof(tmpl));
305 tmpl.insn = INSN_READ;
307 tmpl.subdev = setup->ad_subdev;
309 memset(&po_tmpl, 0, sizeof(po_tmpl));
310 po_tmpl.insn = INSN_WRITE;
312 po_tmpl.subdev = setup->da_subdev;
314 for( channel = 0; channel < 2; channel++ )
317 o = setup->observables + ni_ao_zero_offset( channel );
318 assert( o->name == NULL );
319 asprintf( &o->name, "ao %i, zero offset, low gain", channel );
320 o->preobserve_insn = po_tmpl;
321 o->preobserve_insn.chanspec = CR_PACK(channel,ao_bipolar_lowgain,0);
322 o->preobserve_insn.data = o->preobserve_data;
323 o->observe_insn = tmpl;
324 o->observe_insn.chanspec =
325 CR_PACK(REF_DAC_GND( channel ),ai_bipolar_lowgain,AREF_OTHER)
326 | CR_ALT_SOURCE | CR_ALT_FILTER;
327 o->reference_source = REF_DAC_GND( channel );
328 set_target( setup, ni_ao_zero_offset( channel ),0.0);
331 o = setup->observables + ni_ao_reference( channel );
332 assert( o->name == NULL );
333 asprintf( &o->name, "ao %i, reference voltage, low gain", channel );
334 o->preobserve_insn = po_tmpl;
335 o->preobserve_insn.chanspec = CR_PACK(channel,ao_bipolar_lowgain,0);
336 o->preobserve_insn.data = o->preobserve_data;
337 o->observe_insn = tmpl;
338 o->observe_insn.chanspec =
339 CR_PACK(REF_DAC_GND( channel ),ai_bipolar_lowgain,AREF_OTHER)
340 | CR_ALT_SOURCE | CR_ALT_FILTER;
341 o->reference_source = REF_DAC_GND( channel );
342 set_target( setup, ni_ao_reference( channel ),8.0);
344 /* ao linearity, mid */
345 o = setup->observables + ni_ao_mid_linearity( channel );
346 assert( o->name == NULL );
347 asprintf( &o->name, "ao %i, linearity (mid), low gain", channel );
348 o->preobserve_insn = po_tmpl;
349 o->preobserve_insn.chanspec = CR_PACK(channel,ao_bipolar_lowgain,0);
350 o->preobserve_insn.data = o->preobserve_data;
351 o->observe_insn = tmpl;
352 o->observe_insn.chanspec =
353 CR_PACK(REF_DAC_GND( channel ),ai_bipolar_lowgain,AREF_OTHER)
354 | CR_ALT_SOURCE | CR_ALT_FILTER;
355 o->reference_source = REF_DAC_GND( channel );
356 set_target( setup, ni_ao_mid_linearity( channel ),4.0);
358 if( ao_unipolar_lowgain >= 0 )
360 /* ao unipolar zero offset */
361 o = setup->observables + ni_ao_unip_zero_offset( channel );
362 assert( o->name == NULL );
363 asprintf( &o->name, "ao %i, unipolar zero offset, low gain", channel );
364 o->preobserve_insn = po_tmpl;
365 o->preobserve_insn.chanspec = CR_PACK(channel,ao_unipolar_lowgain,0);
366 o->preobserve_insn.data = o->preobserve_data;
367 o->observe_insn = tmpl;
368 o->observe_insn.chanspec =
369 CR_PACK(REF_DAC_GND( channel ),ai_bipolar_lowgain,AREF_OTHER)
370 | CR_ALT_SOURCE | CR_ALT_FILTER;
371 o->reference_source = REF_DAC_GND( channel );
372 set_target( setup, ni_ao_unip_zero_offset( channel ),0.0);
374 /* ao unipolar gain */
375 o = setup->observables + ni_ao_unip_reference( channel );
376 assert( o->name == NULL );
377 asprintf( &o->name, "ao %i, unipolar high, low gain", channel );
378 o->preobserve_insn = po_tmpl;
379 o->preobserve_insn.chanspec = CR_PACK(channel,ao_unipolar_lowgain,0);
380 o->preobserve_insn.data = o->preobserve_data;
381 o->observe_insn = tmpl;
382 o->observe_insn.chanspec =
383 CR_PACK(REF_DAC_GND( channel ),ai_bipolar_lowgain,AREF_OTHER)
384 | CR_ALT_SOURCE | CR_ALT_FILTER;
385 o->reference_source = REF_DAC_GND( channel );
386 set_target( setup, ni_ao_unip_reference( channel ), 9.0);
388 /* ao unipolar linearity, mid */
389 o = setup->observables + ni_ao_unip_mid_linearity( channel );
390 assert( o->name == NULL );
391 asprintf( &o->name, "ao %i, unipolar linearity (mid), low gain", channel );
392 o->preobserve_insn = po_tmpl;
393 o->preobserve_insn.chanspec = CR_PACK(channel,ao_unipolar_lowgain,0);
394 o->preobserve_insn.data = o->preobserve_data;
395 o->observe_insn = tmpl;
396 o->observe_insn.chanspec =
397 CR_PACK(REF_DAC_GND( channel ),ai_bipolar_lowgain,AREF_OTHER)
398 | CR_ALT_SOURCE | CR_ALT_FILTER;
399 o->reference_source = REF_DAC_GND( channel );
400 set_target( setup, ni_ao_unip_mid_linearity( channel ), 5.0);
402 /* ao unipolar linearity, low */
403 o = setup->observables + ni_ao_unip_low_linearity( channel );
404 assert( o->name == NULL );
405 asprintf( &o->name, "ao %i, unipolar linearity (low), low gain", channel );
406 o->preobserve_insn = po_tmpl;
407 o->preobserve_insn.chanspec = CR_PACK(channel,ao_unipolar_lowgain,0);
408 o->preobserve_insn.data = o->preobserve_data;
409 o->observe_insn = tmpl;
410 o->observe_insn.chanspec =
411 CR_PACK(REF_DAC_GND( channel ),ai_bipolar_lowgain,AREF_OTHER)
412 | CR_ALT_SOURCE | CR_ALT_FILTER;
413 o->reference_source = REF_DAC_GND( channel );
414 set_target( setup, ni_ao_unip_low_linearity( channel ), 1.0);
419 static void ni_setup_observables( calibration_setup_t *setup )
423 int bipolar_highgain;
424 int unipolar_lowgain;
425 int unipolar_highgain;
426 double voltage_reference;
429 bipolar_lowgain = get_bipolar_lowgain( setup->dev, setup->ad_subdev);
430 bipolar_highgain = get_bipolar_highgain( setup->dev, setup->ad_subdev);
431 unipolar_lowgain = get_unipolar_lowgain( setup->dev, setup->ad_subdev);
432 unipolar_highgain = get_unipolar_highgain( setup->dev, setup->ad_subdev);
434 if( ni_board( setup )->ref_eeprom_lsb >= 0 &&
435 ni_board( setup )->ref_eeprom_msb >= 0 )
437 voltage_reference = ni_get_reference( setup,
438 ni_board( setup )->ref_eeprom_lsb, ni_board( setup )->ref_eeprom_msb );
441 DPRINT( 0, "WARNING: unknown eeprom address for reference voltage\n"
442 "correction. This might be fixable if you send us an eeprom dump\n"
443 "(see the demo/eeprom_dump program).\n");
444 voltage_reference = 5.0;
447 memset(&tmpl,0,sizeof(tmpl));
448 tmpl.insn = INSN_READ;
450 tmpl.subdev = setup->ad_subdev;
452 setup->n_observables = ni_num_observables;
454 /* 0 offset, low gain */
455 o = setup->observables + ni_zero_offset_low;
456 o->name = "ai, bipolar zero offset, low gain";
457 o->observe_insn = tmpl;
458 o->observe_insn.chanspec = CR_PACK(REF_GND_GND,bipolar_lowgain,AREF_OTHER)
459 | CR_ALT_SOURCE | CR_ALT_FILTER;
460 o->reference_source = REF_GND_GND;
463 /* 0 offset, high gain */
464 o = setup->observables + ni_zero_offset_high;
465 o->name = "ai, bipolar zero offset, high gain";
466 o->observe_insn = tmpl;
467 o->observe_insn.chanspec = CR_PACK(REF_GND_GND,bipolar_highgain,AREF_OTHER)
468 | CR_ALT_SOURCE | CR_ALT_FILTER;
469 o->reference_source = REF_GND_GND;
472 /* voltage reference */
473 o = setup->observables + ni_reference_low;
474 o->name = "ai, bipolar voltage reference, low gain";
475 o->observe_insn = tmpl;
476 o->observe_insn.chanspec = CR_PACK(REF_CALSRC_GND,bipolar_lowgain,AREF_OTHER)
477 | CR_ALT_SOURCE | CR_ALT_FILTER;
478 o->reference_source = REF_CALSRC_GND;
479 o->target = voltage_reference;
481 if(unipolar_lowgain>=0){
482 o = setup->observables + ni_unip_zero_offset_low;
483 o->name = "ai, unipolar zero offset, low gain";
484 o->observe_insn = tmpl;
485 o->observe_insn.chanspec =
486 CR_PACK(REF_GND_GND,unipolar_lowgain,AREF_OTHER)
487 | CR_ALT_SOURCE | CR_ALT_FILTER;
488 o->reference_source = REF_GND_GND;
489 o->target = very_low_target( setup->dev, setup->ad_subdev, 0, unipolar_lowgain );
491 o = setup->observables + ni_unip_reference_low;
492 o->name = "ai, unipolar voltage reference, low gain";
493 o->observe_insn = tmpl;
494 o->observe_insn.chanspec =
495 CR_PACK(REF_CALSRC_GND,unipolar_lowgain,AREF_OTHER)
496 | CR_ALT_SOURCE | CR_ALT_FILTER;
497 o->reference_source = REF_CALSRC_GND;
498 o->target = voltage_reference;
501 if(unipolar_highgain >= 0)
503 o = setup->observables + ni_unip_zero_offset_high;
504 o->name = "ai, unipolar zero offset, high gain";
505 o->observe_insn = tmpl;
506 o->observe_insn.chanspec =
507 CR_PACK(REF_GND_GND,unipolar_highgain,AREF_OTHER)
508 | CR_ALT_SOURCE | CR_ALT_FILTER;
509 o->reference_source = REF_GND_GND;
510 o->target = very_low_target( setup->dev, setup->ad_subdev, 0, unipolar_highgain );
513 if(setup->da_subdev >= 0)
514 ni_setup_ao_observables( setup );
517 /* for +-50V and +-20V ranges, the reference source goes 0V
518 * to 50V instead of 0V to 5V */
519 static unsigned int cal_gain_register_bits_611x( double reference, double *voltage )
523 bits = 200.0 * ( *voltage / reference );
524 if( bits > 200 ) bits = 200;
525 if( bits < 0 ) bits = 0;
527 *voltage = reference * ( bits / 200.0 );
531 static unsigned int ref_source_611x( unsigned int ref_source, unsigned int cal_gain_bits )
533 return ( ref_source & 0xf ) | ( ( cal_gain_bits << 4 ) & 0xff0 );
536 static void reference_target_611x( calibration_setup_t *setup,
537 observable *o, double master_reference, unsigned int range )
539 int cal_gain_reg_bits;
542 comedi_range *range_ptr;
544 range_ptr = comedi_get_range( setup->dev, setup->ad_subdev, 0, range );
545 assert( range_ptr != NULL );
546 if( range_ptr->max > 19.0 ) reference = 10 * master_reference;
547 else reference = master_reference;
548 target = range_ptr->max * 0.8;
550 cal_gain_reg_bits = cal_gain_register_bits_611x( reference, &target );
552 o->reference_source = ref_source_611x( REF_CALSRC_GND, cal_gain_reg_bits );
556 static void ni_setup_observables_611x( calibration_setup_t *setup )
561 double master_reference;
563 int num_ai_channels, num_ai_ranges;
564 static const int num_ao_channels = 2;
566 setup->sv_settling_time_ns = 10000000;
567 setup->sv_order = 14;
569 master_reference = ni_get_reference( setup,
570 ni_board( setup )->ref_eeprom_lsb, ni_board( setup )->ref_eeprom_msb );
572 memset(&tmpl,0,sizeof(tmpl));
573 tmpl.insn = INSN_READ;
575 tmpl.subdev = setup->ad_subdev;
577 num_ai_channels = comedi_get_n_channels( setup->dev, setup->ad_subdev );
578 assert( num_ai_channels >= 0 );
579 num_ai_ranges = comedi_get_n_ranges( setup->dev, setup->ad_subdev, 0 );
580 assert( num_ai_ranges >= 0 );
582 for( channel = 0; channel < num_ai_channels; channel++ )
584 for( range = 0; range < num_ai_ranges; range++ )
587 o = setup->observables + ni_zero_offset_611x( setup, channel, range );
588 assert( o->name == NULL );
589 asprintf( &o->name, "ai, ch %i, range %i, zero offset",
591 o->observe_insn = tmpl;
592 o->observe_insn.chanspec = CR_PACK( channel, range, AREF_DIFF )
593 | CR_ALT_SOURCE | CR_ALT_FILTER;
594 o->reference_source = REF_GND_GND;
597 /* voltage reference */
598 o = setup->observables + ni_reference_611x( setup, channel, range );
599 assert( o->name == NULL );
600 asprintf( &o->name, "ai, ch %i, range %i, voltage reference",
602 o->observe_insn = tmpl;
603 o->observe_insn.chanspec = CR_PACK( channel, range, AREF_DIFF )
604 | CR_ALT_SOURCE | CR_ALT_FILTER;
605 reference_target_611x( setup, o, master_reference, range );
609 memset(&po_tmpl,0,sizeof(po_tmpl));
610 po_tmpl.insn = INSN_WRITE;
612 po_tmpl.subdev = setup->da_subdev;
614 for( channel = 0; channel < num_ao_channels; channel ++ )
616 static const int ai_range_for_ao = 2;
619 o = setup->observables + ni_ao_zero_offset_611x( setup, channel, 0 );
620 assert( o->name == NULL );
621 asprintf( &o->name, "ao ch %i, zero offset", channel );
622 o->preobserve_insn = po_tmpl;
623 o->preobserve_insn.chanspec = CR_PACK( channel, 0, AREF_GROUND );
624 o->preobserve_insn.data = o->preobserve_data;
625 o->observe_insn = tmpl;
626 o->observe_insn.chanspec = CR_PACK( 0, ai_range_for_ao, AREF_DIFF )
627 | CR_ALT_SOURCE | CR_ALT_FILTER;
628 o->reference_source = REF_DAC_GND( channel );
629 set_target( setup, ni_ao_zero_offset_611x( setup, channel, 0 ), 0.0 );
632 o = setup->observables + ni_ao_reference_611x( setup, channel, 0 );
633 assert( o->name == NULL );
634 asprintf( &o->name, "ao ch %i, reference voltage", channel );
635 o->preobserve_insn = po_tmpl;
636 o->preobserve_insn.chanspec = CR_PACK( channel, 0, AREF_GROUND );
637 o->preobserve_insn.data = o->preobserve_data;
638 o->observe_insn = tmpl;
639 o->observe_insn.chanspec = CR_PACK( 0, ai_range_for_ao, AREF_DIFF )
640 | CR_ALT_SOURCE | CR_ALT_FILTER;
641 o->reference_source = REF_DAC_GND( channel );
642 set_target( setup, ni_ao_reference_611x( setup, channel, 0 ), 5.0 );
645 setup->n_observables = num_ao_observables_611x + 2 * num_ai_ranges * num_ai_channels;
648 static int cal_ni_at_mio_16e_2(calibration_setup_t *setup)
650 ni_caldac_layout_t layout;
652 init_ni_caldac_layout( &layout );
653 layout.adc_pregain_offset = 0;
654 layout.adc_postgain_offset = 1;
656 layout.adc_unip_offset = 2;
657 layout.dac_offset[ 0 ] = 5;
658 layout.dac_gain[ 0 ] = 6;
659 layout.dac_offset[ 1 ] = 8;
660 layout.dac_gain[ 1 ] = 9;
662 return cal_ni_generic( setup, &layout );
665 static int cal_ni_daqcard_ai_16xe_50(calibration_setup_t *setup)
667 ni_caldac_layout_t layout;
669 init_ni_caldac_layout( &layout );
670 layout.adc_pregain_offset = 8;
671 layout.adc_postgain_offset = 2;
673 layout.adc_gain_fine = 1;
675 return cal_ni_generic( setup, &layout );
678 static int cal_ni_at_mio_16xe_50(calibration_setup_t *setup)
680 ni_caldac_layout_t layout;
682 init_ni_caldac_layout( &layout );
683 layout.adc_pregain_offset = 8;
684 layout.adc_postgain_offset = 2;
686 layout.adc_gain_fine = 1;
687 layout.dac_offset[ 0 ] = 6;
688 layout.dac_gain[ 0 ] = 4;
689 layout.dac_offset[ 1 ] = 7;
690 layout.dac_gain[ 1 ] = 5;
692 return cal_ni_generic( setup, &layout );
695 static int cal_ni_pci_mio_16xe_10(calibration_setup_t *setup)
697 ni_caldac_layout_t layout;
699 init_ni_caldac_layout( &layout );
700 layout.adc_pregain_offset = 8;
701 layout.adc_postgain_offset = 2;
702 layout.adc_postgain_offset_fine = 3;
704 layout.adc_gain_fine = 1;
705 layout.dac_offset[ 0 ] = 6;
706 layout.dac_gain[ 0 ] = 4;
707 layout.dac_offset[ 1 ] = 7;
708 layout.dac_gain[ 1 ] = 5;
710 return cal_ni_generic( setup, &layout );
713 static int cal_ni_at_mio_16e_1(calibration_setup_t *setup)
715 return cal_ni_at_mio_16e_2( setup );
718 static int cal_ni_pci_mio_16e_1(calibration_setup_t *setup)
720 ni_caldac_layout_t layout;
722 init_ni_caldac_layout( &layout );
723 layout.adc_pregain_offset = 0;
724 layout.adc_postgain_offset = 1;
725 layout.adc_unip_offset = 2;
727 layout.dac_offset[ 0 ] = 5;
728 layout.dac_gain[ 0 ] = 6;
729 layout.dac_linearity[ 0 ] = 4;
730 layout.dac_offset[ 1 ] = 8;
731 layout.dac_gain[ 1 ] = 9;
732 layout.dac_linearity[ 1 ] = 7;
734 return cal_ni_generic( setup, &layout );
737 static int cal_ni_pci_6032e(calibration_setup_t *setup)
739 ni_caldac_layout_t layout;
741 init_ni_caldac_layout( &layout );
742 layout.adc_pregain_offset = 8;
743 layout.adc_postgain_offset = 2;
744 layout.adc_postgain_offset_fine = 3;
746 layout.adc_gain_fine = 1;
748 return cal_ni_generic( setup, &layout );
751 static int cal_ni_pci_6035e(calibration_setup_t *setup)
753 /* this is for the ad8804_debug caldac */
754 ni_caldac_layout_t layout;
756 init_ni_caldac_layout( &layout );
757 layout.adc_pregain_offset = 0;
758 layout.adc_pregain_offset_fine = 8;
759 layout.adc_postgain_offset = 4;
761 layout.dac_offset[ 0 ] = 6;
762 layout.dac_gain[ 0 ] = 11;
763 layout.dac_linearity[ 0 ] = 10;
764 layout.dac_offset[ 1 ] = 9;
765 layout.dac_gain[ 1 ] = 5;
766 layout.dac_linearity[ 1 ] = 1;
768 return cal_ni_generic( setup, &layout );
771 static int cal_ni_pci_6036e(calibration_setup_t *setup)
773 ni_caldac_layout_t layout;
775 if( comedi_get_version_code( setup->dev ) <= COMEDI_VERSION_CODE( 0, 7, 66 ) )
777 DPRINT(0, "WARNING: you need comedi driver version 0.7.67 or later\n"
778 "for this calibration to work properly\n" );
781 /* this is for the ad8804_debug caldac */
782 init_ni_caldac_layout( &layout );
783 layout.adc_pregain_offset = 0;
784 layout.adc_postgain_offset = 4;
785 layout.adc_pregain_offset_fine = 8;
787 layout.dac_offset[ 0 ] = 6;
788 layout.dac_gain[ 0 ] = 7;
789 layout.dac_gain_fine[ 0 ] = 11;
790 layout.dac_linearity[ 0 ] = 10;
791 layout.dac_offset[ 1 ] = 9;
792 layout.dac_gain[ 1 ] = 3;
793 layout.dac_gain_fine[ 1 ] = 5;
794 layout.dac_linearity[ 1 ] = 1;
796 return cal_ni_generic( setup, &layout );
799 static int cal_ni_pci_6071e(calibration_setup_t *setup)
801 ni_caldac_layout_t layout;
803 if( comedi_get_version_code( setup->dev ) <= COMEDI_VERSION_CODE( 0, 7, 66 ) )
805 DPRINT(0, "WARNING: you need comedi driver version 0.7.67 or later\n"
806 "for this calibration to work properly\n" );
809 init_ni_caldac_layout( &layout );
810 layout.adc_pregain_offset = 8;
811 layout.adc_postgain_offset = 4;
812 layout.adc_unip_offset = 7;
814 layout.dac_offset[ 0 ] = 6;
815 layout.dac_gain[ 0 ] = 11;
816 layout.dac_linearity[ 0 ] = 10;
817 layout.dac_offset[ 1 ] = 9;
818 layout.dac_gain[ 1 ] = 5;
819 layout.dac_linearity[ 1 ] = 1;
820 return cal_ni_generic( setup, &layout );
823 static int cal_ni_pxi_6071e(calibration_setup_t *setup)
825 ni_caldac_layout_t layout;
827 if( comedi_get_version_code( setup->dev ) <= COMEDI_VERSION_CODE( 0, 7, 66 ) )
829 DPRINT(0, "WARNING: you need comedi driver version 0.7.67 or later\n"
830 "for this calibration to work properly\n" );
833 init_ni_caldac_layout( &layout );
834 layout.adc_pregain_offset = 0;
835 layout.adc_pregain_offset_fine = 8;
836 layout.adc_postgain_offset = 4;
838 layout.dac_offset[ 0 ] = 6;
839 layout.dac_gain[ 0 ] = 11;
840 layout.dac_linearity[ 0 ] = 10;
841 layout.dac_offset[ 1 ] = 9;
842 layout.dac_gain[ 1 ] = 5;
843 layout.dac_linearity[ 1 ] = 1;
844 return cal_ni_generic( setup, &layout );
847 static int cal_ni_at_mio_16e_10(calibration_setup_t *setup)
850 ni_caldac_layout_t layout;
852 init_ni_caldac_layout( &layout );
853 layout.adc_pregain_offset = 10;
854 layout.adc_pregain_offset_fine = 0;
855 layout.adc_postgain_offset = 1;
857 layout.adc_unip_offset = 2;
858 layout.dac_offset[ 0 ] = 5; /* guess */
859 layout.dac_gain[ 0 ] = 6; /* guess */
860 layout.dac_offset[ 1 ] = 8; /* guess */
861 layout.dac_gain[ 1 ] = 9; /* guess */
863 return cal_ni_generic( setup, &layout );
866 static int cal_ni_pci_mio_16xe_50(calibration_setup_t *setup)
868 ni_caldac_layout_t layout;
870 init_ni_caldac_layout( &layout );
871 layout.adc_pregain_offset = 8;
872 layout.adc_postgain_offset = 2;
874 layout.adc_gain_fine = 1;
875 layout.adc_unip_offset = 7;
876 layout.dac_offset[ 0 ] = 6;
877 layout.dac_gain[ 0 ] = 4;
878 layout.dac_offset[ 1 ] = 7;
879 layout.dac_gain[ 1 ] = 5;
881 return cal_ni_generic( setup, &layout );
884 static int cal_ni_pci_6023e(calibration_setup_t *setup)
886 /* for comedi-0.7.65 */
887 ni_caldac_layout_t layout;
889 init_ni_caldac_layout( &layout );
890 layout.adc_pregain_offset = 8; /* possibly wrong */
891 layout.adc_pregain_offset_fine = 0;
892 layout.adc_postgain_offset = 4;
895 return cal_ni_generic( setup, &layout );
898 static int cal_ni_pci_6024e(calibration_setup_t *setup)
900 ni_caldac_layout_t layout;
902 init_ni_caldac_layout( &layout );
903 layout.adc_pregain_offset = 8;
904 layout.adc_postgain_offset = 4;
905 layout.adc_pregain_offset_fine = 0;
907 layout.dac_offset[ 0 ] = 6;
908 layout.dac_gain[ 0 ] = 11;
909 layout.dac_linearity[ 0 ] = 10;
910 layout.dac_offset[ 1 ] = 9;
911 layout.dac_gain[ 1 ] = 5;
912 layout.dac_linearity[ 1 ] = 1;
914 return cal_ni_generic( setup, &layout );
917 static int cal_ni_pci_6025e(calibration_setup_t *setup)
919 ni_caldac_layout_t layout;
921 init_ni_caldac_layout( &layout );
922 layout.adc_pregain_offset = 8;
923 layout.adc_postgain_offset = 4;
924 layout.adc_pregain_offset_fine = 0;
926 layout.dac_offset[ 0 ] = 6;
927 layout.dac_gain[ 0 ] = 11;
928 layout.dac_linearity[ 0 ] = 10;
929 layout.dac_offset[ 1 ] = 9;
930 layout.dac_gain[ 1 ] = 5;
931 layout.dac_linearity[ 1 ] = 1;
933 return cal_ni_generic( setup, &layout );
936 static int cal_ni_pci_6052e(calibration_setup_t *setup)
939 * This board has noisy caldacs
941 * The NI documentation says (true mb88341 addressing):
942 * 0, 8 AI pregain (coarse, fine)
945 * 14, 7 AI unipolar offset
951 * 10, 6 AO1 reference
954 * For us, these map to (ad8804 channels)
956 * 0, 1 AI pregain (coarse, fine)
959 * 7 AI unipolar offset
968 * or, with mb88341 channels
978 ni_caldac_layout_t layout;
980 init_ni_caldac_layout( &layout );
981 layout.adc_pregain_offset = 0;
982 layout.adc_postgain_offset = 2;
984 layout.adc_unip_offset = 6;
985 layout.adc_pregain_offset_fine = 1;
986 layout.adc_postgain_offset_fine = 3;
987 layout.adc_gain_fine = 5;
989 /* this seems broken, i think we need to change
990 * second caldac in driver to ad8804_debug */
991 layout.dac_offset[ 0 ] = 12 + 11;
992 layout.dac_gain[ 0 ] = 12 + 7;
993 layout.dac_gain_fine[ 0 ] = 12 + 3;
994 layout.dac_offset[ 1 ] = 12 + 1;
995 layout.dac_gain[ 1 ] = 12 + 9;
996 layout.dac_gain_fine[ 1 ] = 12 + 5;
998 DPRINT(0, "WARNING: you need comedi driver version 0.7.67 or later\n"
999 "for this calibration to work properly\n" );
1000 /* this should work if the first two caldacs were ad8804_debug */
1001 layout.dac_offset[ 0 ] = 16 + 3;
1002 layout.dac_gain[ 0 ] = 16 + 1;
1003 layout.dac_gain_fine[ 0 ] = 16 + 2;
1004 layout.dac_linearity[ 0 ] = 16 + 0;
1005 layout.dac_offset[ 1 ] = 16 + 7;
1006 layout.dac_gain[ 1 ] = 16 + 5;
1007 layout.dac_gain_fine[ 1 ] = 16 + 6;
1008 layout.dac_linearity[ 1 ] = 16 + 4;
1010 return cal_ni_generic( setup, &layout );
1013 static int cal_ni_daqcard_ai_16e_4(calibration_setup_t *setup)
1015 ni_caldac_layout_t layout;
1017 init_ni_caldac_layout( &layout );
1018 layout.adc_pregain_offset = 0;
1019 layout.adc_postgain_offset = 1;
1020 layout.adc_gain = 3;
1021 layout.adc_unip_offset = 2;
1023 return cal_ni_generic( setup, &layout );
1026 static int adc_offset_611x( unsigned int channel )
1028 return 2 * channel + 2;
1030 static int adc_gain_611x( unsigned int channel )
1032 return 2 * channel + 1;
1034 static int dac_offset_611x( unsigned int channel )
1036 return 12 + 2 + 2 * channel;
1038 static int dac_gain_611x( unsigned int channel )
1040 return 12 + 1 + 2 * channel;
1042 static int cal_ni_pci_611x( calibration_setup_t *setup )
1044 generic_layout_t layout;
1046 init_generic_layout( &layout );
1047 layout.adc_offset = adc_offset_611x;
1048 layout.adc_gain = adc_gain_611x;
1049 layout.dac_offset = dac_offset_611x;
1050 layout.dac_gain = dac_gain_611x;
1051 layout.adc_high_observable = ni_reference_611x;
1052 layout.adc_ground_observable = ni_zero_offset_611x;
1053 layout.dac_high_observable = ni_ao_reference_611x;
1054 layout.dac_ground_observable = ni_ao_zero_offset_611x;
1056 return generic_cal_by_channel_and_range( setup, &layout );
1059 static int cal_ni_pci_mio_16e_4( calibration_setup_t *setup )
1061 ni_caldac_layout_t layout;
1063 init_ni_caldac_layout( &layout );
1064 layout.adc_pregain_offset = 8;
1065 layout.adc_postgain_offset = 4;
1066 layout.adc_gain = 2;
1067 layout.adc_unip_offset = 7;
1068 layout.dac_offset[ 0 ] = 6;
1069 layout.dac_gain[ 0 ] = 11;
1070 layout.dac_linearity[ 0 ] = 10;
1071 layout.dac_offset[ 1 ] = 9;
1072 layout.dac_gain[ 1 ] = 5;
1073 layout.dac_linearity[ 1 ] = 1;
1075 return cal_ni_generic( setup, &layout );
1078 static int cal_ni_daqcard_6062e( calibration_setup_t *setup )
1080 ni_caldac_layout_t layout;
1082 if( comedi_get_version_code( setup->dev ) <= COMEDI_VERSION_CODE( 0, 7, 66 ) )
1084 DPRINT(0, "WARNING: you need comedi driver version 0.7.67 or later\n"
1085 "for this calibration to work properly\n" );
1087 init_ni_caldac_layout( &layout );
1088 layout.adc_pregain_offset = 8;
1089 layout.adc_postgain_offset = 4;
1090 layout.adc_gain = 2;
1091 layout.adc_unip_offset = 7;
1092 layout.dac_offset[ 0 ] = 6;
1093 layout.dac_gain[ 0 ] = 11;
1094 layout.dac_linearity[ 0 ] = 10;
1095 layout.dac_offset[ 1 ] = 9;
1096 layout.dac_gain[ 1 ] = 5;
1097 layout.dac_linearity[ 1 ] = 1;
1099 return cal_ni_generic( setup, &layout );
1102 static int cal_ni_daqcard_6024e( calibration_setup_t *setup )
1104 ni_caldac_layout_t layout;
1106 init_ni_caldac_layout( &layout );
1108 layout.adc_pregain_offset = 0;
1109 layout.adc_postgain_offset = 4;
1110 layout.adc_gain = 2;
1111 //layout.adc_unip_offset = 7;
1112 layout.dac_offset[ 0 ] = 6;
1113 layout.dac_gain[ 0 ] = 3;
1114 //layout.dac_linearity[ 0 ] = 10;
1115 layout.dac_offset[ 1 ] = 1;
1116 layout.dac_gain[ 1 ] = 5;
1117 //layout.dac_linearity[ 1 ] = 1;
1119 return cal_ni_generic( setup, &layout );
1122 static void prep_adc_caldacs_generic( calibration_setup_t *setup,
1123 const ni_caldac_layout_t *layout )
1127 if( setup->old_calibration == NULL )
1129 reset_caldac( setup, layout->adc_pregain_offset );
1130 reset_caldac( setup, layout->adc_postgain_offset );
1131 reset_caldac( setup, layout->adc_gain );
1132 reset_caldac( setup, layout->adc_pregain_offset_fine );
1133 reset_caldac( setup, layout->adc_postgain_offset_fine );
1134 reset_caldac( setup, layout->adc_gain_fine );
1135 reset_caldac( setup, layout->adc_unip_offset );
1138 retval = comedi_apply_parsed_calibration( setup->dev, setup->ad_subdev,
1139 0, 0, AREF_GROUND, setup->old_calibration );
1142 DPRINT( 0, "Failed to apply existing calibration, reseting adc caldacs.\n" );
1143 reset_caldac( setup, layout->adc_pregain_offset );
1144 reset_caldac( setup, layout->adc_postgain_offset );
1145 reset_caldac( setup, layout->adc_gain );
1146 reset_caldac( setup, layout->adc_pregain_offset_fine );
1147 reset_caldac( setup, layout->adc_postgain_offset_fine );
1148 reset_caldac( setup, layout->adc_gain_fine );
1149 reset_caldac( setup, layout->adc_unip_offset );
1154 static void prep_dac_caldacs_generic( calibration_setup_t *setup,
1155 const ni_caldac_layout_t *layout, unsigned int channel, unsigned int range )
1159 if( setup->da_subdev < 0 ) return;
1161 if( setup->old_calibration == NULL )
1163 reset_caldac( setup, layout->dac_offset[ channel ] );
1164 reset_caldac( setup, layout->dac_gain[ channel ] );
1165 reset_caldac( setup, layout->dac_gain_fine[ channel ] );
1166 reset_caldac( setup, layout->dac_linearity[ channel ] );
1169 retval = comedi_apply_parsed_calibration( setup->dev, setup->da_subdev,
1170 channel, range, AREF_GROUND, setup->old_calibration );
1173 DPRINT( 0, "Failed to apply existing calibration, reseting dac caldacs.\n" );
1174 reset_caldac( setup, layout->dac_offset[ channel ] );
1175 reset_caldac( setup, layout->dac_gain[ channel ] );
1176 reset_caldac( setup, layout->dac_gain_fine[ channel ] );
1177 reset_caldac( setup, layout->dac_linearity[ channel ] );
1182 static int cal_ni_generic( calibration_setup_t *setup, const ni_caldac_layout_t *layout )
1184 comedi_calibration_setting_t *current_cal;
1187 prep_adc_caldacs_generic( setup, layout );
1189 current_cal = sc_alloc_calibration_setting( setup );
1190 current_cal->subdevice = setup->ad_subdev;
1191 generic_do_relative( setup, current_cal, ni_zero_offset_low,
1192 ni_reference_low, layout->adc_gain );
1193 generic_do_relative( setup, current_cal, ni_zero_offset_low,
1194 ni_zero_offset_high, layout->adc_postgain_offset );
1195 generic_do_cal( setup, current_cal, ni_zero_offset_high, layout->adc_pregain_offset );
1196 generic_do_relative( setup, current_cal, ni_zero_offset_low,
1197 ni_reference_low, layout->adc_gain_fine );
1198 generic_do_relative( setup, current_cal, ni_zero_offset_low,
1199 ni_zero_offset_high, layout->adc_postgain_offset_fine );
1200 generic_do_cal( setup, current_cal, ni_zero_offset_high,
1201 layout->adc_pregain_offset_fine );
1202 generic_do_cal( setup, current_cal, ni_unip_zero_offset_high, layout->adc_unip_offset );
1203 sc_push_channel( current_cal, SC_ALL_CHANNELS );
1204 sc_push_range( current_cal, SC_ALL_RANGES );
1205 sc_push_aref( current_cal, SC_ALL_AREFS );
1207 if( setup->da_subdev >= 0 && setup->do_output )
1209 unsigned int channel, range;
1210 int ao_unipolar_lowgain = get_unipolar_lowgain( setup->dev, setup->da_subdev );
1211 int ao_bipolar_lowgain = get_bipolar_lowgain( setup->dev, setup->da_subdev );
1214 for( channel = 0; channel < 2; channel++ )
1216 num_ao_ranges = comedi_get_n_ranges( setup->dev, setup->da_subdev, channel );
1217 prep_dac_caldacs_generic( setup, layout, channel, ao_bipolar_lowgain );
1219 current_cal = sc_alloc_calibration_setting( setup );
1220 current_cal->subdevice = setup->da_subdev;
1221 generic_do_linearity( setup, current_cal, ni_ao_zero_offset( channel ),
1222 ni_ao_mid_linearity( channel ), ni_ao_reference( channel ),
1223 layout->dac_linearity[ channel ] );
1224 generic_do_cal( setup, current_cal, ni_ao_zero_offset( channel ),
1225 layout->dac_offset[ channel ] );
1226 generic_do_cal( setup, current_cal, ni_ao_reference( channel ),
1227 layout->dac_gain[ channel ] );
1228 generic_do_cal( setup, current_cal, ni_ao_reference( channel ),
1229 layout->dac_gain_fine[ channel ] );
1230 sc_push_channel( current_cal, channel );
1231 for( range = 0; range < num_ao_ranges; range++ )
1233 if( is_bipolar( setup->dev, setup->da_subdev, channel, range ) )
1234 sc_push_range( current_cal, range );
1236 sc_push_aref( current_cal, SC_ALL_AREFS );
1238 if( ao_unipolar_lowgain >= 0 )
1240 prep_dac_caldacs_generic( setup, layout, channel, ao_unipolar_lowgain );
1242 current_cal = sc_alloc_calibration_setting( setup );
1243 current_cal->subdevice = setup->da_subdev;
1244 generic_do_linearity( setup, current_cal, ni_ao_unip_low_linearity( channel ),
1245 ni_ao_unip_mid_linearity( channel ), ni_ao_unip_reference( channel ),
1246 layout->dac_linearity[ channel ] );
1247 generic_do_cal( setup, current_cal, ni_ao_unip_zero_offset( channel),
1248 layout->dac_offset[ channel ] );
1249 generic_do_cal( setup, current_cal, ni_ao_unip_reference( channel ),
1250 layout->dac_gain[ channel ] );
1251 generic_do_cal( setup, current_cal, ni_ao_unip_reference( channel ),
1252 layout->dac_gain_fine[ channel ] );
1253 sc_push_channel( current_cal, channel );
1254 for( range = 0; range < num_ao_ranges; range++ )
1256 if( is_unipolar( setup->dev, setup->da_subdev, channel, range ) )
1257 sc_push_range( current_cal, range );
1259 sc_push_aref( current_cal, SC_ALL_AREFS );
1264 retval = write_calibration_file( setup );
1269 static double ni_get_reference( calibration_setup_t *setup, int lsb_loc,int msb_loc)
1275 lsb=read_eeprom( setup, lsb_loc );
1276 msb=read_eeprom( setup, msb_loc );
1277 assert( lsb >=0 && msb >= 0 );
1278 DPRINT(0,"eeprom reference lsb=%d msb=%d\n", lsb, msb);
1280 uv = ( lsb & 0xff ) | ( ( msb << 8 ) & 0xff00 );
1281 ref=5.000+1.0e-6*uv;
1282 DPRINT(0, "resulting reference voltage: %g\n", ref );
1283 if( fabs( ref - 5.0 ) > 0.005 )
1284 DPRINT( 0, "WARNING: eeprom indicates reference is more than 5mV away\n"
1285 "from 5V. Possible bad eeprom address?\n" );