From 01bb4b291eb48a2556096ce0d56a212f52405985 Mon Sep 17 00:00:00 2001
From: Kevin O'Connor <kevin@koconnor.net>
Date: Tue, 23 Jan 2018 12:47:28 -0500
Subject: [PATCH] probe: Create a probe:z_virtual_endstop pin

Create a virtual pin that may be used as the z endstop pin on
cartesian printers that use the probe in place of a z endstop.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
---
 config/example-extras.cfg |  9 ++++++++-
 klippy/extras/probe.py    | 13 ++++++++++++-
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/config/example-extras.cfg b/config/example-extras.cfg
index 9a792afa7..bd39e99b0 100644
--- a/config/example-extras.cfg
+++ b/config/example-extras.cfg
@@ -2,11 +2,18 @@
 # additional devices that may be configured on a printer. The snippets
 # in this file may be copied into the main printer.cfg file. See the
 # "example.cfg" file for description of common config parameters.
+#
+# Note, where an extra config section creates additional pins, the
+# section defining the pins must be listed in the config file before
+# any sections using those pins.
 
 
 # Z height probe. One may define this section to enable Z height
 # probing hardware. When this section is enabled, PROBE and
-# QUERY_PROBE extended g-code commands become available.
+# QUERY_PROBE extended g-code commands become available. The probe
+# section also creates a virtual probe:z_virtual_endstop pin. One may
+# set the stepper_z endstop_pin to this virtual pin on cartesian style
+# printers that use the probe in place of a z endstop.
 #[probe]
 #pin: ar15
 #   Probe detection pin. This parameter must be provided.
diff --git a/klippy/extras/probe.py b/klippy/extras/probe.py
index b1e89944d..084612fe4 100644
--- a/klippy/extras/probe.py
+++ b/klippy/extras/probe.py
@@ -4,13 +4,14 @@
 #
 # This file may be distributed under the terms of the GNU GPLv3 license.
 import logging
-import homing
+import pins, homing
 
 class PrinterProbe:
     def __init__(self, config):
         self.printer = config.get_printer()
         self.speed = config.getfloat('speed', 5.0)
         self.z_position = config.getfloat('z_position', 0.)
+        # Create an "endstop" object to handle the probe pin
         ppins = self.printer.lookup_object('pins')
         pin_params = ppins.lookup_pin('endstop', config.get('pin'))
         mcu = pin_params['chip']
@@ -19,6 +20,9 @@ class PrinterProbe:
         if (config.get('activate_gcode', None) is not None or
             config.get('deactivate_gcode', None) is not None):
             self.mcu_probe = ProbeEndstopWrapper(config, self.mcu_probe)
+        # Create z_virtual_endstop pin
+        ppins.register_chip('probe', self)
+        # Register PROBE/QUERY_PROBE commands
         self.gcode = self.printer.lookup_object('gcode')
         self.gcode.register_command(
             'PROBE', self.cmd_PROBE, desc=self.cmd_PROBE_help)
@@ -31,6 +35,13 @@ class PrinterProbe:
             for mcu_endstop, name in s.get_endstops():
                 for mcu_stepper in mcu_endstop.get_steppers():
                     self.mcu_probe.add_stepper(mcu_stepper)
+    def setup_pin(self, pin_params):
+        if (pin_params['pin'] != 'z_virtual_endstop'
+            or pin_params['type'] != 'endstop'):
+            raise pins.error("Probe virtual endstop only useful as endstop pin")
+        if pin_params['invert'] or pin_params['pullup']:
+            raise pins.error("Can not pullup/invert probe virtual endstop")
+        return self.mcu_probe
     cmd_PROBE_help = "Probe Z-height at current XY position"
     def cmd_PROBE(self, params):
         toolhead = self.printer.lookup_object('toolhead')