Added beginnings of support for m-series calibration. So far, it just
authorFrank Mori Hess <fmhess@speakeasy.net>
Wed, 4 Jan 2006 02:55:40 +0000 (02:55 +0000)
committerFrank Mori Hess <fmhess@speakeasy.net>
Wed, 4 Jan 2006 02:55:40 +0000 (02:55 +0000)
reads various internal calibration sources.

comedi_calibrate/Makefile.am
comedi_calibrate/calib.h
comedi_calibrate/ni.c
comedi_calibrate/ni_m_series.c [new file with mode: 0644]

index 0d14d1a6e347aa51abd22a5a18841e1dfcd253b4..b9982f9d645ddcebd2a0d325bd5796f342562138 100644 (file)
@@ -4,7 +4,7 @@ bin_PROGRAMS = comedi_calibrate
 noinst_HEADERS = calib.h
 
 comedi_calibrate_SOURCES = \
-       comedi_calibrate.c ni.c cb.c cb64.c other.c save_cal.c cal_common.c ni_labpc.c
+       comedi_calibrate.c ni.c cb.c cb64.c other.c save_cal.c cal_common.c ni_labpc.c ni_m_series.c
 comedi_calibrate_CFLAGS = $(COMEDILIB_CFLAGS)
 comedi_calibrate_LDADD = $(COMEDILIB_LIBS)
 
index fdd584f1ac32562537d8b9a569c90d74cb030cca..b1b7ada48578c360e0618f3f1ec31f9da1a4f649 100644 (file)
@@ -101,11 +101,13 @@ extern char ni_id[];
 extern char cb_id[];
 extern char cb64_id[];
 extern char ni_labpc_id[];
+extern char ni_m_series_id[];
 
 int ni_setup( calibration_setup_t*, const char *device_name );
 int cb_setup( calibration_setup_t*, const char *device_name );
 int cb64_setup( calibration_setup_t*, const char *device_name );
 int ni_labpc_setup( calibration_setup_t*, const char *device_name );
+int ni_m_series_setup(calibration_setup_t*, const char *device_name);
 
 /* low level */
 
index 45c3d5691cc637f2333c3272f3298c6b3ba9a687..3ae5a27daa312f68d5928b42389b2f3b5cae5827 100644 (file)
@@ -285,7 +285,10 @@ int ni_setup( calibration_setup_t *setup , const char *device_name )
        int retval;
 
        retval = ni_setup_board( setup, device_name );
-       if( retval < 0 ) return retval;
+       if( retval < 0 )
+       {
+               return ni_m_series_setup(setup, device_name);
+       }
        setup_caldacs( setup, setup->caldac_subdev );
 
        return 0;
