With corrected calculations, the new PID values are a bit loose
in comparison to the old calculations.
Hysteresis in general shifts the output from "real" value towards
some imaginary numbers.
Regardless, for some heaters, large hysteresis can screw up results.
Towards much larger Kd then actually necessary.
Trade it back with reduced hysteresis in half.
Signed-off-by: Timofey Titovets <nefelim4ag@gmail.com>
Add SPI access, internal-clock PLL setup, integrated-current-sense
current control, SpreadCycle, temperature reporting, and standard TMC
fault and status helpers. Check the PLL whenever registers are restored
and clear the phase offset when reinitializing the PLL.
Document the new configuration and include a Klippy regression case.
Derived from the GPLv3 TMC5262 driver by Rogerio Goncalves in Kalico.
Signed-off-by: Rogerio Goncalves <rogerlz@gmail.com>
Signed-off-by: Uriah Kessman <fishyfabspnw@gmail.com>
Run an optional callback before restoring registers on connect, enable,
and INIT_TMC. Export clear_mcu_phase_offset() so drivers that reset their
phase counter can invalidate the offset without accessing helper state.
Signed-off-by: Uriah Kessman <fishyfabspnw@gmail.com>
Move the TMC2240 ADC conversion into its driver and pass it explicitly
through the common helpers. Extract the ADC field before conversion so
drivers with packed temperature registers can use the same status path.
Signed-off-by: Uriah Kessman <fishyfabspnw@gmail.com>
A command waiting for an ack from an mcu that stopped responding never
completes and may hold the gcode mutex. On a communication timeout fail
all current and future raw_send_wait_ack() calls with an error instead.
Signed-off-by: Maksim Bolgov <maksim8024@gmail.com>
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
_gcode_params was set before the checks, so a rejected command could
change the params of a running or a later calibration.
Signed-off-by: Maksim Bolgov <maksim8024@gmail.com>
cal_samples[-1][0] is the first sample of the last height, equal to
min_temp. Use the last sample so validation covers the calibrated range.
Signed-off-by: Maksim Bolgov <maksim8024@gmail.com>
An error in the auto-started TEMPERATURE_PROBE_NEXT reached the reactor and
shut down the printer. Log it instead, run_script() already reports it.
Signed-off-by: Maksim Bolgov <maksim8024@gmail.com>
Polynomial2d.fit() raised TypeError when the solver returned None, which
shut down the printer. Raise a gcode error instead.
Signed-off-by: Maksim Bolgov <maksim8024@gmail.com>
The check used the number of heights, which is always 9, so it never
fired. Count the collected samples instead.
Signed-off-by: Maksim Bolgov <maksim8024@gmail.com>
Add a timeout for waiting for sensor data. Without it, a sensor outage or
mcu shutdown left collect_sample() waiting forever with the gcode mutex
held, so RESTART and FIRMWARE_RESTART were blocked.
Signed-off-by: Maksim Bolgov <maksim8024@gmail.com>
TIM3 channels 1 and 2 are available on PB4 and PB5 through the timer's
partial remap. gpio_peripheral() already programs TIM3_REMAP_PARTIALREMAP
for those two pins, but they were missing from the stm32f1 hardware pwm
table, so a config naming them was rejected as "Not a valid PWM pin".
The stm32f0 and stm32h7 tables already list them.
Signed-off-by: Lev Voronov <minicx@disroot.org>
Several links pointed at heading anchors that no longer exist (renamed
or moved sections), so they did not jump to the intended section.
Update them to the current anchors, and use a relative path for the
sample-pwm-tool.cfg link so it resolves like the other config links.
Signed-off-by: Satvik Mishra <Satvikmishra.ipu146183@maims.ac.in>
Utilize the generic code. The previous code could possibly busy wait
for a long time during console_sendf().
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Signed-off-by: Elias Bakken <elias@iagent.no>
Add a new variant of timer_dispatch_many() for chips that do not
support hardware irqs, or do not support hardware irqs being enabled
during timer dispatch. This new variant allows the boards to poll for
events if many timers are run back to back.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
The n32g45x defaulted to 128Mhz, which is not reachable from a 12Mhz or
24Mhz crystal: the PLL takes the crystal or half of it, so only exact
multiples of crystal / 2 can be generated, and the build time check in
clock_setup_n32g45x() rejects the rate. CLOCK_FREQ has no prompt, so a
board with one of those crystals could not be built at all.
Run it at 144Mhz instead, the chip's rated maximum, which is an exact
multiple of half of each of the 8, 12, 16 and 24Mhz crystals. That
includes usb builds: at 144Mhz the usb prescaler divides by 3 to give
the 48Mhz the peripheral needs, so the separate 96Mhz usb rate is no
longer required. 20Mhz and 25Mhz crystals, which do not give 72Mhz on
an stm32f103 either, still fail at build time.
Signed-off-by: Lev Voronov <minicx@disroot.org>
Add an hd44780_delay config option so the minimum wait time after
sending a command or data byte to the hd44780 chip can be tuned.
Some displays need more than the default 40us. The value is limited
to a maximum of 60us, as the mcu busy-waits for this delay.
Signed-off-by: Florian Hofer <SirDeath81_github@outlook.com>
The bare clock pulses in cs1237_write_config() are indistinguishable
from reading a bit with the result ignored, and the command and config
bytes are always written back to back with the direction-change clock
between them. Dropping cs1237_clock_pulses() and passing a bit count to
cs1237_write_bits() lets the whole 16 clock command be written in one
call, which makes the bit-banged sequence easier to follow.
No functional change: the same 46 clocks are issued in the same order.
Suggested-by: Kevin O'Connor <kevin@koconnor.net>
Signed-off-by: Koshik Oleg <qwertyboy58@gmail.com>
The 27th SCLK pulse of a CS1237 conversion frame does not carry
conversion data - per the datasheet it forces DOUT high until the next
conversion is ready. Its sampled level therefore depends on when the
chip drives the line rather than on the conversion result.
Sampling it as a data bit and requiring it to read back as 1 produces
spurious SERIAL_DATA_DESYNCHRONISED errors on MCUs under load, where
the bit-banged read can be preempted between clocks. On a toolhead MCU
running the CS1237 at 640sps this yields roughly 30 errors per second,
which makes load_cell_probe unusable - every probe aborts with "Load
cell sensor reported errors while probing".
Still clock all 27 pulses, but discard the last one and base the desync
check on the reserved bit instead. The update1 bit used for config
verification is preserved.
This is the approach used by the out-of-tree QIDI Q2 driver in
MisterSheikh/Qidi_Q2_Mainline_Klipper, where the 27th clock has been
issued without sampling since f9f6cf0 (Feb 2026) and the reserved-bit
desync check was added in 1ee516d (Aug 2026). That driver ran reliably
on the same hardware for months, which is what identified the 27th bit
as the difference once the in-tree driver started reporting desyncs.
Co-authored-by: Ahmed Sheikh <ahmed.ali.sheikh1998@gmail.com>
Signed-off-by: Ahmed Sheikh <ahmed.ali.sheikh1998@gmail.com>
Signed-off-by: Koshik Oleg <qwertyboy58@gmail.com>
Klipper on ar100 is currently built with -O3 optimizations.
-O2 is a reasonable compromise between size and speed. -O3 does
not give any meaningful improvements.
Regarding the size difference, Allwinner A64 has 64 KB of SRAM A2,
and we can use all of it for Klipper. The previous size check
capped the size at 48 KB instead of the 64 KB that is available.
Signed-off-by: Elias Bakken <elias@iagent.no>
TimedRotatingFileHandler.doRollover() internally
checks if the name already exists; if it does
it does not advance the rolloverAt
So, the function gets triggered for every emitted log line
Signed-off-by: Timofey Titovets <nefelim4ag@gmail.com>
gpio_adc_setup() enabled and calibrated an adc block every time one of
its channels was configured. The n32g455 puts PA0 and PA1 on the same
block, so configuring the second pin recalibrated an adc that was
already running: from then on that block could no longer complete a
conversion for the newly added channel, and the mcu spent its time
polling an adc that never signalled completion.
On a FlashForge AD5M toolhead this left the hotend thermistor reading
0C while the mcu busy time reported in the periodic stats grew by more
than a factor of two.
Enable the clock of the block that is actually needed rather than all
four, and use that clock enable bit to tell whether the block still
needs to be initialised, the way stm32/adc.c uses is_enabled_pclock().
Signed-off-by: Lev Voronov <minicx@disroot.org>
The n32g45x adc runs from two clocks: ADCHCLK, divided down from HCLK,
and a separate 1Mhz reference clock, ADC1M. The driver hardcoded
ADCHCLK to HCLK/16, which its comment shows was picked for a 64Mhz
HCLK, and left ADC1M entirely alone. At the 144Mhz this chip can run
at that leaves ADCHCLK at 9Mhz, and ADC1M at whatever the reset default
happens to be rather than the 1Mhz the vendor code selects.
Derive the ADCHCLK divisor from CONFIG_CLOCK_FREQ so the adc clock
stays within range at every supported system clock rate, and divide
ADC1M down from the oscillator the pll already uses, so it lands on
1Mhz for any of the supported crystals.
Also match the vendor sequence when starting the adc: select the HCLK
sourced clock mode explicitly instead of relying on the reset value of
CKMOD, and set AD_ON and CAL as individual bits rather than assigning
CTRL2, which discarded the trigger and alignment configuration
ADC_Init() had just written. Let the adc settle after leaving power
down mode before polling it, as ADC_Enable() does.
Signed-off-by: Lev Voronov <minicx@disroot.org>
The n32g45x keeps its adc, sdio, qspi, rng, crypto engine, opamp, comp
and can2 behind the "ex mode" bit in PWR_CTRL3. While that bit is
clear the peripherals stay unclocked and their RCC enable bits do not
even latch: writing all ones to RCC_AHBPCLKEN reads back 0x57, without
any of the ADC1-4 bits, and writing all ones to RCC_APB1PCLKEN leaves
opamp, comp and can2 clear.
Klipper never set it, so gpio_adc_setup() spun forever waiting for the
ADC_FLAG_RDY of an unclocked adc. The mcu went silent in the middle of
the host's configuration and the host waited for a reply that never
came, which makes this look like a dead board rather than a missing
clock.
Set the bit before configuring any clock, the way the vendor
SystemInit() in system_n32g45x.c does. The stm32f103 headers Klipper
builds the n32g45x against describe a PWR block with two registers
only, so address the third one directly.
Signed-off-by: Lev Voronov <minicx@disroot.org>
zero_reference_position updates every point in the bed mesh
With direct mode z_matrix is used directly for probe_matrix
and mesh_matrix
Which, in turn, makes compensation applied twice
Signed-off-by: Timofey Titovets <nefelim4ag@gmail.com>
With config like:
[bed_mesh]
mesh_pps: 0,0
algorithm: bicubic
The algorithm direct should be "always" chosen
But it only gets applied/enabled if `need_cfg_update = True`
is triggered
Signed-off-by: Timofey Titovets <nefelim4ag@gmail.com>
Sometimes it can be necessary to tune the threshold
but it is obscure knowledge that contact_slope_delta
Is basically about the maximum safe value
Signed-off-by: Timofey Titovets <nefelim4ag@gmail.com>
Guess can fail for specific users and
often outputs about 60% of refine value
Bump it a bit to increase the success probability
Signed-off-by: Timofey Titovets <nefelim4ag@gmail.com>
Detection of a too-early trigger is defined as a time window size
but because we require at least an end_time - start_time window
It is always true as long as there are no lost samples
Signed-off-by: Timofey Titovets <nefelim4ag@gmail.com>
Insufficient slope: a bit of an obscure error.
Add a slightly friendlier output with Z where
tap failed
Signed-off-by: Timofey Titovets <nefelim4ag@gmail.com>
After implementation of tap over retraction data
Tap only uses args passed to the gcmd
It is not viable to write and pass every possible arg
So, encode and pass args used in the calibration start
Signed-off-by: Timofey Titovets <nefelim4ag@gmail.com>