Tag: Paraport

PB Parallel Port Library

Posted by on January 12, 2011

What is it:

This is a minimalist  library based on the inpout32 DLL

Basically I wrapped the original library and added a whole bunch of useful constants to easily access the Control and Status registers while keeping things clean and simple.

This library is currently being used on a side project I’ve been working on with a friend, since he doesn’t have any μController experience we decided to use LPT for the time being.

The code:

 
; 	Minimalist Library for Parallel port access based on inpout32.dll 
;		by Gustavo J. Fiorenza AKA GuShH (info@gushh.net - info@gushh.com.ar)
;		Version 1.0 - 11/01/2011
 
EnableExplicit
 
; Default LPT Addresses.
#PARALLEL_PORT_LPT1						= $3BC
#PARALLEL_PORT_LPT2						= $378
#PARALLEL_PORT_LPT3						= $278
 
; Register offsets.
#PARALLEL_PORT_STATUS						= $01
#PARALLEL_PORT_CONTROL						= $02
 
; Shared with Data Register.
#PARALLEL_PORT_OFF						= $00
#PARALLEL_PORT_BIT0						= $01
#PARALLEL_PORT_BIT1						= $02
#PARALLEL_PORT_BIT2						= $04
#PARALLEL_PORT_BIT3						= $08
#PARALLEL_PORT_BIT4						= $10
#PARALLEL_PORT_BIT5						= $20
#PARALLEL_PORT_BIT6						= $40
#PARALLEL_PORT_BIT7						= $80
 
XIncludeFile "ParallelPort_Constants.pbi" 	; All of the helper, non-essential constants are defined here.
 
 
Structure PARALLEL_PORT
	Handle.i
	Port.i
	LastData.i
EndStructure
 
 
;- Instance construction and destruction
 
