''
'	Vista CNC iMach Pro Pendant macropump driver
'
'	by Ray Livingston (jagboy@pacbell.net)
'
'	To install:
'		1) Uninstall the iMachPro plug-in, by deleting the DLL file
'		2) In Config->GeneralConfig, check "Enable macro-pump"
'		3) Copy this file to Mach3\macros\YourProfileName, and re-name to macropump.m1s
'		4) Re-start Mach3
'
'	Interface Connections:
'
'	iMach Pro w/25-pin cable:	
'
'	Conn. Pin	Function	Mach Signal
'	    1        	+5V		
'	    2        	MPG1-A          MPG1A
'	    3        	MPG1-B          MPG1B
'	    4        	Axis Select LSB OEMTRIG12
'	    5        	GND
'	    6        	Axis Select MSB OEMTRIG11
'	    14     	Mode Select LSB OEMTRIG14
'	    15      	Mode Select MSB OEMTRIG13
'	    16      	Action Button   OEMTRIG15
'	    17      	E-STOP
'
'	iMach Pro w/15-pin cable:	
'
'	Connector Pin	Function	Mach Signal
'	    1        	+5V
'	    2        	MPG1-A          MPG1A
'	    3        	MPG1-B          MPG1B
'	    4        	Axis Select LSB OEMTRIG12
'	    5        	GND
'	    6        	Axis Select MSB OEMTRIG11
'	    7      	Mode Select LSB OEMTRIG14
'	    8      	Mode Select MSB OEMTRIG13
'	    10      	Action Button   OEMTRIG15
'	    11     	E-STOP
'
'	iMach w/9-pin cable:	
'
'	Connector Pin	Function	Mach Signal
'	    1        	+5V
'	    2        	MPG1-A          MPG1A
'	    3        	MPG1-B          MPG1B
'	    4        	Axis Select LSB OEMTRIG12
'	    5        	GND
'	    6        	Axis Select MSB OEMTRIG11
'	    7      	Mode Select LSB OEMTRIG14
'	    8      	Mode Select MSB OEMTRIG13
'	    9     	Action Button   OEMTRIG15
'
'	The iMachPro has been successfully interfaced to parallel ports, SmoothSteppers, and 
'	a ModIO using this plug-in.  If using SmoothStepper, do NOT use the differential inputs
'	(2A+, 2A-, 2B+, 2B-, 2I+, 2I-) on Port3.  The single-ended inputs (1A, 1B, 1I) on Port 3
'	may be used.  If using ModIO, connect the MPG signals (MPG1-A, MPG1-B) to either the 
'	MPG1 inputs of the ModIO.
'
'	Any valid Mach inputs can be used, but you will need to modify the few lines of code 
'	below that actually read those inputs.
'
'	The MPG1-A and MPG1-B pins connect directly to the MPG
'	The Axis Select pins binary encode the position of the axis select switch as follows:
'		00 = X Axis
'		01 = Y Axis
'		10 = Z Axis
'		11 = A Axis
'	The Mode Select pins binary encode the position of the mode select switch as follows:
'		00 = Step/Velocity Jog Mode
'		01 = Continuous/Velocity Jog Mode
'		10 = FRO/SSO Mode
'		11 = Operation Mode
'	The Action Button is active whenever the Action button is pressed
'
'	Functionality By Mode:
'
'    StepVel Jog Mode:
'        MPG:             Move current axis in multi-step mode
'        Action-MPG:      Move current axis in MPG velocity mode
'        Double-click:    Undefined
'
'    Continuous Jog Mode:
'        MPG:             Move current axis at slow jog rate
'        Action-MPG:      Move current axis in MPG velocity mode
'        Double-click:    Undefined
'
'    Probe Mode:          
'        MPG:             Modify Feedrate Override
'        Action-MPG:      Modify Spindle Speed Override
'        Double-click:    Undefined
'
'    Operation Mode:
'        Run/Pause:
'            MPG:         Undefined
'            Action-MPG:  Undefined
'            Double-click:If program is running, FeedHold, else CycleStart
'        Stop/Rewind:
'            MPG:         Undefined
'            Action-MPG:  Undefined
'            Double-click:If program is running, Stop, else Rewind
'        Spindle On/Off:
'            MPG:         Undefined
'            Action-MPG:  Undefined
'            Double-click:Toggle spindle CW On/Off
'        Jog On/Off:
'            MPG:         Undefined
'            Action-MPG:  Undefined
'            Double-click:Toggle Jog On/Off
''

