Comedi callback problem using NI_PCIMIO driver

Hello,

My name is Joerg Biedermann and i also don't have much experience using 
comedi. I ran into the same problem like you. I am using comedi-0.7.67, 
comedilib 0.7.21 and RTAI 24.1.12 and a NI-6024E DAQCard.

I've also registered my callback function using
comedi_register_callback, and it was called, but the data was not
placed on the buffer pointed by the cmd.data structure. So I examined 
the source code of the driver (ni_mio_common.c and ni_mio_cs.c) and 
found out, that there is some code missing, which transports the sampled 
values in the cmd.data structure. So i added those lines in the 
ni_mio_common.c:

static void handle_a_interrupt(comedi_device *dev,unsigned short status,
	unsigned int m_status) {

	comedi_subdevice *s=dev->subdevices+0;
	comedi_async *async = s->async;
	comedi_cmd cmd = async->cmd;
	unsigned short ack=0;
	sampl_t *joedata = cmd.data;
	unsigned int chanlen = cmd.chanlist_len;
	int k;

.......
.......
.......
		if(devpriv->aimode==AIMODE_SCAN && status&AI_STOP_St){
		
			ni_handle_fifo_dregs(dev);
	
			for(k=0; k < chanlen; k++) {
				comedi_buf_get(s->async, &joedata[k]);
			}
.......
.......

I don't know if this is the most elegant way, but it seems to work.




Andrés Cascallana Alvarez wrote:

Hello,

My name is Andrés Cascallana, I'm a software developer from Spain. I don't
have much experience using comedi.

I'm currently developing a data logging application based on a NI-6052E
board. I'm using comedi-0.7.67, comedilib-0.7.21 and rtlinux-3.2-pre3 with
kernel 2.4.20.
I've succesfully acquired data from user space using comedi_data_read and
comedi_do_cmd, they work fine using the ni_pcimio driver.

In order to perform real time control, I've  managed to do data acquisition
on kernel space using a rt-linux real time timer. In each period i read the
data from each channel with comedi_data_read, but i think it would be more
appropiate / efficient to use the end of scan event instead, so i've tried
to use the comedi callbacks. I've registered my callback function using
comedi_register_callback, and it seems to be called, but the data is not
placed on the buffer pointed by the cmd.data structure. I'm attaching the
code to this message.

Any help/comments would be greatly appreciated.

Regards,

Andrés Cascallana

/***************************************************************************
*********************************************/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/comedilib.h>
#include <linux/comedidev.h>

#define BUFSIZE 1024

int dev=0;
int subd=0;
int error=0;

int n_chan=16;

#define N_CHANS 256
unsigned int chanlist[N_CHANS];

sampl_t data[BUFSIZE];
comedi_t *dispositivo_comedi;

int do_cmd(void)
{
  int ret,i;

  comedi_cmd cmd;

   /* Set up channel list */
  for(i=0;i<n_chan;i++)
   chanlist[i]=CR_PACK(i,9,AREF_GROUND);

  cmd.subdev = subd;
  cmd.flags = TRIG_WAKE_EOS | TRIG_RT;

  cmd.start_src = TRIG_NOW;
  cmd.start_arg = 0;

  cmd.scan_begin_src = TRIG_TIMER;
  cmd.scan_begin_arg = 500000000;

  cmd.convert_src = TRIG_TIMER;
  cmd.convert_arg = 0;

  cmd.scan_end_src = TRIG_COUNT;
  cmd.scan_end_arg = 1;

  cmd.stop_src = TRIG_NONE;
  cmd.stop_arg = 0;

  cmd.chanlist = chanlist;
  cmd.chanlist_len = n_chan;

  cmd.data=data;
  cmd.data_len=16;

  ret = comedi_command_test(dispositivo_comedi,&cmd);
  printk("1st command test returned %d\n",ret);

  ret = comedi_command_test(dispositivo_comedi,&cmd);
  printk("2nd command test returned %d\n",ret);

  if(ret)
   return ret;

  ret = comedi_command(dispositivo_comedi,&cmd);
  printk("command returned %d\n",ret);

  return ret;
}

static int counter = 0;

int callback(unsigned int i,void *arg)
{
  int j;

  printk("%d:",counter);
  for (j=0;j<n_chan;j++)
   printk("%d ",data[j]);

  printk("\n");
  counter++;

  return 0;
}

#define DEFAULT_COMEDI_MINOR   0  // /dev/comedi0

int init_module(void)
{
  int ret;

  printk("Comedi real-time example #1\n");

  dispositivo_comedi = comedi_open("/dev/comedi0");

  if (dispositivo_comedi==NULL)
  {
   error=1;
   printk("Error en comedi_open.\n");
   return 0;
  }


  ret = comedi_lock(dispositivo_comedi,subd);
  printk("comedi_lock: %d\n",ret);

  if (ret==-1)
  {
   error=1;
   printk("Error en comedilock.\n");
   return 0;
  }



comedi_register_callback(dispositivo_comedi,subd,COMEDI_CB_EOS,callback,NULL
);
  do_cmd();


  printk("Modulo inicializado OK.\n");
  return 0;
}

void cleanup_module(void)
{
  int ret;

  if (error==0)
  {
   ret = comedi_cancel(dispositivo_comedi,subd);
   printk("comedi_cancel: %d\n",ret);

   ret = comedi_unlock(dispositivo_comedi,subd);
   printk("comedi_unlock: %d\n",ret);

   comedi_close(dispositivo_comedi);
   printk("comedi_close:\n");
  }
}

Received on 2004-02-09Z13:55:22