2 * GraphLCD driver library
4 * port.c - parallel port class with low level routines
6 * This file is released under the GNU General Public License. Refer
7 * to the COPYING file distributed with this package.
9 * (c) 2004 Andreas Regel <andreas.regel AT powarman.de>
21 #include <sys/ioctl.h>
22 #include <linux/ppdev.h>
23 #include <linux/parport.h>
35 static inline int port_in(int port)
38 __asm__ volatile ("inb %1,%0"
40 : "d" ((unsigned short) port));
44 static inline void port_out(unsigned short int port, unsigned char val)
46 __asm__ volatile ("outb %0,%1\n"
48 : "a" (val), "d" (port));
51 cParallelPort::cParallelPort()
58 cParallelPort::~cParallelPort()
62 int cParallelPort::Open(int portIO)
69 if (ioperm(port, 3, 255) == -1)
71 syslog(LOG_ERR, "glcd drivers: ERROR ioperm(0x%X) failed! Err:%s (cParallelPort::Open)\n",
72 port, strerror(errno));
80 syslog(LOG_ERR, "glcd drivers: ERROR iopl failed! Err:%s (cParallelPort::Init)\n",
88 int cParallelPort::Open(const char * device)
92 fd = open(device, O_RDWR);
95 syslog(LOG_ERR, "glcd drivers: ERROR cannot open %s. Err:%s (cParallelPort::Init)\n",
96 device, strerror(errno));
100 if (ioctl(fd, PPCLAIM, NULL) == -1)
102 syslog(LOG_ERR, "glcd drivers: ERROR cannot claim %s. Err:%s (cParallelPort::Init)\n",
103 device, strerror(errno));
108 int mode = PARPORT_MODE_PCSPP;
109 if (ioctl(fd, PPSETMODE, &mode) == -1)
111 syslog(LOG_ERR, "glcd drivers: ERROR cannot setmode %s. Err:%s (cParallelPort::Init)\n",
112 device, strerror(errno));
120 int cParallelPort::Close()
126 ioctl(fd, PPRELEASE);
139 if (ioperm(port, 3, 0) == -1)
155 void cParallelPort::Claim()
161 void cParallelPort::Release()
164 ioctl(fd, PPRELEASE);
167 void cParallelPort::SetDirection(int direction)
171 if (ioctl(fd, PPDATADIR, &direction) == -1)
173 perror("ioctl(PPDATADIR)");
179 if (direction == kForward)
180 port_out(port + 2, port_in(port + 2) & 0xdf);
182 port_out(port + 2, port_in(port + 2) | 0x20);
186 unsigned char cParallelPort::ReadControl()
192 if (ioctl(fd, PPRCONTROL, &value) == -1)
194 perror("ioctl(PPRCONTROL)");
200 value = port_in(port + 2);
206 void cParallelPort::WriteControl(unsigned char value)
210 if (ioctl(fd, PPWCONTROL, &value) == -1)
212 perror("ioctl(PPWCONTROL)");
218 port_out(port + 2, value);
222 unsigned char cParallelPort::ReadStatus()
228 if (ioctl(fd, PPRSTATUS, &value) == -1)
230 perror("ioctl(PPRSTATUS)");
236 value = port_in(port + 1);
242 unsigned char cParallelPort::ReadData()
248 if (ioctl(fd, PPRDATA, &data) == -1)
250 perror("ioctl(PPRDATA)");
256 data = port_in(port);
262 void cParallelPort::WriteData(unsigned char data)
266 if (ioctl(fd, PPWDATA, &data) == -1)
268 perror("ioctl(PPWDATA)");
274 port_out(port, data);
280 cSerialPort::cSerialPort()
285 cSerialPort::~cSerialPort()
289 int cSerialPort::Open(const char * device, void (*FP)(int))
291 struct sigaction saio;
297 if (Open(device) == 0) {
298 // install the signal handler before making the device asynchronous/
299 saio.sa_handler = FP;
300 sigemptyset (&saio.sa_mask);
302 saio.sa_restorer = NULL;
303 sigaction(SIGIO,&saio,NULL);
305 // allow the process to receive SIGIO
306 fcntl(fd, F_SETOWN, getpid());
307 // Make the file descriptor asynchronous
308 fcntl(fd, F_SETFL, FASYNC | O_NONBLOCK);
317 int cSerialPort::Open(const char * device)
319 struct termios options;
321 fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK);
324 printf("error opening port\n");
328 tcgetattr(fd, &options);
330 cfsetispeed(&options, B921600);
331 cfsetospeed(&options, B921600);
333 options.c_cflag &= ~PARENB;
334 options.c_cflag &= ~CSTOPB;
335 options.c_cflag &= ~CSIZE;
336 options.c_cflag |= CS8;
338 options.c_cflag &= ~CRTSCTS;
340 options.c_cflag |= (CLOCAL | CREAD);
342 options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
344 options.c_iflag &= ~(IXON | IXOFF | IXANY);
346 options.c_oflag &= ~OPOST;
348 tcsetattr(fd, TCSANOW, &options);
353 int cSerialPort::Close()
355 struct sigaction saio;
360 saio.sa_handler = NULL;
361 sigemptyset (&saio.sa_mask);
363 saio.sa_restorer = NULL;
364 sigaction(SIGIO,&saio,NULL);
369 int cSerialPort::ReadData(unsigned char * data)
373 return read(fd, data, 1);
376 void cSerialPort::WriteData(unsigned char data)
381 void cSerialPort::WriteData(unsigned char * data, unsigned short length)
385 write(fd, data, length);
386 // for (int x=0; x<length; x++) printf("0x%x ",data[x]);
390 } // end of namespace