''
'	DROs
''
SlowJogPercentDRO = 	3

SpindleOverrideDRO = 	74

MPG1CountDRO =		101

CurrentLineDRO =	816

FeedOverrideDRO = 	821

''
'	User Vars
''
' These Vars may have to be re-defined, if already in use
StateVar = 		1250
ActionStateVar =	1251
ActionCountVar =	1252
LastMPG1CountVar = 	1253

''
'	Buttons
''
ToggleJogOnOffButton =	103

FeedRaiseButton = 	108
FeedLowerButton = 	109
SpindleRaiseButton = 	163
SpindleLowerButton = 	164

MPG1JogXButton = 	185
MPG1JogYButton = 	186
MPG1JogZButton = 	187
MPG1JogAButton = 	188
MPG1JogBButton = 	189
MPG1JogCButton = 	190

ContJogModeButton = 	204

MPG1ModeVelButton = 	303
MPG1ModeVelStepButton = 304
MPG1ModeMultiStepButton = 306

JogXPlusButton =	307
JogXMinusButton = 	308

MPGJogModeButton = 	327

ToggleXJogOffButton = 	334

CycleStartButton = 	1000
FeedHoldButton = 	1001
RewindButton = 		1002
StopButton =		1003
SingleStepButton = 	1004

ZeroXButton =		1008
ZeroYButton =		1009
ZeroZButton =		1010
ZeroAButton =		1011

''
'	LEDs
''
SpindleCWLED = 		11
MistCoolantLED = 	12
IdleLED =		803
StartLED =		804
PauseLED =		805

''
' 	Local Variables
''
Dim StepVelJogMode As Integer
Dim ContJogMode As Integer
Dim FROSSOMode As Integer
Dim OpMode As Integer

StepVelJogMode = 	0
ContJogMode = 		1
FROSSOMode =		2
OpMode = 		3

Dim JogMode As Integer
Dim Axis As Integer
Dim Action As Integer
Dim State As Integer

Dim PreviousJogMode As Integer
Dim PreviousAxis As Integer
Dim PreviousAction As Integer
Dim PreviousState As integer

Dim DoubleClick As Boolean
Dim MPGPLus As Boolean
Dim MPGMinus As Boolean

PreviousState = GetVar(StateVar)
' Separate out controls
PreviousAxis = PreviousState AND 3
PreviousJogMode = Int(PreviousState / 4) AND 3
PreviousAction = Int(PreviousState / 16) AND 1
PreviousState = PreviousState AND 15

''
'	If you do not use the Mach signal assignments outlined above,
'	you will need to modify the arguments in the following IsActive
'	calls accordingly
''
State = 0
If IsActive(OEMTRIG12) Then
	State = State OR 1
End If
If IsActive(OEMTRIG11) Then
	State = State OR 2
End If
If IsActive(OEMTRIG14) Then
	State = State OR 4
End If
If IsActive(OEMTRIG13) Then
	State = State OR 8
End If
If IsActive(OEMTRIG15) Then
	State = State OR 16
End If

' Separate out controls
Axis = State AND 3
JogMode = Int(State / 4) AND 3
Action = Int(State / 16) AND 1
State = State AND 15

' Update double-click timer
ActionState = GetVar(ActionStateVar)
ActionCount = GetVar(ActionCountVar)
If ActionCount > 0 Then
	' If timer is on, increment it
	ActionCount = ActionCount + 1
	If ActionCount = 10 Then
		' Timed out
		ActionCount = 0
		If Action = 0 Then
			SetVar(ActionStateVar, 3)
			SetVar(ActionCountVar, 0)
		End If
	End If
	SetVar(ActionCountVar, ActionCount)
