From: David Schleef Date: Sun, 15 Jul 2001 22:46:02 +0000 (+0000) Subject: Fix comedi_get_cmd_* so that commands are only generated once. X-Git-Tag: r0_7_16~17 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=beb18635c4a8af203c2a649a94c220a72fe11b45;p=comedilib.git Fix comedi_get_cmd_* so that commands are only generated once. More error messages. --- diff --git a/lib/buffer.c b/lib/buffer.c index 04e80cb..ef1ff91 100644 --- a/lib/buffer.c +++ b/lib/buffer.c @@ -11,6 +11,7 @@ int comedi_set_buffer_size(comedi_t *it, unsigned int subdev, unsigned int size) bc.subdevice = subdev; bc.size = size; ret = ioctl_bufconfig(it->fd, &bc); + __comedi_errno = errno; if(ret < 0) return ret; return bc.size; @@ -25,6 +26,7 @@ int comedi_set_max_buffer_size(comedi_t *it, unsigned int subdev, unsigned int m bc.subdevice = subdev; bc.maximum_size = max_size; ret = ioctl_bufconfig(it->fd, &bc); + __comedi_errno = errno; if(ret < 0) return ret; return bc.maximum_size; @@ -53,7 +55,8 @@ int comedi_mark_buffer_read(comedi_t *it, unsigned int subdev, unsigned int byte memset(&bi, 0, sizeof(bi)); bi.bytes_read = bytes; ret = ioctl_bufinfo(it->fd, &bi); - if(ret < 0) return ret; + __comedi_errno = errno; + if(__comedi_errno == EINVAL)__comedi_errno = EBUF_OVR; return bi.buf_int_count - bi.buf_user_count; } @@ -67,3 +70,15 @@ int comedi_get_buffer_offset(comedi_t *it, unsigned int subdev) if(ret < 0) return ret; return bi.buf_user_ptr; } + +int comedi_get_front_count(comedi_t *it, unsigned int subdev) +{ + int ret; + comedi_bufinfo bi; + + memset(&bi, 0, sizeof(bi)); + ret = ioctl_bufinfo(it->fd, &bi); + if(ret < 0) return ret; + return bi.buf_int_count; +} + diff --git a/lib/cmd.c b/lib/cmd.c index 676334e..44a4291 100644 --- a/lib/cmd.c +++ b/lib/cmd.c @@ -11,32 +11,60 @@ #include #include +#include -int comedi_get_cmd_src_mask(comedi_t *it,unsigned int s,comedi_cmd *cmd) + +int comedi_get_cmd_src_mask(comedi_t *it,unsigned int subd,comedi_cmd *cmd) { - memset(cmd,0,sizeof(*cmd)); + subdevice *s; + int ret; - cmd->subdev = s; + if(!valid_subd(it,subd))return -1; - cmd->flags = 0; + s=it->subdevices+subd; - cmd->start_src = TRIG_ANY; - cmd->scan_begin_src = TRIG_ANY; - cmd->convert_src = TRIG_ANY; - cmd->scan_end_src = TRIG_ANY; - cmd->stop_src = TRIG_ANY; + if(s->cmd_mask_errno){ + errno = s->cmd_mask_errno; + return -1; + } - return comedi_command_test(it,cmd); -} + if(!s->cmd_mask){ + comedi_cmd *mask; + + mask = malloc(sizeof(comedi_cmd)); + + memset(mask,0,sizeof(*cmd)); + mask->subdev = subd; + mask->flags = 0; + mask->start_src = TRIG_ANY; + mask->scan_begin_src = TRIG_ANY; + mask->convert_src = TRIG_ANY; + mask->scan_end_src = TRIG_ANY; + mask->stop_src = TRIG_ANY; -int comedi_get_cmd_generic_timed(comedi_t *it,unsigned int s,comedi_cmd *cmd) + s->cmd_mask = mask; + + ret = comedi_command_test(it,mask); + if(ret<0){ + s->cmd_mask_errno = errno; + return -1; + } + } + *cmd=*s->cmd_mask; + return 0; +} + +static int __generic_timed(comedi_t *it,unsigned int s, + comedi_cmd *cmd, unsigned int ns) { int ret; ret = comedi_get_cmd_src_mask(it,s,cmd); if(ret<0)return ret; + __comedi_errno = ENOTSUPPORTED; + if(cmd->start_src&TRIG_NOW){ cmd->start_src=TRIG_NOW; cmd->start_arg=0; @@ -44,25 +72,34 @@ int comedi_get_cmd_generic_timed(comedi_t *it,unsigned int s,comedi_cmd *cmd) cmd->start_src=TRIG_FOLLOW; cmd->start_arg=0; }else{ - /* hmmm... don't know what to do */ + DEBUG(3,"can't find good start_src\n"); return -1; } + /* Potential bug: there is a possibility that the source mask may + * have * TRIG_TIMER set for both convert_src and scan_begin_src, + * but they may not be supported together. */ if(cmd->convert_src&TRIG_TIMER){ if(cmd->scan_begin_src&TRIG_FOLLOW){ cmd->convert_src = TRIG_TIMER; + cmd->convert_arg = ns; cmd->scan_begin_src = TRIG_FOLLOW; + cmd->scan_begin_arg = 0; }else{ cmd->convert_src = TRIG_TIMER; + cmd->convert_arg = ns; cmd->scan_begin_src = TRIG_TIMER; + cmd->scan_begin_arg = ns; } }else if(cmd->convert_src & TRIG_NOW && cmd->scan_begin_src & TRIG_TIMER) { cmd->convert_src = TRIG_NOW; + cmd->convert_arg = 0; cmd->scan_begin_src = TRIG_TIMER; + cmd->scan_begin_arg = ns; }else{ - //printf("can't do timed?!?\n"); + DEBUG(3,"comedi_get_cmd_generic_timed: can't do timed?\n"); return -1; } @@ -76,20 +113,51 @@ int comedi_get_cmd_generic_timed(comedi_t *it,unsigned int s,comedi_cmd *cmd) cmd->stop_src=TRIG_NONE; cmd->stop_arg=0; }else{ - printf("can't find a good stop_src\n"); + DEBUG(3,"comedi_get_cmd_generic_timed: can't find a good stop_src\n"); return -1; } cmd->chanlist_len = 1; ret=comedi_command_test(it,cmd); + DEBUG(3,"comedi_get_cmd_generic_timed: test 1 returned %d\n",ret); if(ret==3){ /* good */ ret=comedi_command_test(it,cmd); + DEBUG(3,"comedi_get_cmd_generic_timed: test 2 returned %d\n",ret); } if(ret==4 || ret==0){ + __comedi_errno = 0; return 0; } return -1; } +int comedi_get_cmd_generic_timed(comedi_t *it,unsigned int subd,comedi_cmd *cmd, + unsigned int ns) +{ + subdevice *s; + int ret; + + if(!valid_subd(it,subd))return -1; + + s=it->subdevices+subd; + + if(s->cmd_timed_errno){ + errno = s->cmd_mask_errno; + return -1; + } + + if(!s->cmd_timed){ + s->cmd_timed = malloc(sizeof(comedi_cmd)); + + ret = __generic_timed(it,subd,s->cmd_timed,ns); + if(ret<0){ + s->cmd_mask_errno = errno; + return -1; + } + } + *cmd=*s->cmd_timed; + return 0; +} + diff --git a/lib/comedi.c b/lib/comedi.c index 0f9c5c4..2b7499b 100644 --- a/lib/comedi.c +++ b/lib/comedi.c @@ -35,17 +35,17 @@ #include -int __comedi_init=0; +INTERNAL int __comedi_init=0; -void initialize(void) +INTERNAL void initialize(void) { char *s; __comedi_init=1; if( (s=getenv("COMEDILIB_LOGLEVEL")) ){ - __comedi_loglevel=strtol(s,NULL,10); - fprintf(stderr,"setting loglevel to %d\n",__comedi_loglevel); + __comedi_loglevel=strtol(s,NULL,0); + DEBUG(3,"setting loglevel to %d\n",__comedi_loglevel); } } @@ -111,6 +111,8 @@ int comedi_close(comedi_t *it) }else{ free(s->rangeinfo); } + if(s->cmd_mask)free(s->cmd_mask); + if(s->cmd_timed)free(s->cmd_timed); } if(it->subdevices){ free(it->subdevices); @@ -151,6 +153,11 @@ int comedi_command(comedi_t *it,comedi_cmd *t) int ret; ret = ioctl(it->fd,COMEDI_CMD,t); __comedi_errno = errno; + switch(__comedi_errno){ + case EIO: + __comedi_errno = ECMDNOTSUPP; + break; + } return ret; } @@ -159,6 +166,11 @@ int comedi_command_test(comedi_t *it,comedi_cmd *t) int ret; ret = ioctl(it->fd,COMEDI_CMDTEST,t); __comedi_errno = errno; + switch(__comedi_errno){ + case EIO: + __comedi_errno = ECMDNOTSUPP; + break; + } return ret; } diff --git a/lib/comedi_errno.h b/lib/comedi_errno.h index af31410..04b1574 100644 --- a/lib/comedi_errno.h +++ b/lib/comedi_errno.h @@ -3,21 +3,21 @@ header file for comedi's symbolic error names COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 1997-2000 David A. Schleef + Copyright (C) 1997-2000 David A. Schleef This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + it under the terms of the GNU Lesser General Public License as + ublished by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Cambridge, MA 02111, USA. */ @@ -31,13 +31,15 @@ #endif // define symbolic error names, extensions peculiar to comedi -#define COMEDI_NOERROR 0X1000 +#define COMEDI_NOERROR 0x1000 #define EUNKNOWN (COMEDI_NOERROR + 1) // unknown error -#define EBAD_CT (COMEDI_NOERROR + 2) // bad comedi_t struct +#define EBAD_CT (COMEDI_NOERROR + 2) // bad comedi_t struct #define EINVAL_SUBD (COMEDI_NOERROR + 3) // invalid subdevice #define EINVAL_CHAN (COMEDI_NOERROR + 4) // invalid channel #define EBUF_OVR (COMEDI_NOERROR + 5) // buffer overflow #define EBUF_UNDR (COMEDI_NOERROR + 6) // buffer underflow +#define ECMDNOTSUPP (COMEDI_NOERROR + 7) // command not supported +#define ENOTSUPPORTED (COMEDI_NOERROR + 8) // not supported #endif // _COMEDI_ERRNO_H diff --git a/lib/error.c b/lib/error.c index f92f9a5..3d52c33 100644 --- a/lib/error.c +++ b/lib/error.c @@ -35,7 +35,10 @@ char *__comedilib_error_strings[]={ "Invalid channel", "Buffer overflow", "Buffer underflow", + "Command not supported", + "Not supported", }; +#define n_errors (sizeof(__comedilib_error_strings)/sizeof(void *)) int __comedi_loglevel=1; int __comedi_errno=0; @@ -56,9 +59,7 @@ int comedi_errno(void) char *comedi_strerror(int errnum) { - if(errnum=COMEDI_NOERROR+sizeof(__comedilib_error_strings) - /sizeof(__comedilib_error_strings[0])) + if(errnum=COMEDI_NOERROR+n_errors) return strerror(errnum); return __comedilib_error_strings[errnum-COMEDI_NOERROR]; diff --git a/lib/libinternal.h b/lib/libinternal.h index 7390459..718f67a 100644 --- a/lib/libinternal.h +++ b/lib/libinternal.h @@ -32,12 +32,20 @@ #include #include +#include + + +/* This indicates a symbol that should not be exported as part of + * the library. But I don't know how to make it useful yet. */ +#define INTERNAL + #define debug_ptr(a) if(!(a))fprintf(stderr," ** NULL pointer: " __FILE__ ", line %d\n",__LINE__); #define debug_int(a) if((a)<0)fprintf(stderr," ** error: " __FILE__ ", line %d\n",__LINE__); -#define COMEDILIB_MAGIC 0xc001dafe +#define DEBUG(level,format,args...) do{if(__comedi_loglevel>=(level))fprintf(stderr,__FUNCTION__ ": " format, ## args);}while(0) +#define COMEDILIB_MAGIC 0xc001dafe extern int __comedi_init; extern int __comedi_loglevel; @@ -92,6 +100,11 @@ struct subdevice_struct{ unsigned int has_cmd; unsigned int has_insn_bits; + + int cmd_mask_errno; + comedi_cmd *cmd_mask; + int cmd_timed_errno; + comedi_cmd *cmd_timed; };