Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
0xD34D committed Sep 26, 2024
2 parents 159a739 + ef75346 commit 87b7c35
Show file tree
Hide file tree
Showing 13 changed files with 108 additions and 103 deletions.
18 changes: 1 addition & 17 deletions klippy/extras/bus.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ def __init__(self, mcu, bus, addr, speed, sw_pins=None):
% (self.oid, speed, addr))
self.cmd_queue = self.mcu.alloc_command_queue()
self.mcu.register_config_callback(self.build_config)
self.i2c_write_cmd = self.i2c_read_cmd = self.i2c_modify_bits_cmd = None
self.i2c_write_cmd = self.i2c_read_cmd = None
def get_oid(self):
return self.oid
def get_mcu(self):
Expand All @@ -180,9 +180,6 @@ def build_config(self):
"i2c_read oid=%c reg=%*s read_len=%u",
"i2c_read_response oid=%c response=%*s", oid=self.oid,
cq=self.cmd_queue)
self.i2c_modify_bits_cmd = self.mcu.lookup_command(
"i2c_modify_bits oid=%c reg=%*s clear_set_bits=%*s",
cq=self.cmd_queue)
def i2c_write(self, data, minclock=0, reqclock=0):
if self.i2c_write_cmd is None:
# Send setup message via mcu initialization
Expand All @@ -197,19 +194,6 @@ def i2c_write_wait_ack(self, data, minclock=0, reqclock=0):
minclock=minclock, reqclock=reqclock)
def i2c_read(self, write, read_len):
return self.i2c_read_cmd.send([self.oid, write, read_len])
def i2c_modify_bits(self, reg, clear_bits, set_bits,
minclock=0, reqclock=0):
clearset = clear_bits + set_bits
if self.i2c_modify_bits_cmd is None:
# Send setup message via mcu initialization
reg_msg = "".join(["%02x" % (x,) for x in reg])
clearset_msg = "".join(["%02x" % (x,) for x in clearset])
self.mcu.add_config_cmd(
"i2c_modify_bits oid=%d reg=%s clear_set_bits=%s" % (
self.oid, reg_msg, clearset_msg), is_init=True)
return
self.i2c_modify_bits_cmd.send([self.oid, reg, clearset],
minclock=minclock, reqclock=reqclock)

def MCU_I2C_from_config(config, default_addr=None, default_speed=100000):
# Load bus parameters
Expand Down
35 changes: 18 additions & 17 deletions klippy/extras/fan.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
# Printer cooling fan
#
# Copyright (C) 2016-2020 Kevin O'Connor <[email protected]>
# Copyright (C) 2016-2024 Kevin O'Connor <[email protected]>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
from . import pulse_counter

FAN_MIN_TIME = 0.100
from . import pulse_counter, output_pin

