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
26 #include <comedilib.h>
39 char ni_id[] = "$Id$";
44 int (*cal)( calibration_setup_t *setup);
45 void (*setup_observables)( calibration_setup_t *setup );
48 int ni_setup_board( calibration_setup_t *setup , const char *device_name );
49 void ni_setup_observables( calibration_setup_t *setup );
50 void ni_setup_observables_611x( calibration_setup_t *setup );
52 int cal_ni_at_mio_16e_2(calibration_setup_t *setup);
53 int cal_ni_daqcard_ai_16xe_50(calibration_setup_t *setup);
54 int cal_ni_at_mio_16e_1(calibration_setup_t *setup);
55 int cal_ni_pci_mio_16e_1(calibration_setup_t *setup);
56 int cal_ni_pci_6025e(calibration_setup_t *setup);
57 int cal_ni_pci_6035e(calibration_setup_t *setup);
58 int cal_ni_pci_6071e(calibration_setup_t *setup);
59 int cal_ni_pxi_6071e(calibration_setup_t *setup);
60 int cal_ni_at_mio_16e_10(calibration_setup_t *setup);
61 int cal_ni_pci_mio_16xe_50(calibration_setup_t *setup);
62 int cal_ni_pci_6023e(calibration_setup_t *setup);
63 int cal_ni_pci_6024e(calibration_setup_t *setup);
64 int cal_ni_at_mio_16xe_50(calibration_setup_t *setup);
65 int cal_ni_pci_mio_16xe_10(calibration_setup_t *setup);
66 int cal_ni_pci_6052e(calibration_setup_t *setup);
67 int cal_ni_pci_mio_16e_4(calibration_setup_t *setup);
68 int cal_ni_pci_6032e(calibration_setup_t *setup);
69 int cal_ni_daqcard_ai_16e_4(calibration_setup_t *setup);
70 int cal_ni_pci_611x(calibration_setup_t *setup);
72 static struct board_struct boards[]={
73 { "at-mio-16e-2", STATUS_DONE, cal_ni_at_mio_16e_2, ni_setup_observables },
74 { "DAQCard-ai-16xe-50", STATUS_DONE, cal_ni_daqcard_ai_16xe_50, ni_setup_observables },
75 { "at-mio-16xe-50", STATUS_SOME, cal_ni_at_mio_16xe_50, ni_setup_observables },
76 { "at-mio-16e-1", STATUS_SOME, cal_ni_at_mio_16e_1, ni_setup_observables },
77 { "pci-mio-16e-1", STATUS_DONE, cal_ni_pci_mio_16e_1, ni_setup_observables },
78 { "pci-6025e", STATUS_SOME, cal_ni_pci_6025e, ni_setup_observables },
79 { "pci-6035e", STATUS_DONE, cal_ni_pci_6035e, ni_setup_observables },
80 { "pci-6071e", STATUS_SOME, cal_ni_pci_6071e, ni_setup_observables },
81 { "pxi-6071e", STATUS_GUESS, cal_ni_pxi_6071e, ni_setup_observables },
82 { "at-mio-16e-10", STATUS_GUESS, cal_ni_at_mio_16e_10, ni_setup_observables },
83 { "pci-mio-16xe-50", STATUS_SOME, cal_ni_pci_mio_16xe_50, ni_setup_observables },
84 { "pci-6023e", STATUS_DONE, cal_ni_pci_6023e, ni_setup_observables },
85 { "pci-mio-16xe-10", STATUS_DONE, cal_ni_pci_mio_16xe_10, ni_setup_observables },
86 { "pci-6052e", STATUS_DONE, cal_ni_pci_6052e, ni_setup_observables },
87 { "pci-6024e", STATUS_SOME, cal_ni_pci_6024e, ni_setup_observables },
88 { "pci-mio-16e-4", STATUS_SOME, cal_ni_pci_mio_16e_4, ni_setup_observables },
89 { "pci-6032e", STATUS_DONE, cal_ni_pci_6032e, ni_setup_observables },
90 { "DAQCard-ai-16e-4", STATUS_DONE, cal_ni_daqcard_ai_16e_4, ni_setup_observables },
91 { "pci-6110", STATUS_SOME, cal_ni_pci_611x, ni_setup_observables_611x },
92 { "pci-6111", STATUS_SOME, cal_ni_pci_611x, ni_setup_observables_611x },
94 // { "at-mio-16de-10", cal_ni_unknown },
95 { "at-mio-64e-3", cal_ni_16e_1 },
96 // { "at-mio-16xe-50", cal_ni_unknown },
97 // { "at-mio-16xe-10", cal_ni_unknown },
98 // { "at-ai-16xe-10", cal_ni_unknown },
99 // { "pxi-6030e", cal_ni_unknown },
100 // { "pxi-6040e", cal_ni_unknown },
101 // { "pci-6031e", cal_ni_unknown },
102 // { "pci-6033e", cal_ni_unknown },
103 { "pxi-6025e", cal_ni_6023e }, // guess
104 { "pci-6034e", cal_ni_6023e }, // guess
105 // { "pci-6711", cal_ni_unknown },
106 // { "pci-6713", cal_ni_unknown },
107 // { "pxi-6070e", cal_ni_unknown },
108 // { "pxi-6052e", cal_ni_unknown },
109 // { "DAQCard-6062e", cal_ni_unknown },
110 // { "DAQCard-6024e", cal_ni_unknown },
113 #define n_boards (sizeof(boards)/sizeof(boards[0]))
116 ni_zero_offset_low = 0,
125 static int ni_zero_offset_611x( int channel ) {
128 static int ni_reference_611x( int channel ) {
131 enum observables_611x{
132 ni_ao0_zero_offset_611x = 8,
133 ni_ao0_reference_611x = 9,
134 ni_ao1_zero_offset_611x = 10,
135 ni_ao1_reference_611x = 11,
138 enum reference_sources {
149 // 611x documentation wrong, this was determined from hardware behaviour
150 enum reference_sources_611x {
151 REF_GND_GND_611x = 0,
153 REF_DAC0_0V_611x = 2,
154 REF_DAC1_0V_611x = 3,
157 int ni_setup( calibration_setup_t *setup , const char *device_name )
159 ni_setup_board( setup, device_name );
160 setup_caldacs( setup, setup->caldac_subdev );
165 int ni_setup_board( calibration_setup_t *setup, const char *device_name )
169 for(i = 0; i < n_boards; i++ ){
170 if(!strcmp( device_name, boards[i].name )){
171 setup->status = boards[i].status;
172 setup->do_cal = boards[i].cal;
173 boards[i].setup_observables( setup );
177 if( i == n_boards ) return -1;
181 void ni_setup_observables( calibration_setup_t *setup )
185 int bipolar_highgain;
186 int unipolar_lowgain;
187 double voltage_reference;
190 bipolar_lowgain = get_bipolar_lowgain( setup->dev, setup->ad_subdev);
191 bipolar_highgain = get_bipolar_highgain( setup->dev, setup->ad_subdev);
192 unipolar_lowgain = get_unipolar_lowgain( setup->dev, setup->ad_subdev);
194 voltage_reference = 5.000;
196 memset(&tmpl,0,sizeof(tmpl));
197 tmpl.insn = INSN_READ;
199 tmpl.subdev = setup->ad_subdev;
201 /* 0 offset, low gain */
202 o = setup->observables + ni_zero_offset_low;
203 o->name = "ai, bipolar zero offset, low gain";
204 o->observe_insn = tmpl;
205 o->observe_insn.chanspec = CR_PACK(REF_GND_GND,bipolar_lowgain,AREF_OTHER)
206 | CR_ALT_SOURCE | CR_ALT_FILTER;
207 o->reference_source = REF_GND_GND;
210 /* 0 offset, high gain */
211 o = setup->observables + ni_zero_offset_high;
212 o->name = "ai, bipolar zero offset, high gain";
213 o->observe_insn = tmpl;
214 o->observe_insn.chanspec = CR_PACK(REF_GND_GND,bipolar_highgain,AREF_OTHER)
215 | CR_ALT_SOURCE | CR_ALT_FILTER;
216 o->reference_source = REF_GND_GND;
219 /* voltage reference */
220 o = setup->observables + ni_reference_low;
221 o->name = "ai, bipolar voltage reference, low gain";
222 o->observe_insn = tmpl;
223 o->observe_insn.chanspec = CR_PACK(REF_5V_0V,bipolar_lowgain,AREF_OTHER)
224 | CR_ALT_SOURCE | CR_ALT_FILTER;
225 o->reference_source = REF_5V_0V;
226 o->target = voltage_reference;
228 setup->n_observables = ni_reference_low + 1;
230 if(unipolar_lowgain>=0){
231 /* unip/bip offset */
232 o = setup->observables + ni_unip_offset_low;
233 o->name = "ai, unipolar zero offset, low gain";
234 o->observe_insn = tmpl;
235 o->observe_insn.chanspec =
236 CR_PACK(REF_GND_GND,unipolar_lowgain,AREF_OTHER)
237 | CR_ALT_SOURCE | CR_ALT_FILTER;
239 o->reference_source = REF_GND_GND;
244 o = observables + ni_unip_reference_low;
245 o->name = "ai, unipolar voltage reference, low gain";
246 o->observe_insn = tmpl;
247 o->observe_insn.chanspec =
248 CR_PACK(REF_5V_0V,unipolar_lowgain,AREF_OTHER)
249 | CR_ALT_SOURCE | CR_ALT_FILTER;
250 o->reference_source = REF_5V_0V;
251 o->target = voltage_reference;
254 setup->n_observables = ni_unip_offset_low + 1;
257 if(setup->da_subdev>=0){
260 memset(&po_tmpl,0,sizeof(po_tmpl));
261 po_tmpl.insn = INSN_WRITE;
263 po_tmpl.subdev = setup->da_subdev;
265 /* ao 0, zero offset */
266 o = setup->observables + ni_ao0_zero_offset;
267 o->name = "ao 0, zero offset, low gain";
268 o->preobserve_insn = po_tmpl;
269 o->preobserve_insn.chanspec = CR_PACK(0,0,0);
270 o->preobserve_insn.data = o->preobserve_data;
271 o->observe_insn = tmpl;
272 o->observe_insn.chanspec =
273 CR_PACK(REF_DAC0_0V,bipolar_lowgain,AREF_OTHER)
274 | CR_ALT_SOURCE | CR_ALT_FILTER;
275 o->reference_source = REF_DAC0_0V;
276 set_target( setup, ni_ao0_zero_offset,0.0);
279 o = setup->observables + ni_ao0_reference;
280 o->name = "ao 0, reference voltage, low gain";
281 o->preobserve_insn = po_tmpl;
282 o->preobserve_insn.chanspec = CR_PACK(0,0,0);
283 o->preobserve_insn.data = o->preobserve_data;
284 o->observe_insn = tmpl;
285 o->observe_insn.chanspec =
286 CR_PACK(REF_DAC0_5V,bipolar_lowgain,AREF_OTHER)
287 | CR_ALT_SOURCE | CR_ALT_FILTER;
288 o->reference_source = REF_DAC0_5V;
289 set_target( setup, ni_ao0_reference,5.0);
290 o->target -= voltage_reference;
292 /* ao 1, zero offset */
293 o = setup->observables + ni_ao1_zero_offset;
294 o->name = "ao 1, zero offset, low gain";
295 o->preobserve_insn = po_tmpl;
296 o->preobserve_insn.chanspec = CR_PACK(1,0,0);
297 o->preobserve_insn.data = o->preobserve_data;
298 o->observe_insn = tmpl;
299 o->observe_insn.chanspec =
300 CR_PACK(REF_DAC1_0V,bipolar_lowgain,AREF_OTHER)
301 | CR_ALT_SOURCE | CR_ALT_FILTER;
302 o->reference_source = REF_DAC1_0V;
303 set_target( setup, ni_ao1_zero_offset,0.0);
306 o = setup->observables + ni_ao1_reference;
307 o->name = "ao 1, reference voltage, low gain";
308 o->preobserve_insn = po_tmpl;
309 o->preobserve_insn.chanspec = CR_PACK(1,0,0);
310 o->preobserve_insn.data = o->preobserve_data;
311 o->observe_insn = tmpl;
312 o->observe_insn.chanspec =
313 CR_PACK(REF_DAC1_5V,bipolar_lowgain,AREF_OTHER)
314 | CR_ALT_SOURCE | CR_ALT_FILTER;
315 o->reference_source = REF_DAC1_5V;
316 set_target( setup, ni_ao1_reference,5.0);
317 o->target -= voltage_reference;
319 setup->n_observables = ni_ao1_reference + 1;
323 void ni_setup_observables_611x( calibration_setup_t *setup )
327 int range, ai_range_for_ao;
328 double voltage_reference;
335 voltage_reference = 5.000;
337 memset(&tmpl,0,sizeof(tmpl));
338 tmpl.insn = INSN_READ;
340 tmpl.subdev = setup->ad_subdev;
342 num_chans = comedi_get_n_channels( setup->dev, setup->ad_subdev );
344 for( ai_chan = 0; ai_chan < num_chans; ai_chan++ )
347 o = setup->observables + ni_zero_offset_611x( ai_chan );
348 o->name = "ai, bipolar zero offset";
349 o->observe_insn = tmpl;
350 o->observe_insn.chanspec = CR_PACK(ai_chan, range, AREF_DIFF)
351 | CR_ALT_SOURCE | CR_ALT_FILTER;
352 o->reference_source = REF_GND_GND_611x;
355 /* voltage reference */
356 o = setup->observables + ni_reference_611x( ai_chan );
357 o->name = "ai, bipolar voltage reference";
358 o->observe_insn = tmpl;
359 o->observe_insn.chanspec = CR_PACK(ai_chan, range, AREF_DIFF)
360 | CR_ALT_SOURCE | CR_ALT_FILTER;
361 o->reference_source = REF_5V_0V_611x;
365 memset(&po_tmpl,0,sizeof(po_tmpl));
366 po_tmpl.insn = INSN_WRITE;
368 po_tmpl.subdev = setup->da_subdev;
372 /* ao 0, zero offset */
373 o = setup->observables + ni_ao0_zero_offset_611x;
374 o->name = "ao 0, zero offset";
375 o->preobserve_insn = po_tmpl;
376 o->preobserve_insn.chanspec = CR_PACK( 0, 0, AREF_GROUND );
377 o->preobserve_insn.data = o->preobserve_data;
378 o->observe_insn = tmpl;
379 o->observe_insn.chanspec = CR_PACK( 0, ai_range_for_ao, AREF_DIFF )
380 | CR_ALT_SOURCE | CR_ALT_FILTER;
381 o->reference_source = REF_DAC0_0V_611x;
382 set_target( setup, ni_ao0_zero_offset_611x, 0.0 );
385 o = setup->observables + ni_ao0_reference_611x;
386 o->name = "ao 0, reference voltage";
387 o->preobserve_insn = po_tmpl;
388 o->preobserve_insn.chanspec = CR_PACK( 0, 0, AREF_GROUND );
389 o->preobserve_insn.data = o->preobserve_data;
390 o->observe_insn = tmpl;
391 o->observe_insn.chanspec = CR_PACK( 0, ai_range_for_ao, AREF_DIFF )
392 | CR_ALT_SOURCE | CR_ALT_FILTER;
393 o->reference_source = REF_DAC0_0V_611x;
394 set_target( setup, ni_ao0_reference_611x, 5.0 );
396 /* ao 1, zero offset */
397 o = setup->observables + ni_ao1_zero_offset_611x;
398 o->name = "ao 1, zero offset";
399 o->preobserve_insn = po_tmpl;
400 o->preobserve_insn.chanspec = CR_PACK( 1, 0, AREF_GROUND );
401 o->preobserve_insn.data = o->preobserve_data;
402 o->observe_insn = tmpl;
403 o->observe_insn.chanspec = CR_PACK( 0, ai_range_for_ao, AREF_DIFF)
404 | CR_ALT_SOURCE | CR_ALT_FILTER;
405 o->reference_source = REF_DAC1_0V_611x;
406 set_target( setup, ni_ao1_zero_offset_611x, 0.0 );
409 o = setup->observables + ni_ao1_reference_611x;
410 o->name = "ao 1, reference voltage";
411 o->preobserve_insn = po_tmpl;
412 o->preobserve_insn.chanspec = CR_PACK( 1, 0, AREF_GROUND );
413 o->preobserve_insn.data = o->preobserve_data;
414 o->observe_insn = tmpl;
415 o->observe_insn.chanspec = CR_PACK( 0, ai_range_for_ao, AREF_DIFF )
416 | CR_ALT_SOURCE | CR_ALT_FILTER;
417 o->reference_source = REF_DAC1_0V_611x;
418 set_target( setup, ni_ao1_reference_611x, 5.0 );
420 setup->n_observables = ni_ao1_reference_611x + 1;
423 int cal_ni_at_mio_16e_2(calibration_setup_t *setup)
425 postgain_cal( setup, ni_zero_offset_low,ni_zero_offset_high,1);
426 cal1( setup, ni_zero_offset_high,0);
427 cal1( setup, ni_reference_low,3);
428 cal1( setup, ni_unip_offset_low,2);
430 cal1( setup, ni_ao0_zero_offset,5);
431 cal1( setup, ni_ao0_reference,6);
432 cal1( setup, ni_ao1_zero_offset,8);
433 cal1( setup, ni_ao1_reference,9);
439 * Device name: DAQCard-ai-16xe-50
440 * Comedi version: 0.7.60
441 * ai, bipolar zero offset, low gain
442 * offset 5.87(63)e-3, target 0
443 * caldac[0] gain=-2.243(21)e-6 V/bit S_min=208.079 dof=254
444 * caldac[2] gain=1.56378(22)e-4 V/bit S_min=1782.91 dof=254
445 * caldac[8] gain=2.499(14)e-7 V/bit S_min=234.915 dof=254
446 * ai, bipolar zero offset, high gain
447 * offset 4.251(49)e-5, target 0
448 * caldac[0] gain=-2.396(30)e-8 V/bit S_min=231.387 dof=254
449 * caldac[2] gain=1.56428(28)e-6 V/bit S_min=829.096 dof=254
450 * caldac[8] gain=2.61244(18)e-7 V/bit S_min=773.092 dof=254
451 * ai, bipolar voltage reference, low gain
452 * offset 4.99650(81), target 5
453 * caldac[0] gain=-3.78250(23)e-4 V/bit S_min=12207.6 dof=254
454 * caldac[1] gain=-9.878(22)e-6 V/bit S_min=346.795 dof=254
455 * caldac[2] gain=1.57172(23)e-4 V/bit S_min=969.526 dof=254
456 * caldac[8] gain=2.795(14)e-7 V/bit S_min=245.703 dof=254
457 * ai, unipolar zero offset, low gain
458 * offset 0.0133(14), target 0
459 * caldac[0] gain=3.73923(29)e-4 V/bit S_min=2855.79 dof=151
460 * caldac[1] gain=9.784(11)e-6 V/bit S_min=727.295 dof=254
461 * caldac[2] gain=7.8670(11)e-5 V/bit S_min=903.291 dof=254
462 * caldac[8] gain=2.7732(74)e-7 V/bit S_min=415.399 dof=254
464 int cal_ni_daqcard_ai_16xe_50(calibration_setup_t *setup)
466 postgain_cal( setup, ni_zero_offset_low,ni_zero_offset_high,2);
467 cal1( setup, ni_zero_offset_high,8);
468 cal1( setup, ni_reference_low,0);
469 cal1_fine( setup, ni_reference_low,0);
470 cal1( setup, ni_reference_low,1);
474 int cal_ni_at_mio_16xe_50(calibration_setup_t *setup)
476 postgain_cal( setup, ni_zero_offset_low,ni_zero_offset_high,2);
477 cal1( setup, ni_zero_offset_high,8);
478 cal1( setup, ni_reference_low,0);
479 cal1_fine( setup, ni_reference_low,0);
480 cal1( setup, ni_reference_low,1);
483 cal1( setup, ni_ao0_zero_offset,6);
484 cal1( setup, ni_ao0_reference,4);
485 cal1( setup, ni_ao1_zero_offset,7);
486 cal1( setup, ni_ao1_reference,5);
491 int cal_ni_pci_mio_16xe_10(calibration_setup_t *setup)
493 postgain_cal( setup, ni_zero_offset_low, ni_zero_offset_high, 2);
494 postgain_cal( setup, ni_zero_offset_low, ni_zero_offset_high, 3);
495 cal1( setup, ni_zero_offset_high, 8);
496 cal1( setup, ni_reference_low, 0);
497 cal1( setup, ni_reference_low, 1);
500 cal1( setup, ni_ao0_zero_offset,6);
501 cal1( setup, ni_ao0_reference,4);
502 cal1( setup, ni_ao1_zero_offset,7);
503 cal1( setup, ni_ao1_reference,5);
508 int cal_ni_at_mio_16e_1(calibration_setup_t *setup)
510 return cal_ni_at_mio_16e_2( setup );
513 int cal_ni_pci_mio_16e_1(calibration_setup_t *setup)
515 //cal_ni_at_mio_16e_2();
517 postgain_cal( setup, ni_zero_offset_low,ni_zero_offset_high,1);
518 cal1( setup, ni_zero_offset_high,0);
519 cal1( setup, ni_reference_low,3);
520 cal1( setup, ni_unip_offset_low,2);
522 cal1( setup, ni_ao0_zero_offset,5);
523 //cal1( setup, ni_ao0_zero_offset,4); /* linearity? */
524 cal1( setup, ni_ao0_reference,6);
525 cal1( setup, ni_ao1_zero_offset,8);
526 //cal1( setup, ni_ao1_zero_offset,7); /* linearity? */
527 cal1( setup, ni_ao1_reference,9);
532 int cal_ni_pci_6032e(calibration_setup_t *setup)
534 postgain_cal(setup, ni_zero_offset_low, ni_zero_offset_high, 2);
535 postgain_cal(setup, ni_zero_offset_low, ni_zero_offset_high, 3);
537 cal1( setup, ni_zero_offset_high,8);
539 cal1( setup, ni_reference_low,0);
540 cal1_fine( setup, ni_reference_low,0);
541 cal1( setup, ni_reference_low,1);
546 int cal_ni_pci_6035e(calibration_setup_t *setup)
548 /* this is for the ad8804_debug caldac */
550 postgain_cal( setup, ni_zero_offset_low,ni_zero_offset_high,4);
552 cal1( setup, ni_zero_offset_high,0);
553 cal1( setup, ni_zero_offset_high,8);
555 cal1( setup, ni_reference_low,2);
558 cal1( setup, ni_ao0_zero_offset,6);
559 //cal1( setup, ni_ao0_zero_offset,10); /* linearity? */
560 cal1( setup, ni_ao0_reference,11);
561 cal1( setup, ni_ao1_zero_offset,9);
562 //cal1( setup, ni_ao1_zero_offset,1); /* linearity? */
563 cal1( setup, ni_ao1_reference,5);
568 int cal_ni_pci_6071e(calibration_setup_t *setup)
570 postgain_cal( setup, ni_zero_offset_low,ni_zero_offset_high,1);
571 cal1( setup, ni_zero_offset_high,0);
572 cal1( setup, ni_reference_low,3);
573 cal1_fine( setup, ni_reference_low,3);
575 cal1( setup, ni_ao0_zero_offset,5);
576 //cal1( setup, ni_ao0_zero_offset,4); /* linearity? */
577 /* caldac 6 should most likely be AO0 reference, but it
579 /*cal1( setup, ni_ao0_reference,6);*/
580 cal1( setup, ni_ao1_zero_offset,8);
581 //cal1( setup, ni_ao1_zero_offset,7); /* linearity? */
582 cal1( setup, ni_ao1_reference,9);
587 int cal_ni_pxi_6071e(calibration_setup_t *setup)
590 postgain_cal( setup, ni_zero_offset_low,ni_zero_offset_high,1);
591 cal1( setup, ni_zero_offset_high,0);
592 cal1( setup, ni_reference_low,3);
599 int cal_ni_at_mio_16e_10(calibration_setup_t *setup)
602 postgain_cal( setup, ni_zero_offset_low,ni_zero_offset_high,1);
603 cal1( setup, ni_zero_offset_high,10);
604 cal1( setup, ni_zero_offset_high,0);
605 cal1( setup, ni_reference_low,3);
606 cal1( setup, ni_unip_offset_low,2);
608 cal1( setup, ni_ao0_zero_offset,5); // guess
609 cal1( setup, ni_ao0_reference,6); // guess
610 cal1( setup, ni_ao1_zero_offset,8); // guess
611 cal1( setup, ni_ao1_reference,9); // guess
616 int cal_ni_pci_mio_16xe_50(calibration_setup_t *setup)
618 postgain_cal( setup, ni_zero_offset_low,ni_zero_offset_high,2);
619 cal1( setup, ni_zero_offset_high,8);
620 cal1( setup, ni_reference_low,0);
621 cal1_fine( setup, ni_reference_low,0);
622 cal1( setup, ni_reference_low,1);
625 cal1( setup, ni_ao0_zero_offset,6);
626 cal1( setup, ni_ao0_reference,4);
627 cal1( setup, ni_ao1_zero_offset,7);
628 cal1( setup, ni_ao1_reference,5);
633 int cal_ni_pci_6023e(calibration_setup_t *setup)
635 /* for comedi-0.7.65 */
637 postgain_cal( setup, ni_zero_offset_low,ni_zero_offset_high,4);
638 cal1( setup, ni_zero_offset_high,0);
639 cal1( setup, ni_zero_offset_high,8); /* possibly wrong */
640 cal1( setup, ni_reference_low,2);
645 int cal_ni_pci_6024e(calibration_setup_t *setup)
647 postgain_cal( setup, ni_zero_offset_low,ni_zero_offset_high,4);
648 cal1( setup, ni_zero_offset_high,0);
649 cal1( setup, ni_zero_offset_high,8);
650 cal1( setup, ni_reference_low,2);
652 cal1( setup, ni_ao0_zero_offset,6);
653 //cal1( setup, ni_ao0_zero_offset,10); // nonlinearity?
654 cal1( setup, ni_ao0_reference,11);
655 cal1( setup, ni_ao1_zero_offset,9);
656 //cal1( setup, ni_ao1_zero_offset,1); // nonlinearity?
657 cal1( setup, ni_ao1_reference,5);
662 int cal_ni_pci_6025e(calibration_setup_t *setup)
664 postgain_cal( setup, ni_zero_offset_low,ni_zero_offset_high,4);
665 cal1( setup, ni_zero_offset_high,0);
666 cal1( setup, ni_zero_offset_high,8);
667 cal1( setup, ni_reference_low,2);
669 cal1( setup, ni_ao0_zero_offset,6);
670 //cal1( setup, ni_ao0_zero_offset,10); /* nonlinearity */
671 cal1( setup, ni_ao0_reference,11);
672 cal1( setup, ni_ao1_zero_offset,9);
673 //cal1( setup, ni_ao1_zero_offset,1); /* nonlinearity */
674 cal1( setup, ni_ao1_reference,5);
679 int cal_ni_pci_6052e(calibration_setup_t *setup)
682 * This board has noisy caldacs
684 * The NI documentation says:
685 * 0, 8 AI pregain (coarse, fine) 3, 11
686 * 4, 12 AI postgain 15,7
687 * 2, 10 AI reference 1, 9
688 * 14, 7 AI unipolar offset 5, 13
691 * 8, 4 AO0 reference 23, 19 7, 3
692 * 12 AO0 offset 27 11
694 * 10, 6 AO1 reference 25, 21 9, 5
695 * 14 AO1 offset 29, 17 13, 1
705 * 8 11 19 7 1011 0111
707 * 10 9 21 9 1001 1001
711 * 14 5 13 1 0101 0001
715 cal_postgain_binary( setup, ni_zero_offset_low,ni_zero_offset_high,2);
716 postgain_cal( setup, ni_zero_offset_low,ni_zero_offset_high,3);
717 cal1( setup, ni_zero_offset_high,0);
718 cal1( setup, ni_zero_offset_high,1);
719 cal_binary( setup, ni_reference_low,4);
720 cal1_fine( setup, ni_reference_low,4);
721 cal1( setup, ni_reference_low,5);
722 cal1( setup, ni_unip_offset_low,6);
723 cal1_fine( setup, ni_unip_offset_low,6);
725 cal1( setup, ni_ao0_zero_offset,12+11);
726 cal1_fine( setup, ni_ao0_zero_offset,12+11);
727 cal1( setup, ni_ao0_reference,12+7);
728 cal1_fine( setup, ni_ao0_reference,12+7);
729 cal1( setup, ni_ao0_reference,12+3);
730 cal1( setup, ni_ao1_zero_offset,12+1);
731 cal1( setup, ni_ao1_reference,12+9);
732 cal1_fine( setup, ni_ao1_reference,12+9);
733 cal1( setup, ni_ao1_reference,12+5);
738 int cal_ni_pci_mio_16e_4(calibration_setup_t *setup)
740 /* this is for the ad8804_debug caldac */
742 cal_postgain_binary( setup, ni_zero_offset_low,ni_zero_offset_high,4);
743 //cal_postgain_fine( setup, ni_zero_offset_low,ni_zero_offset_high,4);
744 cal1( setup, ni_zero_offset_high,8);
745 cal_binary( setup, ni_reference_low,2);
746 cal1_fine( setup, ni_reference_low,2);
748 cal1( setup, ni_unip_offset_low,7);
749 cal1_fine( setup, ni_unip_offset_low,7);
752 cal_binary( setup, ni_ao0_zero_offset,6);
753 cal1_fine( setup, ni_ao0_zero_offset,6);
754 //cal1( setup, ni_ao0_nonlinearity,10);
755 cal_binary( setup, ni_ao0_reference,11);
756 cal1_fine( setup, ni_ao0_reference,11);
757 cal_binary( setup, ni_ao1_zero_offset,9);
758 cal1_fine( setup, ni_ao1_zero_offset,9);
759 //cal1( setup, ni_ao1_nonlinearity,1);
760 cal_binary( setup, ni_ao1_reference,5);
761 cal1_fine( setup, ni_ao1_reference,5);
766 int cal_ni_daqcard_ai_16e_4(calibration_setup_t *setup)
768 cal_postgain_binary(setup, ni_zero_offset_low, ni_zero_offset_high, 1);
769 //cal_postgain_fine(setup, ni_zero_offset_low, ni_zero_offset_high, 1);
771 cal_binary( setup, ni_zero_offset_high,0);
772 cal1_fine( setup, ni_zero_offset_high,0);
774 cal_binary( setup, ni_reference_low,3);
775 cal1_fine( setup, ni_reference_low,3);
777 cal1( setup, ni_unip_offset_low,2);
782 int cal_ni_pci_611x( calibration_setup_t *setup )
787 num_chans = comedi_get_n_channels( setup->dev, setup->ad_subdev );
789 for( i = 0; i < num_chans; i++ ){
790 cal1( setup, ni_zero_offset_611x( i ), ( 2 * i + 2 ) );
791 cal1( setup, ni_reference_611x( i ), ( 2 * i + 1 ) );
795 cal1( setup, ni_ao0_zero_offset_611x, 14 );
796 cal1( setup, ni_ao0_reference_611x, 13 );
797 cal1( setup, ni_ao1_zero_offset_611x, 16 );
798 cal1( setup, ni_ao1_reference_611x, 15 );
804 double ni_get_reference( calibration_setup_t *setup, int lsb_loc,int msb_loc)
810 lsb=read_eeprom( setup, lsb_loc);
811 msb=read_eeprom( setup, msb_loc);
812 printf("lsb=%d msb=%d\n",read_eeprom( setup, 425),read_eeprom( setup, 426));
815 if(uv>=0x8000)uv-=0x10000;
817 printf("ref=%g\n",ref);
823 void cal_ni_results(void)
827 int bipolar_highgain;
828 int unipolar_lowgain;
832 bipolar_lowgain = get_bipolar_lowgain(dev,setup->ad_subdev);
833 bipolar_highgain = get_bipolar_highgain(dev,setup->ad_subdev);
834 unipolar_lowgain = get_unipolar_lowgain(dev,setup->ad_subdev);
836 /* 0 offset, low gain */
837 range = comedi_get_range(dev,setup->ad_subdev,0,bipolar_lowgain);
838 read_chan2(s,0,bipolar_lowgain);
839 DPRINT(0,"bipolar zero offset, low gain [%g,%g]: %s\n",
840 range->min,range->max,s);
842 /* 0 offset, high gain */
843 range = comedi_get_range(dev,setup->ad_subdev,0,bipolar_highgain);
844 read_chan2(s,0,bipolar_highgain);
845 DPRINT(0,"bipolar zero offset, high gain [%g,%g]: %s\n",
846 range->min,range->max,s);
848 /* unip/bip offset */
849 range = comedi_get_range(dev,setup->ad_subdev,0,unipolar_lowgain);
850 read_chan2(s,0,unipolar_lowgain);
851 DPRINT(0,"unipolar zero offset, low gain [%g,%g]: %s\n",
852 range->min,range->max,s);
856 void ni_mio_ai_postgain_cal(void)
864 check_gain_chan_x(&l,CR_PACK(0,0,AREF_OTHER),1);
865 offset_r0=linear_fit_func_y(&l,caldacs[1].current);
866 printf("offset r0 %g\n",offset_r0);
868 check_gain_chan_x(&l,CR_PACK(0,7,AREF_OTHER),1);
869 offset_r7=linear_fit_func_y(&l,caldacs[1].current);
870 printf("offset r7 %g\n",offset_r7);
874 a=(offset_r0-offset_r7)/(200.0-1.0);
875 a=caldacs[1].current-a/gain;
879 caldacs[1].current=rint(a);
883 void ni_mio_ai_postgain_cal_2(int chan,int dac,int range_lo,int range_hi,double gain)
885 double offset_lo,offset_hi;
890 check_gain_chan_x(&l,CR_PACK(chan,range_lo,AREF_OTHER),dac);
891 offset_lo=linear_fit_func_y(&l,caldacs[dac].current);
892 printf("offset lo %g\n",offset_lo);
894 check_gain_chan_x(&l,CR_PACK(chan,range_hi,AREF_OTHER),dac);
895 offset_hi=linear_fit_func_y(&l,caldacs[dac].current);
896 printf("offset hi %g\n",offset_hi);
900 a=(offset_lo-offset_hi)/(gain-1.0);
901 a=caldacs[dac].current-a/slope;
905 caldacs[dac].current=rint(a);