- From: Alessandro Paolo Cerruti <apc20_at_cornell.edu>
- Date: Fri, 9 Apr 2004 18:21:38 -0400 (EDT)
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