From 0b55b0435d1f1cad37b74bcce9063ee04eecf82b Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Wed, 4 Jan 2006 02:55:40 +0000 Subject: [PATCH] Added beginnings of support for m-series calibration. So far, it just reads various internal calibration sources. --- comedi_calibrate/Makefile.am | 2 +- comedi_calibrate/calib.h | 2 + comedi_calibrate/ni.c | 5 +- comedi_calibrate/ni_m_series.c | 192 +++++++++++++++++++++++++++++++++ 4 files changed, 199 insertions(+), 2 deletions(-) create mode 100644 comedi_calibrate/ni_m_series.c diff --git a/comedi_calibrate/Makefile.am b/comedi_calibrate/Makefile.am index 0d14d1a..b9982f9 100644 --- a/comedi_calibrate/Makefile.am +++ b/comedi_calibrate/Makefile.am @@ -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) diff --git a/comedi_calibrate/calib.h b/comedi_calibrate/calib.h index fdd584f..b1b7ada 100644 --- a/comedi_calibrate/calib.h +++ b/comedi_calibrate/calib.h @@ -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 */ diff --git a/comedi_calibrate/ni.c b/comedi_calibrate/ni.c index 45c3d56..3ae5a27 100644 --- a/comedi_calibrate/ni.c +++ b/comedi_calibrate/ni.c @@ -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 index 0000000..1911e3d --- /dev/null +++ b/comedi_calibrate/ni_m_series.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +} +