3 * Copyright 2001,2003,2004,2008 Free Software Foundation, Inc.
5 * This file is part of GNU Radio
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)
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.
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.
26 #include <ppio_ppdev.h>
27 #include <sys/types.h>
35 #if defined(HAVE_LINUX_PPDEV_H)
36 #include <sys/ioctl.h>
37 #include <linux/ppdev.h>
38 #include <linux/parport.h>
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>
46 // #warn "ppio_ppdev is not functional on this platform"
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.
53 static int CP_ACTIVE_LOW_BITS = 0x0B;
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.
59 static int SP_ACTIVE_LOW_BITS = 0x80;
61 #if defined(HAVE_LINUX_PPDEV_H)
63 // The real Linux code...
65 ppio_ppdev::ppio_ppdev (int which)
67 std::ostringstream filename;
68 filename << "/dev/parport" << which;
69 const char *c_filename = filename.str().c_str();
71 if ((d_fd = open (c_filename, O_RDWR)) < 0){
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;
80 throw std::runtime_error ("open");
83 int mode = IEEE1284_MODE_COMPAT;
84 if (ioctl (d_fd, PPSETMODE, &mode) != 0){
85 perror ("ppio_ppdev: PPSETMODE");
87 throw std::runtime_error ("PPSETMODE");
91 ppio_ppdev::~ppio_ppdev ()
98 ppio_ppdev::write_data (unsigned char v)
100 if (ioctl (d_fd, PPWDATA, &v) != 0){
101 perror ("ppio_ppdev: PPWDATA");
102 throw std::runtime_error ("PPWDATA");
107 ppio_ppdev::read_data ()
111 if (ioctl (d_fd, PPRDATA, &v) != 0){
112 perror ("ppio_ppdev: PPRDATA");
113 throw std::runtime_error ("PPRDATA");
119 ppio_ppdev::write_control (unsigned char v)
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");
129 ppio_ppdev::read_control ()
132 if (ioctl (d_fd, PPRCONTROL, &ctrl) != 0){
133 perror ("ppio_ppdev: PPRCONTROL");
134 throw std::runtime_error ("PPRCONTROL");
137 return ctrl ^ CP_ACTIVE_LOW_BITS;
141 ppio_ppdev::read_status ()
143 unsigned char status;
144 if (ioctl (d_fd, PPRSTATUS, &status) != 0){
145 perror ("ppio_ppdev: PPRSTATUS");
146 throw std::runtime_error ("PPRSTATUS");
149 return status ^ SP_ACTIVE_LOW_BITS;
155 if (ioctl (d_fd, PPCLAIM) != 0){
156 perror ("ppio_ppdev: PPCLAIM");
157 throw std::runtime_error ("PPCLAIM");
162 ppio_ppdev::unlock ()
164 if (ioctl (d_fd, PPRELEASE) != 0){
165 perror ("ppio_ppdev: PPRELEASE");
166 throw std::runtime_error ("PPRELEASE");
170 #elif defined(HAVE_DEV_PPBUS_PPI_H)
172 // The real FreeBSD code... (Could work on other BSDs as well)
174 ppio_ppdev::ppio_ppdev (int which)
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;
182 throw std::runtime_error ("open");
186 int mode = IEEE1284_MODE_COMPAT;
187 if (ioctl (d_fd, PPSETMODE, &mode) != 0){
188 perror ("ppio_ppdev: PPSETMODE");
190 throw std::runtime_error ("PPSETMODE");
195 ppio_ppdev::~ppio_ppdev ()
202 ppio_ppdev::write_data (unsigned char v)
204 if (ioctl (d_fd, PPISDATA, &v) != 0){
205 perror ("ppio_ppdev: PPISDATA");
206 throw std::runtime_error ("PPISDATA");
211 ppio_ppdev::read_data ()
215 if (ioctl (d_fd, PPIGDATA, &v) != 0){
216 perror ("ppio_ppdev: PPIGDATA");
217 throw std::runtime_error ("PPIGDATA");
223 ppio_ppdev::write_control (unsigned char v)
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");
233 ppio_ppdev::read_control ()
236 if (ioctl (d_fd, PPIGCTRL, &ctrl) != 0){
237 perror ("ppio_ppdev: PPIGCTRL");
238 throw std::runtime_error ("PPIGCTRL");
241 return ctrl ^ CP_ACTIVE_LOW_BITS;
245 ppio_ppdev::read_status ()
247 unsigned char status;
248 if (ioctl (d_fd, PPIGSTATUS, &status) != 0){
249 perror ("ppio_ppdev: PPIGSTATUS");
250 throw std::runtime_error ("PPIGSTATUS");
252 return status ^ SP_ACTIVE_LOW_BITS;
261 ppio_ppdev::unlock ()
265 /* Apparently, non real code */
267 ppio_ppdev::ppio_ppdev (int which)
269 std::cerr << "ppio_ppdev: Not implemented on this platform\n";
270 throw std::runtime_error ("not implmeneted");
273 ppio_ppdev::~ppio_ppdev ()
278 ppio_ppdev::write_data (unsigned char v)
283 ppio_ppdev::read_data ()
289 ppio_ppdev::write_control (unsigned char v)
294 ppio_ppdev::read_control ()
300 ppio_ppdev::read_status ()
311 ppio_ppdev::unlock ()
318 make_ppio_ppdev (int which)
320 return ppio_ppdev_sptr (new ppio_ppdev (which));