PEBL 2.2
Psychology Experiment Building Language - Cross-platform psychological experiment development system
PParallelPort.cpp
Go to the documentation of this file.
1/* -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*- */
3// Name: src/devices/PParellelPort.cpp
4// Purpose: Class for handling parallel port
5// Author: Shane T. Mueller, Ph.D.
6// Copyright: (c) 2010-2026 Shane T. Mueller <smueller@obereed.net>
7// License: GPL 2
8//
9//
10//
11// This file is part of the PEBL project.
12//
13// PEBL is free software; you can redistribute it and/or modify
14// it under the terms of the GNU General Public License as published by
15// the Free Software Foundation; either version 2 of the License, or
16// (at your option) any later version.
17//
18// PEBL is distributed in the hope that it will be useful,
19// but WITHOUT ANY WARRANTY; without even the implied warranty of
20// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21// GNU General Public License for more details.
22//
23// You should have received a copy of the GNU General Public License
24// along with PEBL; if not, write to the Free Software
25// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27#include "PParallelPort.h"
28#include "../utility/PError.h"
29
30#if defined (PEBL_LINUX)
31#include <sys/io.h>
32#endif
33
34
35#if defined (PEBL_WIN32)
36#include <winsock2.h> //avoid collision
37#include <windows.h>
38//#include <conio.h> // Not available in MSYS2, commented out if not needed
39#include <stdio.h>
40
41//Prototype function typefed for DLL function Inp32:
42 typedef short (_stdcall *inpfuncPtr)(short portaddr);
43 typedef void (_stdcall *oupfuncPtr)(short portaddr, short datum);
44
45
46#endif
47
48using std::ostream;
49using std::fstream;
50using std::flush;
51using std::string;
52using std::cout;
53using std::endl;
54
55//#define mPort 0x378
56
57int Inp32(int i){return 1;};
58int Out32(int i,int x ){return 1;};
59
61 {
64 PEBLPPortLPTX=0x3BC
65 };
66
68 mPort(PEBLPPortLPT1),
69 mIsOpen(false)
70{
72}
73
74
80
81
82
84{
85
86#ifdef PEBL_LINUX
87 //This works on linux: open 3 bytes to access
88 int out = ioperm(mPort, 3, 1);
89 //int out = iopl(3);
90 mIsOpen = true;
91 std::cerr << "Initiating parallel port. Return value :["<<out<<"]\n";
92
93
94 // EmulateStandardPort();
95 if(out)
96 {
97 PError::SignalFatalError("Unable to Access Parallel Port. Make sure script is run with root access.\n");
98 }
99
100
101#elif defined(PEBL_WIN32)
102 HINSTANCE hLib;
103 inpfuncPtr inp32fp;
104 oupfuncPtr oup32fp;
105 hLib = LoadLibrary("inpout32.dll");
106 if(hLib == NULL)
107 {
108 PError::SignalFatalError("Unable to load library inpout32.dll. Cannot initiate parallel port device");
109 }
110
111// Get the address of the Input function
112
113 inp32fp = (inpfuncPtr) GetProcAddress(hLib, "Inp32");
114
115 if (inp32fp == NULL)
116 {
117 PError::SignalFatalError("Unable to get Inp32.");
118 }
119
120
121 oup32fp = (oupfuncPtr) GetProcAddress(hLib, "Out32");
122
123 if (oup32fp == NULL) {
124
125 PError::SignalFatalError("Unable to get oup32");
126 }
127
128
129#endif
130
131
132
133
134}
135
136#ifdef SetPort
137#undef SetPort // Undefine Windows API macro that conflicts with our method
138#endif
139
141{
142 if(v=="LPT1")
143 {
145
146 }else if(v=="LPT2")
147 {
149 } else if(v=="LPTX")
150 {
152 }else{
153
154 //SHould allow to set to arbitrary hex-coded port address here.
155 std::cerr << "Cannot set port to ["<<v<<"]. Setting to LPT1.\n";
156 }
157
158}
159
160
162{
163#ifdef PEBL_LINUX
164 int out =ioperm(mPort,3,0);
165#elif defined (PEBL_WIN32)
166
167 //This doesnot work yet:
168// FreeLibrary(hLib);
169#endif
170 mIsOpen = false;
171}
172
173
175//Returns a byte (char) with five lowest bits
176//indicating state of pins:
177// 15, Error
178// 13, Select
179// 12, Paper empty
180// 10, ACK
181// 11. Busy
182
184{
185#if defined(PEBL_LINUX)
186 return inb(mPort+1);
187#elif defined (PEBL_WIN32)
188 return Inp32(mPort+1);
189#else
190 return '\0';
191#endif
192 // return (inb(mPort+1)>>3)^0x10;
193}
194
195//Gets a byte whos bits are pins 2...9 (for dual-mode ports)
196//
198{
199#if defined(PEBL_LINUX)
200 return (inb(mPort));
201
202#elif defined (PEBL_WIN32)
203 return Inp32(mPort);
204#else
205 return '\0';
206#endif
207
208}
209
210//sets the data bytes (pins 2..9) to the specified state.
212{
213#if defined(PEBL_LINUX)
214 outb(x,mPort);
215#elif defined (PEBL_WIN32)
216 Out32(mPort,x);
217#endif
218
219}
220
221
223{
224//Not functional
225
226}
227
228
229// Sets port to output mode. This works for dual-mode ports.
230//
232{
233
234
235#if defined(PEBL_LINUX)
236 unsigned char x;
237 x = inb(mPort+2); //get state of control register
238 outb(x & ~0x20, mPort+2);
239#elif defined (PEBL_WIN32)
240 unsigned char x;
241 x = Inp32(mPort+2);
242 Out32(mPort+2,x&~0x20);
243#endif
244
245
246}
247
248
249// Sets port to input mode
250//
252{
253
254#if defined(PEBL_LINUX)
255 unsigned char x = inb(mPort+2);
256 // turns 7th bit of the control byte on
257 outb( x | 0x20, mPort+2);
258#elif defined (PEBL_WIN32)
259 unsigned char x = Inp32(mPort+2);
260 Out32(mPort+2,x|0x20);
261#endif
262
263
264}
265
266ostream & PParallelPort::SendToStream(ostream & out) const
267{
268 out << "<Generic Parallel Port Object>" << flush;
269 return out;
270}
271
272
273
274//Interface: 0 for data bits; 1 for status bits
276{
277 int out =0;
278 if(iface==0)
279 {
281 SetDataState((char)0);
282 SetInputMode();
283 out = GetDataState();
284 } else
285 if(iface==1)
286 {
287 out = GetStatusState();
288 }
289
290 return out;
291}
#define NULL
Definition BinReloc.cpp:317
@ CDT_PARALLELPORT
Definition PEBLObject.h:65
int Out32(int i, int x)
int Inp32(int i)
PEBLPPort
@ PEBLPPortLPT1
@ PEBLPPortLPTX
@ PEBLPPortLPT2
ComplexDataType mCDT
Definition PEBLObject.h:109
virtual void SetDataState(char x)
virtual void Close()
virtual void Init()
virtual void SetOutputMode()
virtual void SetPort(Variant v)
virtual char GetStatusState()
virtual void SetInputMode()
virtual void EmulateStandardPort()
PParallelPort()
The Standard constructor.
virtual char GetDataState()
virtual int GetState(int iface)
unsigned int mPort
virtual std::ostream & SendToStream(std::ostream &out) const
virtual ~PParallelPort()
The Standard destructor.
void SignalFatalError(const std::string &message)