Procedure.i ParallelPort_Create( Port.i = #PARALLEL_PORT_LPT2 )
 
	Define.PARALLEL_PORT *this = AllocateMemory( SizeOf(PARALLEL_PORT) )
	If *this
 
		*this\Port 	= port
		*this\Handle 	= OpenLibrary( #PB_Any, "inpout32.dll" )
 
		If IsLibrary( *this\Handle )
			ProcedureReturn *this
		Else
			Debug "Couldn't load inpout32.dll"
			FreeMemory(*this)
			ProcedureReturn #Null
		EndIf
 
	EndIf
 
EndProcedure
 
Procedure.i ParallelPort_Destroy( *this.PARALLEL_PORT )
 
	If *this
 
		If IsLibrary( *this\Handle )
			CloseLibrary( *this\Handle )
		EndIf
 
		FreeMemory( *this )
		*this = #Null
		ProcedureReturn *this
 
	EndIf
 
EndProcedure
 
;- Communication Functions
 
Procedure.i ParallelPort_Out( *this.PARALLEL_PORT, Bits.w = $00 )
	If *this
		*this\LastData = Bits & $FF
		ProcedureReturn CallFunction( *this\handle, "Out32", *this\Port, Bits )
	EndIf
EndProcedure
 
Procedure.i ParallelPort_In( *this.PARALLEL_PORT, Type.i )
	If *this
		ProcedureReturn CallFunction( *this\handle, "Inp32", *this\Port + Type )
	EndIf
EndProcedure
 
;- Getter Functions
 
Procedure.i ParallelPort_GetHandle( *this.PARALLEL_PORT )
	If *this
		ProcedureReturn *this\Handle
	EndIf
EndProcedure
 
Procedure.i ParallelPort_GetPort( *this.PARALLEL_PORT )
	If *this
		ProcedureReturn *this\Port
	EndIf
EndProcedure
 
Procedure.i ParallelPort_GetLastData( *this.PARALLEL_PORT )
	If *this
		ProcedureReturn *this\LastData
	EndIf
EndProcedure
 
;- Helper Functions
 
Procedure.i ParallelPort_Clear( *this.PARALLEL_PORT )
	If *this
		ParallelPort_Out( *this ) ; The default data parameter is $00
	EndIf
EndProcedure

And the constants include:

 
; Read Only Status Register.
#PARALLEL_PORT_STATUS_IRQ		= #PARALLEL_PORT_BIT2
 
#PARALLEL_PORT_STATUS_ERROR		= #PARALLEL_PORT_BIT3
#PARALLEL_PORT_STATUS_SELECT		= #PARALLEL_PORT_BIT4
#PARALLEL_PORT_STATUS_PAPEROUT		= #PARALLEL_PORT_BIT5
#PARALLEL_PORT_STATUS_ACK		= #PARALLEL_PORT_BIT6
#PARALLEL_PORT_STATUS_BUSY		= #PARALLEL_PORT_BIT7
 
; Read / Write Control Register.
#PARALLEL_PORT_CONTROL_STROBE		= #PARALLEL_PORT_BIT0
#PARALLEL_PORT_CONTROL_LINEFEED		= #PARALLEL_PORT_BIT1
#PARALLEL_PORT_CONTROL_RESET		= #PARALLEL_PORT_BIT2 ; AKA Initialize Printer OR Init.
#PARALLEL_PORT_CONTROL_SELECT		= #PARALLEL_PORT_BIT3
 
; These constants are icluded for completeness. All pin numbers are relative to D-Type 25, Centronics pins are between parentheses.
 
#PARALLEL_PORT_D0	=	#PARALLEL_PORT_BIT0			; PIN2
#PARALLEL_PORT_D1	=	#PARALLEL_PORT_BIT1			; PIN3
#PARALLEL_PORT_D2	=	#PARALLEL_PORT_BIT2			; PIN4
#PARALLEL_PORT_D3	=	#PARALLEL_PORT_BIT3			; PIN5
#PARALLEL_PORT_D4	=	#PARALLEL_PORT_BIT4			; PIN6
#PARALLEL_PORT_D5	=	#PARALLEL_PORT_BIT5			; PIN7
#PARALLEL_PORT_D6	=	#PARALLEL_PORT_BIT6			; PIN8
#PARALLEL_PORT_D7	=	#PARALLEL_PORT_BIT7			; PIN9
 
#PARALLEL_PORT_C0	=	#PARALLEL_PORT_CONTROL_STROBE		; PIN 1
#PARALLEL_PORT_C1	=	#PARALLEL_PORT_CONTROL_LINEFEED		; PIN 14
#PARALLEL_PORT_C2	=	#PARALLEL_PORT_CONTROL_RESET		; PIN 16	(31)
#PARALLEL_PORT_C3	=	#PARALLEL_PORT_CONTROL_SELECT		; PIN 17	(36)
 
#PARALLEL_PORT_S3	=	#PARALLEL_PORT_STATUS_ERROR		; PIN 15	(32)
#PARALLEL_PORT_S4	=	#PARALLEL_PORT_STATUS_SELECT		; PIN 13
#PARALLEL_PORT_S5	=	#PARALLEL_PORT_STATUS_PAPEROUT		; PIN 12
#PARALLEL_PORT_S6	=	#PARALLEL_PORT_STATUS_ACK		; PIN 10
#PARALLEL_PORT_S7	=	#PARALLEL_PORT_STATUS_BUSY		; PIN 11
 
; PINS 18-25 (19-30) Are all tied to GND.

The hardware:

You don’t need any special hardware other than a Centronics or similar cable and a PC with a Parallel port (I’m sure some of you keep older PCs around for a good reason!) — Aside from this if you’re planning on running the examples you might want to get some LEDs and Switches.

Something to download:

The entire sources and support files including the examples can be found Here. Remember to exit the demo programs with the ESC key so the program gets a chance to reset the output bits.

Useful companion:

During development you may want to keep an eye on the status of each pin, however not everyone has a breakout board for this particular interface so you may want to use a software version of this concept instead, one of my favourite ones is LPT.exe — It works fairly well and there are several ports to different languages in case you’re interested in modifying it to suit your own needs.

Closing up:

That’s all for now, hopefully I’ll be able to finish the project and post some of the code here. Hint: it involves controlling unipolar steppers, computer vision and webcams!

Can you guess what it is?

Cheers.