End If

' Do Double-click processing
DoubleClick = 0
If State = PreviousState Then
	If ActionState = 0 Then
		' State 0 - Idle
		If Action = 1 Then
			' First Press - Move to state 1
			SetVar(ActionStateVar, 1)
			SetVar(ActionCountVar, 1)
		End If
	ElseIf ActionState = 1 Then
		' State 1 - First Press
		If Action = 0 Then
			' First Release - Move to State 2
			SetVar(ActionStateVar, 2)
			SetVar(ActionCountVar, 1)
		End If
	ElseIf ActionState = 2 Then
		' State 2 - First Release
		If Action = 1 Then
			' We got a double-click
			SetVar(ActionStateVar, 3)
			SetVar(ActionCountVar, 0)
			DoubleClick = True
		End If
	ElseIf ActionState = 3 Then
		' State 3 - Second Press or Timeout
		If Action = 0 Then
			' Final Release - Move to State 0
			SetVar(ActionStateVar, 0)
			SetVar(ActionCountVar, 0)
		End If
	End If
Else	
	' State Changed, so reset double click state machine
	ActionState = 0
	SetVar(ActionStateVar, 0)
	SetVar(ActionCountVar, 0)
End If

' Handle MPG Changes
MPGPlus = False
MPGMinus = False
MPG1Count = GetOEMDRO(MPG1CountDRO)
LastMPG1Count = GetVar(LastMPG1CountVar)
If MPG1Count > LastMPG1Count Then
	MPGPlus = True
ElseIf MPG1Count < LastMPG1Count Then
	MPGMinus = True
End If
SetVar(LastMPG1CountVar, MPG1Count)

' Do "real-time" modal processing
If JogMode = StepVelJogMode Then
	' Step/Velocity Jog
	If Action = 0 Then
		' If Action changes, make sure all axes are stopped
		If Action <> PreviousAction Then
			DoOEMButton(ToggleXJogOffButton + Axis)
			DoOEMButton(ToggleXJogOffButton + Axis)
		End If
		' MPG - Multi-Step Mode
		DoOEMButton(MPG1ModeMultiStepButton)
	Else
		' Shift/MPG - Velocity Mode
		DoOEMButton(MPG1ModeVelButton)
	End If		
ElseIf JogMode = ContJogMode Then
	' Continuous Jog
	If Action = 0 Then
		' MPG - Continuous Jog
		' If Action changes, make sure all axes are stopped
		If Action <> PreviousAction Then
			DoOEMButton(ToggleXJogOffButton + Axis)
			DoOEMButton(ToggleXJogOffButton + Axis)
		End If
		' MPG - Multi-Step Mode
		DoOEMButton(MPG1ModeMultiStepButton)
		If MPGPlus = True Then
			DoOEMButton(ContJogModeButton)
			DoOEMButton(JogXPlusButton + (Axis * 2))
		ElseIf MPGMinus = True Then
			DoOEMButton(ContJogModeButton)
			DoOEMButton(JogXMinusButton + (Axis * 2))
		Else
			DoOEMButton(ToggleXJogOffButton + Axis)
			DoOEMButton(ToggleXJogOffButton + Axis)
		End If
	Else
		' Shift/MPG - Velocity Mode
		DoOEMButton(MPGJogModeButton)
		DoOEMButton(MPG1ModeVelButton)
	End If
