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

ppmc_internal.c

Go to the documentation of this file.
00001 //internal low level functions
00002 //this is for 
00003 //parport related functions
00004 #include "ppmc.h"
00005 
00006 #ifdef RTLINUX
00007 #ifndef MODULE
00008 #define MODULE
00009 #endif
00010 #define DO_IT
00011 #endif
00012 
00013 
00014 #ifdef LINUX
00015 #define DO_IT
00016 /*
00017   Compiling this for LINUX (not RTLINUX) means linking this into a Linux
00018   process, running non-real-time in user space. This is useful for debugging.
00019   If this is done, then the following stuff needs to be  done to access the
00020   IO space.
00021   */
00022 
00023 
00024 #ifdef DEFINE_EXTERN_BEFORE_IO
00025 /*
00026   Because of a limitation in gcc (present at least in 2.7.2.1 and below), you
00027   _have to_ compile any source code that uses these routines with optimisation
00028   turned on (gcc -O1 or higher), or alternatively #define extern to be
00029   empty before #including <asm/io.h>.
00030   */
00031 #define extern
00032 #endif
00033 
00034 
00035 /*
00036   Need to access ports in range 0x278 - 0x378, for default
00037   PPMC base address. ioperm() only enables up to 0x3FF, so we need to use
00038   iopl() to grant full access to IO space.
00039   */
00040 
00041 #include <unistd.h>             /* iopl() */
00042 
00043 #endif /* LINUX  */
00044 
00045 #ifdef linux
00046 #include <linux/version.h>      /* LINUX_KERNEL_VERSION  */
00047 #endif
00048 
00049 
00050 #ifdef DO_IT
00051 
00052 /* outb,inb already included by sys/io.h for 2.2 kernels  */
00053 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,0)
00054 #include <asm/io.h>             /* outb, inb */
00055 #else
00056 #include <sys/io.h>             /* outb, inb */
00057 #endif
00058 #else
00059 
00060 /* otherwise do nothing */
00061 
00062 #include <stdio.h>
00063 
00064 static int iopl(int level)
00065 {
00066   return 0;
00067 }
00068 
00069 static unsigned char inb(unsigned int port)
00070 {
00071   if (port >= STG_BASE_ADDRESS &&
00072       port <= STG_BASE_ADDRESS + 0x1f)
00073     {
00074       return 0;
00075     }
00076 
00077   if (port >= STG_BASE_ADDRESS + 0x400 &&
00078       port <= STG_BASE_ADDRESS + 0x400 + 0x1f)
00079     {
00080       return 0;
00081     }
00082 
00083   printf("inb: address out of bounds: %X\n", port);
00084   return 0;
00085 }
00086 
00087 static void outb(unsigned char byte, unsigned int port)
00088 {
00089   /* allow writes to 0x80 for 1 msec delay */
00090   if (port == 0x80)
00091     {
00092       return;
00093     }
00094 
00095   if (port >= STG_BASE_ADDRESS &&
00096       port <= STG_BASE_ADDRESS + 0x1f)
00097     {
00098       return;
00099     }
00100 
00101   if (port >= STG_BASE_ADDRESS + 0x400 &&
00102       port <= STG_BASE_ADDRESS + 0x400 + 0x1f)
00103     {
00104       return;
00105     }
00106 
00107   printf("outb: address out of bounds: %X\n", port);
00108 }
00109 
00110 static unsigned short inw(unsigned int port)
00111 {
00112   if (port % 2)
00113     {
00114       printf("inw: alignment error: %X\n", port);
00115       return 0;
00116     }
00117 
00118   if (port >= STG_BASE_ADDRESS &&
00119       port <= STG_BASE_ADDRESS + 0x1e)
00120     {
00121       return 0;
00122     }
00123 
00124   if (port >= STG_BASE_ADDRESS + 0x400 &&
00125       port <= STG_BASE_ADDRESS + 0x400 + 0x1e)
00126     {
00127       return 0;
00128     }
00129 
00130   printf("inw: address out of bounds: %X\n", port);
00131   return 0;
00132 }
00133 
00134 static void outw(unsigned short word, unsigned int port)
00135 {
00136   if (port % 2)
00137     {
00138       printf("outw: alignment error: %X\n", port);
00139       return;
00140     }
00141 
00142   if (port >= STG_BASE_ADDRESS &&
00143       port <= STG_BASE_ADDRESS + 0x1e)
00144     {
00145       return;
00146     }
00147 
00148   if (port >= STG_BASE_ADDRESS + 0x400 &&
00149       port <= STG_BASE_ADDRESS + 0x400 + 0x1e)
00150     {
00151       return;
00152     }
00153 
00154   printf("outw: address out of bounds: %X\n", port);
00155   return;
00156 }
00157 
00158 
00159 #endif
00160 
00161 //extern unsigned int stg_base_addr;
00162 unsigned short STG_BASE_ADDRESS = DEFAULT_PPMC_BASE_ADDRESS;
00163 #define ppmc_base_addr STG_BASE_ADDRESS
00164 /*
00165         base+0          data
00166  *      base+1          status
00167  *      base+2          control
00168   *     base+3          EPP address
00169  *      base+4          EPP data
00170 */
00171 #define SPPDATA ppmc_base_addr
00172 #define STATUSPORT ppmc_base_addr+1
00173 #define CONTROLPORT ppmc_base_addr+2
00174 #define ADDRPORT ppmc_base_addr+3
00175 #define DATAPORT ppmc_base_addr+4
00176 
00177 
00178 
00179 void BusReset(void)
00180 {
00181   outb(0,CONTROLPORT);
00182   outb(4,CONTROLPORT);
00183 }
00184 
00185 //internal routine to initialize the port itself
00186 short InitializeParPort(void);
00187 //internal routine to initialize the encoder board(s)
00188 
00189  int ClrTimeout(void)
00190 {
00191         unsigned char r;
00192 
00193         if  (!(inb(STATUSPORT) & 0x01))
00194                 return 0;
00195 
00196         /* To clear timeout some chips require double read */
00197         
00198         BusReset();
00199         r = inb(STATUSPORT);
00200         outb(r | 0x01, STATUSPORT); /* Some reset by writing 1 */
00201         r = inb(STATUSPORT);
00202 
00203         return !(r & 0x01);
00204 }
00205 
00206 
00207 void SelAddr(unsigned int port)
00208 {
00209   /* writes a device address to the data port and toggles address strobe low, and waits
00210                 for handshake */
00211     ClrTimeout();
00212     //    outb(inb(CONTROLPORT) & 0xDF,CONTROLPORT);  // set port direction to output
00213     outb(0x04,CONTROLPORT);  // set port direction to output
00214  
00215    outb(port,ADDRPORT);
00216     return;
00217 }
00218 
00219 void WriteData(unsigned char byte)
00220 {
00221   /* writes data to the data port and toggles data strobe low, and waits
00222                 for handshake */
00223     outb(byte,DATAPORT);
00224         ClrTimeout();
00225     return;
00226 }
00227 void WriteData16(unsigned short word)
00228 {
00229   
00230     outb(word & 0x00FF,DATAPORT);
00231     outb(word >> 8,DATAPORT);
00232     return;
00233 }
00234 unsigned short ReadData(void)
00235   {
00236     //    outb(inb(CONTROLPORT) | 0x20,CONTROLPORT);  // set port direction to input
00237     outb(0x24,CONTROLPORT);  // set port direction to input
00238     return inb(DATAPORT);
00239     
00240   }
00241 
00242 unsigned short SelRead(unsigned int port)
00243 {
00244   /* writes a device address to the data port and toggles address strobe low, and waits
00245                 for handshake, then inputs data byte and toggles data strobe low, then
00246                 high again */
00247     ClrTimeout();
00248     outb(inb(CONTROLPORT) & 0xDF,CONTROLPORT);  // set port direction to output
00249     outb(port,ADDRPORT);
00250     outb(inb(CONTROLPORT) | 0x20,CONTROLPORT);  // set port direction to input
00251     return inb(DATAPORT);
00252     
00253 }
00254 
00255 void SelWrt(unsigned int port, unsigned char byte)
00256 {
00257   /* writes a device address to the data port and toggles address strobe low, and waits
00258                 for handshake, then outputs data byte and toggles data strobe low, then
00259                 high again */
00260     ClrTimeout();
00261     //    outb(inb(CONTROLPORT) & 0xDF,CONTROLPORT);  // set port direction to output
00262     outb(0x04,CONTROLPORT);  // set port direction to output
00263     outb(port,ADDRPORT);
00264     outb(byte,DATAPORT);
00265     return;
00266 }
00267 void SelWrt16(unsigned int port, unsigned short word)
00268 {
00269   /* writes a device address to the data port and toggles address strobe low, and waits
00270                 for handshake, then (outputs data byte and toggles data strobe low, then
00271                 high again) repeat for 2nd byte */
00272     ClrTimeout();
00273     outb(inb(CONTROLPORT) & 0xDF,CONTROLPORT);  // set port direction to output
00274     outb(port,ADDRPORT);
00275     outb(word & 0x00FF,DATAPORT);
00276     outb(word >> 8,DATAPORT);
00277     return;
00278 }
00279 
00280 
00281 short int InitializeParPort(void)
00282 {
00283 #ifdef LINUX
00284         ioperm(ppmc_base_addr,5,1) ;//turn on the 5
00285                         //if you want to run ecp, need to use iopl()
00286 #endif
00287   return 0;
00288 }
00289 
00290 int ppmcMotInit(const char * stuffstuff)
00291 {
00292         if(InitializeParPort()==-1)
00293                 return -1;
00294         BusReset();
00295         if(EncoderInit()==-1)
00296                 return -1;
00297         /*      if(DACInit()==-1)
00298                 return -1;
00299         if(DIOInit()==-1)
00300         return -1;  */
00301   return 0;
00302 
00303 }
00304 
00305 int ppmcMotQuit()
00306 {
00307         DACQuit();
00308         EncoderQuit();
00309         DIOQuit();
00310   return 0;
00311 }
00312 
00313 
00314 

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