From 8532e2123ecd3868381fd7438dc25e3fd535bfbf Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Mon, 20 May 2019 17:41:42 -0400 Subject: [PATCH] gpiocmds: Specify soft pwm duration in clock ticks Improve the precision of soft pwm pulses by allowing the host to directly specify the clock duration of the pulse. This improvement in precision may be noticeable when controller servos (and bltouch). Signed-off-by: Kevin O'Connor --- klippy/mcu.py | 5 +++-- src/gpiocmds.c | 18 ++++++------------ 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/klippy/mcu.py b/klippy/mcu.py index e7c28a03..256c15f2 100644 --- a/klippy/mcu.py +++ b/klippy/mcu.py @@ -341,7 +341,7 @@ class MCU_pwm: or self._shutdown_value not in [0., 1.]): raise pins.error( "start and shutdown values must be 0.0 or 1.0 on soft pwm") - self._pwm_max = self._mcu.get_constant_float("SOFT_PWM_MAX") + self._pwm_max = float(cycle_ticks) if self._is_static: self._mcu.add_config_cmd("set_digital_out pin=%s value=%d" % ( self._pin, self._start_value >= 0.5)) @@ -354,7 +354,8 @@ class MCU_pwm: self._start_value >= 0.5, 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", cq=cmd_queue) + "schedule_soft_pwm_out oid=%c clock=%u on_ticks=%u", + cq=cmd_queue) def set_pwm(self, print_time, value): clock = self._mcu.print_time_to_clock(print_time) if self._invert: diff --git a/src/gpiocmds.c b/src/gpiocmds.c index 1d48a40e..91d97b75 100644 --- a/src/gpiocmds.c +++ b/src/gpiocmds.c @@ -106,9 +106,6 @@ DECL_COMMAND(command_set_digital_out, "set_digital_out pin=%u value=%c"); * Soft PWM output pins ****************************************************************/ -#define MAX_SOFT_PWM 256 -DECL_CONSTANT("SOFT_PWM_MAX", MAX_SOFT_PWM); - struct soft_pwm_s { struct timer timer; uint32_t on_duration, off_duration, end_time; @@ -192,17 +189,14 @@ void command_schedule_soft_pwm_out(uint32_t *args) { struct soft_pwm_s *s = oid_lookup(args[0], command_config_soft_pwm_out); - uint32_t time = args[1]; - uint16_t value = args[2]; + uint32_t time = args[1], next_on_duration = args[2], next_off_duration; uint8_t next_flags = SPF_CHECK_END | SPF_HAVE_NEXT; - uint32_t next_on_duration, next_off_duration; - if (value == 0 || value >= MAX_SOFT_PWM) { - next_on_duration = next_off_duration = 0; - next_flags |= value ? SPF_NEXT_ON : 0; - if (!!value != s->default_value && s->max_duration) + if (next_on_duration == 0 || next_on_duration >= s->cycle_time) { + next_flags |= next_on_duration ? SPF_NEXT_ON : 0; + if (!!next_on_duration != s->default_value && s->max_duration) next_flags |= SPF_NEXT_CHECK_END; + next_on_duration = next_off_duration = 0; } else { - next_on_duration = (s->cycle_time / MAX_SOFT_PWM) * value; next_off_duration = s->cycle_time - next_on_duration; next_flags |= SPF_NEXT_ON | SPF_NEXT_TOGGLING; if (s->max_duration) @@ -227,7 +221,7 @@ command_schedule_soft_pwm_out(uint32_t *args) irq_enable(); } DECL_COMMAND(command_schedule_soft_pwm_out, - "schedule_soft_pwm_out oid=%c clock=%u value=%hu"); + "schedule_soft_pwm_out oid=%c clock=%u on_ticks=%u"); void soft_pwm_shutdown(void)