2 A little auto-calibration utility, for boards
5 Right now, it only supports NI E series boards,
6 but it should be easily portable.
8 A few things need improvement here:
9 - current system gets "close", but doesn't
11 - no pre/post gain discrimination for the
13 - should read (and use) the actual reference
14 voltage value from eeprom
15 - statistics would be nice, to show how good
17 - doesn't check unipolar ranges
18 - "alternate calibrations" would be cool--to
19 accurately measure 0 in a unipolar range
23 /***************************************************************************
25 * This program is free software; you can redistribute it and/or modify *
26 * it under the terms of the GNU Lesser General Public License as *
28 * the Free Software Foundation; either version 2.1 of the License, or *
29 * (at your option) any later version. *
31 ***************************************************************************/
36 #include "comedilib.h"
49 char ni_id[] = "$Id$";
54 int (*cal)( calibration_setup_t *setup);
55 void (*setup_observables)( calibration_setup_t *setup );
58 static int ni_setup_board( calibration_setup_t *setup , const char *device_name );
59 static void ni_setup_observables( calibration_setup_t *setup );
60 static void ni_setup_observables_611x( calibration_setup_t *setup );
62 static int cal_ni_at_mio_16e_2(calibration_setup_t *setup);
63 static int cal_ni_daqcard_ai_16xe_50(calibration_setup_t *setup);
64 static int cal_ni_at_mio_16e_1(calibration_setup_t *setup);
65 static int cal_ni_pci_mio_16e_1(calibration_setup_t *setup);
66 static int cal_ni_pci_6025e(calibration_setup_t *setup);
67 static int cal_ni_pci_6035e(calibration_setup_t *setup);
68 static int cal_ni_pci_6071e(calibration_setup_t *setup);
69 static int cal_ni_pxi_6071e(calibration_setup_t *setup);
70 static int cal_ni_at_mio_16e_10(calibration_setup_t *setup);
71 static int cal_ni_pci_mio_16xe_50(calibration_setup_t *setup);
72 static int cal_ni_pci_6023e(calibration_setup_t *setup);
73 static int cal_ni_pci_6024e(calibration_setup_t *setup);
74 static int cal_ni_at_mio_16xe_50(calibration_setup_t *setup);
75 static int cal_ni_pci_mio_16xe_10(calibration_setup_t *setup);
76 static int cal_ni_pci_6052e(calibration_setup_t *setup);
77 static int cal_ni_pci_mio_16e_4(calibration_setup_t *setup);
78 static int cal_ni_pci_6032e(calibration_setup_t *setup);
79 static int cal_ni_daqcard_ai_16e_4(calibration_setup_t *setup);
80 static int cal_ni_pci_611x(calibration_setup_t *setup);
81 static int cal_ni_daqcard_6062e(calibration_setup_t *setup);
83 static double ni_get_reference( calibration_setup_t *setup, int lsb_loc,int msb_loc);
85 static struct board_struct boards[]={
86 { "at-mio-16e-2", STATUS_DONE, cal_ni_at_mio_16e_2, ni_setup_observables },
87 { "DAQCard-ai-16xe-50", STATUS_DONE, cal_ni_daqcard_ai_16xe_50, ni_setup_observables },
88 { "at-mio-16xe-50", STATUS_SOME, cal_ni_at_mio_16xe_50, ni_setup_observables },
89 { "at-mio-16e-1", STATUS_SOME, cal_ni_at_mio_16e_1, ni_setup_observables },
90 { "pci-mio-16e-1", STATUS_DONE, cal_ni_pci_mio_16e_1, ni_setup_observables },
91 { "pci-6025e", STATUS_SOME, cal_ni_pci_6025e, ni_setup_observables },
92 { "pci-6035e", STATUS_DONE, cal_ni_pci_6035e, ni_setup_observables },
93 { "pci-6071e", STATUS_SOME, cal_ni_pci_6071e, ni_setup_observables },
94 { "pxi-6071e", STATUS_GUESS, cal_ni_pxi_6071e, ni_setup_observables },
95 { "at-mio-16e-10", STATUS_GUESS, cal_ni_at_mio_16e_10, ni_setup_observables },
96 { "pci-mio-16xe-50", STATUS_SOME, cal_ni_pci_mio_16xe_50, ni_setup_observables },
97 { "pci-6023e", STATUS_DONE, cal_ni_pci_6023e, ni_setup_observables },
98 { "pci-mio-16xe-10", STATUS_DONE, cal_ni_pci_mio_16xe_10, ni_setup_observables },
99 { "pci-6052e", STATUS_DONE, cal_ni_pci_6052e, ni_setup_observables },
100 { "pci-6024e", STATUS_SOME, cal_ni_pci_6024e, ni_setup_observables },
101 { "pci-mio-16e-4", STATUS_SOME, cal_ni_pci_mio_16e_4, ni_setup_observables },
102 { "pci-6032e", STATUS_DONE, cal_ni_pci_6032e, ni_setup_observables },
103 { "DAQCard-ai-16e-4", STATUS_DONE, cal_ni_daqcard_ai_16e_4, ni_setup_observables },
104 { "pci-6110", STATUS_DONE, cal_ni_pci_611x, ni_setup_observables_611x },
105 { "pci-6111", STATUS_DONE, cal_ni_pci_611x, ni_setup_observables_611x },
106 { "DAQCard-6062e", STATUS_SOME, cal_ni_daqcard_6062e, ni_setup_observables },
108 // { "at-mio-16de-10", cal_ni_unknown },
109 { "at-mio-64e-3", cal_ni_16e_1 },
110 // { "at-mio-16xe-50", cal_ni_unknown },
111 // { "at-mio-16xe-10", cal_ni_unknown },
112 // { "at-ai-16xe-10", cal_ni_unknown },
113 // { "pxi-6030e", cal_ni_unknown },
114 // { "pxi-6040e", cal_ni_unknown },
115 // { "pci-6031e", cal_ni_unknown },
116 // { "pci-6033e", cal_ni_unknown },
117 { "pxi-6025e", cal_ni_6023e }, // guess
118 { "pci-6034e", cal_ni_6023e }, // guess
119 // { "pci-6711", cal_ni_unknown },
120 // { "pci-6713", cal_ni_unknown },
121 // { "pxi-6070e", cal_ni_unknown },
122 // { "pxi-6052e", cal_ni_unknown },
123 // { "DAQCard-6024e", cal_ni_unknown },
126 #define n_boards (sizeof(boards)/sizeof(boards[0]))
129 ni_zero_offset_low = 0,
139 enum observables_611x{
140 ni_ao0_zero_offset_611x = 0,
141 ni_ao0_reference_611x = 1,
142 ni_ao1_zero_offset_611x = 2,
143 ni_ao1_reference_611x = 3,
145 inline static int ni_zero_offset_611x( int channel ) {
146 return 4 + 2 * channel;
148 inline static int ni_reference_611x( int channel ) {
149 return 5 + 2 * channel;
152 enum reference_sources {
157 REF_CALSRC_CALSRC = 4,
163 int ni_setup( calibration_setup_t *setup , const char *device_name )
165 ni_setup_board( setup, device_name );
166 setup_caldacs( setup, setup->caldac_subdev );
171 static int ni_setup_board( calibration_setup_t *setup, const char *device_name )
175 for(i = 0; i < n_boards; i++ ){
176 if(!strcmp( device_name, boards[i].name )){
177 setup->status = boards[i].status;
178 setup->do_cal = boards[i].cal;
179 boards[i].setup_observables( setup );
183 if( i == n_boards ) return -1;
187 static void ni_setup_observables( calibration_setup_t *setup )
191 int bipolar_highgain;
192 int unipolar_lowgain;
193 double voltage_reference;
196 bipolar_lowgain = get_bipolar_lowgain( setup->dev, setup->ad_subdev);
197 bipolar_highgain = get_bipolar_highgain( setup->dev, setup->ad_subdev);
198 unipolar_lowgain = get_unipolar_lowgain( setup->dev, setup->ad_subdev);
200 voltage_reference = 5.000;
202 memset(&tmpl,0,sizeof(tmpl));
203 tmpl.insn = INSN_READ;
205 tmpl.subdev = setup->ad_subdev;
207 /* 0 offset, low gain */
208 o = setup->observables + ni_zero_offset_low;
209 o->name = "ai, bipolar zero offset, low gain";
210 o->observe_insn = tmpl;
211 o->observe_insn.chanspec = CR_PACK(REF_GND_GND,bipolar_lowgain,AREF_OTHER)
212 | CR_ALT_SOURCE | CR_ALT_FILTER;
213 o->reference_source = REF_GND_GND;
216 /* 0 offset, high gain */
217 o = setup->observables + ni_zero_offset_high;
218 o->name = "ai, bipolar zero offset, high gain";
219 o->observe_insn = tmpl;
220 o->observe_insn.chanspec = CR_PACK(REF_GND_GND,bipolar_highgain,AREF_OTHER)
221 | CR_ALT_SOURCE | CR_ALT_FILTER;
222 o->reference_source = REF_GND_GND;
225 /* voltage reference */
226 o = setup->observables + ni_reference_low;
227 o->name = "ai, bipolar voltage reference, low gain";
228 o->observe_insn = tmpl;
229 o->observe_insn.chanspec = CR_PACK(REF_CALSRC_GND,bipolar_lowgain,AREF_OTHER)
230 | CR_ALT_SOURCE | CR_ALT_FILTER;
231 o->reference_source = REF_CALSRC_GND;
232 o->target = voltage_reference;
234 setup->n_observables = ni_reference_low + 1;
236 if(unipolar_lowgain>=0){
237 /* unip/bip offset */
238 o = setup->observables + ni_unip_offset_low;
239 o->name = "ai, unipolar zero offset, low gain";
240 o->observe_insn = tmpl;
241 o->observe_insn.chanspec =
242 CR_PACK(REF_GND_GND,unipolar_lowgain,AREF_OTHER)
243 | CR_ALT_SOURCE | CR_ALT_FILTER;
245 o->reference_source = REF_GND_GND;
250 o = observables + ni_unip_reference_low;
251 o->name = "ai, unipolar voltage reference, low gain";
252 o->observe_insn = tmpl;
253 o->observe_insn.chanspec =
254 CR_PACK(REF_CALSRC_GND,unipolar_lowgain,AREF_OTHER)
255 | CR_ALT_SOURCE | CR_ALT_FILTER;
256 o->reference_source = REF_CALSRC_GND;
257 o->target = voltage_reference;
260 setup->n_observables = ni_unip_offset_low + 1;
263 if(setup->da_subdev>=0){
266 memset(&po_tmpl,0,sizeof(po_tmpl));
267 po_tmpl.insn = INSN_WRITE;
269 po_tmpl.subdev = setup->da_subdev;
271 /* ao 0, zero offset */
272 o = setup->observables + ni_ao0_zero_offset;
273 o->name = "ao 0, zero offset, low gain";
274 o->preobserve_insn = po_tmpl;
275 o->preobserve_insn.chanspec = CR_PACK(0,0,0);
276 o->preobserve_insn.data = o->preobserve_data;
277 o->observe_insn = tmpl;
278 o->observe_insn.chanspec =
279 CR_PACK(REF_DAC0_GND,bipolar_lowgain,AREF_OTHER)
280 | CR_ALT_SOURCE | CR_ALT_FILTER;
281 o->reference_source = REF_DAC0_GND;
282 set_target( setup, ni_ao0_zero_offset,0.0);
285 o = setup->observables + ni_ao0_reference;
286 o->name = "ao 0, reference voltage, low gain";
287 o->preobserve_insn = po_tmpl;
288 o->preobserve_insn.chanspec = CR_PACK(0,0,0);
289 o->preobserve_insn.data = o->preobserve_data;
290 o->observe_insn = tmpl;
291 o->observe_insn.chanspec =
292 CR_PACK(REF_DAC0_CALSRC,bipolar_lowgain,AREF_OTHER)
293 | CR_ALT_SOURCE | CR_ALT_FILTER;
294 o->reference_source = REF_DAC0_CALSRC;
295 set_target( setup, ni_ao0_reference,5.0);
296 o->target -= voltage_reference;
298 /* ao 1, zero offset */
299 o = setup->observables + ni_ao1_zero_offset;
300 o->name = "ao 1, zero offset, low gain";
301 o->preobserve_insn = po_tmpl;
302 o->preobserve_insn.chanspec = CR_PACK(1,0,0);
303 o->preobserve_insn.data = o->preobserve_data;
304 o->observe_insn = tmpl;
305 o->observe_insn.chanspec =
306 CR_PACK(REF_DAC1_GND,bipolar_lowgain,AREF_OTHER)
307 | CR_ALT_SOURCE | CR_ALT_FILTER;
308 o->reference_source = REF_DAC1_GND;
309 set_target( setup, ni_ao1_zero_offset,0.0);
312 o = setup->observables + ni_ao1_reference;
313 o->name = "ao 1, reference voltage, low gain";
314 o->preobserve_insn = po_tmpl;
315 o->preobserve_insn.chanspec = CR_PACK(1,0,0);
316 o->preobserve_insn.data = o->preobserve_data;
317 o->observe_insn = tmpl;
318 o->observe_insn.chanspec =
319 CR_PACK(REF_DAC1_CALSRC,bipolar_lowgain,AREF_OTHER)
320 | CR_ALT_SOURCE | CR_ALT_FILTER;
321 o->reference_source = REF_DAC1_CALSRC;
322 set_target( setup, ni_ao1_reference,5.0);
323 o->target -= voltage_reference;
325 setup->n_observables = ni_ao1_reference + 1;
329 /* XXX for +-50V and +-20V ranges, the reference source goes 0V
330 * to 50V instead of 0V to 5V */
331 static unsigned int cal_gain_register_bits_611x( double *voltage )
335 bits = 200.0 * ( *voltage / 5.0 );
336 if( bits > 200 ) bits = 200;
338 *voltage = 5.0 * ( bits / 200.0 );
342 static unsigned int ref_source_611x( unsigned int ref_source, unsigned int cal_gain_bits )
344 return ( ref_source & 0xf ) | ( ( cal_gain_bits << 4 ) & 0xff0 );
347 static void ni_setup_observables_611x( calibration_setup_t *setup )
351 int range, ai_range_for_ao;
352 double voltage_reference;
356 int cal_gain_reg_bits;
358 setup->settling_time_ns = 1000000;
362 /* voltage_reference = ni_get_reference( setup, 468, 469 ); */
363 voltage_reference = 5.0;
364 cal_gain_reg_bits = cal_gain_register_bits_611x( &voltage_reference );
366 memset(&tmpl,0,sizeof(tmpl));
367 tmpl.insn = INSN_READ;
369 tmpl.subdev = setup->ad_subdev;
371 num_chans = comedi_get_n_channels( setup->dev, setup->ad_subdev );
373 for( ai_chan = 0; ai_chan < num_chans; ai_chan++ )
376 o = setup->observables + ni_zero_offset_611x( ai_chan );
377 o->name = "ai, bipolar zero offset";
378 o->observe_insn = tmpl;
379 o->observe_insn.chanspec = CR_PACK(ai_chan, range, AREF_DIFF)
380 | CR_ALT_SOURCE | CR_ALT_FILTER;
381 o->reference_source = REF_GND_GND;
384 /* voltage reference */
385 o = setup->observables + ni_reference_611x( ai_chan );
386 o->name = "ai, bipolar voltage reference";
387 o->observe_insn = tmpl;
388 o->observe_insn.chanspec = CR_PACK(ai_chan, range, AREF_DIFF)
389 | CR_ALT_SOURCE | CR_ALT_FILTER;
390 o->reference_source = ref_source_611x( REF_CALSRC_GND, cal_gain_reg_bits );
391 o->target = voltage_reference;
394 memset(&po_tmpl,0,sizeof(po_tmpl));
395 po_tmpl.insn = INSN_WRITE;
397 po_tmpl.subdev = setup->da_subdev;
401 /* ao 0, zero offset */
402 o = setup->observables + ni_ao0_zero_offset_611x;
403 o->name = "ao 0, zero offset";
404 o->preobserve_insn = po_tmpl;
405 o->preobserve_insn.chanspec = CR_PACK( 0, 0, AREF_GROUND );
406 o->preobserve_insn.data = o->preobserve_data;
407 o->observe_insn = tmpl;
408 o->observe_insn.chanspec = CR_PACK( 0, ai_range_for_ao, AREF_DIFF )
409 | CR_ALT_SOURCE | CR_ALT_FILTER;
410 o->reference_source = REF_DAC0_GND;
411 set_target( setup, ni_ao0_zero_offset_611x, 0.0 );
414 o = setup->observables + ni_ao0_reference_611x;
415 o->name = "ao 0, reference voltage";
416 o->preobserve_insn = po_tmpl;
417 o->preobserve_insn.chanspec = CR_PACK( 0, 0, AREF_GROUND );
418 o->preobserve_insn.data = o->preobserve_data;
419 o->observe_insn = tmpl;
420 o->observe_insn.chanspec = CR_PACK( 0, ai_range_for_ao, AREF_DIFF )
421 | CR_ALT_SOURCE | CR_ALT_FILTER;
422 o->reference_source = REF_DAC0_GND;
423 set_target( setup, ni_ao0_reference_611x, 5.0 );
425 /* ao 1, zero offset */
426 o = setup->observables + ni_ao1_zero_offset_611x;
427 o->name = "ao 1, zero offset";
428 o->preobserve_insn = po_tmpl;
429 o->preobserve_insn.chanspec = CR_PACK( 1, 0, AREF_GROUND );
430 o->preobserve_insn.data = o->preobserve_data;
431 o->observe_insn = tmpl;
432 o->observe_insn.chanspec = CR_PACK( 0, ai_range_for_ao, AREF_DIFF)
433 | CR_ALT_SOURCE | CR_ALT_FILTER;
434 o->reference_source = REF_DAC1_GND;
435 set_target( setup, ni_ao1_zero_offset_611x, 0.0 );
438 o = setup->observables + ni_ao1_reference_611x;
439 o->name = "ao 1, reference voltage";
440 o->preobserve_insn = po_tmpl;
441 o->preobserve_insn.chanspec = CR_PACK( 1, 0, AREF_GROUND );
442 o->preobserve_insn.data = o->preobserve_data;
443 o->observe_insn = tmpl;
444 o->observe_insn.chanspec = CR_PACK( 0, ai_range_for_ao, AREF_DIFF )
445 | CR_ALT_SOURCE | CR_ALT_FILTER;
446 o->reference_source = REF_DAC1_GND;
447 set_target( setup, ni_ao1_reference_611x, 5.0 );
449 setup->n_observables = 4 + 2 * num_chans;
452 static int cal_ni_at_mio_16e_2(calibration_setup_t *setup)
454 postgain_cal( setup, ni_zero_offset_low,ni_zero_offset_high,1);
455 cal1( setup, ni_zero_offset_high,0);
456 cal1( setup, ni_reference_low,3);
457 cal1( setup, ni_unip_offset_low,2);
458 if(setup->do_output){
459 cal1( setup, ni_ao0_zero_offset,5);
460 cal1( setup, ni_ao0_reference,6);
461 cal1( setup, ni_ao1_zero_offset,8);
462 cal1( setup, ni_ao1_reference,9);
468 * Device name: DAQCard-ai-16xe-50
469 * Comedi version: 0.7.60
470 * ai, bipolar zero offset, low gain
471 * offset 5.87(63)e-3, target 0
472 * caldac[0] gain=-2.243(21)e-6 V/bit S_min=208.079 dof=254
473 * caldac[2] gain=1.56378(22)e-4 V/bit S_min=1782.91 dof=254
474 * caldac[8] gain=2.499(14)e-7 V/bit S_min=234.915 dof=254
475 * ai, bipolar zero offset, high gain
476 * offset 4.251(49)e-5, target 0
477 * caldac[0] gain=-2.396(30)e-8 V/bit S_min=231.387 dof=254
478 * caldac[2] gain=1.56428(28)e-6 V/bit S_min=829.096 dof=254
479 * caldac[8] gain=2.61244(18)e-7 V/bit S_min=773.092 dof=254
480 * ai, bipolar voltage reference, low gain
481 * offset 4.99650(81), target 5
482 * caldac[0] gain=-3.78250(23)e-4 V/bit S_min=12207.6 dof=254
483 * caldac[1] gain=-9.878(22)e-6 V/bit S_min=346.795 dof=254
484 * caldac[2] gain=1.57172(23)e-4 V/bit S_min=969.526 dof=254
485 * caldac[8] gain=2.795(14)e-7 V/bit S_min=245.703 dof=254
486 * ai, unipolar zero offset, low gain
487 * offset 0.0133(14), target 0
488 * caldac[0] gain=3.73923(29)e-4 V/bit S_min=2855.79 dof=151
489 * caldac[1] gain=9.784(11)e-6 V/bit S_min=727.295 dof=254
490 * caldac[2] gain=7.8670(11)e-5 V/bit S_min=903.291 dof=254
491 * caldac[8] gain=2.7732(74)e-7 V/bit S_min=415.399 dof=254
493 static int cal_ni_daqcard_ai_16xe_50(calibration_setup_t *setup)
495 postgain_cal( setup, ni_zero_offset_low,ni_zero_offset_high,2);
496 cal1( setup, ni_zero_offset_high,8);
497 cal1( setup, ni_reference_low,0);
498 cal1_fine( setup, ni_reference_low,0);
499 cal1( setup, ni_reference_low,1);
503 static int cal_ni_at_mio_16xe_50(calibration_setup_t *setup)
505 postgain_cal( setup, ni_zero_offset_low,ni_zero_offset_high,2);
506 cal1( setup, ni_zero_offset_high,8);
507 cal1( setup, ni_reference_low,0);
508 cal1_fine( setup, ni_reference_low,0);
509 cal1( setup, ni_reference_low,1);
511 if(setup->do_output){
512 cal1( setup, ni_ao0_zero_offset,6);
513 cal1( setup, ni_ao0_reference,4);
514 cal1( setup, ni_ao1_zero_offset,7);
515 cal1( setup, ni_ao1_reference,5);
520 static int cal_ni_pci_mio_16xe_10(calibration_setup_t *setup)
522 postgain_cal( setup, ni_zero_offset_low, ni_zero_offset_high, 2);
523 postgain_cal( setup, ni_zero_offset_low, ni_zero_offset_high, 3);
524 cal1( setup, ni_zero_offset_high, 8);
525 cal1( setup, ni_reference_low, 0);
526 cal1( setup, ni_reference_low, 1);
528 if(setup->do_output){
529 cal1( setup, ni_ao0_zero_offset,6);
530 cal1( setup, ni_ao0_reference,4);
531 cal1( setup, ni_ao1_zero_offset,7);
532 cal1( setup, ni_ao1_reference,5);
537 static int cal_ni_at_mio_16e_1(calibration_setup_t *setup)
539 return cal_ni_at_mio_16e_2( setup );
542 static int cal_ni_pci_mio_16e_1(calibration_setup_t *setup)
544 //cal_ni_at_mio_16e_2();
546 postgain_cal( setup, ni_zero_offset_low,ni_zero_offset_high,1);
547 cal1( setup, ni_zero_offset_high,0);
548 cal1( setup, ni_reference_low,3);
549 cal1( setup, ni_unip_offset_low,2);
550 if(setup->do_output){
551 cal1( setup, ni_ao0_zero_offset,5);
552 //cal1( setup, ni_ao0_zero_offset,4); /* linearity? */
553 cal1( setup, ni_ao0_reference,6);
554 cal1( setup, ni_ao1_zero_offset,8);
555 //cal1( setup, ni_ao1_zero_offset,7); /* linearity? */
556 cal1( setup, ni_ao1_reference,9);
561 static int cal_ni_pci_6032e(calibration_setup_t *setup)
563 postgain_cal(setup, ni_zero_offset_low, ni_zero_offset_high, 2);
564 postgain_cal(setup, ni_zero_offset_low, ni_zero_offset_high, 3);
566 cal1( setup, ni_zero_offset_high,8);
568 cal1( setup, ni_reference_low,0);
569 cal1_fine( setup, ni_reference_low,0);
570 cal1( setup, ni_reference_low,1);
575 static int cal_ni_pci_6035e(calibration_setup_t *setup)
577 /* this is for the ad8804_debug caldac */
579 postgain_cal( setup, ni_zero_offset_low,ni_zero_offset_high,4);
581 cal1( setup, ni_zero_offset_high,0);
582 cal1( setup, ni_zero_offset_high,8);
584 cal1( setup, ni_reference_low,2);
586 if(setup->do_output){
587 cal1( setup, ni_ao0_zero_offset,6);
588 //cal1( setup, ni_ao0_zero_offset,10); /* linearity? */
589 cal1( setup, ni_ao0_reference,11);
590 cal1( setup, ni_ao1_zero_offset,9);
591 //cal1( setup, ni_ao1_zero_offset,1); /* linearity? */
592 cal1( setup, ni_ao1_reference,5);
597 static int cal_ni_pci_6071e(calibration_setup_t *setup)
599 postgain_cal( setup, ni_zero_offset_low,ni_zero_offset_high,1);
600 cal1( setup, ni_zero_offset_high,0);
601 cal1( setup, ni_reference_low,3);
602 cal1_fine( setup, ni_reference_low,3);
603 if(setup->do_output){
604 cal1( setup, ni_ao0_zero_offset,5);
605 //cal1( setup, ni_ao0_zero_offset,4); /* linearity? */
606 /* caldac 6 should most likely be AO0 reference, but it
608 /*cal1( setup, ni_ao0_reference,6);*/
609 cal1( setup, ni_ao1_zero_offset,8);
610 //cal1( setup, ni_ao1_zero_offset,7); /* linearity? */
611 cal1( setup, ni_ao1_reference,9);
616 static int cal_ni_pxi_6071e(calibration_setup_t *setup)
619 postgain_cal( setup, ni_zero_offset_low,ni_zero_offset_high,1);
620 cal1( setup, ni_zero_offset_high,0);
621 cal1( setup, ni_reference_low,3);
622 if(setup->do_output){
628 static int cal_ni_at_mio_16e_10(calibration_setup_t *setup)
631 postgain_cal( setup, ni_zero_offset_low,ni_zero_offset_high,1);
632 cal1( setup, ni_zero_offset_high,10);
633 cal1( setup, ni_zero_offset_high,0);
634 cal1( setup, ni_reference_low,3);
635 cal1( setup, ni_unip_offset_low,2);
636 if(setup->do_output){
637 cal1( setup, ni_ao0_zero_offset,5); // guess
638 cal1( setup, ni_ao0_reference,6); // guess
639 cal1( setup, ni_ao1_zero_offset,8); // guess
640 cal1( setup, ni_ao1_reference,9); // guess
645 static int cal_ni_pci_mio_16xe_50(calibration_setup_t *setup)
647 postgain_cal( setup, ni_zero_offset_low,ni_zero_offset_high,2);
648 cal1( setup, ni_zero_offset_high,8);
649 cal1( setup, ni_reference_low,0);
650 cal1_fine( setup, ni_reference_low,0);
651 cal1( setup, ni_reference_low,1);
653 if(setup->do_output){
654 cal1( setup, ni_ao0_zero_offset,6);
655 cal1( setup, ni_ao0_reference,4);
656 cal1( setup, ni_ao1_zero_offset,7);
657 cal1( setup, ni_ao1_reference,5);
662 static int cal_ni_pci_6023e(calibration_setup_t *setup)
664 /* for comedi-0.7.65 */
666 postgain_cal( setup, ni_zero_offset_low,ni_zero_offset_high,4);
667 cal1( setup, ni_zero_offset_high,0);
668 cal1( setup, ni_zero_offset_high,8); /* possibly wrong */
669 cal1( setup, ni_reference_low,2);
674 static int cal_ni_pci_6024e(calibration_setup_t *setup)
676 postgain_cal( setup, ni_zero_offset_low,ni_zero_offset_high,4);
677 cal1( setup, ni_zero_offset_high,0);
678 cal1( setup, ni_zero_offset_high,8);
679 cal1( setup, ni_reference_low,2);
680 if(setup->do_output){
681 cal1( setup, ni_ao0_zero_offset,6);
682 //cal1( setup, ni_ao0_zero_offset,10); // nonlinearity?
683 cal1( setup, ni_ao0_reference,11);
684 cal1( setup, ni_ao1_zero_offset,9);
685 //cal1( setup, ni_ao1_zero_offset,1); // nonlinearity?
686 cal1( setup, ni_ao1_reference,5);
691 static int cal_ni_pci_6025e(calibration_setup_t *setup)
693 postgain_cal( setup, ni_zero_offset_low,ni_zero_offset_high,4);
694 cal1( setup, ni_zero_offset_high,0);
695 cal1( setup, ni_zero_offset_high,8);
696 cal1( setup, ni_reference_low,2);
697 if(setup->do_output){
698 cal1( setup, ni_ao0_zero_offset,6);
699 //cal1( setup, ni_ao0_zero_offset,10); /* nonlinearity */
700 cal1( setup, ni_ao0_reference,11);
701 cal1( setup, ni_ao1_zero_offset,9);
702 //cal1( setup, ni_ao1_zero_offset,1); /* nonlinearity */
703 cal1( setup, ni_ao1_reference,5);
708 static int cal_ni_pci_6052e(calibration_setup_t *setup)
711 * This board has noisy caldacs
713 * The NI documentation says:
714 * 0, 8 AI pregain (coarse, fine) 3, 11
715 * 4, 12 AI postgain 15,7
716 * 2, 10 AI reference 1, 9
717 * 14, 7 AI unipolar offset 5, 13
720 * 8, 4 AO0 reference 23, 19 7, 3
721 * 12 AO0 offset 27 11
723 * 10, 6 AO1 reference 25, 21 9, 5
724 * 14 AO1 offset 29, 17 13, 1
734 * 8 11 19 7 1011 0111
736 * 10 9 21 9 1001 1001
740 * 14 5 13 1 0101 0001
744 cal_postgain_binary( setup, ni_zero_offset_low,ni_zero_offset_high,2);
745 postgain_cal( setup, ni_zero_offset_low,ni_zero_offset_high,3);
746 cal1( setup, ni_zero_offset_high,0);
747 cal1( setup, ni_zero_offset_high,1);
748 cal_binary( setup, ni_reference_low,4);
749 cal1_fine( setup, ni_reference_low,4);
750 cal1( setup, ni_reference_low,5);
751 cal1( setup, ni_unip_offset_low,6);
752 cal1_fine( setup, ni_unip_offset_low,6);
753 if(setup->do_output){
754 cal1( setup, ni_ao0_zero_offset,12+11);
755 cal1_fine( setup, ni_ao0_zero_offset,12+11);
756 cal1( setup, ni_ao0_reference,12+7);
757 cal1_fine( setup, ni_ao0_reference,12+7);
758 cal1( setup, ni_ao0_reference,12+3);
759 cal1( setup, ni_ao1_zero_offset,12+1);
760 cal1( setup, ni_ao1_reference,12+9);
761 cal1_fine( setup, ni_ao1_reference,12+9);
762 cal1( setup, ni_ao1_reference,12+5);
767 static int cal_ni_pci_mio_16e_4(calibration_setup_t *setup)
769 /* this is for the ad8804_debug caldac */
771 cal_postgain_binary( setup, ni_zero_offset_low,ni_zero_offset_high,4);
772 //cal_postgain_fine( setup, ni_zero_offset_low,ni_zero_offset_high,4);
773 cal1( setup, ni_zero_offset_high,8);
774 cal_binary( setup, ni_reference_low,2);
775 cal1_fine( setup, ni_reference_low,2);
777 cal1( setup, ni_unip_offset_low,7);
778 cal1_fine( setup, ni_unip_offset_low,7);
780 if(setup->do_output){
781 cal_binary( setup, ni_ao0_zero_offset,6);
782 cal1_fine( setup, ni_ao0_zero_offset,6);
783 //cal1( setup, ni_ao0_nonlinearity,10);
784 cal_binary( setup, ni_ao0_reference,11);
785 cal1_fine( setup, ni_ao0_reference,11);
786 cal_binary( setup, ni_ao1_zero_offset,9);
787 cal1_fine( setup, ni_ao1_zero_offset,9);
788 //cal1( setup, ni_ao1_nonlinearity,1);
789 cal_binary( setup, ni_ao1_reference,5);
790 cal1_fine( setup, ni_ao1_reference,5);
795 static int cal_ni_daqcard_ai_16e_4(calibration_setup_t *setup)
797 cal_postgain_binary(setup, ni_zero_offset_low, ni_zero_offset_high, 1);
798 //cal_postgain_fine(setup, ni_zero_offset_low, ni_zero_offset_high, 1);
800 cal_binary( setup, ni_zero_offset_high,0);
801 cal1_fine( setup, ni_zero_offset_high,0);
803 cal_binary( setup, ni_reference_low,3);
804 cal1_fine( setup, ni_reference_low,3);
806 cal1( setup, ni_unip_offset_low,2);
811 static int cal_ni_pci_611x( calibration_setup_t *setup )
816 num_chans = comedi_get_n_channels( setup->dev, setup->ad_subdev );
818 for( i = 0; i < num_chans; i++ ){
819 cal1( setup, ni_zero_offset_611x( i ), ( 2 * i + 2 ) );
820 cal1( setup, ni_reference_611x( i ), ( 2 * i + 1 ) );
823 if(setup->do_output){
824 cal1( setup, ni_ao0_zero_offset_611x, 14 );
825 cal1( setup, ni_ao0_reference_611x, 13 );
826 cal1( setup, ni_ao1_zero_offset_611x, 16 );
827 cal1( setup, ni_ao1_reference_611x, 15 );
833 static int cal_ni_daqcard_6062e( calibration_setup_t *setup )
835 saved_calibration_t saved_cals[ 3 ], *current_cal;
836 static const int num_calibrations = sizeof( saved_cals ) / sizeof( saved_cals[0] );
839 comedi_set_global_oor_behavior( COMEDI_OOR_NUMBER );
841 current_cal = saved_cals;
843 cal_postgain_binary( setup, ni_zero_offset_low, ni_zero_offset_high, 4 );
844 cal_binary( setup, ni_zero_offset_high,0 );
845 cal_binary( setup, ni_reference_low,2 );
847 current_cal->subdevice = setup->ad_subdev;
848 sc_push_caldac( current_cal, setup->caldacs[ 0 ] );
849 sc_push_caldac( current_cal, setup->caldacs[ 2 ] );
850 sc_push_caldac( current_cal, setup->caldacs[ 4 ] );
851 sc_push_channel( current_cal, SC_ALL_CHANNELS );
852 sc_push_range( current_cal, SC_ALL_RANGES );
853 sc_push_aref( current_cal, SC_ALL_AREFS );
856 if(setup->do_output){
857 cal_binary( setup, ni_ao0_zero_offset, 6 );
858 cal_binary( setup, ni_ao0_reference, 3 );
860 current_cal->subdevice = setup->da_subdev;
861 sc_push_caldac( current_cal, setup->caldacs[ 6 ] );
862 sc_push_caldac( current_cal, setup->caldacs[ 3 ] );
863 sc_push_channel( current_cal, 0 );
864 sc_push_range( current_cal, SC_ALL_RANGES );
865 sc_push_aref( current_cal, SC_ALL_AREFS );
868 cal_binary( setup, ni_ao1_zero_offset, 1 );
869 cal_binary( setup, ni_ao1_reference, 5 );
871 current_cal->subdevice = setup->da_subdev;
872 sc_push_caldac( current_cal, setup->caldacs[ 1 ] );
873 sc_push_caldac( current_cal, setup->caldacs[ 5 ] );
874 sc_push_channel( current_cal, 1 );
875 sc_push_range( current_cal, SC_ALL_RANGES );
876 sc_push_aref( current_cal, SC_ALL_AREFS );
880 retval = write_calibration_file( setup, saved_cals, num_calibrations );
881 for( i = 0; i < num_calibrations; i++ )
882 clear_saved_calibration( &saved_cals[ i ] );
888 static double ni_get_reference( calibration_setup_t *setup, int lsb_loc,int msb_loc)
894 lsb=read_eeprom( setup, lsb_loc);
895 msb=read_eeprom( setup, msb_loc);
896 printf("lsb=%d msb=%d\n", lsb, msb);
898 uv = ( lsb & 0xff ) | ( ( msb << 8 ) & 0xff00 );
900 printf("ref=%g\n",ref);
906 static void cal_ni_results(void)
910 int bipolar_highgain;
911 int unipolar_lowgain;
915 bipolar_lowgain = get_bipolar_lowgain(dev,setup->ad_subdev);
916 bipolar_highgain = get_bipolar_highgain(dev,setup->ad_subdev);
917 unipolar_lowgain = get_unipolar_lowgain(dev,setup->ad_subdev);
919 /* 0 offset, low gain */
920 range = comedi_get_range(dev,setup->ad_subdev,0,bipolar_lowgain);
921 read_chan2(s,0,bipolar_lowgain);
922 DPRINT(0,"bipolar zero offset, low gain [%g,%g]: %s\n",
923 range->min,range->max,s);
925 /* 0 offset, high gain */
926 range = comedi_get_range(dev,setup->ad_subdev,0,bipolar_highgain);
927 read_chan2(s,0,bipolar_highgain);
928 DPRINT(0,"bipolar zero offset, high gain [%g,%g]: %s\n",
929 range->min,range->max,s);
931 /* unip/bip offset */
932 range = comedi_get_range(dev,setup->ad_subdev,0,unipolar_lowgain);
933 read_chan2(s,0,unipolar_lowgain);
934 DPRINT(0,"unipolar zero offset, low gain [%g,%g]: %s\n",
935 range->min,range->max,s);
939 static void ni_mio_ai_postgain_cal(void)
947 check_gain_chan_x(&l,CR_PACK(0,0,AREF_OTHER),1);
948 offset_r0=linear_fit_func_y(&l,caldacs[1].current);
949 printf("offset r0 %g\n",offset_r0);
951 check_gain_chan_x(&l,CR_PACK(0,7,AREF_OTHER),1);
952 offset_r7=linear_fit_func_y(&l,caldacs[1].current);
953 printf("offset r7 %g\n",offset_r7);
957 a=(offset_r0-offset_r7)/(200.0-1.0);
958 a=caldacs[1].current-a/gain;
962 caldacs[1].current=rint(a);
966 static void ni_mio_ai_postgain_cal_2(int chan,int dac,int range_lo,int range_hi,double gain)
968 double offset_lo,offset_hi;
973 check_gain_chan_x(&l,CR_PACK(chan,range_lo,AREF_OTHER),dac);
974 offset_lo=linear_fit_func_y(&l,caldacs[dac].current);
975 printf("offset lo %g\n",offset_lo);
977 check_gain_chan_x(&l,CR_PACK(chan,range_hi,AREF_OTHER),dac);
978 offset_hi=linear_fit_func_y(&l,caldacs[dac].current);
979 printf("offset hi %g\n",offset_hi);
983 a=(offset_lo-offset_hi)/(gain-1.0);
984 a=caldacs[dac].current-a/slope;
988 caldacs[dac].current=rint(a);