/* lib/comedi.c comedi library routines COMEDI - Linux Control and Measurement Device Interface Copyright (C) 1997-8 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. 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. */ #include #include #include #include #include #include #include #include #include #include #include #include /* dt282x timer */ static int dt282x_timer(double freq,unsigned int *trigvar,double *actual_freq) { int divider,prescaler; double basefreq=4e6; divider=floor(4e6/(freq)); prescaler=0; while(divider>255){ prescaler++; divider>>=1; basefreq/=2; } if(prescaler==1){ prescaler++; divider>>=1; basefreq/=2; } if(prescaler>=16)return -1; *trigvar=(prescaler<<8)|(255-divider); *actual_freq=basefreq/divider; return 0; } /* dt2814 timer */ static int dt2814_timer(double freq,unsigned int *trigvar,double *actual_freq) { double f; int i; f=1e5; for(i=0;i<8;i++){ if(f-freq32767){ prescaler*=2; divider>>=1; } *trigvar = (prescaler<<16) | divider; *actual_freq=basefreq/(divider*prescaler); return 0; } /* nanosec timer */ static int nanosec_timer(double freq,unsigned int *trigvar,double *actual_freq) { *trigvar=(1e9/freq); *actual_freq=1e9/(*trigvar); return 0; } typedef int (*timerfunc)(double freq,unsigned int *trigvar,double *actual_freq); static timerfunc timer_functions[]={ NULL, dt282x_timer, dt2814_timer, atmio_timer, acl8112_timer, nanosec_timer, }; #define N_TIMERTYPES 6 int comedi_get_timer(comedi_t *it,unsigned int subdev,double freq, unsigned int *trigvar,double *actual_freq) { int timer_type; if(!it || !trigvar || !actual_freq) return -1; timer_type=it->subdevices[subdev].timer_type; if(timer_type==0 || timer_type>=N_TIMERTYPES) return -1; return (timer_functions[timer_type])(freq,trigvar,actual_freq); }