class Fan:
def __init__(self, config, default_shutdown_speed=0.):
self.printer = config.get_printer()
self.last_fan_value = 0.
self.last_fan_time = 0.
self.last_fan_value = self.last_req_value = 0.
# Read config
self.max_power = config.getfloat('max_power', 1., above=0., maxval=1.)
self.kick_start_time = config.getfloat('kick_start_time', 0.1,
Expand All @@ -36,6 +33,10 @@ def __init__(self, config, default_shutdown_speed=0.):
self.enable_pin = ppins.setup_pin('digital_out', enable_pin)
self.enable_pin.setup_max_duration(0.)

# Create gcode request queue
self.gcrq = output_pin.GCodeRequestQueue(config, self.mcu_fan.get_mcu(),
self._apply_speed)

# Setup tachometer
self.tachometer = FanTachometer(config)

Expand All @@ -45,37 +46,37 @@ def __init__(self, config, default_shutdown_speed=0.):

def get_mcu(self):
return self.mcu_fan.get_mcu()
def set_speed(self, print_time, value):
def _apply_speed(self, print_time, value):
if value < self.off_below:
value = 0.
value = max(0., min(self.max_power, value * self.max_power))
if value == self.last_fan_value:
return
print_time = max(self.last_fan_time + FAN_MIN_TIME, print_time)
return "discard", 0.
if self.enable_pin:
if value > 0 and self.last_fan_value == 0:
self.enable_pin.set_digital(print_time, 1)
elif value == 0 and self.last_fan_value > 0:
self.enable_pin.set_digital(print_time, 0)
if (value and value < self.max_power and self.kick_start_time
if (value and self.kick_start_time
and (not self.last_fan_value or value - self.last_fan_value > .5)):
# Run fan at full speed for specified kick_start_time
self.last_req_value = value
self.last_fan_value = self.max_power
self.mcu_fan.set_pwm(print_time, self.max_power)
print_time += self.kick_start_time
return "delay", self.kick_start_time
self.last_fan_value = self.last_req_value = value
self.mcu_fan.set_pwm(print_time, value)
self.last_fan_time = print_time
self.last_fan_value = value
def set_speed(self, print_time, value):
self.gcrq.send_async_request(print_time, value)
def set_speed_from_command(self, value):
toolhead = self.printer.lookup_object('toolhead')
toolhead.register_lookahead_callback((lambda pt:
self.set_speed(pt, value)))
self.gcrq.queue_gcode_request(value)
def _handle_request_restart(self, print_time):
self.set_speed(print_time, 0.)

def get_status(self, eventtime):
tachometer_status = self.tachometer.get_status(eventtime)
return {
'speed': self.last_fan_value,
'speed': self.last_req_value,
'rpm': tachometer_status['rpm'],
}

Expand Down
3 changes: 2 additions & 1 deletion klippy/extras/heaters.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,8 @@ def load_config(self, config):
try:
dconfig = pconfig.read_config(filename)
except Exception:
raise config.config_error("Cannot load config '%s'" % (filename,))
logging.exception("Unable to load temperature_sensors.cfg")
raise config.error("Cannot load config '%s'" % (filename,))
for c in dconfig.get_prefix_sections(''):
self.printer.load_object(dconfig, c.get_name())
def add_sensor_factory(self, sensor_type, sensor_factory):
Expand Down
2 changes: 1 addition & 1 deletion klippy/extras/led.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def _render(self, eventtime):
if not self.active_templates:
# Nothing to do - unregister timer
reactor = self.printer.get_reactor()
reactor.register_timer(self.render_timer)
reactor.unregister_timer(self.render_timer)
self.render_timer = None
return reactor.NEVER
# Setup gcode_macro template context
Expand Down
50 changes: 35 additions & 15 deletions klippy/extras/output_pin.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,40 @@ def _flush_notification(self, print_time, clock):
pos += 1
req_pt, req_val = rqueue[pos]
# Invoke callback for the request
want_dequeue, min_wait_time = self.callback(next_time, req_val)
self.next_min_flush_time = next_time + max(min_wait_time,
PIN_MIN_TIME)
if want_dequeue:
pos += 1
del rqueue[:pos]
min_wait = 0.
ret = self.callback(next_time, req_val)
if ret is not None:
# Handle special cases
action, min_wait = ret
if action == "discard":
del rqueue[:pos+1]
continue
if action == "delay":
pos -= 1
del rqueue[:pos+1]
self.next_min_flush_time = next_time + max(min_wait, PIN_MIN_TIME)
# Ensure following queue items are flushed
self.toolhead.note_mcu_movequeue_activity(self.next_min_flush_time)
def queue_request(self, print_time, value):
def _queue_request(self, print_time, value):
self.rqueue.append((print_time, value))
self.toolhead.note_mcu_movequeue_activity(print_time)
def queue_gcode_request(self, value):
self.toolhead.register_lookahead_callback(
(lambda pt: self.queue_request(pt, value)))
(lambda pt: self._queue_request(pt, value)))
def send_async_request(self, print_time, value):
while 1:
next_time = max(print_time, self.next_min_flush_time)
# Invoke callback for the request
action, min_wait = "normal", 0.
ret = self.callback(next_time, value)
if ret is not None:
# Handle special cases
action, min_wait = ret
if action == "discard":
break
self.next_min_flush_time = next_time + max(min_wait, PIN_MIN_TIME)
if action != "delay":
break

class PrinterOutputPin:
def __init__(self, config):
Expand Down Expand Up @@ -82,13 +102,13 @@ def __init__(self, config):
def get_status(self, eventtime):
return {'value': self.last_value}
def _set_pin(self, print_time, value):
if value != self.last_value:
self.last_value = value
if self.is_pwm:
self.mcu_pin.set_pwm(print_time, value)
else:
self.mcu_pin.set_digital(print_time, value)
return (True, 0.)
if value == self.last_value:
return "discard", 0.
self.last_value = value
if self.is_pwm:
self.mcu_pin.set_pwm(print_time, value)
else:
self.mcu_pin.set_digital(print_time, value)
cmd_SET_PIN_help = "Set the value of an output pin"
def cmd_SET_PIN(self, gcmd):
# Read requested value
Expand Down
8 changes: 4 additions & 4 deletions klippy/extras/servo.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ def __init__(self, config):
def get_status(self, eventtime):
return {'value': self.last_value}
def _set_pwm(self, print_time, value):
if value != self.last_value:
self.last_value = value
self.mcu_servo.set_pwm(print_time, value)
return (True, 0.)
if value == self.last_value:
return "discard", 0.
self.last_value = value
self.mcu_servo.set_pwm(print_time, value)
def _get_pwm_from_angle(self, angle):
angle = max(0., min(self.max_angle, angle))
width = self.min_width + angle * self.angle_to_width
Expand Down
12 changes: 5 additions & 7 deletions klippy/extras/sx1509.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,17 @@ def __init__(self, config):
REG_INPUT_DISABLE : 0, REG_ANALOG_DRIVER_ENABLE : 0}
self.reg_i_on_dict = {reg : 0 for reg in REG_I_ON}
def _build_config(self):
# Reset the chip
# Reset the chip, Default RegClock/RegMisc 0x0
self._mcu.add_config_cmd("i2c_write oid=%d data=%02x%02x" % (
self._oid, REG_RESET, 0x12))
self._mcu.add_config_cmd("i2c_write oid=%d data=%02x%02x" % (
self._oid, REG_RESET, 0x34))
# Enable Oscillator
self._mcu.add_config_cmd("i2c_modify_bits oid=%d reg=%02x"
" clear_set_bits=%02x%02x" % (
self._oid, REG_CLOCK, 0, (1 << 6)))
self._mcu.add_config_cmd("i2c_write oid=%d data=%02x%02x" % (
self._oid, REG_CLOCK, (1 << 6)))
# Setup Clock Divider
self._mcu.add_config_cmd("i2c_modify_bits oid=%d reg=%02x"
" clear_set_bits=%02x%02x" % (
self._oid, REG_MISC, 0, (1 << 4)))
self._mcu.add_config_cmd("i2c_write oid=%d data=%02x%02x" % (
self._oid, REG_MISC, (1 << 4)))
# Transfer all regs with their initial cached state
for _reg, _data in self.reg_dict.items():
self._mcu.add_config_cmd("i2c_write oid=%d data=%02x%04x" % (
Expand Down
2 changes: 1 addition & 1 deletion scripts/flash_usb.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ def flash_picoboot(device, binfile, sudo):
# We need one level up to get access to busnum/devnum files
usbdir = os.path.dirname(devpath)
enter_bootloader(device)
wait_path(usbdir)
wait_path(usbdir + "/busnum")
with open(usbdir + "/busnum") as f:
bus = f.read().strip()
with open(usbdir + "/devnum") as f:
Expand Down
33 changes: 0 additions & 33 deletions src/i2ccmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,36 +81,3 @@ command_i2c_read(uint32_t * args)
sendf("i2c_read_response oid=%c response=%*s", oid, data_len, data);
}
DECL_COMMAND(command_i2c_read, "i2c_read oid=%c reg=%*s read_len=%u");

void
command_i2c_modify_bits(uint32_t *args)
{
uint8_t oid = args[0];
struct i2cdev_s *i2c = oid_lookup(oid, command_config_i2c);
uint8_t reg_len = args[1];
uint8_t *reg = command_decode_ptr(args[2]);
uint32_t clear_set_len = args[3];
if (clear_set_len % 2 != 0)
shutdown("i2c_modify_bits: Odd number of bits!");
uint8_t data_len = clear_set_len/2;
uint8_t *clear_set = command_decode_ptr(args[4]);
uint8_t receive_data[reg_len + data_len];
uint_fast8_t flags = i2c->flags;
memcpy(receive_data, reg, reg_len);
if (CONFIG_WANT_SOFTWARE_I2C && flags & IF_SOFTWARE)
i2c_software_read(
i2c->i2c_software, reg_len, reg, data_len, receive_data + reg_len);
else
i2c_read(
i2c->i2c_config, reg_len, reg, data_len, receive_data + reg_len);
for (int i = 0; i < data_len; i++) {
receive_data[reg_len + i] &= ~clear_set[i];
receive_data[reg_len + i] |= clear_set[data_len + i];
}
if (CONFIG_WANT_SOFTWARE_I2C && flags & IF_SOFTWARE)
i2c_software_write(i2c->i2c_software, reg_len + data_len, receive_data);
else
i2c_write(i2c->i2c_config, reg_len + data_len, receive_data);
}
DECL_COMMAND(command_i2c_modify_bits,
"i2c_modify_bits oid=%c reg=%*s clear_set_bits=%*s");
22 changes: 22 additions & 0 deletions src/rp2040/i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,20 @@ i2c_do_write(i2c_hw_t *i2c, uint8_t addr, uint8_t write_len, uint8_t *write
if (!timer_is_before(timer_read_time(), timeout))
shutdown("i2c timeout");
}

if (i2c->raw_intr_stat & I2C_IC_RAW_INTR_STAT_TX_ABRT_BITS) {
uint32_t abort_source = i2c->tx_abrt_source;
if (abort_source & I2C_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK_BITS)
{
i2c->clr_tx_abrt;
shutdown("i2c Start NACK");
}
if (abort_source & I2C_IC_TX_ABRT_SOURCE_ABRT_TXDATA_NOACK_BITS)
{
i2c->clr_tx_abrt;
shutdown("i2c NACK");
}
}
}