diff --git a/comedi_calibrate/ni_m_series.c b/comedi_calibrate/ni_m_series.c
new file mode 100644 (file)
index 0000000..1911e3d
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+   calibration support for NI m-series boards
+
+   copyright (C) 2003, 2006 by Frank Mori Hess
+
+ */
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU Lesser General Public License as        *
+ *   published by                                                          *
+ *   the Free Software Foundation; either version 2.1 of the License, or   *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <getopt.h>
+#include <ctype.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "calib.h"
+
+char ni_m_series_id[] = "$Id$";
+
+int ni_m_series_setup(calibration_setup_t *setup , const char *device_name);
+static int cal_ni_m_series(calibration_setup_t *setup);
+
+struct board_struct{
+       char *name;
+       int status;
+};
+
+static struct board_struct boards[]={
+       { "pci-6289", STATUS_UNKNOWN},
+};
+
+static const int n_boards = sizeof(boards) / sizeof(boards[0]);
+
+static struct board_struct* ni_board(calibration_setup_t *setup)
+{
+       return setup->private_data;
+}
+
+uint16_t ni_read_eeprom_u16(calibration_setup_t *setup, int offset)
+{
+       uint16_t value = read_eeprom(setup, offset) << 8;
+       value |= read_eeprom(setup, offset + 1) & 0xff;
+       return value;
+}
+
+float ni_read_eeprom_f32(calibration_setup_t *setup, int offset)
+{
+       union float_converter
+       {
+               uint32_t raw;
+               float converted;
+       };
+       union float_converter my_converter;
+       
+       assert(sizeof(float) == 4);
+       my_converter.raw = read_eeprom(setup, offset++) << 24 & 0xff000000;
+       my_converter.raw |= (read_eeprom(setup, offset++) << 16) & 0xff0000;
+       my_converter.raw |= (read_eeprom(setup, offset++) << 8) & 0xff00;
+       my_converter.raw |= read_eeprom(setup, offset++) & 0xff;
+       return my_converter.converted;
+}
+
+static void ni_m_series_setup_observables(calibration_setup_t *setup)
+{
+       static const int positive_cal_shift = 7;
+       static const int negative_cal_shift = 10;
+       enum positive_cal_source
+       {
+               POS_CAL_GROUND = 0 << positive_cal_shift,
+               POS_CAL_REF = 2 << positive_cal_shift,
+               POS_CAL_500mV = 3 << positive_cal_shift,
+               POS_CAL_2V = 4 << positive_cal_shift,
+               POS_CAL_10V = 5 << positive_cal_shift,
+               POS_CAL_AO = 7 << positive_cal_shift
+       };
+       enum negative_cal_source
+       {
+               NEG_CAL_GROUND = 0 << negative_cal_shift,
+               NEG_CAL_850mV = 2 << negative_cal_shift,
+               NEG_CAL_10V = 7 << negative_cal_shift,
+       };
+       static const int calibration_area_offset = 24;
+       int calibration_area_start;
+       static const int voltage_reference_offset = 12;
+       comedi_insn tmpl;
+       double voltage_reference;
+       observable *o = setup->observables;
+       
+       calibration_area_start = ni_read_eeprom_u16(setup, calibration_area_offset);
+       DPRINT(1, "calibration area starts at offset %i\n", calibration_area_start);
+       voltage_reference = ni_read_eeprom_f32(setup, calibration_area_start + voltage_reference_offset);
+       DPRINT(1, "eeprom says voltage reference is %g V.\n", voltage_reference);
+
+       memset(&tmpl,0,sizeof(tmpl));
+       tmpl.insn = INSN_READ;
+       tmpl.n = 1;
+       tmpl.subdev = setup->ad_subdev;
+
+       o = setup->observables;
+       
+       o->name = "ai, reference voltage source";
+       o->observe_insn = tmpl;
+       o->observe_insn.chanspec = CR_PACK(0, 0, AREF_DIFF) | CR_ALT_SOURCE | CR_ALT_FILTER;
+       o->reference_source = NEG_CAL_GROUND | POS_CAL_REF;
+       o->target = voltage_reference;
+       ++o;
+       
+       o->name = "ai, nominal 10V";
+       o->observe_insn = tmpl;
+       o->observe_insn.chanspec = CR_PACK(0, 0, AREF_DIFF) | CR_ALT_SOURCE | CR_ALT_FILTER;
+       o->reference_source = NEG_CAL_GROUND | POS_CAL_10V;
+       o->target = 10.;
+       ++o;
+
+       o->name = "ai, nominal 2V";
+       o->observe_insn = tmpl;
+       o->observe_insn.chanspec = CR_PACK(0, 0, AREF_DIFF) | CR_ALT_SOURCE | CR_ALT_FILTER;
+       o->reference_source = NEG_CAL_GROUND | POS_CAL_2V;
+       o->target = 2.;
+       ++o;
+               
+       o->name = "ai, nominal 0.5V";
+       o->observe_insn = tmpl;
+       o->observe_insn.chanspec = CR_PACK(0, 0, AREF_DIFF) | CR_ALT_SOURCE | CR_ALT_FILTER;
+       o->reference_source = NEG_CAL_GROUND | POS_CAL_500mV;
+       o->target = 0.5;
+       ++o;
+
+       o->name = "ai, ground";
+       o->observe_insn = tmpl;
+       o->observe_insn.chanspec = CR_PACK(0, 0, AREF_DIFF) | CR_ALT_SOURCE | CR_ALT_FILTER;
+       o->reference_source = NEG_CAL_GROUND | POS_CAL_GROUND;
+       o->target = 0.0;
+       ++o;
+
+       o->name = "ai, nominal -0.85V";
+       o->observe_insn = tmpl;
+       o->observe_insn.chanspec = CR_PACK(0, 0, AREF_DIFF) | CR_ALT_SOURCE | CR_ALT_FILTER;
+       o->reference_source = NEG_CAL_850mV | POS_CAL_GROUND;
+       o->target = -0.85;
+       ++o;
+
+       o->name = "ai, nominal -10V";
+       o->observe_insn = tmpl;
+       o->observe_insn.chanspec = CR_PACK(0, 0, AREF_DIFF) | CR_ALT_SOURCE | CR_ALT_FILTER;
+       o->reference_source = NEG_CAL_10V | POS_CAL_GROUND;
+       o->target = -10.;
+       ++o;
+
+       setup->n_observables = o - setup->observables;
+}
+
+int ni_m_series_setup(calibration_setup_t *setup , const char *device_name)
+{      
+       int i;
+       for(i = 0; i < n_boards; ++i)
+       {
+               if(!strcmp(device_name, boards[i].name))
+               {
+                       setup->status = boards[i].status;
+                       setup->private_data = &boards[i];
+                       setup->do_cal = &cal_ni_m_series;
+                       ni_m_series_setup_observables(setup);
+                       break;
+               }
+       }
+       if(i == n_boards) return -1;
+
+       return 0;
+}
+
+static int cal_ni_m_series(calibration_setup_t *setup)
+{
+       return 0;
+}
+