graphlcd-base/glcddrivers/port.c
author root@rika
Thu, 23 Apr 2009 19:10:12 +0200
changeset 30 7fd00015f62f
parent 29 2723893dc865
permissions -rw-r--r--
several changes..
     1 /*
     2  * GraphLCD driver library
     3  *
     4  * port.c  -  parallel port class with low level routines
     5  *
     6  * This file is released under the GNU General Public License. Refer
     7  * to the COPYING file distributed with this package.
     8  *
     9  * (c) 2004 Andreas Regel <andreas.regel AT powarman.de>
    10  */
    11 
    12 #include <errno.h>
    13 #include <fcntl.h>
    14 #include <stdio.h>
    15 #include <string.h>
    16 #include <syslog.h>
    17 #include <unistd.h>
    18 #include <termios.h>
    19 #include <sys/io.h>
    20 #include <sys/ioctl.h>
    21 #include <linux/ppdev.h>
    22 #include <linux/parport.h>
    23 #include "port.h"
    24 
    25 namespace GLCD
    26 {
    27 
    28 static inline int port_in(int port)
    29 {
    30     unsigned char value;
    31     __asm__ volatile ("inb %1,%0"
    32                       : "=a" (value)
    33                       : "d" ((unsigned short) port));
    34     return value;
    35 }
    36 
    37 static inline void port_out(unsigned short int port, unsigned char val)
    38 {
    39     __asm__ volatile ("outb %0,%1\n"
    40                       :
    41                       : "a" (val), "d" (port));
    42 }
    43 
    44 cParallelPort::cParallelPort()
    45 :   fd(-1),
    46     port(0),
    47     usePPDev(false)
    48 {
    49 }
    50 
    51 cParallelPort::~cParallelPort()
    52 {
    53 }
    54 
    55 int cParallelPort::Open(int portIO)
    56 {
    57     usePPDev = false;
    58     port = portIO;
    59 
    60     if (port < 0x400)
    61     {
    62         if (ioperm(port, 3, 255) == -1)
    63         {
    64             syslog(LOG_ERR, "glcd drivers: ERROR ioperm(0x%X) failed! Err:%s (cParallelPort::Open)\n",
    65                    port, strerror(errno));
    66             return -1;
    67         }
    68     }
    69     else
    70     {
    71         if (iopl(3) == -1)
    72         {
    73             syslog(LOG_ERR, "glcd drivers: ERROR iopl failed! Err:%s (cParallelPort::Init)\n",
    74                    strerror(errno));
    75             return -1;
    76         }
    77     }
    78     return 0;
    79 }
    80 
    81 int cParallelPort::Open(const char * device)
    82 {
    83     usePPDev = true;
    84 
    85     fd = open(device, O_RDWR);
    86     if (fd == -1)
    87     {
    88         syslog(LOG_ERR, "glcd drivers: ERROR cannot open %s. Err:%s (cParallelPort::Init)\n",
    89                device, strerror(errno));
    90         return -1;
    91     }
    92 
    93     if (ioctl(fd, PPCLAIM, NULL) == -1)
    94     {
    95         syslog(LOG_ERR, "glcd drivers: ERROR cannot claim %s. Err:%s (cParallelPort::Init)\n",
    96                device, strerror(errno));
    97         close(fd);
    98         return -1;
    99     }
   100 
   101     int mode = PARPORT_MODE_PCSPP;
   102     if (ioctl(fd, PPSETMODE, &mode) == -1)
   103     {
   104         syslog(LOG_ERR, "glcd drivers: ERROR cannot setmode %s. Err:%s (cParallelPort::Init)\n",
   105                device, strerror(errno));
   106         close(fd);
   107         return -1;
   108     }
   109 
   110     return 0;
   111 }
   112 
   113 int cParallelPort::Close()
   114 {
   115     if (usePPDev)
   116     {
   117         if (fd != -1)
   118         {
   119             ioctl(fd, PPRELEASE);
   120             close(fd);
   121             fd = -1;
   122         }
   123         else
   124         {
   125             return -1;
   126         }
   127     }
   128     else
   129     {
   130         if (port < 0x400)
   131         {
   132             if (ioperm(port, 3, 0) == -1)
   133             {
   134                 return -1;
   135             }
   136         }
   137         else
   138         {
   139             if (iopl(0) == -1)
   140             {
   141                 return -1;
   142             }
   143         }
   144     }
   145     return 0;
   146 }
   147 
   148 void cParallelPort::Claim()
   149 {
   150     if (usePPDev)
   151         ioctl(fd, PPCLAIM);
   152 }
   153 
   154 void cParallelPort::Release()
   155 {
   156     if (usePPDev)
   157         ioctl(fd, PPRELEASE);
   158 }
   159 
   160 void cParallelPort::SetDirection(int direction)
   161 {
   162     if (usePPDev)
   163     {
   164         if (ioctl(fd, PPDATADIR, &direction) == -1)
   165         {
   166             perror("ioctl(PPDATADIR)");
   167             //exit(1);
   168         }
   169     }
   170     else
   171     {
   172         if (direction == kForward)
   173             port_out(port + 2, port_in(port + 2) & 0xdf);
   174         else
   175             port_out(port + 2, port_in(port + 2) | 0x20);
   176     }
   177 }
   178 
   179 unsigned char cParallelPort::ReadControl()
   180 {
   181     unsigned char value;
   182 
   183     if (usePPDev)
   184     {
   185         if (ioctl(fd, PPRCONTROL, &value) == -1)
   186         {
   187             perror("ioctl(PPRCONTROL)");
   188             //exit(1);
   189         }
   190     }
   191     else
   192     {
   193         value = port_in(port + 2);
   194     }
   195 
   196     return value;
   197 }
   198 
   199 void cParallelPort::WriteControl(unsigned char value)
   200 {
   201     if (usePPDev)
   202     {
   203         if (ioctl(fd, PPWCONTROL, &value) == -1)
   204         {
   205             perror("ioctl(PPWCONTROL)");
   206             //exit(1);
   207         }
   208     }
   209     else
   210     {
   211         port_out(port + 2, value);
   212     }
   213 }
   214 
   215 unsigned char cParallelPort::ReadStatus()
   216 {
   217     unsigned char value;
   218 
   219     if (usePPDev)
   220     {
   221         if (ioctl(fd, PPRSTATUS, &value) == -1)
   222         {
   223             perror("ioctl(PPRSTATUS)");
   224             //exit(1);
   225         }
   226     }
   227     else
   228     {
   229         value = port_in(port + 1);
   230     }
   231 
   232     return value;
   233 }
   234 
   235 unsigned char cParallelPort::ReadData()
   236 {
   237     unsigned char data;
   238 
   239     if (usePPDev)
   240     {
   241         if (ioctl(fd, PPRDATA, &data) == -1)
   242         {
   243             perror("ioctl(PPRDATA)");
   244             //exit(1);
   245         }
   246     }
   247     else
   248     {
   249         data = port_in(port);
   250     }
   251 
   252     return data;
   253 }
   254 
   255 void cParallelPort::WriteData(unsigned char data)
   256 {
   257     if (usePPDev)
   258     {
   259         if (ioctl(fd, PPWDATA, &data) == -1)
   260         {
   261             perror("ioctl(PPWDATA)");
   262             //exit(1);
   263         }
   264     }
   265     else
   266     {
   267         port_out(port, data);
   268     }
   269 }
   270 
   271 
   272 
   273 cSerialPort::cSerialPort()
   274 :   fd(-1)
   275 {
   276 }
   277 
   278 cSerialPort::~cSerialPort()
   279 {
   280 }
   281 
   282 int cSerialPort::Open(const char * device)
   283 {
   284     struct termios options;
   285 
   286     fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK);
   287     if (fd == -1)
   288     {
   289         printf("error opening port\n");
   290         return -1;
   291     }
   292 
   293     tcgetattr(fd, &options);
   294 
   295     cfsetispeed(&options, B921600);
   296     cfsetospeed(&options, B921600);
   297 
   298     options.c_cflag &= ~PARENB;
   299     options.c_cflag &= ~CSTOPB;
   300     options.c_cflag &= ~CSIZE;
   301     options.c_cflag |= CS8;
   302 
   303     options.c_cflag &= ~CRTSCTS;
   304 
   305     options.c_cflag |= (CLOCAL | CREAD);
   306 
   307     options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
   308 
   309     options.c_iflag &= ~(IXON | IXOFF | IXANY);
   310 
   311     options.c_oflag &= ~OPOST;
   312 
   313     tcsetattr(fd, TCSANOW, &options);
   314 
   315     return 0;
   316 }
   317 
   318 int cSerialPort::Close()
   319 {
   320     if (fd == -1)
   321         return -1;
   322     close(fd);
   323     return 0;
   324 }
   325 
   326 int cSerialPort::ReadData(unsigned char * data)
   327 {
   328     if (fd == -1)
   329         return 0;
   330     return read(fd, data, 1);
   331 }
   332 
   333 void cSerialPort::WriteData(unsigned char data)
   334 {
   335     WriteData(&data, 1);
   336 }
   337 
   338 void cSerialPort::WriteData(unsigned char * data, unsigned short length)
   339 {
   340     if (fd == -1)
   341         return;
   342     write(fd, data, length);
   343 }
   344 
   345 
   346 } // end of namespace
   347