do seperate unipolar ai calibration on ni boards that need it
authorFrank Mori Hess <fmhess@speakeasy.net>
Sun, 20 Jul 2003 05:10:13 +0000 (05:10 +0000)
committerFrank Mori Hess <fmhess@speakeasy.net>
Sun, 20 Jul 2003 05:10:13 +0000 (05:10 +0000)
comedi_calibrate/cal_common.c
comedi_calibrate/calib.h
comedi_calibrate/ni.c

index 611cb0fdc484dfe912a742a24ff4346de5bbc295..a1c4704184aaa0ab768413e64bd297f61acb2d98 100644 (file)
@@ -118,7 +118,7 @@ void generic_prep_dac_caldacs( calibration_setup_t *setup,
        }
 }
 
-static void generic_prep_adc_for_dac( calibration_setup_t *setup, const generic_layout_t *layout,
+static void generic_prep_adc_for_dac( calibration_setup_t *setup,
        comedi_calibration_t *calibration, int observable )
 {
        unsigned int adc_channel, adc_range;
@@ -154,7 +154,9 @@ static void generic_do_dac_channel( calibration_setup_t *setup, const generic_la
        static const int max_iterations = 4;
        int i;
 
-       generic_prep_adc_for_dac( setup, layout, calibration,
+       current_cal->subdevice = setup->da_subdev;
+
+       generic_prep_adc_for_dac( setup, calibration,
                layout->dac_ground_observable( setup, channel, range ) );
 
        for( i = 0; i < max_iterations; i++ )
@@ -172,7 +174,6 @@ static void generic_do_dac_channel( calibration_setup_t *setup, const generic_la
        if( i == max_iterations )
                DPRINT(0, "WARNING: unable to calibrate dac channel %i, range %i to desired %g tolerance\n",
                        channel, range, layout->dac_fractional_tolerance );
-       current_cal->subdevice = setup->da_subdev;
        sc_push_channel( current_cal, channel );
        sc_push_range( current_cal, range );
        sc_push_aref( current_cal, SC_ALL_AREFS );
@@ -197,6 +198,8 @@ static void generic_do_adc_channel( calibration_setup_t *setup, const generic_la
        static const int max_iterations = 4;
        int i;
 
+       current_cal->subdevice = setup->ad_subdev;
+
        for( i = 0; i < max_iterations; i++ )
        {
                generic_do_relative( setup, current_cal, layout->adc_high_observable( setup, channel, range ),
@@ -212,7 +215,6 @@ static void generic_do_adc_channel( calibration_setup_t *setup, const generic_la
        if( i == max_iterations )
                DPRINT(0, "WARNING: unable to calibrate adc channel %i, range %i to desired %g tolerance\n",
                        channel, range, layout->adc_fractional_tolerance );
-       current_cal->subdevice = setup->ad_subdev;
        sc_push_channel( current_cal, channel );
        sc_push_range( current_cal, range );
        sc_push_aref( current_cal, SC_ALL_AREFS );
@@ -224,6 +226,8 @@ static void generic_do_adc_postgain_offset( calibration_setup_t *setup, const ge
        int lowgain, highgain;
        int bip_lowgain;
 
+       current_cal->subdevice = setup->ad_subdev;
+
        bip_lowgain = get_bipolar_lowgain( setup->dev, setup->ad_subdev );
        if( unipolar )
        {
@@ -248,7 +252,6 @@ static void generic_do_adc_postgain_offset( calibration_setup_t *setup, const ge
        generic_do_relative( setup, current_cal, layout->adc_ground_observable( setup, channel, lowgain ),
                layout->adc_ground_observable( setup, channel, highgain ), layout->adc_postgain_offset( channel ) );
 
-       current_cal->subdevice = setup->ad_subdev;
        sc_push_channel( current_cal, channel );
        sc_push_aref( current_cal, SC_ALL_AREFS );
 }
index 7cc9e130269a79a65daf5d19927dd3c19fe6380d..23a10d2226bbc01d551bb148edc5391c51efff2e 100644 (file)
@@ -276,6 +276,8 @@ void generic_prep_adc_caldacs( calibration_setup_t *setup,
        const generic_layout_t *layout, unsigned int channel, unsigned int range );
 void generic_prep_dac_caldacs( calibration_setup_t *setup,
        const generic_layout_t *layout, unsigned int channel, unsigned int range );
+void generic_peg( calibration_setup_t *setup, int observable, int caldac,
+       int maximize );
 
 #endif
 
index 41f5fb74ce083b72437c5d013cc1f3ae34d66193..52c6b420cd9c79bdfa07229fa0d2b21252993909 100644 (file)
@@ -1120,7 +1120,7 @@ static int cal_ni_daqcard_6024e( calibration_setup_t *setup )
 }
 
 static void prep_adc_caldacs_generic( calibration_setup_t *setup,
-       const ni_caldac_layout_t *layout )
+       const ni_caldac_layout_t *layout, unsigned int range )
 {
        int retval;
 
@@ -1136,7 +1136,7 @@ static void prep_adc_caldacs_generic( calibration_setup_t *setup,
        }else
        {
                retval = comedi_apply_parsed_calibration( setup->dev, setup->ad_subdev,
-                       0, 0, AREF_GROUND, setup->old_calibration );
+                       0, range, AREF_GROUND, setup->old_calibration );
                if( retval < 0 )
                {
                        DPRINT( 0, "Failed to apply existing calibration, reseting adc caldacs.\n" );
@@ -1179,12 +1179,35 @@ static void prep_dac_caldacs_generic( calibration_setup_t *setup,
        }
 }
 
+static void prep_adc_for_dac( calibration_setup_t *setup, int observable )
+{
+       unsigned int adc_range;
+       int chanspec;
+
+       if( observable < 0 ) return;
+
+       chanspec = setup->observables[ observable ].observe_insn.chanspec;
+       adc_range = CR_RANGE( chanspec );
+
+       comedi_apply_parsed_calibration( setup->dev, setup->ad_subdev,
+               0, adc_range, 0, setup->new_calibration );
+}
+
 static int cal_ni_generic( calibration_setup_t *setup, const ni_caldac_layout_t *layout )
 {
        comedi_calibration_setting_t *current_cal;
        int retval;
+       int num_ai_ranges;
+       int range;
+       int ai_unipolar_lowgain, ai_bipolar_lowgain;
 
-       prep_adc_caldacs_generic( setup, layout );
+       num_ai_ranges = comedi_get_n_ranges( setup->dev, setup->ad_subdev, 0 );
+       assert( num_ai_ranges > 0 );
+
+       ai_bipolar_lowgain = get_bipolar_lowgain( setup->dev, setup->ad_subdev );
+       ai_unipolar_lowgain = get_unipolar_lowgain( setup->dev, setup->ad_subdev );
+
+       prep_adc_caldacs_generic( setup, layout, ai_bipolar_lowgain );
 
        current_cal = sc_alloc_calibration_setting( setup );
        current_cal->subdevice = setup->ad_subdev;
@@ -1199,11 +1222,55 @@ static int cal_ni_generic( calibration_setup_t *setup, const ni_caldac_layout_t
                ni_zero_offset_high, layout->adc_postgain_offset_fine );
        generic_do_cal( setup, current_cal, ni_zero_offset_high,
                layout->adc_pregain_offset_fine );
-       generic_do_cal( setup, current_cal, ni_unip_zero_offset_high, layout->adc_unip_offset );
        sc_push_channel( current_cal, SC_ALL_CHANNELS );
-       sc_push_range( current_cal, SC_ALL_RANGES );
        sc_push_aref( current_cal, SC_ALL_AREFS );
+       if( layout->adc_unip_offset >= 0 )
+       {
+               sc_push_range( current_cal, SC_ALL_RANGES );
+       }else
+       {
+               for( range = 0; range < num_ai_ranges; range++ )
+               {
+                       if( is_bipolar( setup->dev, setup->ad_subdev, 0, range ) )
+                               sc_push_range( current_cal, range );
+               }
+       }
 
+       /* do seperate unipolar calibration if appropriate */
+       if( ai_unipolar_lowgain >= 0 )
+       {
+               current_cal = sc_alloc_calibration_setting( setup );
+               current_cal->subdevice = setup->ad_subdev;
+               if( layout->adc_unip_offset >= 0 )
+               {
+                       generic_do_cal( setup, current_cal, ni_unip_zero_offset_high,
+                               layout->adc_unip_offset );
+               }else
+               {
+                       prep_adc_caldacs_generic( setup, layout, ai_unipolar_lowgain );
+                       generic_peg( setup, ni_unip_zero_offset_low,
+                               layout->adc_pregain_offset, 1 );
+                       generic_do_relative( setup, current_cal, ni_unip_zero_offset_low,
+                               ni_unip_reference_low, layout->adc_gain );
+                       generic_do_relative( setup, current_cal, ni_unip_zero_offset_low,
+                               ni_unip_zero_offset_high, layout->adc_postgain_offset );
+                       generic_do_cal( setup, current_cal, ni_unip_zero_offset_high,
+                               layout->adc_pregain_offset );
+                       generic_do_relative( setup, current_cal, ni_unip_zero_offset_low,
+                               ni_unip_reference_low, layout->adc_gain_fine );
+                       generic_do_relative( setup, current_cal, ni_unip_zero_offset_low,
+                               ni_unip_zero_offset_high, layout->adc_postgain_offset_fine );
+                       generic_do_cal( setup, current_cal, ni_unip_zero_offset_high,
+                               layout->adc_pregain_offset_fine );
+               }
+               for( range = 0; range < num_ai_ranges; range++ )
+               {
+                       if( is_unipolar( setup->dev, setup->ad_subdev, 0, range ) )
+                               sc_push_range( current_cal, range );
+               }
+               sc_push_channel( current_cal, SC_ALL_CHANNELS );
+               sc_push_aref( current_cal, SC_ALL_AREFS );
+       }
        if( setup->da_subdev >= 0 && setup->do_output )
        {
                unsigned int channel, range;
@@ -1215,6 +1282,7 @@ static int cal_ni_generic( calibration_setup_t *setup, const ni_caldac_layout_t
                {
                        num_ao_ranges = comedi_get_n_ranges( setup->dev, setup->da_subdev, channel );
                        prep_dac_caldacs_generic( setup, layout, channel, ao_bipolar_lowgain );
+                       prep_adc_for_dac( setup, ni_ao_reference( channel ) );
 
                        current_cal = sc_alloc_calibration_setting( setup );
                        current_cal->subdevice = setup->da_subdev;