aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2017-10-11 22:50:29 -0400
committerKevin O'Connor <kevin@koconnor.net>2017-10-12 11:59:27 -0400
commitdb97f3663168a138461d5b693aa285b67a0193d5 (patch)
treeeb50cf6fce088c73518b97090e0b955bfb84cddc
parentd03cf2b83f9df6b802af72860d8d3b56df89956f (diff)
downloadkutter-db97f3663168a138461d5b693aa285b67a0193d5.tar.gz
kutter-db97f3663168a138461d5b693aa285b67a0193d5.tar.xz
kutter-db97f3663168a138461d5b693aa285b67a0193d5.zip
gpiocmds: Allow the start value for a pin to differ from the default_value
Allow the start value to be different from the default/shutdown value for the pin. This will be useful for "heater fans" that should startup in the off state, and transition to full on in a shutdown state. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
-rw-r--r--docs/MCU_Commands.md42
-rw-r--r--klippy/mcu.py35
-rw-r--r--src/gpiocmds.c20
-rw-r--r--src/pwmcmds.c11
4 files changed, 62 insertions, 46 deletions
diff --git a/docs/MCU_Commands.md b/docs/MCU_Commands.md
index 51505545..edbaef11 100644
--- a/docs/MCU_Commands.md
+++ b/docs/MCU_Commands.md
@@ -118,16 +118,16 @@ Common micro-controller objects
This section lists some commonly used config commands.
-* `config_digital_out oid=%c pin=%u default_value=%c
+* `config_digital_out oid=%c pin=%u value=%c default_value=%c
max_duration=%u` : This command creates an internal micro-controller
object for the given GPIO 'pin'. The pin will be configured in
digital output mode and set to an initial value as specified by
- 'default_value' (0 for low, 1 for high). Creating a digital_out
- object allows the host to schedule GPIO updates for the given pin at
+ 'value' (0 for low, 1 for high). Creating a digital_out object
+ allows the host to schedule GPIO updates for the given pin at
specified times (see the schedule_digital_out command described
below). Should the micro-controller software go into shutdown mode
- then all configured digital_out objects will be set back to their
- default values. The 'max_duration' parameter is used to implement a
+ then all configured digital_out objects will be set to
+ 'default_value'. The 'max_duration' parameter is used to implement a
safety check - if it is non-zero then it is the maximum number of
clock ticks that the host may set the given GPIO to a non-default
value without further updates. For example, if the default_value is
@@ -137,23 +137,23 @@ This section lists some commonly used config commands.
feature can be used with heater pins to ensure the host does not
enable the heater and then go off-line.
-* `config_pwm_out oid=%c pin=%u cycle_ticks=%u default_value=%hu
- max_duration=%u` : This command creates an internal object for
- hardware based PWM pins that the host may schedule updates for. Its
- usage is analogous to config_digital_out - see the description of
- the 'set_pwm_out' and 'config_digital_out' commands for parameter
- description.
+* `config_pwm_out oid=%c pin=%u cycle_ticks=%u value=%hu
+ default_value=%hu max_duration=%u` : This command creates an
+ internal object for hardware based PWM pins that the host may
+ schedule updates for. Its usage is analogous to config_digital_out -
+ see the description of the 'set_pwm_out' and 'config_digital_out'
+ commands for parameter description.
-* `config_soft_pwm_out oid=%c pin=%u cycle_ticks=%u default_value=%c
- max_duration=%u` : This command creates an internal micro-controller
- object for software implemented PWM. Unlike hardware pwm pins, a
- software pwm object does not require any special hardware support
- (other than the ability to configure the pin as a digital output
- GPIO). Because the output switching is implemented in the
- micro-controller software, it is recommended that the cycle_ticks
- parameter correspond to a time of 10ms or greater. See the
- description of the 'set_pwm_out' and 'config_digital_out' commands
- for parameter description.
+* `config_soft_pwm_out oid=%c pin=%u cycle_ticks=%u value=%c
+ default_value=%c max_duration=%u` : This command creates an internal
+ micro-controller object for software implemented PWM. Unlike
+ hardware pwm pins, a software pwm object does not require any
+ special hardware support (other than the ability to configure the
+ pin as a digital output GPIO). Because the output switching is
+ implemented in the micro-controller software, it is recommended that
+ the cycle_ticks parameter correspond to a time of 10ms or
+ greater. See the description of the 'set_pwm_out' and
+ 'config_digital_out' commands for parameter description.
* `config_analog_in oid=%c pin=%u` : This command is used to configure
a pin in analog input sampling mode. Once configured, the pin can be
diff --git a/klippy/mcu.py b/klippy/mcu.py
index a89e6106..9d76e0fa 100644
--- a/klippy/mcu.py
+++ b/klippy/mcu.py
@@ -226,7 +226,7 @@ class MCU_digital_out:
self._oid = None
self._static_value = None
self._pin = pin_params['pin']
- self._invert = pin_params['invert']
+ self._invert = self._shutdown_value = pin_params['invert']
self._max_duration = 2.
self._last_clock = 0
self._last_value = None
@@ -238,6 +238,8 @@ class MCU_digital_out:
self._max_duration = max_duration
def setup_static(self):
self._static_value = not self._invert
+ def setup_shutdown_value(self, value):
+ self._shutdown_value = (not not value) ^ self._invert
def build_config(self):
if self._static_value is not None:
self._mcu.add_config_cmd("set_digital_out pin=%s value=%d" % (
@@ -245,16 +247,16 @@ class MCU_digital_out:
return
self._oid = self._mcu.create_oid()
self._mcu.add_config_cmd(
- "config_digital_out oid=%d pin=%s default_value=%d"
+ "config_digital_out oid=%d pin=%s value=%d default_value=%d"
" max_duration=%d" % (
- self._oid, self._pin, self._invert,
+ self._oid, self._pin, self._invert, self._shutdown_value,
self._mcu.seconds_to_clock(self._max_duration)))
self._set_cmd = self._mcu.lookup_command(
"schedule_digital_out oid=%c clock=%u value=%c")
def set_digital(self, print_time, value):
clock = self._mcu.print_time_to_clock(print_time)
msg = self._set_cmd.encode(
- self._oid, clock, not not (value ^ self._invert))
+ self._oid, clock, (not not value) ^ self._invert)
self._mcu.send(msg, minclock=self._last_clock, reqclock=clock
, cq=self._cmd_queue)
self._last_clock = clock
@@ -274,6 +276,7 @@ class MCU_pwm:
self._static_value = None
self._pin = pin_params['pin']
self._invert = pin_params['invert']
+ self._shutdown_value = float(self._invert)
self._last_clock = 0
self._pwm_max = 0.
self._cmd_queue = mcu.alloc_command_queue()
@@ -294,6 +297,10 @@ class MCU_pwm:
if self._invert:
value = 1. - value
self._static_value = max(0., min(1., value))
+ def setup_shutdown_value(self, value):
+ if self._invert:
+ value = 1. - value
+ self._shutdown_value = max(0., min(1., value))
def build_config(self):
if self._hard_pwm:
self._pwm_max = self._mcu.get_constant_float("PWM_MAX")
@@ -305,27 +312,33 @@ class MCU_pwm:
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=%d" % (
- self._oid, self._pin, self._cycle_time, self._invert,
+ "config_pwm_out oid=%d pin=%s cycle_ticks=%d value=%d"
+ " default_value=%d max_duration=%d" % (
+ self._oid, self._pin, self._cycle_time,
+ self._invert * self._pwm_max,
+ self._shutdown_value * self._pwm_max,
self._mcu.seconds_to_clock(self._max_duration)))
self._set_cmd = self._mcu.lookup_command(
"schedule_pwm_out oid=%c clock=%u value=%hu")
else:
self._pwm_max = self._mcu.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")
+ if self._static_value not in [0., 1.]:
+ raise pins.error(
+ "static value must be 0.0 or 1.0 on soft pwm")
self._mcu.add_config_cmd("set_digital_out pin=%s value=%d" % (
self._pin, self._static_value >= 0.5))
return
+ if self._shutdown_value not in [0., 1.]:
+ raise pins.error(
+ "shutdown value must be 0.0 or 1.0 on soft pwm")
self._oid = self._mcu.create_oid()
self._mcu.add_config_cmd(
- "config_soft_pwm_out oid=%d pin=%s cycle_ticks=%d"
+ "config_soft_pwm_out oid=%d pin=%s cycle_ticks=%d value=%d"
" default_value=%d max_duration=%d" % (
self._oid, self._pin,
self._mcu.seconds_to_clock(self._cycle_time),
- self._invert,
+ self._invert, self._shutdown_value >= 0.5,
self._mcu.seconds_to_clock(self._max_duration)))
self._set_cmd = self._mcu.lookup_command(
"schedule_soft_pwm_out oid=%c clock=%u value=%hu")
diff --git a/src/gpiocmds.c b/src/gpiocmds.c
index 69f60f97..52e3d8d5 100644
--- a/src/gpiocmds.c
+++ b/src/gpiocmds.c
@@ -44,14 +44,15 @@ digital_out_event(struct timer *timer)
void
command_config_digital_out(uint32_t *args)
{
+ struct gpio_out pin = gpio_out_setup(args[1], args[2]);
struct digital_out_s *d = oid_alloc(args[0], command_config_digital_out
, sizeof(*d));
- d->default_value = args[2];
- d->pin = gpio_out_setup(args[1], d->default_value);
- d->max_duration = args[3];
+ d->pin = pin;
+ d->default_value = args[3];
+ d->max_duration = args[4];
}
DECL_COMMAND(command_config_digital_out,
- "config_digital_out oid=%c pin=%u default_value=%c"
+ "config_digital_out oid=%c pin=%u value=%c default_value=%c"
" max_duration=%u");
void
@@ -159,17 +160,18 @@ soft_pwm_load_event(struct timer *timer)
void
command_config_soft_pwm_out(uint32_t *args)
{
+ struct gpio_out pin = gpio_out_setup(args[1], !!args[3]);
struct soft_pwm_s *s = oid_alloc(args[0], command_config_soft_pwm_out
, sizeof(*s));
+ s->pin = pin;
s->cycle_time = args[2];
- s->default_value = !!args[3];
- s->max_duration = args[4];
+ s->default_value = !!args[4];
+ s->max_duration = args[5];
s->flags = s->default_value ? SPF_ON : 0;
- s->pin = gpio_out_setup(args[1], s->default_value);
}
DECL_COMMAND(command_config_soft_pwm_out,
- "config_soft_pwm_out oid=%c pin=%u cycle_ticks=%u default_value=%c"
- " max_duration=%u");
+ "config_soft_pwm_out oid=%c pin=%u cycle_ticks=%u value=%c"
+ " default_value=%c max_duration=%u");
void
command_schedule_soft_pwm_out(uint32_t *args)
diff --git a/src/pwmcmds.c b/src/pwmcmds.c
index 82326b9d..cf025ddb 100644
--- a/src/pwmcmds.c
+++ b/src/pwmcmds.c
@@ -37,14 +37,15 @@ pwm_event(struct timer *timer)
void
command_config_pwm_out(uint32_t *args)
{
+ struct gpio_pwm pin = gpio_pwm_setup(args[1], args[2], args[3]);
struct pwm_out_s *p = oid_alloc(args[0], command_config_pwm_out, sizeof(*p));
- p->default_value = args[3];
- p->pin = gpio_pwm_setup(args[1], args[2], p->default_value);
- p->max_duration = args[4];
+ p->pin = pin;
+ p->default_value = args[4];
+ p->max_duration = args[5];
}
DECL_COMMAND(command_config_pwm_out,
- "config_pwm_out oid=%c pin=%u cycle_ticks=%u default_value=%hu"
- " max_duration=%u");
+ "config_pwm_out oid=%c pin=%u cycle_ticks=%u value=%hu"
+ " default_value=%hu max_duration=%u");
void
command_schedule_pwm_out(uint32_t *args)