From 9d75c3b0cace034ef8d51be1b38b705db33ac793 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Thu, 24 Aug 2017 09:34:31 -0400 Subject: [PATCH] chipmisc: Add support for statically configured output pins Allow digital and PWM output pins to be setup via new config sections. This makes it easier to setup pin configurations. Signed-off-by: Kevin O'Connor --- config/example-extras.cfg | 83 ++++++++++++++++++++++++++++++++++++ config/example.cfg | 38 +---------------- config/generic-rambo.cfg | 25 ++++++----- config/makergear-m2-2012.cfg | 22 +++++----- klippy/chipmisc.py | 43 +++++++++++++++++++ klippy/klippy.py | 4 +- klippy/mcu.py | 52 ++++++++++++++++------ 7 files changed, 193 insertions(+), 74 deletions(-) create mode 100644 config/example-extras.cfg create mode 100644 klippy/chipmisc.py diff --git a/config/example-extras.cfg b/config/example-extras.cfg new file mode 100644 index 00000000..ec9de90b --- /dev/null +++ b/config/example-extras.cfg @@ -0,0 +1,83 @@ +# This file serves as documentation for config parameters of +# 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. + + +# In a multi-extruder printer add an additional extruder section for +# each additional extruder. The additional extruder sections should be +# named "extruder1", "extruder2", "extruder3", and so on. See the +# "extruder" section in example.cfg for a description of available +# parameters. +#[extruder1] +#step_pin: ar36 +#dir_pin: ar34 +#... +#deactivate_gcode: +# A list of G-Code commands (one per line) to execute on a G-Code +# tool change command (eg, "T1") that deactivates this extruder and +# activates some other extruder. It only makes sense to define this +# section on multi-extruder printers. The default is to not run any +# special G-Code commands on deactivation. +#activate_gcode: +# A list of G-Code commands (one per line) to execute on a G-Code +# tool change command (eg, "T0") that activates this extruder. It +# only makes sense to define this section on multi-extruder +# printers. The default is to not run any special G-Code commands on +# activation. + + +# Heater cooling fans (one may define any number of sections with a +# "heater_fan" prefix). A "heater fan" is a fan that will be enabled +# whenever its associated heater is active. +#[heater_fan my_nozzle_fan] +# See the "fan" section for fan configuration parameters. +#pin: ar4 +# The remaining variables are specific to heater_fan. +#heater: extruder +# Name of the config section defining the heater that this fan is +# associated with. The default is "extruder". +#heater_temp: 50.0 +# A temperature (in Celsius) that the heater must drop below before +# the fan is disabled. The default is 50 Celsius. + + +# Statically configured digital output pins (one may define any number +# of sections with a "static_digital_output" prefix). Pins configured +# here will be setup as a GPIO output during MCU configuration. +#[static_digital_output my_output_pins] +#pins: +# A comma separated list of pins to be set as GPIO output pins. The +# pin will be set to a high level unless the pin name is prefaced +# with "!". This parameter must be provided. + + +# Statically configured PWM output pins (one may define any number of +# sections with a "static_pwm_output" prefix). Pins configured here +# will be setup as PWM outputs during MCU configuration. +#[static_pwm_output my_output_pwm] +#pin: +# The pin to configure as PWM output. This parameter must be +# provided. +#value: +# The value to statically set the PWM output to. This is typically +# set to a number between 0.0 and 1.0 with 1.0 being full on and 0.0 +# being full off. However, the range may be changed with the 'scale' +# parameter (see below). This parameter must be provided. +#hard_pwm: +# Set this value to force hardware PWM instead of software PWM. Set +# to 1 to force a hardware PWM at the fastest rate; set to a higher +# number to force hardware PWM with the given cycle time in clock +# ticks. The default is to use software PWM. +#cycle_time: 0.100 +# The amount of time (in seconds) per PWM cycle when using software +# based PWM. The default is 0.100 seconds. +#scale: +# This parameter can be used to alter how the 'value' parameter is +# interpreted. If provided, then the 'value' parameter should be +# between 0.0 and 'scale'. This may be useful when configuring a PWM +# pin that controls a stepper voltage reference. The 'scale' can be +# set to the equivalent stepper amperage if the PWM were fully +# enabled, and then the 'value' parameter can be specified using the +# desired amperage for the stepper. The default is to not scale the +# 'value' parameter. diff --git a/config/example.cfg b/config/example.cfg index 4bb805db..32ece835 100644 --- a/config/example.cfg +++ b/config/example.cfg @@ -2,7 +2,8 @@ # copy and edit this file to configure a new cartesian style # printer. For delta style printers, see the "example-delta.cfg" # file. For corexy/h-bot style printers, see the "example-corexy.cfg" -# file. +# file. Only common config sections are described here - see the +# "example-extras.cfg" file for configuring less common devices. # DO NOT COPY THIS FILE WITHOUT CAREFULLY READING AND UPDATING IT # FIRST. Incorrectly configured parameters may cause damage. @@ -150,18 +151,6 @@ filament_diameter: 3.500 # otherwise cause retraction followed immediately by pressure # buildup. This setting only applies if pressure_advance is # non-zero. The default is 0.010 (10 milliseconds). -#deactivate_gcode: -# A list of G-Code commands (one per line) to execute on a G-Code -# tool change command (eg, "T1") that deactivates this extruder and -# activates some other extruder. It only makes sense to define this -# section on multi-extruder printers. The default is to not run any -# special G-Code commands on deactivation. -#activate_gcode: -# A list of G-Code commands (one per line) to execute on a G-Code -# tool change command (eg, "T0") that activates this extruder. It -# only makes sense to define this section on multi-extruder -# printers. The default is to not run any special G-Code commands on -# activation. # # The remaining variables describe the extruder heater. heater_pin: ar10 @@ -217,15 +206,6 @@ max_temp: 210 # Maximum temperature (mcu will shutdown if temperature is above # this value). This parameter must be provided. -# In a multi-extruder printer add an additional extruder section for -# each additional extruder. The additional extruder sections should be -# named "extruder1", "extruder2", "extruder3", and so on. See the -# "extruder" section above for a description of available parameters. -#[extruder1] -#step_pin: ar36 -#dir_pin: ar34 -#... - # The heater_bed section describes a heated bed (if present - omit # section if not present). [heater_bed] @@ -323,17 +303,3 @@ max_z_accel: 30 # centripetal velocity cornering algorithm. A larger number will # permit higher "cornering speeds" at the junction of two moves. The # default is 0.02mm. - -# Heater cooling fans (one may define any number of sections with a -# "heater_fan" prefix). A "heater fan" is a fan that will be enabled -# whenever its associated heater is active. -#[heater_fan my_nozzle_fan] -# See the "fan" section for fan configuration parameters. -#pin: ar4 -# The remaining variables are specific to heater_fan. -#heater: extruder -# Name of the config section defining the heater that this fan is -# associated with. The default is "extruder". -#heater_temp: 50.0 -# A temperature (in Celsius) that the heater must drop below before -# the fan is disabled. The default is 50 Celsius. diff --git a/config/generic-rambo.cfg b/config/generic-rambo.cfg index f1cc0389..f01eb82f 100644 --- a/config/generic-rambo.cfg +++ b/config/generic-rambo.cfg @@ -77,19 +77,6 @@ pin: PH5 [mcu] serial: /dev/ttyACM0 custom: - # Turn off yellow led - set_digital_out pin=PB7 value=0 - # Stepper micro-step pins - set_digital_out pin=PG1 value=1 - set_digital_out pin=PG0 value=1 - set_digital_out pin=PK7 value=1 - set_digital_out pin=PG2 value=1 - set_digital_out pin=PK6 value=1 - set_digital_out pin=PK5 value=1 - set_digital_out pin=PK3 value=1 - set_digital_out pin=PK4 value=1 - #set_digital_out pin=PK2 value=1 - #set_digital_out pin=PK1 value=1 # Initialize digipot send_spi_message pin=PD7 msg=0487 # X = ~0.75A send_spi_message pin=PD7 msg=0587 # Y = ~0.75A @@ -103,3 +90,15 @@ max_velocity: 300 max_accel: 3000 max_z_velocity: 5 max_z_accel: 100 + +# Enable 16 micro-steps on steppers X, Y, Z, E0, E1 +[static_digital_output stepper_config] +pins: + PG1, PG0, + PK7, PG2, + PK6, PK5, + PK3, PK4, + PK2, PK1 + +[static_digital_output yellow_led] +pins: !PB7 diff --git a/config/makergear-m2-2012.cfg b/config/makergear-m2-2012.cfg index a2b0e89d..1bf72a54 100644 --- a/config/makergear-m2-2012.cfg +++ b/config/makergear-m2-2012.cfg @@ -77,17 +77,6 @@ hard_pwm: 1 [mcu] serial: /dev/ttyACM0 custom: - # Turn off yellow led - set_digital_out pin=PB7 value=0 - # Stepper micro-step pins - set_digital_out pin=PG1 value=1 - set_digital_out pin=PG0 value=1 - set_digital_out pin=PK7 value=1 - set_digital_out pin=PG2 value=1 - set_digital_out pin=PK6 value=1 - set_digital_out pin=PK5 value=1 - set_digital_out pin=PK3 value=1 - set_digital_out pin=PK4 value=1 # Initialize digipot send_spi_message pin=PD7 msg=0487 # X = ~0.75A send_spi_message pin=PD7 msg=0587 # Y = ~0.75A @@ -101,3 +90,14 @@ max_velocity: 500 max_accel: 3000 max_z_velocity: 25 max_z_accel: 30 + +# Enable 8 micro-steps on steppers X, Y, Z, E0 +[static_digital_output stepper_config] +pins: + PG1, PG0, + PK7, PG2, + PK6, PK5, + PK3, PK4 + +[static_digital_output yellow_led] +pins: !PB7 diff --git a/klippy/chipmisc.py b/klippy/chipmisc.py new file mode 100644 index 00000000..bdcb59d8 --- /dev/null +++ b/klippy/chipmisc.py @@ -0,0 +1,43 @@ +# Code to configure miscellaneous chips +# +# Copyright (C) 2017 Kevin O'Connor +# +# This file may be distributed under the terms of the GNU GPLv3 license. +import pins + + +###################################################################### +# Statically configured output pins +###################################################################### + +class PrinterStaticDigitalOut: + def __init__(self, printer, config): + pin_list = [pin.strip() for pin in config.get('pins').split(',')] + for pin_desc in pin_list: + mcu_pin = pins.setup_pin(printer, 'digital_out', pin_desc) + mcu_pin.setup_static() + +class PrinterStaticPWM: + def __init__(self, printer, config): + mcu_pwm = pins.setup_pin(printer, 'pwm', config.get('pin')) + mcu_pwm.setup_max_duration(0.) + hard_pwm = config.getint('hard_pwm', None, minval=1) + if hard_pwm is None: + mcu_pwm.setup_cycle_time(config.getfloat( + 'cycle_time', 0.100, above=0.)) + else: + mcu_pwm.setup_hard_pwm(hard_pwm) + scale = config.getfloat('scale', 1., above=0.) + value = config.getfloat('value', minval=0., maxval=scale) + mcu_pwm.setup_static_pwm(value / scale) + + +###################################################################### +# Setup +###################################################################### + +def add_printer_objects(printer, config): + for s in config.get_prefix_sections('static_digital_output '): + printer.add_object(s.section, PrinterStaticDigitalOut(printer, s)) + for s in config.get_prefix_sections('static_pwm_output '): + printer.add_object(s.section, PrinterStaticPWM(printer, s)) diff --git a/klippy/klippy.py b/klippy/klippy.py index d733c3a8..f674720b 100644 --- a/klippy/klippy.py +++ b/klippy/klippy.py @@ -6,7 +6,7 @@ # This file may be distributed under the terms of the GNU GPLv3 license. import sys, optparse, ConfigParser, logging, time, threading import util, reactor, queuelogger, msgproto, gcode -import pins, mcu, extruder, fan, heater, toolhead +import pins, mcu, chipmisc, extruder, fan, heater, toolhead message_ready = "Printer is ready" @@ -172,7 +172,7 @@ class Printer: ConfigLogger(self.fileconfig, self.bglogger) # Create printer components config = ConfigWrapper(self, 'printer') - for m in [pins, mcu, extruder, fan, heater, toolhead]: + for m in [pins, mcu, chipmisc, extruder, fan, heater, toolhead]: m.add_printer_objects(self, config) self.mcu = self.objects['mcu'] # Validate that there are no undefined parameters in the config file diff --git a/klippy/mcu.py b/klippy/mcu.py index 4d012286..1132ab42 100644 --- a/klippy/mcu.py +++ b/klippy/mcu.py @@ -14,7 +14,6 @@ STEPCOMPRESS_ERROR_RET = -989898989 class MCU_stepper: def __init__(self, mcu, pin_params): self._mcu = mcu - self._oid = mcu.create_oid() self._step_pin = pin_params['pin'] self._invert_step = pin_params['invert'] self._dir_pin = self._invert_dir = None @@ -23,7 +22,7 @@ class MCU_stepper: self._velocity_factor = self._accel_factor = 0. self._mcu_position_offset = 0 self._mcu_freq = self._min_stop_interval = 0. - self._reset_cmd = self._get_position_cmd = None + self._oid = self._reset_cmd = self._get_position_cmd = None 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 @@ -39,6 +38,7 @@ class MCU_stepper: self._inv_step_dist = 1. / step_dist def build_config(self): self._mcu_freq = self._mcu.get_mcu_freq() + self._oid = self._mcu.create_oid() self._velocity_factor = 1. / (self._mcu_freq * self._step_dist) self._accel_factor = 1. / (self._mcu_freq**2 * self._step_dist) max_error = self._mcu.get_max_stepper_error() @@ -142,13 +142,12 @@ class MCU_endstop: RETRY_QUERY = 1.000 def __init__(self, mcu, pin_params): self._mcu = mcu - self._oid = mcu.create_oid() self._steppers = [] 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._oid = self._home_cmd = self._query_cmd = None self._homing = False self._min_query_time = self._mcu_freq = 0. self._next_query_clock = self._home_timeout_clock = 0 @@ -160,6 +159,7 @@ class MCU_endstop: self._steppers.append(stepper) def build_config(self): self._mcu_freq = self._mcu.get_mcu_freq() + self._oid = self._mcu.create_oid() self._mcu.add_config_cmd( "config_end_stop oid=%d pin=%s pull_up=%d stepper_count=%d" % ( self._oid, self._pin, self._pullup, len(self._steppers))) @@ -236,7 +236,8 @@ class MCU_endstop: class MCU_digital_out: def __init__(self, mcu, pin_params): self._mcu = mcu - self._oid = mcu.create_oid() + self._oid = None + self._static_value = None self._pin = pin_params['pin'] self._invert = pin_params['invert'] self._max_duration = 2. @@ -249,8 +250,15 @@ class MCU_digital_out: self.system_to_mcu_time = mcu.system_to_mcu_time def setup_max_duration(self, max_duration): self._max_duration = max_duration + def setup_static(self): + self._static_value = not self._invert def build_config(self): self._mcu_freq = self._mcu.get_mcu_freq() + if self._static_value is not None: + self._mcu.add_config_cmd("set_digital_out pin=%s value=%d" % ( + self._pin, self._static_value)) + return + self._oid = self._mcu.create_oid() self._mcu.add_config_cmd( "config_digital_out oid=%d pin=%s default_value=%d" " max_duration=TICKS(%f)" % ( @@ -278,7 +286,8 @@ class MCU_pwm: self._hard_pwm = False self._cycle_time = 0.100 self._max_duration = 2. - self._oid = mcu.create_oid() + self._oid = None + self._static_value = None self._pin = pin_params['pin'] self._invert = pin_params['invert'] self._last_clock = 0 @@ -298,26 +307,45 @@ class MCU_pwm: return self._cycle_time = hard_cycle_ticks self._hard_pwm = True + def setup_static_pwm(self, value): + if self._invert: + self._static_value = 1. - value + else: + self._static_value = value def build_config(self): self._mcu_freq = self._mcu.get_mcu_freq() if self._hard_pwm: + self._pwm_max = self._mcu.serial.msgparser.get_constant_float( + "PWM_MAX") + if self._static_value is not None: + value = int(self._static_value * self._pwm_max + 0.5) + self._mcu.add_config_cmd( + "set_pwm_out pin=%s cycle_ticks=%d value=%d" % ( + self._pin, self._cycle_time, value)) + return + self._oid = self._mcu.create_oid() 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._pwm_max = self._mcu.serial.msgparser.get_constant_float( + "SOFT_PWM_MAX") + if self._static_value is not None: + if self._static_value != 0. and self._static_value != 1.: + raise pins.error("static value on soft pwm not supported") + self._mcu.add_config_cmd("set_digital_out pin=%s value=%d" % ( + self._pin, int(self._static_value))) + return + self._oid = self._mcu.create_oid() 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( "schedule_soft_pwm_out oid=%c clock=%u value=%hu") def set_pwm(self, mcu_time, value): @@ -334,12 +362,11 @@ class MCU_adc: def __init__(self, mcu, pin_params): self._mcu = mcu self._pin = pin_params['pin'] - self._oid = mcu.create_oid() self._min_sample = self._max_sample = 0. self._sample_time = self._report_time = 0. self._sample_count = 0 self._report_clock = 0 - self._callback = None + self._oid = self._callback = None self._inv_max_adc = 0. self._mcu_freq = 0. self._cmd_queue = mcu.alloc_command_queue() @@ -355,6 +382,7 @@ class MCU_adc: if not self._sample_count: return self._mcu_freq = self._mcu.get_mcu_freq() + self._oid = self._mcu.create_oid() self._mcu.add_config_cmd("config_analog_in oid=%d pin=%s" % ( self._oid, self._pin)) last_clock, last_clock_time = self._mcu.get_last_clock()