Accesing parallel port in windows 7

494 views
Skip to first unread message

Marcel Farrés Franch

unread,
Mar 3, 2015, 2:46:07 PM3/3/15
to golan...@googlegroups.com

Hello;


I want to access to printer port/parallel port in a windows machine.

I am trying to use the unsafe package to write/read at the LPT1 to 3 addresses

const (

// Physical addresses of Parallel port

LTP1_BASE = 0x00000408

LTP2_BASE = 0x0000040A

LTP3_BASE = 0x0000040C

LTP4_BASE = 0x0000040E


// Physical addresses of Parallel port

LTP1_ADDRESS = 0x0378

LTP2_ADDRESS = 0x0278


// Where to read/write the data (I/O)

LTP1_DATAPORT = LTP1_BASE + 0x0

LTP2_DATAPORT = LTP2_BASE + 0x0

LTP3_DATAPORT = LTP3_BASE + 0x0

LTP4_DATAPORT = LTP4_BASE + 0x0


// Status of the port (Read ONLY)

LTP1_STATUS = LTP1_BASE + 0x1

LTP2_STATUS = LTP2_BASE + 0x1

LTP3_STATUS = LTP3_BASE + 0x1

LTP4_STATUS = LTP4_BASE + 0x1


// Control Port (I/O)

LTP1_CONTROL = LTP1_BASE + 0x2

LTP2_CONTROL = LTP2_BASE + 0x2

LTP3_CONTROL = LTP3_BASE + 0x2

LTP4_CONTROL = LTP4_BASE + 0x2

)


I have trouble to convert this integers to unsafe pointers

lpt_data = []*uint32{

(*uint32)(unsafe.Pointer(LTP1_DATAPORT)),

(*uint32)(unsafe.Pointer(LTP2_DATAPORT)),

(*uint32)(unsafe.Pointer(LTP3_DATAPORT)),

(*uint32)(unsafe.Pointer(LTP4_DATAPORT)),

}


What is the correct procedure? Has somebody tried before?

Thanks!

Jan Mercl

unread,
Mar 3, 2015, 2:54:26 PM3/3/15
to golan...@googlegroups.com

On Tue, Mar 3, 2015 at 8:46 PM Marcel Farrés Franch <marcel...@gmail.com> wrote:

Those are I/O adresses, not memory addresses.

-j

Matthew Kane

unread,
Mar 3, 2015, 3:01:08 PM3/3/15
to Marcel Farrés Franch, golang-nuts
The rules for converting to unsafe.Pointer allow only pointer types or
uintptrs to be converted to unsafe.Pointer. If you make your constants
into uintptr-typed constants, this should work.
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



--
matt kane's brain
im: mkb.di...@gmail.com (gtalk) / mkbatwerk (AIM)
twitter: the_real_mkb / nynexrepublic
http://hydrogenproject.com

Michael Hofmann

unread,
Mar 4, 2015, 11:25:49 AM3/4/15
to golan...@googlegroups.com
You can't access I/O ports directly from an userspace program in modern
Windows. Serial and parallel ports are supposed to be opened as special
files using the Windows API (at least that's how it was done some years
ago when I last tried something like that).

The MSDN has more information on the subject:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa363196(v=vs.85).aspx

Depending on how Go's file operations are implemented internally, you
might have luck with os.OpenFile("LPT1", os.O_RDWR, 0666) and
reading/writing the returned file.

Regards,
Michael

Marcel Farrés Franch

unread,
Jul 1, 2015, 9:59:46 AM7/1/15
to golan...@googlegroups.com
I finally found the solution!

I found 64 bits versions of IntOut32 dll here http://www.highrez.co.uk/Downloads/InpOut32/

And here the example code it works for me. 


package main

import (
"fmt"
"syscall"
"unicode/utf16"
)

func main() {
fmt.Println("Hello World!")

InpOutDll, err := syscall.LoadLibrary("inpoutx64.dll")
if err != nil {
fmt.Println("Error Loading inpout64 dll, ", err)
}
defer func() {
syscall.FreeLibrary(InpOutDll)
}()

PAddressOut32, err := syscall.GetProcAddress(syscall.Handle(InpOutDll), "Out32")
if err != nil {
fmt.Println("Error getting ProcAdress Out32, ", err)
}
PAddressInp32, err := syscall.GetProcAddress(syscall.Handle(InpOutDll), "Inp32")
if err != nil {
fmt.Println("Error getting ProcAdress Inp32, ", err)
}
//Returns TRUE if the InpOut driver was opened successfully
IsInpOutDriverOpen, err := syscall.GetProcAddress(syscall.Handle(InpOutDll), "IsInpOutDriverOpen")
if err != nil {
fmt.Println("Error getting ProcAdress IsInpOutDriverOpen, ", err)
}

IsOpen, _, callErr := syscall.Syscall(uintptr(IsInpOutDriverOpen), 0, 0, 0, 0)
if callErr != 0 {
fmt.Println("Error in ProcAdress IsInpOutDriverOpen! ", callErr)
}

if uint16(IsOpen) == 1 {
_, _, callErr := syscall.Syscall(uintptr(PAddressOut32),
1,
uintptr(890),
uintptr(0),
0)
if callErr != 0 {
fmt.Println("Error in LTP Write! ", callErr)
}
Word, _, callErr := syscall.Syscall(uintptr(PAddressInp32),
0,
uintptr(890),
0,
0)
if callErr != 0 {
fmt.Println("Error in LTP Read! ", callErr)
} else {
fmt.Println("Data in is ", Word)

}
} else {
fmt.Println("InpOut driver wasn't opened successfully!")
}
}


Thanks for the solutions you propouse!

Marcel Farrés Franch

unread,
Jul 1, 2015, 12:06:37 PM7/1/15
to golan...@googlegroups.com
PD: There is en error!

Delete this line 

import (
"fmt"
"syscall"
--> "unicode/utf16"
)

Marcel Farrés Franch

unread,
Jul 1, 2015, 12:08:47 PM7/1/15
to golan...@googlegroups.com
Use adress 888 to test (there is no inverted pins)
Reply all
Reply to author
Forward
0 new messages