replicape: Only call note_pwm_enable() in main thread
The pca9685_pwm set_pwm() code can be called from a background thread (when the pin controls a heater). Propagate updates to the main thread for enable tracking. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
1a693c18d6
commit
6026a99ad8
|
@ -21,6 +21,7 @@ class pca9685_pwm:
|
||||||
raise pins.error("Pin type not supported on replicape")
|
raise pins.error("Pin type not supported on replicape")
|
||||||
self._mcu = replicape.host_mcu
|
self._mcu = replicape.host_mcu
|
||||||
self._mcu.register_config_callback(self._build_config)
|
self._mcu.register_config_callback(self._build_config)
|
||||||
|
self._reactor = self._mcu.get_printer().get_reactor()
|
||||||
self._bus = REPLICAPE_PCA9685_BUS
|
self._bus = REPLICAPE_PCA9685_BUS
|
||||||
self._address = REPLICAPE_PCA9685_ADDRESS
|
self._address = REPLICAPE_PCA9685_ADDRESS
|
||||||
self._cycle_time = REPLICAPE_PCA9685_CYCLE_TIME
|
self._cycle_time = REPLICAPE_PCA9685_CYCLE_TIME
|
||||||
|
@ -28,6 +29,7 @@ class pca9685_pwm:
|
||||||
self._oid = None
|
self._oid = None
|
||||||
self._invert = pin_params['invert']
|
self._invert = pin_params['invert']
|
||||||
self._start_value = self._shutdown_value = float(self._invert)
|
self._start_value = self._shutdown_value = float(self._invert)
|
||||||
|
self._is_enable = not not self._start_value
|
||||||
self._is_static = False
|
self._is_static = False
|
||||||
self._last_clock = 0
|
self._last_clock = 0
|
||||||
self._pwm_max = 0.
|
self._pwm_max = 0.
|
||||||
|
@ -53,6 +55,7 @@ class pca9685_pwm:
|
||||||
self._is_static = is_static
|
self._is_static = is_static
|
||||||
self._replicape.note_pwm_start_value(
|
self._replicape.note_pwm_start_value(
|
||||||
self._channel, self._start_value, self._shutdown_value)
|
self._channel, self._start_value, self._shutdown_value)
|
||||||
|
self._is_enable = not not self._start_value
|
||||||
def _build_config(self):
|
def _build_config(self):
|
||||||
self._pwm_max = self._mcu.get_constant_float("PCA9685_MAX")
|
self._pwm_max = self._mcu.get_constant_float("PCA9685_MAX")
|
||||||
cycle_ticks = self._mcu.seconds_to_clock(self._cycle_time)
|
cycle_ticks = self._mcu.seconds_to_clock(self._cycle_time)
|
||||||
|
@ -80,7 +83,12 @@ class pca9685_pwm:
|
||||||
if self._invert:
|
if self._invert:
|
||||||
value = 1. - value
|
value = 1. - value
|
||||||
value = int(max(0., min(1., value)) * self._pwm_max + 0.5)
|
value = int(max(0., min(1., value)) * self._pwm_max + 0.5)
|
||||||
self._replicape.note_pwm_enable(print_time, self._channel, value)
|
is_enable = not not value
|
||||||
|
if is_enable != self._is_enable:
|
||||||
|
self._is_enable = is_enable
|
||||||
|
self._reactor.register_async_callback(
|
||||||
|
(lambda e, s=self, pt=print_time, ie=is_enable:
|
||||||
|
s._replicape.note_pwm_enable(pt, s._channel, ie)))
|
||||||
self._set_cmd.send([self._oid, clock, value],
|
self._set_cmd.send([self._oid, clock, value],
|
||||||
minclock=self._last_clock, reqclock=clock)
|
minclock=self._last_clock, reqclock=clock)
|
||||||
self._last_clock = clock
|
self._last_clock = clock
|
||||||
|
@ -148,7 +156,7 @@ class servo_pwm:
|
||||||
pin_resolver.reserve_pin(resv1, config_name)
|
pin_resolver.reserve_pin(resv1, config_name)
|
||||||
pin_resolver.reserve_pin(resv2, config_name)
|
pin_resolver.reserve_pin(resv2, config_name)
|
||||||
def setup_cycle_time(self, cycle_time, hardware_pwm=False):
|
def setup_cycle_time(self, cycle_time, hardware_pwm=False):
|
||||||
self.mcu_pwm.setup_cycle_time(cycle_time, True);
|
self.mcu_pwm.setup_cycle_time(cycle_time, True)
|
||||||
|
|
||||||
ReplicapeStepConfig = {
|
ReplicapeStepConfig = {
|
||||||
'disable': None,
|
'disable': None,
|
||||||
|
@ -171,6 +179,7 @@ class Replicape:
|
||||||
self.mcu_pwm_enable = ppins.setup_pin('digital_out', enable_pin)
|
self.mcu_pwm_enable = ppins.setup_pin('digital_out', enable_pin)
|
||||||
self.mcu_pwm_enable.setup_max_duration(0.)
|
self.mcu_pwm_enable.setup_max_duration(0.)
|
||||||
self.mcu_pwm_start_value = self.mcu_pwm_shutdown_value = False
|
self.mcu_pwm_start_value = self.mcu_pwm_shutdown_value = False
|
||||||
|
self.last_pwm_enable_time = 0.
|
||||||
# Setup power pins
|
# Setup power pins
|
||||||
self.pins = {
|
self.pins = {
|
||||||
"power_e": (pca9685_pwm, 5), "power_h": (pca9685_pwm, 3),
|
"power_e": (pca9685_pwm, 5), "power_h": (pca9685_pwm, 3),
|
||||||
|
@ -180,7 +189,6 @@ class Replicape:
|
||||||
self.servo_pins = {
|
self.servo_pins = {
|
||||||
"servo0": 3, "servo1": 2 }
|
"servo0": 3, "servo1": 2 }
|
||||||
# Setup stepper config
|
# Setup stepper config
|
||||||
self.last_stepper_time = 0.
|
|
||||||
self.stepper_dacs = {}
|
self.stepper_dacs = {}
|
||||||
shift_registers = [1, 0, 0, 1, 1]
|
shift_registers = [1, 0, 0, 1, 1]
|
||||||
for port, name in enumerate('xyzeh'):
|
for port, name in enumerate('xyzeh'):
|
||||||
|
@ -227,18 +235,17 @@ class Replicape:
|
||||||
self.mcu_pwm_enable.setup_start_value(
|
self.mcu_pwm_enable.setup_start_value(
|
||||||
self.mcu_pwm_start_value, self.mcu_pwm_shutdown_value)
|
self.mcu_pwm_start_value, self.mcu_pwm_shutdown_value)
|
||||||
self.enabled_channels[channel] = not not start_value
|
self.enabled_channels[channel] = not not start_value
|
||||||
def note_pwm_enable(self, print_time, channel, value):
|
def note_pwm_enable(self, print_time, channel, is_enable):
|
||||||
is_enable = not not value
|
|
||||||
if self.enabled_channels[channel] == is_enable:
|
|
||||||
# Nothing to do
|
|
||||||
return
|
|
||||||
self.enabled_channels[channel] = is_enable
|
self.enabled_channels[channel] = is_enable
|
||||||
# Check if need to set the pca9685 enable pin
|
# Check if need to set the pca9685 enable pin
|
||||||
|
pe_time = max(print_time, self.last_pwm_enable_time + PIN_MIN_TIME)
|
||||||
on_channels = [1 for c, e in self.enabled_channels.items() if e]
|
on_channels = [1 for c, e in self.enabled_channels.items() if e]
|
||||||
if not on_channels:
|
if not on_channels:
|
||||||
self.mcu_pwm_enable.set_digital(print_time, 0)
|
self.mcu_pwm_enable.set_digital(pe_time, 0)
|
||||||
|
self.last_pwm_enable_time = pe_time
|
||||||
elif is_enable and len(on_channels) == 1:
|
elif is_enable and len(on_channels) == 1:
|
||||||
self.mcu_pwm_enable.set_digital(print_time, 1)
|
self.mcu_pwm_enable.set_digital(pe_time, 1)
|
||||||
|
self.last_pwm_enable_time = pe_time
|
||||||
# Check if need to set the stepper enable lines
|
# Check if need to set the stepper enable lines
|
||||||
if channel not in self.stepper_dacs:
|
if channel not in self.stepper_dacs:
|
||||||
return
|
return
|
||||||
|
@ -250,7 +257,6 @@ class Replicape:
|
||||||
sr = self.sr_enabled
|
sr = self.sr_enabled
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
print_time = max(print_time, self.last_stepper_time + PIN_MIN_TIME)
|
|
||||||
clock = self.host_mcu.print_time_to_clock(print_time)
|
clock = self.host_mcu.print_time_to_clock(print_time)
|
||||||
self.sr_spi.spi_send(sr, minclock=clock, reqclock=clock)
|
self.sr_spi.spi_send(sr, minclock=clock, reqclock=clock)
|
||||||
def setup_pin(self, pin_type, pin_params):
|
def setup_pin(self, pin_type, pin_params):
|
||||||
|
|
Loading…
Reference in New Issue