comedilib/python/compy.c
2002-03-09 00:20:20 +00:00

469 lines
13 KiB
C

/* Compy: COMedi PYthon interface
* A simple hack sharded object for importing into Python
* to start using Comedi drivers for Digital I/O
*
* Extensively referenced xxmodule.c and others from python distribution
* misc comedi examples.
*
* Blaine Lee Copyright 11/2000 Licence LGPL 2.0
*
* V 0.4 Major additions to add support for more of the comedilib
* functions. So far we have support for the comedi_ commands
* open, close, get_n_subdevices, get_driver_name, get_board_name
* get_n_channels, get_maxdata, get_n_ranges, get_range,
* to_phys, from_phys, data_read. Changed the way the debug
* and printstatus code works.
* V 0.3 changed to tuple parsing & added version number __version__()
* V 0.21 Resynced with sorce that had printstats debugging code in it
* V 0.2 Added card number, so that multiple cards are supported
* V 0.1 First release, only 'trig' type transfers are supported
*
*/
#include <Python.h>
#include <stdio.h> /* for printf() */
#include <comedilib.h>
#define Version 4
#define maxcards 4
static comedi_t *compy_it[maxcards];
#ifdef _COMEDILIB_DEPRECATED
static comedi_trig trig;
static int trigchan[2];
static short trigdata;
#endif
/******************************
* Debug flags - set with the
* open call. Output is sent
* to stderr.
*****************************/
static int printstats=0; // if 1 prints mostly the received calling parms
static int debug = 0; // if 1 print details of function calls
/******************************
* compy_open()
* opens the requested comedi device
* args - a tuple containing
* int - board number (0 to maxcards)
* string - the comedi device to open
* int - printstats 0-no, 1-yes, 2-also debug
******************************/
static PyObject *
compy_open( PyObject *self, PyObject *args )
{
const char *filen;
int card;
if (!PyArg_ParseTuple(args, "isi", &card, &filen, &printstats))
return NULL;
if (printstats > 1)
debug = 1;
if ((card < 0) || (card >= maxcards))
return NULL;
if(printstats)
fprintf(stderr,"compy open '%s'\n",filen);
compy_it[card]=comedi_open(filen);
if(debug)
fprintf(stderr,"open returned %p\n",compy_it[card]);
return Py_BuildValue("i", 1);
}
/******************************
* compy_close()
* close the requested comedi device
* args - a tuple containing
* int - board number (0 to maxcards)
******************************/
static PyObject *
compy_close( PyObject *self, PyObject *args )
{
int card;
if (!PyArg_ParseTuple(args, "i", &card))
return NULL;
if ((card < 0) || (card >= maxcards))
return NULL;
if(printstats)
fprintf(stderr,"compy close %d\n",card);
comedi_close(compy_it[card]);
return Py_BuildValue("i", 1);
}
/******************************
* compy_get_n_subdevices()
* get the number of subdevices
* args -
* int - board number (0 to maxcards)
* returns the number of subdevices on card
******************************/
static PyObject *
compy_get_n_subdevices( PyObject *self, PyObject *args )
{
int card;
if (!PyArg_ParseTuple(args, "i:get_n_subdevices", &card))
return NULL;
if ((card < 0) || (card >= maxcards))
return NULL;
if(printstats)
fprintf(stderr,"compy get_n_subdevices %d\n",card);
return Py_BuildValue("i", comedi_get_n_subdevices(compy_it[card]));
}
/******************************
* compy_get_driver_name()
* get the number of subdevices
* args -
* int - board number (0 to maxcards)
* returns the name of the driver for the board
******************************/
static PyObject *
compy_get_driver_name( PyObject *self, PyObject *args )
{
int card;
if (!PyArg_ParseTuple(args, "i:get_driver_name", &card))
return NULL;
if ((card < 0) || (card >= maxcards))
return NULL;
if(printstats)
fprintf(stderr,"compy get_driver_name (%d)\n",card);
return Py_BuildValue("s", comedi_get_driver_name(compy_it[card]));
}
/******************************
* compy_get_board_name()
* get the number of subdevices
* args -
* int - board number (0 to maxcards)
* returns the name of the driver for the board
******************************/
static PyObject *
compy_get_board_name( PyObject *self, PyObject *args )
{
int card;
if (!PyArg_ParseTuple(args, "i:get_board_name", &card))
return NULL;
if ((card < 0) || (card >= maxcards))
return NULL;
if(printstats)
fprintf(stderr,"compy get_board_name (%d)\n",card);
return Py_BuildValue("s", comedi_get_board_name(compy_it[card]));
}
/******************************
* compy_get_subdevice_type()
* get the number of subdevices
* args -
* int - board number (0 to maxcards)
* returns the name of the driver for the board
******************************/
static PyObject *
compy_get_subdevice_type( PyObject *self, PyObject *args )
{
int card;
int sub_dev;
if (!PyArg_ParseTuple(args, "ii:get_subdevice_type", &card,&sub_dev))
return NULL;
if ((card < 0) || (card >= maxcards))
return NULL;
if(printstats)
fprintf(stderr,"compy get_subdevice_type (%d)\n",card);
return Py_BuildValue("i", comedi_get_subdevice_type(compy_it[card],sub_dev));
}
/******************************
* compy_get_n_channels()
* get the number of channels on subdevice
* args -
* int - board number (0 to maxcards)
* int - subdevice
* returns number of channels on subdevice
******************************/
static PyObject *
compy_get_n_channels( PyObject *self, PyObject *args )
{
int card;
int sub_dev;
if (!PyArg_ParseTuple(args, "ii", &card, &sub_dev))
return NULL;
if ((card < 0) || (card >= maxcards))
return NULL;
if(printstats)
fprintf(stderr,"compy get_n_channels ( %d, %d)\n",card,sub_dev);
return Py_BuildValue("i", comedi_get_n_channels(compy_it[card],sub_dev));
}
/******************************
* compy_get_maxdata()
* get the maxdata value for a channel
* args -
* int - board number (0 to maxcards)
* int - subdevice number
* int - channel number
* returns maximum sample value for channel (0 on error)
******************************/
static PyObject *
compy_get_maxdata( PyObject *self, PyObject *args )
{
int card;
int sub_dev;
int channel;
if (!PyArg_ParseTuple(args, "iii:maxdata", &card,&sub_dev,&channel))
return NULL;
if ((card < 0) || (card >= maxcards))
return NULL;
if(printstats)
fprintf(stderr,"compy get_maxdata ( %d, %d, %d)\n",card,sub_dev,channel);
return Py_BuildValue("i", comedi_get_maxdata(compy_it[card],sub_dev,channel));
}
/******************************
* compy_get_n_ranges()
* get the number of ranges a channel
* args -
* int - board number (0 to maxcards)
* int - subdevice number
* int - channel number
* returns number of ranges for channel (-1 on error)
******************************/
static PyObject *
compy_get_n_ranges( PyObject *self, PyObject *args )
{
int card;
int sub_dev;
int channel;
if (!PyArg_ParseTuple(args, "iii:get_n_ranges", &card,&sub_dev,&channel))
return NULL;
if ((card < 0) || (card >= maxcards))
return NULL;
if(printstats)
fprintf(stderr,"compy get_n_ranges ( %d, %d, %d)\n",card,sub_dev,channel);
return Py_BuildValue("i", comedi_get_n_ranges(compy_it[card],sub_dev,channel));
}
/******************************
* compy_get_range()
* get the number of ranges a channel
* args -
* int - board number (0 to maxcards)
* int - subdevice number
* int - channel number
* returns range information on channel
* tuple containing
* min value
* max value
* units ( 0-volts, 1-mAmps, 2-none)
******************************/
static PyObject *
compy_get_range( PyObject *self, PyObject *args )
{
comedi_range *rng_p;
int card;
int sub_dev;
int channel;
int range;
if (!PyArg_ParseTuple(args, "iiii:get_range", &card,&sub_dev,&channel,&range))
return NULL;
if ((card < 0) || (card >= maxcards))
return NULL;
if(printstats)
fprintf(stderr,"compy get_n_ranges ( %d, %d, %d, %d)\n",card,sub_dev,channel,range);
if ((rng_p = comedi_get_range(compy_it[card],sub_dev,channel,range))==NULL)
return NULL;
else
return Py_BuildValue("ddi", rng_p->min, rng_p->max, rng_p->unit);
}
/******************************
* compy_to_phys()
* convert sample to physical units
* args -
* int - data
* tuple containing range information
* min value
* max value
* units ( 0-volts, 1-mAmps, 2-none)
* int - maxdata value for channel
* returns physical value (volts) for input
******************************/
static PyObject *
compy_to_phys( PyObject *self, PyObject *args )
{
comedi_range rng;
lsampl_t data;
lsampl_t maxdata;
if (!PyArg_ParseTuple(args, "i(ddi)i:to_phys",
&data,&rng.min,&rng.max,&rng.unit,&maxdata))
return NULL;
if(printstats)
fprintf(stderr,"compy get_to_phys ( %d, %8.3f, %8.3f, %d, %d)\n",
data,rng.min,rng.max,rng.unit,maxdata);
return Py_BuildValue("d",comedi_to_phys(data,&rng, maxdata) );
}
/******************************
* compy_from_phys()
* convert physical units to sample
* args -
* int - data
* tuple containing range information
* min value
* max value
* units ( 0-volts, 1-mAmps, 2-none)
* int - maxdata value for channel
* returns the sample value (0-maxdata)
******************************/
static PyObject *
compy_from_phys( PyObject *self, PyObject *args )
{
comedi_range rng;
double data;
lsampl_t maxdata;
if (!PyArg_ParseTuple(args, "d(ddi)i:from_phys",
&data,&rng.min,&rng.max,&rng.unit,&maxdata))
return NULL;
if(printstats)
fprintf(stderr,"compy get_from_phys ( %8.3f, %8.3f, %8.3f, %d, %d)\n",
data,rng.min,rng.max,rng.unit,maxdata);
return Py_BuildValue("i",comedi_from_phys(data,&rng, maxdata) );
}
/******************************
* compy_data_read()
* read the requested comedi device
* args -
* tuple containing
* int - board number (0 to maxcards)
* int - subdevice number
* int - channel number
* int - range
* int - aref
******************************/
static PyObject *
compy_data_read(PyObject *self, PyObject *args)
{
int card;
int subd, chan;
unsigned int range = 0;
unsigned int aref = 0;
lsampl_t data;
if (!PyArg_ParseTuple(args, "(ii)i|ii:data_read", &card, &subd, &chan,&range,&aref))
return NULL;
if ((card < 0) || (card >= maxcards))
return NULL;
if(debug)
fprintf(stderr,"compy_data_read dev %d subd %d chan %d range %d aref %d\n",card,subd,chan,range,aref);
comedi_data_read(compy_it[card],subd,chan,range,aref,&data);
if(debug)
fprintf(stderr,"comedi_data_read value %d\n",data);
return Py_BuildValue("l", data);
}
#ifdef _COMEDILIB_DEPRECATED
/******************************
* compy_trig()
* read the requested comedi device
* args - a tuple containing
* int - board number (0 to maxcards)
* int - subdevice number
* int - channel number
******************************/
static PyObject *
compy_trig( PyObject *self, PyObject *args )
{
int dev, chan, data;
int card;
if (!PyArg_ParseTuple(args, "(iii)i", &card, &dev, &chan, &data))
return NULL;
if ((card < 0) || (card >= maxcards))
return NULL;
if(printstats)
fprintf(stderr,"compy trig card %d dev %d chanel %d val %d\n",card,dev,chan,data);
trig.subdev=dev;
trig.chanlist[0]=chan;
trig.data[0]=data;
comedi_trigger(compy_it[card],&trig);
return Py_BuildValue("i", trig.data[0]);
}
#endif
static PyObject *
compy_version( PyObject *self, PyObject *args )
{
if(printstats)
fprintf(stderr,"Compy version %d\n",Version);
return Py_BuildValue("i", Version);
}
/* List of functions defined in the module */
static PyMethodDef comedi_methods[] = {
{"open", compy_open, METH_VARARGS},
{"close", compy_close, METH_VARARGS},
{"get_n_subdevices",compy_get_n_subdevices, METH_VARARGS},
{"get_driver_name", compy_get_driver_name, METH_VARARGS},
{"get_board_name", compy_get_board_name, METH_VARARGS},
{"get_subdevice_type",compy_get_subdevice_type, METH_VARARGS},
{"get_n_channels", compy_get_n_channels, METH_VARARGS},
{"get_maxdata", compy_get_maxdata, METH_VARARGS},
{"get_n_ranges", compy_get_n_ranges, METH_VARARGS},
{"get_range", compy_get_range, METH_VARARGS},
#ifdef _COMEDILIB_DEPRECATED
{"trig", compy_trig, METH_VARARGS},
#endif
{"to_phys", compy_to_phys, METH_VARARGS},
{"from_phys", compy_from_phys, METH_VARARGS},
{"data_read", compy_data_read, METH_VARARGS},
{"__version__", compy_version, METH_VARARGS},
{NULL, NULL} /* sentinel */
};
static char comedi_doc[] = "Module to interface comedi library to Python\n";
/* Initialization function for the module (*must* be called initxx) */
DL_EXPORT(void)
initcomedi(void)
{
/* Create the module and add the functions */
(void) Py_InitModule3("comedi", comedi_methods, comedi_doc);
}