Fix comedi_get_cmd_* so that commands are only generated once.
More error messages.
This commit is contained in:
parent
7973a0f2ad
commit
beb18635c4
6 changed files with 144 additions and 33 deletions
17
lib/buffer.c
17
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;
|
||||
}
|
||||
|
||||
|
|
98
lib/cmd.c
98
lib/cmd.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
20
lib/comedi.c
20
lib/comedi.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue