Problems writing data using ni_pcidio

Hi,

I'm trying to output data using the NI_PCIDIO driver ona NI-DIO-32HS (32
bit DIO card) and a modified version of the 4th example from the
documentation posted on the web.  My code will not write the data to the
card--when executed the code returns:

./simulate
Comedi_open: Success
Comedi_lock: Success
Comedi_subdevice: Success
start:      int      0
scan_begin: timer    1000000
convert:    now      0
scan_end:   count    32
stop:       none     0
write: Input/output error

I've tried using the comedi_dio_bitfield and comedi_dio_write functions,
but they also return an error that the Device/resource is busy.

I'm truly lost as to what could be causing the problems.  The code I am
using is posted below.

Thanks for your help!

Alex

#include <stdio.h>
#include <comedilib.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <getopt.h>
#include <ctype.h>
#include <math.h>
#include "examples.h"

double waveform_frequency = 10.0; /* frequency of the sine wave to output */
double amplitude          = 4000; /* peak-to-peak amplitude, in DAC units
(i.e., 0-4095) */
double offset             = 2048; /* offset, in DAC units */

/* This is the size of chunks we deal with when creating and
   outputting data.  This *could* be 1, but that would be
   inefficient */
#define BUF_LEN 4096

int subdevice;
int external_trigger_number = 0;

sampl_t data[BUF_LEN];

void dds_output(sampl_t *buf,int n);
void dds_init(void);

/* This define determines which waveform to use. */
#define dds_init_function dds_init_sine
void dds_init_sine(void);
void dds_init_pseudocycloid(void);
void dds_init_sawtooth(void);

int comedi_internal_trigger(comedi_t *dev, unsigned int subd, unsigned int
trignum)
{
  comedi_insn insn;
  lsampl_t data[1];

  memset(&insn, 0, sizeof(comedi_insn));
  insn.insn = INSN_INTTRIG;
  insn.subdev = subd;
  insn.data = data;
  insn.n = 1;

  data[0] = trignum;

  return comedi_do_insn(dev, &insn);
}


int main(int argc, char *argv[])
{
  comedi_cmd cmd;
  int err;
  int n,m,i;
  int total=0;
  comedi_t *dev;
  //size of next parameter doesn't seem to matter for some odd reason
  unsigned int chanlist[32];
  unsigned int maxdata;
  comedi_range *rng;
  int ret;
  lsampl_t insn_data = 0;
  lsampl_t bits;

  parse_options(argc,argv);

  /* Force n_chan to be 32 (used to be 2) */
  n_chan = 32;

  if(value){ waveform_frequency = value; }

  dev = comedi_open(filename);
  if(dev == NULL){
    fprintf(stderr, "error opening %s\n", filename);
    return -1;
  }

  comedi_perror("Comedi_open");
  //necessary to lock the device?
  comedi_lock(dev,0);

  comedi_perror("Comedi_lock");

  //changed 3rd argument to COMEDI_SUBD_DIO
  subdevice = comedi_find_subdevice_by_type(dev,COMEDI_SUBD_DIO,0);

  comedi_perror("Comedi_subdevice");

  maxdata   = comedi_get_maxdata(dev,subdevice,0);
  rng       = comedi_get_range(dev,subdevice,0,0);
  offset    = (double)comedi_from_phys(0.0,rng,maxdata);
  amplitude = (double)comedi_from_phys(1.0,rng,maxdata) - offset;

  //move this up from below cmd data structure, scan through each chanlist

  for(i=0;i<n_chan;i++){
   chanlist[i]=CR_PACK(channel+i,range,aref);
  }

  memset(&cmd,0,sizeof(cmd));
  /* fill in the command data structure: */
  cmd.subdev         = subdevice;
  cmd.flags          = 0;
  cmd.start_src      = TRIG_INT;
  cmd.start_arg      = 0;
  cmd.scan_begin_src = TRIG_TIMER;
  cmd.scan_begin_arg = 1e9/freq;
  cmd.convert_src    = TRIG_NOW;
  cmd.convert_arg    = 0;
  cmd.scan_end_src   = TRIG_COUNT;
  cmd.scan_end_arg   = n_chan;
  cmd.stop_src       = TRIG_NONE;
  cmd.stop_arg       = 0;

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

  dds_init();

  dds_output(data,BUF_LEN);
  dds_output(data,BUF_LEN);

  dump_cmd(stdout,&cmd);

  if ((err = comedi_command(dev, &cmd)) < 0) {
    comedi_perror("comedi_command");
    return;
  }

  m=write(comedi_fileno(dev),data,BUF_LEN*sizeof(sampl_t));

  if(m<0){
    perror("write");
    exit(1);
    }

  ret = comedi_internal_trigger(dev, subdevice, 0);
  if(ret<0){
    perror("comedi_internal_trigger\n");
    exit(1);
  }

  while(1){
    dds_output(data,BUF_LEN);
    n=BUF_LEN*sizeof(sampl_t);
    while(n>0){
      m=write(comedi_fileno(dev),(void *)data+(BUF_LEN*sizeof(sampl_t)-n),n);
      if(m<0){
        perror("write");
        exit(0);
      }
      printf("m=%d\n",m);
      n-=m;
    }
    total+=BUF_LEN;
  }

  return 0;
}

#define WAVEFORM_SHIFT 16
#define WAVEFORM_LEN (1<<WAVEFORM_SHIFT)
#define WAVEFORM_MASK (WAVEFORM_LEN-1)

sampl_t waveform[WAVEFORM_LEN];

unsigned int acc;
unsigned int adder;

void dds_init(void)
{
  adder=waveform_frequency/freq*(1<<16)*(1<<WAVEFORM_SHIFT);

  dds_init_function();
}

void dds_output(sampl_t *buf,int n)
{
  int i;
  sampl_t *p=buf;


  for(i=0;i<n;i++){
  *p=waveform[(acc>>16)&WAVEFORM_MASK];

  p++;
  acc+=adder;
  }
}


void dds_init_sine(void)
{
  int i;


  for(i=0;i<WAVEFORM_LEN;i++){
    waveform[i]=rint(offset+0.5*amplitude*cos(i*2*M_PI/WAVEFORM_LEN));

  }
}

/* Yes, I know this is not the proper equation for a cycloid.  Fix it. */
void dds_init_pseudocycloid(void)
{
  int i;
  double t;


  for(i=0;i<WAVEFORM_LEN/2;i++){
  t=2*((double)i)/WAVEFORM_LEN;
  waveform[i]=rint(offset+amplitude*sqrt(1-4*t*t));
  }
  for(i=WAVEFORM_LEN/2;i<WAVEFORM_LEN;i++){
  t=2*(1-((double)i)/WAVEFORM_LEN);
  waveform[i]=rint(offset+amplitude*sqrt(1-t*t));
  }

}

void dds_init_sawtooth(void)
{
  int i;


  for(i=0;i<WAVEFORM_LEN;i++){
  waveform[i]=rint(offset+amplitude*((double)i)/WAVEFORM_LEN);

  }
}

Received on 2004-04-09Z21:21:38