- From: Wim Meeussen <Wim.Meeussen_at_gmx.net>
- Date: Wed, 05 Feb 2003 14:19:53 +0100
Hallo, I am trying to read 6 channels in continuous scan mode, with the ni_mio_common dirver. I'm using the CVS version of comedi form one week ago. My test program runs in kernel space on a x86 machine, 2.4.18 kernel. First I initialise a continuous scan (0.5 Hz). I registered a callback function (CB_EOF) so an interrupt occures after each scan. In the callback function I read the comedi buffer using the cfc_read_array_from_buffer(..) function. I am having the following problems: 1) The first scan only contains 5 samples instead of 6. All the next scans contain 6 samples 2) All the 6 samples I get are samples from channel 0, and none from the 5 other channels. See also the test.c file in attachment. Thanks, Wim
// include
// ------------------------------------------------
#include <linux/comedilib.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <comedi_fc.h>
MODULE_LICENSE("GPL");
EXPORT_NO_SYMBOLS;
// define
// ------------------------------------------------
#define sec_to_nsec(x) ((x)*1000000000)
#define sec_to_usec(x) ((x)*1000000)
#define sec_to_msec(x) ((x)*1000)
#define msec_to_nsec(x) ((x)*1000000)
#define msec_to_usec(x) ((x)*1000)
#define usec_to_nsec(x) ((x)*1000)
#define N_CHANS 6
#define N_SCANS 20
static int n_chans = N_CHANS;
static int n_scans = N_SCANS;
unsigned int chanlist[N_CHANS];
static comedi_t* device;
static int aref;
static int range;
static int channel;
static int subdevice;
// forward declaration
// ------------------------------------------------
void prepare_cmd(comedi_t* dev,comedi_cmd* cmd);
void do_cmd(comedi_t* dev,comedi_cmd* cmd);
int callback(unsigned int i, void* arg);
// init module
// ------------------------------------------------
int init_module(void)
{
comedi_cmd cmd;
int i;
unsigned int chanlist[n_scans];
printk("test_module: init_module()\n");
// open device
device = comedi_open("/dev/comedi0");
// lock device
comedi_lock(device,0);
// register callback function
comedi_register_callback(device,0,COMEDI_CB_EOS,callback,NULL);
// make make chanlist
for ( i=0; i < n_chans; i++ )
chanlist[i]=CR_PACK(channel+i,range,aref);
prepare_cmd(device,&cmd);
do_cmd(device,&cmd);
return 0;
}
// cleanup module
// --------------------------------------------------
int cleanup_module(void)
{
printk("test_module: cleanup_module()\n");
comedi_unlock(device,0);
comedi_cancel(device,0);
comedi_close(device);
return 1;
}
// callback function
// --------------------------------------------------
static sampl_t data[N_CHANS];
static unsigned int ret;
static unsigned int size;
int callback(unsigned int i, void* arg)
{
comedi_subdevice* s;
s = ( (comedi_device*) device )->subdevices;
// read data form comedi buffer
size = sizeof(sampl_t)*N_CHANS;
ret = cfc_read_array_from_buffer( s, data, size );
printk("test -- cb -- read form buffer: %d/%d\n",ret,size);
printk("test -- cb -- data --> %d/%d/%d//%d/%d/%d\n",data[0],data[1],data[2],data[3],data[4],data[5]);
return 0;
}
void do_cmd(comedi_t *dev,comedi_cmd *cmd)
{
int ret;
// check validity of command
ret = comedi_command_test(dev,cmd);
// print validity check return values
printk("command test ret: %d\n",ret);
// execute command
ret = comedi_command(dev,cmd);
// print command return values
printk("execute ret %d\n",ret);
}
void prepare_cmd(comedi_t* dev,comedi_cmd* cmd)
{
// set whole command to 0
memset(cmd,0,sizeof(*cmd));
/* the subdevice that the command is sent to */
cmd->subdev = subdevice;
/* flags */
cmd->flags = 0; //TRIG_WAKE_EOS;
/* each event requires a trigger, which is specified
by a source and an argument. For example, to specify
an external digital line 3 as a source, you would use
src=TRIG_EXT and arg=3. */
/* In this case, we specify using TRIG_NOW to start
* acquisition immediately when the command is issued.
* The argument of TRIG_NOW is "number of nsec after
* NOW", but no driver supports it yet. Also, no driver
* currently supports using a start_src other than
* TRIG_NOW. */
cmd->start_src = TRIG_NOW;
cmd->start_arg = 0;
/* The timing of the beginning of each scan is controlled
* by scan_begin. TRIG_TIMER specifies that scan_start
* events occur periodically at a rate of scan_begin_arg
* nanoseconds between scans. */
cmd->scan_begin_src = TRIG_TIMER;
cmd->scan_begin_arg = msec_to_nsec(500);
/* The timing between each sample in a scan is controlled
* by convert. Like above, TRIG_TIMER specifies that
* convert events occur periodically at a rate of convert_arg
* nanoseconds between scans. */
cmd->convert_src = TRIG_TIMER;
cmd->convert_arg = usec_to_nsec(50);
/* The end of each scan is almost always specified using
* TRIG_COUNT, with the argument being the same as the
* number of channels in the chanlist. You could probably
* find a device that allows something else, but it would
* be strange. */
cmd->scan_end_src = TRIG_COUNT;
cmd->scan_end_arg = n_chans; // number of items in chan_list
/* The end of acquisition is controlled by stop_src and
* stop_arg. The src will typically be TRIG_COUNT or
* TRIG_NONE. Specifying TRIG_COUNT will stop acquisition
* after stop_arg number of scans, or TRIG_NONE will
* cause acquisition to continue until stopped using
* comedi_cancel(). */
cmd->stop_src = TRIG_NONE;
cmd->stop_arg = 0;
/* the channel list determined which channels are sampled.
In general, chanlist_len is the same as scan_end_arg. Most
boards require this. */
cmd->chanlist = chanlist;
cmd->chanlist_len = n_chans;
}
Received on 2003-02-05Z13:19:53