+
+I always seem to forget how to convert the calibration
+dump information into code for doing a calibration, so
+I'm writing this mostly for myself.
+
+Boards may have one of 4 calibrations statuses, depending
+on how well the calibration code is trusted. These are:
+STATUS_NONE, the default for no information; STATUS_SOME,
+meaning that a dump has been converted to initial code,
+but not tested; STATUS_DONE means that the output of a
+STATUS_SOME dump has been checked, and is correct;
+STATUS_GUESS is a marker that code has been converted
+from a previous version of the code, but not checked.
+
+The NI E series boards have several internal voltages that
+can be measured, and also several calibration DACs that function
+similar to adjustable resistors on old data acquisition boards.
+The information we need is which DACs affect which measurable
+voltages; then we can write calibration code that adjusts those
+DACs until the voltages are within spec.
+
+Usually, there are DACs (or multiple DACs) that are added to
+an analog input signal: 1) before the variable gain amplifier
+("pre-gain"), 2) after the variable gain amplifier ("post-gain"),
+3) between the board's stable voltage reference and the
+reference input to the ADC ("gain offset"), and 4) before a
+unipolar-to-bipolar adjuster ("unipolar offset"), or other
+equivalent circuit.
+
+In addition there are DACs that adjust the output voltages and/or
+reference voltage inputs to a D/A converter. These are pretty
+intuitive once analog input is understood, and is dependent on
+correct analog input calibration.
+
+The measurable quantities are 0 volts and an internal voltage
+reference near 5 volts, and can be measured at any gain. The
+interesting combinations are:
+
+ ai, bipolar zero offset, low gain
+ ai, bipolar zero offset, high gain
+ ai, bipolar voltage reference, low gain
+ ai, unipolar zero offset, low gain
+
+The unipolar zero offset may not be available on some boards.
+
+In a STATUS_NONE dump, for each measurable quantity and each
+calibration DAC, the DAC is varied throughout its entire range
+and the quantity measured. The data is linearly fit, and if
+the slope is statistically non-zero, a line is printed:
+
+ caldac[0] gain=1.26(11)e-7 V/bit S_min=235.659 dof=254
+
+The information given is caldac index, slope (gain) and slope
+error (in parenthesis, modifying the last two digits of the
+slope), and two statistical parameters S_min and degrees
+of freedom. S_min and dof will be roughly similar for a
+good fit. If S_min is more than a factor of 4 greater than
+dof, this is probably not a good fit. Typically this means
+that the DAC doesn't affect the measureable strictly linearly,
+or there is systematic noise. The latter seems to common in
+E series boards, so I'm not too worried about the following
+dump where there are S_min/dof ratios above 4.
+
+Here's an example dump, generated by a STATUS_NONE dump for
+a pci-mio-16xe-10, with the analog output section removed:
+
+ Warning: device not fully calibrated due to insufficient information
+ Please send this output to <ds@schleef.org>
+ Id: comedi_calibrate.c,v 1.21 2001/10/10 22:07:53 ds Exp
+ Driver name: ni_pcimio
+ Device name: pci-mio-16xe-10
+ Comedi version: 0.7.61
+ ai, bipolar zero offset, low gain
+ offset -6.795(14)e-3, target 0
+ caldac[0] gain=1.26(11)e-7 V/bit S_min=235.659 dof=254
+ caldac[2] gain=3.96840(14)e-4 V/bit S_min=1390.18 dof=254
+ caldac[3] gain=4.348(11)e-6 V/bit S_min=258.75 dof=254
+ caldac[8] gain=5.4659(69)e-7 V/bit S_min=386.361 dof=254
+ ai, bipolar zero offset, high gain
+ offset -2.4224(55)e-4, target 0
+ caldac[0] gain=3.61(45)e-9 V/bit S_min=247.26 dof=254
+ caldac[2] gain=3.96644(48)e-6 V/bit S_min=351.927 dof=254
+ caldac[3] gain=4.063(46)e-8 V/bit S_min=272.024 dof=254
+ caldac[8] gain=5.46305(30)e-7 V/bit S_min=314.035 dof=254
+ ai, bipolar voltage reference, low gain
+ offset 4.992959(13), target 5
+ caldac[0] gain=-4.4928(11)e-5 V/bit S_min=1111.4 dof=254
+ caldac[1] gain=-2.792(11)e-6 V/bit S_min=248.971 dof=254
+ caldac[2] gain=3.96488(14)e-4 V/bit S_min=1059.18 dof=254
+ caldac[3] gain=4.318(11)e-6 V/bit S_min=437.441 dof=254
+ caldac[8] gain=5.4810(70)e-7 V/bit S_min=404.213 dof=254
+ ai, unipolar zero offset, low gain
+ offset nan, target 0
+ caldac[2] gain=3.96773(39)e-4 V/bit S_min=158.236 dof=107
+
+[The explanation gets a little fuzzy here]
+
+The resulting function for calibration will look something like:
+
+ void cal_ni_pci_mio_16xe_10(void)
+ {
+ postgain_cal(ni_zero_offset_low, ni_zero_offset_high, XXX);
+ cal1(ni_zero_offset_high, XXX);
+ cal1(ni_reference_low, XXX);
+ cal1(ni_unip_offset_low, XXX);
+ }
+
+You get to fill in the XXX's. The post-gain calibration DAC will
+be the one for which the ratio of caldac slopes for the low and
+high gain measurables is similar to the ratio of input ranges for
+low and high gain. This ratio is typically 100 or 200, and really
+should be printed by the program. Thus, for this dump, we choose
+caldac[2], since the ratio is very nearly 100. We don't choose
+caldac[0] or caldac[3], because the gains are smaller, and the
+ratio isn't exactly 100 or 200.
+
+Next is the pre-gain calibration. Adding a voltage before the
+amplifier will affect every input range selection equally, so the
+pre-gain cadac slope will be nearly equal for both bipolar zero
+offset at low and high gain. In this example, it would be caldac[8].
+
+Next is the voltage reference calibration. The caldac controlling
+the voltage reference adjustment is proportional to the offset,
+so the correct caldac will typically be the one that has a large
+slope for the bipolar voltage reference measurement, but a small
+slope (by a factor of 2e4, here) for the zero offset measurements.
+It could be any of caldac[0], caldac[1], or caldac[3], or possibly
+all of them. We'll choose the caldac with the largest slope for
+rough calibration, then use the one with the smallest slope for
+fine calibration, namely caldac[0] and caldac[1].
+
+This is one way that STATUS_SOME is useful, because you can calibrate
+the zero offset, then get a much better idea which other channels
+are likely to be for the voltage reference.
+
+In this example, there doesn't appear to be a caldac that affects
+unipolar zero offset, so it will not be used in the final function:
+
+ void cal_ni_pci_mio_16xe_10(void)
+ {
+ postgain_cal(ni_zero_offset_low, ni_zero_offset_high, 2);
+ cal1(ni_zero_offset_high, 8);
+ cal1(ni_reference_low, 0);
+ cal1(ni_reference_low, 1);
+ }
+