static void
Expand Down Expand Up @@ -186,6 +200,14 @@ i2c_do_read(i2c_hw_t *i2c, uint8_t addr, uint8_t read_len, uint8_t *read
*read++ = i2c->data_cmd & 0xFF;
have_read++;
}

if (i2c->raw_intr_stat & I2C_IC_RAW_INTR_STAT_TX_ABRT_BITS) {
uint32_t abort_source = i2c->tx_abrt_source;
if (abort_source & I2C_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK_BITS) {
i2c->clr_tx_abrt;
shutdown("i2c Start Read NACK");
}
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/stm32/i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ i2c_wait(I2C_TypeDef *i2c, uint32_t set, uint32_t clear, uint32_t timeout)
uint32_t sr1 = i2c->SR1;
if ((sr1 & set) == set && (sr1 & clear) == 0)
return sr1;
if (sr1 & I2C_SR1_AF)
shutdown("I2C NACK error encountered");
if (!timer_is_before(timer_read_time(), timeout))
shutdown("i2c timeout");
}
Expand Down
20 changes: 15 additions & 5 deletions src/stm32/stm32f0_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,19 @@ i2c_setup(uint32_t bus, uint32_t rate, uint8_t addr)
gpio_peripheral(ii->sda_pin, ii->function | GPIO_OPEN_DRAIN, 1);

