00001 /*!@file BeoSub/BeoSubMotor.C Low-level driver for BeoSub motors */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2003 // 00005 // by the University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Laurent Itti <itti@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/BeoSub/BeoSubMotor.C $ 00035 // $Id: BeoSubMotor.C 7183 2006-09-20 00:02:57Z rjpeters $ 00036 // 00037 00038 // core of the code contributed by Harris Chiu, USC/ISI 00039 00040 #include "BeoSub/BeoSubMotor.H" 00041 00042 #include "Component/OptionManager.H" 00043 #include "Util/Assert.H" 00044 #ifdef HAVE_SYS_IO_H 00045 #include <sys/io.h> /* for glibc */ 00046 #endif 00047 #include <unistd.h> /* for libc5 */ 00048 00049 #define BSM_NUMCHAN 9 00050 00051 // ###################################################################### 00052 BeoSubMotor::BeoSubMotor(OptionManager& mgr, const std::string& descrName, 00053 const std::string& tagName, 00054 const int def_parallel_port_addr) : 00055 ModelComponent(mgr, descrName, tagName), 00056 itsPort("BeoSubMotorParPortAddr", this, def_parallel_port_addr) 00057 { 00058 strobelo = 205; strobehi = 204; 00059 00060 chMin[0] = 59; chMax[0] = 117; 00061 chMin[1] = 1; chMax[1] = 255; 00062 chMin[2] = 25; chMax[2] = 150; 00063 chMin[3] = 1; chMax[3] = 255; 00064 chMin[4] = 25; chMax[4] = 133; 00065 chMin[5] = 128; chMax[5] = 128; 00066 chMin[6] = 1; chMax[6] = 255; 00067 chMin[7] = 128; chMax[7] = 128; 00068 chMin[8] = 128; chMax[8] = 128; 00069 00070 chDefault[0] = 78; 00071 chDefault[1] = 83; 00072 chDefault[2] = 90; 00073 chDefault[3] = 83; 00074 chDefault[4] = 93; 00075 chDefault[5] = 128; 00076 chDefault[6] = 124; 00077 chDefault[7] = 128; 00078 chDefault[8] = 128; 00079 00080 if (geteuid()) LFATAL("Need to run as root"); 00081 #ifdef HAVE_IOPERM 00082 ioperm(itsPort.getVal(), 3, 1); 00083 #else 00084 LFATAL("libc must have ioperm() to use this function"); 00085 #endif 00086 reset(); 00087 } 00088 00089 // ###################################################################### 00090 BeoSubMotor::~BeoSubMotor() 00091 { 00092 reset(); 00093 } 00094 00095 // ###################################################################### 00096 bool BeoSubMotor::WritePort() 00097 { 00098 #ifndef HAVE_SYS_IO_H 00099 LFATAL("Oops! I need <sys/io.h> for this operation"); 00100 return false; 00101 #else 00102 const int timeout = 100; 00103 00104 for (int i = 0; i < timeout; i++) 00105 { 00106 char PortValue = inb(itsPort.getVal() + 1); 00107 if (PortValue < 0) 00108 { 00109 for (int j = 0; j < 9; j++) SendCh(ch[j]); 00110 return true; 00111 } 00112 usleep(10000); 00113 } 00114 LERROR("Parallel port busy -- GIVING UP"); 00115 return false; // port was busy 00116 #endif // HAVE_SYS_IO_H 00117 } 00118 00119 // ###################################################################### 00120 void BeoSubMotor::SendCh(const int value) 00121 { 00122 #ifndef HAVE_SYS_IO_H 00123 LFATAL("Oops! I need <sys/io.h> for this operation"); 00124 #else 00125 outb(value, itsPort.getVal()); 00126 outb(strobelo, (itsPort.getVal() + 2)); 00127 for (int i = 0; i < 5000; i ++) ; 00128 outb(strobehi, (itsPort.getVal() + 2)); 00129 for (int i = 0; i < 5000; i ++) ; 00130 #endif // HAVE_SYS_IO_H 00131 } 00132 00133 // ###################################################################### 00134 void BeoSubMotor::reset() 00135 { 00136 for (int i = 0; i < BSM_NUMCHAN; i ++) ch[i] = chDefault[i]; 00137 WritePort(); 00138 usleep(100000); 00139 } 00140 00141 // ###################################################################### 00142 bool BeoSubMotor::setValue(const byte value, const int channel, 00143 const bool immed) 00144 { 00145 ASSERT(channel >= 0 && channel < BSM_NUMCHAN); 00146 00147 if (value < chMin[channel]) ch[channel] = chMin[channel]; 00148 else if (value > chMax[channel]) ch[channel] = chMax[channel]; 00149 else ch[channel] = value; 00150 00151 if (immed) return WritePort(); 00152 return true; 00153 } 00154 00155 // ###################################################################### 00156 bool BeoSubMotor::pulseValue(const int channel, const bool positive) 00157 { 00158 ASSERT(channel >= 0 && channel < BSM_NUMCHAN); 00159 int length = 600000; int delta = 80; 00160 if (channel == BSM_UPDOWN) { length = 1000000; delta = 100; } 00161 // go to rest: 00162 if (setValue(chDefault[channel], channel, true) == false) return false; 00163 usleep(100000); 00164 00165 // turn on: 00166 if (positive) 00167 { 00168 if (setValue(chDefault[channel] - delta, channel, true) == false) 00169 return false; 00170 } 00171 else 00172 { 00173 if (setValue(chDefault[channel] + delta, channel, true) == false) 00174 return false; 00175 } 00176 usleep(length); 00177 00178 // back to rest: 00179 if (setValue(chDefault[channel], channel, true) == false) return false; 00180 usleep(200000); 00181 00182 // success! 00183 return true; 00184 } 00185 00186 // ###################################################################### 00187 byte BeoSubMotor::getValue(const int channel) const 00188 { 00189 ASSERT(channel >= 0 && channel < BSM_NUMCHAN); 00190 return ch[channel]; 00191 } 00192 00193 00194 00195 // ###################################################################### 00196 /* So things look consistent in everyone's emacs... */ 00197 /* Local Variables: */ 00198 /* indent-tabs-mode: nil */ 00199 /* End: */