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.