/* -*- 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 #endif #include #include #include #include #include #include #include #include #include #if defined(HAVE_LINUX_PPDEV_H) #include #include #include #include #elif defined(HAVE_DEV_PPBUS_PPI_H) #include #include #include #include #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)); }