Fix comedi_get_cmd_* so that commands are only generated once.

More error messages.
This commit is contained in:
David Schleef 2001-07-15 22:46:02 +00:00
parent 7973a0f2ad
commit beb18635c4
6 changed files with 144 additions and 33 deletions

View file

@ -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;
}

View file

@ -11,32 +11,60 @@
#include <sys/time.h>
#include <string.h>
#include <libinternal.h>
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;
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;
}
int comedi_get_cmd_generic_timed(comedi_t *it,unsigned int s,comedi_cmd *cmd)
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;
}

View file

@ -35,17 +35,17 @@
#include <libinternal.h>
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;
}

View file

@ -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 <ds@stm.lbl.gov>
Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
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

View file

@ -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 ||
errnum>=COMEDI_NOERROR+sizeof(__comedilib_error_strings)
/sizeof(__comedilib_error_strings[0]))
if(errnum<COMEDI_NOERROR || errnum>=COMEDI_NOERROR+n_errors)
return strerror(errnum);
return __comedilib_error_strings[errnum-COMEDI_NOERROR];

View file

@ -32,12 +32,20 @@
#include <fcntl.h>
#include <stdio.h>
#include <comedi_errno.h>
/* 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;
};