ElseIf JogMode = FROSSOMode Then
	' FRO/SSO 
	If MPGPlus = True Then
		If Action = 0 Then
			FeedOverride = GetOEMDRO(FeedOverrideDRO)
			If FeedOverride <= 295 Then
				FeedOverride = FeedOverride + 5
			Else
				FeedOverride = 300
			End If
			SetOEMDRO(FeedOverrideDRO, FeedOverride)
		Else
			SpindleOverride = GetOEMDRO(SpindleOverrideDRO)
			If SpindleOverride <= 245 Then
				SpindleOverride = SpindleOverride + 5
			Else
				SpindleOverride = 250
			End If
			SetOEMDRO(SpindleOverrideDRO, SpindleOverride)
		End If
	ElseIf MPGMinus = True Then
		If Action = 0 Then
			FeedOverride = GetOEMDRO(FeedOverrideDRO)
			If FeedOverride >= 10 Then
				FeedOverride = FeedOverride - 5
			Else
				FeedOverride = 5
			End If
			SetOEMDRO(FeedOverrideDRO, FeedOverride)
		Else
			SpindleOverride = GetOEMDRO(SpindleOverrideDRO)
			If SpindleOverride >= 10 Then
				SpindleOverride = SpindleOverride - 5
			Else
				SpindleOverride = 5
			End If
			SetOEMDRO(SpindleOverrideDRO, SpindleOverride)
		End If
	End If
ElseIf JogMode = OpMode Then
	' OpMode
	If Axis = 0 Then
		' CycleState/FeedHold
		If DoubleClick = True Then
			' Double-Click - Start/Hold
			if GetOEMLED(StartLED) Then
				DoOEMButton(FeedHoldButton)
			Else
				DoOEMButton(CycleStartButton)
			End If
		End If
	ElseIf Axis = 1 Then
		' Stop/Rewind
		If DoubleClick = True Then
			' Double-Click Stop/Rewind
			if GetOEMLED(StartLED) AND GetOEMDRO(CurrentLineDRO) > 0 Then
				DoOEMButton(StopButton)
			Else
				DoOEMButton(RewindButton)
			End If
		End If
	ElseIf Axis = 2 Then
		' Spindle Control
		If DoubleClick = True Then
			' Double-Click - Spindle On/Off
			If GetOEMLED(SpindleCWLED) Then
				Code "M5"
			Else
				Code "M3"
			End If
		End If
	Else
		' Jog On/Off
		If DoubleClick = True Then
			' Double-Click - Jog On/Off
			DoOEMButton(ToggleJogOnOffButton)
		End If
	End If
End If

' Now do the one-time mode change processing
If State <> PreviousState Then
	If JogMode = StepVelJogMode Then
		' Step/Velocity Jog
		DoOEMButton(MPGJogModeButton)
		If Axis = 0 Then
			' Jog X Axis
			DoOEMButton(MPG1JOGXButton)
		ElseIf Axis = 1 Then
			' Jog Y Axis
			DoOEMButton(MPG1JOGYButton)
		ElseIf Axis = 2 Then
			' Jog Z Axis
			DoOEMButton(MPG1JOGZButton)
		Else
			' Jog Z Axis
			DoOEMButton(MPG1JOGAButton)
		End If
	ElseIf JogMode = ContJogMode Then
		' Continuous/Velocity Jog
		' Make sure the MPG doesn't try to jog
		'DoOEMButton(ContJogModeButton)
		If Axis = 0 Then
			' Jog X Axis
			DoOEMButton(MPG1JOGXButton)
		ElseIf Axis = 1 Then
			' Jog Y Axis
			DoOEMButton(MPG1JOGYButton)
		ElseIf Axis = 2 Then
			' Jog Z Axis
			DoOEMButton(MPG1JOGZButton)
		Else
			' Jog Z Axis
			DoOEMButton(MPG1JOGAButton)
		End If
	ElseIf JogMode = FROSSOMode Then
		' FRO/SSO Mode
		If PreviousJogMode <> FROSSOMode Then
			' Make sure the MPG doesn't try to jog
			DoOEMButton(ContJogModeButton)
		End If
	ElseIf JogMode = OpMode Then
		' Op Mode
		' Make sure the MPG doesn't try to jog
		DoOEMButton(ContJogModeButton)
	End If

End If

SetVar(StateVar, State + (Action * 16))