// Set 100Khz frequency and enable
i2c->TIMINGR = ((0xB << I2C_TIMINGR_PRESC_Pos)
| (0x13 << I2C_TIMINGR_SCLL_Pos)
| (0xF << I2C_TIMINGR_SCLH_Pos)
| (0x2 << I2C_TIMINGR_SDADEL_Pos)
| (0x4 << I2C_TIMINGR_SCLDEL_Pos));
uint32_t nom_i2c_clock = 8000000; // 8mhz internal clock = 125ns ticks
uint32_t scll = 40; // 40 * 125ns = 5us
uint32_t sclh = 32; // 32 * 125ns = 4us
uint32_t sdadel = 4; // 4 * 125ns = 500ns
uint32_t scldel = 10; // 10 * 125ns = 1250ns

uint32_t pclk = get_pclock_frequency((uint32_t)i2c);
uint32_t presc = DIV_ROUND_UP(pclk, nom_i2c_clock);
i2c->TIMINGR = (((presc - 1) << I2C_TIMINGR_PRESC_Pos)
| ((scll - 1) << I2C_TIMINGR_SCLL_Pos)
| ((sclh - 1) << I2C_TIMINGR_SCLH_Pos)
| (sdadel << I2C_TIMINGR_SDADEL_Pos)
| ((scldel - 1) << I2C_TIMINGR_SCLDEL_Pos));
i2c->CR1 = I2C_CR1_PE;
}

Expand All @@ -166,6 +174,8 @@ i2c_wait(I2C_TypeDef *i2c, uint32_t set, uint32_t timeout)
uint32_t isr = i2c->ISR;
if (isr & set)
return isr;
if (isr & I2C_ISR_NACKF)
shutdown("I2C NACK error encountered");
if (!timer_is_before(timer_read_time(), timeout))
shutdown("i2c timeout");
}
Expand Down
4 changes: 2 additions & 2 deletions src/stm32/stm32g4.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include "internal.h" // enable_pclock
#include "sched.h" // sched_main

#define FREQ_PERIPH_DIV 1
#define FREQ_PERIPH_DIV 2
#define FREQ_PERIPH (CONFIG_CLOCK_FREQ / FREQ_PERIPH_DIV)

// Map a peripheral address to its enable bits
Expand Down Expand Up @@ -142,7 +142,7 @@ clock_setup(void)
RCC->PLLCFGR |= RCC_PLLCFGR_PLLREN;

// Switch system clock to PLL
RCC->CFGR = RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE1_DIV1 | RCC_CFGR_PPRE2_DIV1
RCC->CFGR = RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE1_DIV2 | RCC_CFGR_PPRE2_DIV2
| RCC_CFGR_SW_PLL;
while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_PLL)
;
Expand Down

0 comments on commit 87b7c35

Please sign in to comment.