Main Page   Class Hierarchy   Alphabetical List   Data Structures   File List   Data Fields   Globals  

dro.c

Go to the documentation of this file.
00001 /*
00002   dro.c
00003 
00004   Modification history:
00005 
00006   12-Jul-2000 WPS put in stupid stuff see FIXME FIXME FIXME.
00007   15-Jun-2000 WPS changed include asm/io.h to sys/io.h for rtlinux_2_2.
00008   12-Apr-2000 WPS forced this file to compile on a SUN.
00009   13-Jan-2000 WPS updated for rtlinux2 :  see etime(),
00010 */
00011 
00012 
00013 #ifdef MAIN
00014 #include <stdio.h>              /* printf(), fflush() */
00015 #include <stdlib.h>             /* exit() */
00016 #include <unistd.h>             /* usleep() */
00017 #endif
00018 
00019 
00020 #include "dro.h"                /* these decls */
00021 
00022 #if defined(linux) || defined(rtlinux)
00023 
00024 #include <linux/version.h>      /* LINUX_VERSION_CODE, KERNEL_VERSION */
00025 
00026 #ifdef DEFINE_EXTERN_BEFORE_IO
00027 /*
00028   Because of a limitation in gcc (present at least in 2.7.2.1 and below), you
00029   _have to_ compile any source code that uses these routines with optimisation
00030   turned on (gcc -O1 or higher), or alternatively #define extern to be
00031   empty before #including <asm/io.h>.
00032   */
00033 #define extern
00034 #endif
00035 
00036 // Pre 2.2 kernels don't seem to have the KERNEL_VERSION macro.
00037 #ifndef KERNEL_VERSION
00038 #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
00039 #endif
00040 
00041 /* outb,inb already included by sys/io.h for 2.2 kernels  */
00042 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,0)
00043 #include <asm/io.h>             /* outb, inb */
00044 #else
00045 #include <sys/io.h>             /* outb, inb */
00046 #endif
00047 
00048 
00049 #ifdef rtlinux_2_0
00050 /*
00051   FIXME FIXME FIXME
00052   Without these next two lines I could not compile on spinerfem. I would
00053  get the following insane errors:
00054  /usr/src/rtlinux-2.0/linux/include/linux/nfs.h:100: storage size of `nfs_program' isn't known
00055  /usr/src/rtlinux-2.0/linux/include/linux/nfs.h:101: storage size of `nfs_rpcstat' isn't known
00056  ...
00057  even though this file has nothing to do with NFS or RPC and nfs.h is not
00058  included. (It doesn't happen on any other systems or even on spinerfem when
00059  compiled for regular linux rather than rtlinux.)
00060 */
00061 struct rpc_program { int i; };
00062 struct rpc_stat { int i; };
00063 #endif
00064 
00065 
00066 #define inportb(port) inb(port)
00067 #define outportb(port,val) outb(val,port)
00068 
00069 #else
00070 
00071 #define inportb(port) (0)
00072 #define outportb(port,val) {printf("outportb(%d (0x%X),%d)\n",port,port,val);}
00073 
00074 #endif
00075 
00076 #define CLOCK_DATA              0x0E
00077 #define CLOCK_SETUP             0x98
00078 #define INPUT_SETUP             0xC1
00079 #define QUAD_X1                 0xA8
00080 #define QUAD_X2                 0xB0
00081 #define QUAD_X4                 0xB8
00082 #define BP_RESET                0x01
00083 #define BP_RESETB               0x81
00084 #define CNTR_RESET              0x02
00085 #define CNTR_RESETB             0x82
00086 #define TRSFRPR_CNTR            0x08
00087 #define TRSFRCNTR_OL            0x90
00088 #define EFLAG_RESET             0x86
00089 #define INDEX_DISABLE           0xE0
00090 
00091 static int BASE7266 = 0x200;
00092 static int Present[4] = {1, 1, 1, 1};
00093 
00094 #define DATA(x) (BASE7266 + (2 * x))
00095 #define CTRL(x) (BASE7266 + (2 * x) + 1)
00096 
00097 /*
00098    LS7266Init()
00099 
00100    Returns char, masked with axes present
00101 */
00102 int LS7266Init()
00103 {
00104   int t;
00105 
00106   for (t = 0; t < 4; t++) {
00107     /* set present flag to true, clear it later if not there */
00108     Present[t] = 1;
00109 
00110     /* if even, initialize chip half */
00111     if (! t % 2) {
00112       outportb(CTRL(t), INDEX_DISABLE);
00113       outportb(CTRL(t), EFLAG_RESET);
00114       outportb(CTRL(t), BP_RESETB);
00115       outportb(DATA(t), CLOCK_DATA);
00116       outportb(CTRL(t), CLOCK_SETUP);
00117       outportb(CTRL(t), INPUT_SETUP);
00118       outportb(CTRL(t), QUAD_X4);
00119       outportb(CTRL(t), CNTR_RESETB);
00120 
00121       outportb(CTRL(t), 184);
00122       outportb(CTRL(t), 135);
00123       outportb(CTRL(t), 133);
00124       outportb(CTRL(t), 131);
00125       outportb(CTRL(t), 193);
00126       outportb(CTRL(t), 224);
00127     }
00128 
00129     /* initialize encoder input */
00130     outportb(CTRL(t), BP_RESET);
00131     outportb(DATA(t), 3 * t + 1);
00132     outportb(DATA(t), 3 * t + 2);
00133     outportb(DATA(t), 3 * t + 3);
00134 
00135     outportb(CTRL(t), TRSFRPR_CNTR);
00136     outportb(CTRL(t), TRSFRCNTR_OL);
00137     outportb(CTRL(t), CNTR_RESET);
00138 
00139     outportb(CTRL(t), BP_RESET);
00140     if (inportb(DATA(t)) != 3 * t + 1) {
00141       Present[t] = 0;
00142     }
00143     if (inportb(DATA(t)) != 3 * t + 2) {
00144       Present[t] = 0;
00145     }
00146     if (inportb(DATA(t)) != 3 * t + 3) {
00147       Present[t] = 0;
00148     }
00149   }
00150 
00151   if (Present[0] || Present[1] || Present[2] || Present[3]) {
00152     return 0;
00153   }
00154 
00155   return -1;
00156 }
00157 
00158 /*
00159   LS7266Read()
00160 */
00161 long LS7266Read(int i)
00162 {
00163   union pos_tag {
00164     long l;
00165     struct byte_tag { char b0; char b1; char b2; char b3;} byte;
00166   } pos;
00167 
00168   outportb(CTRL(i), TRSFRCNTR_OL);
00169   outportb(CTRL(i), BP_RESET);
00170   pos.byte.b0=inportb(DATA(i));
00171   pos.byte.b1=inportb(DATA(i));
00172   pos.byte.b2=inportb(DATA(i));
00173   if (pos.byte.b2 < 0) {
00174     pos.byte.b3 = -1;
00175   }
00176   else {
00177     pos.byte.b3 = 0;
00178   }
00179 
00180   return pos.l;
00181 }
00182 
00183 /*
00184   LS7266Write()
00185 */
00186 void LS7266Write(int i, long in)
00187 {
00188   union pos_tag {
00189     long l;
00190     struct byte_tag { char b0; char b1; char b2; char b3;} byte;
00191   } pos;
00192 
00193   pos.l = in;
00194   outportb(CTRL(i), BP_RESET);
00195   outportb(DATA(i), pos.byte.b0);
00196   outportb(DATA(i), pos.byte.b1);
00197   outportb(DATA(i), pos.byte.b2);
00198   outportb(CTRL(i), TRSFRPR_CNTR);
00199   outportb(CTRL(i), TRSFRCNTR_OL);
00200   outportb(CTRL(i), BP_RESET);
00201 
00202   return;
00203 }
00204 
00205 #ifdef MAIN
00206 
00207 int main(int argc, char *argv[])
00208 {
00209   int t;
00210 
00211   if (argc == 1) {
00212     /* no args, so leave BASE7266 as is */
00213   }
00214   else if (argc == 2) {
00215     if (1 != sscanf(argv[1], "%i", &BASE7266)) {
00216       fprintf(stderr, "invalid board address: %s\n", argv[1]);
00217       exit(1);
00218     }
00219   }
00220   else {
00221     fprintf(stderr, "syntax: %s <address>\n", argv[0]);
00222     exit(1);
00223   }
00224 
00225 #if defined(linux) || defined(rtlinux)
00226   if (0 != ioperm(BASE7266, 8, 1)) {
00227     fprintf(stderr, "can't access 7266 chip-- need to be root\n");
00228     exit(1);
00229   }
00230 #endif
00231 
00232   if (0 != LS7266Init()) {
00233     fprintf(stderr, "no card detected\n");
00234     exit(1);
00235   }
00236 
00237   printf("board detected at 0x%X\n", BASE7266);
00238   printf("axes %c%c%c%c\n",
00239          Present[0] ? 'X' : '-',
00240          Present[1] ? 'Y' : '-',
00241          Present[2] ? 'Z' : '-',
00242          Present[3] ? 'W' : '-');
00243 
00244   while (1) {
00245     for (t = 0; t < 4; t++) {
00246       if (Present[t]) {
00247         printf("%10ld\t", LS7266Read(t));
00248       }
00249       else {
00250         printf("-\t");
00251       }
00252     }
00253     printf("\r");
00254     fflush(stdout);
00255     usleep(10000);
00256   }
00257 
00258   return 0;
00259 }
00260 
00261 #endif /* MAIN */

Generated on Sun Dec 2 15:27:36 2001 for EMC by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001