Imported Upstream version 3.2.2
[debian/gnuradio] / gnuradio-core / src / lib / io / ppio_ppdev.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2001,2003,2004,2008 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 3, 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 #if defined(HAVE_LINUX_PPDEV_H)
36 #include <sys/ioctl.h>
37 #include <linux/ppdev.h>
38 #include <linux/parport.h>
39 #include <sstream>
40 #elif defined(HAVE_DEV_PPBUS_PPI_H)
41 #include <sys/ioctl.h>
42 #include <dev/ppbus/ppi.h>
43 #include <dev/ppbus/ppbconf.h>
44 #include <sstream>
45 #else
46 // #warn "ppio_ppdev is not functional on this platform"
47 #endif
48
49 // These control port bits are active low.
50 // We toggle them so that this weirdness doesn't get get propagated
51 // through our interface.
52
53 static int CP_ACTIVE_LOW_BITS   = 0x0B;
54
55 // These status port bits are active low.
56 // We toggle them so that this weirdness doesn't get get propagated
57 // through our interface.
58
59 static int SP_ACTIVE_LOW_BITS   = 0x80;
60
61 #if defined(HAVE_LINUX_PPDEV_H)
62
63 // The real Linux code...
64
65 ppio_ppdev::ppio_ppdev (int which)
66 {
67   std::ostringstream filename;
68   filename << "/dev/parport" << which;
69   const char *c_filename = filename.str().c_str();
70
71   if ((d_fd = open (c_filename, O_RDWR)) < 0){
72     int my_errno = errno;
73     perror (c_filename);
74     if (my_errno == ENOENT){
75       std::cerr << "Does the device file " << c_filename << " exist?\n";
76       std::cerr << "If not, as root execute: \n";
77       std::cerr << "  # mknod " << c_filename << " c 99 0\n";
78       std::cerr << "  # chmod 666 " << c_filename << std::endl;
79     }
80     throw std::runtime_error ("open");
81   }
82
83   int mode = IEEE1284_MODE_COMPAT;
84   if (ioctl (d_fd, PPSETMODE, &mode) != 0){
85     perror ("ppio_ppdev: PPSETMODE");
86     close (d_fd);
87     throw std::runtime_error ("PPSETMODE");
88   }
89 }
90
91 ppio_ppdev::~ppio_ppdev ()
92 {
93   close (d_fd);
94 }
95
96
97 void 
98 ppio_ppdev::write_data (unsigned char v)
99 {
100   if (ioctl (d_fd, PPWDATA, &v) != 0){
101     perror ("ppio_ppdev: PPWDATA");
102     throw std::runtime_error ("PPWDATA");
103   }
104 }
105
106 unsigned char
107 ppio_ppdev::read_data ()
108 {
109   unsigned char v;
110
111   if (ioctl (d_fd, PPRDATA, &v) != 0){
112     perror ("ppio_ppdev: PPRDATA");
113     throw std::runtime_error ("PPRDATA");
114   }
115   return v;
116 }
117
118 void 
119 ppio_ppdev::write_control (unsigned char v)
120 {
121   unsigned char ctrl = v ^ CP_ACTIVE_LOW_BITS;
122   if (ioctl (d_fd, PPWCONTROL, &ctrl) != 0){
123     perror ("ppio_ppdev: PPWCONTROL");
124     throw std::runtime_error ("PPWCONTROL");
125   }
126 }
127
128 unsigned char
129 ppio_ppdev::read_control ()
130 {
131   unsigned char ctrl;
132   if (ioctl (d_fd, PPRCONTROL, &ctrl) != 0){
133     perror ("ppio_ppdev: PPRCONTROL");
134     throw std::runtime_error ("PPRCONTROL");
135   }
136
137   return ctrl ^ CP_ACTIVE_LOW_BITS;
138 }
139
140 unsigned char
141 ppio_ppdev::read_status ()
142 {
143   unsigned char status;
144   if (ioctl (d_fd, PPRSTATUS, &status) != 0){
145     perror ("ppio_ppdev: PPRSTATUS");
146     throw std::runtime_error ("PPRSTATUS");
147   }
148
149   return status ^ SP_ACTIVE_LOW_BITS;
150 }
151
152 void
153 ppio_ppdev::lock ()
154 {
155   if (ioctl (d_fd, PPCLAIM) != 0){
156     perror ("ppio_ppdev: PPCLAIM");
157     throw std::runtime_error ("PPCLAIM");
158   }
159 }
160
161 void
162 ppio_ppdev::unlock ()
163 {
164   if (ioctl (d_fd, PPRELEASE) != 0){
165     perror ("ppio_ppdev: PPRELEASE");
166     throw std::runtime_error ("PPRELEASE");
167   }
168 }
169
170 #elif defined(HAVE_DEV_PPBUS_PPI_H)
171
172 // The real FreeBSD code... (Could work on other BSDs as well)
173
174 ppio_ppdev::ppio_ppdev (int which)
175 {
176   std::ostringstream filename;
177   filename << "/dev/ppi" << which;
178   const char *c_filename = filename.str().c_str();
179   if ((d_fd = open (c_filename, O_RDWR)) < 0){
180     int my_errno = errno;
181     perror (c_filename);
182     throw std::runtime_error ("open");
183   }
184
185 #if 0
186   int mode = IEEE1284_MODE_COMPAT;
187   if (ioctl (d_fd, PPSETMODE, &mode) != 0){
188     perror ("ppio_ppdev: PPSETMODE");
189     close (d_fd);
190     throw std::runtime_error ("PPSETMODE");
191   }
192 #endif
193 }
194
195 ppio_ppdev::~ppio_ppdev ()
196 {
197   close (d_fd);
198 }
199
200
201 void 
202 ppio_ppdev::write_data (unsigned char v)
203 {
204   if (ioctl (d_fd, PPISDATA, &v) != 0){
205     perror ("ppio_ppdev: PPISDATA");
206     throw std::runtime_error ("PPISDATA");
207   }
208 }
209
210 unsigned char
211 ppio_ppdev::read_data ()
212 {
213   unsigned char v;
214
215   if (ioctl (d_fd, PPIGDATA, &v) != 0){
216     perror ("ppio_ppdev: PPIGDATA");
217     throw std::runtime_error ("PPIGDATA");
218   }
219   return v;
220 }
221
222 void 
223 ppio_ppdev::write_control (unsigned char v)
224 {
225   unsigned char ctrl = v ^ CP_ACTIVE_LOW_BITS;
226   if (ioctl (d_fd, PPISCTRL, &ctrl) != 0){
227     perror ("ppio_ppdev: PPISCTRL");
228     throw std::runtime_error ("PPISCTRL");
229   }
230 }
231
232 unsigned char
233 ppio_ppdev::read_control ()
234 {
235   unsigned char ctrl;
236   if (ioctl (d_fd, PPIGCTRL, &ctrl) != 0){
237     perror ("ppio_ppdev: PPIGCTRL");
238     throw std::runtime_error ("PPIGCTRL");
239   }
240
241   return ctrl ^ CP_ACTIVE_LOW_BITS;
242 }
243
244 unsigned char
245 ppio_ppdev::read_status ()
246 {
247   unsigned char status;
248   if (ioctl (d_fd, PPIGSTATUS, &status) != 0){
249     perror ("ppio_ppdev: PPIGSTATUS");
250     throw std::runtime_error ("PPIGSTATUS");
251   }
252   return status ^ SP_ACTIVE_LOW_BITS;
253 }
254
255 void
256 ppio_ppdev::lock ()
257 {
258 }
259
260 void
261 ppio_ppdev::unlock ()
262 {
263 }
264 #else
265 /* Apparently, non real code */
266
267 ppio_ppdev::ppio_ppdev (int which)
268 {
269   std::cerr << "ppio_ppdev: Not implemented on this platform\n";
270   throw std::runtime_error ("not implmeneted");
271 }
272
273 ppio_ppdev::~ppio_ppdev ()
274 {
275 }
276
277 void 
278 ppio_ppdev::write_data (unsigned char v)
279 {
280 }
281
282 unsigned char
283 ppio_ppdev::read_data ()
284 {
285   return 0;
286 }
287
288 void 
289 ppio_ppdev::write_control (unsigned char v)
290 {
291 }
292
293 unsigned char
294 ppio_ppdev::read_control ()
295 {
296   return 0;
297 }
298
299 unsigned char
300 ppio_ppdev::read_status ()
301 {
302   return 0;
303 }
304
305 void
306 ppio_ppdev::lock ()
307 {
308 }
309
310 void
311 ppio_ppdev::unlock ()
312 {
313 }
314
315 #endif
316
317 ppio_ppdev_sptr
318 make_ppio_ppdev (int which)
319 {
320   return ppio_ppdev_sptr (new ppio_ppdev (which));
321 }