Testing out the PPD42 Air Quality Sensor, with an MSP430 Launchpad and graphing the data with GNUplot.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

825 lines
24 KiB

/*-------------------------------------------------------------------------
| A wrapper to convert RXTX into Linux Java Comm
| Copyright 1998 Kevin Hester, kevinh@acm.org
| Copyright 2000-2004 Trent Jarvi, taj@www.linux.org.uk
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Library General Public
| License as published by the Free Software Foundation; either
| version 2 of the License, or (at your option) any later version.
|
| This library 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
| Library General Public License for more details.
|
| You should have received a copy of the GNU Library General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--------------------------------------------------------------------------*/
/* Martin Pool <mbp@linuxcare.com> added support for explicitly-specified
* lists of ports, October 2000. */
/* Joseph Goldstone <joseph@lp.com> reorganized to support registered ports,
* known ports, and scanned ports, July 2001 */
package gnu.io;
import java.util.*;
import java.io.*;
import java.util.StringTokenizer;
/**
This is the JavaComm for Linux driver.
*/
public class RXTXCommDriver implements CommDriver
{
private final static boolean debug = false;
private final static boolean devel = true;
static
{
if(debug ) System.out.println("RXTXCommDriver {}");
/*
System.loadLibrary( "rxtxSerial" );
*/
/*
Perform a crude check to make sure people don't mix
versions of the Jar and native lib
Mixing the libs can create a nightmare.
It could be possible to move this over to RXTXVersion
but All we want to do is warn people when first loading
the Library.
*/
String JarVersion = RXTXVersion.getVersion();
String LibVersion = nativeGetVersion();
if ( devel )
{
System.out.println("Devel Library");
System.out.println("=========================================");
System.out.println("Native lib Version = " + JarVersion );
System.out.println("Java lib Version = " + LibVersion );
}
/* FIXME static not working
if ( ! JarVersion.equals( LibVersion ) )
{
System.out.println( "WARNING: RXTX Version mismatch\n\tJar version = " + JarVersion + "\n\tnative lib Version = " + LibVersion );
}
else if ( debug )
{
System.out.println( "RXTXCommDriver:\n\tJar version = " + JarVersion + "\n\tnative lib Version = " + LibVersion );
}
*/
}
/** Get the Serial port prefixes for the running OS */
private String deviceDirectory;
private String osName;
private static native String nativeGetVersion();
private native boolean registerKnownPorts(int PortType);
private native boolean isPortPrefixValid(String dev);
private native boolean testRead(String dev, int type);
private native String getDeviceDirectory();
private final String[] getValidPortPrefixes(String CandidatePortPrefixes[])
{
/*
256 is the number of prefixes ( COM, cua, ttyS, ...) not
the number of devices (ttyS0, ttyS1, ttyS2, ...)
On a Linux system there are about 400 prefixes in
deviceDirectory.
registerScannedPorts() assigns CandidatePortPrefixes to
something less than 50 prefixes.
Trent
*/
String ValidPortPrefixes[]=new String [256];
if (debug)
System.out.println("\nRXTXCommDriver:getValidPortPrefixes()");
if(CandidatePortPrefixes==null)
{
if (debug)
System.out.println("\nRXTXCommDriver:getValidPortPrefixes() No ports prefixes known for this System.\nPlease check the port prefixes listed for " + osName + " in RXTXCommDriver:registerScannedPorts()\n");
}
int i=0;
for(int j=0;j<CandidatePortPrefixes.length;j++){
if(isPortPrefixValid(CandidatePortPrefixes[j])) {
ValidPortPrefixes[i++]=
new String(CandidatePortPrefixes[j]);
}
}
String[] returnArray=new String[i];
System.arraycopy(ValidPortPrefixes, 0, returnArray, 0, i);
if(ValidPortPrefixes[0]==null)
{
if (debug)
{
System.out.println("\nRXTXCommDriver:getValidPortPrefixes() No ports matched the list assumed for this\nSystem in the directory " + deviceDirectory + ". Please check the ports listed for \"" + osName + "\" in\nRXTXCommDriver:registerScannedPorts()\nTried:");
for(int j=0;j<CandidatePortPrefixes.length;j++){
System.out.println("\t" +
CandidatePortPrefixes[i]);
}
}
}
else
{
if (debug)
System.out.println("\nRXTXCommDriver:getValidPortPrefixes()\nThe following port prefixes have been identified as valid on " + osName + ":\n");
/*
for(int j=0;j<returnArray.length;j++)
{
if (debug)
System.out.println("\t" + j + " " +
returnArray[j]);
}
*/
}
return returnArray;
}
/** handle solaris/sunos /dev/cua/a convention */
private void checkSolaris(String PortName, int PortType)
{
char p[] = { 91 };
for( p[0] =97 ;p[0] < 123; p[0]++ )
{
if (testRead(PortName.concat(new String(p)),PortType))
{
CommPortIdentifier.addPortName(
PortName.concat(new String(p)),
PortType,
this
);
}
}
}
private void registerValidPorts(
String CandidateDeviceNames[],
String ValidPortPrefixes[],
int PortType
) {
int i =0;
int p =0 ;
/* FIXME quick fix to get COM1-8 on windows working. The
Read test is not working properly and its crunch time...
if(osName.toLowerCase().indexOf("windows") != -1 )
{
for( i=0;i < CandidateDeviceNames.length;i++ )
{
CommPortIdentifier.addPortName( CandidateDeviceNames[i],
PortType, this );
}
return;
}
*/
if (debug)
{
System.out.println("Entering registerValidPorts()");
/* */
System.out.println(" Candidate devices:");
for (int dn=0;dn<CandidateDeviceNames.length;dn++)
System.out.println(" " +
CandidateDeviceNames[dn]);
System.out.println(" valid port prefixes:");
for (int pp=0;pp<ValidPortPrefixes.length;pp++)
System.out.println(" "+ValidPortPrefixes[pp]);
/* */
}
if ( CandidateDeviceNames!=null && ValidPortPrefixes!=null)
{
for( i = 0;i<CandidateDeviceNames.length; i++ ) {
for( p = 0;p<ValidPortPrefixes.length; p++ ) {
/* this determines:
* device file Valid ports
* /dev/ttyR[0-9]* != /dev/ttyS[0-9]*
* /dev/ttySI[0-9]* != /dev/ttyS[0-9]*
* /dev/ttyS[0-9]* == /dev/ttyS[0-9]*
* Otherwise we check some ports
* multiple times. Perl would rock
* here.
*
* If the above passes, we try to read
* from the port. If there is no err
* the port is added.
* Trent
*/
String V = ValidPortPrefixes[ p ];
int VL = V.length();
String C = CandidateDeviceNames[ i ];
if( C.length() < VL ) continue;
String CU =
C.substring(VL).toUpperCase();
String Cl =
C.substring(VL).toLowerCase();
if( !( C.regionMatches(0, V, 0, VL ) &&
CU.equals( Cl ) ) )
{
continue;
}
String PortName;
if(osName.toLowerCase().indexOf("windows") == -1 )
{
PortName =
new String(deviceDirectory +
C );
}
else
{
PortName =
new String( C );
}
if (debug)
{
System.out.println( C +
" " + V );
System.out.println( CU +
" " + Cl );
}
if( osName.equals("Solaris") ||
osName.equals("SunOS"))
checkSolaris(PortName,PortType);
else if (testRead(PortName, PortType))
{
CommPortIdentifier.addPortName(
PortName,
PortType,
this
);
}
}
}
}
if (debug)
System.out.println("Leaving registerValidPorts()");
}
/*
* initialize() will be called by the CommPortIdentifier's static
* initializer. The responsibility of this method is:
* 1) Ensure that that the hardware is present.
* 2) Load any required native libraries.
* 3) Register the port names with the CommPortIdentifier.
*
* <p>From the NullDriver.java CommAPI sample.
*
* added printerport stuff
* Holger Lehmann
* July 12, 1999
* IBM
* Added ttyM for Moxa boards
* Removed obsolete device cuaa
* Peter Bennett
* January 02, 2000
* Bencom
*/
/**
* Determine the OS and where the OS has the devices located
*/
public void initialize()
{
if (debug) System.out.println("RXTXCommDriver:initialize()");
osName=System.getProperty("os.name");
deviceDirectory=getDeviceDirectory();
/*
First try to register ports specified in the properties
file. If that doesn't exist, then scan for ports.
*/
for (int PortType=CommPortIdentifier.PORT_SERIAL;PortType<=CommPortIdentifier.PORT_PARALLEL;PortType++) {
if (!registerSpecifiedPorts(PortType)) {
if (!registerKnownPorts(PortType)) {
registerScannedPorts(PortType);
}
}
}
}
private void addSpecifiedPorts(String names, int PortType)
{
final String pathSep = System.getProperty("path.separator", ":");
final StringTokenizer tok = new StringTokenizer(names, pathSep);
if (debug)
System.out.println("\nRXTXCommDriver:addSpecifiedPorts()");
while (tok.hasMoreElements())
{
String PortName = tok.nextToken();
if (testRead(PortName, PortType))
CommPortIdentifier.addPortName(PortName,
PortType, this);
}
}
/*
* Register ports specified in the file "gnu.io.rxtx.properties"
* Key system properties:
* gnu.io.rxtx.SerialPorts
* gnu.io.rxtx.ParallelPorts
*
* Tested only with sun jdk1.3
* The file gnu.io.rxtx.properties must reside in the java extension dir
*
* Example: /usr/local/java/jre/lib/ext/gnu.io.rxtx.properties
*
* The file contains the following key properties:
*
* gnu.io.rxtx.SerialPorts=/dev/ttyS0:/dev/ttyS1:
* gnu.io.rxtx.ParallelPorts=/dev/lp0:
*
*/
private boolean registerSpecifiedPorts(int PortType)
{
String val = null;
try
{
String ext_dir=System.getProperty("java.ext.dirs")+System.getProperty("file.separator");
FileInputStream rxtx_prop=new FileInputStream(ext_dir+"gnu.io.rxtx.properties");
Properties p=new Properties(System.getProperties());
p.load(rxtx_prop);
System.setProperties(p);
}catch(Exception e){
if (debug){
System.out.println("The file: gnu.io.rxtx.properties doesn't exists.");
System.out.println(e.toString());
}//end if
}//end catch
if (debug)
System.out.println("checking for system-known ports of type "+PortType);
if (debug)
System.out.println("checking registry for ports of type "+PortType);
switch (PortType) {
case CommPortIdentifier.PORT_SERIAL:
if ((val = System.getProperty("gnu.io.rxtx.SerialPorts")) == null)
val = System.getProperty("gnu.io.SerialPorts");
break;
case CommPortIdentifier.PORT_PARALLEL:
if ((val = System.getProperty("gnu.io.rxtx.ParallelPorts")) == null)
val = System.getProperty("gnu.io.ParallelPorts");
break;
default:
if (debug)
System.out.println("unknown port type "+PortType+" passed to RXTXCommDriver.registerSpecifiedPorts()");
}
if (val != null) {
addSpecifiedPorts(val, PortType);
return true;
} else return false;
}
/*
* Look for all entries in deviceDirectory, and if they look like they should
* be serial ports on this OS and they can be opened then register
* them.
*
*/
private void registerScannedPorts(int PortType)
{
String[] CandidateDeviceNames;
if (debug)
System.out.println("scanning device directory "+deviceDirectory+" for ports of type "+PortType);
if(osName.equals("Windows CE"))
{
String[] temp =
{ "COM1:", "COM2:","COM3:","COM4:",
"COM5:", "COM6:", "COM7:", "COM8:" };
CandidateDeviceNames=temp;
}
else if(osName.toLowerCase().indexOf("windows") != -1 )
{
/*
{ "COM1:", "COM2:","COM3:","COM4:",
"COM5:", "COM6:", "COM7:", "COM8:" };
*/
/* //./name is supposed to work for port numbers > 8 */
/*
{ "//./COM1", "//./COM2", "//./COM3",
"//./COM4", "//./COM5", "//./COM6",
"//./COM7", "//./COM8" };
*/
String[] temp =
{
"COM1", "COM2", "COM3",
"COM4", "COM5", "COM6",
"COM7", "COM8",
/*
OK, you asked for it The thread gods will
not like this.
*/
"COM9", "COM10", "COM11",
"COM12", "COM13", "COM14",
"COM15", "COM16",
/*
Lets toss in LPT too!
*/
"LPT1", "LPT2", "LPT3"
};
/*
{ "COM1", "COM2","COM3","COM4",
"COM5", "COM6", "COM7", "COM8" };
*/
CandidateDeviceNames=temp;
}
else if ( osName.equals("Solaris") || osName.equals("SunOS"))
{
/* Solaris uses a few different ways to identify ports.
They could be /dev/term/a /dev/term0 /dev/cua/a /dev/cuaa
the /dev/???/a appears to be on more systems.
The uucp lock files should not cause problems.
*/
/*
File dev = new File( "/dev/term" );
String deva[] = dev.list();
dev = new File( "/dev/cua" );
String devb[] = dev.list();
String[] temp = new String[ deva.length + devb.length ];
for(int j =0;j<deva.length;j++)
deva[j] = "term/" + deva[j];
for(int j =0;j<devb.length;j++)
devb[j] = "cua/" + devb[j];
System.arraycopy( deva, 0, temp, 0, deva.length );
System.arraycopy( devb, 0, temp,
deva.length, devb.length );
if( debug ) {
for( int j = 0; j< temp.length;j++)
System.out.println( temp[j] );
}
CandidateDeviceNames=temp;
*/
/*
ok.. Look the the dirctories representing the port
kernel driver interface.
If there are entries there are possibly ports we can
use and need to enumerate.
*/
String term[] = new String[2];
int l = 0;
File dev = null;
dev = new File( "/dev/term" );
if( dev.list().length > 0 );
term[l++] = new String( "term/" );
/*
dev = new File( "/dev/cua0" );
if( dev.list().length > 0 );
term[l++] = new String( "cua/" );
*/
String[] temp = new String[l];
for(l--;l >= 0;l--)
temp[l] = term[l];
CandidateDeviceNames=temp;
}
else
{
File dev = new File( deviceDirectory );
String[] temp = dev.list();
CandidateDeviceNames=temp;
}
if (CandidateDeviceNames==null)
{
if (debug)
System.out.println("RXTXCommDriver:registerScannedPorts() no Device files to check ");
return;
}
String CandidatePortPrefixes[] = {};
switch (PortType) {
case CommPortIdentifier.PORT_SERIAL:
if (debug)
System.out.println("scanning for serial ports for os "+osName);
if(osName.equals("Linux"))
{
String[] Temp = {
"ttyS", // linux Serial Ports
"ttySA" // for the IPAQs
};
CandidatePortPrefixes=Temp;
}
else if(osName.equals("Linux-all-ports"))
{
/* if you want to enumerate all ports ~5000
possible, then replace the above with this
*/
String[] Temp = {
"comx", // linux COMMX synchronous serial card
"holter", // custom card for heart monitoring
"modem", // linux symbolic link to modem.
"ttyircomm", // linux IrCommdevices (IrDA serial emu)
"ttycosa0c", // linux COSA/SRP synchronous serial card
"ttycosa1c", // linux COSA/SRP synchronous serial card
"ttyC", // linux cyclades cards
"ttyCH",// linux Chase Research AT/PCI-Fast serial card
"ttyD", // linux Digiboard serial card
"ttyE", // linux Stallion serial card
"ttyF", // linux Computone IntelliPort serial card
"ttyH", // linux Chase serial card
"ttyI", // linux virtual modems
"ttyL", // linux SDL RISCom serial card
"ttyM", // linux PAM Software's multimodem boards
// linux ISI serial card
"ttyMX",// linux Moxa Smart IO cards
"ttyP", // linux Hayes ESP serial card
"ttyR", // linux comtrol cards
// linux Specialix RIO serial card
"ttyS", // linux Serial Ports
"ttySI",// linux SmartIO serial card
"ttySR",// linux Specialix RIO serial card 257+
"ttyT", // linux Technology Concepts serial card
"ttyUSB",//linux USB serial converters
"ttyV", // linux Comtrol VS-1000 serial controller
"ttyW", // linux specialix cards
"ttyX" // linux SpecialX serial card
};
CandidatePortPrefixes=Temp;
}
else if(osName.toLowerCase().indexOf("qnx") != -1 )
{
String[] Temp = {
"ser"
};
CandidatePortPrefixes=Temp;
}
else if(osName.equals("Irix"))
{
String[] Temp = {
"ttyc", // irix raw character devices
"ttyd", // irix basic serial ports
"ttyf", // irix serial ports with hardware flow
"ttym", // irix modems
"ttyq", // irix pseudo ttys
"tty4d",// irix RS422
"tty4f",// irix RS422 with HSKo/HSki
"midi", // irix serial midi
"us" // irix mapped interface
};
CandidatePortPrefixes=Temp;
}
else if(osName.equals("FreeBSD")) //FIXME this is probably wrong
{
String[] Temp = {
"ttyd", //general purpose serial ports
"cuaa", //dialout serial ports
"ttyA", //Specialix SI/XIO dialin ports
"cuaA", //Specialix SI/XIO dialout ports
"ttyD", //Digiboard - 16 dialin ports
"cuaD", //Digiboard - 16 dialout ports
"ttyE", //Stallion EasyIO (stl) dialin ports
"cuaE", //Stallion EasyIO (stl) dialout ports
"ttyF", //Stallion Brumby (stli) dialin ports
"cuaF", //Stallion Brumby (stli) dialout ports
"ttyR", //Rocketport dialin ports
"cuaR", //Rocketport dialout ports
"stl" //Stallion EasyIO board or Brumby N
};
CandidatePortPrefixes=Temp;
}
else if(osName.equals("NetBSD")) // FIXME this is probably wrong
{
String[] Temp = {
"tty0" // netbsd serial ports
};
CandidatePortPrefixes=Temp;
}
else if ( osName.equals("Solaris")
|| osName.equals("SunOS"))
{
String[] Temp = {
"term/",
"cua/"
};
CandidatePortPrefixes=Temp;
}
else if(osName.equals("HP-UX"))
{
String[] Temp = {
"tty0p",// HP-UX serial ports
"tty1p" // HP-UX serial ports
};
CandidatePortPrefixes=Temp;
}
else if(osName.equals("UnixWare") ||
osName.equals("OpenUNIX"))
{
String[] Temp = {
"tty00s", // UW7/OU8 serial ports
"tty01s",
"tty02s",
"tty03s"
};
CandidatePortPrefixes=Temp;
}
else if (osName.equals("OpenServer"))
{
String[] Temp = {
"tty1A", // OSR5 serial ports
"tty2A",
"tty3A",
"tty4A",
"tty5A",
"tty6A",
"tty7A",
"tty8A",
"tty9A",
"tty10A",
"tty11A",
"tty12A",
"tty13A",
"tty14A",
"tty15A",
"tty16A",
"ttyu1A", // OSR5 USB-serial ports
"ttyu2A",
"ttyu3A",
"ttyu4A",
"ttyu5A",
"ttyu6A",
"ttyu7A",
"ttyu8A",
"ttyu9A",
"ttyu10A",
"ttyu11A",
"ttyu12A",
"ttyu13A",
"ttyu14A",
"ttyu15A",
"ttyu16A"
};
CandidatePortPrefixes=Temp;
}
else if (osName.equals("Compaq's Digital UNIX") || osName.equals("OSF1"))
{
String[] Temp = {
"tty0" // Digital Unix serial ports
};
CandidatePortPrefixes=Temp;
}
else if(osName.equals("BeOS"))
{
String[] Temp = {
"serial" // BeOS serial ports
};
CandidatePortPrefixes=Temp;
}
else if(osName.equals("Mac OS X"))
{
String[] Temp = {
// Keyspan USA-28X adapter, USB port 1
"cu.KeyUSA28X191.",
// Keyspan USA-28X adapter, USB port 1
"tty.KeyUSA28X191.",
// Keyspan USA-28X adapter, USB port 2
"cu.KeyUSA28X181.",
// Keyspan USA-28X adapter, USB port 2
"tty.KeyUSA28X181.",
// Keyspan USA-19 adapter
"cu.KeyUSA19181.",
// Keyspan USA-19 adapter
"tty.KeyUSA19181."
};
CandidatePortPrefixes=Temp;
}
else if(osName.toLowerCase().indexOf("windows") != -1 )
{
String[] Temp = {
"COM" // win32 serial ports
//"//./COM" // win32 serial ports
};
CandidatePortPrefixes=Temp;
}
else
{
if (debug)
System.out.println("No valid prefixes for serial ports have been entered for "+osName + " in RXTXCommDriver.java. This may just be a typo in the method registerScanPorts().");
}
break;
case CommPortIdentifier.PORT_PARALLEL:
if (debug)
System.out.println("scanning for parallel ports for os "+osName);
/** Get the Parallel port prefixes for the running os
* Holger Lehmann
* July 12, 1999
* IBM
*/
if(osName.equals("Linux")
/*
|| osName.equals("NetBSD") FIXME
|| osName.equals("HP-UX") FIXME
|| osName.equals("Irix") FIXME
|| osName.equals("BeOS") FIXME
|| osName.equals("Compaq's Digital UNIX") FIXME
*/
)
{
String[] temp={
"lp" // linux printer port
};
CandidatePortPrefixes=temp;
}
else if(osName.equals("FreeBSD"))
{
String[] temp={
"lpt"
};
CandidatePortPrefixes=temp;
}
else if(osName.toLowerCase().indexOf("windows") != -1 )
{
String[] temp={
"LPT"
};
CandidatePortPrefixes=temp;
}
else /* printer support is green */
{
String [] temp={};
CandidatePortPrefixes=temp;
}
break;
default:
if (debug)
System.out.println("Unknown PortType "+PortType+" passed to RXTXCommDriver.registerScannedPorts()");
}
registerValidPorts(CandidateDeviceNames, CandidatePortPrefixes, PortType);
}
/*
* <p>From the NullDriver.java CommAPI sample.
*/
/**
* @param PortName The name of the port the OS recognizes
* @param PortType CommPortIdentifier.PORT_SERIAL or PORT_PARALLEL
* @returns CommPort
* getCommPort() will be called by CommPortIdentifier from its
* openPort() method. PortName is a string that was registered earlier
* using the CommPortIdentifier.addPortName() method. getCommPort()
* returns an object that extends either SerialPort or ParallelPort.
*/
public CommPort getCommPort( String PortName, int PortType )
{
if (debug) System.out.println("RXTXCommDriver:getCommPort("
+PortName+","+PortType+")");
try {
switch (PortType) {
case CommPortIdentifier.PORT_SERIAL:
if(osName.toLowerCase().indexOf("windows") == -1 )
{
return new RXTXPort( PortName );
}
else
{
return new RXTXPort( deviceDirectory + PortName );
}
case CommPortIdentifier.PORT_PARALLEL:
//return new LPRPort( PortName );
default:
if (debug)
System.out.println("unknown PortType "+PortType+" passed to RXTXCommDriver.getCommPort()");
}
} catch( PortInUseException e ) {
if (debug)
System.out.println(
"Port "+PortName+" in use by another application");
}
return null;
}
/* Yikes. Trying to call println from C for odd reasons */
public void Report( String arg )
{
System.out.println(arg);
}
}