README 1-Wire(TM) API for Java(TM) Version 0.00 Contents * Introduction * Installation, System Requirements * Examples * 1-Wire API Primer * Documentation * TINI * Platform 1-Wire Times * License * Future Introduction The 1-Wire(TM) API for Java(TM) contains classes and interfaces that enable rapid development of 1-Wire applications in the Java language on a variety of platforms. Current platforms tested are Win32, TINI(TM), Linux, and Solaris. Support for particular 1-Wire device types (including iButtons(TM)) is provided through 'containers'. This kit has 27 different 'container' types. All desktop 1-Wire adapters are supported on the Win32 platform through a native driver. TINI has its own native 1-Wire ports. All other platforms are supported through the DS9097U serial adapter using javax.comm. The DS9097U serial adapter information can be found on the Dallas Semiconductor web site: http://www.dalsemi.com/datasheets/pdfs/9097u.pdf ALL Java source code for this kit is provided in the 'src' directory. See the 'License' section. Installation Uncompress the kit file into a directory on your development system. The Kit is currently ~4mB. The development system must be able to run the javac compiler. See your JDK (or equivalent) for minimum system requirements. For every platform except TINI, put the OneWireAPI.jar file found in the 'lib' directory of this kit in your classpath or in the 'ext' directory (for JDK 1.2 and later). TINI This kit supports firmware version 1.01 of the TINI OS. The 1-Wire API in this kit is in a different package than what is provided on TINI so an interface layer has been provided. The application and interface layer are compiled together to produce a 'tini' file. Installation of the application then consists of FTP-ing the file to the TINI system and running it. See the 'TINI' section of this README for details on creating 1-Wire applications on the TINI platform. WIN32 There are two ways to read the 1-Wire network under Win32 (Win95,98,NT,2K): javax.comm with the DS9097U and native drivers. javax.comm/DS9097U Install javax.comm from Sun. Note that javax.comm does NOT come in the JDK or JRE, it must be installed separately. It can be found here: http://java.sun.com/products/javacomm/index.html The DS9097U adapter class in this kit should work with any platform that has javax.comm however only Win32, Linux and Solaris were tested. Native The native driver for Win32 is the iButton-TMEX Runtime Environment 32-bit drivers. Install the standard drivers from here: http://www.ibutton.com/software/tmex/index.html To connect these native drivers to the Java classes copy the driver 'ibtmjava.dll' from the 'lib' directory of this kit into \system (or \system32 for NT). By default the 1-Wire port will be the one selected during the installation of the iButton-TMEX Runtime Environment and changed with the 'Default 1-Wire Net' application. Linux Install javax.comm from Sun. Note that javax.comm does NOT come in the JDK or JRE, it must be installed separately. Retrieve the 'Solaris' version from here: http://java.sun.com/products/javacomm/index.html Only the 'comm.jar' file will be used from this kit. The 'native' part of javax.comm for the Linux platform is provided by 'rxtx'. Info on rxtx can be found here: http://www.rxtx.org Note: for better serial performance (but more CPU utilization) use the 'setserial' utility to set the latency of the port to low. (example: setserial /dev/ttyS0 low_latency) Solaris Install javax.comm from Sun. Note that javax.comm does NOT come in the JDK or JRE, it must be installed separately. Retrieve the 'Solaris' version from here: http://java.sun.com/products/javacomm/index.html Currently the performance of the DS9097U javax.comm example on Solaris(TM) is poor due to two factors. It appears that the native driver has trouble reading 0xFF (perhaps used as an internal flag?). To get around this the driver sends only 'bit' commands which slows it down by 8X. This 'bit' mode can be disabled by setting the following flag in the 'onewire.properties' file: onewire.serial.forcebitsonly=false Also the DS2480 (chip in the DS9097U adapter) has the following valid baud rates: 9600, 19200, 57600, 115200. Of these baud rates, the fastest baud rate observed on the Solaris machine tested was 19200. This slows 'overdrive' reads down by another 6X. The maximum baud rate the driver will try is specified by the following flag in the 'onewire.properties' file: onewire.serial.maxbaud=19200 See the 'Default 1-Wire Network' section for details on the location of the 'onewire.properties' file. Examples The following is a list of the provided examples and a brief explanation. A more detailed explanation may be found in the individual directories under 'examples' in this kit. ADContainerDemo - Find the first 1-Wire device that implement the ADContainer interface (A/D). It has a simple text/menu that allows most of the A/D features to be explored. FindiButtonsConsole - Find all 1-Wire devices (and iButtons) on all available 1-Wire adapters. Note that this application is almost identical to the example of the same name in previous 1-Wire kits. ListOW - Minimal 1-Wire application to list the devices found on the default 1-Wire Network. OWC16Test - Java iButton demo. It has a simple text/menu driven interface that allows applets to be loaded and tested. OWDump - Dump the memory contents of all 1-Wire devices (and iButtons) that contain Memory Banks (see 1-Wire Container Documentation for a description of Memory Banks) on the default 1-Wire Network. OWMemUtil - Text/menu driven utility to read and write the memory of virtually all 1-Wire devices and iButtons (see 1-Wire Container Documentation for a description of Memory Banks). OWNetWatch - Monitor the arrival and departure of all 1-Wire devices on a complex network utilizing the DS2409 Coupler to create branches. Also starts a thread to read the temperature of any DS1920/DS1820 devices found on the network. OWWatch - Monitor the arrival and departure of all 1-Wire devices on a simple 1-Wire Network. This application does not implement sub- branches but has been optimized and is very fast. ReadClock - Find and read all 1-Wire devices that implement the ClockContainer interface. ReadDigPot - Find and read all 1-Wire devices that implement the PotentiometerContainer interface. ReadSwitch - Find and read all 1-Wire devices that implement the SwitchContainer interface. ReadTemp - Find and read all 1-Wire devices that implement the TemperatureContainer interface. SetDefault - Set the default 1-Wire Network by selecting the adapter/port combination. This will write a 'onewire.properties' file in a platform specific location. SHA - DS1963S (SHA iButton) demo that consists of three applications. Two applications to set up a 'co-processor' and 'roving' device and then a 'debit' application to demo a secure monetary transaction. TemperatureContainerDemo - Text/menu driven application to read any 1- Wire device that implements the TemperatureContainer interface. Thermochron - DS1921 temperature gathering demo consisting of two applications. One application 'missions' a DS1921 to collect data and the other 'dumps' the mission data. TINI101BuildTool - Utility to build 1-Wire applications for TINI OS version 1.01. See the 'TINI' section of this document for details. 1-Wire API Primer Communication with the 1-Wire Network is through an 'adapter' (com.dalsemi.onewire.adapter.DSPortAdapter class). The static class, 'com.dalsemi.onewire.OneWireAccessProvider' is used to get an adapter class instance. All of the adapters can be enumerated or a particular or the default adapter can be retrieved (enumerateAllAdapters(), getAdapter(), and getDefaultAdapter()). Each adapter may support multiple 'ports' so a 1-Wire Network consists of an adapter/port combination. Here is a brief list of the operations needed to access and use the 1-Wire network 1. Get an adapter instance 2. Get exclusive use of the 1-Wire network 3. Find a 1-Wire device 4. Perform operations through the device's container 5. End exclusive use of the 1-wire network 6. Free the port when ending application Note that '1.' and '6.' are performed only once at the beginning and end of the application. '2.' through '5.' comprise the bulk of the 1-Wire operations and are performed multiple times during the execution of an application. Default 1-Wire Network The default 1-Wire Network is specified with two properties: onewire.adapter.default - the adapter name, for example DS9097U onewire.port.default - the port name, for example COM1 The values for properties are retrieved in the following search order: 1) System.properties (use -D option on java command line) 2) onewire.properties file in current directory 3) onewire.properties file /lib/ (Desktop) or /etc/ (TINI) If these properties cannot be found then a platform dependent "Smart default" is used. For Win32 native it is the iButton-TMEX default 1- Wire Net, for TINI it is TINIExternalAdapter/serial1, and for all other platforms it is DS9097U/(first serial communications port). See the example application 'SetDefault' to set the default 1-Wire Network adapter/port. Access to 1-Wire Network To allow for multi-thread access to the 1-Wire network, a pair of methods are provided in the adapter class to give exclusive access. They are 'beginExclusive()' and 'endExclusive()'. It is recommended that this pair wrap any access to the 1-Wire network. Finding 1-Wire devices (and iButtons) Each 1-Wire device type is identified with a 1 byte 'family code'. This family code is used to provide the appropriate container and can also be used to limit the search of the 1-Wire Network to one or more device types. For example the following code fragment will search for devices with 0x10 family code. Note that 'adapter' is a working instance of DSPortAdapter. // clear any previous search restrictions adapter.setSearchAllDevices(); adapter.targetAllFamilies(); adapter.setSpeed(adapter.SPEED_REGULAR); // target 0x10 family devices adapter.targetFamily(0x10); // enumerate through all the 1-Wire devices found for(Enumeration owd_enum = adapter.getAllDeviceContainers(); owd_enum.hasMoreElements(); ) { OneWireContainer owd = (OneWireContainer)owd_enum.nextElement(); // do something with the container } Note that there are other search methods (findFirstDevice() and findNextDevice()) that do not automatically create a container and may be quicker if speed is essential. Also see these other methods for search options: getAddress(), getDeviceContainer(), excludeFamily(), setSearchOnlyAlarmDevices(), and setNoResetSearch(). 1-Wire Containers As described in the 'Finding 1-Wire Devices' section, each type of 1- Wire device has a 'family code' that indicates its functionality. The adapter uses this family code to provide a 'container' to interface to it. The container (com.dalsem.onewire.container.OneWireContainer) is then used by the application to manipulate the device. Each container class has the following format OneWireContainerXX where XX is the 'family code'. For example, the DS1920 has a family code of 0x10 so the container to use it is OneWireContainer10. The adapter will automatically provide the correct container. If the family code is unknown then the adapter will provide the super-class generic container. Here is a list of the containers provided in this kit. DS1990A/DS2401(01) - 1-Wire Address only DS1991/DS1425 (02) - Secure memory device DS1994/DS2404 (04) - 4K NVRAM memory and clock/timer/alarms [ClockContainer] {MemoryBank, PagedMemoryBank} DS2405 (05) - single addressable switch DS1993 (06) - 4K NVRAM memory {MemoryBank, PagedMemoryBank} DS1992 (08) - 1K NVRAM memory {MemoryBank, PagedMemoryBank} DS1982/DS2502 (09) - 1K EPROM memory {MemoryBank, PagedMemoryBank, OTPMemoryBank} DS1995 (0A) - 16K NVRAM memory {MemoryBank, PagedMemoryBank} DS1985/DS2505 (0B) - 16K EPROM memory {MemoryBank, PagedMemoryBank, OTPMemoryBank} DS1996 (0C) - 64K NVRAM memory {MemoryBank, PagedMemoryBank} DS1986/DS2506 (0F) - 64K EPROM memory {MemoryBank, PagedMemoryBank, OTPMMemoryBank} DS1920/DS1820/DS18S20 (10) - temperature and alarm trips [TemperatureContainer] DS2406/DS2407 (12) - 1K EPROM memory, dual switch [SwitchContainer] {MemoryBank, PagedMemoryBank, OTPMemoryBank} DS1983/DS2503 (13) - 4K EPROM memory {MemoryBank, PagedMemoryBank, OTPMMemoryBank} DS1971 (14) - 256bit EEPROM memory and OTP register {MemoryBank, PagedMemoryBank, OTPMMemoryBank} DS1954/... (16) - Java Powered Cryptographic iButton DS1963S (18) - 4K NVRAM memory and SHA-1 engine {MemoryBank, PagedMemoryBank} DS1963L (1A) - 4K NVRAM memory with write cycle counters {MemoryBank, PagedMemoryBank} DS2423 (1D) - 4K NVRAM memory with external counters {MemoryBank, PagedMemoryBank} DS2409 (1F) - dual switch, coupler [SwitchContainer] DS2450 (20) - quad A/D [ADContainer] {MemoryBank, PagedMemoryBank} DS1921 (21) - Thermochron temperature logger [TemperatureContainer, ClockContainer] {MemoryBank, PagedMemoryBank} DS1973 (23) - 4K EEPROM memory {MemoryBank, PagedMemoryBank} DS2438 (26) - temperature, A/D [ClockContainer, ADContainer, TemperatureContainer] DS18B20 (28) - adjustable resolution temperature [TemperatureContainer] DS2890 (2C) - single channel digital pot [PotentiometerContainer] DS2760 (30) - temp, current, A/D [ADContainer, TemperatureContainer] Note the interfaces that the container implements are indicated in []. If the getMemoryBanks() methods returns an enumeration, the type of banks returned is indicated in {}. Types of Containers Memory The base class of all containers 'OneWireContainer' has a method called 'getMemoryBanks()' that returns an enumeration of memory bank instances. A memory bank is a section of memory on a 1- Wire device that has specific properties. For example the 1- Wire Network Address of a device is a read-only bank of 8 bytes. This technique is used to get a handle on the diverse types of memory that comprise 1-Wire devices. There are three interfaces that the memory bank may implement. These interfaces are hierarchical: - MemoryBank - basic read/write (getSize(), read(), write()..) - PagedMemoryBank (extends MemoryBank) - paged read/write with packets (getNumberPages(), readPage(), writePagePacket()..) - OTPMemoryBank (extents PagedMemoryBank) - One-Time- Programmable, usually EPROM (canRedirectPage(), lockPage()) See the examples 'OWDump' and 'OWMemUtil' for applications that utilize memory banks. Sensor A 1-Wire Sensor is a device that can make a reading or change the state of something physical (such as a DS2406 switch). Typically the operations of 1-Wire Sensors is memory mapped so writing to a particular location causes the state to change. To accommodate this type of architecture and reduce the number of 1- Wire operations that need to take place, a 'read-modify-write' technique is used. Each Sensor interface is derived from a super-interface (com.dalsemi.onewire.container.OneWireSensor) that contain just two methods: readDevice(), writeDevice(). The read returns a byte array and the write takes a byte array. The byte array is the state of the device. The interfaces that extend this interface have 'get' and 'set' methods that manipulate the byte array. So a OneWireSensor operation is: 1. readDevice() 2. 'get' and 'set' methods 3. writeDevice() The following is a list of the interfaces and a brief description. Note that the container list above indicates the interfaces used. ADContainer - A/D sensor ClockContainer - clock SwitchContainer - switch TemperatureContainer - temperature reading sensor PotentiometerContainer - digital potentiometer device Other The most celebrated 'other' device Dallas Semiconductor has is the Java Powered Cryptographic iButton. This is a microprocessor in an iButton package that has a Java Virtual Machine that can run Java applets. These applets typically perform highly secure cryptographic operations. See this web page for more information: http://www.ibutton.com/ibuttons/java.html Documentation See the 'docs' directory for a complete javadoc of the com.dalsemi.onewire package. The examples are not javadoc'ed but individual example directories may contain documentation. All of the Java source in this kit is provided so if the documentation is not clear or is non-existent, look in the source. Dallas Semiconductor's 1-Wire device data sheets can be found by part number here: http://www.dalsemi.com/datasheets/pdfindex.html TINI TINI is a micro-controller with a Java Virtual Machine. See this page for more information. http://www.ibutton.com/TINI/index.html Since its memory resources are limited, only the containers and necessary classes needed for the application are transferred to TINI. The utility 'TINI101BuildTool' was created to build only the necessary files. See this example's directory for further information. For developers that are already doing 1-Wire applications on TINI you will note that the package name has changed (com.ibutton -> com.dalsemi.onewire). There are also several other method name changes to remove iButton and use the more generic 1-Wire nomenclature. There is a script provided in the 'TINI101BuildTool' called 'changeapi.txt' that uses the sed utility to convert Java source to use the new names. For applications not on UN!X platforms here are the strings that can be replaced to do the conversion: Find Replace ------------------------------------------------------- com.ibutton com.dalsemi.onewire iButtonContainer OneWireContainer iButtonAccess OneWireAccess iButtonException OneWireException getFirstiButton getFirstDeviceContainer getNextiButton getNextDeviceContainer FirstiButton FirstDevice NextiButton NextDevice GetContainer getDeviceContainer SetSearchOnlyAlarmingiButtons setSearchOnlyAlarmingDevices SetSearchAlliButtons setSearchAllDevices GetAlliButtons getAllDeviceContainers GetiButtonPartName getName Platform 1-Wire Times The following is a rough time estimate of the 1-Wire speeds on the tested platforms. There are 7 typical 1-Wire operations done in standard and overdrive speed. The times are expressed in Microseconds. The last line is the output of the 'TIME_TEST' mode of the included OWDump demo performed on a DS1996. TINI TINI Win32 Win32 Linux Solaris* (ext) (int) (javax) (native) (javax) (javax) DS9097U DS1410E DS9097U DS9097U |---------------------------------------------------------------------- |-----Standard Speed reset() 2533us 2466 3300 9333 7583 29956 putBit() 1700 1266 2400 366 6543 30010 putByte() 1966 1666 2933 933 6980 30096 findFirstDevice() 23300 18600 26900 35700 40050 62990 select() 10300 8900 16500 18650 24920 150245 isPresent() 21700 16800 27400 35200 40040 63590 dataBlock(32) 23400 25800 34600 32400 40500 360790 |-----Overdrive Speed reset() 1566 1200 2400 200 6610 30133 putBit() 1600 1233 2366 166 6493 30030 putByte() 1533 1400 1100 366 980 31130 findFirstDevice() 11400 9400 7200 12600 6820 62790 select() 3800 3750 3250 2500 2830 150345 isPresent() 9700 7700 3300 6000 5570 64190 dataBlock(32) 4600 6900 3300 7700 4640 360590 Read DS1996 (OWDump) 1030ms 1500 770 1970 931 40846 * Note that the Solaris times are unusually high due to a workaround we were having with javax.comm on that platform and a baud rate limitation. See the Solaris section for details. License Dallas Semiconductor has selected the least restrictive license it could find to apply to the Java source code in this kit. It is based almost word for word on the Xfree86 license (http://www.xfree86.org/4.0/LICENSE1.html). It basically says you can do anything you want with this code. If you distribute the source then just leave the license blurb at the top of the source files. That's it. See the license in the 'COPYRIGHT' file and at the top of all of the source files. Future This version of the 1-Wire API for Java is chiefly a vehicle to provide TINI developers with a peek at the 1-Wire support that will be seen in TINI 1.02. Feedback from these developers may change the structure of the API in hopefully only minor ways. It is our intention that after TINI 1.02 is released, this API will be THE way to do 1-Wire Java applications on any platform. One of our TODO items is to build on the MemoryBank foundation in these containers to provide complete support for the TMEX File Structure.