Imported Upstream version 3.0
[debian/gnuradio] / gnuradio-core / src / lib / io / ppio_ppdev.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2001,2003,2004 Free Software Foundation, Inc.
4  * 
5  * This file is part of GNU Radio
6  * 
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  * 
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 #include <ppio_ppdev.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #include <stdlib.h>
31 #include <iostream>
32 #include <errno.h>
33 #include <stdio.h>
34 #include <stdexcept>
35 #ifdef HAVE_LINUX_PPDEV_H
36 #include <sys/ioctl.h>
37 #include <linux/ppdev.h>
38 #include <linux/parport.h>
39 #include <sstream>
40 #else
41 // #warn "ppio_ppdev is not functional on this platform"
42 #endif
43
44 // These control port bits are active low.
45 // We toggle them so that this weirdness doesn't get get propagated
46 // through our interface.
47
48 static int CP_ACTIVE_LOW_BITS   = 0x0B;
49
50 // These status port bits are active low.
51 // We toggle them so that this weirdness doesn't get get propagated
52 // through our interface.
53
54 static int SP_ACTIVE_LOW_BITS   = 0x80;
55
56 #ifndef HAVE_LINUX_PPDEV_H              // use stubs
57
58 ppio_ppdev::ppio_ppdev (int which)
59 {
60   std::cerr << "ppio_ppdev: Not implemented on this platform\n";
61   throw std::runtime_error ("not implmeneted");
62 }
63
64 ppio_ppdev::~ppio_ppdev ()
65 {
66 }
67
68 void 
69 ppio_ppdev::write_data (unsigned char v)
70 {
71 }
72
73 unsigned char
74 ppio_ppdev::read_data ()
75 {
76   return 0;
77 }
78
79 void 
80 ppio_ppdev::write_control (unsigned char v)
81 {
82 }
83
84 unsigned char
85 ppio_ppdev::read_control ()
86 {
87   return 0;
88 }
89
90 unsigned char
91 ppio_ppdev::read_status ()
92 {
93   return 0;
94 }
95
96 void
97 ppio_ppdev::lock ()
98 {
99 }
100
101 void
102 ppio_ppdev::unlock ()
103 {
104 }
105
106 #else           
107
108 // The real code...
109
110 ppio_ppdev::ppio_ppdev (int which)
111 {
112   std::ostringstream filename;
113   filename << "/dev/parport" << which;
114   const char *c_filename = filename.str().c_str();
115
116   if ((d_fd = open (c_filename, O_RDWR)) < 0){
117     int my_errno = errno;
118     perror (c_filename);
119     if (my_errno == ENOENT){
120       std::cerr << "Does the device file " << c_filename << " exist?\n";
121       std::cerr << "If not, as root execute: \n";
122       std::cerr << "  # mknod " << c_filename << " c 99 0\n";
123       std::cerr << "  # chmod 666 " << c_filename << std::endl;
124     }
125     throw std::runtime_error ("open");
126   }
127
128   int mode = IEEE1284_MODE_COMPAT;
129   if (ioctl (d_fd, PPSETMODE, &mode) != 0){
130     perror ("ppio_ppdev: PPSETMODE");
131     close (d_fd);
132     throw std::runtime_error ("PPSETMODE");
133   }
134 }
135
136 ppio_ppdev::~ppio_ppdev ()
137 {
138   close (d_fd);
139 }
140
141
142 void 
143 ppio_ppdev::write_data (unsigned char v)
144 {
145   if (ioctl (d_fd, PPWDATA, &v) != 0){
146     perror ("ppio_ppdev: PPWDATA");
147     throw std::runtime_error ("PPWDATA");
148   }
149 }
150
151 unsigned char
152 ppio_ppdev::read_data ()
153 {
154   unsigned char v;
155
156   if (ioctl (d_fd, PPRDATA, &v) != 0){
157     perror ("ppio_ppdev: PPRDATA");
158     throw std::runtime_error ("PPRDATA");
159   }
160   return v;
161 }
162
163 void 
164 ppio_ppdev::write_control (unsigned char v)
165 {
166   unsigned char ctrl = v ^ CP_ACTIVE_LOW_BITS;
167   if (ioctl (d_fd, PPWCONTROL, &ctrl) != 0){
168     perror ("ppio_ppdev: PPWCONTROL");
169     throw std::runtime_error ("PPWCONTROL");
170   }
171 }
172
173 unsigned char
174 ppio_ppdev::read_control ()
175 {
176   unsigned char ctrl;
177   if (ioctl (d_fd, PPRCONTROL, &ctrl) != 0){
178     perror ("ppio_ppdev: PPRCONTROL");
179     throw std::runtime_error ("PPRCONTROL");
180   }
181
182   return ctrl ^ CP_ACTIVE_LOW_BITS;
183 }
184
185 unsigned char
186 ppio_ppdev::read_status ()
187 {
188   unsigned char status;
189   if (ioctl (d_fd, PPRSTATUS, &status) != 0){
190     perror ("ppio_ppdev: PPRSTATUS");
191     throw std::runtime_error ("PPRSTATUS");
192   }
193
194   return status ^ SP_ACTIVE_LOW_BITS;
195 }
196
197 void
198 ppio_ppdev::lock ()
199 {
200   if (ioctl (d_fd, PPCLAIM) != 0){
201     perror ("ppio_ppdev: PPCLAIM");
202     throw std::runtime_error ("PPCLAIM");
203   }
204 }
205
206 void
207 ppio_ppdev::unlock ()
208 {
209   if (ioctl (d_fd, PPRELEASE) != 0){
210     perror ("ppio_ppdev: PPRELEASE");
211     throw std::runtime_error ("PPRELEASE");
212   }
213 }
214
215 #endif
216
217 ppio_ppdev_sptr
218 make_ppio_ppdev (int which)
219 {
220   return ppio_ppdev_sptr (new ppio_ppdev (which));
221 }