From 01a017f5151fdb038a5629b63ba878d14baebdda Mon Sep 17 00:00:00 2001 From: David Schleef Date: Thu, 1 Mar 2001 21:57:00 +0000 Subject: [PATCH] 5 new demos cmd uses main.c removal of direct ioctl calls --- demo/Makefile | 16 +-- demo/antialias.c | 5 +- demo/ao_waveform.c | 8 +- demo/cmd.c | 221 +++++++++++++------------------------ demo/dio.c | 19 +++- demo/eeprom_dump.c | 4 +- demo/examples.h | 10 ++ demo/info.c | 23 ---- demo/inp.c | 1 - demo/inpn.c | 1 - demo/insn.c | 19 +--- demo/ledclock.c | 270 +++++++++++++++++++++++++++++++++++++++++++++ demo/main.c | 48 +++++++- demo/mmap.c | 73 +----------- demo/outp.c | 1 - demo/receiver.c | 236 +++++++++++++++++++++++++++++++++++++++ demo/select.c | 227 +++++++++++++++++++++++++++++++++++++ demo/sender.c | 144 ++++++++++++++++++++++++ demo/sigio.c | 242 ++++++++++++++++++++++++++++++++++++++++ demo/sv.c | 1 - 20 files changed, 1295 insertions(+), 274 deletions(-) create mode 100644 demo/ledclock.c create mode 100644 demo/receiver.c create mode 100644 demo/select.c create mode 100644 demo/sender.c create mode 100644 demo/sigio.c diff --git a/demo/Makefile b/demo/Makefile index 5a2d19f..f2fcfc3 100644 --- a/demo/Makefile +++ b/demo/Makefile @@ -2,19 +2,21 @@ CFLAGS += -I ../include -I . -O2 -Wall -Wstrict-prototypes +#CFLAGS += -I ../include -I . -Wall -Wstrict-prototypes -g LDFLAGS = -L../lib/ -lcomedi -lm -BINS=cmd tut1 tut2 -MBINS=inp inpn sv eeprom_dump info outp insn antialias ao_waveform dio mmap +BINS=tut1 tut2 +MBINS=inp inpn sv eeprom_dump info outp insn antialias ao_waveform \ + dio mmap ledclock receiver sigio select sender cmd -all: $(patsubst %,_mbins_%,$(MBINS)) $(patsubst %,_bins_%,$(BINS)) +all: $(BINS) $(MBINS) -$(patsubst %,_mbins_%,$(MBINS)) : main.o $(patsubst %,%.o,$(MBINS)) - $(CC) -o $(patsubst _mbins_%,%,$@) main.o $(patsubst _mbins_%,%.o,$@) $(LDFLAGS) +$(BINS): % : %.o + $(CC) $(LDFLAGS) -o $@ $< -$(patsubst %,_bins_%,$(BINS)) : $(patsubst %,%.o,$(BINS)) - $(CC) -o $(patsubst _bins_%,%,$@) $(patsubst _bins_%,%.o,$@) $(LDFLAGS) +$(MBINS): % : %.o main.o + $(CC) $(LDFLAGS) -o $@ main.o $< clean: -rm -f *.o $(BINS) $(MBINS) diff --git a/demo/antialias.c b/demo/antialias.c index 1a0b127..b3881fd 100644 --- a/demo/antialias.c +++ b/demo/antialias.c @@ -33,16 +33,15 @@ #include #include #include -#include #include #include #include #include "examples.h" -comedi_t *device; - void ao_antialias(unsigned int data); +comedi_t *device; + int main(int argc, char *argv[]) { lsampl_t data; diff --git a/demo/ao_waveform.c b/demo/ao_waveform.c index cef62e6..4edc518 100644 --- a/demo/ao_waveform.c +++ b/demo/ao_waveform.c @@ -37,9 +37,9 @@ * flag. Once you have issued the command, comedi then * expects you to keep the buffer full of data to output * to the DAC. This is done by write(). Since there - * may be a delay between the ioctl() and a subsequent + * may be a delay between the comedi_command() and a subsequent * write(), you should fill the buffer using write() before - * you call ioctl(), as is done here. + * you call comedi_command(), as is done here. * * Also NOTE! The lseek() to offset 1 is used to tell * comedi that you want to write to subdevice 1. This @@ -52,7 +52,6 @@ #include #include #include -#include #include #include #include @@ -142,9 +141,8 @@ int main(int argc, char *argv[]) perror("write"); printf("m=%d\n",m); - if ((err = comedi_command(dev, &cmd)) < 0) { - perror("ioctl"); + comedi_perror("comedi_command"); exit(1); } while(1){ diff --git a/demo/cmd.c b/demo/cmd.c index 33ddb0f..32fe26b 100644 --- a/demo/cmd.c +++ b/demo/cmd.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -30,36 +29,41 @@ #define N_CHANS 16 int subdevice = 0; -int chan=0; +int chan=9; int range = 0; int aref = AREF_GROUND; +int n_chan = 3; double freq = 1000; -#define BUFSZ 1000 +#define BUFSZ 10000 char buf[BUFSZ]; +unsigned int chanlist[N_CHANS]; + +void prepare_cmd_1(comedi_t *dev,comedi_cmd *cmd); +void prepare_cmd_2(comedi_t *dev,comedi_cmd *cmd); -void do_cmd_1(comedi_t *dev); -void do_cmd_2(comedi_t *dev); void do_cmd(comedi_t *dev,comedi_cmd *cmd); void dump_cmd(comedi_cmd *cmd); int main(int argc, char *argv[]) { - char *fn = NULL; comedi_t *dev; + comedi_cmd cmd; - fn = "/dev/comedi0"; + parse_options(argc,argv); - dev = comedi_open(fn); + dev = comedi_open(filename); if(!dev){ - perror(fn); + perror(filename); exit(1); } fcntl(comedi_fileno(dev),F_SETFL,O_NONBLOCK); - do_cmd_1(dev); + prepare_cmd_1(dev,&cmd); + + do_cmd(dev,&cmd); return 0; } @@ -75,43 +79,42 @@ void do_cmd(comedi_t *dev,comedi_cmd *cmd) chanlist = cmd->chanlist; n_chans = cmd->chanlist_len; - ret=ioctl(comedi_fileno(dev),COMEDI_CMDTEST,cmd); + ret=comedi_command_test(dev,cmd); printf("test ret=%d\n",ret); if(ret<0){ printf("errno=%d\n",errno); - perror("ioctl"); + comedi_perror("comedi_command_test"); return; } dump_cmd(cmd); +#if 0 /* restoring the chanlist stuff in this way is only required * for comedi versions before 0.7.56 */ cmd->chanlist = chanlist; cmd->chanlist_len = n_chans; +#endif - ret=ioctl(comedi_fileno(dev),COMEDI_CMDTEST,cmd); + ret=comedi_command_test(dev,cmd); printf("test ret=%d\n",ret); if(ret<0){ printf("errno=%d\n",errno); - comedi_perror("ioctl"); + comedi_perror("comedi_command_test"); return; } dump_cmd(cmd); - cmd->chanlist = chanlist; - cmd->chanlist_len = n_chans; - - ret=ioctl(comedi_fileno(dev),COMEDI_CMD,cmd); + ret=comedi_command(dev,cmd); printf("ret=%d\n",ret); if(ret<0){ printf("errno=%d\n",errno); - comedi_perror("ioctl"); + comedi_perror("comedi_command"); return; } @@ -128,8 +131,20 @@ void do_cmd(comedi_t *dev,comedi_cmd *cmd) }else if(ret==0){ go = 0; }else{ + static int col = 0; + int i; total+=ret; - printf("read %d %d\n",ret,total); + //printf("read %d %d\n",ret,total); +#if 1 + for(i=0;isubdev = subdevice; /* flags */ - cmd.flags = 0; - /* the TRIG_RT flag will ask that the driver's interrupt handler be - * run at hard real time priority if you have a real time OS - */ - //cmd.flags |= TRIG_RT; + cmd->flags = TRIG_WAKE_EOS; + //cmd.flags = 0; /* each event requires a trigger, which is specified by a source and an argument. For example, to specify @@ -168,30 +177,30 @@ void do_cmd_1(comedi_t *dev) * 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; + 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 = 100000; /* in ns */ + cmd->scan_begin_src = TRIG_TIMER; + cmd->scan_begin_arg = 10000000; /* 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 = 10000; /* in ns */ + cmd->convert_src = TRIG_TIMER; + cmd->convert_arg = 10000; /* in ns */ /* 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 = 4; /* number of channels */ + cmd->scan_end_src = TRIG_COUNT; + cmd->scan_end_arg = n_chan; /* number of channels */ /* The end of acquisition is controlled by stop_src and * stop_arg. The src will typically be TRIG_COUNT or @@ -199,125 +208,53 @@ void do_cmd_1(comedi_t *dev) * after stop_arg number of scans, or TRIG_NONE will * cause acquisition to continue until stopped using * comedi_cancel(). */ -#if 1 - cmd.stop_src = TRIG_COUNT; - cmd.stop_arg = 100; -#else - cmd.stop_src = TRIG_NONE; - cmd.stop_arg = 0; -#endif + cmd->stop_src = TRIG_COUNT; + cmd->stop_arg = 10000; /* 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 = 4; - - chanlist[0]=CR_PACK(0,range,aref); - chanlist[1]=CR_PACK(1,range,aref); - chanlist[2]=CR_PACK(2,range,aref); - chanlist[3]=CR_PACK(3,range,aref); + cmd->chanlist = chanlist; + cmd->chanlist_len = n_chan; - do_cmd(dev,&cmd); + chanlist[0]=CR_PACK(chan+0,range,aref); + chanlist[1]=CR_PACK(chan+1,range,aref); + chanlist[2]=CR_PACK(15,range,aref); + chanlist[3]=CR_PACK(chan+3,range,aref); } -void do_cmd_2(comedi_t *dev) +/* + */ +void prepare_cmd_2(comedi_t *dev,comedi_cmd *cmd) { - comedi_cmd cmd; - unsigned int chanlist[4]; - - memset(&cmd,0,sizeof(cmd)); - - /* the subdevice that the command is sent to */ - cmd.subdev = subdevice; - - /* flags */ - cmd.flags = 0; - - /* 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. */ - - cmd.start_src = TRIG_NOW; - cmd.start_arg = 0; - - cmd.scan_begin_src = TRIG_TIMER; - cmd.scan_begin_arg = 1; /* in ns */ - - cmd.convert_src = TRIG_TIMER; - cmd.convert_arg = 1; /* in ns */ - - cmd.scan_end_src = TRIG_COUNT; - cmd.scan_end_arg = 4; /* number of channels */ - -#if 1 - cmd.stop_src = TRIG_COUNT; - cmd.stop_arg = 100; -#else - cmd.stop_src = TRIG_NONE; - cmd.stop_arg = 0; -#endif + memset(cmd,0,sizeof(cmd)); - /* 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 = 4; + cmd->subdev = subdevice; - chanlist[0]=CR_PACK(0,range,aref); - chanlist[1]=CR_PACK(1,range,aref); - chanlist[2]=CR_PACK(2,range,aref); - chanlist[3]=CR_PACK(3,range,aref); + //cmd->flags = TRIG_RT|TRIG_WAKE_EOS; + cmd->flags = 0; - do_cmd(dev,&cmd); -} + cmd->start_src = TRIG_NOW; + cmd->start_arg = 0; -char *cmd_src(int src,char *buf) -{ - buf[0]=0; - - if(src&TRIG_NONE)strcat(buf,"none|"); - if(src&TRIG_NOW)strcat(buf,"now|"); - if(src&TRIG_FOLLOW)strcat(buf, "follow|"); - if(src&TRIG_TIME)strcat(buf, "time|"); - if(src&TRIG_TIMER)strcat(buf, "timer|"); - if(src&TRIG_COUNT)strcat(buf, "count|"); - if(src&TRIG_EXT)strcat(buf, "ext|"); - if(src&TRIG_INT)strcat(buf, "int|"); - - if(strlen(buf)==0){ - sprintf(buf,"unknown(0x%02x)",src); - }else{ - buf[strlen(buf)-1]=0; - } + cmd->scan_begin_src = TRIG_TIMER; + cmd->scan_begin_arg = 1; - return buf; -} - - -void dump_cmd(comedi_cmd *cmd) -{ - char buf[100]; - - printf("start: %s %d\n", - cmd_src(cmd->start_src,buf), - cmd->start_arg); + cmd->convert_src = TRIG_TIMER; + cmd->convert_arg = 1000000; - printf("scan_begin: %s %d\n", - cmd_src(cmd->scan_begin_src,buf), - cmd->scan_begin_arg); + cmd->scan_end_src = TRIG_COUNT; + cmd->scan_end_arg = n_chan; - printf("convert: %s %d\n", - cmd_src(cmd->convert_src,buf), - cmd->convert_arg); + cmd->stop_src = TRIG_NONE; + cmd->stop_arg = 0; - printf("scan_end: %s %d\n", - cmd_src(cmd->scan_end_src,buf), - cmd->scan_end_arg); + cmd->chanlist = chanlist; + cmd->chanlist_len = n_chan; - printf("stop: %s %d\n", - cmd_src(cmd->stop_src,buf), - cmd->stop_arg); + chanlist[0]=CR_PACK(chan+0,range,aref); + chanlist[1]=CR_PACK(chan+1,range,aref); + chanlist[2]=CR_PACK(chan+2,range,aref); + chanlist[3]=CR_PACK(chan+3,range,aref); } diff --git a/demo/dio.c b/demo/dio.c index 2b3bdbc..81f8bf7 100644 --- a/demo/dio.c +++ b/demo/dio.c @@ -18,22 +18,19 @@ #include #include #include -#include #include #include #include #include "examples.h" -comedi_t *device; +comedi_t *device; int main(int argc, char *argv[]) { int ret; int stype; int i; - unsigned int mask; - unsigned int data; parse_options(argc,argv); @@ -55,10 +52,22 @@ int main(int argc, char *argv[]) printf("toggling pin %d rapidly...\n",channel); + comedi_dio_write(device,subdevice,channel,1); +#if 0 for(i=0;i<10000;i++){ + usleep(1000000); comedi_dio_write(device,subdevice,channel,1); + printf("1\n"); + usleep(1000000); comedi_dio_write(device,subdevice,channel,0); + printf("0\n"); } +#endif + +#if 0 + { + unsigned int mask; + unsigned int data; printf("toggling pin %d rapidly (using bitfield)...\n",channel); @@ -69,6 +78,8 @@ int main(int argc, char *argv[]) data = 0; comedi_dio_bitfield(device,subdevice,mask,&data); } + } +#endif return 0; } diff --git a/demo/eeprom_dump.c b/demo/eeprom_dump.c index e4b6510..5403007 100644 --- a/demo/eeprom_dump.c +++ b/demo/eeprom_dump.c @@ -6,18 +6,16 @@ #include #include #include -#include #include #include #include #include #include "examples.h" -comedi_t *device; - int read_eeprom(comedi_t *it,unsigned int **eeprom); void dump_eeprom(unsigned int *eeprom,int len); +comedi_t *device; int main(int argc, char *argv[]) { diff --git a/demo/examples.h b/demo/examples.h index 8d0b2df..41cc3bc 100644 --- a/demo/examples.h +++ b/demo/examples.h @@ -17,6 +17,16 @@ extern int aref; extern int range; int parse_options(int argc, char *argv[]); +char *cmd_src(int src,char *buf); +void dump_cmd(comedi_cmd *cmd); + + +#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) #endif diff --git a/demo/info.c b/demo/info.c index a597556..bc99af1 100644 --- a/demo/info.c +++ b/demo/info.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include "examples.h" @@ -118,28 +117,6 @@ char *tobinary(char *s,int bits,int n) return s; } -char *cmd_src(int src,char *buf) -{ - buf[0]=0; - - if(src&TRIG_NONE)strcat(buf,"none|"); - if(src&TRIG_NOW)strcat(buf,"now|"); - if(src&TRIG_FOLLOW)strcat(buf,"follow|"); - if(src&TRIG_TIME)strcat(buf,"time|"); - if(src&TRIG_TIMER)strcat(buf,"timer|"); - if(src&TRIG_COUNT)strcat(buf,"count|"); - if(src&TRIG_EXT)strcat(buf,"ext|"); - if(src&TRIG_INT)strcat(buf,"int|"); - - if(strlen(buf)==0){ - sprintf(buf,"unknown(0x%02x)",src); - }else{ - buf[strlen(buf)-1]=0; - } - - return buf; -} - void probe_max_1chan(comedi_t *it,int s); int comedi_get_cmd_src_mask(comedi_t *it,unsigned int s,comedi_cmd *cmd) diff --git a/demo/inp.c b/demo/inp.c index 391a43e..02425a6 100644 --- a/demo/inp.c +++ b/demo/inp.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/demo/inpn.c b/demo/inpn.c index e503d27..f855eb2 100644 --- a/demo/inpn.c +++ b/demo/inpn.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/demo/insn.c b/demo/insn.c index 9c3cfb0..96a1c10 100644 --- a/demo/insn.c +++ b/demo/insn.c @@ -13,8 +13,9 @@ Using instructions directly, as in this example, is not recommended for the beginner. Use the higher-level functions such as - comedi_data_read(), comedi_data_write(), etc. Then, if you - need the additional flexibility that using instructions directly + comedi_data_read(), comedi_data_write(), etc., as demonstrated + in the inp, outp, and dio examples. Then, if you need the + additional flexibility that using instructions directly provides, study this example and the implementations of comedi_data_read(), etc. */ @@ -23,24 +24,21 @@ #include #include #include -#include #include #include #include #include "examples.h" -comedi_t *device; - - /* * This example does 3 instructions in one system call. It does * a gettimeofday() call, then reads N_SAMPLES samples from an * analog input, and the another gettimeofday() call. - * */ #define N_SAMPLES 1 +comedi_t *device; + int main(int argc, char *argv[]) { int ret,i; @@ -73,7 +71,6 @@ int main(int argc, char *argv[]) insn[0].n=2; insn[0].data=(void *)&t1; -//#if 0 /* Instruction 1: do 10 analog input reads */ insn[1].insn=INSN_READ; insn[1].n=N_SAMPLES; @@ -85,12 +82,6 @@ int main(int argc, char *argv[]) insn[2].insn=INSN_GTOD; insn[2].n=2; insn[2].data=(void *)&t2; -//#endif -#if 0 - insn[1].insn=INSN_GTOD; - insn[1].n=2; - insn[1].data=(void *)&t2; -#endif ret=comedi_do_insnlist(device,&il); if(ret<0){ diff --git a/demo/ledclock.c b/demo/ledclock.c new file mode 100644 index 0000000..673f0c4 --- /dev/null +++ b/demo/ledclock.c @@ -0,0 +1,270 @@ +/* + * Digital I/O example + * Part of Comedilib + * + * Copyright (c) 1999,2000 David A. Schleef + * + * This file may be freely modified, distributed, and combined with + * other software, as long as proper attribution is given in the + * source code. + */ +/* + * Requirements: A board with a digital I/O subdevice. Not just + * a 'digital input' or 'digital output' subdevice, but one in + * which the channels can be configured between input and output. + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "examples.h" + + +comedi_t *device; + +int count; + +int out_subd; + +#define BUFSZ 1024 +sampl_t buf[BUFSZ]; + +unsigned int chanlist[16]; + + +void prepare_cmd(comedi_t *dev,comedi_cmd *cmd); +void do_cmd(comedi_t *dev,comedi_cmd *cmd); +void do_toggle(void); + + +void config_output(void) +{ + int i; + + for(i=0;i<8;i++){ + comedi_dio_config(device,out_subd,i,COMEDI_OUTPUT); + } +} + +void do_toggle(void) +{ +#if 1 + comedi_insnlist il; + comedi_insn insn[3]; + lsampl_t data[6]; + int mask = 0xff; + + count++; + + il.n_insns = 3; + il.insns = insn; + + memset(insn,0,3*sizeof(comedi_insn)); + + insn[0].insn = INSN_BITS; + insn[0].n = 2; + insn[0].data = data+0; + insn[0].subdev = out_subd; + + data[0] = mask; + //data[1] = count; + data[1] = 0xfc; + + insn[1].insn = INSN_WAIT; + insn[1].n = 1; + insn[1].data = data+2; + + data[2] = 100000-1; + + insn[2].insn = INSN_BITS; + insn[2].n = 2; + insn[2].data = data+4; + insn[2].subdev = out_subd; + + data[4] = mask; + //data[5] = count; + data[5] = 0xff; + + comedi_do_insnlist(device,&il); +#else + unsigned int data; + unsigned int mask = 0xff; + + count++; + data = count; + + comedi_dio_bitfield(device,out_subd,mask,&data); +#endif +} + +int main(int argc, char *argv[]) +{ + char *fn = NULL; + int ret; + comedi_cmd cmd; + + fn = "/dev/comedi0"; + + device = comedi_open(fn); + if(!device){ + perror(fn); + exit(1); + } + + subdevice = 0; + out_subd = 2; + + config_output(); + + ret = fcntl(comedi_fileno(device),F_SETFL,O_NONBLOCK|O_ASYNC); + if(ret<0)perror("fcntl"); + + ret = fcntl(comedi_fileno(device),F_SETSIG,SIGIO); + if(ret<0)perror("fcntl"); + +#if 0 + { + struct sched_param p; + + memset(&p,0,sizeof(p)); + p.sched_priority = 1; + ret = sched_setscheduler(0,SCHED_FIFO,&p); + if(ret<0)perror("sched_setscheduler"); + } +#endif + + prepare_cmd(device,&cmd); + + do_cmd(device,&cmd); + + return 0; +} + +void do_cmd(comedi_t *dev,comedi_cmd *cmd) +{ + int total=0; + int ret; + int go; + fd_set rdset; + struct timeval timeout; + + ret=comedi_command_test(dev,cmd); + + printf("test ret=%d\n",ret); + if(ret<0){ + printf("errno=%d\n",errno); + comedi_perror("comedi_command_test"); + return; + } + + dump_cmd(cmd); + + ret=comedi_command_test(dev,cmd); + + printf("test ret=%d\n",ret); + if(ret<0){ + printf("errno=%d\n",errno); + comedi_perror("comedi_command_test"); + return; + } + + dump_cmd(cmd); + + ret=comedi_command(dev,cmd); + + printf("ret=%d\n",ret); + if(ret<0){ + printf("errno=%d\n",errno); + comedi_perror("comedi_command"); + return; + } + + go=1; + while(go){ + FD_ZERO(&rdset); + FD_SET(comedi_fileno(dev),&rdset); + timeout.tv_sec = 0; + timeout.tv_usec = 50000; + ret = select(comedi_fileno(dev)+1,&rdset,NULL,NULL,&timeout); + if(ret<0){ + perror("select"); + }else if(ret==0){ + /* timeout */ + }else if(FD_ISSET(comedi_fileno(dev),&rdset)){ + ret=read(comedi_fileno(dev),buf,BUFSZ); + if(ret<0){ + if(errno==EAGAIN){ + go = 0; + perror("read"); + } + }else if(ret==0){ + go = 0; + }else{ + //int i; + + total+=ret; + //printf("read %d %d\n",ret,total); + //printf("count = %d\n",count); + do_toggle(); +#if 0 + for(i=0;isubdev = subdevice; + + /* flags */ + cmd->flags = TRIG_WAKE_EOS; + + cmd->start_src = TRIG_NOW; + cmd->start_arg = 0; + + cmd->scan_begin_src = TRIG_EXT; + cmd->scan_begin_arg = (1<<31); + +#if 1 + cmd->convert_src = TRIG_TIMER; + cmd->convert_arg = 1; +#else + cmd->convert_src = TRIG_ANY; + cmd->convert_arg = 0; +#endif + + 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 = 1; + + chanlist[0]=CR_PACK(0,0,0); +} + diff --git a/demo/main.c b/demo/main.c index 0c9ab46..d3e302e 100644 --- a/demo/main.c +++ b/demo/main.c @@ -7,17 +7,16 @@ #include #include #include -#include #include #include #include #include +#include #include "examples.h" char *filename="/dev/comedi0"; int verbose_flag; -comedi_t *device; int value; int subdevice; @@ -76,5 +75,50 @@ int parse_options(int argc, char *argv[]) return argc; } +char *cmd_src(int src,char *buf) +{ + buf[0]=0; + + if(src&TRIG_NONE)strcat(buf,"none|"); + if(src&TRIG_NOW)strcat(buf,"now|"); + if(src&TRIG_FOLLOW)strcat(buf, "follow|"); + if(src&TRIG_TIME)strcat(buf, "time|"); + if(src&TRIG_TIMER)strcat(buf, "timer|"); + if(src&TRIG_COUNT)strcat(buf, "count|"); + if(src&TRIG_EXT)strcat(buf, "ext|"); + if(src&TRIG_INT)strcat(buf, "int|"); + + if(strlen(buf)==0){ + sprintf(buf,"unknown(0x%02x)",src); + }else{ + buf[strlen(buf)-1]=0; + } + return buf; +} + +void dump_cmd(comedi_cmd *cmd) +{ + char buf[100]; + + printf("start: %s %d\n", + cmd_src(cmd->start_src,buf), + cmd->start_arg); + + printf("scan_begin: %s %d\n", + cmd_src(cmd->scan_begin_src,buf), + cmd->scan_begin_arg); + + printf("convert: %s %d\n", + cmd_src(cmd->convert_src,buf), + cmd->convert_arg); + + printf("scan_end: %s %d\n", + cmd_src(cmd->scan_end_src,buf), + cmd->scan_end_arg); + + printf("stop: %s %d\n", + cmd_src(cmd->stop_src,buf), + cmd->stop_arg); +} diff --git a/demo/mmap.c b/demo/mmap.c index 55d6d67..19f80a7 100644 --- a/demo/mmap.c +++ b/demo/mmap.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -45,7 +44,6 @@ sampl_t *map; void do_cmd_1(comedi_t *dev); void do_cmd_2(comedi_t *dev); void do_cmd(comedi_t *dev,comedi_cmd *cmd); -void dump_cmd(comedi_cmd *cmd); int main(int argc, char *argv[]) { @@ -72,50 +70,39 @@ int main(int argc, char *argv[]) void do_cmd(comedi_t *dev,comedi_cmd *cmd) { - unsigned int *chanlist; - int n_chans; int total=0; int ret; int go; int i; - chanlist = cmd->chanlist; - n_chans = cmd->chanlist_len; - - ret=ioctl(comedi_fileno(dev),COMEDI_CMDTEST,cmd); + ret = comedi_command_test(dev,cmd); printf("test ret=%d\n",ret); if(ret<0){ printf("errno=%d\n",errno); - perror("ioctl"); + comedi_perror("comedi_command_test"); return; } dump_cmd(cmd); - cmd->chanlist = chanlist; - cmd->chanlist_len = n_chans; - - ret=ioctl(comedi_fileno(dev),COMEDI_CMDTEST,cmd); + ret = comedi_command_test(dev,cmd); printf("test ret=%d\n",ret); if(ret<0){ printf("errno=%d\n",errno); - comedi_perror("ioctl"); + comedi_perror("comedi_command_test"); return; } dump_cmd(cmd); - cmd->chanlist = chanlist; - cmd->chanlist_len = n_chans; - - ret=ioctl(comedi_fileno(dev),COMEDI_CMD,cmd); + ret = comedi_command(dev,cmd); printf("ret=%d\n",ret); if(ret<0){ printf("errno=%d\n",errno); - comedi_perror("ioctl"); + comedi_perror("comedi_command"); return; } @@ -277,51 +264,3 @@ void do_cmd_2(comedi_t *dev) do_cmd(dev,&cmd); } -char *cmd_src(int src,char *buf) -{ - buf[0]=0; - - if(src&TRIG_NONE)strcat(buf,"none|"); - if(src&TRIG_NOW)strcat(buf,"now|"); - if(src&TRIG_FOLLOW)strcat(buf, "follow|"); - if(src&TRIG_TIME)strcat(buf, "time|"); - if(src&TRIG_TIMER)strcat(buf, "timer|"); - if(src&TRIG_COUNT)strcat(buf, "count|"); - if(src&TRIG_EXT)strcat(buf, "ext|"); - if(src&TRIG_INT)strcat(buf, "int|"); - - if(strlen(buf)==0){ - sprintf(buf,"unknown(0x%02x)",src); - }else{ - buf[strlen(buf)-1]=0; - } - - return buf; -} - - -void dump_cmd(comedi_cmd *cmd) -{ - char buf[100]; - - printf("start: %s %d\n", - cmd_src(cmd->start_src,buf), - cmd->start_arg); - - printf("scan_begin: %s %d\n", - cmd_src(cmd->scan_begin_src,buf), - cmd->scan_begin_arg); - - printf("convert: %s %d\n", - cmd_src(cmd->convert_src,buf), - cmd->convert_arg); - - printf("scan_end: %s %d\n", - cmd_src(cmd->scan_end_src,buf), - cmd->scan_end_arg); - - printf("stop: %s %d\n", - cmd_src(cmd->stop_src,buf), - cmd->stop_arg); -} - diff --git a/demo/outp.c b/demo/outp.c index 1300199..6fafef7 100644 --- a/demo/outp.c +++ b/demo/outp.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/demo/receiver.c b/demo/receiver.c new file mode 100644 index 0000000..1aae47c --- /dev/null +++ b/demo/receiver.c @@ -0,0 +1,236 @@ +/* + * Digital I/O example + * Part of Comedilib + * + * Copyright (c) 1999,2000 David A. Schleef + * + * This file may be freely modified, distributed, and combined with + * other software, as long as proper attribution is given in the + * source code. + */ +/* + * Requirements: A board with a digital I/O subdevice. Not just + * a 'digital input' or 'digital output' subdevice, but one in + * which the channels can be configured between input and output. + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "examples.h" + +int pin_clk = 2; +int pin_data = 10; + +comedi_t *device; + +#define BUFSZ 1024 +sampl_t buf[BUFSZ]; + +void prepare_cmd(comedi_t *dev,comedi_cmd *cmd); +void do_cmd(comedi_t *dev,comedi_cmd *cmd); + +int main(int argc, char *argv[]) +{ + char *fn = NULL; + comedi_t *dev; + comedi_cmd cmd; + int ret; + + parse_options(argc,argv); + + //fn = "/dev/comedi1"; + fn = "/dev/comedi0"; + + dev = comedi_open(fn); + if(!dev){ + perror(fn); + exit(1); + } + device = dev; + + subdevice = 0; + + if(channel)pin_data=channel; + + ret = fcntl(comedi_fileno(dev),F_SETFL,O_NONBLOCK); + if(ret<0)perror("fcntl"); + + prepare_cmd(dev,&cmd); + + do_cmd(dev,&cmd); + + return 0; +} + +static int c=0; +static unsigned int bits =0; + +void do_cmd(comedi_t *dev,comedi_cmd *cmd) +{ + unsigned int *chanlist; + int n_chans; + int total=0; + int ret; + int go; + struct timeval timeout; + fd_set rdset; + + chanlist = cmd->chanlist; + n_chans = cmd->chanlist_len; + + ret=comedi_command_test(dev,cmd); + + //printf("test ret=%d\n",ret); + if(ret<0){ + printf("errno=%d\n",errno); + comedi_perror("comedi_command_test"); + return; + } + + dump_cmd(cmd); + + cmd->chanlist = chanlist; + cmd->chanlist_len = n_chans; + + ret=comedi_command_test(dev,cmd); + + printf("test ret=%d\n",ret); + if(ret<0){ + printf("errno=%d\n",errno); + comedi_perror("comedi_command_test"); + return; + } + + dump_cmd(cmd); + + cmd->chanlist = chanlist; + cmd->chanlist_len = n_chans; + + ret=comedi_command(dev,cmd); + + printf("ret=%d\n",ret); + if(ret<0){ + printf("errno=%d\n",errno); + comedi_perror("comedi_command"); + return; + } + + go=1; + while(go){ + FD_ZERO(&rdset); + FD_SET(comedi_fileno(dev),&rdset); + timeout.tv_sec=0; + timeout.tv_usec=50000; + ret = select(comedi_fileno(dev)+1,&rdset,NULL,NULL,&timeout); + if(ret<0){ + perror("select"); + }else if(ret==0){ + if(c){ + fprintf(stderr,"\n"); + c=0; + bits=0; + } + }else if(FD_ISSET(comedi_fileno(dev),&rdset)){ + ret=read(comedi_fileno(dev),buf,BUFSZ); + if(ret<0){ + if(errno==EAGAIN){ + go = 0; + perror("read"); + } + }else if(ret==0){ + go = 0; + }else{ + int i; + + total+=ret; + for(i=0;i0xa000); + c++; + if(c>=32){ + fprintf(stderr,"\n"); + c=0; + } +#if 0 + //printf("%d %d\n",buf[i],buf[i]>0xa000); + //printf("%d",buf[i]>0xa000); + bits<<=1; + bits|=(buf[i]>0xa000); + c++; + if(c>=33){ +#if 0 + struct timeval now; + + gettimeofday(&now,NULL); + printf(" %08x %ld.%06ld\n",bits,now.tv_sec,now.tv_usec); + c=0; + bits=0; +#else + printf(" %08x\n",bits); + c=0; + bits=0; +#endif + } + if(!bits)c=0; +#endif + } + fflush(stdout); + fflush(stderr); + } + } + } +} + +unsigned int chanlist[16]; +/* + * This part of the demo measures channels 1, 2, 3, 4 at a rate of + * 10 khz, with the inter-sample time at 10 us (100 khz). The number + * of scans measured is 10. This is analogous to the old mode2 + * acquisition. + */ +void prepare_cmd(comedi_t *dev,comedi_cmd *cmd) +{ + memset(cmd,0,sizeof(comedi_cmd)); + + /* the subdevice that the command is sent to */ + cmd->subdev = subdevice; + + /* flags */ + cmd->flags = TRIG_WAKE_EOS; + + cmd->start_src = TRIG_NOW; + cmd->start_arg = 0; + + cmd->scan_begin_src = TRIG_EXT; + cmd->scan_begin_arg = (1<<31)|(1<<30)|pin_clk; + +#if 1 + cmd->convert_src = TRIG_TIMER; + cmd->convert_arg = 1; +#else + cmd->convert_src = TRIG_ANY; + cmd->convert_arg = 0; +#endif + + 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 = 1; + + chanlist[0]=CR_PACK(pin_data,0,0); +} + diff --git a/demo/select.c b/demo/select.c new file mode 100644 index 0000000..5e59c98 --- /dev/null +++ b/demo/select.c @@ -0,0 +1,227 @@ +/* + * selet.c - Example of using select() with Comedi + * Part of Comedilib + * + * Copyright (c) 1999,2000 David A. Schleef + * + * This file may be freely modified, distributed, and combined with + * other software, as long as proper attribution is given in the + * source code. + */ + +/* + * An example for using select() with asynchronous input. This + * example requires an asynchronous input subdevice that can + * handle TRIG_TIMER as a scan_begin_src. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "examples.h" + +#define N_SCANS 10 +#define N_CHANS 16 + +double freq = 1000; + +#define BUFSZ 1000 +sampl_t buf[BUFSZ]; + +int n_chans = 1; +int n_scans = 10; + +unsigned int chanlist[4]; + +comedi_t *device; + +void prepare_cmd(comedi_t *dev,comedi_cmd *cmd); +void do_cmd(comedi_t *dev,comedi_cmd *cmd); + +#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) + +int main(int argc, char *argv[]) +{ + comedi_cmd cmd; + int i; + + parse_options(argc,argv); + + device = comedi_open(filename); + if(!device){ + perror(filename); + exit(1); + } + + fcntl(comedi_fileno(device),F_SETFL,O_NONBLOCK); + + for(i=0;isubdev = subdevice; + + /* flags */ + cmd->flags = TRIG_WAKE_EOS; + //cmd.flags = 0; + + /* 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(100); + + /* 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 = msec_to_nsec(1); + + /* 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 channels */ + + /* 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_COUNT; + cmd->stop_arg = n_scans; + + /* 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; +} + diff --git a/demo/sender.c b/demo/sender.c new file mode 100644 index 0000000..97279e2 --- /dev/null +++ b/demo/sender.c @@ -0,0 +1,144 @@ +/* + * Digital I/O example + * Part of Comedilib + * + * Copyright (c) 1999,2000 David A. Schleef + * + * This file may be freely modified, distributed, and combined with + * other software, as long as proper attribution is given in the + * source code. + */ +/* + * Requirements: A board with a digital I/O subdevice. Not just + * a 'digital input' or 'digital output' subdevice, but one in + * which the channels can be configured between input and output. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "examples.h" + + +int chan_dat = 1; +int chan_clk = 0; + +int wait1 = usec_to_nsec(0); +int wait2 = usec_to_nsec(0); + +comedi_t *device; + +void write_bits(int bits); + + +int main(int argc, char *argv[]) +{ + int ret; + int stype; + int i; + + parse_options(argc,argv); + + device=comedi_open(filename); + if(!device){ + comedi_perror(filename); + exit(0); + } + + subdevice = 2; + + stype = comedi_get_subdevice_type(device,subdevice); + if(stype!=COMEDI_SUBD_DIO){ + printf("%d is not a digital I/O subdevice\n",subdevice); + exit(0); + } + + printf("configuring pin %d for output...\n",chan_dat); + ret=comedi_dio_config(device,subdevice,chan_dat,COMEDI_OUTPUT); + + printf("configuring pin %d for output...\n",chan_clk); + ret=comedi_dio_config(device,subdevice,chan_clk,COMEDI_OUTPUT); + + for(i=0;i<0x100;i++){ + write_bits(i); + } + //write_bits(0xa5); + + return 0; +} + + +void write_bits(int bits) +{ + comedi_insnlist il; + comedi_insn insn[5]; + lsampl_t data[10]; + int mask = (1< + * + * This file may be freely modified, distributed, and combined with + * other software, as long as proper attribution is given in the + * source code. + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "examples.h" + +comedi_t *device; + + +void print_time(void); + +void sigio_handler(int sig,siginfo_t *si,void *x) +{ + print_time(); +} + +void print_time(void) +{ + struct timeval tv; + static struct timeval oldtime={0}; + int dsec,dusec; + + gettimeofday(&tv,NULL); + + dsec=tv.tv_sec-oldtime.tv_sec; + dusec=tv.tv_usec-oldtime.tv_usec; + if(dusec<0){ + dsec--; + dusec+=1000000; + } + printf("%d.%06d +%d.%06d\n",(int)tv.tv_sec,(int)tv.tv_usec,dsec,dusec); + + oldtime=tv; +} + +int out_subd; + +void config_output(void) +{ + int i; + + for(i=0;i<8;i++){ + comedi_dio_config(device,out_subd,i,COMEDI_OUTPUT); + } +} + +int count; + +#define BUFSZ 1024 +sampl_t buf[BUFSZ]; + +void do_cmd_1(comedi_t *dev); +void do_cmd_2(comedi_t *dev); +void do_cmd(comedi_t *dev,comedi_cmd *cmd); + +int main(int argc, char *argv[]) +{ + char *fn = NULL; + comedi_t *dev; + struct sigaction sa; + int ret; + sigset_t sigset; + int flags; + + //fn = "/dev/comedi1"; + fn = "/dev/comedi0"; + + dev = comedi_open(fn); + if(!dev){ + perror(fn); + exit(1); + } + device = dev; + + subdevice = 0; + out_subd = 2; + + config_output(); + + fcntl(comedi_fileno(dev),F_SETOWN,getpid()); + flags = fcntl(comedi_fileno(dev),F_GETFL); + ret = fcntl(comedi_fileno(dev),F_SETFL,flags|O_ASYNC); + //ret = fcntl(comedi_fileno(dev),F_SETFL,O_NONBLOCK|O_ASYNC); + if(ret<0)perror("fcntl"); + + memset(&sa,0,sizeof(sa)); + sa.sa_sigaction = &sigio_handler; + sa.sa_flags = SA_SIGINFO; + ret = sigaction(SIGIO,&sa,NULL); + if(ret<0)perror("sigaction"); + + ret = fcntl(comedi_fileno(dev),F_SETSIG,SIGIO); + if(ret<0)perror("fcntl"); + + sigemptyset(&sigset); + sigaddset(&sigset,SIGIO); + ret = sigprocmask(SIG_UNBLOCK,&sigset,NULL); + if(ret<0)perror("sigprocmask"); + +#if 0 + { + struct sched_param p; + memset(&p,0,sizeof(p)); + p.sched_priority = 1; + ret = sched_setscheduler(0,SCHED_FIFO,&p); + if(ret<0)perror("sched_setscheduler"); + } +#endif + + do_cmd_1(dev); + + return 0; +} + +void do_cmd(comedi_t *dev,comedi_cmd *cmd) +{ + int total=0; + int ret; + int go; + + ret=comedi_command_test(dev,cmd); + + printf("test ret=%d\n",ret); + if(ret<0){ + printf("errno=%d\n",errno); + comedi_perror("comedi_command_test"); + return; + } + + dump_cmd(cmd); + + ret=comedi_command_test(dev,cmd); + + printf("test ret=%d\n",ret); + if(ret<0){ + printf("errno=%d\n",errno); + comedi_perror("comedi_command_test"); + return; + } + + dump_cmd(cmd); + + ret=comedi_command(dev,cmd); + + printf("ret=%d\n",ret); + if(ret<0){ + printf("errno=%d\n",errno); + comedi_perror("comedi_command"); + return; + } + + go=1; + while(go){ + ret=read(comedi_fileno(dev),buf,BUFSZ); + if(ret<0){ + if(errno==EAGAIN){ + printf("EAGAIN\n"); + usleep(10000); + }else{ + go = 0; + perror("read"); + } + }else if(ret==0){ + go = 0; + }else{ + //int i; + + total+=ret; + //printf("read %d %d\n",ret,total); + //printf("count = %d\n",count); + //print_time(); + } + } +} + +unsigned int chanlist[0]; +/* + * This part of the demo measures channels 1, 2, 3, 4 at a rate of + * 10 khz, with the inter-sample time at 10 us (100 khz). The number + * of scans measured is 10. This is analogous to the old mode2 + * acquisition. + */ +void do_cmd_1(comedi_t *dev) +{ + comedi_cmd cmd; + + memset(&cmd,0,sizeof(cmd)); + + /* the subdevice that the command is sent to */ + cmd.subdev = subdevice; + + /* flags */ + cmd.flags = TRIG_WAKE_EOS; + + cmd.start_src = TRIG_NOW; + cmd.start_arg = 0; + + cmd.scan_begin_src = TRIG_TIMER; + cmd.scan_begin_arg = msec_to_nsec(100); + +#if 1 + cmd.convert_src = TRIG_TIMER; + cmd.convert_arg = 1; +#else + cmd.convert_src = TRIG_ANY; + cmd.convert_arg = 0; +#endif + + 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 = 1; + + chanlist[0]=CR_PACK(0,0,0); + + do_cmd(dev,&cmd); +} + diff --git a/demo/sv.c b/demo/sv.c index 7ebecbb..14c7c43 100644 --- a/demo/sv.c +++ b/demo/sv.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include -- 2.26.2