aboutsummaryrefslogtreecommitdiffstats
path: root/klippy/mcu.py
diff options
context:
space:
mode:
Diffstat (limited to 'klippy/mcu.py')
-rw-r--r--klippy/mcu.py142
1 files changed, 76 insertions, 66 deletions
diff --git a/klippy/mcu.py b/klippy/mcu.py
index aa35f76d..3190a325 100644
--- a/klippy/mcu.py
+++ b/klippy/mcu.py
@@ -9,24 +9,15 @@ import serialhdl, pins, chelper
class error(Exception):
pass
-def parse_pin_extras(pin, can_pullup=False):
- pullup = invert = 0
- if can_pullup and pin.startswith('^'):
- pullup = 1
- pin = pin[1:].strip()
- if pin.startswith('!'):
- invert = 1
- pin = pin[1:].strip()
- return pin, pullup, invert
-
STEPCOMPRESS_ERROR_RET = -989898989
class MCU_stepper:
- def __init__(self, mcu, step_pin, dir_pin):
+ def __init__(self, mcu, pin_params):
self._mcu = mcu
self._oid = mcu.create_oid(self)
- self._step_pin, pullup, self._invert_step = parse_pin_extras(step_pin)
- self._dir_pin, pullup, self._invert_dir = parse_pin_extras(dir_pin)
+ self._step_pin = pin_params['pin']
+ self._invert_step = pin_params['invert']
+ self._dir_pin = self._invert_dir = None
self._commanded_pos = 0
self._step_dist = self._inv_step_dist = 1.
self._velocity_factor = self._accel_factor = 0.
@@ -36,9 +27,14 @@ class MCU_stepper:
self._ffi_lib = self._stepqueue = None
self.print_to_mcu_time = mcu.print_to_mcu_time
self.system_to_mcu_time = mcu.system_to_mcu_time
- def set_min_stop_interval(self, min_stop_interval):
+ def setup_dir_pin(self, pin_params):
+ if pin_params['chip'] is not self._mcu:
+ raise pins.error("Stepper dir pin must be on same mcu as step pin")
+ self._dir_pin = pin_params['pin']
+ self._invert_dir = pin_params['invert']
+ def setup_min_stop_interval(self, min_stop_interval):
self._min_stop_interval = min_stop_interval
- def set_step_distance(self, step_dist):
+ def setup_step_distance(self, step_dist):
self._step_dist = step_dist
self._inv_step_dist = 1. / step_dist
def build_config(self):
@@ -144,12 +140,13 @@ class MCU_stepper:
class MCU_endstop:
error = error
RETRY_QUERY = 1.000
- def __init__(self, mcu, pin):
+ def __init__(self, mcu, pin_params):
self._mcu = mcu
self._oid = mcu.create_oid(self)
self._steppers = []
- self._pin, self._pullup, self._invert = parse_pin_extras(
- pin, can_pullup=True)
+ self._pin = pin_params['pin']
+ self._pullup = pin_params['pullup']
+ self._invert = pin_params['invert']
self._cmd_queue = mcu.alloc_command_queue()
self._home_cmd = self._query_cmd = None
self._homing = False
@@ -240,23 +237,27 @@ class MCU_endstop:
return self._last_state.get('pin', self._invert) ^ self._invert
class MCU_digital_out:
- def __init__(self, mcu, pin, max_duration):
+ def __init__(self, mcu, pin_params):
self._mcu = mcu
self._oid = mcu.create_oid(self)
- pin, pullup, self._invert = parse_pin_extras(pin)
+ self._pin = pin_params['pin']
+ self._invert = pin_params['invert']
+ self._max_duration = 2.
self._last_clock = 0
self._last_value = None
self._mcu_freq = 0.
self._cmd_queue = mcu.alloc_command_queue()
- mcu.add_config_cmd(
- "config_digital_out oid=%d pin=%s default_value=%d"
- " max_duration=TICKS(%f)" % (
- self._oid, pin, self._invert, max_duration))
self._set_cmd = None
self.print_to_mcu_time = mcu.print_to_mcu_time
self.system_to_mcu_time = mcu.system_to_mcu_time
+ def setup_max_duration(self, max_duration):
+ self._max_duration = max_duration
def build_config(self):
self._mcu_freq = self._mcu.get_mcu_freq()
+ self._mcu.add_config_cmd(
+ "config_digital_out oid=%d pin=%s default_value=%d"
+ " max_duration=TICKS(%f)" % (
+ self._oid, self._pin, self._invert, self._max_duration))
self._set_cmd = self._mcu.lookup_command(
"schedule_digital_out oid=%c clock=%u value=%c")
def set_digital(self, mcu_time, value):
@@ -275,37 +276,49 @@ class MCU_digital_out:
self.set_digital(mcu_time, dval)
class MCU_pwm:
- def __init__(self, mcu, pin, cycle_time, hard_cycle_ticks, max_duration):
+ def __init__(self, mcu, pin_params):
self._mcu = mcu
- self._hard_cycle_ticks = hard_cycle_ticks
+ self._hard_pwm = False
+ self._cycle_time = 0.100
+ self._max_duration = 2.
self._oid = mcu.create_oid(self)
- pin, pullup, self._invert = parse_pin_extras(pin)
+ self._pin = pin_params['pin']
+ self._invert = pin_params['invert']
self._last_clock = 0
self._mcu_freq = 0.
self._pwm_max = 0.
self._cmd_queue = mcu.alloc_command_queue()
- if hard_cycle_ticks:
- mcu.add_config_cmd(
- "config_pwm_out oid=%d pin=%s cycle_ticks=%d default_value=%d"
- " max_duration=TICKS(%f)" % (
- self._oid, pin, hard_cycle_ticks, self._invert,
- max_duration))
- else:
- mcu.add_config_cmd(
- "config_soft_pwm_out oid=%d pin=%s cycle_ticks=TICKS(%f)"
- " default_value=%d max_duration=TICKS(%f)" % (
- self._oid, pin, cycle_time, self._invert, max_duration))
self._set_cmd = None
self.print_to_mcu_time = mcu.print_to_mcu_time
self.system_to_mcu_time = mcu.system_to_mcu_time
+ def setup_max_duration(self, max_duration):
+ self._max_duration = max_duration
+ def setup_cycle_time(self, cycle_time):
+ self._cycle_time = cycle_time
+ self._hard_pwm = False
+ def setup_hard_pwm(self, hard_cycle_ticks):
+ if not hard_cycle_ticks:
+ return
+ self._cycle_time = hard_cycle_ticks
+ self._hard_pwm = True
def build_config(self):
self._mcu_freq = self._mcu.get_mcu_freq()
- if self._hard_cycle_ticks:
+ if self._hard_pwm:
+ self._mcu.add_config_cmd(
+ "config_pwm_out oid=%d pin=%s cycle_ticks=%d default_value=%d"
+ " max_duration=TICKS(%f)" % (
+ self._oid, self._pin, self._cycle_time, self._invert,
+ self._max_duration))
self._pwm_max = self._mcu.serial.msgparser.get_constant_float(
"PWM_MAX")
self._set_cmd = self._mcu.lookup_command(
"schedule_pwm_out oid=%c clock=%u value=%hu")
else:
+ self._mcu.add_config_cmd(
+ "config_soft_pwm_out oid=%d pin=%s cycle_ticks=TICKS(%f)"
+ " default_value=%d max_duration=TICKS(%f)" % (
+ self._oid, self._pin, self._cycle_time, self._invert,
+ self._max_duration))
self._pwm_max = self._mcu.serial.msgparser.get_constant_float(
"SOFT_PWM_MAX")
self._set_cmd = self._mcu.lookup_command(
@@ -321,8 +334,9 @@ class MCU_pwm:
self._last_clock = clock
class MCU_adc:
- def __init__(self, mcu, pin):
+ def __init__(self, mcu, pin_params):
self._mcu = mcu
+ self._pin = pin_params['pin']
self._oid = mcu.create_oid(self)
self._min_sample = self._max_sample = 0.
self._sample_time = self._report_time = 0.
@@ -332,20 +346,23 @@ class MCU_adc:
self._inv_max_adc = 0.
self._mcu_freq = 0.
self._cmd_queue = mcu.alloc_command_queue()
- mcu.add_config_cmd("config_analog_in oid=%d pin=%s" % (self._oid, pin))
self._query_cmd = None
mcu.add_init_callback(self._init_callback)
- self._query_cmd = None
+ def setup_minmax(self, sample_time, sample_count, minval=0., maxval=1.):
+ self._sample_time = sample_time
+ self._sample_count = sample_count
+ self._min_sample = minval
+ self._max_sample = maxval
+ def setup_adc_callback(self, report_time, callback):
+ self._report_time = report_time
+ self._callback = callback
def build_config(self):
self._mcu_freq = self._mcu.get_mcu_freq()
+ self._mcu.add_config_cmd("config_analog_in oid=%d pin=%s" % (
+ self._oid, self._pin))
self._query_cmd = self._mcu.lookup_command(
"query_analog_in oid=%c clock=%u sample_ticks=%u sample_count=%c"
" rest_ticks=%u min_value=%hu max_value=%hu")
- def set_minmax(self, sample_time, sample_count, minval=0., maxval=1.):
- self._sample_time = sample_time
- self._sample_count = sample_count
- self._min_sample = minval
- self._max_sample = maxval
def _init_callback(self):
if not self._sample_count:
return
@@ -370,9 +387,6 @@ class MCU_adc:
last_read_time = (next_clock - self._report_clock) / self._mcu_freq
if self._callback is not None:
self._callback(last_read_time, last_value)
- def set_adc_callback(self, report_time, callback):
- self._report_time = report_time
- self._callback = callback
class MCU:
error = error
@@ -398,7 +412,7 @@ class MCU:
# Config building
if printer.bglogger is not None:
printer.bglogger.set_rollover_info("mcu", None)
- self._config_error = config.error
+ pins.get_printer_pins(printer).register_chip("mcu", self)
self._emergency_stop_cmd = self._reset_cmd = None
self._oids = []
self._config_cmds = []
@@ -564,8 +578,7 @@ class MCU:
updated_cmds.append(pins.update_command(
cmd, self._mcu_freq, pnames))
except:
- raise self._config_error("Unable to translate pin name: %s" % (
- cmd,))
+ raise pins.error("Unable to translate pin name: %s" % (cmd,))
self._config_cmds = updated_cmds
# Calculate config CRC
@@ -617,6 +630,13 @@ class MCU:
for cb in self._init_callbacks:
cb()
# Config creation helpers
+ def setup_pin(self, pin_params):
+ pcs = {'stepper': MCU_stepper, 'endstop': MCU_endstop,
+ 'digital_out': MCU_digital_out, 'pwm': MCU_pwm, 'adc': MCU_adc}
+ pin_type = pin_params['type']
+ if pin_type not in pcs:
+ raise pins.error("pin type %s not supported on mcu" % (pin_type,))
+ return pcs[pin_type](self, pin_params)
def create_oid(self, oid):
self._oids.append(oid)
return len(self._oids) - 1
@@ -634,19 +654,6 @@ class MCU:
return self.serial.msgparser.lookup_command(msgformat)
def create_command(self, msg):
return self.serial.msgparser.create_command(msg)
- # Wrappers for mcu object creation
- def create_stepper(self, step_pin, dir_pin):
- return MCU_stepper(self, step_pin, dir_pin)
- def create_endstop(self, pin):
- return MCU_endstop(self, pin)
- def create_digital_out(self, pin, max_duration=2.):
- return MCU_digital_out(self, pin, max_duration)
- def create_pwm(self, pin, cycle_time, hard_cycle_ticks=0, max_duration=2.):
- if hard_cycle_ticks < 0:
- return MCU_digital_out(self, pin, max_duration)
- return MCU_pwm(self, pin, cycle_time, hard_cycle_ticks, max_duration)
- def create_adc(self, pin):
- return MCU_adc(self, pin)
# Clock syncing
def set_print_start_time(self, eventtime):
clock = self.serial.get_clock(eventtime)
@@ -687,3 +694,6 @@ class MCU:
return self._printer.reactor.monotonic()
def __del__(self):
self.disconnect()
+
+def add_printer_objects(printer, config):
+ printer.add_object('mcu', MCU(printer, config.getsection('mcu')))