summaryrefslogtreecommitdiff
path: root/gnuradio-core/src/lib/io/ppio_ppdev.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gnuradio-core/src/lib/io/ppio_ppdev.cc')
-rw-r--r--gnuradio-core/src/lib/io/ppio_ppdev.cc321
1 files changed, 321 insertions, 0 deletions
diff --git a/gnuradio-core/src/lib/io/ppio_ppdev.cc b/gnuradio-core/src/lib/io/ppio_ppdev.cc
new file mode 100644
index 000000000..f52845958
--- /dev/null
+++ b/gnuradio-core/src/lib/io/ppio_ppdev.cc
@@ -0,0 +1,321 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2003,2004,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <ppio_ppdev.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <iostream>
+#include <errno.h>
+#include <stdio.h>
+#include <stdexcept>
+#if defined(HAVE_LINUX_PPDEV_H)
+#include <sys/ioctl.h>
+#include <linux/ppdev.h>
+#include <linux/parport.h>
+#include <sstream>
+#elif defined(HAVE_DEV_PPBUS_PPI_H)
+#include <sys/ioctl.h>
+#include <dev/ppbus/ppi.h>
+#include <dev/ppbus/ppbconf.h>
+#include <sstream>
+#else
+// #warn "ppio_ppdev is not functional on this platform"
+#endif
+
+// These control port bits are active low.
+// We toggle them so that this weirdness doesn't get get propagated
+// through our interface.
+
+static int CP_ACTIVE_LOW_BITS = 0x0B;
+
+// These status port bits are active low.
+// We toggle them so that this weirdness doesn't get get propagated
+// through our interface.
+
+static int SP_ACTIVE_LOW_BITS = 0x80;
+
+#if defined(HAVE_LINUX_PPDEV_H)
+
+// The real Linux code...
+
+ppio_ppdev::ppio_ppdev (int which)
+{
+ std::ostringstream filename;
+ filename << "/dev/parport" << which;
+ const char *c_filename = filename.str().c_str();
+
+ if ((d_fd = open (c_filename, O_RDWR)) < 0){
+ int my_errno = errno;
+ perror (c_filename);
+ if (my_errno == ENOENT){
+ std::cerr << "Does the device file " << c_filename << " exist?\n";
+ std::cerr << "If not, as root execute: \n";
+ std::cerr << " # mknod " << c_filename << " c 99 0\n";
+ std::cerr << " # chmod 666 " << c_filename << std::endl;
+ }
+ throw std::runtime_error ("open");
+ }
+
+ int mode = IEEE1284_MODE_COMPAT;
+ if (ioctl (d_fd, PPSETMODE, &mode) != 0){
+ perror ("ppio_ppdev: PPSETMODE");
+ close (d_fd);
+ throw std::runtime_error ("PPSETMODE");
+ }
+}
+
+ppio_ppdev::~ppio_ppdev ()
+{
+ close (d_fd);
+}
+
+
+void
+ppio_ppdev::write_data (unsigned char v)
+{
+ if (ioctl (d_fd, PPWDATA, &v) != 0){
+ perror ("ppio_ppdev: PPWDATA");
+ throw std::runtime_error ("PPWDATA");
+ }
+}
+
+unsigned char
+ppio_ppdev::read_data ()
+{
+ unsigned char v;
+
+ if (ioctl (d_fd, PPRDATA, &v) != 0){
+ perror ("ppio_ppdev: PPRDATA");
+ throw std::runtime_error ("PPRDATA");
+ }
+ return v;
+}
+
+void
+ppio_ppdev::write_control (unsigned char v)
+{
+ unsigned char ctrl = v ^ CP_ACTIVE_LOW_BITS;
+ if (ioctl (d_fd, PPWCONTROL, &ctrl) != 0){
+ perror ("ppio_ppdev: PPWCONTROL");
+ throw std::runtime_error ("PPWCONTROL");
+ }
+}
+
+unsigned char
+ppio_ppdev::read_control ()
+{
+ unsigned char ctrl;
+ if (ioctl (d_fd, PPRCONTROL, &ctrl) != 0){
+ perror ("ppio_ppdev: PPRCONTROL");
+ throw std::runtime_error ("PPRCONTROL");
+ }
+
+ return ctrl ^ CP_ACTIVE_LOW_BITS;
+}
+
+unsigned char
+ppio_ppdev::read_status ()
+{
+ unsigned char status;
+ if (ioctl (d_fd, PPRSTATUS, &status) != 0){
+ perror ("ppio_ppdev: PPRSTATUS");
+ throw std::runtime_error ("PPRSTATUS");
+ }
+
+ return status ^ SP_ACTIVE_LOW_BITS;
+}
+
+void
+ppio_ppdev::lock ()
+{
+ if (ioctl (d_fd, PPCLAIM) != 0){
+ perror ("ppio_ppdev: PPCLAIM");
+ throw std::runtime_error ("PPCLAIM");
+ }
+}
+
+void
+ppio_ppdev::unlock ()
+{
+ if (ioctl (d_fd, PPRELEASE) != 0){
+ perror ("ppio_ppdev: PPRELEASE");
+ throw std::runtime_error ("PPRELEASE");
+ }
+}
+
+#elif defined(HAVE_DEV_PPBUS_PPI_H)
+
+// The real FreeBSD code... (Could work on other BSDs as well)
+
+ppio_ppdev::ppio_ppdev (int which)
+{
+ std::ostringstream filename;
+ filename << "/dev/ppi" << which;
+ const char *c_filename = filename.str().c_str();
+ if ((d_fd = open (c_filename, O_RDWR)) < 0){
+ int my_errno = errno;
+ perror (c_filename);
+ throw std::runtime_error ("open");
+ }
+
+#if 0
+ int mode = IEEE1284_MODE_COMPAT;
+ if (ioctl (d_fd, PPSETMODE, &mode) != 0){
+ perror ("ppio_ppdev: PPSETMODE");
+ close (d_fd);
+ throw std::runtime_error ("PPSETMODE");
+ }
+#endif
+}
+
+ppio_ppdev::~ppio_ppdev ()
+{
+ close (d_fd);
+}
+
+
+void
+ppio_ppdev::write_data (unsigned char v)
+{
+ if (ioctl (d_fd, PPISDATA, &v) != 0){
+ perror ("ppio_ppdev: PPISDATA");
+ throw std::runtime_error ("PPISDATA");
+ }
+}
+
+unsigned char
+ppio_ppdev::read_data ()
+{
+ unsigned char v;
+
+ if (ioctl (d_fd, PPIGDATA, &v) != 0){
+ perror ("ppio_ppdev: PPIGDATA");
+ throw std::runtime_error ("PPIGDATA");
+ }
+ return v;
+}
+
+void
+ppio_ppdev::write_control (unsigned char v)
+{
+ unsigned char ctrl = v ^ CP_ACTIVE_LOW_BITS;
+ if (ioctl (d_fd, PPISCTRL, &ctrl) != 0){
+ perror ("ppio_ppdev: PPISCTRL");
+ throw std::runtime_error ("PPISCTRL");
+ }
+}
+
+unsigned char
+ppio_ppdev::read_control ()
+{
+ unsigned char ctrl;
+ if (ioctl (d_fd, PPIGCTRL, &ctrl) != 0){
+ perror ("ppio_ppdev: PPIGCTRL");
+ throw std::runtime_error ("PPIGCTRL");
+ }
+
+ return ctrl ^ CP_ACTIVE_LOW_BITS;
+}
+
+unsigned char
+ppio_ppdev::read_status ()
+{
+ unsigned char status;
+ if (ioctl (d_fd, PPIGSTATUS, &status) != 0){
+ perror ("ppio_ppdev: PPIGSTATUS");
+ throw std::runtime_error ("PPIGSTATUS");
+ }
+ return status ^ SP_ACTIVE_LOW_BITS;
+}
+
+void
+ppio_ppdev::lock ()
+{
+}
+
+void
+ppio_ppdev::unlock ()
+{
+}
+#else
+/* Apparently, non real code */
+
+ppio_ppdev::ppio_ppdev (int which)
+{
+ std::cerr << "ppio_ppdev: Not implemented on this platform\n";
+ throw std::runtime_error ("not implmeneted");
+}
+
+ppio_ppdev::~ppio_ppdev ()
+{
+}
+
+void
+ppio_ppdev::write_data (unsigned char v)
+{
+}
+
+unsigned char
+ppio_ppdev::read_data ()
+{
+ return 0;
+}
+
+void
+ppio_ppdev::write_control (unsigned char v)
+{
+}
+
+unsigned char
+ppio_ppdev::read_control ()
+{
+ return 0;
+}
+
+unsigned char
+ppio_ppdev::read_status ()
+{
+ return 0;
+}
+
+void
+ppio_ppdev::lock ()
+{
+}
+
+void
+ppio_ppdev::unlock ()
+{
+}
+
+#endif
+
+ppio_ppdev_sptr
+make_ppio_ppdev (int which)
+{
+ return ppio_ppdev_sptr (new ppio_ppdev (which));
+}