LPTTCL ver. 3.0
To overcome some of the limitations of LPTTCL v.1.0, a new wrapper has been added to the Inpout32.dll available at Logix4U [4].
This new low-level access library allows you to avoid any installation and uninstall (a great advantage!!) and offers better compatibility on WinXP and on all machines (as we were reported that some desktops did not work properly with rev 1.0). In addition:
- we added commands to address a generic offest (perfect for accessing the LPT Extended Control Register, useful for advanced tricks.....)
- allowed 32-bit base address (useful for PCI-based parallel port cards)
- added LPT selection by number and not only by address (finally); now you can select LPT1 or LPT2 and avoid looking on the Hardware Device Manager to find out the base address
- we tried to make the command set fully backward-compatible with version 1.0; so, on existing code you may only change LPT selection (if you wish).
Please notice that the new LPT selection mode and the removed requirement for installation allow you to simply copy a few files with a wrapped executable, and you have a perfectly transportable Tcl application with LPT access. We do this with TclKit and Freewrap all the time.
Installation can be as follows: keep both DLLs in your working directory, or copy them on the system32 folder.
Consider that the extension is just released, so please report any issues you may find. In particular, we could not verify proper access with a PCI card; these LPT cards typically require a high base address ( > 1024).
LPTTCL ver. 1.0
There are still reasons to keep the old LPTTCL around: access is a faster, and may be interesting for slower hosts; also for Windows 98 it does not require installation.
A brief summary of its characteristics:
- parallel port access is rather easy on Win98, but requires a driver on NT, 2000 and XP. LPTTCL attempts to provide the same technique on all three platforms.
- read and write access to data port, control and status registers
- it has been designed for simple control of external devices and emulation of serial protocols as I2C.
- uninstall must be done manually (sorry for this), by deleting the files and by removing the HKEY_LOCAL_MACHINE\SYSTEM\CURRENTCONTROLSET\SERVICES\ZPPORT entry from the Windows registry.
- only works for low-range I/O (ISA style). If you have a PCI parallel port card that maps into a high I/O, you will not be able to access it.
- you need to explicitly specify the LPT base address by issuing a lp_setba command; there is no detection of base address from BIOS.
- LPTTCL must be installed and run by a user with administrator privileges (not relevant on Win98)
- we received feedback from many programmers that use it for access to custom hardware, development boards and similar. Someone has used it for PLD download, others for I2C bit-bang emulation, others for adding pushbuttons to a PC...
- LPTTCL does NOT conflict with Windriver-based drivers (i.e., Xilinx parallel port cable), provided, of course, you are not using both on the same port...
Users have reported that it works correctly under Windows XP, but on some hosts it fails; we could not identify the reason, but in any case the new 3.0 version works fine for the same users.
Commands summary
both versions
| lpt_getba | returns base address of selected LPT |
| lpt_setba <addr> | selects LPT at base address <addr> |
| lpt_rddata | returns LPT data register value |
| lpt_rdstat | returns LPT status register value |
| lpt_rdctrl | returns LPT control register value |
| lpt_wrdata <val> | writes <val> to LPT data register |
| lpt_wrstat <val> | writes <val> to LPT status register |
| lpt_wrctrl <val> | writes <val> to LPT control register |
only in version 3.0
| lpt_rdreg <offset> | generic register read at (base_address + offset) |
| lpt_wrreg <offset> <val> | generic register write at (base_address + offset) |
| lpt_setport <id> | selects LPT<id>, where <id> = 1,2,3,...; |
| lpt_getport | returns 1,2,.... |
Notes:
- lpt_getba returns -1 if lpt_setport points to a non-existing LPT
- lpt_setba now accepts a 32-bit value
Basic startup code
console show wm withdraw . load lpttcl set ver [package require lpttcl] puts [format "LPTTCL, version %s" $ver] puts "---------------------" puts [format "Current port: LPT%d" [lpt_getport]] puts [format "Base address: 0x%08X" [lpt_getba]] puts " " puts [format "Data register: 0x%02X" [lpt_rdreg 0]] puts [format "Status register: 0x%02X" [lpt_rdreg 1]] puts [format "Control register: 0x%02X" [lpt_rdreg 2]] puts [format "Extended control register: 0x%02X" [lpt_rdreg 0x402]]
and its output on a console:
LPTTCL, version 3.0 --------------------- Current port: LPT1 Base address: 0x00000378 Data register: 0xAA Status register: 0x78 Control register: 0x0C Extended control register: 0x15
Utilities
Note that in ver. 3.0 you can now perform a quick autoscan of available LPT ports:
proc LPTscan {{nmax 8}} {
for {set i 1} {$i < $nmax} {incr i} {
lpt_setport $i
if {[lpt_getba] == -1} {
puts "LPT$i absent"
} else {
puts "LPT$i present"
}
}
}
We made some profiling of access speed (when you insert real code in the loop, it goes slower); note that the test is compatible with both versions.
proc toggle {num} {
for {set i 0} {$i < $num} {incr i} {
lpt_wrdata 0x55
lpt_wrdata 0xAA
}
}
proc getmaxfreq {{ntimes 10000}} {
set tt [time {toggle $ntimes}]
scan $tt %i tt
set mf [expr (2000 * $ntimes / $tt)] ;# 2 writes, expressed in kHz
puts "Max frequency is $mf kHz"
}
Some results (using freewrap 5.4, based on Tcl/tk 8.3.5) using getmaxfreq:
- laptop, P4 M 1.6 GHz, XP prof.: around 130 kHz
- desktop, P4 2.4 GHz, XP prof.: around 210 kHz
The old version runs faster (around 2,5 times faster on some PCs!!); furthermore, newer tcl versions are slower. As an example, we measured that 8.3.5 (freewrap) is about 20% faster than 8.4.7 (activestate).